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.
2366 For add & sub, we must generate the overflow exception when needed. */
2371 l1 = gen_new_label();
2374 if (likely(rt != 0))
2375 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2381 if (likely(rt != 0))
2382 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2387 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2389 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2392 (void)opn; /* avoid a compiler warning */
2393 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2397 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2398 int rd, int rs, int rt)
2400 const char *opn = "logic";
2403 /* If no destination, treat it as a NOP. */
2410 if (likely(rs != 0 && rt != 0)) {
2411 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2413 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2418 if (rs != 0 && rt != 0) {
2419 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2420 } else if (rs == 0 && rt != 0) {
2421 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2422 } else if (rs != 0 && rt == 0) {
2423 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2425 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2430 if (likely(rs != 0 && rt != 0)) {
2431 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2432 } else if (rs == 0 && rt != 0) {
2433 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2434 } else if (rs != 0 && rt == 0) {
2435 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2437 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2442 if (likely(rs != 0 && rt != 0)) {
2443 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2444 } else if (rs == 0 && rt != 0) {
2445 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2446 } else if (rs != 0 && rt == 0) {
2447 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2449 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2454 (void)opn; /* avoid a compiler warning */
2455 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2458 /* Set on lower than */
2459 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2460 int rd, int rs, int rt)
2462 const char *opn = "slt";
2466 /* If no destination, treat it as a NOP. */
2471 t0 = tcg_temp_new();
2472 t1 = tcg_temp_new();
2473 gen_load_gpr(t0, rs);
2474 gen_load_gpr(t1, rt);
2477 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2481 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2485 (void)opn; /* avoid a compiler warning */
2486 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2492 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2493 int rd, int rs, int rt)
2495 const char *opn = "shifts";
2499 /* If no destination, treat it as a NOP.
2500 For add & sub, we must generate the overflow exception when needed. */
2505 t0 = tcg_temp_new();
2506 t1 = tcg_temp_new();
2507 gen_load_gpr(t0, rs);
2508 gen_load_gpr(t1, rt);
2511 tcg_gen_andi_tl(t0, t0, 0x1f);
2512 tcg_gen_shl_tl(t0, t1, t0);
2513 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2517 tcg_gen_andi_tl(t0, t0, 0x1f);
2518 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2522 tcg_gen_ext32u_tl(t1, t1);
2523 tcg_gen_andi_tl(t0, t0, 0x1f);
2524 tcg_gen_shr_tl(t0, t1, t0);
2525 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2530 TCGv_i32 t2 = tcg_temp_new_i32();
2531 TCGv_i32 t3 = tcg_temp_new_i32();
2533 tcg_gen_trunc_tl_i32(t2, t0);
2534 tcg_gen_trunc_tl_i32(t3, t1);
2535 tcg_gen_andi_i32(t2, t2, 0x1f);
2536 tcg_gen_rotr_i32(t2, t3, t2);
2537 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2538 tcg_temp_free_i32(t2);
2539 tcg_temp_free_i32(t3);
2543 #if defined(TARGET_MIPS64)
2545 tcg_gen_andi_tl(t0, t0, 0x3f);
2546 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2550 tcg_gen_andi_tl(t0, t0, 0x3f);
2551 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2555 tcg_gen_andi_tl(t0, t0, 0x3f);
2556 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2560 tcg_gen_andi_tl(t0, t0, 0x3f);
2561 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2566 (void)opn; /* avoid a compiler warning */
2567 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2572 /* Arithmetic on HI/LO registers */
2573 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2575 const char *opn = "hilo";
2578 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2584 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2585 acc = ((ctx->opcode) >> 21) & 0x03;
2587 acc = ((ctx->opcode) >> 11) & 0x03;
2596 #if defined(TARGET_MIPS64)
2598 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2602 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2607 #if defined(TARGET_MIPS64)
2609 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2613 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2619 #if defined(TARGET_MIPS64)
2621 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2625 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2628 tcg_gen_movi_tl(cpu_HI[acc], 0);
2634 #if defined(TARGET_MIPS64)
2636 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2640 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2643 tcg_gen_movi_tl(cpu_LO[acc], 0);
2648 (void)opn; /* avoid a compiler warning */
2649 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2652 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2655 const char *opn = "mul/div";
2662 #if defined(TARGET_MIPS64)
2666 t0 = tcg_temp_local_new();
2667 t1 = tcg_temp_local_new();
2670 t0 = tcg_temp_new();
2671 t1 = tcg_temp_new();
2675 gen_load_gpr(t0, rs);
2676 gen_load_gpr(t1, rt);
2680 int l1 = gen_new_label();
2681 int l2 = gen_new_label();
2683 tcg_gen_ext32s_tl(t0, t0);
2684 tcg_gen_ext32s_tl(t1, t1);
2685 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2686 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2687 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2689 tcg_gen_mov_tl(cpu_LO[0], t0);
2690 tcg_gen_movi_tl(cpu_HI[0], 0);
2693 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2694 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2695 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2696 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2703 int l1 = gen_new_label();
2705 tcg_gen_ext32u_tl(t0, t0);
2706 tcg_gen_ext32u_tl(t1, t1);
2707 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2708 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2709 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2710 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2711 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2718 TCGv_i64 t2 = tcg_temp_new_i64();
2719 TCGv_i64 t3 = tcg_temp_new_i64();
2720 acc = ((ctx->opcode) >> 11) & 0x03;
2725 tcg_gen_ext_tl_i64(t2, t0);
2726 tcg_gen_ext_tl_i64(t3, t1);
2727 tcg_gen_mul_i64(t2, t2, t3);
2728 tcg_temp_free_i64(t3);
2729 tcg_gen_trunc_i64_tl(t0, t2);
2730 tcg_gen_shri_i64(t2, t2, 32);
2731 tcg_gen_trunc_i64_tl(t1, t2);
2732 tcg_temp_free_i64(t2);
2733 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2734 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2740 TCGv_i64 t2 = tcg_temp_new_i64();
2741 TCGv_i64 t3 = tcg_temp_new_i64();
2742 acc = ((ctx->opcode) >> 11) & 0x03;
2747 tcg_gen_ext32u_tl(t0, t0);
2748 tcg_gen_ext32u_tl(t1, t1);
2749 tcg_gen_extu_tl_i64(t2, t0);
2750 tcg_gen_extu_tl_i64(t3, t1);
2751 tcg_gen_mul_i64(t2, t2, t3);
2752 tcg_temp_free_i64(t3);
2753 tcg_gen_trunc_i64_tl(t0, t2);
2754 tcg_gen_shri_i64(t2, t2, 32);
2755 tcg_gen_trunc_i64_tl(t1, t2);
2756 tcg_temp_free_i64(t2);
2757 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2758 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2762 #if defined(TARGET_MIPS64)
2765 int l1 = gen_new_label();
2766 int l2 = gen_new_label();
2768 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2769 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2770 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2771 tcg_gen_mov_tl(cpu_LO[0], t0);
2772 tcg_gen_movi_tl(cpu_HI[0], 0);
2775 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2776 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2783 int l1 = gen_new_label();
2785 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2786 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2787 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2793 gen_helper_dmult(cpu_env, t0, t1);
2797 gen_helper_dmultu(cpu_env, t0, t1);
2803 TCGv_i64 t2 = tcg_temp_new_i64();
2804 TCGv_i64 t3 = tcg_temp_new_i64();
2805 acc = ((ctx->opcode) >> 11) & 0x03;
2810 tcg_gen_ext_tl_i64(t2, t0);
2811 tcg_gen_ext_tl_i64(t3, t1);
2812 tcg_gen_mul_i64(t2, t2, t3);
2813 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2814 tcg_gen_add_i64(t2, t2, t3);
2815 tcg_temp_free_i64(t3);
2816 tcg_gen_trunc_i64_tl(t0, t2);
2817 tcg_gen_shri_i64(t2, t2, 32);
2818 tcg_gen_trunc_i64_tl(t1, t2);
2819 tcg_temp_free_i64(t2);
2820 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2821 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2827 TCGv_i64 t2 = tcg_temp_new_i64();
2828 TCGv_i64 t3 = tcg_temp_new_i64();
2829 acc = ((ctx->opcode) >> 11) & 0x03;
2834 tcg_gen_ext32u_tl(t0, t0);
2835 tcg_gen_ext32u_tl(t1, t1);
2836 tcg_gen_extu_tl_i64(t2, t0);
2837 tcg_gen_extu_tl_i64(t3, t1);
2838 tcg_gen_mul_i64(t2, t2, t3);
2839 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2840 tcg_gen_add_i64(t2, t2, t3);
2841 tcg_temp_free_i64(t3);
2842 tcg_gen_trunc_i64_tl(t0, t2);
2843 tcg_gen_shri_i64(t2, t2, 32);
2844 tcg_gen_trunc_i64_tl(t1, t2);
2845 tcg_temp_free_i64(t2);
2846 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2847 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2853 TCGv_i64 t2 = tcg_temp_new_i64();
2854 TCGv_i64 t3 = tcg_temp_new_i64();
2855 acc = ((ctx->opcode) >> 11) & 0x03;
2860 tcg_gen_ext_tl_i64(t2, t0);
2861 tcg_gen_ext_tl_i64(t3, t1);
2862 tcg_gen_mul_i64(t2, t2, t3);
2863 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2864 tcg_gen_sub_i64(t2, t3, t2);
2865 tcg_temp_free_i64(t3);
2866 tcg_gen_trunc_i64_tl(t0, t2);
2867 tcg_gen_shri_i64(t2, t2, 32);
2868 tcg_gen_trunc_i64_tl(t1, t2);
2869 tcg_temp_free_i64(t2);
2870 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2871 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2877 TCGv_i64 t2 = tcg_temp_new_i64();
2878 TCGv_i64 t3 = tcg_temp_new_i64();
2879 acc = ((ctx->opcode) >> 11) & 0x03;
2884 tcg_gen_ext32u_tl(t0, t0);
2885 tcg_gen_ext32u_tl(t1, t1);
2886 tcg_gen_extu_tl_i64(t2, t0);
2887 tcg_gen_extu_tl_i64(t3, t1);
2888 tcg_gen_mul_i64(t2, t2, t3);
2889 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2890 tcg_gen_sub_i64(t2, t3, t2);
2891 tcg_temp_free_i64(t3);
2892 tcg_gen_trunc_i64_tl(t0, t2);
2893 tcg_gen_shri_i64(t2, t2, 32);
2894 tcg_gen_trunc_i64_tl(t1, t2);
2895 tcg_temp_free_i64(t2);
2896 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2897 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2903 generate_exception(ctx, EXCP_RI);
2906 (void)opn; /* avoid a compiler warning */
2907 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2913 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2914 int rd, int rs, int rt)
2916 const char *opn = "mul vr54xx";
2917 TCGv t0 = tcg_temp_new();
2918 TCGv t1 = tcg_temp_new();
2920 gen_load_gpr(t0, rs);
2921 gen_load_gpr(t1, rt);
2924 case OPC_VR54XX_MULS:
2925 gen_helper_muls(t0, cpu_env, t0, t1);
2928 case OPC_VR54XX_MULSU:
2929 gen_helper_mulsu(t0, cpu_env, t0, t1);
2932 case OPC_VR54XX_MACC:
2933 gen_helper_macc(t0, cpu_env, t0, t1);
2936 case OPC_VR54XX_MACCU:
2937 gen_helper_maccu(t0, cpu_env, t0, t1);
2940 case OPC_VR54XX_MSAC:
2941 gen_helper_msac(t0, cpu_env, t0, t1);
2944 case OPC_VR54XX_MSACU:
2945 gen_helper_msacu(t0, cpu_env, t0, t1);
2948 case OPC_VR54XX_MULHI:
2949 gen_helper_mulhi(t0, cpu_env, t0, t1);
2952 case OPC_VR54XX_MULHIU:
2953 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2956 case OPC_VR54XX_MULSHI:
2957 gen_helper_mulshi(t0, cpu_env, t0, t1);
2960 case OPC_VR54XX_MULSHIU:
2961 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2964 case OPC_VR54XX_MACCHI:
2965 gen_helper_macchi(t0, cpu_env, t0, t1);
2968 case OPC_VR54XX_MACCHIU:
2969 gen_helper_macchiu(t0, cpu_env, t0, t1);
2972 case OPC_VR54XX_MSACHI:
2973 gen_helper_msachi(t0, cpu_env, t0, t1);
2976 case OPC_VR54XX_MSACHIU:
2977 gen_helper_msachiu(t0, cpu_env, t0, t1);
2981 MIPS_INVAL("mul vr54xx");
2982 generate_exception(ctx, EXCP_RI);
2985 gen_store_gpr(t0, rd);
2986 (void)opn; /* avoid a compiler warning */
2987 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2994 static void gen_cl (DisasContext *ctx, uint32_t opc,
2997 const char *opn = "CLx";
3005 t0 = tcg_temp_new();
3006 gen_load_gpr(t0, rs);
3009 gen_helper_clo(cpu_gpr[rd], t0);
3013 gen_helper_clz(cpu_gpr[rd], t0);
3016 #if defined(TARGET_MIPS64)
3018 gen_helper_dclo(cpu_gpr[rd], t0);
3022 gen_helper_dclz(cpu_gpr[rd], t0);
3027 (void)opn; /* avoid a compiler warning */
3028 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3032 /* Godson integer instructions */
3033 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3034 int rd, int rs, int rt)
3036 const char *opn = "loongson";
3048 case OPC_MULTU_G_2E:
3049 case OPC_MULTU_G_2F:
3050 #if defined(TARGET_MIPS64)
3051 case OPC_DMULT_G_2E:
3052 case OPC_DMULT_G_2F:
3053 case OPC_DMULTU_G_2E:
3054 case OPC_DMULTU_G_2F:
3056 t0 = tcg_temp_new();
3057 t1 = tcg_temp_new();
3060 t0 = tcg_temp_local_new();
3061 t1 = tcg_temp_local_new();
3065 gen_load_gpr(t0, rs);
3066 gen_load_gpr(t1, rt);
3071 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3072 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3075 case OPC_MULTU_G_2E:
3076 case OPC_MULTU_G_2F:
3077 tcg_gen_ext32u_tl(t0, t0);
3078 tcg_gen_ext32u_tl(t1, t1);
3079 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3080 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3086 int l1 = gen_new_label();
3087 int l2 = gen_new_label();
3088 int l3 = gen_new_label();
3089 tcg_gen_ext32s_tl(t0, t0);
3090 tcg_gen_ext32s_tl(t1, t1);
3091 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3092 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3095 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3097 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3100 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3101 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3109 int l1 = gen_new_label();
3110 int l2 = gen_new_label();
3111 tcg_gen_ext32u_tl(t0, t0);
3112 tcg_gen_ext32u_tl(t1, t1);
3113 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3114 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3117 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3118 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3126 int l1 = gen_new_label();
3127 int l2 = gen_new_label();
3128 int l3 = gen_new_label();
3129 tcg_gen_ext32u_tl(t0, t0);
3130 tcg_gen_ext32u_tl(t1, t1);
3131 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3132 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3133 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3135 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3138 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3139 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3147 int l1 = gen_new_label();
3148 int l2 = gen_new_label();
3149 tcg_gen_ext32u_tl(t0, t0);
3150 tcg_gen_ext32u_tl(t1, t1);
3151 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3152 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3155 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3156 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3161 #if defined(TARGET_MIPS64)
3162 case OPC_DMULT_G_2E:
3163 case OPC_DMULT_G_2F:
3164 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3167 case OPC_DMULTU_G_2E:
3168 case OPC_DMULTU_G_2F:
3169 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3175 int l1 = gen_new_label();
3176 int l2 = gen_new_label();
3177 int l3 = gen_new_label();
3178 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3179 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3182 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3183 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3184 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3187 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3192 case OPC_DDIVU_G_2E:
3193 case OPC_DDIVU_G_2F:
3195 int l1 = gen_new_label();
3196 int l2 = gen_new_label();
3197 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3198 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3201 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3209 int l1 = gen_new_label();
3210 int l2 = gen_new_label();
3211 int l3 = gen_new_label();
3212 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3213 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3214 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3216 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3219 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3224 case OPC_DMODU_G_2E:
3225 case OPC_DMODU_G_2F:
3227 int l1 = gen_new_label();
3228 int l2 = gen_new_label();
3229 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3230 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3233 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3241 (void)opn; /* avoid a compiler warning */
3242 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3247 /* Loongson multimedia instructions */
3248 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3250 const char *opn = "loongson_cp2";
3251 uint32_t opc, shift_max;
3254 opc = MASK_LMI(ctx->opcode);
3260 t0 = tcg_temp_local_new_i64();
3261 t1 = tcg_temp_local_new_i64();
3264 t0 = tcg_temp_new_i64();
3265 t1 = tcg_temp_new_i64();
3269 gen_load_fpr64(ctx, t0, rs);
3270 gen_load_fpr64(ctx, t1, rt);
3272 #define LMI_HELPER(UP, LO) \
3273 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3274 #define LMI_HELPER_1(UP, LO) \
3275 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3276 #define LMI_DIRECT(UP, LO, OP) \
3277 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3280 LMI_HELPER(PADDSH, paddsh);
3281 LMI_HELPER(PADDUSH, paddush);
3282 LMI_HELPER(PADDH, paddh);
3283 LMI_HELPER(PADDW, paddw);
3284 LMI_HELPER(PADDSB, paddsb);
3285 LMI_HELPER(PADDUSB, paddusb);
3286 LMI_HELPER(PADDB, paddb);
3288 LMI_HELPER(PSUBSH, psubsh);
3289 LMI_HELPER(PSUBUSH, psubush);
3290 LMI_HELPER(PSUBH, psubh);
3291 LMI_HELPER(PSUBW, psubw);
3292 LMI_HELPER(PSUBSB, psubsb);
3293 LMI_HELPER(PSUBUSB, psubusb);
3294 LMI_HELPER(PSUBB, psubb);
3296 LMI_HELPER(PSHUFH, pshufh);
3297 LMI_HELPER(PACKSSWH, packsswh);
3298 LMI_HELPER(PACKSSHB, packsshb);
3299 LMI_HELPER(PACKUSHB, packushb);
3301 LMI_HELPER(PUNPCKLHW, punpcklhw);
3302 LMI_HELPER(PUNPCKHHW, punpckhhw);
3303 LMI_HELPER(PUNPCKLBH, punpcklbh);
3304 LMI_HELPER(PUNPCKHBH, punpckhbh);
3305 LMI_HELPER(PUNPCKLWD, punpcklwd);
3306 LMI_HELPER(PUNPCKHWD, punpckhwd);
3308 LMI_HELPER(PAVGH, pavgh);
3309 LMI_HELPER(PAVGB, pavgb);
3310 LMI_HELPER(PMAXSH, pmaxsh);
3311 LMI_HELPER(PMINSH, pminsh);
3312 LMI_HELPER(PMAXUB, pmaxub);
3313 LMI_HELPER(PMINUB, pminub);
3315 LMI_HELPER(PCMPEQW, pcmpeqw);
3316 LMI_HELPER(PCMPGTW, pcmpgtw);
3317 LMI_HELPER(PCMPEQH, pcmpeqh);
3318 LMI_HELPER(PCMPGTH, pcmpgth);
3319 LMI_HELPER(PCMPEQB, pcmpeqb);
3320 LMI_HELPER(PCMPGTB, pcmpgtb);
3322 LMI_HELPER(PSLLW, psllw);
3323 LMI_HELPER(PSLLH, psllh);
3324 LMI_HELPER(PSRLW, psrlw);
3325 LMI_HELPER(PSRLH, psrlh);
3326 LMI_HELPER(PSRAW, psraw);
3327 LMI_HELPER(PSRAH, psrah);
3329 LMI_HELPER(PMULLH, pmullh);
3330 LMI_HELPER(PMULHH, pmulhh);
3331 LMI_HELPER(PMULHUH, pmulhuh);
3332 LMI_HELPER(PMADDHW, pmaddhw);
3334 LMI_HELPER(PASUBUB, pasubub);
3335 LMI_HELPER_1(BIADD, biadd);
3336 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3338 LMI_DIRECT(PADDD, paddd, add);
3339 LMI_DIRECT(PSUBD, psubd, sub);
3340 LMI_DIRECT(XOR_CP2, xor, xor);
3341 LMI_DIRECT(NOR_CP2, nor, nor);
3342 LMI_DIRECT(AND_CP2, and, and);
3343 LMI_DIRECT(PANDN, pandn, andc);
3344 LMI_DIRECT(OR, or, or);
3347 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3351 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3355 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3359 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3364 tcg_gen_andi_i64(t1, t1, 3);
3365 tcg_gen_shli_i64(t1, t1, 4);
3366 tcg_gen_shr_i64(t0, t0, t1);
3367 tcg_gen_ext16u_i64(t0, t0);
3372 tcg_gen_add_i64(t0, t0, t1);
3373 tcg_gen_ext32s_i64(t0, t0);
3377 tcg_gen_sub_i64(t0, t0, t1);
3378 tcg_gen_ext32s_i64(t0, t0);
3407 /* Make sure shift count isn't TCG undefined behaviour. */
3408 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3413 tcg_gen_shl_i64(t0, t0, t1);
3417 /* Since SRA is UndefinedResult without sign-extended inputs,
3418 we can treat SRA and DSRA the same. */
3419 tcg_gen_sar_i64(t0, t0, t1);
3422 /* We want to shift in zeros for SRL; zero-extend first. */
3423 tcg_gen_ext32u_i64(t0, t0);
3426 tcg_gen_shr_i64(t0, t0, t1);
3430 if (shift_max == 32) {
3431 tcg_gen_ext32s_i64(t0, t0);
3434 /* Shifts larger than MAX produce zero. */
3435 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3436 tcg_gen_neg_i64(t1, t1);
3437 tcg_gen_and_i64(t0, t0, t1);
3443 TCGv_i64 t2 = tcg_temp_new_i64();
3444 int lab = gen_new_label();
3446 tcg_gen_mov_i64(t2, t0);
3447 tcg_gen_add_i64(t0, t1, t2);
3448 if (opc == OPC_ADD_CP2) {
3449 tcg_gen_ext32s_i64(t0, t0);
3451 tcg_gen_xor_i64(t1, t1, t2);
3452 tcg_gen_xor_i64(t2, t2, t0);
3453 tcg_gen_andc_i64(t1, t2, t1);
3454 tcg_temp_free_i64(t2);
3455 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3456 generate_exception(ctx, EXCP_OVERFLOW);
3459 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3466 TCGv_i64 t2 = tcg_temp_new_i64();
3467 int lab = gen_new_label();
3469 tcg_gen_mov_i64(t2, t0);
3470 tcg_gen_sub_i64(t0, t1, t2);
3471 if (opc == OPC_SUB_CP2) {
3472 tcg_gen_ext32s_i64(t0, t0);
3474 tcg_gen_xor_i64(t1, t1, t2);
3475 tcg_gen_xor_i64(t2, t2, t0);
3476 tcg_gen_and_i64(t1, t1, t2);
3477 tcg_temp_free_i64(t2);
3478 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3479 generate_exception(ctx, EXCP_OVERFLOW);
3482 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3487 tcg_gen_ext32u_i64(t0, t0);
3488 tcg_gen_ext32u_i64(t1, t1);
3489 tcg_gen_mul_i64(t0, t0, t1);
3499 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3500 FD field is the CC field? */
3503 generate_exception(ctx, EXCP_RI);
3510 gen_store_fpr64(ctx, t0, rd);
3512 (void)opn; /* avoid a compiler warning */
3513 MIPS_DEBUG("%s %s, %s, %s", opn,
3514 fregnames[rd], fregnames[rs], fregnames[rt]);
3515 tcg_temp_free_i64(t0);
3516 tcg_temp_free_i64(t1);
3520 static void gen_trap (DisasContext *ctx, uint32_t opc,
3521 int rs, int rt, int16_t imm)
3524 TCGv t0 = tcg_temp_new();
3525 TCGv t1 = tcg_temp_new();
3528 /* Load needed operands */
3536 /* Compare two registers */
3538 gen_load_gpr(t0, rs);
3539 gen_load_gpr(t1, rt);
3549 /* Compare register to immediate */
3550 if (rs != 0 || imm != 0) {
3551 gen_load_gpr(t0, rs);
3552 tcg_gen_movi_tl(t1, (int32_t)imm);
3559 case OPC_TEQ: /* rs == rs */
3560 case OPC_TEQI: /* r0 == 0 */
3561 case OPC_TGE: /* rs >= rs */
3562 case OPC_TGEI: /* r0 >= 0 */
3563 case OPC_TGEU: /* rs >= rs unsigned */
3564 case OPC_TGEIU: /* r0 >= 0 unsigned */
3566 generate_exception(ctx, EXCP_TRAP);
3568 case OPC_TLT: /* rs < rs */
3569 case OPC_TLTI: /* r0 < 0 */
3570 case OPC_TLTU: /* rs < rs unsigned */
3571 case OPC_TLTIU: /* r0 < 0 unsigned */
3572 case OPC_TNE: /* rs != rs */
3573 case OPC_TNEI: /* r0 != 0 */
3574 /* Never trap: treat as NOP. */
3578 int l1 = gen_new_label();
3583 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3587 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3591 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3595 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3599 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3603 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3606 generate_exception(ctx, EXCP_TRAP);
3613 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3615 TranslationBlock *tb;
3617 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3618 likely(!ctx->singlestep_enabled)) {
3621 tcg_gen_exit_tb((tcg_target_long)tb + n);
3624 if (ctx->singlestep_enabled) {
3625 save_cpu_state(ctx, 0);
3626 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3632 /* Branches (before delay slot) */
3633 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3635 int rs, int rt, int32_t offset)
3637 target_ulong btgt = -1;
3639 int bcond_compute = 0;
3640 TCGv t0 = tcg_temp_new();
3641 TCGv t1 = tcg_temp_new();
3643 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3644 #ifdef MIPS_DEBUG_DISAS
3645 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3647 generate_exception(ctx, EXCP_RI);
3651 /* Load needed operands */
3657 /* Compare two registers */
3659 gen_load_gpr(t0, rs);
3660 gen_load_gpr(t1, rt);
3663 btgt = ctx->pc + insn_bytes + offset;
3679 /* Compare to zero */
3681 gen_load_gpr(t0, rs);
3684 btgt = ctx->pc + insn_bytes + offset;
3687 #if defined(TARGET_MIPS64)
3689 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3691 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3694 btgt = ctx->pc + insn_bytes + offset;
3701 /* Jump to immediate */
3702 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3708 /* Jump to register */
3709 if (offset != 0 && offset != 16) {
3710 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3711 others are reserved. */
3712 MIPS_INVAL("jump hint");
3713 generate_exception(ctx, EXCP_RI);
3716 gen_load_gpr(btarget, rs);
3719 MIPS_INVAL("branch/jump");
3720 generate_exception(ctx, EXCP_RI);
3723 if (bcond_compute == 0) {
3724 /* No condition to be computed */
3726 case OPC_BEQ: /* rx == rx */
3727 case OPC_BEQL: /* rx == rx likely */
3728 case OPC_BGEZ: /* 0 >= 0 */
3729 case OPC_BGEZL: /* 0 >= 0 likely */
3730 case OPC_BLEZ: /* 0 <= 0 */
3731 case OPC_BLEZL: /* 0 <= 0 likely */
3733 ctx->hflags |= MIPS_HFLAG_B;
3734 MIPS_DEBUG("balways");
3737 case OPC_BGEZAL: /* 0 >= 0 */
3738 case OPC_BGEZALL: /* 0 >= 0 likely */
3739 ctx->hflags |= (opc == OPC_BGEZALS
3741 : MIPS_HFLAG_BDS32);
3742 /* Always take and link */
3744 ctx->hflags |= MIPS_HFLAG_B;
3745 MIPS_DEBUG("balways and link");
3747 case OPC_BNE: /* rx != rx */
3748 case OPC_BGTZ: /* 0 > 0 */
3749 case OPC_BLTZ: /* 0 < 0 */
3751 MIPS_DEBUG("bnever (NOP)");
3754 case OPC_BLTZAL: /* 0 < 0 */
3755 ctx->hflags |= (opc == OPC_BLTZALS
3757 : MIPS_HFLAG_BDS32);
3758 /* Handle as an unconditional branch to get correct delay
3761 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3762 ctx->hflags |= MIPS_HFLAG_B;
3763 MIPS_DEBUG("bnever and link");
3765 case OPC_BLTZALL: /* 0 < 0 likely */
3766 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3767 /* Skip the instruction in the delay slot */
3768 MIPS_DEBUG("bnever, link and skip");
3771 case OPC_BNEL: /* rx != rx likely */
3772 case OPC_BGTZL: /* 0 > 0 likely */
3773 case OPC_BLTZL: /* 0 < 0 likely */
3774 /* Skip the instruction in the delay slot */
3775 MIPS_DEBUG("bnever and skip");
3779 ctx->hflags |= MIPS_HFLAG_B;
3780 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3784 ctx->hflags |= MIPS_HFLAG_BX;
3789 ctx->hflags |= MIPS_HFLAG_B;
3790 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3792 : MIPS_HFLAG_BDS32);
3793 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3796 ctx->hflags |= MIPS_HFLAG_BR;
3797 if (insn_bytes == 4)
3798 ctx->hflags |= MIPS_HFLAG_BDS32;
3799 MIPS_DEBUG("jr %s", regnames[rs]);
3805 ctx->hflags |= MIPS_HFLAG_BR;
3806 ctx->hflags |= (opc == OPC_JALRS
3808 : MIPS_HFLAG_BDS32);
3809 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3812 MIPS_INVAL("branch/jump");
3813 generate_exception(ctx, EXCP_RI);
3819 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3820 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3821 regnames[rs], regnames[rt], btgt);
3824 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3825 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3826 regnames[rs], regnames[rt], btgt);
3829 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3830 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3831 regnames[rs], regnames[rt], btgt);
3834 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3835 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3836 regnames[rs], regnames[rt], btgt);
3839 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3840 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3843 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3844 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3848 ctx->hflags |= (opc == OPC_BGEZALS
3850 : MIPS_HFLAG_BDS32);
3851 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3852 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3856 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3858 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3861 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3862 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3865 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3866 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3869 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3870 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3873 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3874 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3877 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3878 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3881 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3882 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3885 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3886 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3888 #if defined(TARGET_MIPS64)
3890 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3891 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3896 ctx->hflags |= (opc == OPC_BLTZALS
3898 : MIPS_HFLAG_BDS32);
3899 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3901 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3903 ctx->hflags |= MIPS_HFLAG_BC;
3906 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3908 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3910 ctx->hflags |= MIPS_HFLAG_BL;
3913 MIPS_INVAL("conditional branch/jump");
3914 generate_exception(ctx, EXCP_RI);
3918 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3919 blink, ctx->hflags, btgt);
3921 ctx->btarget = btgt;
3923 int post_delay = insn_bytes;
3924 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3926 if (opc != OPC_JALRC)
3927 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3929 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3933 if (insn_bytes == 2)
3934 ctx->hflags |= MIPS_HFLAG_B16;
3939 /* special3 bitfield operations */
3940 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3941 int rs, int lsb, int msb)
3943 TCGv t0 = tcg_temp_new();
3944 TCGv t1 = tcg_temp_new();
3947 gen_load_gpr(t1, rs);
3952 tcg_gen_shri_tl(t0, t1, lsb);
3954 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3956 tcg_gen_ext32s_tl(t0, t0);
3959 #if defined(TARGET_MIPS64)
3961 tcg_gen_shri_tl(t0, t1, lsb);
3963 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3967 tcg_gen_shri_tl(t0, t1, lsb + 32);
3968 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3971 tcg_gen_shri_tl(t0, t1, lsb);
3972 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3978 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3979 gen_load_gpr(t0, rt);
3980 tcg_gen_andi_tl(t0, t0, ~mask);
3981 tcg_gen_shli_tl(t1, t1, lsb);
3982 tcg_gen_andi_tl(t1, t1, mask);
3983 tcg_gen_or_tl(t0, t0, t1);
3984 tcg_gen_ext32s_tl(t0, t0);
3986 #if defined(TARGET_MIPS64)
3990 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3991 gen_load_gpr(t0, rt);
3992 tcg_gen_andi_tl(t0, t0, ~mask);
3993 tcg_gen_shli_tl(t1, t1, lsb);
3994 tcg_gen_andi_tl(t1, t1, mask);
3995 tcg_gen_or_tl(t0, t0, t1);
4000 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
4001 gen_load_gpr(t0, rt);
4002 tcg_gen_andi_tl(t0, t0, ~mask);
4003 tcg_gen_shli_tl(t1, t1, lsb + 32);
4004 tcg_gen_andi_tl(t1, t1, mask);
4005 tcg_gen_or_tl(t0, t0, t1);
4010 gen_load_gpr(t0, rt);
4011 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
4012 gen_load_gpr(t0, rt);
4013 tcg_gen_andi_tl(t0, t0, ~mask);
4014 tcg_gen_shli_tl(t1, t1, lsb);
4015 tcg_gen_andi_tl(t1, t1, mask);
4016 tcg_gen_or_tl(t0, t0, t1);
4021 MIPS_INVAL("bitops");
4022 generate_exception(ctx, EXCP_RI);
4027 gen_store_gpr(t0, rt);
4032 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4037 /* If no destination, treat it as a NOP. */
4042 t0 = tcg_temp_new();
4043 gen_load_gpr(t0, rt);
4047 TCGv t1 = tcg_temp_new();
4049 tcg_gen_shri_tl(t1, t0, 8);
4050 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4051 tcg_gen_shli_tl(t0, t0, 8);
4052 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4053 tcg_gen_or_tl(t0, t0, t1);
4055 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4059 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4062 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4064 #if defined(TARGET_MIPS64)
4067 TCGv t1 = tcg_temp_new();
4069 tcg_gen_shri_tl(t1, t0, 8);
4070 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4071 tcg_gen_shli_tl(t0, t0, 8);
4072 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4073 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4079 TCGv t1 = tcg_temp_new();
4081 tcg_gen_shri_tl(t1, t0, 16);
4082 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4083 tcg_gen_shli_tl(t0, t0, 16);
4084 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4085 tcg_gen_or_tl(t0, t0, t1);
4086 tcg_gen_shri_tl(t1, t0, 32);
4087 tcg_gen_shli_tl(t0, t0, 32);
4088 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4094 MIPS_INVAL("bsfhl");
4095 generate_exception(ctx, EXCP_RI);
4102 #ifndef CONFIG_USER_ONLY
4103 /* CP0 (MMU and control) */
4104 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4106 TCGv_i32 t0 = tcg_temp_new_i32();
4108 tcg_gen_ld_i32(t0, cpu_env, off);
4109 tcg_gen_ext_i32_tl(arg, t0);
4110 tcg_temp_free_i32(t0);
4113 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4115 tcg_gen_ld_tl(arg, cpu_env, off);
4116 tcg_gen_ext32s_tl(arg, arg);
4119 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4121 TCGv_i32 t0 = tcg_temp_new_i32();
4123 tcg_gen_trunc_tl_i32(t0, arg);
4124 tcg_gen_st_i32(t0, cpu_env, off);
4125 tcg_temp_free_i32(t0);
4128 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4130 tcg_gen_ext32s_tl(arg, arg);
4131 tcg_gen_st_tl(arg, cpu_env, off);
4134 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4136 const char *rn = "invalid";
4139 check_insn(env, ctx, ISA_MIPS32);
4145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4149 check_insn(env, ctx, ASE_MT);
4150 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4154 check_insn(env, ctx, ASE_MT);
4155 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4159 check_insn(env, ctx, ASE_MT);
4160 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4170 gen_helper_mfc0_random(arg, cpu_env);
4174 check_insn(env, ctx, ASE_MT);
4175 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4179 check_insn(env, ctx, ASE_MT);
4180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4184 check_insn(env, ctx, ASE_MT);
4185 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4189 check_insn(env, ctx, ASE_MT);
4190 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4194 check_insn(env, ctx, ASE_MT);
4195 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4199 check_insn(env, ctx, ASE_MT);
4200 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4201 rn = "VPEScheFBack";
4204 check_insn(env, ctx, ASE_MT);
4205 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4215 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4216 tcg_gen_ext32s_tl(arg, arg);
4220 check_insn(env, ctx, ASE_MT);
4221 gen_helper_mfc0_tcstatus(arg, cpu_env);
4225 check_insn(env, ctx, ASE_MT);
4226 gen_helper_mfc0_tcbind(arg, cpu_env);
4230 check_insn(env, ctx, ASE_MT);
4231 gen_helper_mfc0_tcrestart(arg, cpu_env);
4235 check_insn(env, ctx, ASE_MT);
4236 gen_helper_mfc0_tchalt(arg, cpu_env);
4240 check_insn(env, ctx, ASE_MT);
4241 gen_helper_mfc0_tccontext(arg, cpu_env);
4245 check_insn(env, ctx, ASE_MT);
4246 gen_helper_mfc0_tcschedule(arg, cpu_env);
4250 check_insn(env, ctx, ASE_MT);
4251 gen_helper_mfc0_tcschefback(arg, cpu_env);
4261 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4262 tcg_gen_ext32s_tl(arg, arg);
4272 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4273 tcg_gen_ext32s_tl(arg, arg);
4277 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4278 rn = "ContextConfig";
4287 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4291 check_insn(env, ctx, ISA_MIPS32R2);
4292 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4302 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4306 check_insn(env, ctx, ISA_MIPS32R2);
4307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4311 check_insn(env, ctx, ISA_MIPS32R2);
4312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4316 check_insn(env, ctx, ISA_MIPS32R2);
4317 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4321 check_insn(env, ctx, ISA_MIPS32R2);
4322 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4326 check_insn(env, ctx, ISA_MIPS32R2);
4327 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4337 check_insn(env, ctx, ISA_MIPS32R2);
4338 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4348 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4349 tcg_gen_ext32s_tl(arg, arg);
4359 /* Mark as an IO operation because we read the time. */
4362 gen_helper_mfc0_count(arg, cpu_env);
4366 /* Break the TB to be able to take timer interrupts immediately
4367 after reading count. */
4368 ctx->bstate = BS_STOP;
4371 /* 6,7 are implementation dependent */
4379 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4380 tcg_gen_ext32s_tl(arg, arg);
4390 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4393 /* 6,7 are implementation dependent */
4401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4405 check_insn(env, ctx, ISA_MIPS32R2);
4406 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4410 check_insn(env, ctx, ISA_MIPS32R2);
4411 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4415 check_insn(env, ctx, ISA_MIPS32R2);
4416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4426 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4436 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4437 tcg_gen_ext32s_tl(arg, arg);
4447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4451 check_insn(env, ctx, ISA_MIPS32R2);
4452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4474 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4477 /* 4,5 are reserved */
4478 /* 6,7 are implementation dependent */
4480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4484 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4494 gen_helper_mfc0_lladdr(arg, cpu_env);
4504 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4514 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4524 #if defined(TARGET_MIPS64)
4525 check_insn(env, ctx, ISA_MIPS3);
4526 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4527 tcg_gen_ext32s_tl(arg, arg);
4536 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4547 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4548 rn = "'Diagnostic"; /* implementation dependent */
4553 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4557 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4558 rn = "TraceControl";
4561 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4562 rn = "TraceControl2";
4565 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4566 rn = "UserTraceData";
4569 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4580 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4581 tcg_gen_ext32s_tl(arg, arg);
4591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4592 rn = "Performance0";
4595 // gen_helper_mfc0_performance1(arg);
4596 rn = "Performance1";
4599 // gen_helper_mfc0_performance2(arg);
4600 rn = "Performance2";
4603 // gen_helper_mfc0_performance3(arg);
4604 rn = "Performance3";
4607 // gen_helper_mfc0_performance4(arg);
4608 rn = "Performance4";
4611 // gen_helper_mfc0_performance5(arg);
4612 rn = "Performance5";
4615 // gen_helper_mfc0_performance6(arg);
4616 rn = "Performance6";
4619 // gen_helper_mfc0_performance7(arg);
4620 rn = "Performance7";
4627 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4633 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4646 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4653 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4666 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4683 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4684 tcg_gen_ext32s_tl(arg, arg);
4695 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4705 (void)rn; /* avoid a compiler warning */
4706 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4710 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4711 generate_exception(ctx, EXCP_RI);
4714 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4716 const char *rn = "invalid";
4719 check_insn(env, ctx, ISA_MIPS32);
4728 gen_helper_mtc0_index(cpu_env, arg);
4732 check_insn(env, ctx, ASE_MT);
4733 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4737 check_insn(env, ctx, ASE_MT);
4742 check_insn(env, ctx, ASE_MT);
4757 check_insn(env, ctx, ASE_MT);
4758 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4762 check_insn(env, ctx, ASE_MT);
4763 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4767 check_insn(env, ctx, ASE_MT);
4768 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4772 check_insn(env, ctx, ASE_MT);
4773 gen_helper_mtc0_yqmask(cpu_env, arg);
4777 check_insn(env, ctx, ASE_MT);
4778 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4782 check_insn(env, ctx, ASE_MT);
4783 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4784 rn = "VPEScheFBack";
4787 check_insn(env, ctx, ASE_MT);
4788 gen_helper_mtc0_vpeopt(cpu_env, arg);
4798 gen_helper_mtc0_entrylo0(cpu_env, arg);
4802 check_insn(env, ctx, ASE_MT);
4803 gen_helper_mtc0_tcstatus(cpu_env, arg);
4807 check_insn(env, ctx, ASE_MT);
4808 gen_helper_mtc0_tcbind(cpu_env, arg);
4812 check_insn(env, ctx, ASE_MT);
4813 gen_helper_mtc0_tcrestart(cpu_env, arg);
4817 check_insn(env, ctx, ASE_MT);
4818 gen_helper_mtc0_tchalt(cpu_env, arg);
4822 check_insn(env, ctx, ASE_MT);
4823 gen_helper_mtc0_tccontext(cpu_env, arg);
4827 check_insn(env, ctx, ASE_MT);
4828 gen_helper_mtc0_tcschedule(cpu_env, arg);
4832 check_insn(env, ctx, ASE_MT);
4833 gen_helper_mtc0_tcschefback(cpu_env, arg);
4843 gen_helper_mtc0_entrylo1(cpu_env, arg);
4853 gen_helper_mtc0_context(cpu_env, arg);
4857 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4858 rn = "ContextConfig";
4867 gen_helper_mtc0_pagemask(cpu_env, arg);
4871 check_insn(env, ctx, ISA_MIPS32R2);
4872 gen_helper_mtc0_pagegrain(cpu_env, arg);
4882 gen_helper_mtc0_wired(cpu_env, arg);
4886 check_insn(env, ctx, ISA_MIPS32R2);
4887 gen_helper_mtc0_srsconf0(cpu_env, arg);
4891 check_insn(env, ctx, ISA_MIPS32R2);
4892 gen_helper_mtc0_srsconf1(cpu_env, arg);
4896 check_insn(env, ctx, ISA_MIPS32R2);
4897 gen_helper_mtc0_srsconf2(cpu_env, arg);
4901 check_insn(env, ctx, ISA_MIPS32R2);
4902 gen_helper_mtc0_srsconf3(cpu_env, arg);
4906 check_insn(env, ctx, ISA_MIPS32R2);
4907 gen_helper_mtc0_srsconf4(cpu_env, arg);
4917 check_insn(env, ctx, ISA_MIPS32R2);
4918 gen_helper_mtc0_hwrena(cpu_env, arg);
4932 gen_helper_mtc0_count(cpu_env, arg);
4935 /* 6,7 are implementation dependent */
4943 gen_helper_mtc0_entryhi(cpu_env, arg);
4953 gen_helper_mtc0_compare(cpu_env, arg);
4956 /* 6,7 are implementation dependent */
4964 save_cpu_state(ctx, 1);
4965 gen_helper_mtc0_status(cpu_env, arg);
4966 /* BS_STOP isn't good enough here, hflags may have changed. */
4967 gen_save_pc(ctx->pc + 4);
4968 ctx->bstate = BS_EXCP;
4972 check_insn(env, ctx, ISA_MIPS32R2);
4973 gen_helper_mtc0_intctl(cpu_env, arg);
4974 /* Stop translation as we may have switched the execution mode */
4975 ctx->bstate = BS_STOP;
4979 check_insn(env, ctx, ISA_MIPS32R2);
4980 gen_helper_mtc0_srsctl(cpu_env, arg);
4981 /* Stop translation as we may have switched the execution mode */
4982 ctx->bstate = BS_STOP;
4986 check_insn(env, ctx, ISA_MIPS32R2);
4987 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4988 /* Stop translation as we may have switched the execution mode */
4989 ctx->bstate = BS_STOP;
4999 save_cpu_state(ctx, 1);
5000 gen_helper_mtc0_cause(cpu_env, arg);
5010 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5024 check_insn(env, ctx, ISA_MIPS32R2);
5025 gen_helper_mtc0_ebase(cpu_env, arg);
5035 gen_helper_mtc0_config0(cpu_env, arg);
5037 /* Stop translation as we may have switched the execution mode */
5038 ctx->bstate = BS_STOP;
5041 /* ignored, read only */
5045 gen_helper_mtc0_config2(cpu_env, arg);
5047 /* Stop translation as we may have switched the execution mode */
5048 ctx->bstate = BS_STOP;
5051 /* ignored, read only */
5054 /* 4,5 are reserved */
5055 /* 6,7 are implementation dependent */
5065 rn = "Invalid config selector";
5072 gen_helper_mtc0_lladdr(cpu_env, arg);
5082 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5092 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5102 #if defined(TARGET_MIPS64)
5103 check_insn(env, ctx, ISA_MIPS3);
5104 gen_helper_mtc0_xcontext(cpu_env, arg);
5113 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5116 gen_helper_mtc0_framemask(cpu_env, arg);
5125 rn = "Diagnostic"; /* implementation dependent */
5130 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5131 /* BS_STOP isn't good enough here, hflags may have changed. */
5132 gen_save_pc(ctx->pc + 4);
5133 ctx->bstate = BS_EXCP;
5137 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5138 rn = "TraceControl";
5139 /* Stop translation as we may have switched the execution mode */
5140 ctx->bstate = BS_STOP;
5143 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5144 rn = "TraceControl2";
5145 /* Stop translation as we may have switched the execution mode */
5146 ctx->bstate = BS_STOP;
5149 /* Stop translation as we may have switched the execution mode */
5150 ctx->bstate = BS_STOP;
5151 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5152 rn = "UserTraceData";
5153 /* Stop translation as we may have switched the execution mode */
5154 ctx->bstate = BS_STOP;
5157 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5158 /* Stop translation as we may have switched the execution mode */
5159 ctx->bstate = BS_STOP;
5170 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5180 gen_helper_mtc0_performance0(cpu_env, arg);
5181 rn = "Performance0";
5184 // gen_helper_mtc0_performance1(arg);
5185 rn = "Performance1";
5188 // gen_helper_mtc0_performance2(arg);
5189 rn = "Performance2";
5192 // gen_helper_mtc0_performance3(arg);
5193 rn = "Performance3";
5196 // gen_helper_mtc0_performance4(arg);
5197 rn = "Performance4";
5200 // gen_helper_mtc0_performance5(arg);
5201 rn = "Performance5";
5204 // gen_helper_mtc0_performance6(arg);
5205 rn = "Performance6";
5208 // gen_helper_mtc0_performance7(arg);
5209 rn = "Performance7";
5235 gen_helper_mtc0_taglo(cpu_env, arg);
5242 gen_helper_mtc0_datalo(cpu_env, arg);
5255 gen_helper_mtc0_taghi(cpu_env, arg);
5262 gen_helper_mtc0_datahi(cpu_env, arg);
5273 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5284 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5290 /* Stop translation as we may have switched the execution mode */
5291 ctx->bstate = BS_STOP;
5296 (void)rn; /* avoid a compiler warning */
5297 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5298 /* For simplicity assume that all writes can cause interrupts. */
5301 ctx->bstate = BS_STOP;
5306 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5307 generate_exception(ctx, EXCP_RI);
5310 #if defined(TARGET_MIPS64)
5311 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5313 const char *rn = "invalid";
5316 check_insn(env, ctx, ISA_MIPS64);
5322 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5326 check_insn(env, ctx, ASE_MT);
5327 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5331 check_insn(env, ctx, ASE_MT);
5332 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5336 check_insn(env, ctx, ASE_MT);
5337 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5347 gen_helper_mfc0_random(arg, cpu_env);
5351 check_insn(env, ctx, ASE_MT);
5352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5356 check_insn(env, ctx, ASE_MT);
5357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5361 check_insn(env, ctx, ASE_MT);
5362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5366 check_insn(env, ctx, ASE_MT);
5367 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5371 check_insn(env, ctx, ASE_MT);
5372 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5376 check_insn(env, ctx, ASE_MT);
5377 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5378 rn = "VPEScheFBack";
5381 check_insn(env, ctx, ASE_MT);
5382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5392 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5396 check_insn(env, ctx, ASE_MT);
5397 gen_helper_mfc0_tcstatus(arg, cpu_env);
5401 check_insn(env, ctx, ASE_MT);
5402 gen_helper_mfc0_tcbind(arg, cpu_env);
5406 check_insn(env, ctx, ASE_MT);
5407 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5411 check_insn(env, ctx, ASE_MT);
5412 gen_helper_dmfc0_tchalt(arg, cpu_env);
5416 check_insn(env, ctx, ASE_MT);
5417 gen_helper_dmfc0_tccontext(arg, cpu_env);
5421 check_insn(env, ctx, ASE_MT);
5422 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5426 check_insn(env, ctx, ASE_MT);
5427 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5437 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5447 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5451 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5452 rn = "ContextConfig";
5461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5465 check_insn(env, ctx, ISA_MIPS32R2);
5466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5476 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5480 check_insn(env, ctx, ISA_MIPS32R2);
5481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5485 check_insn(env, ctx, ISA_MIPS32R2);
5486 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5490 check_insn(env, ctx, ISA_MIPS32R2);
5491 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5495 check_insn(env, ctx, ISA_MIPS32R2);
5496 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5500 check_insn(env, ctx, ISA_MIPS32R2);
5501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5511 check_insn(env, ctx, ISA_MIPS32R2);
5512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5522 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5532 /* Mark as an IO operation because we read the time. */
5535 gen_helper_mfc0_count(arg, cpu_env);
5539 /* Break the TB to be able to take timer interrupts immediately
5540 after reading count. */
5541 ctx->bstate = BS_STOP;
5544 /* 6,7 are implementation dependent */
5552 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5565 /* 6,7 are implementation dependent */
5573 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5577 check_insn(env, ctx, ISA_MIPS32R2);
5578 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5582 check_insn(env, ctx, ISA_MIPS32R2);
5583 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5587 check_insn(env, ctx, ISA_MIPS32R2);
5588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5608 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5622 check_insn(env, ctx, ISA_MIPS32R2);
5623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5633 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5641 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5648 /* 6,7 are implementation dependent */
5650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5654 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5664 gen_helper_dmfc0_lladdr(arg, cpu_env);
5674 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5684 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5694 check_insn(env, ctx, ISA_MIPS3);
5695 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5703 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5714 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5715 rn = "'Diagnostic"; /* implementation dependent */
5720 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5724 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5725 rn = "TraceControl";
5728 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5729 rn = "TraceControl2";
5732 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5733 rn = "UserTraceData";
5736 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5747 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5757 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5758 rn = "Performance0";
5761 // gen_helper_dmfc0_performance1(arg);
5762 rn = "Performance1";
5765 // gen_helper_dmfc0_performance2(arg);
5766 rn = "Performance2";
5769 // gen_helper_dmfc0_performance3(arg);
5770 rn = "Performance3";
5773 // gen_helper_dmfc0_performance4(arg);
5774 rn = "Performance4";
5777 // gen_helper_dmfc0_performance5(arg);
5778 rn = "Performance5";
5781 // gen_helper_dmfc0_performance6(arg);
5782 rn = "Performance6";
5785 // gen_helper_dmfc0_performance7(arg);
5786 rn = "Performance7";
5793 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5800 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5813 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5820 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5833 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5850 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5861 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5871 (void)rn; /* avoid a compiler warning */
5872 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5876 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5877 generate_exception(ctx, EXCP_RI);
5880 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5882 const char *rn = "invalid";
5885 check_insn(env, ctx, ISA_MIPS64);
5894 gen_helper_mtc0_index(cpu_env, arg);
5898 check_insn(env, ctx, ASE_MT);
5899 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5903 check_insn(env, ctx, ASE_MT);
5908 check_insn(env, ctx, ASE_MT);
5923 check_insn(env, ctx, ASE_MT);
5924 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5928 check_insn(env, ctx, ASE_MT);
5929 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5933 check_insn(env, ctx, ASE_MT);
5934 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5938 check_insn(env, ctx, ASE_MT);
5939 gen_helper_mtc0_yqmask(cpu_env, arg);
5943 check_insn(env, ctx, ASE_MT);
5944 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5948 check_insn(env, ctx, ASE_MT);
5949 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5950 rn = "VPEScheFBack";
5953 check_insn(env, ctx, ASE_MT);
5954 gen_helper_mtc0_vpeopt(cpu_env, arg);
5964 gen_helper_mtc0_entrylo0(cpu_env, arg);
5968 check_insn(env, ctx, ASE_MT);
5969 gen_helper_mtc0_tcstatus(cpu_env, arg);
5973 check_insn(env, ctx, ASE_MT);
5974 gen_helper_mtc0_tcbind(cpu_env, arg);
5978 check_insn(env, ctx, ASE_MT);
5979 gen_helper_mtc0_tcrestart(cpu_env, arg);
5983 check_insn(env, ctx, ASE_MT);
5984 gen_helper_mtc0_tchalt(cpu_env, arg);
5988 check_insn(env, ctx, ASE_MT);
5989 gen_helper_mtc0_tccontext(cpu_env, arg);
5993 check_insn(env, ctx, ASE_MT);
5994 gen_helper_mtc0_tcschedule(cpu_env, arg);
5998 check_insn(env, ctx, ASE_MT);
5999 gen_helper_mtc0_tcschefback(cpu_env, arg);
6009 gen_helper_mtc0_entrylo1(cpu_env, arg);
6019 gen_helper_mtc0_context(cpu_env, arg);
6023 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6024 rn = "ContextConfig";
6033 gen_helper_mtc0_pagemask(cpu_env, arg);
6037 check_insn(env, ctx, ISA_MIPS32R2);
6038 gen_helper_mtc0_pagegrain(cpu_env, arg);
6048 gen_helper_mtc0_wired(cpu_env, arg);
6052 check_insn(env, ctx, ISA_MIPS32R2);
6053 gen_helper_mtc0_srsconf0(cpu_env, arg);
6057 check_insn(env, ctx, ISA_MIPS32R2);
6058 gen_helper_mtc0_srsconf1(cpu_env, arg);
6062 check_insn(env, ctx, ISA_MIPS32R2);
6063 gen_helper_mtc0_srsconf2(cpu_env, arg);
6067 check_insn(env, ctx, ISA_MIPS32R2);
6068 gen_helper_mtc0_srsconf3(cpu_env, arg);
6072 check_insn(env, ctx, ISA_MIPS32R2);
6073 gen_helper_mtc0_srsconf4(cpu_env, arg);
6083 check_insn(env, ctx, ISA_MIPS32R2);
6084 gen_helper_mtc0_hwrena(cpu_env, arg);
6098 gen_helper_mtc0_count(cpu_env, arg);
6101 /* 6,7 are implementation dependent */
6105 /* Stop translation as we may have switched the execution mode */
6106 ctx->bstate = BS_STOP;
6111 gen_helper_mtc0_entryhi(cpu_env, arg);
6121 gen_helper_mtc0_compare(cpu_env, arg);
6124 /* 6,7 are implementation dependent */
6128 /* Stop translation as we may have switched the execution mode */
6129 ctx->bstate = BS_STOP;
6134 save_cpu_state(ctx, 1);
6135 gen_helper_mtc0_status(cpu_env, arg);
6136 /* BS_STOP isn't good enough here, hflags may have changed. */
6137 gen_save_pc(ctx->pc + 4);
6138 ctx->bstate = BS_EXCP;
6142 check_insn(env, ctx, ISA_MIPS32R2);
6143 gen_helper_mtc0_intctl(cpu_env, arg);
6144 /* Stop translation as we may have switched the execution mode */
6145 ctx->bstate = BS_STOP;
6149 check_insn(env, ctx, ISA_MIPS32R2);
6150 gen_helper_mtc0_srsctl(cpu_env, arg);
6151 /* Stop translation as we may have switched the execution mode */
6152 ctx->bstate = BS_STOP;
6156 check_insn(env, ctx, ISA_MIPS32R2);
6157 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6158 /* Stop translation as we may have switched the execution mode */
6159 ctx->bstate = BS_STOP;
6169 save_cpu_state(ctx, 1);
6170 /* Mark as an IO operation because we may trigger a software
6175 gen_helper_mtc0_cause(cpu_env, arg);
6179 /* Stop translation as we may have triggered an intetrupt */
6180 ctx->bstate = BS_STOP;
6190 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6204 check_insn(env, ctx, ISA_MIPS32R2);
6205 gen_helper_mtc0_ebase(cpu_env, arg);
6215 gen_helper_mtc0_config0(cpu_env, arg);
6217 /* Stop translation as we may have switched the execution mode */
6218 ctx->bstate = BS_STOP;
6221 /* ignored, read only */
6225 gen_helper_mtc0_config2(cpu_env, arg);
6227 /* Stop translation as we may have switched the execution mode */
6228 ctx->bstate = BS_STOP;
6234 /* 6,7 are implementation dependent */
6236 rn = "Invalid config selector";
6243 gen_helper_mtc0_lladdr(cpu_env, arg);
6253 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6263 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6273 check_insn(env, ctx, ISA_MIPS3);
6274 gen_helper_mtc0_xcontext(cpu_env, arg);
6282 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6285 gen_helper_mtc0_framemask(cpu_env, arg);
6294 rn = "Diagnostic"; /* implementation dependent */
6299 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6300 /* BS_STOP isn't good enough here, hflags may have changed. */
6301 gen_save_pc(ctx->pc + 4);
6302 ctx->bstate = BS_EXCP;
6306 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6307 /* Stop translation as we may have switched the execution mode */
6308 ctx->bstate = BS_STOP;
6309 rn = "TraceControl";
6312 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6313 /* Stop translation as we may have switched the execution mode */
6314 ctx->bstate = BS_STOP;
6315 rn = "TraceControl2";
6318 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6319 /* Stop translation as we may have switched the execution mode */
6320 ctx->bstate = BS_STOP;
6321 rn = "UserTraceData";
6324 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6325 /* Stop translation as we may have switched the execution mode */
6326 ctx->bstate = BS_STOP;
6337 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6347 gen_helper_mtc0_performance0(cpu_env, arg);
6348 rn = "Performance0";
6351 // gen_helper_mtc0_performance1(cpu_env, arg);
6352 rn = "Performance1";
6355 // gen_helper_mtc0_performance2(cpu_env, arg);
6356 rn = "Performance2";
6359 // gen_helper_mtc0_performance3(cpu_env, arg);
6360 rn = "Performance3";
6363 // gen_helper_mtc0_performance4(cpu_env, arg);
6364 rn = "Performance4";
6367 // gen_helper_mtc0_performance5(cpu_env, arg);
6368 rn = "Performance5";
6371 // gen_helper_mtc0_performance6(cpu_env, arg);
6372 rn = "Performance6";
6375 // gen_helper_mtc0_performance7(cpu_env, arg);
6376 rn = "Performance7";
6402 gen_helper_mtc0_taglo(cpu_env, arg);
6409 gen_helper_mtc0_datalo(cpu_env, arg);
6422 gen_helper_mtc0_taghi(cpu_env, arg);
6429 gen_helper_mtc0_datahi(cpu_env, arg);
6440 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6451 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6457 /* Stop translation as we may have switched the execution mode */
6458 ctx->bstate = BS_STOP;
6463 (void)rn; /* avoid a compiler warning */
6464 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6465 /* For simplicity assume that all writes can cause interrupts. */
6468 ctx->bstate = BS_STOP;
6473 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6474 generate_exception(ctx, EXCP_RI);
6476 #endif /* TARGET_MIPS64 */
6478 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6479 int u, int sel, int h)
6481 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6482 TCGv t0 = tcg_temp_local_new();
6484 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6485 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6486 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6487 tcg_gen_movi_tl(t0, -1);
6488 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6489 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6490 tcg_gen_movi_tl(t0, -1);
6496 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6499 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6509 gen_helper_mftc0_tcstatus(t0, cpu_env);
6512 gen_helper_mftc0_tcbind(t0, cpu_env);
6515 gen_helper_mftc0_tcrestart(t0, cpu_env);
6518 gen_helper_mftc0_tchalt(t0, cpu_env);
6521 gen_helper_mftc0_tccontext(t0, cpu_env);
6524 gen_helper_mftc0_tcschedule(t0, cpu_env);
6527 gen_helper_mftc0_tcschefback(t0, cpu_env);
6530 gen_mfc0(env, ctx, t0, rt, sel);
6537 gen_helper_mftc0_entryhi(t0, cpu_env);
6540 gen_mfc0(env, ctx, t0, rt, sel);
6546 gen_helper_mftc0_status(t0, cpu_env);
6549 gen_mfc0(env, ctx, t0, rt, sel);
6555 gen_helper_mftc0_cause(t0, cpu_env);
6565 gen_helper_mftc0_epc(t0, cpu_env);
6575 gen_helper_mftc0_ebase(t0, cpu_env);
6585 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6595 gen_helper_mftc0_debug(t0, cpu_env);
6598 gen_mfc0(env, ctx, t0, rt, sel);
6603 gen_mfc0(env, ctx, t0, rt, sel);
6605 } else switch (sel) {
6606 /* GPR registers. */
6608 gen_helper_1e0i(mftgpr, t0, rt);
6610 /* Auxiliary CPU registers */
6614 gen_helper_1e0i(mftlo, t0, 0);
6617 gen_helper_1e0i(mfthi, t0, 0);
6620 gen_helper_1e0i(mftacx, t0, 0);
6623 gen_helper_1e0i(mftlo, t0, 1);
6626 gen_helper_1e0i(mfthi, t0, 1);
6629 gen_helper_1e0i(mftacx, t0, 1);
6632 gen_helper_1e0i(mftlo, t0, 2);
6635 gen_helper_1e0i(mfthi, t0, 2);
6638 gen_helper_1e0i(mftacx, t0, 2);
6641 gen_helper_1e0i(mftlo, t0, 3);
6644 gen_helper_1e0i(mfthi, t0, 3);
6647 gen_helper_1e0i(mftacx, t0, 3);
6650 gen_helper_mftdsp(t0, cpu_env);
6656 /* Floating point (COP1). */
6658 /* XXX: For now we support only a single FPU context. */
6660 TCGv_i32 fp0 = tcg_temp_new_i32();
6662 gen_load_fpr32(fp0, rt);
6663 tcg_gen_ext_i32_tl(t0, fp0);
6664 tcg_temp_free_i32(fp0);
6666 TCGv_i32 fp0 = tcg_temp_new_i32();
6668 gen_load_fpr32h(fp0, rt);
6669 tcg_gen_ext_i32_tl(t0, fp0);
6670 tcg_temp_free_i32(fp0);
6674 /* XXX: For now we support only a single FPU context. */
6675 gen_helper_1e0i(cfc1, t0, rt);
6677 /* COP2: Not implemented. */
6684 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6685 gen_store_gpr(t0, rd);
6691 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6692 generate_exception(ctx, EXCP_RI);
6695 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6696 int u, int sel, int h)
6698 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6699 TCGv t0 = tcg_temp_local_new();
6701 gen_load_gpr(t0, rt);
6702 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6703 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6704 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6706 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6707 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6714 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6717 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6727 gen_helper_mttc0_tcstatus(cpu_env, t0);
6730 gen_helper_mttc0_tcbind(cpu_env, t0);
6733 gen_helper_mttc0_tcrestart(cpu_env, t0);
6736 gen_helper_mttc0_tchalt(cpu_env, t0);
6739 gen_helper_mttc0_tccontext(cpu_env, t0);
6742 gen_helper_mttc0_tcschedule(cpu_env, t0);
6745 gen_helper_mttc0_tcschefback(cpu_env, t0);
6748 gen_mtc0(env, ctx, t0, rd, sel);
6755 gen_helper_mttc0_entryhi(cpu_env, t0);
6758 gen_mtc0(env, ctx, t0, rd, sel);
6764 gen_helper_mttc0_status(cpu_env, t0);
6767 gen_mtc0(env, ctx, t0, rd, sel);
6773 gen_helper_mttc0_cause(cpu_env, t0);
6783 gen_helper_mttc0_ebase(cpu_env, t0);
6793 gen_helper_mttc0_debug(cpu_env, t0);
6796 gen_mtc0(env, ctx, t0, rd, sel);
6801 gen_mtc0(env, ctx, t0, rd, sel);
6803 } else switch (sel) {
6804 /* GPR registers. */
6806 gen_helper_0e1i(mttgpr, t0, rd);
6808 /* Auxiliary CPU registers */
6812 gen_helper_0e1i(mttlo, t0, 0);
6815 gen_helper_0e1i(mtthi, t0, 0);
6818 gen_helper_0e1i(mttacx, t0, 0);
6821 gen_helper_0e1i(mttlo, t0, 1);
6824 gen_helper_0e1i(mtthi, t0, 1);
6827 gen_helper_0e1i(mttacx, t0, 1);
6830 gen_helper_0e1i(mttlo, t0, 2);
6833 gen_helper_0e1i(mtthi, t0, 2);
6836 gen_helper_0e1i(mttacx, t0, 2);
6839 gen_helper_0e1i(mttlo, t0, 3);
6842 gen_helper_0e1i(mtthi, t0, 3);
6845 gen_helper_0e1i(mttacx, t0, 3);
6848 gen_helper_mttdsp(cpu_env, t0);
6854 /* Floating point (COP1). */
6856 /* XXX: For now we support only a single FPU context. */
6858 TCGv_i32 fp0 = tcg_temp_new_i32();
6860 tcg_gen_trunc_tl_i32(fp0, t0);
6861 gen_store_fpr32(fp0, rd);
6862 tcg_temp_free_i32(fp0);
6864 TCGv_i32 fp0 = tcg_temp_new_i32();
6866 tcg_gen_trunc_tl_i32(fp0, t0);
6867 gen_store_fpr32h(fp0, rd);
6868 tcg_temp_free_i32(fp0);
6872 /* XXX: For now we support only a single FPU context. */
6873 gen_helper_0e1i(ctc1, t0, rd);
6875 /* COP2: Not implemented. */
6882 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6888 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6889 generate_exception(ctx, EXCP_RI);
6892 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6894 const char *opn = "ldst";
6896 check_cp0_enabled(ctx);
6903 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6908 TCGv t0 = tcg_temp_new();
6910 gen_load_gpr(t0, rt);
6911 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6916 #if defined(TARGET_MIPS64)
6918 check_insn(env, ctx, ISA_MIPS3);
6923 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6927 check_insn(env, ctx, ISA_MIPS3);
6929 TCGv t0 = tcg_temp_new();
6931 gen_load_gpr(t0, rt);
6932 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6939 check_insn(env, ctx, ASE_MT);
6944 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6945 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6949 check_insn(env, ctx, ASE_MT);
6950 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6951 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6956 if (!env->tlb->helper_tlbwi)
6958 gen_helper_tlbwi(cpu_env);
6962 if (!env->tlb->helper_tlbwr)
6964 gen_helper_tlbwr(cpu_env);
6968 if (!env->tlb->helper_tlbp)
6970 gen_helper_tlbp(cpu_env);
6974 if (!env->tlb->helper_tlbr)
6976 gen_helper_tlbr(cpu_env);
6980 check_insn(env, ctx, ISA_MIPS2);
6981 gen_helper_eret(cpu_env);
6982 ctx->bstate = BS_EXCP;
6986 check_insn(env, ctx, ISA_MIPS32);
6987 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6989 generate_exception(ctx, EXCP_RI);
6991 gen_helper_deret(cpu_env);
6992 ctx->bstate = BS_EXCP;
6997 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6998 /* If we get an exception, we want to restart at next instruction */
7000 save_cpu_state(ctx, 1);
7002 gen_helper_wait(cpu_env);
7003 ctx->bstate = BS_EXCP;
7008 generate_exception(ctx, EXCP_RI);
7011 (void)opn; /* avoid a compiler warning */
7012 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7014 #endif /* !CONFIG_USER_ONLY */
7016 /* CP1 Branches (before delay slot) */
7017 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
7018 int32_t cc, int32_t offset)
7020 target_ulong btarget;
7021 const char *opn = "cp1 cond branch";
7022 TCGv_i32 t0 = tcg_temp_new_i32();
7025 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7027 btarget = ctx->pc + 4 + offset;
7031 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7032 tcg_gen_not_i32(t0, t0);
7033 tcg_gen_andi_i32(t0, t0, 1);
7034 tcg_gen_extu_i32_tl(bcond, t0);
7038 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7039 tcg_gen_not_i32(t0, t0);
7040 tcg_gen_andi_i32(t0, t0, 1);
7041 tcg_gen_extu_i32_tl(bcond, t0);
7045 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7046 tcg_gen_andi_i32(t0, t0, 1);
7047 tcg_gen_extu_i32_tl(bcond, t0);
7051 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7052 tcg_gen_andi_i32(t0, t0, 1);
7053 tcg_gen_extu_i32_tl(bcond, t0);
7056 ctx->hflags |= MIPS_HFLAG_BL;
7060 TCGv_i32 t1 = tcg_temp_new_i32();
7061 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7062 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7063 tcg_gen_nand_i32(t0, t0, t1);
7064 tcg_temp_free_i32(t1);
7065 tcg_gen_andi_i32(t0, t0, 1);
7066 tcg_gen_extu_i32_tl(bcond, t0);
7072 TCGv_i32 t1 = tcg_temp_new_i32();
7073 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7074 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7075 tcg_gen_or_i32(t0, t0, t1);
7076 tcg_temp_free_i32(t1);
7077 tcg_gen_andi_i32(t0, t0, 1);
7078 tcg_gen_extu_i32_tl(bcond, t0);
7084 TCGv_i32 t1 = tcg_temp_new_i32();
7085 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7086 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7087 tcg_gen_and_i32(t0, t0, t1);
7088 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7089 tcg_gen_and_i32(t0, t0, t1);
7090 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7091 tcg_gen_nand_i32(t0, t0, t1);
7092 tcg_temp_free_i32(t1);
7093 tcg_gen_andi_i32(t0, t0, 1);
7094 tcg_gen_extu_i32_tl(bcond, t0);
7100 TCGv_i32 t1 = tcg_temp_new_i32();
7101 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7102 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7103 tcg_gen_or_i32(t0, t0, t1);
7104 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7105 tcg_gen_or_i32(t0, t0, t1);
7106 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7107 tcg_gen_or_i32(t0, t0, t1);
7108 tcg_temp_free_i32(t1);
7109 tcg_gen_andi_i32(t0, t0, 1);
7110 tcg_gen_extu_i32_tl(bcond, t0);
7114 ctx->hflags |= MIPS_HFLAG_BC;
7118 generate_exception (ctx, EXCP_RI);
7121 (void)opn; /* avoid a compiler warning */
7122 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7123 ctx->hflags, btarget);
7124 ctx->btarget = btarget;
7127 tcg_temp_free_i32(t0);
7130 /* Coprocessor 1 (FPU) */
7132 #define FOP(func, fmt) (((fmt) << 21) | (func))
7135 OPC_ADD_S = FOP(0, FMT_S),
7136 OPC_SUB_S = FOP(1, FMT_S),
7137 OPC_MUL_S = FOP(2, FMT_S),
7138 OPC_DIV_S = FOP(3, FMT_S),
7139 OPC_SQRT_S = FOP(4, FMT_S),
7140 OPC_ABS_S = FOP(5, FMT_S),
7141 OPC_MOV_S = FOP(6, FMT_S),
7142 OPC_NEG_S = FOP(7, FMT_S),
7143 OPC_ROUND_L_S = FOP(8, FMT_S),
7144 OPC_TRUNC_L_S = FOP(9, FMT_S),
7145 OPC_CEIL_L_S = FOP(10, FMT_S),
7146 OPC_FLOOR_L_S = FOP(11, FMT_S),
7147 OPC_ROUND_W_S = FOP(12, FMT_S),
7148 OPC_TRUNC_W_S = FOP(13, FMT_S),
7149 OPC_CEIL_W_S = FOP(14, FMT_S),
7150 OPC_FLOOR_W_S = FOP(15, FMT_S),
7151 OPC_MOVCF_S = FOP(17, FMT_S),
7152 OPC_MOVZ_S = FOP(18, FMT_S),
7153 OPC_MOVN_S = FOP(19, FMT_S),
7154 OPC_RECIP_S = FOP(21, FMT_S),
7155 OPC_RSQRT_S = FOP(22, FMT_S),
7156 OPC_RECIP2_S = FOP(28, FMT_S),
7157 OPC_RECIP1_S = FOP(29, FMT_S),
7158 OPC_RSQRT1_S = FOP(30, FMT_S),
7159 OPC_RSQRT2_S = FOP(31, FMT_S),
7160 OPC_CVT_D_S = FOP(33, FMT_S),
7161 OPC_CVT_W_S = FOP(36, FMT_S),
7162 OPC_CVT_L_S = FOP(37, FMT_S),
7163 OPC_CVT_PS_S = FOP(38, FMT_S),
7164 OPC_CMP_F_S = FOP (48, FMT_S),
7165 OPC_CMP_UN_S = FOP (49, FMT_S),
7166 OPC_CMP_EQ_S = FOP (50, FMT_S),
7167 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7168 OPC_CMP_OLT_S = FOP (52, FMT_S),
7169 OPC_CMP_ULT_S = FOP (53, FMT_S),
7170 OPC_CMP_OLE_S = FOP (54, FMT_S),
7171 OPC_CMP_ULE_S = FOP (55, FMT_S),
7172 OPC_CMP_SF_S = FOP (56, FMT_S),
7173 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7174 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7175 OPC_CMP_NGL_S = FOP (59, FMT_S),
7176 OPC_CMP_LT_S = FOP (60, FMT_S),
7177 OPC_CMP_NGE_S = FOP (61, FMT_S),
7178 OPC_CMP_LE_S = FOP (62, FMT_S),
7179 OPC_CMP_NGT_S = FOP (63, FMT_S),
7181 OPC_ADD_D = FOP(0, FMT_D),
7182 OPC_SUB_D = FOP(1, FMT_D),
7183 OPC_MUL_D = FOP(2, FMT_D),
7184 OPC_DIV_D = FOP(3, FMT_D),
7185 OPC_SQRT_D = FOP(4, FMT_D),
7186 OPC_ABS_D = FOP(5, FMT_D),
7187 OPC_MOV_D = FOP(6, FMT_D),
7188 OPC_NEG_D = FOP(7, FMT_D),
7189 OPC_ROUND_L_D = FOP(8, FMT_D),
7190 OPC_TRUNC_L_D = FOP(9, FMT_D),
7191 OPC_CEIL_L_D = FOP(10, FMT_D),
7192 OPC_FLOOR_L_D = FOP(11, FMT_D),
7193 OPC_ROUND_W_D = FOP(12, FMT_D),
7194 OPC_TRUNC_W_D = FOP(13, FMT_D),
7195 OPC_CEIL_W_D = FOP(14, FMT_D),
7196 OPC_FLOOR_W_D = FOP(15, FMT_D),
7197 OPC_MOVCF_D = FOP(17, FMT_D),
7198 OPC_MOVZ_D = FOP(18, FMT_D),
7199 OPC_MOVN_D = FOP(19, FMT_D),
7200 OPC_RECIP_D = FOP(21, FMT_D),
7201 OPC_RSQRT_D = FOP(22, FMT_D),
7202 OPC_RECIP2_D = FOP(28, FMT_D),
7203 OPC_RECIP1_D = FOP(29, FMT_D),
7204 OPC_RSQRT1_D = FOP(30, FMT_D),
7205 OPC_RSQRT2_D = FOP(31, FMT_D),
7206 OPC_CVT_S_D = FOP(32, FMT_D),
7207 OPC_CVT_W_D = FOP(36, FMT_D),
7208 OPC_CVT_L_D = FOP(37, FMT_D),
7209 OPC_CMP_F_D = FOP (48, FMT_D),
7210 OPC_CMP_UN_D = FOP (49, FMT_D),
7211 OPC_CMP_EQ_D = FOP (50, FMT_D),
7212 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7213 OPC_CMP_OLT_D = FOP (52, FMT_D),
7214 OPC_CMP_ULT_D = FOP (53, FMT_D),
7215 OPC_CMP_OLE_D = FOP (54, FMT_D),
7216 OPC_CMP_ULE_D = FOP (55, FMT_D),
7217 OPC_CMP_SF_D = FOP (56, FMT_D),
7218 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7219 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7220 OPC_CMP_NGL_D = FOP (59, FMT_D),
7221 OPC_CMP_LT_D = FOP (60, FMT_D),
7222 OPC_CMP_NGE_D = FOP (61, FMT_D),
7223 OPC_CMP_LE_D = FOP (62, FMT_D),
7224 OPC_CMP_NGT_D = FOP (63, FMT_D),
7226 OPC_CVT_S_W = FOP(32, FMT_W),
7227 OPC_CVT_D_W = FOP(33, FMT_W),
7228 OPC_CVT_S_L = FOP(32, FMT_L),
7229 OPC_CVT_D_L = FOP(33, FMT_L),
7230 OPC_CVT_PS_PW = FOP(38, FMT_W),
7232 OPC_ADD_PS = FOP(0, FMT_PS),
7233 OPC_SUB_PS = FOP(1, FMT_PS),
7234 OPC_MUL_PS = FOP(2, FMT_PS),
7235 OPC_DIV_PS = FOP(3, FMT_PS),
7236 OPC_ABS_PS = FOP(5, FMT_PS),
7237 OPC_MOV_PS = FOP(6, FMT_PS),
7238 OPC_NEG_PS = FOP(7, FMT_PS),
7239 OPC_MOVCF_PS = FOP(17, FMT_PS),
7240 OPC_MOVZ_PS = FOP(18, FMT_PS),
7241 OPC_MOVN_PS = FOP(19, FMT_PS),
7242 OPC_ADDR_PS = FOP(24, FMT_PS),
7243 OPC_MULR_PS = FOP(26, FMT_PS),
7244 OPC_RECIP2_PS = FOP(28, FMT_PS),
7245 OPC_RECIP1_PS = FOP(29, FMT_PS),
7246 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7247 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7249 OPC_CVT_S_PU = FOP(32, FMT_PS),
7250 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7251 OPC_CVT_S_PL = FOP(40, FMT_PS),
7252 OPC_PLL_PS = FOP(44, FMT_PS),
7253 OPC_PLU_PS = FOP(45, FMT_PS),
7254 OPC_PUL_PS = FOP(46, FMT_PS),
7255 OPC_PUU_PS = FOP(47, FMT_PS),
7256 OPC_CMP_F_PS = FOP (48, FMT_PS),
7257 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7258 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7259 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7260 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7261 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7262 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7263 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7264 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7265 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7266 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7267 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7268 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7269 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7270 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7271 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7274 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7276 const char *opn = "cp1 move";
7277 TCGv t0 = tcg_temp_new();
7282 TCGv_i32 fp0 = tcg_temp_new_i32();
7284 gen_load_fpr32(fp0, fs);
7285 tcg_gen_ext_i32_tl(t0, fp0);
7286 tcg_temp_free_i32(fp0);
7288 gen_store_gpr(t0, rt);
7292 gen_load_gpr(t0, rt);
7294 TCGv_i32 fp0 = tcg_temp_new_i32();
7296 tcg_gen_trunc_tl_i32(fp0, t0);
7297 gen_store_fpr32(fp0, fs);
7298 tcg_temp_free_i32(fp0);
7303 gen_helper_1e0i(cfc1, t0, fs);
7304 gen_store_gpr(t0, rt);
7308 gen_load_gpr(t0, rt);
7309 gen_helper_0e1i(ctc1, t0, fs);
7312 #if defined(TARGET_MIPS64)
7314 gen_load_fpr64(ctx, t0, fs);
7315 gen_store_gpr(t0, rt);
7319 gen_load_gpr(t0, rt);
7320 gen_store_fpr64(ctx, t0, fs);
7326 TCGv_i32 fp0 = tcg_temp_new_i32();
7328 gen_load_fpr32h(fp0, fs);
7329 tcg_gen_ext_i32_tl(t0, fp0);
7330 tcg_temp_free_i32(fp0);
7332 gen_store_gpr(t0, rt);
7336 gen_load_gpr(t0, rt);
7338 TCGv_i32 fp0 = tcg_temp_new_i32();
7340 tcg_gen_trunc_tl_i32(fp0, t0);
7341 gen_store_fpr32h(fp0, fs);
7342 tcg_temp_free_i32(fp0);
7348 generate_exception (ctx, EXCP_RI);
7351 (void)opn; /* avoid a compiler warning */
7352 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7358 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7374 l1 = gen_new_label();
7375 t0 = tcg_temp_new_i32();
7376 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7377 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7378 tcg_temp_free_i32(t0);
7380 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7382 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7387 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7390 TCGv_i32 t0 = tcg_temp_new_i32();
7391 int l1 = gen_new_label();
7398 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7399 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7400 gen_load_fpr32(t0, fs);
7401 gen_store_fpr32(t0, fd);
7403 tcg_temp_free_i32(t0);
7406 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7409 TCGv_i32 t0 = tcg_temp_new_i32();
7411 int l1 = gen_new_label();
7418 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7419 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7420 tcg_temp_free_i32(t0);
7421 fp0 = tcg_temp_new_i64();
7422 gen_load_fpr64(ctx, fp0, fs);
7423 gen_store_fpr64(ctx, fp0, fd);
7424 tcg_temp_free_i64(fp0);
7428 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7431 TCGv_i32 t0 = tcg_temp_new_i32();
7432 int l1 = gen_new_label();
7433 int l2 = gen_new_label();
7440 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7441 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7442 gen_load_fpr32(t0, fs);
7443 gen_store_fpr32(t0, fd);
7446 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7447 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7448 gen_load_fpr32h(t0, fs);
7449 gen_store_fpr32h(t0, fd);
7450 tcg_temp_free_i32(t0);
7455 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7456 int ft, int fs, int fd, int cc)
7458 const char *opn = "farith";
7459 const char *condnames[] = {
7477 const char *condnames_abs[] = {
7495 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7496 uint32_t func = ctx->opcode & 0x3f;
7501 TCGv_i32 fp0 = tcg_temp_new_i32();
7502 TCGv_i32 fp1 = tcg_temp_new_i32();
7504 gen_load_fpr32(fp0, fs);
7505 gen_load_fpr32(fp1, ft);
7506 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7507 tcg_temp_free_i32(fp1);
7508 gen_store_fpr32(fp0, fd);
7509 tcg_temp_free_i32(fp0);
7516 TCGv_i32 fp0 = tcg_temp_new_i32();
7517 TCGv_i32 fp1 = tcg_temp_new_i32();
7519 gen_load_fpr32(fp0, fs);
7520 gen_load_fpr32(fp1, ft);
7521 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7522 tcg_temp_free_i32(fp1);
7523 gen_store_fpr32(fp0, fd);
7524 tcg_temp_free_i32(fp0);
7531 TCGv_i32 fp0 = tcg_temp_new_i32();
7532 TCGv_i32 fp1 = tcg_temp_new_i32();
7534 gen_load_fpr32(fp0, fs);
7535 gen_load_fpr32(fp1, ft);
7536 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7537 tcg_temp_free_i32(fp1);
7538 gen_store_fpr32(fp0, fd);
7539 tcg_temp_free_i32(fp0);
7546 TCGv_i32 fp0 = tcg_temp_new_i32();
7547 TCGv_i32 fp1 = tcg_temp_new_i32();
7549 gen_load_fpr32(fp0, fs);
7550 gen_load_fpr32(fp1, ft);
7551 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7552 tcg_temp_free_i32(fp1);
7553 gen_store_fpr32(fp0, fd);
7554 tcg_temp_free_i32(fp0);
7561 TCGv_i32 fp0 = tcg_temp_new_i32();
7563 gen_load_fpr32(fp0, fs);
7564 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7565 gen_store_fpr32(fp0, fd);
7566 tcg_temp_free_i32(fp0);
7572 TCGv_i32 fp0 = tcg_temp_new_i32();
7574 gen_load_fpr32(fp0, fs);
7575 gen_helper_float_abs_s(fp0, fp0);
7576 gen_store_fpr32(fp0, fd);
7577 tcg_temp_free_i32(fp0);
7583 TCGv_i32 fp0 = tcg_temp_new_i32();
7585 gen_load_fpr32(fp0, fs);
7586 gen_store_fpr32(fp0, fd);
7587 tcg_temp_free_i32(fp0);
7593 TCGv_i32 fp0 = tcg_temp_new_i32();
7595 gen_load_fpr32(fp0, fs);
7596 gen_helper_float_chs_s(fp0, fp0);
7597 gen_store_fpr32(fp0, fd);
7598 tcg_temp_free_i32(fp0);
7603 check_cp1_64bitmode(ctx);
7605 TCGv_i32 fp32 = tcg_temp_new_i32();
7606 TCGv_i64 fp64 = tcg_temp_new_i64();
7608 gen_load_fpr32(fp32, fs);
7609 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7610 tcg_temp_free_i32(fp32);
7611 gen_store_fpr64(ctx, fp64, fd);
7612 tcg_temp_free_i64(fp64);
7617 check_cp1_64bitmode(ctx);
7619 TCGv_i32 fp32 = tcg_temp_new_i32();
7620 TCGv_i64 fp64 = tcg_temp_new_i64();
7622 gen_load_fpr32(fp32, fs);
7623 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7624 tcg_temp_free_i32(fp32);
7625 gen_store_fpr64(ctx, fp64, fd);
7626 tcg_temp_free_i64(fp64);
7631 check_cp1_64bitmode(ctx);
7633 TCGv_i32 fp32 = tcg_temp_new_i32();
7634 TCGv_i64 fp64 = tcg_temp_new_i64();
7636 gen_load_fpr32(fp32, fs);
7637 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7638 tcg_temp_free_i32(fp32);
7639 gen_store_fpr64(ctx, fp64, fd);
7640 tcg_temp_free_i64(fp64);
7645 check_cp1_64bitmode(ctx);
7647 TCGv_i32 fp32 = tcg_temp_new_i32();
7648 TCGv_i64 fp64 = tcg_temp_new_i64();
7650 gen_load_fpr32(fp32, fs);
7651 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7652 tcg_temp_free_i32(fp32);
7653 gen_store_fpr64(ctx, fp64, fd);
7654 tcg_temp_free_i64(fp64);
7660 TCGv_i32 fp0 = tcg_temp_new_i32();
7662 gen_load_fpr32(fp0, fs);
7663 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7664 gen_store_fpr32(fp0, fd);
7665 tcg_temp_free_i32(fp0);
7671 TCGv_i32 fp0 = tcg_temp_new_i32();
7673 gen_load_fpr32(fp0, fs);
7674 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7675 gen_store_fpr32(fp0, fd);
7676 tcg_temp_free_i32(fp0);
7682 TCGv_i32 fp0 = tcg_temp_new_i32();
7684 gen_load_fpr32(fp0, fs);
7685 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7686 gen_store_fpr32(fp0, fd);
7687 tcg_temp_free_i32(fp0);
7693 TCGv_i32 fp0 = tcg_temp_new_i32();
7695 gen_load_fpr32(fp0, fs);
7696 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7697 gen_store_fpr32(fp0, fd);
7698 tcg_temp_free_i32(fp0);
7703 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7708 int l1 = gen_new_label();
7712 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7714 fp0 = tcg_temp_new_i32();
7715 gen_load_fpr32(fp0, fs);
7716 gen_store_fpr32(fp0, fd);
7717 tcg_temp_free_i32(fp0);
7724 int l1 = gen_new_label();
7728 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7729 fp0 = tcg_temp_new_i32();
7730 gen_load_fpr32(fp0, fs);
7731 gen_store_fpr32(fp0, fd);
7732 tcg_temp_free_i32(fp0);
7741 TCGv_i32 fp0 = tcg_temp_new_i32();
7743 gen_load_fpr32(fp0, fs);
7744 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7745 gen_store_fpr32(fp0, fd);
7746 tcg_temp_free_i32(fp0);
7753 TCGv_i32 fp0 = tcg_temp_new_i32();
7755 gen_load_fpr32(fp0, fs);
7756 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7757 gen_store_fpr32(fp0, fd);
7758 tcg_temp_free_i32(fp0);
7763 check_cp1_64bitmode(ctx);
7765 TCGv_i32 fp0 = tcg_temp_new_i32();
7766 TCGv_i32 fp1 = tcg_temp_new_i32();
7768 gen_load_fpr32(fp0, fs);
7769 gen_load_fpr32(fp1, ft);
7770 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7771 tcg_temp_free_i32(fp1);
7772 gen_store_fpr32(fp0, fd);
7773 tcg_temp_free_i32(fp0);
7778 check_cp1_64bitmode(ctx);
7780 TCGv_i32 fp0 = tcg_temp_new_i32();
7782 gen_load_fpr32(fp0, fs);
7783 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7784 gen_store_fpr32(fp0, fd);
7785 tcg_temp_free_i32(fp0);
7790 check_cp1_64bitmode(ctx);
7792 TCGv_i32 fp0 = tcg_temp_new_i32();
7794 gen_load_fpr32(fp0, fs);
7795 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7796 gen_store_fpr32(fp0, fd);
7797 tcg_temp_free_i32(fp0);
7802 check_cp1_64bitmode(ctx);
7804 TCGv_i32 fp0 = tcg_temp_new_i32();
7805 TCGv_i32 fp1 = tcg_temp_new_i32();
7807 gen_load_fpr32(fp0, fs);
7808 gen_load_fpr32(fp1, ft);
7809 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7810 tcg_temp_free_i32(fp1);
7811 gen_store_fpr32(fp0, fd);
7812 tcg_temp_free_i32(fp0);
7817 check_cp1_registers(ctx, fd);
7819 TCGv_i32 fp32 = tcg_temp_new_i32();
7820 TCGv_i64 fp64 = tcg_temp_new_i64();
7822 gen_load_fpr32(fp32, fs);
7823 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7824 tcg_temp_free_i32(fp32);
7825 gen_store_fpr64(ctx, fp64, fd);
7826 tcg_temp_free_i64(fp64);
7832 TCGv_i32 fp0 = tcg_temp_new_i32();
7834 gen_load_fpr32(fp0, fs);
7835 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7836 gen_store_fpr32(fp0, fd);
7837 tcg_temp_free_i32(fp0);
7842 check_cp1_64bitmode(ctx);
7844 TCGv_i32 fp32 = tcg_temp_new_i32();
7845 TCGv_i64 fp64 = tcg_temp_new_i64();
7847 gen_load_fpr32(fp32, fs);
7848 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7849 tcg_temp_free_i32(fp32);
7850 gen_store_fpr64(ctx, fp64, fd);
7851 tcg_temp_free_i64(fp64);
7856 check_cp1_64bitmode(ctx);
7858 TCGv_i64 fp64 = tcg_temp_new_i64();
7859 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7860 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7862 gen_load_fpr32(fp32_0, fs);
7863 gen_load_fpr32(fp32_1, ft);
7864 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7865 tcg_temp_free_i32(fp32_1);
7866 tcg_temp_free_i32(fp32_0);
7867 gen_store_fpr64(ctx, fp64, fd);
7868 tcg_temp_free_i64(fp64);
7881 case OPC_CMP_NGLE_S:
7888 if (ctx->opcode & (1 << 6)) {
7889 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7890 opn = condnames_abs[func-48];
7892 gen_cmp_s(ctx, func-48, ft, fs, cc);
7893 opn = condnames[func-48];
7897 check_cp1_registers(ctx, fs | ft | fd);
7899 TCGv_i64 fp0 = tcg_temp_new_i64();
7900 TCGv_i64 fp1 = tcg_temp_new_i64();
7902 gen_load_fpr64(ctx, fp0, fs);
7903 gen_load_fpr64(ctx, fp1, ft);
7904 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7905 tcg_temp_free_i64(fp1);
7906 gen_store_fpr64(ctx, fp0, fd);
7907 tcg_temp_free_i64(fp0);
7913 check_cp1_registers(ctx, fs | ft | fd);
7915 TCGv_i64 fp0 = tcg_temp_new_i64();
7916 TCGv_i64 fp1 = tcg_temp_new_i64();
7918 gen_load_fpr64(ctx, fp0, fs);
7919 gen_load_fpr64(ctx, fp1, ft);
7920 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7921 tcg_temp_free_i64(fp1);
7922 gen_store_fpr64(ctx, fp0, fd);
7923 tcg_temp_free_i64(fp0);
7929 check_cp1_registers(ctx, fs | ft | fd);
7931 TCGv_i64 fp0 = tcg_temp_new_i64();
7932 TCGv_i64 fp1 = tcg_temp_new_i64();
7934 gen_load_fpr64(ctx, fp0, fs);
7935 gen_load_fpr64(ctx, fp1, ft);
7936 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7937 tcg_temp_free_i64(fp1);
7938 gen_store_fpr64(ctx, fp0, fd);
7939 tcg_temp_free_i64(fp0);
7945 check_cp1_registers(ctx, fs | ft | fd);
7947 TCGv_i64 fp0 = tcg_temp_new_i64();
7948 TCGv_i64 fp1 = tcg_temp_new_i64();
7950 gen_load_fpr64(ctx, fp0, fs);
7951 gen_load_fpr64(ctx, fp1, ft);
7952 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7953 tcg_temp_free_i64(fp1);
7954 gen_store_fpr64(ctx, fp0, fd);
7955 tcg_temp_free_i64(fp0);
7961 check_cp1_registers(ctx, fs | fd);
7963 TCGv_i64 fp0 = tcg_temp_new_i64();
7965 gen_load_fpr64(ctx, fp0, fs);
7966 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7967 gen_store_fpr64(ctx, fp0, fd);
7968 tcg_temp_free_i64(fp0);
7973 check_cp1_registers(ctx, fs | fd);
7975 TCGv_i64 fp0 = tcg_temp_new_i64();
7977 gen_load_fpr64(ctx, fp0, fs);
7978 gen_helper_float_abs_d(fp0, fp0);
7979 gen_store_fpr64(ctx, fp0, fd);
7980 tcg_temp_free_i64(fp0);
7985 check_cp1_registers(ctx, fs | fd);
7987 TCGv_i64 fp0 = tcg_temp_new_i64();
7989 gen_load_fpr64(ctx, fp0, fs);
7990 gen_store_fpr64(ctx, fp0, fd);
7991 tcg_temp_free_i64(fp0);
7996 check_cp1_registers(ctx, fs | fd);
7998 TCGv_i64 fp0 = tcg_temp_new_i64();
8000 gen_load_fpr64(ctx, fp0, fs);
8001 gen_helper_float_chs_d(fp0, fp0);
8002 gen_store_fpr64(ctx, fp0, fd);
8003 tcg_temp_free_i64(fp0);
8008 check_cp1_64bitmode(ctx);
8010 TCGv_i64 fp0 = tcg_temp_new_i64();
8012 gen_load_fpr64(ctx, fp0, fs);
8013 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
8014 gen_store_fpr64(ctx, fp0, fd);
8015 tcg_temp_free_i64(fp0);
8020 check_cp1_64bitmode(ctx);
8022 TCGv_i64 fp0 = tcg_temp_new_i64();
8024 gen_load_fpr64(ctx, fp0, fs);
8025 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8026 gen_store_fpr64(ctx, fp0, fd);
8027 tcg_temp_free_i64(fp0);
8032 check_cp1_64bitmode(ctx);
8034 TCGv_i64 fp0 = tcg_temp_new_i64();
8036 gen_load_fpr64(ctx, fp0, fs);
8037 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8038 gen_store_fpr64(ctx, fp0, fd);
8039 tcg_temp_free_i64(fp0);
8044 check_cp1_64bitmode(ctx);
8046 TCGv_i64 fp0 = tcg_temp_new_i64();
8048 gen_load_fpr64(ctx, fp0, fs);
8049 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8050 gen_store_fpr64(ctx, fp0, fd);
8051 tcg_temp_free_i64(fp0);
8056 check_cp1_registers(ctx, fs);
8058 TCGv_i32 fp32 = tcg_temp_new_i32();
8059 TCGv_i64 fp64 = tcg_temp_new_i64();
8061 gen_load_fpr64(ctx, fp64, fs);
8062 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8063 tcg_temp_free_i64(fp64);
8064 gen_store_fpr32(fp32, fd);
8065 tcg_temp_free_i32(fp32);
8070 check_cp1_registers(ctx, fs);
8072 TCGv_i32 fp32 = tcg_temp_new_i32();
8073 TCGv_i64 fp64 = tcg_temp_new_i64();
8075 gen_load_fpr64(ctx, fp64, fs);
8076 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8077 tcg_temp_free_i64(fp64);
8078 gen_store_fpr32(fp32, fd);
8079 tcg_temp_free_i32(fp32);
8084 check_cp1_registers(ctx, fs);
8086 TCGv_i32 fp32 = tcg_temp_new_i32();
8087 TCGv_i64 fp64 = tcg_temp_new_i64();
8089 gen_load_fpr64(ctx, fp64, fs);
8090 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8091 tcg_temp_free_i64(fp64);
8092 gen_store_fpr32(fp32, fd);
8093 tcg_temp_free_i32(fp32);
8098 check_cp1_registers(ctx, fs);
8100 TCGv_i32 fp32 = tcg_temp_new_i32();
8101 TCGv_i64 fp64 = tcg_temp_new_i64();
8103 gen_load_fpr64(ctx, fp64, fs);
8104 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8105 tcg_temp_free_i64(fp64);
8106 gen_store_fpr32(fp32, fd);
8107 tcg_temp_free_i32(fp32);
8112 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8117 int l1 = gen_new_label();
8121 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8123 fp0 = tcg_temp_new_i64();
8124 gen_load_fpr64(ctx, fp0, fs);
8125 gen_store_fpr64(ctx, fp0, fd);
8126 tcg_temp_free_i64(fp0);
8133 int l1 = gen_new_label();
8137 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8138 fp0 = tcg_temp_new_i64();
8139 gen_load_fpr64(ctx, fp0, fs);
8140 gen_store_fpr64(ctx, fp0, fd);
8141 tcg_temp_free_i64(fp0);
8148 check_cp1_64bitmode(ctx);
8150 TCGv_i64 fp0 = tcg_temp_new_i64();
8152 gen_load_fpr64(ctx, fp0, fs);
8153 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8154 gen_store_fpr64(ctx, fp0, fd);
8155 tcg_temp_free_i64(fp0);
8160 check_cp1_64bitmode(ctx);
8162 TCGv_i64 fp0 = tcg_temp_new_i64();
8164 gen_load_fpr64(ctx, fp0, fs);
8165 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8166 gen_store_fpr64(ctx, fp0, fd);
8167 tcg_temp_free_i64(fp0);
8172 check_cp1_64bitmode(ctx);
8174 TCGv_i64 fp0 = tcg_temp_new_i64();
8175 TCGv_i64 fp1 = tcg_temp_new_i64();
8177 gen_load_fpr64(ctx, fp0, fs);
8178 gen_load_fpr64(ctx, fp1, ft);
8179 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8180 tcg_temp_free_i64(fp1);
8181 gen_store_fpr64(ctx, fp0, fd);
8182 tcg_temp_free_i64(fp0);
8187 check_cp1_64bitmode(ctx);
8189 TCGv_i64 fp0 = tcg_temp_new_i64();
8191 gen_load_fpr64(ctx, fp0, fs);
8192 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8193 gen_store_fpr64(ctx, fp0, fd);
8194 tcg_temp_free_i64(fp0);
8199 check_cp1_64bitmode(ctx);
8201 TCGv_i64 fp0 = tcg_temp_new_i64();
8203 gen_load_fpr64(ctx, fp0, fs);
8204 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8205 gen_store_fpr64(ctx, fp0, fd);
8206 tcg_temp_free_i64(fp0);
8211 check_cp1_64bitmode(ctx);
8213 TCGv_i64 fp0 = tcg_temp_new_i64();
8214 TCGv_i64 fp1 = tcg_temp_new_i64();
8216 gen_load_fpr64(ctx, fp0, fs);
8217 gen_load_fpr64(ctx, fp1, ft);
8218 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8219 tcg_temp_free_i64(fp1);
8220 gen_store_fpr64(ctx, fp0, fd);
8221 tcg_temp_free_i64(fp0);
8234 case OPC_CMP_NGLE_D:
8241 if (ctx->opcode & (1 << 6)) {
8242 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8243 opn = condnames_abs[func-48];
8245 gen_cmp_d(ctx, func-48, ft, fs, cc);
8246 opn = condnames[func-48];
8250 check_cp1_registers(ctx, fs);
8252 TCGv_i32 fp32 = tcg_temp_new_i32();
8253 TCGv_i64 fp64 = tcg_temp_new_i64();
8255 gen_load_fpr64(ctx, fp64, fs);
8256 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8257 tcg_temp_free_i64(fp64);
8258 gen_store_fpr32(fp32, fd);
8259 tcg_temp_free_i32(fp32);
8264 check_cp1_registers(ctx, fs);
8266 TCGv_i32 fp32 = tcg_temp_new_i32();
8267 TCGv_i64 fp64 = tcg_temp_new_i64();
8269 gen_load_fpr64(ctx, fp64, fs);
8270 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8271 tcg_temp_free_i64(fp64);
8272 gen_store_fpr32(fp32, fd);
8273 tcg_temp_free_i32(fp32);
8278 check_cp1_64bitmode(ctx);
8280 TCGv_i64 fp0 = tcg_temp_new_i64();
8282 gen_load_fpr64(ctx, fp0, fs);
8283 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8284 gen_store_fpr64(ctx, fp0, fd);
8285 tcg_temp_free_i64(fp0);
8291 TCGv_i32 fp0 = tcg_temp_new_i32();
8293 gen_load_fpr32(fp0, fs);
8294 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8295 gen_store_fpr32(fp0, fd);
8296 tcg_temp_free_i32(fp0);
8301 check_cp1_registers(ctx, fd);
8303 TCGv_i32 fp32 = tcg_temp_new_i32();
8304 TCGv_i64 fp64 = tcg_temp_new_i64();
8306 gen_load_fpr32(fp32, fs);
8307 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8308 tcg_temp_free_i32(fp32);
8309 gen_store_fpr64(ctx, fp64, fd);
8310 tcg_temp_free_i64(fp64);
8315 check_cp1_64bitmode(ctx);
8317 TCGv_i32 fp32 = tcg_temp_new_i32();
8318 TCGv_i64 fp64 = tcg_temp_new_i64();
8320 gen_load_fpr64(ctx, fp64, fs);
8321 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8322 tcg_temp_free_i64(fp64);
8323 gen_store_fpr32(fp32, fd);
8324 tcg_temp_free_i32(fp32);
8329 check_cp1_64bitmode(ctx);
8331 TCGv_i64 fp0 = tcg_temp_new_i64();
8333 gen_load_fpr64(ctx, fp0, fs);
8334 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8335 gen_store_fpr64(ctx, fp0, fd);
8336 tcg_temp_free_i64(fp0);
8341 check_cp1_64bitmode(ctx);
8343 TCGv_i64 fp0 = tcg_temp_new_i64();
8345 gen_load_fpr64(ctx, fp0, fs);
8346 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8347 gen_store_fpr64(ctx, fp0, fd);
8348 tcg_temp_free_i64(fp0);
8353 check_cp1_64bitmode(ctx);
8355 TCGv_i64 fp0 = tcg_temp_new_i64();
8356 TCGv_i64 fp1 = tcg_temp_new_i64();
8358 gen_load_fpr64(ctx, fp0, fs);
8359 gen_load_fpr64(ctx, fp1, ft);
8360 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8361 tcg_temp_free_i64(fp1);
8362 gen_store_fpr64(ctx, fp0, fd);
8363 tcg_temp_free_i64(fp0);
8368 check_cp1_64bitmode(ctx);
8370 TCGv_i64 fp0 = tcg_temp_new_i64();
8371 TCGv_i64 fp1 = tcg_temp_new_i64();
8373 gen_load_fpr64(ctx, fp0, fs);
8374 gen_load_fpr64(ctx, fp1, ft);
8375 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8376 tcg_temp_free_i64(fp1);
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();
8386 TCGv_i64 fp1 = tcg_temp_new_i64();
8388 gen_load_fpr64(ctx, fp0, fs);
8389 gen_load_fpr64(ctx, fp1, ft);
8390 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8391 tcg_temp_free_i64(fp1);
8392 gen_store_fpr64(ctx, fp0, fd);
8393 tcg_temp_free_i64(fp0);
8398 check_cp1_64bitmode(ctx);
8400 TCGv_i64 fp0 = tcg_temp_new_i64();
8402 gen_load_fpr64(ctx, fp0, fs);
8403 gen_helper_float_abs_ps(fp0, fp0);
8404 gen_store_fpr64(ctx, fp0, fd);
8405 tcg_temp_free_i64(fp0);
8410 check_cp1_64bitmode(ctx);
8412 TCGv_i64 fp0 = tcg_temp_new_i64();
8414 gen_load_fpr64(ctx, fp0, fs);
8415 gen_store_fpr64(ctx, fp0, fd);
8416 tcg_temp_free_i64(fp0);
8421 check_cp1_64bitmode(ctx);
8423 TCGv_i64 fp0 = tcg_temp_new_i64();
8425 gen_load_fpr64(ctx, fp0, fs);
8426 gen_helper_float_chs_ps(fp0, fp0);
8427 gen_store_fpr64(ctx, fp0, fd);
8428 tcg_temp_free_i64(fp0);
8433 check_cp1_64bitmode(ctx);
8434 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8438 check_cp1_64bitmode(ctx);
8440 int l1 = gen_new_label();
8444 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8445 fp0 = tcg_temp_new_i64();
8446 gen_load_fpr64(ctx, fp0, fs);
8447 gen_store_fpr64(ctx, fp0, fd);
8448 tcg_temp_free_i64(fp0);
8454 check_cp1_64bitmode(ctx);
8456 int l1 = gen_new_label();
8460 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8461 fp0 = tcg_temp_new_i64();
8462 gen_load_fpr64(ctx, fp0, fs);
8463 gen_store_fpr64(ctx, fp0, fd);
8464 tcg_temp_free_i64(fp0);
8471 check_cp1_64bitmode(ctx);
8473 TCGv_i64 fp0 = tcg_temp_new_i64();
8474 TCGv_i64 fp1 = tcg_temp_new_i64();
8476 gen_load_fpr64(ctx, fp0, ft);
8477 gen_load_fpr64(ctx, fp1, fs);
8478 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8479 tcg_temp_free_i64(fp1);
8480 gen_store_fpr64(ctx, fp0, fd);
8481 tcg_temp_free_i64(fp0);
8486 check_cp1_64bitmode(ctx);
8488 TCGv_i64 fp0 = tcg_temp_new_i64();
8489 TCGv_i64 fp1 = tcg_temp_new_i64();
8491 gen_load_fpr64(ctx, fp0, ft);
8492 gen_load_fpr64(ctx, fp1, fs);
8493 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8494 tcg_temp_free_i64(fp1);
8495 gen_store_fpr64(ctx, fp0, fd);
8496 tcg_temp_free_i64(fp0);
8501 check_cp1_64bitmode(ctx);
8503 TCGv_i64 fp0 = tcg_temp_new_i64();
8504 TCGv_i64 fp1 = tcg_temp_new_i64();
8506 gen_load_fpr64(ctx, fp0, fs);
8507 gen_load_fpr64(ctx, fp1, ft);
8508 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8509 tcg_temp_free_i64(fp1);
8510 gen_store_fpr64(ctx, fp0, fd);
8511 tcg_temp_free_i64(fp0);
8516 check_cp1_64bitmode(ctx);
8518 TCGv_i64 fp0 = tcg_temp_new_i64();
8520 gen_load_fpr64(ctx, fp0, fs);
8521 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8522 gen_store_fpr64(ctx, fp0, fd);
8523 tcg_temp_free_i64(fp0);
8528 check_cp1_64bitmode(ctx);
8530 TCGv_i64 fp0 = tcg_temp_new_i64();
8532 gen_load_fpr64(ctx, fp0, fs);
8533 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8534 gen_store_fpr64(ctx, fp0, fd);
8535 tcg_temp_free_i64(fp0);
8540 check_cp1_64bitmode(ctx);
8542 TCGv_i64 fp0 = tcg_temp_new_i64();
8543 TCGv_i64 fp1 = tcg_temp_new_i64();
8545 gen_load_fpr64(ctx, fp0, fs);
8546 gen_load_fpr64(ctx, fp1, ft);
8547 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8548 tcg_temp_free_i64(fp1);
8549 gen_store_fpr64(ctx, fp0, fd);
8550 tcg_temp_free_i64(fp0);
8555 check_cp1_64bitmode(ctx);
8557 TCGv_i32 fp0 = tcg_temp_new_i32();
8559 gen_load_fpr32h(fp0, fs);
8560 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8561 gen_store_fpr32(fp0, fd);
8562 tcg_temp_free_i32(fp0);
8567 check_cp1_64bitmode(ctx);
8569 TCGv_i64 fp0 = tcg_temp_new_i64();
8571 gen_load_fpr64(ctx, fp0, fs);
8572 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8573 gen_store_fpr64(ctx, fp0, fd);
8574 tcg_temp_free_i64(fp0);
8579 check_cp1_64bitmode(ctx);
8581 TCGv_i32 fp0 = tcg_temp_new_i32();
8583 gen_load_fpr32(fp0, fs);
8584 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8585 gen_store_fpr32(fp0, fd);
8586 tcg_temp_free_i32(fp0);
8591 check_cp1_64bitmode(ctx);
8593 TCGv_i32 fp0 = tcg_temp_new_i32();
8594 TCGv_i32 fp1 = tcg_temp_new_i32();
8596 gen_load_fpr32(fp0, fs);
8597 gen_load_fpr32(fp1, ft);
8598 gen_store_fpr32h(fp0, fd);
8599 gen_store_fpr32(fp1, fd);
8600 tcg_temp_free_i32(fp0);
8601 tcg_temp_free_i32(fp1);
8606 check_cp1_64bitmode(ctx);
8608 TCGv_i32 fp0 = tcg_temp_new_i32();
8609 TCGv_i32 fp1 = tcg_temp_new_i32();
8611 gen_load_fpr32(fp0, fs);
8612 gen_load_fpr32h(fp1, ft);
8613 gen_store_fpr32(fp1, fd);
8614 gen_store_fpr32h(fp0, fd);
8615 tcg_temp_free_i32(fp0);
8616 tcg_temp_free_i32(fp1);
8621 check_cp1_64bitmode(ctx);
8623 TCGv_i32 fp0 = tcg_temp_new_i32();
8624 TCGv_i32 fp1 = tcg_temp_new_i32();
8626 gen_load_fpr32h(fp0, fs);
8627 gen_load_fpr32(fp1, ft);
8628 gen_store_fpr32(fp1, fd);
8629 gen_store_fpr32h(fp0, fd);
8630 tcg_temp_free_i32(fp0);
8631 tcg_temp_free_i32(fp1);
8636 check_cp1_64bitmode(ctx);
8638 TCGv_i32 fp0 = tcg_temp_new_i32();
8639 TCGv_i32 fp1 = tcg_temp_new_i32();
8641 gen_load_fpr32h(fp0, fs);
8642 gen_load_fpr32h(fp1, ft);
8643 gen_store_fpr32(fp1, fd);
8644 gen_store_fpr32h(fp0, fd);
8645 tcg_temp_free_i32(fp0);
8646 tcg_temp_free_i32(fp1);
8653 case OPC_CMP_UEQ_PS:
8654 case OPC_CMP_OLT_PS:
8655 case OPC_CMP_ULT_PS:
8656 case OPC_CMP_OLE_PS:
8657 case OPC_CMP_ULE_PS:
8659 case OPC_CMP_NGLE_PS:
8660 case OPC_CMP_SEQ_PS:
8661 case OPC_CMP_NGL_PS:
8663 case OPC_CMP_NGE_PS:
8665 case OPC_CMP_NGT_PS:
8666 if (ctx->opcode & (1 << 6)) {
8667 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8668 opn = condnames_abs[func-48];
8670 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8671 opn = condnames[func-48];
8676 generate_exception (ctx, EXCP_RI);
8679 (void)opn; /* avoid a compiler warning */
8682 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8685 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8688 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8693 /* Coprocessor 3 (FPU) */
8694 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8695 int fd, int fs, int base, int index)
8697 const char *opn = "extended float load/store";
8699 TCGv t0 = tcg_temp_new();
8702 gen_load_gpr(t0, index);
8703 } else if (index == 0) {
8704 gen_load_gpr(t0, base);
8706 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8708 /* Don't do NOP if destination is zero: we must perform the actual
8714 TCGv_i32 fp0 = tcg_temp_new_i32();
8716 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8717 tcg_gen_trunc_tl_i32(fp0, t0);
8718 gen_store_fpr32(fp0, fd);
8719 tcg_temp_free_i32(fp0);
8725 check_cp1_registers(ctx, fd);
8727 TCGv_i64 fp0 = tcg_temp_new_i64();
8729 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8730 gen_store_fpr64(ctx, fp0, fd);
8731 tcg_temp_free_i64(fp0);
8736 check_cp1_64bitmode(ctx);
8737 tcg_gen_andi_tl(t0, t0, ~0x7);
8739 TCGv_i64 fp0 = tcg_temp_new_i64();
8741 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8742 gen_store_fpr64(ctx, fp0, fd);
8743 tcg_temp_free_i64(fp0);
8750 TCGv_i32 fp0 = tcg_temp_new_i32();
8751 TCGv t1 = tcg_temp_new();
8753 gen_load_fpr32(fp0, fs);
8754 tcg_gen_extu_i32_tl(t1, fp0);
8755 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8756 tcg_temp_free_i32(fp0);
8764 check_cp1_registers(ctx, fs);
8766 TCGv_i64 fp0 = tcg_temp_new_i64();
8768 gen_load_fpr64(ctx, fp0, fs);
8769 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8770 tcg_temp_free_i64(fp0);
8776 check_cp1_64bitmode(ctx);
8777 tcg_gen_andi_tl(t0, t0, ~0x7);
8779 TCGv_i64 fp0 = tcg_temp_new_i64();
8781 gen_load_fpr64(ctx, fp0, fs);
8782 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8783 tcg_temp_free_i64(fp0);
8790 (void)opn; (void)store; /* avoid compiler warnings */
8791 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8792 regnames[index], regnames[base]);
8795 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8796 int fd, int fr, int fs, int ft)
8798 const char *opn = "flt3_arith";
8802 check_cp1_64bitmode(ctx);
8804 TCGv t0 = tcg_temp_local_new();
8805 TCGv_i32 fp = tcg_temp_new_i32();
8806 TCGv_i32 fph = tcg_temp_new_i32();
8807 int l1 = gen_new_label();
8808 int l2 = gen_new_label();
8810 gen_load_gpr(t0, fr);
8811 tcg_gen_andi_tl(t0, t0, 0x7);
8813 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8814 gen_load_fpr32(fp, fs);
8815 gen_load_fpr32h(fph, fs);
8816 gen_store_fpr32(fp, fd);
8817 gen_store_fpr32h(fph, fd);
8820 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8822 #ifdef TARGET_WORDS_BIGENDIAN
8823 gen_load_fpr32(fp, fs);
8824 gen_load_fpr32h(fph, ft);
8825 gen_store_fpr32h(fp, fd);
8826 gen_store_fpr32(fph, fd);
8828 gen_load_fpr32h(fph, fs);
8829 gen_load_fpr32(fp, ft);
8830 gen_store_fpr32(fph, fd);
8831 gen_store_fpr32h(fp, fd);
8834 tcg_temp_free_i32(fp);
8835 tcg_temp_free_i32(fph);
8842 TCGv_i32 fp0 = tcg_temp_new_i32();
8843 TCGv_i32 fp1 = tcg_temp_new_i32();
8844 TCGv_i32 fp2 = tcg_temp_new_i32();
8846 gen_load_fpr32(fp0, fs);
8847 gen_load_fpr32(fp1, ft);
8848 gen_load_fpr32(fp2, fr);
8849 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8850 tcg_temp_free_i32(fp0);
8851 tcg_temp_free_i32(fp1);
8852 gen_store_fpr32(fp2, fd);
8853 tcg_temp_free_i32(fp2);
8859 check_cp1_registers(ctx, fd | fs | ft | fr);
8861 TCGv_i64 fp0 = tcg_temp_new_i64();
8862 TCGv_i64 fp1 = tcg_temp_new_i64();
8863 TCGv_i64 fp2 = tcg_temp_new_i64();
8865 gen_load_fpr64(ctx, fp0, fs);
8866 gen_load_fpr64(ctx, fp1, ft);
8867 gen_load_fpr64(ctx, fp2, fr);
8868 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8869 tcg_temp_free_i64(fp0);
8870 tcg_temp_free_i64(fp1);
8871 gen_store_fpr64(ctx, fp2, fd);
8872 tcg_temp_free_i64(fp2);
8877 check_cp1_64bitmode(ctx);
8879 TCGv_i64 fp0 = tcg_temp_new_i64();
8880 TCGv_i64 fp1 = tcg_temp_new_i64();
8881 TCGv_i64 fp2 = tcg_temp_new_i64();
8883 gen_load_fpr64(ctx, fp0, fs);
8884 gen_load_fpr64(ctx, fp1, ft);
8885 gen_load_fpr64(ctx, fp2, fr);
8886 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8887 tcg_temp_free_i64(fp0);
8888 tcg_temp_free_i64(fp1);
8889 gen_store_fpr64(ctx, fp2, fd);
8890 tcg_temp_free_i64(fp2);
8897 TCGv_i32 fp0 = tcg_temp_new_i32();
8898 TCGv_i32 fp1 = tcg_temp_new_i32();
8899 TCGv_i32 fp2 = tcg_temp_new_i32();
8901 gen_load_fpr32(fp0, fs);
8902 gen_load_fpr32(fp1, ft);
8903 gen_load_fpr32(fp2, fr);
8904 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8905 tcg_temp_free_i32(fp0);
8906 tcg_temp_free_i32(fp1);
8907 gen_store_fpr32(fp2, fd);
8908 tcg_temp_free_i32(fp2);
8914 check_cp1_registers(ctx, fd | fs | ft | fr);
8916 TCGv_i64 fp0 = tcg_temp_new_i64();
8917 TCGv_i64 fp1 = tcg_temp_new_i64();
8918 TCGv_i64 fp2 = tcg_temp_new_i64();
8920 gen_load_fpr64(ctx, fp0, fs);
8921 gen_load_fpr64(ctx, fp1, ft);
8922 gen_load_fpr64(ctx, fp2, fr);
8923 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8924 tcg_temp_free_i64(fp0);
8925 tcg_temp_free_i64(fp1);
8926 gen_store_fpr64(ctx, fp2, fd);
8927 tcg_temp_free_i64(fp2);
8932 check_cp1_64bitmode(ctx);
8934 TCGv_i64 fp0 = tcg_temp_new_i64();
8935 TCGv_i64 fp1 = tcg_temp_new_i64();
8936 TCGv_i64 fp2 = tcg_temp_new_i64();
8938 gen_load_fpr64(ctx, fp0, fs);
8939 gen_load_fpr64(ctx, fp1, ft);
8940 gen_load_fpr64(ctx, fp2, fr);
8941 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8942 tcg_temp_free_i64(fp0);
8943 tcg_temp_free_i64(fp1);
8944 gen_store_fpr64(ctx, fp2, fd);
8945 tcg_temp_free_i64(fp2);
8952 TCGv_i32 fp0 = tcg_temp_new_i32();
8953 TCGv_i32 fp1 = tcg_temp_new_i32();
8954 TCGv_i32 fp2 = tcg_temp_new_i32();
8956 gen_load_fpr32(fp0, fs);
8957 gen_load_fpr32(fp1, ft);
8958 gen_load_fpr32(fp2, fr);
8959 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8960 tcg_temp_free_i32(fp0);
8961 tcg_temp_free_i32(fp1);
8962 gen_store_fpr32(fp2, fd);
8963 tcg_temp_free_i32(fp2);
8969 check_cp1_registers(ctx, fd | fs | ft | fr);
8971 TCGv_i64 fp0 = tcg_temp_new_i64();
8972 TCGv_i64 fp1 = tcg_temp_new_i64();
8973 TCGv_i64 fp2 = tcg_temp_new_i64();
8975 gen_load_fpr64(ctx, fp0, fs);
8976 gen_load_fpr64(ctx, fp1, ft);
8977 gen_load_fpr64(ctx, fp2, fr);
8978 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8979 tcg_temp_free_i64(fp0);
8980 tcg_temp_free_i64(fp1);
8981 gen_store_fpr64(ctx, fp2, fd);
8982 tcg_temp_free_i64(fp2);
8987 check_cp1_64bitmode(ctx);
8989 TCGv_i64 fp0 = tcg_temp_new_i64();
8990 TCGv_i64 fp1 = tcg_temp_new_i64();
8991 TCGv_i64 fp2 = tcg_temp_new_i64();
8993 gen_load_fpr64(ctx, fp0, fs);
8994 gen_load_fpr64(ctx, fp1, ft);
8995 gen_load_fpr64(ctx, fp2, fr);
8996 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8997 tcg_temp_free_i64(fp0);
8998 tcg_temp_free_i64(fp1);
8999 gen_store_fpr64(ctx, fp2, fd);
9000 tcg_temp_free_i64(fp2);
9007 TCGv_i32 fp0 = tcg_temp_new_i32();
9008 TCGv_i32 fp1 = tcg_temp_new_i32();
9009 TCGv_i32 fp2 = tcg_temp_new_i32();
9011 gen_load_fpr32(fp0, fs);
9012 gen_load_fpr32(fp1, ft);
9013 gen_load_fpr32(fp2, fr);
9014 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
9015 tcg_temp_free_i32(fp0);
9016 tcg_temp_free_i32(fp1);
9017 gen_store_fpr32(fp2, fd);
9018 tcg_temp_free_i32(fp2);
9024 check_cp1_registers(ctx, fd | fs | ft | fr);
9026 TCGv_i64 fp0 = tcg_temp_new_i64();
9027 TCGv_i64 fp1 = tcg_temp_new_i64();
9028 TCGv_i64 fp2 = tcg_temp_new_i64();
9030 gen_load_fpr64(ctx, fp0, fs);
9031 gen_load_fpr64(ctx, fp1, ft);
9032 gen_load_fpr64(ctx, fp2, fr);
9033 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9034 tcg_temp_free_i64(fp0);
9035 tcg_temp_free_i64(fp1);
9036 gen_store_fpr64(ctx, fp2, fd);
9037 tcg_temp_free_i64(fp2);
9042 check_cp1_64bitmode(ctx);
9044 TCGv_i64 fp0 = tcg_temp_new_i64();
9045 TCGv_i64 fp1 = tcg_temp_new_i64();
9046 TCGv_i64 fp2 = tcg_temp_new_i64();
9048 gen_load_fpr64(ctx, fp0, fs);
9049 gen_load_fpr64(ctx, fp1, ft);
9050 gen_load_fpr64(ctx, fp2, fr);
9051 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9052 tcg_temp_free_i64(fp0);
9053 tcg_temp_free_i64(fp1);
9054 gen_store_fpr64(ctx, fp2, fd);
9055 tcg_temp_free_i64(fp2);
9061 generate_exception (ctx, EXCP_RI);
9064 (void)opn; /* avoid a compiler warning */
9065 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9066 fregnames[fs], fregnames[ft]);
9070 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9074 #if !defined(CONFIG_USER_ONLY)
9075 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9076 Therefore only check the ISA in system mode. */
9077 check_insn(env, ctx, ISA_MIPS32R2);
9079 t0 = tcg_temp_new();
9083 save_cpu_state(ctx, 1);
9084 gen_helper_rdhwr_cpunum(t0, cpu_env);
9085 gen_store_gpr(t0, rt);
9088 save_cpu_state(ctx, 1);
9089 gen_helper_rdhwr_synci_step(t0, cpu_env);
9090 gen_store_gpr(t0, rt);
9093 save_cpu_state(ctx, 1);
9094 gen_helper_rdhwr_cc(t0, cpu_env);
9095 gen_store_gpr(t0, rt);
9098 save_cpu_state(ctx, 1);
9099 gen_helper_rdhwr_ccres(t0, cpu_env);
9100 gen_store_gpr(t0, rt);
9103 #if defined(CONFIG_USER_ONLY)
9104 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9105 gen_store_gpr(t0, rt);
9108 /* XXX: Some CPUs implement this in hardware.
9109 Not supported yet. */
9111 default: /* Invalid */
9112 MIPS_INVAL("rdhwr");
9113 generate_exception(ctx, EXCP_RI);
9119 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9122 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9123 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9124 /* Branches completion */
9125 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9126 ctx->bstate = BS_BRANCH;
9127 save_cpu_state(ctx, 0);
9128 /* FIXME: Need to clear can_do_io. */
9129 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9131 /* unconditional branch */
9132 MIPS_DEBUG("unconditional branch");
9133 if (proc_hflags & MIPS_HFLAG_BX) {
9134 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9136 gen_goto_tb(ctx, 0, ctx->btarget);
9139 /* blikely taken case */
9140 MIPS_DEBUG("blikely branch taken");
9141 gen_goto_tb(ctx, 0, ctx->btarget);
9144 /* Conditional branch */
9145 MIPS_DEBUG("conditional branch");
9147 int l1 = gen_new_label();
9149 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9150 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9152 gen_goto_tb(ctx, 0, ctx->btarget);
9156 /* unconditional branch to register */
9157 MIPS_DEBUG("branch to register");
9158 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9159 TCGv t0 = tcg_temp_new();
9160 TCGv_i32 t1 = tcg_temp_new_i32();
9162 tcg_gen_andi_tl(t0, btarget, 0x1);
9163 tcg_gen_trunc_tl_i32(t1, t0);
9165 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9166 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9167 tcg_gen_or_i32(hflags, hflags, t1);
9168 tcg_temp_free_i32(t1);
9170 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9172 tcg_gen_mov_tl(cpu_PC, btarget);
9174 if (ctx->singlestep_enabled) {
9175 save_cpu_state(ctx, 0);
9176 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9181 MIPS_DEBUG("unknown branch");
9187 /* ISA extensions (ASEs) */
9188 /* MIPS16 extension to MIPS32 */
9190 /* MIPS16 major opcodes */
9192 M16_OPC_ADDIUSP = 0x00,
9193 M16_OPC_ADDIUPC = 0x01,
9196 M16_OPC_BEQZ = 0x04,
9197 M16_OPC_BNEQZ = 0x05,
9198 M16_OPC_SHIFT = 0x06,
9200 M16_OPC_RRIA = 0x08,
9201 M16_OPC_ADDIU8 = 0x09,
9202 M16_OPC_SLTI = 0x0a,
9203 M16_OPC_SLTIU = 0x0b,
9206 M16_OPC_CMPI = 0x0e,
9210 M16_OPC_LWSP = 0x12,
9214 M16_OPC_LWPC = 0x16,
9218 M16_OPC_SWSP = 0x1a,
9222 M16_OPC_EXTEND = 0x1e,
9226 /* I8 funct field */
9245 /* RR funct field */
9279 /* I64 funct field */
9291 /* RR ry field for CNVT */
9293 RR_RY_CNVT_ZEB = 0x0,
9294 RR_RY_CNVT_ZEH = 0x1,
9295 RR_RY_CNVT_ZEW = 0x2,
9296 RR_RY_CNVT_SEB = 0x4,
9297 RR_RY_CNVT_SEH = 0x5,
9298 RR_RY_CNVT_SEW = 0x6,
9301 static int xlat (int r)
9303 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9308 static void gen_mips16_save (DisasContext *ctx,
9309 int xsregs, int aregs,
9310 int do_ra, int do_s0, int do_s1,
9313 TCGv t0 = tcg_temp_new();
9314 TCGv t1 = tcg_temp_new();
9344 generate_exception(ctx, EXCP_RI);
9350 gen_base_offset_addr(ctx, t0, 29, 12);
9351 gen_load_gpr(t1, 7);
9352 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9355 gen_base_offset_addr(ctx, t0, 29, 8);
9356 gen_load_gpr(t1, 6);
9357 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9360 gen_base_offset_addr(ctx, t0, 29, 4);
9361 gen_load_gpr(t1, 5);
9362 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9365 gen_base_offset_addr(ctx, t0, 29, 0);
9366 gen_load_gpr(t1, 4);
9367 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9370 gen_load_gpr(t0, 29);
9372 #define DECR_AND_STORE(reg) do { \
9373 tcg_gen_subi_tl(t0, t0, 4); \
9374 gen_load_gpr(t1, reg); \
9375 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9439 generate_exception(ctx, EXCP_RI);
9455 #undef DECR_AND_STORE
9457 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9462 static void gen_mips16_restore (DisasContext *ctx,
9463 int xsregs, int aregs,
9464 int do_ra, int do_s0, int do_s1,
9468 TCGv t0 = tcg_temp_new();
9469 TCGv t1 = tcg_temp_new();
9471 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9473 #define DECR_AND_LOAD(reg) do { \
9474 tcg_gen_subi_tl(t0, t0, 4); \
9475 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9476 gen_store_gpr(t1, reg); \
9540 generate_exception(ctx, EXCP_RI);
9556 #undef DECR_AND_LOAD
9558 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9563 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9564 int is_64_bit, int extended)
9568 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9569 generate_exception(ctx, EXCP_RI);
9573 t0 = tcg_temp_new();
9575 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9576 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9578 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9584 #if defined(TARGET_MIPS64)
9585 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9586 int ry, int funct, int16_t offset,
9592 offset = extended ? offset : offset << 3;
9593 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9597 offset = extended ? offset : offset << 3;
9598 gen_st(ctx, OPC_SD, ry, 29, offset);
9602 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9603 gen_st(ctx, OPC_SD, 31, 29, offset);
9607 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9608 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9611 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9612 generate_exception(ctx, EXCP_RI);
9614 offset = extended ? offset : offset << 3;
9615 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9620 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9621 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9625 offset = extended ? offset : offset << 2;
9626 gen_addiupc(ctx, ry, offset, 1, extended);
9630 offset = extended ? offset : offset << 2;
9631 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9637 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9640 int extend = cpu_lduw_code(env, ctx->pc + 2);
9641 int op, rx, ry, funct, sa;
9642 int16_t imm, offset;
9644 ctx->opcode = (ctx->opcode << 16) | extend;
9645 op = (ctx->opcode >> 11) & 0x1f;
9646 sa = (ctx->opcode >> 22) & 0x1f;
9647 funct = (ctx->opcode >> 8) & 0x7;
9648 rx = xlat((ctx->opcode >> 8) & 0x7);
9649 ry = xlat((ctx->opcode >> 5) & 0x7);
9650 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9651 | ((ctx->opcode >> 21) & 0x3f) << 5
9652 | (ctx->opcode & 0x1f));
9654 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9657 case M16_OPC_ADDIUSP:
9658 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9660 case M16_OPC_ADDIUPC:
9661 gen_addiupc(ctx, rx, imm, 0, 1);
9664 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9665 /* No delay slot, so just process as a normal instruction */
9668 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9669 /* No delay slot, so just process as a normal instruction */
9672 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9673 /* No delay slot, so just process as a normal instruction */
9676 switch (ctx->opcode & 0x3) {
9678 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9681 #if defined(TARGET_MIPS64)
9683 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9685 generate_exception(ctx, EXCP_RI);
9689 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9692 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9696 #if defined(TARGET_MIPS64)
9699 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9703 imm = ctx->opcode & 0xf;
9704 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9705 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9706 imm = (int16_t) (imm << 1) >> 1;
9707 if ((ctx->opcode >> 4) & 0x1) {
9708 #if defined(TARGET_MIPS64)
9710 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9712 generate_exception(ctx, EXCP_RI);
9715 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9718 case M16_OPC_ADDIU8:
9719 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9722 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9725 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9730 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9733 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9736 gen_st(ctx, OPC_SW, 31, 29, imm);
9739 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9743 int xsregs = (ctx->opcode >> 24) & 0x7;
9744 int aregs = (ctx->opcode >> 16) & 0xf;
9745 int do_ra = (ctx->opcode >> 6) & 0x1;
9746 int do_s0 = (ctx->opcode >> 5) & 0x1;
9747 int do_s1 = (ctx->opcode >> 4) & 0x1;
9748 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9749 | (ctx->opcode & 0xf)) << 3;
9751 if (ctx->opcode & (1 << 7)) {
9752 gen_mips16_save(ctx, xsregs, aregs,
9753 do_ra, do_s0, do_s1,
9756 gen_mips16_restore(ctx, xsregs, aregs,
9757 do_ra, do_s0, do_s1,
9763 generate_exception(ctx, EXCP_RI);
9768 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9771 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9773 #if defined(TARGET_MIPS64)
9775 gen_st(ctx, OPC_SD, ry, rx, offset);
9779 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9782 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9785 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9788 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9791 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9794 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9797 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9799 #if defined(TARGET_MIPS64)
9801 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9805 gen_st(ctx, OPC_SB, ry, rx, offset);
9808 gen_st(ctx, OPC_SH, ry, rx, offset);
9811 gen_st(ctx, OPC_SW, rx, 29, offset);
9814 gen_st(ctx, OPC_SW, ry, rx, offset);
9816 #if defined(TARGET_MIPS64)
9818 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9822 generate_exception(ctx, EXCP_RI);
9829 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9834 int op, cnvt_op, op1, offset;
9838 op = (ctx->opcode >> 11) & 0x1f;
9839 sa = (ctx->opcode >> 2) & 0x7;
9840 sa = sa == 0 ? 8 : sa;
9841 rx = xlat((ctx->opcode >> 8) & 0x7);
9842 cnvt_op = (ctx->opcode >> 5) & 0x7;
9843 ry = xlat((ctx->opcode >> 5) & 0x7);
9844 op1 = offset = ctx->opcode & 0x1f;
9849 case M16_OPC_ADDIUSP:
9851 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9853 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9856 case M16_OPC_ADDIUPC:
9857 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9860 offset = (ctx->opcode & 0x7ff) << 1;
9861 offset = (int16_t)(offset << 4) >> 4;
9862 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9863 /* No delay slot, so just process as a normal instruction */
9866 offset = cpu_lduw_code(env, ctx->pc + 2);
9867 offset = (((ctx->opcode & 0x1f) << 21)
9868 | ((ctx->opcode >> 5) & 0x1f) << 16
9870 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9871 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9876 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9877 /* No delay slot, so just process as a normal instruction */
9880 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9881 /* No delay slot, so just process as a normal instruction */
9884 switch (ctx->opcode & 0x3) {
9886 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9889 #if defined(TARGET_MIPS64)
9891 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9893 generate_exception(ctx, EXCP_RI);
9897 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9900 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9904 #if defined(TARGET_MIPS64)
9907 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9912 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9914 if ((ctx->opcode >> 4) & 1) {
9915 #if defined(TARGET_MIPS64)
9917 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9919 generate_exception(ctx, EXCP_RI);
9922 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9926 case M16_OPC_ADDIU8:
9928 int16_t imm = (int8_t) ctx->opcode;
9930 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9935 int16_t imm = (uint8_t) ctx->opcode;
9936 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9941 int16_t imm = (uint8_t) ctx->opcode;
9942 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9949 funct = (ctx->opcode >> 8) & 0x7;
9952 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9953 ((int8_t)ctx->opcode) << 1);
9956 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9957 ((int8_t)ctx->opcode) << 1);
9960 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9963 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9964 ((int8_t)ctx->opcode) << 3);
9968 int do_ra = ctx->opcode & (1 << 6);
9969 int do_s0 = ctx->opcode & (1 << 5);
9970 int do_s1 = ctx->opcode & (1 << 4);
9971 int framesize = ctx->opcode & 0xf;
9973 if (framesize == 0) {
9976 framesize = framesize << 3;
9979 if (ctx->opcode & (1 << 7)) {
9980 gen_mips16_save(ctx, 0, 0,
9981 do_ra, do_s0, do_s1, framesize);
9983 gen_mips16_restore(ctx, 0, 0,
9984 do_ra, do_s0, do_s1, framesize);
9990 int rz = xlat(ctx->opcode & 0x7);
9992 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9993 ((ctx->opcode >> 5) & 0x7);
9994 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9998 reg32 = ctx->opcode & 0x1f;
9999 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
10002 generate_exception(ctx, EXCP_RI);
10009 int16_t imm = (uint8_t) ctx->opcode;
10011 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10016 int16_t imm = (uint8_t) ctx->opcode;
10017 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
10020 #if defined(TARGET_MIPS64)
10022 check_mips_64(ctx);
10023 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10027 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10030 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10033 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10036 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10039 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10042 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10045 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10047 #if defined (TARGET_MIPS64)
10049 check_mips_64(ctx);
10050 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10054 gen_st(ctx, OPC_SB, ry, rx, offset);
10057 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10060 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10063 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10067 int rz = xlat((ctx->opcode >> 2) & 0x7);
10070 switch (ctx->opcode & 0x3) {
10072 mips32_op = OPC_ADDU;
10075 mips32_op = OPC_SUBU;
10077 #if defined(TARGET_MIPS64)
10079 mips32_op = OPC_DADDU;
10080 check_mips_64(ctx);
10083 mips32_op = OPC_DSUBU;
10084 check_mips_64(ctx);
10088 generate_exception(ctx, EXCP_RI);
10092 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10101 int nd = (ctx->opcode >> 7) & 0x1;
10102 int link = (ctx->opcode >> 6) & 0x1;
10103 int ra = (ctx->opcode >> 5) & 0x1;
10106 op = nd ? OPC_JALRC : OPC_JALRS;
10111 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10118 /* XXX: not clear which exception should be raised
10119 * when in debug mode...
10121 check_insn(env, ctx, ISA_MIPS32);
10122 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10123 generate_exception(ctx, EXCP_DBp);
10125 generate_exception(ctx, EXCP_DBp);
10129 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10132 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10135 generate_exception(ctx, EXCP_BREAK);
10138 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10141 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10144 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10146 #if defined (TARGET_MIPS64)
10148 check_mips_64(ctx);
10149 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10153 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10156 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10159 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10162 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10165 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10168 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10171 gen_HILO(ctx, OPC_MFHI, rx);
10175 case RR_RY_CNVT_ZEB:
10176 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10178 case RR_RY_CNVT_ZEH:
10179 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10181 case RR_RY_CNVT_SEB:
10182 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10184 case RR_RY_CNVT_SEH:
10185 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10187 #if defined (TARGET_MIPS64)
10188 case RR_RY_CNVT_ZEW:
10189 check_mips_64(ctx);
10190 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10192 case RR_RY_CNVT_SEW:
10193 check_mips_64(ctx);
10194 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10198 generate_exception(ctx, EXCP_RI);
10203 gen_HILO(ctx, OPC_MFLO, rx);
10205 #if defined (TARGET_MIPS64)
10207 check_mips_64(ctx);
10208 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10211 check_mips_64(ctx);
10212 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10215 check_mips_64(ctx);
10216 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10219 check_mips_64(ctx);
10220 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10224 gen_muldiv(ctx, OPC_MULT, rx, ry);
10227 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10230 gen_muldiv(ctx, OPC_DIV, rx, ry);
10233 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10235 #if defined (TARGET_MIPS64)
10237 check_mips_64(ctx);
10238 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10241 check_mips_64(ctx);
10242 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10245 check_mips_64(ctx);
10246 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10249 check_mips_64(ctx);
10250 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10254 generate_exception(ctx, EXCP_RI);
10258 case M16_OPC_EXTEND:
10259 decode_extended_mips16_opc(env, ctx, is_branch);
10262 #if defined(TARGET_MIPS64)
10264 funct = (ctx->opcode >> 8) & 0x7;
10265 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10269 generate_exception(ctx, EXCP_RI);
10276 /* microMIPS extension to MIPS32 */
10278 /* microMIPS32 major opcodes */
10317 /* 0x20 is reserved */
10327 /* 0x28 and 0x29 are reserved */
10337 /* 0x30 and 0x31 are reserved */
10347 /* 0x38 and 0x39 are reserved */
10358 /* POOL32A encoding of minor opcode field */
10361 /* These opcodes are distinguished only by bits 9..6; those bits are
10362 * what are recorded below. */
10388 /* The following can be distinguished by their lower 6 bits. */
10394 /* POOL32AXF encoding of minor opcode field extension */
10408 /* bits 13..12 for 0x01 */
10414 /* bits 13..12 for 0x2a */
10420 /* bits 13..12 for 0x32 */
10424 /* bits 15..12 for 0x2c */
10440 /* bits 15..12 for 0x34 */
10448 /* bits 15..12 for 0x3c */
10450 JR = 0x0, /* alias */
10455 /* bits 15..12 for 0x05 */
10459 /* bits 15..12 for 0x0d */
10469 /* bits 15..12 for 0x15 */
10475 /* bits 15..12 for 0x1d */
10479 /* bits 15..12 for 0x2d */
10484 /* bits 15..12 for 0x35 */
10491 /* POOL32B encoding of minor opcode field (bits 15..12) */
10507 /* POOL32C encoding of minor opcode field (bits 15..12) */
10515 /* 0xa is reserved */
10522 /* 0x6 is reserved */
10528 /* POOL32F encoding of minor opcode field (bits 5..0) */
10531 /* These are the bit 7..6 values */
10542 /* These are the bit 8..6 values */
10586 CABS_COND_FMT = 0x1c, /* MIPS3D */
10590 /* POOL32Fxf encoding of minor opcode extension field */
10628 /* POOL32I encoding of minor opcode field (bits 25..21) */
10653 /* These overlap and are distinguished by bit16 of the instruction */
10662 /* POOL16A encoding of minor opcode field */
10669 /* POOL16B encoding of minor opcode field */
10676 /* POOL16C encoding of minor opcode field */
10696 /* POOL16D encoding of minor opcode field */
10703 /* POOL16E encoding of minor opcode field */
10710 static int mmreg (int r)
10712 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10717 /* Used for 16-bit store instructions. */
10718 static int mmreg2 (int r)
10720 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10725 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10726 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10727 #define uMIPS_RS2(op) uMIPS_RS(op)
10728 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10729 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10730 #define uMIPS_RS5(op) (op & 0x1f)
10732 /* Signed immediate */
10733 #define SIMM(op, start, width) \
10734 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10737 /* Zero-extended immediate */
10738 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10740 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10742 int rd = mmreg(uMIPS_RD(ctx->opcode));
10744 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10747 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10749 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10750 int rd = mmreg(uMIPS_RD(ctx->opcode));
10751 int rs = mmreg(uMIPS_RS(ctx->opcode));
10753 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10756 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10758 int encoded = ZIMM(ctx->opcode, 1, 9);
10761 if (encoded <= 1) {
10762 decoded = 256 + encoded;
10763 } else if (encoded <= 255) {
10765 } else if (encoded <= 509) {
10766 decoded = encoded - 512;
10768 decoded = encoded - 768;
10771 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10774 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10776 int imm = SIMM(ctx->opcode, 1, 4);
10777 int rd = (ctx->opcode >> 5) & 0x1f;
10779 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10782 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10784 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10785 31, 32, 63, 64, 255, 32768, 65535 };
10786 int rd = mmreg(uMIPS_RD(ctx->opcode));
10787 int rs = mmreg(uMIPS_RS(ctx->opcode));
10788 int encoded = ZIMM(ctx->opcode, 0, 4);
10790 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10793 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10794 int base, int16_t offset)
10796 const char *opn = "ldst_multiple";
10800 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10801 generate_exception(ctx, EXCP_RI);
10805 t0 = tcg_temp_new();
10807 gen_base_offset_addr(ctx, t0, base, offset);
10809 t1 = tcg_const_tl(reglist);
10810 t2 = tcg_const_i32(ctx->mem_idx);
10812 save_cpu_state(ctx, 1);
10815 gen_helper_lwm(cpu_env, t0, t1, t2);
10819 gen_helper_swm(cpu_env, t0, t1, t2);
10822 #ifdef TARGET_MIPS64
10824 gen_helper_ldm(cpu_env, t0, t1, t2);
10828 gen_helper_sdm(cpu_env, t0, t1, t2);
10834 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10837 tcg_temp_free_i32(t2);
10841 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10843 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10844 int rs = mmreg(ctx->opcode & 0x7);
10847 switch (((ctx->opcode) >> 4) & 0x3f) {
10852 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10858 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10864 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10870 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10877 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10878 int offset = ZIMM(ctx->opcode, 0, 4);
10880 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10889 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10890 int offset = ZIMM(ctx->opcode, 0, 4);
10892 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10899 int reg = ctx->opcode & 0x1f;
10901 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10908 int reg = ctx->opcode & 0x1f;
10910 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10911 /* Let normal delay slot handling in our caller take us
10912 to the branch target. */
10924 int reg = ctx->opcode & 0x1f;
10926 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10932 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10936 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10939 generate_exception(ctx, EXCP_BREAK);
10942 /* XXX: not clear which exception should be raised
10943 * when in debug mode...
10945 check_insn(env, ctx, ISA_MIPS32);
10946 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10947 generate_exception(ctx, EXCP_DBp);
10949 generate_exception(ctx, EXCP_DBp);
10952 case JRADDIUSP + 0:
10953 case JRADDIUSP + 1:
10955 int imm = ZIMM(ctx->opcode, 0, 5);
10957 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10958 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10959 /* Let normal delay slot handling in our caller take us
10960 to the branch target. */
10964 generate_exception(ctx, EXCP_RI);
10969 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10971 TCGv t0 = tcg_temp_new();
10972 TCGv t1 = tcg_temp_new();
10974 gen_load_gpr(t0, base);
10977 gen_load_gpr(t1, index);
10978 tcg_gen_shli_tl(t1, t1, 2);
10979 gen_op_addr_add(ctx, t0, t1, t0);
10982 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10983 gen_store_gpr(t1, rd);
10989 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10990 int base, int16_t offset)
10992 const char *opn = "ldst_pair";
10995 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10996 generate_exception(ctx, EXCP_RI);
11000 t0 = tcg_temp_new();
11001 t1 = tcg_temp_new();
11003 gen_base_offset_addr(ctx, t0, base, offset);
11008 generate_exception(ctx, EXCP_RI);
11011 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11012 gen_store_gpr(t1, rd);
11013 tcg_gen_movi_tl(t1, 4);
11014 gen_op_addr_add(ctx, t0, t0, t1);
11015 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11016 gen_store_gpr(t1, rd+1);
11020 gen_load_gpr(t1, rd);
11021 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11022 tcg_gen_movi_tl(t1, 4);
11023 gen_op_addr_add(ctx, t0, t0, t1);
11024 gen_load_gpr(t1, rd+1);
11025 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11028 #ifdef TARGET_MIPS64
11031 generate_exception(ctx, EXCP_RI);
11034 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11035 gen_store_gpr(t1, rd);
11036 tcg_gen_movi_tl(t1, 8);
11037 gen_op_addr_add(ctx, t0, t0, t1);
11038 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11039 gen_store_gpr(t1, rd+1);
11043 gen_load_gpr(t1, rd);
11044 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11045 tcg_gen_movi_tl(t1, 8);
11046 gen_op_addr_add(ctx, t0, t0, t1);
11047 gen_load_gpr(t1, rd+1);
11048 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11053 (void)opn; /* avoid a compiler warning */
11054 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11059 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11062 int extension = (ctx->opcode >> 6) & 0x3f;
11063 int minor = (ctx->opcode >> 12) & 0xf;
11064 uint32_t mips32_op;
11066 switch (extension) {
11068 mips32_op = OPC_TEQ;
11071 mips32_op = OPC_TGE;
11074 mips32_op = OPC_TGEU;
11077 mips32_op = OPC_TLT;
11080 mips32_op = OPC_TLTU;
11083 mips32_op = OPC_TNE;
11085 gen_trap(ctx, mips32_op, rs, rt, -1);
11087 #ifndef CONFIG_USER_ONLY
11090 check_cp0_enabled(ctx);
11092 /* Treat as NOP. */
11095 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11099 check_cp0_enabled(ctx);
11101 TCGv t0 = tcg_temp_new();
11103 gen_load_gpr(t0, rt);
11104 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11112 gen_bshfl(ctx, OPC_SEB, rs, rt);
11115 gen_bshfl(ctx, OPC_SEH, rs, rt);
11118 mips32_op = OPC_CLO;
11121 mips32_op = OPC_CLZ;
11123 check_insn(env, ctx, ISA_MIPS32);
11124 gen_cl(ctx, mips32_op, rt, rs);
11127 gen_rdhwr(env, ctx, rt, rs);
11130 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11133 mips32_op = OPC_MULT;
11136 mips32_op = OPC_MULTU;
11139 mips32_op = OPC_DIV;
11142 mips32_op = OPC_DIVU;
11145 mips32_op = OPC_MADD;
11148 mips32_op = OPC_MADDU;
11151 mips32_op = OPC_MSUB;
11154 mips32_op = OPC_MSUBU;
11156 check_insn(env, ctx, ISA_MIPS32);
11157 gen_muldiv(ctx, mips32_op, rs, rt);
11160 goto pool32axf_invalid;
11171 generate_exception_err(ctx, EXCP_CpU, 2);
11174 goto pool32axf_invalid;
11181 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11186 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11190 goto pool32axf_invalid;
11196 check_cp0_enabled(ctx);
11197 check_insn(env, ctx, ISA_MIPS32R2);
11198 gen_load_srsgpr(rt, rs);
11201 check_cp0_enabled(ctx);
11202 check_insn(env, ctx, ISA_MIPS32R2);
11203 gen_store_srsgpr(rt, rs);
11206 goto pool32axf_invalid;
11209 #ifndef CONFIG_USER_ONLY
11213 mips32_op = OPC_TLBP;
11216 mips32_op = OPC_TLBR;
11219 mips32_op = OPC_TLBWI;
11222 mips32_op = OPC_TLBWR;
11225 mips32_op = OPC_WAIT;
11228 mips32_op = OPC_DERET;
11231 mips32_op = OPC_ERET;
11233 gen_cp0(env, ctx, mips32_op, rt, rs);
11236 goto pool32axf_invalid;
11242 check_cp0_enabled(ctx);
11244 TCGv t0 = tcg_temp_new();
11246 save_cpu_state(ctx, 1);
11247 gen_helper_di(t0, cpu_env);
11248 gen_store_gpr(t0, rs);
11249 /* Stop translation as we may have switched the execution mode */
11250 ctx->bstate = BS_STOP;
11255 check_cp0_enabled(ctx);
11257 TCGv t0 = tcg_temp_new();
11259 save_cpu_state(ctx, 1);
11260 gen_helper_ei(t0, cpu_env);
11261 gen_store_gpr(t0, rs);
11262 /* Stop translation as we may have switched the execution mode */
11263 ctx->bstate = BS_STOP;
11268 goto pool32axf_invalid;
11278 generate_exception(ctx, EXCP_SYSCALL);
11279 ctx->bstate = BS_STOP;
11282 check_insn(env, ctx, ISA_MIPS32);
11283 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11284 generate_exception(ctx, EXCP_DBp);
11286 generate_exception(ctx, EXCP_DBp);
11290 goto pool32axf_invalid;
11296 gen_HILO(ctx, OPC_MFHI, rs);
11299 gen_HILO(ctx, OPC_MFLO, rs);
11302 gen_HILO(ctx, OPC_MTHI, rs);
11305 gen_HILO(ctx, OPC_MTLO, rs);
11308 goto pool32axf_invalid;
11313 MIPS_INVAL("pool32axf");
11314 generate_exception(ctx, EXCP_RI);
11319 /* Values for microMIPS fmt field. Variable-width, depending on which
11320 formats the instruction supports. */
11339 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11341 int extension = (ctx->opcode >> 6) & 0x3ff;
11342 uint32_t mips32_op;
11344 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11345 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11346 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11348 switch (extension) {
11349 case FLOAT_1BIT_FMT(CFC1, 0):
11350 mips32_op = OPC_CFC1;
11352 case FLOAT_1BIT_FMT(CTC1, 0):
11353 mips32_op = OPC_CTC1;
11355 case FLOAT_1BIT_FMT(MFC1, 0):
11356 mips32_op = OPC_MFC1;
11358 case FLOAT_1BIT_FMT(MTC1, 0):
11359 mips32_op = OPC_MTC1;
11361 case FLOAT_1BIT_FMT(MFHC1, 0):
11362 mips32_op = OPC_MFHC1;
11364 case FLOAT_1BIT_FMT(MTHC1, 0):
11365 mips32_op = OPC_MTHC1;
11367 gen_cp1(ctx, mips32_op, rt, rs);
11370 /* Reciprocal square root */
11371 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11372 mips32_op = OPC_RSQRT_S;
11374 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11375 mips32_op = OPC_RSQRT_D;
11379 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11380 mips32_op = OPC_SQRT_S;
11382 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11383 mips32_op = OPC_SQRT_D;
11387 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11388 mips32_op = OPC_RECIP_S;
11390 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11391 mips32_op = OPC_RECIP_D;
11395 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11396 mips32_op = OPC_FLOOR_L_S;
11398 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11399 mips32_op = OPC_FLOOR_L_D;
11401 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11402 mips32_op = OPC_FLOOR_W_S;
11404 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11405 mips32_op = OPC_FLOOR_W_D;
11409 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11410 mips32_op = OPC_CEIL_L_S;
11412 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11413 mips32_op = OPC_CEIL_L_D;
11415 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11416 mips32_op = OPC_CEIL_W_S;
11418 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11419 mips32_op = OPC_CEIL_W_D;
11423 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11424 mips32_op = OPC_TRUNC_L_S;
11426 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11427 mips32_op = OPC_TRUNC_L_D;
11429 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11430 mips32_op = OPC_TRUNC_W_S;
11432 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11433 mips32_op = OPC_TRUNC_W_D;
11437 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11438 mips32_op = OPC_ROUND_L_S;
11440 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11441 mips32_op = OPC_ROUND_L_D;
11443 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11444 mips32_op = OPC_ROUND_W_S;
11446 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11447 mips32_op = OPC_ROUND_W_D;
11450 /* Integer to floating-point conversion */
11451 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11452 mips32_op = OPC_CVT_L_S;
11454 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11455 mips32_op = OPC_CVT_L_D;
11457 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11458 mips32_op = OPC_CVT_W_S;
11460 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11461 mips32_op = OPC_CVT_W_D;
11464 /* Paired-foo conversions */
11465 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11466 mips32_op = OPC_CVT_S_PL;
11468 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11469 mips32_op = OPC_CVT_S_PU;
11471 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11472 mips32_op = OPC_CVT_PW_PS;
11474 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11475 mips32_op = OPC_CVT_PS_PW;
11478 /* Floating-point moves */
11479 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11480 mips32_op = OPC_MOV_S;
11482 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11483 mips32_op = OPC_MOV_D;
11485 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11486 mips32_op = OPC_MOV_PS;
11489 /* Absolute value */
11490 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11491 mips32_op = OPC_ABS_S;
11493 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11494 mips32_op = OPC_ABS_D;
11496 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11497 mips32_op = OPC_ABS_PS;
11501 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11502 mips32_op = OPC_NEG_S;
11504 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11505 mips32_op = OPC_NEG_D;
11507 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11508 mips32_op = OPC_NEG_PS;
11511 /* Reciprocal square root step */
11512 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11513 mips32_op = OPC_RSQRT1_S;
11515 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11516 mips32_op = OPC_RSQRT1_D;
11518 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11519 mips32_op = OPC_RSQRT1_PS;
11522 /* Reciprocal step */
11523 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11524 mips32_op = OPC_RECIP1_S;
11526 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11527 mips32_op = OPC_RECIP1_S;
11529 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11530 mips32_op = OPC_RECIP1_PS;
11533 /* Conversions from double */
11534 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11535 mips32_op = OPC_CVT_D_S;
11537 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11538 mips32_op = OPC_CVT_D_W;
11540 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11541 mips32_op = OPC_CVT_D_L;
11544 /* Conversions from single */
11545 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11546 mips32_op = OPC_CVT_S_D;
11548 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11549 mips32_op = OPC_CVT_S_W;
11551 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11552 mips32_op = OPC_CVT_S_L;
11554 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11557 /* Conditional moves on floating-point codes */
11558 case COND_FLOAT_MOV(MOVT, 0):
11559 case COND_FLOAT_MOV(MOVT, 1):
11560 case COND_FLOAT_MOV(MOVT, 2):
11561 case COND_FLOAT_MOV(MOVT, 3):
11562 case COND_FLOAT_MOV(MOVT, 4):
11563 case COND_FLOAT_MOV(MOVT, 5):
11564 case COND_FLOAT_MOV(MOVT, 6):
11565 case COND_FLOAT_MOV(MOVT, 7):
11566 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11568 case COND_FLOAT_MOV(MOVF, 0):
11569 case COND_FLOAT_MOV(MOVF, 1):
11570 case COND_FLOAT_MOV(MOVF, 2):
11571 case COND_FLOAT_MOV(MOVF, 3):
11572 case COND_FLOAT_MOV(MOVF, 4):
11573 case COND_FLOAT_MOV(MOVF, 5):
11574 case COND_FLOAT_MOV(MOVF, 6):
11575 case COND_FLOAT_MOV(MOVF, 7):
11576 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11579 MIPS_INVAL("pool32fxf");
11580 generate_exception(ctx, EXCP_RI);
11585 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11586 uint16_t insn_hw1, int *is_branch)
11590 int rt, rs, rd, rr;
11592 uint32_t op, minor, mips32_op;
11593 uint32_t cond, fmt, cc;
11595 insn = cpu_lduw_code(env, ctx->pc + 2);
11596 ctx->opcode = (ctx->opcode << 16) | insn;
11598 rt = (ctx->opcode >> 21) & 0x1f;
11599 rs = (ctx->opcode >> 16) & 0x1f;
11600 rd = (ctx->opcode >> 11) & 0x1f;
11601 rr = (ctx->opcode >> 6) & 0x1f;
11602 imm = (int16_t) ctx->opcode;
11604 op = (ctx->opcode >> 26) & 0x3f;
11607 minor = ctx->opcode & 0x3f;
11610 minor = (ctx->opcode >> 6) & 0xf;
11613 mips32_op = OPC_SLL;
11616 mips32_op = OPC_SRA;
11619 mips32_op = OPC_SRL;
11622 mips32_op = OPC_ROTR;
11624 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11627 goto pool32a_invalid;
11631 minor = (ctx->opcode >> 6) & 0xf;
11635 mips32_op = OPC_ADD;
11638 mips32_op = OPC_ADDU;
11641 mips32_op = OPC_SUB;
11644 mips32_op = OPC_SUBU;
11647 mips32_op = OPC_MUL;
11649 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11653 mips32_op = OPC_SLLV;
11656 mips32_op = OPC_SRLV;
11659 mips32_op = OPC_SRAV;
11662 mips32_op = OPC_ROTRV;
11664 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11666 /* Logical operations */
11668 mips32_op = OPC_AND;
11671 mips32_op = OPC_OR;
11674 mips32_op = OPC_NOR;
11677 mips32_op = OPC_XOR;
11679 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11681 /* Set less than */
11683 mips32_op = OPC_SLT;
11686 mips32_op = OPC_SLTU;
11688 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11691 goto pool32a_invalid;
11695 minor = (ctx->opcode >> 6) & 0xf;
11697 /* Conditional moves */
11699 mips32_op = OPC_MOVN;
11702 mips32_op = OPC_MOVZ;
11704 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11707 gen_ldxs(ctx, rs, rt, rd);
11710 goto pool32a_invalid;
11714 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11717 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11720 gen_pool32axf(env, ctx, rt, rs, is_branch);
11723 generate_exception(ctx, EXCP_BREAK);
11727 MIPS_INVAL("pool32a");
11728 generate_exception(ctx, EXCP_RI);
11733 minor = (ctx->opcode >> 12) & 0xf;
11736 check_cp0_enabled(ctx);
11737 /* Treat as no-op. */
11741 /* COP2: Not implemented. */
11742 generate_exception_err(ctx, EXCP_CpU, 2);
11746 #ifdef TARGET_MIPS64
11750 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11754 #ifdef TARGET_MIPS64
11758 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11761 MIPS_INVAL("pool32b");
11762 generate_exception(ctx, EXCP_RI);
11767 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11768 minor = ctx->opcode & 0x3f;
11769 check_cp1_enabled(ctx);
11772 mips32_op = OPC_ALNV_PS;
11775 mips32_op = OPC_MADD_S;
11778 mips32_op = OPC_MADD_D;
11781 mips32_op = OPC_MADD_PS;
11784 mips32_op = OPC_MSUB_S;
11787 mips32_op = OPC_MSUB_D;
11790 mips32_op = OPC_MSUB_PS;
11793 mips32_op = OPC_NMADD_S;
11796 mips32_op = OPC_NMADD_D;
11799 mips32_op = OPC_NMADD_PS;
11802 mips32_op = OPC_NMSUB_S;
11805 mips32_op = OPC_NMSUB_D;
11808 mips32_op = OPC_NMSUB_PS;
11810 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11812 case CABS_COND_FMT:
11813 cond = (ctx->opcode >> 6) & 0xf;
11814 cc = (ctx->opcode >> 13) & 0x7;
11815 fmt = (ctx->opcode >> 10) & 0x3;
11818 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11821 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11824 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11827 goto pool32f_invalid;
11831 cond = (ctx->opcode >> 6) & 0xf;
11832 cc = (ctx->opcode >> 13) & 0x7;
11833 fmt = (ctx->opcode >> 10) & 0x3;
11836 gen_cmp_s(ctx, cond, rt, rs, cc);
11839 gen_cmp_d(ctx, cond, rt, rs, cc);
11842 gen_cmp_ps(ctx, cond, rt, rs, cc);
11845 goto pool32f_invalid;
11849 gen_pool32fxf(env, ctx, rt, rs);
11853 switch ((ctx->opcode >> 6) & 0x7) {
11855 mips32_op = OPC_PLL_PS;
11858 mips32_op = OPC_PLU_PS;
11861 mips32_op = OPC_PUL_PS;
11864 mips32_op = OPC_PUU_PS;
11867 mips32_op = OPC_CVT_PS_S;
11869 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11872 goto pool32f_invalid;
11877 switch ((ctx->opcode >> 6) & 0x7) {
11879 mips32_op = OPC_LWXC1;
11882 mips32_op = OPC_SWXC1;
11885 mips32_op = OPC_LDXC1;
11888 mips32_op = OPC_SDXC1;
11891 mips32_op = OPC_LUXC1;
11894 mips32_op = OPC_SUXC1;
11896 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11899 goto pool32f_invalid;
11904 fmt = (ctx->opcode >> 9) & 0x3;
11905 switch ((ctx->opcode >> 6) & 0x7) {
11909 mips32_op = OPC_RSQRT2_S;
11912 mips32_op = OPC_RSQRT2_D;
11915 mips32_op = OPC_RSQRT2_PS;
11918 goto pool32f_invalid;
11924 mips32_op = OPC_RECIP2_S;
11927 mips32_op = OPC_RECIP2_D;
11930 mips32_op = OPC_RECIP2_PS;
11933 goto pool32f_invalid;
11937 mips32_op = OPC_ADDR_PS;
11940 mips32_op = OPC_MULR_PS;
11942 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11945 goto pool32f_invalid;
11949 /* MOV[FT].fmt and PREFX */
11950 cc = (ctx->opcode >> 13) & 0x7;
11951 fmt = (ctx->opcode >> 9) & 0x3;
11952 switch ((ctx->opcode >> 6) & 0x7) {
11956 gen_movcf_s(rs, rt, cc, 0);
11959 gen_movcf_d(ctx, rs, rt, cc, 0);
11962 gen_movcf_ps(rs, rt, cc, 0);
11965 goto pool32f_invalid;
11971 gen_movcf_s(rs, rt, cc, 1);
11974 gen_movcf_d(ctx, rs, rt, cc, 1);
11977 gen_movcf_ps(rs, rt, cc, 1);
11980 goto pool32f_invalid;
11986 goto pool32f_invalid;
11989 #define FINSN_3ARG_SDPS(prfx) \
11990 switch ((ctx->opcode >> 8) & 0x3) { \
11992 mips32_op = OPC_##prfx##_S; \
11995 mips32_op = OPC_##prfx##_D; \
11997 case FMT_SDPS_PS: \
11998 mips32_op = OPC_##prfx##_PS; \
12001 goto pool32f_invalid; \
12004 /* regular FP ops */
12005 switch ((ctx->opcode >> 6) & 0x3) {
12007 FINSN_3ARG_SDPS(ADD);
12010 FINSN_3ARG_SDPS(SUB);
12013 FINSN_3ARG_SDPS(MUL);
12016 fmt = (ctx->opcode >> 8) & 0x3;
12018 mips32_op = OPC_DIV_D;
12019 } else if (fmt == 0) {
12020 mips32_op = OPC_DIV_S;
12022 goto pool32f_invalid;
12026 goto pool32f_invalid;
12031 switch ((ctx->opcode >> 6) & 0x3) {
12033 FINSN_3ARG_SDPS(MOVN);
12036 FINSN_3ARG_SDPS(MOVZ);
12039 goto pool32f_invalid;
12043 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12047 MIPS_INVAL("pool32f");
12048 generate_exception(ctx, EXCP_RI);
12052 generate_exception_err(ctx, EXCP_CpU, 1);
12056 minor = (ctx->opcode >> 21) & 0x1f;
12059 mips32_op = OPC_BLTZ;
12062 mips32_op = OPC_BLTZAL;
12065 mips32_op = OPC_BLTZALS;
12068 mips32_op = OPC_BGEZ;
12071 mips32_op = OPC_BGEZAL;
12074 mips32_op = OPC_BGEZALS;
12077 mips32_op = OPC_BLEZ;
12080 mips32_op = OPC_BGTZ;
12082 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12088 mips32_op = OPC_TLTI;
12091 mips32_op = OPC_TGEI;
12094 mips32_op = OPC_TLTIU;
12097 mips32_op = OPC_TGEIU;
12100 mips32_op = OPC_TNEI;
12103 mips32_op = OPC_TEQI;
12105 gen_trap(ctx, mips32_op, rs, -1, imm);
12110 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12111 4, rs, 0, imm << 1);
12112 /* Compact branches don't have a delay slot, so just let
12113 the normal delay slot handling take us to the branch
12117 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12123 /* COP2: Not implemented. */
12124 generate_exception_err(ctx, EXCP_CpU, 2);
12127 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12130 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12133 mips32_op = OPC_BC1FANY4;
12136 mips32_op = OPC_BC1TANY4;
12139 check_insn(env, ctx, ASE_MIPS3D);
12142 gen_compute_branch1(env, ctx, mips32_op,
12143 (ctx->opcode >> 18) & 0x7, imm << 1);
12148 /* MIPS DSP: not implemented */
12151 MIPS_INVAL("pool32i");
12152 generate_exception(ctx, EXCP_RI);
12157 minor = (ctx->opcode >> 12) & 0xf;
12160 mips32_op = OPC_LWL;
12163 mips32_op = OPC_SWL;
12166 mips32_op = OPC_LWR;
12169 mips32_op = OPC_SWR;
12171 #if defined(TARGET_MIPS64)
12173 mips32_op = OPC_LDL;
12176 mips32_op = OPC_SDL;
12179 mips32_op = OPC_LDR;
12182 mips32_op = OPC_SDR;
12185 mips32_op = OPC_LWU;
12188 mips32_op = OPC_LLD;
12192 mips32_op = OPC_LL;
12195 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12198 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12201 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12203 #if defined(TARGET_MIPS64)
12205 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12209 /* Treat as no-op */
12212 MIPS_INVAL("pool32c");
12213 generate_exception(ctx, EXCP_RI);
12218 mips32_op = OPC_ADDI;
12221 mips32_op = OPC_ADDIU;
12223 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12226 /* Logical operations */
12228 mips32_op = OPC_ORI;
12231 mips32_op = OPC_XORI;
12234 mips32_op = OPC_ANDI;
12236 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12239 /* Set less than immediate */
12241 mips32_op = OPC_SLTI;
12244 mips32_op = OPC_SLTIU;
12246 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12249 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12250 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12254 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12255 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12259 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12263 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12267 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12268 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12272 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12273 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12276 /* Floating point (COP1) */
12278 mips32_op = OPC_LWC1;
12281 mips32_op = OPC_LDC1;
12284 mips32_op = OPC_SWC1;
12287 mips32_op = OPC_SDC1;
12289 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12293 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12294 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12296 gen_addiupc(ctx, reg, offset, 0, 0);
12299 /* Loads and stores */
12301 mips32_op = OPC_LB;
12304 mips32_op = OPC_LBU;
12307 mips32_op = OPC_LH;
12310 mips32_op = OPC_LHU;
12313 mips32_op = OPC_LW;
12315 #ifdef TARGET_MIPS64
12317 mips32_op = OPC_LD;
12320 mips32_op = OPC_SD;
12324 mips32_op = OPC_SB;
12327 mips32_op = OPC_SH;
12330 mips32_op = OPC_SW;
12333 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12336 gen_st(ctx, mips32_op, rt, rs, imm);
12339 generate_exception(ctx, EXCP_RI);
12344 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12348 /* make sure instructions are on a halfword boundary */
12349 if (ctx->pc & 0x1) {
12350 env->CP0_BadVAddr = ctx->pc;
12351 generate_exception(ctx, EXCP_AdEL);
12352 ctx->bstate = BS_STOP;
12356 op = (ctx->opcode >> 10) & 0x3f;
12357 /* Enforce properly-sized instructions in a delay slot */
12358 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12359 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12393 case POOL48A: /* ??? */
12398 if (bits & MIPS_HFLAG_BDS16) {
12399 generate_exception(ctx, EXCP_RI);
12400 /* Just stop translation; the user is confused. */
12401 ctx->bstate = BS_STOP;
12426 if (bits & MIPS_HFLAG_BDS32) {
12427 generate_exception(ctx, EXCP_RI);
12428 /* Just stop translation; the user is confused. */
12429 ctx->bstate = BS_STOP;
12440 int rd = mmreg(uMIPS_RD(ctx->opcode));
12441 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12442 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12445 switch (ctx->opcode & 0x1) {
12454 gen_arith(env, ctx, opc, rd, rs1, rs2);
12459 int rd = mmreg(uMIPS_RD(ctx->opcode));
12460 int rs = mmreg(uMIPS_RS(ctx->opcode));
12461 int amount = (ctx->opcode >> 1) & 0x7;
12463 amount = amount == 0 ? 8 : amount;
12465 switch (ctx->opcode & 0x1) {
12474 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12478 gen_pool16c_insn(env, ctx, is_branch);
12482 int rd = mmreg(uMIPS_RD(ctx->opcode));
12483 int rb = 28; /* GP */
12484 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12486 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12490 if (ctx->opcode & 1) {
12491 generate_exception(ctx, EXCP_RI);
12494 int enc_dest = uMIPS_RD(ctx->opcode);
12495 int enc_rt = uMIPS_RS2(ctx->opcode);
12496 int enc_rs = uMIPS_RS1(ctx->opcode);
12497 int rd, rs, re, rt;
12498 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12499 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12500 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12502 rd = rd_enc[enc_dest];
12503 re = re_enc[enc_dest];
12504 rs = rs_rt_enc[enc_rs];
12505 rt = rs_rt_enc[enc_rt];
12507 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12508 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12513 int rd = mmreg(uMIPS_RD(ctx->opcode));
12514 int rb = mmreg(uMIPS_RS(ctx->opcode));
12515 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12516 offset = (offset == 0xf ? -1 : offset);
12518 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12523 int rd = mmreg(uMIPS_RD(ctx->opcode));
12524 int rb = mmreg(uMIPS_RS(ctx->opcode));
12525 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12527 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12532 int rd = (ctx->opcode >> 5) & 0x1f;
12533 int rb = 29; /* SP */
12534 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12536 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12541 int rd = mmreg(uMIPS_RD(ctx->opcode));
12542 int rb = mmreg(uMIPS_RS(ctx->opcode));
12543 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12545 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12550 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12551 int rb = mmreg(uMIPS_RS(ctx->opcode));
12552 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12554 gen_st(ctx, OPC_SB, rd, rb, offset);
12559 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12560 int rb = mmreg(uMIPS_RS(ctx->opcode));
12561 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12563 gen_st(ctx, OPC_SH, rd, rb, offset);
12568 int rd = (ctx->opcode >> 5) & 0x1f;
12569 int rb = 29; /* SP */
12570 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12572 gen_st(ctx, OPC_SW, rd, rb, offset);
12577 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12578 int rb = mmreg(uMIPS_RS(ctx->opcode));
12579 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12581 gen_st(ctx, OPC_SW, rd, rb, offset);
12586 int rd = uMIPS_RD5(ctx->opcode);
12587 int rs = uMIPS_RS5(ctx->opcode);
12589 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12593 gen_andi16(env, ctx);
12596 switch (ctx->opcode & 0x1) {
12598 gen_addius5(env, ctx);
12601 gen_addiusp(env, ctx);
12606 switch (ctx->opcode & 0x1) {
12608 gen_addiur2(env, ctx);
12611 gen_addiur1sp(env, ctx);
12616 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12617 SIMM(ctx->opcode, 0, 10) << 1);
12622 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12623 mmreg(uMIPS_RD(ctx->opcode)),
12624 0, SIMM(ctx->opcode, 0, 7) << 1);
12629 int reg = mmreg(uMIPS_RD(ctx->opcode));
12630 int imm = ZIMM(ctx->opcode, 0, 7);
12632 imm = (imm == 0x7f ? -1 : imm);
12633 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12643 generate_exception(ctx, EXCP_RI);
12646 decode_micromips32_opc (env, ctx, op, is_branch);
12653 /* SmartMIPS extension to MIPS32 */
12655 #if defined(TARGET_MIPS64)
12657 /* MDMX extension to MIPS64 */
12661 /* MIPSDSP functions. */
12662 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12663 int rd, int base, int offset)
12665 const char *opn = "ldx";
12674 t0 = tcg_temp_new();
12677 gen_load_gpr(t0, offset);
12678 } else if (offset == 0) {
12679 gen_load_gpr(t0, base);
12681 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12686 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12687 gen_store_gpr(t0, rd);
12691 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12692 gen_store_gpr(t0, rd);
12696 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12697 gen_store_gpr(t0, rd);
12700 #if defined(TARGET_MIPS64)
12702 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12703 gen_store_gpr(t0, rd);
12708 (void)opn; /* avoid a compiler warning */
12709 MIPS_DEBUG("%s %s, %s(%s)", opn,
12710 regnames[rd], regnames[offset], regnames[base]);
12714 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12715 int ret, int v1, int v2)
12717 const char *opn = "mipsdsp arith";
12722 /* Treat as NOP. */
12727 v1_t = tcg_temp_new();
12728 v2_t = tcg_temp_new();
12730 gen_load_gpr(v1_t, v1);
12731 gen_load_gpr(v2_t, v2);
12734 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12735 case OPC_MULT_G_2E:
12739 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12741 case OPC_ADDUH_R_QB:
12742 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12745 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12747 case OPC_ADDQH_R_PH:
12748 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12751 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12753 case OPC_ADDQH_R_W:
12754 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12757 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12759 case OPC_SUBUH_R_QB:
12760 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12763 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12765 case OPC_SUBQH_R_PH:
12766 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12769 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12771 case OPC_SUBQH_R_W:
12772 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12776 case OPC_ABSQ_S_PH_DSP:
12778 case OPC_ABSQ_S_QB:
12780 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12782 case OPC_ABSQ_S_PH:
12784 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12788 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12790 case OPC_PRECEQ_W_PHL:
12792 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12793 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12795 case OPC_PRECEQ_W_PHR:
12797 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12798 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12799 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12801 case OPC_PRECEQU_PH_QBL:
12803 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12805 case OPC_PRECEQU_PH_QBR:
12807 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12809 case OPC_PRECEQU_PH_QBLA:
12811 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12813 case OPC_PRECEQU_PH_QBRA:
12815 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12817 case OPC_PRECEU_PH_QBL:
12819 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12821 case OPC_PRECEU_PH_QBR:
12823 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12825 case OPC_PRECEU_PH_QBLA:
12827 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12829 case OPC_PRECEU_PH_QBRA:
12831 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12835 case OPC_ADDU_QB_DSP:
12839 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12841 case OPC_ADDQ_S_PH:
12843 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12847 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12851 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853 case OPC_ADDU_S_QB:
12855 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12859 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861 case OPC_ADDU_S_PH:
12863 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12867 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12869 case OPC_SUBQ_S_PH:
12871 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12875 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12879 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12881 case OPC_SUBU_S_QB:
12883 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12887 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 case OPC_SUBU_S_PH:
12891 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12895 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12899 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12903 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12905 case OPC_RADDU_W_QB:
12907 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12911 case OPC_CMPU_EQ_QB_DSP:
12913 case OPC_PRECR_QB_PH:
12915 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12917 case OPC_PRECRQ_QB_PH:
12919 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12921 case OPC_PRECR_SRA_PH_W:
12924 TCGv_i32 sa_t = tcg_const_i32(v2);
12925 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12927 tcg_temp_free_i32(sa_t);
12930 case OPC_PRECR_SRA_R_PH_W:
12933 TCGv_i32 sa_t = tcg_const_i32(v2);
12934 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12936 tcg_temp_free_i32(sa_t);
12939 case OPC_PRECRQ_PH_W:
12941 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12943 case OPC_PRECRQ_RS_PH_W:
12945 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12947 case OPC_PRECRQU_S_QB_PH:
12949 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12953 #ifdef TARGET_MIPS64
12954 case OPC_ABSQ_S_QH_DSP:
12956 case OPC_PRECEQ_L_PWL:
12958 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12960 case OPC_PRECEQ_L_PWR:
12962 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12964 case OPC_PRECEQ_PW_QHL:
12966 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12968 case OPC_PRECEQ_PW_QHR:
12970 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12972 case OPC_PRECEQ_PW_QHLA:
12974 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12976 case OPC_PRECEQ_PW_QHRA:
12978 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12980 case OPC_PRECEQU_QH_OBL:
12982 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12984 case OPC_PRECEQU_QH_OBR:
12986 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12988 case OPC_PRECEQU_QH_OBLA:
12990 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12992 case OPC_PRECEQU_QH_OBRA:
12994 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12996 case OPC_PRECEU_QH_OBL:
12998 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13000 case OPC_PRECEU_QH_OBR:
13002 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13004 case OPC_PRECEU_QH_OBLA:
13006 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13008 case OPC_PRECEU_QH_OBRA:
13010 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13012 case OPC_ABSQ_S_OB:
13014 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13016 case OPC_ABSQ_S_PW:
13018 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13020 case OPC_ABSQ_S_QH:
13022 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13026 case OPC_ADDU_OB_DSP:
13028 case OPC_RADDU_L_OB:
13030 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13034 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13036 case OPC_SUBQ_S_PW:
13038 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13042 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044 case OPC_SUBQ_S_QH:
13046 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13050 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052 case OPC_SUBU_S_OB:
13054 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13058 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13060 case OPC_SUBU_S_QH:
13062 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13066 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13068 case OPC_SUBUH_R_OB:
13070 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13074 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13076 case OPC_ADDQ_S_PW:
13078 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13082 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084 case OPC_ADDQ_S_QH:
13086 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13090 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092 case OPC_ADDU_S_OB:
13094 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13098 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13100 case OPC_ADDU_S_QH:
13102 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13106 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13108 case OPC_ADDUH_R_OB:
13110 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13114 case OPC_CMPU_EQ_OB_DSP:
13116 case OPC_PRECR_OB_QH:
13118 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13120 case OPC_PRECR_SRA_QH_PW:
13123 TCGv_i32 ret_t = tcg_const_i32(ret);
13124 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13125 tcg_temp_free_i32(ret_t);
13128 case OPC_PRECR_SRA_R_QH_PW:
13131 TCGv_i32 sa_v = tcg_const_i32(ret);
13132 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13133 tcg_temp_free_i32(sa_v);
13136 case OPC_PRECRQ_OB_QH:
13138 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13140 case OPC_PRECRQ_PW_L:
13142 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13144 case OPC_PRECRQ_QH_PW:
13146 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13148 case OPC_PRECRQ_RS_QH_PW:
13150 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13152 case OPC_PRECRQU_S_OB_QH:
13154 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13161 tcg_temp_free(v1_t);
13162 tcg_temp_free(v2_t);
13164 (void)opn; /* avoid a compiler warning */
13165 MIPS_DEBUG("%s", opn);
13168 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13169 int ret, int v1, int v2)
13172 const char *opn = "mipsdsp shift";
13178 /* Treat as NOP. */
13183 t0 = tcg_temp_new();
13184 v1_t = tcg_temp_new();
13185 v2_t = tcg_temp_new();
13187 tcg_gen_movi_tl(t0, v1);
13188 gen_load_gpr(v1_t, v1);
13189 gen_load_gpr(v2_t, v2);
13192 case OPC_SHLL_QB_DSP:
13194 op2 = MASK_SHLL_QB(ctx->opcode);
13198 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13202 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13206 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13210 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13212 case OPC_SHLL_S_PH:
13214 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13216 case OPC_SHLLV_S_PH:
13218 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13222 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13224 case OPC_SHLLV_S_W:
13226 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13230 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13234 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13238 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13242 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13246 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13248 case OPC_SHRA_R_QB:
13250 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13254 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13256 case OPC_SHRAV_R_QB:
13258 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13262 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13264 case OPC_SHRA_R_PH:
13266 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13270 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13272 case OPC_SHRAV_R_PH:
13274 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13278 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13280 case OPC_SHRAV_R_W:
13282 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13284 default: /* Invalid */
13285 MIPS_INVAL("MASK SHLL.QB");
13286 generate_exception(ctx, EXCP_RI);
13291 #ifdef TARGET_MIPS64
13292 case OPC_SHLL_OB_DSP:
13293 op2 = MASK_SHLL_OB(ctx->opcode);
13297 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13301 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13303 case OPC_SHLL_S_PW:
13305 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13307 case OPC_SHLLV_S_PW:
13309 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13313 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13317 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13321 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13325 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13327 case OPC_SHLL_S_QH:
13329 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13331 case OPC_SHLLV_S_QH:
13333 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13337 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13341 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13343 case OPC_SHRA_R_OB:
13345 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13347 case OPC_SHRAV_R_OB:
13349 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13353 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13357 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13359 case OPC_SHRA_R_PW:
13361 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13363 case OPC_SHRAV_R_PW:
13365 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13369 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13373 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13375 case OPC_SHRA_R_QH:
13377 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13379 case OPC_SHRAV_R_QH:
13381 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13385 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13389 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13393 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13397 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13399 default: /* Invalid */
13400 MIPS_INVAL("MASK SHLL.OB");
13401 generate_exception(ctx, EXCP_RI);
13409 tcg_temp_free(v1_t);
13410 tcg_temp_free(v2_t);
13411 (void)opn; /* avoid a compiler warning */
13412 MIPS_DEBUG("%s", opn);
13415 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13416 int ret, int v1, int v2, int check_ret)
13418 const char *opn = "mipsdsp multiply";
13423 if ((ret == 0) && (check_ret == 1)) {
13424 /* Treat as NOP. */
13429 t0 = tcg_temp_new_i32();
13430 v1_t = tcg_temp_new();
13431 v2_t = tcg_temp_new();
13433 tcg_gen_movi_i32(t0, ret);
13434 gen_load_gpr(v1_t, v1);
13435 gen_load_gpr(v2_t, v2);
13438 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13439 * the same mask and op1. */
13440 case OPC_MULT_G_2E:
13443 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13446 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13449 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13451 case OPC_MULQ_RS_W:
13452 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13456 case OPC_DPA_W_PH_DSP:
13458 case OPC_DPAU_H_QBL:
13460 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13462 case OPC_DPAU_H_QBR:
13464 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13466 case OPC_DPSU_H_QBL:
13468 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13470 case OPC_DPSU_H_QBR:
13472 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13476 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13478 case OPC_DPAX_W_PH:
13480 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13482 case OPC_DPAQ_S_W_PH:
13484 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13486 case OPC_DPAQX_S_W_PH:
13488 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13490 case OPC_DPAQX_SA_W_PH:
13492 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13496 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13498 case OPC_DPSX_W_PH:
13500 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13502 case OPC_DPSQ_S_W_PH:
13504 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13506 case OPC_DPSQX_S_W_PH:
13508 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13510 case OPC_DPSQX_SA_W_PH:
13512 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13514 case OPC_MULSAQ_S_W_PH:
13516 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13518 case OPC_DPAQ_SA_L_W:
13520 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13522 case OPC_DPSQ_SA_L_W:
13524 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13526 case OPC_MAQ_S_W_PHL:
13528 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13530 case OPC_MAQ_S_W_PHR:
13532 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13534 case OPC_MAQ_SA_W_PHL:
13536 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13538 case OPC_MAQ_SA_W_PHR:
13540 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13542 case OPC_MULSA_W_PH:
13544 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13548 #ifdef TARGET_MIPS64
13549 case OPC_DPAQ_W_QH_DSP:
13551 int ac = ret & 0x03;
13552 tcg_gen_movi_i32(t0, ac);
13557 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13561 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13565 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13569 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13573 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13575 case OPC_DPAQ_S_W_QH:
13577 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13579 case OPC_DPAQ_SA_L_PW:
13581 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13583 case OPC_DPAU_H_OBL:
13585 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13587 case OPC_DPAU_H_OBR:
13589 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13593 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13595 case OPC_DPSQ_S_W_QH:
13597 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13599 case OPC_DPSQ_SA_L_PW:
13601 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13603 case OPC_DPSU_H_OBL:
13605 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13607 case OPC_DPSU_H_OBR:
13609 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13611 case OPC_MAQ_S_L_PWL:
13613 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13615 case OPC_MAQ_S_L_PWR:
13617 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13619 case OPC_MAQ_S_W_QHLL:
13621 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13623 case OPC_MAQ_SA_W_QHLL:
13625 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13627 case OPC_MAQ_S_W_QHLR:
13629 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13631 case OPC_MAQ_SA_W_QHLR:
13633 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13635 case OPC_MAQ_S_W_QHRL:
13637 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13639 case OPC_MAQ_SA_W_QHRL:
13641 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13643 case OPC_MAQ_S_W_QHRR:
13645 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13647 case OPC_MAQ_SA_W_QHRR:
13649 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13651 case OPC_MULSAQ_S_L_PW:
13653 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13655 case OPC_MULSAQ_S_W_QH:
13657 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13663 case OPC_ADDU_QB_DSP:
13665 case OPC_MULEU_S_PH_QBL:
13667 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13669 case OPC_MULEU_S_PH_QBR:
13671 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13673 case OPC_MULQ_RS_PH:
13675 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13677 case OPC_MULEQ_S_W_PHL:
13679 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13681 case OPC_MULEQ_S_W_PHR:
13683 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13685 case OPC_MULQ_S_PH:
13687 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13691 #ifdef TARGET_MIPS64
13692 case OPC_ADDU_OB_DSP:
13694 case OPC_MULEQ_S_PW_QHL:
13696 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13698 case OPC_MULEQ_S_PW_QHR:
13700 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13702 case OPC_MULEU_S_QH_OBL:
13704 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13706 case OPC_MULEU_S_QH_OBR:
13708 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13710 case OPC_MULQ_RS_QH:
13712 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13719 tcg_temp_free_i32(t0);
13720 tcg_temp_free(v1_t);
13721 tcg_temp_free(v2_t);
13723 (void)opn; /* avoid a compiler warning */
13724 MIPS_DEBUG("%s", opn);
13728 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13729 uint32_t op1, uint32_t op2,
13732 const char *opn = "mipsdsp Bit/ Manipulation";
13738 /* Treat as NOP. */
13743 t0 = tcg_temp_new();
13744 val_t = tcg_temp_new();
13745 gen_load_gpr(val_t, val);
13748 case OPC_ABSQ_S_PH_DSP:
13752 gen_helper_bitrev(cpu_gpr[ret], val_t);
13757 target_long result;
13758 imm = (ctx->opcode >> 16) & 0xFF;
13759 result = (uint32_t)imm << 24 |
13760 (uint32_t)imm << 16 |
13761 (uint32_t)imm << 8 |
13763 result = (int32_t)result;
13764 tcg_gen_movi_tl(cpu_gpr[ret], result);
13769 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13770 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13771 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13772 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13773 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13774 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13779 imm = (ctx->opcode >> 16) & 0x03FF;
13780 tcg_gen_movi_tl(cpu_gpr[ret], \
13781 (target_long)((int32_t)imm << 16 | \
13782 (uint32_t)(uint16_t)imm));
13787 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13788 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13789 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13790 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13794 #ifdef TARGET_MIPS64
13795 case OPC_ABSQ_S_QH_DSP:
13802 imm = (ctx->opcode >> 16) & 0xFF;
13803 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13804 temp = (temp << 16) | temp;
13805 temp = (temp << 32) | temp;
13806 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13814 imm = (ctx->opcode >> 16) & 0x03FF;
13815 imm = (int16_t)(imm << 6) >> 6;
13816 temp = ((target_long)imm << 32) \
13817 | ((target_long)imm & 0xFFFFFFFF);
13818 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13826 imm = (ctx->opcode >> 16) & 0x03FF;
13827 imm = (int16_t)(imm << 6) >> 6;
13829 temp = ((uint64_t)(uint16_t)imm << 48) |
13830 ((uint64_t)(uint16_t)imm << 32) |
13831 ((uint64_t)(uint16_t)imm << 16) |
13832 (uint64_t)(uint16_t)imm;
13833 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13838 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13839 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13840 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13841 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13842 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13843 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13844 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13848 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13849 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13850 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13854 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13855 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13856 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13857 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13858 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13865 tcg_temp_free(val_t);
13867 (void)opn; /* avoid a compiler warning */
13868 MIPS_DEBUG("%s", opn);
13871 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13872 uint32_t op1, uint32_t op2,
13873 int ret, int v1, int v2, int check_ret)
13875 const char *opn = "mipsdsp add compare pick";
13881 if ((ret == 0) && (check_ret == 1)) {
13882 /* Treat as NOP. */
13887 t0 = tcg_temp_new_i32();
13888 t1 = tcg_temp_new();
13889 v1_t = tcg_temp_new();
13890 v2_t = tcg_temp_new();
13892 gen_load_gpr(v1_t, v1);
13893 gen_load_gpr(v2_t, v2);
13896 case OPC_APPEND_DSP:
13899 tcg_gen_movi_i32(t0, v2);
13900 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13903 tcg_gen_movi_i32(t0, v2);
13904 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13907 tcg_gen_movi_i32(t0, v2);
13908 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13910 default: /* Invid */
13911 MIPS_INVAL("MASK APPEND");
13912 generate_exception(ctx, EXCP_RI);
13916 case OPC_CMPU_EQ_QB_DSP:
13918 case OPC_CMPU_EQ_QB:
13920 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13922 case OPC_CMPU_LT_QB:
13924 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13926 case OPC_CMPU_LE_QB:
13928 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13930 case OPC_CMPGU_EQ_QB:
13932 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13934 case OPC_CMPGU_LT_QB:
13936 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13938 case OPC_CMPGU_LE_QB:
13940 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13942 case OPC_CMPGDU_EQ_QB:
13944 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13945 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13946 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13947 tcg_gen_shli_tl(t1, t1, 24);
13948 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13950 case OPC_CMPGDU_LT_QB:
13952 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13953 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13954 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13955 tcg_gen_shli_tl(t1, t1, 24);
13956 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13958 case OPC_CMPGDU_LE_QB:
13960 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13961 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13962 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13963 tcg_gen_shli_tl(t1, t1, 24);
13964 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13966 case OPC_CMP_EQ_PH:
13968 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13970 case OPC_CMP_LT_PH:
13972 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13974 case OPC_CMP_LE_PH:
13976 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13980 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13984 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13986 case OPC_PACKRL_PH:
13988 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13992 #ifdef TARGET_MIPS64
13993 case OPC_CMPU_EQ_OB_DSP:
13995 case OPC_CMP_EQ_PW:
13997 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13999 case OPC_CMP_LT_PW:
14001 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14003 case OPC_CMP_LE_PW:
14005 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14007 case OPC_CMP_EQ_QH:
14009 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14011 case OPC_CMP_LT_QH:
14013 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14015 case OPC_CMP_LE_QH:
14017 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14019 case OPC_CMPGDU_EQ_OB:
14021 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14023 case OPC_CMPGDU_LT_OB:
14025 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14027 case OPC_CMPGDU_LE_OB:
14029 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14031 case OPC_CMPGU_EQ_OB:
14033 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14035 case OPC_CMPGU_LT_OB:
14037 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14039 case OPC_CMPGU_LE_OB:
14041 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14043 case OPC_CMPU_EQ_OB:
14045 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14047 case OPC_CMPU_LT_OB:
14049 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14051 case OPC_CMPU_LE_OB:
14053 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14055 case OPC_PACKRL_PW:
14057 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14061 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14065 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14069 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14073 case OPC_DAPPEND_DSP:
14076 tcg_gen_movi_i32(t0, v2);
14077 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14080 tcg_gen_movi_i32(t0, v2);
14081 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14084 tcg_gen_movi_i32(t0, v2);
14085 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14088 tcg_gen_movi_i32(t0, v2);
14089 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14091 default: /* Invalid */
14092 MIPS_INVAL("MASK DAPPEND");
14093 generate_exception(ctx, EXCP_RI);
14100 tcg_temp_free_i32(t0);
14102 tcg_temp_free(v1_t);
14103 tcg_temp_free(v2_t);
14105 (void)opn; /* avoid a compiler warning */
14106 MIPS_DEBUG("%s", opn);
14109 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14110 int ret, int v1, int v2, int check_ret)
14113 const char *opn = "mipsdsp accumulator";
14120 if ((ret == 0) && (check_ret == 1)) {
14121 /* Treat as NOP. */
14126 t0 = tcg_temp_new();
14127 t1 = tcg_temp_new();
14128 v1_t = tcg_temp_new();
14129 v2_t = tcg_temp_new();
14131 gen_load_gpr(v1_t, v1);
14132 gen_load_gpr(v2_t, v2);
14135 case OPC_EXTR_W_DSP:
14139 tcg_gen_movi_tl(t0, v2);
14140 tcg_gen_movi_tl(t1, v1);
14141 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14144 tcg_gen_movi_tl(t0, v2);
14145 tcg_gen_movi_tl(t1, v1);
14146 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14148 case OPC_EXTR_RS_W:
14149 tcg_gen_movi_tl(t0, v2);
14150 tcg_gen_movi_tl(t1, v1);
14151 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14154 tcg_gen_movi_tl(t0, v2);
14155 tcg_gen_movi_tl(t1, v1);
14156 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14158 case OPC_EXTRV_S_H:
14159 tcg_gen_movi_tl(t0, v2);
14160 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14163 tcg_gen_movi_tl(t0, v2);
14164 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14166 case OPC_EXTRV_R_W:
14167 tcg_gen_movi_tl(t0, v2);
14168 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14170 case OPC_EXTRV_RS_W:
14171 tcg_gen_movi_tl(t0, v2);
14172 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14175 tcg_gen_movi_tl(t0, v2);
14176 tcg_gen_movi_tl(t1, v1);
14177 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14180 tcg_gen_movi_tl(t0, v2);
14181 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14184 tcg_gen_movi_tl(t0, v2);
14185 tcg_gen_movi_tl(t1, v1);
14186 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14189 tcg_gen_movi_tl(t0, v2);
14190 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14193 imm = (ctx->opcode >> 20) & 0x3F;
14194 tcg_gen_movi_tl(t0, ret);
14195 tcg_gen_movi_tl(t1, imm);
14196 gen_helper_shilo(t0, t1, cpu_env);
14199 tcg_gen_movi_tl(t0, ret);
14200 gen_helper_shilo(t0, v1_t, cpu_env);
14203 tcg_gen_movi_tl(t0, ret);
14204 gen_helper_mthlip(t0, v1_t, cpu_env);
14207 imm = (ctx->opcode >> 11) & 0x3FF;
14208 tcg_gen_movi_tl(t0, imm);
14209 gen_helper_wrdsp(v1_t, t0, cpu_env);
14212 imm = (ctx->opcode >> 16) & 0x03FF;
14213 tcg_gen_movi_tl(t0, imm);
14214 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14218 #ifdef TARGET_MIPS64
14219 case OPC_DEXTR_W_DSP:
14223 tcg_gen_movi_tl(t0, ret);
14224 gen_helper_dmthlip(v1_t, t0, cpu_env);
14228 int shift = (ctx->opcode >> 19) & 0x7F;
14229 int ac = (ctx->opcode >> 11) & 0x03;
14230 tcg_gen_movi_tl(t0, shift);
14231 tcg_gen_movi_tl(t1, ac);
14232 gen_helper_dshilo(t0, t1, cpu_env);
14237 int ac = (ctx->opcode >> 11) & 0x03;
14238 tcg_gen_movi_tl(t0, ac);
14239 gen_helper_dshilo(v1_t, t0, cpu_env);
14243 tcg_gen_movi_tl(t0, v2);
14244 tcg_gen_movi_tl(t1, v1);
14246 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14249 tcg_gen_movi_tl(t0, v2);
14250 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14253 tcg_gen_movi_tl(t0, v2);
14254 tcg_gen_movi_tl(t1, v1);
14255 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14258 tcg_gen_movi_tl(t0, v2);
14259 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14262 tcg_gen_movi_tl(t0, v2);
14263 tcg_gen_movi_tl(t1, v1);
14264 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14266 case OPC_DEXTR_R_L:
14267 tcg_gen_movi_tl(t0, v2);
14268 tcg_gen_movi_tl(t1, v1);
14269 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14271 case OPC_DEXTR_RS_L:
14272 tcg_gen_movi_tl(t0, v2);
14273 tcg_gen_movi_tl(t1, v1);
14274 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14277 tcg_gen_movi_tl(t0, v2);
14278 tcg_gen_movi_tl(t1, v1);
14279 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14281 case OPC_DEXTR_R_W:
14282 tcg_gen_movi_tl(t0, v2);
14283 tcg_gen_movi_tl(t1, v1);
14284 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14286 case OPC_DEXTR_RS_W:
14287 tcg_gen_movi_tl(t0, v2);
14288 tcg_gen_movi_tl(t1, v1);
14289 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14291 case OPC_DEXTR_S_H:
14292 tcg_gen_movi_tl(t0, v2);
14293 tcg_gen_movi_tl(t1, v1);
14294 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14296 case OPC_DEXTRV_S_H:
14297 tcg_gen_movi_tl(t0, v2);
14298 tcg_gen_movi_tl(t1, v1);
14299 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14302 tcg_gen_movi_tl(t0, v2);
14303 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14305 case OPC_DEXTRV_R_L:
14306 tcg_gen_movi_tl(t0, v2);
14307 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14309 case OPC_DEXTRV_RS_L:
14310 tcg_gen_movi_tl(t0, v2);
14311 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14314 tcg_gen_movi_tl(t0, v2);
14315 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14317 case OPC_DEXTRV_R_W:
14318 tcg_gen_movi_tl(t0, v2);
14319 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14321 case OPC_DEXTRV_RS_W:
14322 tcg_gen_movi_tl(t0, v2);
14323 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14332 tcg_temp_free(v1_t);
14333 tcg_temp_free(v2_t);
14335 (void)opn; /* avoid a compiler warning */
14336 MIPS_DEBUG("%s", opn);
14339 /* End MIPSDSP functions. */
14341 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14344 int rs, rt, rd, sa;
14345 uint32_t op, op1, op2;
14348 /* make sure instructions are on a word boundary */
14349 if (ctx->pc & 0x3) {
14350 env->CP0_BadVAddr = ctx->pc;
14351 generate_exception(ctx, EXCP_AdEL);
14355 /* Handle blikely not taken case */
14356 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14357 int l1 = gen_new_label();
14359 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14360 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14361 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14362 gen_goto_tb(ctx, 1, ctx->pc + 4);
14366 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14367 tcg_gen_debug_insn_start(ctx->pc);
14370 op = MASK_OP_MAJOR(ctx->opcode);
14371 rs = (ctx->opcode >> 21) & 0x1f;
14372 rt = (ctx->opcode >> 16) & 0x1f;
14373 rd = (ctx->opcode >> 11) & 0x1f;
14374 sa = (ctx->opcode >> 6) & 0x1f;
14375 imm = (int16_t)ctx->opcode;
14378 op1 = MASK_SPECIAL(ctx->opcode);
14380 case OPC_SLL: /* Shift with immediate */
14382 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14385 switch ((ctx->opcode >> 21) & 0x1f) {
14387 /* rotr is decoded as srl on non-R2 CPUs */
14388 if (env->insn_flags & ISA_MIPS32R2) {
14393 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14396 generate_exception(ctx, EXCP_RI);
14400 case OPC_MOVN: /* Conditional move */
14402 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14403 INSN_LOONGSON2E | INSN_LOONGSON2F);
14404 gen_cond_move(env, ctx, op1, rd, rs, rt);
14406 case OPC_ADD ... OPC_SUBU:
14407 gen_arith(env, ctx, op1, rd, rs, rt);
14409 case OPC_SLLV: /* Shifts */
14411 gen_shift(env, ctx, op1, rd, rs, rt);
14414 switch ((ctx->opcode >> 6) & 0x1f) {
14416 /* rotrv is decoded as srlv on non-R2 CPUs */
14417 if (env->insn_flags & ISA_MIPS32R2) {
14422 gen_shift(env, ctx, op1, rd, rs, rt);
14425 generate_exception(ctx, EXCP_RI);
14429 case OPC_SLT: /* Set on less than */
14431 gen_slt(env, ctx, op1, rd, rs, rt);
14433 case OPC_AND: /* Logic*/
14437 gen_logic(env, ctx, op1, rd, rs, rt);
14439 case OPC_MULT ... OPC_DIVU:
14441 check_insn(env, ctx, INSN_VR54XX);
14442 op1 = MASK_MUL_VR54XX(ctx->opcode);
14443 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14445 gen_muldiv(ctx, op1, rs, rt);
14447 case OPC_JR ... OPC_JALR:
14448 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14451 case OPC_TGE ... OPC_TEQ: /* Traps */
14453 gen_trap(ctx, op1, rs, rt, -1);
14455 case OPC_MFHI: /* Move from HI/LO */
14457 gen_HILO(ctx, op1, rd);
14460 case OPC_MTLO: /* Move to HI/LO */
14461 gen_HILO(ctx, op1, rs);
14463 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14464 #ifdef MIPS_STRICT_STANDARD
14465 MIPS_INVAL("PMON / selsl");
14466 generate_exception(ctx, EXCP_RI);
14468 gen_helper_0e0i(pmon, sa);
14472 generate_exception(ctx, EXCP_SYSCALL);
14473 ctx->bstate = BS_STOP;
14476 generate_exception(ctx, EXCP_BREAK);
14479 #ifdef MIPS_STRICT_STANDARD
14480 MIPS_INVAL("SPIM");
14481 generate_exception(ctx, EXCP_RI);
14483 /* Implemented as RI exception for now. */
14484 MIPS_INVAL("spim (unofficial)");
14485 generate_exception(ctx, EXCP_RI);
14489 /* Treat as NOP. */
14493 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14494 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14495 check_cp1_enabled(ctx);
14496 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14497 (ctx->opcode >> 16) & 1);
14499 generate_exception_err(ctx, EXCP_CpU, 1);
14503 #if defined(TARGET_MIPS64)
14504 /* MIPS64 specific opcodes */
14509 check_insn(env, ctx, ISA_MIPS3);
14510 check_mips_64(ctx);
14511 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14514 switch ((ctx->opcode >> 21) & 0x1f) {
14516 /* drotr is decoded as dsrl on non-R2 CPUs */
14517 if (env->insn_flags & ISA_MIPS32R2) {
14522 check_insn(env, ctx, ISA_MIPS3);
14523 check_mips_64(ctx);
14524 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14527 generate_exception(ctx, EXCP_RI);
14532 switch ((ctx->opcode >> 21) & 0x1f) {
14534 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14535 if (env->insn_flags & ISA_MIPS32R2) {
14540 check_insn(env, ctx, ISA_MIPS3);
14541 check_mips_64(ctx);
14542 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14545 generate_exception(ctx, EXCP_RI);
14549 case OPC_DADD ... OPC_DSUBU:
14550 check_insn(env, ctx, ISA_MIPS3);
14551 check_mips_64(ctx);
14552 gen_arith(env, ctx, op1, rd, rs, rt);
14556 check_insn(env, ctx, ISA_MIPS3);
14557 check_mips_64(ctx);
14558 gen_shift(env, ctx, op1, rd, rs, rt);
14561 switch ((ctx->opcode >> 6) & 0x1f) {
14563 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14564 if (env->insn_flags & ISA_MIPS32R2) {
14569 check_insn(env, ctx, ISA_MIPS3);
14570 check_mips_64(ctx);
14571 gen_shift(env, ctx, op1, rd, rs, rt);
14574 generate_exception(ctx, EXCP_RI);
14578 case OPC_DMULT ... OPC_DDIVU:
14579 check_insn(env, ctx, ISA_MIPS3);
14580 check_mips_64(ctx);
14581 gen_muldiv(ctx, op1, rs, rt);
14584 default: /* Invalid */
14585 MIPS_INVAL("special");
14586 generate_exception(ctx, EXCP_RI);
14591 op1 = MASK_SPECIAL2(ctx->opcode);
14593 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14594 case OPC_MSUB ... OPC_MSUBU:
14595 check_insn(env, ctx, ISA_MIPS32);
14596 gen_muldiv(ctx, op1, rs, rt);
14599 gen_arith(env, ctx, op1, rd, rs, rt);
14603 check_insn(env, ctx, ISA_MIPS32);
14604 gen_cl(ctx, op1, rd, rs);
14607 /* XXX: not clear which exception should be raised
14608 * when in debug mode...
14610 check_insn(env, ctx, ISA_MIPS32);
14611 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14612 generate_exception(ctx, EXCP_DBp);
14614 generate_exception(ctx, EXCP_DBp);
14616 /* Treat as NOP. */
14619 case OPC_DIVU_G_2F:
14620 case OPC_MULT_G_2F:
14621 case OPC_MULTU_G_2F:
14623 case OPC_MODU_G_2F:
14624 check_insn(env, ctx, INSN_LOONGSON2F);
14625 gen_loongson_integer(ctx, op1, rd, rs, rt);
14627 #if defined(TARGET_MIPS64)
14630 check_insn(env, ctx, ISA_MIPS64);
14631 check_mips_64(ctx);
14632 gen_cl(ctx, op1, rd, rs);
14634 case OPC_DMULT_G_2F:
14635 case OPC_DMULTU_G_2F:
14636 case OPC_DDIV_G_2F:
14637 case OPC_DDIVU_G_2F:
14638 case OPC_DMOD_G_2F:
14639 case OPC_DMODU_G_2F:
14640 check_insn(env, ctx, INSN_LOONGSON2F);
14641 gen_loongson_integer(ctx, op1, rd, rs, rt);
14644 default: /* Invalid */
14645 MIPS_INVAL("special2");
14646 generate_exception(ctx, EXCP_RI);
14651 op1 = MASK_SPECIAL3(ctx->opcode);
14655 check_insn(env, ctx, ISA_MIPS32R2);
14656 gen_bitops(ctx, op1, rt, rs, sa, rd);
14659 check_insn(env, ctx, ISA_MIPS32R2);
14660 op2 = MASK_BSHFL(ctx->opcode);
14661 gen_bshfl(ctx, op2, rt, rd);
14664 gen_rdhwr(env, ctx, rt, rd);
14667 check_insn(env, ctx, ASE_MT);
14669 TCGv t0 = tcg_temp_new();
14670 TCGv t1 = tcg_temp_new();
14672 gen_load_gpr(t0, rt);
14673 gen_load_gpr(t1, rs);
14674 gen_helper_fork(t0, t1);
14680 check_insn(env, ctx, ASE_MT);
14682 TCGv t0 = tcg_temp_new();
14684 save_cpu_state(ctx, 1);
14685 gen_load_gpr(t0, rs);
14686 gen_helper_yield(t0, cpu_env, t0);
14687 gen_store_gpr(t0, rd);
14691 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14692 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14693 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14694 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14695 * the same mask and op1. */
14696 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14697 op2 = MASK_ADDUH_QB(ctx->opcode);
14700 case OPC_ADDUH_R_QB:
14702 case OPC_ADDQH_R_PH:
14704 case OPC_ADDQH_R_W:
14706 case OPC_SUBUH_R_QB:
14708 case OPC_SUBQH_R_PH:
14710 case OPC_SUBQH_R_W:
14711 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14716 case OPC_MULQ_RS_W:
14717 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14720 MIPS_INVAL("MASK ADDUH.QB");
14721 generate_exception(ctx, EXCP_RI);
14724 } else if (env->insn_flags & INSN_LOONGSON2E) {
14725 gen_loongson_integer(ctx, op1, rd, rs, rt);
14727 generate_exception(ctx, EXCP_RI);
14731 op2 = MASK_LX(ctx->opcode);
14733 #if defined(TARGET_MIPS64)
14739 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14741 default: /* Invalid */
14742 MIPS_INVAL("MASK LX");
14743 generate_exception(ctx, EXCP_RI);
14747 case OPC_ABSQ_S_PH_DSP:
14748 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14750 case OPC_ABSQ_S_QB:
14751 case OPC_ABSQ_S_PH:
14753 case OPC_PRECEQ_W_PHL:
14754 case OPC_PRECEQ_W_PHR:
14755 case OPC_PRECEQU_PH_QBL:
14756 case OPC_PRECEQU_PH_QBR:
14757 case OPC_PRECEQU_PH_QBLA:
14758 case OPC_PRECEQU_PH_QBRA:
14759 case OPC_PRECEU_PH_QBL:
14760 case OPC_PRECEU_PH_QBR:
14761 case OPC_PRECEU_PH_QBLA:
14762 case OPC_PRECEU_PH_QBRA:
14763 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14770 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14773 MIPS_INVAL("MASK ABSQ_S.PH");
14774 generate_exception(ctx, EXCP_RI);
14778 case OPC_ADDU_QB_DSP:
14779 op2 = MASK_ADDU_QB(ctx->opcode);
14782 case OPC_ADDQ_S_PH:
14785 case OPC_ADDU_S_QB:
14787 case OPC_ADDU_S_PH:
14789 case OPC_SUBQ_S_PH:
14792 case OPC_SUBU_S_QB:
14794 case OPC_SUBU_S_PH:
14798 case OPC_RADDU_W_QB:
14799 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14801 case OPC_MULEU_S_PH_QBL:
14802 case OPC_MULEU_S_PH_QBR:
14803 case OPC_MULQ_RS_PH:
14804 case OPC_MULEQ_S_W_PHL:
14805 case OPC_MULEQ_S_W_PHR:
14806 case OPC_MULQ_S_PH:
14807 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14809 default: /* Invalid */
14810 MIPS_INVAL("MASK ADDU.QB");
14811 generate_exception(ctx, EXCP_RI);
14816 case OPC_CMPU_EQ_QB_DSP:
14817 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14819 case OPC_PRECR_SRA_PH_W:
14820 case OPC_PRECR_SRA_R_PH_W:
14821 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14823 case OPC_PRECR_QB_PH:
14824 case OPC_PRECRQ_QB_PH:
14825 case OPC_PRECRQ_PH_W:
14826 case OPC_PRECRQ_RS_PH_W:
14827 case OPC_PRECRQU_S_QB_PH:
14828 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14830 case OPC_CMPU_EQ_QB:
14831 case OPC_CMPU_LT_QB:
14832 case OPC_CMPU_LE_QB:
14833 case OPC_CMP_EQ_PH:
14834 case OPC_CMP_LT_PH:
14835 case OPC_CMP_LE_PH:
14836 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14838 case OPC_CMPGU_EQ_QB:
14839 case OPC_CMPGU_LT_QB:
14840 case OPC_CMPGU_LE_QB:
14841 case OPC_CMPGDU_EQ_QB:
14842 case OPC_CMPGDU_LT_QB:
14843 case OPC_CMPGDU_LE_QB:
14846 case OPC_PACKRL_PH:
14847 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14849 default: /* Invalid */
14850 MIPS_INVAL("MASK CMPU.EQ.QB");
14851 generate_exception(ctx, EXCP_RI);
14855 case OPC_SHLL_QB_DSP:
14856 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14858 case OPC_DPA_W_PH_DSP:
14859 op2 = MASK_DPA_W_PH(ctx->opcode);
14861 case OPC_DPAU_H_QBL:
14862 case OPC_DPAU_H_QBR:
14863 case OPC_DPSU_H_QBL:
14864 case OPC_DPSU_H_QBR:
14866 case OPC_DPAX_W_PH:
14867 case OPC_DPAQ_S_W_PH:
14868 case OPC_DPAQX_S_W_PH:
14869 case OPC_DPAQX_SA_W_PH:
14871 case OPC_DPSX_W_PH:
14872 case OPC_DPSQ_S_W_PH:
14873 case OPC_DPSQX_S_W_PH:
14874 case OPC_DPSQX_SA_W_PH:
14875 case OPC_MULSAQ_S_W_PH:
14876 case OPC_DPAQ_SA_L_W:
14877 case OPC_DPSQ_SA_L_W:
14878 case OPC_MAQ_S_W_PHL:
14879 case OPC_MAQ_S_W_PHR:
14880 case OPC_MAQ_SA_W_PHL:
14881 case OPC_MAQ_SA_W_PHR:
14882 case OPC_MULSA_W_PH:
14883 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14885 default: /* Invalid */
14886 MIPS_INVAL("MASK DPAW.PH");
14887 generate_exception(ctx, EXCP_RI);
14892 op2 = MASK_INSV(ctx->opcode);
14904 t0 = tcg_temp_new();
14905 t1 = tcg_temp_new();
14907 gen_load_gpr(t0, rt);
14908 gen_load_gpr(t1, rs);
14910 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14916 default: /* Invalid */
14917 MIPS_INVAL("MASK INSV");
14918 generate_exception(ctx, EXCP_RI);
14922 case OPC_APPEND_DSP:
14924 op2 = MASK_APPEND(ctx->opcode);
14925 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14927 case OPC_EXTR_W_DSP:
14928 op2 = MASK_EXTR_W(ctx->opcode);
14932 case OPC_EXTR_RS_W:
14934 case OPC_EXTRV_S_H:
14936 case OPC_EXTRV_R_W:
14937 case OPC_EXTRV_RS_W:
14942 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14945 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14951 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14953 default: /* Invalid */
14954 MIPS_INVAL("MASK EXTR.W");
14955 generate_exception(ctx, EXCP_RI);
14959 #if defined(TARGET_MIPS64)
14960 case OPC_DEXTM ... OPC_DEXT:
14961 case OPC_DINSM ... OPC_DINS:
14962 check_insn(env, ctx, ISA_MIPS64R2);
14963 check_mips_64(ctx);
14964 gen_bitops(ctx, op1, rt, rs, sa, rd);
14967 check_insn(env, ctx, ISA_MIPS64R2);
14968 check_mips_64(ctx);
14969 op2 = MASK_DBSHFL(ctx->opcode);
14970 gen_bshfl(ctx, op2, rt, rd);
14972 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14973 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14974 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14975 check_insn(env, ctx, INSN_LOONGSON2E);
14976 gen_loongson_integer(ctx, op1, rd, rs, rt);
14978 case OPC_ABSQ_S_QH_DSP:
14979 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14981 case OPC_PRECEQ_L_PWL:
14982 case OPC_PRECEQ_L_PWR:
14983 case OPC_PRECEQ_PW_QHL:
14984 case OPC_PRECEQ_PW_QHR:
14985 case OPC_PRECEQ_PW_QHLA:
14986 case OPC_PRECEQ_PW_QHRA:
14987 case OPC_PRECEQU_QH_OBL:
14988 case OPC_PRECEQU_QH_OBR:
14989 case OPC_PRECEQU_QH_OBLA:
14990 case OPC_PRECEQU_QH_OBRA:
14991 case OPC_PRECEU_QH_OBL:
14992 case OPC_PRECEU_QH_OBR:
14993 case OPC_PRECEU_QH_OBLA:
14994 case OPC_PRECEU_QH_OBRA:
14995 case OPC_ABSQ_S_OB:
14996 case OPC_ABSQ_S_PW:
14997 case OPC_ABSQ_S_QH:
14998 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15006 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
15008 default: /* Invalid */
15009 MIPS_INVAL("MASK ABSQ_S.QH");
15010 generate_exception(ctx, EXCP_RI);
15014 case OPC_ADDU_OB_DSP:
15015 op2 = MASK_ADDU_OB(ctx->opcode);
15017 case OPC_RADDU_L_OB:
15019 case OPC_SUBQ_S_PW:
15021 case OPC_SUBQ_S_QH:
15023 case OPC_SUBU_S_OB:
15025 case OPC_SUBU_S_QH:
15027 case OPC_SUBUH_R_OB:
15029 case OPC_ADDQ_S_PW:
15031 case OPC_ADDQ_S_QH:
15033 case OPC_ADDU_S_OB:
15035 case OPC_ADDU_S_QH:
15037 case OPC_ADDUH_R_OB:
15038 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15040 case OPC_MULEQ_S_PW_QHL:
15041 case OPC_MULEQ_S_PW_QHR:
15042 case OPC_MULEU_S_QH_OBL:
15043 case OPC_MULEU_S_QH_OBR:
15044 case OPC_MULQ_RS_QH:
15045 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15047 default: /* Invalid */
15048 MIPS_INVAL("MASK ADDU.OB");
15049 generate_exception(ctx, EXCP_RI);
15053 case OPC_CMPU_EQ_OB_DSP:
15054 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15056 case OPC_PRECR_SRA_QH_PW:
15057 case OPC_PRECR_SRA_R_QH_PW:
15058 /* Return value is rt. */
15059 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15061 case OPC_PRECR_OB_QH:
15062 case OPC_PRECRQ_OB_QH:
15063 case OPC_PRECRQ_PW_L:
15064 case OPC_PRECRQ_QH_PW:
15065 case OPC_PRECRQ_RS_QH_PW:
15066 case OPC_PRECRQU_S_OB_QH:
15067 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15069 case OPC_CMPU_EQ_OB:
15070 case OPC_CMPU_LT_OB:
15071 case OPC_CMPU_LE_OB:
15072 case OPC_CMP_EQ_QH:
15073 case OPC_CMP_LT_QH:
15074 case OPC_CMP_LE_QH:
15075 case OPC_CMP_EQ_PW:
15076 case OPC_CMP_LT_PW:
15077 case OPC_CMP_LE_PW:
15078 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15080 case OPC_CMPGDU_EQ_OB:
15081 case OPC_CMPGDU_LT_OB:
15082 case OPC_CMPGDU_LE_OB:
15083 case OPC_CMPGU_EQ_OB:
15084 case OPC_CMPGU_LT_OB:
15085 case OPC_CMPGU_LE_OB:
15086 case OPC_PACKRL_PW:
15090 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15092 default: /* Invalid */
15093 MIPS_INVAL("MASK CMPU_EQ.OB");
15094 generate_exception(ctx, EXCP_RI);
15098 case OPC_DAPPEND_DSP:
15100 op2 = MASK_DAPPEND(ctx->opcode);
15101 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15103 case OPC_DEXTR_W_DSP:
15104 op2 = MASK_DEXTR_W(ctx->opcode);
15111 case OPC_DEXTR_R_L:
15112 case OPC_DEXTR_RS_L:
15114 case OPC_DEXTR_R_W:
15115 case OPC_DEXTR_RS_W:
15116 case OPC_DEXTR_S_H:
15118 case OPC_DEXTRV_R_L:
15119 case OPC_DEXTRV_RS_L:
15120 case OPC_DEXTRV_S_H:
15122 case OPC_DEXTRV_R_W:
15123 case OPC_DEXTRV_RS_W:
15124 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15129 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15131 default: /* Invalid */
15132 MIPS_INVAL("MASK EXTR.W");
15133 generate_exception(ctx, EXCP_RI);
15137 case OPC_DPAQ_W_QH_DSP:
15138 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15140 case OPC_DPAU_H_OBL:
15141 case OPC_DPAU_H_OBR:
15142 case OPC_DPSU_H_OBL:
15143 case OPC_DPSU_H_OBR:
15145 case OPC_DPAQ_S_W_QH:
15147 case OPC_DPSQ_S_W_QH:
15148 case OPC_MULSAQ_S_W_QH:
15149 case OPC_DPAQ_SA_L_PW:
15150 case OPC_DPSQ_SA_L_PW:
15151 case OPC_MULSAQ_S_L_PW:
15152 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15154 case OPC_MAQ_S_W_QHLL:
15155 case OPC_MAQ_S_W_QHLR:
15156 case OPC_MAQ_S_W_QHRL:
15157 case OPC_MAQ_S_W_QHRR:
15158 case OPC_MAQ_SA_W_QHLL:
15159 case OPC_MAQ_SA_W_QHLR:
15160 case OPC_MAQ_SA_W_QHRL:
15161 case OPC_MAQ_SA_W_QHRR:
15162 case OPC_MAQ_S_L_PWL:
15163 case OPC_MAQ_S_L_PWR:
15168 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15170 default: /* Invalid */
15171 MIPS_INVAL("MASK DPAQ.W.QH");
15172 generate_exception(ctx, EXCP_RI);
15176 case OPC_DINSV_DSP:
15177 op2 = MASK_INSV(ctx->opcode);
15189 t0 = tcg_temp_new();
15190 t1 = tcg_temp_new();
15192 gen_load_gpr(t0, rt);
15193 gen_load_gpr(t1, rs);
15195 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15198 default: /* Invalid */
15199 MIPS_INVAL("MASK DINSV");
15200 generate_exception(ctx, EXCP_RI);
15204 case OPC_SHLL_OB_DSP:
15205 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15208 default: /* Invalid */
15209 MIPS_INVAL("special3");
15210 generate_exception(ctx, EXCP_RI);
15215 op1 = MASK_REGIMM(ctx->opcode);
15217 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15218 case OPC_BLTZAL ... OPC_BGEZALL:
15219 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15222 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15224 gen_trap(ctx, op1, rs, -1, imm);
15227 check_insn(env, ctx, ISA_MIPS32R2);
15228 /* Treat as NOP. */
15230 case OPC_BPOSGE32: /* MIPS DSP branch */
15231 #if defined(TARGET_MIPS64)
15235 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15238 default: /* Invalid */
15239 MIPS_INVAL("regimm");
15240 generate_exception(ctx, EXCP_RI);
15245 check_cp0_enabled(ctx);
15246 op1 = MASK_CP0(ctx->opcode);
15252 #if defined(TARGET_MIPS64)
15256 #ifndef CONFIG_USER_ONLY
15257 gen_cp0(env, ctx, op1, rt, rd);
15258 #endif /* !CONFIG_USER_ONLY */
15260 case OPC_C0_FIRST ... OPC_C0_LAST:
15261 #ifndef CONFIG_USER_ONLY
15262 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15263 #endif /* !CONFIG_USER_ONLY */
15266 #ifndef CONFIG_USER_ONLY
15268 TCGv t0 = tcg_temp_new();
15270 op2 = MASK_MFMC0(ctx->opcode);
15273 check_insn(env, ctx, ASE_MT);
15274 gen_helper_dmt(t0);
15275 gen_store_gpr(t0, rt);
15278 check_insn(env, ctx, ASE_MT);
15279 gen_helper_emt(t0);
15280 gen_store_gpr(t0, rt);
15283 check_insn(env, ctx, ASE_MT);
15284 gen_helper_dvpe(t0, cpu_env);
15285 gen_store_gpr(t0, rt);
15288 check_insn(env, ctx, ASE_MT);
15289 gen_helper_evpe(t0, cpu_env);
15290 gen_store_gpr(t0, rt);
15293 check_insn(env, ctx, ISA_MIPS32R2);
15294 save_cpu_state(ctx, 1);
15295 gen_helper_di(t0, cpu_env);
15296 gen_store_gpr(t0, rt);
15297 /* Stop translation as we may have switched the execution mode */
15298 ctx->bstate = BS_STOP;
15301 check_insn(env, ctx, ISA_MIPS32R2);
15302 save_cpu_state(ctx, 1);
15303 gen_helper_ei(t0, cpu_env);
15304 gen_store_gpr(t0, rt);
15305 /* Stop translation as we may have switched the execution mode */
15306 ctx->bstate = BS_STOP;
15308 default: /* Invalid */
15309 MIPS_INVAL("mfmc0");
15310 generate_exception(ctx, EXCP_RI);
15315 #endif /* !CONFIG_USER_ONLY */
15318 check_insn(env, ctx, ISA_MIPS32R2);
15319 gen_load_srsgpr(rt, rd);
15322 check_insn(env, ctx, ISA_MIPS32R2);
15323 gen_store_srsgpr(rt, rd);
15327 generate_exception(ctx, EXCP_RI);
15331 case OPC_ADDI: /* Arithmetic with immediate opcode */
15333 gen_arith_imm(env, ctx, op, rt, rs, imm);
15335 case OPC_SLTI: /* Set on less than with immediate opcode */
15337 gen_slt_imm(env, ctx, op, rt, rs, imm);
15339 case OPC_ANDI: /* Arithmetic with immediate opcode */
15343 gen_logic_imm(env, ctx, op, rt, rs, imm);
15345 case OPC_J ... OPC_JAL: /* Jump */
15346 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15347 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15350 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15351 case OPC_BEQL ... OPC_BGTZL:
15352 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15355 case OPC_LB ... OPC_LWR: /* Load and stores */
15357 gen_ld(env, ctx, op, rt, rs, imm);
15359 case OPC_SB ... OPC_SW:
15361 gen_st(ctx, op, rt, rs, imm);
15364 gen_st_cond(ctx, op, rt, rs, imm);
15367 check_cp0_enabled(ctx);
15368 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15369 /* Treat as NOP. */
15372 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15373 /* Treat as NOP. */
15376 /* Floating point (COP1). */
15381 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15385 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15386 check_cp1_enabled(ctx);
15387 op1 = MASK_CP1(ctx->opcode);
15391 check_insn(env, ctx, ISA_MIPS32R2);
15396 gen_cp1(ctx, op1, rt, rd);
15398 #if defined(TARGET_MIPS64)
15401 check_insn(env, ctx, ISA_MIPS3);
15402 gen_cp1(ctx, op1, rt, rd);
15408 check_insn(env, ctx, ASE_MIPS3D);
15411 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15412 (rt >> 2) & 0x7, imm << 2);
15420 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15425 generate_exception (ctx, EXCP_RI);
15429 generate_exception_err(ctx, EXCP_CpU, 1);
15438 /* COP2: Not implemented. */
15439 generate_exception_err(ctx, EXCP_CpU, 2);
15442 check_insn(env, ctx, INSN_LOONGSON2F);
15443 /* Note that these instructions use different fields. */
15444 gen_loongson_multimedia(ctx, sa, rd, rt);
15448 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15449 check_cp1_enabled(ctx);
15450 op1 = MASK_CP3(ctx->opcode);
15458 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15461 /* Treat as NOP. */
15476 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15480 generate_exception (ctx, EXCP_RI);
15484 generate_exception_err(ctx, EXCP_CpU, 1);
15488 #if defined(TARGET_MIPS64)
15489 /* MIPS64 opcodes */
15491 case OPC_LDL ... OPC_LDR:
15494 check_insn(env, ctx, ISA_MIPS3);
15495 check_mips_64(ctx);
15496 gen_ld(env, ctx, op, rt, rs, imm);
15498 case OPC_SDL ... OPC_SDR:
15500 check_insn(env, ctx, ISA_MIPS3);
15501 check_mips_64(ctx);
15502 gen_st(ctx, op, rt, rs, imm);
15505 check_insn(env, ctx, ISA_MIPS3);
15506 check_mips_64(ctx);
15507 gen_st_cond(ctx, op, rt, rs, imm);
15511 check_insn(env, ctx, ISA_MIPS3);
15512 check_mips_64(ctx);
15513 gen_arith_imm(env, ctx, op, rt, rs, imm);
15517 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15518 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15519 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15523 check_insn(env, ctx, ASE_MDMX);
15524 /* MDMX: Not implemented. */
15525 default: /* Invalid */
15526 MIPS_INVAL("major opcode");
15527 generate_exception(ctx, EXCP_RI);
15533 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15537 target_ulong pc_start;
15538 uint16_t *gen_opc_end;
15547 qemu_log("search pc %d\n", search_pc);
15550 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15553 ctx.singlestep_enabled = env->singlestep_enabled;
15555 ctx.bstate = BS_NONE;
15556 /* Restore delay slot state from the tb context. */
15557 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15558 restore_cpu_state(env, &ctx);
15559 #ifdef CONFIG_USER_ONLY
15560 ctx.mem_idx = MIPS_HFLAG_UM;
15562 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15565 max_insns = tb->cflags & CF_COUNT_MASK;
15566 if (max_insns == 0)
15567 max_insns = CF_COUNT_MASK;
15568 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15569 gen_icount_start();
15570 while (ctx.bstate == BS_NONE) {
15571 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15572 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15573 if (bp->pc == ctx.pc) {
15574 save_cpu_state(&ctx, 1);
15575 ctx.bstate = BS_BRANCH;
15576 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15577 /* Include the breakpoint location or the tb won't
15578 * be flushed when it must be. */
15580 goto done_generating;
15586 j = gen_opc_ptr - gen_opc_buf;
15590 gen_opc_instr_start[lj++] = 0;
15592 gen_opc_pc[lj] = ctx.pc;
15593 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15594 gen_opc_btarget[lj] = ctx.btarget;
15595 gen_opc_instr_start[lj] = 1;
15596 gen_opc_icount[lj] = num_insns;
15598 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15602 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15603 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15605 decode_opc(env, &ctx, &is_branch);
15606 } else if (env->insn_flags & ASE_MICROMIPS) {
15607 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15608 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15609 } else if (env->insn_flags & ASE_MIPS16) {
15610 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15611 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15613 generate_exception(&ctx, EXCP_RI);
15614 ctx.bstate = BS_STOP;
15618 handle_delay_slot(env, &ctx, insn_bytes);
15620 ctx.pc += insn_bytes;
15624 /* Execute a branch and its delay slot as a single instruction.
15625 This is what GDB expects and is consistent with what the
15626 hardware does (e.g. if a delay slot instruction faults, the
15627 reported PC is the PC of the branch). */
15628 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15631 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15634 if (gen_opc_ptr >= gen_opc_end)
15637 if (num_insns >= max_insns)
15643 if (tb->cflags & CF_LAST_IO)
15645 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15646 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15647 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15649 switch (ctx.bstate) {
15651 gen_goto_tb(&ctx, 0, ctx.pc);
15654 save_cpu_state(&ctx, 0);
15655 gen_goto_tb(&ctx, 0, ctx.pc);
15658 tcg_gen_exit_tb(0);
15666 gen_icount_end(tb, num_insns);
15667 *gen_opc_ptr = INDEX_op_end;
15669 j = gen_opc_ptr - gen_opc_buf;
15672 gen_opc_instr_start[lj++] = 0;
15674 tb->size = ctx.pc - pc_start;
15675 tb->icount = num_insns;
15679 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15680 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15681 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15687 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15689 gen_intermediate_code_internal(env, tb, 0);
15692 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15694 gen_intermediate_code_internal(env, tb, 1);
15697 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15701 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15703 #define printfpr(fp) \
15706 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15707 " fd:%13g fs:%13g psu: %13g\n", \
15708 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15709 (double)(fp)->fd, \
15710 (double)(fp)->fs[FP_ENDIAN_IDX], \
15711 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15714 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15715 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15716 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15717 " fd:%13g fs:%13g psu:%13g\n", \
15718 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15720 (double)tmp.fs[FP_ENDIAN_IDX], \
15721 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15726 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15727 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15728 get_float_exception_flags(&env->active_fpu.fp_status));
15729 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15730 fpu_fprintf(f, "%3s: ", fregnames[i]);
15731 printfpr(&env->active_fpu.fpr[i]);
15737 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15738 /* Debug help: The architecture requires 32bit code to maintain proper
15739 sign-extended values on 64bit machines. */
15741 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15744 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15745 fprintf_function cpu_fprintf,
15750 if (!SIGN_EXT_P(env->active_tc.PC))
15751 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15752 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15753 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15754 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15755 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15756 if (!SIGN_EXT_P(env->btarget))
15757 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15759 for (i = 0; i < 32; i++) {
15760 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15761 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15764 if (!SIGN_EXT_P(env->CP0_EPC))
15765 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15766 if (!SIGN_EXT_P(env->lladdr))
15767 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15771 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15776 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15777 " LO=0x" TARGET_FMT_lx " ds %04x "
15778 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15779 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15780 env->hflags, env->btarget, env->bcond);
15781 for (i = 0; i < 32; i++) {
15783 cpu_fprintf(f, "GPR%02d:", i);
15784 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15786 cpu_fprintf(f, "\n");
15789 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15790 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15791 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15792 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15793 if (env->hflags & MIPS_HFLAG_FPU)
15794 fpu_dump_state(env, f, cpu_fprintf, flags);
15795 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15796 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15800 static void mips_tcg_init(void)
15805 /* Initialize various static tables. */
15809 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15810 TCGV_UNUSED(cpu_gpr[0]);
15811 for (i = 1; i < 32; i++)
15812 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15813 offsetof(CPUMIPSState, active_tc.gpr[i]),
15816 for (i = 0; i < 32; i++) {
15817 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15818 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15821 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15822 offsetof(CPUMIPSState, active_tc.PC), "PC");
15823 for (i = 0; i < MIPS_DSP_ACC; i++) {
15824 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15825 offsetof(CPUMIPSState, active_tc.HI[i]),
15827 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15828 offsetof(CPUMIPSState, active_tc.LO[i]),
15830 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15831 offsetof(CPUMIPSState, active_tc.ACX[i]),
15834 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15835 offsetof(CPUMIPSState, active_tc.DSPControl),
15837 bcond = tcg_global_mem_new(TCG_AREG0,
15838 offsetof(CPUMIPSState, bcond), "bcond");
15839 btarget = tcg_global_mem_new(TCG_AREG0,
15840 offsetof(CPUMIPSState, btarget), "btarget");
15841 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15842 offsetof(CPUMIPSState, hflags), "hflags");
15844 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15845 offsetof(CPUMIPSState, active_fpu.fcr0),
15847 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15848 offsetof(CPUMIPSState, active_fpu.fcr31),
15851 /* register helpers */
15852 #define GEN_HELPER 2
15853 #include "helper.h"
15858 #include "translate_init.c"
15860 MIPSCPU *cpu_mips_init(const char *cpu_model)
15864 const mips_def_t *def;
15866 def = cpu_mips_find_by_name(cpu_model);
15869 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15871 env->cpu_model = def;
15872 env->cpu_model_str = cpu_model;
15874 #ifndef CONFIG_USER_ONLY
15875 mmu_init(env, def);
15877 fpu_init(env, def);
15878 mvp_init(env, def);
15880 cpu_reset(CPU(cpu));
15881 qemu_init_vcpu(env);
15885 void cpu_state_reset(CPUMIPSState *env)
15887 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15888 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15889 log_cpu_state(env, 0);
15892 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15895 /* Reset registers to their default values */
15896 env->CP0_PRid = env->cpu_model->CP0_PRid;
15897 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15898 #ifdef TARGET_WORDS_BIGENDIAN
15899 env->CP0_Config0 |= (1 << CP0C0_BE);
15901 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15902 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15903 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15904 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15905 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15906 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15907 << env->cpu_model->CP0_LLAddr_shift;
15908 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15909 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15910 env->CCRes = env->cpu_model->CCRes;
15911 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15912 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15913 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15914 env->current_tc = 0;
15915 env->SEGBITS = env->cpu_model->SEGBITS;
15916 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15917 #if defined(TARGET_MIPS64)
15918 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15919 env->SEGMask |= 3ULL << 62;
15922 env->PABITS = env->cpu_model->PABITS;
15923 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15924 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15925 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15926 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15927 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15928 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15929 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15930 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15931 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15932 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15933 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15934 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15935 env->insn_flags = env->cpu_model->insn_flags;
15937 #if defined(CONFIG_USER_ONLY)
15938 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15939 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15940 hardware registers. */
15941 env->CP0_HWREna |= 0x0000000F;
15942 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15943 env->CP0_Status |= (1 << CP0St_CU1);
15945 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15946 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15947 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15948 env->hflags |= MIPS_HFLAG_DSP;
15951 if (env->hflags & MIPS_HFLAG_BMASK) {
15952 /* If the exception was raised from a delay slot,
15953 come back to the jump. */
15954 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15956 env->CP0_ErrorEPC = env->active_tc.PC;
15958 env->active_tc.PC = (int32_t)0xBFC00000;
15959 env->CP0_Random = env->tlb->nb_tlb - 1;
15960 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15961 env->CP0_Wired = 0;
15962 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15963 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15964 /* vectored interrupts not implemented, timer on int 7,
15965 no performance counters. */
15966 env->CP0_IntCtl = 0xe0000000;
15970 for (i = 0; i < 7; i++) {
15971 env->CP0_WatchLo[i] = 0;
15972 env->CP0_WatchHi[i] = 0x80000000;
15974 env->CP0_WatchLo[7] = 0;
15975 env->CP0_WatchHi[7] = 0;
15977 /* Count register increments in debug mode, EJTAG version 1 */
15978 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15980 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15983 /* Only TC0 on VPE 0 starts as active. */
15984 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15985 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15986 env->tcs[i].CP0_TCHalt = 1;
15988 env->active_tc.CP0_TCHalt = 1;
15991 if (!env->cpu_index) {
15992 /* VPE0 starts up enabled. */
15993 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15994 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15996 /* TC0 starts up unhalted. */
15998 env->active_tc.CP0_TCHalt = 0;
15999 env->tcs[0].CP0_TCHalt = 0;
16000 /* With thread 0 active. */
16001 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16002 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16006 compute_hflags(env);
16007 env->exception_index = EXCP_NONE;
16010 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16012 env->active_tc.PC = gen_opc_pc[pc_pos];
16013 env->hflags &= ~MIPS_HFLAG_BMASK;
16014 env->hflags |= gen_opc_hflags[pc_pos];
16015 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16016 case MIPS_HFLAG_BR:
16018 case MIPS_HFLAG_BC:
16019 case MIPS_HFLAG_BL:
16021 env->btarget = gen_opc_btarget[pc_pos];