2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Compare-Pick Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Compare-Pick Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Compare-Pick Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1020 #include "gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1068 int singlestep_enabled;
1069 /* Routine used to access memory */
1071 uint32_t hflags, saved_hflags;
1073 target_ulong btarget;
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1078 * exception condition */
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1084 static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1091 static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1095 static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1099 static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1103 static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1110 #define MIPS_DEBUG(fmt, ...) \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1119 #define LOG_DISAS(...) \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1126 #define MIPS_INVAL(op) \
1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1130 /* General purpose registers moves. */
1131 static inline void gen_load_gpr (TCGv t, int reg)
1134 tcg_gen_movi_tl(t, 0);
1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1139 static inline void gen_store_gpr (TCGv t, int reg)
1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
1145 /* Moves to/from ACX register. */
1146 static inline void gen_load_ACX (TCGv t, int reg)
1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1151 static inline void gen_store_ACX (TCGv t, int reg)
1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
1156 /* Moves to/from shadow registers. */
1157 static inline void gen_load_srsgpr (int from, int to)
1159 TCGv t0 = tcg_temp_new();
1162 tcg_gen_movi_tl(t0, 0);
1164 TCGv_i32 t2 = tcg_temp_new_i32();
1165 TCGv_ptr addr = tcg_temp_new_ptr();
1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
1172 tcg_gen_add_ptr(addr, cpu_env, addr);
1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1175 tcg_temp_free_ptr(addr);
1176 tcg_temp_free_i32(t2);
1178 gen_store_gpr(t0, to);
1182 static inline void gen_store_srsgpr (int from, int to)
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
1187 TCGv_ptr addr = tcg_temp_new_ptr();
1189 gen_load_gpr(t0, from);
1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
1195 tcg_gen_add_ptr(addr, cpu_env, addr);
1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1198 tcg_temp_free_ptr(addr);
1199 tcg_temp_free_i32(t2);
1204 /* Floating point register moves. */
1205 static void gen_load_fpr32(TCGv_i32 t, int reg)
1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1210 static void gen_store_fpr32(TCGv_i32 t, int reg)
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
1218 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
1226 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
1234 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1236 if (ctx->hflags & MIPS_HFLAG_F64) {
1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1243 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1245 if (ctx->hflags & MIPS_HFLAG_F64) {
1246 tcg_gen_mov_i64(fpu_f64[reg], t);
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
1251 tcg_gen_shri_i64(t0, t, 32);
1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1253 tcg_temp_free_i64(t0);
1257 static inline int get_fp_bit (int cc)
1266 static inline void gen_save_pc(target_ulong pc)
1268 tcg_gen_movi_tl(cpu_PC, pc);
1271 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1275 gen_save_pc(ctx->pc);
1276 ctx->saved_pc = ctx->pc;
1278 if (ctx->hflags != ctx->saved_hflags) {
1279 tcg_gen_movi_i32(hflags, ctx->hflags);
1280 ctx->saved_hflags = ctx->hflags;
1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1287 tcg_gen_movi_tl(btarget, ctx->btarget);
1293 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1295 ctx->saved_hflags = ctx->hflags;
1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1302 ctx->btarget = env->btarget;
1308 generate_exception_err (DisasContext *ctx, int excp, int err)
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
1312 save_cpu_state(ctx, 1);
1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
1319 generate_exception (DisasContext *ctx, int excp)
1321 save_cpu_state(ctx, 1);
1322 gen_helper_0e0i(raise_exception, excp);
1325 /* Addresses computation */
1326 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1328 tcg_gen_add_tl(ret, arg0, arg1);
1330 #if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
1336 tcg_gen_ext32s_i64(ret, ret);
1341 static inline void check_cp0_enabled(DisasContext *ctx)
1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1344 generate_exception_err(ctx, EXCP_CpU, 0);
1347 static inline void check_cp1_enabled(DisasContext *ctx)
1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1353 /* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1357 static inline void check_cop1x(DisasContext *ctx)
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1363 /* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1366 static inline void check_cp1_64bitmode(DisasContext *ctx)
1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1369 generate_exception(ctx, EXCP_RI);
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1386 generate_exception(ctx, EXCP_RI);
1389 /* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1393 static inline void check_dsp(DisasContext *ctx)
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1400 static inline void check_dspr2(DisasContext *ctx)
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1407 /* This code generates a "reserved instruction" exception if the
1408 CPU does not support the instruction set corresponding to flags. */
1409 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1411 if (unlikely(!(env->insn_flags & flags)))
1412 generate_exception(ctx, EXCP_RI);
1415 /* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
1417 static inline void check_mips_64(DisasContext *ctx)
1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1420 generate_exception(ctx, EXCP_RI);
1423 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1427 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1437 check_cp1_64bitmode(ctx); \
1443 check_cp1_registers(ctx, fs | ft); \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1476 FOP_CONDS(, 0, d, FMT_D, 64)
1477 FOP_CONDS(abs, 1, d, FMT_D, 64)
1478 FOP_CONDS(, 0, s, FMT_S, 32)
1479 FOP_CONDS(abs, 1, s, FMT_S, 32)
1480 FOP_CONDS(, 0, ps, FMT_PS, 64)
1481 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1483 #undef gen_ldcmp_fpr32
1484 #undef gen_ldcmp_fpr64
1486 /* load/store instructions. */
1487 #ifdef CONFIG_USER_ONLY
1488 #define OP_LD_ATOMIC(insn,fname) \
1489 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1491 TCGv t0 = tcg_temp_new(); \
1492 tcg_gen_mov_tl(t0, arg1); \
1493 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1494 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1495 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1496 tcg_temp_free(t0); \
1499 #define OP_LD_ATOMIC(insn,fname) \
1500 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1502 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1505 OP_LD_ATOMIC(ll,ld32s);
1506 #if defined(TARGET_MIPS64)
1507 OP_LD_ATOMIC(lld,ld64);
1511 #ifdef CONFIG_USER_ONLY
1512 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1513 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1515 TCGv t0 = tcg_temp_new(); \
1516 int l1 = gen_new_label(); \
1517 int l2 = gen_new_label(); \
1519 tcg_gen_andi_tl(t0, arg2, almask); \
1520 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1521 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1522 generate_exception(ctx, EXCP_AdES); \
1523 gen_set_label(l1); \
1524 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1525 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1526 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1527 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1528 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1529 gen_helper_0e0i(raise_exception, EXCP_SC); \
1530 gen_set_label(l2); \
1531 tcg_gen_movi_tl(t0, 0); \
1532 gen_store_gpr(t0, rt); \
1533 tcg_temp_free(t0); \
1536 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1537 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1539 TCGv t0 = tcg_temp_new(); \
1540 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1541 gen_store_gpr(t0, rt); \
1542 tcg_temp_free(t0); \
1545 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1546 #if defined(TARGET_MIPS64)
1547 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1551 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1552 int base, int16_t offset)
1555 tcg_gen_movi_tl(addr, offset);
1556 } else if (offset == 0) {
1557 gen_load_gpr(addr, base);
1559 tcg_gen_movi_tl(addr, offset);
1560 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1564 static target_ulong pc_relative_pc (DisasContext *ctx)
1566 target_ulong pc = ctx->pc;
1568 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1569 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1574 pc &= ~(target_ulong)3;
1579 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1580 int rt, int base, int16_t offset)
1582 const char *opn = "ld";
1585 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1586 /* Loongson CPU uses a load to zero register for prefetch.
1587 We emulate it as a NOP. On other CPU we must perform the
1588 actual memory access. */
1593 t0 = tcg_temp_new();
1594 gen_base_offset_addr(ctx, t0, base, offset);
1597 #if defined(TARGET_MIPS64)
1599 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1600 gen_store_gpr(t0, rt);
1604 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1605 gen_store_gpr(t0, rt);
1609 save_cpu_state(ctx, 1);
1610 op_ld_lld(t0, t0, ctx);
1611 gen_store_gpr(t0, rt);
1615 t1 = tcg_temp_new();
1616 tcg_gen_andi_tl(t1, t0, 7);
1617 #ifndef TARGET_WORDS_BIGENDIAN
1618 tcg_gen_xori_tl(t1, t1, 7);
1620 tcg_gen_shli_tl(t1, t1, 3);
1621 tcg_gen_andi_tl(t0, t0, ~7);
1622 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1623 tcg_gen_shl_tl(t0, t0, t1);
1624 tcg_gen_xori_tl(t1, t1, 63);
1625 t2 = tcg_const_tl(0x7fffffffffffffffull);
1626 tcg_gen_shr_tl(t2, t2, t1);
1627 gen_load_gpr(t1, rt);
1628 tcg_gen_and_tl(t1, t1, t2);
1630 tcg_gen_or_tl(t0, t0, t1);
1632 gen_store_gpr(t0, rt);
1636 t1 = tcg_temp_new();
1637 tcg_gen_andi_tl(t1, t0, 7);
1638 #ifdef TARGET_WORDS_BIGENDIAN
1639 tcg_gen_xori_tl(t1, t1, 7);
1641 tcg_gen_shli_tl(t1, t1, 3);
1642 tcg_gen_andi_tl(t0, t0, ~7);
1643 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1644 tcg_gen_shr_tl(t0, t0, t1);
1645 tcg_gen_xori_tl(t1, t1, 63);
1646 t2 = tcg_const_tl(0xfffffffffffffffeull);
1647 tcg_gen_shl_tl(t2, t2, t1);
1648 gen_load_gpr(t1, rt);
1649 tcg_gen_and_tl(t1, t1, t2);
1651 tcg_gen_or_tl(t0, t0, t1);
1653 gen_store_gpr(t0, rt);
1657 t1 = tcg_const_tl(pc_relative_pc(ctx));
1658 gen_op_addr_add(ctx, t0, t0, t1);
1660 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1661 gen_store_gpr(t0, rt);
1666 t1 = tcg_const_tl(pc_relative_pc(ctx));
1667 gen_op_addr_add(ctx, t0, t0, t1);
1669 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1670 gen_store_gpr(t0, rt);
1674 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1675 gen_store_gpr(t0, rt);
1679 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1680 gen_store_gpr(t0, rt);
1684 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1685 gen_store_gpr(t0, rt);
1689 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1690 gen_store_gpr(t0, rt);
1694 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1695 gen_store_gpr(t0, rt);
1699 t1 = tcg_temp_new();
1700 tcg_gen_andi_tl(t1, t0, 3);
1701 #ifndef TARGET_WORDS_BIGENDIAN
1702 tcg_gen_xori_tl(t1, t1, 3);
1704 tcg_gen_shli_tl(t1, t1, 3);
1705 tcg_gen_andi_tl(t0, t0, ~3);
1706 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1707 tcg_gen_shl_tl(t0, t0, t1);
1708 tcg_gen_xori_tl(t1, t1, 31);
1709 t2 = tcg_const_tl(0x7fffffffull);
1710 tcg_gen_shr_tl(t2, t2, t1);
1711 gen_load_gpr(t1, rt);
1712 tcg_gen_and_tl(t1, t1, t2);
1714 tcg_gen_or_tl(t0, t0, t1);
1716 tcg_gen_ext32s_tl(t0, t0);
1717 gen_store_gpr(t0, rt);
1721 t1 = tcg_temp_new();
1722 tcg_gen_andi_tl(t1, t0, 3);
1723 #ifdef TARGET_WORDS_BIGENDIAN
1724 tcg_gen_xori_tl(t1, t1, 3);
1726 tcg_gen_shli_tl(t1, t1, 3);
1727 tcg_gen_andi_tl(t0, t0, ~3);
1728 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1729 tcg_gen_shr_tl(t0, t0, t1);
1730 tcg_gen_xori_tl(t1, t1, 31);
1731 t2 = tcg_const_tl(0xfffffffeull);
1732 tcg_gen_shl_tl(t2, t2, t1);
1733 gen_load_gpr(t1, rt);
1734 tcg_gen_and_tl(t1, t1, t2);
1736 tcg_gen_or_tl(t0, t0, t1);
1738 gen_store_gpr(t0, rt);
1742 save_cpu_state(ctx, 1);
1743 op_ld_ll(t0, t0, ctx);
1744 gen_store_gpr(t0, rt);
1748 (void)opn; /* avoid a compiler warning */
1749 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1754 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1755 int base, int16_t offset)
1757 const char *opn = "st";
1758 TCGv t0 = tcg_temp_new();
1759 TCGv t1 = tcg_temp_new();
1761 gen_base_offset_addr(ctx, t0, base, offset);
1762 gen_load_gpr(t1, rt);
1764 #if defined(TARGET_MIPS64)
1766 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1770 save_cpu_state(ctx, 1);
1771 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1775 save_cpu_state(ctx, 1);
1776 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1781 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1785 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1789 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1793 save_cpu_state(ctx, 1);
1794 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1798 save_cpu_state(ctx, 1);
1799 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1803 (void)opn; /* avoid a compiler warning */
1804 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1810 /* Store conditional */
1811 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1812 int base, int16_t offset)
1814 const char *opn = "st_cond";
1817 #ifdef CONFIG_USER_ONLY
1818 t0 = tcg_temp_local_new();
1819 t1 = tcg_temp_local_new();
1821 t0 = tcg_temp_new();
1822 t1 = tcg_temp_new();
1824 gen_base_offset_addr(ctx, t0, base, offset);
1825 gen_load_gpr(t1, rt);
1827 #if defined(TARGET_MIPS64)
1829 save_cpu_state(ctx, 1);
1830 op_st_scd(t1, t0, rt, ctx);
1835 save_cpu_state(ctx, 1);
1836 op_st_sc(t1, t0, rt, ctx);
1840 (void)opn; /* avoid a compiler warning */
1841 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1846 /* Load and store */
1847 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1848 int base, int16_t offset)
1850 const char *opn = "flt_ldst";
1851 TCGv t0 = tcg_temp_new();
1853 gen_base_offset_addr(ctx, t0, base, offset);
1854 /* Don't do NOP if destination is zero: we must perform the actual
1859 TCGv_i32 fp0 = tcg_temp_new_i32();
1861 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1862 tcg_gen_trunc_tl_i32(fp0, t0);
1863 gen_store_fpr32(fp0, ft);
1864 tcg_temp_free_i32(fp0);
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 TCGv t1 = tcg_temp_new();
1873 gen_load_fpr32(fp0, ft);
1874 tcg_gen_extu_i32_tl(t1, fp0);
1875 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1877 tcg_temp_free_i32(fp0);
1883 TCGv_i64 fp0 = tcg_temp_new_i64();
1885 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1886 gen_store_fpr64(ctx, fp0, ft);
1887 tcg_temp_free_i64(fp0);
1893 TCGv_i64 fp0 = tcg_temp_new_i64();
1895 gen_load_fpr64(ctx, fp0, ft);
1896 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1897 tcg_temp_free_i64(fp0);
1903 generate_exception(ctx, EXCP_RI);
1906 (void)opn; /* avoid a compiler warning */
1907 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1912 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1913 uint32_t op, int rt, int rs, int16_t imm)
1915 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1916 check_cp1_enabled(ctx);
1917 gen_flt_ldst(ctx, op, rt, rs, imm);
1919 generate_exception_err(ctx, EXCP_CpU, 1);
1923 /* Arithmetic with immediate operand */
1924 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1925 int rt, int rs, int16_t imm)
1927 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1928 const char *opn = "imm arith";
1930 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1931 /* If no destination, treat it as a NOP.
1932 For addi, we must generate the overflow exception when needed. */
1939 TCGv t0 = tcg_temp_local_new();
1940 TCGv t1 = tcg_temp_new();
1941 TCGv t2 = tcg_temp_new();
1942 int l1 = gen_new_label();
1944 gen_load_gpr(t1, rs);
1945 tcg_gen_addi_tl(t0, t1, uimm);
1946 tcg_gen_ext32s_tl(t0, t0);
1948 tcg_gen_xori_tl(t1, t1, ~uimm);
1949 tcg_gen_xori_tl(t2, t0, uimm);
1950 tcg_gen_and_tl(t1, t1, t2);
1952 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1954 /* operands of same sign, result different sign */
1955 generate_exception(ctx, EXCP_OVERFLOW);
1957 tcg_gen_ext32s_tl(t0, t0);
1958 gen_store_gpr(t0, rt);
1965 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1966 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1968 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1972 #if defined(TARGET_MIPS64)
1975 TCGv t0 = tcg_temp_local_new();
1976 TCGv t1 = tcg_temp_new();
1977 TCGv t2 = tcg_temp_new();
1978 int l1 = gen_new_label();
1980 gen_load_gpr(t1, rs);
1981 tcg_gen_addi_tl(t0, t1, uimm);
1983 tcg_gen_xori_tl(t1, t1, ~uimm);
1984 tcg_gen_xori_tl(t2, t0, uimm);
1985 tcg_gen_and_tl(t1, t1, t2);
1987 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1989 /* operands of same sign, result different sign */
1990 generate_exception(ctx, EXCP_OVERFLOW);
1992 gen_store_gpr(t0, rt);
1999 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2001 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2007 (void)opn; /* avoid a compiler warning */
2008 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2011 /* Logic with immediate operand */
2012 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2013 int rt, int rs, int16_t imm)
2016 const char *opn = "imm logic";
2019 /* If no destination, treat it as a NOP. */
2023 uimm = (uint16_t)imm;
2026 if (likely(rs != 0))
2027 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2029 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2034 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2036 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2040 if (likely(rs != 0))
2041 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2043 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2047 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2051 (void)opn; /* avoid a compiler warning */
2052 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2055 /* Set on less than with immediate operand */
2056 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2057 int rt, int rs, int16_t imm)
2059 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2060 const char *opn = "imm arith";
2064 /* If no destination, treat it as a NOP. */
2068 t0 = tcg_temp_new();
2069 gen_load_gpr(t0, rs);
2072 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2076 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2080 (void)opn; /* avoid a compiler warning */
2081 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2085 /* Shifts with immediate operand */
2086 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2087 int rt, int rs, int16_t imm)
2089 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2090 const char *opn = "imm shift";
2094 /* If no destination, treat it as a NOP. */
2099 t0 = tcg_temp_new();
2100 gen_load_gpr(t0, rs);
2103 tcg_gen_shli_tl(t0, t0, uimm);
2104 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2108 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2113 tcg_gen_ext32u_tl(t0, t0);
2114 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2116 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2122 TCGv_i32 t1 = tcg_temp_new_i32();
2124 tcg_gen_trunc_tl_i32(t1, t0);
2125 tcg_gen_rotri_i32(t1, t1, uimm);
2126 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2127 tcg_temp_free_i32(t1);
2129 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2133 #if defined(TARGET_MIPS64)
2135 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2139 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2143 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2148 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2150 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2155 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2159 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2163 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2167 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2172 (void)opn; /* avoid a compiler warning */
2173 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2178 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2179 int rd, int rs, int rt)
2181 const char *opn = "arith";
2183 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2184 && opc != OPC_DADD && opc != OPC_DSUB) {
2185 /* If no destination, treat it as a NOP.
2186 For add & sub, we must generate the overflow exception when needed. */
2194 TCGv t0 = tcg_temp_local_new();
2195 TCGv t1 = tcg_temp_new();
2196 TCGv t2 = tcg_temp_new();
2197 int l1 = gen_new_label();
2199 gen_load_gpr(t1, rs);
2200 gen_load_gpr(t2, rt);
2201 tcg_gen_add_tl(t0, t1, t2);
2202 tcg_gen_ext32s_tl(t0, t0);
2203 tcg_gen_xor_tl(t1, t1, t2);
2204 tcg_gen_xor_tl(t2, t0, t2);
2205 tcg_gen_andc_tl(t1, t2, t1);
2207 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2209 /* operands of same sign, result different sign */
2210 generate_exception(ctx, EXCP_OVERFLOW);
2212 gen_store_gpr(t0, rd);
2218 if (rs != 0 && rt != 0) {
2219 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2220 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2221 } else if (rs == 0 && rt != 0) {
2222 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2223 } else if (rs != 0 && rt == 0) {
2224 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2226 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2232 TCGv t0 = tcg_temp_local_new();
2233 TCGv t1 = tcg_temp_new();
2234 TCGv t2 = tcg_temp_new();
2235 int l1 = gen_new_label();
2237 gen_load_gpr(t1, rs);
2238 gen_load_gpr(t2, rt);
2239 tcg_gen_sub_tl(t0, t1, t2);
2240 tcg_gen_ext32s_tl(t0, t0);
2241 tcg_gen_xor_tl(t2, t1, t2);
2242 tcg_gen_xor_tl(t1, t0, t1);
2243 tcg_gen_and_tl(t1, t1, t2);
2245 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2247 /* operands of different sign, first operand and result different sign */
2248 generate_exception(ctx, EXCP_OVERFLOW);
2250 gen_store_gpr(t0, rd);
2256 if (rs != 0 && rt != 0) {
2257 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2258 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2259 } else if (rs == 0 && rt != 0) {
2260 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2261 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2262 } else if (rs != 0 && rt == 0) {
2263 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2265 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2269 #if defined(TARGET_MIPS64)
2272 TCGv t0 = tcg_temp_local_new();
2273 TCGv t1 = tcg_temp_new();
2274 TCGv t2 = tcg_temp_new();
2275 int l1 = gen_new_label();
2277 gen_load_gpr(t1, rs);
2278 gen_load_gpr(t2, rt);
2279 tcg_gen_add_tl(t0, t1, t2);
2280 tcg_gen_xor_tl(t1, t1, t2);
2281 tcg_gen_xor_tl(t2, t0, t2);
2282 tcg_gen_andc_tl(t1, t2, t1);
2284 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2286 /* operands of same sign, result different sign */
2287 generate_exception(ctx, EXCP_OVERFLOW);
2289 gen_store_gpr(t0, rd);
2295 if (rs != 0 && rt != 0) {
2296 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2297 } else if (rs == 0 && rt != 0) {
2298 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2299 } else if (rs != 0 && rt == 0) {
2300 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2302 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2308 TCGv t0 = tcg_temp_local_new();
2309 TCGv t1 = tcg_temp_new();
2310 TCGv t2 = tcg_temp_new();
2311 int l1 = gen_new_label();
2313 gen_load_gpr(t1, rs);
2314 gen_load_gpr(t2, rt);
2315 tcg_gen_sub_tl(t0, t1, t2);
2316 tcg_gen_xor_tl(t2, t1, t2);
2317 tcg_gen_xor_tl(t1, t0, t1);
2318 tcg_gen_and_tl(t1, t1, t2);
2320 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2322 /* operands of different sign, first operand and result different sign */
2323 generate_exception(ctx, EXCP_OVERFLOW);
2325 gen_store_gpr(t0, rd);
2331 if (rs != 0 && rt != 0) {
2332 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2333 } else if (rs == 0 && rt != 0) {
2334 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2335 } else if (rs != 0 && rt == 0) {
2336 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2338 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2344 if (likely(rs != 0 && rt != 0)) {
2345 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2346 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2348 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2353 (void)opn; /* avoid a compiler warning */
2354 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2357 /* Conditional move */
2358 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2359 int rd, int rs, int rt)
2361 const char *opn = "cond move";
2365 /* If no destination, treat it as a NOP. */
2370 t0 = tcg_temp_new();
2371 gen_load_gpr(t0, rt);
2372 t1 = tcg_const_tl(0);
2373 t2 = tcg_temp_new();
2374 gen_load_gpr(t2, rs);
2377 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2381 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2389 (void)opn; /* avoid a compiler warning */
2390 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2394 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2395 int rd, int rs, int rt)
2397 const char *opn = "logic";
2400 /* If no destination, treat it as a NOP. */
2407 if (likely(rs != 0 && rt != 0)) {
2408 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2410 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2415 if (rs != 0 && rt != 0) {
2416 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2417 } else if (rs == 0 && rt != 0) {
2418 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2419 } else if (rs != 0 && rt == 0) {
2420 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2422 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2427 if (likely(rs != 0 && rt != 0)) {
2428 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2429 } else if (rs == 0 && rt != 0) {
2430 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2431 } else if (rs != 0 && rt == 0) {
2432 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2434 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2439 if (likely(rs != 0 && rt != 0)) {
2440 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2441 } else if (rs == 0 && rt != 0) {
2442 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2443 } else if (rs != 0 && rt == 0) {
2444 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2446 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2451 (void)opn; /* avoid a compiler warning */
2452 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2455 /* Set on lower than */
2456 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2457 int rd, int rs, int rt)
2459 const char *opn = "slt";
2463 /* If no destination, treat it as a NOP. */
2468 t0 = tcg_temp_new();
2469 t1 = tcg_temp_new();
2470 gen_load_gpr(t0, rs);
2471 gen_load_gpr(t1, rt);
2474 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2478 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2482 (void)opn; /* avoid a compiler warning */
2483 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2489 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2490 int rd, int rs, int rt)
2492 const char *opn = "shifts";
2496 /* If no destination, treat it as a NOP.
2497 For add & sub, we must generate the overflow exception when needed. */
2502 t0 = tcg_temp_new();
2503 t1 = tcg_temp_new();
2504 gen_load_gpr(t0, rs);
2505 gen_load_gpr(t1, rt);
2508 tcg_gen_andi_tl(t0, t0, 0x1f);
2509 tcg_gen_shl_tl(t0, t1, t0);
2510 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2514 tcg_gen_andi_tl(t0, t0, 0x1f);
2515 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2519 tcg_gen_ext32u_tl(t1, t1);
2520 tcg_gen_andi_tl(t0, t0, 0x1f);
2521 tcg_gen_shr_tl(t0, t1, t0);
2522 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2527 TCGv_i32 t2 = tcg_temp_new_i32();
2528 TCGv_i32 t3 = tcg_temp_new_i32();
2530 tcg_gen_trunc_tl_i32(t2, t0);
2531 tcg_gen_trunc_tl_i32(t3, t1);
2532 tcg_gen_andi_i32(t2, t2, 0x1f);
2533 tcg_gen_rotr_i32(t2, t3, t2);
2534 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2535 tcg_temp_free_i32(t2);
2536 tcg_temp_free_i32(t3);
2540 #if defined(TARGET_MIPS64)
2542 tcg_gen_andi_tl(t0, t0, 0x3f);
2543 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2547 tcg_gen_andi_tl(t0, t0, 0x3f);
2548 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2552 tcg_gen_andi_tl(t0, t0, 0x3f);
2553 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2557 tcg_gen_andi_tl(t0, t0, 0x3f);
2558 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2563 (void)opn; /* avoid a compiler warning */
2564 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2569 /* Arithmetic on HI/LO registers */
2570 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2572 const char *opn = "hilo";
2575 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2581 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2582 acc = ((ctx->opcode) >> 21) & 0x03;
2584 acc = ((ctx->opcode) >> 11) & 0x03;
2593 #if defined(TARGET_MIPS64)
2595 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2599 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2604 #if defined(TARGET_MIPS64)
2606 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2610 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2616 #if defined(TARGET_MIPS64)
2618 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2622 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2625 tcg_gen_movi_tl(cpu_HI[acc], 0);
2631 #if defined(TARGET_MIPS64)
2633 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2637 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2640 tcg_gen_movi_tl(cpu_LO[acc], 0);
2645 (void)opn; /* avoid a compiler warning */
2646 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2649 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2652 const char *opn = "mul/div";
2656 t0 = tcg_temp_new();
2657 t1 = tcg_temp_new();
2659 gen_load_gpr(t0, rs);
2660 gen_load_gpr(t1, rt);
2665 TCGv t2 = tcg_temp_new();
2666 TCGv t3 = tcg_temp_new();
2667 tcg_gen_ext32s_tl(t0, t0);
2668 tcg_gen_ext32s_tl(t1, t1);
2669 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2670 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2671 tcg_gen_and_tl(t2, t2, t3);
2672 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2673 tcg_gen_or_tl(t2, t2, t3);
2674 tcg_gen_movi_tl(t3, 0);
2675 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2676 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2677 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2678 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2679 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2687 TCGv t2 = tcg_const_tl(0);
2688 TCGv t3 = tcg_const_tl(1);
2689 tcg_gen_ext32u_tl(t0, t0);
2690 tcg_gen_ext32u_tl(t1, t1);
2691 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2692 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2693 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2694 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2695 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2703 TCGv_i64 t2 = tcg_temp_new_i64();
2704 TCGv_i64 t3 = tcg_temp_new_i64();
2705 acc = ((ctx->opcode) >> 11) & 0x03;
2710 tcg_gen_ext_tl_i64(t2, t0);
2711 tcg_gen_ext_tl_i64(t3, t1);
2712 tcg_gen_mul_i64(t2, t2, t3);
2713 tcg_temp_free_i64(t3);
2714 tcg_gen_trunc_i64_tl(t0, t2);
2715 tcg_gen_shri_i64(t2, t2, 32);
2716 tcg_gen_trunc_i64_tl(t1, t2);
2717 tcg_temp_free_i64(t2);
2718 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2719 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2725 TCGv_i64 t2 = tcg_temp_new_i64();
2726 TCGv_i64 t3 = tcg_temp_new_i64();
2727 acc = ((ctx->opcode) >> 11) & 0x03;
2732 tcg_gen_ext32u_tl(t0, t0);
2733 tcg_gen_ext32u_tl(t1, t1);
2734 tcg_gen_extu_tl_i64(t2, t0);
2735 tcg_gen_extu_tl_i64(t3, t1);
2736 tcg_gen_mul_i64(t2, t2, t3);
2737 tcg_temp_free_i64(t3);
2738 tcg_gen_trunc_i64_tl(t0, t2);
2739 tcg_gen_shri_i64(t2, t2, 32);
2740 tcg_gen_trunc_i64_tl(t1, t2);
2741 tcg_temp_free_i64(t2);
2742 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2743 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2747 #if defined(TARGET_MIPS64)
2750 TCGv t2 = tcg_temp_new();
2751 TCGv t3 = tcg_temp_new();
2752 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2753 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2754 tcg_gen_and_tl(t2, t2, t3);
2755 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2756 tcg_gen_or_tl(t2, t2, t3);
2757 tcg_gen_movi_tl(t3, 0);
2758 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2759 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2760 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2768 TCGv t2 = tcg_const_tl(0);
2769 TCGv t3 = tcg_const_tl(1);
2770 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2771 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2772 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2779 gen_helper_dmult(cpu_env, t0, t1);
2783 gen_helper_dmultu(cpu_env, t0, t1);
2789 TCGv_i64 t2 = tcg_temp_new_i64();
2790 TCGv_i64 t3 = tcg_temp_new_i64();
2791 acc = ((ctx->opcode) >> 11) & 0x03;
2796 tcg_gen_ext_tl_i64(t2, t0);
2797 tcg_gen_ext_tl_i64(t3, t1);
2798 tcg_gen_mul_i64(t2, t2, t3);
2799 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2800 tcg_gen_add_i64(t2, t2, t3);
2801 tcg_temp_free_i64(t3);
2802 tcg_gen_trunc_i64_tl(t0, t2);
2803 tcg_gen_shri_i64(t2, t2, 32);
2804 tcg_gen_trunc_i64_tl(t1, t2);
2805 tcg_temp_free_i64(t2);
2806 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2807 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2813 TCGv_i64 t2 = tcg_temp_new_i64();
2814 TCGv_i64 t3 = tcg_temp_new_i64();
2815 acc = ((ctx->opcode) >> 11) & 0x03;
2820 tcg_gen_ext32u_tl(t0, t0);
2821 tcg_gen_ext32u_tl(t1, t1);
2822 tcg_gen_extu_tl_i64(t2, t0);
2823 tcg_gen_extu_tl_i64(t3, t1);
2824 tcg_gen_mul_i64(t2, t2, t3);
2825 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2826 tcg_gen_add_i64(t2, t2, t3);
2827 tcg_temp_free_i64(t3);
2828 tcg_gen_trunc_i64_tl(t0, t2);
2829 tcg_gen_shri_i64(t2, t2, 32);
2830 tcg_gen_trunc_i64_tl(t1, t2);
2831 tcg_temp_free_i64(t2);
2832 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2833 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2839 TCGv_i64 t2 = tcg_temp_new_i64();
2840 TCGv_i64 t3 = tcg_temp_new_i64();
2841 acc = ((ctx->opcode) >> 11) & 0x03;
2846 tcg_gen_ext_tl_i64(t2, t0);
2847 tcg_gen_ext_tl_i64(t3, t1);
2848 tcg_gen_mul_i64(t2, t2, t3);
2849 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2850 tcg_gen_sub_i64(t2, t3, t2);
2851 tcg_temp_free_i64(t3);
2852 tcg_gen_trunc_i64_tl(t0, t2);
2853 tcg_gen_shri_i64(t2, t2, 32);
2854 tcg_gen_trunc_i64_tl(t1, t2);
2855 tcg_temp_free_i64(t2);
2856 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2857 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2863 TCGv_i64 t2 = tcg_temp_new_i64();
2864 TCGv_i64 t3 = tcg_temp_new_i64();
2865 acc = ((ctx->opcode) >> 11) & 0x03;
2870 tcg_gen_ext32u_tl(t0, t0);
2871 tcg_gen_ext32u_tl(t1, t1);
2872 tcg_gen_extu_tl_i64(t2, t0);
2873 tcg_gen_extu_tl_i64(t3, t1);
2874 tcg_gen_mul_i64(t2, t2, t3);
2875 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2876 tcg_gen_sub_i64(t2, t3, t2);
2877 tcg_temp_free_i64(t3);
2878 tcg_gen_trunc_i64_tl(t0, t2);
2879 tcg_gen_shri_i64(t2, t2, 32);
2880 tcg_gen_trunc_i64_tl(t1, t2);
2881 tcg_temp_free_i64(t2);
2882 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2883 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2889 generate_exception(ctx, EXCP_RI);
2892 (void)opn; /* avoid a compiler warning */
2893 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2899 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2900 int rd, int rs, int rt)
2902 const char *opn = "mul vr54xx";
2903 TCGv t0 = tcg_temp_new();
2904 TCGv t1 = tcg_temp_new();
2906 gen_load_gpr(t0, rs);
2907 gen_load_gpr(t1, rt);
2910 case OPC_VR54XX_MULS:
2911 gen_helper_muls(t0, cpu_env, t0, t1);
2914 case OPC_VR54XX_MULSU:
2915 gen_helper_mulsu(t0, cpu_env, t0, t1);
2918 case OPC_VR54XX_MACC:
2919 gen_helper_macc(t0, cpu_env, t0, t1);
2922 case OPC_VR54XX_MACCU:
2923 gen_helper_maccu(t0, cpu_env, t0, t1);
2926 case OPC_VR54XX_MSAC:
2927 gen_helper_msac(t0, cpu_env, t0, t1);
2930 case OPC_VR54XX_MSACU:
2931 gen_helper_msacu(t0, cpu_env, t0, t1);
2934 case OPC_VR54XX_MULHI:
2935 gen_helper_mulhi(t0, cpu_env, t0, t1);
2938 case OPC_VR54XX_MULHIU:
2939 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2942 case OPC_VR54XX_MULSHI:
2943 gen_helper_mulshi(t0, cpu_env, t0, t1);
2946 case OPC_VR54XX_MULSHIU:
2947 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2950 case OPC_VR54XX_MACCHI:
2951 gen_helper_macchi(t0, cpu_env, t0, t1);
2954 case OPC_VR54XX_MACCHIU:
2955 gen_helper_macchiu(t0, cpu_env, t0, t1);
2958 case OPC_VR54XX_MSACHI:
2959 gen_helper_msachi(t0, cpu_env, t0, t1);
2962 case OPC_VR54XX_MSACHIU:
2963 gen_helper_msachiu(t0, cpu_env, t0, t1);
2967 MIPS_INVAL("mul vr54xx");
2968 generate_exception(ctx, EXCP_RI);
2971 gen_store_gpr(t0, rd);
2972 (void)opn; /* avoid a compiler warning */
2973 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2980 static void gen_cl (DisasContext *ctx, uint32_t opc,
2983 const char *opn = "CLx";
2991 t0 = tcg_temp_new();
2992 gen_load_gpr(t0, rs);
2995 gen_helper_clo(cpu_gpr[rd], t0);
2999 gen_helper_clz(cpu_gpr[rd], t0);
3002 #if defined(TARGET_MIPS64)
3004 gen_helper_dclo(cpu_gpr[rd], t0);
3008 gen_helper_dclz(cpu_gpr[rd], t0);
3013 (void)opn; /* avoid a compiler warning */
3014 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3018 /* Godson integer instructions */
3019 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3020 int rd, int rs, int rt)
3022 const char *opn = "loongson";
3034 case OPC_MULTU_G_2E:
3035 case OPC_MULTU_G_2F:
3036 #if defined(TARGET_MIPS64)
3037 case OPC_DMULT_G_2E:
3038 case OPC_DMULT_G_2F:
3039 case OPC_DMULTU_G_2E:
3040 case OPC_DMULTU_G_2F:
3042 t0 = tcg_temp_new();
3043 t1 = tcg_temp_new();
3046 t0 = tcg_temp_local_new();
3047 t1 = tcg_temp_local_new();
3051 gen_load_gpr(t0, rs);
3052 gen_load_gpr(t1, rt);
3057 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3058 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3061 case OPC_MULTU_G_2E:
3062 case OPC_MULTU_G_2F:
3063 tcg_gen_ext32u_tl(t0, t0);
3064 tcg_gen_ext32u_tl(t1, t1);
3065 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3066 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3072 int l1 = gen_new_label();
3073 int l2 = gen_new_label();
3074 int l3 = gen_new_label();
3075 tcg_gen_ext32s_tl(t0, t0);
3076 tcg_gen_ext32s_tl(t1, t1);
3077 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3078 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3081 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3082 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3083 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3086 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3087 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3095 int l1 = gen_new_label();
3096 int l2 = gen_new_label();
3097 tcg_gen_ext32u_tl(t0, t0);
3098 tcg_gen_ext32u_tl(t1, t1);
3099 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3100 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3103 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3104 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3112 int l1 = gen_new_label();
3113 int l2 = gen_new_label();
3114 int l3 = gen_new_label();
3115 tcg_gen_ext32u_tl(t0, t0);
3116 tcg_gen_ext32u_tl(t1, t1);
3117 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3118 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3119 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3121 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3124 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3125 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3133 int l1 = gen_new_label();
3134 int l2 = gen_new_label();
3135 tcg_gen_ext32u_tl(t0, t0);
3136 tcg_gen_ext32u_tl(t1, t1);
3137 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3138 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3141 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3142 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3147 #if defined(TARGET_MIPS64)
3148 case OPC_DMULT_G_2E:
3149 case OPC_DMULT_G_2F:
3150 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3153 case OPC_DMULTU_G_2E:
3154 case OPC_DMULTU_G_2F:
3155 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3161 int l1 = gen_new_label();
3162 int l2 = gen_new_label();
3163 int l3 = gen_new_label();
3164 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3165 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3168 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3169 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3170 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3173 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3178 case OPC_DDIVU_G_2E:
3179 case OPC_DDIVU_G_2F:
3181 int l1 = gen_new_label();
3182 int l2 = gen_new_label();
3183 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3184 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3187 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3195 int l1 = gen_new_label();
3196 int l2 = gen_new_label();
3197 int l3 = gen_new_label();
3198 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3199 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3200 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3202 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3205 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3210 case OPC_DMODU_G_2E:
3211 case OPC_DMODU_G_2F:
3213 int l1 = gen_new_label();
3214 int l2 = gen_new_label();
3215 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3216 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3219 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3227 (void)opn; /* avoid a compiler warning */
3228 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3233 /* Loongson multimedia instructions */
3234 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3236 const char *opn = "loongson_cp2";
3237 uint32_t opc, shift_max;
3240 opc = MASK_LMI(ctx->opcode);
3246 t0 = tcg_temp_local_new_i64();
3247 t1 = tcg_temp_local_new_i64();
3250 t0 = tcg_temp_new_i64();
3251 t1 = tcg_temp_new_i64();
3255 gen_load_fpr64(ctx, t0, rs);
3256 gen_load_fpr64(ctx, t1, rt);
3258 #define LMI_HELPER(UP, LO) \
3259 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3260 #define LMI_HELPER_1(UP, LO) \
3261 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3262 #define LMI_DIRECT(UP, LO, OP) \
3263 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3266 LMI_HELPER(PADDSH, paddsh);
3267 LMI_HELPER(PADDUSH, paddush);
3268 LMI_HELPER(PADDH, paddh);
3269 LMI_HELPER(PADDW, paddw);
3270 LMI_HELPER(PADDSB, paddsb);
3271 LMI_HELPER(PADDUSB, paddusb);
3272 LMI_HELPER(PADDB, paddb);
3274 LMI_HELPER(PSUBSH, psubsh);
3275 LMI_HELPER(PSUBUSH, psubush);
3276 LMI_HELPER(PSUBH, psubh);
3277 LMI_HELPER(PSUBW, psubw);
3278 LMI_HELPER(PSUBSB, psubsb);
3279 LMI_HELPER(PSUBUSB, psubusb);
3280 LMI_HELPER(PSUBB, psubb);
3282 LMI_HELPER(PSHUFH, pshufh);
3283 LMI_HELPER(PACKSSWH, packsswh);
3284 LMI_HELPER(PACKSSHB, packsshb);
3285 LMI_HELPER(PACKUSHB, packushb);
3287 LMI_HELPER(PUNPCKLHW, punpcklhw);
3288 LMI_HELPER(PUNPCKHHW, punpckhhw);
3289 LMI_HELPER(PUNPCKLBH, punpcklbh);
3290 LMI_HELPER(PUNPCKHBH, punpckhbh);
3291 LMI_HELPER(PUNPCKLWD, punpcklwd);
3292 LMI_HELPER(PUNPCKHWD, punpckhwd);
3294 LMI_HELPER(PAVGH, pavgh);
3295 LMI_HELPER(PAVGB, pavgb);
3296 LMI_HELPER(PMAXSH, pmaxsh);
3297 LMI_HELPER(PMINSH, pminsh);
3298 LMI_HELPER(PMAXUB, pmaxub);
3299 LMI_HELPER(PMINUB, pminub);
3301 LMI_HELPER(PCMPEQW, pcmpeqw);
3302 LMI_HELPER(PCMPGTW, pcmpgtw);
3303 LMI_HELPER(PCMPEQH, pcmpeqh);
3304 LMI_HELPER(PCMPGTH, pcmpgth);
3305 LMI_HELPER(PCMPEQB, pcmpeqb);
3306 LMI_HELPER(PCMPGTB, pcmpgtb);
3308 LMI_HELPER(PSLLW, psllw);
3309 LMI_HELPER(PSLLH, psllh);
3310 LMI_HELPER(PSRLW, psrlw);
3311 LMI_HELPER(PSRLH, psrlh);
3312 LMI_HELPER(PSRAW, psraw);
3313 LMI_HELPER(PSRAH, psrah);
3315 LMI_HELPER(PMULLH, pmullh);
3316 LMI_HELPER(PMULHH, pmulhh);
3317 LMI_HELPER(PMULHUH, pmulhuh);
3318 LMI_HELPER(PMADDHW, pmaddhw);
3320 LMI_HELPER(PASUBUB, pasubub);
3321 LMI_HELPER_1(BIADD, biadd);
3322 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3324 LMI_DIRECT(PADDD, paddd, add);
3325 LMI_DIRECT(PSUBD, psubd, sub);
3326 LMI_DIRECT(XOR_CP2, xor, xor);
3327 LMI_DIRECT(NOR_CP2, nor, nor);
3328 LMI_DIRECT(AND_CP2, and, and);
3329 LMI_DIRECT(PANDN, pandn, andc);
3330 LMI_DIRECT(OR, or, or);
3333 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3337 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3341 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3345 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3350 tcg_gen_andi_i64(t1, t1, 3);
3351 tcg_gen_shli_i64(t1, t1, 4);
3352 tcg_gen_shr_i64(t0, t0, t1);
3353 tcg_gen_ext16u_i64(t0, t0);
3358 tcg_gen_add_i64(t0, t0, t1);
3359 tcg_gen_ext32s_i64(t0, t0);
3363 tcg_gen_sub_i64(t0, t0, t1);
3364 tcg_gen_ext32s_i64(t0, t0);
3393 /* Make sure shift count isn't TCG undefined behaviour. */
3394 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3399 tcg_gen_shl_i64(t0, t0, t1);
3403 /* Since SRA is UndefinedResult without sign-extended inputs,
3404 we can treat SRA and DSRA the same. */
3405 tcg_gen_sar_i64(t0, t0, t1);
3408 /* We want to shift in zeros for SRL; zero-extend first. */
3409 tcg_gen_ext32u_i64(t0, t0);
3412 tcg_gen_shr_i64(t0, t0, t1);
3416 if (shift_max == 32) {
3417 tcg_gen_ext32s_i64(t0, t0);
3420 /* Shifts larger than MAX produce zero. */
3421 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3422 tcg_gen_neg_i64(t1, t1);
3423 tcg_gen_and_i64(t0, t0, t1);
3429 TCGv_i64 t2 = tcg_temp_new_i64();
3430 int lab = gen_new_label();
3432 tcg_gen_mov_i64(t2, t0);
3433 tcg_gen_add_i64(t0, t1, t2);
3434 if (opc == OPC_ADD_CP2) {
3435 tcg_gen_ext32s_i64(t0, t0);
3437 tcg_gen_xor_i64(t1, t1, t2);
3438 tcg_gen_xor_i64(t2, t2, t0);
3439 tcg_gen_andc_i64(t1, t2, t1);
3440 tcg_temp_free_i64(t2);
3441 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3442 generate_exception(ctx, EXCP_OVERFLOW);
3445 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3452 TCGv_i64 t2 = tcg_temp_new_i64();
3453 int lab = gen_new_label();
3455 tcg_gen_mov_i64(t2, t0);
3456 tcg_gen_sub_i64(t0, t1, t2);
3457 if (opc == OPC_SUB_CP2) {
3458 tcg_gen_ext32s_i64(t0, t0);
3460 tcg_gen_xor_i64(t1, t1, t2);
3461 tcg_gen_xor_i64(t2, t2, t0);
3462 tcg_gen_and_i64(t1, t1, t2);
3463 tcg_temp_free_i64(t2);
3464 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3465 generate_exception(ctx, EXCP_OVERFLOW);
3468 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3473 tcg_gen_ext32u_i64(t0, t0);
3474 tcg_gen_ext32u_i64(t1, t1);
3475 tcg_gen_mul_i64(t0, t0, t1);
3485 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3486 FD field is the CC field? */
3489 generate_exception(ctx, EXCP_RI);
3496 gen_store_fpr64(ctx, t0, rd);
3498 (void)opn; /* avoid a compiler warning */
3499 MIPS_DEBUG("%s %s, %s, %s", opn,
3500 fregnames[rd], fregnames[rs], fregnames[rt]);
3501 tcg_temp_free_i64(t0);
3502 tcg_temp_free_i64(t1);
3506 static void gen_trap (DisasContext *ctx, uint32_t opc,
3507 int rs, int rt, int16_t imm)
3510 TCGv t0 = tcg_temp_new();
3511 TCGv t1 = tcg_temp_new();
3514 /* Load needed operands */
3522 /* Compare two registers */
3524 gen_load_gpr(t0, rs);
3525 gen_load_gpr(t1, rt);
3535 /* Compare register to immediate */
3536 if (rs != 0 || imm != 0) {
3537 gen_load_gpr(t0, rs);
3538 tcg_gen_movi_tl(t1, (int32_t)imm);
3545 case OPC_TEQ: /* rs == rs */
3546 case OPC_TEQI: /* r0 == 0 */
3547 case OPC_TGE: /* rs >= rs */
3548 case OPC_TGEI: /* r0 >= 0 */
3549 case OPC_TGEU: /* rs >= rs unsigned */
3550 case OPC_TGEIU: /* r0 >= 0 unsigned */
3552 generate_exception(ctx, EXCP_TRAP);
3554 case OPC_TLT: /* rs < rs */
3555 case OPC_TLTI: /* r0 < 0 */
3556 case OPC_TLTU: /* rs < rs unsigned */
3557 case OPC_TLTIU: /* r0 < 0 unsigned */
3558 case OPC_TNE: /* rs != rs */
3559 case OPC_TNEI: /* r0 != 0 */
3560 /* Never trap: treat as NOP. */
3564 int l1 = gen_new_label();
3569 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3573 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3577 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3581 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3585 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3589 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3592 generate_exception(ctx, EXCP_TRAP);
3599 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3601 TranslationBlock *tb;
3603 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3604 likely(!ctx->singlestep_enabled)) {
3607 tcg_gen_exit_tb((tcg_target_long)tb + n);
3610 if (ctx->singlestep_enabled) {
3611 save_cpu_state(ctx, 0);
3612 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3618 /* Branches (before delay slot) */
3619 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3621 int rs, int rt, int32_t offset)
3623 target_ulong btgt = -1;
3625 int bcond_compute = 0;
3626 TCGv t0 = tcg_temp_new();
3627 TCGv t1 = tcg_temp_new();
3629 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3630 #ifdef MIPS_DEBUG_DISAS
3631 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3633 generate_exception(ctx, EXCP_RI);
3637 /* Load needed operands */
3643 /* Compare two registers */
3645 gen_load_gpr(t0, rs);
3646 gen_load_gpr(t1, rt);
3649 btgt = ctx->pc + insn_bytes + offset;
3665 /* Compare to zero */
3667 gen_load_gpr(t0, rs);
3670 btgt = ctx->pc + insn_bytes + offset;
3673 #if defined(TARGET_MIPS64)
3675 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3677 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3680 btgt = ctx->pc + insn_bytes + offset;
3687 /* Jump to immediate */
3688 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3694 /* Jump to register */
3695 if (offset != 0 && offset != 16) {
3696 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3697 others are reserved. */
3698 MIPS_INVAL("jump hint");
3699 generate_exception(ctx, EXCP_RI);
3702 gen_load_gpr(btarget, rs);
3705 MIPS_INVAL("branch/jump");
3706 generate_exception(ctx, EXCP_RI);
3709 if (bcond_compute == 0) {
3710 /* No condition to be computed */
3712 case OPC_BEQ: /* rx == rx */
3713 case OPC_BEQL: /* rx == rx likely */
3714 case OPC_BGEZ: /* 0 >= 0 */
3715 case OPC_BGEZL: /* 0 >= 0 likely */
3716 case OPC_BLEZ: /* 0 <= 0 */
3717 case OPC_BLEZL: /* 0 <= 0 likely */
3719 ctx->hflags |= MIPS_HFLAG_B;
3720 MIPS_DEBUG("balways");
3723 case OPC_BGEZAL: /* 0 >= 0 */
3724 case OPC_BGEZALL: /* 0 >= 0 likely */
3725 ctx->hflags |= (opc == OPC_BGEZALS
3727 : MIPS_HFLAG_BDS32);
3728 /* Always take and link */
3730 ctx->hflags |= MIPS_HFLAG_B;
3731 MIPS_DEBUG("balways and link");
3733 case OPC_BNE: /* rx != rx */
3734 case OPC_BGTZ: /* 0 > 0 */
3735 case OPC_BLTZ: /* 0 < 0 */
3737 MIPS_DEBUG("bnever (NOP)");
3740 case OPC_BLTZAL: /* 0 < 0 */
3741 ctx->hflags |= (opc == OPC_BLTZALS
3743 : MIPS_HFLAG_BDS32);
3744 /* Handle as an unconditional branch to get correct delay
3747 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3748 ctx->hflags |= MIPS_HFLAG_B;
3749 MIPS_DEBUG("bnever and link");
3751 case OPC_BLTZALL: /* 0 < 0 likely */
3752 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3753 /* Skip the instruction in the delay slot */
3754 MIPS_DEBUG("bnever, link and skip");
3757 case OPC_BNEL: /* rx != rx likely */
3758 case OPC_BGTZL: /* 0 > 0 likely */
3759 case OPC_BLTZL: /* 0 < 0 likely */
3760 /* Skip the instruction in the delay slot */
3761 MIPS_DEBUG("bnever and skip");
3765 ctx->hflags |= MIPS_HFLAG_B;
3766 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3770 ctx->hflags |= MIPS_HFLAG_BX;
3775 ctx->hflags |= MIPS_HFLAG_B;
3776 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3778 : MIPS_HFLAG_BDS32);
3779 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3782 ctx->hflags |= MIPS_HFLAG_BR;
3783 if (insn_bytes == 4)
3784 ctx->hflags |= MIPS_HFLAG_BDS32;
3785 MIPS_DEBUG("jr %s", regnames[rs]);
3791 ctx->hflags |= MIPS_HFLAG_BR;
3792 ctx->hflags |= (opc == OPC_JALRS
3794 : MIPS_HFLAG_BDS32);
3795 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3798 MIPS_INVAL("branch/jump");
3799 generate_exception(ctx, EXCP_RI);
3805 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3806 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3807 regnames[rs], regnames[rt], btgt);
3810 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3811 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3812 regnames[rs], regnames[rt], btgt);
3815 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3816 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3817 regnames[rs], regnames[rt], btgt);
3820 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3821 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3822 regnames[rs], regnames[rt], btgt);
3825 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3826 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3829 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3830 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3834 ctx->hflags |= (opc == OPC_BGEZALS
3836 : MIPS_HFLAG_BDS32);
3837 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3838 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3842 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3844 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3847 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3848 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3851 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3852 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3855 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3856 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3859 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3860 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3863 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3864 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3867 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3868 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3871 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3872 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3874 #if defined(TARGET_MIPS64)
3876 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3877 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3882 ctx->hflags |= (opc == OPC_BLTZALS
3884 : MIPS_HFLAG_BDS32);
3885 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3887 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3889 ctx->hflags |= MIPS_HFLAG_BC;
3892 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3894 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3896 ctx->hflags |= MIPS_HFLAG_BL;
3899 MIPS_INVAL("conditional branch/jump");
3900 generate_exception(ctx, EXCP_RI);
3904 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3905 blink, ctx->hflags, btgt);
3907 ctx->btarget = btgt;
3909 int post_delay = insn_bytes;
3910 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3912 if (opc != OPC_JALRC)
3913 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3915 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3919 if (insn_bytes == 2)
3920 ctx->hflags |= MIPS_HFLAG_B16;
3925 /* special3 bitfield operations */
3926 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3927 int rs, int lsb, int msb)
3929 TCGv t0 = tcg_temp_new();
3930 TCGv t1 = tcg_temp_new();
3932 gen_load_gpr(t1, rs);
3937 tcg_gen_shri_tl(t0, t1, lsb);
3939 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3941 tcg_gen_ext32s_tl(t0, t0);
3944 #if defined(TARGET_MIPS64)
3946 tcg_gen_shri_tl(t0, t1, lsb);
3948 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3952 tcg_gen_shri_tl(t0, t1, lsb + 32);
3953 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3956 tcg_gen_shri_tl(t0, t1, lsb);
3957 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3963 gen_load_gpr(t0, rt);
3964 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3965 tcg_gen_ext32s_tl(t0, t0);
3967 #if defined(TARGET_MIPS64)
3969 gen_load_gpr(t0, rt);
3970 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3973 gen_load_gpr(t0, rt);
3974 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3977 gen_load_gpr(t0, rt);
3978 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3983 MIPS_INVAL("bitops");
3984 generate_exception(ctx, EXCP_RI);
3989 gen_store_gpr(t0, rt);
3994 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3999 /* If no destination, treat it as a NOP. */
4004 t0 = tcg_temp_new();
4005 gen_load_gpr(t0, rt);
4009 TCGv t1 = tcg_temp_new();
4011 tcg_gen_shri_tl(t1, t0, 8);
4012 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4013 tcg_gen_shli_tl(t0, t0, 8);
4014 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4015 tcg_gen_or_tl(t0, t0, t1);
4017 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4021 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4024 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4026 #if defined(TARGET_MIPS64)
4029 TCGv t1 = tcg_temp_new();
4031 tcg_gen_shri_tl(t1, t0, 8);
4032 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4033 tcg_gen_shli_tl(t0, t0, 8);
4034 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4035 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4041 TCGv t1 = tcg_temp_new();
4043 tcg_gen_shri_tl(t1, t0, 16);
4044 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4045 tcg_gen_shli_tl(t0, t0, 16);
4046 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4047 tcg_gen_or_tl(t0, t0, t1);
4048 tcg_gen_shri_tl(t1, t0, 32);
4049 tcg_gen_shli_tl(t0, t0, 32);
4050 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4056 MIPS_INVAL("bsfhl");
4057 generate_exception(ctx, EXCP_RI);
4064 #ifndef CONFIG_USER_ONLY
4065 /* CP0 (MMU and control) */
4066 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4068 TCGv_i32 t0 = tcg_temp_new_i32();
4070 tcg_gen_ld_i32(t0, cpu_env, off);
4071 tcg_gen_ext_i32_tl(arg, t0);
4072 tcg_temp_free_i32(t0);
4075 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4077 tcg_gen_ld_tl(arg, cpu_env, off);
4078 tcg_gen_ext32s_tl(arg, arg);
4081 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4083 TCGv_i32 t0 = tcg_temp_new_i32();
4085 tcg_gen_trunc_tl_i32(t0, arg);
4086 tcg_gen_st_i32(t0, cpu_env, off);
4087 tcg_temp_free_i32(t0);
4090 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4092 tcg_gen_ext32s_tl(arg, arg);
4093 tcg_gen_st_tl(arg, cpu_env, off);
4096 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4098 const char *rn = "invalid";
4101 check_insn(env, ctx, ISA_MIPS32);
4107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4111 check_insn(env, ctx, ASE_MT);
4112 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4116 check_insn(env, ctx, ASE_MT);
4117 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4121 check_insn(env, ctx, ASE_MT);
4122 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4132 gen_helper_mfc0_random(arg, cpu_env);
4136 check_insn(env, ctx, ASE_MT);
4137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4141 check_insn(env, ctx, ASE_MT);
4142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4146 check_insn(env, ctx, ASE_MT);
4147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4151 check_insn(env, ctx, ASE_MT);
4152 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4156 check_insn(env, ctx, ASE_MT);
4157 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4161 check_insn(env, ctx, ASE_MT);
4162 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4163 rn = "VPEScheFBack";
4166 check_insn(env, ctx, ASE_MT);
4167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4177 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4178 tcg_gen_ext32s_tl(arg, arg);
4182 check_insn(env, ctx, ASE_MT);
4183 gen_helper_mfc0_tcstatus(arg, cpu_env);
4187 check_insn(env, ctx, ASE_MT);
4188 gen_helper_mfc0_tcbind(arg, cpu_env);
4192 check_insn(env, ctx, ASE_MT);
4193 gen_helper_mfc0_tcrestart(arg, cpu_env);
4197 check_insn(env, ctx, ASE_MT);
4198 gen_helper_mfc0_tchalt(arg, cpu_env);
4202 check_insn(env, ctx, ASE_MT);
4203 gen_helper_mfc0_tccontext(arg, cpu_env);
4207 check_insn(env, ctx, ASE_MT);
4208 gen_helper_mfc0_tcschedule(arg, cpu_env);
4212 check_insn(env, ctx, ASE_MT);
4213 gen_helper_mfc0_tcschefback(arg, cpu_env);
4223 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4224 tcg_gen_ext32s_tl(arg, arg);
4234 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4235 tcg_gen_ext32s_tl(arg, arg);
4239 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4240 rn = "ContextConfig";
4249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4253 check_insn(env, ctx, ISA_MIPS32R2);
4254 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4264 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4268 check_insn(env, ctx, ISA_MIPS32R2);
4269 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4273 check_insn(env, ctx, ISA_MIPS32R2);
4274 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4278 check_insn(env, ctx, ISA_MIPS32R2);
4279 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4283 check_insn(env, ctx, ISA_MIPS32R2);
4284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4288 check_insn(env, ctx, ISA_MIPS32R2);
4289 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4299 check_insn(env, ctx, ISA_MIPS32R2);
4300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4310 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4311 tcg_gen_ext32s_tl(arg, arg);
4321 /* Mark as an IO operation because we read the time. */
4324 gen_helper_mfc0_count(arg, cpu_env);
4328 /* Break the TB to be able to take timer interrupts immediately
4329 after reading count. */
4330 ctx->bstate = BS_STOP;
4333 /* 6,7 are implementation dependent */
4341 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4342 tcg_gen_ext32s_tl(arg, arg);
4352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4355 /* 6,7 are implementation dependent */
4363 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4367 check_insn(env, ctx, ISA_MIPS32R2);
4368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4372 check_insn(env, ctx, ISA_MIPS32R2);
4373 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4377 check_insn(env, ctx, ISA_MIPS32R2);
4378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4398 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4399 tcg_gen_ext32s_tl(arg, arg);
4409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4413 check_insn(env, ctx, ISA_MIPS32R2);
4414 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4436 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4439 /* 4,5 are reserved */
4440 /* 6,7 are implementation dependent */
4442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4456 gen_helper_mfc0_lladdr(arg, cpu_env);
4466 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4476 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4486 #if defined(TARGET_MIPS64)
4487 check_insn(env, ctx, ISA_MIPS3);
4488 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4489 tcg_gen_ext32s_tl(arg, arg);
4498 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4509 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4510 rn = "'Diagnostic"; /* implementation dependent */
4515 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4519 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4520 rn = "TraceControl";
4523 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4524 rn = "TraceControl2";
4527 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4528 rn = "UserTraceData";
4531 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4542 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4543 tcg_gen_ext32s_tl(arg, arg);
4553 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4554 rn = "Performance0";
4557 // gen_helper_mfc0_performance1(arg);
4558 rn = "Performance1";
4561 // gen_helper_mfc0_performance2(arg);
4562 rn = "Performance2";
4565 // gen_helper_mfc0_performance3(arg);
4566 rn = "Performance3";
4569 // gen_helper_mfc0_performance4(arg);
4570 rn = "Performance4";
4573 // gen_helper_mfc0_performance5(arg);
4574 rn = "Performance5";
4577 // gen_helper_mfc0_performance6(arg);
4578 rn = "Performance6";
4581 // gen_helper_mfc0_performance7(arg);
4582 rn = "Performance7";
4589 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4595 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4615 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4635 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4645 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4646 tcg_gen_ext32s_tl(arg, arg);
4657 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4667 (void)rn; /* avoid a compiler warning */
4668 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4672 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4673 generate_exception(ctx, EXCP_RI);
4676 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4678 const char *rn = "invalid";
4681 check_insn(env, ctx, ISA_MIPS32);
4690 gen_helper_mtc0_index(cpu_env, arg);
4694 check_insn(env, ctx, ASE_MT);
4695 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4699 check_insn(env, ctx, ASE_MT);
4704 check_insn(env, ctx, ASE_MT);
4719 check_insn(env, ctx, ASE_MT);
4720 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4724 check_insn(env, ctx, ASE_MT);
4725 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4729 check_insn(env, ctx, ASE_MT);
4730 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4734 check_insn(env, ctx, ASE_MT);
4735 gen_helper_mtc0_yqmask(cpu_env, arg);
4739 check_insn(env, ctx, ASE_MT);
4740 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4744 check_insn(env, ctx, ASE_MT);
4745 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4746 rn = "VPEScheFBack";
4749 check_insn(env, ctx, ASE_MT);
4750 gen_helper_mtc0_vpeopt(cpu_env, arg);
4760 gen_helper_mtc0_entrylo0(cpu_env, arg);
4764 check_insn(env, ctx, ASE_MT);
4765 gen_helper_mtc0_tcstatus(cpu_env, arg);
4769 check_insn(env, ctx, ASE_MT);
4770 gen_helper_mtc0_tcbind(cpu_env, arg);
4774 check_insn(env, ctx, ASE_MT);
4775 gen_helper_mtc0_tcrestart(cpu_env, arg);
4779 check_insn(env, ctx, ASE_MT);
4780 gen_helper_mtc0_tchalt(cpu_env, arg);
4784 check_insn(env, ctx, ASE_MT);
4785 gen_helper_mtc0_tccontext(cpu_env, arg);
4789 check_insn(env, ctx, ASE_MT);
4790 gen_helper_mtc0_tcschedule(cpu_env, arg);
4794 check_insn(env, ctx, ASE_MT);
4795 gen_helper_mtc0_tcschefback(cpu_env, arg);
4805 gen_helper_mtc0_entrylo1(cpu_env, arg);
4815 gen_helper_mtc0_context(cpu_env, arg);
4819 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4820 rn = "ContextConfig";
4829 gen_helper_mtc0_pagemask(cpu_env, arg);
4833 check_insn(env, ctx, ISA_MIPS32R2);
4834 gen_helper_mtc0_pagegrain(cpu_env, arg);
4844 gen_helper_mtc0_wired(cpu_env, arg);
4848 check_insn(env, ctx, ISA_MIPS32R2);
4849 gen_helper_mtc0_srsconf0(cpu_env, arg);
4853 check_insn(env, ctx, ISA_MIPS32R2);
4854 gen_helper_mtc0_srsconf1(cpu_env, arg);
4858 check_insn(env, ctx, ISA_MIPS32R2);
4859 gen_helper_mtc0_srsconf2(cpu_env, arg);
4863 check_insn(env, ctx, ISA_MIPS32R2);
4864 gen_helper_mtc0_srsconf3(cpu_env, arg);
4868 check_insn(env, ctx, ISA_MIPS32R2);
4869 gen_helper_mtc0_srsconf4(cpu_env, arg);
4879 check_insn(env, ctx, ISA_MIPS32R2);
4880 gen_helper_mtc0_hwrena(cpu_env, arg);
4894 gen_helper_mtc0_count(cpu_env, arg);
4897 /* 6,7 are implementation dependent */
4905 gen_helper_mtc0_entryhi(cpu_env, arg);
4915 gen_helper_mtc0_compare(cpu_env, arg);
4918 /* 6,7 are implementation dependent */
4926 save_cpu_state(ctx, 1);
4927 gen_helper_mtc0_status(cpu_env, arg);
4928 /* BS_STOP isn't good enough here, hflags may have changed. */
4929 gen_save_pc(ctx->pc + 4);
4930 ctx->bstate = BS_EXCP;
4934 check_insn(env, ctx, ISA_MIPS32R2);
4935 gen_helper_mtc0_intctl(cpu_env, arg);
4936 /* Stop translation as we may have switched the execution mode */
4937 ctx->bstate = BS_STOP;
4941 check_insn(env, ctx, ISA_MIPS32R2);
4942 gen_helper_mtc0_srsctl(cpu_env, arg);
4943 /* Stop translation as we may have switched the execution mode */
4944 ctx->bstate = BS_STOP;
4948 check_insn(env, ctx, ISA_MIPS32R2);
4949 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4950 /* Stop translation as we may have switched the execution mode */
4951 ctx->bstate = BS_STOP;
4961 save_cpu_state(ctx, 1);
4962 gen_helper_mtc0_cause(cpu_env, arg);
4972 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4986 check_insn(env, ctx, ISA_MIPS32R2);
4987 gen_helper_mtc0_ebase(cpu_env, arg);
4997 gen_helper_mtc0_config0(cpu_env, arg);
4999 /* Stop translation as we may have switched the execution mode */
5000 ctx->bstate = BS_STOP;
5003 /* ignored, read only */
5007 gen_helper_mtc0_config2(cpu_env, arg);
5009 /* Stop translation as we may have switched the execution mode */
5010 ctx->bstate = BS_STOP;
5013 /* ignored, read only */
5016 /* 4,5 are reserved */
5017 /* 6,7 are implementation dependent */
5027 rn = "Invalid config selector";
5034 gen_helper_mtc0_lladdr(cpu_env, arg);
5044 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5054 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5064 #if defined(TARGET_MIPS64)
5065 check_insn(env, ctx, ISA_MIPS3);
5066 gen_helper_mtc0_xcontext(cpu_env, arg);
5075 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5078 gen_helper_mtc0_framemask(cpu_env, arg);
5087 rn = "Diagnostic"; /* implementation dependent */
5092 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5093 /* BS_STOP isn't good enough here, hflags may have changed. */
5094 gen_save_pc(ctx->pc + 4);
5095 ctx->bstate = BS_EXCP;
5099 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5100 rn = "TraceControl";
5101 /* Stop translation as we may have switched the execution mode */
5102 ctx->bstate = BS_STOP;
5105 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5106 rn = "TraceControl2";
5107 /* Stop translation as we may have switched the execution mode */
5108 ctx->bstate = BS_STOP;
5111 /* Stop translation as we may have switched the execution mode */
5112 ctx->bstate = BS_STOP;
5113 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5114 rn = "UserTraceData";
5115 /* Stop translation as we may have switched the execution mode */
5116 ctx->bstate = BS_STOP;
5119 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5120 /* Stop translation as we may have switched the execution mode */
5121 ctx->bstate = BS_STOP;
5132 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5142 gen_helper_mtc0_performance0(cpu_env, arg);
5143 rn = "Performance0";
5146 // gen_helper_mtc0_performance1(arg);
5147 rn = "Performance1";
5150 // gen_helper_mtc0_performance2(arg);
5151 rn = "Performance2";
5154 // gen_helper_mtc0_performance3(arg);
5155 rn = "Performance3";
5158 // gen_helper_mtc0_performance4(arg);
5159 rn = "Performance4";
5162 // gen_helper_mtc0_performance5(arg);
5163 rn = "Performance5";
5166 // gen_helper_mtc0_performance6(arg);
5167 rn = "Performance6";
5170 // gen_helper_mtc0_performance7(arg);
5171 rn = "Performance7";
5197 gen_helper_mtc0_taglo(cpu_env, arg);
5204 gen_helper_mtc0_datalo(cpu_env, arg);
5217 gen_helper_mtc0_taghi(cpu_env, arg);
5224 gen_helper_mtc0_datahi(cpu_env, arg);
5235 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5246 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5252 /* Stop translation as we may have switched the execution mode */
5253 ctx->bstate = BS_STOP;
5258 (void)rn; /* avoid a compiler warning */
5259 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5260 /* For simplicity assume that all writes can cause interrupts. */
5263 ctx->bstate = BS_STOP;
5268 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5269 generate_exception(ctx, EXCP_RI);
5272 #if defined(TARGET_MIPS64)
5273 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5275 const char *rn = "invalid";
5278 check_insn(env, ctx, ISA_MIPS64);
5284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5288 check_insn(env, ctx, ASE_MT);
5289 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5293 check_insn(env, ctx, ASE_MT);
5294 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5298 check_insn(env, ctx, ASE_MT);
5299 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5309 gen_helper_mfc0_random(arg, cpu_env);
5313 check_insn(env, ctx, ASE_MT);
5314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5318 check_insn(env, ctx, ASE_MT);
5319 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5323 check_insn(env, ctx, ASE_MT);
5324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5328 check_insn(env, ctx, ASE_MT);
5329 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5333 check_insn(env, ctx, ASE_MT);
5334 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5338 check_insn(env, ctx, ASE_MT);
5339 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5340 rn = "VPEScheFBack";
5343 check_insn(env, ctx, ASE_MT);
5344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5358 check_insn(env, ctx, ASE_MT);
5359 gen_helper_mfc0_tcstatus(arg, cpu_env);
5363 check_insn(env, ctx, ASE_MT);
5364 gen_helper_mfc0_tcbind(arg, cpu_env);
5368 check_insn(env, ctx, ASE_MT);
5369 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5373 check_insn(env, ctx, ASE_MT);
5374 gen_helper_dmfc0_tchalt(arg, cpu_env);
5378 check_insn(env, ctx, ASE_MT);
5379 gen_helper_dmfc0_tccontext(arg, cpu_env);
5383 check_insn(env, ctx, ASE_MT);
5384 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5388 check_insn(env, ctx, ASE_MT);
5389 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5399 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5409 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5413 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5414 rn = "ContextConfig";
5423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5427 check_insn(env, ctx, ISA_MIPS32R2);
5428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5442 check_insn(env, ctx, ISA_MIPS32R2);
5443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5447 check_insn(env, ctx, ISA_MIPS32R2);
5448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5452 check_insn(env, ctx, ISA_MIPS32R2);
5453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5457 check_insn(env, ctx, ISA_MIPS32R2);
5458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5462 check_insn(env, ctx, ISA_MIPS32R2);
5463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5473 check_insn(env, ctx, ISA_MIPS32R2);
5474 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5484 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5494 /* Mark as an IO operation because we read the time. */
5497 gen_helper_mfc0_count(arg, cpu_env);
5501 /* Break the TB to be able to take timer interrupts immediately
5502 after reading count. */
5503 ctx->bstate = BS_STOP;
5506 /* 6,7 are implementation dependent */
5514 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5524 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5527 /* 6,7 are implementation dependent */
5535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5539 check_insn(env, ctx, ISA_MIPS32R2);
5540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5544 check_insn(env, ctx, ISA_MIPS32R2);
5545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5549 check_insn(env, ctx, ISA_MIPS32R2);
5550 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5570 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5584 check_insn(env, ctx, ISA_MIPS32R2);
5585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5603 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5610 /* 6,7 are implementation dependent */
5612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5626 gen_helper_dmfc0_lladdr(arg, cpu_env);
5636 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5646 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5656 check_insn(env, ctx, ISA_MIPS3);
5657 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5665 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5668 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5676 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5677 rn = "'Diagnostic"; /* implementation dependent */
5682 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5686 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5687 rn = "TraceControl";
5690 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5691 rn = "TraceControl2";
5694 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5695 rn = "UserTraceData";
5698 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5709 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5719 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5720 rn = "Performance0";
5723 // gen_helper_dmfc0_performance1(arg);
5724 rn = "Performance1";
5727 // gen_helper_dmfc0_performance2(arg);
5728 rn = "Performance2";
5731 // gen_helper_dmfc0_performance3(arg);
5732 rn = "Performance3";
5735 // gen_helper_dmfc0_performance4(arg);
5736 rn = "Performance4";
5739 // gen_helper_dmfc0_performance5(arg);
5740 rn = "Performance5";
5743 // gen_helper_dmfc0_performance6(arg);
5744 rn = "Performance6";
5747 // gen_helper_dmfc0_performance7(arg);
5748 rn = "Performance7";
5755 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5762 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5775 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5782 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5795 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5812 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5823 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5833 (void)rn; /* avoid a compiler warning */
5834 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5838 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5839 generate_exception(ctx, EXCP_RI);
5842 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5844 const char *rn = "invalid";
5847 check_insn(env, ctx, ISA_MIPS64);
5856 gen_helper_mtc0_index(cpu_env, arg);
5860 check_insn(env, ctx, ASE_MT);
5861 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5865 check_insn(env, ctx, ASE_MT);
5870 check_insn(env, ctx, ASE_MT);
5885 check_insn(env, ctx, ASE_MT);
5886 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5890 check_insn(env, ctx, ASE_MT);
5891 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5895 check_insn(env, ctx, ASE_MT);
5896 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5900 check_insn(env, ctx, ASE_MT);
5901 gen_helper_mtc0_yqmask(cpu_env, arg);
5905 check_insn(env, ctx, ASE_MT);
5906 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5910 check_insn(env, ctx, ASE_MT);
5911 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5912 rn = "VPEScheFBack";
5915 check_insn(env, ctx, ASE_MT);
5916 gen_helper_mtc0_vpeopt(cpu_env, arg);
5926 gen_helper_mtc0_entrylo0(cpu_env, arg);
5930 check_insn(env, ctx, ASE_MT);
5931 gen_helper_mtc0_tcstatus(cpu_env, arg);
5935 check_insn(env, ctx, ASE_MT);
5936 gen_helper_mtc0_tcbind(cpu_env, arg);
5940 check_insn(env, ctx, ASE_MT);
5941 gen_helper_mtc0_tcrestart(cpu_env, arg);
5945 check_insn(env, ctx, ASE_MT);
5946 gen_helper_mtc0_tchalt(cpu_env, arg);
5950 check_insn(env, ctx, ASE_MT);
5951 gen_helper_mtc0_tccontext(cpu_env, arg);
5955 check_insn(env, ctx, ASE_MT);
5956 gen_helper_mtc0_tcschedule(cpu_env, arg);
5960 check_insn(env, ctx, ASE_MT);
5961 gen_helper_mtc0_tcschefback(cpu_env, arg);
5971 gen_helper_mtc0_entrylo1(cpu_env, arg);
5981 gen_helper_mtc0_context(cpu_env, arg);
5985 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5986 rn = "ContextConfig";
5995 gen_helper_mtc0_pagemask(cpu_env, arg);
5999 check_insn(env, ctx, ISA_MIPS32R2);
6000 gen_helper_mtc0_pagegrain(cpu_env, arg);
6010 gen_helper_mtc0_wired(cpu_env, arg);
6014 check_insn(env, ctx, ISA_MIPS32R2);
6015 gen_helper_mtc0_srsconf0(cpu_env, arg);
6019 check_insn(env, ctx, ISA_MIPS32R2);
6020 gen_helper_mtc0_srsconf1(cpu_env, arg);
6024 check_insn(env, ctx, ISA_MIPS32R2);
6025 gen_helper_mtc0_srsconf2(cpu_env, arg);
6029 check_insn(env, ctx, ISA_MIPS32R2);
6030 gen_helper_mtc0_srsconf3(cpu_env, arg);
6034 check_insn(env, ctx, ISA_MIPS32R2);
6035 gen_helper_mtc0_srsconf4(cpu_env, arg);
6045 check_insn(env, ctx, ISA_MIPS32R2);
6046 gen_helper_mtc0_hwrena(cpu_env, arg);
6060 gen_helper_mtc0_count(cpu_env, arg);
6063 /* 6,7 are implementation dependent */
6067 /* Stop translation as we may have switched the execution mode */
6068 ctx->bstate = BS_STOP;
6073 gen_helper_mtc0_entryhi(cpu_env, arg);
6083 gen_helper_mtc0_compare(cpu_env, arg);
6086 /* 6,7 are implementation dependent */
6090 /* Stop translation as we may have switched the execution mode */
6091 ctx->bstate = BS_STOP;
6096 save_cpu_state(ctx, 1);
6097 gen_helper_mtc0_status(cpu_env, arg);
6098 /* BS_STOP isn't good enough here, hflags may have changed. */
6099 gen_save_pc(ctx->pc + 4);
6100 ctx->bstate = BS_EXCP;
6104 check_insn(env, ctx, ISA_MIPS32R2);
6105 gen_helper_mtc0_intctl(cpu_env, arg);
6106 /* Stop translation as we may have switched the execution mode */
6107 ctx->bstate = BS_STOP;
6111 check_insn(env, ctx, ISA_MIPS32R2);
6112 gen_helper_mtc0_srsctl(cpu_env, arg);
6113 /* Stop translation as we may have switched the execution mode */
6114 ctx->bstate = BS_STOP;
6118 check_insn(env, ctx, ISA_MIPS32R2);
6119 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6120 /* Stop translation as we may have switched the execution mode */
6121 ctx->bstate = BS_STOP;
6131 save_cpu_state(ctx, 1);
6132 /* Mark as an IO operation because we may trigger a software
6137 gen_helper_mtc0_cause(cpu_env, arg);
6141 /* Stop translation as we may have triggered an intetrupt */
6142 ctx->bstate = BS_STOP;
6152 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6166 check_insn(env, ctx, ISA_MIPS32R2);
6167 gen_helper_mtc0_ebase(cpu_env, arg);
6177 gen_helper_mtc0_config0(cpu_env, arg);
6179 /* Stop translation as we may have switched the execution mode */
6180 ctx->bstate = BS_STOP;
6183 /* ignored, read only */
6187 gen_helper_mtc0_config2(cpu_env, arg);
6189 /* Stop translation as we may have switched the execution mode */
6190 ctx->bstate = BS_STOP;
6196 /* 6,7 are implementation dependent */
6198 rn = "Invalid config selector";
6205 gen_helper_mtc0_lladdr(cpu_env, arg);
6215 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6225 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6235 check_insn(env, ctx, ISA_MIPS3);
6236 gen_helper_mtc0_xcontext(cpu_env, arg);
6244 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6247 gen_helper_mtc0_framemask(cpu_env, arg);
6256 rn = "Diagnostic"; /* implementation dependent */
6261 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6262 /* BS_STOP isn't good enough here, hflags may have changed. */
6263 gen_save_pc(ctx->pc + 4);
6264 ctx->bstate = BS_EXCP;
6268 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6269 /* Stop translation as we may have switched the execution mode */
6270 ctx->bstate = BS_STOP;
6271 rn = "TraceControl";
6274 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6275 /* Stop translation as we may have switched the execution mode */
6276 ctx->bstate = BS_STOP;
6277 rn = "TraceControl2";
6280 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6281 /* Stop translation as we may have switched the execution mode */
6282 ctx->bstate = BS_STOP;
6283 rn = "UserTraceData";
6286 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6287 /* Stop translation as we may have switched the execution mode */
6288 ctx->bstate = BS_STOP;
6299 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6309 gen_helper_mtc0_performance0(cpu_env, arg);
6310 rn = "Performance0";
6313 // gen_helper_mtc0_performance1(cpu_env, arg);
6314 rn = "Performance1";
6317 // gen_helper_mtc0_performance2(cpu_env, arg);
6318 rn = "Performance2";
6321 // gen_helper_mtc0_performance3(cpu_env, arg);
6322 rn = "Performance3";
6325 // gen_helper_mtc0_performance4(cpu_env, arg);
6326 rn = "Performance4";
6329 // gen_helper_mtc0_performance5(cpu_env, arg);
6330 rn = "Performance5";
6333 // gen_helper_mtc0_performance6(cpu_env, arg);
6334 rn = "Performance6";
6337 // gen_helper_mtc0_performance7(cpu_env, arg);
6338 rn = "Performance7";
6364 gen_helper_mtc0_taglo(cpu_env, arg);
6371 gen_helper_mtc0_datalo(cpu_env, arg);
6384 gen_helper_mtc0_taghi(cpu_env, arg);
6391 gen_helper_mtc0_datahi(cpu_env, arg);
6402 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6413 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6419 /* Stop translation as we may have switched the execution mode */
6420 ctx->bstate = BS_STOP;
6425 (void)rn; /* avoid a compiler warning */
6426 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6427 /* For simplicity assume that all writes can cause interrupts. */
6430 ctx->bstate = BS_STOP;
6435 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6436 generate_exception(ctx, EXCP_RI);
6438 #endif /* TARGET_MIPS64 */
6440 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6441 int u, int sel, int h)
6443 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6444 TCGv t0 = tcg_temp_local_new();
6446 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6447 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6448 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6449 tcg_gen_movi_tl(t0, -1);
6450 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6451 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6452 tcg_gen_movi_tl(t0, -1);
6458 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6461 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6471 gen_helper_mftc0_tcstatus(t0, cpu_env);
6474 gen_helper_mftc0_tcbind(t0, cpu_env);
6477 gen_helper_mftc0_tcrestart(t0, cpu_env);
6480 gen_helper_mftc0_tchalt(t0, cpu_env);
6483 gen_helper_mftc0_tccontext(t0, cpu_env);
6486 gen_helper_mftc0_tcschedule(t0, cpu_env);
6489 gen_helper_mftc0_tcschefback(t0, cpu_env);
6492 gen_mfc0(env, ctx, t0, rt, sel);
6499 gen_helper_mftc0_entryhi(t0, cpu_env);
6502 gen_mfc0(env, ctx, t0, rt, sel);
6508 gen_helper_mftc0_status(t0, cpu_env);
6511 gen_mfc0(env, ctx, t0, rt, sel);
6517 gen_helper_mftc0_cause(t0, cpu_env);
6527 gen_helper_mftc0_epc(t0, cpu_env);
6537 gen_helper_mftc0_ebase(t0, cpu_env);
6547 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6557 gen_helper_mftc0_debug(t0, cpu_env);
6560 gen_mfc0(env, ctx, t0, rt, sel);
6565 gen_mfc0(env, ctx, t0, rt, sel);
6567 } else switch (sel) {
6568 /* GPR registers. */
6570 gen_helper_1e0i(mftgpr, t0, rt);
6572 /* Auxiliary CPU registers */
6576 gen_helper_1e0i(mftlo, t0, 0);
6579 gen_helper_1e0i(mfthi, t0, 0);
6582 gen_helper_1e0i(mftacx, t0, 0);
6585 gen_helper_1e0i(mftlo, t0, 1);
6588 gen_helper_1e0i(mfthi, t0, 1);
6591 gen_helper_1e0i(mftacx, t0, 1);
6594 gen_helper_1e0i(mftlo, t0, 2);
6597 gen_helper_1e0i(mfthi, t0, 2);
6600 gen_helper_1e0i(mftacx, t0, 2);
6603 gen_helper_1e0i(mftlo, t0, 3);
6606 gen_helper_1e0i(mfthi, t0, 3);
6609 gen_helper_1e0i(mftacx, t0, 3);
6612 gen_helper_mftdsp(t0, cpu_env);
6618 /* Floating point (COP1). */
6620 /* XXX: For now we support only a single FPU context. */
6622 TCGv_i32 fp0 = tcg_temp_new_i32();
6624 gen_load_fpr32(fp0, rt);
6625 tcg_gen_ext_i32_tl(t0, fp0);
6626 tcg_temp_free_i32(fp0);
6628 TCGv_i32 fp0 = tcg_temp_new_i32();
6630 gen_load_fpr32h(fp0, rt);
6631 tcg_gen_ext_i32_tl(t0, fp0);
6632 tcg_temp_free_i32(fp0);
6636 /* XXX: For now we support only a single FPU context. */
6637 gen_helper_1e0i(cfc1, t0, rt);
6639 /* COP2: Not implemented. */
6646 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6647 gen_store_gpr(t0, rd);
6653 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6654 generate_exception(ctx, EXCP_RI);
6657 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6658 int u, int sel, int h)
6660 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6661 TCGv t0 = tcg_temp_local_new();
6663 gen_load_gpr(t0, rt);
6664 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6665 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6666 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6668 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6669 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6676 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6679 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6689 gen_helper_mttc0_tcstatus(cpu_env, t0);
6692 gen_helper_mttc0_tcbind(cpu_env, t0);
6695 gen_helper_mttc0_tcrestart(cpu_env, t0);
6698 gen_helper_mttc0_tchalt(cpu_env, t0);
6701 gen_helper_mttc0_tccontext(cpu_env, t0);
6704 gen_helper_mttc0_tcschedule(cpu_env, t0);
6707 gen_helper_mttc0_tcschefback(cpu_env, t0);
6710 gen_mtc0(env, ctx, t0, rd, sel);
6717 gen_helper_mttc0_entryhi(cpu_env, t0);
6720 gen_mtc0(env, ctx, t0, rd, sel);
6726 gen_helper_mttc0_status(cpu_env, t0);
6729 gen_mtc0(env, ctx, t0, rd, sel);
6735 gen_helper_mttc0_cause(cpu_env, t0);
6745 gen_helper_mttc0_ebase(cpu_env, t0);
6755 gen_helper_mttc0_debug(cpu_env, t0);
6758 gen_mtc0(env, ctx, t0, rd, sel);
6763 gen_mtc0(env, ctx, t0, rd, sel);
6765 } else switch (sel) {
6766 /* GPR registers. */
6768 gen_helper_0e1i(mttgpr, t0, rd);
6770 /* Auxiliary CPU registers */
6774 gen_helper_0e1i(mttlo, t0, 0);
6777 gen_helper_0e1i(mtthi, t0, 0);
6780 gen_helper_0e1i(mttacx, t0, 0);
6783 gen_helper_0e1i(mttlo, t0, 1);
6786 gen_helper_0e1i(mtthi, t0, 1);
6789 gen_helper_0e1i(mttacx, t0, 1);
6792 gen_helper_0e1i(mttlo, t0, 2);
6795 gen_helper_0e1i(mtthi, t0, 2);
6798 gen_helper_0e1i(mttacx, t0, 2);
6801 gen_helper_0e1i(mttlo, t0, 3);
6804 gen_helper_0e1i(mtthi, t0, 3);
6807 gen_helper_0e1i(mttacx, t0, 3);
6810 gen_helper_mttdsp(cpu_env, t0);
6816 /* Floating point (COP1). */
6818 /* XXX: For now we support only a single FPU context. */
6820 TCGv_i32 fp0 = tcg_temp_new_i32();
6822 tcg_gen_trunc_tl_i32(fp0, t0);
6823 gen_store_fpr32(fp0, rd);
6824 tcg_temp_free_i32(fp0);
6826 TCGv_i32 fp0 = tcg_temp_new_i32();
6828 tcg_gen_trunc_tl_i32(fp0, t0);
6829 gen_store_fpr32h(fp0, rd);
6830 tcg_temp_free_i32(fp0);
6834 /* XXX: For now we support only a single FPU context. */
6835 gen_helper_0e1i(ctc1, t0, rd);
6837 /* COP2: Not implemented. */
6844 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6850 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6851 generate_exception(ctx, EXCP_RI);
6854 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6856 const char *opn = "ldst";
6858 check_cp0_enabled(ctx);
6865 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6870 TCGv t0 = tcg_temp_new();
6872 gen_load_gpr(t0, rt);
6873 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6878 #if defined(TARGET_MIPS64)
6880 check_insn(env, ctx, ISA_MIPS3);
6885 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6889 check_insn(env, ctx, ISA_MIPS3);
6891 TCGv t0 = tcg_temp_new();
6893 gen_load_gpr(t0, rt);
6894 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6901 check_insn(env, ctx, ASE_MT);
6906 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6907 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6911 check_insn(env, ctx, ASE_MT);
6912 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6913 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6918 if (!env->tlb->helper_tlbwi)
6920 gen_helper_tlbwi(cpu_env);
6924 if (!env->tlb->helper_tlbwr)
6926 gen_helper_tlbwr(cpu_env);
6930 if (!env->tlb->helper_tlbp)
6932 gen_helper_tlbp(cpu_env);
6936 if (!env->tlb->helper_tlbr)
6938 gen_helper_tlbr(cpu_env);
6942 check_insn(env, ctx, ISA_MIPS2);
6943 gen_helper_eret(cpu_env);
6944 ctx->bstate = BS_EXCP;
6948 check_insn(env, ctx, ISA_MIPS32);
6949 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6951 generate_exception(ctx, EXCP_RI);
6953 gen_helper_deret(cpu_env);
6954 ctx->bstate = BS_EXCP;
6959 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6960 /* If we get an exception, we want to restart at next instruction */
6962 save_cpu_state(ctx, 1);
6964 gen_helper_wait(cpu_env);
6965 ctx->bstate = BS_EXCP;
6970 generate_exception(ctx, EXCP_RI);
6973 (void)opn; /* avoid a compiler warning */
6974 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6976 #endif /* !CONFIG_USER_ONLY */
6978 /* CP1 Branches (before delay slot) */
6979 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
6980 int32_t cc, int32_t offset)
6982 target_ulong btarget;
6983 const char *opn = "cp1 cond branch";
6984 TCGv_i32 t0 = tcg_temp_new_i32();
6987 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6989 btarget = ctx->pc + 4 + offset;
6993 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6994 tcg_gen_not_i32(t0, t0);
6995 tcg_gen_andi_i32(t0, t0, 1);
6996 tcg_gen_extu_i32_tl(bcond, t0);
7000 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7001 tcg_gen_not_i32(t0, t0);
7002 tcg_gen_andi_i32(t0, t0, 1);
7003 tcg_gen_extu_i32_tl(bcond, t0);
7007 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7008 tcg_gen_andi_i32(t0, t0, 1);
7009 tcg_gen_extu_i32_tl(bcond, t0);
7013 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7014 tcg_gen_andi_i32(t0, t0, 1);
7015 tcg_gen_extu_i32_tl(bcond, t0);
7018 ctx->hflags |= MIPS_HFLAG_BL;
7022 TCGv_i32 t1 = tcg_temp_new_i32();
7023 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7024 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7025 tcg_gen_nand_i32(t0, t0, t1);
7026 tcg_temp_free_i32(t1);
7027 tcg_gen_andi_i32(t0, t0, 1);
7028 tcg_gen_extu_i32_tl(bcond, t0);
7034 TCGv_i32 t1 = tcg_temp_new_i32();
7035 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7036 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7037 tcg_gen_or_i32(t0, t0, t1);
7038 tcg_temp_free_i32(t1);
7039 tcg_gen_andi_i32(t0, t0, 1);
7040 tcg_gen_extu_i32_tl(bcond, t0);
7046 TCGv_i32 t1 = tcg_temp_new_i32();
7047 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7048 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7049 tcg_gen_and_i32(t0, t0, t1);
7050 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7051 tcg_gen_and_i32(t0, t0, t1);
7052 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7053 tcg_gen_nand_i32(t0, t0, t1);
7054 tcg_temp_free_i32(t1);
7055 tcg_gen_andi_i32(t0, t0, 1);
7056 tcg_gen_extu_i32_tl(bcond, t0);
7062 TCGv_i32 t1 = tcg_temp_new_i32();
7063 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7064 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7065 tcg_gen_or_i32(t0, t0, t1);
7066 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7067 tcg_gen_or_i32(t0, t0, t1);
7068 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7069 tcg_gen_or_i32(t0, t0, t1);
7070 tcg_temp_free_i32(t1);
7071 tcg_gen_andi_i32(t0, t0, 1);
7072 tcg_gen_extu_i32_tl(bcond, t0);
7076 ctx->hflags |= MIPS_HFLAG_BC;
7080 generate_exception (ctx, EXCP_RI);
7083 (void)opn; /* avoid a compiler warning */
7084 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7085 ctx->hflags, btarget);
7086 ctx->btarget = btarget;
7089 tcg_temp_free_i32(t0);
7092 /* Coprocessor 1 (FPU) */
7094 #define FOP(func, fmt) (((fmt) << 21) | (func))
7097 OPC_ADD_S = FOP(0, FMT_S),
7098 OPC_SUB_S = FOP(1, FMT_S),
7099 OPC_MUL_S = FOP(2, FMT_S),
7100 OPC_DIV_S = FOP(3, FMT_S),
7101 OPC_SQRT_S = FOP(4, FMT_S),
7102 OPC_ABS_S = FOP(5, FMT_S),
7103 OPC_MOV_S = FOP(6, FMT_S),
7104 OPC_NEG_S = FOP(7, FMT_S),
7105 OPC_ROUND_L_S = FOP(8, FMT_S),
7106 OPC_TRUNC_L_S = FOP(9, FMT_S),
7107 OPC_CEIL_L_S = FOP(10, FMT_S),
7108 OPC_FLOOR_L_S = FOP(11, FMT_S),
7109 OPC_ROUND_W_S = FOP(12, FMT_S),
7110 OPC_TRUNC_W_S = FOP(13, FMT_S),
7111 OPC_CEIL_W_S = FOP(14, FMT_S),
7112 OPC_FLOOR_W_S = FOP(15, FMT_S),
7113 OPC_MOVCF_S = FOP(17, FMT_S),
7114 OPC_MOVZ_S = FOP(18, FMT_S),
7115 OPC_MOVN_S = FOP(19, FMT_S),
7116 OPC_RECIP_S = FOP(21, FMT_S),
7117 OPC_RSQRT_S = FOP(22, FMT_S),
7118 OPC_RECIP2_S = FOP(28, FMT_S),
7119 OPC_RECIP1_S = FOP(29, FMT_S),
7120 OPC_RSQRT1_S = FOP(30, FMT_S),
7121 OPC_RSQRT2_S = FOP(31, FMT_S),
7122 OPC_CVT_D_S = FOP(33, FMT_S),
7123 OPC_CVT_W_S = FOP(36, FMT_S),
7124 OPC_CVT_L_S = FOP(37, FMT_S),
7125 OPC_CVT_PS_S = FOP(38, FMT_S),
7126 OPC_CMP_F_S = FOP (48, FMT_S),
7127 OPC_CMP_UN_S = FOP (49, FMT_S),
7128 OPC_CMP_EQ_S = FOP (50, FMT_S),
7129 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7130 OPC_CMP_OLT_S = FOP (52, FMT_S),
7131 OPC_CMP_ULT_S = FOP (53, FMT_S),
7132 OPC_CMP_OLE_S = FOP (54, FMT_S),
7133 OPC_CMP_ULE_S = FOP (55, FMT_S),
7134 OPC_CMP_SF_S = FOP (56, FMT_S),
7135 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7136 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7137 OPC_CMP_NGL_S = FOP (59, FMT_S),
7138 OPC_CMP_LT_S = FOP (60, FMT_S),
7139 OPC_CMP_NGE_S = FOP (61, FMT_S),
7140 OPC_CMP_LE_S = FOP (62, FMT_S),
7141 OPC_CMP_NGT_S = FOP (63, FMT_S),
7143 OPC_ADD_D = FOP(0, FMT_D),
7144 OPC_SUB_D = FOP(1, FMT_D),
7145 OPC_MUL_D = FOP(2, FMT_D),
7146 OPC_DIV_D = FOP(3, FMT_D),
7147 OPC_SQRT_D = FOP(4, FMT_D),
7148 OPC_ABS_D = FOP(5, FMT_D),
7149 OPC_MOV_D = FOP(6, FMT_D),
7150 OPC_NEG_D = FOP(7, FMT_D),
7151 OPC_ROUND_L_D = FOP(8, FMT_D),
7152 OPC_TRUNC_L_D = FOP(9, FMT_D),
7153 OPC_CEIL_L_D = FOP(10, FMT_D),
7154 OPC_FLOOR_L_D = FOP(11, FMT_D),
7155 OPC_ROUND_W_D = FOP(12, FMT_D),
7156 OPC_TRUNC_W_D = FOP(13, FMT_D),
7157 OPC_CEIL_W_D = FOP(14, FMT_D),
7158 OPC_FLOOR_W_D = FOP(15, FMT_D),
7159 OPC_MOVCF_D = FOP(17, FMT_D),
7160 OPC_MOVZ_D = FOP(18, FMT_D),
7161 OPC_MOVN_D = FOP(19, FMT_D),
7162 OPC_RECIP_D = FOP(21, FMT_D),
7163 OPC_RSQRT_D = FOP(22, FMT_D),
7164 OPC_RECIP2_D = FOP(28, FMT_D),
7165 OPC_RECIP1_D = FOP(29, FMT_D),
7166 OPC_RSQRT1_D = FOP(30, FMT_D),
7167 OPC_RSQRT2_D = FOP(31, FMT_D),
7168 OPC_CVT_S_D = FOP(32, FMT_D),
7169 OPC_CVT_W_D = FOP(36, FMT_D),
7170 OPC_CVT_L_D = FOP(37, FMT_D),
7171 OPC_CMP_F_D = FOP (48, FMT_D),
7172 OPC_CMP_UN_D = FOP (49, FMT_D),
7173 OPC_CMP_EQ_D = FOP (50, FMT_D),
7174 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7175 OPC_CMP_OLT_D = FOP (52, FMT_D),
7176 OPC_CMP_ULT_D = FOP (53, FMT_D),
7177 OPC_CMP_OLE_D = FOP (54, FMT_D),
7178 OPC_CMP_ULE_D = FOP (55, FMT_D),
7179 OPC_CMP_SF_D = FOP (56, FMT_D),
7180 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7181 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7182 OPC_CMP_NGL_D = FOP (59, FMT_D),
7183 OPC_CMP_LT_D = FOP (60, FMT_D),
7184 OPC_CMP_NGE_D = FOP (61, FMT_D),
7185 OPC_CMP_LE_D = FOP (62, FMT_D),
7186 OPC_CMP_NGT_D = FOP (63, FMT_D),
7188 OPC_CVT_S_W = FOP(32, FMT_W),
7189 OPC_CVT_D_W = FOP(33, FMT_W),
7190 OPC_CVT_S_L = FOP(32, FMT_L),
7191 OPC_CVT_D_L = FOP(33, FMT_L),
7192 OPC_CVT_PS_PW = FOP(38, FMT_W),
7194 OPC_ADD_PS = FOP(0, FMT_PS),
7195 OPC_SUB_PS = FOP(1, FMT_PS),
7196 OPC_MUL_PS = FOP(2, FMT_PS),
7197 OPC_DIV_PS = FOP(3, FMT_PS),
7198 OPC_ABS_PS = FOP(5, FMT_PS),
7199 OPC_MOV_PS = FOP(6, FMT_PS),
7200 OPC_NEG_PS = FOP(7, FMT_PS),
7201 OPC_MOVCF_PS = FOP(17, FMT_PS),
7202 OPC_MOVZ_PS = FOP(18, FMT_PS),
7203 OPC_MOVN_PS = FOP(19, FMT_PS),
7204 OPC_ADDR_PS = FOP(24, FMT_PS),
7205 OPC_MULR_PS = FOP(26, FMT_PS),
7206 OPC_RECIP2_PS = FOP(28, FMT_PS),
7207 OPC_RECIP1_PS = FOP(29, FMT_PS),
7208 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7209 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7211 OPC_CVT_S_PU = FOP(32, FMT_PS),
7212 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7213 OPC_CVT_S_PL = FOP(40, FMT_PS),
7214 OPC_PLL_PS = FOP(44, FMT_PS),
7215 OPC_PLU_PS = FOP(45, FMT_PS),
7216 OPC_PUL_PS = FOP(46, FMT_PS),
7217 OPC_PUU_PS = FOP(47, FMT_PS),
7218 OPC_CMP_F_PS = FOP (48, FMT_PS),
7219 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7220 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7221 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7222 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7223 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7224 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7225 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7226 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7227 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7228 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7229 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7230 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7231 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7232 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7233 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7236 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7238 const char *opn = "cp1 move";
7239 TCGv t0 = tcg_temp_new();
7244 TCGv_i32 fp0 = tcg_temp_new_i32();
7246 gen_load_fpr32(fp0, fs);
7247 tcg_gen_ext_i32_tl(t0, fp0);
7248 tcg_temp_free_i32(fp0);
7250 gen_store_gpr(t0, rt);
7254 gen_load_gpr(t0, rt);
7256 TCGv_i32 fp0 = tcg_temp_new_i32();
7258 tcg_gen_trunc_tl_i32(fp0, t0);
7259 gen_store_fpr32(fp0, fs);
7260 tcg_temp_free_i32(fp0);
7265 gen_helper_1e0i(cfc1, t0, fs);
7266 gen_store_gpr(t0, rt);
7270 gen_load_gpr(t0, rt);
7271 gen_helper_0e1i(ctc1, t0, fs);
7274 #if defined(TARGET_MIPS64)
7276 gen_load_fpr64(ctx, t0, fs);
7277 gen_store_gpr(t0, rt);
7281 gen_load_gpr(t0, rt);
7282 gen_store_fpr64(ctx, t0, fs);
7288 TCGv_i32 fp0 = tcg_temp_new_i32();
7290 gen_load_fpr32h(fp0, fs);
7291 tcg_gen_ext_i32_tl(t0, fp0);
7292 tcg_temp_free_i32(fp0);
7294 gen_store_gpr(t0, rt);
7298 gen_load_gpr(t0, rt);
7300 TCGv_i32 fp0 = tcg_temp_new_i32();
7302 tcg_gen_trunc_tl_i32(fp0, t0);
7303 gen_store_fpr32h(fp0, fs);
7304 tcg_temp_free_i32(fp0);
7310 generate_exception (ctx, EXCP_RI);
7313 (void)opn; /* avoid a compiler warning */
7314 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7320 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7336 l1 = gen_new_label();
7337 t0 = tcg_temp_new_i32();
7338 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7339 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7340 tcg_temp_free_i32(t0);
7342 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7344 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7349 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7352 TCGv_i32 t0 = tcg_temp_new_i32();
7353 int l1 = gen_new_label();
7360 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7361 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7362 gen_load_fpr32(t0, fs);
7363 gen_store_fpr32(t0, fd);
7365 tcg_temp_free_i32(t0);
7368 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7371 TCGv_i32 t0 = tcg_temp_new_i32();
7373 int l1 = gen_new_label();
7380 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7381 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7382 tcg_temp_free_i32(t0);
7383 fp0 = tcg_temp_new_i64();
7384 gen_load_fpr64(ctx, fp0, fs);
7385 gen_store_fpr64(ctx, fp0, fd);
7386 tcg_temp_free_i64(fp0);
7390 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7393 TCGv_i32 t0 = tcg_temp_new_i32();
7394 int l1 = gen_new_label();
7395 int l2 = gen_new_label();
7402 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7403 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7404 gen_load_fpr32(t0, fs);
7405 gen_store_fpr32(t0, fd);
7408 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7409 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7410 gen_load_fpr32h(t0, fs);
7411 gen_store_fpr32h(t0, fd);
7412 tcg_temp_free_i32(t0);
7417 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7418 int ft, int fs, int fd, int cc)
7420 const char *opn = "farith";
7421 const char *condnames[] = {
7439 const char *condnames_abs[] = {
7457 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7458 uint32_t func = ctx->opcode & 0x3f;
7463 TCGv_i32 fp0 = tcg_temp_new_i32();
7464 TCGv_i32 fp1 = tcg_temp_new_i32();
7466 gen_load_fpr32(fp0, fs);
7467 gen_load_fpr32(fp1, ft);
7468 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7469 tcg_temp_free_i32(fp1);
7470 gen_store_fpr32(fp0, fd);
7471 tcg_temp_free_i32(fp0);
7478 TCGv_i32 fp0 = tcg_temp_new_i32();
7479 TCGv_i32 fp1 = tcg_temp_new_i32();
7481 gen_load_fpr32(fp0, fs);
7482 gen_load_fpr32(fp1, ft);
7483 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7484 tcg_temp_free_i32(fp1);
7485 gen_store_fpr32(fp0, fd);
7486 tcg_temp_free_i32(fp0);
7493 TCGv_i32 fp0 = tcg_temp_new_i32();
7494 TCGv_i32 fp1 = tcg_temp_new_i32();
7496 gen_load_fpr32(fp0, fs);
7497 gen_load_fpr32(fp1, ft);
7498 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7499 tcg_temp_free_i32(fp1);
7500 gen_store_fpr32(fp0, fd);
7501 tcg_temp_free_i32(fp0);
7508 TCGv_i32 fp0 = tcg_temp_new_i32();
7509 TCGv_i32 fp1 = tcg_temp_new_i32();
7511 gen_load_fpr32(fp0, fs);
7512 gen_load_fpr32(fp1, ft);
7513 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7514 tcg_temp_free_i32(fp1);
7515 gen_store_fpr32(fp0, fd);
7516 tcg_temp_free_i32(fp0);
7523 TCGv_i32 fp0 = tcg_temp_new_i32();
7525 gen_load_fpr32(fp0, fs);
7526 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7527 gen_store_fpr32(fp0, fd);
7528 tcg_temp_free_i32(fp0);
7534 TCGv_i32 fp0 = tcg_temp_new_i32();
7536 gen_load_fpr32(fp0, fs);
7537 gen_helper_float_abs_s(fp0, fp0);
7538 gen_store_fpr32(fp0, fd);
7539 tcg_temp_free_i32(fp0);
7545 TCGv_i32 fp0 = tcg_temp_new_i32();
7547 gen_load_fpr32(fp0, fs);
7548 gen_store_fpr32(fp0, fd);
7549 tcg_temp_free_i32(fp0);
7555 TCGv_i32 fp0 = tcg_temp_new_i32();
7557 gen_load_fpr32(fp0, fs);
7558 gen_helper_float_chs_s(fp0, fp0);
7559 gen_store_fpr32(fp0, fd);
7560 tcg_temp_free_i32(fp0);
7565 check_cp1_64bitmode(ctx);
7567 TCGv_i32 fp32 = tcg_temp_new_i32();
7568 TCGv_i64 fp64 = tcg_temp_new_i64();
7570 gen_load_fpr32(fp32, fs);
7571 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7572 tcg_temp_free_i32(fp32);
7573 gen_store_fpr64(ctx, fp64, fd);
7574 tcg_temp_free_i64(fp64);
7579 check_cp1_64bitmode(ctx);
7581 TCGv_i32 fp32 = tcg_temp_new_i32();
7582 TCGv_i64 fp64 = tcg_temp_new_i64();
7584 gen_load_fpr32(fp32, fs);
7585 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7586 tcg_temp_free_i32(fp32);
7587 gen_store_fpr64(ctx, fp64, fd);
7588 tcg_temp_free_i64(fp64);
7593 check_cp1_64bitmode(ctx);
7595 TCGv_i32 fp32 = tcg_temp_new_i32();
7596 TCGv_i64 fp64 = tcg_temp_new_i64();
7598 gen_load_fpr32(fp32, fs);
7599 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7600 tcg_temp_free_i32(fp32);
7601 gen_store_fpr64(ctx, fp64, fd);
7602 tcg_temp_free_i64(fp64);
7607 check_cp1_64bitmode(ctx);
7609 TCGv_i32 fp32 = tcg_temp_new_i32();
7610 TCGv_i64 fp64 = tcg_temp_new_i64();
7612 gen_load_fpr32(fp32, fs);
7613 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7614 tcg_temp_free_i32(fp32);
7615 gen_store_fpr64(ctx, fp64, fd);
7616 tcg_temp_free_i64(fp64);
7622 TCGv_i32 fp0 = tcg_temp_new_i32();
7624 gen_load_fpr32(fp0, fs);
7625 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7626 gen_store_fpr32(fp0, fd);
7627 tcg_temp_free_i32(fp0);
7633 TCGv_i32 fp0 = tcg_temp_new_i32();
7635 gen_load_fpr32(fp0, fs);
7636 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7637 gen_store_fpr32(fp0, fd);
7638 tcg_temp_free_i32(fp0);
7644 TCGv_i32 fp0 = tcg_temp_new_i32();
7646 gen_load_fpr32(fp0, fs);
7647 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7648 gen_store_fpr32(fp0, fd);
7649 tcg_temp_free_i32(fp0);
7655 TCGv_i32 fp0 = tcg_temp_new_i32();
7657 gen_load_fpr32(fp0, fs);
7658 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7659 gen_store_fpr32(fp0, fd);
7660 tcg_temp_free_i32(fp0);
7665 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7670 int l1 = gen_new_label();
7674 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7676 fp0 = tcg_temp_new_i32();
7677 gen_load_fpr32(fp0, fs);
7678 gen_store_fpr32(fp0, fd);
7679 tcg_temp_free_i32(fp0);
7686 int l1 = gen_new_label();
7690 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7691 fp0 = tcg_temp_new_i32();
7692 gen_load_fpr32(fp0, fs);
7693 gen_store_fpr32(fp0, fd);
7694 tcg_temp_free_i32(fp0);
7703 TCGv_i32 fp0 = tcg_temp_new_i32();
7705 gen_load_fpr32(fp0, fs);
7706 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7707 gen_store_fpr32(fp0, fd);
7708 tcg_temp_free_i32(fp0);
7715 TCGv_i32 fp0 = tcg_temp_new_i32();
7717 gen_load_fpr32(fp0, fs);
7718 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7719 gen_store_fpr32(fp0, fd);
7720 tcg_temp_free_i32(fp0);
7725 check_cp1_64bitmode(ctx);
7727 TCGv_i32 fp0 = tcg_temp_new_i32();
7728 TCGv_i32 fp1 = tcg_temp_new_i32();
7730 gen_load_fpr32(fp0, fs);
7731 gen_load_fpr32(fp1, ft);
7732 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7733 tcg_temp_free_i32(fp1);
7734 gen_store_fpr32(fp0, fd);
7735 tcg_temp_free_i32(fp0);
7740 check_cp1_64bitmode(ctx);
7742 TCGv_i32 fp0 = tcg_temp_new_i32();
7744 gen_load_fpr32(fp0, fs);
7745 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7746 gen_store_fpr32(fp0, fd);
7747 tcg_temp_free_i32(fp0);
7752 check_cp1_64bitmode(ctx);
7754 TCGv_i32 fp0 = tcg_temp_new_i32();
7756 gen_load_fpr32(fp0, fs);
7757 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7758 gen_store_fpr32(fp0, fd);
7759 tcg_temp_free_i32(fp0);
7764 check_cp1_64bitmode(ctx);
7766 TCGv_i32 fp0 = tcg_temp_new_i32();
7767 TCGv_i32 fp1 = tcg_temp_new_i32();
7769 gen_load_fpr32(fp0, fs);
7770 gen_load_fpr32(fp1, ft);
7771 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7772 tcg_temp_free_i32(fp1);
7773 gen_store_fpr32(fp0, fd);
7774 tcg_temp_free_i32(fp0);
7779 check_cp1_registers(ctx, fd);
7781 TCGv_i32 fp32 = tcg_temp_new_i32();
7782 TCGv_i64 fp64 = tcg_temp_new_i64();
7784 gen_load_fpr32(fp32, fs);
7785 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7786 tcg_temp_free_i32(fp32);
7787 gen_store_fpr64(ctx, fp64, fd);
7788 tcg_temp_free_i64(fp64);
7794 TCGv_i32 fp0 = tcg_temp_new_i32();
7796 gen_load_fpr32(fp0, fs);
7797 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7798 gen_store_fpr32(fp0, fd);
7799 tcg_temp_free_i32(fp0);
7804 check_cp1_64bitmode(ctx);
7806 TCGv_i32 fp32 = tcg_temp_new_i32();
7807 TCGv_i64 fp64 = tcg_temp_new_i64();
7809 gen_load_fpr32(fp32, fs);
7810 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7811 tcg_temp_free_i32(fp32);
7812 gen_store_fpr64(ctx, fp64, fd);
7813 tcg_temp_free_i64(fp64);
7818 check_cp1_64bitmode(ctx);
7820 TCGv_i64 fp64 = tcg_temp_new_i64();
7821 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7822 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7824 gen_load_fpr32(fp32_0, fs);
7825 gen_load_fpr32(fp32_1, ft);
7826 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7827 tcg_temp_free_i32(fp32_1);
7828 tcg_temp_free_i32(fp32_0);
7829 gen_store_fpr64(ctx, fp64, fd);
7830 tcg_temp_free_i64(fp64);
7843 case OPC_CMP_NGLE_S:
7850 if (ctx->opcode & (1 << 6)) {
7851 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7852 opn = condnames_abs[func-48];
7854 gen_cmp_s(ctx, func-48, ft, fs, cc);
7855 opn = condnames[func-48];
7859 check_cp1_registers(ctx, fs | ft | fd);
7861 TCGv_i64 fp0 = tcg_temp_new_i64();
7862 TCGv_i64 fp1 = tcg_temp_new_i64();
7864 gen_load_fpr64(ctx, fp0, fs);
7865 gen_load_fpr64(ctx, fp1, ft);
7866 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7867 tcg_temp_free_i64(fp1);
7868 gen_store_fpr64(ctx, fp0, fd);
7869 tcg_temp_free_i64(fp0);
7875 check_cp1_registers(ctx, fs | ft | fd);
7877 TCGv_i64 fp0 = tcg_temp_new_i64();
7878 TCGv_i64 fp1 = tcg_temp_new_i64();
7880 gen_load_fpr64(ctx, fp0, fs);
7881 gen_load_fpr64(ctx, fp1, ft);
7882 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7883 tcg_temp_free_i64(fp1);
7884 gen_store_fpr64(ctx, fp0, fd);
7885 tcg_temp_free_i64(fp0);
7891 check_cp1_registers(ctx, fs | ft | fd);
7893 TCGv_i64 fp0 = tcg_temp_new_i64();
7894 TCGv_i64 fp1 = tcg_temp_new_i64();
7896 gen_load_fpr64(ctx, fp0, fs);
7897 gen_load_fpr64(ctx, fp1, ft);
7898 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7899 tcg_temp_free_i64(fp1);
7900 gen_store_fpr64(ctx, fp0, fd);
7901 tcg_temp_free_i64(fp0);
7907 check_cp1_registers(ctx, fs | ft | fd);
7909 TCGv_i64 fp0 = tcg_temp_new_i64();
7910 TCGv_i64 fp1 = tcg_temp_new_i64();
7912 gen_load_fpr64(ctx, fp0, fs);
7913 gen_load_fpr64(ctx, fp1, ft);
7914 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7915 tcg_temp_free_i64(fp1);
7916 gen_store_fpr64(ctx, fp0, fd);
7917 tcg_temp_free_i64(fp0);
7923 check_cp1_registers(ctx, fs | fd);
7925 TCGv_i64 fp0 = tcg_temp_new_i64();
7927 gen_load_fpr64(ctx, fp0, fs);
7928 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7929 gen_store_fpr64(ctx, fp0, fd);
7930 tcg_temp_free_i64(fp0);
7935 check_cp1_registers(ctx, fs | fd);
7937 TCGv_i64 fp0 = tcg_temp_new_i64();
7939 gen_load_fpr64(ctx, fp0, fs);
7940 gen_helper_float_abs_d(fp0, fp0);
7941 gen_store_fpr64(ctx, fp0, fd);
7942 tcg_temp_free_i64(fp0);
7947 check_cp1_registers(ctx, fs | fd);
7949 TCGv_i64 fp0 = tcg_temp_new_i64();
7951 gen_load_fpr64(ctx, fp0, fs);
7952 gen_store_fpr64(ctx, fp0, fd);
7953 tcg_temp_free_i64(fp0);
7958 check_cp1_registers(ctx, fs | fd);
7960 TCGv_i64 fp0 = tcg_temp_new_i64();
7962 gen_load_fpr64(ctx, fp0, fs);
7963 gen_helper_float_chs_d(fp0, fp0);
7964 gen_store_fpr64(ctx, fp0, fd);
7965 tcg_temp_free_i64(fp0);
7970 check_cp1_64bitmode(ctx);
7972 TCGv_i64 fp0 = tcg_temp_new_i64();
7974 gen_load_fpr64(ctx, fp0, fs);
7975 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7976 gen_store_fpr64(ctx, fp0, fd);
7977 tcg_temp_free_i64(fp0);
7982 check_cp1_64bitmode(ctx);
7984 TCGv_i64 fp0 = tcg_temp_new_i64();
7986 gen_load_fpr64(ctx, fp0, fs);
7987 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7988 gen_store_fpr64(ctx, fp0, fd);
7989 tcg_temp_free_i64(fp0);
7994 check_cp1_64bitmode(ctx);
7996 TCGv_i64 fp0 = tcg_temp_new_i64();
7998 gen_load_fpr64(ctx, fp0, fs);
7999 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8000 gen_store_fpr64(ctx, fp0, fd);
8001 tcg_temp_free_i64(fp0);
8006 check_cp1_64bitmode(ctx);
8008 TCGv_i64 fp0 = tcg_temp_new_i64();
8010 gen_load_fpr64(ctx, fp0, fs);
8011 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8012 gen_store_fpr64(ctx, fp0, fd);
8013 tcg_temp_free_i64(fp0);
8018 check_cp1_registers(ctx, fs);
8020 TCGv_i32 fp32 = tcg_temp_new_i32();
8021 TCGv_i64 fp64 = tcg_temp_new_i64();
8023 gen_load_fpr64(ctx, fp64, fs);
8024 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8025 tcg_temp_free_i64(fp64);
8026 gen_store_fpr32(fp32, fd);
8027 tcg_temp_free_i32(fp32);
8032 check_cp1_registers(ctx, fs);
8034 TCGv_i32 fp32 = tcg_temp_new_i32();
8035 TCGv_i64 fp64 = tcg_temp_new_i64();
8037 gen_load_fpr64(ctx, fp64, fs);
8038 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8039 tcg_temp_free_i64(fp64);
8040 gen_store_fpr32(fp32, fd);
8041 tcg_temp_free_i32(fp32);
8046 check_cp1_registers(ctx, fs);
8048 TCGv_i32 fp32 = tcg_temp_new_i32();
8049 TCGv_i64 fp64 = tcg_temp_new_i64();
8051 gen_load_fpr64(ctx, fp64, fs);
8052 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8053 tcg_temp_free_i64(fp64);
8054 gen_store_fpr32(fp32, fd);
8055 tcg_temp_free_i32(fp32);
8060 check_cp1_registers(ctx, fs);
8062 TCGv_i32 fp32 = tcg_temp_new_i32();
8063 TCGv_i64 fp64 = tcg_temp_new_i64();
8065 gen_load_fpr64(ctx, fp64, fs);
8066 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8067 tcg_temp_free_i64(fp64);
8068 gen_store_fpr32(fp32, fd);
8069 tcg_temp_free_i32(fp32);
8074 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8079 int l1 = gen_new_label();
8083 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8085 fp0 = tcg_temp_new_i64();
8086 gen_load_fpr64(ctx, fp0, fs);
8087 gen_store_fpr64(ctx, fp0, fd);
8088 tcg_temp_free_i64(fp0);
8095 int l1 = gen_new_label();
8099 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8100 fp0 = tcg_temp_new_i64();
8101 gen_load_fpr64(ctx, fp0, fs);
8102 gen_store_fpr64(ctx, fp0, fd);
8103 tcg_temp_free_i64(fp0);
8110 check_cp1_64bitmode(ctx);
8112 TCGv_i64 fp0 = tcg_temp_new_i64();
8114 gen_load_fpr64(ctx, fp0, fs);
8115 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8116 gen_store_fpr64(ctx, fp0, fd);
8117 tcg_temp_free_i64(fp0);
8122 check_cp1_64bitmode(ctx);
8124 TCGv_i64 fp0 = tcg_temp_new_i64();
8126 gen_load_fpr64(ctx, fp0, fs);
8127 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8128 gen_store_fpr64(ctx, fp0, fd);
8129 tcg_temp_free_i64(fp0);
8134 check_cp1_64bitmode(ctx);
8136 TCGv_i64 fp0 = tcg_temp_new_i64();
8137 TCGv_i64 fp1 = tcg_temp_new_i64();
8139 gen_load_fpr64(ctx, fp0, fs);
8140 gen_load_fpr64(ctx, fp1, ft);
8141 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8142 tcg_temp_free_i64(fp1);
8143 gen_store_fpr64(ctx, fp0, fd);
8144 tcg_temp_free_i64(fp0);
8149 check_cp1_64bitmode(ctx);
8151 TCGv_i64 fp0 = tcg_temp_new_i64();
8153 gen_load_fpr64(ctx, fp0, fs);
8154 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8155 gen_store_fpr64(ctx, fp0, fd);
8156 tcg_temp_free_i64(fp0);
8161 check_cp1_64bitmode(ctx);
8163 TCGv_i64 fp0 = tcg_temp_new_i64();
8165 gen_load_fpr64(ctx, fp0, fs);
8166 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8167 gen_store_fpr64(ctx, fp0, fd);
8168 tcg_temp_free_i64(fp0);
8173 check_cp1_64bitmode(ctx);
8175 TCGv_i64 fp0 = tcg_temp_new_i64();
8176 TCGv_i64 fp1 = tcg_temp_new_i64();
8178 gen_load_fpr64(ctx, fp0, fs);
8179 gen_load_fpr64(ctx, fp1, ft);
8180 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8181 tcg_temp_free_i64(fp1);
8182 gen_store_fpr64(ctx, fp0, fd);
8183 tcg_temp_free_i64(fp0);
8196 case OPC_CMP_NGLE_D:
8203 if (ctx->opcode & (1 << 6)) {
8204 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8205 opn = condnames_abs[func-48];
8207 gen_cmp_d(ctx, func-48, ft, fs, cc);
8208 opn = condnames[func-48];
8212 check_cp1_registers(ctx, fs);
8214 TCGv_i32 fp32 = tcg_temp_new_i32();
8215 TCGv_i64 fp64 = tcg_temp_new_i64();
8217 gen_load_fpr64(ctx, fp64, fs);
8218 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8219 tcg_temp_free_i64(fp64);
8220 gen_store_fpr32(fp32, fd);
8221 tcg_temp_free_i32(fp32);
8226 check_cp1_registers(ctx, fs);
8228 TCGv_i32 fp32 = tcg_temp_new_i32();
8229 TCGv_i64 fp64 = tcg_temp_new_i64();
8231 gen_load_fpr64(ctx, fp64, fs);
8232 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8233 tcg_temp_free_i64(fp64);
8234 gen_store_fpr32(fp32, fd);
8235 tcg_temp_free_i32(fp32);
8240 check_cp1_64bitmode(ctx);
8242 TCGv_i64 fp0 = tcg_temp_new_i64();
8244 gen_load_fpr64(ctx, fp0, fs);
8245 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8246 gen_store_fpr64(ctx, fp0, fd);
8247 tcg_temp_free_i64(fp0);
8253 TCGv_i32 fp0 = tcg_temp_new_i32();
8255 gen_load_fpr32(fp0, fs);
8256 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8257 gen_store_fpr32(fp0, fd);
8258 tcg_temp_free_i32(fp0);
8263 check_cp1_registers(ctx, fd);
8265 TCGv_i32 fp32 = tcg_temp_new_i32();
8266 TCGv_i64 fp64 = tcg_temp_new_i64();
8268 gen_load_fpr32(fp32, fs);
8269 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8270 tcg_temp_free_i32(fp32);
8271 gen_store_fpr64(ctx, fp64, fd);
8272 tcg_temp_free_i64(fp64);
8277 check_cp1_64bitmode(ctx);
8279 TCGv_i32 fp32 = tcg_temp_new_i32();
8280 TCGv_i64 fp64 = tcg_temp_new_i64();
8282 gen_load_fpr64(ctx, fp64, fs);
8283 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8284 tcg_temp_free_i64(fp64);
8285 gen_store_fpr32(fp32, fd);
8286 tcg_temp_free_i32(fp32);
8291 check_cp1_64bitmode(ctx);
8293 TCGv_i64 fp0 = tcg_temp_new_i64();
8295 gen_load_fpr64(ctx, fp0, fs);
8296 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8297 gen_store_fpr64(ctx, fp0, fd);
8298 tcg_temp_free_i64(fp0);
8303 check_cp1_64bitmode(ctx);
8305 TCGv_i64 fp0 = tcg_temp_new_i64();
8307 gen_load_fpr64(ctx, fp0, fs);
8308 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8309 gen_store_fpr64(ctx, fp0, fd);
8310 tcg_temp_free_i64(fp0);
8315 check_cp1_64bitmode(ctx);
8317 TCGv_i64 fp0 = tcg_temp_new_i64();
8318 TCGv_i64 fp1 = tcg_temp_new_i64();
8320 gen_load_fpr64(ctx, fp0, fs);
8321 gen_load_fpr64(ctx, fp1, ft);
8322 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8323 tcg_temp_free_i64(fp1);
8324 gen_store_fpr64(ctx, fp0, fd);
8325 tcg_temp_free_i64(fp0);
8330 check_cp1_64bitmode(ctx);
8332 TCGv_i64 fp0 = tcg_temp_new_i64();
8333 TCGv_i64 fp1 = tcg_temp_new_i64();
8335 gen_load_fpr64(ctx, fp0, fs);
8336 gen_load_fpr64(ctx, fp1, ft);
8337 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8338 tcg_temp_free_i64(fp1);
8339 gen_store_fpr64(ctx, fp0, fd);
8340 tcg_temp_free_i64(fp0);
8345 check_cp1_64bitmode(ctx);
8347 TCGv_i64 fp0 = tcg_temp_new_i64();
8348 TCGv_i64 fp1 = tcg_temp_new_i64();
8350 gen_load_fpr64(ctx, fp0, fs);
8351 gen_load_fpr64(ctx, fp1, ft);
8352 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8353 tcg_temp_free_i64(fp1);
8354 gen_store_fpr64(ctx, fp0, fd);
8355 tcg_temp_free_i64(fp0);
8360 check_cp1_64bitmode(ctx);
8362 TCGv_i64 fp0 = tcg_temp_new_i64();
8364 gen_load_fpr64(ctx, fp0, fs);
8365 gen_helper_float_abs_ps(fp0, fp0);
8366 gen_store_fpr64(ctx, fp0, fd);
8367 tcg_temp_free_i64(fp0);
8372 check_cp1_64bitmode(ctx);
8374 TCGv_i64 fp0 = tcg_temp_new_i64();
8376 gen_load_fpr64(ctx, fp0, fs);
8377 gen_store_fpr64(ctx, fp0, fd);
8378 tcg_temp_free_i64(fp0);
8383 check_cp1_64bitmode(ctx);
8385 TCGv_i64 fp0 = tcg_temp_new_i64();
8387 gen_load_fpr64(ctx, fp0, fs);
8388 gen_helper_float_chs_ps(fp0, fp0);
8389 gen_store_fpr64(ctx, fp0, fd);
8390 tcg_temp_free_i64(fp0);
8395 check_cp1_64bitmode(ctx);
8396 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8400 check_cp1_64bitmode(ctx);
8402 int l1 = gen_new_label();
8406 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8407 fp0 = tcg_temp_new_i64();
8408 gen_load_fpr64(ctx, fp0, fs);
8409 gen_store_fpr64(ctx, fp0, fd);
8410 tcg_temp_free_i64(fp0);
8416 check_cp1_64bitmode(ctx);
8418 int l1 = gen_new_label();
8422 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8423 fp0 = tcg_temp_new_i64();
8424 gen_load_fpr64(ctx, fp0, fs);
8425 gen_store_fpr64(ctx, fp0, fd);
8426 tcg_temp_free_i64(fp0);
8433 check_cp1_64bitmode(ctx);
8435 TCGv_i64 fp0 = tcg_temp_new_i64();
8436 TCGv_i64 fp1 = tcg_temp_new_i64();
8438 gen_load_fpr64(ctx, fp0, ft);
8439 gen_load_fpr64(ctx, fp1, fs);
8440 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8441 tcg_temp_free_i64(fp1);
8442 gen_store_fpr64(ctx, fp0, fd);
8443 tcg_temp_free_i64(fp0);
8448 check_cp1_64bitmode(ctx);
8450 TCGv_i64 fp0 = tcg_temp_new_i64();
8451 TCGv_i64 fp1 = tcg_temp_new_i64();
8453 gen_load_fpr64(ctx, fp0, ft);
8454 gen_load_fpr64(ctx, fp1, fs);
8455 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8456 tcg_temp_free_i64(fp1);
8457 gen_store_fpr64(ctx, fp0, fd);
8458 tcg_temp_free_i64(fp0);
8463 check_cp1_64bitmode(ctx);
8465 TCGv_i64 fp0 = tcg_temp_new_i64();
8466 TCGv_i64 fp1 = tcg_temp_new_i64();
8468 gen_load_fpr64(ctx, fp0, fs);
8469 gen_load_fpr64(ctx, fp1, ft);
8470 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8471 tcg_temp_free_i64(fp1);
8472 gen_store_fpr64(ctx, fp0, fd);
8473 tcg_temp_free_i64(fp0);
8478 check_cp1_64bitmode(ctx);
8480 TCGv_i64 fp0 = tcg_temp_new_i64();
8482 gen_load_fpr64(ctx, fp0, fs);
8483 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8484 gen_store_fpr64(ctx, fp0, fd);
8485 tcg_temp_free_i64(fp0);
8490 check_cp1_64bitmode(ctx);
8492 TCGv_i64 fp0 = tcg_temp_new_i64();
8494 gen_load_fpr64(ctx, fp0, fs);
8495 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8496 gen_store_fpr64(ctx, fp0, fd);
8497 tcg_temp_free_i64(fp0);
8502 check_cp1_64bitmode(ctx);
8504 TCGv_i64 fp0 = tcg_temp_new_i64();
8505 TCGv_i64 fp1 = tcg_temp_new_i64();
8507 gen_load_fpr64(ctx, fp0, fs);
8508 gen_load_fpr64(ctx, fp1, ft);
8509 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8510 tcg_temp_free_i64(fp1);
8511 gen_store_fpr64(ctx, fp0, fd);
8512 tcg_temp_free_i64(fp0);
8517 check_cp1_64bitmode(ctx);
8519 TCGv_i32 fp0 = tcg_temp_new_i32();
8521 gen_load_fpr32h(fp0, fs);
8522 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8523 gen_store_fpr32(fp0, fd);
8524 tcg_temp_free_i32(fp0);
8529 check_cp1_64bitmode(ctx);
8531 TCGv_i64 fp0 = tcg_temp_new_i64();
8533 gen_load_fpr64(ctx, fp0, fs);
8534 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8535 gen_store_fpr64(ctx, fp0, fd);
8536 tcg_temp_free_i64(fp0);
8541 check_cp1_64bitmode(ctx);
8543 TCGv_i32 fp0 = tcg_temp_new_i32();
8545 gen_load_fpr32(fp0, fs);
8546 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8547 gen_store_fpr32(fp0, fd);
8548 tcg_temp_free_i32(fp0);
8553 check_cp1_64bitmode(ctx);
8555 TCGv_i32 fp0 = tcg_temp_new_i32();
8556 TCGv_i32 fp1 = tcg_temp_new_i32();
8558 gen_load_fpr32(fp0, fs);
8559 gen_load_fpr32(fp1, ft);
8560 gen_store_fpr32h(fp0, fd);
8561 gen_store_fpr32(fp1, fd);
8562 tcg_temp_free_i32(fp0);
8563 tcg_temp_free_i32(fp1);
8568 check_cp1_64bitmode(ctx);
8570 TCGv_i32 fp0 = tcg_temp_new_i32();
8571 TCGv_i32 fp1 = tcg_temp_new_i32();
8573 gen_load_fpr32(fp0, fs);
8574 gen_load_fpr32h(fp1, ft);
8575 gen_store_fpr32(fp1, fd);
8576 gen_store_fpr32h(fp0, fd);
8577 tcg_temp_free_i32(fp0);
8578 tcg_temp_free_i32(fp1);
8583 check_cp1_64bitmode(ctx);
8585 TCGv_i32 fp0 = tcg_temp_new_i32();
8586 TCGv_i32 fp1 = tcg_temp_new_i32();
8588 gen_load_fpr32h(fp0, fs);
8589 gen_load_fpr32(fp1, ft);
8590 gen_store_fpr32(fp1, fd);
8591 gen_store_fpr32h(fp0, fd);
8592 tcg_temp_free_i32(fp0);
8593 tcg_temp_free_i32(fp1);
8598 check_cp1_64bitmode(ctx);
8600 TCGv_i32 fp0 = tcg_temp_new_i32();
8601 TCGv_i32 fp1 = tcg_temp_new_i32();
8603 gen_load_fpr32h(fp0, fs);
8604 gen_load_fpr32h(fp1, ft);
8605 gen_store_fpr32(fp1, fd);
8606 gen_store_fpr32h(fp0, fd);
8607 tcg_temp_free_i32(fp0);
8608 tcg_temp_free_i32(fp1);
8615 case OPC_CMP_UEQ_PS:
8616 case OPC_CMP_OLT_PS:
8617 case OPC_CMP_ULT_PS:
8618 case OPC_CMP_OLE_PS:
8619 case OPC_CMP_ULE_PS:
8621 case OPC_CMP_NGLE_PS:
8622 case OPC_CMP_SEQ_PS:
8623 case OPC_CMP_NGL_PS:
8625 case OPC_CMP_NGE_PS:
8627 case OPC_CMP_NGT_PS:
8628 if (ctx->opcode & (1 << 6)) {
8629 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8630 opn = condnames_abs[func-48];
8632 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8633 opn = condnames[func-48];
8638 generate_exception (ctx, EXCP_RI);
8641 (void)opn; /* avoid a compiler warning */
8644 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8647 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8650 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8655 /* Coprocessor 3 (FPU) */
8656 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8657 int fd, int fs, int base, int index)
8659 const char *opn = "extended float load/store";
8661 TCGv t0 = tcg_temp_new();
8664 gen_load_gpr(t0, index);
8665 } else if (index == 0) {
8666 gen_load_gpr(t0, base);
8668 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8670 /* Don't do NOP if destination is zero: we must perform the actual
8676 TCGv_i32 fp0 = tcg_temp_new_i32();
8678 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8679 tcg_gen_trunc_tl_i32(fp0, t0);
8680 gen_store_fpr32(fp0, fd);
8681 tcg_temp_free_i32(fp0);
8687 check_cp1_registers(ctx, fd);
8689 TCGv_i64 fp0 = tcg_temp_new_i64();
8691 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8692 gen_store_fpr64(ctx, fp0, fd);
8693 tcg_temp_free_i64(fp0);
8698 check_cp1_64bitmode(ctx);
8699 tcg_gen_andi_tl(t0, t0, ~0x7);
8701 TCGv_i64 fp0 = tcg_temp_new_i64();
8703 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8704 gen_store_fpr64(ctx, fp0, fd);
8705 tcg_temp_free_i64(fp0);
8712 TCGv_i32 fp0 = tcg_temp_new_i32();
8713 TCGv t1 = tcg_temp_new();
8715 gen_load_fpr32(fp0, fs);
8716 tcg_gen_extu_i32_tl(t1, fp0);
8717 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8718 tcg_temp_free_i32(fp0);
8726 check_cp1_registers(ctx, fs);
8728 TCGv_i64 fp0 = tcg_temp_new_i64();
8730 gen_load_fpr64(ctx, fp0, fs);
8731 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8732 tcg_temp_free_i64(fp0);
8738 check_cp1_64bitmode(ctx);
8739 tcg_gen_andi_tl(t0, t0, ~0x7);
8741 TCGv_i64 fp0 = tcg_temp_new_i64();
8743 gen_load_fpr64(ctx, fp0, fs);
8744 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8745 tcg_temp_free_i64(fp0);
8752 (void)opn; (void)store; /* avoid compiler warnings */
8753 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8754 regnames[index], regnames[base]);
8757 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8758 int fd, int fr, int fs, int ft)
8760 const char *opn = "flt3_arith";
8764 check_cp1_64bitmode(ctx);
8766 TCGv t0 = tcg_temp_local_new();
8767 TCGv_i32 fp = tcg_temp_new_i32();
8768 TCGv_i32 fph = tcg_temp_new_i32();
8769 int l1 = gen_new_label();
8770 int l2 = gen_new_label();
8772 gen_load_gpr(t0, fr);
8773 tcg_gen_andi_tl(t0, t0, 0x7);
8775 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8776 gen_load_fpr32(fp, fs);
8777 gen_load_fpr32h(fph, fs);
8778 gen_store_fpr32(fp, fd);
8779 gen_store_fpr32h(fph, fd);
8782 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8784 #ifdef TARGET_WORDS_BIGENDIAN
8785 gen_load_fpr32(fp, fs);
8786 gen_load_fpr32h(fph, ft);
8787 gen_store_fpr32h(fp, fd);
8788 gen_store_fpr32(fph, fd);
8790 gen_load_fpr32h(fph, fs);
8791 gen_load_fpr32(fp, ft);
8792 gen_store_fpr32(fph, fd);
8793 gen_store_fpr32h(fp, fd);
8796 tcg_temp_free_i32(fp);
8797 tcg_temp_free_i32(fph);
8804 TCGv_i32 fp0 = tcg_temp_new_i32();
8805 TCGv_i32 fp1 = tcg_temp_new_i32();
8806 TCGv_i32 fp2 = tcg_temp_new_i32();
8808 gen_load_fpr32(fp0, fs);
8809 gen_load_fpr32(fp1, ft);
8810 gen_load_fpr32(fp2, fr);
8811 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8812 tcg_temp_free_i32(fp0);
8813 tcg_temp_free_i32(fp1);
8814 gen_store_fpr32(fp2, fd);
8815 tcg_temp_free_i32(fp2);
8821 check_cp1_registers(ctx, fd | fs | ft | fr);
8823 TCGv_i64 fp0 = tcg_temp_new_i64();
8824 TCGv_i64 fp1 = tcg_temp_new_i64();
8825 TCGv_i64 fp2 = tcg_temp_new_i64();
8827 gen_load_fpr64(ctx, fp0, fs);
8828 gen_load_fpr64(ctx, fp1, ft);
8829 gen_load_fpr64(ctx, fp2, fr);
8830 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8831 tcg_temp_free_i64(fp0);
8832 tcg_temp_free_i64(fp1);
8833 gen_store_fpr64(ctx, fp2, fd);
8834 tcg_temp_free_i64(fp2);
8839 check_cp1_64bitmode(ctx);
8841 TCGv_i64 fp0 = tcg_temp_new_i64();
8842 TCGv_i64 fp1 = tcg_temp_new_i64();
8843 TCGv_i64 fp2 = tcg_temp_new_i64();
8845 gen_load_fpr64(ctx, fp0, fs);
8846 gen_load_fpr64(ctx, fp1, ft);
8847 gen_load_fpr64(ctx, fp2, fr);
8848 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8849 tcg_temp_free_i64(fp0);
8850 tcg_temp_free_i64(fp1);
8851 gen_store_fpr64(ctx, fp2, fd);
8852 tcg_temp_free_i64(fp2);
8859 TCGv_i32 fp0 = tcg_temp_new_i32();
8860 TCGv_i32 fp1 = tcg_temp_new_i32();
8861 TCGv_i32 fp2 = tcg_temp_new_i32();
8863 gen_load_fpr32(fp0, fs);
8864 gen_load_fpr32(fp1, ft);
8865 gen_load_fpr32(fp2, fr);
8866 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8867 tcg_temp_free_i32(fp0);
8868 tcg_temp_free_i32(fp1);
8869 gen_store_fpr32(fp2, fd);
8870 tcg_temp_free_i32(fp2);
8876 check_cp1_registers(ctx, fd | fs | ft | fr);
8878 TCGv_i64 fp0 = tcg_temp_new_i64();
8879 TCGv_i64 fp1 = tcg_temp_new_i64();
8880 TCGv_i64 fp2 = tcg_temp_new_i64();
8882 gen_load_fpr64(ctx, fp0, fs);
8883 gen_load_fpr64(ctx, fp1, ft);
8884 gen_load_fpr64(ctx, fp2, fr);
8885 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8886 tcg_temp_free_i64(fp0);
8887 tcg_temp_free_i64(fp1);
8888 gen_store_fpr64(ctx, fp2, fd);
8889 tcg_temp_free_i64(fp2);
8894 check_cp1_64bitmode(ctx);
8896 TCGv_i64 fp0 = tcg_temp_new_i64();
8897 TCGv_i64 fp1 = tcg_temp_new_i64();
8898 TCGv_i64 fp2 = tcg_temp_new_i64();
8900 gen_load_fpr64(ctx, fp0, fs);
8901 gen_load_fpr64(ctx, fp1, ft);
8902 gen_load_fpr64(ctx, fp2, fr);
8903 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8904 tcg_temp_free_i64(fp0);
8905 tcg_temp_free_i64(fp1);
8906 gen_store_fpr64(ctx, fp2, fd);
8907 tcg_temp_free_i64(fp2);
8914 TCGv_i32 fp0 = tcg_temp_new_i32();
8915 TCGv_i32 fp1 = tcg_temp_new_i32();
8916 TCGv_i32 fp2 = tcg_temp_new_i32();
8918 gen_load_fpr32(fp0, fs);
8919 gen_load_fpr32(fp1, ft);
8920 gen_load_fpr32(fp2, fr);
8921 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8922 tcg_temp_free_i32(fp0);
8923 tcg_temp_free_i32(fp1);
8924 gen_store_fpr32(fp2, fd);
8925 tcg_temp_free_i32(fp2);
8931 check_cp1_registers(ctx, fd | fs | ft | fr);
8933 TCGv_i64 fp0 = tcg_temp_new_i64();
8934 TCGv_i64 fp1 = tcg_temp_new_i64();
8935 TCGv_i64 fp2 = tcg_temp_new_i64();
8937 gen_load_fpr64(ctx, fp0, fs);
8938 gen_load_fpr64(ctx, fp1, ft);
8939 gen_load_fpr64(ctx, fp2, fr);
8940 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8941 tcg_temp_free_i64(fp0);
8942 tcg_temp_free_i64(fp1);
8943 gen_store_fpr64(ctx, fp2, fd);
8944 tcg_temp_free_i64(fp2);
8949 check_cp1_64bitmode(ctx);
8951 TCGv_i64 fp0 = tcg_temp_new_i64();
8952 TCGv_i64 fp1 = tcg_temp_new_i64();
8953 TCGv_i64 fp2 = tcg_temp_new_i64();
8955 gen_load_fpr64(ctx, fp0, fs);
8956 gen_load_fpr64(ctx, fp1, ft);
8957 gen_load_fpr64(ctx, fp2, fr);
8958 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8959 tcg_temp_free_i64(fp0);
8960 tcg_temp_free_i64(fp1);
8961 gen_store_fpr64(ctx, fp2, fd);
8962 tcg_temp_free_i64(fp2);
8969 TCGv_i32 fp0 = tcg_temp_new_i32();
8970 TCGv_i32 fp1 = tcg_temp_new_i32();
8971 TCGv_i32 fp2 = tcg_temp_new_i32();
8973 gen_load_fpr32(fp0, fs);
8974 gen_load_fpr32(fp1, ft);
8975 gen_load_fpr32(fp2, fr);
8976 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8977 tcg_temp_free_i32(fp0);
8978 tcg_temp_free_i32(fp1);
8979 gen_store_fpr32(fp2, fd);
8980 tcg_temp_free_i32(fp2);
8986 check_cp1_registers(ctx, fd | fs | ft | fr);
8988 TCGv_i64 fp0 = tcg_temp_new_i64();
8989 TCGv_i64 fp1 = tcg_temp_new_i64();
8990 TCGv_i64 fp2 = tcg_temp_new_i64();
8992 gen_load_fpr64(ctx, fp0, fs);
8993 gen_load_fpr64(ctx, fp1, ft);
8994 gen_load_fpr64(ctx, fp2, fr);
8995 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
8996 tcg_temp_free_i64(fp0);
8997 tcg_temp_free_i64(fp1);
8998 gen_store_fpr64(ctx, fp2, fd);
8999 tcg_temp_free_i64(fp2);
9004 check_cp1_64bitmode(ctx);
9006 TCGv_i64 fp0 = tcg_temp_new_i64();
9007 TCGv_i64 fp1 = tcg_temp_new_i64();
9008 TCGv_i64 fp2 = tcg_temp_new_i64();
9010 gen_load_fpr64(ctx, fp0, fs);
9011 gen_load_fpr64(ctx, fp1, ft);
9012 gen_load_fpr64(ctx, fp2, fr);
9013 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9014 tcg_temp_free_i64(fp0);
9015 tcg_temp_free_i64(fp1);
9016 gen_store_fpr64(ctx, fp2, fd);
9017 tcg_temp_free_i64(fp2);
9023 generate_exception (ctx, EXCP_RI);
9026 (void)opn; /* avoid a compiler warning */
9027 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9028 fregnames[fs], fregnames[ft]);
9032 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9036 #if !defined(CONFIG_USER_ONLY)
9037 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9038 Therefore only check the ISA in system mode. */
9039 check_insn(env, ctx, ISA_MIPS32R2);
9041 t0 = tcg_temp_new();
9045 save_cpu_state(ctx, 1);
9046 gen_helper_rdhwr_cpunum(t0, cpu_env);
9047 gen_store_gpr(t0, rt);
9050 save_cpu_state(ctx, 1);
9051 gen_helper_rdhwr_synci_step(t0, cpu_env);
9052 gen_store_gpr(t0, rt);
9055 save_cpu_state(ctx, 1);
9056 gen_helper_rdhwr_cc(t0, cpu_env);
9057 gen_store_gpr(t0, rt);
9060 save_cpu_state(ctx, 1);
9061 gen_helper_rdhwr_ccres(t0, cpu_env);
9062 gen_store_gpr(t0, rt);
9065 #if defined(CONFIG_USER_ONLY)
9066 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9067 gen_store_gpr(t0, rt);
9070 /* XXX: Some CPUs implement this in hardware.
9071 Not supported yet. */
9073 default: /* Invalid */
9074 MIPS_INVAL("rdhwr");
9075 generate_exception(ctx, EXCP_RI);
9081 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9084 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9085 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9086 /* Branches completion */
9087 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9088 ctx->bstate = BS_BRANCH;
9089 save_cpu_state(ctx, 0);
9090 /* FIXME: Need to clear can_do_io. */
9091 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9093 /* unconditional branch */
9094 MIPS_DEBUG("unconditional branch");
9095 if (proc_hflags & MIPS_HFLAG_BX) {
9096 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9098 gen_goto_tb(ctx, 0, ctx->btarget);
9101 /* blikely taken case */
9102 MIPS_DEBUG("blikely branch taken");
9103 gen_goto_tb(ctx, 0, ctx->btarget);
9106 /* Conditional branch */
9107 MIPS_DEBUG("conditional branch");
9109 int l1 = gen_new_label();
9111 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9112 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9114 gen_goto_tb(ctx, 0, ctx->btarget);
9118 /* unconditional branch to register */
9119 MIPS_DEBUG("branch to register");
9120 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9121 TCGv t0 = tcg_temp_new();
9122 TCGv_i32 t1 = tcg_temp_new_i32();
9124 tcg_gen_andi_tl(t0, btarget, 0x1);
9125 tcg_gen_trunc_tl_i32(t1, t0);
9127 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9128 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9129 tcg_gen_or_i32(hflags, hflags, t1);
9130 tcg_temp_free_i32(t1);
9132 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9134 tcg_gen_mov_tl(cpu_PC, btarget);
9136 if (ctx->singlestep_enabled) {
9137 save_cpu_state(ctx, 0);
9138 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9143 MIPS_DEBUG("unknown branch");
9149 /* ISA extensions (ASEs) */
9150 /* MIPS16 extension to MIPS32 */
9152 /* MIPS16 major opcodes */
9154 M16_OPC_ADDIUSP = 0x00,
9155 M16_OPC_ADDIUPC = 0x01,
9158 M16_OPC_BEQZ = 0x04,
9159 M16_OPC_BNEQZ = 0x05,
9160 M16_OPC_SHIFT = 0x06,
9162 M16_OPC_RRIA = 0x08,
9163 M16_OPC_ADDIU8 = 0x09,
9164 M16_OPC_SLTI = 0x0a,
9165 M16_OPC_SLTIU = 0x0b,
9168 M16_OPC_CMPI = 0x0e,
9172 M16_OPC_LWSP = 0x12,
9176 M16_OPC_LWPC = 0x16,
9180 M16_OPC_SWSP = 0x1a,
9184 M16_OPC_EXTEND = 0x1e,
9188 /* I8 funct field */
9207 /* RR funct field */
9241 /* I64 funct field */
9253 /* RR ry field for CNVT */
9255 RR_RY_CNVT_ZEB = 0x0,
9256 RR_RY_CNVT_ZEH = 0x1,
9257 RR_RY_CNVT_ZEW = 0x2,
9258 RR_RY_CNVT_SEB = 0x4,
9259 RR_RY_CNVT_SEH = 0x5,
9260 RR_RY_CNVT_SEW = 0x6,
9263 static int xlat (int r)
9265 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9270 static void gen_mips16_save (DisasContext *ctx,
9271 int xsregs, int aregs,
9272 int do_ra, int do_s0, int do_s1,
9275 TCGv t0 = tcg_temp_new();
9276 TCGv t1 = tcg_temp_new();
9306 generate_exception(ctx, EXCP_RI);
9312 gen_base_offset_addr(ctx, t0, 29, 12);
9313 gen_load_gpr(t1, 7);
9314 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9317 gen_base_offset_addr(ctx, t0, 29, 8);
9318 gen_load_gpr(t1, 6);
9319 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9322 gen_base_offset_addr(ctx, t0, 29, 4);
9323 gen_load_gpr(t1, 5);
9324 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9327 gen_base_offset_addr(ctx, t0, 29, 0);
9328 gen_load_gpr(t1, 4);
9329 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9332 gen_load_gpr(t0, 29);
9334 #define DECR_AND_STORE(reg) do { \
9335 tcg_gen_subi_tl(t0, t0, 4); \
9336 gen_load_gpr(t1, reg); \
9337 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9401 generate_exception(ctx, EXCP_RI);
9417 #undef DECR_AND_STORE
9419 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9424 static void gen_mips16_restore (DisasContext *ctx,
9425 int xsregs, int aregs,
9426 int do_ra, int do_s0, int do_s1,
9430 TCGv t0 = tcg_temp_new();
9431 TCGv t1 = tcg_temp_new();
9433 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9435 #define DECR_AND_LOAD(reg) do { \
9436 tcg_gen_subi_tl(t0, t0, 4); \
9437 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9438 gen_store_gpr(t1, reg); \
9502 generate_exception(ctx, EXCP_RI);
9518 #undef DECR_AND_LOAD
9520 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9525 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9526 int is_64_bit, int extended)
9530 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9531 generate_exception(ctx, EXCP_RI);
9535 t0 = tcg_temp_new();
9537 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9538 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9540 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9546 #if defined(TARGET_MIPS64)
9547 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9548 int ry, int funct, int16_t offset,
9554 offset = extended ? offset : offset << 3;
9555 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9559 offset = extended ? offset : offset << 3;
9560 gen_st(ctx, OPC_SD, ry, 29, offset);
9564 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9565 gen_st(ctx, OPC_SD, 31, 29, offset);
9569 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9570 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9573 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9574 generate_exception(ctx, EXCP_RI);
9576 offset = extended ? offset : offset << 3;
9577 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9582 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9583 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9587 offset = extended ? offset : offset << 2;
9588 gen_addiupc(ctx, ry, offset, 1, extended);
9592 offset = extended ? offset : offset << 2;
9593 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9599 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9602 int extend = cpu_lduw_code(env, ctx->pc + 2);
9603 int op, rx, ry, funct, sa;
9604 int16_t imm, offset;
9606 ctx->opcode = (ctx->opcode << 16) | extend;
9607 op = (ctx->opcode >> 11) & 0x1f;
9608 sa = (ctx->opcode >> 22) & 0x1f;
9609 funct = (ctx->opcode >> 8) & 0x7;
9610 rx = xlat((ctx->opcode >> 8) & 0x7);
9611 ry = xlat((ctx->opcode >> 5) & 0x7);
9612 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9613 | ((ctx->opcode >> 21) & 0x3f) << 5
9614 | (ctx->opcode & 0x1f));
9616 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9619 case M16_OPC_ADDIUSP:
9620 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9622 case M16_OPC_ADDIUPC:
9623 gen_addiupc(ctx, rx, imm, 0, 1);
9626 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9627 /* No delay slot, so just process as a normal instruction */
9630 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9631 /* No delay slot, so just process as a normal instruction */
9634 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9635 /* No delay slot, so just process as a normal instruction */
9638 switch (ctx->opcode & 0x3) {
9640 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9643 #if defined(TARGET_MIPS64)
9645 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9647 generate_exception(ctx, EXCP_RI);
9651 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9654 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9658 #if defined(TARGET_MIPS64)
9661 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9665 imm = ctx->opcode & 0xf;
9666 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9667 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9668 imm = (int16_t) (imm << 1) >> 1;
9669 if ((ctx->opcode >> 4) & 0x1) {
9670 #if defined(TARGET_MIPS64)
9672 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9674 generate_exception(ctx, EXCP_RI);
9677 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9680 case M16_OPC_ADDIU8:
9681 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9684 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9687 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9692 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9695 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9698 gen_st(ctx, OPC_SW, 31, 29, imm);
9701 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9705 int xsregs = (ctx->opcode >> 24) & 0x7;
9706 int aregs = (ctx->opcode >> 16) & 0xf;
9707 int do_ra = (ctx->opcode >> 6) & 0x1;
9708 int do_s0 = (ctx->opcode >> 5) & 0x1;
9709 int do_s1 = (ctx->opcode >> 4) & 0x1;
9710 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9711 | (ctx->opcode & 0xf)) << 3;
9713 if (ctx->opcode & (1 << 7)) {
9714 gen_mips16_save(ctx, xsregs, aregs,
9715 do_ra, do_s0, do_s1,
9718 gen_mips16_restore(ctx, xsregs, aregs,
9719 do_ra, do_s0, do_s1,
9725 generate_exception(ctx, EXCP_RI);
9730 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9733 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9735 #if defined(TARGET_MIPS64)
9737 gen_st(ctx, OPC_SD, ry, rx, offset);
9741 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9744 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9747 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9750 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9753 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9756 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9759 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9761 #if defined(TARGET_MIPS64)
9763 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9767 gen_st(ctx, OPC_SB, ry, rx, offset);
9770 gen_st(ctx, OPC_SH, ry, rx, offset);
9773 gen_st(ctx, OPC_SW, rx, 29, offset);
9776 gen_st(ctx, OPC_SW, ry, rx, offset);
9778 #if defined(TARGET_MIPS64)
9780 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9784 generate_exception(ctx, EXCP_RI);
9791 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9796 int op, cnvt_op, op1, offset;
9800 op = (ctx->opcode >> 11) & 0x1f;
9801 sa = (ctx->opcode >> 2) & 0x7;
9802 sa = sa == 0 ? 8 : sa;
9803 rx = xlat((ctx->opcode >> 8) & 0x7);
9804 cnvt_op = (ctx->opcode >> 5) & 0x7;
9805 ry = xlat((ctx->opcode >> 5) & 0x7);
9806 op1 = offset = ctx->opcode & 0x1f;
9811 case M16_OPC_ADDIUSP:
9813 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9815 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9818 case M16_OPC_ADDIUPC:
9819 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9822 offset = (ctx->opcode & 0x7ff) << 1;
9823 offset = (int16_t)(offset << 4) >> 4;
9824 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9825 /* No delay slot, so just process as a normal instruction */
9828 offset = cpu_lduw_code(env, ctx->pc + 2);
9829 offset = (((ctx->opcode & 0x1f) << 21)
9830 | ((ctx->opcode >> 5) & 0x1f) << 16
9832 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9833 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9838 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9839 /* No delay slot, so just process as a normal instruction */
9842 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9843 /* No delay slot, so just process as a normal instruction */
9846 switch (ctx->opcode & 0x3) {
9848 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9851 #if defined(TARGET_MIPS64)
9853 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9855 generate_exception(ctx, EXCP_RI);
9859 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9862 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9866 #if defined(TARGET_MIPS64)
9869 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9874 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9876 if ((ctx->opcode >> 4) & 1) {
9877 #if defined(TARGET_MIPS64)
9879 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9881 generate_exception(ctx, EXCP_RI);
9884 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9888 case M16_OPC_ADDIU8:
9890 int16_t imm = (int8_t) ctx->opcode;
9892 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9897 int16_t imm = (uint8_t) ctx->opcode;
9898 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9903 int16_t imm = (uint8_t) ctx->opcode;
9904 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9911 funct = (ctx->opcode >> 8) & 0x7;
9914 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9915 ((int8_t)ctx->opcode) << 1);
9918 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9919 ((int8_t)ctx->opcode) << 1);
9922 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9925 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9926 ((int8_t)ctx->opcode) << 3);
9930 int do_ra = ctx->opcode & (1 << 6);
9931 int do_s0 = ctx->opcode & (1 << 5);
9932 int do_s1 = ctx->opcode & (1 << 4);
9933 int framesize = ctx->opcode & 0xf;
9935 if (framesize == 0) {
9938 framesize = framesize << 3;
9941 if (ctx->opcode & (1 << 7)) {
9942 gen_mips16_save(ctx, 0, 0,
9943 do_ra, do_s0, do_s1, framesize);
9945 gen_mips16_restore(ctx, 0, 0,
9946 do_ra, do_s0, do_s1, framesize);
9952 int rz = xlat(ctx->opcode & 0x7);
9954 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9955 ((ctx->opcode >> 5) & 0x7);
9956 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9960 reg32 = ctx->opcode & 0x1f;
9961 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9964 generate_exception(ctx, EXCP_RI);
9971 int16_t imm = (uint8_t) ctx->opcode;
9973 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9978 int16_t imm = (uint8_t) ctx->opcode;
9979 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
9982 #if defined(TARGET_MIPS64)
9985 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9989 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9992 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9995 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9998 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10001 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10004 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10007 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10009 #if defined (TARGET_MIPS64)
10011 check_mips_64(ctx);
10012 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10016 gen_st(ctx, OPC_SB, ry, rx, offset);
10019 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10022 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10025 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10029 int rz = xlat((ctx->opcode >> 2) & 0x7);
10032 switch (ctx->opcode & 0x3) {
10034 mips32_op = OPC_ADDU;
10037 mips32_op = OPC_SUBU;
10039 #if defined(TARGET_MIPS64)
10041 mips32_op = OPC_DADDU;
10042 check_mips_64(ctx);
10045 mips32_op = OPC_DSUBU;
10046 check_mips_64(ctx);
10050 generate_exception(ctx, EXCP_RI);
10054 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10063 int nd = (ctx->opcode >> 7) & 0x1;
10064 int link = (ctx->opcode >> 6) & 0x1;
10065 int ra = (ctx->opcode >> 5) & 0x1;
10068 op = nd ? OPC_JALRC : OPC_JALRS;
10073 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10080 /* XXX: not clear which exception should be raised
10081 * when in debug mode...
10083 check_insn(env, ctx, ISA_MIPS32);
10084 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10085 generate_exception(ctx, EXCP_DBp);
10087 generate_exception(ctx, EXCP_DBp);
10091 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10094 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10097 generate_exception(ctx, EXCP_BREAK);
10100 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10103 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10106 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10108 #if defined (TARGET_MIPS64)
10110 check_mips_64(ctx);
10111 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10115 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10118 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10121 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10124 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10127 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10130 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10133 gen_HILO(ctx, OPC_MFHI, rx);
10137 case RR_RY_CNVT_ZEB:
10138 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10140 case RR_RY_CNVT_ZEH:
10141 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10143 case RR_RY_CNVT_SEB:
10144 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10146 case RR_RY_CNVT_SEH:
10147 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10149 #if defined (TARGET_MIPS64)
10150 case RR_RY_CNVT_ZEW:
10151 check_mips_64(ctx);
10152 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10154 case RR_RY_CNVT_SEW:
10155 check_mips_64(ctx);
10156 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10160 generate_exception(ctx, EXCP_RI);
10165 gen_HILO(ctx, OPC_MFLO, rx);
10167 #if defined (TARGET_MIPS64)
10169 check_mips_64(ctx);
10170 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10173 check_mips_64(ctx);
10174 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10177 check_mips_64(ctx);
10178 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10181 check_mips_64(ctx);
10182 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10186 gen_muldiv(ctx, OPC_MULT, rx, ry);
10189 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10192 gen_muldiv(ctx, OPC_DIV, rx, ry);
10195 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10197 #if defined (TARGET_MIPS64)
10199 check_mips_64(ctx);
10200 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10203 check_mips_64(ctx);
10204 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10207 check_mips_64(ctx);
10208 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10211 check_mips_64(ctx);
10212 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10216 generate_exception(ctx, EXCP_RI);
10220 case M16_OPC_EXTEND:
10221 decode_extended_mips16_opc(env, ctx, is_branch);
10224 #if defined(TARGET_MIPS64)
10226 funct = (ctx->opcode >> 8) & 0x7;
10227 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10231 generate_exception(ctx, EXCP_RI);
10238 /* microMIPS extension to MIPS32 */
10240 /* microMIPS32 major opcodes */
10279 /* 0x20 is reserved */
10289 /* 0x28 and 0x29 are reserved */
10299 /* 0x30 and 0x31 are reserved */
10309 /* 0x38 and 0x39 are reserved */
10320 /* POOL32A encoding of minor opcode field */
10323 /* These opcodes are distinguished only by bits 9..6; those bits are
10324 * what are recorded below. */
10350 /* The following can be distinguished by their lower 6 bits. */
10356 /* POOL32AXF encoding of minor opcode field extension */
10370 /* bits 13..12 for 0x01 */
10376 /* bits 13..12 for 0x2a */
10382 /* bits 13..12 for 0x32 */
10386 /* bits 15..12 for 0x2c */
10402 /* bits 15..12 for 0x34 */
10410 /* bits 15..12 for 0x3c */
10412 JR = 0x0, /* alias */
10417 /* bits 15..12 for 0x05 */
10421 /* bits 15..12 for 0x0d */
10431 /* bits 15..12 for 0x15 */
10437 /* bits 15..12 for 0x1d */
10441 /* bits 15..12 for 0x2d */
10446 /* bits 15..12 for 0x35 */
10453 /* POOL32B encoding of minor opcode field (bits 15..12) */
10469 /* POOL32C encoding of minor opcode field (bits 15..12) */
10477 /* 0xa is reserved */
10484 /* 0x6 is reserved */
10490 /* POOL32F encoding of minor opcode field (bits 5..0) */
10493 /* These are the bit 7..6 values */
10504 /* These are the bit 8..6 values */
10548 CABS_COND_FMT = 0x1c, /* MIPS3D */
10552 /* POOL32Fxf encoding of minor opcode extension field */
10590 /* POOL32I encoding of minor opcode field (bits 25..21) */
10615 /* These overlap and are distinguished by bit16 of the instruction */
10624 /* POOL16A encoding of minor opcode field */
10631 /* POOL16B encoding of minor opcode field */
10638 /* POOL16C encoding of minor opcode field */
10658 /* POOL16D encoding of minor opcode field */
10665 /* POOL16E encoding of minor opcode field */
10672 static int mmreg (int r)
10674 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10679 /* Used for 16-bit store instructions. */
10680 static int mmreg2 (int r)
10682 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10687 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10688 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10689 #define uMIPS_RS2(op) uMIPS_RS(op)
10690 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10691 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10692 #define uMIPS_RS5(op) (op & 0x1f)
10694 /* Signed immediate */
10695 #define SIMM(op, start, width) \
10696 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10699 /* Zero-extended immediate */
10700 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10702 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10704 int rd = mmreg(uMIPS_RD(ctx->opcode));
10706 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10709 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10711 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10712 int rd = mmreg(uMIPS_RD(ctx->opcode));
10713 int rs = mmreg(uMIPS_RS(ctx->opcode));
10715 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10718 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10720 int encoded = ZIMM(ctx->opcode, 1, 9);
10723 if (encoded <= 1) {
10724 decoded = 256 + encoded;
10725 } else if (encoded <= 255) {
10727 } else if (encoded <= 509) {
10728 decoded = encoded - 512;
10730 decoded = encoded - 768;
10733 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10736 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10738 int imm = SIMM(ctx->opcode, 1, 4);
10739 int rd = (ctx->opcode >> 5) & 0x1f;
10741 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10744 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10746 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10747 31, 32, 63, 64, 255, 32768, 65535 };
10748 int rd = mmreg(uMIPS_RD(ctx->opcode));
10749 int rs = mmreg(uMIPS_RS(ctx->opcode));
10750 int encoded = ZIMM(ctx->opcode, 0, 4);
10752 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10755 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10756 int base, int16_t offset)
10758 const char *opn = "ldst_multiple";
10762 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10763 generate_exception(ctx, EXCP_RI);
10767 t0 = tcg_temp_new();
10769 gen_base_offset_addr(ctx, t0, base, offset);
10771 t1 = tcg_const_tl(reglist);
10772 t2 = tcg_const_i32(ctx->mem_idx);
10774 save_cpu_state(ctx, 1);
10777 gen_helper_lwm(cpu_env, t0, t1, t2);
10781 gen_helper_swm(cpu_env, t0, t1, t2);
10784 #ifdef TARGET_MIPS64
10786 gen_helper_ldm(cpu_env, t0, t1, t2);
10790 gen_helper_sdm(cpu_env, t0, t1, t2);
10796 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10799 tcg_temp_free_i32(t2);
10803 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10805 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10806 int rs = mmreg(ctx->opcode & 0x7);
10809 switch (((ctx->opcode) >> 4) & 0x3f) {
10814 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10820 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10826 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10832 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10839 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10840 int offset = ZIMM(ctx->opcode, 0, 4);
10842 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10851 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10852 int offset = ZIMM(ctx->opcode, 0, 4);
10854 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10861 int reg = ctx->opcode & 0x1f;
10863 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10870 int reg = ctx->opcode & 0x1f;
10872 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10873 /* Let normal delay slot handling in our caller take us
10874 to the branch target. */
10886 int reg = ctx->opcode & 0x1f;
10888 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10894 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10898 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10901 generate_exception(ctx, EXCP_BREAK);
10904 /* XXX: not clear which exception should be raised
10905 * when in debug mode...
10907 check_insn(env, ctx, ISA_MIPS32);
10908 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10909 generate_exception(ctx, EXCP_DBp);
10911 generate_exception(ctx, EXCP_DBp);
10914 case JRADDIUSP + 0:
10915 case JRADDIUSP + 1:
10917 int imm = ZIMM(ctx->opcode, 0, 5);
10919 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10920 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10921 /* Let normal delay slot handling in our caller take us
10922 to the branch target. */
10926 generate_exception(ctx, EXCP_RI);
10931 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10933 TCGv t0 = tcg_temp_new();
10934 TCGv t1 = tcg_temp_new();
10936 gen_load_gpr(t0, base);
10939 gen_load_gpr(t1, index);
10940 tcg_gen_shli_tl(t1, t1, 2);
10941 gen_op_addr_add(ctx, t0, t1, t0);
10944 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10945 gen_store_gpr(t1, rd);
10951 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10952 int base, int16_t offset)
10954 const char *opn = "ldst_pair";
10957 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10958 generate_exception(ctx, EXCP_RI);
10962 t0 = tcg_temp_new();
10963 t1 = tcg_temp_new();
10965 gen_base_offset_addr(ctx, t0, base, offset);
10970 generate_exception(ctx, EXCP_RI);
10973 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10974 gen_store_gpr(t1, rd);
10975 tcg_gen_movi_tl(t1, 4);
10976 gen_op_addr_add(ctx, t0, t0, t1);
10977 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10978 gen_store_gpr(t1, rd+1);
10982 gen_load_gpr(t1, rd);
10983 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10984 tcg_gen_movi_tl(t1, 4);
10985 gen_op_addr_add(ctx, t0, t0, t1);
10986 gen_load_gpr(t1, rd+1);
10987 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10990 #ifdef TARGET_MIPS64
10993 generate_exception(ctx, EXCP_RI);
10996 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
10997 gen_store_gpr(t1, rd);
10998 tcg_gen_movi_tl(t1, 8);
10999 gen_op_addr_add(ctx, t0, t0, t1);
11000 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11001 gen_store_gpr(t1, rd+1);
11005 gen_load_gpr(t1, rd);
11006 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11007 tcg_gen_movi_tl(t1, 8);
11008 gen_op_addr_add(ctx, t0, t0, t1);
11009 gen_load_gpr(t1, rd+1);
11010 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11015 (void)opn; /* avoid a compiler warning */
11016 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11021 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11024 int extension = (ctx->opcode >> 6) & 0x3f;
11025 int minor = (ctx->opcode >> 12) & 0xf;
11026 uint32_t mips32_op;
11028 switch (extension) {
11030 mips32_op = OPC_TEQ;
11033 mips32_op = OPC_TGE;
11036 mips32_op = OPC_TGEU;
11039 mips32_op = OPC_TLT;
11042 mips32_op = OPC_TLTU;
11045 mips32_op = OPC_TNE;
11047 gen_trap(ctx, mips32_op, rs, rt, -1);
11049 #ifndef CONFIG_USER_ONLY
11052 check_cp0_enabled(ctx);
11054 /* Treat as NOP. */
11057 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11061 check_cp0_enabled(ctx);
11063 TCGv t0 = tcg_temp_new();
11065 gen_load_gpr(t0, rt);
11066 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11074 gen_bshfl(ctx, OPC_SEB, rs, rt);
11077 gen_bshfl(ctx, OPC_SEH, rs, rt);
11080 mips32_op = OPC_CLO;
11083 mips32_op = OPC_CLZ;
11085 check_insn(env, ctx, ISA_MIPS32);
11086 gen_cl(ctx, mips32_op, rt, rs);
11089 gen_rdhwr(env, ctx, rt, rs);
11092 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11095 mips32_op = OPC_MULT;
11098 mips32_op = OPC_MULTU;
11101 mips32_op = OPC_DIV;
11104 mips32_op = OPC_DIVU;
11107 mips32_op = OPC_MADD;
11110 mips32_op = OPC_MADDU;
11113 mips32_op = OPC_MSUB;
11116 mips32_op = OPC_MSUBU;
11118 check_insn(env, ctx, ISA_MIPS32);
11119 gen_muldiv(ctx, mips32_op, rs, rt);
11122 goto pool32axf_invalid;
11133 generate_exception_err(ctx, EXCP_CpU, 2);
11136 goto pool32axf_invalid;
11143 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11148 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11152 goto pool32axf_invalid;
11158 check_cp0_enabled(ctx);
11159 check_insn(env, ctx, ISA_MIPS32R2);
11160 gen_load_srsgpr(rt, rs);
11163 check_cp0_enabled(ctx);
11164 check_insn(env, ctx, ISA_MIPS32R2);
11165 gen_store_srsgpr(rt, rs);
11168 goto pool32axf_invalid;
11171 #ifndef CONFIG_USER_ONLY
11175 mips32_op = OPC_TLBP;
11178 mips32_op = OPC_TLBR;
11181 mips32_op = OPC_TLBWI;
11184 mips32_op = OPC_TLBWR;
11187 mips32_op = OPC_WAIT;
11190 mips32_op = OPC_DERET;
11193 mips32_op = OPC_ERET;
11195 gen_cp0(env, ctx, mips32_op, rt, rs);
11198 goto pool32axf_invalid;
11204 check_cp0_enabled(ctx);
11206 TCGv t0 = tcg_temp_new();
11208 save_cpu_state(ctx, 1);
11209 gen_helper_di(t0, cpu_env);
11210 gen_store_gpr(t0, rs);
11211 /* Stop translation as we may have switched the execution mode */
11212 ctx->bstate = BS_STOP;
11217 check_cp0_enabled(ctx);
11219 TCGv t0 = tcg_temp_new();
11221 save_cpu_state(ctx, 1);
11222 gen_helper_ei(t0, cpu_env);
11223 gen_store_gpr(t0, rs);
11224 /* Stop translation as we may have switched the execution mode */
11225 ctx->bstate = BS_STOP;
11230 goto pool32axf_invalid;
11240 generate_exception(ctx, EXCP_SYSCALL);
11241 ctx->bstate = BS_STOP;
11244 check_insn(env, ctx, ISA_MIPS32);
11245 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11246 generate_exception(ctx, EXCP_DBp);
11248 generate_exception(ctx, EXCP_DBp);
11252 goto pool32axf_invalid;
11258 gen_HILO(ctx, OPC_MFHI, rs);
11261 gen_HILO(ctx, OPC_MFLO, rs);
11264 gen_HILO(ctx, OPC_MTHI, rs);
11267 gen_HILO(ctx, OPC_MTLO, rs);
11270 goto pool32axf_invalid;
11275 MIPS_INVAL("pool32axf");
11276 generate_exception(ctx, EXCP_RI);
11281 /* Values for microMIPS fmt field. Variable-width, depending on which
11282 formats the instruction supports. */
11301 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11303 int extension = (ctx->opcode >> 6) & 0x3ff;
11304 uint32_t mips32_op;
11306 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11307 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11308 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11310 switch (extension) {
11311 case FLOAT_1BIT_FMT(CFC1, 0):
11312 mips32_op = OPC_CFC1;
11314 case FLOAT_1BIT_FMT(CTC1, 0):
11315 mips32_op = OPC_CTC1;
11317 case FLOAT_1BIT_FMT(MFC1, 0):
11318 mips32_op = OPC_MFC1;
11320 case FLOAT_1BIT_FMT(MTC1, 0):
11321 mips32_op = OPC_MTC1;
11323 case FLOAT_1BIT_FMT(MFHC1, 0):
11324 mips32_op = OPC_MFHC1;
11326 case FLOAT_1BIT_FMT(MTHC1, 0):
11327 mips32_op = OPC_MTHC1;
11329 gen_cp1(ctx, mips32_op, rt, rs);
11332 /* Reciprocal square root */
11333 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11334 mips32_op = OPC_RSQRT_S;
11336 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11337 mips32_op = OPC_RSQRT_D;
11341 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11342 mips32_op = OPC_SQRT_S;
11344 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11345 mips32_op = OPC_SQRT_D;
11349 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11350 mips32_op = OPC_RECIP_S;
11352 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11353 mips32_op = OPC_RECIP_D;
11357 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11358 mips32_op = OPC_FLOOR_L_S;
11360 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11361 mips32_op = OPC_FLOOR_L_D;
11363 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11364 mips32_op = OPC_FLOOR_W_S;
11366 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11367 mips32_op = OPC_FLOOR_W_D;
11371 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11372 mips32_op = OPC_CEIL_L_S;
11374 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11375 mips32_op = OPC_CEIL_L_D;
11377 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11378 mips32_op = OPC_CEIL_W_S;
11380 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11381 mips32_op = OPC_CEIL_W_D;
11385 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11386 mips32_op = OPC_TRUNC_L_S;
11388 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11389 mips32_op = OPC_TRUNC_L_D;
11391 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11392 mips32_op = OPC_TRUNC_W_S;
11394 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11395 mips32_op = OPC_TRUNC_W_D;
11399 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11400 mips32_op = OPC_ROUND_L_S;
11402 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11403 mips32_op = OPC_ROUND_L_D;
11405 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11406 mips32_op = OPC_ROUND_W_S;
11408 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11409 mips32_op = OPC_ROUND_W_D;
11412 /* Integer to floating-point conversion */
11413 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11414 mips32_op = OPC_CVT_L_S;
11416 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11417 mips32_op = OPC_CVT_L_D;
11419 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11420 mips32_op = OPC_CVT_W_S;
11422 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11423 mips32_op = OPC_CVT_W_D;
11426 /* Paired-foo conversions */
11427 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11428 mips32_op = OPC_CVT_S_PL;
11430 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11431 mips32_op = OPC_CVT_S_PU;
11433 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11434 mips32_op = OPC_CVT_PW_PS;
11436 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11437 mips32_op = OPC_CVT_PS_PW;
11440 /* Floating-point moves */
11441 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11442 mips32_op = OPC_MOV_S;
11444 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11445 mips32_op = OPC_MOV_D;
11447 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11448 mips32_op = OPC_MOV_PS;
11451 /* Absolute value */
11452 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11453 mips32_op = OPC_ABS_S;
11455 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11456 mips32_op = OPC_ABS_D;
11458 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11459 mips32_op = OPC_ABS_PS;
11463 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11464 mips32_op = OPC_NEG_S;
11466 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11467 mips32_op = OPC_NEG_D;
11469 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11470 mips32_op = OPC_NEG_PS;
11473 /* Reciprocal square root step */
11474 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11475 mips32_op = OPC_RSQRT1_S;
11477 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11478 mips32_op = OPC_RSQRT1_D;
11480 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11481 mips32_op = OPC_RSQRT1_PS;
11484 /* Reciprocal step */
11485 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11486 mips32_op = OPC_RECIP1_S;
11488 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11489 mips32_op = OPC_RECIP1_S;
11491 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11492 mips32_op = OPC_RECIP1_PS;
11495 /* Conversions from double */
11496 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11497 mips32_op = OPC_CVT_D_S;
11499 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11500 mips32_op = OPC_CVT_D_W;
11502 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11503 mips32_op = OPC_CVT_D_L;
11506 /* Conversions from single */
11507 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11508 mips32_op = OPC_CVT_S_D;
11510 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11511 mips32_op = OPC_CVT_S_W;
11513 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11514 mips32_op = OPC_CVT_S_L;
11516 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11519 /* Conditional moves on floating-point codes */
11520 case COND_FLOAT_MOV(MOVT, 0):
11521 case COND_FLOAT_MOV(MOVT, 1):
11522 case COND_FLOAT_MOV(MOVT, 2):
11523 case COND_FLOAT_MOV(MOVT, 3):
11524 case COND_FLOAT_MOV(MOVT, 4):
11525 case COND_FLOAT_MOV(MOVT, 5):
11526 case COND_FLOAT_MOV(MOVT, 6):
11527 case COND_FLOAT_MOV(MOVT, 7):
11528 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11530 case COND_FLOAT_MOV(MOVF, 0):
11531 case COND_FLOAT_MOV(MOVF, 1):
11532 case COND_FLOAT_MOV(MOVF, 2):
11533 case COND_FLOAT_MOV(MOVF, 3):
11534 case COND_FLOAT_MOV(MOVF, 4):
11535 case COND_FLOAT_MOV(MOVF, 5):
11536 case COND_FLOAT_MOV(MOVF, 6):
11537 case COND_FLOAT_MOV(MOVF, 7):
11538 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11541 MIPS_INVAL("pool32fxf");
11542 generate_exception(ctx, EXCP_RI);
11547 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11548 uint16_t insn_hw1, int *is_branch)
11552 int rt, rs, rd, rr;
11554 uint32_t op, minor, mips32_op;
11555 uint32_t cond, fmt, cc;
11557 insn = cpu_lduw_code(env, ctx->pc + 2);
11558 ctx->opcode = (ctx->opcode << 16) | insn;
11560 rt = (ctx->opcode >> 21) & 0x1f;
11561 rs = (ctx->opcode >> 16) & 0x1f;
11562 rd = (ctx->opcode >> 11) & 0x1f;
11563 rr = (ctx->opcode >> 6) & 0x1f;
11564 imm = (int16_t) ctx->opcode;
11566 op = (ctx->opcode >> 26) & 0x3f;
11569 minor = ctx->opcode & 0x3f;
11572 minor = (ctx->opcode >> 6) & 0xf;
11575 mips32_op = OPC_SLL;
11578 mips32_op = OPC_SRA;
11581 mips32_op = OPC_SRL;
11584 mips32_op = OPC_ROTR;
11586 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11589 goto pool32a_invalid;
11593 minor = (ctx->opcode >> 6) & 0xf;
11597 mips32_op = OPC_ADD;
11600 mips32_op = OPC_ADDU;
11603 mips32_op = OPC_SUB;
11606 mips32_op = OPC_SUBU;
11609 mips32_op = OPC_MUL;
11611 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11615 mips32_op = OPC_SLLV;
11618 mips32_op = OPC_SRLV;
11621 mips32_op = OPC_SRAV;
11624 mips32_op = OPC_ROTRV;
11626 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11628 /* Logical operations */
11630 mips32_op = OPC_AND;
11633 mips32_op = OPC_OR;
11636 mips32_op = OPC_NOR;
11639 mips32_op = OPC_XOR;
11641 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11643 /* Set less than */
11645 mips32_op = OPC_SLT;
11648 mips32_op = OPC_SLTU;
11650 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11653 goto pool32a_invalid;
11657 minor = (ctx->opcode >> 6) & 0xf;
11659 /* Conditional moves */
11661 mips32_op = OPC_MOVN;
11664 mips32_op = OPC_MOVZ;
11666 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11669 gen_ldxs(ctx, rs, rt, rd);
11672 goto pool32a_invalid;
11676 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11679 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11682 gen_pool32axf(env, ctx, rt, rs, is_branch);
11685 generate_exception(ctx, EXCP_BREAK);
11689 MIPS_INVAL("pool32a");
11690 generate_exception(ctx, EXCP_RI);
11695 minor = (ctx->opcode >> 12) & 0xf;
11698 check_cp0_enabled(ctx);
11699 /* Treat as no-op. */
11703 /* COP2: Not implemented. */
11704 generate_exception_err(ctx, EXCP_CpU, 2);
11708 #ifdef TARGET_MIPS64
11712 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11716 #ifdef TARGET_MIPS64
11720 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11723 MIPS_INVAL("pool32b");
11724 generate_exception(ctx, EXCP_RI);
11729 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11730 minor = ctx->opcode & 0x3f;
11731 check_cp1_enabled(ctx);
11734 mips32_op = OPC_ALNV_PS;
11737 mips32_op = OPC_MADD_S;
11740 mips32_op = OPC_MADD_D;
11743 mips32_op = OPC_MADD_PS;
11746 mips32_op = OPC_MSUB_S;
11749 mips32_op = OPC_MSUB_D;
11752 mips32_op = OPC_MSUB_PS;
11755 mips32_op = OPC_NMADD_S;
11758 mips32_op = OPC_NMADD_D;
11761 mips32_op = OPC_NMADD_PS;
11764 mips32_op = OPC_NMSUB_S;
11767 mips32_op = OPC_NMSUB_D;
11770 mips32_op = OPC_NMSUB_PS;
11772 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11774 case CABS_COND_FMT:
11775 cond = (ctx->opcode >> 6) & 0xf;
11776 cc = (ctx->opcode >> 13) & 0x7;
11777 fmt = (ctx->opcode >> 10) & 0x3;
11780 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11783 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11786 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11789 goto pool32f_invalid;
11793 cond = (ctx->opcode >> 6) & 0xf;
11794 cc = (ctx->opcode >> 13) & 0x7;
11795 fmt = (ctx->opcode >> 10) & 0x3;
11798 gen_cmp_s(ctx, cond, rt, rs, cc);
11801 gen_cmp_d(ctx, cond, rt, rs, cc);
11804 gen_cmp_ps(ctx, cond, rt, rs, cc);
11807 goto pool32f_invalid;
11811 gen_pool32fxf(env, ctx, rt, rs);
11815 switch ((ctx->opcode >> 6) & 0x7) {
11817 mips32_op = OPC_PLL_PS;
11820 mips32_op = OPC_PLU_PS;
11823 mips32_op = OPC_PUL_PS;
11826 mips32_op = OPC_PUU_PS;
11829 mips32_op = OPC_CVT_PS_S;
11831 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11834 goto pool32f_invalid;
11839 switch ((ctx->opcode >> 6) & 0x7) {
11841 mips32_op = OPC_LWXC1;
11844 mips32_op = OPC_SWXC1;
11847 mips32_op = OPC_LDXC1;
11850 mips32_op = OPC_SDXC1;
11853 mips32_op = OPC_LUXC1;
11856 mips32_op = OPC_SUXC1;
11858 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11861 goto pool32f_invalid;
11866 fmt = (ctx->opcode >> 9) & 0x3;
11867 switch ((ctx->opcode >> 6) & 0x7) {
11871 mips32_op = OPC_RSQRT2_S;
11874 mips32_op = OPC_RSQRT2_D;
11877 mips32_op = OPC_RSQRT2_PS;
11880 goto pool32f_invalid;
11886 mips32_op = OPC_RECIP2_S;
11889 mips32_op = OPC_RECIP2_D;
11892 mips32_op = OPC_RECIP2_PS;
11895 goto pool32f_invalid;
11899 mips32_op = OPC_ADDR_PS;
11902 mips32_op = OPC_MULR_PS;
11904 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11907 goto pool32f_invalid;
11911 /* MOV[FT].fmt and PREFX */
11912 cc = (ctx->opcode >> 13) & 0x7;
11913 fmt = (ctx->opcode >> 9) & 0x3;
11914 switch ((ctx->opcode >> 6) & 0x7) {
11918 gen_movcf_s(rs, rt, cc, 0);
11921 gen_movcf_d(ctx, rs, rt, cc, 0);
11924 gen_movcf_ps(rs, rt, cc, 0);
11927 goto pool32f_invalid;
11933 gen_movcf_s(rs, rt, cc, 1);
11936 gen_movcf_d(ctx, rs, rt, cc, 1);
11939 gen_movcf_ps(rs, rt, cc, 1);
11942 goto pool32f_invalid;
11948 goto pool32f_invalid;
11951 #define FINSN_3ARG_SDPS(prfx) \
11952 switch ((ctx->opcode >> 8) & 0x3) { \
11954 mips32_op = OPC_##prfx##_S; \
11957 mips32_op = OPC_##prfx##_D; \
11959 case FMT_SDPS_PS: \
11960 mips32_op = OPC_##prfx##_PS; \
11963 goto pool32f_invalid; \
11966 /* regular FP ops */
11967 switch ((ctx->opcode >> 6) & 0x3) {
11969 FINSN_3ARG_SDPS(ADD);
11972 FINSN_3ARG_SDPS(SUB);
11975 FINSN_3ARG_SDPS(MUL);
11978 fmt = (ctx->opcode >> 8) & 0x3;
11980 mips32_op = OPC_DIV_D;
11981 } else if (fmt == 0) {
11982 mips32_op = OPC_DIV_S;
11984 goto pool32f_invalid;
11988 goto pool32f_invalid;
11993 switch ((ctx->opcode >> 6) & 0x3) {
11995 FINSN_3ARG_SDPS(MOVN);
11998 FINSN_3ARG_SDPS(MOVZ);
12001 goto pool32f_invalid;
12005 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12009 MIPS_INVAL("pool32f");
12010 generate_exception(ctx, EXCP_RI);
12014 generate_exception_err(ctx, EXCP_CpU, 1);
12018 minor = (ctx->opcode >> 21) & 0x1f;
12021 mips32_op = OPC_BLTZ;
12024 mips32_op = OPC_BLTZAL;
12027 mips32_op = OPC_BLTZALS;
12030 mips32_op = OPC_BGEZ;
12033 mips32_op = OPC_BGEZAL;
12036 mips32_op = OPC_BGEZALS;
12039 mips32_op = OPC_BLEZ;
12042 mips32_op = OPC_BGTZ;
12044 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12050 mips32_op = OPC_TLTI;
12053 mips32_op = OPC_TGEI;
12056 mips32_op = OPC_TLTIU;
12059 mips32_op = OPC_TGEIU;
12062 mips32_op = OPC_TNEI;
12065 mips32_op = OPC_TEQI;
12067 gen_trap(ctx, mips32_op, rs, -1, imm);
12072 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12073 4, rs, 0, imm << 1);
12074 /* Compact branches don't have a delay slot, so just let
12075 the normal delay slot handling take us to the branch
12079 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12085 /* COP2: Not implemented. */
12086 generate_exception_err(ctx, EXCP_CpU, 2);
12089 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12092 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12095 mips32_op = OPC_BC1FANY4;
12098 mips32_op = OPC_BC1TANY4;
12101 check_insn(env, ctx, ASE_MIPS3D);
12104 gen_compute_branch1(env, ctx, mips32_op,
12105 (ctx->opcode >> 18) & 0x7, imm << 1);
12110 /* MIPS DSP: not implemented */
12113 MIPS_INVAL("pool32i");
12114 generate_exception(ctx, EXCP_RI);
12119 minor = (ctx->opcode >> 12) & 0xf;
12122 mips32_op = OPC_LWL;
12125 mips32_op = OPC_SWL;
12128 mips32_op = OPC_LWR;
12131 mips32_op = OPC_SWR;
12133 #if defined(TARGET_MIPS64)
12135 mips32_op = OPC_LDL;
12138 mips32_op = OPC_SDL;
12141 mips32_op = OPC_LDR;
12144 mips32_op = OPC_SDR;
12147 mips32_op = OPC_LWU;
12150 mips32_op = OPC_LLD;
12154 mips32_op = OPC_LL;
12157 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12160 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12163 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12165 #if defined(TARGET_MIPS64)
12167 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12171 /* Treat as no-op */
12174 MIPS_INVAL("pool32c");
12175 generate_exception(ctx, EXCP_RI);
12180 mips32_op = OPC_ADDI;
12183 mips32_op = OPC_ADDIU;
12185 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12188 /* Logical operations */
12190 mips32_op = OPC_ORI;
12193 mips32_op = OPC_XORI;
12196 mips32_op = OPC_ANDI;
12198 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12201 /* Set less than immediate */
12203 mips32_op = OPC_SLTI;
12206 mips32_op = OPC_SLTIU;
12208 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12211 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12212 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12216 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12217 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12221 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12225 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12229 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12230 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12234 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12235 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12238 /* Floating point (COP1) */
12240 mips32_op = OPC_LWC1;
12243 mips32_op = OPC_LDC1;
12246 mips32_op = OPC_SWC1;
12249 mips32_op = OPC_SDC1;
12251 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12255 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12256 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12258 gen_addiupc(ctx, reg, offset, 0, 0);
12261 /* Loads and stores */
12263 mips32_op = OPC_LB;
12266 mips32_op = OPC_LBU;
12269 mips32_op = OPC_LH;
12272 mips32_op = OPC_LHU;
12275 mips32_op = OPC_LW;
12277 #ifdef TARGET_MIPS64
12279 mips32_op = OPC_LD;
12282 mips32_op = OPC_SD;
12286 mips32_op = OPC_SB;
12289 mips32_op = OPC_SH;
12292 mips32_op = OPC_SW;
12295 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12298 gen_st(ctx, mips32_op, rt, rs, imm);
12301 generate_exception(ctx, EXCP_RI);
12306 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12310 /* make sure instructions are on a halfword boundary */
12311 if (ctx->pc & 0x1) {
12312 env->CP0_BadVAddr = ctx->pc;
12313 generate_exception(ctx, EXCP_AdEL);
12314 ctx->bstate = BS_STOP;
12318 op = (ctx->opcode >> 10) & 0x3f;
12319 /* Enforce properly-sized instructions in a delay slot */
12320 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12321 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12355 case POOL48A: /* ??? */
12360 if (bits & MIPS_HFLAG_BDS16) {
12361 generate_exception(ctx, EXCP_RI);
12362 /* Just stop translation; the user is confused. */
12363 ctx->bstate = BS_STOP;
12388 if (bits & MIPS_HFLAG_BDS32) {
12389 generate_exception(ctx, EXCP_RI);
12390 /* Just stop translation; the user is confused. */
12391 ctx->bstate = BS_STOP;
12402 int rd = mmreg(uMIPS_RD(ctx->opcode));
12403 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12404 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12407 switch (ctx->opcode & 0x1) {
12416 gen_arith(env, ctx, opc, rd, rs1, rs2);
12421 int rd = mmreg(uMIPS_RD(ctx->opcode));
12422 int rs = mmreg(uMIPS_RS(ctx->opcode));
12423 int amount = (ctx->opcode >> 1) & 0x7;
12425 amount = amount == 0 ? 8 : amount;
12427 switch (ctx->opcode & 0x1) {
12436 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12440 gen_pool16c_insn(env, ctx, is_branch);
12444 int rd = mmreg(uMIPS_RD(ctx->opcode));
12445 int rb = 28; /* GP */
12446 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12448 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12452 if (ctx->opcode & 1) {
12453 generate_exception(ctx, EXCP_RI);
12456 int enc_dest = uMIPS_RD(ctx->opcode);
12457 int enc_rt = uMIPS_RS2(ctx->opcode);
12458 int enc_rs = uMIPS_RS1(ctx->opcode);
12459 int rd, rs, re, rt;
12460 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12461 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12462 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12464 rd = rd_enc[enc_dest];
12465 re = re_enc[enc_dest];
12466 rs = rs_rt_enc[enc_rs];
12467 rt = rs_rt_enc[enc_rt];
12469 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12470 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12475 int rd = mmreg(uMIPS_RD(ctx->opcode));
12476 int rb = mmreg(uMIPS_RS(ctx->opcode));
12477 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12478 offset = (offset == 0xf ? -1 : offset);
12480 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12485 int rd = mmreg(uMIPS_RD(ctx->opcode));
12486 int rb = mmreg(uMIPS_RS(ctx->opcode));
12487 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12489 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12494 int rd = (ctx->opcode >> 5) & 0x1f;
12495 int rb = 29; /* SP */
12496 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12498 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12503 int rd = mmreg(uMIPS_RD(ctx->opcode));
12504 int rb = mmreg(uMIPS_RS(ctx->opcode));
12505 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12507 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12512 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12513 int rb = mmreg(uMIPS_RS(ctx->opcode));
12514 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12516 gen_st(ctx, OPC_SB, rd, rb, offset);
12521 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12522 int rb = mmreg(uMIPS_RS(ctx->opcode));
12523 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12525 gen_st(ctx, OPC_SH, rd, rb, offset);
12530 int rd = (ctx->opcode >> 5) & 0x1f;
12531 int rb = 29; /* SP */
12532 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12534 gen_st(ctx, OPC_SW, rd, rb, offset);
12539 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12540 int rb = mmreg(uMIPS_RS(ctx->opcode));
12541 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12543 gen_st(ctx, OPC_SW, rd, rb, offset);
12548 int rd = uMIPS_RD5(ctx->opcode);
12549 int rs = uMIPS_RS5(ctx->opcode);
12551 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12555 gen_andi16(env, ctx);
12558 switch (ctx->opcode & 0x1) {
12560 gen_addius5(env, ctx);
12563 gen_addiusp(env, ctx);
12568 switch (ctx->opcode & 0x1) {
12570 gen_addiur2(env, ctx);
12573 gen_addiur1sp(env, ctx);
12578 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12579 SIMM(ctx->opcode, 0, 10) << 1);
12584 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12585 mmreg(uMIPS_RD(ctx->opcode)),
12586 0, SIMM(ctx->opcode, 0, 7) << 1);
12591 int reg = mmreg(uMIPS_RD(ctx->opcode));
12592 int imm = ZIMM(ctx->opcode, 0, 7);
12594 imm = (imm == 0x7f ? -1 : imm);
12595 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12605 generate_exception(ctx, EXCP_RI);
12608 decode_micromips32_opc (env, ctx, op, is_branch);
12615 /* SmartMIPS extension to MIPS32 */
12617 #if defined(TARGET_MIPS64)
12619 /* MDMX extension to MIPS64 */
12623 /* MIPSDSP functions. */
12624 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12625 int rd, int base, int offset)
12627 const char *opn = "ldx";
12636 t0 = tcg_temp_new();
12639 gen_load_gpr(t0, offset);
12640 } else if (offset == 0) {
12641 gen_load_gpr(t0, base);
12643 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12648 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12649 gen_store_gpr(t0, rd);
12653 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12654 gen_store_gpr(t0, rd);
12658 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12659 gen_store_gpr(t0, rd);
12662 #if defined(TARGET_MIPS64)
12664 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12665 gen_store_gpr(t0, rd);
12670 (void)opn; /* avoid a compiler warning */
12671 MIPS_DEBUG("%s %s, %s(%s)", opn,
12672 regnames[rd], regnames[offset], regnames[base]);
12676 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12677 int ret, int v1, int v2)
12679 const char *opn = "mipsdsp arith";
12684 /* Treat as NOP. */
12689 v1_t = tcg_temp_new();
12690 v2_t = tcg_temp_new();
12692 gen_load_gpr(v1_t, v1);
12693 gen_load_gpr(v2_t, v2);
12696 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12697 case OPC_MULT_G_2E:
12701 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12703 case OPC_ADDUH_R_QB:
12704 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12707 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12709 case OPC_ADDQH_R_PH:
12710 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12713 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12715 case OPC_ADDQH_R_W:
12716 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12719 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12721 case OPC_SUBUH_R_QB:
12722 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12725 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12727 case OPC_SUBQH_R_PH:
12728 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12731 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12733 case OPC_SUBQH_R_W:
12734 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12738 case OPC_ABSQ_S_PH_DSP:
12740 case OPC_ABSQ_S_QB:
12742 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12744 case OPC_ABSQ_S_PH:
12746 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12750 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12752 case OPC_PRECEQ_W_PHL:
12754 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12755 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12757 case OPC_PRECEQ_W_PHR:
12759 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12760 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12761 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12763 case OPC_PRECEQU_PH_QBL:
12765 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12767 case OPC_PRECEQU_PH_QBR:
12769 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12771 case OPC_PRECEQU_PH_QBLA:
12773 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12775 case OPC_PRECEQU_PH_QBRA:
12777 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12779 case OPC_PRECEU_PH_QBL:
12781 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12783 case OPC_PRECEU_PH_QBR:
12785 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12787 case OPC_PRECEU_PH_QBLA:
12789 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12791 case OPC_PRECEU_PH_QBRA:
12793 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12797 case OPC_ADDU_QB_DSP:
12801 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12803 case OPC_ADDQ_S_PH:
12805 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12809 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12813 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12815 case OPC_ADDU_S_QB:
12817 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12821 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12823 case OPC_ADDU_S_PH:
12825 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12829 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12831 case OPC_SUBQ_S_PH:
12833 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12837 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12841 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12843 case OPC_SUBU_S_QB:
12845 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12851 case OPC_SUBU_S_PH:
12853 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12857 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12867 case OPC_RADDU_W_QB:
12869 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12873 case OPC_CMPU_EQ_QB_DSP:
12875 case OPC_PRECR_QB_PH:
12877 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12879 case OPC_PRECRQ_QB_PH:
12881 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12883 case OPC_PRECR_SRA_PH_W:
12886 TCGv_i32 sa_t = tcg_const_i32(v2);
12887 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12889 tcg_temp_free_i32(sa_t);
12892 case OPC_PRECR_SRA_R_PH_W:
12895 TCGv_i32 sa_t = tcg_const_i32(v2);
12896 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12898 tcg_temp_free_i32(sa_t);
12901 case OPC_PRECRQ_PH_W:
12903 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12905 case OPC_PRECRQ_RS_PH_W:
12907 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12909 case OPC_PRECRQU_S_QB_PH:
12911 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12915 #ifdef TARGET_MIPS64
12916 case OPC_ABSQ_S_QH_DSP:
12918 case OPC_PRECEQ_L_PWL:
12920 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12922 case OPC_PRECEQ_L_PWR:
12924 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12926 case OPC_PRECEQ_PW_QHL:
12928 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12930 case OPC_PRECEQ_PW_QHR:
12932 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12934 case OPC_PRECEQ_PW_QHLA:
12936 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12938 case OPC_PRECEQ_PW_QHRA:
12940 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12942 case OPC_PRECEQU_QH_OBL:
12944 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12946 case OPC_PRECEQU_QH_OBR:
12948 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12950 case OPC_PRECEQU_QH_OBLA:
12952 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12954 case OPC_PRECEQU_QH_OBRA:
12956 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12958 case OPC_PRECEU_QH_OBL:
12960 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12962 case OPC_PRECEU_QH_OBR:
12964 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12966 case OPC_PRECEU_QH_OBLA:
12968 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12970 case OPC_PRECEU_QH_OBRA:
12972 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12974 case OPC_ABSQ_S_OB:
12976 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12978 case OPC_ABSQ_S_PW:
12980 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12982 case OPC_ABSQ_S_QH:
12984 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12988 case OPC_ADDU_OB_DSP:
12990 case OPC_RADDU_L_OB:
12992 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12996 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12998 case OPC_SUBQ_S_PW:
13000 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13004 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13006 case OPC_SUBQ_S_QH:
13008 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13012 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13014 case OPC_SUBU_S_OB:
13016 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13020 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13022 case OPC_SUBU_S_QH:
13024 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13028 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13030 case OPC_SUBUH_R_OB:
13032 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13036 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13038 case OPC_ADDQ_S_PW:
13040 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13046 case OPC_ADDQ_S_QH:
13048 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13054 case OPC_ADDU_S_OB:
13056 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13060 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13062 case OPC_ADDU_S_QH:
13064 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13068 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13070 case OPC_ADDUH_R_OB:
13072 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13076 case OPC_CMPU_EQ_OB_DSP:
13078 case OPC_PRECR_OB_QH:
13080 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13082 case OPC_PRECR_SRA_QH_PW:
13085 TCGv_i32 ret_t = tcg_const_i32(ret);
13086 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13087 tcg_temp_free_i32(ret_t);
13090 case OPC_PRECR_SRA_R_QH_PW:
13093 TCGv_i32 sa_v = tcg_const_i32(ret);
13094 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13095 tcg_temp_free_i32(sa_v);
13098 case OPC_PRECRQ_OB_QH:
13100 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13102 case OPC_PRECRQ_PW_L:
13104 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13106 case OPC_PRECRQ_QH_PW:
13108 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13110 case OPC_PRECRQ_RS_QH_PW:
13112 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13114 case OPC_PRECRQU_S_OB_QH:
13116 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13123 tcg_temp_free(v1_t);
13124 tcg_temp_free(v2_t);
13126 (void)opn; /* avoid a compiler warning */
13127 MIPS_DEBUG("%s", opn);
13130 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13131 int ret, int v1, int v2)
13134 const char *opn = "mipsdsp shift";
13140 /* Treat as NOP. */
13145 t0 = tcg_temp_new();
13146 v1_t = tcg_temp_new();
13147 v2_t = tcg_temp_new();
13149 tcg_gen_movi_tl(t0, v1);
13150 gen_load_gpr(v1_t, v1);
13151 gen_load_gpr(v2_t, v2);
13154 case OPC_SHLL_QB_DSP:
13156 op2 = MASK_SHLL_QB(ctx->opcode);
13160 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13164 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13168 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13172 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13174 case OPC_SHLL_S_PH:
13176 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13178 case OPC_SHLLV_S_PH:
13180 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13184 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13186 case OPC_SHLLV_S_W:
13188 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13192 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13196 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13200 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13204 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13208 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13210 case OPC_SHRA_R_QB:
13212 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13216 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13218 case OPC_SHRAV_R_QB:
13220 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13224 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13226 case OPC_SHRA_R_PH:
13228 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13232 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13234 case OPC_SHRAV_R_PH:
13236 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13240 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13242 case OPC_SHRAV_R_W:
13244 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13246 default: /* Invalid */
13247 MIPS_INVAL("MASK SHLL.QB");
13248 generate_exception(ctx, EXCP_RI);
13253 #ifdef TARGET_MIPS64
13254 case OPC_SHLL_OB_DSP:
13255 op2 = MASK_SHLL_OB(ctx->opcode);
13259 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13263 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13265 case OPC_SHLL_S_PW:
13267 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13269 case OPC_SHLLV_S_PW:
13271 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13275 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13279 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13283 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13287 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13289 case OPC_SHLL_S_QH:
13291 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13293 case OPC_SHLLV_S_QH:
13295 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13299 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13303 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13305 case OPC_SHRA_R_OB:
13307 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13309 case OPC_SHRAV_R_OB:
13311 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13315 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13319 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13321 case OPC_SHRA_R_PW:
13323 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13325 case OPC_SHRAV_R_PW:
13327 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13331 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13335 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13337 case OPC_SHRA_R_QH:
13339 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13341 case OPC_SHRAV_R_QH:
13343 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13347 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13351 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13355 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13359 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13361 default: /* Invalid */
13362 MIPS_INVAL("MASK SHLL.OB");
13363 generate_exception(ctx, EXCP_RI);
13371 tcg_temp_free(v1_t);
13372 tcg_temp_free(v2_t);
13373 (void)opn; /* avoid a compiler warning */
13374 MIPS_DEBUG("%s", opn);
13377 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13378 int ret, int v1, int v2, int check_ret)
13380 const char *opn = "mipsdsp multiply";
13385 if ((ret == 0) && (check_ret == 1)) {
13386 /* Treat as NOP. */
13391 t0 = tcg_temp_new_i32();
13392 v1_t = tcg_temp_new();
13393 v2_t = tcg_temp_new();
13395 tcg_gen_movi_i32(t0, ret);
13396 gen_load_gpr(v1_t, v1);
13397 gen_load_gpr(v2_t, v2);
13400 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13401 * the same mask and op1. */
13402 case OPC_MULT_G_2E:
13405 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13408 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13411 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13413 case OPC_MULQ_RS_W:
13414 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13418 case OPC_DPA_W_PH_DSP:
13420 case OPC_DPAU_H_QBL:
13422 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13424 case OPC_DPAU_H_QBR:
13426 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13428 case OPC_DPSU_H_QBL:
13430 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13432 case OPC_DPSU_H_QBR:
13434 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13438 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13440 case OPC_DPAX_W_PH:
13442 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13444 case OPC_DPAQ_S_W_PH:
13446 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13448 case OPC_DPAQX_S_W_PH:
13450 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13452 case OPC_DPAQX_SA_W_PH:
13454 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13458 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13460 case OPC_DPSX_W_PH:
13462 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13464 case OPC_DPSQ_S_W_PH:
13466 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13468 case OPC_DPSQX_S_W_PH:
13470 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13472 case OPC_DPSQX_SA_W_PH:
13474 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13476 case OPC_MULSAQ_S_W_PH:
13478 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13480 case OPC_DPAQ_SA_L_W:
13482 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13484 case OPC_DPSQ_SA_L_W:
13486 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13488 case OPC_MAQ_S_W_PHL:
13490 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13492 case OPC_MAQ_S_W_PHR:
13494 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13496 case OPC_MAQ_SA_W_PHL:
13498 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13500 case OPC_MAQ_SA_W_PHR:
13502 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13504 case OPC_MULSA_W_PH:
13506 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13510 #ifdef TARGET_MIPS64
13511 case OPC_DPAQ_W_QH_DSP:
13513 int ac = ret & 0x03;
13514 tcg_gen_movi_i32(t0, ac);
13519 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13523 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13527 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13531 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13535 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13537 case OPC_DPAQ_S_W_QH:
13539 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13541 case OPC_DPAQ_SA_L_PW:
13543 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13545 case OPC_DPAU_H_OBL:
13547 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13549 case OPC_DPAU_H_OBR:
13551 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13555 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13557 case OPC_DPSQ_S_W_QH:
13559 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13561 case OPC_DPSQ_SA_L_PW:
13563 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13565 case OPC_DPSU_H_OBL:
13567 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13569 case OPC_DPSU_H_OBR:
13571 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13573 case OPC_MAQ_S_L_PWL:
13575 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13577 case OPC_MAQ_S_L_PWR:
13579 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13581 case OPC_MAQ_S_W_QHLL:
13583 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13585 case OPC_MAQ_SA_W_QHLL:
13587 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13589 case OPC_MAQ_S_W_QHLR:
13591 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13593 case OPC_MAQ_SA_W_QHLR:
13595 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13597 case OPC_MAQ_S_W_QHRL:
13599 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13601 case OPC_MAQ_SA_W_QHRL:
13603 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13605 case OPC_MAQ_S_W_QHRR:
13607 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13609 case OPC_MAQ_SA_W_QHRR:
13611 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13613 case OPC_MULSAQ_S_L_PW:
13615 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13617 case OPC_MULSAQ_S_W_QH:
13619 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13625 case OPC_ADDU_QB_DSP:
13627 case OPC_MULEU_S_PH_QBL:
13629 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13631 case OPC_MULEU_S_PH_QBR:
13633 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13635 case OPC_MULQ_RS_PH:
13637 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13639 case OPC_MULEQ_S_W_PHL:
13641 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13643 case OPC_MULEQ_S_W_PHR:
13645 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13647 case OPC_MULQ_S_PH:
13649 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13653 #ifdef TARGET_MIPS64
13654 case OPC_ADDU_OB_DSP:
13656 case OPC_MULEQ_S_PW_QHL:
13658 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13660 case OPC_MULEQ_S_PW_QHR:
13662 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13664 case OPC_MULEU_S_QH_OBL:
13666 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 case OPC_MULEU_S_QH_OBR:
13670 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 case OPC_MULQ_RS_QH:
13674 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13681 tcg_temp_free_i32(t0);
13682 tcg_temp_free(v1_t);
13683 tcg_temp_free(v2_t);
13685 (void)opn; /* avoid a compiler warning */
13686 MIPS_DEBUG("%s", opn);
13690 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13691 uint32_t op1, uint32_t op2,
13694 const char *opn = "mipsdsp Bit/ Manipulation";
13700 /* Treat as NOP. */
13705 t0 = tcg_temp_new();
13706 val_t = tcg_temp_new();
13707 gen_load_gpr(val_t, val);
13710 case OPC_ABSQ_S_PH_DSP:
13714 gen_helper_bitrev(cpu_gpr[ret], val_t);
13719 target_long result;
13720 imm = (ctx->opcode >> 16) & 0xFF;
13721 result = (uint32_t)imm << 24 |
13722 (uint32_t)imm << 16 |
13723 (uint32_t)imm << 8 |
13725 result = (int32_t)result;
13726 tcg_gen_movi_tl(cpu_gpr[ret], result);
13731 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13732 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13733 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13734 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13735 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13736 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13741 imm = (ctx->opcode >> 16) & 0x03FF;
13742 tcg_gen_movi_tl(cpu_gpr[ret], \
13743 (target_long)((int32_t)imm << 16 | \
13744 (uint32_t)(uint16_t)imm));
13749 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13750 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13751 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13752 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13756 #ifdef TARGET_MIPS64
13757 case OPC_ABSQ_S_QH_DSP:
13764 imm = (ctx->opcode >> 16) & 0xFF;
13765 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13766 temp = (temp << 16) | temp;
13767 temp = (temp << 32) | temp;
13768 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13776 imm = (ctx->opcode >> 16) & 0x03FF;
13777 imm = (int16_t)(imm << 6) >> 6;
13778 temp = ((target_long)imm << 32) \
13779 | ((target_long)imm & 0xFFFFFFFF);
13780 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13788 imm = (ctx->opcode >> 16) & 0x03FF;
13789 imm = (int16_t)(imm << 6) >> 6;
13791 temp = ((uint64_t)(uint16_t)imm << 48) |
13792 ((uint64_t)(uint16_t)imm << 32) |
13793 ((uint64_t)(uint16_t)imm << 16) |
13794 (uint64_t)(uint16_t)imm;
13795 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13800 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13801 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13802 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13803 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13804 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13805 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13806 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13810 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13811 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13812 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13816 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13817 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13818 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13819 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13820 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13827 tcg_temp_free(val_t);
13829 (void)opn; /* avoid a compiler warning */
13830 MIPS_DEBUG("%s", opn);
13833 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13834 uint32_t op1, uint32_t op2,
13835 int ret, int v1, int v2, int check_ret)
13837 const char *opn = "mipsdsp add compare pick";
13843 if ((ret == 0) && (check_ret == 1)) {
13844 /* Treat as NOP. */
13849 t0 = tcg_temp_new_i32();
13850 t1 = tcg_temp_new();
13851 v1_t = tcg_temp_new();
13852 v2_t = tcg_temp_new();
13854 gen_load_gpr(v1_t, v1);
13855 gen_load_gpr(v2_t, v2);
13858 case OPC_APPEND_DSP:
13861 tcg_gen_movi_i32(t0, v2);
13862 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13865 tcg_gen_movi_i32(t0, v2);
13866 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13869 tcg_gen_movi_i32(t0, v2);
13870 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13872 default: /* Invid */
13873 MIPS_INVAL("MASK APPEND");
13874 generate_exception(ctx, EXCP_RI);
13878 case OPC_CMPU_EQ_QB_DSP:
13880 case OPC_CMPU_EQ_QB:
13882 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13884 case OPC_CMPU_LT_QB:
13886 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13888 case OPC_CMPU_LE_QB:
13890 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13892 case OPC_CMPGU_EQ_QB:
13894 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13896 case OPC_CMPGU_LT_QB:
13898 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13900 case OPC_CMPGU_LE_QB:
13902 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13904 case OPC_CMPGDU_EQ_QB:
13906 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13907 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13908 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13909 tcg_gen_shli_tl(t1, t1, 24);
13910 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13912 case OPC_CMPGDU_LT_QB:
13914 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13915 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13916 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13917 tcg_gen_shli_tl(t1, t1, 24);
13918 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13920 case OPC_CMPGDU_LE_QB:
13922 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13923 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13924 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13925 tcg_gen_shli_tl(t1, t1, 24);
13926 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13928 case OPC_CMP_EQ_PH:
13930 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13932 case OPC_CMP_LT_PH:
13934 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13936 case OPC_CMP_LE_PH:
13938 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13942 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13946 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13948 case OPC_PACKRL_PH:
13950 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13954 #ifdef TARGET_MIPS64
13955 case OPC_CMPU_EQ_OB_DSP:
13957 case OPC_CMP_EQ_PW:
13959 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13961 case OPC_CMP_LT_PW:
13963 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13965 case OPC_CMP_LE_PW:
13967 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13969 case OPC_CMP_EQ_QH:
13971 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13973 case OPC_CMP_LT_QH:
13975 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13977 case OPC_CMP_LE_QH:
13979 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13981 case OPC_CMPGDU_EQ_OB:
13983 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13985 case OPC_CMPGDU_LT_OB:
13987 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13989 case OPC_CMPGDU_LE_OB:
13991 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13993 case OPC_CMPGU_EQ_OB:
13995 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13997 case OPC_CMPGU_LT_OB:
13999 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14001 case OPC_CMPGU_LE_OB:
14003 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14005 case OPC_CMPU_EQ_OB:
14007 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14009 case OPC_CMPU_LT_OB:
14011 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14013 case OPC_CMPU_LE_OB:
14015 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14017 case OPC_PACKRL_PW:
14019 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14023 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14027 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14031 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14035 case OPC_DAPPEND_DSP:
14038 tcg_gen_movi_i32(t0, v2);
14039 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14042 tcg_gen_movi_i32(t0, v2);
14043 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14046 tcg_gen_movi_i32(t0, v2);
14047 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14050 tcg_gen_movi_i32(t0, v2);
14051 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14053 default: /* Invalid */
14054 MIPS_INVAL("MASK DAPPEND");
14055 generate_exception(ctx, EXCP_RI);
14062 tcg_temp_free_i32(t0);
14064 tcg_temp_free(v1_t);
14065 tcg_temp_free(v2_t);
14067 (void)opn; /* avoid a compiler warning */
14068 MIPS_DEBUG("%s", opn);
14071 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14072 int ret, int v1, int v2, int check_ret)
14075 const char *opn = "mipsdsp accumulator";
14082 if ((ret == 0) && (check_ret == 1)) {
14083 /* Treat as NOP. */
14088 t0 = tcg_temp_new();
14089 t1 = tcg_temp_new();
14090 v1_t = tcg_temp_new();
14091 v2_t = tcg_temp_new();
14093 gen_load_gpr(v1_t, v1);
14094 gen_load_gpr(v2_t, v2);
14097 case OPC_EXTR_W_DSP:
14101 tcg_gen_movi_tl(t0, v2);
14102 tcg_gen_movi_tl(t1, v1);
14103 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14106 tcg_gen_movi_tl(t0, v2);
14107 tcg_gen_movi_tl(t1, v1);
14108 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14110 case OPC_EXTR_RS_W:
14111 tcg_gen_movi_tl(t0, v2);
14112 tcg_gen_movi_tl(t1, v1);
14113 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14116 tcg_gen_movi_tl(t0, v2);
14117 tcg_gen_movi_tl(t1, v1);
14118 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14120 case OPC_EXTRV_S_H:
14121 tcg_gen_movi_tl(t0, v2);
14122 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14125 tcg_gen_movi_tl(t0, v2);
14126 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14128 case OPC_EXTRV_R_W:
14129 tcg_gen_movi_tl(t0, v2);
14130 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14132 case OPC_EXTRV_RS_W:
14133 tcg_gen_movi_tl(t0, v2);
14134 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14137 tcg_gen_movi_tl(t0, v2);
14138 tcg_gen_movi_tl(t1, v1);
14139 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14142 tcg_gen_movi_tl(t0, v2);
14143 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14146 tcg_gen_movi_tl(t0, v2);
14147 tcg_gen_movi_tl(t1, v1);
14148 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14151 tcg_gen_movi_tl(t0, v2);
14152 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14155 imm = (ctx->opcode >> 20) & 0x3F;
14156 tcg_gen_movi_tl(t0, ret);
14157 tcg_gen_movi_tl(t1, imm);
14158 gen_helper_shilo(t0, t1, cpu_env);
14161 tcg_gen_movi_tl(t0, ret);
14162 gen_helper_shilo(t0, v1_t, cpu_env);
14165 tcg_gen_movi_tl(t0, ret);
14166 gen_helper_mthlip(t0, v1_t, cpu_env);
14169 imm = (ctx->opcode >> 11) & 0x3FF;
14170 tcg_gen_movi_tl(t0, imm);
14171 gen_helper_wrdsp(v1_t, t0, cpu_env);
14174 imm = (ctx->opcode >> 16) & 0x03FF;
14175 tcg_gen_movi_tl(t0, imm);
14176 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14180 #ifdef TARGET_MIPS64
14181 case OPC_DEXTR_W_DSP:
14185 tcg_gen_movi_tl(t0, ret);
14186 gen_helper_dmthlip(v1_t, t0, cpu_env);
14190 int shift = (ctx->opcode >> 19) & 0x7F;
14191 int ac = (ctx->opcode >> 11) & 0x03;
14192 tcg_gen_movi_tl(t0, shift);
14193 tcg_gen_movi_tl(t1, ac);
14194 gen_helper_dshilo(t0, t1, cpu_env);
14199 int ac = (ctx->opcode >> 11) & 0x03;
14200 tcg_gen_movi_tl(t0, ac);
14201 gen_helper_dshilo(v1_t, t0, cpu_env);
14205 tcg_gen_movi_tl(t0, v2);
14206 tcg_gen_movi_tl(t1, v1);
14208 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14211 tcg_gen_movi_tl(t0, v2);
14212 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14215 tcg_gen_movi_tl(t0, v2);
14216 tcg_gen_movi_tl(t1, v1);
14217 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14220 tcg_gen_movi_tl(t0, v2);
14221 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14224 tcg_gen_movi_tl(t0, v2);
14225 tcg_gen_movi_tl(t1, v1);
14226 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14228 case OPC_DEXTR_R_L:
14229 tcg_gen_movi_tl(t0, v2);
14230 tcg_gen_movi_tl(t1, v1);
14231 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14233 case OPC_DEXTR_RS_L:
14234 tcg_gen_movi_tl(t0, v2);
14235 tcg_gen_movi_tl(t1, v1);
14236 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14239 tcg_gen_movi_tl(t0, v2);
14240 tcg_gen_movi_tl(t1, v1);
14241 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14243 case OPC_DEXTR_R_W:
14244 tcg_gen_movi_tl(t0, v2);
14245 tcg_gen_movi_tl(t1, v1);
14246 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14248 case OPC_DEXTR_RS_W:
14249 tcg_gen_movi_tl(t0, v2);
14250 tcg_gen_movi_tl(t1, v1);
14251 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14253 case OPC_DEXTR_S_H:
14254 tcg_gen_movi_tl(t0, v2);
14255 tcg_gen_movi_tl(t1, v1);
14256 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14258 case OPC_DEXTRV_S_H:
14259 tcg_gen_movi_tl(t0, v2);
14260 tcg_gen_movi_tl(t1, v1);
14261 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14264 tcg_gen_movi_tl(t0, v2);
14265 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14267 case OPC_DEXTRV_R_L:
14268 tcg_gen_movi_tl(t0, v2);
14269 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14271 case OPC_DEXTRV_RS_L:
14272 tcg_gen_movi_tl(t0, v2);
14273 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14276 tcg_gen_movi_tl(t0, v2);
14277 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14279 case OPC_DEXTRV_R_W:
14280 tcg_gen_movi_tl(t0, v2);
14281 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14283 case OPC_DEXTRV_RS_W:
14284 tcg_gen_movi_tl(t0, v2);
14285 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14294 tcg_temp_free(v1_t);
14295 tcg_temp_free(v2_t);
14297 (void)opn; /* avoid a compiler warning */
14298 MIPS_DEBUG("%s", opn);
14301 /* End MIPSDSP functions. */
14303 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14306 int rs, rt, rd, sa;
14307 uint32_t op, op1, op2;
14310 /* make sure instructions are on a word boundary */
14311 if (ctx->pc & 0x3) {
14312 env->CP0_BadVAddr = ctx->pc;
14313 generate_exception(ctx, EXCP_AdEL);
14317 /* Handle blikely not taken case */
14318 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14319 int l1 = gen_new_label();
14321 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14322 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14323 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14324 gen_goto_tb(ctx, 1, ctx->pc + 4);
14328 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14329 tcg_gen_debug_insn_start(ctx->pc);
14332 op = MASK_OP_MAJOR(ctx->opcode);
14333 rs = (ctx->opcode >> 21) & 0x1f;
14334 rt = (ctx->opcode >> 16) & 0x1f;
14335 rd = (ctx->opcode >> 11) & 0x1f;
14336 sa = (ctx->opcode >> 6) & 0x1f;
14337 imm = (int16_t)ctx->opcode;
14340 op1 = MASK_SPECIAL(ctx->opcode);
14342 case OPC_SLL: /* Shift with immediate */
14344 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14347 switch ((ctx->opcode >> 21) & 0x1f) {
14349 /* rotr is decoded as srl on non-R2 CPUs */
14350 if (env->insn_flags & ISA_MIPS32R2) {
14355 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14358 generate_exception(ctx, EXCP_RI);
14362 case OPC_MOVN: /* Conditional move */
14364 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14365 INSN_LOONGSON2E | INSN_LOONGSON2F);
14366 gen_cond_move(env, ctx, op1, rd, rs, rt);
14368 case OPC_ADD ... OPC_SUBU:
14369 gen_arith(env, ctx, op1, rd, rs, rt);
14371 case OPC_SLLV: /* Shifts */
14373 gen_shift(env, ctx, op1, rd, rs, rt);
14376 switch ((ctx->opcode >> 6) & 0x1f) {
14378 /* rotrv is decoded as srlv on non-R2 CPUs */
14379 if (env->insn_flags & ISA_MIPS32R2) {
14384 gen_shift(env, ctx, op1, rd, rs, rt);
14387 generate_exception(ctx, EXCP_RI);
14391 case OPC_SLT: /* Set on less than */
14393 gen_slt(env, ctx, op1, rd, rs, rt);
14395 case OPC_AND: /* Logic*/
14399 gen_logic(env, ctx, op1, rd, rs, rt);
14401 case OPC_MULT ... OPC_DIVU:
14403 check_insn(env, ctx, INSN_VR54XX);
14404 op1 = MASK_MUL_VR54XX(ctx->opcode);
14405 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14407 gen_muldiv(ctx, op1, rs, rt);
14409 case OPC_JR ... OPC_JALR:
14410 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14413 case OPC_TGE ... OPC_TEQ: /* Traps */
14415 gen_trap(ctx, op1, rs, rt, -1);
14417 case OPC_MFHI: /* Move from HI/LO */
14419 gen_HILO(ctx, op1, rd);
14422 case OPC_MTLO: /* Move to HI/LO */
14423 gen_HILO(ctx, op1, rs);
14425 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14426 #ifdef MIPS_STRICT_STANDARD
14427 MIPS_INVAL("PMON / selsl");
14428 generate_exception(ctx, EXCP_RI);
14430 gen_helper_0e0i(pmon, sa);
14434 generate_exception(ctx, EXCP_SYSCALL);
14435 ctx->bstate = BS_STOP;
14438 generate_exception(ctx, EXCP_BREAK);
14441 #ifdef MIPS_STRICT_STANDARD
14442 MIPS_INVAL("SPIM");
14443 generate_exception(ctx, EXCP_RI);
14445 /* Implemented as RI exception for now. */
14446 MIPS_INVAL("spim (unofficial)");
14447 generate_exception(ctx, EXCP_RI);
14451 /* Treat as NOP. */
14455 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14456 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14457 check_cp1_enabled(ctx);
14458 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14459 (ctx->opcode >> 16) & 1);
14461 generate_exception_err(ctx, EXCP_CpU, 1);
14465 #if defined(TARGET_MIPS64)
14466 /* MIPS64 specific opcodes */
14471 check_insn(env, ctx, ISA_MIPS3);
14472 check_mips_64(ctx);
14473 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14476 switch ((ctx->opcode >> 21) & 0x1f) {
14478 /* drotr is decoded as dsrl on non-R2 CPUs */
14479 if (env->insn_flags & ISA_MIPS32R2) {
14484 check_insn(env, ctx, ISA_MIPS3);
14485 check_mips_64(ctx);
14486 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14489 generate_exception(ctx, EXCP_RI);
14494 switch ((ctx->opcode >> 21) & 0x1f) {
14496 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14497 if (env->insn_flags & ISA_MIPS32R2) {
14502 check_insn(env, ctx, ISA_MIPS3);
14503 check_mips_64(ctx);
14504 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14507 generate_exception(ctx, EXCP_RI);
14511 case OPC_DADD ... OPC_DSUBU:
14512 check_insn(env, ctx, ISA_MIPS3);
14513 check_mips_64(ctx);
14514 gen_arith(env, ctx, op1, rd, rs, rt);
14518 check_insn(env, ctx, ISA_MIPS3);
14519 check_mips_64(ctx);
14520 gen_shift(env, ctx, op1, rd, rs, rt);
14523 switch ((ctx->opcode >> 6) & 0x1f) {
14525 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14526 if (env->insn_flags & ISA_MIPS32R2) {
14531 check_insn(env, ctx, ISA_MIPS3);
14532 check_mips_64(ctx);
14533 gen_shift(env, ctx, op1, rd, rs, rt);
14536 generate_exception(ctx, EXCP_RI);
14540 case OPC_DMULT ... OPC_DDIVU:
14541 check_insn(env, ctx, ISA_MIPS3);
14542 check_mips_64(ctx);
14543 gen_muldiv(ctx, op1, rs, rt);
14546 default: /* Invalid */
14547 MIPS_INVAL("special");
14548 generate_exception(ctx, EXCP_RI);
14553 op1 = MASK_SPECIAL2(ctx->opcode);
14555 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14556 case OPC_MSUB ... OPC_MSUBU:
14557 check_insn(env, ctx, ISA_MIPS32);
14558 gen_muldiv(ctx, op1, rs, rt);
14561 gen_arith(env, ctx, op1, rd, rs, rt);
14565 check_insn(env, ctx, ISA_MIPS32);
14566 gen_cl(ctx, op1, rd, rs);
14569 /* XXX: not clear which exception should be raised
14570 * when in debug mode...
14572 check_insn(env, ctx, ISA_MIPS32);
14573 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14574 generate_exception(ctx, EXCP_DBp);
14576 generate_exception(ctx, EXCP_DBp);
14578 /* Treat as NOP. */
14581 case OPC_DIVU_G_2F:
14582 case OPC_MULT_G_2F:
14583 case OPC_MULTU_G_2F:
14585 case OPC_MODU_G_2F:
14586 check_insn(env, ctx, INSN_LOONGSON2F);
14587 gen_loongson_integer(ctx, op1, rd, rs, rt);
14589 #if defined(TARGET_MIPS64)
14592 check_insn(env, ctx, ISA_MIPS64);
14593 check_mips_64(ctx);
14594 gen_cl(ctx, op1, rd, rs);
14596 case OPC_DMULT_G_2F:
14597 case OPC_DMULTU_G_2F:
14598 case OPC_DDIV_G_2F:
14599 case OPC_DDIVU_G_2F:
14600 case OPC_DMOD_G_2F:
14601 case OPC_DMODU_G_2F:
14602 check_insn(env, ctx, INSN_LOONGSON2F);
14603 gen_loongson_integer(ctx, op1, rd, rs, rt);
14606 default: /* Invalid */
14607 MIPS_INVAL("special2");
14608 generate_exception(ctx, EXCP_RI);
14613 op1 = MASK_SPECIAL3(ctx->opcode);
14617 check_insn(env, ctx, ISA_MIPS32R2);
14618 gen_bitops(ctx, op1, rt, rs, sa, rd);
14621 check_insn(env, ctx, ISA_MIPS32R2);
14622 op2 = MASK_BSHFL(ctx->opcode);
14623 gen_bshfl(ctx, op2, rt, rd);
14626 gen_rdhwr(env, ctx, rt, rd);
14629 check_insn(env, ctx, ASE_MT);
14631 TCGv t0 = tcg_temp_new();
14632 TCGv t1 = tcg_temp_new();
14634 gen_load_gpr(t0, rt);
14635 gen_load_gpr(t1, rs);
14636 gen_helper_fork(t0, t1);
14642 check_insn(env, ctx, ASE_MT);
14644 TCGv t0 = tcg_temp_new();
14646 save_cpu_state(ctx, 1);
14647 gen_load_gpr(t0, rs);
14648 gen_helper_yield(t0, cpu_env, t0);
14649 gen_store_gpr(t0, rd);
14653 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14654 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14655 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14656 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14657 * the same mask and op1. */
14658 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14659 op2 = MASK_ADDUH_QB(ctx->opcode);
14662 case OPC_ADDUH_R_QB:
14664 case OPC_ADDQH_R_PH:
14666 case OPC_ADDQH_R_W:
14668 case OPC_SUBUH_R_QB:
14670 case OPC_SUBQH_R_PH:
14672 case OPC_SUBQH_R_W:
14673 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14678 case OPC_MULQ_RS_W:
14679 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14682 MIPS_INVAL("MASK ADDUH.QB");
14683 generate_exception(ctx, EXCP_RI);
14686 } else if (env->insn_flags & INSN_LOONGSON2E) {
14687 gen_loongson_integer(ctx, op1, rd, rs, rt);
14689 generate_exception(ctx, EXCP_RI);
14693 op2 = MASK_LX(ctx->opcode);
14695 #if defined(TARGET_MIPS64)
14701 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14703 default: /* Invalid */
14704 MIPS_INVAL("MASK LX");
14705 generate_exception(ctx, EXCP_RI);
14709 case OPC_ABSQ_S_PH_DSP:
14710 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14712 case OPC_ABSQ_S_QB:
14713 case OPC_ABSQ_S_PH:
14715 case OPC_PRECEQ_W_PHL:
14716 case OPC_PRECEQ_W_PHR:
14717 case OPC_PRECEQU_PH_QBL:
14718 case OPC_PRECEQU_PH_QBR:
14719 case OPC_PRECEQU_PH_QBLA:
14720 case OPC_PRECEQU_PH_QBRA:
14721 case OPC_PRECEU_PH_QBL:
14722 case OPC_PRECEU_PH_QBR:
14723 case OPC_PRECEU_PH_QBLA:
14724 case OPC_PRECEU_PH_QBRA:
14725 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14732 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14735 MIPS_INVAL("MASK ABSQ_S.PH");
14736 generate_exception(ctx, EXCP_RI);
14740 case OPC_ADDU_QB_DSP:
14741 op2 = MASK_ADDU_QB(ctx->opcode);
14744 case OPC_ADDQ_S_PH:
14747 case OPC_ADDU_S_QB:
14749 case OPC_ADDU_S_PH:
14751 case OPC_SUBQ_S_PH:
14754 case OPC_SUBU_S_QB:
14756 case OPC_SUBU_S_PH:
14760 case OPC_RADDU_W_QB:
14761 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14763 case OPC_MULEU_S_PH_QBL:
14764 case OPC_MULEU_S_PH_QBR:
14765 case OPC_MULQ_RS_PH:
14766 case OPC_MULEQ_S_W_PHL:
14767 case OPC_MULEQ_S_W_PHR:
14768 case OPC_MULQ_S_PH:
14769 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14771 default: /* Invalid */
14772 MIPS_INVAL("MASK ADDU.QB");
14773 generate_exception(ctx, EXCP_RI);
14778 case OPC_CMPU_EQ_QB_DSP:
14779 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14781 case OPC_PRECR_SRA_PH_W:
14782 case OPC_PRECR_SRA_R_PH_W:
14783 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14785 case OPC_PRECR_QB_PH:
14786 case OPC_PRECRQ_QB_PH:
14787 case OPC_PRECRQ_PH_W:
14788 case OPC_PRECRQ_RS_PH_W:
14789 case OPC_PRECRQU_S_QB_PH:
14790 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14792 case OPC_CMPU_EQ_QB:
14793 case OPC_CMPU_LT_QB:
14794 case OPC_CMPU_LE_QB:
14795 case OPC_CMP_EQ_PH:
14796 case OPC_CMP_LT_PH:
14797 case OPC_CMP_LE_PH:
14798 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14800 case OPC_CMPGU_EQ_QB:
14801 case OPC_CMPGU_LT_QB:
14802 case OPC_CMPGU_LE_QB:
14803 case OPC_CMPGDU_EQ_QB:
14804 case OPC_CMPGDU_LT_QB:
14805 case OPC_CMPGDU_LE_QB:
14808 case OPC_PACKRL_PH:
14809 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14811 default: /* Invalid */
14812 MIPS_INVAL("MASK CMPU.EQ.QB");
14813 generate_exception(ctx, EXCP_RI);
14817 case OPC_SHLL_QB_DSP:
14818 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14820 case OPC_DPA_W_PH_DSP:
14821 op2 = MASK_DPA_W_PH(ctx->opcode);
14823 case OPC_DPAU_H_QBL:
14824 case OPC_DPAU_H_QBR:
14825 case OPC_DPSU_H_QBL:
14826 case OPC_DPSU_H_QBR:
14828 case OPC_DPAX_W_PH:
14829 case OPC_DPAQ_S_W_PH:
14830 case OPC_DPAQX_S_W_PH:
14831 case OPC_DPAQX_SA_W_PH:
14833 case OPC_DPSX_W_PH:
14834 case OPC_DPSQ_S_W_PH:
14835 case OPC_DPSQX_S_W_PH:
14836 case OPC_DPSQX_SA_W_PH:
14837 case OPC_MULSAQ_S_W_PH:
14838 case OPC_DPAQ_SA_L_W:
14839 case OPC_DPSQ_SA_L_W:
14840 case OPC_MAQ_S_W_PHL:
14841 case OPC_MAQ_S_W_PHR:
14842 case OPC_MAQ_SA_W_PHL:
14843 case OPC_MAQ_SA_W_PHR:
14844 case OPC_MULSA_W_PH:
14845 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14847 default: /* Invalid */
14848 MIPS_INVAL("MASK DPAW.PH");
14849 generate_exception(ctx, EXCP_RI);
14854 op2 = MASK_INSV(ctx->opcode);
14866 t0 = tcg_temp_new();
14867 t1 = tcg_temp_new();
14869 gen_load_gpr(t0, rt);
14870 gen_load_gpr(t1, rs);
14872 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14878 default: /* Invalid */
14879 MIPS_INVAL("MASK INSV");
14880 generate_exception(ctx, EXCP_RI);
14884 case OPC_APPEND_DSP:
14886 op2 = MASK_APPEND(ctx->opcode);
14887 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14889 case OPC_EXTR_W_DSP:
14890 op2 = MASK_EXTR_W(ctx->opcode);
14894 case OPC_EXTR_RS_W:
14896 case OPC_EXTRV_S_H:
14898 case OPC_EXTRV_R_W:
14899 case OPC_EXTRV_RS_W:
14904 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14907 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14913 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14915 default: /* Invalid */
14916 MIPS_INVAL("MASK EXTR.W");
14917 generate_exception(ctx, EXCP_RI);
14921 #if defined(TARGET_MIPS64)
14922 case OPC_DEXTM ... OPC_DEXT:
14923 case OPC_DINSM ... OPC_DINS:
14924 check_insn(env, ctx, ISA_MIPS64R2);
14925 check_mips_64(ctx);
14926 gen_bitops(ctx, op1, rt, rs, sa, rd);
14929 check_insn(env, ctx, ISA_MIPS64R2);
14930 check_mips_64(ctx);
14931 op2 = MASK_DBSHFL(ctx->opcode);
14932 gen_bshfl(ctx, op2, rt, rd);
14934 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14935 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14936 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14937 check_insn(env, ctx, INSN_LOONGSON2E);
14938 gen_loongson_integer(ctx, op1, rd, rs, rt);
14940 case OPC_ABSQ_S_QH_DSP:
14941 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14943 case OPC_PRECEQ_L_PWL:
14944 case OPC_PRECEQ_L_PWR:
14945 case OPC_PRECEQ_PW_QHL:
14946 case OPC_PRECEQ_PW_QHR:
14947 case OPC_PRECEQ_PW_QHLA:
14948 case OPC_PRECEQ_PW_QHRA:
14949 case OPC_PRECEQU_QH_OBL:
14950 case OPC_PRECEQU_QH_OBR:
14951 case OPC_PRECEQU_QH_OBLA:
14952 case OPC_PRECEQU_QH_OBRA:
14953 case OPC_PRECEU_QH_OBL:
14954 case OPC_PRECEU_QH_OBR:
14955 case OPC_PRECEU_QH_OBLA:
14956 case OPC_PRECEU_QH_OBRA:
14957 case OPC_ABSQ_S_OB:
14958 case OPC_ABSQ_S_PW:
14959 case OPC_ABSQ_S_QH:
14960 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14968 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14970 default: /* Invalid */
14971 MIPS_INVAL("MASK ABSQ_S.QH");
14972 generate_exception(ctx, EXCP_RI);
14976 case OPC_ADDU_OB_DSP:
14977 op2 = MASK_ADDU_OB(ctx->opcode);
14979 case OPC_RADDU_L_OB:
14981 case OPC_SUBQ_S_PW:
14983 case OPC_SUBQ_S_QH:
14985 case OPC_SUBU_S_OB:
14987 case OPC_SUBU_S_QH:
14989 case OPC_SUBUH_R_OB:
14991 case OPC_ADDQ_S_PW:
14993 case OPC_ADDQ_S_QH:
14995 case OPC_ADDU_S_OB:
14997 case OPC_ADDU_S_QH:
14999 case OPC_ADDUH_R_OB:
15000 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15002 case OPC_MULEQ_S_PW_QHL:
15003 case OPC_MULEQ_S_PW_QHR:
15004 case OPC_MULEU_S_QH_OBL:
15005 case OPC_MULEU_S_QH_OBR:
15006 case OPC_MULQ_RS_QH:
15007 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15009 default: /* Invalid */
15010 MIPS_INVAL("MASK ADDU.OB");
15011 generate_exception(ctx, EXCP_RI);
15015 case OPC_CMPU_EQ_OB_DSP:
15016 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15018 case OPC_PRECR_SRA_QH_PW:
15019 case OPC_PRECR_SRA_R_QH_PW:
15020 /* Return value is rt. */
15021 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15023 case OPC_PRECR_OB_QH:
15024 case OPC_PRECRQ_OB_QH:
15025 case OPC_PRECRQ_PW_L:
15026 case OPC_PRECRQ_QH_PW:
15027 case OPC_PRECRQ_RS_QH_PW:
15028 case OPC_PRECRQU_S_OB_QH:
15029 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15031 case OPC_CMPU_EQ_OB:
15032 case OPC_CMPU_LT_OB:
15033 case OPC_CMPU_LE_OB:
15034 case OPC_CMP_EQ_QH:
15035 case OPC_CMP_LT_QH:
15036 case OPC_CMP_LE_QH:
15037 case OPC_CMP_EQ_PW:
15038 case OPC_CMP_LT_PW:
15039 case OPC_CMP_LE_PW:
15040 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15042 case OPC_CMPGDU_EQ_OB:
15043 case OPC_CMPGDU_LT_OB:
15044 case OPC_CMPGDU_LE_OB:
15045 case OPC_CMPGU_EQ_OB:
15046 case OPC_CMPGU_LT_OB:
15047 case OPC_CMPGU_LE_OB:
15048 case OPC_PACKRL_PW:
15052 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15054 default: /* Invalid */
15055 MIPS_INVAL("MASK CMPU_EQ.OB");
15056 generate_exception(ctx, EXCP_RI);
15060 case OPC_DAPPEND_DSP:
15062 op2 = MASK_DAPPEND(ctx->opcode);
15063 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15065 case OPC_DEXTR_W_DSP:
15066 op2 = MASK_DEXTR_W(ctx->opcode);
15073 case OPC_DEXTR_R_L:
15074 case OPC_DEXTR_RS_L:
15076 case OPC_DEXTR_R_W:
15077 case OPC_DEXTR_RS_W:
15078 case OPC_DEXTR_S_H:
15080 case OPC_DEXTRV_R_L:
15081 case OPC_DEXTRV_RS_L:
15082 case OPC_DEXTRV_S_H:
15084 case OPC_DEXTRV_R_W:
15085 case OPC_DEXTRV_RS_W:
15086 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15091 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15093 default: /* Invalid */
15094 MIPS_INVAL("MASK EXTR.W");
15095 generate_exception(ctx, EXCP_RI);
15099 case OPC_DPAQ_W_QH_DSP:
15100 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15102 case OPC_DPAU_H_OBL:
15103 case OPC_DPAU_H_OBR:
15104 case OPC_DPSU_H_OBL:
15105 case OPC_DPSU_H_OBR:
15107 case OPC_DPAQ_S_W_QH:
15109 case OPC_DPSQ_S_W_QH:
15110 case OPC_MULSAQ_S_W_QH:
15111 case OPC_DPAQ_SA_L_PW:
15112 case OPC_DPSQ_SA_L_PW:
15113 case OPC_MULSAQ_S_L_PW:
15114 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15116 case OPC_MAQ_S_W_QHLL:
15117 case OPC_MAQ_S_W_QHLR:
15118 case OPC_MAQ_S_W_QHRL:
15119 case OPC_MAQ_S_W_QHRR:
15120 case OPC_MAQ_SA_W_QHLL:
15121 case OPC_MAQ_SA_W_QHLR:
15122 case OPC_MAQ_SA_W_QHRL:
15123 case OPC_MAQ_SA_W_QHRR:
15124 case OPC_MAQ_S_L_PWL:
15125 case OPC_MAQ_S_L_PWR:
15130 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15132 default: /* Invalid */
15133 MIPS_INVAL("MASK DPAQ.W.QH");
15134 generate_exception(ctx, EXCP_RI);
15138 case OPC_DINSV_DSP:
15139 op2 = MASK_INSV(ctx->opcode);
15151 t0 = tcg_temp_new();
15152 t1 = tcg_temp_new();
15154 gen_load_gpr(t0, rt);
15155 gen_load_gpr(t1, rs);
15157 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15160 default: /* Invalid */
15161 MIPS_INVAL("MASK DINSV");
15162 generate_exception(ctx, EXCP_RI);
15166 case OPC_SHLL_OB_DSP:
15167 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15170 default: /* Invalid */
15171 MIPS_INVAL("special3");
15172 generate_exception(ctx, EXCP_RI);
15177 op1 = MASK_REGIMM(ctx->opcode);
15179 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15180 case OPC_BLTZAL ... OPC_BGEZALL:
15181 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15184 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15186 gen_trap(ctx, op1, rs, -1, imm);
15189 check_insn(env, ctx, ISA_MIPS32R2);
15190 /* Treat as NOP. */
15192 case OPC_BPOSGE32: /* MIPS DSP branch */
15193 #if defined(TARGET_MIPS64)
15197 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15200 default: /* Invalid */
15201 MIPS_INVAL("regimm");
15202 generate_exception(ctx, EXCP_RI);
15207 check_cp0_enabled(ctx);
15208 op1 = MASK_CP0(ctx->opcode);
15214 #if defined(TARGET_MIPS64)
15218 #ifndef CONFIG_USER_ONLY
15219 gen_cp0(env, ctx, op1, rt, rd);
15220 #endif /* !CONFIG_USER_ONLY */
15222 case OPC_C0_FIRST ... OPC_C0_LAST:
15223 #ifndef CONFIG_USER_ONLY
15224 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15225 #endif /* !CONFIG_USER_ONLY */
15228 #ifndef CONFIG_USER_ONLY
15230 TCGv t0 = tcg_temp_new();
15232 op2 = MASK_MFMC0(ctx->opcode);
15235 check_insn(env, ctx, ASE_MT);
15236 gen_helper_dmt(t0);
15237 gen_store_gpr(t0, rt);
15240 check_insn(env, ctx, ASE_MT);
15241 gen_helper_emt(t0);
15242 gen_store_gpr(t0, rt);
15245 check_insn(env, ctx, ASE_MT);
15246 gen_helper_dvpe(t0, cpu_env);
15247 gen_store_gpr(t0, rt);
15250 check_insn(env, ctx, ASE_MT);
15251 gen_helper_evpe(t0, cpu_env);
15252 gen_store_gpr(t0, rt);
15255 check_insn(env, ctx, ISA_MIPS32R2);
15256 save_cpu_state(ctx, 1);
15257 gen_helper_di(t0, cpu_env);
15258 gen_store_gpr(t0, rt);
15259 /* Stop translation as we may have switched the execution mode */
15260 ctx->bstate = BS_STOP;
15263 check_insn(env, ctx, ISA_MIPS32R2);
15264 save_cpu_state(ctx, 1);
15265 gen_helper_ei(t0, cpu_env);
15266 gen_store_gpr(t0, rt);
15267 /* Stop translation as we may have switched the execution mode */
15268 ctx->bstate = BS_STOP;
15270 default: /* Invalid */
15271 MIPS_INVAL("mfmc0");
15272 generate_exception(ctx, EXCP_RI);
15277 #endif /* !CONFIG_USER_ONLY */
15280 check_insn(env, ctx, ISA_MIPS32R2);
15281 gen_load_srsgpr(rt, rd);
15284 check_insn(env, ctx, ISA_MIPS32R2);
15285 gen_store_srsgpr(rt, rd);
15289 generate_exception(ctx, EXCP_RI);
15293 case OPC_ADDI: /* Arithmetic with immediate opcode */
15295 gen_arith_imm(env, ctx, op, rt, rs, imm);
15297 case OPC_SLTI: /* Set on less than with immediate opcode */
15299 gen_slt_imm(env, ctx, op, rt, rs, imm);
15301 case OPC_ANDI: /* Arithmetic with immediate opcode */
15305 gen_logic_imm(env, ctx, op, rt, rs, imm);
15307 case OPC_J ... OPC_JAL: /* Jump */
15308 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15309 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15312 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15313 case OPC_BEQL ... OPC_BGTZL:
15314 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15317 case OPC_LB ... OPC_LWR: /* Load and stores */
15319 gen_ld(env, ctx, op, rt, rs, imm);
15321 case OPC_SB ... OPC_SW:
15323 gen_st(ctx, op, rt, rs, imm);
15326 gen_st_cond(ctx, op, rt, rs, imm);
15329 check_cp0_enabled(ctx);
15330 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15331 /* Treat as NOP. */
15334 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15335 /* Treat as NOP. */
15338 /* Floating point (COP1). */
15343 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15347 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15348 check_cp1_enabled(ctx);
15349 op1 = MASK_CP1(ctx->opcode);
15353 check_insn(env, ctx, ISA_MIPS32R2);
15358 gen_cp1(ctx, op1, rt, rd);
15360 #if defined(TARGET_MIPS64)
15363 check_insn(env, ctx, ISA_MIPS3);
15364 gen_cp1(ctx, op1, rt, rd);
15370 check_insn(env, ctx, ASE_MIPS3D);
15373 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15374 (rt >> 2) & 0x7, imm << 2);
15382 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15387 generate_exception (ctx, EXCP_RI);
15391 generate_exception_err(ctx, EXCP_CpU, 1);
15400 /* COP2: Not implemented. */
15401 generate_exception_err(ctx, EXCP_CpU, 2);
15404 check_insn(env, ctx, INSN_LOONGSON2F);
15405 /* Note that these instructions use different fields. */
15406 gen_loongson_multimedia(ctx, sa, rd, rt);
15410 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15411 check_cp1_enabled(ctx);
15412 op1 = MASK_CP3(ctx->opcode);
15420 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15423 /* Treat as NOP. */
15438 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15442 generate_exception (ctx, EXCP_RI);
15446 generate_exception_err(ctx, EXCP_CpU, 1);
15450 #if defined(TARGET_MIPS64)
15451 /* MIPS64 opcodes */
15453 case OPC_LDL ... OPC_LDR:
15456 check_insn(env, ctx, ISA_MIPS3);
15457 check_mips_64(ctx);
15458 gen_ld(env, ctx, op, rt, rs, imm);
15460 case OPC_SDL ... OPC_SDR:
15462 check_insn(env, ctx, ISA_MIPS3);
15463 check_mips_64(ctx);
15464 gen_st(ctx, op, rt, rs, imm);
15467 check_insn(env, ctx, ISA_MIPS3);
15468 check_mips_64(ctx);
15469 gen_st_cond(ctx, op, rt, rs, imm);
15473 check_insn(env, ctx, ISA_MIPS3);
15474 check_mips_64(ctx);
15475 gen_arith_imm(env, ctx, op, rt, rs, imm);
15479 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15480 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15481 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15485 check_insn(env, ctx, ASE_MDMX);
15486 /* MDMX: Not implemented. */
15487 default: /* Invalid */
15488 MIPS_INVAL("major opcode");
15489 generate_exception(ctx, EXCP_RI);
15495 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15499 target_ulong pc_start;
15500 uint16_t *gen_opc_end;
15509 qemu_log("search pc %d\n", search_pc);
15512 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15515 ctx.singlestep_enabled = env->singlestep_enabled;
15517 ctx.bstate = BS_NONE;
15518 /* Restore delay slot state from the tb context. */
15519 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15520 restore_cpu_state(env, &ctx);
15521 #ifdef CONFIG_USER_ONLY
15522 ctx.mem_idx = MIPS_HFLAG_UM;
15524 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15527 max_insns = tb->cflags & CF_COUNT_MASK;
15528 if (max_insns == 0)
15529 max_insns = CF_COUNT_MASK;
15530 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15531 gen_icount_start();
15532 while (ctx.bstate == BS_NONE) {
15533 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15534 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15535 if (bp->pc == ctx.pc) {
15536 save_cpu_state(&ctx, 1);
15537 ctx.bstate = BS_BRANCH;
15538 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15539 /* Include the breakpoint location or the tb won't
15540 * be flushed when it must be. */
15542 goto done_generating;
15548 j = gen_opc_ptr - gen_opc_buf;
15552 gen_opc_instr_start[lj++] = 0;
15554 gen_opc_pc[lj] = ctx.pc;
15555 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15556 gen_opc_btarget[lj] = ctx.btarget;
15557 gen_opc_instr_start[lj] = 1;
15558 gen_opc_icount[lj] = num_insns;
15560 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15564 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15565 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15567 decode_opc(env, &ctx, &is_branch);
15568 } else if (env->insn_flags & ASE_MICROMIPS) {
15569 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15570 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15571 } else if (env->insn_flags & ASE_MIPS16) {
15572 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15573 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15575 generate_exception(&ctx, EXCP_RI);
15576 ctx.bstate = BS_STOP;
15580 handle_delay_slot(env, &ctx, insn_bytes);
15582 ctx.pc += insn_bytes;
15586 /* Execute a branch and its delay slot as a single instruction.
15587 This is what GDB expects and is consistent with what the
15588 hardware does (e.g. if a delay slot instruction faults, the
15589 reported PC is the PC of the branch). */
15590 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15593 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15596 if (gen_opc_ptr >= gen_opc_end)
15599 if (num_insns >= max_insns)
15605 if (tb->cflags & CF_LAST_IO)
15607 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15608 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15609 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15611 switch (ctx.bstate) {
15613 gen_goto_tb(&ctx, 0, ctx.pc);
15616 save_cpu_state(&ctx, 0);
15617 gen_goto_tb(&ctx, 0, ctx.pc);
15620 tcg_gen_exit_tb(0);
15628 gen_icount_end(tb, num_insns);
15629 *gen_opc_ptr = INDEX_op_end;
15631 j = gen_opc_ptr - gen_opc_buf;
15634 gen_opc_instr_start[lj++] = 0;
15636 tb->size = ctx.pc - pc_start;
15637 tb->icount = num_insns;
15641 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15642 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15643 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15649 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15651 gen_intermediate_code_internal(env, tb, 0);
15654 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15656 gen_intermediate_code_internal(env, tb, 1);
15659 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15663 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15665 #define printfpr(fp) \
15668 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15669 " fd:%13g fs:%13g psu: %13g\n", \
15670 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15671 (double)(fp)->fd, \
15672 (double)(fp)->fs[FP_ENDIAN_IDX], \
15673 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15676 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15677 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15678 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15679 " fd:%13g fs:%13g psu:%13g\n", \
15680 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15682 (double)tmp.fs[FP_ENDIAN_IDX], \
15683 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15688 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15689 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15690 get_float_exception_flags(&env->active_fpu.fp_status));
15691 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15692 fpu_fprintf(f, "%3s: ", fregnames[i]);
15693 printfpr(&env->active_fpu.fpr[i]);
15699 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15700 /* Debug help: The architecture requires 32bit code to maintain proper
15701 sign-extended values on 64bit machines. */
15703 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15706 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15707 fprintf_function cpu_fprintf,
15712 if (!SIGN_EXT_P(env->active_tc.PC))
15713 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15714 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15715 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15716 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15717 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15718 if (!SIGN_EXT_P(env->btarget))
15719 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15721 for (i = 0; i < 32; i++) {
15722 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15723 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15726 if (!SIGN_EXT_P(env->CP0_EPC))
15727 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15728 if (!SIGN_EXT_P(env->lladdr))
15729 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15733 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15738 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15739 " LO=0x" TARGET_FMT_lx " ds %04x "
15740 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15741 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15742 env->hflags, env->btarget, env->bcond);
15743 for (i = 0; i < 32; i++) {
15745 cpu_fprintf(f, "GPR%02d:", i);
15746 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15748 cpu_fprintf(f, "\n");
15751 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15752 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15753 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15754 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15755 if (env->hflags & MIPS_HFLAG_FPU)
15756 fpu_dump_state(env, f, cpu_fprintf, flags);
15757 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15758 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15762 static void mips_tcg_init(void)
15767 /* Initialize various static tables. */
15771 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15772 TCGV_UNUSED(cpu_gpr[0]);
15773 for (i = 1; i < 32; i++)
15774 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15775 offsetof(CPUMIPSState, active_tc.gpr[i]),
15778 for (i = 0; i < 32; i++) {
15779 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15780 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15783 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15784 offsetof(CPUMIPSState, active_tc.PC), "PC");
15785 for (i = 0; i < MIPS_DSP_ACC; i++) {
15786 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15787 offsetof(CPUMIPSState, active_tc.HI[i]),
15789 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15790 offsetof(CPUMIPSState, active_tc.LO[i]),
15792 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15793 offsetof(CPUMIPSState, active_tc.ACX[i]),
15796 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15797 offsetof(CPUMIPSState, active_tc.DSPControl),
15799 bcond = tcg_global_mem_new(TCG_AREG0,
15800 offsetof(CPUMIPSState, bcond), "bcond");
15801 btarget = tcg_global_mem_new(TCG_AREG0,
15802 offsetof(CPUMIPSState, btarget), "btarget");
15803 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15804 offsetof(CPUMIPSState, hflags), "hflags");
15806 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15807 offsetof(CPUMIPSState, active_fpu.fcr0),
15809 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15810 offsetof(CPUMIPSState, active_fpu.fcr31),
15813 /* register helpers */
15814 #define GEN_HELPER 2
15815 #include "helper.h"
15820 #include "translate_init.c"
15822 MIPSCPU *cpu_mips_init(const char *cpu_model)
15826 const mips_def_t *def;
15828 def = cpu_mips_find_by_name(cpu_model);
15831 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15833 env->cpu_model = def;
15834 env->cpu_model_str = cpu_model;
15836 #ifndef CONFIG_USER_ONLY
15837 mmu_init(env, def);
15839 fpu_init(env, def);
15840 mvp_init(env, def);
15842 cpu_reset(CPU(cpu));
15843 qemu_init_vcpu(env);
15847 void cpu_state_reset(CPUMIPSState *env)
15849 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15850 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15851 log_cpu_state(env, 0);
15854 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15857 /* Reset registers to their default values */
15858 env->CP0_PRid = env->cpu_model->CP0_PRid;
15859 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15860 #ifdef TARGET_WORDS_BIGENDIAN
15861 env->CP0_Config0 |= (1 << CP0C0_BE);
15863 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15864 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15865 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15866 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15867 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15868 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15869 << env->cpu_model->CP0_LLAddr_shift;
15870 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15871 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15872 env->CCRes = env->cpu_model->CCRes;
15873 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15874 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15875 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15876 env->current_tc = 0;
15877 env->SEGBITS = env->cpu_model->SEGBITS;
15878 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15879 #if defined(TARGET_MIPS64)
15880 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15881 env->SEGMask |= 3ULL << 62;
15884 env->PABITS = env->cpu_model->PABITS;
15885 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15886 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15887 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15888 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15889 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15890 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15891 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15892 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15893 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15894 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15895 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15896 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15897 env->insn_flags = env->cpu_model->insn_flags;
15899 #if defined(CONFIG_USER_ONLY)
15900 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15901 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15902 hardware registers. */
15903 env->CP0_HWREna |= 0x0000000F;
15904 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15905 env->CP0_Status |= (1 << CP0St_CU1);
15907 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15908 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15909 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15910 env->hflags |= MIPS_HFLAG_DSP;
15913 if (env->hflags & MIPS_HFLAG_BMASK) {
15914 /* If the exception was raised from a delay slot,
15915 come back to the jump. */
15916 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15918 env->CP0_ErrorEPC = env->active_tc.PC;
15920 env->active_tc.PC = (int32_t)0xBFC00000;
15921 env->CP0_Random = env->tlb->nb_tlb - 1;
15922 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15923 env->CP0_Wired = 0;
15924 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15925 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15926 /* vectored interrupts not implemented, timer on int 7,
15927 no performance counters. */
15928 env->CP0_IntCtl = 0xe0000000;
15932 for (i = 0; i < 7; i++) {
15933 env->CP0_WatchLo[i] = 0;
15934 env->CP0_WatchHi[i] = 0x80000000;
15936 env->CP0_WatchLo[7] = 0;
15937 env->CP0_WatchHi[7] = 0;
15939 /* Count register increments in debug mode, EJTAG version 1 */
15940 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15942 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15945 /* Only TC0 on VPE 0 starts as active. */
15946 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15947 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15948 env->tcs[i].CP0_TCHalt = 1;
15950 env->active_tc.CP0_TCHalt = 1;
15953 if (!env->cpu_index) {
15954 /* VPE0 starts up enabled. */
15955 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15956 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15958 /* TC0 starts up unhalted. */
15960 env->active_tc.CP0_TCHalt = 0;
15961 env->tcs[0].CP0_TCHalt = 0;
15962 /* With thread 0 active. */
15963 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15964 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15968 compute_hflags(env);
15969 env->exception_index = EXCP_NONE;
15972 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
15974 env->active_tc.PC = gen_opc_pc[pc_pos];
15975 env->hflags &= ~MIPS_HFLAG_BMASK;
15976 env->hflags |= gen_opc_hflags[pc_pos];
15977 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15978 case MIPS_HFLAG_BR:
15980 case MIPS_HFLAG_BC:
15981 case MIPS_HFLAG_BL:
15983 env->btarget = gen_opc_btarget[pc_pos];