2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Compare-Pick Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Compare-Pick Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Compare-Pick Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1020 #include "gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1068 int singlestep_enabled;
1069 /* Routine used to access memory */
1071 uint32_t hflags, saved_hflags;
1073 target_ulong btarget;
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1078 * exception condition */
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1084 static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1091 static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1095 static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1099 static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1103 static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1110 #define MIPS_DEBUG(fmt, ...) \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1119 #define LOG_DISAS(...) \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1126 #define MIPS_INVAL(op) \
1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1130 /* General purpose registers moves. */
1131 static inline void gen_load_gpr (TCGv t, int reg)
1134 tcg_gen_movi_tl(t, 0);
1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1139 static inline void gen_store_gpr (TCGv t, int reg)
1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
1145 /* Moves to/from ACX register. */
1146 static inline void gen_load_ACX (TCGv t, int reg)
1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1151 static inline void gen_store_ACX (TCGv t, int reg)
1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
1156 /* Moves to/from shadow registers. */
1157 static inline void gen_load_srsgpr (int from, int to)
1159 TCGv t0 = tcg_temp_new();
1162 tcg_gen_movi_tl(t0, 0);
1164 TCGv_i32 t2 = tcg_temp_new_i32();
1165 TCGv_ptr addr = tcg_temp_new_ptr();
1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
1172 tcg_gen_add_ptr(addr, cpu_env, addr);
1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1175 tcg_temp_free_ptr(addr);
1176 tcg_temp_free_i32(t2);
1178 gen_store_gpr(t0, to);
1182 static inline void gen_store_srsgpr (int from, int to)
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
1187 TCGv_ptr addr = tcg_temp_new_ptr();
1189 gen_load_gpr(t0, from);
1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
1195 tcg_gen_add_ptr(addr, cpu_env, addr);
1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1198 tcg_temp_free_ptr(addr);
1199 tcg_temp_free_i32(t2);
1204 /* Floating point register moves. */
1205 static void gen_load_fpr32(TCGv_i32 t, int reg)
1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1210 static void gen_store_fpr32(TCGv_i32 t, int reg)
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
1218 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
1226 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
1234 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1236 if (ctx->hflags & MIPS_HFLAG_F64) {
1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1243 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1245 if (ctx->hflags & MIPS_HFLAG_F64) {
1246 tcg_gen_mov_i64(fpu_f64[reg], t);
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
1251 tcg_gen_shri_i64(t0, t, 32);
1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1253 tcg_temp_free_i64(t0);
1257 static inline int get_fp_bit (int cc)
1266 static inline void gen_save_pc(target_ulong pc)
1268 tcg_gen_movi_tl(cpu_PC, pc);
1271 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1275 gen_save_pc(ctx->pc);
1276 ctx->saved_pc = ctx->pc;
1278 if (ctx->hflags != ctx->saved_hflags) {
1279 tcg_gen_movi_i32(hflags, ctx->hflags);
1280 ctx->saved_hflags = ctx->hflags;
1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1287 tcg_gen_movi_tl(btarget, ctx->btarget);
1293 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1295 ctx->saved_hflags = ctx->hflags;
1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1302 ctx->btarget = env->btarget;
1308 generate_exception_err (DisasContext *ctx, int excp, int err)
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
1312 save_cpu_state(ctx, 1);
1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
1319 generate_exception (DisasContext *ctx, int excp)
1321 save_cpu_state(ctx, 1);
1322 gen_helper_0e0i(raise_exception, excp);
1325 /* Addresses computation */
1326 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1328 tcg_gen_add_tl(ret, arg0, arg1);
1330 #if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
1336 tcg_gen_ext32s_i64(ret, ret);
1341 static inline void check_cp0_enabled(DisasContext *ctx)
1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1344 generate_exception_err(ctx, EXCP_CpU, 0);
1347 static inline void check_cp1_enabled(DisasContext *ctx)
1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1353 /* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1357 static inline void check_cop1x(DisasContext *ctx)
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1363 /* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1366 static inline void check_cp1_64bitmode(DisasContext *ctx)
1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1369 generate_exception(ctx, EXCP_RI);
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1386 generate_exception(ctx, EXCP_RI);
1389 /* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1393 static inline void check_dsp(DisasContext *ctx)
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1400 static inline void check_dspr2(DisasContext *ctx)
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1407 /* This code generates a "reserved instruction" exception if the
1408 CPU does not support the instruction set corresponding to flags. */
1409 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1411 if (unlikely(!(env->insn_flags & flags)))
1412 generate_exception(ctx, EXCP_RI);
1415 /* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
1417 static inline void check_mips_64(DisasContext *ctx)
1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1420 generate_exception(ctx, EXCP_RI);
1423 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1427 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1437 check_cp1_64bitmode(ctx); \
1443 check_cp1_registers(ctx, fs | ft); \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1476 FOP_CONDS(, 0, d, FMT_D, 64)
1477 FOP_CONDS(abs, 1, d, FMT_D, 64)
1478 FOP_CONDS(, 0, s, FMT_S, 32)
1479 FOP_CONDS(abs, 1, s, FMT_S, 32)
1480 FOP_CONDS(, 0, ps, FMT_PS, 64)
1481 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1483 #undef gen_ldcmp_fpr32
1484 #undef gen_ldcmp_fpr64
1486 /* load/store instructions. */
1487 #define OP_LD(insn,fname) \
1488 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1490 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1497 #if defined(TARGET_MIPS64)
1503 #define OP_ST(insn,fname) \
1504 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
1506 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
1511 #if defined(TARGET_MIPS64)
1516 #ifdef CONFIG_USER_ONLY
1517 #define OP_LD_ATOMIC(insn,fname) \
1518 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1520 TCGv t0 = tcg_temp_new(); \
1521 tcg_gen_mov_tl(t0, arg1); \
1522 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1523 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1524 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1525 tcg_temp_free(t0); \
1528 #define OP_LD_ATOMIC(insn,fname) \
1529 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1531 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1534 OP_LD_ATOMIC(ll,ld32s);
1535 #if defined(TARGET_MIPS64)
1536 OP_LD_ATOMIC(lld,ld64);
1540 #ifdef CONFIG_USER_ONLY
1541 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1542 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1544 TCGv t0 = tcg_temp_new(); \
1545 int l1 = gen_new_label(); \
1546 int l2 = gen_new_label(); \
1548 tcg_gen_andi_tl(t0, arg2, almask); \
1549 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1550 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1551 generate_exception(ctx, EXCP_AdES); \
1552 gen_set_label(l1); \
1553 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1554 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1555 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1556 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1557 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1558 gen_helper_0e0i(raise_exception, EXCP_SC); \
1559 gen_set_label(l2); \
1560 tcg_gen_movi_tl(t0, 0); \
1561 gen_store_gpr(t0, rt); \
1562 tcg_temp_free(t0); \
1565 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1566 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1568 TCGv t0 = tcg_temp_new(); \
1569 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1570 gen_store_gpr(t0, rt); \
1571 tcg_temp_free(t0); \
1574 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1575 #if defined(TARGET_MIPS64)
1576 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1580 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1581 int base, int16_t offset)
1584 tcg_gen_movi_tl(addr, offset);
1585 } else if (offset == 0) {
1586 gen_load_gpr(addr, base);
1588 tcg_gen_movi_tl(addr, offset);
1589 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1593 static target_ulong pc_relative_pc (DisasContext *ctx)
1595 target_ulong pc = ctx->pc;
1597 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1598 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1603 pc &= ~(target_ulong)3;
1608 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1609 int rt, int base, int16_t offset)
1611 const char *opn = "ld";
1614 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1615 /* Loongson CPU uses a load to zero register for prefetch.
1616 We emulate it as a NOP. On other CPU we must perform the
1617 actual memory access. */
1622 t0 = tcg_temp_new();
1623 t1 = tcg_temp_new();
1624 gen_base_offset_addr(ctx, t0, base, offset);
1627 #if defined(TARGET_MIPS64)
1629 save_cpu_state(ctx, 0);
1630 op_ld_lwu(t0, t0, ctx);
1631 gen_store_gpr(t0, rt);
1635 save_cpu_state(ctx, 0);
1636 op_ld_ld(t0, t0, ctx);
1637 gen_store_gpr(t0, rt);
1641 save_cpu_state(ctx, 1);
1642 op_ld_lld(t0, t0, ctx);
1643 gen_store_gpr(t0, rt);
1647 save_cpu_state(ctx, 1);
1648 gen_load_gpr(t1, rt);
1649 gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
1650 gen_store_gpr(t1, rt);
1654 save_cpu_state(ctx, 1);
1655 gen_load_gpr(t1, rt);
1656 gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
1657 gen_store_gpr(t1, rt);
1661 save_cpu_state(ctx, 0);
1662 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1663 gen_op_addr_add(ctx, t0, t0, t1);
1664 op_ld_ld(t0, t0, ctx);
1665 gen_store_gpr(t0, rt);
1670 save_cpu_state(ctx, 0);
1671 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1672 gen_op_addr_add(ctx, t0, t0, t1);
1673 op_ld_lw(t0, t0, ctx);
1674 gen_store_gpr(t0, rt);
1678 save_cpu_state(ctx, 0);
1679 op_ld_lw(t0, t0, ctx);
1680 gen_store_gpr(t0, rt);
1684 save_cpu_state(ctx, 0);
1685 op_ld_lh(t0, t0, ctx);
1686 gen_store_gpr(t0, rt);
1690 save_cpu_state(ctx, 0);
1691 op_ld_lhu(t0, t0, ctx);
1692 gen_store_gpr(t0, rt);
1696 save_cpu_state(ctx, 0);
1697 op_ld_lb(t0, t0, ctx);
1698 gen_store_gpr(t0, rt);
1702 save_cpu_state(ctx, 0);
1703 op_ld_lbu(t0, t0, ctx);
1704 gen_store_gpr(t0, rt);
1708 save_cpu_state(ctx, 1);
1709 gen_load_gpr(t1, rt);
1710 gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
1711 gen_store_gpr(t1, rt);
1715 save_cpu_state(ctx, 1);
1716 gen_load_gpr(t1, rt);
1717 gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
1718 gen_store_gpr(t1, rt);
1722 save_cpu_state(ctx, 1);
1723 op_ld_ll(t0, t0, ctx);
1724 gen_store_gpr(t0, rt);
1728 (void)opn; /* avoid a compiler warning */
1729 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1735 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1736 int base, int16_t offset)
1738 const char *opn = "st";
1739 TCGv t0 = tcg_temp_new();
1740 TCGv t1 = tcg_temp_new();
1742 gen_base_offset_addr(ctx, t0, base, offset);
1743 gen_load_gpr(t1, rt);
1745 #if defined(TARGET_MIPS64)
1747 save_cpu_state(ctx, 0);
1748 op_st_sd(t1, t0, ctx);
1752 save_cpu_state(ctx, 1);
1753 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1757 save_cpu_state(ctx, 1);
1758 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1763 save_cpu_state(ctx, 0);
1764 op_st_sw(t1, t0, ctx);
1768 save_cpu_state(ctx, 0);
1769 op_st_sh(t1, t0, ctx);
1773 save_cpu_state(ctx, 0);
1774 op_st_sb(t1, t0, ctx);
1778 save_cpu_state(ctx, 1);
1779 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1783 save_cpu_state(ctx, 1);
1784 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1788 (void)opn; /* avoid a compiler warning */
1789 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1795 /* Store conditional */
1796 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1797 int base, int16_t offset)
1799 const char *opn = "st_cond";
1802 t0 = tcg_temp_local_new();
1804 gen_base_offset_addr(ctx, t0, base, offset);
1805 /* Don't do NOP if destination is zero: we must perform the actual
1808 t1 = tcg_temp_local_new();
1809 gen_load_gpr(t1, rt);
1811 #if defined(TARGET_MIPS64)
1813 save_cpu_state(ctx, 1);
1814 op_st_scd(t1, t0, rt, ctx);
1819 save_cpu_state(ctx, 1);
1820 op_st_sc(t1, t0, rt, ctx);
1824 (void)opn; /* avoid a compiler warning */
1825 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1830 /* Load and store */
1831 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1832 int base, int16_t offset)
1834 const char *opn = "flt_ldst";
1835 TCGv t0 = tcg_temp_new();
1837 gen_base_offset_addr(ctx, t0, base, offset);
1838 /* Don't do NOP if destination is zero: we must perform the actual
1843 TCGv_i32 fp0 = tcg_temp_new_i32();
1845 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1846 tcg_gen_trunc_tl_i32(fp0, t0);
1847 gen_store_fpr32(fp0, ft);
1848 tcg_temp_free_i32(fp0);
1854 TCGv_i32 fp0 = tcg_temp_new_i32();
1855 TCGv t1 = tcg_temp_new();
1857 gen_load_fpr32(fp0, ft);
1858 tcg_gen_extu_i32_tl(t1, fp0);
1859 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1861 tcg_temp_free_i32(fp0);
1867 TCGv_i64 fp0 = tcg_temp_new_i64();
1869 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1870 gen_store_fpr64(ctx, fp0, ft);
1871 tcg_temp_free_i64(fp0);
1877 TCGv_i64 fp0 = tcg_temp_new_i64();
1879 gen_load_fpr64(ctx, fp0, ft);
1880 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1881 tcg_temp_free_i64(fp0);
1887 generate_exception(ctx, EXCP_RI);
1890 (void)opn; /* avoid a compiler warning */
1891 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1896 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1897 uint32_t op, int rt, int rs, int16_t imm)
1899 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1900 check_cp1_enabled(ctx);
1901 gen_flt_ldst(ctx, op, rt, rs, imm);
1903 generate_exception_err(ctx, EXCP_CpU, 1);
1907 /* Arithmetic with immediate operand */
1908 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1909 int rt, int rs, int16_t imm)
1911 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1912 const char *opn = "imm arith";
1914 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1915 /* If no destination, treat it as a NOP.
1916 For addi, we must generate the overflow exception when needed. */
1923 TCGv t0 = tcg_temp_local_new();
1924 TCGv t1 = tcg_temp_new();
1925 TCGv t2 = tcg_temp_new();
1926 int l1 = gen_new_label();
1928 gen_load_gpr(t1, rs);
1929 tcg_gen_addi_tl(t0, t1, uimm);
1930 tcg_gen_ext32s_tl(t0, t0);
1932 tcg_gen_xori_tl(t1, t1, ~uimm);
1933 tcg_gen_xori_tl(t2, t0, uimm);
1934 tcg_gen_and_tl(t1, t1, t2);
1936 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1938 /* operands of same sign, result different sign */
1939 generate_exception(ctx, EXCP_OVERFLOW);
1941 tcg_gen_ext32s_tl(t0, t0);
1942 gen_store_gpr(t0, rt);
1949 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1950 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1952 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1956 #if defined(TARGET_MIPS64)
1959 TCGv t0 = tcg_temp_local_new();
1960 TCGv t1 = tcg_temp_new();
1961 TCGv t2 = tcg_temp_new();
1962 int l1 = gen_new_label();
1964 gen_load_gpr(t1, rs);
1965 tcg_gen_addi_tl(t0, t1, uimm);
1967 tcg_gen_xori_tl(t1, t1, ~uimm);
1968 tcg_gen_xori_tl(t2, t0, uimm);
1969 tcg_gen_and_tl(t1, t1, t2);
1971 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1973 /* operands of same sign, result different sign */
1974 generate_exception(ctx, EXCP_OVERFLOW);
1976 gen_store_gpr(t0, rt);
1983 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1985 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1991 (void)opn; /* avoid a compiler warning */
1992 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1995 /* Logic with immediate operand */
1996 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1997 int rt, int rs, int16_t imm)
2000 const char *opn = "imm logic";
2003 /* If no destination, treat it as a NOP. */
2007 uimm = (uint16_t)imm;
2010 if (likely(rs != 0))
2011 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2013 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2018 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2020 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2024 if (likely(rs != 0))
2025 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2027 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2031 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2035 (void)opn; /* avoid a compiler warning */
2036 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2039 /* Set on less than with immediate operand */
2040 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2041 int rt, int rs, int16_t imm)
2043 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2044 const char *opn = "imm arith";
2048 /* If no destination, treat it as a NOP. */
2052 t0 = tcg_temp_new();
2053 gen_load_gpr(t0, rs);
2056 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2060 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2064 (void)opn; /* avoid a compiler warning */
2065 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2069 /* Shifts with immediate operand */
2070 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2071 int rt, int rs, int16_t imm)
2073 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2074 const char *opn = "imm shift";
2078 /* If no destination, treat it as a NOP. */
2083 t0 = tcg_temp_new();
2084 gen_load_gpr(t0, rs);
2087 tcg_gen_shli_tl(t0, t0, uimm);
2088 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2092 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2097 tcg_gen_ext32u_tl(t0, t0);
2098 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2100 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2106 TCGv_i32 t1 = tcg_temp_new_i32();
2108 tcg_gen_trunc_tl_i32(t1, t0);
2109 tcg_gen_rotri_i32(t1, t1, uimm);
2110 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2111 tcg_temp_free_i32(t1);
2113 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2117 #if defined(TARGET_MIPS64)
2119 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2123 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2127 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2132 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2134 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2139 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2143 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2147 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2151 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2156 (void)opn; /* avoid a compiler warning */
2157 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2162 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2163 int rd, int rs, int rt)
2165 const char *opn = "arith";
2167 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2168 && opc != OPC_DADD && opc != OPC_DSUB) {
2169 /* If no destination, treat it as a NOP.
2170 For add & sub, we must generate the overflow exception when needed. */
2178 TCGv t0 = tcg_temp_local_new();
2179 TCGv t1 = tcg_temp_new();
2180 TCGv t2 = tcg_temp_new();
2181 int l1 = gen_new_label();
2183 gen_load_gpr(t1, rs);
2184 gen_load_gpr(t2, rt);
2185 tcg_gen_add_tl(t0, t1, t2);
2186 tcg_gen_ext32s_tl(t0, t0);
2187 tcg_gen_xor_tl(t1, t1, t2);
2188 tcg_gen_xor_tl(t2, t0, t2);
2189 tcg_gen_andc_tl(t1, t2, t1);
2191 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2193 /* operands of same sign, result different sign */
2194 generate_exception(ctx, EXCP_OVERFLOW);
2196 gen_store_gpr(t0, rd);
2202 if (rs != 0 && rt != 0) {
2203 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2204 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2205 } else if (rs == 0 && rt != 0) {
2206 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2207 } else if (rs != 0 && rt == 0) {
2208 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2210 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2216 TCGv t0 = tcg_temp_local_new();
2217 TCGv t1 = tcg_temp_new();
2218 TCGv t2 = tcg_temp_new();
2219 int l1 = gen_new_label();
2221 gen_load_gpr(t1, rs);
2222 gen_load_gpr(t2, rt);
2223 tcg_gen_sub_tl(t0, t1, t2);
2224 tcg_gen_ext32s_tl(t0, t0);
2225 tcg_gen_xor_tl(t2, t1, t2);
2226 tcg_gen_xor_tl(t1, t0, t1);
2227 tcg_gen_and_tl(t1, t1, t2);
2229 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2231 /* operands of different sign, first operand and result different sign */
2232 generate_exception(ctx, EXCP_OVERFLOW);
2234 gen_store_gpr(t0, rd);
2240 if (rs != 0 && rt != 0) {
2241 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2242 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2243 } else if (rs == 0 && rt != 0) {
2244 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2245 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2246 } else if (rs != 0 && rt == 0) {
2247 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2249 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2253 #if defined(TARGET_MIPS64)
2256 TCGv t0 = tcg_temp_local_new();
2257 TCGv t1 = tcg_temp_new();
2258 TCGv t2 = tcg_temp_new();
2259 int l1 = gen_new_label();
2261 gen_load_gpr(t1, rs);
2262 gen_load_gpr(t2, rt);
2263 tcg_gen_add_tl(t0, t1, t2);
2264 tcg_gen_xor_tl(t1, t1, t2);
2265 tcg_gen_xor_tl(t2, t0, t2);
2266 tcg_gen_andc_tl(t1, t2, t1);
2268 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2270 /* operands of same sign, result different sign */
2271 generate_exception(ctx, EXCP_OVERFLOW);
2273 gen_store_gpr(t0, rd);
2279 if (rs != 0 && rt != 0) {
2280 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2281 } else if (rs == 0 && rt != 0) {
2282 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2283 } else if (rs != 0 && rt == 0) {
2284 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2286 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2292 TCGv t0 = tcg_temp_local_new();
2293 TCGv t1 = tcg_temp_new();
2294 TCGv t2 = tcg_temp_new();
2295 int l1 = gen_new_label();
2297 gen_load_gpr(t1, rs);
2298 gen_load_gpr(t2, rt);
2299 tcg_gen_sub_tl(t0, t1, t2);
2300 tcg_gen_xor_tl(t2, t1, t2);
2301 tcg_gen_xor_tl(t1, t0, t1);
2302 tcg_gen_and_tl(t1, t1, t2);
2304 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2306 /* operands of different sign, first operand and result different sign */
2307 generate_exception(ctx, EXCP_OVERFLOW);
2309 gen_store_gpr(t0, rd);
2315 if (rs != 0 && rt != 0) {
2316 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2317 } else if (rs == 0 && rt != 0) {
2318 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2319 } else if (rs != 0 && rt == 0) {
2320 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2322 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2328 if (likely(rs != 0 && rt != 0)) {
2329 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2330 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2332 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2337 (void)opn; /* avoid a compiler warning */
2338 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2341 /* Conditional move */
2342 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2343 int rd, int rs, int rt)
2345 const char *opn = "cond move";
2349 /* If no destination, treat it as a NOP.
2350 For add & sub, we must generate the overflow exception when needed. */
2355 l1 = gen_new_label();
2358 if (likely(rt != 0))
2359 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2365 if (likely(rt != 0))
2366 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2371 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2373 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2376 (void)opn; /* avoid a compiler warning */
2377 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2381 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2382 int rd, int rs, int rt)
2384 const char *opn = "logic";
2387 /* If no destination, treat it as a NOP. */
2394 if (likely(rs != 0 && rt != 0)) {
2395 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2397 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2402 if (rs != 0 && rt != 0) {
2403 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2404 } else if (rs == 0 && rt != 0) {
2405 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2406 } else if (rs != 0 && rt == 0) {
2407 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2409 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2414 if (likely(rs != 0 && rt != 0)) {
2415 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2416 } else if (rs == 0 && rt != 0) {
2417 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2418 } else if (rs != 0 && rt == 0) {
2419 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2421 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2426 if (likely(rs != 0 && rt != 0)) {
2427 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2428 } else if (rs == 0 && rt != 0) {
2429 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2430 } else if (rs != 0 && rt == 0) {
2431 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2433 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2438 (void)opn; /* avoid a compiler warning */
2439 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2442 /* Set on lower than */
2443 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2444 int rd, int rs, int rt)
2446 const char *opn = "slt";
2450 /* If no destination, treat it as a NOP. */
2455 t0 = tcg_temp_new();
2456 t1 = tcg_temp_new();
2457 gen_load_gpr(t0, rs);
2458 gen_load_gpr(t1, rt);
2461 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2465 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2469 (void)opn; /* avoid a compiler warning */
2470 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2476 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2477 int rd, int rs, int rt)
2479 const char *opn = "shifts";
2483 /* If no destination, treat it as a NOP.
2484 For add & sub, we must generate the overflow exception when needed. */
2489 t0 = tcg_temp_new();
2490 t1 = tcg_temp_new();
2491 gen_load_gpr(t0, rs);
2492 gen_load_gpr(t1, rt);
2495 tcg_gen_andi_tl(t0, t0, 0x1f);
2496 tcg_gen_shl_tl(t0, t1, t0);
2497 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2501 tcg_gen_andi_tl(t0, t0, 0x1f);
2502 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2506 tcg_gen_ext32u_tl(t1, t1);
2507 tcg_gen_andi_tl(t0, t0, 0x1f);
2508 tcg_gen_shr_tl(t0, t1, t0);
2509 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2514 TCGv_i32 t2 = tcg_temp_new_i32();
2515 TCGv_i32 t3 = tcg_temp_new_i32();
2517 tcg_gen_trunc_tl_i32(t2, t0);
2518 tcg_gen_trunc_tl_i32(t3, t1);
2519 tcg_gen_andi_i32(t2, t2, 0x1f);
2520 tcg_gen_rotr_i32(t2, t3, t2);
2521 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2522 tcg_temp_free_i32(t2);
2523 tcg_temp_free_i32(t3);
2527 #if defined(TARGET_MIPS64)
2529 tcg_gen_andi_tl(t0, t0, 0x3f);
2530 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2534 tcg_gen_andi_tl(t0, t0, 0x3f);
2535 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2539 tcg_gen_andi_tl(t0, t0, 0x3f);
2540 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2544 tcg_gen_andi_tl(t0, t0, 0x3f);
2545 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2550 (void)opn; /* avoid a compiler warning */
2551 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2556 /* Arithmetic on HI/LO registers */
2557 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2559 const char *opn = "hilo";
2562 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2568 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2569 acc = ((ctx->opcode) >> 21) & 0x03;
2571 acc = ((ctx->opcode) >> 11) & 0x03;
2580 #if defined(TARGET_MIPS64)
2582 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2586 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2591 #if defined(TARGET_MIPS64)
2593 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2597 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2603 #if defined(TARGET_MIPS64)
2605 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2609 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2612 tcg_gen_movi_tl(cpu_HI[acc], 0);
2618 #if defined(TARGET_MIPS64)
2620 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2624 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2627 tcg_gen_movi_tl(cpu_LO[acc], 0);
2632 (void)opn; /* avoid a compiler warning */
2633 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2636 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2639 const char *opn = "mul/div";
2646 #if defined(TARGET_MIPS64)
2650 t0 = tcg_temp_local_new();
2651 t1 = tcg_temp_local_new();
2654 t0 = tcg_temp_new();
2655 t1 = tcg_temp_new();
2659 gen_load_gpr(t0, rs);
2660 gen_load_gpr(t1, rt);
2664 int l1 = gen_new_label();
2665 int l2 = gen_new_label();
2667 tcg_gen_ext32s_tl(t0, t0);
2668 tcg_gen_ext32s_tl(t1, t1);
2669 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2670 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2671 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2673 tcg_gen_mov_tl(cpu_LO[0], t0);
2674 tcg_gen_movi_tl(cpu_HI[0], 0);
2677 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2678 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2679 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2680 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2687 int l1 = gen_new_label();
2689 tcg_gen_ext32u_tl(t0, t0);
2690 tcg_gen_ext32u_tl(t1, t1);
2691 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2692 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2693 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2694 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2695 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2702 TCGv_i64 t2 = tcg_temp_new_i64();
2703 TCGv_i64 t3 = tcg_temp_new_i64();
2704 acc = ((ctx->opcode) >> 11) & 0x03;
2709 tcg_gen_ext_tl_i64(t2, t0);
2710 tcg_gen_ext_tl_i64(t3, t1);
2711 tcg_gen_mul_i64(t2, t2, t3);
2712 tcg_temp_free_i64(t3);
2713 tcg_gen_trunc_i64_tl(t0, t2);
2714 tcg_gen_shri_i64(t2, t2, 32);
2715 tcg_gen_trunc_i64_tl(t1, t2);
2716 tcg_temp_free_i64(t2);
2717 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2718 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2724 TCGv_i64 t2 = tcg_temp_new_i64();
2725 TCGv_i64 t3 = tcg_temp_new_i64();
2726 acc = ((ctx->opcode) >> 11) & 0x03;
2731 tcg_gen_ext32u_tl(t0, t0);
2732 tcg_gen_ext32u_tl(t1, t1);
2733 tcg_gen_extu_tl_i64(t2, t0);
2734 tcg_gen_extu_tl_i64(t3, t1);
2735 tcg_gen_mul_i64(t2, t2, t3);
2736 tcg_temp_free_i64(t3);
2737 tcg_gen_trunc_i64_tl(t0, t2);
2738 tcg_gen_shri_i64(t2, t2, 32);
2739 tcg_gen_trunc_i64_tl(t1, t2);
2740 tcg_temp_free_i64(t2);
2741 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2742 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2746 #if defined(TARGET_MIPS64)
2749 int l1 = gen_new_label();
2750 int l2 = gen_new_label();
2752 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2753 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2754 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2755 tcg_gen_mov_tl(cpu_LO[0], t0);
2756 tcg_gen_movi_tl(cpu_HI[0], 0);
2759 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2760 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2767 int l1 = gen_new_label();
2769 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2770 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2771 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2777 gen_helper_dmult(cpu_env, t0, t1);
2781 gen_helper_dmultu(cpu_env, t0, t1);
2787 TCGv_i64 t2 = tcg_temp_new_i64();
2788 TCGv_i64 t3 = tcg_temp_new_i64();
2789 acc = ((ctx->opcode) >> 11) & 0x03;
2794 tcg_gen_ext_tl_i64(t2, t0);
2795 tcg_gen_ext_tl_i64(t3, t1);
2796 tcg_gen_mul_i64(t2, t2, t3);
2797 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2798 tcg_gen_add_i64(t2, t2, t3);
2799 tcg_temp_free_i64(t3);
2800 tcg_gen_trunc_i64_tl(t0, t2);
2801 tcg_gen_shri_i64(t2, t2, 32);
2802 tcg_gen_trunc_i64_tl(t1, t2);
2803 tcg_temp_free_i64(t2);
2804 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2805 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2811 TCGv_i64 t2 = tcg_temp_new_i64();
2812 TCGv_i64 t3 = tcg_temp_new_i64();
2813 acc = ((ctx->opcode) >> 11) & 0x03;
2818 tcg_gen_ext32u_tl(t0, t0);
2819 tcg_gen_ext32u_tl(t1, t1);
2820 tcg_gen_extu_tl_i64(t2, t0);
2821 tcg_gen_extu_tl_i64(t3, t1);
2822 tcg_gen_mul_i64(t2, t2, t3);
2823 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2824 tcg_gen_add_i64(t2, t2, t3);
2825 tcg_temp_free_i64(t3);
2826 tcg_gen_trunc_i64_tl(t0, t2);
2827 tcg_gen_shri_i64(t2, t2, 32);
2828 tcg_gen_trunc_i64_tl(t1, t2);
2829 tcg_temp_free_i64(t2);
2830 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2831 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2837 TCGv_i64 t2 = tcg_temp_new_i64();
2838 TCGv_i64 t3 = tcg_temp_new_i64();
2839 acc = ((ctx->opcode) >> 11) & 0x03;
2844 tcg_gen_ext_tl_i64(t2, t0);
2845 tcg_gen_ext_tl_i64(t3, t1);
2846 tcg_gen_mul_i64(t2, t2, t3);
2847 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2848 tcg_gen_sub_i64(t2, t3, t2);
2849 tcg_temp_free_i64(t3);
2850 tcg_gen_trunc_i64_tl(t0, t2);
2851 tcg_gen_shri_i64(t2, t2, 32);
2852 tcg_gen_trunc_i64_tl(t1, t2);
2853 tcg_temp_free_i64(t2);
2854 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2855 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2861 TCGv_i64 t2 = tcg_temp_new_i64();
2862 TCGv_i64 t3 = tcg_temp_new_i64();
2863 acc = ((ctx->opcode) >> 11) & 0x03;
2868 tcg_gen_ext32u_tl(t0, t0);
2869 tcg_gen_ext32u_tl(t1, t1);
2870 tcg_gen_extu_tl_i64(t2, t0);
2871 tcg_gen_extu_tl_i64(t3, t1);
2872 tcg_gen_mul_i64(t2, t2, t3);
2873 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2874 tcg_gen_sub_i64(t2, t3, t2);
2875 tcg_temp_free_i64(t3);
2876 tcg_gen_trunc_i64_tl(t0, t2);
2877 tcg_gen_shri_i64(t2, t2, 32);
2878 tcg_gen_trunc_i64_tl(t1, t2);
2879 tcg_temp_free_i64(t2);
2880 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2881 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2887 generate_exception(ctx, EXCP_RI);
2890 (void)opn; /* avoid a compiler warning */
2891 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2897 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2898 int rd, int rs, int rt)
2900 const char *opn = "mul vr54xx";
2901 TCGv t0 = tcg_temp_new();
2902 TCGv t1 = tcg_temp_new();
2904 gen_load_gpr(t0, rs);
2905 gen_load_gpr(t1, rt);
2908 case OPC_VR54XX_MULS:
2909 gen_helper_muls(t0, cpu_env, t0, t1);
2912 case OPC_VR54XX_MULSU:
2913 gen_helper_mulsu(t0, cpu_env, t0, t1);
2916 case OPC_VR54XX_MACC:
2917 gen_helper_macc(t0, cpu_env, t0, t1);
2920 case OPC_VR54XX_MACCU:
2921 gen_helper_maccu(t0, cpu_env, t0, t1);
2924 case OPC_VR54XX_MSAC:
2925 gen_helper_msac(t0, cpu_env, t0, t1);
2928 case OPC_VR54XX_MSACU:
2929 gen_helper_msacu(t0, cpu_env, t0, t1);
2932 case OPC_VR54XX_MULHI:
2933 gen_helper_mulhi(t0, cpu_env, t0, t1);
2936 case OPC_VR54XX_MULHIU:
2937 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2940 case OPC_VR54XX_MULSHI:
2941 gen_helper_mulshi(t0, cpu_env, t0, t1);
2944 case OPC_VR54XX_MULSHIU:
2945 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2948 case OPC_VR54XX_MACCHI:
2949 gen_helper_macchi(t0, cpu_env, t0, t1);
2952 case OPC_VR54XX_MACCHIU:
2953 gen_helper_macchiu(t0, cpu_env, t0, t1);
2956 case OPC_VR54XX_MSACHI:
2957 gen_helper_msachi(t0, cpu_env, t0, t1);
2960 case OPC_VR54XX_MSACHIU:
2961 gen_helper_msachiu(t0, cpu_env, t0, t1);
2965 MIPS_INVAL("mul vr54xx");
2966 generate_exception(ctx, EXCP_RI);
2969 gen_store_gpr(t0, rd);
2970 (void)opn; /* avoid a compiler warning */
2971 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2978 static void gen_cl (DisasContext *ctx, uint32_t opc,
2981 const char *opn = "CLx";
2989 t0 = tcg_temp_new();
2990 gen_load_gpr(t0, rs);
2993 gen_helper_clo(cpu_gpr[rd], t0);
2997 gen_helper_clz(cpu_gpr[rd], t0);
3000 #if defined(TARGET_MIPS64)
3002 gen_helper_dclo(cpu_gpr[rd], t0);
3006 gen_helper_dclz(cpu_gpr[rd], t0);
3011 (void)opn; /* avoid a compiler warning */
3012 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3016 /* Godson integer instructions */
3017 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3018 int rd, int rs, int rt)
3020 const char *opn = "loongson";
3032 case OPC_MULTU_G_2E:
3033 case OPC_MULTU_G_2F:
3034 #if defined(TARGET_MIPS64)
3035 case OPC_DMULT_G_2E:
3036 case OPC_DMULT_G_2F:
3037 case OPC_DMULTU_G_2E:
3038 case OPC_DMULTU_G_2F:
3040 t0 = tcg_temp_new();
3041 t1 = tcg_temp_new();
3044 t0 = tcg_temp_local_new();
3045 t1 = tcg_temp_local_new();
3049 gen_load_gpr(t0, rs);
3050 gen_load_gpr(t1, rt);
3055 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3056 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3059 case OPC_MULTU_G_2E:
3060 case OPC_MULTU_G_2F:
3061 tcg_gen_ext32u_tl(t0, t0);
3062 tcg_gen_ext32u_tl(t1, t1);
3063 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3064 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3070 int l1 = gen_new_label();
3071 int l2 = gen_new_label();
3072 int l3 = gen_new_label();
3073 tcg_gen_ext32s_tl(t0, t0);
3074 tcg_gen_ext32s_tl(t1, t1);
3075 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3076 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3079 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3080 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3081 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3084 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3085 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3093 int l1 = gen_new_label();
3094 int l2 = gen_new_label();
3095 tcg_gen_ext32u_tl(t0, t0);
3096 tcg_gen_ext32u_tl(t1, t1);
3097 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3098 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3101 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3102 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3110 int l1 = gen_new_label();
3111 int l2 = gen_new_label();
3112 int l3 = gen_new_label();
3113 tcg_gen_ext32u_tl(t0, t0);
3114 tcg_gen_ext32u_tl(t1, t1);
3115 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3116 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3117 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3119 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3122 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3123 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3131 int l1 = gen_new_label();
3132 int l2 = gen_new_label();
3133 tcg_gen_ext32u_tl(t0, t0);
3134 tcg_gen_ext32u_tl(t1, t1);
3135 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3136 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3139 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3140 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3145 #if defined(TARGET_MIPS64)
3146 case OPC_DMULT_G_2E:
3147 case OPC_DMULT_G_2F:
3148 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3151 case OPC_DMULTU_G_2E:
3152 case OPC_DMULTU_G_2F:
3153 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3159 int l1 = gen_new_label();
3160 int l2 = gen_new_label();
3161 int l3 = gen_new_label();
3162 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3163 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3166 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3167 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3168 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3171 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3176 case OPC_DDIVU_G_2E:
3177 case OPC_DDIVU_G_2F:
3179 int l1 = gen_new_label();
3180 int l2 = gen_new_label();
3181 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3182 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3185 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3193 int l1 = gen_new_label();
3194 int l2 = gen_new_label();
3195 int l3 = gen_new_label();
3196 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3197 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3198 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3200 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3203 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3208 case OPC_DMODU_G_2E:
3209 case OPC_DMODU_G_2F:
3211 int l1 = gen_new_label();
3212 int l2 = gen_new_label();
3213 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3214 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3217 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3225 (void)opn; /* avoid a compiler warning */
3226 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3231 /* Loongson multimedia instructions */
3232 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3234 const char *opn = "loongson_cp2";
3235 uint32_t opc, shift_max;
3238 opc = MASK_LMI(ctx->opcode);
3244 t0 = tcg_temp_local_new_i64();
3245 t1 = tcg_temp_local_new_i64();
3248 t0 = tcg_temp_new_i64();
3249 t1 = tcg_temp_new_i64();
3253 gen_load_fpr64(ctx, t0, rs);
3254 gen_load_fpr64(ctx, t1, rt);
3256 #define LMI_HELPER(UP, LO) \
3257 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3258 #define LMI_HELPER_1(UP, LO) \
3259 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3260 #define LMI_DIRECT(UP, LO, OP) \
3261 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3264 LMI_HELPER(PADDSH, paddsh);
3265 LMI_HELPER(PADDUSH, paddush);
3266 LMI_HELPER(PADDH, paddh);
3267 LMI_HELPER(PADDW, paddw);
3268 LMI_HELPER(PADDSB, paddsb);
3269 LMI_HELPER(PADDUSB, paddusb);
3270 LMI_HELPER(PADDB, paddb);
3272 LMI_HELPER(PSUBSH, psubsh);
3273 LMI_HELPER(PSUBUSH, psubush);
3274 LMI_HELPER(PSUBH, psubh);
3275 LMI_HELPER(PSUBW, psubw);
3276 LMI_HELPER(PSUBSB, psubsb);
3277 LMI_HELPER(PSUBUSB, psubusb);
3278 LMI_HELPER(PSUBB, psubb);
3280 LMI_HELPER(PSHUFH, pshufh);
3281 LMI_HELPER(PACKSSWH, packsswh);
3282 LMI_HELPER(PACKSSHB, packsshb);
3283 LMI_HELPER(PACKUSHB, packushb);
3285 LMI_HELPER(PUNPCKLHW, punpcklhw);
3286 LMI_HELPER(PUNPCKHHW, punpckhhw);
3287 LMI_HELPER(PUNPCKLBH, punpcklbh);
3288 LMI_HELPER(PUNPCKHBH, punpckhbh);
3289 LMI_HELPER(PUNPCKLWD, punpcklwd);
3290 LMI_HELPER(PUNPCKHWD, punpckhwd);
3292 LMI_HELPER(PAVGH, pavgh);
3293 LMI_HELPER(PAVGB, pavgb);
3294 LMI_HELPER(PMAXSH, pmaxsh);
3295 LMI_HELPER(PMINSH, pminsh);
3296 LMI_HELPER(PMAXUB, pmaxub);
3297 LMI_HELPER(PMINUB, pminub);
3299 LMI_HELPER(PCMPEQW, pcmpeqw);
3300 LMI_HELPER(PCMPGTW, pcmpgtw);
3301 LMI_HELPER(PCMPEQH, pcmpeqh);
3302 LMI_HELPER(PCMPGTH, pcmpgth);
3303 LMI_HELPER(PCMPEQB, pcmpeqb);
3304 LMI_HELPER(PCMPGTB, pcmpgtb);
3306 LMI_HELPER(PSLLW, psllw);
3307 LMI_HELPER(PSLLH, psllh);
3308 LMI_HELPER(PSRLW, psrlw);
3309 LMI_HELPER(PSRLH, psrlh);
3310 LMI_HELPER(PSRAW, psraw);
3311 LMI_HELPER(PSRAH, psrah);
3313 LMI_HELPER(PMULLH, pmullh);
3314 LMI_HELPER(PMULHH, pmulhh);
3315 LMI_HELPER(PMULHUH, pmulhuh);
3316 LMI_HELPER(PMADDHW, pmaddhw);
3318 LMI_HELPER(PASUBUB, pasubub);
3319 LMI_HELPER_1(BIADD, biadd);
3320 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3322 LMI_DIRECT(PADDD, paddd, add);
3323 LMI_DIRECT(PSUBD, psubd, sub);
3324 LMI_DIRECT(XOR_CP2, xor, xor);
3325 LMI_DIRECT(NOR_CP2, nor, nor);
3326 LMI_DIRECT(AND_CP2, and, and);
3327 LMI_DIRECT(PANDN, pandn, andc);
3328 LMI_DIRECT(OR, or, or);
3331 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3335 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3339 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3343 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3348 tcg_gen_andi_i64(t1, t1, 3);
3349 tcg_gen_shli_i64(t1, t1, 4);
3350 tcg_gen_shr_i64(t0, t0, t1);
3351 tcg_gen_ext16u_i64(t0, t0);
3356 tcg_gen_add_i64(t0, t0, t1);
3357 tcg_gen_ext32s_i64(t0, t0);
3361 tcg_gen_sub_i64(t0, t0, t1);
3362 tcg_gen_ext32s_i64(t0, t0);
3391 /* Make sure shift count isn't TCG undefined behaviour. */
3392 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3397 tcg_gen_shl_i64(t0, t0, t1);
3401 /* Since SRA is UndefinedResult without sign-extended inputs,
3402 we can treat SRA and DSRA the same. */
3403 tcg_gen_sar_i64(t0, t0, t1);
3406 /* We want to shift in zeros for SRL; zero-extend first. */
3407 tcg_gen_ext32u_i64(t0, t0);
3410 tcg_gen_shr_i64(t0, t0, t1);
3414 if (shift_max == 32) {
3415 tcg_gen_ext32s_i64(t0, t0);
3418 /* Shifts larger than MAX produce zero. */
3419 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3420 tcg_gen_neg_i64(t1, t1);
3421 tcg_gen_and_i64(t0, t0, t1);
3427 TCGv_i64 t2 = tcg_temp_new_i64();
3428 int lab = gen_new_label();
3430 tcg_gen_mov_i64(t2, t0);
3431 tcg_gen_add_i64(t0, t1, t2);
3432 if (opc == OPC_ADD_CP2) {
3433 tcg_gen_ext32s_i64(t0, t0);
3435 tcg_gen_xor_i64(t1, t1, t2);
3436 tcg_gen_xor_i64(t2, t2, t0);
3437 tcg_gen_andc_i64(t1, t2, t1);
3438 tcg_temp_free_i64(t2);
3439 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3440 generate_exception(ctx, EXCP_OVERFLOW);
3443 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3450 TCGv_i64 t2 = tcg_temp_new_i64();
3451 int lab = gen_new_label();
3453 tcg_gen_mov_i64(t2, t0);
3454 tcg_gen_sub_i64(t0, t1, t2);
3455 if (opc == OPC_SUB_CP2) {
3456 tcg_gen_ext32s_i64(t0, t0);
3458 tcg_gen_xor_i64(t1, t1, t2);
3459 tcg_gen_xor_i64(t2, t2, t0);
3460 tcg_gen_and_i64(t1, t1, t2);
3461 tcg_temp_free_i64(t2);
3462 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3463 generate_exception(ctx, EXCP_OVERFLOW);
3466 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3471 tcg_gen_ext32u_i64(t0, t0);
3472 tcg_gen_ext32u_i64(t1, t1);
3473 tcg_gen_mul_i64(t0, t0, t1);
3483 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3484 FD field is the CC field? */
3487 generate_exception(ctx, EXCP_RI);
3494 gen_store_fpr64(ctx, t0, rd);
3496 (void)opn; /* avoid a compiler warning */
3497 MIPS_DEBUG("%s %s, %s, %s", opn,
3498 fregnames[rd], fregnames[rs], fregnames[rt]);
3499 tcg_temp_free_i64(t0);
3500 tcg_temp_free_i64(t1);
3504 static void gen_trap (DisasContext *ctx, uint32_t opc,
3505 int rs, int rt, int16_t imm)
3508 TCGv t0 = tcg_temp_new();
3509 TCGv t1 = tcg_temp_new();
3512 /* Load needed operands */
3520 /* Compare two registers */
3522 gen_load_gpr(t0, rs);
3523 gen_load_gpr(t1, rt);
3533 /* Compare register to immediate */
3534 if (rs != 0 || imm != 0) {
3535 gen_load_gpr(t0, rs);
3536 tcg_gen_movi_tl(t1, (int32_t)imm);
3543 case OPC_TEQ: /* rs == rs */
3544 case OPC_TEQI: /* r0 == 0 */
3545 case OPC_TGE: /* rs >= rs */
3546 case OPC_TGEI: /* r0 >= 0 */
3547 case OPC_TGEU: /* rs >= rs unsigned */
3548 case OPC_TGEIU: /* r0 >= 0 unsigned */
3550 generate_exception(ctx, EXCP_TRAP);
3552 case OPC_TLT: /* rs < rs */
3553 case OPC_TLTI: /* r0 < 0 */
3554 case OPC_TLTU: /* rs < rs unsigned */
3555 case OPC_TLTIU: /* r0 < 0 unsigned */
3556 case OPC_TNE: /* rs != rs */
3557 case OPC_TNEI: /* r0 != 0 */
3558 /* Never trap: treat as NOP. */
3562 int l1 = gen_new_label();
3567 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3571 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3575 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3579 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3583 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3587 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3590 generate_exception(ctx, EXCP_TRAP);
3597 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3599 TranslationBlock *tb;
3601 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3602 likely(!ctx->singlestep_enabled)) {
3605 tcg_gen_exit_tb((tcg_target_long)tb + n);
3608 if (ctx->singlestep_enabled) {
3609 save_cpu_state(ctx, 0);
3610 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3616 /* Branches (before delay slot) */
3617 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3619 int rs, int rt, int32_t offset)
3621 target_ulong btgt = -1;
3623 int bcond_compute = 0;
3624 TCGv t0 = tcg_temp_new();
3625 TCGv t1 = tcg_temp_new();
3627 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3628 #ifdef MIPS_DEBUG_DISAS
3629 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3631 generate_exception(ctx, EXCP_RI);
3635 /* Load needed operands */
3641 /* Compare two registers */
3643 gen_load_gpr(t0, rs);
3644 gen_load_gpr(t1, rt);
3647 btgt = ctx->pc + insn_bytes + offset;
3663 /* Compare to zero */
3665 gen_load_gpr(t0, rs);
3668 btgt = ctx->pc + insn_bytes + offset;
3671 #if defined(TARGET_MIPS64)
3673 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3675 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3678 btgt = ctx->pc + insn_bytes + offset;
3685 /* Jump to immediate */
3686 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3692 /* Jump to register */
3693 if (offset != 0 && offset != 16) {
3694 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3695 others are reserved. */
3696 MIPS_INVAL("jump hint");
3697 generate_exception(ctx, EXCP_RI);
3700 gen_load_gpr(btarget, rs);
3703 MIPS_INVAL("branch/jump");
3704 generate_exception(ctx, EXCP_RI);
3707 if (bcond_compute == 0) {
3708 /* No condition to be computed */
3710 case OPC_BEQ: /* rx == rx */
3711 case OPC_BEQL: /* rx == rx likely */
3712 case OPC_BGEZ: /* 0 >= 0 */
3713 case OPC_BGEZL: /* 0 >= 0 likely */
3714 case OPC_BLEZ: /* 0 <= 0 */
3715 case OPC_BLEZL: /* 0 <= 0 likely */
3717 ctx->hflags |= MIPS_HFLAG_B;
3718 MIPS_DEBUG("balways");
3721 case OPC_BGEZAL: /* 0 >= 0 */
3722 case OPC_BGEZALL: /* 0 >= 0 likely */
3723 ctx->hflags |= (opc == OPC_BGEZALS
3725 : MIPS_HFLAG_BDS32);
3726 /* Always take and link */
3728 ctx->hflags |= MIPS_HFLAG_B;
3729 MIPS_DEBUG("balways and link");
3731 case OPC_BNE: /* rx != rx */
3732 case OPC_BGTZ: /* 0 > 0 */
3733 case OPC_BLTZ: /* 0 < 0 */
3735 MIPS_DEBUG("bnever (NOP)");
3738 case OPC_BLTZAL: /* 0 < 0 */
3739 ctx->hflags |= (opc == OPC_BLTZALS
3741 : MIPS_HFLAG_BDS32);
3742 /* Handle as an unconditional branch to get correct delay
3745 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3746 ctx->hflags |= MIPS_HFLAG_B;
3747 MIPS_DEBUG("bnever and link");
3749 case OPC_BLTZALL: /* 0 < 0 likely */
3750 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3751 /* Skip the instruction in the delay slot */
3752 MIPS_DEBUG("bnever, link and skip");
3755 case OPC_BNEL: /* rx != rx likely */
3756 case OPC_BGTZL: /* 0 > 0 likely */
3757 case OPC_BLTZL: /* 0 < 0 likely */
3758 /* Skip the instruction in the delay slot */
3759 MIPS_DEBUG("bnever and skip");
3763 ctx->hflags |= MIPS_HFLAG_B;
3764 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3768 ctx->hflags |= MIPS_HFLAG_BX;
3773 ctx->hflags |= MIPS_HFLAG_B;
3774 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3776 : MIPS_HFLAG_BDS32);
3777 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3780 ctx->hflags |= MIPS_HFLAG_BR;
3781 if (insn_bytes == 4)
3782 ctx->hflags |= MIPS_HFLAG_BDS32;
3783 MIPS_DEBUG("jr %s", regnames[rs]);
3789 ctx->hflags |= MIPS_HFLAG_BR;
3790 ctx->hflags |= (opc == OPC_JALRS
3792 : MIPS_HFLAG_BDS32);
3793 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3796 MIPS_INVAL("branch/jump");
3797 generate_exception(ctx, EXCP_RI);
3803 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3804 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3805 regnames[rs], regnames[rt], btgt);
3808 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3809 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3810 regnames[rs], regnames[rt], btgt);
3813 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3814 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3815 regnames[rs], regnames[rt], btgt);
3818 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3819 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3820 regnames[rs], regnames[rt], btgt);
3823 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3824 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3827 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3828 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3832 ctx->hflags |= (opc == OPC_BGEZALS
3834 : MIPS_HFLAG_BDS32);
3835 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3836 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3840 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3842 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3845 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3846 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3849 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3850 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3853 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3854 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3857 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3858 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3861 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3862 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3865 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3866 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3869 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3870 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3872 #if defined(TARGET_MIPS64)
3874 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3875 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3880 ctx->hflags |= (opc == OPC_BLTZALS
3882 : MIPS_HFLAG_BDS32);
3883 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3885 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3887 ctx->hflags |= MIPS_HFLAG_BC;
3890 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3892 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3894 ctx->hflags |= MIPS_HFLAG_BL;
3897 MIPS_INVAL("conditional branch/jump");
3898 generate_exception(ctx, EXCP_RI);
3902 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3903 blink, ctx->hflags, btgt);
3905 ctx->btarget = btgt;
3907 int post_delay = insn_bytes;
3908 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3910 if (opc != OPC_JALRC)
3911 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3913 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3917 if (insn_bytes == 2)
3918 ctx->hflags |= MIPS_HFLAG_B16;
3923 /* special3 bitfield operations */
3924 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3925 int rs, int lsb, int msb)
3927 TCGv t0 = tcg_temp_new();
3928 TCGv t1 = tcg_temp_new();
3931 gen_load_gpr(t1, rs);
3936 tcg_gen_shri_tl(t0, t1, lsb);
3938 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3940 tcg_gen_ext32s_tl(t0, t0);
3943 #if defined(TARGET_MIPS64)
3945 tcg_gen_shri_tl(t0, t1, lsb);
3947 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3951 tcg_gen_shri_tl(t0, t1, lsb + 32);
3952 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3955 tcg_gen_shri_tl(t0, t1, lsb);
3956 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3962 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3963 gen_load_gpr(t0, rt);
3964 tcg_gen_andi_tl(t0, t0, ~mask);
3965 tcg_gen_shli_tl(t1, t1, lsb);
3966 tcg_gen_andi_tl(t1, t1, mask);
3967 tcg_gen_or_tl(t0, t0, t1);
3968 tcg_gen_ext32s_tl(t0, t0);
3970 #if defined(TARGET_MIPS64)
3974 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3975 gen_load_gpr(t0, rt);
3976 tcg_gen_andi_tl(t0, t0, ~mask);
3977 tcg_gen_shli_tl(t1, t1, lsb);
3978 tcg_gen_andi_tl(t1, t1, mask);
3979 tcg_gen_or_tl(t0, t0, t1);
3984 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3985 gen_load_gpr(t0, rt);
3986 tcg_gen_andi_tl(t0, t0, ~mask);
3987 tcg_gen_shli_tl(t1, t1, lsb + 32);
3988 tcg_gen_andi_tl(t1, t1, mask);
3989 tcg_gen_or_tl(t0, t0, t1);
3994 gen_load_gpr(t0, rt);
3995 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3996 gen_load_gpr(t0, rt);
3997 tcg_gen_andi_tl(t0, t0, ~mask);
3998 tcg_gen_shli_tl(t1, t1, lsb);
3999 tcg_gen_andi_tl(t1, t1, mask);
4000 tcg_gen_or_tl(t0, t0, t1);
4005 MIPS_INVAL("bitops");
4006 generate_exception(ctx, EXCP_RI);
4011 gen_store_gpr(t0, rt);
4016 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4021 /* If no destination, treat it as a NOP. */
4026 t0 = tcg_temp_new();
4027 gen_load_gpr(t0, rt);
4031 TCGv t1 = tcg_temp_new();
4033 tcg_gen_shri_tl(t1, t0, 8);
4034 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4035 tcg_gen_shli_tl(t0, t0, 8);
4036 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4037 tcg_gen_or_tl(t0, t0, t1);
4039 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4043 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4046 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4048 #if defined(TARGET_MIPS64)
4051 TCGv t1 = tcg_temp_new();
4053 tcg_gen_shri_tl(t1, t0, 8);
4054 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4055 tcg_gen_shli_tl(t0, t0, 8);
4056 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4057 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4063 TCGv t1 = tcg_temp_new();
4065 tcg_gen_shri_tl(t1, t0, 16);
4066 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4067 tcg_gen_shli_tl(t0, t0, 16);
4068 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4069 tcg_gen_or_tl(t0, t0, t1);
4070 tcg_gen_shri_tl(t1, t0, 32);
4071 tcg_gen_shli_tl(t0, t0, 32);
4072 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4078 MIPS_INVAL("bsfhl");
4079 generate_exception(ctx, EXCP_RI);
4086 #ifndef CONFIG_USER_ONLY
4087 /* CP0 (MMU and control) */
4088 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4090 TCGv_i32 t0 = tcg_temp_new_i32();
4092 tcg_gen_ld_i32(t0, cpu_env, off);
4093 tcg_gen_ext_i32_tl(arg, t0);
4094 tcg_temp_free_i32(t0);
4097 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4099 tcg_gen_ld_tl(arg, cpu_env, off);
4100 tcg_gen_ext32s_tl(arg, arg);
4103 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4105 TCGv_i32 t0 = tcg_temp_new_i32();
4107 tcg_gen_trunc_tl_i32(t0, arg);
4108 tcg_gen_st_i32(t0, cpu_env, off);
4109 tcg_temp_free_i32(t0);
4112 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4114 tcg_gen_ext32s_tl(arg, arg);
4115 tcg_gen_st_tl(arg, cpu_env, off);
4118 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4120 const char *rn = "invalid";
4123 check_insn(env, ctx, ISA_MIPS32);
4129 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4133 check_insn(env, ctx, ASE_MT);
4134 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4138 check_insn(env, ctx, ASE_MT);
4139 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4143 check_insn(env, ctx, ASE_MT);
4144 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4154 gen_helper_mfc0_random(arg, cpu_env);
4158 check_insn(env, ctx, ASE_MT);
4159 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4163 check_insn(env, ctx, ASE_MT);
4164 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4168 check_insn(env, ctx, ASE_MT);
4169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4173 check_insn(env, ctx, ASE_MT);
4174 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4178 check_insn(env, ctx, ASE_MT);
4179 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4183 check_insn(env, ctx, ASE_MT);
4184 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4185 rn = "VPEScheFBack";
4188 check_insn(env, ctx, ASE_MT);
4189 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4199 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4200 tcg_gen_ext32s_tl(arg, arg);
4204 check_insn(env, ctx, ASE_MT);
4205 gen_helper_mfc0_tcstatus(arg, cpu_env);
4209 check_insn(env, ctx, ASE_MT);
4210 gen_helper_mfc0_tcbind(arg, cpu_env);
4214 check_insn(env, ctx, ASE_MT);
4215 gen_helper_mfc0_tcrestart(arg, cpu_env);
4219 check_insn(env, ctx, ASE_MT);
4220 gen_helper_mfc0_tchalt(arg, cpu_env);
4224 check_insn(env, ctx, ASE_MT);
4225 gen_helper_mfc0_tccontext(arg, cpu_env);
4229 check_insn(env, ctx, ASE_MT);
4230 gen_helper_mfc0_tcschedule(arg, cpu_env);
4234 check_insn(env, ctx, ASE_MT);
4235 gen_helper_mfc0_tcschefback(arg, cpu_env);
4245 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4246 tcg_gen_ext32s_tl(arg, arg);
4256 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4257 tcg_gen_ext32s_tl(arg, arg);
4261 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4262 rn = "ContextConfig";
4271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4275 check_insn(env, ctx, ISA_MIPS32R2);
4276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4290 check_insn(env, ctx, ISA_MIPS32R2);
4291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4295 check_insn(env, ctx, ISA_MIPS32R2);
4296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4300 check_insn(env, ctx, ISA_MIPS32R2);
4301 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4305 check_insn(env, ctx, ISA_MIPS32R2);
4306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4310 check_insn(env, ctx, ISA_MIPS32R2);
4311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4321 check_insn(env, ctx, ISA_MIPS32R2);
4322 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4332 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4333 tcg_gen_ext32s_tl(arg, arg);
4343 /* Mark as an IO operation because we read the time. */
4346 gen_helper_mfc0_count(arg, cpu_env);
4350 /* Break the TB to be able to take timer interrupts immediately
4351 after reading count. */
4352 ctx->bstate = BS_STOP;
4355 /* 6,7 are implementation dependent */
4363 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4364 tcg_gen_ext32s_tl(arg, arg);
4374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4377 /* 6,7 are implementation dependent */
4385 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4389 check_insn(env, ctx, ISA_MIPS32R2);
4390 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4394 check_insn(env, ctx, ISA_MIPS32R2);
4395 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4399 check_insn(env, ctx, ISA_MIPS32R2);
4400 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4410 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4420 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4421 tcg_gen_ext32s_tl(arg, arg);
4431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4435 check_insn(env, ctx, ISA_MIPS32R2);
4436 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4454 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4461 /* 4,5 are reserved */
4462 /* 6,7 are implementation dependent */
4464 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4468 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4478 gen_helper_mfc0_lladdr(arg, cpu_env);
4488 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4498 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4508 #if defined(TARGET_MIPS64)
4509 check_insn(env, ctx, ISA_MIPS3);
4510 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4511 tcg_gen_ext32s_tl(arg, arg);
4520 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4523 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4531 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4532 rn = "'Diagnostic"; /* implementation dependent */
4537 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4541 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4542 rn = "TraceControl";
4545 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4546 rn = "TraceControl2";
4549 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4550 rn = "UserTraceData";
4553 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4564 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4565 tcg_gen_ext32s_tl(arg, arg);
4575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4576 rn = "Performance0";
4579 // gen_helper_mfc0_performance1(arg);
4580 rn = "Performance1";
4583 // gen_helper_mfc0_performance2(arg);
4584 rn = "Performance2";
4587 // gen_helper_mfc0_performance3(arg);
4588 rn = "Performance3";
4591 // gen_helper_mfc0_performance4(arg);
4592 rn = "Performance4";
4595 // gen_helper_mfc0_performance5(arg);
4596 rn = "Performance5";
4599 // gen_helper_mfc0_performance6(arg);
4600 rn = "Performance6";
4603 // gen_helper_mfc0_performance7(arg);
4604 rn = "Performance7";
4611 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4617 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4657 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4667 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4668 tcg_gen_ext32s_tl(arg, arg);
4679 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4689 (void)rn; /* avoid a compiler warning */
4690 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4694 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4695 generate_exception(ctx, EXCP_RI);
4698 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4700 const char *rn = "invalid";
4703 check_insn(env, ctx, ISA_MIPS32);
4712 gen_helper_mtc0_index(cpu_env, arg);
4716 check_insn(env, ctx, ASE_MT);
4717 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4721 check_insn(env, ctx, ASE_MT);
4726 check_insn(env, ctx, ASE_MT);
4741 check_insn(env, ctx, ASE_MT);
4742 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4746 check_insn(env, ctx, ASE_MT);
4747 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4751 check_insn(env, ctx, ASE_MT);
4752 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4756 check_insn(env, ctx, ASE_MT);
4757 gen_helper_mtc0_yqmask(cpu_env, arg);
4761 check_insn(env, ctx, ASE_MT);
4762 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4766 check_insn(env, ctx, ASE_MT);
4767 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4768 rn = "VPEScheFBack";
4771 check_insn(env, ctx, ASE_MT);
4772 gen_helper_mtc0_vpeopt(cpu_env, arg);
4782 gen_helper_mtc0_entrylo0(cpu_env, arg);
4786 check_insn(env, ctx, ASE_MT);
4787 gen_helper_mtc0_tcstatus(cpu_env, arg);
4791 check_insn(env, ctx, ASE_MT);
4792 gen_helper_mtc0_tcbind(cpu_env, arg);
4796 check_insn(env, ctx, ASE_MT);
4797 gen_helper_mtc0_tcrestart(cpu_env, arg);
4801 check_insn(env, ctx, ASE_MT);
4802 gen_helper_mtc0_tchalt(cpu_env, arg);
4806 check_insn(env, ctx, ASE_MT);
4807 gen_helper_mtc0_tccontext(cpu_env, arg);
4811 check_insn(env, ctx, ASE_MT);
4812 gen_helper_mtc0_tcschedule(cpu_env, arg);
4816 check_insn(env, ctx, ASE_MT);
4817 gen_helper_mtc0_tcschefback(cpu_env, arg);
4827 gen_helper_mtc0_entrylo1(cpu_env, arg);
4837 gen_helper_mtc0_context(cpu_env, arg);
4841 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4842 rn = "ContextConfig";
4851 gen_helper_mtc0_pagemask(cpu_env, arg);
4855 check_insn(env, ctx, ISA_MIPS32R2);
4856 gen_helper_mtc0_pagegrain(cpu_env, arg);
4866 gen_helper_mtc0_wired(cpu_env, arg);
4870 check_insn(env, ctx, ISA_MIPS32R2);
4871 gen_helper_mtc0_srsconf0(cpu_env, arg);
4875 check_insn(env, ctx, ISA_MIPS32R2);
4876 gen_helper_mtc0_srsconf1(cpu_env, arg);
4880 check_insn(env, ctx, ISA_MIPS32R2);
4881 gen_helper_mtc0_srsconf2(cpu_env, arg);
4885 check_insn(env, ctx, ISA_MIPS32R2);
4886 gen_helper_mtc0_srsconf3(cpu_env, arg);
4890 check_insn(env, ctx, ISA_MIPS32R2);
4891 gen_helper_mtc0_srsconf4(cpu_env, arg);
4901 check_insn(env, ctx, ISA_MIPS32R2);
4902 gen_helper_mtc0_hwrena(cpu_env, arg);
4916 gen_helper_mtc0_count(cpu_env, arg);
4919 /* 6,7 are implementation dependent */
4927 gen_helper_mtc0_entryhi(cpu_env, arg);
4937 gen_helper_mtc0_compare(cpu_env, arg);
4940 /* 6,7 are implementation dependent */
4948 save_cpu_state(ctx, 1);
4949 gen_helper_mtc0_status(cpu_env, arg);
4950 /* BS_STOP isn't good enough here, hflags may have changed. */
4951 gen_save_pc(ctx->pc + 4);
4952 ctx->bstate = BS_EXCP;
4956 check_insn(env, ctx, ISA_MIPS32R2);
4957 gen_helper_mtc0_intctl(cpu_env, arg);
4958 /* Stop translation as we may have switched the execution mode */
4959 ctx->bstate = BS_STOP;
4963 check_insn(env, ctx, ISA_MIPS32R2);
4964 gen_helper_mtc0_srsctl(cpu_env, arg);
4965 /* Stop translation as we may have switched the execution mode */
4966 ctx->bstate = BS_STOP;
4970 check_insn(env, ctx, ISA_MIPS32R2);
4971 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4972 /* Stop translation as we may have switched the execution mode */
4973 ctx->bstate = BS_STOP;
4983 save_cpu_state(ctx, 1);
4984 gen_helper_mtc0_cause(cpu_env, arg);
4994 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5008 check_insn(env, ctx, ISA_MIPS32R2);
5009 gen_helper_mtc0_ebase(cpu_env, arg);
5019 gen_helper_mtc0_config0(cpu_env, arg);
5021 /* Stop translation as we may have switched the execution mode */
5022 ctx->bstate = BS_STOP;
5025 /* ignored, read only */
5029 gen_helper_mtc0_config2(cpu_env, arg);
5031 /* Stop translation as we may have switched the execution mode */
5032 ctx->bstate = BS_STOP;
5035 /* ignored, read only */
5038 /* 4,5 are reserved */
5039 /* 6,7 are implementation dependent */
5049 rn = "Invalid config selector";
5056 gen_helper_mtc0_lladdr(cpu_env, arg);
5066 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5076 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5086 #if defined(TARGET_MIPS64)
5087 check_insn(env, ctx, ISA_MIPS3);
5088 gen_helper_mtc0_xcontext(cpu_env, arg);
5097 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5100 gen_helper_mtc0_framemask(cpu_env, arg);
5109 rn = "Diagnostic"; /* implementation dependent */
5114 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5115 /* BS_STOP isn't good enough here, hflags may have changed. */
5116 gen_save_pc(ctx->pc + 4);
5117 ctx->bstate = BS_EXCP;
5121 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5122 rn = "TraceControl";
5123 /* Stop translation as we may have switched the execution mode */
5124 ctx->bstate = BS_STOP;
5127 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5128 rn = "TraceControl2";
5129 /* Stop translation as we may have switched the execution mode */
5130 ctx->bstate = BS_STOP;
5133 /* Stop translation as we may have switched the execution mode */
5134 ctx->bstate = BS_STOP;
5135 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5136 rn = "UserTraceData";
5137 /* Stop translation as we may have switched the execution mode */
5138 ctx->bstate = BS_STOP;
5141 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5142 /* Stop translation as we may have switched the execution mode */
5143 ctx->bstate = BS_STOP;
5154 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5164 gen_helper_mtc0_performance0(cpu_env, arg);
5165 rn = "Performance0";
5168 // gen_helper_mtc0_performance1(arg);
5169 rn = "Performance1";
5172 // gen_helper_mtc0_performance2(arg);
5173 rn = "Performance2";
5176 // gen_helper_mtc0_performance3(arg);
5177 rn = "Performance3";
5180 // gen_helper_mtc0_performance4(arg);
5181 rn = "Performance4";
5184 // gen_helper_mtc0_performance5(arg);
5185 rn = "Performance5";
5188 // gen_helper_mtc0_performance6(arg);
5189 rn = "Performance6";
5192 // gen_helper_mtc0_performance7(arg);
5193 rn = "Performance7";
5219 gen_helper_mtc0_taglo(cpu_env, arg);
5226 gen_helper_mtc0_datalo(cpu_env, arg);
5239 gen_helper_mtc0_taghi(cpu_env, arg);
5246 gen_helper_mtc0_datahi(cpu_env, arg);
5257 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5268 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5274 /* Stop translation as we may have switched the execution mode */
5275 ctx->bstate = BS_STOP;
5280 (void)rn; /* avoid a compiler warning */
5281 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5282 /* For simplicity assume that all writes can cause interrupts. */
5285 ctx->bstate = BS_STOP;
5290 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5291 generate_exception(ctx, EXCP_RI);
5294 #if defined(TARGET_MIPS64)
5295 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5297 const char *rn = "invalid";
5300 check_insn(env, ctx, ISA_MIPS64);
5306 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5310 check_insn(env, ctx, ASE_MT);
5311 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5315 check_insn(env, ctx, ASE_MT);
5316 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5320 check_insn(env, ctx, ASE_MT);
5321 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5331 gen_helper_mfc0_random(arg, cpu_env);
5335 check_insn(env, ctx, ASE_MT);
5336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5340 check_insn(env, ctx, ASE_MT);
5341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5345 check_insn(env, ctx, ASE_MT);
5346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5350 check_insn(env, ctx, ASE_MT);
5351 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5355 check_insn(env, ctx, ASE_MT);
5356 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5360 check_insn(env, ctx, ASE_MT);
5361 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5362 rn = "VPEScheFBack";
5365 check_insn(env, ctx, ASE_MT);
5366 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5376 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5380 check_insn(env, ctx, ASE_MT);
5381 gen_helper_mfc0_tcstatus(arg, cpu_env);
5385 check_insn(env, ctx, ASE_MT);
5386 gen_helper_mfc0_tcbind(arg, cpu_env);
5390 check_insn(env, ctx, ASE_MT);
5391 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5395 check_insn(env, ctx, ASE_MT);
5396 gen_helper_dmfc0_tchalt(arg, cpu_env);
5400 check_insn(env, ctx, ASE_MT);
5401 gen_helper_dmfc0_tccontext(arg, cpu_env);
5405 check_insn(env, ctx, ASE_MT);
5406 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5410 check_insn(env, ctx, ASE_MT);
5411 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5421 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5431 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5435 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5436 rn = "ContextConfig";
5445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5449 check_insn(env, ctx, ISA_MIPS32R2);
5450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5464 check_insn(env, ctx, ISA_MIPS32R2);
5465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5469 check_insn(env, ctx, ISA_MIPS32R2);
5470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5474 check_insn(env, ctx, ISA_MIPS32R2);
5475 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5479 check_insn(env, ctx, ISA_MIPS32R2);
5480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5484 check_insn(env, ctx, ISA_MIPS32R2);
5485 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5495 check_insn(env, ctx, ISA_MIPS32R2);
5496 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5506 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5516 /* Mark as an IO operation because we read the time. */
5519 gen_helper_mfc0_count(arg, cpu_env);
5523 /* Break the TB to be able to take timer interrupts immediately
5524 after reading count. */
5525 ctx->bstate = BS_STOP;
5528 /* 6,7 are implementation dependent */
5536 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5546 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5549 /* 6,7 are implementation dependent */
5557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5561 check_insn(env, ctx, ISA_MIPS32R2);
5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5566 check_insn(env, ctx, ISA_MIPS32R2);
5567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5571 check_insn(env, ctx, ISA_MIPS32R2);
5572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5582 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5592 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5606 check_insn(env, ctx, ISA_MIPS32R2);
5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5629 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5632 /* 6,7 are implementation dependent */
5634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5648 gen_helper_dmfc0_lladdr(arg, cpu_env);
5658 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5668 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5678 check_insn(env, ctx, ISA_MIPS3);
5679 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5687 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5690 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5698 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5699 rn = "'Diagnostic"; /* implementation dependent */
5704 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5708 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5709 rn = "TraceControl";
5712 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5713 rn = "TraceControl2";
5716 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5717 rn = "UserTraceData";
5720 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5731 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5741 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5742 rn = "Performance0";
5745 // gen_helper_dmfc0_performance1(arg);
5746 rn = "Performance1";
5749 // gen_helper_dmfc0_performance2(arg);
5750 rn = "Performance2";
5753 // gen_helper_dmfc0_performance3(arg);
5754 rn = "Performance3";
5757 // gen_helper_dmfc0_performance4(arg);
5758 rn = "Performance4";
5761 // gen_helper_dmfc0_performance5(arg);
5762 rn = "Performance5";
5765 // gen_helper_dmfc0_performance6(arg);
5766 rn = "Performance6";
5769 // gen_helper_dmfc0_performance7(arg);
5770 rn = "Performance7";
5777 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5784 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5797 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5817 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5824 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5834 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5845 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5855 (void)rn; /* avoid a compiler warning */
5856 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5860 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5861 generate_exception(ctx, EXCP_RI);
5864 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5866 const char *rn = "invalid";
5869 check_insn(env, ctx, ISA_MIPS64);
5878 gen_helper_mtc0_index(cpu_env, arg);
5882 check_insn(env, ctx, ASE_MT);
5883 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5887 check_insn(env, ctx, ASE_MT);
5892 check_insn(env, ctx, ASE_MT);
5907 check_insn(env, ctx, ASE_MT);
5908 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5912 check_insn(env, ctx, ASE_MT);
5913 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5917 check_insn(env, ctx, ASE_MT);
5918 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5922 check_insn(env, ctx, ASE_MT);
5923 gen_helper_mtc0_yqmask(cpu_env, arg);
5927 check_insn(env, ctx, ASE_MT);
5928 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5932 check_insn(env, ctx, ASE_MT);
5933 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5934 rn = "VPEScheFBack";
5937 check_insn(env, ctx, ASE_MT);
5938 gen_helper_mtc0_vpeopt(cpu_env, arg);
5948 gen_helper_mtc0_entrylo0(cpu_env, arg);
5952 check_insn(env, ctx, ASE_MT);
5953 gen_helper_mtc0_tcstatus(cpu_env, arg);
5957 check_insn(env, ctx, ASE_MT);
5958 gen_helper_mtc0_tcbind(cpu_env, arg);
5962 check_insn(env, ctx, ASE_MT);
5963 gen_helper_mtc0_tcrestart(cpu_env, arg);
5967 check_insn(env, ctx, ASE_MT);
5968 gen_helper_mtc0_tchalt(cpu_env, arg);
5972 check_insn(env, ctx, ASE_MT);
5973 gen_helper_mtc0_tccontext(cpu_env, arg);
5977 check_insn(env, ctx, ASE_MT);
5978 gen_helper_mtc0_tcschedule(cpu_env, arg);
5982 check_insn(env, ctx, ASE_MT);
5983 gen_helper_mtc0_tcschefback(cpu_env, arg);
5993 gen_helper_mtc0_entrylo1(cpu_env, arg);
6003 gen_helper_mtc0_context(cpu_env, arg);
6007 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6008 rn = "ContextConfig";
6017 gen_helper_mtc0_pagemask(cpu_env, arg);
6021 check_insn(env, ctx, ISA_MIPS32R2);
6022 gen_helper_mtc0_pagegrain(cpu_env, arg);
6032 gen_helper_mtc0_wired(cpu_env, arg);
6036 check_insn(env, ctx, ISA_MIPS32R2);
6037 gen_helper_mtc0_srsconf0(cpu_env, arg);
6041 check_insn(env, ctx, ISA_MIPS32R2);
6042 gen_helper_mtc0_srsconf1(cpu_env, arg);
6046 check_insn(env, ctx, ISA_MIPS32R2);
6047 gen_helper_mtc0_srsconf2(cpu_env, arg);
6051 check_insn(env, ctx, ISA_MIPS32R2);
6052 gen_helper_mtc0_srsconf3(cpu_env, arg);
6056 check_insn(env, ctx, ISA_MIPS32R2);
6057 gen_helper_mtc0_srsconf4(cpu_env, arg);
6067 check_insn(env, ctx, ISA_MIPS32R2);
6068 gen_helper_mtc0_hwrena(cpu_env, arg);
6082 gen_helper_mtc0_count(cpu_env, arg);
6085 /* 6,7 are implementation dependent */
6089 /* Stop translation as we may have switched the execution mode */
6090 ctx->bstate = BS_STOP;
6095 gen_helper_mtc0_entryhi(cpu_env, arg);
6105 gen_helper_mtc0_compare(cpu_env, arg);
6108 /* 6,7 are implementation dependent */
6112 /* Stop translation as we may have switched the execution mode */
6113 ctx->bstate = BS_STOP;
6118 save_cpu_state(ctx, 1);
6119 gen_helper_mtc0_status(cpu_env, arg);
6120 /* BS_STOP isn't good enough here, hflags may have changed. */
6121 gen_save_pc(ctx->pc + 4);
6122 ctx->bstate = BS_EXCP;
6126 check_insn(env, ctx, ISA_MIPS32R2);
6127 gen_helper_mtc0_intctl(cpu_env, arg);
6128 /* Stop translation as we may have switched the execution mode */
6129 ctx->bstate = BS_STOP;
6133 check_insn(env, ctx, ISA_MIPS32R2);
6134 gen_helper_mtc0_srsctl(cpu_env, arg);
6135 /* Stop translation as we may have switched the execution mode */
6136 ctx->bstate = BS_STOP;
6140 check_insn(env, ctx, ISA_MIPS32R2);
6141 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6142 /* Stop translation as we may have switched the execution mode */
6143 ctx->bstate = BS_STOP;
6153 save_cpu_state(ctx, 1);
6154 /* Mark as an IO operation because we may trigger a software
6159 gen_helper_mtc0_cause(cpu_env, arg);
6163 /* Stop translation as we may have triggered an intetrupt */
6164 ctx->bstate = BS_STOP;
6174 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6188 check_insn(env, ctx, ISA_MIPS32R2);
6189 gen_helper_mtc0_ebase(cpu_env, arg);
6199 gen_helper_mtc0_config0(cpu_env, arg);
6201 /* Stop translation as we may have switched the execution mode */
6202 ctx->bstate = BS_STOP;
6205 /* ignored, read only */
6209 gen_helper_mtc0_config2(cpu_env, arg);
6211 /* Stop translation as we may have switched the execution mode */
6212 ctx->bstate = BS_STOP;
6218 /* 6,7 are implementation dependent */
6220 rn = "Invalid config selector";
6227 gen_helper_mtc0_lladdr(cpu_env, arg);
6237 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6247 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6257 check_insn(env, ctx, ISA_MIPS3);
6258 gen_helper_mtc0_xcontext(cpu_env, arg);
6266 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6269 gen_helper_mtc0_framemask(cpu_env, arg);
6278 rn = "Diagnostic"; /* implementation dependent */
6283 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6284 /* BS_STOP isn't good enough here, hflags may have changed. */
6285 gen_save_pc(ctx->pc + 4);
6286 ctx->bstate = BS_EXCP;
6290 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6291 /* Stop translation as we may have switched the execution mode */
6292 ctx->bstate = BS_STOP;
6293 rn = "TraceControl";
6296 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6297 /* Stop translation as we may have switched the execution mode */
6298 ctx->bstate = BS_STOP;
6299 rn = "TraceControl2";
6302 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6303 /* Stop translation as we may have switched the execution mode */
6304 ctx->bstate = BS_STOP;
6305 rn = "UserTraceData";
6308 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6309 /* Stop translation as we may have switched the execution mode */
6310 ctx->bstate = BS_STOP;
6321 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6331 gen_helper_mtc0_performance0(cpu_env, arg);
6332 rn = "Performance0";
6335 // gen_helper_mtc0_performance1(cpu_env, arg);
6336 rn = "Performance1";
6339 // gen_helper_mtc0_performance2(cpu_env, arg);
6340 rn = "Performance2";
6343 // gen_helper_mtc0_performance3(cpu_env, arg);
6344 rn = "Performance3";
6347 // gen_helper_mtc0_performance4(cpu_env, arg);
6348 rn = "Performance4";
6351 // gen_helper_mtc0_performance5(cpu_env, arg);
6352 rn = "Performance5";
6355 // gen_helper_mtc0_performance6(cpu_env, arg);
6356 rn = "Performance6";
6359 // gen_helper_mtc0_performance7(cpu_env, arg);
6360 rn = "Performance7";
6386 gen_helper_mtc0_taglo(cpu_env, arg);
6393 gen_helper_mtc0_datalo(cpu_env, arg);
6406 gen_helper_mtc0_taghi(cpu_env, arg);
6413 gen_helper_mtc0_datahi(cpu_env, arg);
6424 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6435 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6441 /* Stop translation as we may have switched the execution mode */
6442 ctx->bstate = BS_STOP;
6447 (void)rn; /* avoid a compiler warning */
6448 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6449 /* For simplicity assume that all writes can cause interrupts. */
6452 ctx->bstate = BS_STOP;
6457 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6458 generate_exception(ctx, EXCP_RI);
6460 #endif /* TARGET_MIPS64 */
6462 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6463 int u, int sel, int h)
6465 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6466 TCGv t0 = tcg_temp_local_new();
6468 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6469 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6470 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6471 tcg_gen_movi_tl(t0, -1);
6472 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6473 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6474 tcg_gen_movi_tl(t0, -1);
6480 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6483 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6493 gen_helper_mftc0_tcstatus(t0, cpu_env);
6496 gen_helper_mftc0_tcbind(t0, cpu_env);
6499 gen_helper_mftc0_tcrestart(t0, cpu_env);
6502 gen_helper_mftc0_tchalt(t0, cpu_env);
6505 gen_helper_mftc0_tccontext(t0, cpu_env);
6508 gen_helper_mftc0_tcschedule(t0, cpu_env);
6511 gen_helper_mftc0_tcschefback(t0, cpu_env);
6514 gen_mfc0(env, ctx, t0, rt, sel);
6521 gen_helper_mftc0_entryhi(t0, cpu_env);
6524 gen_mfc0(env, ctx, t0, rt, sel);
6530 gen_helper_mftc0_status(t0, cpu_env);
6533 gen_mfc0(env, ctx, t0, rt, sel);
6539 gen_helper_mftc0_cause(t0, cpu_env);
6549 gen_helper_mftc0_epc(t0, cpu_env);
6559 gen_helper_mftc0_ebase(t0, cpu_env);
6569 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6579 gen_helper_mftc0_debug(t0, cpu_env);
6582 gen_mfc0(env, ctx, t0, rt, sel);
6587 gen_mfc0(env, ctx, t0, rt, sel);
6589 } else switch (sel) {
6590 /* GPR registers. */
6592 gen_helper_1e0i(mftgpr, t0, rt);
6594 /* Auxiliary CPU registers */
6598 gen_helper_1e0i(mftlo, t0, 0);
6601 gen_helper_1e0i(mfthi, t0, 0);
6604 gen_helper_1e0i(mftacx, t0, 0);
6607 gen_helper_1e0i(mftlo, t0, 1);
6610 gen_helper_1e0i(mfthi, t0, 1);
6613 gen_helper_1e0i(mftacx, t0, 1);
6616 gen_helper_1e0i(mftlo, t0, 2);
6619 gen_helper_1e0i(mfthi, t0, 2);
6622 gen_helper_1e0i(mftacx, t0, 2);
6625 gen_helper_1e0i(mftlo, t0, 3);
6628 gen_helper_1e0i(mfthi, t0, 3);
6631 gen_helper_1e0i(mftacx, t0, 3);
6634 gen_helper_mftdsp(t0, cpu_env);
6640 /* Floating point (COP1). */
6642 /* XXX: For now we support only a single FPU context. */
6644 TCGv_i32 fp0 = tcg_temp_new_i32();
6646 gen_load_fpr32(fp0, rt);
6647 tcg_gen_ext_i32_tl(t0, fp0);
6648 tcg_temp_free_i32(fp0);
6650 TCGv_i32 fp0 = tcg_temp_new_i32();
6652 gen_load_fpr32h(fp0, rt);
6653 tcg_gen_ext_i32_tl(t0, fp0);
6654 tcg_temp_free_i32(fp0);
6658 /* XXX: For now we support only a single FPU context. */
6659 gen_helper_1e0i(cfc1, t0, rt);
6661 /* COP2: Not implemented. */
6668 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6669 gen_store_gpr(t0, rd);
6675 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6676 generate_exception(ctx, EXCP_RI);
6679 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6680 int u, int sel, int h)
6682 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6683 TCGv t0 = tcg_temp_local_new();
6685 gen_load_gpr(t0, rt);
6686 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6687 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6688 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6690 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6691 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6698 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6701 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6711 gen_helper_mttc0_tcstatus(cpu_env, t0);
6714 gen_helper_mttc0_tcbind(cpu_env, t0);
6717 gen_helper_mttc0_tcrestart(cpu_env, t0);
6720 gen_helper_mttc0_tchalt(cpu_env, t0);
6723 gen_helper_mttc0_tccontext(cpu_env, t0);
6726 gen_helper_mttc0_tcschedule(cpu_env, t0);
6729 gen_helper_mttc0_tcschefback(cpu_env, t0);
6732 gen_mtc0(env, ctx, t0, rd, sel);
6739 gen_helper_mttc0_entryhi(cpu_env, t0);
6742 gen_mtc0(env, ctx, t0, rd, sel);
6748 gen_helper_mttc0_status(cpu_env, t0);
6751 gen_mtc0(env, ctx, t0, rd, sel);
6757 gen_helper_mttc0_cause(cpu_env, t0);
6767 gen_helper_mttc0_ebase(cpu_env, t0);
6777 gen_helper_mttc0_debug(cpu_env, t0);
6780 gen_mtc0(env, ctx, t0, rd, sel);
6785 gen_mtc0(env, ctx, t0, rd, sel);
6787 } else switch (sel) {
6788 /* GPR registers. */
6790 gen_helper_0e1i(mttgpr, t0, rd);
6792 /* Auxiliary CPU registers */
6796 gen_helper_0e1i(mttlo, t0, 0);
6799 gen_helper_0e1i(mtthi, t0, 0);
6802 gen_helper_0e1i(mttacx, t0, 0);
6805 gen_helper_0e1i(mttlo, t0, 1);
6808 gen_helper_0e1i(mtthi, t0, 1);
6811 gen_helper_0e1i(mttacx, t0, 1);
6814 gen_helper_0e1i(mttlo, t0, 2);
6817 gen_helper_0e1i(mtthi, t0, 2);
6820 gen_helper_0e1i(mttacx, t0, 2);
6823 gen_helper_0e1i(mttlo, t0, 3);
6826 gen_helper_0e1i(mtthi, t0, 3);
6829 gen_helper_0e1i(mttacx, t0, 3);
6832 gen_helper_mttdsp(cpu_env, t0);
6838 /* Floating point (COP1). */
6840 /* XXX: For now we support only a single FPU context. */
6842 TCGv_i32 fp0 = tcg_temp_new_i32();
6844 tcg_gen_trunc_tl_i32(fp0, t0);
6845 gen_store_fpr32(fp0, rd);
6846 tcg_temp_free_i32(fp0);
6848 TCGv_i32 fp0 = tcg_temp_new_i32();
6850 tcg_gen_trunc_tl_i32(fp0, t0);
6851 gen_store_fpr32h(fp0, rd);
6852 tcg_temp_free_i32(fp0);
6856 /* XXX: For now we support only a single FPU context. */
6857 gen_helper_0e1i(ctc1, t0, rd);
6859 /* COP2: Not implemented. */
6866 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6872 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6873 generate_exception(ctx, EXCP_RI);
6876 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6878 const char *opn = "ldst";
6880 check_cp0_enabled(ctx);
6887 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6892 TCGv t0 = tcg_temp_new();
6894 gen_load_gpr(t0, rt);
6895 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6900 #if defined(TARGET_MIPS64)
6902 check_insn(env, ctx, ISA_MIPS3);
6907 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6911 check_insn(env, ctx, ISA_MIPS3);
6913 TCGv t0 = tcg_temp_new();
6915 gen_load_gpr(t0, rt);
6916 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6923 check_insn(env, ctx, ASE_MT);
6928 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6929 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6933 check_insn(env, ctx, ASE_MT);
6934 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6935 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6940 if (!env->tlb->helper_tlbwi)
6942 gen_helper_tlbwi(cpu_env);
6946 if (!env->tlb->helper_tlbwr)
6948 gen_helper_tlbwr(cpu_env);
6952 if (!env->tlb->helper_tlbp)
6954 gen_helper_tlbp(cpu_env);
6958 if (!env->tlb->helper_tlbr)
6960 gen_helper_tlbr(cpu_env);
6964 check_insn(env, ctx, ISA_MIPS2);
6965 gen_helper_eret(cpu_env);
6966 ctx->bstate = BS_EXCP;
6970 check_insn(env, ctx, ISA_MIPS32);
6971 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6973 generate_exception(ctx, EXCP_RI);
6975 gen_helper_deret(cpu_env);
6976 ctx->bstate = BS_EXCP;
6981 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6982 /* If we get an exception, we want to restart at next instruction */
6984 save_cpu_state(ctx, 1);
6986 gen_helper_wait(cpu_env);
6987 ctx->bstate = BS_EXCP;
6992 generate_exception(ctx, EXCP_RI);
6995 (void)opn; /* avoid a compiler warning */
6996 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6998 #endif /* !CONFIG_USER_ONLY */
7000 /* CP1 Branches (before delay slot) */
7001 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
7002 int32_t cc, int32_t offset)
7004 target_ulong btarget;
7005 const char *opn = "cp1 cond branch";
7006 TCGv_i32 t0 = tcg_temp_new_i32();
7009 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7011 btarget = ctx->pc + 4 + offset;
7015 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7016 tcg_gen_not_i32(t0, t0);
7017 tcg_gen_andi_i32(t0, t0, 1);
7018 tcg_gen_extu_i32_tl(bcond, t0);
7022 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7023 tcg_gen_not_i32(t0, t0);
7024 tcg_gen_andi_i32(t0, t0, 1);
7025 tcg_gen_extu_i32_tl(bcond, t0);
7029 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
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_andi_i32(t0, t0, 1);
7037 tcg_gen_extu_i32_tl(bcond, t0);
7040 ctx->hflags |= MIPS_HFLAG_BL;
7044 TCGv_i32 t1 = tcg_temp_new_i32();
7045 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7046 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7047 tcg_gen_nand_i32(t0, t0, t1);
7048 tcg_temp_free_i32(t1);
7049 tcg_gen_andi_i32(t0, t0, 1);
7050 tcg_gen_extu_i32_tl(bcond, t0);
7056 TCGv_i32 t1 = tcg_temp_new_i32();
7057 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7058 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7059 tcg_gen_or_i32(t0, t0, t1);
7060 tcg_temp_free_i32(t1);
7061 tcg_gen_andi_i32(t0, t0, 1);
7062 tcg_gen_extu_i32_tl(bcond, t0);
7068 TCGv_i32 t1 = tcg_temp_new_i32();
7069 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7070 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7071 tcg_gen_and_i32(t0, t0, t1);
7072 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7073 tcg_gen_and_i32(t0, t0, t1);
7074 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7075 tcg_gen_nand_i32(t0, t0, t1);
7076 tcg_temp_free_i32(t1);
7077 tcg_gen_andi_i32(t0, t0, 1);
7078 tcg_gen_extu_i32_tl(bcond, t0);
7084 TCGv_i32 t1 = tcg_temp_new_i32();
7085 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7086 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7087 tcg_gen_or_i32(t0, t0, t1);
7088 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7089 tcg_gen_or_i32(t0, t0, t1);
7090 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7091 tcg_gen_or_i32(t0, t0, t1);
7092 tcg_temp_free_i32(t1);
7093 tcg_gen_andi_i32(t0, t0, 1);
7094 tcg_gen_extu_i32_tl(bcond, t0);
7098 ctx->hflags |= MIPS_HFLAG_BC;
7102 generate_exception (ctx, EXCP_RI);
7105 (void)opn; /* avoid a compiler warning */
7106 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7107 ctx->hflags, btarget);
7108 ctx->btarget = btarget;
7111 tcg_temp_free_i32(t0);
7114 /* Coprocessor 1 (FPU) */
7116 #define FOP(func, fmt) (((fmt) << 21) | (func))
7119 OPC_ADD_S = FOP(0, FMT_S),
7120 OPC_SUB_S = FOP(1, FMT_S),
7121 OPC_MUL_S = FOP(2, FMT_S),
7122 OPC_DIV_S = FOP(3, FMT_S),
7123 OPC_SQRT_S = FOP(4, FMT_S),
7124 OPC_ABS_S = FOP(5, FMT_S),
7125 OPC_MOV_S = FOP(6, FMT_S),
7126 OPC_NEG_S = FOP(7, FMT_S),
7127 OPC_ROUND_L_S = FOP(8, FMT_S),
7128 OPC_TRUNC_L_S = FOP(9, FMT_S),
7129 OPC_CEIL_L_S = FOP(10, FMT_S),
7130 OPC_FLOOR_L_S = FOP(11, FMT_S),
7131 OPC_ROUND_W_S = FOP(12, FMT_S),
7132 OPC_TRUNC_W_S = FOP(13, FMT_S),
7133 OPC_CEIL_W_S = FOP(14, FMT_S),
7134 OPC_FLOOR_W_S = FOP(15, FMT_S),
7135 OPC_MOVCF_S = FOP(17, FMT_S),
7136 OPC_MOVZ_S = FOP(18, FMT_S),
7137 OPC_MOVN_S = FOP(19, FMT_S),
7138 OPC_RECIP_S = FOP(21, FMT_S),
7139 OPC_RSQRT_S = FOP(22, FMT_S),
7140 OPC_RECIP2_S = FOP(28, FMT_S),
7141 OPC_RECIP1_S = FOP(29, FMT_S),
7142 OPC_RSQRT1_S = FOP(30, FMT_S),
7143 OPC_RSQRT2_S = FOP(31, FMT_S),
7144 OPC_CVT_D_S = FOP(33, FMT_S),
7145 OPC_CVT_W_S = FOP(36, FMT_S),
7146 OPC_CVT_L_S = FOP(37, FMT_S),
7147 OPC_CVT_PS_S = FOP(38, FMT_S),
7148 OPC_CMP_F_S = FOP (48, FMT_S),
7149 OPC_CMP_UN_S = FOP (49, FMT_S),
7150 OPC_CMP_EQ_S = FOP (50, FMT_S),
7151 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7152 OPC_CMP_OLT_S = FOP (52, FMT_S),
7153 OPC_CMP_ULT_S = FOP (53, FMT_S),
7154 OPC_CMP_OLE_S = FOP (54, FMT_S),
7155 OPC_CMP_ULE_S = FOP (55, FMT_S),
7156 OPC_CMP_SF_S = FOP (56, FMT_S),
7157 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7158 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7159 OPC_CMP_NGL_S = FOP (59, FMT_S),
7160 OPC_CMP_LT_S = FOP (60, FMT_S),
7161 OPC_CMP_NGE_S = FOP (61, FMT_S),
7162 OPC_CMP_LE_S = FOP (62, FMT_S),
7163 OPC_CMP_NGT_S = FOP (63, FMT_S),
7165 OPC_ADD_D = FOP(0, FMT_D),
7166 OPC_SUB_D = FOP(1, FMT_D),
7167 OPC_MUL_D = FOP(2, FMT_D),
7168 OPC_DIV_D = FOP(3, FMT_D),
7169 OPC_SQRT_D = FOP(4, FMT_D),
7170 OPC_ABS_D = FOP(5, FMT_D),
7171 OPC_MOV_D = FOP(6, FMT_D),
7172 OPC_NEG_D = FOP(7, FMT_D),
7173 OPC_ROUND_L_D = FOP(8, FMT_D),
7174 OPC_TRUNC_L_D = FOP(9, FMT_D),
7175 OPC_CEIL_L_D = FOP(10, FMT_D),
7176 OPC_FLOOR_L_D = FOP(11, FMT_D),
7177 OPC_ROUND_W_D = FOP(12, FMT_D),
7178 OPC_TRUNC_W_D = FOP(13, FMT_D),
7179 OPC_CEIL_W_D = FOP(14, FMT_D),
7180 OPC_FLOOR_W_D = FOP(15, FMT_D),
7181 OPC_MOVCF_D = FOP(17, FMT_D),
7182 OPC_MOVZ_D = FOP(18, FMT_D),
7183 OPC_MOVN_D = FOP(19, FMT_D),
7184 OPC_RECIP_D = FOP(21, FMT_D),
7185 OPC_RSQRT_D = FOP(22, FMT_D),
7186 OPC_RECIP2_D = FOP(28, FMT_D),
7187 OPC_RECIP1_D = FOP(29, FMT_D),
7188 OPC_RSQRT1_D = FOP(30, FMT_D),
7189 OPC_RSQRT2_D = FOP(31, FMT_D),
7190 OPC_CVT_S_D = FOP(32, FMT_D),
7191 OPC_CVT_W_D = FOP(36, FMT_D),
7192 OPC_CVT_L_D = FOP(37, FMT_D),
7193 OPC_CMP_F_D = FOP (48, FMT_D),
7194 OPC_CMP_UN_D = FOP (49, FMT_D),
7195 OPC_CMP_EQ_D = FOP (50, FMT_D),
7196 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7197 OPC_CMP_OLT_D = FOP (52, FMT_D),
7198 OPC_CMP_ULT_D = FOP (53, FMT_D),
7199 OPC_CMP_OLE_D = FOP (54, FMT_D),
7200 OPC_CMP_ULE_D = FOP (55, FMT_D),
7201 OPC_CMP_SF_D = FOP (56, FMT_D),
7202 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7203 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7204 OPC_CMP_NGL_D = FOP (59, FMT_D),
7205 OPC_CMP_LT_D = FOP (60, FMT_D),
7206 OPC_CMP_NGE_D = FOP (61, FMT_D),
7207 OPC_CMP_LE_D = FOP (62, FMT_D),
7208 OPC_CMP_NGT_D = FOP (63, FMT_D),
7210 OPC_CVT_S_W = FOP(32, FMT_W),
7211 OPC_CVT_D_W = FOP(33, FMT_W),
7212 OPC_CVT_S_L = FOP(32, FMT_L),
7213 OPC_CVT_D_L = FOP(33, FMT_L),
7214 OPC_CVT_PS_PW = FOP(38, FMT_W),
7216 OPC_ADD_PS = FOP(0, FMT_PS),
7217 OPC_SUB_PS = FOP(1, FMT_PS),
7218 OPC_MUL_PS = FOP(2, FMT_PS),
7219 OPC_DIV_PS = FOP(3, FMT_PS),
7220 OPC_ABS_PS = FOP(5, FMT_PS),
7221 OPC_MOV_PS = FOP(6, FMT_PS),
7222 OPC_NEG_PS = FOP(7, FMT_PS),
7223 OPC_MOVCF_PS = FOP(17, FMT_PS),
7224 OPC_MOVZ_PS = FOP(18, FMT_PS),
7225 OPC_MOVN_PS = FOP(19, FMT_PS),
7226 OPC_ADDR_PS = FOP(24, FMT_PS),
7227 OPC_MULR_PS = FOP(26, FMT_PS),
7228 OPC_RECIP2_PS = FOP(28, FMT_PS),
7229 OPC_RECIP1_PS = FOP(29, FMT_PS),
7230 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7231 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7233 OPC_CVT_S_PU = FOP(32, FMT_PS),
7234 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7235 OPC_CVT_S_PL = FOP(40, FMT_PS),
7236 OPC_PLL_PS = FOP(44, FMT_PS),
7237 OPC_PLU_PS = FOP(45, FMT_PS),
7238 OPC_PUL_PS = FOP(46, FMT_PS),
7239 OPC_PUU_PS = FOP(47, FMT_PS),
7240 OPC_CMP_F_PS = FOP (48, FMT_PS),
7241 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7242 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7243 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7244 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7245 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7246 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7247 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7248 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7249 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7250 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7251 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7252 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7253 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7254 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7255 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7258 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7260 const char *opn = "cp1 move";
7261 TCGv t0 = tcg_temp_new();
7266 TCGv_i32 fp0 = tcg_temp_new_i32();
7268 gen_load_fpr32(fp0, fs);
7269 tcg_gen_ext_i32_tl(t0, fp0);
7270 tcg_temp_free_i32(fp0);
7272 gen_store_gpr(t0, rt);
7276 gen_load_gpr(t0, rt);
7278 TCGv_i32 fp0 = tcg_temp_new_i32();
7280 tcg_gen_trunc_tl_i32(fp0, t0);
7281 gen_store_fpr32(fp0, fs);
7282 tcg_temp_free_i32(fp0);
7287 gen_helper_1e0i(cfc1, t0, fs);
7288 gen_store_gpr(t0, rt);
7292 gen_load_gpr(t0, rt);
7293 gen_helper_0e1i(ctc1, t0, fs);
7296 #if defined(TARGET_MIPS64)
7298 gen_load_fpr64(ctx, t0, fs);
7299 gen_store_gpr(t0, rt);
7303 gen_load_gpr(t0, rt);
7304 gen_store_fpr64(ctx, t0, fs);
7310 TCGv_i32 fp0 = tcg_temp_new_i32();
7312 gen_load_fpr32h(fp0, fs);
7313 tcg_gen_ext_i32_tl(t0, fp0);
7314 tcg_temp_free_i32(fp0);
7316 gen_store_gpr(t0, rt);
7320 gen_load_gpr(t0, rt);
7322 TCGv_i32 fp0 = tcg_temp_new_i32();
7324 tcg_gen_trunc_tl_i32(fp0, t0);
7325 gen_store_fpr32h(fp0, fs);
7326 tcg_temp_free_i32(fp0);
7332 generate_exception (ctx, EXCP_RI);
7335 (void)opn; /* avoid a compiler warning */
7336 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7342 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7358 l1 = gen_new_label();
7359 t0 = tcg_temp_new_i32();
7360 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7361 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7362 tcg_temp_free_i32(t0);
7364 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7366 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7371 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7374 TCGv_i32 t0 = tcg_temp_new_i32();
7375 int l1 = gen_new_label();
7382 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7383 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7384 gen_load_fpr32(t0, fs);
7385 gen_store_fpr32(t0, fd);
7387 tcg_temp_free_i32(t0);
7390 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7393 TCGv_i32 t0 = tcg_temp_new_i32();
7395 int l1 = gen_new_label();
7402 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7403 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7404 tcg_temp_free_i32(t0);
7405 fp0 = tcg_temp_new_i64();
7406 gen_load_fpr64(ctx, fp0, fs);
7407 gen_store_fpr64(ctx, fp0, fd);
7408 tcg_temp_free_i64(fp0);
7412 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7415 TCGv_i32 t0 = tcg_temp_new_i32();
7416 int l1 = gen_new_label();
7417 int l2 = gen_new_label();
7424 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7425 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7426 gen_load_fpr32(t0, fs);
7427 gen_store_fpr32(t0, fd);
7430 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7431 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7432 gen_load_fpr32h(t0, fs);
7433 gen_store_fpr32h(t0, fd);
7434 tcg_temp_free_i32(t0);
7439 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7440 int ft, int fs, int fd, int cc)
7442 const char *opn = "farith";
7443 const char *condnames[] = {
7461 const char *condnames_abs[] = {
7479 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7480 uint32_t func = ctx->opcode & 0x3f;
7485 TCGv_i32 fp0 = tcg_temp_new_i32();
7486 TCGv_i32 fp1 = tcg_temp_new_i32();
7488 gen_load_fpr32(fp0, fs);
7489 gen_load_fpr32(fp1, ft);
7490 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7491 tcg_temp_free_i32(fp1);
7492 gen_store_fpr32(fp0, fd);
7493 tcg_temp_free_i32(fp0);
7500 TCGv_i32 fp0 = tcg_temp_new_i32();
7501 TCGv_i32 fp1 = tcg_temp_new_i32();
7503 gen_load_fpr32(fp0, fs);
7504 gen_load_fpr32(fp1, ft);
7505 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7506 tcg_temp_free_i32(fp1);
7507 gen_store_fpr32(fp0, fd);
7508 tcg_temp_free_i32(fp0);
7515 TCGv_i32 fp0 = tcg_temp_new_i32();
7516 TCGv_i32 fp1 = tcg_temp_new_i32();
7518 gen_load_fpr32(fp0, fs);
7519 gen_load_fpr32(fp1, ft);
7520 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7521 tcg_temp_free_i32(fp1);
7522 gen_store_fpr32(fp0, fd);
7523 tcg_temp_free_i32(fp0);
7530 TCGv_i32 fp0 = tcg_temp_new_i32();
7531 TCGv_i32 fp1 = tcg_temp_new_i32();
7533 gen_load_fpr32(fp0, fs);
7534 gen_load_fpr32(fp1, ft);
7535 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7536 tcg_temp_free_i32(fp1);
7537 gen_store_fpr32(fp0, fd);
7538 tcg_temp_free_i32(fp0);
7545 TCGv_i32 fp0 = tcg_temp_new_i32();
7547 gen_load_fpr32(fp0, fs);
7548 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7549 gen_store_fpr32(fp0, fd);
7550 tcg_temp_free_i32(fp0);
7556 TCGv_i32 fp0 = tcg_temp_new_i32();
7558 gen_load_fpr32(fp0, fs);
7559 gen_helper_float_abs_s(fp0, fp0);
7560 gen_store_fpr32(fp0, fd);
7561 tcg_temp_free_i32(fp0);
7567 TCGv_i32 fp0 = tcg_temp_new_i32();
7569 gen_load_fpr32(fp0, fs);
7570 gen_store_fpr32(fp0, fd);
7571 tcg_temp_free_i32(fp0);
7577 TCGv_i32 fp0 = tcg_temp_new_i32();
7579 gen_load_fpr32(fp0, fs);
7580 gen_helper_float_chs_s(fp0, fp0);
7581 gen_store_fpr32(fp0, fd);
7582 tcg_temp_free_i32(fp0);
7587 check_cp1_64bitmode(ctx);
7589 TCGv_i32 fp32 = tcg_temp_new_i32();
7590 TCGv_i64 fp64 = tcg_temp_new_i64();
7592 gen_load_fpr32(fp32, fs);
7593 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7594 tcg_temp_free_i32(fp32);
7595 gen_store_fpr64(ctx, fp64, fd);
7596 tcg_temp_free_i64(fp64);
7601 check_cp1_64bitmode(ctx);
7603 TCGv_i32 fp32 = tcg_temp_new_i32();
7604 TCGv_i64 fp64 = tcg_temp_new_i64();
7606 gen_load_fpr32(fp32, fs);
7607 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7608 tcg_temp_free_i32(fp32);
7609 gen_store_fpr64(ctx, fp64, fd);
7610 tcg_temp_free_i64(fp64);
7615 check_cp1_64bitmode(ctx);
7617 TCGv_i32 fp32 = tcg_temp_new_i32();
7618 TCGv_i64 fp64 = tcg_temp_new_i64();
7620 gen_load_fpr32(fp32, fs);
7621 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7622 tcg_temp_free_i32(fp32);
7623 gen_store_fpr64(ctx, fp64, fd);
7624 tcg_temp_free_i64(fp64);
7629 check_cp1_64bitmode(ctx);
7631 TCGv_i32 fp32 = tcg_temp_new_i32();
7632 TCGv_i64 fp64 = tcg_temp_new_i64();
7634 gen_load_fpr32(fp32, fs);
7635 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7636 tcg_temp_free_i32(fp32);
7637 gen_store_fpr64(ctx, fp64, fd);
7638 tcg_temp_free_i64(fp64);
7644 TCGv_i32 fp0 = tcg_temp_new_i32();
7646 gen_load_fpr32(fp0, fs);
7647 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7648 gen_store_fpr32(fp0, fd);
7649 tcg_temp_free_i32(fp0);
7655 TCGv_i32 fp0 = tcg_temp_new_i32();
7657 gen_load_fpr32(fp0, fs);
7658 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7659 gen_store_fpr32(fp0, fd);
7660 tcg_temp_free_i32(fp0);
7666 TCGv_i32 fp0 = tcg_temp_new_i32();
7668 gen_load_fpr32(fp0, fs);
7669 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7670 gen_store_fpr32(fp0, fd);
7671 tcg_temp_free_i32(fp0);
7677 TCGv_i32 fp0 = tcg_temp_new_i32();
7679 gen_load_fpr32(fp0, fs);
7680 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7681 gen_store_fpr32(fp0, fd);
7682 tcg_temp_free_i32(fp0);
7687 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7692 int l1 = gen_new_label();
7696 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7698 fp0 = tcg_temp_new_i32();
7699 gen_load_fpr32(fp0, fs);
7700 gen_store_fpr32(fp0, fd);
7701 tcg_temp_free_i32(fp0);
7708 int l1 = gen_new_label();
7712 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7713 fp0 = tcg_temp_new_i32();
7714 gen_load_fpr32(fp0, fs);
7715 gen_store_fpr32(fp0, fd);
7716 tcg_temp_free_i32(fp0);
7725 TCGv_i32 fp0 = tcg_temp_new_i32();
7727 gen_load_fpr32(fp0, fs);
7728 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7729 gen_store_fpr32(fp0, fd);
7730 tcg_temp_free_i32(fp0);
7737 TCGv_i32 fp0 = tcg_temp_new_i32();
7739 gen_load_fpr32(fp0, fs);
7740 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7741 gen_store_fpr32(fp0, fd);
7742 tcg_temp_free_i32(fp0);
7747 check_cp1_64bitmode(ctx);
7749 TCGv_i32 fp0 = tcg_temp_new_i32();
7750 TCGv_i32 fp1 = tcg_temp_new_i32();
7752 gen_load_fpr32(fp0, fs);
7753 gen_load_fpr32(fp1, ft);
7754 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7755 tcg_temp_free_i32(fp1);
7756 gen_store_fpr32(fp0, fd);
7757 tcg_temp_free_i32(fp0);
7762 check_cp1_64bitmode(ctx);
7764 TCGv_i32 fp0 = tcg_temp_new_i32();
7766 gen_load_fpr32(fp0, fs);
7767 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7768 gen_store_fpr32(fp0, fd);
7769 tcg_temp_free_i32(fp0);
7774 check_cp1_64bitmode(ctx);
7776 TCGv_i32 fp0 = tcg_temp_new_i32();
7778 gen_load_fpr32(fp0, fs);
7779 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7780 gen_store_fpr32(fp0, fd);
7781 tcg_temp_free_i32(fp0);
7786 check_cp1_64bitmode(ctx);
7788 TCGv_i32 fp0 = tcg_temp_new_i32();
7789 TCGv_i32 fp1 = tcg_temp_new_i32();
7791 gen_load_fpr32(fp0, fs);
7792 gen_load_fpr32(fp1, ft);
7793 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7794 tcg_temp_free_i32(fp1);
7795 gen_store_fpr32(fp0, fd);
7796 tcg_temp_free_i32(fp0);
7801 check_cp1_registers(ctx, fd);
7803 TCGv_i32 fp32 = tcg_temp_new_i32();
7804 TCGv_i64 fp64 = tcg_temp_new_i64();
7806 gen_load_fpr32(fp32, fs);
7807 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7808 tcg_temp_free_i32(fp32);
7809 gen_store_fpr64(ctx, fp64, fd);
7810 tcg_temp_free_i64(fp64);
7816 TCGv_i32 fp0 = tcg_temp_new_i32();
7818 gen_load_fpr32(fp0, fs);
7819 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7820 gen_store_fpr32(fp0, fd);
7821 tcg_temp_free_i32(fp0);
7826 check_cp1_64bitmode(ctx);
7828 TCGv_i32 fp32 = tcg_temp_new_i32();
7829 TCGv_i64 fp64 = tcg_temp_new_i64();
7831 gen_load_fpr32(fp32, fs);
7832 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7833 tcg_temp_free_i32(fp32);
7834 gen_store_fpr64(ctx, fp64, fd);
7835 tcg_temp_free_i64(fp64);
7840 check_cp1_64bitmode(ctx);
7842 TCGv_i64 fp64 = tcg_temp_new_i64();
7843 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7844 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7846 gen_load_fpr32(fp32_0, fs);
7847 gen_load_fpr32(fp32_1, ft);
7848 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7849 tcg_temp_free_i32(fp32_1);
7850 tcg_temp_free_i32(fp32_0);
7851 gen_store_fpr64(ctx, fp64, fd);
7852 tcg_temp_free_i64(fp64);
7865 case OPC_CMP_NGLE_S:
7872 if (ctx->opcode & (1 << 6)) {
7873 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7874 opn = condnames_abs[func-48];
7876 gen_cmp_s(ctx, func-48, ft, fs, cc);
7877 opn = condnames[func-48];
7881 check_cp1_registers(ctx, fs | ft | fd);
7883 TCGv_i64 fp0 = tcg_temp_new_i64();
7884 TCGv_i64 fp1 = tcg_temp_new_i64();
7886 gen_load_fpr64(ctx, fp0, fs);
7887 gen_load_fpr64(ctx, fp1, ft);
7888 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7889 tcg_temp_free_i64(fp1);
7890 gen_store_fpr64(ctx, fp0, fd);
7891 tcg_temp_free_i64(fp0);
7897 check_cp1_registers(ctx, fs | ft | fd);
7899 TCGv_i64 fp0 = tcg_temp_new_i64();
7900 TCGv_i64 fp1 = tcg_temp_new_i64();
7902 gen_load_fpr64(ctx, fp0, fs);
7903 gen_load_fpr64(ctx, fp1, ft);
7904 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7905 tcg_temp_free_i64(fp1);
7906 gen_store_fpr64(ctx, fp0, fd);
7907 tcg_temp_free_i64(fp0);
7913 check_cp1_registers(ctx, fs | ft | fd);
7915 TCGv_i64 fp0 = tcg_temp_new_i64();
7916 TCGv_i64 fp1 = tcg_temp_new_i64();
7918 gen_load_fpr64(ctx, fp0, fs);
7919 gen_load_fpr64(ctx, fp1, ft);
7920 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7921 tcg_temp_free_i64(fp1);
7922 gen_store_fpr64(ctx, fp0, fd);
7923 tcg_temp_free_i64(fp0);
7929 check_cp1_registers(ctx, fs | ft | fd);
7931 TCGv_i64 fp0 = tcg_temp_new_i64();
7932 TCGv_i64 fp1 = tcg_temp_new_i64();
7934 gen_load_fpr64(ctx, fp0, fs);
7935 gen_load_fpr64(ctx, fp1, ft);
7936 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7937 tcg_temp_free_i64(fp1);
7938 gen_store_fpr64(ctx, fp0, fd);
7939 tcg_temp_free_i64(fp0);
7945 check_cp1_registers(ctx, fs | fd);
7947 TCGv_i64 fp0 = tcg_temp_new_i64();
7949 gen_load_fpr64(ctx, fp0, fs);
7950 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7951 gen_store_fpr64(ctx, fp0, fd);
7952 tcg_temp_free_i64(fp0);
7957 check_cp1_registers(ctx, fs | fd);
7959 TCGv_i64 fp0 = tcg_temp_new_i64();
7961 gen_load_fpr64(ctx, fp0, fs);
7962 gen_helper_float_abs_d(fp0, fp0);
7963 gen_store_fpr64(ctx, fp0, fd);
7964 tcg_temp_free_i64(fp0);
7969 check_cp1_registers(ctx, fs | fd);
7971 TCGv_i64 fp0 = tcg_temp_new_i64();
7973 gen_load_fpr64(ctx, fp0, fs);
7974 gen_store_fpr64(ctx, fp0, fd);
7975 tcg_temp_free_i64(fp0);
7980 check_cp1_registers(ctx, fs | fd);
7982 TCGv_i64 fp0 = tcg_temp_new_i64();
7984 gen_load_fpr64(ctx, fp0, fs);
7985 gen_helper_float_chs_d(fp0, fp0);
7986 gen_store_fpr64(ctx, fp0, fd);
7987 tcg_temp_free_i64(fp0);
7992 check_cp1_64bitmode(ctx);
7994 TCGv_i64 fp0 = tcg_temp_new_i64();
7996 gen_load_fpr64(ctx, fp0, fs);
7997 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7998 gen_store_fpr64(ctx, fp0, fd);
7999 tcg_temp_free_i64(fp0);
8004 check_cp1_64bitmode(ctx);
8006 TCGv_i64 fp0 = tcg_temp_new_i64();
8008 gen_load_fpr64(ctx, fp0, fs);
8009 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8010 gen_store_fpr64(ctx, fp0, fd);
8011 tcg_temp_free_i64(fp0);
8016 check_cp1_64bitmode(ctx);
8018 TCGv_i64 fp0 = tcg_temp_new_i64();
8020 gen_load_fpr64(ctx, fp0, fs);
8021 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8022 gen_store_fpr64(ctx, fp0, fd);
8023 tcg_temp_free_i64(fp0);
8028 check_cp1_64bitmode(ctx);
8030 TCGv_i64 fp0 = tcg_temp_new_i64();
8032 gen_load_fpr64(ctx, fp0, fs);
8033 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8034 gen_store_fpr64(ctx, fp0, fd);
8035 tcg_temp_free_i64(fp0);
8040 check_cp1_registers(ctx, fs);
8042 TCGv_i32 fp32 = tcg_temp_new_i32();
8043 TCGv_i64 fp64 = tcg_temp_new_i64();
8045 gen_load_fpr64(ctx, fp64, fs);
8046 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8047 tcg_temp_free_i64(fp64);
8048 gen_store_fpr32(fp32, fd);
8049 tcg_temp_free_i32(fp32);
8054 check_cp1_registers(ctx, fs);
8056 TCGv_i32 fp32 = tcg_temp_new_i32();
8057 TCGv_i64 fp64 = tcg_temp_new_i64();
8059 gen_load_fpr64(ctx, fp64, fs);
8060 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8061 tcg_temp_free_i64(fp64);
8062 gen_store_fpr32(fp32, fd);
8063 tcg_temp_free_i32(fp32);
8068 check_cp1_registers(ctx, fs);
8070 TCGv_i32 fp32 = tcg_temp_new_i32();
8071 TCGv_i64 fp64 = tcg_temp_new_i64();
8073 gen_load_fpr64(ctx, fp64, fs);
8074 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8075 tcg_temp_free_i64(fp64);
8076 gen_store_fpr32(fp32, fd);
8077 tcg_temp_free_i32(fp32);
8082 check_cp1_registers(ctx, fs);
8084 TCGv_i32 fp32 = tcg_temp_new_i32();
8085 TCGv_i64 fp64 = tcg_temp_new_i64();
8087 gen_load_fpr64(ctx, fp64, fs);
8088 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8089 tcg_temp_free_i64(fp64);
8090 gen_store_fpr32(fp32, fd);
8091 tcg_temp_free_i32(fp32);
8096 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8101 int l1 = gen_new_label();
8105 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8107 fp0 = tcg_temp_new_i64();
8108 gen_load_fpr64(ctx, fp0, fs);
8109 gen_store_fpr64(ctx, fp0, fd);
8110 tcg_temp_free_i64(fp0);
8117 int l1 = gen_new_label();
8121 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8122 fp0 = tcg_temp_new_i64();
8123 gen_load_fpr64(ctx, fp0, fs);
8124 gen_store_fpr64(ctx, fp0, fd);
8125 tcg_temp_free_i64(fp0);
8132 check_cp1_64bitmode(ctx);
8134 TCGv_i64 fp0 = tcg_temp_new_i64();
8136 gen_load_fpr64(ctx, fp0, fs);
8137 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8138 gen_store_fpr64(ctx, fp0, fd);
8139 tcg_temp_free_i64(fp0);
8144 check_cp1_64bitmode(ctx);
8146 TCGv_i64 fp0 = tcg_temp_new_i64();
8148 gen_load_fpr64(ctx, fp0, fs);
8149 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8150 gen_store_fpr64(ctx, fp0, fd);
8151 tcg_temp_free_i64(fp0);
8156 check_cp1_64bitmode(ctx);
8158 TCGv_i64 fp0 = tcg_temp_new_i64();
8159 TCGv_i64 fp1 = tcg_temp_new_i64();
8161 gen_load_fpr64(ctx, fp0, fs);
8162 gen_load_fpr64(ctx, fp1, ft);
8163 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8164 tcg_temp_free_i64(fp1);
8165 gen_store_fpr64(ctx, fp0, fd);
8166 tcg_temp_free_i64(fp0);
8171 check_cp1_64bitmode(ctx);
8173 TCGv_i64 fp0 = tcg_temp_new_i64();
8175 gen_load_fpr64(ctx, fp0, fs);
8176 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8177 gen_store_fpr64(ctx, fp0, fd);
8178 tcg_temp_free_i64(fp0);
8183 check_cp1_64bitmode(ctx);
8185 TCGv_i64 fp0 = tcg_temp_new_i64();
8187 gen_load_fpr64(ctx, fp0, fs);
8188 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8189 gen_store_fpr64(ctx, fp0, fd);
8190 tcg_temp_free_i64(fp0);
8195 check_cp1_64bitmode(ctx);
8197 TCGv_i64 fp0 = tcg_temp_new_i64();
8198 TCGv_i64 fp1 = tcg_temp_new_i64();
8200 gen_load_fpr64(ctx, fp0, fs);
8201 gen_load_fpr64(ctx, fp1, ft);
8202 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8203 tcg_temp_free_i64(fp1);
8204 gen_store_fpr64(ctx, fp0, fd);
8205 tcg_temp_free_i64(fp0);
8218 case OPC_CMP_NGLE_D:
8225 if (ctx->opcode & (1 << 6)) {
8226 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8227 opn = condnames_abs[func-48];
8229 gen_cmp_d(ctx, func-48, ft, fs, cc);
8230 opn = condnames[func-48];
8234 check_cp1_registers(ctx, fs);
8236 TCGv_i32 fp32 = tcg_temp_new_i32();
8237 TCGv_i64 fp64 = tcg_temp_new_i64();
8239 gen_load_fpr64(ctx, fp64, fs);
8240 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8241 tcg_temp_free_i64(fp64);
8242 gen_store_fpr32(fp32, fd);
8243 tcg_temp_free_i32(fp32);
8248 check_cp1_registers(ctx, fs);
8250 TCGv_i32 fp32 = tcg_temp_new_i32();
8251 TCGv_i64 fp64 = tcg_temp_new_i64();
8253 gen_load_fpr64(ctx, fp64, fs);
8254 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8255 tcg_temp_free_i64(fp64);
8256 gen_store_fpr32(fp32, fd);
8257 tcg_temp_free_i32(fp32);
8262 check_cp1_64bitmode(ctx);
8264 TCGv_i64 fp0 = tcg_temp_new_i64();
8266 gen_load_fpr64(ctx, fp0, fs);
8267 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8268 gen_store_fpr64(ctx, fp0, fd);
8269 tcg_temp_free_i64(fp0);
8275 TCGv_i32 fp0 = tcg_temp_new_i32();
8277 gen_load_fpr32(fp0, fs);
8278 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8279 gen_store_fpr32(fp0, fd);
8280 tcg_temp_free_i32(fp0);
8285 check_cp1_registers(ctx, fd);
8287 TCGv_i32 fp32 = tcg_temp_new_i32();
8288 TCGv_i64 fp64 = tcg_temp_new_i64();
8290 gen_load_fpr32(fp32, fs);
8291 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8292 tcg_temp_free_i32(fp32);
8293 gen_store_fpr64(ctx, fp64, fd);
8294 tcg_temp_free_i64(fp64);
8299 check_cp1_64bitmode(ctx);
8301 TCGv_i32 fp32 = tcg_temp_new_i32();
8302 TCGv_i64 fp64 = tcg_temp_new_i64();
8304 gen_load_fpr64(ctx, fp64, fs);
8305 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8306 tcg_temp_free_i64(fp64);
8307 gen_store_fpr32(fp32, fd);
8308 tcg_temp_free_i32(fp32);
8313 check_cp1_64bitmode(ctx);
8315 TCGv_i64 fp0 = tcg_temp_new_i64();
8317 gen_load_fpr64(ctx, fp0, fs);
8318 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8319 gen_store_fpr64(ctx, fp0, fd);
8320 tcg_temp_free_i64(fp0);
8325 check_cp1_64bitmode(ctx);
8327 TCGv_i64 fp0 = tcg_temp_new_i64();
8329 gen_load_fpr64(ctx, fp0, fs);
8330 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8331 gen_store_fpr64(ctx, fp0, fd);
8332 tcg_temp_free_i64(fp0);
8337 check_cp1_64bitmode(ctx);
8339 TCGv_i64 fp0 = tcg_temp_new_i64();
8340 TCGv_i64 fp1 = tcg_temp_new_i64();
8342 gen_load_fpr64(ctx, fp0, fs);
8343 gen_load_fpr64(ctx, fp1, ft);
8344 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8345 tcg_temp_free_i64(fp1);
8346 gen_store_fpr64(ctx, fp0, fd);
8347 tcg_temp_free_i64(fp0);
8352 check_cp1_64bitmode(ctx);
8354 TCGv_i64 fp0 = tcg_temp_new_i64();
8355 TCGv_i64 fp1 = tcg_temp_new_i64();
8357 gen_load_fpr64(ctx, fp0, fs);
8358 gen_load_fpr64(ctx, fp1, ft);
8359 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8360 tcg_temp_free_i64(fp1);
8361 gen_store_fpr64(ctx, fp0, fd);
8362 tcg_temp_free_i64(fp0);
8367 check_cp1_64bitmode(ctx);
8369 TCGv_i64 fp0 = tcg_temp_new_i64();
8370 TCGv_i64 fp1 = tcg_temp_new_i64();
8372 gen_load_fpr64(ctx, fp0, fs);
8373 gen_load_fpr64(ctx, fp1, ft);
8374 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8375 tcg_temp_free_i64(fp1);
8376 gen_store_fpr64(ctx, fp0, fd);
8377 tcg_temp_free_i64(fp0);
8382 check_cp1_64bitmode(ctx);
8384 TCGv_i64 fp0 = tcg_temp_new_i64();
8386 gen_load_fpr64(ctx, fp0, fs);
8387 gen_helper_float_abs_ps(fp0, fp0);
8388 gen_store_fpr64(ctx, fp0, fd);
8389 tcg_temp_free_i64(fp0);
8394 check_cp1_64bitmode(ctx);
8396 TCGv_i64 fp0 = tcg_temp_new_i64();
8398 gen_load_fpr64(ctx, fp0, fs);
8399 gen_store_fpr64(ctx, fp0, fd);
8400 tcg_temp_free_i64(fp0);
8405 check_cp1_64bitmode(ctx);
8407 TCGv_i64 fp0 = tcg_temp_new_i64();
8409 gen_load_fpr64(ctx, fp0, fs);
8410 gen_helper_float_chs_ps(fp0, fp0);
8411 gen_store_fpr64(ctx, fp0, fd);
8412 tcg_temp_free_i64(fp0);
8417 check_cp1_64bitmode(ctx);
8418 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8422 check_cp1_64bitmode(ctx);
8424 int l1 = gen_new_label();
8428 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8429 fp0 = tcg_temp_new_i64();
8430 gen_load_fpr64(ctx, fp0, fs);
8431 gen_store_fpr64(ctx, fp0, fd);
8432 tcg_temp_free_i64(fp0);
8438 check_cp1_64bitmode(ctx);
8440 int l1 = gen_new_label();
8444 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8445 fp0 = tcg_temp_new_i64();
8446 gen_load_fpr64(ctx, fp0, fs);
8447 gen_store_fpr64(ctx, fp0, fd);
8448 tcg_temp_free_i64(fp0);
8455 check_cp1_64bitmode(ctx);
8457 TCGv_i64 fp0 = tcg_temp_new_i64();
8458 TCGv_i64 fp1 = tcg_temp_new_i64();
8460 gen_load_fpr64(ctx, fp0, ft);
8461 gen_load_fpr64(ctx, fp1, fs);
8462 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8463 tcg_temp_free_i64(fp1);
8464 gen_store_fpr64(ctx, fp0, fd);
8465 tcg_temp_free_i64(fp0);
8470 check_cp1_64bitmode(ctx);
8472 TCGv_i64 fp0 = tcg_temp_new_i64();
8473 TCGv_i64 fp1 = tcg_temp_new_i64();
8475 gen_load_fpr64(ctx, fp0, ft);
8476 gen_load_fpr64(ctx, fp1, fs);
8477 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8478 tcg_temp_free_i64(fp1);
8479 gen_store_fpr64(ctx, fp0, fd);
8480 tcg_temp_free_i64(fp0);
8485 check_cp1_64bitmode(ctx);
8487 TCGv_i64 fp0 = tcg_temp_new_i64();
8488 TCGv_i64 fp1 = tcg_temp_new_i64();
8490 gen_load_fpr64(ctx, fp0, fs);
8491 gen_load_fpr64(ctx, fp1, ft);
8492 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8493 tcg_temp_free_i64(fp1);
8494 gen_store_fpr64(ctx, fp0, fd);
8495 tcg_temp_free_i64(fp0);
8500 check_cp1_64bitmode(ctx);
8502 TCGv_i64 fp0 = tcg_temp_new_i64();
8504 gen_load_fpr64(ctx, fp0, fs);
8505 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8506 gen_store_fpr64(ctx, fp0, fd);
8507 tcg_temp_free_i64(fp0);
8512 check_cp1_64bitmode(ctx);
8514 TCGv_i64 fp0 = tcg_temp_new_i64();
8516 gen_load_fpr64(ctx, fp0, fs);
8517 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8518 gen_store_fpr64(ctx, fp0, fd);
8519 tcg_temp_free_i64(fp0);
8524 check_cp1_64bitmode(ctx);
8526 TCGv_i64 fp0 = tcg_temp_new_i64();
8527 TCGv_i64 fp1 = tcg_temp_new_i64();
8529 gen_load_fpr64(ctx, fp0, fs);
8530 gen_load_fpr64(ctx, fp1, ft);
8531 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8532 tcg_temp_free_i64(fp1);
8533 gen_store_fpr64(ctx, fp0, fd);
8534 tcg_temp_free_i64(fp0);
8539 check_cp1_64bitmode(ctx);
8541 TCGv_i32 fp0 = tcg_temp_new_i32();
8543 gen_load_fpr32h(fp0, fs);
8544 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8545 gen_store_fpr32(fp0, fd);
8546 tcg_temp_free_i32(fp0);
8551 check_cp1_64bitmode(ctx);
8553 TCGv_i64 fp0 = tcg_temp_new_i64();
8555 gen_load_fpr64(ctx, fp0, fs);
8556 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8557 gen_store_fpr64(ctx, fp0, fd);
8558 tcg_temp_free_i64(fp0);
8563 check_cp1_64bitmode(ctx);
8565 TCGv_i32 fp0 = tcg_temp_new_i32();
8567 gen_load_fpr32(fp0, fs);
8568 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8569 gen_store_fpr32(fp0, fd);
8570 tcg_temp_free_i32(fp0);
8575 check_cp1_64bitmode(ctx);
8577 TCGv_i32 fp0 = tcg_temp_new_i32();
8578 TCGv_i32 fp1 = tcg_temp_new_i32();
8580 gen_load_fpr32(fp0, fs);
8581 gen_load_fpr32(fp1, ft);
8582 gen_store_fpr32h(fp0, fd);
8583 gen_store_fpr32(fp1, fd);
8584 tcg_temp_free_i32(fp0);
8585 tcg_temp_free_i32(fp1);
8590 check_cp1_64bitmode(ctx);
8592 TCGv_i32 fp0 = tcg_temp_new_i32();
8593 TCGv_i32 fp1 = tcg_temp_new_i32();
8595 gen_load_fpr32(fp0, fs);
8596 gen_load_fpr32h(fp1, ft);
8597 gen_store_fpr32(fp1, fd);
8598 gen_store_fpr32h(fp0, fd);
8599 tcg_temp_free_i32(fp0);
8600 tcg_temp_free_i32(fp1);
8605 check_cp1_64bitmode(ctx);
8607 TCGv_i32 fp0 = tcg_temp_new_i32();
8608 TCGv_i32 fp1 = tcg_temp_new_i32();
8610 gen_load_fpr32h(fp0, fs);
8611 gen_load_fpr32(fp1, ft);
8612 gen_store_fpr32(fp1, fd);
8613 gen_store_fpr32h(fp0, fd);
8614 tcg_temp_free_i32(fp0);
8615 tcg_temp_free_i32(fp1);
8620 check_cp1_64bitmode(ctx);
8622 TCGv_i32 fp0 = tcg_temp_new_i32();
8623 TCGv_i32 fp1 = tcg_temp_new_i32();
8625 gen_load_fpr32h(fp0, fs);
8626 gen_load_fpr32h(fp1, ft);
8627 gen_store_fpr32(fp1, fd);
8628 gen_store_fpr32h(fp0, fd);
8629 tcg_temp_free_i32(fp0);
8630 tcg_temp_free_i32(fp1);
8637 case OPC_CMP_UEQ_PS:
8638 case OPC_CMP_OLT_PS:
8639 case OPC_CMP_ULT_PS:
8640 case OPC_CMP_OLE_PS:
8641 case OPC_CMP_ULE_PS:
8643 case OPC_CMP_NGLE_PS:
8644 case OPC_CMP_SEQ_PS:
8645 case OPC_CMP_NGL_PS:
8647 case OPC_CMP_NGE_PS:
8649 case OPC_CMP_NGT_PS:
8650 if (ctx->opcode & (1 << 6)) {
8651 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8652 opn = condnames_abs[func-48];
8654 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8655 opn = condnames[func-48];
8660 generate_exception (ctx, EXCP_RI);
8663 (void)opn; /* avoid a compiler warning */
8666 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8669 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8672 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8677 /* Coprocessor 3 (FPU) */
8678 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8679 int fd, int fs, int base, int index)
8681 const char *opn = "extended float load/store";
8683 TCGv t0 = tcg_temp_new();
8686 gen_load_gpr(t0, index);
8687 } else if (index == 0) {
8688 gen_load_gpr(t0, base);
8690 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8692 /* Don't do NOP if destination is zero: we must perform the actual
8694 save_cpu_state(ctx, 0);
8699 TCGv_i32 fp0 = tcg_temp_new_i32();
8701 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8702 tcg_gen_trunc_tl_i32(fp0, t0);
8703 gen_store_fpr32(fp0, fd);
8704 tcg_temp_free_i32(fp0);
8710 check_cp1_registers(ctx, fd);
8712 TCGv_i64 fp0 = tcg_temp_new_i64();
8714 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8715 gen_store_fpr64(ctx, fp0, fd);
8716 tcg_temp_free_i64(fp0);
8721 check_cp1_64bitmode(ctx);
8722 tcg_gen_andi_tl(t0, t0, ~0x7);
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);
8735 TCGv_i32 fp0 = tcg_temp_new_i32();
8736 TCGv t1 = tcg_temp_new();
8738 gen_load_fpr32(fp0, fs);
8739 tcg_gen_extu_i32_tl(t1, fp0);
8740 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8741 tcg_temp_free_i32(fp0);
8749 check_cp1_registers(ctx, fs);
8751 TCGv_i64 fp0 = tcg_temp_new_i64();
8753 gen_load_fpr64(ctx, fp0, fs);
8754 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8755 tcg_temp_free_i64(fp0);
8761 check_cp1_64bitmode(ctx);
8762 tcg_gen_andi_tl(t0, t0, ~0x7);
8764 TCGv_i64 fp0 = tcg_temp_new_i64();
8766 gen_load_fpr64(ctx, fp0, fs);
8767 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8768 tcg_temp_free_i64(fp0);
8775 (void)opn; (void)store; /* avoid compiler warnings */
8776 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8777 regnames[index], regnames[base]);
8780 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8781 int fd, int fr, int fs, int ft)
8783 const char *opn = "flt3_arith";
8787 check_cp1_64bitmode(ctx);
8789 TCGv t0 = tcg_temp_local_new();
8790 TCGv_i32 fp = tcg_temp_new_i32();
8791 TCGv_i32 fph = tcg_temp_new_i32();
8792 int l1 = gen_new_label();
8793 int l2 = gen_new_label();
8795 gen_load_gpr(t0, fr);
8796 tcg_gen_andi_tl(t0, t0, 0x7);
8798 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8799 gen_load_fpr32(fp, fs);
8800 gen_load_fpr32h(fph, fs);
8801 gen_store_fpr32(fp, fd);
8802 gen_store_fpr32h(fph, fd);
8805 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8807 #ifdef TARGET_WORDS_BIGENDIAN
8808 gen_load_fpr32(fp, fs);
8809 gen_load_fpr32h(fph, ft);
8810 gen_store_fpr32h(fp, fd);
8811 gen_store_fpr32(fph, fd);
8813 gen_load_fpr32h(fph, fs);
8814 gen_load_fpr32(fp, ft);
8815 gen_store_fpr32(fph, fd);
8816 gen_store_fpr32h(fp, fd);
8819 tcg_temp_free_i32(fp);
8820 tcg_temp_free_i32(fph);
8827 TCGv_i32 fp0 = tcg_temp_new_i32();
8828 TCGv_i32 fp1 = tcg_temp_new_i32();
8829 TCGv_i32 fp2 = tcg_temp_new_i32();
8831 gen_load_fpr32(fp0, fs);
8832 gen_load_fpr32(fp1, ft);
8833 gen_load_fpr32(fp2, fr);
8834 gen_helper_float_muladd_s(fp2, cpu_env, fp0, fp1, fp2);
8835 tcg_temp_free_i32(fp0);
8836 tcg_temp_free_i32(fp1);
8837 gen_store_fpr32(fp2, fd);
8838 tcg_temp_free_i32(fp2);
8844 check_cp1_registers(ctx, fd | fs | ft | fr);
8846 TCGv_i64 fp0 = tcg_temp_new_i64();
8847 TCGv_i64 fp1 = tcg_temp_new_i64();
8848 TCGv_i64 fp2 = tcg_temp_new_i64();
8850 gen_load_fpr64(ctx, fp0, fs);
8851 gen_load_fpr64(ctx, fp1, ft);
8852 gen_load_fpr64(ctx, fp2, fr);
8853 gen_helper_float_muladd_d(fp2, cpu_env, fp0, fp1, fp2);
8854 tcg_temp_free_i64(fp0);
8855 tcg_temp_free_i64(fp1);
8856 gen_store_fpr64(ctx, fp2, fd);
8857 tcg_temp_free_i64(fp2);
8862 check_cp1_64bitmode(ctx);
8864 TCGv_i64 fp0 = tcg_temp_new_i64();
8865 TCGv_i64 fp1 = tcg_temp_new_i64();
8866 TCGv_i64 fp2 = tcg_temp_new_i64();
8868 gen_load_fpr64(ctx, fp0, fs);
8869 gen_load_fpr64(ctx, fp1, ft);
8870 gen_load_fpr64(ctx, fp2, fr);
8871 gen_helper_float_muladd_ps(fp2, cpu_env, fp0, fp1, fp2);
8872 tcg_temp_free_i64(fp0);
8873 tcg_temp_free_i64(fp1);
8874 gen_store_fpr64(ctx, fp2, fd);
8875 tcg_temp_free_i64(fp2);
8882 TCGv_i32 fp0 = tcg_temp_new_i32();
8883 TCGv_i32 fp1 = tcg_temp_new_i32();
8884 TCGv_i32 fp2 = tcg_temp_new_i32();
8886 gen_load_fpr32(fp0, fs);
8887 gen_load_fpr32(fp1, ft);
8888 gen_load_fpr32(fp2, fr);
8889 gen_helper_float_mulsub_s(fp2, cpu_env, fp0, fp1, fp2);
8890 tcg_temp_free_i32(fp0);
8891 tcg_temp_free_i32(fp1);
8892 gen_store_fpr32(fp2, fd);
8893 tcg_temp_free_i32(fp2);
8899 check_cp1_registers(ctx, fd | fs | ft | fr);
8901 TCGv_i64 fp0 = tcg_temp_new_i64();
8902 TCGv_i64 fp1 = tcg_temp_new_i64();
8903 TCGv_i64 fp2 = tcg_temp_new_i64();
8905 gen_load_fpr64(ctx, fp0, fs);
8906 gen_load_fpr64(ctx, fp1, ft);
8907 gen_load_fpr64(ctx, fp2, fr);
8908 gen_helper_float_mulsub_d(fp2, cpu_env, fp0, fp1, fp2);
8909 tcg_temp_free_i64(fp0);
8910 tcg_temp_free_i64(fp1);
8911 gen_store_fpr64(ctx, fp2, fd);
8912 tcg_temp_free_i64(fp2);
8917 check_cp1_64bitmode(ctx);
8919 TCGv_i64 fp0 = tcg_temp_new_i64();
8920 TCGv_i64 fp1 = tcg_temp_new_i64();
8921 TCGv_i64 fp2 = tcg_temp_new_i64();
8923 gen_load_fpr64(ctx, fp0, fs);
8924 gen_load_fpr64(ctx, fp1, ft);
8925 gen_load_fpr64(ctx, fp2, fr);
8926 gen_helper_float_mulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8927 tcg_temp_free_i64(fp0);
8928 tcg_temp_free_i64(fp1);
8929 gen_store_fpr64(ctx, fp2, fd);
8930 tcg_temp_free_i64(fp2);
8937 TCGv_i32 fp0 = tcg_temp_new_i32();
8938 TCGv_i32 fp1 = tcg_temp_new_i32();
8939 TCGv_i32 fp2 = tcg_temp_new_i32();
8941 gen_load_fpr32(fp0, fs);
8942 gen_load_fpr32(fp1, ft);
8943 gen_load_fpr32(fp2, fr);
8944 gen_helper_float_nmuladd_s(fp2, cpu_env, fp0, fp1, fp2);
8945 tcg_temp_free_i32(fp0);
8946 tcg_temp_free_i32(fp1);
8947 gen_store_fpr32(fp2, fd);
8948 tcg_temp_free_i32(fp2);
8954 check_cp1_registers(ctx, fd | fs | ft | fr);
8956 TCGv_i64 fp0 = tcg_temp_new_i64();
8957 TCGv_i64 fp1 = tcg_temp_new_i64();
8958 TCGv_i64 fp2 = tcg_temp_new_i64();
8960 gen_load_fpr64(ctx, fp0, fs);
8961 gen_load_fpr64(ctx, fp1, ft);
8962 gen_load_fpr64(ctx, fp2, fr);
8963 gen_helper_float_nmuladd_d(fp2, cpu_env, fp0, fp1, fp2);
8964 tcg_temp_free_i64(fp0);
8965 tcg_temp_free_i64(fp1);
8966 gen_store_fpr64(ctx, fp2, fd);
8967 tcg_temp_free_i64(fp2);
8972 check_cp1_64bitmode(ctx);
8974 TCGv_i64 fp0 = tcg_temp_new_i64();
8975 TCGv_i64 fp1 = tcg_temp_new_i64();
8976 TCGv_i64 fp2 = tcg_temp_new_i64();
8978 gen_load_fpr64(ctx, fp0, fs);
8979 gen_load_fpr64(ctx, fp1, ft);
8980 gen_load_fpr64(ctx, fp2, fr);
8981 gen_helper_float_nmuladd_ps(fp2, cpu_env, fp0, fp1, fp2);
8982 tcg_temp_free_i64(fp0);
8983 tcg_temp_free_i64(fp1);
8984 gen_store_fpr64(ctx, fp2, fd);
8985 tcg_temp_free_i64(fp2);
8992 TCGv_i32 fp0 = tcg_temp_new_i32();
8993 TCGv_i32 fp1 = tcg_temp_new_i32();
8994 TCGv_i32 fp2 = tcg_temp_new_i32();
8996 gen_load_fpr32(fp0, fs);
8997 gen_load_fpr32(fp1, ft);
8998 gen_load_fpr32(fp2, fr);
8999 gen_helper_float_nmulsub_s(fp2, cpu_env, fp0, fp1, fp2);
9000 tcg_temp_free_i32(fp0);
9001 tcg_temp_free_i32(fp1);
9002 gen_store_fpr32(fp2, fd);
9003 tcg_temp_free_i32(fp2);
9009 check_cp1_registers(ctx, fd | fs | ft | fr);
9011 TCGv_i64 fp0 = tcg_temp_new_i64();
9012 TCGv_i64 fp1 = tcg_temp_new_i64();
9013 TCGv_i64 fp2 = tcg_temp_new_i64();
9015 gen_load_fpr64(ctx, fp0, fs);
9016 gen_load_fpr64(ctx, fp1, ft);
9017 gen_load_fpr64(ctx, fp2, fr);
9018 gen_helper_float_nmulsub_d(fp2, cpu_env, fp0, fp1, fp2);
9019 tcg_temp_free_i64(fp0);
9020 tcg_temp_free_i64(fp1);
9021 gen_store_fpr64(ctx, fp2, fd);
9022 tcg_temp_free_i64(fp2);
9027 check_cp1_64bitmode(ctx);
9029 TCGv_i64 fp0 = tcg_temp_new_i64();
9030 TCGv_i64 fp1 = tcg_temp_new_i64();
9031 TCGv_i64 fp2 = tcg_temp_new_i64();
9033 gen_load_fpr64(ctx, fp0, fs);
9034 gen_load_fpr64(ctx, fp1, ft);
9035 gen_load_fpr64(ctx, fp2, fr);
9036 gen_helper_float_nmulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9037 tcg_temp_free_i64(fp0);
9038 tcg_temp_free_i64(fp1);
9039 gen_store_fpr64(ctx, fp2, fd);
9040 tcg_temp_free_i64(fp2);
9046 generate_exception (ctx, EXCP_RI);
9049 (void)opn; /* avoid a compiler warning */
9050 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9051 fregnames[fs], fregnames[ft]);
9055 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9059 #if !defined(CONFIG_USER_ONLY)
9060 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9061 Therefore only check the ISA in system mode. */
9062 check_insn(env, ctx, ISA_MIPS32R2);
9064 t0 = tcg_temp_new();
9068 save_cpu_state(ctx, 1);
9069 gen_helper_rdhwr_cpunum(t0, cpu_env);
9070 gen_store_gpr(t0, rt);
9073 save_cpu_state(ctx, 1);
9074 gen_helper_rdhwr_synci_step(t0, cpu_env);
9075 gen_store_gpr(t0, rt);
9078 save_cpu_state(ctx, 1);
9079 gen_helper_rdhwr_cc(t0, cpu_env);
9080 gen_store_gpr(t0, rt);
9083 save_cpu_state(ctx, 1);
9084 gen_helper_rdhwr_ccres(t0, cpu_env);
9085 gen_store_gpr(t0, rt);
9088 #if defined(CONFIG_USER_ONLY)
9089 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9090 gen_store_gpr(t0, rt);
9093 /* XXX: Some CPUs implement this in hardware.
9094 Not supported yet. */
9096 default: /* Invalid */
9097 MIPS_INVAL("rdhwr");
9098 generate_exception(ctx, EXCP_RI);
9104 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9107 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9108 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9109 /* Branches completion */
9110 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9111 ctx->bstate = BS_BRANCH;
9112 save_cpu_state(ctx, 0);
9113 /* FIXME: Need to clear can_do_io. */
9114 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9116 /* unconditional branch */
9117 MIPS_DEBUG("unconditional branch");
9118 if (proc_hflags & MIPS_HFLAG_BX) {
9119 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9121 gen_goto_tb(ctx, 0, ctx->btarget);
9124 /* blikely taken case */
9125 MIPS_DEBUG("blikely branch taken");
9126 gen_goto_tb(ctx, 0, ctx->btarget);
9129 /* Conditional branch */
9130 MIPS_DEBUG("conditional branch");
9132 int l1 = gen_new_label();
9134 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9135 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9137 gen_goto_tb(ctx, 0, ctx->btarget);
9141 /* unconditional branch to register */
9142 MIPS_DEBUG("branch to register");
9143 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9144 TCGv t0 = tcg_temp_new();
9145 TCGv_i32 t1 = tcg_temp_new_i32();
9147 tcg_gen_andi_tl(t0, btarget, 0x1);
9148 tcg_gen_trunc_tl_i32(t1, t0);
9150 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9151 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9152 tcg_gen_or_i32(hflags, hflags, t1);
9153 tcg_temp_free_i32(t1);
9155 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9157 tcg_gen_mov_tl(cpu_PC, btarget);
9159 if (ctx->singlestep_enabled) {
9160 save_cpu_state(ctx, 0);
9161 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9166 MIPS_DEBUG("unknown branch");
9172 /* ISA extensions (ASEs) */
9173 /* MIPS16 extension to MIPS32 */
9175 /* MIPS16 major opcodes */
9177 M16_OPC_ADDIUSP = 0x00,
9178 M16_OPC_ADDIUPC = 0x01,
9181 M16_OPC_BEQZ = 0x04,
9182 M16_OPC_BNEQZ = 0x05,
9183 M16_OPC_SHIFT = 0x06,
9185 M16_OPC_RRIA = 0x08,
9186 M16_OPC_ADDIU8 = 0x09,
9187 M16_OPC_SLTI = 0x0a,
9188 M16_OPC_SLTIU = 0x0b,
9191 M16_OPC_CMPI = 0x0e,
9195 M16_OPC_LWSP = 0x12,
9199 M16_OPC_LWPC = 0x16,
9203 M16_OPC_SWSP = 0x1a,
9207 M16_OPC_EXTEND = 0x1e,
9211 /* I8 funct field */
9230 /* RR funct field */
9264 /* I64 funct field */
9276 /* RR ry field for CNVT */
9278 RR_RY_CNVT_ZEB = 0x0,
9279 RR_RY_CNVT_ZEH = 0x1,
9280 RR_RY_CNVT_ZEW = 0x2,
9281 RR_RY_CNVT_SEB = 0x4,
9282 RR_RY_CNVT_SEH = 0x5,
9283 RR_RY_CNVT_SEW = 0x6,
9286 static int xlat (int r)
9288 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9293 static void gen_mips16_save (DisasContext *ctx,
9294 int xsregs, int aregs,
9295 int do_ra, int do_s0, int do_s1,
9298 TCGv t0 = tcg_temp_new();
9299 TCGv t1 = tcg_temp_new();
9329 generate_exception(ctx, EXCP_RI);
9335 gen_base_offset_addr(ctx, t0, 29, 12);
9336 gen_load_gpr(t1, 7);
9337 op_st_sw(t1, t0, ctx);
9340 gen_base_offset_addr(ctx, t0, 29, 8);
9341 gen_load_gpr(t1, 6);
9342 op_st_sw(t1, t0, ctx);
9345 gen_base_offset_addr(ctx, t0, 29, 4);
9346 gen_load_gpr(t1, 5);
9347 op_st_sw(t1, t0, ctx);
9350 gen_base_offset_addr(ctx, t0, 29, 0);
9351 gen_load_gpr(t1, 4);
9352 op_st_sw(t1, t0, ctx);
9355 gen_load_gpr(t0, 29);
9357 #define DECR_AND_STORE(reg) do { \
9358 tcg_gen_subi_tl(t0, t0, 4); \
9359 gen_load_gpr(t1, reg); \
9360 op_st_sw(t1, t0, ctx); \
9424 generate_exception(ctx, EXCP_RI);
9440 #undef DECR_AND_STORE
9442 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9447 static void gen_mips16_restore (DisasContext *ctx,
9448 int xsregs, int aregs,
9449 int do_ra, int do_s0, int do_s1,
9453 TCGv t0 = tcg_temp_new();
9454 TCGv t1 = tcg_temp_new();
9456 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9458 #define DECR_AND_LOAD(reg) do { \
9459 tcg_gen_subi_tl(t0, t0, 4); \
9460 op_ld_lw(t1, t0, ctx); \
9461 gen_store_gpr(t1, reg); \
9525 generate_exception(ctx, EXCP_RI);
9541 #undef DECR_AND_LOAD
9543 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9548 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9549 int is_64_bit, int extended)
9553 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9554 generate_exception(ctx, EXCP_RI);
9558 t0 = tcg_temp_new();
9560 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9561 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9563 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9569 #if defined(TARGET_MIPS64)
9570 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9571 int ry, int funct, int16_t offset,
9577 offset = extended ? offset : offset << 3;
9578 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9582 offset = extended ? offset : offset << 3;
9583 gen_st(ctx, OPC_SD, ry, 29, offset);
9587 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9588 gen_st(ctx, OPC_SD, 31, 29, offset);
9592 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9593 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9596 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9597 generate_exception(ctx, EXCP_RI);
9599 offset = extended ? offset : offset << 3;
9600 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9605 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9606 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9610 offset = extended ? offset : offset << 2;
9611 gen_addiupc(ctx, ry, offset, 1, extended);
9615 offset = extended ? offset : offset << 2;
9616 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9622 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9625 int extend = cpu_lduw_code(env, ctx->pc + 2);
9626 int op, rx, ry, funct, sa;
9627 int16_t imm, offset;
9629 ctx->opcode = (ctx->opcode << 16) | extend;
9630 op = (ctx->opcode >> 11) & 0x1f;
9631 sa = (ctx->opcode >> 22) & 0x1f;
9632 funct = (ctx->opcode >> 8) & 0x7;
9633 rx = xlat((ctx->opcode >> 8) & 0x7);
9634 ry = xlat((ctx->opcode >> 5) & 0x7);
9635 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9636 | ((ctx->opcode >> 21) & 0x3f) << 5
9637 | (ctx->opcode & 0x1f));
9639 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9642 case M16_OPC_ADDIUSP:
9643 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9645 case M16_OPC_ADDIUPC:
9646 gen_addiupc(ctx, rx, imm, 0, 1);
9649 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9650 /* No delay slot, so just process as a normal instruction */
9653 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9654 /* No delay slot, so just process as a normal instruction */
9657 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9658 /* No delay slot, so just process as a normal instruction */
9661 switch (ctx->opcode & 0x3) {
9663 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9666 #if defined(TARGET_MIPS64)
9668 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9670 generate_exception(ctx, EXCP_RI);
9674 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9677 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9681 #if defined(TARGET_MIPS64)
9684 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9688 imm = ctx->opcode & 0xf;
9689 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9690 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9691 imm = (int16_t) (imm << 1) >> 1;
9692 if ((ctx->opcode >> 4) & 0x1) {
9693 #if defined(TARGET_MIPS64)
9695 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9697 generate_exception(ctx, EXCP_RI);
9700 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9703 case M16_OPC_ADDIU8:
9704 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9707 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9710 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9715 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9718 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9721 gen_st(ctx, OPC_SW, 31, 29, imm);
9724 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9728 int xsregs = (ctx->opcode >> 24) & 0x7;
9729 int aregs = (ctx->opcode >> 16) & 0xf;
9730 int do_ra = (ctx->opcode >> 6) & 0x1;
9731 int do_s0 = (ctx->opcode >> 5) & 0x1;
9732 int do_s1 = (ctx->opcode >> 4) & 0x1;
9733 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9734 | (ctx->opcode & 0xf)) << 3;
9736 if (ctx->opcode & (1 << 7)) {
9737 gen_mips16_save(ctx, xsregs, aregs,
9738 do_ra, do_s0, do_s1,
9741 gen_mips16_restore(ctx, xsregs, aregs,
9742 do_ra, do_s0, do_s1,
9748 generate_exception(ctx, EXCP_RI);
9753 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9756 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9758 #if defined(TARGET_MIPS64)
9760 gen_st(ctx, OPC_SD, ry, rx, offset);
9764 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9767 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9770 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9773 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9776 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9779 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9782 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9784 #if defined(TARGET_MIPS64)
9786 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9790 gen_st(ctx, OPC_SB, ry, rx, offset);
9793 gen_st(ctx, OPC_SH, ry, rx, offset);
9796 gen_st(ctx, OPC_SW, rx, 29, offset);
9799 gen_st(ctx, OPC_SW, ry, rx, offset);
9801 #if defined(TARGET_MIPS64)
9803 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9807 generate_exception(ctx, EXCP_RI);
9814 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9819 int op, cnvt_op, op1, offset;
9823 op = (ctx->opcode >> 11) & 0x1f;
9824 sa = (ctx->opcode >> 2) & 0x7;
9825 sa = sa == 0 ? 8 : sa;
9826 rx = xlat((ctx->opcode >> 8) & 0x7);
9827 cnvt_op = (ctx->opcode >> 5) & 0x7;
9828 ry = xlat((ctx->opcode >> 5) & 0x7);
9829 op1 = offset = ctx->opcode & 0x1f;
9834 case M16_OPC_ADDIUSP:
9836 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9838 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9841 case M16_OPC_ADDIUPC:
9842 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9845 offset = (ctx->opcode & 0x7ff) << 1;
9846 offset = (int16_t)(offset << 4) >> 4;
9847 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9848 /* No delay slot, so just process as a normal instruction */
9851 offset = cpu_lduw_code(env, ctx->pc + 2);
9852 offset = (((ctx->opcode & 0x1f) << 21)
9853 | ((ctx->opcode >> 5) & 0x1f) << 16
9855 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9856 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9861 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9862 /* No delay slot, so just process as a normal instruction */
9865 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9866 /* No delay slot, so just process as a normal instruction */
9869 switch (ctx->opcode & 0x3) {
9871 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9874 #if defined(TARGET_MIPS64)
9876 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9878 generate_exception(ctx, EXCP_RI);
9882 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9885 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9889 #if defined(TARGET_MIPS64)
9892 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9897 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9899 if ((ctx->opcode >> 4) & 1) {
9900 #if defined(TARGET_MIPS64)
9902 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9904 generate_exception(ctx, EXCP_RI);
9907 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9911 case M16_OPC_ADDIU8:
9913 int16_t imm = (int8_t) ctx->opcode;
9915 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9920 int16_t imm = (uint8_t) ctx->opcode;
9921 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9926 int16_t imm = (uint8_t) ctx->opcode;
9927 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9934 funct = (ctx->opcode >> 8) & 0x7;
9937 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9938 ((int8_t)ctx->opcode) << 1);
9941 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9942 ((int8_t)ctx->opcode) << 1);
9945 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9948 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9949 ((int8_t)ctx->opcode) << 3);
9953 int do_ra = ctx->opcode & (1 << 6);
9954 int do_s0 = ctx->opcode & (1 << 5);
9955 int do_s1 = ctx->opcode & (1 << 4);
9956 int framesize = ctx->opcode & 0xf;
9958 if (framesize == 0) {
9961 framesize = framesize << 3;
9964 if (ctx->opcode & (1 << 7)) {
9965 gen_mips16_save(ctx, 0, 0,
9966 do_ra, do_s0, do_s1, framesize);
9968 gen_mips16_restore(ctx, 0, 0,
9969 do_ra, do_s0, do_s1, framesize);
9975 int rz = xlat(ctx->opcode & 0x7);
9977 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9978 ((ctx->opcode >> 5) & 0x7);
9979 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9983 reg32 = ctx->opcode & 0x1f;
9984 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9987 generate_exception(ctx, EXCP_RI);
9994 int16_t imm = (uint8_t) ctx->opcode;
9996 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10001 int16_t imm = (uint8_t) ctx->opcode;
10002 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
10005 #if defined(TARGET_MIPS64)
10007 check_mips_64(ctx);
10008 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10012 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10015 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10018 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10021 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10024 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10027 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10030 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10032 #if defined (TARGET_MIPS64)
10034 check_mips_64(ctx);
10035 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10039 gen_st(ctx, OPC_SB, ry, rx, offset);
10042 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10045 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10048 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10052 int rz = xlat((ctx->opcode >> 2) & 0x7);
10055 switch (ctx->opcode & 0x3) {
10057 mips32_op = OPC_ADDU;
10060 mips32_op = OPC_SUBU;
10062 #if defined(TARGET_MIPS64)
10064 mips32_op = OPC_DADDU;
10065 check_mips_64(ctx);
10068 mips32_op = OPC_DSUBU;
10069 check_mips_64(ctx);
10073 generate_exception(ctx, EXCP_RI);
10077 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10086 int nd = (ctx->opcode >> 7) & 0x1;
10087 int link = (ctx->opcode >> 6) & 0x1;
10088 int ra = (ctx->opcode >> 5) & 0x1;
10091 op = nd ? OPC_JALRC : OPC_JALRS;
10096 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10103 /* XXX: not clear which exception should be raised
10104 * when in debug mode...
10106 check_insn(env, ctx, ISA_MIPS32);
10107 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10108 generate_exception(ctx, EXCP_DBp);
10110 generate_exception(ctx, EXCP_DBp);
10114 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10117 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10120 generate_exception(ctx, EXCP_BREAK);
10123 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10126 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10129 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10131 #if defined (TARGET_MIPS64)
10133 check_mips_64(ctx);
10134 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10138 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10141 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10144 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10147 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10150 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10153 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10156 gen_HILO(ctx, OPC_MFHI, rx);
10160 case RR_RY_CNVT_ZEB:
10161 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10163 case RR_RY_CNVT_ZEH:
10164 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10166 case RR_RY_CNVT_SEB:
10167 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10169 case RR_RY_CNVT_SEH:
10170 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10172 #if defined (TARGET_MIPS64)
10173 case RR_RY_CNVT_ZEW:
10174 check_mips_64(ctx);
10175 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10177 case RR_RY_CNVT_SEW:
10178 check_mips_64(ctx);
10179 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10183 generate_exception(ctx, EXCP_RI);
10188 gen_HILO(ctx, OPC_MFLO, rx);
10190 #if defined (TARGET_MIPS64)
10192 check_mips_64(ctx);
10193 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10196 check_mips_64(ctx);
10197 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10200 check_mips_64(ctx);
10201 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10204 check_mips_64(ctx);
10205 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10209 gen_muldiv(ctx, OPC_MULT, rx, ry);
10212 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10215 gen_muldiv(ctx, OPC_DIV, rx, ry);
10218 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10220 #if defined (TARGET_MIPS64)
10222 check_mips_64(ctx);
10223 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10226 check_mips_64(ctx);
10227 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10230 check_mips_64(ctx);
10231 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10234 check_mips_64(ctx);
10235 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10239 generate_exception(ctx, EXCP_RI);
10243 case M16_OPC_EXTEND:
10244 decode_extended_mips16_opc(env, ctx, is_branch);
10247 #if defined(TARGET_MIPS64)
10249 funct = (ctx->opcode >> 8) & 0x7;
10250 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10254 generate_exception(ctx, EXCP_RI);
10261 /* microMIPS extension to MIPS32 */
10263 /* microMIPS32 major opcodes */
10302 /* 0x20 is reserved */
10312 /* 0x28 and 0x29 are reserved */
10322 /* 0x30 and 0x31 are reserved */
10332 /* 0x38 and 0x39 are reserved */
10343 /* POOL32A encoding of minor opcode field */
10346 /* These opcodes are distinguished only by bits 9..6; those bits are
10347 * what are recorded below. */
10373 /* The following can be distinguished by their lower 6 bits. */
10379 /* POOL32AXF encoding of minor opcode field extension */
10393 /* bits 13..12 for 0x01 */
10399 /* bits 13..12 for 0x2a */
10405 /* bits 13..12 for 0x32 */
10409 /* bits 15..12 for 0x2c */
10425 /* bits 15..12 for 0x34 */
10433 /* bits 15..12 for 0x3c */
10435 JR = 0x0, /* alias */
10440 /* bits 15..12 for 0x05 */
10444 /* bits 15..12 for 0x0d */
10454 /* bits 15..12 for 0x15 */
10460 /* bits 15..12 for 0x1d */
10464 /* bits 15..12 for 0x2d */
10469 /* bits 15..12 for 0x35 */
10476 /* POOL32B encoding of minor opcode field (bits 15..12) */
10492 /* POOL32C encoding of minor opcode field (bits 15..12) */
10500 /* 0xa is reserved */
10507 /* 0x6 is reserved */
10513 /* POOL32F encoding of minor opcode field (bits 5..0) */
10516 /* These are the bit 7..6 values */
10527 /* These are the bit 8..6 values */
10571 CABS_COND_FMT = 0x1c, /* MIPS3D */
10575 /* POOL32Fxf encoding of minor opcode extension field */
10613 /* POOL32I encoding of minor opcode field (bits 25..21) */
10638 /* These overlap and are distinguished by bit16 of the instruction */
10647 /* POOL16A encoding of minor opcode field */
10654 /* POOL16B encoding of minor opcode field */
10661 /* POOL16C encoding of minor opcode field */
10681 /* POOL16D encoding of minor opcode field */
10688 /* POOL16E encoding of minor opcode field */
10695 static int mmreg (int r)
10697 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10702 /* Used for 16-bit store instructions. */
10703 static int mmreg2 (int r)
10705 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10710 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10711 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10712 #define uMIPS_RS2(op) uMIPS_RS(op)
10713 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10714 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10715 #define uMIPS_RS5(op) (op & 0x1f)
10717 /* Signed immediate */
10718 #define SIMM(op, start, width) \
10719 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10722 /* Zero-extended immediate */
10723 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10725 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10727 int rd = mmreg(uMIPS_RD(ctx->opcode));
10729 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10732 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10734 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10735 int rd = mmreg(uMIPS_RD(ctx->opcode));
10736 int rs = mmreg(uMIPS_RS(ctx->opcode));
10738 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10741 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10743 int encoded = ZIMM(ctx->opcode, 1, 9);
10746 if (encoded <= 1) {
10747 decoded = 256 + encoded;
10748 } else if (encoded <= 255) {
10750 } else if (encoded <= 509) {
10751 decoded = encoded - 512;
10753 decoded = encoded - 768;
10756 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10759 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10761 int imm = SIMM(ctx->opcode, 1, 4);
10762 int rd = (ctx->opcode >> 5) & 0x1f;
10764 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10767 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10769 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10770 31, 32, 63, 64, 255, 32768, 65535 };
10771 int rd = mmreg(uMIPS_RD(ctx->opcode));
10772 int rs = mmreg(uMIPS_RS(ctx->opcode));
10773 int encoded = ZIMM(ctx->opcode, 0, 4);
10775 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10778 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10779 int base, int16_t offset)
10781 const char *opn = "ldst_multiple";
10785 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10786 generate_exception(ctx, EXCP_RI);
10790 t0 = tcg_temp_new();
10792 gen_base_offset_addr(ctx, t0, base, offset);
10794 t1 = tcg_const_tl(reglist);
10795 t2 = tcg_const_i32(ctx->mem_idx);
10797 save_cpu_state(ctx, 1);
10800 gen_helper_lwm(cpu_env, t0, t1, t2);
10804 gen_helper_swm(cpu_env, t0, t1, t2);
10807 #ifdef TARGET_MIPS64
10809 gen_helper_ldm(cpu_env, t0, t1, t2);
10813 gen_helper_sdm(cpu_env, t0, t1, t2);
10819 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10822 tcg_temp_free_i32(t2);
10826 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10828 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10829 int rs = mmreg(ctx->opcode & 0x7);
10832 switch (((ctx->opcode) >> 4) & 0x3f) {
10837 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10843 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10849 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10855 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10862 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10863 int offset = ZIMM(ctx->opcode, 0, 4);
10865 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10874 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10875 int offset = ZIMM(ctx->opcode, 0, 4);
10877 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10884 int reg = ctx->opcode & 0x1f;
10886 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10893 int reg = ctx->opcode & 0x1f;
10895 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10896 /* Let normal delay slot handling in our caller take us
10897 to the branch target. */
10909 int reg = ctx->opcode & 0x1f;
10911 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10917 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10921 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10924 generate_exception(ctx, EXCP_BREAK);
10927 /* XXX: not clear which exception should be raised
10928 * when in debug mode...
10930 check_insn(env, ctx, ISA_MIPS32);
10931 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10932 generate_exception(ctx, EXCP_DBp);
10934 generate_exception(ctx, EXCP_DBp);
10937 case JRADDIUSP + 0:
10938 case JRADDIUSP + 1:
10940 int imm = ZIMM(ctx->opcode, 0, 5);
10942 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10943 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10944 /* Let normal delay slot handling in our caller take us
10945 to the branch target. */
10949 generate_exception(ctx, EXCP_RI);
10954 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10956 TCGv t0 = tcg_temp_new();
10957 TCGv t1 = tcg_temp_new();
10959 gen_load_gpr(t0, base);
10962 gen_load_gpr(t1, index);
10963 tcg_gen_shli_tl(t1, t1, 2);
10964 gen_op_addr_add(ctx, t0, t1, t0);
10967 save_cpu_state(ctx, 0);
10968 op_ld_lw(t1, t0, ctx);
10969 gen_store_gpr(t1, rd);
10975 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10976 int base, int16_t offset)
10978 const char *opn = "ldst_pair";
10981 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10982 generate_exception(ctx, EXCP_RI);
10986 t0 = tcg_temp_new();
10987 t1 = tcg_temp_new();
10989 gen_base_offset_addr(ctx, t0, base, offset);
10994 generate_exception(ctx, EXCP_RI);
10997 save_cpu_state(ctx, 0);
10998 op_ld_lw(t1, t0, ctx);
10999 gen_store_gpr(t1, rd);
11000 tcg_gen_movi_tl(t1, 4);
11001 gen_op_addr_add(ctx, t0, t0, t1);
11002 op_ld_lw(t1, t0, ctx);
11003 gen_store_gpr(t1, rd+1);
11007 save_cpu_state(ctx, 0);
11008 gen_load_gpr(t1, rd);
11009 op_st_sw(t1, t0, ctx);
11010 tcg_gen_movi_tl(t1, 4);
11011 gen_op_addr_add(ctx, t0, t0, t1);
11012 gen_load_gpr(t1, rd+1);
11013 op_st_sw(t1, t0, ctx);
11016 #ifdef TARGET_MIPS64
11019 generate_exception(ctx, EXCP_RI);
11022 save_cpu_state(ctx, 0);
11023 op_ld_ld(t1, t0, ctx);
11024 gen_store_gpr(t1, rd);
11025 tcg_gen_movi_tl(t1, 8);
11026 gen_op_addr_add(ctx, t0, t0, t1);
11027 op_ld_ld(t1, t0, ctx);
11028 gen_store_gpr(t1, rd+1);
11032 save_cpu_state(ctx, 0);
11033 gen_load_gpr(t1, rd);
11034 op_st_sd(t1, t0, ctx);
11035 tcg_gen_movi_tl(t1, 8);
11036 gen_op_addr_add(ctx, t0, t0, t1);
11037 gen_load_gpr(t1, rd+1);
11038 op_st_sd(t1, t0, ctx);
11043 (void)opn; /* avoid a compiler warning */
11044 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11049 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11052 int extension = (ctx->opcode >> 6) & 0x3f;
11053 int minor = (ctx->opcode >> 12) & 0xf;
11054 uint32_t mips32_op;
11056 switch (extension) {
11058 mips32_op = OPC_TEQ;
11061 mips32_op = OPC_TGE;
11064 mips32_op = OPC_TGEU;
11067 mips32_op = OPC_TLT;
11070 mips32_op = OPC_TLTU;
11073 mips32_op = OPC_TNE;
11075 gen_trap(ctx, mips32_op, rs, rt, -1);
11077 #ifndef CONFIG_USER_ONLY
11080 check_cp0_enabled(ctx);
11082 /* Treat as NOP. */
11085 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11089 check_cp0_enabled(ctx);
11091 TCGv t0 = tcg_temp_new();
11093 gen_load_gpr(t0, rt);
11094 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11102 gen_bshfl(ctx, OPC_SEB, rs, rt);
11105 gen_bshfl(ctx, OPC_SEH, rs, rt);
11108 mips32_op = OPC_CLO;
11111 mips32_op = OPC_CLZ;
11113 check_insn(env, ctx, ISA_MIPS32);
11114 gen_cl(ctx, mips32_op, rt, rs);
11117 gen_rdhwr(env, ctx, rt, rs);
11120 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11123 mips32_op = OPC_MULT;
11126 mips32_op = OPC_MULTU;
11129 mips32_op = OPC_DIV;
11132 mips32_op = OPC_DIVU;
11135 mips32_op = OPC_MADD;
11138 mips32_op = OPC_MADDU;
11141 mips32_op = OPC_MSUB;
11144 mips32_op = OPC_MSUBU;
11146 check_insn(env, ctx, ISA_MIPS32);
11147 gen_muldiv(ctx, mips32_op, rs, rt);
11150 goto pool32axf_invalid;
11161 generate_exception_err(ctx, EXCP_CpU, 2);
11164 goto pool32axf_invalid;
11171 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11176 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11180 goto pool32axf_invalid;
11186 check_cp0_enabled(ctx);
11187 check_insn(env, ctx, ISA_MIPS32R2);
11188 gen_load_srsgpr(rt, rs);
11191 check_cp0_enabled(ctx);
11192 check_insn(env, ctx, ISA_MIPS32R2);
11193 gen_store_srsgpr(rt, rs);
11196 goto pool32axf_invalid;
11199 #ifndef CONFIG_USER_ONLY
11203 mips32_op = OPC_TLBP;
11206 mips32_op = OPC_TLBR;
11209 mips32_op = OPC_TLBWI;
11212 mips32_op = OPC_TLBWR;
11215 mips32_op = OPC_WAIT;
11218 mips32_op = OPC_DERET;
11221 mips32_op = OPC_ERET;
11223 gen_cp0(env, ctx, mips32_op, rt, rs);
11226 goto pool32axf_invalid;
11232 check_cp0_enabled(ctx);
11234 TCGv t0 = tcg_temp_new();
11236 save_cpu_state(ctx, 1);
11237 gen_helper_di(t0, cpu_env);
11238 gen_store_gpr(t0, rs);
11239 /* Stop translation as we may have switched the execution mode */
11240 ctx->bstate = BS_STOP;
11245 check_cp0_enabled(ctx);
11247 TCGv t0 = tcg_temp_new();
11249 save_cpu_state(ctx, 1);
11250 gen_helper_ei(t0, cpu_env);
11251 gen_store_gpr(t0, rs);
11252 /* Stop translation as we may have switched the execution mode */
11253 ctx->bstate = BS_STOP;
11258 goto pool32axf_invalid;
11268 generate_exception(ctx, EXCP_SYSCALL);
11269 ctx->bstate = BS_STOP;
11272 check_insn(env, ctx, ISA_MIPS32);
11273 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11274 generate_exception(ctx, EXCP_DBp);
11276 generate_exception(ctx, EXCP_DBp);
11280 goto pool32axf_invalid;
11286 gen_HILO(ctx, OPC_MFHI, rs);
11289 gen_HILO(ctx, OPC_MFLO, rs);
11292 gen_HILO(ctx, OPC_MTHI, rs);
11295 gen_HILO(ctx, OPC_MTLO, rs);
11298 goto pool32axf_invalid;
11303 MIPS_INVAL("pool32axf");
11304 generate_exception(ctx, EXCP_RI);
11309 /* Values for microMIPS fmt field. Variable-width, depending on which
11310 formats the instruction supports. */
11329 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11331 int extension = (ctx->opcode >> 6) & 0x3ff;
11332 uint32_t mips32_op;
11334 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11335 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11336 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11338 switch (extension) {
11339 case FLOAT_1BIT_FMT(CFC1, 0):
11340 mips32_op = OPC_CFC1;
11342 case FLOAT_1BIT_FMT(CTC1, 0):
11343 mips32_op = OPC_CTC1;
11345 case FLOAT_1BIT_FMT(MFC1, 0):
11346 mips32_op = OPC_MFC1;
11348 case FLOAT_1BIT_FMT(MTC1, 0):
11349 mips32_op = OPC_MTC1;
11351 case FLOAT_1BIT_FMT(MFHC1, 0):
11352 mips32_op = OPC_MFHC1;
11354 case FLOAT_1BIT_FMT(MTHC1, 0):
11355 mips32_op = OPC_MTHC1;
11357 gen_cp1(ctx, mips32_op, rt, rs);
11360 /* Reciprocal square root */
11361 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11362 mips32_op = OPC_RSQRT_S;
11364 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11365 mips32_op = OPC_RSQRT_D;
11369 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11370 mips32_op = OPC_SQRT_S;
11372 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11373 mips32_op = OPC_SQRT_D;
11377 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11378 mips32_op = OPC_RECIP_S;
11380 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11381 mips32_op = OPC_RECIP_D;
11385 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11386 mips32_op = OPC_FLOOR_L_S;
11388 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11389 mips32_op = OPC_FLOOR_L_D;
11391 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11392 mips32_op = OPC_FLOOR_W_S;
11394 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11395 mips32_op = OPC_FLOOR_W_D;
11399 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11400 mips32_op = OPC_CEIL_L_S;
11402 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11403 mips32_op = OPC_CEIL_L_D;
11405 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11406 mips32_op = OPC_CEIL_W_S;
11408 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11409 mips32_op = OPC_CEIL_W_D;
11413 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11414 mips32_op = OPC_TRUNC_L_S;
11416 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11417 mips32_op = OPC_TRUNC_L_D;
11419 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11420 mips32_op = OPC_TRUNC_W_S;
11422 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11423 mips32_op = OPC_TRUNC_W_D;
11427 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11428 mips32_op = OPC_ROUND_L_S;
11430 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11431 mips32_op = OPC_ROUND_L_D;
11433 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11434 mips32_op = OPC_ROUND_W_S;
11436 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11437 mips32_op = OPC_ROUND_W_D;
11440 /* Integer to floating-point conversion */
11441 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11442 mips32_op = OPC_CVT_L_S;
11444 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11445 mips32_op = OPC_CVT_L_D;
11447 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11448 mips32_op = OPC_CVT_W_S;
11450 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11451 mips32_op = OPC_CVT_W_D;
11454 /* Paired-foo conversions */
11455 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11456 mips32_op = OPC_CVT_S_PL;
11458 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11459 mips32_op = OPC_CVT_S_PU;
11461 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11462 mips32_op = OPC_CVT_PW_PS;
11464 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11465 mips32_op = OPC_CVT_PS_PW;
11468 /* Floating-point moves */
11469 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11470 mips32_op = OPC_MOV_S;
11472 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11473 mips32_op = OPC_MOV_D;
11475 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11476 mips32_op = OPC_MOV_PS;
11479 /* Absolute value */
11480 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11481 mips32_op = OPC_ABS_S;
11483 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11484 mips32_op = OPC_ABS_D;
11486 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11487 mips32_op = OPC_ABS_PS;
11491 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11492 mips32_op = OPC_NEG_S;
11494 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11495 mips32_op = OPC_NEG_D;
11497 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11498 mips32_op = OPC_NEG_PS;
11501 /* Reciprocal square root step */
11502 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11503 mips32_op = OPC_RSQRT1_S;
11505 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11506 mips32_op = OPC_RSQRT1_D;
11508 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11509 mips32_op = OPC_RSQRT1_PS;
11512 /* Reciprocal step */
11513 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11514 mips32_op = OPC_RECIP1_S;
11516 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11517 mips32_op = OPC_RECIP1_S;
11519 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11520 mips32_op = OPC_RECIP1_PS;
11523 /* Conversions from double */
11524 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11525 mips32_op = OPC_CVT_D_S;
11527 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11528 mips32_op = OPC_CVT_D_W;
11530 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11531 mips32_op = OPC_CVT_D_L;
11534 /* Conversions from single */
11535 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11536 mips32_op = OPC_CVT_S_D;
11538 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11539 mips32_op = OPC_CVT_S_W;
11541 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11542 mips32_op = OPC_CVT_S_L;
11544 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11547 /* Conditional moves on floating-point codes */
11548 case COND_FLOAT_MOV(MOVT, 0):
11549 case COND_FLOAT_MOV(MOVT, 1):
11550 case COND_FLOAT_MOV(MOVT, 2):
11551 case COND_FLOAT_MOV(MOVT, 3):
11552 case COND_FLOAT_MOV(MOVT, 4):
11553 case COND_FLOAT_MOV(MOVT, 5):
11554 case COND_FLOAT_MOV(MOVT, 6):
11555 case COND_FLOAT_MOV(MOVT, 7):
11556 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11558 case COND_FLOAT_MOV(MOVF, 0):
11559 case COND_FLOAT_MOV(MOVF, 1):
11560 case COND_FLOAT_MOV(MOVF, 2):
11561 case COND_FLOAT_MOV(MOVF, 3):
11562 case COND_FLOAT_MOV(MOVF, 4):
11563 case COND_FLOAT_MOV(MOVF, 5):
11564 case COND_FLOAT_MOV(MOVF, 6):
11565 case COND_FLOAT_MOV(MOVF, 7):
11566 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11569 MIPS_INVAL("pool32fxf");
11570 generate_exception(ctx, EXCP_RI);
11575 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11576 uint16_t insn_hw1, int *is_branch)
11580 int rt, rs, rd, rr;
11582 uint32_t op, minor, mips32_op;
11583 uint32_t cond, fmt, cc;
11585 insn = cpu_lduw_code(env, ctx->pc + 2);
11586 ctx->opcode = (ctx->opcode << 16) | insn;
11588 rt = (ctx->opcode >> 21) & 0x1f;
11589 rs = (ctx->opcode >> 16) & 0x1f;
11590 rd = (ctx->opcode >> 11) & 0x1f;
11591 rr = (ctx->opcode >> 6) & 0x1f;
11592 imm = (int16_t) ctx->opcode;
11594 op = (ctx->opcode >> 26) & 0x3f;
11597 minor = ctx->opcode & 0x3f;
11600 minor = (ctx->opcode >> 6) & 0xf;
11603 mips32_op = OPC_SLL;
11606 mips32_op = OPC_SRA;
11609 mips32_op = OPC_SRL;
11612 mips32_op = OPC_ROTR;
11614 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11617 goto pool32a_invalid;
11621 minor = (ctx->opcode >> 6) & 0xf;
11625 mips32_op = OPC_ADD;
11628 mips32_op = OPC_ADDU;
11631 mips32_op = OPC_SUB;
11634 mips32_op = OPC_SUBU;
11637 mips32_op = OPC_MUL;
11639 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11643 mips32_op = OPC_SLLV;
11646 mips32_op = OPC_SRLV;
11649 mips32_op = OPC_SRAV;
11652 mips32_op = OPC_ROTRV;
11654 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11656 /* Logical operations */
11658 mips32_op = OPC_AND;
11661 mips32_op = OPC_OR;
11664 mips32_op = OPC_NOR;
11667 mips32_op = OPC_XOR;
11669 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11671 /* Set less than */
11673 mips32_op = OPC_SLT;
11676 mips32_op = OPC_SLTU;
11678 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11681 goto pool32a_invalid;
11685 minor = (ctx->opcode >> 6) & 0xf;
11687 /* Conditional moves */
11689 mips32_op = OPC_MOVN;
11692 mips32_op = OPC_MOVZ;
11694 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11697 gen_ldxs(ctx, rs, rt, rd);
11700 goto pool32a_invalid;
11704 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11707 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11710 gen_pool32axf(env, ctx, rt, rs, is_branch);
11713 generate_exception(ctx, EXCP_BREAK);
11717 MIPS_INVAL("pool32a");
11718 generate_exception(ctx, EXCP_RI);
11723 minor = (ctx->opcode >> 12) & 0xf;
11726 check_cp0_enabled(ctx);
11727 /* Treat as no-op. */
11731 /* COP2: Not implemented. */
11732 generate_exception_err(ctx, EXCP_CpU, 2);
11736 #ifdef TARGET_MIPS64
11740 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11744 #ifdef TARGET_MIPS64
11748 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11751 MIPS_INVAL("pool32b");
11752 generate_exception(ctx, EXCP_RI);
11757 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11758 minor = ctx->opcode & 0x3f;
11759 check_cp1_enabled(ctx);
11762 mips32_op = OPC_ALNV_PS;
11765 mips32_op = OPC_MADD_S;
11768 mips32_op = OPC_MADD_D;
11771 mips32_op = OPC_MADD_PS;
11774 mips32_op = OPC_MSUB_S;
11777 mips32_op = OPC_MSUB_D;
11780 mips32_op = OPC_MSUB_PS;
11783 mips32_op = OPC_NMADD_S;
11786 mips32_op = OPC_NMADD_D;
11789 mips32_op = OPC_NMADD_PS;
11792 mips32_op = OPC_NMSUB_S;
11795 mips32_op = OPC_NMSUB_D;
11798 mips32_op = OPC_NMSUB_PS;
11800 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11802 case CABS_COND_FMT:
11803 cond = (ctx->opcode >> 6) & 0xf;
11804 cc = (ctx->opcode >> 13) & 0x7;
11805 fmt = (ctx->opcode >> 10) & 0x3;
11808 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11811 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11814 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11817 goto pool32f_invalid;
11821 cond = (ctx->opcode >> 6) & 0xf;
11822 cc = (ctx->opcode >> 13) & 0x7;
11823 fmt = (ctx->opcode >> 10) & 0x3;
11826 gen_cmp_s(ctx, cond, rt, rs, cc);
11829 gen_cmp_d(ctx, cond, rt, rs, cc);
11832 gen_cmp_ps(ctx, cond, rt, rs, cc);
11835 goto pool32f_invalid;
11839 gen_pool32fxf(env, ctx, rt, rs);
11843 switch ((ctx->opcode >> 6) & 0x7) {
11845 mips32_op = OPC_PLL_PS;
11848 mips32_op = OPC_PLU_PS;
11851 mips32_op = OPC_PUL_PS;
11854 mips32_op = OPC_PUU_PS;
11857 mips32_op = OPC_CVT_PS_S;
11859 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11862 goto pool32f_invalid;
11867 switch ((ctx->opcode >> 6) & 0x7) {
11869 mips32_op = OPC_LWXC1;
11872 mips32_op = OPC_SWXC1;
11875 mips32_op = OPC_LDXC1;
11878 mips32_op = OPC_SDXC1;
11881 mips32_op = OPC_LUXC1;
11884 mips32_op = OPC_SUXC1;
11886 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11889 goto pool32f_invalid;
11894 fmt = (ctx->opcode >> 9) & 0x3;
11895 switch ((ctx->opcode >> 6) & 0x7) {
11899 mips32_op = OPC_RSQRT2_S;
11902 mips32_op = OPC_RSQRT2_D;
11905 mips32_op = OPC_RSQRT2_PS;
11908 goto pool32f_invalid;
11914 mips32_op = OPC_RECIP2_S;
11917 mips32_op = OPC_RECIP2_D;
11920 mips32_op = OPC_RECIP2_PS;
11923 goto pool32f_invalid;
11927 mips32_op = OPC_ADDR_PS;
11930 mips32_op = OPC_MULR_PS;
11932 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11935 goto pool32f_invalid;
11939 /* MOV[FT].fmt and PREFX */
11940 cc = (ctx->opcode >> 13) & 0x7;
11941 fmt = (ctx->opcode >> 9) & 0x3;
11942 switch ((ctx->opcode >> 6) & 0x7) {
11946 gen_movcf_s(rs, rt, cc, 0);
11949 gen_movcf_d(ctx, rs, rt, cc, 0);
11952 gen_movcf_ps(rs, rt, cc, 0);
11955 goto pool32f_invalid;
11961 gen_movcf_s(rs, rt, cc, 1);
11964 gen_movcf_d(ctx, rs, rt, cc, 1);
11967 gen_movcf_ps(rs, rt, cc, 1);
11970 goto pool32f_invalid;
11976 goto pool32f_invalid;
11979 #define FINSN_3ARG_SDPS(prfx) \
11980 switch ((ctx->opcode >> 8) & 0x3) { \
11982 mips32_op = OPC_##prfx##_S; \
11985 mips32_op = OPC_##prfx##_D; \
11987 case FMT_SDPS_PS: \
11988 mips32_op = OPC_##prfx##_PS; \
11991 goto pool32f_invalid; \
11994 /* regular FP ops */
11995 switch ((ctx->opcode >> 6) & 0x3) {
11997 FINSN_3ARG_SDPS(ADD);
12000 FINSN_3ARG_SDPS(SUB);
12003 FINSN_3ARG_SDPS(MUL);
12006 fmt = (ctx->opcode >> 8) & 0x3;
12008 mips32_op = OPC_DIV_D;
12009 } else if (fmt == 0) {
12010 mips32_op = OPC_DIV_S;
12012 goto pool32f_invalid;
12016 goto pool32f_invalid;
12021 switch ((ctx->opcode >> 6) & 0x3) {
12023 FINSN_3ARG_SDPS(MOVN);
12026 FINSN_3ARG_SDPS(MOVZ);
12029 goto pool32f_invalid;
12033 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12037 MIPS_INVAL("pool32f");
12038 generate_exception(ctx, EXCP_RI);
12042 generate_exception_err(ctx, EXCP_CpU, 1);
12046 minor = (ctx->opcode >> 21) & 0x1f;
12049 mips32_op = OPC_BLTZ;
12052 mips32_op = OPC_BLTZAL;
12055 mips32_op = OPC_BLTZALS;
12058 mips32_op = OPC_BGEZ;
12061 mips32_op = OPC_BGEZAL;
12064 mips32_op = OPC_BGEZALS;
12067 mips32_op = OPC_BLEZ;
12070 mips32_op = OPC_BGTZ;
12072 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12078 mips32_op = OPC_TLTI;
12081 mips32_op = OPC_TGEI;
12084 mips32_op = OPC_TLTIU;
12087 mips32_op = OPC_TGEIU;
12090 mips32_op = OPC_TNEI;
12093 mips32_op = OPC_TEQI;
12095 gen_trap(ctx, mips32_op, rs, -1, imm);
12100 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12101 4, rs, 0, imm << 1);
12102 /* Compact branches don't have a delay slot, so just let
12103 the normal delay slot handling take us to the branch
12107 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12113 /* COP2: Not implemented. */
12114 generate_exception_err(ctx, EXCP_CpU, 2);
12117 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12120 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12123 mips32_op = OPC_BC1FANY4;
12126 mips32_op = OPC_BC1TANY4;
12129 check_insn(env, ctx, ASE_MIPS3D);
12132 gen_compute_branch1(env, ctx, mips32_op,
12133 (ctx->opcode >> 18) & 0x7, imm << 1);
12138 /* MIPS DSP: not implemented */
12141 MIPS_INVAL("pool32i");
12142 generate_exception(ctx, EXCP_RI);
12147 minor = (ctx->opcode >> 12) & 0xf;
12150 mips32_op = OPC_LWL;
12153 mips32_op = OPC_SWL;
12156 mips32_op = OPC_LWR;
12159 mips32_op = OPC_SWR;
12161 #if defined(TARGET_MIPS64)
12163 mips32_op = OPC_LDL;
12166 mips32_op = OPC_SDL;
12169 mips32_op = OPC_LDR;
12172 mips32_op = OPC_SDR;
12175 mips32_op = OPC_LWU;
12178 mips32_op = OPC_LLD;
12182 mips32_op = OPC_LL;
12185 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12188 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12191 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12193 #if defined(TARGET_MIPS64)
12195 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12199 /* Treat as no-op */
12202 MIPS_INVAL("pool32c");
12203 generate_exception(ctx, EXCP_RI);
12208 mips32_op = OPC_ADDI;
12211 mips32_op = OPC_ADDIU;
12213 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12216 /* Logical operations */
12218 mips32_op = OPC_ORI;
12221 mips32_op = OPC_XORI;
12224 mips32_op = OPC_ANDI;
12226 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12229 /* Set less than immediate */
12231 mips32_op = OPC_SLTI;
12234 mips32_op = OPC_SLTIU;
12236 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12239 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12240 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12244 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12245 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12249 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12253 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12257 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12258 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12262 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12263 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12266 /* Floating point (COP1) */
12268 mips32_op = OPC_LWC1;
12271 mips32_op = OPC_LDC1;
12274 mips32_op = OPC_SWC1;
12277 mips32_op = OPC_SDC1;
12279 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12283 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12284 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12286 gen_addiupc(ctx, reg, offset, 0, 0);
12289 /* Loads and stores */
12291 mips32_op = OPC_LB;
12294 mips32_op = OPC_LBU;
12297 mips32_op = OPC_LH;
12300 mips32_op = OPC_LHU;
12303 mips32_op = OPC_LW;
12305 #ifdef TARGET_MIPS64
12307 mips32_op = OPC_LD;
12310 mips32_op = OPC_SD;
12314 mips32_op = OPC_SB;
12317 mips32_op = OPC_SH;
12320 mips32_op = OPC_SW;
12323 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12326 gen_st(ctx, mips32_op, rt, rs, imm);
12329 generate_exception(ctx, EXCP_RI);
12334 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12338 /* make sure instructions are on a halfword boundary */
12339 if (ctx->pc & 0x1) {
12340 env->CP0_BadVAddr = ctx->pc;
12341 generate_exception(ctx, EXCP_AdEL);
12342 ctx->bstate = BS_STOP;
12346 op = (ctx->opcode >> 10) & 0x3f;
12347 /* Enforce properly-sized instructions in a delay slot */
12348 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12349 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12383 case POOL48A: /* ??? */
12388 if (bits & MIPS_HFLAG_BDS16) {
12389 generate_exception(ctx, EXCP_RI);
12390 /* Just stop translation; the user is confused. */
12391 ctx->bstate = BS_STOP;
12416 if (bits & MIPS_HFLAG_BDS32) {
12417 generate_exception(ctx, EXCP_RI);
12418 /* Just stop translation; the user is confused. */
12419 ctx->bstate = BS_STOP;
12430 int rd = mmreg(uMIPS_RD(ctx->opcode));
12431 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12432 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12435 switch (ctx->opcode & 0x1) {
12444 gen_arith(env, ctx, opc, rd, rs1, rs2);
12449 int rd = mmreg(uMIPS_RD(ctx->opcode));
12450 int rs = mmreg(uMIPS_RS(ctx->opcode));
12451 int amount = (ctx->opcode >> 1) & 0x7;
12453 amount = amount == 0 ? 8 : amount;
12455 switch (ctx->opcode & 0x1) {
12464 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12468 gen_pool16c_insn(env, ctx, is_branch);
12472 int rd = mmreg(uMIPS_RD(ctx->opcode));
12473 int rb = 28; /* GP */
12474 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12476 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12480 if (ctx->opcode & 1) {
12481 generate_exception(ctx, EXCP_RI);
12484 int enc_dest = uMIPS_RD(ctx->opcode);
12485 int enc_rt = uMIPS_RS2(ctx->opcode);
12486 int enc_rs = uMIPS_RS1(ctx->opcode);
12487 int rd, rs, re, rt;
12488 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12489 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12490 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12492 rd = rd_enc[enc_dest];
12493 re = re_enc[enc_dest];
12494 rs = rs_rt_enc[enc_rs];
12495 rt = rs_rt_enc[enc_rt];
12497 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12498 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12503 int rd = mmreg(uMIPS_RD(ctx->opcode));
12504 int rb = mmreg(uMIPS_RS(ctx->opcode));
12505 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12506 offset = (offset == 0xf ? -1 : offset);
12508 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12513 int rd = mmreg(uMIPS_RD(ctx->opcode));
12514 int rb = mmreg(uMIPS_RS(ctx->opcode));
12515 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12517 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12522 int rd = (ctx->opcode >> 5) & 0x1f;
12523 int rb = 29; /* SP */
12524 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12526 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12531 int rd = mmreg(uMIPS_RD(ctx->opcode));
12532 int rb = mmreg(uMIPS_RS(ctx->opcode));
12533 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12535 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12540 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12541 int rb = mmreg(uMIPS_RS(ctx->opcode));
12542 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12544 gen_st(ctx, OPC_SB, rd, rb, offset);
12549 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12550 int rb = mmreg(uMIPS_RS(ctx->opcode));
12551 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12553 gen_st(ctx, OPC_SH, rd, rb, offset);
12558 int rd = (ctx->opcode >> 5) & 0x1f;
12559 int rb = 29; /* SP */
12560 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12562 gen_st(ctx, OPC_SW, rd, rb, offset);
12567 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12568 int rb = mmreg(uMIPS_RS(ctx->opcode));
12569 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12571 gen_st(ctx, OPC_SW, rd, rb, offset);
12576 int rd = uMIPS_RD5(ctx->opcode);
12577 int rs = uMIPS_RS5(ctx->opcode);
12579 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12583 gen_andi16(env, ctx);
12586 switch (ctx->opcode & 0x1) {
12588 gen_addius5(env, ctx);
12591 gen_addiusp(env, ctx);
12596 switch (ctx->opcode & 0x1) {
12598 gen_addiur2(env, ctx);
12601 gen_addiur1sp(env, ctx);
12606 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12607 SIMM(ctx->opcode, 0, 10) << 1);
12612 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12613 mmreg(uMIPS_RD(ctx->opcode)),
12614 0, SIMM(ctx->opcode, 0, 7) << 1);
12619 int reg = mmreg(uMIPS_RD(ctx->opcode));
12620 int imm = ZIMM(ctx->opcode, 0, 7);
12622 imm = (imm == 0x7f ? -1 : imm);
12623 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12633 generate_exception(ctx, EXCP_RI);
12636 decode_micromips32_opc (env, ctx, op, is_branch);
12643 /* SmartMIPS extension to MIPS32 */
12645 #if defined(TARGET_MIPS64)
12647 /* MDMX extension to MIPS64 */
12651 /* MIPSDSP functions. */
12652 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12653 int rd, int base, int offset)
12655 const char *opn = "ldx";
12664 t0 = tcg_temp_new();
12667 gen_load_gpr(t0, offset);
12668 } else if (offset == 0) {
12669 gen_load_gpr(t0, base);
12671 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12674 save_cpu_state(ctx, 0);
12677 op_ld_lbu(t0, t0, ctx);
12678 gen_store_gpr(t0, rd);
12682 op_ld_lh(t0, t0, ctx);
12683 gen_store_gpr(t0, rd);
12687 op_ld_lw(t0, t0, ctx);
12688 gen_store_gpr(t0, rd);
12691 #if defined(TARGET_MIPS64)
12693 op_ld_ld(t0, t0, ctx);
12694 gen_store_gpr(t0, rd);
12699 (void)opn; /* avoid a compiler warning */
12700 MIPS_DEBUG("%s %s, %s(%s)", opn,
12701 regnames[rd], regnames[offset], regnames[base]);
12705 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12706 int ret, int v1, int v2)
12708 const char *opn = "mipsdsp arith";
12713 /* Treat as NOP. */
12718 v1_t = tcg_temp_new();
12719 v2_t = tcg_temp_new();
12721 gen_load_gpr(v1_t, v1);
12722 gen_load_gpr(v2_t, v2);
12725 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12726 case OPC_MULT_G_2E:
12730 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12732 case OPC_ADDUH_R_QB:
12733 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12736 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12738 case OPC_ADDQH_R_PH:
12739 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12742 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12744 case OPC_ADDQH_R_W:
12745 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12748 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12750 case OPC_SUBUH_R_QB:
12751 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12754 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12756 case OPC_SUBQH_R_PH:
12757 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12760 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12762 case OPC_SUBQH_R_W:
12763 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12767 case OPC_ABSQ_S_PH_DSP:
12769 case OPC_ABSQ_S_QB:
12771 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12773 case OPC_ABSQ_S_PH:
12775 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12779 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12781 case OPC_PRECEQ_W_PHL:
12783 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12784 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12786 case OPC_PRECEQ_W_PHR:
12788 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12789 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12790 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12792 case OPC_PRECEQU_PH_QBL:
12794 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12796 case OPC_PRECEQU_PH_QBR:
12798 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12800 case OPC_PRECEQU_PH_QBLA:
12802 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12804 case OPC_PRECEQU_PH_QBRA:
12806 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12808 case OPC_PRECEU_PH_QBL:
12810 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12812 case OPC_PRECEU_PH_QBR:
12814 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12816 case OPC_PRECEU_PH_QBLA:
12818 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12820 case OPC_PRECEU_PH_QBRA:
12822 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12826 case OPC_ADDU_QB_DSP:
12830 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12832 case OPC_ADDQ_S_PH:
12834 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12838 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12842 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12844 case OPC_ADDU_S_QB:
12846 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12850 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12852 case OPC_ADDU_S_PH:
12854 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12858 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12860 case OPC_SUBQ_S_PH:
12862 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12866 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12870 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12872 case OPC_SUBU_S_QB:
12874 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12878 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12880 case OPC_SUBU_S_PH:
12882 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12886 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12890 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12894 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12896 case OPC_RADDU_W_QB:
12898 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12902 case OPC_CMPU_EQ_QB_DSP:
12904 case OPC_PRECR_QB_PH:
12906 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12908 case OPC_PRECRQ_QB_PH:
12910 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12912 case OPC_PRECR_SRA_PH_W:
12915 TCGv_i32 sa_t = tcg_const_i32(v2);
12916 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12918 tcg_temp_free_i32(sa_t);
12921 case OPC_PRECR_SRA_R_PH_W:
12924 TCGv_i32 sa_t = tcg_const_i32(v2);
12925 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12927 tcg_temp_free_i32(sa_t);
12930 case OPC_PRECRQ_PH_W:
12932 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12934 case OPC_PRECRQ_RS_PH_W:
12936 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12938 case OPC_PRECRQU_S_QB_PH:
12940 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12944 #ifdef TARGET_MIPS64
12945 case OPC_ABSQ_S_QH_DSP:
12947 case OPC_PRECEQ_L_PWL:
12949 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12951 case OPC_PRECEQ_L_PWR:
12953 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12955 case OPC_PRECEQ_PW_QHL:
12957 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12959 case OPC_PRECEQ_PW_QHR:
12961 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12963 case OPC_PRECEQ_PW_QHLA:
12965 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12967 case OPC_PRECEQ_PW_QHRA:
12969 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12971 case OPC_PRECEQU_QH_OBL:
12973 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12975 case OPC_PRECEQU_QH_OBR:
12977 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12979 case OPC_PRECEQU_QH_OBLA:
12981 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12983 case OPC_PRECEQU_QH_OBRA:
12985 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12987 case OPC_PRECEU_QH_OBL:
12989 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12991 case OPC_PRECEU_QH_OBR:
12993 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12995 case OPC_PRECEU_QH_OBLA:
12997 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12999 case OPC_PRECEU_QH_OBRA:
13001 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13003 case OPC_ABSQ_S_OB:
13005 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13007 case OPC_ABSQ_S_PW:
13009 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13011 case OPC_ABSQ_S_QH:
13013 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13017 case OPC_ADDU_OB_DSP:
13019 case OPC_RADDU_L_OB:
13021 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13025 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13027 case OPC_SUBQ_S_PW:
13029 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13033 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13035 case OPC_SUBQ_S_QH:
13037 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13041 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13043 case OPC_SUBU_S_OB:
13045 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13049 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13051 case OPC_SUBU_S_QH:
13053 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13057 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13059 case OPC_SUBUH_R_OB:
13061 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13065 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13067 case OPC_ADDQ_S_PW:
13069 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13073 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13075 case OPC_ADDQ_S_QH:
13077 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13081 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13083 case OPC_ADDU_S_OB:
13085 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13089 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13091 case OPC_ADDU_S_QH:
13093 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13097 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13099 case OPC_ADDUH_R_OB:
13101 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13105 case OPC_CMPU_EQ_OB_DSP:
13107 case OPC_PRECR_OB_QH:
13109 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13111 case OPC_PRECR_SRA_QH_PW:
13114 TCGv_i32 ret_t = tcg_const_i32(ret);
13115 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13116 tcg_temp_free_i32(ret_t);
13119 case OPC_PRECR_SRA_R_QH_PW:
13122 TCGv_i32 sa_v = tcg_const_i32(ret);
13123 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13124 tcg_temp_free_i32(sa_v);
13127 case OPC_PRECRQ_OB_QH:
13129 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13131 case OPC_PRECRQ_PW_L:
13133 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13135 case OPC_PRECRQ_QH_PW:
13137 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13139 case OPC_PRECRQ_RS_QH_PW:
13141 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13143 case OPC_PRECRQU_S_OB_QH:
13145 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13152 tcg_temp_free(v1_t);
13153 tcg_temp_free(v2_t);
13155 (void)opn; /* avoid a compiler warning */
13156 MIPS_DEBUG("%s", opn);
13159 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13160 int ret, int v1, int v2)
13163 const char *opn = "mipsdsp shift";
13169 /* Treat as NOP. */
13174 t0 = tcg_temp_new();
13175 v1_t = tcg_temp_new();
13176 v2_t = tcg_temp_new();
13178 tcg_gen_movi_tl(t0, v1);
13179 gen_load_gpr(v1_t, v1);
13180 gen_load_gpr(v2_t, v2);
13183 case OPC_SHLL_QB_DSP:
13185 op2 = MASK_SHLL_QB(ctx->opcode);
13189 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13193 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13197 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13201 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13203 case OPC_SHLL_S_PH:
13205 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13207 case OPC_SHLLV_S_PH:
13209 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13213 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13215 case OPC_SHLLV_S_W:
13217 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13221 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13225 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13229 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13233 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13237 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13239 case OPC_SHRA_R_QB:
13241 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13245 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13247 case OPC_SHRAV_R_QB:
13249 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13253 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13255 case OPC_SHRA_R_PH:
13257 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13261 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13263 case OPC_SHRAV_R_PH:
13265 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13269 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13271 case OPC_SHRAV_R_W:
13273 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13275 default: /* Invalid */
13276 MIPS_INVAL("MASK SHLL.QB");
13277 generate_exception(ctx, EXCP_RI);
13282 #ifdef TARGET_MIPS64
13283 case OPC_SHLL_OB_DSP:
13284 op2 = MASK_SHLL_OB(ctx->opcode);
13288 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13292 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13294 case OPC_SHLL_S_PW:
13296 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13298 case OPC_SHLLV_S_PW:
13300 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13304 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13308 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13312 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13316 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13318 case OPC_SHLL_S_QH:
13320 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13322 case OPC_SHLLV_S_QH:
13324 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13328 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13332 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13334 case OPC_SHRA_R_OB:
13336 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13338 case OPC_SHRAV_R_OB:
13340 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13344 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13348 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13350 case OPC_SHRA_R_PW:
13352 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13354 case OPC_SHRAV_R_PW:
13356 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13360 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13364 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13366 case OPC_SHRA_R_QH:
13368 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13370 case OPC_SHRAV_R_QH:
13372 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13376 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13380 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13384 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13388 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13390 default: /* Invalid */
13391 MIPS_INVAL("MASK SHLL.OB");
13392 generate_exception(ctx, EXCP_RI);
13400 tcg_temp_free(v1_t);
13401 tcg_temp_free(v2_t);
13402 (void)opn; /* avoid a compiler warning */
13403 MIPS_DEBUG("%s", opn);
13406 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13407 int ret, int v1, int v2, int check_ret)
13409 const char *opn = "mipsdsp multiply";
13414 if ((ret == 0) && (check_ret == 1)) {
13415 /* Treat as NOP. */
13420 t0 = tcg_temp_new_i32();
13421 v1_t = tcg_temp_new();
13422 v2_t = tcg_temp_new();
13424 tcg_gen_movi_i32(t0, ret);
13425 gen_load_gpr(v1_t, v1);
13426 gen_load_gpr(v2_t, v2);
13429 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13430 * the same mask and op1. */
13431 case OPC_MULT_G_2E:
13434 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13437 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13440 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13442 case OPC_MULQ_RS_W:
13443 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13447 case OPC_DPA_W_PH_DSP:
13449 case OPC_DPAU_H_QBL:
13451 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13453 case OPC_DPAU_H_QBR:
13455 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13457 case OPC_DPSU_H_QBL:
13459 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13461 case OPC_DPSU_H_QBR:
13463 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13467 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13469 case OPC_DPAX_W_PH:
13471 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13473 case OPC_DPAQ_S_W_PH:
13475 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13477 case OPC_DPAQX_S_W_PH:
13479 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13481 case OPC_DPAQX_SA_W_PH:
13483 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13487 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13489 case OPC_DPSX_W_PH:
13491 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13493 case OPC_DPSQ_S_W_PH:
13495 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13497 case OPC_DPSQX_S_W_PH:
13499 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13501 case OPC_DPSQX_SA_W_PH:
13503 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13505 case OPC_MULSAQ_S_W_PH:
13507 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13509 case OPC_DPAQ_SA_L_W:
13511 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13513 case OPC_DPSQ_SA_L_W:
13515 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13517 case OPC_MAQ_S_W_PHL:
13519 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13521 case OPC_MAQ_S_W_PHR:
13523 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13525 case OPC_MAQ_SA_W_PHL:
13527 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13529 case OPC_MAQ_SA_W_PHR:
13531 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13533 case OPC_MULSA_W_PH:
13535 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13539 #ifdef TARGET_MIPS64
13540 case OPC_DPAQ_W_QH_DSP:
13542 int ac = ret & 0x03;
13543 tcg_gen_movi_i32(t0, ac);
13548 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13552 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13556 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13560 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13564 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13566 case OPC_DPAQ_S_W_QH:
13568 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13570 case OPC_DPAQ_SA_L_PW:
13572 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13574 case OPC_DPAU_H_OBL:
13576 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13578 case OPC_DPAU_H_OBR:
13580 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13584 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13586 case OPC_DPSQ_S_W_QH:
13588 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13590 case OPC_DPSQ_SA_L_PW:
13592 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13594 case OPC_DPSU_H_OBL:
13596 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13598 case OPC_DPSU_H_OBR:
13600 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13602 case OPC_MAQ_S_L_PWL:
13604 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13606 case OPC_MAQ_S_L_PWR:
13608 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13610 case OPC_MAQ_S_W_QHLL:
13612 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13614 case OPC_MAQ_SA_W_QHLL:
13616 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13618 case OPC_MAQ_S_W_QHLR:
13620 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13622 case OPC_MAQ_SA_W_QHLR:
13624 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13626 case OPC_MAQ_S_W_QHRL:
13628 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13630 case OPC_MAQ_SA_W_QHRL:
13632 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13634 case OPC_MAQ_S_W_QHRR:
13636 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13638 case OPC_MAQ_SA_W_QHRR:
13640 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13642 case OPC_MULSAQ_S_L_PW:
13644 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13646 case OPC_MULSAQ_S_W_QH:
13648 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13654 case OPC_ADDU_QB_DSP:
13656 case OPC_MULEU_S_PH_QBL:
13658 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13660 case OPC_MULEU_S_PH_QBR:
13662 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13664 case OPC_MULQ_RS_PH:
13666 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 case OPC_MULEQ_S_W_PHL:
13670 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 case OPC_MULEQ_S_W_PHR:
13674 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 case OPC_MULQ_S_PH:
13678 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13682 #ifdef TARGET_MIPS64
13683 case OPC_ADDU_OB_DSP:
13685 case OPC_MULEQ_S_PW_QHL:
13687 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13689 case OPC_MULEQ_S_PW_QHR:
13691 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13693 case OPC_MULEU_S_QH_OBL:
13695 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13697 case OPC_MULEU_S_QH_OBR:
13699 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13701 case OPC_MULQ_RS_QH:
13703 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13710 tcg_temp_free_i32(t0);
13711 tcg_temp_free(v1_t);
13712 tcg_temp_free(v2_t);
13714 (void)opn; /* avoid a compiler warning */
13715 MIPS_DEBUG("%s", opn);
13719 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13720 uint32_t op1, uint32_t op2,
13723 const char *opn = "mipsdsp Bit/ Manipulation";
13729 /* Treat as NOP. */
13734 t0 = tcg_temp_new();
13735 val_t = tcg_temp_new();
13736 gen_load_gpr(val_t, val);
13739 case OPC_ABSQ_S_PH_DSP:
13743 gen_helper_bitrev(cpu_gpr[ret], val_t);
13748 target_long result;
13749 imm = (ctx->opcode >> 16) & 0xFF;
13750 result = (uint32_t)imm << 24 |
13751 (uint32_t)imm << 16 |
13752 (uint32_t)imm << 8 |
13754 result = (int32_t)result;
13755 tcg_gen_movi_tl(cpu_gpr[ret], result);
13760 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13761 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13762 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13763 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13764 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13765 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13770 imm = (ctx->opcode >> 16) & 0x03FF;
13771 tcg_gen_movi_tl(cpu_gpr[ret], \
13772 (target_long)((int32_t)imm << 16 | \
13773 (uint32_t)(uint16_t)imm));
13778 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13779 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13780 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13781 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13785 #ifdef TARGET_MIPS64
13786 case OPC_ABSQ_S_QH_DSP:
13793 imm = (ctx->opcode >> 16) & 0xFF;
13794 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13795 temp = (temp << 16) | temp;
13796 temp = (temp << 32) | temp;
13797 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13805 imm = (ctx->opcode >> 16) & 0x03FF;
13806 imm = (int16_t)(imm << 6) >> 6;
13807 temp = ((target_long)imm << 32) \
13808 | ((target_long)imm & 0xFFFFFFFF);
13809 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13817 imm = (ctx->opcode >> 16) & 0x03FF;
13818 imm = (int16_t)(imm << 6) >> 6;
13820 temp = ((uint64_t)(uint16_t)imm << 48) |
13821 ((uint64_t)(uint16_t)imm << 32) |
13822 ((uint64_t)(uint16_t)imm << 16) |
13823 (uint64_t)(uint16_t)imm;
13824 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13829 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13830 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13831 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13832 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13833 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13834 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13835 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13839 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
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_ext16u_tl(cpu_gpr[ret], val_t);
13846 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13847 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13848 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13849 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13856 tcg_temp_free(val_t);
13858 (void)opn; /* avoid a compiler warning */
13859 MIPS_DEBUG("%s", opn);
13862 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13863 uint32_t op1, uint32_t op2,
13864 int ret, int v1, int v2, int check_ret)
13866 const char *opn = "mipsdsp add compare pick";
13872 if ((ret == 0) && (check_ret == 1)) {
13873 /* Treat as NOP. */
13878 t0 = tcg_temp_new_i32();
13879 t1 = tcg_temp_new();
13880 v1_t = tcg_temp_new();
13881 v2_t = tcg_temp_new();
13883 gen_load_gpr(v1_t, v1);
13884 gen_load_gpr(v2_t, v2);
13887 case OPC_APPEND_DSP:
13890 tcg_gen_movi_i32(t0, v2);
13891 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13894 tcg_gen_movi_i32(t0, v2);
13895 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13898 tcg_gen_movi_i32(t0, v2);
13899 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13901 default: /* Invid */
13902 MIPS_INVAL("MASK APPEND");
13903 generate_exception(ctx, EXCP_RI);
13907 case OPC_CMPU_EQ_QB_DSP:
13909 case OPC_CMPU_EQ_QB:
13911 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13913 case OPC_CMPU_LT_QB:
13915 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13917 case OPC_CMPU_LE_QB:
13919 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13921 case OPC_CMPGU_EQ_QB:
13923 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13925 case OPC_CMPGU_LT_QB:
13927 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13929 case OPC_CMPGU_LE_QB:
13931 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13933 case OPC_CMPGDU_EQ_QB:
13935 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13936 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13937 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13938 tcg_gen_shli_tl(t1, t1, 24);
13939 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13941 case OPC_CMPGDU_LT_QB:
13943 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13944 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13945 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13946 tcg_gen_shli_tl(t1, t1, 24);
13947 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13949 case OPC_CMPGDU_LE_QB:
13951 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13952 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13953 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13954 tcg_gen_shli_tl(t1, t1, 24);
13955 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13957 case OPC_CMP_EQ_PH:
13959 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13961 case OPC_CMP_LT_PH:
13963 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13965 case OPC_CMP_LE_PH:
13967 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13971 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13975 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13977 case OPC_PACKRL_PH:
13979 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13983 #ifdef TARGET_MIPS64
13984 case OPC_CMPU_EQ_OB_DSP:
13986 case OPC_CMP_EQ_PW:
13988 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13990 case OPC_CMP_LT_PW:
13992 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13994 case OPC_CMP_LE_PW:
13996 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13998 case OPC_CMP_EQ_QH:
14000 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14002 case OPC_CMP_LT_QH:
14004 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14006 case OPC_CMP_LE_QH:
14008 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14010 case OPC_CMPGDU_EQ_OB:
14012 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14014 case OPC_CMPGDU_LT_OB:
14016 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14018 case OPC_CMPGDU_LE_OB:
14020 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14022 case OPC_CMPGU_EQ_OB:
14024 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14026 case OPC_CMPGU_LT_OB:
14028 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14030 case OPC_CMPGU_LE_OB:
14032 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14034 case OPC_CMPU_EQ_OB:
14036 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14038 case OPC_CMPU_LT_OB:
14040 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14042 case OPC_CMPU_LE_OB:
14044 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14046 case OPC_PACKRL_PW:
14048 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14052 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14056 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14060 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14064 case OPC_DAPPEND_DSP:
14067 tcg_gen_movi_i32(t0, v2);
14068 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14071 tcg_gen_movi_i32(t0, v2);
14072 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14075 tcg_gen_movi_i32(t0, v2);
14076 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14079 tcg_gen_movi_i32(t0, v2);
14080 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14082 default: /* Invalid */
14083 MIPS_INVAL("MASK DAPPEND");
14084 generate_exception(ctx, EXCP_RI);
14091 tcg_temp_free_i32(t0);
14093 tcg_temp_free(v1_t);
14094 tcg_temp_free(v2_t);
14096 (void)opn; /* avoid a compiler warning */
14097 MIPS_DEBUG("%s", opn);
14100 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14101 int ret, int v1, int v2, int check_ret)
14104 const char *opn = "mipsdsp accumulator";
14111 if ((ret == 0) && (check_ret == 1)) {
14112 /* Treat as NOP. */
14117 t0 = tcg_temp_new();
14118 t1 = tcg_temp_new();
14119 v1_t = tcg_temp_new();
14120 v2_t = tcg_temp_new();
14122 gen_load_gpr(v1_t, v1);
14123 gen_load_gpr(v2_t, v2);
14126 case OPC_EXTR_W_DSP:
14130 tcg_gen_movi_tl(t0, v2);
14131 tcg_gen_movi_tl(t1, v1);
14132 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14135 tcg_gen_movi_tl(t0, v2);
14136 tcg_gen_movi_tl(t1, v1);
14137 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14139 case OPC_EXTR_RS_W:
14140 tcg_gen_movi_tl(t0, v2);
14141 tcg_gen_movi_tl(t1, v1);
14142 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14145 tcg_gen_movi_tl(t0, v2);
14146 tcg_gen_movi_tl(t1, v1);
14147 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14149 case OPC_EXTRV_S_H:
14150 tcg_gen_movi_tl(t0, v2);
14151 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14154 tcg_gen_movi_tl(t0, v2);
14155 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14157 case OPC_EXTRV_R_W:
14158 tcg_gen_movi_tl(t0, v2);
14159 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14161 case OPC_EXTRV_RS_W:
14162 tcg_gen_movi_tl(t0, v2);
14163 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14166 tcg_gen_movi_tl(t0, v2);
14167 tcg_gen_movi_tl(t1, v1);
14168 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14171 tcg_gen_movi_tl(t0, v2);
14172 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14175 tcg_gen_movi_tl(t0, v2);
14176 tcg_gen_movi_tl(t1, v1);
14177 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14180 tcg_gen_movi_tl(t0, v2);
14181 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14184 imm = (ctx->opcode >> 20) & 0x3F;
14185 tcg_gen_movi_tl(t0, ret);
14186 tcg_gen_movi_tl(t1, imm);
14187 gen_helper_shilo(t0, t1, cpu_env);
14190 tcg_gen_movi_tl(t0, ret);
14191 gen_helper_shilo(t0, v1_t, cpu_env);
14194 tcg_gen_movi_tl(t0, ret);
14195 gen_helper_mthlip(t0, v1_t, cpu_env);
14198 imm = (ctx->opcode >> 11) & 0x3FF;
14199 tcg_gen_movi_tl(t0, imm);
14200 gen_helper_wrdsp(v1_t, t0, cpu_env);
14203 imm = (ctx->opcode >> 16) & 0x03FF;
14204 tcg_gen_movi_tl(t0, imm);
14205 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14209 #ifdef TARGET_MIPS64
14210 case OPC_DEXTR_W_DSP:
14214 tcg_gen_movi_tl(t0, ret);
14215 gen_helper_dmthlip(v1_t, t0, cpu_env);
14219 int shift = (ctx->opcode >> 19) & 0x7F;
14220 int ac = (ctx->opcode >> 11) & 0x03;
14221 tcg_gen_movi_tl(t0, shift);
14222 tcg_gen_movi_tl(t1, ac);
14223 gen_helper_dshilo(t0, t1, cpu_env);
14228 int ac = (ctx->opcode >> 11) & 0x03;
14229 tcg_gen_movi_tl(t0, ac);
14230 gen_helper_dshilo(v1_t, t0, cpu_env);
14234 tcg_gen_movi_tl(t0, v2);
14235 tcg_gen_movi_tl(t1, v1);
14237 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14240 tcg_gen_movi_tl(t0, v2);
14241 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14244 tcg_gen_movi_tl(t0, v2);
14245 tcg_gen_movi_tl(t1, v1);
14246 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14249 tcg_gen_movi_tl(t0, v2);
14250 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14253 tcg_gen_movi_tl(t0, v2);
14254 tcg_gen_movi_tl(t1, v1);
14255 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14257 case OPC_DEXTR_R_L:
14258 tcg_gen_movi_tl(t0, v2);
14259 tcg_gen_movi_tl(t1, v1);
14260 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14262 case OPC_DEXTR_RS_L:
14263 tcg_gen_movi_tl(t0, v2);
14264 tcg_gen_movi_tl(t1, v1);
14265 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14268 tcg_gen_movi_tl(t0, v2);
14269 tcg_gen_movi_tl(t1, v1);
14270 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14272 case OPC_DEXTR_R_W:
14273 tcg_gen_movi_tl(t0, v2);
14274 tcg_gen_movi_tl(t1, v1);
14275 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14277 case OPC_DEXTR_RS_W:
14278 tcg_gen_movi_tl(t0, v2);
14279 tcg_gen_movi_tl(t1, v1);
14280 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14282 case OPC_DEXTR_S_H:
14283 tcg_gen_movi_tl(t0, v2);
14284 tcg_gen_movi_tl(t1, v1);
14285 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14287 case OPC_DEXTRV_S_H:
14288 tcg_gen_movi_tl(t0, v2);
14289 tcg_gen_movi_tl(t1, v1);
14290 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14293 tcg_gen_movi_tl(t0, v2);
14294 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14296 case OPC_DEXTRV_R_L:
14297 tcg_gen_movi_tl(t0, v2);
14298 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14300 case OPC_DEXTRV_RS_L:
14301 tcg_gen_movi_tl(t0, v2);
14302 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14305 tcg_gen_movi_tl(t0, v2);
14306 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14308 case OPC_DEXTRV_R_W:
14309 tcg_gen_movi_tl(t0, v2);
14310 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14312 case OPC_DEXTRV_RS_W:
14313 tcg_gen_movi_tl(t0, v2);
14314 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14323 tcg_temp_free(v1_t);
14324 tcg_temp_free(v2_t);
14326 (void)opn; /* avoid a compiler warning */
14327 MIPS_DEBUG("%s", opn);
14330 /* End MIPSDSP functions. */
14332 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14335 int rs, rt, rd, sa;
14336 uint32_t op, op1, op2;
14339 /* make sure instructions are on a word boundary */
14340 if (ctx->pc & 0x3) {
14341 env->CP0_BadVAddr = ctx->pc;
14342 generate_exception(ctx, EXCP_AdEL);
14346 /* Handle blikely not taken case */
14347 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14348 int l1 = gen_new_label();
14350 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14351 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14352 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14353 gen_goto_tb(ctx, 1, ctx->pc + 4);
14357 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14358 tcg_gen_debug_insn_start(ctx->pc);
14361 op = MASK_OP_MAJOR(ctx->opcode);
14362 rs = (ctx->opcode >> 21) & 0x1f;
14363 rt = (ctx->opcode >> 16) & 0x1f;
14364 rd = (ctx->opcode >> 11) & 0x1f;
14365 sa = (ctx->opcode >> 6) & 0x1f;
14366 imm = (int16_t)ctx->opcode;
14369 op1 = MASK_SPECIAL(ctx->opcode);
14371 case OPC_SLL: /* Shift with immediate */
14373 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14376 switch ((ctx->opcode >> 21) & 0x1f) {
14378 /* rotr is decoded as srl on non-R2 CPUs */
14379 if (env->insn_flags & ISA_MIPS32R2) {
14384 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14387 generate_exception(ctx, EXCP_RI);
14391 case OPC_MOVN: /* Conditional move */
14393 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14394 INSN_LOONGSON2E | INSN_LOONGSON2F);
14395 gen_cond_move(env, ctx, op1, rd, rs, rt);
14397 case OPC_ADD ... OPC_SUBU:
14398 gen_arith(env, ctx, op1, rd, rs, rt);
14400 case OPC_SLLV: /* Shifts */
14402 gen_shift(env, ctx, op1, rd, rs, rt);
14405 switch ((ctx->opcode >> 6) & 0x1f) {
14407 /* rotrv is decoded as srlv on non-R2 CPUs */
14408 if (env->insn_flags & ISA_MIPS32R2) {
14413 gen_shift(env, ctx, op1, rd, rs, rt);
14416 generate_exception(ctx, EXCP_RI);
14420 case OPC_SLT: /* Set on less than */
14422 gen_slt(env, ctx, op1, rd, rs, rt);
14424 case OPC_AND: /* Logic*/
14428 gen_logic(env, ctx, op1, rd, rs, rt);
14430 case OPC_MULT ... OPC_DIVU:
14432 check_insn(env, ctx, INSN_VR54XX);
14433 op1 = MASK_MUL_VR54XX(ctx->opcode);
14434 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14436 gen_muldiv(ctx, op1, rs, rt);
14438 case OPC_JR ... OPC_JALR:
14439 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14442 case OPC_TGE ... OPC_TEQ: /* Traps */
14444 gen_trap(ctx, op1, rs, rt, -1);
14446 case OPC_MFHI: /* Move from HI/LO */
14448 gen_HILO(ctx, op1, rd);
14451 case OPC_MTLO: /* Move to HI/LO */
14452 gen_HILO(ctx, op1, rs);
14454 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14455 #ifdef MIPS_STRICT_STANDARD
14456 MIPS_INVAL("PMON / selsl");
14457 generate_exception(ctx, EXCP_RI);
14459 gen_helper_0e0i(pmon, sa);
14463 generate_exception(ctx, EXCP_SYSCALL);
14464 ctx->bstate = BS_STOP;
14467 generate_exception(ctx, EXCP_BREAK);
14470 #ifdef MIPS_STRICT_STANDARD
14471 MIPS_INVAL("SPIM");
14472 generate_exception(ctx, EXCP_RI);
14474 /* Implemented as RI exception for now. */
14475 MIPS_INVAL("spim (unofficial)");
14476 generate_exception(ctx, EXCP_RI);
14480 /* Treat as NOP. */
14484 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14485 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14486 check_cp1_enabled(ctx);
14487 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14488 (ctx->opcode >> 16) & 1);
14490 generate_exception_err(ctx, EXCP_CpU, 1);
14494 #if defined(TARGET_MIPS64)
14495 /* MIPS64 specific opcodes */
14500 check_insn(env, ctx, ISA_MIPS3);
14501 check_mips_64(ctx);
14502 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14505 switch ((ctx->opcode >> 21) & 0x1f) {
14507 /* drotr is decoded as dsrl on non-R2 CPUs */
14508 if (env->insn_flags & ISA_MIPS32R2) {
14513 check_insn(env, ctx, ISA_MIPS3);
14514 check_mips_64(ctx);
14515 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14518 generate_exception(ctx, EXCP_RI);
14523 switch ((ctx->opcode >> 21) & 0x1f) {
14525 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14526 if (env->insn_flags & ISA_MIPS32R2) {
14531 check_insn(env, ctx, ISA_MIPS3);
14532 check_mips_64(ctx);
14533 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14536 generate_exception(ctx, EXCP_RI);
14540 case OPC_DADD ... OPC_DSUBU:
14541 check_insn(env, ctx, ISA_MIPS3);
14542 check_mips_64(ctx);
14543 gen_arith(env, ctx, op1, rd, rs, rt);
14547 check_insn(env, ctx, ISA_MIPS3);
14548 check_mips_64(ctx);
14549 gen_shift(env, ctx, op1, rd, rs, rt);
14552 switch ((ctx->opcode >> 6) & 0x1f) {
14554 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14555 if (env->insn_flags & ISA_MIPS32R2) {
14560 check_insn(env, ctx, ISA_MIPS3);
14561 check_mips_64(ctx);
14562 gen_shift(env, ctx, op1, rd, rs, rt);
14565 generate_exception(ctx, EXCP_RI);
14569 case OPC_DMULT ... OPC_DDIVU:
14570 check_insn(env, ctx, ISA_MIPS3);
14571 check_mips_64(ctx);
14572 gen_muldiv(ctx, op1, rs, rt);
14575 default: /* Invalid */
14576 MIPS_INVAL("special");
14577 generate_exception(ctx, EXCP_RI);
14582 op1 = MASK_SPECIAL2(ctx->opcode);
14584 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14585 case OPC_MSUB ... OPC_MSUBU:
14586 check_insn(env, ctx, ISA_MIPS32);
14587 gen_muldiv(ctx, op1, rs, rt);
14590 gen_arith(env, ctx, op1, rd, rs, rt);
14594 check_insn(env, ctx, ISA_MIPS32);
14595 gen_cl(ctx, op1, rd, rs);
14598 /* XXX: not clear which exception should be raised
14599 * when in debug mode...
14601 check_insn(env, ctx, ISA_MIPS32);
14602 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14603 generate_exception(ctx, EXCP_DBp);
14605 generate_exception(ctx, EXCP_DBp);
14607 /* Treat as NOP. */
14610 case OPC_DIVU_G_2F:
14611 case OPC_MULT_G_2F:
14612 case OPC_MULTU_G_2F:
14614 case OPC_MODU_G_2F:
14615 check_insn(env, ctx, INSN_LOONGSON2F);
14616 gen_loongson_integer(ctx, op1, rd, rs, rt);
14618 #if defined(TARGET_MIPS64)
14621 check_insn(env, ctx, ISA_MIPS64);
14622 check_mips_64(ctx);
14623 gen_cl(ctx, op1, rd, rs);
14625 case OPC_DMULT_G_2F:
14626 case OPC_DMULTU_G_2F:
14627 case OPC_DDIV_G_2F:
14628 case OPC_DDIVU_G_2F:
14629 case OPC_DMOD_G_2F:
14630 case OPC_DMODU_G_2F:
14631 check_insn(env, ctx, INSN_LOONGSON2F);
14632 gen_loongson_integer(ctx, op1, rd, rs, rt);
14635 default: /* Invalid */
14636 MIPS_INVAL("special2");
14637 generate_exception(ctx, EXCP_RI);
14642 op1 = MASK_SPECIAL3(ctx->opcode);
14646 check_insn(env, ctx, ISA_MIPS32R2);
14647 gen_bitops(ctx, op1, rt, rs, sa, rd);
14650 check_insn(env, ctx, ISA_MIPS32R2);
14651 op2 = MASK_BSHFL(ctx->opcode);
14652 gen_bshfl(ctx, op2, rt, rd);
14655 gen_rdhwr(env, ctx, rt, rd);
14658 check_insn(env, ctx, ASE_MT);
14660 TCGv t0 = tcg_temp_new();
14661 TCGv t1 = tcg_temp_new();
14663 gen_load_gpr(t0, rt);
14664 gen_load_gpr(t1, rs);
14665 gen_helper_fork(t0, t1);
14671 check_insn(env, ctx, ASE_MT);
14673 TCGv t0 = tcg_temp_new();
14675 save_cpu_state(ctx, 1);
14676 gen_load_gpr(t0, rs);
14677 gen_helper_yield(t0, cpu_env, t0);
14678 gen_store_gpr(t0, rd);
14682 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14683 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14684 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14685 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14686 * the same mask and op1. */
14687 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14688 op2 = MASK_ADDUH_QB(ctx->opcode);
14691 case OPC_ADDUH_R_QB:
14693 case OPC_ADDQH_R_PH:
14695 case OPC_ADDQH_R_W:
14697 case OPC_SUBUH_R_QB:
14699 case OPC_SUBQH_R_PH:
14701 case OPC_SUBQH_R_W:
14702 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14707 case OPC_MULQ_RS_W:
14708 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14711 MIPS_INVAL("MASK ADDUH.QB");
14712 generate_exception(ctx, EXCP_RI);
14715 } else if (env->insn_flags & INSN_LOONGSON2E) {
14716 gen_loongson_integer(ctx, op1, rd, rs, rt);
14718 generate_exception(ctx, EXCP_RI);
14722 op2 = MASK_LX(ctx->opcode);
14724 #if defined(TARGET_MIPS64)
14730 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14732 default: /* Invalid */
14733 MIPS_INVAL("MASK LX");
14734 generate_exception(ctx, EXCP_RI);
14738 case OPC_ABSQ_S_PH_DSP:
14739 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14741 case OPC_ABSQ_S_QB:
14742 case OPC_ABSQ_S_PH:
14744 case OPC_PRECEQ_W_PHL:
14745 case OPC_PRECEQ_W_PHR:
14746 case OPC_PRECEQU_PH_QBL:
14747 case OPC_PRECEQU_PH_QBR:
14748 case OPC_PRECEQU_PH_QBLA:
14749 case OPC_PRECEQU_PH_QBRA:
14750 case OPC_PRECEU_PH_QBL:
14751 case OPC_PRECEU_PH_QBR:
14752 case OPC_PRECEU_PH_QBLA:
14753 case OPC_PRECEU_PH_QBRA:
14754 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14761 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14764 MIPS_INVAL("MASK ABSQ_S.PH");
14765 generate_exception(ctx, EXCP_RI);
14769 case OPC_ADDU_QB_DSP:
14770 op2 = MASK_ADDU_QB(ctx->opcode);
14773 case OPC_ADDQ_S_PH:
14776 case OPC_ADDU_S_QB:
14778 case OPC_ADDU_S_PH:
14780 case OPC_SUBQ_S_PH:
14783 case OPC_SUBU_S_QB:
14785 case OPC_SUBU_S_PH:
14789 case OPC_RADDU_W_QB:
14790 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14792 case OPC_MULEU_S_PH_QBL:
14793 case OPC_MULEU_S_PH_QBR:
14794 case OPC_MULQ_RS_PH:
14795 case OPC_MULEQ_S_W_PHL:
14796 case OPC_MULEQ_S_W_PHR:
14797 case OPC_MULQ_S_PH:
14798 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14800 default: /* Invalid */
14801 MIPS_INVAL("MASK ADDU.QB");
14802 generate_exception(ctx, EXCP_RI);
14807 case OPC_CMPU_EQ_QB_DSP:
14808 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14810 case OPC_PRECR_SRA_PH_W:
14811 case OPC_PRECR_SRA_R_PH_W:
14812 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14814 case OPC_PRECR_QB_PH:
14815 case OPC_PRECRQ_QB_PH:
14816 case OPC_PRECRQ_PH_W:
14817 case OPC_PRECRQ_RS_PH_W:
14818 case OPC_PRECRQU_S_QB_PH:
14819 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14821 case OPC_CMPU_EQ_QB:
14822 case OPC_CMPU_LT_QB:
14823 case OPC_CMPU_LE_QB:
14824 case OPC_CMP_EQ_PH:
14825 case OPC_CMP_LT_PH:
14826 case OPC_CMP_LE_PH:
14827 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14829 case OPC_CMPGU_EQ_QB:
14830 case OPC_CMPGU_LT_QB:
14831 case OPC_CMPGU_LE_QB:
14832 case OPC_CMPGDU_EQ_QB:
14833 case OPC_CMPGDU_LT_QB:
14834 case OPC_CMPGDU_LE_QB:
14837 case OPC_PACKRL_PH:
14838 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14840 default: /* Invalid */
14841 MIPS_INVAL("MASK CMPU.EQ.QB");
14842 generate_exception(ctx, EXCP_RI);
14846 case OPC_SHLL_QB_DSP:
14847 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14849 case OPC_DPA_W_PH_DSP:
14850 op2 = MASK_DPA_W_PH(ctx->opcode);
14852 case OPC_DPAU_H_QBL:
14853 case OPC_DPAU_H_QBR:
14854 case OPC_DPSU_H_QBL:
14855 case OPC_DPSU_H_QBR:
14857 case OPC_DPAX_W_PH:
14858 case OPC_DPAQ_S_W_PH:
14859 case OPC_DPAQX_S_W_PH:
14860 case OPC_DPAQX_SA_W_PH:
14862 case OPC_DPSX_W_PH:
14863 case OPC_DPSQ_S_W_PH:
14864 case OPC_DPSQX_S_W_PH:
14865 case OPC_DPSQX_SA_W_PH:
14866 case OPC_MULSAQ_S_W_PH:
14867 case OPC_DPAQ_SA_L_W:
14868 case OPC_DPSQ_SA_L_W:
14869 case OPC_MAQ_S_W_PHL:
14870 case OPC_MAQ_S_W_PHR:
14871 case OPC_MAQ_SA_W_PHL:
14872 case OPC_MAQ_SA_W_PHR:
14873 case OPC_MULSA_W_PH:
14874 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14876 default: /* Invalid */
14877 MIPS_INVAL("MASK DPAW.PH");
14878 generate_exception(ctx, EXCP_RI);
14883 op2 = MASK_INSV(ctx->opcode);
14895 t0 = tcg_temp_new();
14896 t1 = tcg_temp_new();
14898 gen_load_gpr(t0, rt);
14899 gen_load_gpr(t1, rs);
14901 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14907 default: /* Invalid */
14908 MIPS_INVAL("MASK INSV");
14909 generate_exception(ctx, EXCP_RI);
14913 case OPC_APPEND_DSP:
14915 op2 = MASK_APPEND(ctx->opcode);
14916 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14918 case OPC_EXTR_W_DSP:
14919 op2 = MASK_EXTR_W(ctx->opcode);
14923 case OPC_EXTR_RS_W:
14925 case OPC_EXTRV_S_H:
14927 case OPC_EXTRV_R_W:
14928 case OPC_EXTRV_RS_W:
14933 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14936 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14942 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14944 default: /* Invalid */
14945 MIPS_INVAL("MASK EXTR.W");
14946 generate_exception(ctx, EXCP_RI);
14950 #if defined(TARGET_MIPS64)
14951 case OPC_DEXTM ... OPC_DEXT:
14952 case OPC_DINSM ... OPC_DINS:
14953 check_insn(env, ctx, ISA_MIPS64R2);
14954 check_mips_64(ctx);
14955 gen_bitops(ctx, op1, rt, rs, sa, rd);
14958 check_insn(env, ctx, ISA_MIPS64R2);
14959 check_mips_64(ctx);
14960 op2 = MASK_DBSHFL(ctx->opcode);
14961 gen_bshfl(ctx, op2, rt, rd);
14963 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14964 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14965 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14966 check_insn(env, ctx, INSN_LOONGSON2E);
14967 gen_loongson_integer(ctx, op1, rd, rs, rt);
14969 case OPC_ABSQ_S_QH_DSP:
14970 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14972 case OPC_PRECEQ_L_PWL:
14973 case OPC_PRECEQ_L_PWR:
14974 case OPC_PRECEQ_PW_QHL:
14975 case OPC_PRECEQ_PW_QHR:
14976 case OPC_PRECEQ_PW_QHLA:
14977 case OPC_PRECEQ_PW_QHRA:
14978 case OPC_PRECEQU_QH_OBL:
14979 case OPC_PRECEQU_QH_OBR:
14980 case OPC_PRECEQU_QH_OBLA:
14981 case OPC_PRECEQU_QH_OBRA:
14982 case OPC_PRECEU_QH_OBL:
14983 case OPC_PRECEU_QH_OBR:
14984 case OPC_PRECEU_QH_OBLA:
14985 case OPC_PRECEU_QH_OBRA:
14986 case OPC_ABSQ_S_OB:
14987 case OPC_ABSQ_S_PW:
14988 case OPC_ABSQ_S_QH:
14989 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14997 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14999 default: /* Invalid */
15000 MIPS_INVAL("MASK ABSQ_S.QH");
15001 generate_exception(ctx, EXCP_RI);
15005 case OPC_ADDU_OB_DSP:
15006 op2 = MASK_ADDU_OB(ctx->opcode);
15008 case OPC_RADDU_L_OB:
15010 case OPC_SUBQ_S_PW:
15012 case OPC_SUBQ_S_QH:
15014 case OPC_SUBU_S_OB:
15016 case OPC_SUBU_S_QH:
15018 case OPC_SUBUH_R_OB:
15020 case OPC_ADDQ_S_PW:
15022 case OPC_ADDQ_S_QH:
15024 case OPC_ADDU_S_OB:
15026 case OPC_ADDU_S_QH:
15028 case OPC_ADDUH_R_OB:
15029 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15031 case OPC_MULEQ_S_PW_QHL:
15032 case OPC_MULEQ_S_PW_QHR:
15033 case OPC_MULEU_S_QH_OBL:
15034 case OPC_MULEU_S_QH_OBR:
15035 case OPC_MULQ_RS_QH:
15036 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15038 default: /* Invalid */
15039 MIPS_INVAL("MASK ADDU.OB");
15040 generate_exception(ctx, EXCP_RI);
15044 case OPC_CMPU_EQ_OB_DSP:
15045 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15047 case OPC_PRECR_SRA_QH_PW:
15048 case OPC_PRECR_SRA_R_QH_PW:
15049 /* Return value is rt. */
15050 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15052 case OPC_PRECR_OB_QH:
15053 case OPC_PRECRQ_OB_QH:
15054 case OPC_PRECRQ_PW_L:
15055 case OPC_PRECRQ_QH_PW:
15056 case OPC_PRECRQ_RS_QH_PW:
15057 case OPC_PRECRQU_S_OB_QH:
15058 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15060 case OPC_CMPU_EQ_OB:
15061 case OPC_CMPU_LT_OB:
15062 case OPC_CMPU_LE_OB:
15063 case OPC_CMP_EQ_QH:
15064 case OPC_CMP_LT_QH:
15065 case OPC_CMP_LE_QH:
15066 case OPC_CMP_EQ_PW:
15067 case OPC_CMP_LT_PW:
15068 case OPC_CMP_LE_PW:
15069 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15071 case OPC_CMPGDU_EQ_OB:
15072 case OPC_CMPGDU_LT_OB:
15073 case OPC_CMPGDU_LE_OB:
15074 case OPC_CMPGU_EQ_OB:
15075 case OPC_CMPGU_LT_OB:
15076 case OPC_CMPGU_LE_OB:
15077 case OPC_PACKRL_PW:
15081 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15083 default: /* Invalid */
15084 MIPS_INVAL("MASK CMPU_EQ.OB");
15085 generate_exception(ctx, EXCP_RI);
15089 case OPC_DAPPEND_DSP:
15091 op2 = MASK_DAPPEND(ctx->opcode);
15092 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15094 case OPC_DEXTR_W_DSP:
15095 op2 = MASK_DEXTR_W(ctx->opcode);
15102 case OPC_DEXTR_R_L:
15103 case OPC_DEXTR_RS_L:
15105 case OPC_DEXTR_R_W:
15106 case OPC_DEXTR_RS_W:
15107 case OPC_DEXTR_S_H:
15109 case OPC_DEXTRV_R_L:
15110 case OPC_DEXTRV_RS_L:
15111 case OPC_DEXTRV_S_H:
15113 case OPC_DEXTRV_R_W:
15114 case OPC_DEXTRV_RS_W:
15115 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15120 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15122 default: /* Invalid */
15123 MIPS_INVAL("MASK EXTR.W");
15124 generate_exception(ctx, EXCP_RI);
15128 case OPC_DPAQ_W_QH_DSP:
15129 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15131 case OPC_DPAU_H_OBL:
15132 case OPC_DPAU_H_OBR:
15133 case OPC_DPSU_H_OBL:
15134 case OPC_DPSU_H_OBR:
15136 case OPC_DPAQ_S_W_QH:
15138 case OPC_DPSQ_S_W_QH:
15139 case OPC_MULSAQ_S_W_QH:
15140 case OPC_DPAQ_SA_L_PW:
15141 case OPC_DPSQ_SA_L_PW:
15142 case OPC_MULSAQ_S_L_PW:
15143 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15145 case OPC_MAQ_S_W_QHLL:
15146 case OPC_MAQ_S_W_QHLR:
15147 case OPC_MAQ_S_W_QHRL:
15148 case OPC_MAQ_S_W_QHRR:
15149 case OPC_MAQ_SA_W_QHLL:
15150 case OPC_MAQ_SA_W_QHLR:
15151 case OPC_MAQ_SA_W_QHRL:
15152 case OPC_MAQ_SA_W_QHRR:
15153 case OPC_MAQ_S_L_PWL:
15154 case OPC_MAQ_S_L_PWR:
15159 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15161 default: /* Invalid */
15162 MIPS_INVAL("MASK DPAQ.W.QH");
15163 generate_exception(ctx, EXCP_RI);
15167 case OPC_DINSV_DSP:
15168 op2 = MASK_INSV(ctx->opcode);
15180 t0 = tcg_temp_new();
15181 t1 = tcg_temp_new();
15183 gen_load_gpr(t0, rt);
15184 gen_load_gpr(t1, rs);
15186 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15189 default: /* Invalid */
15190 MIPS_INVAL("MASK DINSV");
15191 generate_exception(ctx, EXCP_RI);
15195 case OPC_SHLL_OB_DSP:
15196 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15199 default: /* Invalid */
15200 MIPS_INVAL("special3");
15201 generate_exception(ctx, EXCP_RI);
15206 op1 = MASK_REGIMM(ctx->opcode);
15208 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15209 case OPC_BLTZAL ... OPC_BGEZALL:
15210 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15213 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15215 gen_trap(ctx, op1, rs, -1, imm);
15218 check_insn(env, ctx, ISA_MIPS32R2);
15219 /* Treat as NOP. */
15221 case OPC_BPOSGE32: /* MIPS DSP branch */
15222 #if defined(TARGET_MIPS64)
15226 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15229 default: /* Invalid */
15230 MIPS_INVAL("regimm");
15231 generate_exception(ctx, EXCP_RI);
15236 check_cp0_enabled(ctx);
15237 op1 = MASK_CP0(ctx->opcode);
15243 #if defined(TARGET_MIPS64)
15247 #ifndef CONFIG_USER_ONLY
15248 gen_cp0(env, ctx, op1, rt, rd);
15249 #endif /* !CONFIG_USER_ONLY */
15251 case OPC_C0_FIRST ... OPC_C0_LAST:
15252 #ifndef CONFIG_USER_ONLY
15253 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15254 #endif /* !CONFIG_USER_ONLY */
15257 #ifndef CONFIG_USER_ONLY
15259 TCGv t0 = tcg_temp_new();
15261 op2 = MASK_MFMC0(ctx->opcode);
15264 check_insn(env, ctx, ASE_MT);
15265 gen_helper_dmt(t0);
15266 gen_store_gpr(t0, rt);
15269 check_insn(env, ctx, ASE_MT);
15270 gen_helper_emt(t0);
15271 gen_store_gpr(t0, rt);
15274 check_insn(env, ctx, ASE_MT);
15275 gen_helper_dvpe(t0, cpu_env);
15276 gen_store_gpr(t0, rt);
15279 check_insn(env, ctx, ASE_MT);
15280 gen_helper_evpe(t0, cpu_env);
15281 gen_store_gpr(t0, rt);
15284 check_insn(env, ctx, ISA_MIPS32R2);
15285 save_cpu_state(ctx, 1);
15286 gen_helper_di(t0, cpu_env);
15287 gen_store_gpr(t0, rt);
15288 /* Stop translation as we may have switched the execution mode */
15289 ctx->bstate = BS_STOP;
15292 check_insn(env, ctx, ISA_MIPS32R2);
15293 save_cpu_state(ctx, 1);
15294 gen_helper_ei(t0, cpu_env);
15295 gen_store_gpr(t0, rt);
15296 /* Stop translation as we may have switched the execution mode */
15297 ctx->bstate = BS_STOP;
15299 default: /* Invalid */
15300 MIPS_INVAL("mfmc0");
15301 generate_exception(ctx, EXCP_RI);
15306 #endif /* !CONFIG_USER_ONLY */
15309 check_insn(env, ctx, ISA_MIPS32R2);
15310 gen_load_srsgpr(rt, rd);
15313 check_insn(env, ctx, ISA_MIPS32R2);
15314 gen_store_srsgpr(rt, rd);
15318 generate_exception(ctx, EXCP_RI);
15322 case OPC_ADDI: /* Arithmetic with immediate opcode */
15324 gen_arith_imm(env, ctx, op, rt, rs, imm);
15326 case OPC_SLTI: /* Set on less than with immediate opcode */
15328 gen_slt_imm(env, ctx, op, rt, rs, imm);
15330 case OPC_ANDI: /* Arithmetic with immediate opcode */
15334 gen_logic_imm(env, ctx, op, rt, rs, imm);
15336 case OPC_J ... OPC_JAL: /* Jump */
15337 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15338 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15341 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15342 case OPC_BEQL ... OPC_BGTZL:
15343 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15346 case OPC_LB ... OPC_LWR: /* Load and stores */
15348 gen_ld(env, ctx, op, rt, rs, imm);
15350 case OPC_SB ... OPC_SW:
15352 gen_st(ctx, op, rt, rs, imm);
15355 gen_st_cond(ctx, op, rt, rs, imm);
15358 check_cp0_enabled(ctx);
15359 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15360 /* Treat as NOP. */
15363 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15364 /* Treat as NOP. */
15367 /* Floating point (COP1). */
15372 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15376 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15377 check_cp1_enabled(ctx);
15378 op1 = MASK_CP1(ctx->opcode);
15382 check_insn(env, ctx, ISA_MIPS32R2);
15387 gen_cp1(ctx, op1, rt, rd);
15389 #if defined(TARGET_MIPS64)
15392 check_insn(env, ctx, ISA_MIPS3);
15393 gen_cp1(ctx, op1, rt, rd);
15399 check_insn(env, ctx, ASE_MIPS3D);
15402 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15403 (rt >> 2) & 0x7, imm << 2);
15411 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15416 generate_exception (ctx, EXCP_RI);
15420 generate_exception_err(ctx, EXCP_CpU, 1);
15429 /* COP2: Not implemented. */
15430 generate_exception_err(ctx, EXCP_CpU, 2);
15433 check_insn(env, ctx, INSN_LOONGSON2F);
15434 /* Note that these instructions use different fields. */
15435 gen_loongson_multimedia(ctx, sa, rd, rt);
15439 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15440 check_cp1_enabled(ctx);
15441 op1 = MASK_CP3(ctx->opcode);
15449 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15452 /* Treat as NOP. */
15467 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15471 generate_exception (ctx, EXCP_RI);
15475 generate_exception_err(ctx, EXCP_CpU, 1);
15479 #if defined(TARGET_MIPS64)
15480 /* MIPS64 opcodes */
15482 case OPC_LDL ... OPC_LDR:
15485 check_insn(env, ctx, ISA_MIPS3);
15486 check_mips_64(ctx);
15487 gen_ld(env, ctx, op, rt, rs, imm);
15489 case OPC_SDL ... OPC_SDR:
15491 check_insn(env, ctx, ISA_MIPS3);
15492 check_mips_64(ctx);
15493 gen_st(ctx, op, rt, rs, imm);
15496 check_insn(env, ctx, ISA_MIPS3);
15497 check_mips_64(ctx);
15498 gen_st_cond(ctx, op, rt, rs, imm);
15502 check_insn(env, ctx, ISA_MIPS3);
15503 check_mips_64(ctx);
15504 gen_arith_imm(env, ctx, op, rt, rs, imm);
15508 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15509 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15510 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15514 check_insn(env, ctx, ASE_MDMX);
15515 /* MDMX: Not implemented. */
15516 default: /* Invalid */
15517 MIPS_INVAL("major opcode");
15518 generate_exception(ctx, EXCP_RI);
15524 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15528 target_ulong pc_start;
15529 uint16_t *gen_opc_end;
15538 qemu_log("search pc %d\n", search_pc);
15541 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15544 ctx.singlestep_enabled = env->singlestep_enabled;
15546 ctx.bstate = BS_NONE;
15547 /* Restore delay slot state from the tb context. */
15548 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15549 restore_cpu_state(env, &ctx);
15550 #ifdef CONFIG_USER_ONLY
15551 ctx.mem_idx = MIPS_HFLAG_UM;
15553 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15556 max_insns = tb->cflags & CF_COUNT_MASK;
15557 if (max_insns == 0)
15558 max_insns = CF_COUNT_MASK;
15559 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15560 gen_icount_start();
15561 while (ctx.bstate == BS_NONE) {
15562 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15563 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15564 if (bp->pc == ctx.pc) {
15565 save_cpu_state(&ctx, 1);
15566 ctx.bstate = BS_BRANCH;
15567 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15568 /* Include the breakpoint location or the tb won't
15569 * be flushed when it must be. */
15571 goto done_generating;
15577 j = gen_opc_ptr - gen_opc_buf;
15581 gen_opc_instr_start[lj++] = 0;
15583 gen_opc_pc[lj] = ctx.pc;
15584 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15585 gen_opc_btarget[lj] = ctx.btarget;
15586 gen_opc_instr_start[lj] = 1;
15587 gen_opc_icount[lj] = num_insns;
15589 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15593 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15594 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15596 decode_opc(env, &ctx, &is_branch);
15597 } else if (env->insn_flags & ASE_MICROMIPS) {
15598 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15599 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15600 } else if (env->insn_flags & ASE_MIPS16) {
15601 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15602 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15604 generate_exception(&ctx, EXCP_RI);
15605 ctx.bstate = BS_STOP;
15609 handle_delay_slot(env, &ctx, insn_bytes);
15611 ctx.pc += insn_bytes;
15615 /* Execute a branch and its delay slot as a single instruction.
15616 This is what GDB expects and is consistent with what the
15617 hardware does (e.g. if a delay slot instruction faults, the
15618 reported PC is the PC of the branch). */
15619 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15622 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15625 if (gen_opc_ptr >= gen_opc_end)
15628 if (num_insns >= max_insns)
15634 if (tb->cflags & CF_LAST_IO)
15636 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15637 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15638 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15640 switch (ctx.bstate) {
15642 gen_goto_tb(&ctx, 0, ctx.pc);
15645 save_cpu_state(&ctx, 0);
15646 gen_goto_tb(&ctx, 0, ctx.pc);
15649 tcg_gen_exit_tb(0);
15657 gen_icount_end(tb, num_insns);
15658 *gen_opc_ptr = INDEX_op_end;
15660 j = gen_opc_ptr - gen_opc_buf;
15663 gen_opc_instr_start[lj++] = 0;
15665 tb->size = ctx.pc - pc_start;
15666 tb->icount = num_insns;
15670 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15671 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15672 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15678 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15680 gen_intermediate_code_internal(env, tb, 0);
15683 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15685 gen_intermediate_code_internal(env, tb, 1);
15688 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15692 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15694 #define printfpr(fp) \
15697 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15698 " fd:%13g fs:%13g psu: %13g\n", \
15699 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15700 (double)(fp)->fd, \
15701 (double)(fp)->fs[FP_ENDIAN_IDX], \
15702 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15705 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15706 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15707 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15708 " fd:%13g fs:%13g psu:%13g\n", \
15709 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15711 (double)tmp.fs[FP_ENDIAN_IDX], \
15712 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15717 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15718 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15719 get_float_exception_flags(&env->active_fpu.fp_status));
15720 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15721 fpu_fprintf(f, "%3s: ", fregnames[i]);
15722 printfpr(&env->active_fpu.fpr[i]);
15728 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15729 /* Debug help: The architecture requires 32bit code to maintain proper
15730 sign-extended values on 64bit machines. */
15732 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15735 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15736 fprintf_function cpu_fprintf,
15741 if (!SIGN_EXT_P(env->active_tc.PC))
15742 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15743 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15744 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15745 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15746 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15747 if (!SIGN_EXT_P(env->btarget))
15748 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15750 for (i = 0; i < 32; i++) {
15751 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15752 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15755 if (!SIGN_EXT_P(env->CP0_EPC))
15756 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15757 if (!SIGN_EXT_P(env->lladdr))
15758 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15762 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15767 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15768 " LO=0x" TARGET_FMT_lx " ds %04x "
15769 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15770 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15771 env->hflags, env->btarget, env->bcond);
15772 for (i = 0; i < 32; i++) {
15774 cpu_fprintf(f, "GPR%02d:", i);
15775 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15777 cpu_fprintf(f, "\n");
15780 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15781 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15782 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15783 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15784 if (env->hflags & MIPS_HFLAG_FPU)
15785 fpu_dump_state(env, f, cpu_fprintf, flags);
15786 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15787 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15791 static void mips_tcg_init(void)
15796 /* Initialize various static tables. */
15800 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15801 TCGV_UNUSED(cpu_gpr[0]);
15802 for (i = 1; i < 32; i++)
15803 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15804 offsetof(CPUMIPSState, active_tc.gpr[i]),
15807 for (i = 0; i < 32; i++) {
15808 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15809 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15812 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15813 offsetof(CPUMIPSState, active_tc.PC), "PC");
15814 for (i = 0; i < MIPS_DSP_ACC; i++) {
15815 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15816 offsetof(CPUMIPSState, active_tc.HI[i]),
15818 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15819 offsetof(CPUMIPSState, active_tc.LO[i]),
15821 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15822 offsetof(CPUMIPSState, active_tc.ACX[i]),
15825 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15826 offsetof(CPUMIPSState, active_tc.DSPControl),
15828 bcond = tcg_global_mem_new(TCG_AREG0,
15829 offsetof(CPUMIPSState, bcond), "bcond");
15830 btarget = tcg_global_mem_new(TCG_AREG0,
15831 offsetof(CPUMIPSState, btarget), "btarget");
15832 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15833 offsetof(CPUMIPSState, hflags), "hflags");
15835 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15836 offsetof(CPUMIPSState, active_fpu.fcr0),
15838 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15839 offsetof(CPUMIPSState, active_fpu.fcr31),
15842 /* register helpers */
15843 #define GEN_HELPER 2
15844 #include "helper.h"
15849 #include "translate_init.c"
15851 MIPSCPU *cpu_mips_init(const char *cpu_model)
15855 const mips_def_t *def;
15857 def = cpu_mips_find_by_name(cpu_model);
15860 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15862 env->cpu_model = def;
15863 env->cpu_model_str = cpu_model;
15865 #ifndef CONFIG_USER_ONLY
15866 mmu_init(env, def);
15868 fpu_init(env, def);
15869 mvp_init(env, def);
15871 cpu_reset(CPU(cpu));
15872 qemu_init_vcpu(env);
15876 void cpu_state_reset(CPUMIPSState *env)
15878 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15879 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15880 log_cpu_state(env, 0);
15883 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15886 /* Reset registers to their default values */
15887 env->CP0_PRid = env->cpu_model->CP0_PRid;
15888 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15889 #ifdef TARGET_WORDS_BIGENDIAN
15890 env->CP0_Config0 |= (1 << CP0C0_BE);
15892 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15893 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15894 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15895 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15896 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15897 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15898 << env->cpu_model->CP0_LLAddr_shift;
15899 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15900 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15901 env->CCRes = env->cpu_model->CCRes;
15902 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15903 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15904 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15905 env->current_tc = 0;
15906 env->SEGBITS = env->cpu_model->SEGBITS;
15907 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15908 #if defined(TARGET_MIPS64)
15909 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15910 env->SEGMask |= 3ULL << 62;
15913 env->PABITS = env->cpu_model->PABITS;
15914 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15915 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15916 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15917 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15918 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15919 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15920 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15921 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15922 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15923 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15924 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15925 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15926 env->insn_flags = env->cpu_model->insn_flags;
15928 #if defined(CONFIG_USER_ONLY)
15929 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15930 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15931 hardware registers. */
15932 env->CP0_HWREna |= 0x0000000F;
15933 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15934 env->CP0_Status |= (1 << CP0St_CU1);
15936 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15937 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15938 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15939 env->hflags |= MIPS_HFLAG_DSP;
15942 if (env->hflags & MIPS_HFLAG_BMASK) {
15943 /* If the exception was raised from a delay slot,
15944 come back to the jump. */
15945 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15947 env->CP0_ErrorEPC = env->active_tc.PC;
15949 env->active_tc.PC = (int32_t)0xBFC00000;
15950 env->CP0_Random = env->tlb->nb_tlb - 1;
15951 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15952 env->CP0_Wired = 0;
15953 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15954 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15955 /* vectored interrupts not implemented, timer on int 7,
15956 no performance counters. */
15957 env->CP0_IntCtl = 0xe0000000;
15961 for (i = 0; i < 7; i++) {
15962 env->CP0_WatchLo[i] = 0;
15963 env->CP0_WatchHi[i] = 0x80000000;
15965 env->CP0_WatchLo[7] = 0;
15966 env->CP0_WatchHi[7] = 0;
15968 /* Count register increments in debug mode, EJTAG version 1 */
15969 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15971 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15974 /* Only TC0 on VPE 0 starts as active. */
15975 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15976 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15977 env->tcs[i].CP0_TCHalt = 1;
15979 env->active_tc.CP0_TCHalt = 1;
15982 if (!env->cpu_index) {
15983 /* VPE0 starts up enabled. */
15984 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15985 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15987 /* TC0 starts up unhalted. */
15989 env->active_tc.CP0_TCHalt = 0;
15990 env->tcs[0].CP0_TCHalt = 0;
15991 /* With thread 0 active. */
15992 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15993 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15997 compute_hflags(env);
15998 env->exception_index = EXCP_NONE;
16001 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16003 env->active_tc.PC = gen_opc_pc[pc_pos];
16004 env->hflags &= ~MIPS_HFLAG_BMASK;
16005 env->hflags |= gen_opc_hflags[pc_pos];
16006 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16007 case MIPS_HFLAG_BR:
16009 case MIPS_HFLAG_BC:
16010 case MIPS_HFLAG_BL:
16012 env->btarget = gen_opc_btarget[pc_pos];