2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Compare-Pick Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Compare-Pick Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Compare-Pick Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1020 #include "gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1068 int singlestep_enabled;
1069 /* Routine used to access memory */
1071 uint32_t hflags, saved_hflags;
1073 target_ulong btarget;
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1078 * exception condition */
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1084 static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1091 static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1095 static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1099 static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1103 static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1110 #define MIPS_DEBUG(fmt, ...) \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1119 #define LOG_DISAS(...) \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1126 #define MIPS_INVAL(op) \
1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1130 /* General purpose registers moves. */
1131 static inline void gen_load_gpr (TCGv t, int reg)
1134 tcg_gen_movi_tl(t, 0);
1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1139 static inline void gen_store_gpr (TCGv t, int reg)
1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
1145 /* Moves to/from ACX register. */
1146 static inline void gen_load_ACX (TCGv t, int reg)
1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1151 static inline void gen_store_ACX (TCGv t, int reg)
1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
1156 /* Moves to/from shadow registers. */
1157 static inline void gen_load_srsgpr (int from, int to)
1159 TCGv t0 = tcg_temp_new();
1162 tcg_gen_movi_tl(t0, 0);
1164 TCGv_i32 t2 = tcg_temp_new_i32();
1165 TCGv_ptr addr = tcg_temp_new_ptr();
1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
1172 tcg_gen_add_ptr(addr, cpu_env, addr);
1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1175 tcg_temp_free_ptr(addr);
1176 tcg_temp_free_i32(t2);
1178 gen_store_gpr(t0, to);
1182 static inline void gen_store_srsgpr (int from, int to)
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
1187 TCGv_ptr addr = tcg_temp_new_ptr();
1189 gen_load_gpr(t0, from);
1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
1195 tcg_gen_add_ptr(addr, cpu_env, addr);
1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1198 tcg_temp_free_ptr(addr);
1199 tcg_temp_free_i32(t2);
1204 /* Floating point register moves. */
1205 static void gen_load_fpr32(TCGv_i32 t, int reg)
1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1210 static void gen_store_fpr32(TCGv_i32 t, int reg)
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
1218 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
1226 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
1234 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1236 if (ctx->hflags & MIPS_HFLAG_F64) {
1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1243 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1245 if (ctx->hflags & MIPS_HFLAG_F64) {
1246 tcg_gen_mov_i64(fpu_f64[reg], t);
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
1251 tcg_gen_shri_i64(t0, t, 32);
1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1253 tcg_temp_free_i64(t0);
1257 static inline int get_fp_bit (int cc)
1266 static inline void gen_save_pc(target_ulong pc)
1268 tcg_gen_movi_tl(cpu_PC, pc);
1271 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1275 gen_save_pc(ctx->pc);
1276 ctx->saved_pc = ctx->pc;
1278 if (ctx->hflags != ctx->saved_hflags) {
1279 tcg_gen_movi_i32(hflags, ctx->hflags);
1280 ctx->saved_hflags = ctx->hflags;
1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1287 tcg_gen_movi_tl(btarget, ctx->btarget);
1293 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1295 ctx->saved_hflags = ctx->hflags;
1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1302 ctx->btarget = env->btarget;
1308 generate_exception_err (DisasContext *ctx, int excp, int err)
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
1312 save_cpu_state(ctx, 1);
1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
1319 generate_exception (DisasContext *ctx, int excp)
1321 save_cpu_state(ctx, 1);
1322 gen_helper_0e0i(raise_exception, excp);
1325 /* Addresses computation */
1326 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1328 tcg_gen_add_tl(ret, arg0, arg1);
1330 #if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
1336 tcg_gen_ext32s_i64(ret, ret);
1341 static inline void check_cp0_enabled(DisasContext *ctx)
1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1344 generate_exception_err(ctx, EXCP_CpU, 0);
1347 static inline void check_cp1_enabled(DisasContext *ctx)
1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1353 /* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1357 static inline void check_cop1x(DisasContext *ctx)
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1363 /* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1366 static inline void check_cp1_64bitmode(DisasContext *ctx)
1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1369 generate_exception(ctx, EXCP_RI);
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1386 generate_exception(ctx, EXCP_RI);
1389 /* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1393 static inline void check_dsp(DisasContext *ctx)
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1400 static inline void check_dspr2(DisasContext *ctx)
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1407 /* This code generates a "reserved instruction" exception if the
1408 CPU does not support the instruction set corresponding to flags. */
1409 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1411 if (unlikely(!(env->insn_flags & flags)))
1412 generate_exception(ctx, EXCP_RI);
1415 /* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
1417 static inline void check_mips_64(DisasContext *ctx)
1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1420 generate_exception(ctx, EXCP_RI);
1423 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1427 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1437 check_cp1_64bitmode(ctx); \
1443 check_cp1_registers(ctx, fs | ft); \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1476 FOP_CONDS(, 0, d, FMT_D, 64)
1477 FOP_CONDS(abs, 1, d, FMT_D, 64)
1478 FOP_CONDS(, 0, s, FMT_S, 32)
1479 FOP_CONDS(abs, 1, s, FMT_S, 32)
1480 FOP_CONDS(, 0, ps, FMT_PS, 64)
1481 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1483 #undef gen_ldcmp_fpr32
1484 #undef gen_ldcmp_fpr64
1486 /* load/store instructions. */
1487 #ifdef CONFIG_USER_ONLY
1488 #define OP_LD_ATOMIC(insn,fname) \
1489 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1491 TCGv t0 = tcg_temp_new(); \
1492 tcg_gen_mov_tl(t0, arg1); \
1493 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1494 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1495 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1496 tcg_temp_free(t0); \
1499 #define OP_LD_ATOMIC(insn,fname) \
1500 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1502 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1505 OP_LD_ATOMIC(ll,ld32s);
1506 #if defined(TARGET_MIPS64)
1507 OP_LD_ATOMIC(lld,ld64);
1511 #ifdef CONFIG_USER_ONLY
1512 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1513 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1515 TCGv t0 = tcg_temp_new(); \
1516 int l1 = gen_new_label(); \
1517 int l2 = gen_new_label(); \
1519 tcg_gen_andi_tl(t0, arg2, almask); \
1520 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1521 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1522 generate_exception(ctx, EXCP_AdES); \
1523 gen_set_label(l1); \
1524 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1525 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1526 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1527 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1528 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1529 gen_helper_0e0i(raise_exception, EXCP_SC); \
1530 gen_set_label(l2); \
1531 tcg_gen_movi_tl(t0, 0); \
1532 gen_store_gpr(t0, rt); \
1533 tcg_temp_free(t0); \
1536 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1537 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1539 TCGv t0 = tcg_temp_new(); \
1540 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1541 gen_store_gpr(t0, rt); \
1542 tcg_temp_free(t0); \
1545 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1546 #if defined(TARGET_MIPS64)
1547 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1551 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1552 int base, int16_t offset)
1555 tcg_gen_movi_tl(addr, offset);
1556 } else if (offset == 0) {
1557 gen_load_gpr(addr, base);
1559 tcg_gen_movi_tl(addr, offset);
1560 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1564 static target_ulong pc_relative_pc (DisasContext *ctx)
1566 target_ulong pc = ctx->pc;
1568 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1569 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1574 pc &= ~(target_ulong)3;
1579 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1580 int rt, int base, int16_t offset)
1582 const char *opn = "ld";
1585 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1586 /* Loongson CPU uses a load to zero register for prefetch.
1587 We emulate it as a NOP. On other CPU we must perform the
1588 actual memory access. */
1593 t0 = tcg_temp_new();
1594 gen_base_offset_addr(ctx, t0, base, offset);
1597 #if defined(TARGET_MIPS64)
1599 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1600 gen_store_gpr(t0, rt);
1604 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1605 gen_store_gpr(t0, rt);
1609 save_cpu_state(ctx, 1);
1610 op_ld_lld(t0, t0, ctx);
1611 gen_store_gpr(t0, rt);
1615 t1 = tcg_temp_new();
1616 tcg_gen_andi_tl(t1, t0, 7);
1617 #ifndef TARGET_WORDS_BIGENDIAN
1618 tcg_gen_xori_tl(t1, t1, 7);
1620 tcg_gen_shli_tl(t1, t1, 3);
1621 tcg_gen_andi_tl(t0, t0, ~7);
1622 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1623 tcg_gen_shl_tl(t0, t0, t1);
1624 tcg_gen_xori_tl(t1, t1, 63);
1625 t2 = tcg_const_tl(0x7fffffffffffffffull);
1626 tcg_gen_shr_tl(t2, t2, t1);
1627 gen_load_gpr(t1, rt);
1628 tcg_gen_and_tl(t1, t1, t2);
1630 tcg_gen_or_tl(t0, t0, t1);
1632 gen_store_gpr(t0, rt);
1636 t1 = tcg_temp_new();
1637 tcg_gen_andi_tl(t1, t0, 7);
1638 #ifdef TARGET_WORDS_BIGENDIAN
1639 tcg_gen_xori_tl(t1, t1, 7);
1641 tcg_gen_shli_tl(t1, t1, 3);
1642 tcg_gen_andi_tl(t0, t0, ~7);
1643 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1644 tcg_gen_shr_tl(t0, t0, t1);
1645 tcg_gen_xori_tl(t1, t1, 63);
1646 t2 = tcg_const_tl(0xfffffffffffffffeull);
1647 tcg_gen_shl_tl(t2, t2, t1);
1648 gen_load_gpr(t1, rt);
1649 tcg_gen_and_tl(t1, t1, t2);
1651 tcg_gen_or_tl(t0, t0, t1);
1653 gen_store_gpr(t0, rt);
1657 t1 = tcg_const_tl(pc_relative_pc(ctx));
1658 gen_op_addr_add(ctx, t0, t0, t1);
1660 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1661 gen_store_gpr(t0, rt);
1666 t1 = tcg_const_tl(pc_relative_pc(ctx));
1667 gen_op_addr_add(ctx, t0, t0, t1);
1669 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1670 gen_store_gpr(t0, rt);
1674 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1675 gen_store_gpr(t0, rt);
1679 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1680 gen_store_gpr(t0, rt);
1684 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1685 gen_store_gpr(t0, rt);
1689 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1690 gen_store_gpr(t0, rt);
1694 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1695 gen_store_gpr(t0, rt);
1699 t1 = tcg_temp_new();
1700 tcg_gen_andi_tl(t1, t0, 3);
1701 #ifndef TARGET_WORDS_BIGENDIAN
1702 tcg_gen_xori_tl(t1, t1, 3);
1704 tcg_gen_shli_tl(t1, t1, 3);
1705 tcg_gen_andi_tl(t0, t0, ~3);
1706 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1707 tcg_gen_shl_tl(t0, t0, t1);
1708 tcg_gen_xori_tl(t1, t1, 31);
1709 t2 = tcg_const_tl(0x7fffffffull);
1710 tcg_gen_shr_tl(t2, t2, t1);
1711 gen_load_gpr(t1, rt);
1712 tcg_gen_and_tl(t1, t1, t2);
1714 tcg_gen_or_tl(t0, t0, t1);
1716 tcg_gen_ext32s_tl(t0, t0);
1717 gen_store_gpr(t0, rt);
1721 t1 = tcg_temp_new();
1722 tcg_gen_andi_tl(t1, t0, 3);
1723 #ifdef TARGET_WORDS_BIGENDIAN
1724 tcg_gen_xori_tl(t1, t1, 3);
1726 tcg_gen_shli_tl(t1, t1, 3);
1727 tcg_gen_andi_tl(t0, t0, ~3);
1728 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1729 tcg_gen_shr_tl(t0, t0, t1);
1730 tcg_gen_xori_tl(t1, t1, 31);
1731 t2 = tcg_const_tl(0xfffffffeull);
1732 tcg_gen_shl_tl(t2, t2, t1);
1733 gen_load_gpr(t1, rt);
1734 tcg_gen_and_tl(t1, t1, t2);
1736 tcg_gen_or_tl(t0, t0, t1);
1738 gen_store_gpr(t0, rt);
1742 save_cpu_state(ctx, 1);
1743 op_ld_ll(t0, t0, ctx);
1744 gen_store_gpr(t0, rt);
1748 (void)opn; /* avoid a compiler warning */
1749 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1754 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1755 int base, int16_t offset)
1757 const char *opn = "st";
1758 TCGv t0 = tcg_temp_new();
1759 TCGv t1 = tcg_temp_new();
1761 gen_base_offset_addr(ctx, t0, base, offset);
1762 gen_load_gpr(t1, rt);
1764 #if defined(TARGET_MIPS64)
1766 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1770 save_cpu_state(ctx, 1);
1771 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1775 save_cpu_state(ctx, 1);
1776 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1781 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1785 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1789 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1793 save_cpu_state(ctx, 1);
1794 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1798 save_cpu_state(ctx, 1);
1799 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1803 (void)opn; /* avoid a compiler warning */
1804 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1810 /* Store conditional */
1811 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1812 int base, int16_t offset)
1814 const char *opn = "st_cond";
1817 #ifdef CONFIG_USER_ONLY
1818 t0 = tcg_temp_local_new();
1819 t1 = tcg_temp_local_new();
1821 t0 = tcg_temp_new();
1822 t1 = tcg_temp_new();
1824 gen_base_offset_addr(ctx, t0, base, offset);
1825 gen_load_gpr(t1, rt);
1827 #if defined(TARGET_MIPS64)
1829 save_cpu_state(ctx, 1);
1830 op_st_scd(t1, t0, rt, ctx);
1835 save_cpu_state(ctx, 1);
1836 op_st_sc(t1, t0, rt, ctx);
1840 (void)opn; /* avoid a compiler warning */
1841 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1846 /* Load and store */
1847 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1848 int base, int16_t offset)
1850 const char *opn = "flt_ldst";
1851 TCGv t0 = tcg_temp_new();
1853 gen_base_offset_addr(ctx, t0, base, offset);
1854 /* Don't do NOP if destination is zero: we must perform the actual
1859 TCGv_i32 fp0 = tcg_temp_new_i32();
1861 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1862 tcg_gen_trunc_tl_i32(fp0, t0);
1863 gen_store_fpr32(fp0, ft);
1864 tcg_temp_free_i32(fp0);
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 TCGv t1 = tcg_temp_new();
1873 gen_load_fpr32(fp0, ft);
1874 tcg_gen_extu_i32_tl(t1, fp0);
1875 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1877 tcg_temp_free_i32(fp0);
1883 TCGv_i64 fp0 = tcg_temp_new_i64();
1885 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1886 gen_store_fpr64(ctx, fp0, ft);
1887 tcg_temp_free_i64(fp0);
1893 TCGv_i64 fp0 = tcg_temp_new_i64();
1895 gen_load_fpr64(ctx, fp0, ft);
1896 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1897 tcg_temp_free_i64(fp0);
1903 generate_exception(ctx, EXCP_RI);
1906 (void)opn; /* avoid a compiler warning */
1907 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1912 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1913 uint32_t op, int rt, int rs, int16_t imm)
1915 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1916 check_cp1_enabled(ctx);
1917 gen_flt_ldst(ctx, op, rt, rs, imm);
1919 generate_exception_err(ctx, EXCP_CpU, 1);
1923 /* Arithmetic with immediate operand */
1924 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1925 int rt, int rs, int16_t imm)
1927 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1928 const char *opn = "imm arith";
1930 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1931 /* If no destination, treat it as a NOP.
1932 For addi, we must generate the overflow exception when needed. */
1939 TCGv t0 = tcg_temp_local_new();
1940 TCGv t1 = tcg_temp_new();
1941 TCGv t2 = tcg_temp_new();
1942 int l1 = gen_new_label();
1944 gen_load_gpr(t1, rs);
1945 tcg_gen_addi_tl(t0, t1, uimm);
1946 tcg_gen_ext32s_tl(t0, t0);
1948 tcg_gen_xori_tl(t1, t1, ~uimm);
1949 tcg_gen_xori_tl(t2, t0, uimm);
1950 tcg_gen_and_tl(t1, t1, t2);
1952 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1954 /* operands of same sign, result different sign */
1955 generate_exception(ctx, EXCP_OVERFLOW);
1957 tcg_gen_ext32s_tl(t0, t0);
1958 gen_store_gpr(t0, rt);
1965 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1966 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1968 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1972 #if defined(TARGET_MIPS64)
1975 TCGv t0 = tcg_temp_local_new();
1976 TCGv t1 = tcg_temp_new();
1977 TCGv t2 = tcg_temp_new();
1978 int l1 = gen_new_label();
1980 gen_load_gpr(t1, rs);
1981 tcg_gen_addi_tl(t0, t1, uimm);
1983 tcg_gen_xori_tl(t1, t1, ~uimm);
1984 tcg_gen_xori_tl(t2, t0, uimm);
1985 tcg_gen_and_tl(t1, t1, t2);
1987 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1989 /* operands of same sign, result different sign */
1990 generate_exception(ctx, EXCP_OVERFLOW);
1992 gen_store_gpr(t0, rt);
1999 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2001 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2007 (void)opn; /* avoid a compiler warning */
2008 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2011 /* Logic with immediate operand */
2012 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2013 int rt, int rs, int16_t imm)
2016 const char *opn = "imm logic";
2019 /* If no destination, treat it as a NOP. */
2023 uimm = (uint16_t)imm;
2026 if (likely(rs != 0))
2027 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2029 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2034 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2036 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2040 if (likely(rs != 0))
2041 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2043 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2047 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2051 (void)opn; /* avoid a compiler warning */
2052 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2055 /* Set on less than with immediate operand */
2056 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2057 int rt, int rs, int16_t imm)
2059 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2060 const char *opn = "imm arith";
2064 /* If no destination, treat it as a NOP. */
2068 t0 = tcg_temp_new();
2069 gen_load_gpr(t0, rs);
2072 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2076 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2080 (void)opn; /* avoid a compiler warning */
2081 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2085 /* Shifts with immediate operand */
2086 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2087 int rt, int rs, int16_t imm)
2089 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2090 const char *opn = "imm shift";
2094 /* If no destination, treat it as a NOP. */
2099 t0 = tcg_temp_new();
2100 gen_load_gpr(t0, rs);
2103 tcg_gen_shli_tl(t0, t0, uimm);
2104 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2108 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2113 tcg_gen_ext32u_tl(t0, t0);
2114 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2116 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2122 TCGv_i32 t1 = tcg_temp_new_i32();
2124 tcg_gen_trunc_tl_i32(t1, t0);
2125 tcg_gen_rotri_i32(t1, t1, uimm);
2126 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2127 tcg_temp_free_i32(t1);
2129 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2133 #if defined(TARGET_MIPS64)
2135 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2139 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2143 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2148 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2150 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2155 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2159 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2163 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2167 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2172 (void)opn; /* avoid a compiler warning */
2173 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2178 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2179 int rd, int rs, int rt)
2181 const char *opn = "arith";
2183 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2184 && opc != OPC_DADD && opc != OPC_DSUB) {
2185 /* If no destination, treat it as a NOP.
2186 For add & sub, we must generate the overflow exception when needed. */
2194 TCGv t0 = tcg_temp_local_new();
2195 TCGv t1 = tcg_temp_new();
2196 TCGv t2 = tcg_temp_new();
2197 int l1 = gen_new_label();
2199 gen_load_gpr(t1, rs);
2200 gen_load_gpr(t2, rt);
2201 tcg_gen_add_tl(t0, t1, t2);
2202 tcg_gen_ext32s_tl(t0, t0);
2203 tcg_gen_xor_tl(t1, t1, t2);
2204 tcg_gen_xor_tl(t2, t0, t2);
2205 tcg_gen_andc_tl(t1, t2, t1);
2207 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2209 /* operands of same sign, result different sign */
2210 generate_exception(ctx, EXCP_OVERFLOW);
2212 gen_store_gpr(t0, rd);
2218 if (rs != 0 && rt != 0) {
2219 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2220 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2221 } else if (rs == 0 && rt != 0) {
2222 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2223 } else if (rs != 0 && rt == 0) {
2224 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2226 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2232 TCGv t0 = tcg_temp_local_new();
2233 TCGv t1 = tcg_temp_new();
2234 TCGv t2 = tcg_temp_new();
2235 int l1 = gen_new_label();
2237 gen_load_gpr(t1, rs);
2238 gen_load_gpr(t2, rt);
2239 tcg_gen_sub_tl(t0, t1, t2);
2240 tcg_gen_ext32s_tl(t0, t0);
2241 tcg_gen_xor_tl(t2, t1, t2);
2242 tcg_gen_xor_tl(t1, t0, t1);
2243 tcg_gen_and_tl(t1, t1, t2);
2245 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2247 /* operands of different sign, first operand and result different sign */
2248 generate_exception(ctx, EXCP_OVERFLOW);
2250 gen_store_gpr(t0, rd);
2256 if (rs != 0 && rt != 0) {
2257 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2258 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2259 } else if (rs == 0 && rt != 0) {
2260 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2261 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2262 } else if (rs != 0 && rt == 0) {
2263 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2265 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2269 #if defined(TARGET_MIPS64)
2272 TCGv t0 = tcg_temp_local_new();
2273 TCGv t1 = tcg_temp_new();
2274 TCGv t2 = tcg_temp_new();
2275 int l1 = gen_new_label();
2277 gen_load_gpr(t1, rs);
2278 gen_load_gpr(t2, rt);
2279 tcg_gen_add_tl(t0, t1, t2);
2280 tcg_gen_xor_tl(t1, t1, t2);
2281 tcg_gen_xor_tl(t2, t0, t2);
2282 tcg_gen_andc_tl(t1, t2, t1);
2284 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2286 /* operands of same sign, result different sign */
2287 generate_exception(ctx, EXCP_OVERFLOW);
2289 gen_store_gpr(t0, rd);
2295 if (rs != 0 && rt != 0) {
2296 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2297 } else if (rs == 0 && rt != 0) {
2298 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2299 } else if (rs != 0 && rt == 0) {
2300 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2302 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2308 TCGv t0 = tcg_temp_local_new();
2309 TCGv t1 = tcg_temp_new();
2310 TCGv t2 = tcg_temp_new();
2311 int l1 = gen_new_label();
2313 gen_load_gpr(t1, rs);
2314 gen_load_gpr(t2, rt);
2315 tcg_gen_sub_tl(t0, t1, t2);
2316 tcg_gen_xor_tl(t2, t1, t2);
2317 tcg_gen_xor_tl(t1, t0, t1);
2318 tcg_gen_and_tl(t1, t1, t2);
2320 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2322 /* operands of different sign, first operand and result different sign */
2323 generate_exception(ctx, EXCP_OVERFLOW);
2325 gen_store_gpr(t0, rd);
2331 if (rs != 0 && rt != 0) {
2332 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2333 } else if (rs == 0 && rt != 0) {
2334 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2335 } else if (rs != 0 && rt == 0) {
2336 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2338 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2344 if (likely(rs != 0 && rt != 0)) {
2345 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2346 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2348 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2353 (void)opn; /* avoid a compiler warning */
2354 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2357 /* Conditional move */
2358 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2359 int rd, int rs, int rt)
2361 const char *opn = "cond move";
2365 /* If no destination, treat it as a NOP. */
2370 t0 = tcg_temp_new();
2371 gen_load_gpr(t0, rt);
2372 t1 = tcg_const_tl(0);
2373 t2 = tcg_temp_new();
2374 gen_load_gpr(t2, rs);
2377 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2381 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2389 (void)opn; /* avoid a compiler warning */
2390 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2394 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2395 int rd, int rs, int rt)
2397 const char *opn = "logic";
2400 /* If no destination, treat it as a NOP. */
2407 if (likely(rs != 0 && rt != 0)) {
2408 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2410 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2415 if (rs != 0 && rt != 0) {
2416 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2417 } else if (rs == 0 && rt != 0) {
2418 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2419 } else if (rs != 0 && rt == 0) {
2420 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2422 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2427 if (likely(rs != 0 && rt != 0)) {
2428 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2429 } else if (rs == 0 && rt != 0) {
2430 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2431 } else if (rs != 0 && rt == 0) {
2432 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2434 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2439 if (likely(rs != 0 && rt != 0)) {
2440 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2441 } else if (rs == 0 && rt != 0) {
2442 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2443 } else if (rs != 0 && rt == 0) {
2444 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2446 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2451 (void)opn; /* avoid a compiler warning */
2452 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2455 /* Set on lower than */
2456 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2457 int rd, int rs, int rt)
2459 const char *opn = "slt";
2463 /* If no destination, treat it as a NOP. */
2468 t0 = tcg_temp_new();
2469 t1 = tcg_temp_new();
2470 gen_load_gpr(t0, rs);
2471 gen_load_gpr(t1, rt);
2474 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2478 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2482 (void)opn; /* avoid a compiler warning */
2483 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2489 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2490 int rd, int rs, int rt)
2492 const char *opn = "shifts";
2496 /* If no destination, treat it as a NOP.
2497 For add & sub, we must generate the overflow exception when needed. */
2502 t0 = tcg_temp_new();
2503 t1 = tcg_temp_new();
2504 gen_load_gpr(t0, rs);
2505 gen_load_gpr(t1, rt);
2508 tcg_gen_andi_tl(t0, t0, 0x1f);
2509 tcg_gen_shl_tl(t0, t1, t0);
2510 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2514 tcg_gen_andi_tl(t0, t0, 0x1f);
2515 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2519 tcg_gen_ext32u_tl(t1, t1);
2520 tcg_gen_andi_tl(t0, t0, 0x1f);
2521 tcg_gen_shr_tl(t0, t1, t0);
2522 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2527 TCGv_i32 t2 = tcg_temp_new_i32();
2528 TCGv_i32 t3 = tcg_temp_new_i32();
2530 tcg_gen_trunc_tl_i32(t2, t0);
2531 tcg_gen_trunc_tl_i32(t3, t1);
2532 tcg_gen_andi_i32(t2, t2, 0x1f);
2533 tcg_gen_rotr_i32(t2, t3, t2);
2534 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2535 tcg_temp_free_i32(t2);
2536 tcg_temp_free_i32(t3);
2540 #if defined(TARGET_MIPS64)
2542 tcg_gen_andi_tl(t0, t0, 0x3f);
2543 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2547 tcg_gen_andi_tl(t0, t0, 0x3f);
2548 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2552 tcg_gen_andi_tl(t0, t0, 0x3f);
2553 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2557 tcg_gen_andi_tl(t0, t0, 0x3f);
2558 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2563 (void)opn; /* avoid a compiler warning */
2564 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2569 /* Arithmetic on HI/LO registers */
2570 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2572 const char *opn = "hilo";
2575 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2581 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2582 acc = ((ctx->opcode) >> 21) & 0x03;
2584 acc = ((ctx->opcode) >> 11) & 0x03;
2593 #if defined(TARGET_MIPS64)
2595 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2599 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2604 #if defined(TARGET_MIPS64)
2606 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2610 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2616 #if defined(TARGET_MIPS64)
2618 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2622 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2625 tcg_gen_movi_tl(cpu_HI[acc], 0);
2631 #if defined(TARGET_MIPS64)
2633 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2637 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2640 tcg_gen_movi_tl(cpu_LO[acc], 0);
2645 (void)opn; /* avoid a compiler warning */
2646 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2649 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2652 const char *opn = "mul/div";
2659 #if defined(TARGET_MIPS64)
2663 t0 = tcg_temp_local_new();
2664 t1 = tcg_temp_local_new();
2667 t0 = tcg_temp_new();
2668 t1 = tcg_temp_new();
2672 gen_load_gpr(t0, rs);
2673 gen_load_gpr(t1, rt);
2677 int l1 = gen_new_label();
2678 int l2 = gen_new_label();
2680 tcg_gen_ext32s_tl(t0, t0);
2681 tcg_gen_ext32s_tl(t1, t1);
2682 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2683 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2684 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2686 tcg_gen_mov_tl(cpu_LO[0], t0);
2687 tcg_gen_movi_tl(cpu_HI[0], 0);
2690 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2691 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2692 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2693 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2700 int l1 = gen_new_label();
2702 tcg_gen_ext32u_tl(t0, t0);
2703 tcg_gen_ext32u_tl(t1, t1);
2704 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2705 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2706 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2707 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2708 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2715 TCGv_i64 t2 = tcg_temp_new_i64();
2716 TCGv_i64 t3 = tcg_temp_new_i64();
2717 acc = ((ctx->opcode) >> 11) & 0x03;
2722 tcg_gen_ext_tl_i64(t2, t0);
2723 tcg_gen_ext_tl_i64(t3, t1);
2724 tcg_gen_mul_i64(t2, t2, t3);
2725 tcg_temp_free_i64(t3);
2726 tcg_gen_trunc_i64_tl(t0, t2);
2727 tcg_gen_shri_i64(t2, t2, 32);
2728 tcg_gen_trunc_i64_tl(t1, t2);
2729 tcg_temp_free_i64(t2);
2730 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2731 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2737 TCGv_i64 t2 = tcg_temp_new_i64();
2738 TCGv_i64 t3 = tcg_temp_new_i64();
2739 acc = ((ctx->opcode) >> 11) & 0x03;
2744 tcg_gen_ext32u_tl(t0, t0);
2745 tcg_gen_ext32u_tl(t1, t1);
2746 tcg_gen_extu_tl_i64(t2, t0);
2747 tcg_gen_extu_tl_i64(t3, t1);
2748 tcg_gen_mul_i64(t2, t2, t3);
2749 tcg_temp_free_i64(t3);
2750 tcg_gen_trunc_i64_tl(t0, t2);
2751 tcg_gen_shri_i64(t2, t2, 32);
2752 tcg_gen_trunc_i64_tl(t1, t2);
2753 tcg_temp_free_i64(t2);
2754 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2755 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2759 #if defined(TARGET_MIPS64)
2762 int l1 = gen_new_label();
2763 int l2 = gen_new_label();
2765 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2766 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2767 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2768 tcg_gen_mov_tl(cpu_LO[0], t0);
2769 tcg_gen_movi_tl(cpu_HI[0], 0);
2772 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2773 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2780 int l1 = gen_new_label();
2782 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2783 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2784 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2790 gen_helper_dmult(cpu_env, t0, t1);
2794 gen_helper_dmultu(cpu_env, t0, t1);
2800 TCGv_i64 t2 = tcg_temp_new_i64();
2801 TCGv_i64 t3 = tcg_temp_new_i64();
2802 acc = ((ctx->opcode) >> 11) & 0x03;
2807 tcg_gen_ext_tl_i64(t2, t0);
2808 tcg_gen_ext_tl_i64(t3, t1);
2809 tcg_gen_mul_i64(t2, t2, t3);
2810 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2811 tcg_gen_add_i64(t2, t2, t3);
2812 tcg_temp_free_i64(t3);
2813 tcg_gen_trunc_i64_tl(t0, t2);
2814 tcg_gen_shri_i64(t2, t2, 32);
2815 tcg_gen_trunc_i64_tl(t1, t2);
2816 tcg_temp_free_i64(t2);
2817 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2818 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2824 TCGv_i64 t2 = tcg_temp_new_i64();
2825 TCGv_i64 t3 = tcg_temp_new_i64();
2826 acc = ((ctx->opcode) >> 11) & 0x03;
2831 tcg_gen_ext32u_tl(t0, t0);
2832 tcg_gen_ext32u_tl(t1, t1);
2833 tcg_gen_extu_tl_i64(t2, t0);
2834 tcg_gen_extu_tl_i64(t3, t1);
2835 tcg_gen_mul_i64(t2, t2, t3);
2836 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2837 tcg_gen_add_i64(t2, t2, t3);
2838 tcg_temp_free_i64(t3);
2839 tcg_gen_trunc_i64_tl(t0, t2);
2840 tcg_gen_shri_i64(t2, t2, 32);
2841 tcg_gen_trunc_i64_tl(t1, t2);
2842 tcg_temp_free_i64(t2);
2843 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2844 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2850 TCGv_i64 t2 = tcg_temp_new_i64();
2851 TCGv_i64 t3 = tcg_temp_new_i64();
2852 acc = ((ctx->opcode) >> 11) & 0x03;
2857 tcg_gen_ext_tl_i64(t2, t0);
2858 tcg_gen_ext_tl_i64(t3, t1);
2859 tcg_gen_mul_i64(t2, t2, t3);
2860 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2861 tcg_gen_sub_i64(t2, t3, t2);
2862 tcg_temp_free_i64(t3);
2863 tcg_gen_trunc_i64_tl(t0, t2);
2864 tcg_gen_shri_i64(t2, t2, 32);
2865 tcg_gen_trunc_i64_tl(t1, t2);
2866 tcg_temp_free_i64(t2);
2867 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2868 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2874 TCGv_i64 t2 = tcg_temp_new_i64();
2875 TCGv_i64 t3 = tcg_temp_new_i64();
2876 acc = ((ctx->opcode) >> 11) & 0x03;
2881 tcg_gen_ext32u_tl(t0, t0);
2882 tcg_gen_ext32u_tl(t1, t1);
2883 tcg_gen_extu_tl_i64(t2, t0);
2884 tcg_gen_extu_tl_i64(t3, t1);
2885 tcg_gen_mul_i64(t2, t2, t3);
2886 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2887 tcg_gen_sub_i64(t2, t3, t2);
2888 tcg_temp_free_i64(t3);
2889 tcg_gen_trunc_i64_tl(t0, t2);
2890 tcg_gen_shri_i64(t2, t2, 32);
2891 tcg_gen_trunc_i64_tl(t1, t2);
2892 tcg_temp_free_i64(t2);
2893 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2894 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2900 generate_exception(ctx, EXCP_RI);
2903 (void)opn; /* avoid a compiler warning */
2904 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2910 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2911 int rd, int rs, int rt)
2913 const char *opn = "mul vr54xx";
2914 TCGv t0 = tcg_temp_new();
2915 TCGv t1 = tcg_temp_new();
2917 gen_load_gpr(t0, rs);
2918 gen_load_gpr(t1, rt);
2921 case OPC_VR54XX_MULS:
2922 gen_helper_muls(t0, cpu_env, t0, t1);
2925 case OPC_VR54XX_MULSU:
2926 gen_helper_mulsu(t0, cpu_env, t0, t1);
2929 case OPC_VR54XX_MACC:
2930 gen_helper_macc(t0, cpu_env, t0, t1);
2933 case OPC_VR54XX_MACCU:
2934 gen_helper_maccu(t0, cpu_env, t0, t1);
2937 case OPC_VR54XX_MSAC:
2938 gen_helper_msac(t0, cpu_env, t0, t1);
2941 case OPC_VR54XX_MSACU:
2942 gen_helper_msacu(t0, cpu_env, t0, t1);
2945 case OPC_VR54XX_MULHI:
2946 gen_helper_mulhi(t0, cpu_env, t0, t1);
2949 case OPC_VR54XX_MULHIU:
2950 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2953 case OPC_VR54XX_MULSHI:
2954 gen_helper_mulshi(t0, cpu_env, t0, t1);
2957 case OPC_VR54XX_MULSHIU:
2958 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2961 case OPC_VR54XX_MACCHI:
2962 gen_helper_macchi(t0, cpu_env, t0, t1);
2965 case OPC_VR54XX_MACCHIU:
2966 gen_helper_macchiu(t0, cpu_env, t0, t1);
2969 case OPC_VR54XX_MSACHI:
2970 gen_helper_msachi(t0, cpu_env, t0, t1);
2973 case OPC_VR54XX_MSACHIU:
2974 gen_helper_msachiu(t0, cpu_env, t0, t1);
2978 MIPS_INVAL("mul vr54xx");
2979 generate_exception(ctx, EXCP_RI);
2982 gen_store_gpr(t0, rd);
2983 (void)opn; /* avoid a compiler warning */
2984 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2991 static void gen_cl (DisasContext *ctx, uint32_t opc,
2994 const char *opn = "CLx";
3002 t0 = tcg_temp_new();
3003 gen_load_gpr(t0, rs);
3006 gen_helper_clo(cpu_gpr[rd], t0);
3010 gen_helper_clz(cpu_gpr[rd], t0);
3013 #if defined(TARGET_MIPS64)
3015 gen_helper_dclo(cpu_gpr[rd], t0);
3019 gen_helper_dclz(cpu_gpr[rd], t0);
3024 (void)opn; /* avoid a compiler warning */
3025 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3029 /* Godson integer instructions */
3030 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3031 int rd, int rs, int rt)
3033 const char *opn = "loongson";
3045 case OPC_MULTU_G_2E:
3046 case OPC_MULTU_G_2F:
3047 #if defined(TARGET_MIPS64)
3048 case OPC_DMULT_G_2E:
3049 case OPC_DMULT_G_2F:
3050 case OPC_DMULTU_G_2E:
3051 case OPC_DMULTU_G_2F:
3053 t0 = tcg_temp_new();
3054 t1 = tcg_temp_new();
3057 t0 = tcg_temp_local_new();
3058 t1 = tcg_temp_local_new();
3062 gen_load_gpr(t0, rs);
3063 gen_load_gpr(t1, rt);
3068 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3069 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3072 case OPC_MULTU_G_2E:
3073 case OPC_MULTU_G_2F:
3074 tcg_gen_ext32u_tl(t0, t0);
3075 tcg_gen_ext32u_tl(t1, t1);
3076 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3077 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3083 int l1 = gen_new_label();
3084 int l2 = gen_new_label();
3085 int l3 = gen_new_label();
3086 tcg_gen_ext32s_tl(t0, t0);
3087 tcg_gen_ext32s_tl(t1, t1);
3088 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3089 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3092 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3093 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3094 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3097 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3098 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3106 int l1 = gen_new_label();
3107 int l2 = gen_new_label();
3108 tcg_gen_ext32u_tl(t0, t0);
3109 tcg_gen_ext32u_tl(t1, t1);
3110 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3111 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3114 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3115 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3123 int l1 = gen_new_label();
3124 int l2 = gen_new_label();
3125 int l3 = gen_new_label();
3126 tcg_gen_ext32u_tl(t0, t0);
3127 tcg_gen_ext32u_tl(t1, t1);
3128 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3129 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3130 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3132 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3135 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3136 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3144 int l1 = gen_new_label();
3145 int l2 = gen_new_label();
3146 tcg_gen_ext32u_tl(t0, t0);
3147 tcg_gen_ext32u_tl(t1, t1);
3148 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3149 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3152 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3153 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3158 #if defined(TARGET_MIPS64)
3159 case OPC_DMULT_G_2E:
3160 case OPC_DMULT_G_2F:
3161 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3164 case OPC_DMULTU_G_2E:
3165 case OPC_DMULTU_G_2F:
3166 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3172 int l1 = gen_new_label();
3173 int l2 = gen_new_label();
3174 int l3 = gen_new_label();
3175 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3176 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3179 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3180 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3181 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3184 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3189 case OPC_DDIVU_G_2E:
3190 case OPC_DDIVU_G_2F:
3192 int l1 = gen_new_label();
3193 int l2 = gen_new_label();
3194 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3195 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3198 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3206 int l1 = gen_new_label();
3207 int l2 = gen_new_label();
3208 int l3 = gen_new_label();
3209 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3210 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3211 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3213 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3216 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3221 case OPC_DMODU_G_2E:
3222 case OPC_DMODU_G_2F:
3224 int l1 = gen_new_label();
3225 int l2 = gen_new_label();
3226 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3227 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3230 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3238 (void)opn; /* avoid a compiler warning */
3239 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3244 /* Loongson multimedia instructions */
3245 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3247 const char *opn = "loongson_cp2";
3248 uint32_t opc, shift_max;
3251 opc = MASK_LMI(ctx->opcode);
3257 t0 = tcg_temp_local_new_i64();
3258 t1 = tcg_temp_local_new_i64();
3261 t0 = tcg_temp_new_i64();
3262 t1 = tcg_temp_new_i64();
3266 gen_load_fpr64(ctx, t0, rs);
3267 gen_load_fpr64(ctx, t1, rt);
3269 #define LMI_HELPER(UP, LO) \
3270 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3271 #define LMI_HELPER_1(UP, LO) \
3272 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3273 #define LMI_DIRECT(UP, LO, OP) \
3274 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3277 LMI_HELPER(PADDSH, paddsh);
3278 LMI_HELPER(PADDUSH, paddush);
3279 LMI_HELPER(PADDH, paddh);
3280 LMI_HELPER(PADDW, paddw);
3281 LMI_HELPER(PADDSB, paddsb);
3282 LMI_HELPER(PADDUSB, paddusb);
3283 LMI_HELPER(PADDB, paddb);
3285 LMI_HELPER(PSUBSH, psubsh);
3286 LMI_HELPER(PSUBUSH, psubush);
3287 LMI_HELPER(PSUBH, psubh);
3288 LMI_HELPER(PSUBW, psubw);
3289 LMI_HELPER(PSUBSB, psubsb);
3290 LMI_HELPER(PSUBUSB, psubusb);
3291 LMI_HELPER(PSUBB, psubb);
3293 LMI_HELPER(PSHUFH, pshufh);
3294 LMI_HELPER(PACKSSWH, packsswh);
3295 LMI_HELPER(PACKSSHB, packsshb);
3296 LMI_HELPER(PACKUSHB, packushb);
3298 LMI_HELPER(PUNPCKLHW, punpcklhw);
3299 LMI_HELPER(PUNPCKHHW, punpckhhw);
3300 LMI_HELPER(PUNPCKLBH, punpcklbh);
3301 LMI_HELPER(PUNPCKHBH, punpckhbh);
3302 LMI_HELPER(PUNPCKLWD, punpcklwd);
3303 LMI_HELPER(PUNPCKHWD, punpckhwd);
3305 LMI_HELPER(PAVGH, pavgh);
3306 LMI_HELPER(PAVGB, pavgb);
3307 LMI_HELPER(PMAXSH, pmaxsh);
3308 LMI_HELPER(PMINSH, pminsh);
3309 LMI_HELPER(PMAXUB, pmaxub);
3310 LMI_HELPER(PMINUB, pminub);
3312 LMI_HELPER(PCMPEQW, pcmpeqw);
3313 LMI_HELPER(PCMPGTW, pcmpgtw);
3314 LMI_HELPER(PCMPEQH, pcmpeqh);
3315 LMI_HELPER(PCMPGTH, pcmpgth);
3316 LMI_HELPER(PCMPEQB, pcmpeqb);
3317 LMI_HELPER(PCMPGTB, pcmpgtb);
3319 LMI_HELPER(PSLLW, psllw);
3320 LMI_HELPER(PSLLH, psllh);
3321 LMI_HELPER(PSRLW, psrlw);
3322 LMI_HELPER(PSRLH, psrlh);
3323 LMI_HELPER(PSRAW, psraw);
3324 LMI_HELPER(PSRAH, psrah);
3326 LMI_HELPER(PMULLH, pmullh);
3327 LMI_HELPER(PMULHH, pmulhh);
3328 LMI_HELPER(PMULHUH, pmulhuh);
3329 LMI_HELPER(PMADDHW, pmaddhw);
3331 LMI_HELPER(PASUBUB, pasubub);
3332 LMI_HELPER_1(BIADD, biadd);
3333 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3335 LMI_DIRECT(PADDD, paddd, add);
3336 LMI_DIRECT(PSUBD, psubd, sub);
3337 LMI_DIRECT(XOR_CP2, xor, xor);
3338 LMI_DIRECT(NOR_CP2, nor, nor);
3339 LMI_DIRECT(AND_CP2, and, and);
3340 LMI_DIRECT(PANDN, pandn, andc);
3341 LMI_DIRECT(OR, or, or);
3344 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3348 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3352 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3356 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3361 tcg_gen_andi_i64(t1, t1, 3);
3362 tcg_gen_shli_i64(t1, t1, 4);
3363 tcg_gen_shr_i64(t0, t0, t1);
3364 tcg_gen_ext16u_i64(t0, t0);
3369 tcg_gen_add_i64(t0, t0, t1);
3370 tcg_gen_ext32s_i64(t0, t0);
3374 tcg_gen_sub_i64(t0, t0, t1);
3375 tcg_gen_ext32s_i64(t0, t0);
3404 /* Make sure shift count isn't TCG undefined behaviour. */
3405 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3410 tcg_gen_shl_i64(t0, t0, t1);
3414 /* Since SRA is UndefinedResult without sign-extended inputs,
3415 we can treat SRA and DSRA the same. */
3416 tcg_gen_sar_i64(t0, t0, t1);
3419 /* We want to shift in zeros for SRL; zero-extend first. */
3420 tcg_gen_ext32u_i64(t0, t0);
3423 tcg_gen_shr_i64(t0, t0, t1);
3427 if (shift_max == 32) {
3428 tcg_gen_ext32s_i64(t0, t0);
3431 /* Shifts larger than MAX produce zero. */
3432 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3433 tcg_gen_neg_i64(t1, t1);
3434 tcg_gen_and_i64(t0, t0, t1);
3440 TCGv_i64 t2 = tcg_temp_new_i64();
3441 int lab = gen_new_label();
3443 tcg_gen_mov_i64(t2, t0);
3444 tcg_gen_add_i64(t0, t1, t2);
3445 if (opc == OPC_ADD_CP2) {
3446 tcg_gen_ext32s_i64(t0, t0);
3448 tcg_gen_xor_i64(t1, t1, t2);
3449 tcg_gen_xor_i64(t2, t2, t0);
3450 tcg_gen_andc_i64(t1, t2, t1);
3451 tcg_temp_free_i64(t2);
3452 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3453 generate_exception(ctx, EXCP_OVERFLOW);
3456 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3463 TCGv_i64 t2 = tcg_temp_new_i64();
3464 int lab = gen_new_label();
3466 tcg_gen_mov_i64(t2, t0);
3467 tcg_gen_sub_i64(t0, t1, t2);
3468 if (opc == OPC_SUB_CP2) {
3469 tcg_gen_ext32s_i64(t0, t0);
3471 tcg_gen_xor_i64(t1, t1, t2);
3472 tcg_gen_xor_i64(t2, t2, t0);
3473 tcg_gen_and_i64(t1, t1, t2);
3474 tcg_temp_free_i64(t2);
3475 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3476 generate_exception(ctx, EXCP_OVERFLOW);
3479 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3484 tcg_gen_ext32u_i64(t0, t0);
3485 tcg_gen_ext32u_i64(t1, t1);
3486 tcg_gen_mul_i64(t0, t0, t1);
3496 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3497 FD field is the CC field? */
3500 generate_exception(ctx, EXCP_RI);
3507 gen_store_fpr64(ctx, t0, rd);
3509 (void)opn; /* avoid a compiler warning */
3510 MIPS_DEBUG("%s %s, %s, %s", opn,
3511 fregnames[rd], fregnames[rs], fregnames[rt]);
3512 tcg_temp_free_i64(t0);
3513 tcg_temp_free_i64(t1);
3517 static void gen_trap (DisasContext *ctx, uint32_t opc,
3518 int rs, int rt, int16_t imm)
3521 TCGv t0 = tcg_temp_new();
3522 TCGv t1 = tcg_temp_new();
3525 /* Load needed operands */
3533 /* Compare two registers */
3535 gen_load_gpr(t0, rs);
3536 gen_load_gpr(t1, rt);
3546 /* Compare register to immediate */
3547 if (rs != 0 || imm != 0) {
3548 gen_load_gpr(t0, rs);
3549 tcg_gen_movi_tl(t1, (int32_t)imm);
3556 case OPC_TEQ: /* rs == rs */
3557 case OPC_TEQI: /* r0 == 0 */
3558 case OPC_TGE: /* rs >= rs */
3559 case OPC_TGEI: /* r0 >= 0 */
3560 case OPC_TGEU: /* rs >= rs unsigned */
3561 case OPC_TGEIU: /* r0 >= 0 unsigned */
3563 generate_exception(ctx, EXCP_TRAP);
3565 case OPC_TLT: /* rs < rs */
3566 case OPC_TLTI: /* r0 < 0 */
3567 case OPC_TLTU: /* rs < rs unsigned */
3568 case OPC_TLTIU: /* r0 < 0 unsigned */
3569 case OPC_TNE: /* rs != rs */
3570 case OPC_TNEI: /* r0 != 0 */
3571 /* Never trap: treat as NOP. */
3575 int l1 = gen_new_label();
3580 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3584 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3588 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3592 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3596 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3600 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3603 generate_exception(ctx, EXCP_TRAP);
3610 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3612 TranslationBlock *tb;
3614 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3615 likely(!ctx->singlestep_enabled)) {
3618 tcg_gen_exit_tb((tcg_target_long)tb + n);
3621 if (ctx->singlestep_enabled) {
3622 save_cpu_state(ctx, 0);
3623 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3629 /* Branches (before delay slot) */
3630 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3632 int rs, int rt, int32_t offset)
3634 target_ulong btgt = -1;
3636 int bcond_compute = 0;
3637 TCGv t0 = tcg_temp_new();
3638 TCGv t1 = tcg_temp_new();
3640 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3641 #ifdef MIPS_DEBUG_DISAS
3642 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3644 generate_exception(ctx, EXCP_RI);
3648 /* Load needed operands */
3654 /* Compare two registers */
3656 gen_load_gpr(t0, rs);
3657 gen_load_gpr(t1, rt);
3660 btgt = ctx->pc + insn_bytes + offset;
3676 /* Compare to zero */
3678 gen_load_gpr(t0, rs);
3681 btgt = ctx->pc + insn_bytes + offset;
3684 #if defined(TARGET_MIPS64)
3686 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3688 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3691 btgt = ctx->pc + insn_bytes + offset;
3698 /* Jump to immediate */
3699 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3705 /* Jump to register */
3706 if (offset != 0 && offset != 16) {
3707 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3708 others are reserved. */
3709 MIPS_INVAL("jump hint");
3710 generate_exception(ctx, EXCP_RI);
3713 gen_load_gpr(btarget, rs);
3716 MIPS_INVAL("branch/jump");
3717 generate_exception(ctx, EXCP_RI);
3720 if (bcond_compute == 0) {
3721 /* No condition to be computed */
3723 case OPC_BEQ: /* rx == rx */
3724 case OPC_BEQL: /* rx == rx likely */
3725 case OPC_BGEZ: /* 0 >= 0 */
3726 case OPC_BGEZL: /* 0 >= 0 likely */
3727 case OPC_BLEZ: /* 0 <= 0 */
3728 case OPC_BLEZL: /* 0 <= 0 likely */
3730 ctx->hflags |= MIPS_HFLAG_B;
3731 MIPS_DEBUG("balways");
3734 case OPC_BGEZAL: /* 0 >= 0 */
3735 case OPC_BGEZALL: /* 0 >= 0 likely */
3736 ctx->hflags |= (opc == OPC_BGEZALS
3738 : MIPS_HFLAG_BDS32);
3739 /* Always take and link */
3741 ctx->hflags |= MIPS_HFLAG_B;
3742 MIPS_DEBUG("balways and link");
3744 case OPC_BNE: /* rx != rx */
3745 case OPC_BGTZ: /* 0 > 0 */
3746 case OPC_BLTZ: /* 0 < 0 */
3748 MIPS_DEBUG("bnever (NOP)");
3751 case OPC_BLTZAL: /* 0 < 0 */
3752 ctx->hflags |= (opc == OPC_BLTZALS
3754 : MIPS_HFLAG_BDS32);
3755 /* Handle as an unconditional branch to get correct delay
3758 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3759 ctx->hflags |= MIPS_HFLAG_B;
3760 MIPS_DEBUG("bnever and link");
3762 case OPC_BLTZALL: /* 0 < 0 likely */
3763 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3764 /* Skip the instruction in the delay slot */
3765 MIPS_DEBUG("bnever, link and skip");
3768 case OPC_BNEL: /* rx != rx likely */
3769 case OPC_BGTZL: /* 0 > 0 likely */
3770 case OPC_BLTZL: /* 0 < 0 likely */
3771 /* Skip the instruction in the delay slot */
3772 MIPS_DEBUG("bnever and skip");
3776 ctx->hflags |= MIPS_HFLAG_B;
3777 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3781 ctx->hflags |= MIPS_HFLAG_BX;
3786 ctx->hflags |= MIPS_HFLAG_B;
3787 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3789 : MIPS_HFLAG_BDS32);
3790 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3793 ctx->hflags |= MIPS_HFLAG_BR;
3794 if (insn_bytes == 4)
3795 ctx->hflags |= MIPS_HFLAG_BDS32;
3796 MIPS_DEBUG("jr %s", regnames[rs]);
3802 ctx->hflags |= MIPS_HFLAG_BR;
3803 ctx->hflags |= (opc == OPC_JALRS
3805 : MIPS_HFLAG_BDS32);
3806 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3809 MIPS_INVAL("branch/jump");
3810 generate_exception(ctx, EXCP_RI);
3816 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3817 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3818 regnames[rs], regnames[rt], btgt);
3821 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3822 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3823 regnames[rs], regnames[rt], btgt);
3826 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3827 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3828 regnames[rs], regnames[rt], btgt);
3831 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3832 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3833 regnames[rs], regnames[rt], btgt);
3836 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3837 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3840 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3841 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3845 ctx->hflags |= (opc == OPC_BGEZALS
3847 : MIPS_HFLAG_BDS32);
3848 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3849 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3853 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3855 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3858 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3859 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3862 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3863 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3866 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3867 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3870 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3871 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3874 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3875 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3878 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3879 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3882 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3883 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3885 #if defined(TARGET_MIPS64)
3887 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3888 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3893 ctx->hflags |= (opc == OPC_BLTZALS
3895 : MIPS_HFLAG_BDS32);
3896 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3898 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3900 ctx->hflags |= MIPS_HFLAG_BC;
3903 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3905 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3907 ctx->hflags |= MIPS_HFLAG_BL;
3910 MIPS_INVAL("conditional branch/jump");
3911 generate_exception(ctx, EXCP_RI);
3915 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3916 blink, ctx->hflags, btgt);
3918 ctx->btarget = btgt;
3920 int post_delay = insn_bytes;
3921 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3923 if (opc != OPC_JALRC)
3924 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3926 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3930 if (insn_bytes == 2)
3931 ctx->hflags |= MIPS_HFLAG_B16;
3936 /* special3 bitfield operations */
3937 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3938 int rs, int lsb, int msb)
3940 TCGv t0 = tcg_temp_new();
3941 TCGv t1 = tcg_temp_new();
3944 gen_load_gpr(t1, rs);
3949 tcg_gen_shri_tl(t0, t1, lsb);
3951 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3953 tcg_gen_ext32s_tl(t0, t0);
3956 #if defined(TARGET_MIPS64)
3958 tcg_gen_shri_tl(t0, t1, lsb);
3960 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3964 tcg_gen_shri_tl(t0, t1, lsb + 32);
3965 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3968 tcg_gen_shri_tl(t0, t1, lsb);
3969 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3975 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3976 gen_load_gpr(t0, rt);
3977 tcg_gen_andi_tl(t0, t0, ~mask);
3978 tcg_gen_shli_tl(t1, t1, lsb);
3979 tcg_gen_andi_tl(t1, t1, mask);
3980 tcg_gen_or_tl(t0, t0, t1);
3981 tcg_gen_ext32s_tl(t0, t0);
3983 #if defined(TARGET_MIPS64)
3987 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3988 gen_load_gpr(t0, rt);
3989 tcg_gen_andi_tl(t0, t0, ~mask);
3990 tcg_gen_shli_tl(t1, t1, lsb);
3991 tcg_gen_andi_tl(t1, t1, mask);
3992 tcg_gen_or_tl(t0, t0, t1);
3997 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3998 gen_load_gpr(t0, rt);
3999 tcg_gen_andi_tl(t0, t0, ~mask);
4000 tcg_gen_shli_tl(t1, t1, lsb + 32);
4001 tcg_gen_andi_tl(t1, t1, mask);
4002 tcg_gen_or_tl(t0, t0, t1);
4007 gen_load_gpr(t0, rt);
4008 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
4009 gen_load_gpr(t0, rt);
4010 tcg_gen_andi_tl(t0, t0, ~mask);
4011 tcg_gen_shli_tl(t1, t1, lsb);
4012 tcg_gen_andi_tl(t1, t1, mask);
4013 tcg_gen_or_tl(t0, t0, t1);
4018 MIPS_INVAL("bitops");
4019 generate_exception(ctx, EXCP_RI);
4024 gen_store_gpr(t0, rt);
4029 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4034 /* If no destination, treat it as a NOP. */
4039 t0 = tcg_temp_new();
4040 gen_load_gpr(t0, rt);
4044 TCGv t1 = tcg_temp_new();
4046 tcg_gen_shri_tl(t1, t0, 8);
4047 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4048 tcg_gen_shli_tl(t0, t0, 8);
4049 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4050 tcg_gen_or_tl(t0, t0, t1);
4052 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4056 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4059 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4061 #if defined(TARGET_MIPS64)
4064 TCGv t1 = tcg_temp_new();
4066 tcg_gen_shri_tl(t1, t0, 8);
4067 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4068 tcg_gen_shli_tl(t0, t0, 8);
4069 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4070 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4076 TCGv t1 = tcg_temp_new();
4078 tcg_gen_shri_tl(t1, t0, 16);
4079 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4080 tcg_gen_shli_tl(t0, t0, 16);
4081 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4082 tcg_gen_or_tl(t0, t0, t1);
4083 tcg_gen_shri_tl(t1, t0, 32);
4084 tcg_gen_shli_tl(t0, t0, 32);
4085 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4091 MIPS_INVAL("bsfhl");
4092 generate_exception(ctx, EXCP_RI);
4099 #ifndef CONFIG_USER_ONLY
4100 /* CP0 (MMU and control) */
4101 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4103 TCGv_i32 t0 = tcg_temp_new_i32();
4105 tcg_gen_ld_i32(t0, cpu_env, off);
4106 tcg_gen_ext_i32_tl(arg, t0);
4107 tcg_temp_free_i32(t0);
4110 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4112 tcg_gen_ld_tl(arg, cpu_env, off);
4113 tcg_gen_ext32s_tl(arg, arg);
4116 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4118 TCGv_i32 t0 = tcg_temp_new_i32();
4120 tcg_gen_trunc_tl_i32(t0, arg);
4121 tcg_gen_st_i32(t0, cpu_env, off);
4122 tcg_temp_free_i32(t0);
4125 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4127 tcg_gen_ext32s_tl(arg, arg);
4128 tcg_gen_st_tl(arg, cpu_env, off);
4131 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4133 const char *rn = "invalid";
4136 check_insn(env, ctx, ISA_MIPS32);
4142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4146 check_insn(env, ctx, ASE_MT);
4147 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4151 check_insn(env, ctx, ASE_MT);
4152 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4156 check_insn(env, ctx, ASE_MT);
4157 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4167 gen_helper_mfc0_random(arg, cpu_env);
4171 check_insn(env, ctx, ASE_MT);
4172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4176 check_insn(env, ctx, ASE_MT);
4177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4181 check_insn(env, ctx, ASE_MT);
4182 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4186 check_insn(env, ctx, ASE_MT);
4187 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4191 check_insn(env, ctx, ASE_MT);
4192 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4196 check_insn(env, ctx, ASE_MT);
4197 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4198 rn = "VPEScheFBack";
4201 check_insn(env, ctx, ASE_MT);
4202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4212 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4213 tcg_gen_ext32s_tl(arg, arg);
4217 check_insn(env, ctx, ASE_MT);
4218 gen_helper_mfc0_tcstatus(arg, cpu_env);
4222 check_insn(env, ctx, ASE_MT);
4223 gen_helper_mfc0_tcbind(arg, cpu_env);
4227 check_insn(env, ctx, ASE_MT);
4228 gen_helper_mfc0_tcrestart(arg, cpu_env);
4232 check_insn(env, ctx, ASE_MT);
4233 gen_helper_mfc0_tchalt(arg, cpu_env);
4237 check_insn(env, ctx, ASE_MT);
4238 gen_helper_mfc0_tccontext(arg, cpu_env);
4242 check_insn(env, ctx, ASE_MT);
4243 gen_helper_mfc0_tcschedule(arg, cpu_env);
4247 check_insn(env, ctx, ASE_MT);
4248 gen_helper_mfc0_tcschefback(arg, cpu_env);
4258 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4259 tcg_gen_ext32s_tl(arg, arg);
4269 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4270 tcg_gen_ext32s_tl(arg, arg);
4274 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4275 rn = "ContextConfig";
4284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4288 check_insn(env, ctx, ISA_MIPS32R2);
4289 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4303 check_insn(env, ctx, ISA_MIPS32R2);
4304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4308 check_insn(env, ctx, ISA_MIPS32R2);
4309 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4313 check_insn(env, ctx, ISA_MIPS32R2);
4314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4318 check_insn(env, ctx, ISA_MIPS32R2);
4319 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4323 check_insn(env, ctx, ISA_MIPS32R2);
4324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4334 check_insn(env, ctx, ISA_MIPS32R2);
4335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4345 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4346 tcg_gen_ext32s_tl(arg, arg);
4356 /* Mark as an IO operation because we read the time. */
4359 gen_helper_mfc0_count(arg, cpu_env);
4363 /* Break the TB to be able to take timer interrupts immediately
4364 after reading count. */
4365 ctx->bstate = BS_STOP;
4368 /* 6,7 are implementation dependent */
4376 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4377 tcg_gen_ext32s_tl(arg, arg);
4387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4390 /* 6,7 are implementation dependent */
4398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4402 check_insn(env, ctx, ISA_MIPS32R2);
4403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4407 check_insn(env, ctx, ISA_MIPS32R2);
4408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4412 check_insn(env, ctx, ISA_MIPS32R2);
4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4433 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4434 tcg_gen_ext32s_tl(arg, arg);
4444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4448 check_insn(env, ctx, ISA_MIPS32R2);
4449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4471 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4474 /* 4,5 are reserved */
4475 /* 6,7 are implementation dependent */
4477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4491 gen_helper_mfc0_lladdr(arg, cpu_env);
4501 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4511 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4521 #if defined(TARGET_MIPS64)
4522 check_insn(env, ctx, ISA_MIPS3);
4523 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4524 tcg_gen_ext32s_tl(arg, arg);
4533 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4544 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4545 rn = "'Diagnostic"; /* implementation dependent */
4550 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4554 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4555 rn = "TraceControl";
4558 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4559 rn = "TraceControl2";
4562 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4563 rn = "UserTraceData";
4566 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4577 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4578 tcg_gen_ext32s_tl(arg, arg);
4588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4589 rn = "Performance0";
4592 // gen_helper_mfc0_performance1(arg);
4593 rn = "Performance1";
4596 // gen_helper_mfc0_performance2(arg);
4597 rn = "Performance2";
4600 // gen_helper_mfc0_performance3(arg);
4601 rn = "Performance3";
4604 // gen_helper_mfc0_performance4(arg);
4605 rn = "Performance4";
4608 // gen_helper_mfc0_performance5(arg);
4609 rn = "Performance5";
4612 // gen_helper_mfc0_performance6(arg);
4613 rn = "Performance6";
4616 // gen_helper_mfc0_performance7(arg);
4617 rn = "Performance7";
4624 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4630 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4643 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4663 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4680 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4681 tcg_gen_ext32s_tl(arg, arg);
4692 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4702 (void)rn; /* avoid a compiler warning */
4703 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4707 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4708 generate_exception(ctx, EXCP_RI);
4711 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4713 const char *rn = "invalid";
4716 check_insn(env, ctx, ISA_MIPS32);
4725 gen_helper_mtc0_index(cpu_env, arg);
4729 check_insn(env, ctx, ASE_MT);
4730 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4734 check_insn(env, ctx, ASE_MT);
4739 check_insn(env, ctx, ASE_MT);
4754 check_insn(env, ctx, ASE_MT);
4755 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4759 check_insn(env, ctx, ASE_MT);
4760 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4764 check_insn(env, ctx, ASE_MT);
4765 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4769 check_insn(env, ctx, ASE_MT);
4770 gen_helper_mtc0_yqmask(cpu_env, arg);
4774 check_insn(env, ctx, ASE_MT);
4775 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4779 check_insn(env, ctx, ASE_MT);
4780 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4781 rn = "VPEScheFBack";
4784 check_insn(env, ctx, ASE_MT);
4785 gen_helper_mtc0_vpeopt(cpu_env, arg);
4795 gen_helper_mtc0_entrylo0(cpu_env, arg);
4799 check_insn(env, ctx, ASE_MT);
4800 gen_helper_mtc0_tcstatus(cpu_env, arg);
4804 check_insn(env, ctx, ASE_MT);
4805 gen_helper_mtc0_tcbind(cpu_env, arg);
4809 check_insn(env, ctx, ASE_MT);
4810 gen_helper_mtc0_tcrestart(cpu_env, arg);
4814 check_insn(env, ctx, ASE_MT);
4815 gen_helper_mtc0_tchalt(cpu_env, arg);
4819 check_insn(env, ctx, ASE_MT);
4820 gen_helper_mtc0_tccontext(cpu_env, arg);
4824 check_insn(env, ctx, ASE_MT);
4825 gen_helper_mtc0_tcschedule(cpu_env, arg);
4829 check_insn(env, ctx, ASE_MT);
4830 gen_helper_mtc0_tcschefback(cpu_env, arg);
4840 gen_helper_mtc0_entrylo1(cpu_env, arg);
4850 gen_helper_mtc0_context(cpu_env, arg);
4854 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4855 rn = "ContextConfig";
4864 gen_helper_mtc0_pagemask(cpu_env, arg);
4868 check_insn(env, ctx, ISA_MIPS32R2);
4869 gen_helper_mtc0_pagegrain(cpu_env, arg);
4879 gen_helper_mtc0_wired(cpu_env, arg);
4883 check_insn(env, ctx, ISA_MIPS32R2);
4884 gen_helper_mtc0_srsconf0(cpu_env, arg);
4888 check_insn(env, ctx, ISA_MIPS32R2);
4889 gen_helper_mtc0_srsconf1(cpu_env, arg);
4893 check_insn(env, ctx, ISA_MIPS32R2);
4894 gen_helper_mtc0_srsconf2(cpu_env, arg);
4898 check_insn(env, ctx, ISA_MIPS32R2);
4899 gen_helper_mtc0_srsconf3(cpu_env, arg);
4903 check_insn(env, ctx, ISA_MIPS32R2);
4904 gen_helper_mtc0_srsconf4(cpu_env, arg);
4914 check_insn(env, ctx, ISA_MIPS32R2);
4915 gen_helper_mtc0_hwrena(cpu_env, arg);
4929 gen_helper_mtc0_count(cpu_env, arg);
4932 /* 6,7 are implementation dependent */
4940 gen_helper_mtc0_entryhi(cpu_env, arg);
4950 gen_helper_mtc0_compare(cpu_env, arg);
4953 /* 6,7 are implementation dependent */
4961 save_cpu_state(ctx, 1);
4962 gen_helper_mtc0_status(cpu_env, arg);
4963 /* BS_STOP isn't good enough here, hflags may have changed. */
4964 gen_save_pc(ctx->pc + 4);
4965 ctx->bstate = BS_EXCP;
4969 check_insn(env, ctx, ISA_MIPS32R2);
4970 gen_helper_mtc0_intctl(cpu_env, arg);
4971 /* Stop translation as we may have switched the execution mode */
4972 ctx->bstate = BS_STOP;
4976 check_insn(env, ctx, ISA_MIPS32R2);
4977 gen_helper_mtc0_srsctl(cpu_env, arg);
4978 /* Stop translation as we may have switched the execution mode */
4979 ctx->bstate = BS_STOP;
4983 check_insn(env, ctx, ISA_MIPS32R2);
4984 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4985 /* Stop translation as we may have switched the execution mode */
4986 ctx->bstate = BS_STOP;
4996 save_cpu_state(ctx, 1);
4997 gen_helper_mtc0_cause(cpu_env, arg);
5007 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5021 check_insn(env, ctx, ISA_MIPS32R2);
5022 gen_helper_mtc0_ebase(cpu_env, arg);
5032 gen_helper_mtc0_config0(cpu_env, arg);
5034 /* Stop translation as we may have switched the execution mode */
5035 ctx->bstate = BS_STOP;
5038 /* ignored, read only */
5042 gen_helper_mtc0_config2(cpu_env, arg);
5044 /* Stop translation as we may have switched the execution mode */
5045 ctx->bstate = BS_STOP;
5048 /* ignored, read only */
5051 /* 4,5 are reserved */
5052 /* 6,7 are implementation dependent */
5062 rn = "Invalid config selector";
5069 gen_helper_mtc0_lladdr(cpu_env, arg);
5079 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5089 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5099 #if defined(TARGET_MIPS64)
5100 check_insn(env, ctx, ISA_MIPS3);
5101 gen_helper_mtc0_xcontext(cpu_env, arg);
5110 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5113 gen_helper_mtc0_framemask(cpu_env, arg);
5122 rn = "Diagnostic"; /* implementation dependent */
5127 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5128 /* BS_STOP isn't good enough here, hflags may have changed. */
5129 gen_save_pc(ctx->pc + 4);
5130 ctx->bstate = BS_EXCP;
5134 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5135 rn = "TraceControl";
5136 /* Stop translation as we may have switched the execution mode */
5137 ctx->bstate = BS_STOP;
5140 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5141 rn = "TraceControl2";
5142 /* Stop translation as we may have switched the execution mode */
5143 ctx->bstate = BS_STOP;
5146 /* Stop translation as we may have switched the execution mode */
5147 ctx->bstate = BS_STOP;
5148 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5149 rn = "UserTraceData";
5150 /* Stop translation as we may have switched the execution mode */
5151 ctx->bstate = BS_STOP;
5154 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5155 /* Stop translation as we may have switched the execution mode */
5156 ctx->bstate = BS_STOP;
5167 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5177 gen_helper_mtc0_performance0(cpu_env, arg);
5178 rn = "Performance0";
5181 // gen_helper_mtc0_performance1(arg);
5182 rn = "Performance1";
5185 // gen_helper_mtc0_performance2(arg);
5186 rn = "Performance2";
5189 // gen_helper_mtc0_performance3(arg);
5190 rn = "Performance3";
5193 // gen_helper_mtc0_performance4(arg);
5194 rn = "Performance4";
5197 // gen_helper_mtc0_performance5(arg);
5198 rn = "Performance5";
5201 // gen_helper_mtc0_performance6(arg);
5202 rn = "Performance6";
5205 // gen_helper_mtc0_performance7(arg);
5206 rn = "Performance7";
5232 gen_helper_mtc0_taglo(cpu_env, arg);
5239 gen_helper_mtc0_datalo(cpu_env, arg);
5252 gen_helper_mtc0_taghi(cpu_env, arg);
5259 gen_helper_mtc0_datahi(cpu_env, arg);
5270 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5281 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5287 /* Stop translation as we may have switched the execution mode */
5288 ctx->bstate = BS_STOP;
5293 (void)rn; /* avoid a compiler warning */
5294 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5295 /* For simplicity assume that all writes can cause interrupts. */
5298 ctx->bstate = BS_STOP;
5303 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5304 generate_exception(ctx, EXCP_RI);
5307 #if defined(TARGET_MIPS64)
5308 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5310 const char *rn = "invalid";
5313 check_insn(env, ctx, ISA_MIPS64);
5319 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5323 check_insn(env, ctx, ASE_MT);
5324 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5328 check_insn(env, ctx, ASE_MT);
5329 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5333 check_insn(env, ctx, ASE_MT);
5334 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5344 gen_helper_mfc0_random(arg, cpu_env);
5348 check_insn(env, ctx, ASE_MT);
5349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5353 check_insn(env, ctx, ASE_MT);
5354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5358 check_insn(env, ctx, ASE_MT);
5359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5363 check_insn(env, ctx, ASE_MT);
5364 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5368 check_insn(env, ctx, ASE_MT);
5369 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5373 check_insn(env, ctx, ASE_MT);
5374 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5375 rn = "VPEScheFBack";
5378 check_insn(env, ctx, ASE_MT);
5379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5389 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5393 check_insn(env, ctx, ASE_MT);
5394 gen_helper_mfc0_tcstatus(arg, cpu_env);
5398 check_insn(env, ctx, ASE_MT);
5399 gen_helper_mfc0_tcbind(arg, cpu_env);
5403 check_insn(env, ctx, ASE_MT);
5404 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5408 check_insn(env, ctx, ASE_MT);
5409 gen_helper_dmfc0_tchalt(arg, cpu_env);
5413 check_insn(env, ctx, ASE_MT);
5414 gen_helper_dmfc0_tccontext(arg, cpu_env);
5418 check_insn(env, ctx, ASE_MT);
5419 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5423 check_insn(env, ctx, ASE_MT);
5424 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5434 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5444 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5448 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5449 rn = "ContextConfig";
5458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5462 check_insn(env, ctx, ISA_MIPS32R2);
5463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5477 check_insn(env, ctx, ISA_MIPS32R2);
5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5482 check_insn(env, ctx, ISA_MIPS32R2);
5483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5487 check_insn(env, ctx, ISA_MIPS32R2);
5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5492 check_insn(env, ctx, ISA_MIPS32R2);
5493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5497 check_insn(env, ctx, ISA_MIPS32R2);
5498 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5508 check_insn(env, ctx, ISA_MIPS32R2);
5509 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5519 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5529 /* Mark as an IO operation because we read the time. */
5532 gen_helper_mfc0_count(arg, cpu_env);
5536 /* Break the TB to be able to take timer interrupts immediately
5537 after reading count. */
5538 ctx->bstate = BS_STOP;
5541 /* 6,7 are implementation dependent */
5549 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5562 /* 6,7 are implementation dependent */
5570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5574 check_insn(env, ctx, ISA_MIPS32R2);
5575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5579 check_insn(env, ctx, ISA_MIPS32R2);
5580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5584 check_insn(env, ctx, ISA_MIPS32R2);
5585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5605 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5615 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5619 check_insn(env, ctx, ISA_MIPS32R2);
5620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5642 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5645 /* 6,7 are implementation dependent */
5647 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5651 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5661 gen_helper_dmfc0_lladdr(arg, cpu_env);
5671 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5681 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5691 check_insn(env, ctx, ISA_MIPS3);
5692 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5700 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5703 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5711 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5712 rn = "'Diagnostic"; /* implementation dependent */
5717 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5721 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5722 rn = "TraceControl";
5725 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5726 rn = "TraceControl2";
5729 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5730 rn = "UserTraceData";
5733 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5744 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5754 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5755 rn = "Performance0";
5758 // gen_helper_dmfc0_performance1(arg);
5759 rn = "Performance1";
5762 // gen_helper_dmfc0_performance2(arg);
5763 rn = "Performance2";
5766 // gen_helper_dmfc0_performance3(arg);
5767 rn = "Performance3";
5770 // gen_helper_dmfc0_performance4(arg);
5771 rn = "Performance4";
5774 // gen_helper_dmfc0_performance5(arg);
5775 rn = "Performance5";
5778 // gen_helper_dmfc0_performance6(arg);
5779 rn = "Performance6";
5782 // gen_helper_dmfc0_performance7(arg);
5783 rn = "Performance7";
5790 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5797 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5810 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5817 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5837 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5847 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5858 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5868 (void)rn; /* avoid a compiler warning */
5869 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5873 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5874 generate_exception(ctx, EXCP_RI);
5877 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5879 const char *rn = "invalid";
5882 check_insn(env, ctx, ISA_MIPS64);
5891 gen_helper_mtc0_index(cpu_env, arg);
5895 check_insn(env, ctx, ASE_MT);
5896 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5900 check_insn(env, ctx, ASE_MT);
5905 check_insn(env, ctx, ASE_MT);
5920 check_insn(env, ctx, ASE_MT);
5921 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5925 check_insn(env, ctx, ASE_MT);
5926 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5930 check_insn(env, ctx, ASE_MT);
5931 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5935 check_insn(env, ctx, ASE_MT);
5936 gen_helper_mtc0_yqmask(cpu_env, arg);
5940 check_insn(env, ctx, ASE_MT);
5941 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5945 check_insn(env, ctx, ASE_MT);
5946 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5947 rn = "VPEScheFBack";
5950 check_insn(env, ctx, ASE_MT);
5951 gen_helper_mtc0_vpeopt(cpu_env, arg);
5961 gen_helper_mtc0_entrylo0(cpu_env, arg);
5965 check_insn(env, ctx, ASE_MT);
5966 gen_helper_mtc0_tcstatus(cpu_env, arg);
5970 check_insn(env, ctx, ASE_MT);
5971 gen_helper_mtc0_tcbind(cpu_env, arg);
5975 check_insn(env, ctx, ASE_MT);
5976 gen_helper_mtc0_tcrestart(cpu_env, arg);
5980 check_insn(env, ctx, ASE_MT);
5981 gen_helper_mtc0_tchalt(cpu_env, arg);
5985 check_insn(env, ctx, ASE_MT);
5986 gen_helper_mtc0_tccontext(cpu_env, arg);
5990 check_insn(env, ctx, ASE_MT);
5991 gen_helper_mtc0_tcschedule(cpu_env, arg);
5995 check_insn(env, ctx, ASE_MT);
5996 gen_helper_mtc0_tcschefback(cpu_env, arg);
6006 gen_helper_mtc0_entrylo1(cpu_env, arg);
6016 gen_helper_mtc0_context(cpu_env, arg);
6020 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6021 rn = "ContextConfig";
6030 gen_helper_mtc0_pagemask(cpu_env, arg);
6034 check_insn(env, ctx, ISA_MIPS32R2);
6035 gen_helper_mtc0_pagegrain(cpu_env, arg);
6045 gen_helper_mtc0_wired(cpu_env, arg);
6049 check_insn(env, ctx, ISA_MIPS32R2);
6050 gen_helper_mtc0_srsconf0(cpu_env, arg);
6054 check_insn(env, ctx, ISA_MIPS32R2);
6055 gen_helper_mtc0_srsconf1(cpu_env, arg);
6059 check_insn(env, ctx, ISA_MIPS32R2);
6060 gen_helper_mtc0_srsconf2(cpu_env, arg);
6064 check_insn(env, ctx, ISA_MIPS32R2);
6065 gen_helper_mtc0_srsconf3(cpu_env, arg);
6069 check_insn(env, ctx, ISA_MIPS32R2);
6070 gen_helper_mtc0_srsconf4(cpu_env, arg);
6080 check_insn(env, ctx, ISA_MIPS32R2);
6081 gen_helper_mtc0_hwrena(cpu_env, arg);
6095 gen_helper_mtc0_count(cpu_env, arg);
6098 /* 6,7 are implementation dependent */
6102 /* Stop translation as we may have switched the execution mode */
6103 ctx->bstate = BS_STOP;
6108 gen_helper_mtc0_entryhi(cpu_env, arg);
6118 gen_helper_mtc0_compare(cpu_env, arg);
6121 /* 6,7 are implementation dependent */
6125 /* Stop translation as we may have switched the execution mode */
6126 ctx->bstate = BS_STOP;
6131 save_cpu_state(ctx, 1);
6132 gen_helper_mtc0_status(cpu_env, arg);
6133 /* BS_STOP isn't good enough here, hflags may have changed. */
6134 gen_save_pc(ctx->pc + 4);
6135 ctx->bstate = BS_EXCP;
6139 check_insn(env, ctx, ISA_MIPS32R2);
6140 gen_helper_mtc0_intctl(cpu_env, arg);
6141 /* Stop translation as we may have switched the execution mode */
6142 ctx->bstate = BS_STOP;
6146 check_insn(env, ctx, ISA_MIPS32R2);
6147 gen_helper_mtc0_srsctl(cpu_env, arg);
6148 /* Stop translation as we may have switched the execution mode */
6149 ctx->bstate = BS_STOP;
6153 check_insn(env, ctx, ISA_MIPS32R2);
6154 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6155 /* Stop translation as we may have switched the execution mode */
6156 ctx->bstate = BS_STOP;
6166 save_cpu_state(ctx, 1);
6167 /* Mark as an IO operation because we may trigger a software
6172 gen_helper_mtc0_cause(cpu_env, arg);
6176 /* Stop translation as we may have triggered an intetrupt */
6177 ctx->bstate = BS_STOP;
6187 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6201 check_insn(env, ctx, ISA_MIPS32R2);
6202 gen_helper_mtc0_ebase(cpu_env, arg);
6212 gen_helper_mtc0_config0(cpu_env, arg);
6214 /* Stop translation as we may have switched the execution mode */
6215 ctx->bstate = BS_STOP;
6218 /* ignored, read only */
6222 gen_helper_mtc0_config2(cpu_env, arg);
6224 /* Stop translation as we may have switched the execution mode */
6225 ctx->bstate = BS_STOP;
6231 /* 6,7 are implementation dependent */
6233 rn = "Invalid config selector";
6240 gen_helper_mtc0_lladdr(cpu_env, arg);
6250 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6260 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6270 check_insn(env, ctx, ISA_MIPS3);
6271 gen_helper_mtc0_xcontext(cpu_env, arg);
6279 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6282 gen_helper_mtc0_framemask(cpu_env, arg);
6291 rn = "Diagnostic"; /* implementation dependent */
6296 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6297 /* BS_STOP isn't good enough here, hflags may have changed. */
6298 gen_save_pc(ctx->pc + 4);
6299 ctx->bstate = BS_EXCP;
6303 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6304 /* Stop translation as we may have switched the execution mode */
6305 ctx->bstate = BS_STOP;
6306 rn = "TraceControl";
6309 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6310 /* Stop translation as we may have switched the execution mode */
6311 ctx->bstate = BS_STOP;
6312 rn = "TraceControl2";
6315 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6316 /* Stop translation as we may have switched the execution mode */
6317 ctx->bstate = BS_STOP;
6318 rn = "UserTraceData";
6321 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6322 /* Stop translation as we may have switched the execution mode */
6323 ctx->bstate = BS_STOP;
6334 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6344 gen_helper_mtc0_performance0(cpu_env, arg);
6345 rn = "Performance0";
6348 // gen_helper_mtc0_performance1(cpu_env, arg);
6349 rn = "Performance1";
6352 // gen_helper_mtc0_performance2(cpu_env, arg);
6353 rn = "Performance2";
6356 // gen_helper_mtc0_performance3(cpu_env, arg);
6357 rn = "Performance3";
6360 // gen_helper_mtc0_performance4(cpu_env, arg);
6361 rn = "Performance4";
6364 // gen_helper_mtc0_performance5(cpu_env, arg);
6365 rn = "Performance5";
6368 // gen_helper_mtc0_performance6(cpu_env, arg);
6369 rn = "Performance6";
6372 // gen_helper_mtc0_performance7(cpu_env, arg);
6373 rn = "Performance7";
6399 gen_helper_mtc0_taglo(cpu_env, arg);
6406 gen_helper_mtc0_datalo(cpu_env, arg);
6419 gen_helper_mtc0_taghi(cpu_env, arg);
6426 gen_helper_mtc0_datahi(cpu_env, arg);
6437 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6448 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6454 /* Stop translation as we may have switched the execution mode */
6455 ctx->bstate = BS_STOP;
6460 (void)rn; /* avoid a compiler warning */
6461 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6462 /* For simplicity assume that all writes can cause interrupts. */
6465 ctx->bstate = BS_STOP;
6470 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6471 generate_exception(ctx, EXCP_RI);
6473 #endif /* TARGET_MIPS64 */
6475 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6476 int u, int sel, int h)
6478 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6479 TCGv t0 = tcg_temp_local_new();
6481 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6482 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6483 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6484 tcg_gen_movi_tl(t0, -1);
6485 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6486 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6487 tcg_gen_movi_tl(t0, -1);
6493 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6496 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6506 gen_helper_mftc0_tcstatus(t0, cpu_env);
6509 gen_helper_mftc0_tcbind(t0, cpu_env);
6512 gen_helper_mftc0_tcrestart(t0, cpu_env);
6515 gen_helper_mftc0_tchalt(t0, cpu_env);
6518 gen_helper_mftc0_tccontext(t0, cpu_env);
6521 gen_helper_mftc0_tcschedule(t0, cpu_env);
6524 gen_helper_mftc0_tcschefback(t0, cpu_env);
6527 gen_mfc0(env, ctx, t0, rt, sel);
6534 gen_helper_mftc0_entryhi(t0, cpu_env);
6537 gen_mfc0(env, ctx, t0, rt, sel);
6543 gen_helper_mftc0_status(t0, cpu_env);
6546 gen_mfc0(env, ctx, t0, rt, sel);
6552 gen_helper_mftc0_cause(t0, cpu_env);
6562 gen_helper_mftc0_epc(t0, cpu_env);
6572 gen_helper_mftc0_ebase(t0, cpu_env);
6582 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6592 gen_helper_mftc0_debug(t0, cpu_env);
6595 gen_mfc0(env, ctx, t0, rt, sel);
6600 gen_mfc0(env, ctx, t0, rt, sel);
6602 } else switch (sel) {
6603 /* GPR registers. */
6605 gen_helper_1e0i(mftgpr, t0, rt);
6607 /* Auxiliary CPU registers */
6611 gen_helper_1e0i(mftlo, t0, 0);
6614 gen_helper_1e0i(mfthi, t0, 0);
6617 gen_helper_1e0i(mftacx, t0, 0);
6620 gen_helper_1e0i(mftlo, t0, 1);
6623 gen_helper_1e0i(mfthi, t0, 1);
6626 gen_helper_1e0i(mftacx, t0, 1);
6629 gen_helper_1e0i(mftlo, t0, 2);
6632 gen_helper_1e0i(mfthi, t0, 2);
6635 gen_helper_1e0i(mftacx, t0, 2);
6638 gen_helper_1e0i(mftlo, t0, 3);
6641 gen_helper_1e0i(mfthi, t0, 3);
6644 gen_helper_1e0i(mftacx, t0, 3);
6647 gen_helper_mftdsp(t0, cpu_env);
6653 /* Floating point (COP1). */
6655 /* XXX: For now we support only a single FPU context. */
6657 TCGv_i32 fp0 = tcg_temp_new_i32();
6659 gen_load_fpr32(fp0, rt);
6660 tcg_gen_ext_i32_tl(t0, fp0);
6661 tcg_temp_free_i32(fp0);
6663 TCGv_i32 fp0 = tcg_temp_new_i32();
6665 gen_load_fpr32h(fp0, rt);
6666 tcg_gen_ext_i32_tl(t0, fp0);
6667 tcg_temp_free_i32(fp0);
6671 /* XXX: For now we support only a single FPU context. */
6672 gen_helper_1e0i(cfc1, t0, rt);
6674 /* COP2: Not implemented. */
6681 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6682 gen_store_gpr(t0, rd);
6688 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6689 generate_exception(ctx, EXCP_RI);
6692 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6693 int u, int sel, int h)
6695 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6696 TCGv t0 = tcg_temp_local_new();
6698 gen_load_gpr(t0, rt);
6699 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6700 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6701 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6703 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6704 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6711 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6714 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6724 gen_helper_mttc0_tcstatus(cpu_env, t0);
6727 gen_helper_mttc0_tcbind(cpu_env, t0);
6730 gen_helper_mttc0_tcrestart(cpu_env, t0);
6733 gen_helper_mttc0_tchalt(cpu_env, t0);
6736 gen_helper_mttc0_tccontext(cpu_env, t0);
6739 gen_helper_mttc0_tcschedule(cpu_env, t0);
6742 gen_helper_mttc0_tcschefback(cpu_env, t0);
6745 gen_mtc0(env, ctx, t0, rd, sel);
6752 gen_helper_mttc0_entryhi(cpu_env, t0);
6755 gen_mtc0(env, ctx, t0, rd, sel);
6761 gen_helper_mttc0_status(cpu_env, t0);
6764 gen_mtc0(env, ctx, t0, rd, sel);
6770 gen_helper_mttc0_cause(cpu_env, t0);
6780 gen_helper_mttc0_ebase(cpu_env, t0);
6790 gen_helper_mttc0_debug(cpu_env, t0);
6793 gen_mtc0(env, ctx, t0, rd, sel);
6798 gen_mtc0(env, ctx, t0, rd, sel);
6800 } else switch (sel) {
6801 /* GPR registers. */
6803 gen_helper_0e1i(mttgpr, t0, rd);
6805 /* Auxiliary CPU registers */
6809 gen_helper_0e1i(mttlo, t0, 0);
6812 gen_helper_0e1i(mtthi, t0, 0);
6815 gen_helper_0e1i(mttacx, t0, 0);
6818 gen_helper_0e1i(mttlo, t0, 1);
6821 gen_helper_0e1i(mtthi, t0, 1);
6824 gen_helper_0e1i(mttacx, t0, 1);
6827 gen_helper_0e1i(mttlo, t0, 2);
6830 gen_helper_0e1i(mtthi, t0, 2);
6833 gen_helper_0e1i(mttacx, t0, 2);
6836 gen_helper_0e1i(mttlo, t0, 3);
6839 gen_helper_0e1i(mtthi, t0, 3);
6842 gen_helper_0e1i(mttacx, t0, 3);
6845 gen_helper_mttdsp(cpu_env, t0);
6851 /* Floating point (COP1). */
6853 /* XXX: For now we support only a single FPU context. */
6855 TCGv_i32 fp0 = tcg_temp_new_i32();
6857 tcg_gen_trunc_tl_i32(fp0, t0);
6858 gen_store_fpr32(fp0, rd);
6859 tcg_temp_free_i32(fp0);
6861 TCGv_i32 fp0 = tcg_temp_new_i32();
6863 tcg_gen_trunc_tl_i32(fp0, t0);
6864 gen_store_fpr32h(fp0, rd);
6865 tcg_temp_free_i32(fp0);
6869 /* XXX: For now we support only a single FPU context. */
6870 gen_helper_0e1i(ctc1, t0, rd);
6872 /* COP2: Not implemented. */
6879 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6885 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6886 generate_exception(ctx, EXCP_RI);
6889 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6891 const char *opn = "ldst";
6893 check_cp0_enabled(ctx);
6900 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6905 TCGv t0 = tcg_temp_new();
6907 gen_load_gpr(t0, rt);
6908 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6913 #if defined(TARGET_MIPS64)
6915 check_insn(env, ctx, ISA_MIPS3);
6920 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6924 check_insn(env, ctx, ISA_MIPS3);
6926 TCGv t0 = tcg_temp_new();
6928 gen_load_gpr(t0, rt);
6929 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6936 check_insn(env, ctx, ASE_MT);
6941 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6942 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6946 check_insn(env, ctx, ASE_MT);
6947 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6948 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6953 if (!env->tlb->helper_tlbwi)
6955 gen_helper_tlbwi(cpu_env);
6959 if (!env->tlb->helper_tlbwr)
6961 gen_helper_tlbwr(cpu_env);
6965 if (!env->tlb->helper_tlbp)
6967 gen_helper_tlbp(cpu_env);
6971 if (!env->tlb->helper_tlbr)
6973 gen_helper_tlbr(cpu_env);
6977 check_insn(env, ctx, ISA_MIPS2);
6978 gen_helper_eret(cpu_env);
6979 ctx->bstate = BS_EXCP;
6983 check_insn(env, ctx, ISA_MIPS32);
6984 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6986 generate_exception(ctx, EXCP_RI);
6988 gen_helper_deret(cpu_env);
6989 ctx->bstate = BS_EXCP;
6994 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6995 /* If we get an exception, we want to restart at next instruction */
6997 save_cpu_state(ctx, 1);
6999 gen_helper_wait(cpu_env);
7000 ctx->bstate = BS_EXCP;
7005 generate_exception(ctx, EXCP_RI);
7008 (void)opn; /* avoid a compiler warning */
7009 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7011 #endif /* !CONFIG_USER_ONLY */
7013 /* CP1 Branches (before delay slot) */
7014 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
7015 int32_t cc, int32_t offset)
7017 target_ulong btarget;
7018 const char *opn = "cp1 cond branch";
7019 TCGv_i32 t0 = tcg_temp_new_i32();
7022 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7024 btarget = ctx->pc + 4 + offset;
7028 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7029 tcg_gen_not_i32(t0, t0);
7030 tcg_gen_andi_i32(t0, t0, 1);
7031 tcg_gen_extu_i32_tl(bcond, t0);
7035 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7036 tcg_gen_not_i32(t0, t0);
7037 tcg_gen_andi_i32(t0, t0, 1);
7038 tcg_gen_extu_i32_tl(bcond, t0);
7042 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7043 tcg_gen_andi_i32(t0, t0, 1);
7044 tcg_gen_extu_i32_tl(bcond, t0);
7048 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7049 tcg_gen_andi_i32(t0, t0, 1);
7050 tcg_gen_extu_i32_tl(bcond, t0);
7053 ctx->hflags |= MIPS_HFLAG_BL;
7057 TCGv_i32 t1 = tcg_temp_new_i32();
7058 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7060 tcg_gen_nand_i32(t0, t0, t1);
7061 tcg_temp_free_i32(t1);
7062 tcg_gen_andi_i32(t0, t0, 1);
7063 tcg_gen_extu_i32_tl(bcond, t0);
7069 TCGv_i32 t1 = tcg_temp_new_i32();
7070 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7071 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7072 tcg_gen_or_i32(t0, t0, t1);
7073 tcg_temp_free_i32(t1);
7074 tcg_gen_andi_i32(t0, t0, 1);
7075 tcg_gen_extu_i32_tl(bcond, t0);
7081 TCGv_i32 t1 = tcg_temp_new_i32();
7082 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7083 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7084 tcg_gen_and_i32(t0, t0, t1);
7085 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7086 tcg_gen_and_i32(t0, t0, t1);
7087 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7088 tcg_gen_nand_i32(t0, t0, t1);
7089 tcg_temp_free_i32(t1);
7090 tcg_gen_andi_i32(t0, t0, 1);
7091 tcg_gen_extu_i32_tl(bcond, t0);
7097 TCGv_i32 t1 = tcg_temp_new_i32();
7098 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7099 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7100 tcg_gen_or_i32(t0, t0, t1);
7101 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7102 tcg_gen_or_i32(t0, t0, t1);
7103 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7104 tcg_gen_or_i32(t0, t0, t1);
7105 tcg_temp_free_i32(t1);
7106 tcg_gen_andi_i32(t0, t0, 1);
7107 tcg_gen_extu_i32_tl(bcond, t0);
7111 ctx->hflags |= MIPS_HFLAG_BC;
7115 generate_exception (ctx, EXCP_RI);
7118 (void)opn; /* avoid a compiler warning */
7119 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7120 ctx->hflags, btarget);
7121 ctx->btarget = btarget;
7124 tcg_temp_free_i32(t0);
7127 /* Coprocessor 1 (FPU) */
7129 #define FOP(func, fmt) (((fmt) << 21) | (func))
7132 OPC_ADD_S = FOP(0, FMT_S),
7133 OPC_SUB_S = FOP(1, FMT_S),
7134 OPC_MUL_S = FOP(2, FMT_S),
7135 OPC_DIV_S = FOP(3, FMT_S),
7136 OPC_SQRT_S = FOP(4, FMT_S),
7137 OPC_ABS_S = FOP(5, FMT_S),
7138 OPC_MOV_S = FOP(6, FMT_S),
7139 OPC_NEG_S = FOP(7, FMT_S),
7140 OPC_ROUND_L_S = FOP(8, FMT_S),
7141 OPC_TRUNC_L_S = FOP(9, FMT_S),
7142 OPC_CEIL_L_S = FOP(10, FMT_S),
7143 OPC_FLOOR_L_S = FOP(11, FMT_S),
7144 OPC_ROUND_W_S = FOP(12, FMT_S),
7145 OPC_TRUNC_W_S = FOP(13, FMT_S),
7146 OPC_CEIL_W_S = FOP(14, FMT_S),
7147 OPC_FLOOR_W_S = FOP(15, FMT_S),
7148 OPC_MOVCF_S = FOP(17, FMT_S),
7149 OPC_MOVZ_S = FOP(18, FMT_S),
7150 OPC_MOVN_S = FOP(19, FMT_S),
7151 OPC_RECIP_S = FOP(21, FMT_S),
7152 OPC_RSQRT_S = FOP(22, FMT_S),
7153 OPC_RECIP2_S = FOP(28, FMT_S),
7154 OPC_RECIP1_S = FOP(29, FMT_S),
7155 OPC_RSQRT1_S = FOP(30, FMT_S),
7156 OPC_RSQRT2_S = FOP(31, FMT_S),
7157 OPC_CVT_D_S = FOP(33, FMT_S),
7158 OPC_CVT_W_S = FOP(36, FMT_S),
7159 OPC_CVT_L_S = FOP(37, FMT_S),
7160 OPC_CVT_PS_S = FOP(38, FMT_S),
7161 OPC_CMP_F_S = FOP (48, FMT_S),
7162 OPC_CMP_UN_S = FOP (49, FMT_S),
7163 OPC_CMP_EQ_S = FOP (50, FMT_S),
7164 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7165 OPC_CMP_OLT_S = FOP (52, FMT_S),
7166 OPC_CMP_ULT_S = FOP (53, FMT_S),
7167 OPC_CMP_OLE_S = FOP (54, FMT_S),
7168 OPC_CMP_ULE_S = FOP (55, FMT_S),
7169 OPC_CMP_SF_S = FOP (56, FMT_S),
7170 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7171 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7172 OPC_CMP_NGL_S = FOP (59, FMT_S),
7173 OPC_CMP_LT_S = FOP (60, FMT_S),
7174 OPC_CMP_NGE_S = FOP (61, FMT_S),
7175 OPC_CMP_LE_S = FOP (62, FMT_S),
7176 OPC_CMP_NGT_S = FOP (63, FMT_S),
7178 OPC_ADD_D = FOP(0, FMT_D),
7179 OPC_SUB_D = FOP(1, FMT_D),
7180 OPC_MUL_D = FOP(2, FMT_D),
7181 OPC_DIV_D = FOP(3, FMT_D),
7182 OPC_SQRT_D = FOP(4, FMT_D),
7183 OPC_ABS_D = FOP(5, FMT_D),
7184 OPC_MOV_D = FOP(6, FMT_D),
7185 OPC_NEG_D = FOP(7, FMT_D),
7186 OPC_ROUND_L_D = FOP(8, FMT_D),
7187 OPC_TRUNC_L_D = FOP(9, FMT_D),
7188 OPC_CEIL_L_D = FOP(10, FMT_D),
7189 OPC_FLOOR_L_D = FOP(11, FMT_D),
7190 OPC_ROUND_W_D = FOP(12, FMT_D),
7191 OPC_TRUNC_W_D = FOP(13, FMT_D),
7192 OPC_CEIL_W_D = FOP(14, FMT_D),
7193 OPC_FLOOR_W_D = FOP(15, FMT_D),
7194 OPC_MOVCF_D = FOP(17, FMT_D),
7195 OPC_MOVZ_D = FOP(18, FMT_D),
7196 OPC_MOVN_D = FOP(19, FMT_D),
7197 OPC_RECIP_D = FOP(21, FMT_D),
7198 OPC_RSQRT_D = FOP(22, FMT_D),
7199 OPC_RECIP2_D = FOP(28, FMT_D),
7200 OPC_RECIP1_D = FOP(29, FMT_D),
7201 OPC_RSQRT1_D = FOP(30, FMT_D),
7202 OPC_RSQRT2_D = FOP(31, FMT_D),
7203 OPC_CVT_S_D = FOP(32, FMT_D),
7204 OPC_CVT_W_D = FOP(36, FMT_D),
7205 OPC_CVT_L_D = FOP(37, FMT_D),
7206 OPC_CMP_F_D = FOP (48, FMT_D),
7207 OPC_CMP_UN_D = FOP (49, FMT_D),
7208 OPC_CMP_EQ_D = FOP (50, FMT_D),
7209 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7210 OPC_CMP_OLT_D = FOP (52, FMT_D),
7211 OPC_CMP_ULT_D = FOP (53, FMT_D),
7212 OPC_CMP_OLE_D = FOP (54, FMT_D),
7213 OPC_CMP_ULE_D = FOP (55, FMT_D),
7214 OPC_CMP_SF_D = FOP (56, FMT_D),
7215 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7216 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7217 OPC_CMP_NGL_D = FOP (59, FMT_D),
7218 OPC_CMP_LT_D = FOP (60, FMT_D),
7219 OPC_CMP_NGE_D = FOP (61, FMT_D),
7220 OPC_CMP_LE_D = FOP (62, FMT_D),
7221 OPC_CMP_NGT_D = FOP (63, FMT_D),
7223 OPC_CVT_S_W = FOP(32, FMT_W),
7224 OPC_CVT_D_W = FOP(33, FMT_W),
7225 OPC_CVT_S_L = FOP(32, FMT_L),
7226 OPC_CVT_D_L = FOP(33, FMT_L),
7227 OPC_CVT_PS_PW = FOP(38, FMT_W),
7229 OPC_ADD_PS = FOP(0, FMT_PS),
7230 OPC_SUB_PS = FOP(1, FMT_PS),
7231 OPC_MUL_PS = FOP(2, FMT_PS),
7232 OPC_DIV_PS = FOP(3, FMT_PS),
7233 OPC_ABS_PS = FOP(5, FMT_PS),
7234 OPC_MOV_PS = FOP(6, FMT_PS),
7235 OPC_NEG_PS = FOP(7, FMT_PS),
7236 OPC_MOVCF_PS = FOP(17, FMT_PS),
7237 OPC_MOVZ_PS = FOP(18, FMT_PS),
7238 OPC_MOVN_PS = FOP(19, FMT_PS),
7239 OPC_ADDR_PS = FOP(24, FMT_PS),
7240 OPC_MULR_PS = FOP(26, FMT_PS),
7241 OPC_RECIP2_PS = FOP(28, FMT_PS),
7242 OPC_RECIP1_PS = FOP(29, FMT_PS),
7243 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7244 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7246 OPC_CVT_S_PU = FOP(32, FMT_PS),
7247 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7248 OPC_CVT_S_PL = FOP(40, FMT_PS),
7249 OPC_PLL_PS = FOP(44, FMT_PS),
7250 OPC_PLU_PS = FOP(45, FMT_PS),
7251 OPC_PUL_PS = FOP(46, FMT_PS),
7252 OPC_PUU_PS = FOP(47, FMT_PS),
7253 OPC_CMP_F_PS = FOP (48, FMT_PS),
7254 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7255 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7256 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7257 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7258 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7259 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7260 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7261 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7262 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7263 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7264 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7265 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7266 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7267 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7268 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7271 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7273 const char *opn = "cp1 move";
7274 TCGv t0 = tcg_temp_new();
7279 TCGv_i32 fp0 = tcg_temp_new_i32();
7281 gen_load_fpr32(fp0, fs);
7282 tcg_gen_ext_i32_tl(t0, fp0);
7283 tcg_temp_free_i32(fp0);
7285 gen_store_gpr(t0, rt);
7289 gen_load_gpr(t0, rt);
7291 TCGv_i32 fp0 = tcg_temp_new_i32();
7293 tcg_gen_trunc_tl_i32(fp0, t0);
7294 gen_store_fpr32(fp0, fs);
7295 tcg_temp_free_i32(fp0);
7300 gen_helper_1e0i(cfc1, t0, fs);
7301 gen_store_gpr(t0, rt);
7305 gen_load_gpr(t0, rt);
7306 gen_helper_0e1i(ctc1, t0, fs);
7309 #if defined(TARGET_MIPS64)
7311 gen_load_fpr64(ctx, t0, fs);
7312 gen_store_gpr(t0, rt);
7316 gen_load_gpr(t0, rt);
7317 gen_store_fpr64(ctx, t0, fs);
7323 TCGv_i32 fp0 = tcg_temp_new_i32();
7325 gen_load_fpr32h(fp0, fs);
7326 tcg_gen_ext_i32_tl(t0, fp0);
7327 tcg_temp_free_i32(fp0);
7329 gen_store_gpr(t0, rt);
7333 gen_load_gpr(t0, rt);
7335 TCGv_i32 fp0 = tcg_temp_new_i32();
7337 tcg_gen_trunc_tl_i32(fp0, t0);
7338 gen_store_fpr32h(fp0, fs);
7339 tcg_temp_free_i32(fp0);
7345 generate_exception (ctx, EXCP_RI);
7348 (void)opn; /* avoid a compiler warning */
7349 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7355 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7371 l1 = gen_new_label();
7372 t0 = tcg_temp_new_i32();
7373 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7374 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7375 tcg_temp_free_i32(t0);
7377 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7379 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7384 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7387 TCGv_i32 t0 = tcg_temp_new_i32();
7388 int l1 = gen_new_label();
7395 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7396 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7397 gen_load_fpr32(t0, fs);
7398 gen_store_fpr32(t0, fd);
7400 tcg_temp_free_i32(t0);
7403 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7406 TCGv_i32 t0 = tcg_temp_new_i32();
7408 int l1 = gen_new_label();
7415 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7416 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7417 tcg_temp_free_i32(t0);
7418 fp0 = tcg_temp_new_i64();
7419 gen_load_fpr64(ctx, fp0, fs);
7420 gen_store_fpr64(ctx, fp0, fd);
7421 tcg_temp_free_i64(fp0);
7425 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7428 TCGv_i32 t0 = tcg_temp_new_i32();
7429 int l1 = gen_new_label();
7430 int l2 = gen_new_label();
7437 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7438 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7439 gen_load_fpr32(t0, fs);
7440 gen_store_fpr32(t0, fd);
7443 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7444 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7445 gen_load_fpr32h(t0, fs);
7446 gen_store_fpr32h(t0, fd);
7447 tcg_temp_free_i32(t0);
7452 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7453 int ft, int fs, int fd, int cc)
7455 const char *opn = "farith";
7456 const char *condnames[] = {
7474 const char *condnames_abs[] = {
7492 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7493 uint32_t func = ctx->opcode & 0x3f;
7498 TCGv_i32 fp0 = tcg_temp_new_i32();
7499 TCGv_i32 fp1 = tcg_temp_new_i32();
7501 gen_load_fpr32(fp0, fs);
7502 gen_load_fpr32(fp1, ft);
7503 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7504 tcg_temp_free_i32(fp1);
7505 gen_store_fpr32(fp0, fd);
7506 tcg_temp_free_i32(fp0);
7513 TCGv_i32 fp0 = tcg_temp_new_i32();
7514 TCGv_i32 fp1 = tcg_temp_new_i32();
7516 gen_load_fpr32(fp0, fs);
7517 gen_load_fpr32(fp1, ft);
7518 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7519 tcg_temp_free_i32(fp1);
7520 gen_store_fpr32(fp0, fd);
7521 tcg_temp_free_i32(fp0);
7528 TCGv_i32 fp0 = tcg_temp_new_i32();
7529 TCGv_i32 fp1 = tcg_temp_new_i32();
7531 gen_load_fpr32(fp0, fs);
7532 gen_load_fpr32(fp1, ft);
7533 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7534 tcg_temp_free_i32(fp1);
7535 gen_store_fpr32(fp0, fd);
7536 tcg_temp_free_i32(fp0);
7543 TCGv_i32 fp0 = tcg_temp_new_i32();
7544 TCGv_i32 fp1 = tcg_temp_new_i32();
7546 gen_load_fpr32(fp0, fs);
7547 gen_load_fpr32(fp1, ft);
7548 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7549 tcg_temp_free_i32(fp1);
7550 gen_store_fpr32(fp0, fd);
7551 tcg_temp_free_i32(fp0);
7558 TCGv_i32 fp0 = tcg_temp_new_i32();
7560 gen_load_fpr32(fp0, fs);
7561 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7562 gen_store_fpr32(fp0, fd);
7563 tcg_temp_free_i32(fp0);
7569 TCGv_i32 fp0 = tcg_temp_new_i32();
7571 gen_load_fpr32(fp0, fs);
7572 gen_helper_float_abs_s(fp0, fp0);
7573 gen_store_fpr32(fp0, fd);
7574 tcg_temp_free_i32(fp0);
7580 TCGv_i32 fp0 = tcg_temp_new_i32();
7582 gen_load_fpr32(fp0, fs);
7583 gen_store_fpr32(fp0, fd);
7584 tcg_temp_free_i32(fp0);
7590 TCGv_i32 fp0 = tcg_temp_new_i32();
7592 gen_load_fpr32(fp0, fs);
7593 gen_helper_float_chs_s(fp0, fp0);
7594 gen_store_fpr32(fp0, fd);
7595 tcg_temp_free_i32(fp0);
7600 check_cp1_64bitmode(ctx);
7602 TCGv_i32 fp32 = tcg_temp_new_i32();
7603 TCGv_i64 fp64 = tcg_temp_new_i64();
7605 gen_load_fpr32(fp32, fs);
7606 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7607 tcg_temp_free_i32(fp32);
7608 gen_store_fpr64(ctx, fp64, fd);
7609 tcg_temp_free_i64(fp64);
7614 check_cp1_64bitmode(ctx);
7616 TCGv_i32 fp32 = tcg_temp_new_i32();
7617 TCGv_i64 fp64 = tcg_temp_new_i64();
7619 gen_load_fpr32(fp32, fs);
7620 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7621 tcg_temp_free_i32(fp32);
7622 gen_store_fpr64(ctx, fp64, fd);
7623 tcg_temp_free_i64(fp64);
7628 check_cp1_64bitmode(ctx);
7630 TCGv_i32 fp32 = tcg_temp_new_i32();
7631 TCGv_i64 fp64 = tcg_temp_new_i64();
7633 gen_load_fpr32(fp32, fs);
7634 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7635 tcg_temp_free_i32(fp32);
7636 gen_store_fpr64(ctx, fp64, fd);
7637 tcg_temp_free_i64(fp64);
7642 check_cp1_64bitmode(ctx);
7644 TCGv_i32 fp32 = tcg_temp_new_i32();
7645 TCGv_i64 fp64 = tcg_temp_new_i64();
7647 gen_load_fpr32(fp32, fs);
7648 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7649 tcg_temp_free_i32(fp32);
7650 gen_store_fpr64(ctx, fp64, fd);
7651 tcg_temp_free_i64(fp64);
7657 TCGv_i32 fp0 = tcg_temp_new_i32();
7659 gen_load_fpr32(fp0, fs);
7660 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7661 gen_store_fpr32(fp0, fd);
7662 tcg_temp_free_i32(fp0);
7668 TCGv_i32 fp0 = tcg_temp_new_i32();
7670 gen_load_fpr32(fp0, fs);
7671 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7672 gen_store_fpr32(fp0, fd);
7673 tcg_temp_free_i32(fp0);
7679 TCGv_i32 fp0 = tcg_temp_new_i32();
7681 gen_load_fpr32(fp0, fs);
7682 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7683 gen_store_fpr32(fp0, fd);
7684 tcg_temp_free_i32(fp0);
7690 TCGv_i32 fp0 = tcg_temp_new_i32();
7692 gen_load_fpr32(fp0, fs);
7693 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7694 gen_store_fpr32(fp0, fd);
7695 tcg_temp_free_i32(fp0);
7700 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7705 int l1 = gen_new_label();
7709 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7711 fp0 = tcg_temp_new_i32();
7712 gen_load_fpr32(fp0, fs);
7713 gen_store_fpr32(fp0, fd);
7714 tcg_temp_free_i32(fp0);
7721 int l1 = gen_new_label();
7725 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7726 fp0 = tcg_temp_new_i32();
7727 gen_load_fpr32(fp0, fs);
7728 gen_store_fpr32(fp0, fd);
7729 tcg_temp_free_i32(fp0);
7738 TCGv_i32 fp0 = tcg_temp_new_i32();
7740 gen_load_fpr32(fp0, fs);
7741 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7742 gen_store_fpr32(fp0, fd);
7743 tcg_temp_free_i32(fp0);
7750 TCGv_i32 fp0 = tcg_temp_new_i32();
7752 gen_load_fpr32(fp0, fs);
7753 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7754 gen_store_fpr32(fp0, fd);
7755 tcg_temp_free_i32(fp0);
7760 check_cp1_64bitmode(ctx);
7762 TCGv_i32 fp0 = tcg_temp_new_i32();
7763 TCGv_i32 fp1 = tcg_temp_new_i32();
7765 gen_load_fpr32(fp0, fs);
7766 gen_load_fpr32(fp1, ft);
7767 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7768 tcg_temp_free_i32(fp1);
7769 gen_store_fpr32(fp0, fd);
7770 tcg_temp_free_i32(fp0);
7775 check_cp1_64bitmode(ctx);
7777 TCGv_i32 fp0 = tcg_temp_new_i32();
7779 gen_load_fpr32(fp0, fs);
7780 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7781 gen_store_fpr32(fp0, fd);
7782 tcg_temp_free_i32(fp0);
7787 check_cp1_64bitmode(ctx);
7789 TCGv_i32 fp0 = tcg_temp_new_i32();
7791 gen_load_fpr32(fp0, fs);
7792 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7793 gen_store_fpr32(fp0, fd);
7794 tcg_temp_free_i32(fp0);
7799 check_cp1_64bitmode(ctx);
7801 TCGv_i32 fp0 = tcg_temp_new_i32();
7802 TCGv_i32 fp1 = tcg_temp_new_i32();
7804 gen_load_fpr32(fp0, fs);
7805 gen_load_fpr32(fp1, ft);
7806 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7807 tcg_temp_free_i32(fp1);
7808 gen_store_fpr32(fp0, fd);
7809 tcg_temp_free_i32(fp0);
7814 check_cp1_registers(ctx, fd);
7816 TCGv_i32 fp32 = tcg_temp_new_i32();
7817 TCGv_i64 fp64 = tcg_temp_new_i64();
7819 gen_load_fpr32(fp32, fs);
7820 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7821 tcg_temp_free_i32(fp32);
7822 gen_store_fpr64(ctx, fp64, fd);
7823 tcg_temp_free_i64(fp64);
7829 TCGv_i32 fp0 = tcg_temp_new_i32();
7831 gen_load_fpr32(fp0, fs);
7832 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7833 gen_store_fpr32(fp0, fd);
7834 tcg_temp_free_i32(fp0);
7839 check_cp1_64bitmode(ctx);
7841 TCGv_i32 fp32 = tcg_temp_new_i32();
7842 TCGv_i64 fp64 = tcg_temp_new_i64();
7844 gen_load_fpr32(fp32, fs);
7845 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7846 tcg_temp_free_i32(fp32);
7847 gen_store_fpr64(ctx, fp64, fd);
7848 tcg_temp_free_i64(fp64);
7853 check_cp1_64bitmode(ctx);
7855 TCGv_i64 fp64 = tcg_temp_new_i64();
7856 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7857 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7859 gen_load_fpr32(fp32_0, fs);
7860 gen_load_fpr32(fp32_1, ft);
7861 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7862 tcg_temp_free_i32(fp32_1);
7863 tcg_temp_free_i32(fp32_0);
7864 gen_store_fpr64(ctx, fp64, fd);
7865 tcg_temp_free_i64(fp64);
7878 case OPC_CMP_NGLE_S:
7885 if (ctx->opcode & (1 << 6)) {
7886 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7887 opn = condnames_abs[func-48];
7889 gen_cmp_s(ctx, func-48, ft, fs, cc);
7890 opn = condnames[func-48];
7894 check_cp1_registers(ctx, fs | ft | fd);
7896 TCGv_i64 fp0 = tcg_temp_new_i64();
7897 TCGv_i64 fp1 = tcg_temp_new_i64();
7899 gen_load_fpr64(ctx, fp0, fs);
7900 gen_load_fpr64(ctx, fp1, ft);
7901 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7902 tcg_temp_free_i64(fp1);
7903 gen_store_fpr64(ctx, fp0, fd);
7904 tcg_temp_free_i64(fp0);
7910 check_cp1_registers(ctx, fs | ft | fd);
7912 TCGv_i64 fp0 = tcg_temp_new_i64();
7913 TCGv_i64 fp1 = tcg_temp_new_i64();
7915 gen_load_fpr64(ctx, fp0, fs);
7916 gen_load_fpr64(ctx, fp1, ft);
7917 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7918 tcg_temp_free_i64(fp1);
7919 gen_store_fpr64(ctx, fp0, fd);
7920 tcg_temp_free_i64(fp0);
7926 check_cp1_registers(ctx, fs | ft | fd);
7928 TCGv_i64 fp0 = tcg_temp_new_i64();
7929 TCGv_i64 fp1 = tcg_temp_new_i64();
7931 gen_load_fpr64(ctx, fp0, fs);
7932 gen_load_fpr64(ctx, fp1, ft);
7933 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7934 tcg_temp_free_i64(fp1);
7935 gen_store_fpr64(ctx, fp0, fd);
7936 tcg_temp_free_i64(fp0);
7942 check_cp1_registers(ctx, fs | ft | fd);
7944 TCGv_i64 fp0 = tcg_temp_new_i64();
7945 TCGv_i64 fp1 = tcg_temp_new_i64();
7947 gen_load_fpr64(ctx, fp0, fs);
7948 gen_load_fpr64(ctx, fp1, ft);
7949 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7950 tcg_temp_free_i64(fp1);
7951 gen_store_fpr64(ctx, fp0, fd);
7952 tcg_temp_free_i64(fp0);
7958 check_cp1_registers(ctx, fs | fd);
7960 TCGv_i64 fp0 = tcg_temp_new_i64();
7962 gen_load_fpr64(ctx, fp0, fs);
7963 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7964 gen_store_fpr64(ctx, fp0, fd);
7965 tcg_temp_free_i64(fp0);
7970 check_cp1_registers(ctx, fs | fd);
7972 TCGv_i64 fp0 = tcg_temp_new_i64();
7974 gen_load_fpr64(ctx, fp0, fs);
7975 gen_helper_float_abs_d(fp0, fp0);
7976 gen_store_fpr64(ctx, fp0, fd);
7977 tcg_temp_free_i64(fp0);
7982 check_cp1_registers(ctx, fs | fd);
7984 TCGv_i64 fp0 = tcg_temp_new_i64();
7986 gen_load_fpr64(ctx, fp0, fs);
7987 gen_store_fpr64(ctx, fp0, fd);
7988 tcg_temp_free_i64(fp0);
7993 check_cp1_registers(ctx, fs | fd);
7995 TCGv_i64 fp0 = tcg_temp_new_i64();
7997 gen_load_fpr64(ctx, fp0, fs);
7998 gen_helper_float_chs_d(fp0, fp0);
7999 gen_store_fpr64(ctx, fp0, fd);
8000 tcg_temp_free_i64(fp0);
8005 check_cp1_64bitmode(ctx);
8007 TCGv_i64 fp0 = tcg_temp_new_i64();
8009 gen_load_fpr64(ctx, fp0, fs);
8010 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
8011 gen_store_fpr64(ctx, fp0, fd);
8012 tcg_temp_free_i64(fp0);
8017 check_cp1_64bitmode(ctx);
8019 TCGv_i64 fp0 = tcg_temp_new_i64();
8021 gen_load_fpr64(ctx, fp0, fs);
8022 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8023 gen_store_fpr64(ctx, fp0, fd);
8024 tcg_temp_free_i64(fp0);
8029 check_cp1_64bitmode(ctx);
8031 TCGv_i64 fp0 = tcg_temp_new_i64();
8033 gen_load_fpr64(ctx, fp0, fs);
8034 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8035 gen_store_fpr64(ctx, fp0, fd);
8036 tcg_temp_free_i64(fp0);
8041 check_cp1_64bitmode(ctx);
8043 TCGv_i64 fp0 = tcg_temp_new_i64();
8045 gen_load_fpr64(ctx, fp0, fs);
8046 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8047 gen_store_fpr64(ctx, fp0, fd);
8048 tcg_temp_free_i64(fp0);
8053 check_cp1_registers(ctx, fs);
8055 TCGv_i32 fp32 = tcg_temp_new_i32();
8056 TCGv_i64 fp64 = tcg_temp_new_i64();
8058 gen_load_fpr64(ctx, fp64, fs);
8059 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8060 tcg_temp_free_i64(fp64);
8061 gen_store_fpr32(fp32, fd);
8062 tcg_temp_free_i32(fp32);
8067 check_cp1_registers(ctx, fs);
8069 TCGv_i32 fp32 = tcg_temp_new_i32();
8070 TCGv_i64 fp64 = tcg_temp_new_i64();
8072 gen_load_fpr64(ctx, fp64, fs);
8073 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8074 tcg_temp_free_i64(fp64);
8075 gen_store_fpr32(fp32, fd);
8076 tcg_temp_free_i32(fp32);
8081 check_cp1_registers(ctx, fs);
8083 TCGv_i32 fp32 = tcg_temp_new_i32();
8084 TCGv_i64 fp64 = tcg_temp_new_i64();
8086 gen_load_fpr64(ctx, fp64, fs);
8087 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8088 tcg_temp_free_i64(fp64);
8089 gen_store_fpr32(fp32, fd);
8090 tcg_temp_free_i32(fp32);
8095 check_cp1_registers(ctx, fs);
8097 TCGv_i32 fp32 = tcg_temp_new_i32();
8098 TCGv_i64 fp64 = tcg_temp_new_i64();
8100 gen_load_fpr64(ctx, fp64, fs);
8101 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8102 tcg_temp_free_i64(fp64);
8103 gen_store_fpr32(fp32, fd);
8104 tcg_temp_free_i32(fp32);
8109 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8114 int l1 = gen_new_label();
8118 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8120 fp0 = tcg_temp_new_i64();
8121 gen_load_fpr64(ctx, fp0, fs);
8122 gen_store_fpr64(ctx, fp0, fd);
8123 tcg_temp_free_i64(fp0);
8130 int l1 = gen_new_label();
8134 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8135 fp0 = tcg_temp_new_i64();
8136 gen_load_fpr64(ctx, fp0, fs);
8137 gen_store_fpr64(ctx, fp0, fd);
8138 tcg_temp_free_i64(fp0);
8145 check_cp1_64bitmode(ctx);
8147 TCGv_i64 fp0 = tcg_temp_new_i64();
8149 gen_load_fpr64(ctx, fp0, fs);
8150 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8151 gen_store_fpr64(ctx, fp0, fd);
8152 tcg_temp_free_i64(fp0);
8157 check_cp1_64bitmode(ctx);
8159 TCGv_i64 fp0 = tcg_temp_new_i64();
8161 gen_load_fpr64(ctx, fp0, fs);
8162 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8163 gen_store_fpr64(ctx, fp0, fd);
8164 tcg_temp_free_i64(fp0);
8169 check_cp1_64bitmode(ctx);
8171 TCGv_i64 fp0 = tcg_temp_new_i64();
8172 TCGv_i64 fp1 = tcg_temp_new_i64();
8174 gen_load_fpr64(ctx, fp0, fs);
8175 gen_load_fpr64(ctx, fp1, ft);
8176 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8177 tcg_temp_free_i64(fp1);
8178 gen_store_fpr64(ctx, fp0, fd);
8179 tcg_temp_free_i64(fp0);
8184 check_cp1_64bitmode(ctx);
8186 TCGv_i64 fp0 = tcg_temp_new_i64();
8188 gen_load_fpr64(ctx, fp0, fs);
8189 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8190 gen_store_fpr64(ctx, fp0, fd);
8191 tcg_temp_free_i64(fp0);
8196 check_cp1_64bitmode(ctx);
8198 TCGv_i64 fp0 = tcg_temp_new_i64();
8200 gen_load_fpr64(ctx, fp0, fs);
8201 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8202 gen_store_fpr64(ctx, fp0, fd);
8203 tcg_temp_free_i64(fp0);
8208 check_cp1_64bitmode(ctx);
8210 TCGv_i64 fp0 = tcg_temp_new_i64();
8211 TCGv_i64 fp1 = tcg_temp_new_i64();
8213 gen_load_fpr64(ctx, fp0, fs);
8214 gen_load_fpr64(ctx, fp1, ft);
8215 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8216 tcg_temp_free_i64(fp1);
8217 gen_store_fpr64(ctx, fp0, fd);
8218 tcg_temp_free_i64(fp0);
8231 case OPC_CMP_NGLE_D:
8238 if (ctx->opcode & (1 << 6)) {
8239 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8240 opn = condnames_abs[func-48];
8242 gen_cmp_d(ctx, func-48, ft, fs, cc);
8243 opn = condnames[func-48];
8247 check_cp1_registers(ctx, fs);
8249 TCGv_i32 fp32 = tcg_temp_new_i32();
8250 TCGv_i64 fp64 = tcg_temp_new_i64();
8252 gen_load_fpr64(ctx, fp64, fs);
8253 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8254 tcg_temp_free_i64(fp64);
8255 gen_store_fpr32(fp32, fd);
8256 tcg_temp_free_i32(fp32);
8261 check_cp1_registers(ctx, fs);
8263 TCGv_i32 fp32 = tcg_temp_new_i32();
8264 TCGv_i64 fp64 = tcg_temp_new_i64();
8266 gen_load_fpr64(ctx, fp64, fs);
8267 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8268 tcg_temp_free_i64(fp64);
8269 gen_store_fpr32(fp32, fd);
8270 tcg_temp_free_i32(fp32);
8275 check_cp1_64bitmode(ctx);
8277 TCGv_i64 fp0 = tcg_temp_new_i64();
8279 gen_load_fpr64(ctx, fp0, fs);
8280 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8281 gen_store_fpr64(ctx, fp0, fd);
8282 tcg_temp_free_i64(fp0);
8288 TCGv_i32 fp0 = tcg_temp_new_i32();
8290 gen_load_fpr32(fp0, fs);
8291 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8292 gen_store_fpr32(fp0, fd);
8293 tcg_temp_free_i32(fp0);
8298 check_cp1_registers(ctx, fd);
8300 TCGv_i32 fp32 = tcg_temp_new_i32();
8301 TCGv_i64 fp64 = tcg_temp_new_i64();
8303 gen_load_fpr32(fp32, fs);
8304 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8305 tcg_temp_free_i32(fp32);
8306 gen_store_fpr64(ctx, fp64, fd);
8307 tcg_temp_free_i64(fp64);
8312 check_cp1_64bitmode(ctx);
8314 TCGv_i32 fp32 = tcg_temp_new_i32();
8315 TCGv_i64 fp64 = tcg_temp_new_i64();
8317 gen_load_fpr64(ctx, fp64, fs);
8318 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8319 tcg_temp_free_i64(fp64);
8320 gen_store_fpr32(fp32, fd);
8321 tcg_temp_free_i32(fp32);
8326 check_cp1_64bitmode(ctx);
8328 TCGv_i64 fp0 = tcg_temp_new_i64();
8330 gen_load_fpr64(ctx, fp0, fs);
8331 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8332 gen_store_fpr64(ctx, fp0, fd);
8333 tcg_temp_free_i64(fp0);
8338 check_cp1_64bitmode(ctx);
8340 TCGv_i64 fp0 = tcg_temp_new_i64();
8342 gen_load_fpr64(ctx, fp0, fs);
8343 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8344 gen_store_fpr64(ctx, fp0, fd);
8345 tcg_temp_free_i64(fp0);
8350 check_cp1_64bitmode(ctx);
8352 TCGv_i64 fp0 = tcg_temp_new_i64();
8353 TCGv_i64 fp1 = tcg_temp_new_i64();
8355 gen_load_fpr64(ctx, fp0, fs);
8356 gen_load_fpr64(ctx, fp1, ft);
8357 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8358 tcg_temp_free_i64(fp1);
8359 gen_store_fpr64(ctx, fp0, fd);
8360 tcg_temp_free_i64(fp0);
8365 check_cp1_64bitmode(ctx);
8367 TCGv_i64 fp0 = tcg_temp_new_i64();
8368 TCGv_i64 fp1 = tcg_temp_new_i64();
8370 gen_load_fpr64(ctx, fp0, fs);
8371 gen_load_fpr64(ctx, fp1, ft);
8372 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8373 tcg_temp_free_i64(fp1);
8374 gen_store_fpr64(ctx, fp0, fd);
8375 tcg_temp_free_i64(fp0);
8380 check_cp1_64bitmode(ctx);
8382 TCGv_i64 fp0 = tcg_temp_new_i64();
8383 TCGv_i64 fp1 = tcg_temp_new_i64();
8385 gen_load_fpr64(ctx, fp0, fs);
8386 gen_load_fpr64(ctx, fp1, ft);
8387 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8388 tcg_temp_free_i64(fp1);
8389 gen_store_fpr64(ctx, fp0, fd);
8390 tcg_temp_free_i64(fp0);
8395 check_cp1_64bitmode(ctx);
8397 TCGv_i64 fp0 = tcg_temp_new_i64();
8399 gen_load_fpr64(ctx, fp0, fs);
8400 gen_helper_float_abs_ps(fp0, fp0);
8401 gen_store_fpr64(ctx, fp0, fd);
8402 tcg_temp_free_i64(fp0);
8407 check_cp1_64bitmode(ctx);
8409 TCGv_i64 fp0 = tcg_temp_new_i64();
8411 gen_load_fpr64(ctx, fp0, fs);
8412 gen_store_fpr64(ctx, fp0, fd);
8413 tcg_temp_free_i64(fp0);
8418 check_cp1_64bitmode(ctx);
8420 TCGv_i64 fp0 = tcg_temp_new_i64();
8422 gen_load_fpr64(ctx, fp0, fs);
8423 gen_helper_float_chs_ps(fp0, fp0);
8424 gen_store_fpr64(ctx, fp0, fd);
8425 tcg_temp_free_i64(fp0);
8430 check_cp1_64bitmode(ctx);
8431 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8435 check_cp1_64bitmode(ctx);
8437 int l1 = gen_new_label();
8441 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8442 fp0 = tcg_temp_new_i64();
8443 gen_load_fpr64(ctx, fp0, fs);
8444 gen_store_fpr64(ctx, fp0, fd);
8445 tcg_temp_free_i64(fp0);
8451 check_cp1_64bitmode(ctx);
8453 int l1 = gen_new_label();
8457 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8458 fp0 = tcg_temp_new_i64();
8459 gen_load_fpr64(ctx, fp0, fs);
8460 gen_store_fpr64(ctx, fp0, fd);
8461 tcg_temp_free_i64(fp0);
8468 check_cp1_64bitmode(ctx);
8470 TCGv_i64 fp0 = tcg_temp_new_i64();
8471 TCGv_i64 fp1 = tcg_temp_new_i64();
8473 gen_load_fpr64(ctx, fp0, ft);
8474 gen_load_fpr64(ctx, fp1, fs);
8475 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8476 tcg_temp_free_i64(fp1);
8477 gen_store_fpr64(ctx, fp0, fd);
8478 tcg_temp_free_i64(fp0);
8483 check_cp1_64bitmode(ctx);
8485 TCGv_i64 fp0 = tcg_temp_new_i64();
8486 TCGv_i64 fp1 = tcg_temp_new_i64();
8488 gen_load_fpr64(ctx, fp0, ft);
8489 gen_load_fpr64(ctx, fp1, fs);
8490 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8491 tcg_temp_free_i64(fp1);
8492 gen_store_fpr64(ctx, fp0, fd);
8493 tcg_temp_free_i64(fp0);
8498 check_cp1_64bitmode(ctx);
8500 TCGv_i64 fp0 = tcg_temp_new_i64();
8501 TCGv_i64 fp1 = tcg_temp_new_i64();
8503 gen_load_fpr64(ctx, fp0, fs);
8504 gen_load_fpr64(ctx, fp1, ft);
8505 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8506 tcg_temp_free_i64(fp1);
8507 gen_store_fpr64(ctx, fp0, fd);
8508 tcg_temp_free_i64(fp0);
8513 check_cp1_64bitmode(ctx);
8515 TCGv_i64 fp0 = tcg_temp_new_i64();
8517 gen_load_fpr64(ctx, fp0, fs);
8518 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8519 gen_store_fpr64(ctx, fp0, fd);
8520 tcg_temp_free_i64(fp0);
8525 check_cp1_64bitmode(ctx);
8527 TCGv_i64 fp0 = tcg_temp_new_i64();
8529 gen_load_fpr64(ctx, fp0, fs);
8530 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8531 gen_store_fpr64(ctx, fp0, fd);
8532 tcg_temp_free_i64(fp0);
8537 check_cp1_64bitmode(ctx);
8539 TCGv_i64 fp0 = tcg_temp_new_i64();
8540 TCGv_i64 fp1 = tcg_temp_new_i64();
8542 gen_load_fpr64(ctx, fp0, fs);
8543 gen_load_fpr64(ctx, fp1, ft);
8544 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8545 tcg_temp_free_i64(fp1);
8546 gen_store_fpr64(ctx, fp0, fd);
8547 tcg_temp_free_i64(fp0);
8552 check_cp1_64bitmode(ctx);
8554 TCGv_i32 fp0 = tcg_temp_new_i32();
8556 gen_load_fpr32h(fp0, fs);
8557 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8558 gen_store_fpr32(fp0, fd);
8559 tcg_temp_free_i32(fp0);
8564 check_cp1_64bitmode(ctx);
8566 TCGv_i64 fp0 = tcg_temp_new_i64();
8568 gen_load_fpr64(ctx, fp0, fs);
8569 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8570 gen_store_fpr64(ctx, fp0, fd);
8571 tcg_temp_free_i64(fp0);
8576 check_cp1_64bitmode(ctx);
8578 TCGv_i32 fp0 = tcg_temp_new_i32();
8580 gen_load_fpr32(fp0, fs);
8581 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8582 gen_store_fpr32(fp0, fd);
8583 tcg_temp_free_i32(fp0);
8588 check_cp1_64bitmode(ctx);
8590 TCGv_i32 fp0 = tcg_temp_new_i32();
8591 TCGv_i32 fp1 = tcg_temp_new_i32();
8593 gen_load_fpr32(fp0, fs);
8594 gen_load_fpr32(fp1, ft);
8595 gen_store_fpr32h(fp0, fd);
8596 gen_store_fpr32(fp1, fd);
8597 tcg_temp_free_i32(fp0);
8598 tcg_temp_free_i32(fp1);
8603 check_cp1_64bitmode(ctx);
8605 TCGv_i32 fp0 = tcg_temp_new_i32();
8606 TCGv_i32 fp1 = tcg_temp_new_i32();
8608 gen_load_fpr32(fp0, fs);
8609 gen_load_fpr32h(fp1, ft);
8610 gen_store_fpr32(fp1, fd);
8611 gen_store_fpr32h(fp0, fd);
8612 tcg_temp_free_i32(fp0);
8613 tcg_temp_free_i32(fp1);
8618 check_cp1_64bitmode(ctx);
8620 TCGv_i32 fp0 = tcg_temp_new_i32();
8621 TCGv_i32 fp1 = tcg_temp_new_i32();
8623 gen_load_fpr32h(fp0, fs);
8624 gen_load_fpr32(fp1, ft);
8625 gen_store_fpr32(fp1, fd);
8626 gen_store_fpr32h(fp0, fd);
8627 tcg_temp_free_i32(fp0);
8628 tcg_temp_free_i32(fp1);
8633 check_cp1_64bitmode(ctx);
8635 TCGv_i32 fp0 = tcg_temp_new_i32();
8636 TCGv_i32 fp1 = tcg_temp_new_i32();
8638 gen_load_fpr32h(fp0, fs);
8639 gen_load_fpr32h(fp1, ft);
8640 gen_store_fpr32(fp1, fd);
8641 gen_store_fpr32h(fp0, fd);
8642 tcg_temp_free_i32(fp0);
8643 tcg_temp_free_i32(fp1);
8650 case OPC_CMP_UEQ_PS:
8651 case OPC_CMP_OLT_PS:
8652 case OPC_CMP_ULT_PS:
8653 case OPC_CMP_OLE_PS:
8654 case OPC_CMP_ULE_PS:
8656 case OPC_CMP_NGLE_PS:
8657 case OPC_CMP_SEQ_PS:
8658 case OPC_CMP_NGL_PS:
8660 case OPC_CMP_NGE_PS:
8662 case OPC_CMP_NGT_PS:
8663 if (ctx->opcode & (1 << 6)) {
8664 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8665 opn = condnames_abs[func-48];
8667 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8668 opn = condnames[func-48];
8673 generate_exception (ctx, EXCP_RI);
8676 (void)opn; /* avoid a compiler warning */
8679 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8682 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8685 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8690 /* Coprocessor 3 (FPU) */
8691 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8692 int fd, int fs, int base, int index)
8694 const char *opn = "extended float load/store";
8696 TCGv t0 = tcg_temp_new();
8699 gen_load_gpr(t0, index);
8700 } else if (index == 0) {
8701 gen_load_gpr(t0, base);
8703 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8705 /* Don't do NOP if destination is zero: we must perform the actual
8711 TCGv_i32 fp0 = tcg_temp_new_i32();
8713 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8714 tcg_gen_trunc_tl_i32(fp0, t0);
8715 gen_store_fpr32(fp0, fd);
8716 tcg_temp_free_i32(fp0);
8722 check_cp1_registers(ctx, fd);
8724 TCGv_i64 fp0 = tcg_temp_new_i64();
8726 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8727 gen_store_fpr64(ctx, fp0, fd);
8728 tcg_temp_free_i64(fp0);
8733 check_cp1_64bitmode(ctx);
8734 tcg_gen_andi_tl(t0, t0, ~0x7);
8736 TCGv_i64 fp0 = tcg_temp_new_i64();
8738 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8739 gen_store_fpr64(ctx, fp0, fd);
8740 tcg_temp_free_i64(fp0);
8747 TCGv_i32 fp0 = tcg_temp_new_i32();
8748 TCGv t1 = tcg_temp_new();
8750 gen_load_fpr32(fp0, fs);
8751 tcg_gen_extu_i32_tl(t1, fp0);
8752 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8753 tcg_temp_free_i32(fp0);
8761 check_cp1_registers(ctx, fs);
8763 TCGv_i64 fp0 = tcg_temp_new_i64();
8765 gen_load_fpr64(ctx, fp0, fs);
8766 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8767 tcg_temp_free_i64(fp0);
8773 check_cp1_64bitmode(ctx);
8774 tcg_gen_andi_tl(t0, t0, ~0x7);
8776 TCGv_i64 fp0 = tcg_temp_new_i64();
8778 gen_load_fpr64(ctx, fp0, fs);
8779 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8780 tcg_temp_free_i64(fp0);
8787 (void)opn; (void)store; /* avoid compiler warnings */
8788 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8789 regnames[index], regnames[base]);
8792 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8793 int fd, int fr, int fs, int ft)
8795 const char *opn = "flt3_arith";
8799 check_cp1_64bitmode(ctx);
8801 TCGv t0 = tcg_temp_local_new();
8802 TCGv_i32 fp = tcg_temp_new_i32();
8803 TCGv_i32 fph = tcg_temp_new_i32();
8804 int l1 = gen_new_label();
8805 int l2 = gen_new_label();
8807 gen_load_gpr(t0, fr);
8808 tcg_gen_andi_tl(t0, t0, 0x7);
8810 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8811 gen_load_fpr32(fp, fs);
8812 gen_load_fpr32h(fph, fs);
8813 gen_store_fpr32(fp, fd);
8814 gen_store_fpr32h(fph, fd);
8817 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8819 #ifdef TARGET_WORDS_BIGENDIAN
8820 gen_load_fpr32(fp, fs);
8821 gen_load_fpr32h(fph, ft);
8822 gen_store_fpr32h(fp, fd);
8823 gen_store_fpr32(fph, fd);
8825 gen_load_fpr32h(fph, fs);
8826 gen_load_fpr32(fp, ft);
8827 gen_store_fpr32(fph, fd);
8828 gen_store_fpr32h(fp, fd);
8831 tcg_temp_free_i32(fp);
8832 tcg_temp_free_i32(fph);
8839 TCGv_i32 fp0 = tcg_temp_new_i32();
8840 TCGv_i32 fp1 = tcg_temp_new_i32();
8841 TCGv_i32 fp2 = tcg_temp_new_i32();
8843 gen_load_fpr32(fp0, fs);
8844 gen_load_fpr32(fp1, ft);
8845 gen_load_fpr32(fp2, fr);
8846 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8847 tcg_temp_free_i32(fp0);
8848 tcg_temp_free_i32(fp1);
8849 gen_store_fpr32(fp2, fd);
8850 tcg_temp_free_i32(fp2);
8856 check_cp1_registers(ctx, fd | fs | ft | fr);
8858 TCGv_i64 fp0 = tcg_temp_new_i64();
8859 TCGv_i64 fp1 = tcg_temp_new_i64();
8860 TCGv_i64 fp2 = tcg_temp_new_i64();
8862 gen_load_fpr64(ctx, fp0, fs);
8863 gen_load_fpr64(ctx, fp1, ft);
8864 gen_load_fpr64(ctx, fp2, fr);
8865 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8866 tcg_temp_free_i64(fp0);
8867 tcg_temp_free_i64(fp1);
8868 gen_store_fpr64(ctx, fp2, fd);
8869 tcg_temp_free_i64(fp2);
8874 check_cp1_64bitmode(ctx);
8876 TCGv_i64 fp0 = tcg_temp_new_i64();
8877 TCGv_i64 fp1 = tcg_temp_new_i64();
8878 TCGv_i64 fp2 = tcg_temp_new_i64();
8880 gen_load_fpr64(ctx, fp0, fs);
8881 gen_load_fpr64(ctx, fp1, ft);
8882 gen_load_fpr64(ctx, fp2, fr);
8883 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8884 tcg_temp_free_i64(fp0);
8885 tcg_temp_free_i64(fp1);
8886 gen_store_fpr64(ctx, fp2, fd);
8887 tcg_temp_free_i64(fp2);
8894 TCGv_i32 fp0 = tcg_temp_new_i32();
8895 TCGv_i32 fp1 = tcg_temp_new_i32();
8896 TCGv_i32 fp2 = tcg_temp_new_i32();
8898 gen_load_fpr32(fp0, fs);
8899 gen_load_fpr32(fp1, ft);
8900 gen_load_fpr32(fp2, fr);
8901 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8902 tcg_temp_free_i32(fp0);
8903 tcg_temp_free_i32(fp1);
8904 gen_store_fpr32(fp2, fd);
8905 tcg_temp_free_i32(fp2);
8911 check_cp1_registers(ctx, fd | fs | ft | fr);
8913 TCGv_i64 fp0 = tcg_temp_new_i64();
8914 TCGv_i64 fp1 = tcg_temp_new_i64();
8915 TCGv_i64 fp2 = tcg_temp_new_i64();
8917 gen_load_fpr64(ctx, fp0, fs);
8918 gen_load_fpr64(ctx, fp1, ft);
8919 gen_load_fpr64(ctx, fp2, fr);
8920 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8921 tcg_temp_free_i64(fp0);
8922 tcg_temp_free_i64(fp1);
8923 gen_store_fpr64(ctx, fp2, fd);
8924 tcg_temp_free_i64(fp2);
8929 check_cp1_64bitmode(ctx);
8931 TCGv_i64 fp0 = tcg_temp_new_i64();
8932 TCGv_i64 fp1 = tcg_temp_new_i64();
8933 TCGv_i64 fp2 = tcg_temp_new_i64();
8935 gen_load_fpr64(ctx, fp0, fs);
8936 gen_load_fpr64(ctx, fp1, ft);
8937 gen_load_fpr64(ctx, fp2, fr);
8938 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8939 tcg_temp_free_i64(fp0);
8940 tcg_temp_free_i64(fp1);
8941 gen_store_fpr64(ctx, fp2, fd);
8942 tcg_temp_free_i64(fp2);
8949 TCGv_i32 fp0 = tcg_temp_new_i32();
8950 TCGv_i32 fp1 = tcg_temp_new_i32();
8951 TCGv_i32 fp2 = tcg_temp_new_i32();
8953 gen_load_fpr32(fp0, fs);
8954 gen_load_fpr32(fp1, ft);
8955 gen_load_fpr32(fp2, fr);
8956 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8957 tcg_temp_free_i32(fp0);
8958 tcg_temp_free_i32(fp1);
8959 gen_store_fpr32(fp2, fd);
8960 tcg_temp_free_i32(fp2);
8966 check_cp1_registers(ctx, fd | fs | ft | fr);
8968 TCGv_i64 fp0 = tcg_temp_new_i64();
8969 TCGv_i64 fp1 = tcg_temp_new_i64();
8970 TCGv_i64 fp2 = tcg_temp_new_i64();
8972 gen_load_fpr64(ctx, fp0, fs);
8973 gen_load_fpr64(ctx, fp1, ft);
8974 gen_load_fpr64(ctx, fp2, fr);
8975 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8976 tcg_temp_free_i64(fp0);
8977 tcg_temp_free_i64(fp1);
8978 gen_store_fpr64(ctx, fp2, fd);
8979 tcg_temp_free_i64(fp2);
8984 check_cp1_64bitmode(ctx);
8986 TCGv_i64 fp0 = tcg_temp_new_i64();
8987 TCGv_i64 fp1 = tcg_temp_new_i64();
8988 TCGv_i64 fp2 = tcg_temp_new_i64();
8990 gen_load_fpr64(ctx, fp0, fs);
8991 gen_load_fpr64(ctx, fp1, ft);
8992 gen_load_fpr64(ctx, fp2, fr);
8993 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8994 tcg_temp_free_i64(fp0);
8995 tcg_temp_free_i64(fp1);
8996 gen_store_fpr64(ctx, fp2, fd);
8997 tcg_temp_free_i64(fp2);
9004 TCGv_i32 fp0 = tcg_temp_new_i32();
9005 TCGv_i32 fp1 = tcg_temp_new_i32();
9006 TCGv_i32 fp2 = tcg_temp_new_i32();
9008 gen_load_fpr32(fp0, fs);
9009 gen_load_fpr32(fp1, ft);
9010 gen_load_fpr32(fp2, fr);
9011 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
9012 tcg_temp_free_i32(fp0);
9013 tcg_temp_free_i32(fp1);
9014 gen_store_fpr32(fp2, fd);
9015 tcg_temp_free_i32(fp2);
9021 check_cp1_registers(ctx, fd | fs | ft | fr);
9023 TCGv_i64 fp0 = tcg_temp_new_i64();
9024 TCGv_i64 fp1 = tcg_temp_new_i64();
9025 TCGv_i64 fp2 = tcg_temp_new_i64();
9027 gen_load_fpr64(ctx, fp0, fs);
9028 gen_load_fpr64(ctx, fp1, ft);
9029 gen_load_fpr64(ctx, fp2, fr);
9030 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9031 tcg_temp_free_i64(fp0);
9032 tcg_temp_free_i64(fp1);
9033 gen_store_fpr64(ctx, fp2, fd);
9034 tcg_temp_free_i64(fp2);
9039 check_cp1_64bitmode(ctx);
9041 TCGv_i64 fp0 = tcg_temp_new_i64();
9042 TCGv_i64 fp1 = tcg_temp_new_i64();
9043 TCGv_i64 fp2 = tcg_temp_new_i64();
9045 gen_load_fpr64(ctx, fp0, fs);
9046 gen_load_fpr64(ctx, fp1, ft);
9047 gen_load_fpr64(ctx, fp2, fr);
9048 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9049 tcg_temp_free_i64(fp0);
9050 tcg_temp_free_i64(fp1);
9051 gen_store_fpr64(ctx, fp2, fd);
9052 tcg_temp_free_i64(fp2);
9058 generate_exception (ctx, EXCP_RI);
9061 (void)opn; /* avoid a compiler warning */
9062 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9063 fregnames[fs], fregnames[ft]);
9067 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9071 #if !defined(CONFIG_USER_ONLY)
9072 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9073 Therefore only check the ISA in system mode. */
9074 check_insn(env, ctx, ISA_MIPS32R2);
9076 t0 = tcg_temp_new();
9080 save_cpu_state(ctx, 1);
9081 gen_helper_rdhwr_cpunum(t0, cpu_env);
9082 gen_store_gpr(t0, rt);
9085 save_cpu_state(ctx, 1);
9086 gen_helper_rdhwr_synci_step(t0, cpu_env);
9087 gen_store_gpr(t0, rt);
9090 save_cpu_state(ctx, 1);
9091 gen_helper_rdhwr_cc(t0, cpu_env);
9092 gen_store_gpr(t0, rt);
9095 save_cpu_state(ctx, 1);
9096 gen_helper_rdhwr_ccres(t0, cpu_env);
9097 gen_store_gpr(t0, rt);
9100 #if defined(CONFIG_USER_ONLY)
9101 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9102 gen_store_gpr(t0, rt);
9105 /* XXX: Some CPUs implement this in hardware.
9106 Not supported yet. */
9108 default: /* Invalid */
9109 MIPS_INVAL("rdhwr");
9110 generate_exception(ctx, EXCP_RI);
9116 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9119 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9120 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9121 /* Branches completion */
9122 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9123 ctx->bstate = BS_BRANCH;
9124 save_cpu_state(ctx, 0);
9125 /* FIXME: Need to clear can_do_io. */
9126 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9128 /* unconditional branch */
9129 MIPS_DEBUG("unconditional branch");
9130 if (proc_hflags & MIPS_HFLAG_BX) {
9131 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9133 gen_goto_tb(ctx, 0, ctx->btarget);
9136 /* blikely taken case */
9137 MIPS_DEBUG("blikely branch taken");
9138 gen_goto_tb(ctx, 0, ctx->btarget);
9141 /* Conditional branch */
9142 MIPS_DEBUG("conditional branch");
9144 int l1 = gen_new_label();
9146 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9147 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9149 gen_goto_tb(ctx, 0, ctx->btarget);
9153 /* unconditional branch to register */
9154 MIPS_DEBUG("branch to register");
9155 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9156 TCGv t0 = tcg_temp_new();
9157 TCGv_i32 t1 = tcg_temp_new_i32();
9159 tcg_gen_andi_tl(t0, btarget, 0x1);
9160 tcg_gen_trunc_tl_i32(t1, t0);
9162 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9163 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9164 tcg_gen_or_i32(hflags, hflags, t1);
9165 tcg_temp_free_i32(t1);
9167 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9169 tcg_gen_mov_tl(cpu_PC, btarget);
9171 if (ctx->singlestep_enabled) {
9172 save_cpu_state(ctx, 0);
9173 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9178 MIPS_DEBUG("unknown branch");
9184 /* ISA extensions (ASEs) */
9185 /* MIPS16 extension to MIPS32 */
9187 /* MIPS16 major opcodes */
9189 M16_OPC_ADDIUSP = 0x00,
9190 M16_OPC_ADDIUPC = 0x01,
9193 M16_OPC_BEQZ = 0x04,
9194 M16_OPC_BNEQZ = 0x05,
9195 M16_OPC_SHIFT = 0x06,
9197 M16_OPC_RRIA = 0x08,
9198 M16_OPC_ADDIU8 = 0x09,
9199 M16_OPC_SLTI = 0x0a,
9200 M16_OPC_SLTIU = 0x0b,
9203 M16_OPC_CMPI = 0x0e,
9207 M16_OPC_LWSP = 0x12,
9211 M16_OPC_LWPC = 0x16,
9215 M16_OPC_SWSP = 0x1a,
9219 M16_OPC_EXTEND = 0x1e,
9223 /* I8 funct field */
9242 /* RR funct field */
9276 /* I64 funct field */
9288 /* RR ry field for CNVT */
9290 RR_RY_CNVT_ZEB = 0x0,
9291 RR_RY_CNVT_ZEH = 0x1,
9292 RR_RY_CNVT_ZEW = 0x2,
9293 RR_RY_CNVT_SEB = 0x4,
9294 RR_RY_CNVT_SEH = 0x5,
9295 RR_RY_CNVT_SEW = 0x6,
9298 static int xlat (int r)
9300 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9305 static void gen_mips16_save (DisasContext *ctx,
9306 int xsregs, int aregs,
9307 int do_ra, int do_s0, int do_s1,
9310 TCGv t0 = tcg_temp_new();
9311 TCGv t1 = tcg_temp_new();
9341 generate_exception(ctx, EXCP_RI);
9347 gen_base_offset_addr(ctx, t0, 29, 12);
9348 gen_load_gpr(t1, 7);
9349 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9352 gen_base_offset_addr(ctx, t0, 29, 8);
9353 gen_load_gpr(t1, 6);
9354 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9357 gen_base_offset_addr(ctx, t0, 29, 4);
9358 gen_load_gpr(t1, 5);
9359 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9362 gen_base_offset_addr(ctx, t0, 29, 0);
9363 gen_load_gpr(t1, 4);
9364 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9367 gen_load_gpr(t0, 29);
9369 #define DECR_AND_STORE(reg) do { \
9370 tcg_gen_subi_tl(t0, t0, 4); \
9371 gen_load_gpr(t1, reg); \
9372 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9436 generate_exception(ctx, EXCP_RI);
9452 #undef DECR_AND_STORE
9454 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9459 static void gen_mips16_restore (DisasContext *ctx,
9460 int xsregs, int aregs,
9461 int do_ra, int do_s0, int do_s1,
9465 TCGv t0 = tcg_temp_new();
9466 TCGv t1 = tcg_temp_new();
9468 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9470 #define DECR_AND_LOAD(reg) do { \
9471 tcg_gen_subi_tl(t0, t0, 4); \
9472 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9473 gen_store_gpr(t1, reg); \
9537 generate_exception(ctx, EXCP_RI);
9553 #undef DECR_AND_LOAD
9555 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9560 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9561 int is_64_bit, int extended)
9565 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9566 generate_exception(ctx, EXCP_RI);
9570 t0 = tcg_temp_new();
9572 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9573 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9575 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9581 #if defined(TARGET_MIPS64)
9582 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9583 int ry, int funct, int16_t offset,
9589 offset = extended ? offset : offset << 3;
9590 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9594 offset = extended ? offset : offset << 3;
9595 gen_st(ctx, OPC_SD, ry, 29, offset);
9599 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9600 gen_st(ctx, OPC_SD, 31, 29, offset);
9604 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9605 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9608 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9609 generate_exception(ctx, EXCP_RI);
9611 offset = extended ? offset : offset << 3;
9612 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9617 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9618 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9622 offset = extended ? offset : offset << 2;
9623 gen_addiupc(ctx, ry, offset, 1, extended);
9627 offset = extended ? offset : offset << 2;
9628 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9634 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9637 int extend = cpu_lduw_code(env, ctx->pc + 2);
9638 int op, rx, ry, funct, sa;
9639 int16_t imm, offset;
9641 ctx->opcode = (ctx->opcode << 16) | extend;
9642 op = (ctx->opcode >> 11) & 0x1f;
9643 sa = (ctx->opcode >> 22) & 0x1f;
9644 funct = (ctx->opcode >> 8) & 0x7;
9645 rx = xlat((ctx->opcode >> 8) & 0x7);
9646 ry = xlat((ctx->opcode >> 5) & 0x7);
9647 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9648 | ((ctx->opcode >> 21) & 0x3f) << 5
9649 | (ctx->opcode & 0x1f));
9651 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9654 case M16_OPC_ADDIUSP:
9655 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9657 case M16_OPC_ADDIUPC:
9658 gen_addiupc(ctx, rx, imm, 0, 1);
9661 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9662 /* No delay slot, so just process as a normal instruction */
9665 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9666 /* No delay slot, so just process as a normal instruction */
9669 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9670 /* No delay slot, so just process as a normal instruction */
9673 switch (ctx->opcode & 0x3) {
9675 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9678 #if defined(TARGET_MIPS64)
9680 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9682 generate_exception(ctx, EXCP_RI);
9686 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9689 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9693 #if defined(TARGET_MIPS64)
9696 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9700 imm = ctx->opcode & 0xf;
9701 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9702 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9703 imm = (int16_t) (imm << 1) >> 1;
9704 if ((ctx->opcode >> 4) & 0x1) {
9705 #if defined(TARGET_MIPS64)
9707 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9709 generate_exception(ctx, EXCP_RI);
9712 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9715 case M16_OPC_ADDIU8:
9716 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9719 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9722 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9727 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9730 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9733 gen_st(ctx, OPC_SW, 31, 29, imm);
9736 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9740 int xsregs = (ctx->opcode >> 24) & 0x7;
9741 int aregs = (ctx->opcode >> 16) & 0xf;
9742 int do_ra = (ctx->opcode >> 6) & 0x1;
9743 int do_s0 = (ctx->opcode >> 5) & 0x1;
9744 int do_s1 = (ctx->opcode >> 4) & 0x1;
9745 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9746 | (ctx->opcode & 0xf)) << 3;
9748 if (ctx->opcode & (1 << 7)) {
9749 gen_mips16_save(ctx, xsregs, aregs,
9750 do_ra, do_s0, do_s1,
9753 gen_mips16_restore(ctx, xsregs, aregs,
9754 do_ra, do_s0, do_s1,
9760 generate_exception(ctx, EXCP_RI);
9765 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9768 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9770 #if defined(TARGET_MIPS64)
9772 gen_st(ctx, OPC_SD, ry, rx, offset);
9776 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9779 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9782 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9785 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9788 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9791 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9794 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9796 #if defined(TARGET_MIPS64)
9798 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9802 gen_st(ctx, OPC_SB, ry, rx, offset);
9805 gen_st(ctx, OPC_SH, ry, rx, offset);
9808 gen_st(ctx, OPC_SW, rx, 29, offset);
9811 gen_st(ctx, OPC_SW, ry, rx, offset);
9813 #if defined(TARGET_MIPS64)
9815 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9819 generate_exception(ctx, EXCP_RI);
9826 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9831 int op, cnvt_op, op1, offset;
9835 op = (ctx->opcode >> 11) & 0x1f;
9836 sa = (ctx->opcode >> 2) & 0x7;
9837 sa = sa == 0 ? 8 : sa;
9838 rx = xlat((ctx->opcode >> 8) & 0x7);
9839 cnvt_op = (ctx->opcode >> 5) & 0x7;
9840 ry = xlat((ctx->opcode >> 5) & 0x7);
9841 op1 = offset = ctx->opcode & 0x1f;
9846 case M16_OPC_ADDIUSP:
9848 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9850 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9853 case M16_OPC_ADDIUPC:
9854 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9857 offset = (ctx->opcode & 0x7ff) << 1;
9858 offset = (int16_t)(offset << 4) >> 4;
9859 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9860 /* No delay slot, so just process as a normal instruction */
9863 offset = cpu_lduw_code(env, ctx->pc + 2);
9864 offset = (((ctx->opcode & 0x1f) << 21)
9865 | ((ctx->opcode >> 5) & 0x1f) << 16
9867 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9868 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9873 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9874 /* No delay slot, so just process as a normal instruction */
9877 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9878 /* No delay slot, so just process as a normal instruction */
9881 switch (ctx->opcode & 0x3) {
9883 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9886 #if defined(TARGET_MIPS64)
9888 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9890 generate_exception(ctx, EXCP_RI);
9894 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9897 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9901 #if defined(TARGET_MIPS64)
9904 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9909 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9911 if ((ctx->opcode >> 4) & 1) {
9912 #if defined(TARGET_MIPS64)
9914 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9916 generate_exception(ctx, EXCP_RI);
9919 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9923 case M16_OPC_ADDIU8:
9925 int16_t imm = (int8_t) ctx->opcode;
9927 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9932 int16_t imm = (uint8_t) ctx->opcode;
9933 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9938 int16_t imm = (uint8_t) ctx->opcode;
9939 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9946 funct = (ctx->opcode >> 8) & 0x7;
9949 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9950 ((int8_t)ctx->opcode) << 1);
9953 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9954 ((int8_t)ctx->opcode) << 1);
9957 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9960 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9961 ((int8_t)ctx->opcode) << 3);
9965 int do_ra = ctx->opcode & (1 << 6);
9966 int do_s0 = ctx->opcode & (1 << 5);
9967 int do_s1 = ctx->opcode & (1 << 4);
9968 int framesize = ctx->opcode & 0xf;
9970 if (framesize == 0) {
9973 framesize = framesize << 3;
9976 if (ctx->opcode & (1 << 7)) {
9977 gen_mips16_save(ctx, 0, 0,
9978 do_ra, do_s0, do_s1, framesize);
9980 gen_mips16_restore(ctx, 0, 0,
9981 do_ra, do_s0, do_s1, framesize);
9987 int rz = xlat(ctx->opcode & 0x7);
9989 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9990 ((ctx->opcode >> 5) & 0x7);
9991 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9995 reg32 = ctx->opcode & 0x1f;
9996 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9999 generate_exception(ctx, EXCP_RI);
10006 int16_t imm = (uint8_t) ctx->opcode;
10008 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10013 int16_t imm = (uint8_t) ctx->opcode;
10014 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
10017 #if defined(TARGET_MIPS64)
10019 check_mips_64(ctx);
10020 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10024 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10027 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10030 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10033 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10036 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10039 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10042 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10044 #if defined (TARGET_MIPS64)
10046 check_mips_64(ctx);
10047 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10051 gen_st(ctx, OPC_SB, ry, rx, offset);
10054 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10057 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10060 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10064 int rz = xlat((ctx->opcode >> 2) & 0x7);
10067 switch (ctx->opcode & 0x3) {
10069 mips32_op = OPC_ADDU;
10072 mips32_op = OPC_SUBU;
10074 #if defined(TARGET_MIPS64)
10076 mips32_op = OPC_DADDU;
10077 check_mips_64(ctx);
10080 mips32_op = OPC_DSUBU;
10081 check_mips_64(ctx);
10085 generate_exception(ctx, EXCP_RI);
10089 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10098 int nd = (ctx->opcode >> 7) & 0x1;
10099 int link = (ctx->opcode >> 6) & 0x1;
10100 int ra = (ctx->opcode >> 5) & 0x1;
10103 op = nd ? OPC_JALRC : OPC_JALRS;
10108 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10115 /* XXX: not clear which exception should be raised
10116 * when in debug mode...
10118 check_insn(env, ctx, ISA_MIPS32);
10119 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10120 generate_exception(ctx, EXCP_DBp);
10122 generate_exception(ctx, EXCP_DBp);
10126 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10129 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10132 generate_exception(ctx, EXCP_BREAK);
10135 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10138 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10141 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10143 #if defined (TARGET_MIPS64)
10145 check_mips_64(ctx);
10146 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10150 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10153 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10156 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10159 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10162 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10165 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10168 gen_HILO(ctx, OPC_MFHI, rx);
10172 case RR_RY_CNVT_ZEB:
10173 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10175 case RR_RY_CNVT_ZEH:
10176 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10178 case RR_RY_CNVT_SEB:
10179 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10181 case RR_RY_CNVT_SEH:
10182 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10184 #if defined (TARGET_MIPS64)
10185 case RR_RY_CNVT_ZEW:
10186 check_mips_64(ctx);
10187 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10189 case RR_RY_CNVT_SEW:
10190 check_mips_64(ctx);
10191 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10195 generate_exception(ctx, EXCP_RI);
10200 gen_HILO(ctx, OPC_MFLO, rx);
10202 #if defined (TARGET_MIPS64)
10204 check_mips_64(ctx);
10205 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10208 check_mips_64(ctx);
10209 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10212 check_mips_64(ctx);
10213 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10216 check_mips_64(ctx);
10217 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10221 gen_muldiv(ctx, OPC_MULT, rx, ry);
10224 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10227 gen_muldiv(ctx, OPC_DIV, rx, ry);
10230 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10232 #if defined (TARGET_MIPS64)
10234 check_mips_64(ctx);
10235 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10238 check_mips_64(ctx);
10239 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10242 check_mips_64(ctx);
10243 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10246 check_mips_64(ctx);
10247 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10251 generate_exception(ctx, EXCP_RI);
10255 case M16_OPC_EXTEND:
10256 decode_extended_mips16_opc(env, ctx, is_branch);
10259 #if defined(TARGET_MIPS64)
10261 funct = (ctx->opcode >> 8) & 0x7;
10262 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10266 generate_exception(ctx, EXCP_RI);
10273 /* microMIPS extension to MIPS32 */
10275 /* microMIPS32 major opcodes */
10314 /* 0x20 is reserved */
10324 /* 0x28 and 0x29 are reserved */
10334 /* 0x30 and 0x31 are reserved */
10344 /* 0x38 and 0x39 are reserved */
10355 /* POOL32A encoding of minor opcode field */
10358 /* These opcodes are distinguished only by bits 9..6; those bits are
10359 * what are recorded below. */
10385 /* The following can be distinguished by their lower 6 bits. */
10391 /* POOL32AXF encoding of minor opcode field extension */
10405 /* bits 13..12 for 0x01 */
10411 /* bits 13..12 for 0x2a */
10417 /* bits 13..12 for 0x32 */
10421 /* bits 15..12 for 0x2c */
10437 /* bits 15..12 for 0x34 */
10445 /* bits 15..12 for 0x3c */
10447 JR = 0x0, /* alias */
10452 /* bits 15..12 for 0x05 */
10456 /* bits 15..12 for 0x0d */
10466 /* bits 15..12 for 0x15 */
10472 /* bits 15..12 for 0x1d */
10476 /* bits 15..12 for 0x2d */
10481 /* bits 15..12 for 0x35 */
10488 /* POOL32B encoding of minor opcode field (bits 15..12) */
10504 /* POOL32C encoding of minor opcode field (bits 15..12) */
10512 /* 0xa is reserved */
10519 /* 0x6 is reserved */
10525 /* POOL32F encoding of minor opcode field (bits 5..0) */
10528 /* These are the bit 7..6 values */
10539 /* These are the bit 8..6 values */
10583 CABS_COND_FMT = 0x1c, /* MIPS3D */
10587 /* POOL32Fxf encoding of minor opcode extension field */
10625 /* POOL32I encoding of minor opcode field (bits 25..21) */
10650 /* These overlap and are distinguished by bit16 of the instruction */
10659 /* POOL16A encoding of minor opcode field */
10666 /* POOL16B encoding of minor opcode field */
10673 /* POOL16C encoding of minor opcode field */
10693 /* POOL16D encoding of minor opcode field */
10700 /* POOL16E encoding of minor opcode field */
10707 static int mmreg (int r)
10709 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10714 /* Used for 16-bit store instructions. */
10715 static int mmreg2 (int r)
10717 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10722 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10723 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10724 #define uMIPS_RS2(op) uMIPS_RS(op)
10725 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10726 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10727 #define uMIPS_RS5(op) (op & 0x1f)
10729 /* Signed immediate */
10730 #define SIMM(op, start, width) \
10731 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10734 /* Zero-extended immediate */
10735 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10737 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10739 int rd = mmreg(uMIPS_RD(ctx->opcode));
10741 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10744 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10746 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10747 int rd = mmreg(uMIPS_RD(ctx->opcode));
10748 int rs = mmreg(uMIPS_RS(ctx->opcode));
10750 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10753 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10755 int encoded = ZIMM(ctx->opcode, 1, 9);
10758 if (encoded <= 1) {
10759 decoded = 256 + encoded;
10760 } else if (encoded <= 255) {
10762 } else if (encoded <= 509) {
10763 decoded = encoded - 512;
10765 decoded = encoded - 768;
10768 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10771 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10773 int imm = SIMM(ctx->opcode, 1, 4);
10774 int rd = (ctx->opcode >> 5) & 0x1f;
10776 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10779 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10781 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10782 31, 32, 63, 64, 255, 32768, 65535 };
10783 int rd = mmreg(uMIPS_RD(ctx->opcode));
10784 int rs = mmreg(uMIPS_RS(ctx->opcode));
10785 int encoded = ZIMM(ctx->opcode, 0, 4);
10787 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10790 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10791 int base, int16_t offset)
10793 const char *opn = "ldst_multiple";
10797 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10798 generate_exception(ctx, EXCP_RI);
10802 t0 = tcg_temp_new();
10804 gen_base_offset_addr(ctx, t0, base, offset);
10806 t1 = tcg_const_tl(reglist);
10807 t2 = tcg_const_i32(ctx->mem_idx);
10809 save_cpu_state(ctx, 1);
10812 gen_helper_lwm(cpu_env, t0, t1, t2);
10816 gen_helper_swm(cpu_env, t0, t1, t2);
10819 #ifdef TARGET_MIPS64
10821 gen_helper_ldm(cpu_env, t0, t1, t2);
10825 gen_helper_sdm(cpu_env, t0, t1, t2);
10831 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10834 tcg_temp_free_i32(t2);
10838 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10840 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10841 int rs = mmreg(ctx->opcode & 0x7);
10844 switch (((ctx->opcode) >> 4) & 0x3f) {
10849 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10855 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10861 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10867 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10874 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10875 int offset = ZIMM(ctx->opcode, 0, 4);
10877 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10886 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10887 int offset = ZIMM(ctx->opcode, 0, 4);
10889 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10896 int reg = ctx->opcode & 0x1f;
10898 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10905 int reg = ctx->opcode & 0x1f;
10907 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10908 /* Let normal delay slot handling in our caller take us
10909 to the branch target. */
10921 int reg = ctx->opcode & 0x1f;
10923 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10929 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10933 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10936 generate_exception(ctx, EXCP_BREAK);
10939 /* XXX: not clear which exception should be raised
10940 * when in debug mode...
10942 check_insn(env, ctx, ISA_MIPS32);
10943 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10944 generate_exception(ctx, EXCP_DBp);
10946 generate_exception(ctx, EXCP_DBp);
10949 case JRADDIUSP + 0:
10950 case JRADDIUSP + 1:
10952 int imm = ZIMM(ctx->opcode, 0, 5);
10954 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10955 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10956 /* Let normal delay slot handling in our caller take us
10957 to the branch target. */
10961 generate_exception(ctx, EXCP_RI);
10966 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10968 TCGv t0 = tcg_temp_new();
10969 TCGv t1 = tcg_temp_new();
10971 gen_load_gpr(t0, base);
10974 gen_load_gpr(t1, index);
10975 tcg_gen_shli_tl(t1, t1, 2);
10976 gen_op_addr_add(ctx, t0, t1, t0);
10979 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10980 gen_store_gpr(t1, rd);
10986 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10987 int base, int16_t offset)
10989 const char *opn = "ldst_pair";
10992 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10993 generate_exception(ctx, EXCP_RI);
10997 t0 = tcg_temp_new();
10998 t1 = tcg_temp_new();
11000 gen_base_offset_addr(ctx, t0, base, offset);
11005 generate_exception(ctx, EXCP_RI);
11008 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11009 gen_store_gpr(t1, rd);
11010 tcg_gen_movi_tl(t1, 4);
11011 gen_op_addr_add(ctx, t0, t0, t1);
11012 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11013 gen_store_gpr(t1, rd+1);
11017 gen_load_gpr(t1, rd);
11018 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11019 tcg_gen_movi_tl(t1, 4);
11020 gen_op_addr_add(ctx, t0, t0, t1);
11021 gen_load_gpr(t1, rd+1);
11022 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11025 #ifdef TARGET_MIPS64
11028 generate_exception(ctx, EXCP_RI);
11031 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11032 gen_store_gpr(t1, rd);
11033 tcg_gen_movi_tl(t1, 8);
11034 gen_op_addr_add(ctx, t0, t0, t1);
11035 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11036 gen_store_gpr(t1, rd+1);
11040 gen_load_gpr(t1, rd);
11041 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11042 tcg_gen_movi_tl(t1, 8);
11043 gen_op_addr_add(ctx, t0, t0, t1);
11044 gen_load_gpr(t1, rd+1);
11045 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11050 (void)opn; /* avoid a compiler warning */
11051 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11056 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11059 int extension = (ctx->opcode >> 6) & 0x3f;
11060 int minor = (ctx->opcode >> 12) & 0xf;
11061 uint32_t mips32_op;
11063 switch (extension) {
11065 mips32_op = OPC_TEQ;
11068 mips32_op = OPC_TGE;
11071 mips32_op = OPC_TGEU;
11074 mips32_op = OPC_TLT;
11077 mips32_op = OPC_TLTU;
11080 mips32_op = OPC_TNE;
11082 gen_trap(ctx, mips32_op, rs, rt, -1);
11084 #ifndef CONFIG_USER_ONLY
11087 check_cp0_enabled(ctx);
11089 /* Treat as NOP. */
11092 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11096 check_cp0_enabled(ctx);
11098 TCGv t0 = tcg_temp_new();
11100 gen_load_gpr(t0, rt);
11101 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11109 gen_bshfl(ctx, OPC_SEB, rs, rt);
11112 gen_bshfl(ctx, OPC_SEH, rs, rt);
11115 mips32_op = OPC_CLO;
11118 mips32_op = OPC_CLZ;
11120 check_insn(env, ctx, ISA_MIPS32);
11121 gen_cl(ctx, mips32_op, rt, rs);
11124 gen_rdhwr(env, ctx, rt, rs);
11127 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11130 mips32_op = OPC_MULT;
11133 mips32_op = OPC_MULTU;
11136 mips32_op = OPC_DIV;
11139 mips32_op = OPC_DIVU;
11142 mips32_op = OPC_MADD;
11145 mips32_op = OPC_MADDU;
11148 mips32_op = OPC_MSUB;
11151 mips32_op = OPC_MSUBU;
11153 check_insn(env, ctx, ISA_MIPS32);
11154 gen_muldiv(ctx, mips32_op, rs, rt);
11157 goto pool32axf_invalid;
11168 generate_exception_err(ctx, EXCP_CpU, 2);
11171 goto pool32axf_invalid;
11178 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11183 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11187 goto pool32axf_invalid;
11193 check_cp0_enabled(ctx);
11194 check_insn(env, ctx, ISA_MIPS32R2);
11195 gen_load_srsgpr(rt, rs);
11198 check_cp0_enabled(ctx);
11199 check_insn(env, ctx, ISA_MIPS32R2);
11200 gen_store_srsgpr(rt, rs);
11203 goto pool32axf_invalid;
11206 #ifndef CONFIG_USER_ONLY
11210 mips32_op = OPC_TLBP;
11213 mips32_op = OPC_TLBR;
11216 mips32_op = OPC_TLBWI;
11219 mips32_op = OPC_TLBWR;
11222 mips32_op = OPC_WAIT;
11225 mips32_op = OPC_DERET;
11228 mips32_op = OPC_ERET;
11230 gen_cp0(env, ctx, mips32_op, rt, rs);
11233 goto pool32axf_invalid;
11239 check_cp0_enabled(ctx);
11241 TCGv t0 = tcg_temp_new();
11243 save_cpu_state(ctx, 1);
11244 gen_helper_di(t0, cpu_env);
11245 gen_store_gpr(t0, rs);
11246 /* Stop translation as we may have switched the execution mode */
11247 ctx->bstate = BS_STOP;
11252 check_cp0_enabled(ctx);
11254 TCGv t0 = tcg_temp_new();
11256 save_cpu_state(ctx, 1);
11257 gen_helper_ei(t0, cpu_env);
11258 gen_store_gpr(t0, rs);
11259 /* Stop translation as we may have switched the execution mode */
11260 ctx->bstate = BS_STOP;
11265 goto pool32axf_invalid;
11275 generate_exception(ctx, EXCP_SYSCALL);
11276 ctx->bstate = BS_STOP;
11279 check_insn(env, ctx, ISA_MIPS32);
11280 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11281 generate_exception(ctx, EXCP_DBp);
11283 generate_exception(ctx, EXCP_DBp);
11287 goto pool32axf_invalid;
11293 gen_HILO(ctx, OPC_MFHI, rs);
11296 gen_HILO(ctx, OPC_MFLO, rs);
11299 gen_HILO(ctx, OPC_MTHI, rs);
11302 gen_HILO(ctx, OPC_MTLO, rs);
11305 goto pool32axf_invalid;
11310 MIPS_INVAL("pool32axf");
11311 generate_exception(ctx, EXCP_RI);
11316 /* Values for microMIPS fmt field. Variable-width, depending on which
11317 formats the instruction supports. */
11336 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11338 int extension = (ctx->opcode >> 6) & 0x3ff;
11339 uint32_t mips32_op;
11341 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11342 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11343 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11345 switch (extension) {
11346 case FLOAT_1BIT_FMT(CFC1, 0):
11347 mips32_op = OPC_CFC1;
11349 case FLOAT_1BIT_FMT(CTC1, 0):
11350 mips32_op = OPC_CTC1;
11352 case FLOAT_1BIT_FMT(MFC1, 0):
11353 mips32_op = OPC_MFC1;
11355 case FLOAT_1BIT_FMT(MTC1, 0):
11356 mips32_op = OPC_MTC1;
11358 case FLOAT_1BIT_FMT(MFHC1, 0):
11359 mips32_op = OPC_MFHC1;
11361 case FLOAT_1BIT_FMT(MTHC1, 0):
11362 mips32_op = OPC_MTHC1;
11364 gen_cp1(ctx, mips32_op, rt, rs);
11367 /* Reciprocal square root */
11368 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11369 mips32_op = OPC_RSQRT_S;
11371 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11372 mips32_op = OPC_RSQRT_D;
11376 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11377 mips32_op = OPC_SQRT_S;
11379 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11380 mips32_op = OPC_SQRT_D;
11384 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11385 mips32_op = OPC_RECIP_S;
11387 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11388 mips32_op = OPC_RECIP_D;
11392 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11393 mips32_op = OPC_FLOOR_L_S;
11395 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11396 mips32_op = OPC_FLOOR_L_D;
11398 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11399 mips32_op = OPC_FLOOR_W_S;
11401 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11402 mips32_op = OPC_FLOOR_W_D;
11406 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11407 mips32_op = OPC_CEIL_L_S;
11409 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11410 mips32_op = OPC_CEIL_L_D;
11412 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11413 mips32_op = OPC_CEIL_W_S;
11415 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11416 mips32_op = OPC_CEIL_W_D;
11420 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11421 mips32_op = OPC_TRUNC_L_S;
11423 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11424 mips32_op = OPC_TRUNC_L_D;
11426 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11427 mips32_op = OPC_TRUNC_W_S;
11429 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11430 mips32_op = OPC_TRUNC_W_D;
11434 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11435 mips32_op = OPC_ROUND_L_S;
11437 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11438 mips32_op = OPC_ROUND_L_D;
11440 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11441 mips32_op = OPC_ROUND_W_S;
11443 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11444 mips32_op = OPC_ROUND_W_D;
11447 /* Integer to floating-point conversion */
11448 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11449 mips32_op = OPC_CVT_L_S;
11451 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11452 mips32_op = OPC_CVT_L_D;
11454 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11455 mips32_op = OPC_CVT_W_S;
11457 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11458 mips32_op = OPC_CVT_W_D;
11461 /* Paired-foo conversions */
11462 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11463 mips32_op = OPC_CVT_S_PL;
11465 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11466 mips32_op = OPC_CVT_S_PU;
11468 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11469 mips32_op = OPC_CVT_PW_PS;
11471 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11472 mips32_op = OPC_CVT_PS_PW;
11475 /* Floating-point moves */
11476 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11477 mips32_op = OPC_MOV_S;
11479 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11480 mips32_op = OPC_MOV_D;
11482 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11483 mips32_op = OPC_MOV_PS;
11486 /* Absolute value */
11487 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11488 mips32_op = OPC_ABS_S;
11490 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11491 mips32_op = OPC_ABS_D;
11493 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11494 mips32_op = OPC_ABS_PS;
11498 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11499 mips32_op = OPC_NEG_S;
11501 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11502 mips32_op = OPC_NEG_D;
11504 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11505 mips32_op = OPC_NEG_PS;
11508 /* Reciprocal square root step */
11509 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11510 mips32_op = OPC_RSQRT1_S;
11512 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11513 mips32_op = OPC_RSQRT1_D;
11515 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11516 mips32_op = OPC_RSQRT1_PS;
11519 /* Reciprocal step */
11520 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11521 mips32_op = OPC_RECIP1_S;
11523 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11524 mips32_op = OPC_RECIP1_S;
11526 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11527 mips32_op = OPC_RECIP1_PS;
11530 /* Conversions from double */
11531 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11532 mips32_op = OPC_CVT_D_S;
11534 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11535 mips32_op = OPC_CVT_D_W;
11537 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11538 mips32_op = OPC_CVT_D_L;
11541 /* Conversions from single */
11542 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11543 mips32_op = OPC_CVT_S_D;
11545 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11546 mips32_op = OPC_CVT_S_W;
11548 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11549 mips32_op = OPC_CVT_S_L;
11551 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11554 /* Conditional moves on floating-point codes */
11555 case COND_FLOAT_MOV(MOVT, 0):
11556 case COND_FLOAT_MOV(MOVT, 1):
11557 case COND_FLOAT_MOV(MOVT, 2):
11558 case COND_FLOAT_MOV(MOVT, 3):
11559 case COND_FLOAT_MOV(MOVT, 4):
11560 case COND_FLOAT_MOV(MOVT, 5):
11561 case COND_FLOAT_MOV(MOVT, 6):
11562 case COND_FLOAT_MOV(MOVT, 7):
11563 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11565 case COND_FLOAT_MOV(MOVF, 0):
11566 case COND_FLOAT_MOV(MOVF, 1):
11567 case COND_FLOAT_MOV(MOVF, 2):
11568 case COND_FLOAT_MOV(MOVF, 3):
11569 case COND_FLOAT_MOV(MOVF, 4):
11570 case COND_FLOAT_MOV(MOVF, 5):
11571 case COND_FLOAT_MOV(MOVF, 6):
11572 case COND_FLOAT_MOV(MOVF, 7):
11573 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11576 MIPS_INVAL("pool32fxf");
11577 generate_exception(ctx, EXCP_RI);
11582 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11583 uint16_t insn_hw1, int *is_branch)
11587 int rt, rs, rd, rr;
11589 uint32_t op, minor, mips32_op;
11590 uint32_t cond, fmt, cc;
11592 insn = cpu_lduw_code(env, ctx->pc + 2);
11593 ctx->opcode = (ctx->opcode << 16) | insn;
11595 rt = (ctx->opcode >> 21) & 0x1f;
11596 rs = (ctx->opcode >> 16) & 0x1f;
11597 rd = (ctx->opcode >> 11) & 0x1f;
11598 rr = (ctx->opcode >> 6) & 0x1f;
11599 imm = (int16_t) ctx->opcode;
11601 op = (ctx->opcode >> 26) & 0x3f;
11604 minor = ctx->opcode & 0x3f;
11607 minor = (ctx->opcode >> 6) & 0xf;
11610 mips32_op = OPC_SLL;
11613 mips32_op = OPC_SRA;
11616 mips32_op = OPC_SRL;
11619 mips32_op = OPC_ROTR;
11621 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11624 goto pool32a_invalid;
11628 minor = (ctx->opcode >> 6) & 0xf;
11632 mips32_op = OPC_ADD;
11635 mips32_op = OPC_ADDU;
11638 mips32_op = OPC_SUB;
11641 mips32_op = OPC_SUBU;
11644 mips32_op = OPC_MUL;
11646 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11650 mips32_op = OPC_SLLV;
11653 mips32_op = OPC_SRLV;
11656 mips32_op = OPC_SRAV;
11659 mips32_op = OPC_ROTRV;
11661 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11663 /* Logical operations */
11665 mips32_op = OPC_AND;
11668 mips32_op = OPC_OR;
11671 mips32_op = OPC_NOR;
11674 mips32_op = OPC_XOR;
11676 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11678 /* Set less than */
11680 mips32_op = OPC_SLT;
11683 mips32_op = OPC_SLTU;
11685 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11688 goto pool32a_invalid;
11692 minor = (ctx->opcode >> 6) & 0xf;
11694 /* Conditional moves */
11696 mips32_op = OPC_MOVN;
11699 mips32_op = OPC_MOVZ;
11701 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11704 gen_ldxs(ctx, rs, rt, rd);
11707 goto pool32a_invalid;
11711 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11714 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11717 gen_pool32axf(env, ctx, rt, rs, is_branch);
11720 generate_exception(ctx, EXCP_BREAK);
11724 MIPS_INVAL("pool32a");
11725 generate_exception(ctx, EXCP_RI);
11730 minor = (ctx->opcode >> 12) & 0xf;
11733 check_cp0_enabled(ctx);
11734 /* Treat as no-op. */
11738 /* COP2: Not implemented. */
11739 generate_exception_err(ctx, EXCP_CpU, 2);
11743 #ifdef TARGET_MIPS64
11747 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11751 #ifdef TARGET_MIPS64
11755 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11758 MIPS_INVAL("pool32b");
11759 generate_exception(ctx, EXCP_RI);
11764 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11765 minor = ctx->opcode & 0x3f;
11766 check_cp1_enabled(ctx);
11769 mips32_op = OPC_ALNV_PS;
11772 mips32_op = OPC_MADD_S;
11775 mips32_op = OPC_MADD_D;
11778 mips32_op = OPC_MADD_PS;
11781 mips32_op = OPC_MSUB_S;
11784 mips32_op = OPC_MSUB_D;
11787 mips32_op = OPC_MSUB_PS;
11790 mips32_op = OPC_NMADD_S;
11793 mips32_op = OPC_NMADD_D;
11796 mips32_op = OPC_NMADD_PS;
11799 mips32_op = OPC_NMSUB_S;
11802 mips32_op = OPC_NMSUB_D;
11805 mips32_op = OPC_NMSUB_PS;
11807 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11809 case CABS_COND_FMT:
11810 cond = (ctx->opcode >> 6) & 0xf;
11811 cc = (ctx->opcode >> 13) & 0x7;
11812 fmt = (ctx->opcode >> 10) & 0x3;
11815 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11818 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11821 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11824 goto pool32f_invalid;
11828 cond = (ctx->opcode >> 6) & 0xf;
11829 cc = (ctx->opcode >> 13) & 0x7;
11830 fmt = (ctx->opcode >> 10) & 0x3;
11833 gen_cmp_s(ctx, cond, rt, rs, cc);
11836 gen_cmp_d(ctx, cond, rt, rs, cc);
11839 gen_cmp_ps(ctx, cond, rt, rs, cc);
11842 goto pool32f_invalid;
11846 gen_pool32fxf(env, ctx, rt, rs);
11850 switch ((ctx->opcode >> 6) & 0x7) {
11852 mips32_op = OPC_PLL_PS;
11855 mips32_op = OPC_PLU_PS;
11858 mips32_op = OPC_PUL_PS;
11861 mips32_op = OPC_PUU_PS;
11864 mips32_op = OPC_CVT_PS_S;
11866 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11869 goto pool32f_invalid;
11874 switch ((ctx->opcode >> 6) & 0x7) {
11876 mips32_op = OPC_LWXC1;
11879 mips32_op = OPC_SWXC1;
11882 mips32_op = OPC_LDXC1;
11885 mips32_op = OPC_SDXC1;
11888 mips32_op = OPC_LUXC1;
11891 mips32_op = OPC_SUXC1;
11893 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11896 goto pool32f_invalid;
11901 fmt = (ctx->opcode >> 9) & 0x3;
11902 switch ((ctx->opcode >> 6) & 0x7) {
11906 mips32_op = OPC_RSQRT2_S;
11909 mips32_op = OPC_RSQRT2_D;
11912 mips32_op = OPC_RSQRT2_PS;
11915 goto pool32f_invalid;
11921 mips32_op = OPC_RECIP2_S;
11924 mips32_op = OPC_RECIP2_D;
11927 mips32_op = OPC_RECIP2_PS;
11930 goto pool32f_invalid;
11934 mips32_op = OPC_ADDR_PS;
11937 mips32_op = OPC_MULR_PS;
11939 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11942 goto pool32f_invalid;
11946 /* MOV[FT].fmt and PREFX */
11947 cc = (ctx->opcode >> 13) & 0x7;
11948 fmt = (ctx->opcode >> 9) & 0x3;
11949 switch ((ctx->opcode >> 6) & 0x7) {
11953 gen_movcf_s(rs, rt, cc, 0);
11956 gen_movcf_d(ctx, rs, rt, cc, 0);
11959 gen_movcf_ps(rs, rt, cc, 0);
11962 goto pool32f_invalid;
11968 gen_movcf_s(rs, rt, cc, 1);
11971 gen_movcf_d(ctx, rs, rt, cc, 1);
11974 gen_movcf_ps(rs, rt, cc, 1);
11977 goto pool32f_invalid;
11983 goto pool32f_invalid;
11986 #define FINSN_3ARG_SDPS(prfx) \
11987 switch ((ctx->opcode >> 8) & 0x3) { \
11989 mips32_op = OPC_##prfx##_S; \
11992 mips32_op = OPC_##prfx##_D; \
11994 case FMT_SDPS_PS: \
11995 mips32_op = OPC_##prfx##_PS; \
11998 goto pool32f_invalid; \
12001 /* regular FP ops */
12002 switch ((ctx->opcode >> 6) & 0x3) {
12004 FINSN_3ARG_SDPS(ADD);
12007 FINSN_3ARG_SDPS(SUB);
12010 FINSN_3ARG_SDPS(MUL);
12013 fmt = (ctx->opcode >> 8) & 0x3;
12015 mips32_op = OPC_DIV_D;
12016 } else if (fmt == 0) {
12017 mips32_op = OPC_DIV_S;
12019 goto pool32f_invalid;
12023 goto pool32f_invalid;
12028 switch ((ctx->opcode >> 6) & 0x3) {
12030 FINSN_3ARG_SDPS(MOVN);
12033 FINSN_3ARG_SDPS(MOVZ);
12036 goto pool32f_invalid;
12040 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12044 MIPS_INVAL("pool32f");
12045 generate_exception(ctx, EXCP_RI);
12049 generate_exception_err(ctx, EXCP_CpU, 1);
12053 minor = (ctx->opcode >> 21) & 0x1f;
12056 mips32_op = OPC_BLTZ;
12059 mips32_op = OPC_BLTZAL;
12062 mips32_op = OPC_BLTZALS;
12065 mips32_op = OPC_BGEZ;
12068 mips32_op = OPC_BGEZAL;
12071 mips32_op = OPC_BGEZALS;
12074 mips32_op = OPC_BLEZ;
12077 mips32_op = OPC_BGTZ;
12079 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12085 mips32_op = OPC_TLTI;
12088 mips32_op = OPC_TGEI;
12091 mips32_op = OPC_TLTIU;
12094 mips32_op = OPC_TGEIU;
12097 mips32_op = OPC_TNEI;
12100 mips32_op = OPC_TEQI;
12102 gen_trap(ctx, mips32_op, rs, -1, imm);
12107 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12108 4, rs, 0, imm << 1);
12109 /* Compact branches don't have a delay slot, so just let
12110 the normal delay slot handling take us to the branch
12114 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12120 /* COP2: Not implemented. */
12121 generate_exception_err(ctx, EXCP_CpU, 2);
12124 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12127 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12130 mips32_op = OPC_BC1FANY4;
12133 mips32_op = OPC_BC1TANY4;
12136 check_insn(env, ctx, ASE_MIPS3D);
12139 gen_compute_branch1(env, ctx, mips32_op,
12140 (ctx->opcode >> 18) & 0x7, imm << 1);
12145 /* MIPS DSP: not implemented */
12148 MIPS_INVAL("pool32i");
12149 generate_exception(ctx, EXCP_RI);
12154 minor = (ctx->opcode >> 12) & 0xf;
12157 mips32_op = OPC_LWL;
12160 mips32_op = OPC_SWL;
12163 mips32_op = OPC_LWR;
12166 mips32_op = OPC_SWR;
12168 #if defined(TARGET_MIPS64)
12170 mips32_op = OPC_LDL;
12173 mips32_op = OPC_SDL;
12176 mips32_op = OPC_LDR;
12179 mips32_op = OPC_SDR;
12182 mips32_op = OPC_LWU;
12185 mips32_op = OPC_LLD;
12189 mips32_op = OPC_LL;
12192 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12195 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12198 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12200 #if defined(TARGET_MIPS64)
12202 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12206 /* Treat as no-op */
12209 MIPS_INVAL("pool32c");
12210 generate_exception(ctx, EXCP_RI);
12215 mips32_op = OPC_ADDI;
12218 mips32_op = OPC_ADDIU;
12220 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12223 /* Logical operations */
12225 mips32_op = OPC_ORI;
12228 mips32_op = OPC_XORI;
12231 mips32_op = OPC_ANDI;
12233 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12236 /* Set less than immediate */
12238 mips32_op = OPC_SLTI;
12241 mips32_op = OPC_SLTIU;
12243 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12246 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12247 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12251 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12252 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12256 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12260 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12264 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12265 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12269 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12270 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12273 /* Floating point (COP1) */
12275 mips32_op = OPC_LWC1;
12278 mips32_op = OPC_LDC1;
12281 mips32_op = OPC_SWC1;
12284 mips32_op = OPC_SDC1;
12286 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12290 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12291 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12293 gen_addiupc(ctx, reg, offset, 0, 0);
12296 /* Loads and stores */
12298 mips32_op = OPC_LB;
12301 mips32_op = OPC_LBU;
12304 mips32_op = OPC_LH;
12307 mips32_op = OPC_LHU;
12310 mips32_op = OPC_LW;
12312 #ifdef TARGET_MIPS64
12314 mips32_op = OPC_LD;
12317 mips32_op = OPC_SD;
12321 mips32_op = OPC_SB;
12324 mips32_op = OPC_SH;
12327 mips32_op = OPC_SW;
12330 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12333 gen_st(ctx, mips32_op, rt, rs, imm);
12336 generate_exception(ctx, EXCP_RI);
12341 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12345 /* make sure instructions are on a halfword boundary */
12346 if (ctx->pc & 0x1) {
12347 env->CP0_BadVAddr = ctx->pc;
12348 generate_exception(ctx, EXCP_AdEL);
12349 ctx->bstate = BS_STOP;
12353 op = (ctx->opcode >> 10) & 0x3f;
12354 /* Enforce properly-sized instructions in a delay slot */
12355 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12356 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12390 case POOL48A: /* ??? */
12395 if (bits & MIPS_HFLAG_BDS16) {
12396 generate_exception(ctx, EXCP_RI);
12397 /* Just stop translation; the user is confused. */
12398 ctx->bstate = BS_STOP;
12423 if (bits & MIPS_HFLAG_BDS32) {
12424 generate_exception(ctx, EXCP_RI);
12425 /* Just stop translation; the user is confused. */
12426 ctx->bstate = BS_STOP;
12437 int rd = mmreg(uMIPS_RD(ctx->opcode));
12438 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12439 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12442 switch (ctx->opcode & 0x1) {
12451 gen_arith(env, ctx, opc, rd, rs1, rs2);
12456 int rd = mmreg(uMIPS_RD(ctx->opcode));
12457 int rs = mmreg(uMIPS_RS(ctx->opcode));
12458 int amount = (ctx->opcode >> 1) & 0x7;
12460 amount = amount == 0 ? 8 : amount;
12462 switch (ctx->opcode & 0x1) {
12471 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12475 gen_pool16c_insn(env, ctx, is_branch);
12479 int rd = mmreg(uMIPS_RD(ctx->opcode));
12480 int rb = 28; /* GP */
12481 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12483 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12487 if (ctx->opcode & 1) {
12488 generate_exception(ctx, EXCP_RI);
12491 int enc_dest = uMIPS_RD(ctx->opcode);
12492 int enc_rt = uMIPS_RS2(ctx->opcode);
12493 int enc_rs = uMIPS_RS1(ctx->opcode);
12494 int rd, rs, re, rt;
12495 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12496 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12497 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12499 rd = rd_enc[enc_dest];
12500 re = re_enc[enc_dest];
12501 rs = rs_rt_enc[enc_rs];
12502 rt = rs_rt_enc[enc_rt];
12504 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12505 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12510 int rd = mmreg(uMIPS_RD(ctx->opcode));
12511 int rb = mmreg(uMIPS_RS(ctx->opcode));
12512 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12513 offset = (offset == 0xf ? -1 : offset);
12515 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12520 int rd = mmreg(uMIPS_RD(ctx->opcode));
12521 int rb = mmreg(uMIPS_RS(ctx->opcode));
12522 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12524 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12529 int rd = (ctx->opcode >> 5) & 0x1f;
12530 int rb = 29; /* SP */
12531 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12533 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12538 int rd = mmreg(uMIPS_RD(ctx->opcode));
12539 int rb = mmreg(uMIPS_RS(ctx->opcode));
12540 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12542 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12547 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12548 int rb = mmreg(uMIPS_RS(ctx->opcode));
12549 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12551 gen_st(ctx, OPC_SB, rd, rb, offset);
12556 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12557 int rb = mmreg(uMIPS_RS(ctx->opcode));
12558 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12560 gen_st(ctx, OPC_SH, rd, rb, offset);
12565 int rd = (ctx->opcode >> 5) & 0x1f;
12566 int rb = 29; /* SP */
12567 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12569 gen_st(ctx, OPC_SW, rd, rb, offset);
12574 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12575 int rb = mmreg(uMIPS_RS(ctx->opcode));
12576 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12578 gen_st(ctx, OPC_SW, rd, rb, offset);
12583 int rd = uMIPS_RD5(ctx->opcode);
12584 int rs = uMIPS_RS5(ctx->opcode);
12586 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12590 gen_andi16(env, ctx);
12593 switch (ctx->opcode & 0x1) {
12595 gen_addius5(env, ctx);
12598 gen_addiusp(env, ctx);
12603 switch (ctx->opcode & 0x1) {
12605 gen_addiur2(env, ctx);
12608 gen_addiur1sp(env, ctx);
12613 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12614 SIMM(ctx->opcode, 0, 10) << 1);
12619 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12620 mmreg(uMIPS_RD(ctx->opcode)),
12621 0, SIMM(ctx->opcode, 0, 7) << 1);
12626 int reg = mmreg(uMIPS_RD(ctx->opcode));
12627 int imm = ZIMM(ctx->opcode, 0, 7);
12629 imm = (imm == 0x7f ? -1 : imm);
12630 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12640 generate_exception(ctx, EXCP_RI);
12643 decode_micromips32_opc (env, ctx, op, is_branch);
12650 /* SmartMIPS extension to MIPS32 */
12652 #if defined(TARGET_MIPS64)
12654 /* MDMX extension to MIPS64 */
12658 /* MIPSDSP functions. */
12659 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12660 int rd, int base, int offset)
12662 const char *opn = "ldx";
12671 t0 = tcg_temp_new();
12674 gen_load_gpr(t0, offset);
12675 } else if (offset == 0) {
12676 gen_load_gpr(t0, base);
12678 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12683 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12684 gen_store_gpr(t0, rd);
12688 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12689 gen_store_gpr(t0, rd);
12693 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12694 gen_store_gpr(t0, rd);
12697 #if defined(TARGET_MIPS64)
12699 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12700 gen_store_gpr(t0, rd);
12705 (void)opn; /* avoid a compiler warning */
12706 MIPS_DEBUG("%s %s, %s(%s)", opn,
12707 regnames[rd], regnames[offset], regnames[base]);
12711 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12712 int ret, int v1, int v2)
12714 const char *opn = "mipsdsp arith";
12719 /* Treat as NOP. */
12724 v1_t = tcg_temp_new();
12725 v2_t = tcg_temp_new();
12727 gen_load_gpr(v1_t, v1);
12728 gen_load_gpr(v2_t, v2);
12731 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12732 case OPC_MULT_G_2E:
12736 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12738 case OPC_ADDUH_R_QB:
12739 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12742 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12744 case OPC_ADDQH_R_PH:
12745 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12748 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12750 case OPC_ADDQH_R_W:
12751 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12754 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12756 case OPC_SUBUH_R_QB:
12757 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12760 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12762 case OPC_SUBQH_R_PH:
12763 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12766 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12768 case OPC_SUBQH_R_W:
12769 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12773 case OPC_ABSQ_S_PH_DSP:
12775 case OPC_ABSQ_S_QB:
12777 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12779 case OPC_ABSQ_S_PH:
12781 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12785 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12787 case OPC_PRECEQ_W_PHL:
12789 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12790 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12792 case OPC_PRECEQ_W_PHR:
12794 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12795 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12796 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12798 case OPC_PRECEQU_PH_QBL:
12800 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12802 case OPC_PRECEQU_PH_QBR:
12804 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12806 case OPC_PRECEQU_PH_QBLA:
12808 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12810 case OPC_PRECEQU_PH_QBRA:
12812 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12814 case OPC_PRECEU_PH_QBL:
12816 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12818 case OPC_PRECEU_PH_QBR:
12820 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12822 case OPC_PRECEU_PH_QBLA:
12824 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12826 case OPC_PRECEU_PH_QBRA:
12828 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12832 case OPC_ADDU_QB_DSP:
12836 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12838 case OPC_ADDQ_S_PH:
12840 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12844 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12848 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12850 case OPC_ADDU_S_QB:
12852 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12856 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12858 case OPC_ADDU_S_PH:
12860 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12864 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12866 case OPC_SUBQ_S_PH:
12868 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12872 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12876 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12878 case OPC_SUBU_S_QB:
12880 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12884 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12886 case OPC_SUBU_S_PH:
12888 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12892 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12896 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12900 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12902 case OPC_RADDU_W_QB:
12904 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12908 case OPC_CMPU_EQ_QB_DSP:
12910 case OPC_PRECR_QB_PH:
12912 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12914 case OPC_PRECRQ_QB_PH:
12916 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12918 case OPC_PRECR_SRA_PH_W:
12921 TCGv_i32 sa_t = tcg_const_i32(v2);
12922 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12924 tcg_temp_free_i32(sa_t);
12927 case OPC_PRECR_SRA_R_PH_W:
12930 TCGv_i32 sa_t = tcg_const_i32(v2);
12931 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12933 tcg_temp_free_i32(sa_t);
12936 case OPC_PRECRQ_PH_W:
12938 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12940 case OPC_PRECRQ_RS_PH_W:
12942 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12944 case OPC_PRECRQU_S_QB_PH:
12946 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12950 #ifdef TARGET_MIPS64
12951 case OPC_ABSQ_S_QH_DSP:
12953 case OPC_PRECEQ_L_PWL:
12955 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12957 case OPC_PRECEQ_L_PWR:
12959 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12961 case OPC_PRECEQ_PW_QHL:
12963 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12965 case OPC_PRECEQ_PW_QHR:
12967 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12969 case OPC_PRECEQ_PW_QHLA:
12971 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12973 case OPC_PRECEQ_PW_QHRA:
12975 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12977 case OPC_PRECEQU_QH_OBL:
12979 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12981 case OPC_PRECEQU_QH_OBR:
12983 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12985 case OPC_PRECEQU_QH_OBLA:
12987 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12989 case OPC_PRECEQU_QH_OBRA:
12991 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12993 case OPC_PRECEU_QH_OBL:
12995 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12997 case OPC_PRECEU_QH_OBR:
12999 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13001 case OPC_PRECEU_QH_OBLA:
13003 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13005 case OPC_PRECEU_QH_OBRA:
13007 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13009 case OPC_ABSQ_S_OB:
13011 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13013 case OPC_ABSQ_S_PW:
13015 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13017 case OPC_ABSQ_S_QH:
13019 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13023 case OPC_ADDU_OB_DSP:
13025 case OPC_RADDU_L_OB:
13027 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13031 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13033 case OPC_SUBQ_S_PW:
13035 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13039 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13041 case OPC_SUBQ_S_QH:
13043 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13047 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13049 case OPC_SUBU_S_OB:
13051 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13055 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13057 case OPC_SUBU_S_QH:
13059 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13063 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13065 case OPC_SUBUH_R_OB:
13067 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13071 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13073 case OPC_ADDQ_S_PW:
13075 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13079 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13081 case OPC_ADDQ_S_QH:
13083 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13087 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13089 case OPC_ADDU_S_OB:
13091 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13095 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13097 case OPC_ADDU_S_QH:
13099 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13103 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13105 case OPC_ADDUH_R_OB:
13107 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13111 case OPC_CMPU_EQ_OB_DSP:
13113 case OPC_PRECR_OB_QH:
13115 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13117 case OPC_PRECR_SRA_QH_PW:
13120 TCGv_i32 ret_t = tcg_const_i32(ret);
13121 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13122 tcg_temp_free_i32(ret_t);
13125 case OPC_PRECR_SRA_R_QH_PW:
13128 TCGv_i32 sa_v = tcg_const_i32(ret);
13129 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13130 tcg_temp_free_i32(sa_v);
13133 case OPC_PRECRQ_OB_QH:
13135 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13137 case OPC_PRECRQ_PW_L:
13139 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13141 case OPC_PRECRQ_QH_PW:
13143 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13145 case OPC_PRECRQ_RS_QH_PW:
13147 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13149 case OPC_PRECRQU_S_OB_QH:
13151 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13158 tcg_temp_free(v1_t);
13159 tcg_temp_free(v2_t);
13161 (void)opn; /* avoid a compiler warning */
13162 MIPS_DEBUG("%s", opn);
13165 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13166 int ret, int v1, int v2)
13169 const char *opn = "mipsdsp shift";
13175 /* Treat as NOP. */
13180 t0 = tcg_temp_new();
13181 v1_t = tcg_temp_new();
13182 v2_t = tcg_temp_new();
13184 tcg_gen_movi_tl(t0, v1);
13185 gen_load_gpr(v1_t, v1);
13186 gen_load_gpr(v2_t, v2);
13189 case OPC_SHLL_QB_DSP:
13191 op2 = MASK_SHLL_QB(ctx->opcode);
13195 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13199 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13203 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13207 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13209 case OPC_SHLL_S_PH:
13211 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13213 case OPC_SHLLV_S_PH:
13215 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13219 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13221 case OPC_SHLLV_S_W:
13223 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13227 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13231 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13235 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13239 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13243 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13245 case OPC_SHRA_R_QB:
13247 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13251 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13253 case OPC_SHRAV_R_QB:
13255 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13259 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13261 case OPC_SHRA_R_PH:
13263 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13267 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13269 case OPC_SHRAV_R_PH:
13271 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13275 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13277 case OPC_SHRAV_R_W:
13279 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13281 default: /* Invalid */
13282 MIPS_INVAL("MASK SHLL.QB");
13283 generate_exception(ctx, EXCP_RI);
13288 #ifdef TARGET_MIPS64
13289 case OPC_SHLL_OB_DSP:
13290 op2 = MASK_SHLL_OB(ctx->opcode);
13294 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13298 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13300 case OPC_SHLL_S_PW:
13302 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13304 case OPC_SHLLV_S_PW:
13306 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13310 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13314 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13318 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13322 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13324 case OPC_SHLL_S_QH:
13326 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13328 case OPC_SHLLV_S_QH:
13330 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13334 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13338 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13340 case OPC_SHRA_R_OB:
13342 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13344 case OPC_SHRAV_R_OB:
13346 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13350 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13354 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13356 case OPC_SHRA_R_PW:
13358 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13360 case OPC_SHRAV_R_PW:
13362 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13366 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13370 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13372 case OPC_SHRA_R_QH:
13374 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13376 case OPC_SHRAV_R_QH:
13378 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13382 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13386 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13390 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13394 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13396 default: /* Invalid */
13397 MIPS_INVAL("MASK SHLL.OB");
13398 generate_exception(ctx, EXCP_RI);
13406 tcg_temp_free(v1_t);
13407 tcg_temp_free(v2_t);
13408 (void)opn; /* avoid a compiler warning */
13409 MIPS_DEBUG("%s", opn);
13412 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13413 int ret, int v1, int v2, int check_ret)
13415 const char *opn = "mipsdsp multiply";
13420 if ((ret == 0) && (check_ret == 1)) {
13421 /* Treat as NOP. */
13426 t0 = tcg_temp_new_i32();
13427 v1_t = tcg_temp_new();
13428 v2_t = tcg_temp_new();
13430 tcg_gen_movi_i32(t0, ret);
13431 gen_load_gpr(v1_t, v1);
13432 gen_load_gpr(v2_t, v2);
13435 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13436 * the same mask and op1. */
13437 case OPC_MULT_G_2E:
13440 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13443 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13446 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13448 case OPC_MULQ_RS_W:
13449 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13453 case OPC_DPA_W_PH_DSP:
13455 case OPC_DPAU_H_QBL:
13457 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13459 case OPC_DPAU_H_QBR:
13461 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13463 case OPC_DPSU_H_QBL:
13465 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13467 case OPC_DPSU_H_QBR:
13469 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13473 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13475 case OPC_DPAX_W_PH:
13477 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13479 case OPC_DPAQ_S_W_PH:
13481 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13483 case OPC_DPAQX_S_W_PH:
13485 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13487 case OPC_DPAQX_SA_W_PH:
13489 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13493 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13495 case OPC_DPSX_W_PH:
13497 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13499 case OPC_DPSQ_S_W_PH:
13501 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13503 case OPC_DPSQX_S_W_PH:
13505 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13507 case OPC_DPSQX_SA_W_PH:
13509 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13511 case OPC_MULSAQ_S_W_PH:
13513 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13515 case OPC_DPAQ_SA_L_W:
13517 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13519 case OPC_DPSQ_SA_L_W:
13521 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13523 case OPC_MAQ_S_W_PHL:
13525 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13527 case OPC_MAQ_S_W_PHR:
13529 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13531 case OPC_MAQ_SA_W_PHL:
13533 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13535 case OPC_MAQ_SA_W_PHR:
13537 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13539 case OPC_MULSA_W_PH:
13541 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13545 #ifdef TARGET_MIPS64
13546 case OPC_DPAQ_W_QH_DSP:
13548 int ac = ret & 0x03;
13549 tcg_gen_movi_i32(t0, ac);
13554 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13558 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13562 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13566 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13570 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13572 case OPC_DPAQ_S_W_QH:
13574 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13576 case OPC_DPAQ_SA_L_PW:
13578 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13580 case OPC_DPAU_H_OBL:
13582 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13584 case OPC_DPAU_H_OBR:
13586 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13590 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13592 case OPC_DPSQ_S_W_QH:
13594 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13596 case OPC_DPSQ_SA_L_PW:
13598 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13600 case OPC_DPSU_H_OBL:
13602 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13604 case OPC_DPSU_H_OBR:
13606 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13608 case OPC_MAQ_S_L_PWL:
13610 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13612 case OPC_MAQ_S_L_PWR:
13614 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13616 case OPC_MAQ_S_W_QHLL:
13618 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13620 case OPC_MAQ_SA_W_QHLL:
13622 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13624 case OPC_MAQ_S_W_QHLR:
13626 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13628 case OPC_MAQ_SA_W_QHLR:
13630 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13632 case OPC_MAQ_S_W_QHRL:
13634 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13636 case OPC_MAQ_SA_W_QHRL:
13638 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13640 case OPC_MAQ_S_W_QHRR:
13642 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13644 case OPC_MAQ_SA_W_QHRR:
13646 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13648 case OPC_MULSAQ_S_L_PW:
13650 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13652 case OPC_MULSAQ_S_W_QH:
13654 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13660 case OPC_ADDU_QB_DSP:
13662 case OPC_MULEU_S_PH_QBL:
13664 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13666 case OPC_MULEU_S_PH_QBR:
13668 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13670 case OPC_MULQ_RS_PH:
13672 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13674 case OPC_MULEQ_S_W_PHL:
13676 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13678 case OPC_MULEQ_S_W_PHR:
13680 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13682 case OPC_MULQ_S_PH:
13684 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13688 #ifdef TARGET_MIPS64
13689 case OPC_ADDU_OB_DSP:
13691 case OPC_MULEQ_S_PW_QHL:
13693 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13695 case OPC_MULEQ_S_PW_QHR:
13697 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13699 case OPC_MULEU_S_QH_OBL:
13701 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13703 case OPC_MULEU_S_QH_OBR:
13705 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13707 case OPC_MULQ_RS_QH:
13709 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13716 tcg_temp_free_i32(t0);
13717 tcg_temp_free(v1_t);
13718 tcg_temp_free(v2_t);
13720 (void)opn; /* avoid a compiler warning */
13721 MIPS_DEBUG("%s", opn);
13725 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13726 uint32_t op1, uint32_t op2,
13729 const char *opn = "mipsdsp Bit/ Manipulation";
13735 /* Treat as NOP. */
13740 t0 = tcg_temp_new();
13741 val_t = tcg_temp_new();
13742 gen_load_gpr(val_t, val);
13745 case OPC_ABSQ_S_PH_DSP:
13749 gen_helper_bitrev(cpu_gpr[ret], val_t);
13754 target_long result;
13755 imm = (ctx->opcode >> 16) & 0xFF;
13756 result = (uint32_t)imm << 24 |
13757 (uint32_t)imm << 16 |
13758 (uint32_t)imm << 8 |
13760 result = (int32_t)result;
13761 tcg_gen_movi_tl(cpu_gpr[ret], result);
13766 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13767 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13768 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13769 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13770 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13771 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13776 imm = (ctx->opcode >> 16) & 0x03FF;
13777 tcg_gen_movi_tl(cpu_gpr[ret], \
13778 (target_long)((int32_t)imm << 16 | \
13779 (uint32_t)(uint16_t)imm));
13784 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13785 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13786 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13787 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13791 #ifdef TARGET_MIPS64
13792 case OPC_ABSQ_S_QH_DSP:
13799 imm = (ctx->opcode >> 16) & 0xFF;
13800 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13801 temp = (temp << 16) | temp;
13802 temp = (temp << 32) | temp;
13803 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13811 imm = (ctx->opcode >> 16) & 0x03FF;
13812 imm = (int16_t)(imm << 6) >> 6;
13813 temp = ((target_long)imm << 32) \
13814 | ((target_long)imm & 0xFFFFFFFF);
13815 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13823 imm = (ctx->opcode >> 16) & 0x03FF;
13824 imm = (int16_t)(imm << 6) >> 6;
13826 temp = ((uint64_t)(uint16_t)imm << 48) |
13827 ((uint64_t)(uint16_t)imm << 32) |
13828 ((uint64_t)(uint16_t)imm << 16) |
13829 (uint64_t)(uint16_t)imm;
13830 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13835 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13836 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13837 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13838 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13839 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13840 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13841 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13845 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13846 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13847 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13851 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13852 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13853 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13854 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13855 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13862 tcg_temp_free(val_t);
13864 (void)opn; /* avoid a compiler warning */
13865 MIPS_DEBUG("%s", opn);
13868 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13869 uint32_t op1, uint32_t op2,
13870 int ret, int v1, int v2, int check_ret)
13872 const char *opn = "mipsdsp add compare pick";
13878 if ((ret == 0) && (check_ret == 1)) {
13879 /* Treat as NOP. */
13884 t0 = tcg_temp_new_i32();
13885 t1 = tcg_temp_new();
13886 v1_t = tcg_temp_new();
13887 v2_t = tcg_temp_new();
13889 gen_load_gpr(v1_t, v1);
13890 gen_load_gpr(v2_t, v2);
13893 case OPC_APPEND_DSP:
13896 tcg_gen_movi_i32(t0, v2);
13897 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13900 tcg_gen_movi_i32(t0, v2);
13901 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13904 tcg_gen_movi_i32(t0, v2);
13905 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13907 default: /* Invid */
13908 MIPS_INVAL("MASK APPEND");
13909 generate_exception(ctx, EXCP_RI);
13913 case OPC_CMPU_EQ_QB_DSP:
13915 case OPC_CMPU_EQ_QB:
13917 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13919 case OPC_CMPU_LT_QB:
13921 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13923 case OPC_CMPU_LE_QB:
13925 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13927 case OPC_CMPGU_EQ_QB:
13929 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13931 case OPC_CMPGU_LT_QB:
13933 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13935 case OPC_CMPGU_LE_QB:
13937 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13939 case OPC_CMPGDU_EQ_QB:
13941 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13942 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13943 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13944 tcg_gen_shli_tl(t1, t1, 24);
13945 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13947 case OPC_CMPGDU_LT_QB:
13949 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13950 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13951 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13952 tcg_gen_shli_tl(t1, t1, 24);
13953 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13955 case OPC_CMPGDU_LE_QB:
13957 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13958 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13959 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13960 tcg_gen_shli_tl(t1, t1, 24);
13961 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13963 case OPC_CMP_EQ_PH:
13965 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13967 case OPC_CMP_LT_PH:
13969 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13971 case OPC_CMP_LE_PH:
13973 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13977 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13981 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13983 case OPC_PACKRL_PH:
13985 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13989 #ifdef TARGET_MIPS64
13990 case OPC_CMPU_EQ_OB_DSP:
13992 case OPC_CMP_EQ_PW:
13994 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13996 case OPC_CMP_LT_PW:
13998 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14000 case OPC_CMP_LE_PW:
14002 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14004 case OPC_CMP_EQ_QH:
14006 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14008 case OPC_CMP_LT_QH:
14010 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14012 case OPC_CMP_LE_QH:
14014 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14016 case OPC_CMPGDU_EQ_OB:
14018 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14020 case OPC_CMPGDU_LT_OB:
14022 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14024 case OPC_CMPGDU_LE_OB:
14026 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14028 case OPC_CMPGU_EQ_OB:
14030 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14032 case OPC_CMPGU_LT_OB:
14034 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14036 case OPC_CMPGU_LE_OB:
14038 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14040 case OPC_CMPU_EQ_OB:
14042 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14044 case OPC_CMPU_LT_OB:
14046 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14048 case OPC_CMPU_LE_OB:
14050 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14052 case OPC_PACKRL_PW:
14054 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14058 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14062 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14066 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14070 case OPC_DAPPEND_DSP:
14073 tcg_gen_movi_i32(t0, v2);
14074 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14077 tcg_gen_movi_i32(t0, v2);
14078 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14081 tcg_gen_movi_i32(t0, v2);
14082 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14085 tcg_gen_movi_i32(t0, v2);
14086 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14088 default: /* Invalid */
14089 MIPS_INVAL("MASK DAPPEND");
14090 generate_exception(ctx, EXCP_RI);
14097 tcg_temp_free_i32(t0);
14099 tcg_temp_free(v1_t);
14100 tcg_temp_free(v2_t);
14102 (void)opn; /* avoid a compiler warning */
14103 MIPS_DEBUG("%s", opn);
14106 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14107 int ret, int v1, int v2, int check_ret)
14110 const char *opn = "mipsdsp accumulator";
14117 if ((ret == 0) && (check_ret == 1)) {
14118 /* Treat as NOP. */
14123 t0 = tcg_temp_new();
14124 t1 = tcg_temp_new();
14125 v1_t = tcg_temp_new();
14126 v2_t = tcg_temp_new();
14128 gen_load_gpr(v1_t, v1);
14129 gen_load_gpr(v2_t, v2);
14132 case OPC_EXTR_W_DSP:
14136 tcg_gen_movi_tl(t0, v2);
14137 tcg_gen_movi_tl(t1, v1);
14138 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14141 tcg_gen_movi_tl(t0, v2);
14142 tcg_gen_movi_tl(t1, v1);
14143 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14145 case OPC_EXTR_RS_W:
14146 tcg_gen_movi_tl(t0, v2);
14147 tcg_gen_movi_tl(t1, v1);
14148 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14151 tcg_gen_movi_tl(t0, v2);
14152 tcg_gen_movi_tl(t1, v1);
14153 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14155 case OPC_EXTRV_S_H:
14156 tcg_gen_movi_tl(t0, v2);
14157 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14160 tcg_gen_movi_tl(t0, v2);
14161 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14163 case OPC_EXTRV_R_W:
14164 tcg_gen_movi_tl(t0, v2);
14165 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14167 case OPC_EXTRV_RS_W:
14168 tcg_gen_movi_tl(t0, v2);
14169 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14172 tcg_gen_movi_tl(t0, v2);
14173 tcg_gen_movi_tl(t1, v1);
14174 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14177 tcg_gen_movi_tl(t0, v2);
14178 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14181 tcg_gen_movi_tl(t0, v2);
14182 tcg_gen_movi_tl(t1, v1);
14183 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14186 tcg_gen_movi_tl(t0, v2);
14187 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14190 imm = (ctx->opcode >> 20) & 0x3F;
14191 tcg_gen_movi_tl(t0, ret);
14192 tcg_gen_movi_tl(t1, imm);
14193 gen_helper_shilo(t0, t1, cpu_env);
14196 tcg_gen_movi_tl(t0, ret);
14197 gen_helper_shilo(t0, v1_t, cpu_env);
14200 tcg_gen_movi_tl(t0, ret);
14201 gen_helper_mthlip(t0, v1_t, cpu_env);
14204 imm = (ctx->opcode >> 11) & 0x3FF;
14205 tcg_gen_movi_tl(t0, imm);
14206 gen_helper_wrdsp(v1_t, t0, cpu_env);
14209 imm = (ctx->opcode >> 16) & 0x03FF;
14210 tcg_gen_movi_tl(t0, imm);
14211 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14215 #ifdef TARGET_MIPS64
14216 case OPC_DEXTR_W_DSP:
14220 tcg_gen_movi_tl(t0, ret);
14221 gen_helper_dmthlip(v1_t, t0, cpu_env);
14225 int shift = (ctx->opcode >> 19) & 0x7F;
14226 int ac = (ctx->opcode >> 11) & 0x03;
14227 tcg_gen_movi_tl(t0, shift);
14228 tcg_gen_movi_tl(t1, ac);
14229 gen_helper_dshilo(t0, t1, cpu_env);
14234 int ac = (ctx->opcode >> 11) & 0x03;
14235 tcg_gen_movi_tl(t0, ac);
14236 gen_helper_dshilo(v1_t, t0, cpu_env);
14240 tcg_gen_movi_tl(t0, v2);
14241 tcg_gen_movi_tl(t1, v1);
14243 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14246 tcg_gen_movi_tl(t0, v2);
14247 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14250 tcg_gen_movi_tl(t0, v2);
14251 tcg_gen_movi_tl(t1, v1);
14252 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14255 tcg_gen_movi_tl(t0, v2);
14256 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14259 tcg_gen_movi_tl(t0, v2);
14260 tcg_gen_movi_tl(t1, v1);
14261 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14263 case OPC_DEXTR_R_L:
14264 tcg_gen_movi_tl(t0, v2);
14265 tcg_gen_movi_tl(t1, v1);
14266 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14268 case OPC_DEXTR_RS_L:
14269 tcg_gen_movi_tl(t0, v2);
14270 tcg_gen_movi_tl(t1, v1);
14271 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14274 tcg_gen_movi_tl(t0, v2);
14275 tcg_gen_movi_tl(t1, v1);
14276 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14278 case OPC_DEXTR_R_W:
14279 tcg_gen_movi_tl(t0, v2);
14280 tcg_gen_movi_tl(t1, v1);
14281 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14283 case OPC_DEXTR_RS_W:
14284 tcg_gen_movi_tl(t0, v2);
14285 tcg_gen_movi_tl(t1, v1);
14286 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14288 case OPC_DEXTR_S_H:
14289 tcg_gen_movi_tl(t0, v2);
14290 tcg_gen_movi_tl(t1, v1);
14291 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14293 case OPC_DEXTRV_S_H:
14294 tcg_gen_movi_tl(t0, v2);
14295 tcg_gen_movi_tl(t1, v1);
14296 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14299 tcg_gen_movi_tl(t0, v2);
14300 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14302 case OPC_DEXTRV_R_L:
14303 tcg_gen_movi_tl(t0, v2);
14304 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14306 case OPC_DEXTRV_RS_L:
14307 tcg_gen_movi_tl(t0, v2);
14308 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14311 tcg_gen_movi_tl(t0, v2);
14312 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14314 case OPC_DEXTRV_R_W:
14315 tcg_gen_movi_tl(t0, v2);
14316 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14318 case OPC_DEXTRV_RS_W:
14319 tcg_gen_movi_tl(t0, v2);
14320 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14329 tcg_temp_free(v1_t);
14330 tcg_temp_free(v2_t);
14332 (void)opn; /* avoid a compiler warning */
14333 MIPS_DEBUG("%s", opn);
14336 /* End MIPSDSP functions. */
14338 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14341 int rs, rt, rd, sa;
14342 uint32_t op, op1, op2;
14345 /* make sure instructions are on a word boundary */
14346 if (ctx->pc & 0x3) {
14347 env->CP0_BadVAddr = ctx->pc;
14348 generate_exception(ctx, EXCP_AdEL);
14352 /* Handle blikely not taken case */
14353 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14354 int l1 = gen_new_label();
14356 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14357 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14358 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14359 gen_goto_tb(ctx, 1, ctx->pc + 4);
14363 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14364 tcg_gen_debug_insn_start(ctx->pc);
14367 op = MASK_OP_MAJOR(ctx->opcode);
14368 rs = (ctx->opcode >> 21) & 0x1f;
14369 rt = (ctx->opcode >> 16) & 0x1f;
14370 rd = (ctx->opcode >> 11) & 0x1f;
14371 sa = (ctx->opcode >> 6) & 0x1f;
14372 imm = (int16_t)ctx->opcode;
14375 op1 = MASK_SPECIAL(ctx->opcode);
14377 case OPC_SLL: /* Shift with immediate */
14379 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14382 switch ((ctx->opcode >> 21) & 0x1f) {
14384 /* rotr is decoded as srl on non-R2 CPUs */
14385 if (env->insn_flags & ISA_MIPS32R2) {
14390 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14393 generate_exception(ctx, EXCP_RI);
14397 case OPC_MOVN: /* Conditional move */
14399 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14400 INSN_LOONGSON2E | INSN_LOONGSON2F);
14401 gen_cond_move(env, ctx, op1, rd, rs, rt);
14403 case OPC_ADD ... OPC_SUBU:
14404 gen_arith(env, ctx, op1, rd, rs, rt);
14406 case OPC_SLLV: /* Shifts */
14408 gen_shift(env, ctx, op1, rd, rs, rt);
14411 switch ((ctx->opcode >> 6) & 0x1f) {
14413 /* rotrv is decoded as srlv on non-R2 CPUs */
14414 if (env->insn_flags & ISA_MIPS32R2) {
14419 gen_shift(env, ctx, op1, rd, rs, rt);
14422 generate_exception(ctx, EXCP_RI);
14426 case OPC_SLT: /* Set on less than */
14428 gen_slt(env, ctx, op1, rd, rs, rt);
14430 case OPC_AND: /* Logic*/
14434 gen_logic(env, ctx, op1, rd, rs, rt);
14436 case OPC_MULT ... OPC_DIVU:
14438 check_insn(env, ctx, INSN_VR54XX);
14439 op1 = MASK_MUL_VR54XX(ctx->opcode);
14440 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14442 gen_muldiv(ctx, op1, rs, rt);
14444 case OPC_JR ... OPC_JALR:
14445 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14448 case OPC_TGE ... OPC_TEQ: /* Traps */
14450 gen_trap(ctx, op1, rs, rt, -1);
14452 case OPC_MFHI: /* Move from HI/LO */
14454 gen_HILO(ctx, op1, rd);
14457 case OPC_MTLO: /* Move to HI/LO */
14458 gen_HILO(ctx, op1, rs);
14460 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14461 #ifdef MIPS_STRICT_STANDARD
14462 MIPS_INVAL("PMON / selsl");
14463 generate_exception(ctx, EXCP_RI);
14465 gen_helper_0e0i(pmon, sa);
14469 generate_exception(ctx, EXCP_SYSCALL);
14470 ctx->bstate = BS_STOP;
14473 generate_exception(ctx, EXCP_BREAK);
14476 #ifdef MIPS_STRICT_STANDARD
14477 MIPS_INVAL("SPIM");
14478 generate_exception(ctx, EXCP_RI);
14480 /* Implemented as RI exception for now. */
14481 MIPS_INVAL("spim (unofficial)");
14482 generate_exception(ctx, EXCP_RI);
14486 /* Treat as NOP. */
14490 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14491 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14492 check_cp1_enabled(ctx);
14493 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14494 (ctx->opcode >> 16) & 1);
14496 generate_exception_err(ctx, EXCP_CpU, 1);
14500 #if defined(TARGET_MIPS64)
14501 /* MIPS64 specific opcodes */
14506 check_insn(env, ctx, ISA_MIPS3);
14507 check_mips_64(ctx);
14508 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14511 switch ((ctx->opcode >> 21) & 0x1f) {
14513 /* drotr is decoded as dsrl on non-R2 CPUs */
14514 if (env->insn_flags & ISA_MIPS32R2) {
14519 check_insn(env, ctx, ISA_MIPS3);
14520 check_mips_64(ctx);
14521 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14524 generate_exception(ctx, EXCP_RI);
14529 switch ((ctx->opcode >> 21) & 0x1f) {
14531 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14532 if (env->insn_flags & ISA_MIPS32R2) {
14537 check_insn(env, ctx, ISA_MIPS3);
14538 check_mips_64(ctx);
14539 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14542 generate_exception(ctx, EXCP_RI);
14546 case OPC_DADD ... OPC_DSUBU:
14547 check_insn(env, ctx, ISA_MIPS3);
14548 check_mips_64(ctx);
14549 gen_arith(env, ctx, op1, rd, rs, rt);
14553 check_insn(env, ctx, ISA_MIPS3);
14554 check_mips_64(ctx);
14555 gen_shift(env, ctx, op1, rd, rs, rt);
14558 switch ((ctx->opcode >> 6) & 0x1f) {
14560 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14561 if (env->insn_flags & ISA_MIPS32R2) {
14566 check_insn(env, ctx, ISA_MIPS3);
14567 check_mips_64(ctx);
14568 gen_shift(env, ctx, op1, rd, rs, rt);
14571 generate_exception(ctx, EXCP_RI);
14575 case OPC_DMULT ... OPC_DDIVU:
14576 check_insn(env, ctx, ISA_MIPS3);
14577 check_mips_64(ctx);
14578 gen_muldiv(ctx, op1, rs, rt);
14581 default: /* Invalid */
14582 MIPS_INVAL("special");
14583 generate_exception(ctx, EXCP_RI);
14588 op1 = MASK_SPECIAL2(ctx->opcode);
14590 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14591 case OPC_MSUB ... OPC_MSUBU:
14592 check_insn(env, ctx, ISA_MIPS32);
14593 gen_muldiv(ctx, op1, rs, rt);
14596 gen_arith(env, ctx, op1, rd, rs, rt);
14600 check_insn(env, ctx, ISA_MIPS32);
14601 gen_cl(ctx, op1, rd, rs);
14604 /* XXX: not clear which exception should be raised
14605 * when in debug mode...
14607 check_insn(env, ctx, ISA_MIPS32);
14608 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14609 generate_exception(ctx, EXCP_DBp);
14611 generate_exception(ctx, EXCP_DBp);
14613 /* Treat as NOP. */
14616 case OPC_DIVU_G_2F:
14617 case OPC_MULT_G_2F:
14618 case OPC_MULTU_G_2F:
14620 case OPC_MODU_G_2F:
14621 check_insn(env, ctx, INSN_LOONGSON2F);
14622 gen_loongson_integer(ctx, op1, rd, rs, rt);
14624 #if defined(TARGET_MIPS64)
14627 check_insn(env, ctx, ISA_MIPS64);
14628 check_mips_64(ctx);
14629 gen_cl(ctx, op1, rd, rs);
14631 case OPC_DMULT_G_2F:
14632 case OPC_DMULTU_G_2F:
14633 case OPC_DDIV_G_2F:
14634 case OPC_DDIVU_G_2F:
14635 case OPC_DMOD_G_2F:
14636 case OPC_DMODU_G_2F:
14637 check_insn(env, ctx, INSN_LOONGSON2F);
14638 gen_loongson_integer(ctx, op1, rd, rs, rt);
14641 default: /* Invalid */
14642 MIPS_INVAL("special2");
14643 generate_exception(ctx, EXCP_RI);
14648 op1 = MASK_SPECIAL3(ctx->opcode);
14652 check_insn(env, ctx, ISA_MIPS32R2);
14653 gen_bitops(ctx, op1, rt, rs, sa, rd);
14656 check_insn(env, ctx, ISA_MIPS32R2);
14657 op2 = MASK_BSHFL(ctx->opcode);
14658 gen_bshfl(ctx, op2, rt, rd);
14661 gen_rdhwr(env, ctx, rt, rd);
14664 check_insn(env, ctx, ASE_MT);
14666 TCGv t0 = tcg_temp_new();
14667 TCGv t1 = tcg_temp_new();
14669 gen_load_gpr(t0, rt);
14670 gen_load_gpr(t1, rs);
14671 gen_helper_fork(t0, t1);
14677 check_insn(env, ctx, ASE_MT);
14679 TCGv t0 = tcg_temp_new();
14681 save_cpu_state(ctx, 1);
14682 gen_load_gpr(t0, rs);
14683 gen_helper_yield(t0, cpu_env, t0);
14684 gen_store_gpr(t0, rd);
14688 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14689 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14690 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14691 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14692 * the same mask and op1. */
14693 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14694 op2 = MASK_ADDUH_QB(ctx->opcode);
14697 case OPC_ADDUH_R_QB:
14699 case OPC_ADDQH_R_PH:
14701 case OPC_ADDQH_R_W:
14703 case OPC_SUBUH_R_QB:
14705 case OPC_SUBQH_R_PH:
14707 case OPC_SUBQH_R_W:
14708 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14713 case OPC_MULQ_RS_W:
14714 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14717 MIPS_INVAL("MASK ADDUH.QB");
14718 generate_exception(ctx, EXCP_RI);
14721 } else if (env->insn_flags & INSN_LOONGSON2E) {
14722 gen_loongson_integer(ctx, op1, rd, rs, rt);
14724 generate_exception(ctx, EXCP_RI);
14728 op2 = MASK_LX(ctx->opcode);
14730 #if defined(TARGET_MIPS64)
14736 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14738 default: /* Invalid */
14739 MIPS_INVAL("MASK LX");
14740 generate_exception(ctx, EXCP_RI);
14744 case OPC_ABSQ_S_PH_DSP:
14745 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14747 case OPC_ABSQ_S_QB:
14748 case OPC_ABSQ_S_PH:
14750 case OPC_PRECEQ_W_PHL:
14751 case OPC_PRECEQ_W_PHR:
14752 case OPC_PRECEQU_PH_QBL:
14753 case OPC_PRECEQU_PH_QBR:
14754 case OPC_PRECEQU_PH_QBLA:
14755 case OPC_PRECEQU_PH_QBRA:
14756 case OPC_PRECEU_PH_QBL:
14757 case OPC_PRECEU_PH_QBR:
14758 case OPC_PRECEU_PH_QBLA:
14759 case OPC_PRECEU_PH_QBRA:
14760 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14767 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14770 MIPS_INVAL("MASK ABSQ_S.PH");
14771 generate_exception(ctx, EXCP_RI);
14775 case OPC_ADDU_QB_DSP:
14776 op2 = MASK_ADDU_QB(ctx->opcode);
14779 case OPC_ADDQ_S_PH:
14782 case OPC_ADDU_S_QB:
14784 case OPC_ADDU_S_PH:
14786 case OPC_SUBQ_S_PH:
14789 case OPC_SUBU_S_QB:
14791 case OPC_SUBU_S_PH:
14795 case OPC_RADDU_W_QB:
14796 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14798 case OPC_MULEU_S_PH_QBL:
14799 case OPC_MULEU_S_PH_QBR:
14800 case OPC_MULQ_RS_PH:
14801 case OPC_MULEQ_S_W_PHL:
14802 case OPC_MULEQ_S_W_PHR:
14803 case OPC_MULQ_S_PH:
14804 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14806 default: /* Invalid */
14807 MIPS_INVAL("MASK ADDU.QB");
14808 generate_exception(ctx, EXCP_RI);
14813 case OPC_CMPU_EQ_QB_DSP:
14814 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14816 case OPC_PRECR_SRA_PH_W:
14817 case OPC_PRECR_SRA_R_PH_W:
14818 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14820 case OPC_PRECR_QB_PH:
14821 case OPC_PRECRQ_QB_PH:
14822 case OPC_PRECRQ_PH_W:
14823 case OPC_PRECRQ_RS_PH_W:
14824 case OPC_PRECRQU_S_QB_PH:
14825 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14827 case OPC_CMPU_EQ_QB:
14828 case OPC_CMPU_LT_QB:
14829 case OPC_CMPU_LE_QB:
14830 case OPC_CMP_EQ_PH:
14831 case OPC_CMP_LT_PH:
14832 case OPC_CMP_LE_PH:
14833 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14835 case OPC_CMPGU_EQ_QB:
14836 case OPC_CMPGU_LT_QB:
14837 case OPC_CMPGU_LE_QB:
14838 case OPC_CMPGDU_EQ_QB:
14839 case OPC_CMPGDU_LT_QB:
14840 case OPC_CMPGDU_LE_QB:
14843 case OPC_PACKRL_PH:
14844 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14846 default: /* Invalid */
14847 MIPS_INVAL("MASK CMPU.EQ.QB");
14848 generate_exception(ctx, EXCP_RI);
14852 case OPC_SHLL_QB_DSP:
14853 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14855 case OPC_DPA_W_PH_DSP:
14856 op2 = MASK_DPA_W_PH(ctx->opcode);
14858 case OPC_DPAU_H_QBL:
14859 case OPC_DPAU_H_QBR:
14860 case OPC_DPSU_H_QBL:
14861 case OPC_DPSU_H_QBR:
14863 case OPC_DPAX_W_PH:
14864 case OPC_DPAQ_S_W_PH:
14865 case OPC_DPAQX_S_W_PH:
14866 case OPC_DPAQX_SA_W_PH:
14868 case OPC_DPSX_W_PH:
14869 case OPC_DPSQ_S_W_PH:
14870 case OPC_DPSQX_S_W_PH:
14871 case OPC_DPSQX_SA_W_PH:
14872 case OPC_MULSAQ_S_W_PH:
14873 case OPC_DPAQ_SA_L_W:
14874 case OPC_DPSQ_SA_L_W:
14875 case OPC_MAQ_S_W_PHL:
14876 case OPC_MAQ_S_W_PHR:
14877 case OPC_MAQ_SA_W_PHL:
14878 case OPC_MAQ_SA_W_PHR:
14879 case OPC_MULSA_W_PH:
14880 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14882 default: /* Invalid */
14883 MIPS_INVAL("MASK DPAW.PH");
14884 generate_exception(ctx, EXCP_RI);
14889 op2 = MASK_INSV(ctx->opcode);
14901 t0 = tcg_temp_new();
14902 t1 = tcg_temp_new();
14904 gen_load_gpr(t0, rt);
14905 gen_load_gpr(t1, rs);
14907 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14913 default: /* Invalid */
14914 MIPS_INVAL("MASK INSV");
14915 generate_exception(ctx, EXCP_RI);
14919 case OPC_APPEND_DSP:
14921 op2 = MASK_APPEND(ctx->opcode);
14922 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14924 case OPC_EXTR_W_DSP:
14925 op2 = MASK_EXTR_W(ctx->opcode);
14929 case OPC_EXTR_RS_W:
14931 case OPC_EXTRV_S_H:
14933 case OPC_EXTRV_R_W:
14934 case OPC_EXTRV_RS_W:
14939 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14942 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14948 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14950 default: /* Invalid */
14951 MIPS_INVAL("MASK EXTR.W");
14952 generate_exception(ctx, EXCP_RI);
14956 #if defined(TARGET_MIPS64)
14957 case OPC_DEXTM ... OPC_DEXT:
14958 case OPC_DINSM ... OPC_DINS:
14959 check_insn(env, ctx, ISA_MIPS64R2);
14960 check_mips_64(ctx);
14961 gen_bitops(ctx, op1, rt, rs, sa, rd);
14964 check_insn(env, ctx, ISA_MIPS64R2);
14965 check_mips_64(ctx);
14966 op2 = MASK_DBSHFL(ctx->opcode);
14967 gen_bshfl(ctx, op2, rt, rd);
14969 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14970 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14971 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14972 check_insn(env, ctx, INSN_LOONGSON2E);
14973 gen_loongson_integer(ctx, op1, rd, rs, rt);
14975 case OPC_ABSQ_S_QH_DSP:
14976 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14978 case OPC_PRECEQ_L_PWL:
14979 case OPC_PRECEQ_L_PWR:
14980 case OPC_PRECEQ_PW_QHL:
14981 case OPC_PRECEQ_PW_QHR:
14982 case OPC_PRECEQ_PW_QHLA:
14983 case OPC_PRECEQ_PW_QHRA:
14984 case OPC_PRECEQU_QH_OBL:
14985 case OPC_PRECEQU_QH_OBR:
14986 case OPC_PRECEQU_QH_OBLA:
14987 case OPC_PRECEQU_QH_OBRA:
14988 case OPC_PRECEU_QH_OBL:
14989 case OPC_PRECEU_QH_OBR:
14990 case OPC_PRECEU_QH_OBLA:
14991 case OPC_PRECEU_QH_OBRA:
14992 case OPC_ABSQ_S_OB:
14993 case OPC_ABSQ_S_PW:
14994 case OPC_ABSQ_S_QH:
14995 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15003 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
15005 default: /* Invalid */
15006 MIPS_INVAL("MASK ABSQ_S.QH");
15007 generate_exception(ctx, EXCP_RI);
15011 case OPC_ADDU_OB_DSP:
15012 op2 = MASK_ADDU_OB(ctx->opcode);
15014 case OPC_RADDU_L_OB:
15016 case OPC_SUBQ_S_PW:
15018 case OPC_SUBQ_S_QH:
15020 case OPC_SUBU_S_OB:
15022 case OPC_SUBU_S_QH:
15024 case OPC_SUBUH_R_OB:
15026 case OPC_ADDQ_S_PW:
15028 case OPC_ADDQ_S_QH:
15030 case OPC_ADDU_S_OB:
15032 case OPC_ADDU_S_QH:
15034 case OPC_ADDUH_R_OB:
15035 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15037 case OPC_MULEQ_S_PW_QHL:
15038 case OPC_MULEQ_S_PW_QHR:
15039 case OPC_MULEU_S_QH_OBL:
15040 case OPC_MULEU_S_QH_OBR:
15041 case OPC_MULQ_RS_QH:
15042 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15044 default: /* Invalid */
15045 MIPS_INVAL("MASK ADDU.OB");
15046 generate_exception(ctx, EXCP_RI);
15050 case OPC_CMPU_EQ_OB_DSP:
15051 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15053 case OPC_PRECR_SRA_QH_PW:
15054 case OPC_PRECR_SRA_R_QH_PW:
15055 /* Return value is rt. */
15056 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15058 case OPC_PRECR_OB_QH:
15059 case OPC_PRECRQ_OB_QH:
15060 case OPC_PRECRQ_PW_L:
15061 case OPC_PRECRQ_QH_PW:
15062 case OPC_PRECRQ_RS_QH_PW:
15063 case OPC_PRECRQU_S_OB_QH:
15064 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15066 case OPC_CMPU_EQ_OB:
15067 case OPC_CMPU_LT_OB:
15068 case OPC_CMPU_LE_OB:
15069 case OPC_CMP_EQ_QH:
15070 case OPC_CMP_LT_QH:
15071 case OPC_CMP_LE_QH:
15072 case OPC_CMP_EQ_PW:
15073 case OPC_CMP_LT_PW:
15074 case OPC_CMP_LE_PW:
15075 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15077 case OPC_CMPGDU_EQ_OB:
15078 case OPC_CMPGDU_LT_OB:
15079 case OPC_CMPGDU_LE_OB:
15080 case OPC_CMPGU_EQ_OB:
15081 case OPC_CMPGU_LT_OB:
15082 case OPC_CMPGU_LE_OB:
15083 case OPC_PACKRL_PW:
15087 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15089 default: /* Invalid */
15090 MIPS_INVAL("MASK CMPU_EQ.OB");
15091 generate_exception(ctx, EXCP_RI);
15095 case OPC_DAPPEND_DSP:
15097 op2 = MASK_DAPPEND(ctx->opcode);
15098 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15100 case OPC_DEXTR_W_DSP:
15101 op2 = MASK_DEXTR_W(ctx->opcode);
15108 case OPC_DEXTR_R_L:
15109 case OPC_DEXTR_RS_L:
15111 case OPC_DEXTR_R_W:
15112 case OPC_DEXTR_RS_W:
15113 case OPC_DEXTR_S_H:
15115 case OPC_DEXTRV_R_L:
15116 case OPC_DEXTRV_RS_L:
15117 case OPC_DEXTRV_S_H:
15119 case OPC_DEXTRV_R_W:
15120 case OPC_DEXTRV_RS_W:
15121 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15126 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15128 default: /* Invalid */
15129 MIPS_INVAL("MASK EXTR.W");
15130 generate_exception(ctx, EXCP_RI);
15134 case OPC_DPAQ_W_QH_DSP:
15135 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15137 case OPC_DPAU_H_OBL:
15138 case OPC_DPAU_H_OBR:
15139 case OPC_DPSU_H_OBL:
15140 case OPC_DPSU_H_OBR:
15142 case OPC_DPAQ_S_W_QH:
15144 case OPC_DPSQ_S_W_QH:
15145 case OPC_MULSAQ_S_W_QH:
15146 case OPC_DPAQ_SA_L_PW:
15147 case OPC_DPSQ_SA_L_PW:
15148 case OPC_MULSAQ_S_L_PW:
15149 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15151 case OPC_MAQ_S_W_QHLL:
15152 case OPC_MAQ_S_W_QHLR:
15153 case OPC_MAQ_S_W_QHRL:
15154 case OPC_MAQ_S_W_QHRR:
15155 case OPC_MAQ_SA_W_QHLL:
15156 case OPC_MAQ_SA_W_QHLR:
15157 case OPC_MAQ_SA_W_QHRL:
15158 case OPC_MAQ_SA_W_QHRR:
15159 case OPC_MAQ_S_L_PWL:
15160 case OPC_MAQ_S_L_PWR:
15165 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15167 default: /* Invalid */
15168 MIPS_INVAL("MASK DPAQ.W.QH");
15169 generate_exception(ctx, EXCP_RI);
15173 case OPC_DINSV_DSP:
15174 op2 = MASK_INSV(ctx->opcode);
15186 t0 = tcg_temp_new();
15187 t1 = tcg_temp_new();
15189 gen_load_gpr(t0, rt);
15190 gen_load_gpr(t1, rs);
15192 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15195 default: /* Invalid */
15196 MIPS_INVAL("MASK DINSV");
15197 generate_exception(ctx, EXCP_RI);
15201 case OPC_SHLL_OB_DSP:
15202 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15205 default: /* Invalid */
15206 MIPS_INVAL("special3");
15207 generate_exception(ctx, EXCP_RI);
15212 op1 = MASK_REGIMM(ctx->opcode);
15214 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15215 case OPC_BLTZAL ... OPC_BGEZALL:
15216 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15219 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15221 gen_trap(ctx, op1, rs, -1, imm);
15224 check_insn(env, ctx, ISA_MIPS32R2);
15225 /* Treat as NOP. */
15227 case OPC_BPOSGE32: /* MIPS DSP branch */
15228 #if defined(TARGET_MIPS64)
15232 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15235 default: /* Invalid */
15236 MIPS_INVAL("regimm");
15237 generate_exception(ctx, EXCP_RI);
15242 check_cp0_enabled(ctx);
15243 op1 = MASK_CP0(ctx->opcode);
15249 #if defined(TARGET_MIPS64)
15253 #ifndef CONFIG_USER_ONLY
15254 gen_cp0(env, ctx, op1, rt, rd);
15255 #endif /* !CONFIG_USER_ONLY */
15257 case OPC_C0_FIRST ... OPC_C0_LAST:
15258 #ifndef CONFIG_USER_ONLY
15259 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15260 #endif /* !CONFIG_USER_ONLY */
15263 #ifndef CONFIG_USER_ONLY
15265 TCGv t0 = tcg_temp_new();
15267 op2 = MASK_MFMC0(ctx->opcode);
15270 check_insn(env, ctx, ASE_MT);
15271 gen_helper_dmt(t0);
15272 gen_store_gpr(t0, rt);
15275 check_insn(env, ctx, ASE_MT);
15276 gen_helper_emt(t0);
15277 gen_store_gpr(t0, rt);
15280 check_insn(env, ctx, ASE_MT);
15281 gen_helper_dvpe(t0, cpu_env);
15282 gen_store_gpr(t0, rt);
15285 check_insn(env, ctx, ASE_MT);
15286 gen_helper_evpe(t0, cpu_env);
15287 gen_store_gpr(t0, rt);
15290 check_insn(env, ctx, ISA_MIPS32R2);
15291 save_cpu_state(ctx, 1);
15292 gen_helper_di(t0, cpu_env);
15293 gen_store_gpr(t0, rt);
15294 /* Stop translation as we may have switched the execution mode */
15295 ctx->bstate = BS_STOP;
15298 check_insn(env, ctx, ISA_MIPS32R2);
15299 save_cpu_state(ctx, 1);
15300 gen_helper_ei(t0, cpu_env);
15301 gen_store_gpr(t0, rt);
15302 /* Stop translation as we may have switched the execution mode */
15303 ctx->bstate = BS_STOP;
15305 default: /* Invalid */
15306 MIPS_INVAL("mfmc0");
15307 generate_exception(ctx, EXCP_RI);
15312 #endif /* !CONFIG_USER_ONLY */
15315 check_insn(env, ctx, ISA_MIPS32R2);
15316 gen_load_srsgpr(rt, rd);
15319 check_insn(env, ctx, ISA_MIPS32R2);
15320 gen_store_srsgpr(rt, rd);
15324 generate_exception(ctx, EXCP_RI);
15328 case OPC_ADDI: /* Arithmetic with immediate opcode */
15330 gen_arith_imm(env, ctx, op, rt, rs, imm);
15332 case OPC_SLTI: /* Set on less than with immediate opcode */
15334 gen_slt_imm(env, ctx, op, rt, rs, imm);
15336 case OPC_ANDI: /* Arithmetic with immediate opcode */
15340 gen_logic_imm(env, ctx, op, rt, rs, imm);
15342 case OPC_J ... OPC_JAL: /* Jump */
15343 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15344 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15347 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15348 case OPC_BEQL ... OPC_BGTZL:
15349 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15352 case OPC_LB ... OPC_LWR: /* Load and stores */
15354 gen_ld(env, ctx, op, rt, rs, imm);
15356 case OPC_SB ... OPC_SW:
15358 gen_st(ctx, op, rt, rs, imm);
15361 gen_st_cond(ctx, op, rt, rs, imm);
15364 check_cp0_enabled(ctx);
15365 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15366 /* Treat as NOP. */
15369 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15370 /* Treat as NOP. */
15373 /* Floating point (COP1). */
15378 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15382 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15383 check_cp1_enabled(ctx);
15384 op1 = MASK_CP1(ctx->opcode);
15388 check_insn(env, ctx, ISA_MIPS32R2);
15393 gen_cp1(ctx, op1, rt, rd);
15395 #if defined(TARGET_MIPS64)
15398 check_insn(env, ctx, ISA_MIPS3);
15399 gen_cp1(ctx, op1, rt, rd);
15405 check_insn(env, ctx, ASE_MIPS3D);
15408 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15409 (rt >> 2) & 0x7, imm << 2);
15417 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15422 generate_exception (ctx, EXCP_RI);
15426 generate_exception_err(ctx, EXCP_CpU, 1);
15435 /* COP2: Not implemented. */
15436 generate_exception_err(ctx, EXCP_CpU, 2);
15439 check_insn(env, ctx, INSN_LOONGSON2F);
15440 /* Note that these instructions use different fields. */
15441 gen_loongson_multimedia(ctx, sa, rd, rt);
15445 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15446 check_cp1_enabled(ctx);
15447 op1 = MASK_CP3(ctx->opcode);
15455 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15458 /* Treat as NOP. */
15473 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15477 generate_exception (ctx, EXCP_RI);
15481 generate_exception_err(ctx, EXCP_CpU, 1);
15485 #if defined(TARGET_MIPS64)
15486 /* MIPS64 opcodes */
15488 case OPC_LDL ... OPC_LDR:
15491 check_insn(env, ctx, ISA_MIPS3);
15492 check_mips_64(ctx);
15493 gen_ld(env, ctx, op, rt, rs, imm);
15495 case OPC_SDL ... OPC_SDR:
15497 check_insn(env, ctx, ISA_MIPS3);
15498 check_mips_64(ctx);
15499 gen_st(ctx, op, rt, rs, imm);
15502 check_insn(env, ctx, ISA_MIPS3);
15503 check_mips_64(ctx);
15504 gen_st_cond(ctx, op, rt, rs, imm);
15508 check_insn(env, ctx, ISA_MIPS3);
15509 check_mips_64(ctx);
15510 gen_arith_imm(env, ctx, op, rt, rs, imm);
15514 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15515 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15516 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15520 check_insn(env, ctx, ASE_MDMX);
15521 /* MDMX: Not implemented. */
15522 default: /* Invalid */
15523 MIPS_INVAL("major opcode");
15524 generate_exception(ctx, EXCP_RI);
15530 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15534 target_ulong pc_start;
15535 uint16_t *gen_opc_end;
15544 qemu_log("search pc %d\n", search_pc);
15547 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15550 ctx.singlestep_enabled = env->singlestep_enabled;
15552 ctx.bstate = BS_NONE;
15553 /* Restore delay slot state from the tb context. */
15554 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15555 restore_cpu_state(env, &ctx);
15556 #ifdef CONFIG_USER_ONLY
15557 ctx.mem_idx = MIPS_HFLAG_UM;
15559 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15562 max_insns = tb->cflags & CF_COUNT_MASK;
15563 if (max_insns == 0)
15564 max_insns = CF_COUNT_MASK;
15565 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15566 gen_icount_start();
15567 while (ctx.bstate == BS_NONE) {
15568 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15569 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15570 if (bp->pc == ctx.pc) {
15571 save_cpu_state(&ctx, 1);
15572 ctx.bstate = BS_BRANCH;
15573 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15574 /* Include the breakpoint location or the tb won't
15575 * be flushed when it must be. */
15577 goto done_generating;
15583 j = gen_opc_ptr - gen_opc_buf;
15587 gen_opc_instr_start[lj++] = 0;
15589 gen_opc_pc[lj] = ctx.pc;
15590 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15591 gen_opc_btarget[lj] = ctx.btarget;
15592 gen_opc_instr_start[lj] = 1;
15593 gen_opc_icount[lj] = num_insns;
15595 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15599 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15600 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15602 decode_opc(env, &ctx, &is_branch);
15603 } else if (env->insn_flags & ASE_MICROMIPS) {
15604 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15605 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15606 } else if (env->insn_flags & ASE_MIPS16) {
15607 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15608 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15610 generate_exception(&ctx, EXCP_RI);
15611 ctx.bstate = BS_STOP;
15615 handle_delay_slot(env, &ctx, insn_bytes);
15617 ctx.pc += insn_bytes;
15621 /* Execute a branch and its delay slot as a single instruction.
15622 This is what GDB expects and is consistent with what the
15623 hardware does (e.g. if a delay slot instruction faults, the
15624 reported PC is the PC of the branch). */
15625 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15628 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15631 if (gen_opc_ptr >= gen_opc_end)
15634 if (num_insns >= max_insns)
15640 if (tb->cflags & CF_LAST_IO)
15642 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15643 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15644 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15646 switch (ctx.bstate) {
15648 gen_goto_tb(&ctx, 0, ctx.pc);
15651 save_cpu_state(&ctx, 0);
15652 gen_goto_tb(&ctx, 0, ctx.pc);
15655 tcg_gen_exit_tb(0);
15663 gen_icount_end(tb, num_insns);
15664 *gen_opc_ptr = INDEX_op_end;
15666 j = gen_opc_ptr - gen_opc_buf;
15669 gen_opc_instr_start[lj++] = 0;
15671 tb->size = ctx.pc - pc_start;
15672 tb->icount = num_insns;
15676 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15677 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15678 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15684 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15686 gen_intermediate_code_internal(env, tb, 0);
15689 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15691 gen_intermediate_code_internal(env, tb, 1);
15694 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15698 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15700 #define printfpr(fp) \
15703 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15704 " fd:%13g fs:%13g psu: %13g\n", \
15705 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15706 (double)(fp)->fd, \
15707 (double)(fp)->fs[FP_ENDIAN_IDX], \
15708 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15711 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15712 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15713 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15714 " fd:%13g fs:%13g psu:%13g\n", \
15715 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15717 (double)tmp.fs[FP_ENDIAN_IDX], \
15718 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15723 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15724 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15725 get_float_exception_flags(&env->active_fpu.fp_status));
15726 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15727 fpu_fprintf(f, "%3s: ", fregnames[i]);
15728 printfpr(&env->active_fpu.fpr[i]);
15734 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15735 /* Debug help: The architecture requires 32bit code to maintain proper
15736 sign-extended values on 64bit machines. */
15738 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15741 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15742 fprintf_function cpu_fprintf,
15747 if (!SIGN_EXT_P(env->active_tc.PC))
15748 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15749 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15750 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15751 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15752 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15753 if (!SIGN_EXT_P(env->btarget))
15754 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15756 for (i = 0; i < 32; i++) {
15757 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15758 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15761 if (!SIGN_EXT_P(env->CP0_EPC))
15762 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15763 if (!SIGN_EXT_P(env->lladdr))
15764 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15768 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15773 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15774 " LO=0x" TARGET_FMT_lx " ds %04x "
15775 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15776 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15777 env->hflags, env->btarget, env->bcond);
15778 for (i = 0; i < 32; i++) {
15780 cpu_fprintf(f, "GPR%02d:", i);
15781 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15783 cpu_fprintf(f, "\n");
15786 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15787 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15788 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15789 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15790 if (env->hflags & MIPS_HFLAG_FPU)
15791 fpu_dump_state(env, f, cpu_fprintf, flags);
15792 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15793 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15797 static void mips_tcg_init(void)
15802 /* Initialize various static tables. */
15806 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15807 TCGV_UNUSED(cpu_gpr[0]);
15808 for (i = 1; i < 32; i++)
15809 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15810 offsetof(CPUMIPSState, active_tc.gpr[i]),
15813 for (i = 0; i < 32; i++) {
15814 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15815 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15818 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15819 offsetof(CPUMIPSState, active_tc.PC), "PC");
15820 for (i = 0; i < MIPS_DSP_ACC; i++) {
15821 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15822 offsetof(CPUMIPSState, active_tc.HI[i]),
15824 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15825 offsetof(CPUMIPSState, active_tc.LO[i]),
15827 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15828 offsetof(CPUMIPSState, active_tc.ACX[i]),
15831 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15832 offsetof(CPUMIPSState, active_tc.DSPControl),
15834 bcond = tcg_global_mem_new(TCG_AREG0,
15835 offsetof(CPUMIPSState, bcond), "bcond");
15836 btarget = tcg_global_mem_new(TCG_AREG0,
15837 offsetof(CPUMIPSState, btarget), "btarget");
15838 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15839 offsetof(CPUMIPSState, hflags), "hflags");
15841 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15842 offsetof(CPUMIPSState, active_fpu.fcr0),
15844 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15845 offsetof(CPUMIPSState, active_fpu.fcr31),
15848 /* register helpers */
15849 #define GEN_HELPER 2
15850 #include "helper.h"
15855 #include "translate_init.c"
15857 MIPSCPU *cpu_mips_init(const char *cpu_model)
15861 const mips_def_t *def;
15863 def = cpu_mips_find_by_name(cpu_model);
15866 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15868 env->cpu_model = def;
15869 env->cpu_model_str = cpu_model;
15871 #ifndef CONFIG_USER_ONLY
15872 mmu_init(env, def);
15874 fpu_init(env, def);
15875 mvp_init(env, def);
15877 cpu_reset(CPU(cpu));
15878 qemu_init_vcpu(env);
15882 void cpu_state_reset(CPUMIPSState *env)
15884 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15885 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15886 log_cpu_state(env, 0);
15889 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15892 /* Reset registers to their default values */
15893 env->CP0_PRid = env->cpu_model->CP0_PRid;
15894 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15895 #ifdef TARGET_WORDS_BIGENDIAN
15896 env->CP0_Config0 |= (1 << CP0C0_BE);
15898 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15899 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15900 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15901 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15902 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15903 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15904 << env->cpu_model->CP0_LLAddr_shift;
15905 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15906 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15907 env->CCRes = env->cpu_model->CCRes;
15908 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15909 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15910 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15911 env->current_tc = 0;
15912 env->SEGBITS = env->cpu_model->SEGBITS;
15913 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15914 #if defined(TARGET_MIPS64)
15915 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15916 env->SEGMask |= 3ULL << 62;
15919 env->PABITS = env->cpu_model->PABITS;
15920 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15921 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15922 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15923 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15924 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15925 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15926 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15927 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15928 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15929 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15930 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15931 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15932 env->insn_flags = env->cpu_model->insn_flags;
15934 #if defined(CONFIG_USER_ONLY)
15935 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15936 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15937 hardware registers. */
15938 env->CP0_HWREna |= 0x0000000F;
15939 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15940 env->CP0_Status |= (1 << CP0St_CU1);
15942 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15943 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15944 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15945 env->hflags |= MIPS_HFLAG_DSP;
15948 if (env->hflags & MIPS_HFLAG_BMASK) {
15949 /* If the exception was raised from a delay slot,
15950 come back to the jump. */
15951 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15953 env->CP0_ErrorEPC = env->active_tc.PC;
15955 env->active_tc.PC = (int32_t)0xBFC00000;
15956 env->CP0_Random = env->tlb->nb_tlb - 1;
15957 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15958 env->CP0_Wired = 0;
15959 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15960 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15961 /* vectored interrupts not implemented, timer on int 7,
15962 no performance counters. */
15963 env->CP0_IntCtl = 0xe0000000;
15967 for (i = 0; i < 7; i++) {
15968 env->CP0_WatchLo[i] = 0;
15969 env->CP0_WatchHi[i] = 0x80000000;
15971 env->CP0_WatchLo[7] = 0;
15972 env->CP0_WatchHi[7] = 0;
15974 /* Count register increments in debug mode, EJTAG version 1 */
15975 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15977 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15980 /* Only TC0 on VPE 0 starts as active. */
15981 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15982 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15983 env->tcs[i].CP0_TCHalt = 1;
15985 env->active_tc.CP0_TCHalt = 1;
15988 if (!env->cpu_index) {
15989 /* VPE0 starts up enabled. */
15990 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15991 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15993 /* TC0 starts up unhalted. */
15995 env->active_tc.CP0_TCHalt = 0;
15996 env->tcs[0].CP0_TCHalt = 0;
15997 /* With thread 0 active. */
15998 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15999 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16003 compute_hflags(env);
16004 env->exception_index = EXCP_NONE;
16007 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16009 env->active_tc.PC = gen_opc_pc[pc_pos];
16010 env->hflags &= ~MIPS_HFLAG_BMASK;
16011 env->hflags |= gen_opc_hflags[pc_pos];
16012 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16013 case MIPS_HFLAG_BR:
16015 case MIPS_HFLAG_BC:
16016 case MIPS_HFLAG_BL:
16018 env->btarget = gen_opc_btarget[pc_pos];