2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Compare-Pick Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Compare-Pick Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Compare-Pick Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1020 #include "gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1068 int singlestep_enabled;
1069 /* Routine used to access memory */
1071 uint32_t hflags, saved_hflags;
1073 target_ulong btarget;
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1078 * exception condition */
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1084 static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1091 static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1095 static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1099 static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1103 static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1110 #define MIPS_DEBUG(fmt, ...) \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1119 #define LOG_DISAS(...) \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1126 #define MIPS_INVAL(op) \
1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1130 /* General purpose registers moves. */
1131 static inline void gen_load_gpr (TCGv t, int reg)
1134 tcg_gen_movi_tl(t, 0);
1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1139 static inline void gen_store_gpr (TCGv t, int reg)
1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
1145 /* Moves to/from ACX register. */
1146 static inline void gen_load_ACX (TCGv t, int reg)
1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1151 static inline void gen_store_ACX (TCGv t, int reg)
1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
1156 /* Moves to/from shadow registers. */
1157 static inline void gen_load_srsgpr (int from, int to)
1159 TCGv t0 = tcg_temp_new();
1162 tcg_gen_movi_tl(t0, 0);
1164 TCGv_i32 t2 = tcg_temp_new_i32();
1165 TCGv_ptr addr = tcg_temp_new_ptr();
1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
1172 tcg_gen_add_ptr(addr, cpu_env, addr);
1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1175 tcg_temp_free_ptr(addr);
1176 tcg_temp_free_i32(t2);
1178 gen_store_gpr(t0, to);
1182 static inline void gen_store_srsgpr (int from, int to)
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
1187 TCGv_ptr addr = tcg_temp_new_ptr();
1189 gen_load_gpr(t0, from);
1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
1195 tcg_gen_add_ptr(addr, cpu_env, addr);
1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1198 tcg_temp_free_ptr(addr);
1199 tcg_temp_free_i32(t2);
1204 /* Floating point register moves. */
1205 static void gen_load_fpr32(TCGv_i32 t, int reg)
1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1210 static void gen_store_fpr32(TCGv_i32 t, int reg)
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
1218 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
1226 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
1234 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1236 if (ctx->hflags & MIPS_HFLAG_F64) {
1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1243 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1245 if (ctx->hflags & MIPS_HFLAG_F64) {
1246 tcg_gen_mov_i64(fpu_f64[reg], t);
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
1251 tcg_gen_shri_i64(t0, t, 32);
1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1253 tcg_temp_free_i64(t0);
1257 static inline int get_fp_bit (int cc)
1266 static inline void gen_save_pc(target_ulong pc)
1268 tcg_gen_movi_tl(cpu_PC, pc);
1271 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1275 gen_save_pc(ctx->pc);
1276 ctx->saved_pc = ctx->pc;
1278 if (ctx->hflags != ctx->saved_hflags) {
1279 tcg_gen_movi_i32(hflags, ctx->hflags);
1280 ctx->saved_hflags = ctx->hflags;
1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1287 tcg_gen_movi_tl(btarget, ctx->btarget);
1293 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1295 ctx->saved_hflags = ctx->hflags;
1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1302 ctx->btarget = env->btarget;
1308 generate_exception_err (DisasContext *ctx, int excp, int err)
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
1312 save_cpu_state(ctx, 1);
1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
1319 generate_exception (DisasContext *ctx, int excp)
1321 save_cpu_state(ctx, 1);
1322 gen_helper_0e0i(raise_exception, excp);
1325 /* Addresses computation */
1326 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1328 tcg_gen_add_tl(ret, arg0, arg1);
1330 #if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
1336 tcg_gen_ext32s_i64(ret, ret);
1341 static inline void check_cp0_enabled(DisasContext *ctx)
1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1344 generate_exception_err(ctx, EXCP_CpU, 0);
1347 static inline void check_cp1_enabled(DisasContext *ctx)
1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1353 /* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1357 static inline void check_cop1x(DisasContext *ctx)
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1363 /* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1366 static inline void check_cp1_64bitmode(DisasContext *ctx)
1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1369 generate_exception(ctx, EXCP_RI);
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1386 generate_exception(ctx, EXCP_RI);
1389 /* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1393 static inline void check_dsp(DisasContext *ctx)
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1400 static inline void check_dspr2(DisasContext *ctx)
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1407 /* This code generates a "reserved instruction" exception if the
1408 CPU does not support the instruction set corresponding to flags. */
1409 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1411 if (unlikely(!(env->insn_flags & flags)))
1412 generate_exception(ctx, EXCP_RI);
1415 /* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
1417 static inline void check_mips_64(DisasContext *ctx)
1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1420 generate_exception(ctx, EXCP_RI);
1423 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1427 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1437 check_cp1_64bitmode(ctx); \
1443 check_cp1_registers(ctx, fs | ft); \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1476 FOP_CONDS(, 0, d, FMT_D, 64)
1477 FOP_CONDS(abs, 1, d, FMT_D, 64)
1478 FOP_CONDS(, 0, s, FMT_S, 32)
1479 FOP_CONDS(abs, 1, s, FMT_S, 32)
1480 FOP_CONDS(, 0, ps, FMT_PS, 64)
1481 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1483 #undef gen_ldcmp_fpr32
1484 #undef gen_ldcmp_fpr64
1486 /* load/store instructions. */
1487 #ifdef CONFIG_USER_ONLY
1488 #define OP_LD_ATOMIC(insn,fname) \
1489 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1491 TCGv t0 = tcg_temp_new(); \
1492 tcg_gen_mov_tl(t0, arg1); \
1493 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1494 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1495 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1496 tcg_temp_free(t0); \
1499 #define OP_LD_ATOMIC(insn,fname) \
1500 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1502 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1505 OP_LD_ATOMIC(ll,ld32s);
1506 #if defined(TARGET_MIPS64)
1507 OP_LD_ATOMIC(lld,ld64);
1511 #ifdef CONFIG_USER_ONLY
1512 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1513 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1515 TCGv t0 = tcg_temp_new(); \
1516 int l1 = gen_new_label(); \
1517 int l2 = gen_new_label(); \
1519 tcg_gen_andi_tl(t0, arg2, almask); \
1520 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1521 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1522 generate_exception(ctx, EXCP_AdES); \
1523 gen_set_label(l1); \
1524 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1525 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1526 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1527 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1528 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1529 gen_helper_0e0i(raise_exception, EXCP_SC); \
1530 gen_set_label(l2); \
1531 tcg_gen_movi_tl(t0, 0); \
1532 gen_store_gpr(t0, rt); \
1533 tcg_temp_free(t0); \
1536 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1537 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1539 TCGv t0 = tcg_temp_new(); \
1540 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1541 gen_store_gpr(t0, rt); \
1542 tcg_temp_free(t0); \
1545 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1546 #if defined(TARGET_MIPS64)
1547 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1551 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1552 int base, int16_t offset)
1555 tcg_gen_movi_tl(addr, offset);
1556 } else if (offset == 0) {
1557 gen_load_gpr(addr, base);
1559 tcg_gen_movi_tl(addr, offset);
1560 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1564 static target_ulong pc_relative_pc (DisasContext *ctx)
1566 target_ulong pc = ctx->pc;
1568 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1569 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1574 pc &= ~(target_ulong)3;
1579 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1580 int rt, int base, int16_t offset)
1582 const char *opn = "ld";
1585 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1586 /* Loongson CPU uses a load to zero register for prefetch.
1587 We emulate it as a NOP. On other CPU we must perform the
1588 actual memory access. */
1593 t0 = tcg_temp_new();
1594 t1 = tcg_temp_new();
1595 gen_base_offset_addr(ctx, t0, base, offset);
1598 #if defined(TARGET_MIPS64)
1600 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1601 gen_store_gpr(t0, rt);
1605 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1606 gen_store_gpr(t0, rt);
1610 save_cpu_state(ctx, 1);
1611 op_ld_lld(t0, t0, ctx);
1612 gen_store_gpr(t0, rt);
1616 save_cpu_state(ctx, 1);
1617 gen_load_gpr(t1, rt);
1618 gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
1619 gen_store_gpr(t1, rt);
1623 save_cpu_state(ctx, 1);
1624 gen_load_gpr(t1, rt);
1625 gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
1626 gen_store_gpr(t1, rt);
1630 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1631 gen_op_addr_add(ctx, t0, t0, t1);
1632 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1633 gen_store_gpr(t0, rt);
1638 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1639 gen_op_addr_add(ctx, t0, t0, t1);
1640 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1641 gen_store_gpr(t0, rt);
1645 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1646 gen_store_gpr(t0, rt);
1650 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1651 gen_store_gpr(t0, rt);
1655 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1656 gen_store_gpr(t0, rt);
1660 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1661 gen_store_gpr(t0, rt);
1665 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1666 gen_store_gpr(t0, rt);
1670 save_cpu_state(ctx, 1);
1671 gen_load_gpr(t1, rt);
1672 gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
1673 gen_store_gpr(t1, rt);
1677 save_cpu_state(ctx, 1);
1678 gen_load_gpr(t1, rt);
1679 gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
1680 gen_store_gpr(t1, rt);
1684 save_cpu_state(ctx, 1);
1685 op_ld_ll(t0, t0, ctx);
1686 gen_store_gpr(t0, rt);
1690 (void)opn; /* avoid a compiler warning */
1691 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1697 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1698 int base, int16_t offset)
1700 const char *opn = "st";
1701 TCGv t0 = tcg_temp_new();
1702 TCGv t1 = tcg_temp_new();
1704 gen_base_offset_addr(ctx, t0, base, offset);
1705 gen_load_gpr(t1, rt);
1707 #if defined(TARGET_MIPS64)
1709 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1713 save_cpu_state(ctx, 1);
1714 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1718 save_cpu_state(ctx, 1);
1719 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1724 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1728 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1732 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1736 save_cpu_state(ctx, 1);
1737 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1741 save_cpu_state(ctx, 1);
1742 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1746 (void)opn; /* avoid a compiler warning */
1747 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1753 /* Store conditional */
1754 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1755 int base, int16_t offset)
1757 const char *opn = "st_cond";
1760 t0 = tcg_temp_local_new();
1762 gen_base_offset_addr(ctx, t0, base, offset);
1763 /* Don't do NOP if destination is zero: we must perform the actual
1766 t1 = tcg_temp_local_new();
1767 gen_load_gpr(t1, rt);
1769 #if defined(TARGET_MIPS64)
1771 save_cpu_state(ctx, 1);
1772 op_st_scd(t1, t0, rt, ctx);
1777 save_cpu_state(ctx, 1);
1778 op_st_sc(t1, t0, rt, ctx);
1782 (void)opn; /* avoid a compiler warning */
1783 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1788 /* Load and store */
1789 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1790 int base, int16_t offset)
1792 const char *opn = "flt_ldst";
1793 TCGv t0 = tcg_temp_new();
1795 gen_base_offset_addr(ctx, t0, base, offset);
1796 /* Don't do NOP if destination is zero: we must perform the actual
1801 TCGv_i32 fp0 = tcg_temp_new_i32();
1803 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1804 tcg_gen_trunc_tl_i32(fp0, t0);
1805 gen_store_fpr32(fp0, ft);
1806 tcg_temp_free_i32(fp0);
1812 TCGv_i32 fp0 = tcg_temp_new_i32();
1813 TCGv t1 = tcg_temp_new();
1815 gen_load_fpr32(fp0, ft);
1816 tcg_gen_extu_i32_tl(t1, fp0);
1817 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1819 tcg_temp_free_i32(fp0);
1825 TCGv_i64 fp0 = tcg_temp_new_i64();
1827 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1828 gen_store_fpr64(ctx, fp0, ft);
1829 tcg_temp_free_i64(fp0);
1835 TCGv_i64 fp0 = tcg_temp_new_i64();
1837 gen_load_fpr64(ctx, fp0, ft);
1838 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1839 tcg_temp_free_i64(fp0);
1845 generate_exception(ctx, EXCP_RI);
1848 (void)opn; /* avoid a compiler warning */
1849 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1854 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1855 uint32_t op, int rt, int rs, int16_t imm)
1857 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1858 check_cp1_enabled(ctx);
1859 gen_flt_ldst(ctx, op, rt, rs, imm);
1861 generate_exception_err(ctx, EXCP_CpU, 1);
1865 /* Arithmetic with immediate operand */
1866 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1867 int rt, int rs, int16_t imm)
1869 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1870 const char *opn = "imm arith";
1872 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1873 /* If no destination, treat it as a NOP.
1874 For addi, we must generate the overflow exception when needed. */
1881 TCGv t0 = tcg_temp_local_new();
1882 TCGv t1 = tcg_temp_new();
1883 TCGv t2 = tcg_temp_new();
1884 int l1 = gen_new_label();
1886 gen_load_gpr(t1, rs);
1887 tcg_gen_addi_tl(t0, t1, uimm);
1888 tcg_gen_ext32s_tl(t0, t0);
1890 tcg_gen_xori_tl(t1, t1, ~uimm);
1891 tcg_gen_xori_tl(t2, t0, uimm);
1892 tcg_gen_and_tl(t1, t1, t2);
1894 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1896 /* operands of same sign, result different sign */
1897 generate_exception(ctx, EXCP_OVERFLOW);
1899 tcg_gen_ext32s_tl(t0, t0);
1900 gen_store_gpr(t0, rt);
1907 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1908 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1910 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1914 #if defined(TARGET_MIPS64)
1917 TCGv t0 = tcg_temp_local_new();
1918 TCGv t1 = tcg_temp_new();
1919 TCGv t2 = tcg_temp_new();
1920 int l1 = gen_new_label();
1922 gen_load_gpr(t1, rs);
1923 tcg_gen_addi_tl(t0, t1, uimm);
1925 tcg_gen_xori_tl(t1, t1, ~uimm);
1926 tcg_gen_xori_tl(t2, t0, uimm);
1927 tcg_gen_and_tl(t1, t1, t2);
1929 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1931 /* operands of same sign, result different sign */
1932 generate_exception(ctx, EXCP_OVERFLOW);
1934 gen_store_gpr(t0, rt);
1941 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1943 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1949 (void)opn; /* avoid a compiler warning */
1950 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1953 /* Logic with immediate operand */
1954 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1955 int rt, int rs, int16_t imm)
1958 const char *opn = "imm logic";
1961 /* If no destination, treat it as a NOP. */
1965 uimm = (uint16_t)imm;
1968 if (likely(rs != 0))
1969 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1971 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1976 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1978 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1982 if (likely(rs != 0))
1983 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1985 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1989 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1993 (void)opn; /* avoid a compiler warning */
1994 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1997 /* Set on less than with immediate operand */
1998 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1999 int rt, int rs, int16_t imm)
2001 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2002 const char *opn = "imm arith";
2006 /* If no destination, treat it as a NOP. */
2010 t0 = tcg_temp_new();
2011 gen_load_gpr(t0, rs);
2014 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2018 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2022 (void)opn; /* avoid a compiler warning */
2023 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2027 /* Shifts with immediate operand */
2028 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2029 int rt, int rs, int16_t imm)
2031 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2032 const char *opn = "imm shift";
2036 /* If no destination, treat it as a NOP. */
2041 t0 = tcg_temp_new();
2042 gen_load_gpr(t0, rs);
2045 tcg_gen_shli_tl(t0, t0, uimm);
2046 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2050 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2055 tcg_gen_ext32u_tl(t0, t0);
2056 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2058 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2064 TCGv_i32 t1 = tcg_temp_new_i32();
2066 tcg_gen_trunc_tl_i32(t1, t0);
2067 tcg_gen_rotri_i32(t1, t1, uimm);
2068 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2069 tcg_temp_free_i32(t1);
2071 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2075 #if defined(TARGET_MIPS64)
2077 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2081 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2085 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2090 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2092 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2097 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2101 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2105 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2109 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2114 (void)opn; /* avoid a compiler warning */
2115 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2120 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2121 int rd, int rs, int rt)
2123 const char *opn = "arith";
2125 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2126 && opc != OPC_DADD && opc != OPC_DSUB) {
2127 /* If no destination, treat it as a NOP.
2128 For add & sub, we must generate the overflow exception when needed. */
2136 TCGv t0 = tcg_temp_local_new();
2137 TCGv t1 = tcg_temp_new();
2138 TCGv t2 = tcg_temp_new();
2139 int l1 = gen_new_label();
2141 gen_load_gpr(t1, rs);
2142 gen_load_gpr(t2, rt);
2143 tcg_gen_add_tl(t0, t1, t2);
2144 tcg_gen_ext32s_tl(t0, t0);
2145 tcg_gen_xor_tl(t1, t1, t2);
2146 tcg_gen_xor_tl(t2, t0, t2);
2147 tcg_gen_andc_tl(t1, t2, t1);
2149 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2151 /* operands of same sign, result different sign */
2152 generate_exception(ctx, EXCP_OVERFLOW);
2154 gen_store_gpr(t0, rd);
2160 if (rs != 0 && rt != 0) {
2161 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2162 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2163 } else if (rs == 0 && rt != 0) {
2164 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2165 } else if (rs != 0 && rt == 0) {
2166 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2168 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2174 TCGv t0 = tcg_temp_local_new();
2175 TCGv t1 = tcg_temp_new();
2176 TCGv t2 = tcg_temp_new();
2177 int l1 = gen_new_label();
2179 gen_load_gpr(t1, rs);
2180 gen_load_gpr(t2, rt);
2181 tcg_gen_sub_tl(t0, t1, t2);
2182 tcg_gen_ext32s_tl(t0, t0);
2183 tcg_gen_xor_tl(t2, t1, t2);
2184 tcg_gen_xor_tl(t1, t0, t1);
2185 tcg_gen_and_tl(t1, t1, t2);
2187 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2189 /* operands of different sign, first operand and result different sign */
2190 generate_exception(ctx, EXCP_OVERFLOW);
2192 gen_store_gpr(t0, rd);
2198 if (rs != 0 && rt != 0) {
2199 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2200 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2201 } else if (rs == 0 && rt != 0) {
2202 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2203 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2204 } else if (rs != 0 && rt == 0) {
2205 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2207 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2211 #if defined(TARGET_MIPS64)
2214 TCGv t0 = tcg_temp_local_new();
2215 TCGv t1 = tcg_temp_new();
2216 TCGv t2 = tcg_temp_new();
2217 int l1 = gen_new_label();
2219 gen_load_gpr(t1, rs);
2220 gen_load_gpr(t2, rt);
2221 tcg_gen_add_tl(t0, t1, t2);
2222 tcg_gen_xor_tl(t1, t1, t2);
2223 tcg_gen_xor_tl(t2, t0, t2);
2224 tcg_gen_andc_tl(t1, t2, t1);
2226 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2228 /* operands of same sign, result different sign */
2229 generate_exception(ctx, EXCP_OVERFLOW);
2231 gen_store_gpr(t0, rd);
2237 if (rs != 0 && rt != 0) {
2238 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2239 } else if (rs == 0 && rt != 0) {
2240 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2241 } else if (rs != 0 && rt == 0) {
2242 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2244 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2250 TCGv t0 = tcg_temp_local_new();
2251 TCGv t1 = tcg_temp_new();
2252 TCGv t2 = tcg_temp_new();
2253 int l1 = gen_new_label();
2255 gen_load_gpr(t1, rs);
2256 gen_load_gpr(t2, rt);
2257 tcg_gen_sub_tl(t0, t1, t2);
2258 tcg_gen_xor_tl(t2, t1, t2);
2259 tcg_gen_xor_tl(t1, t0, t1);
2260 tcg_gen_and_tl(t1, t1, t2);
2262 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2264 /* operands of different sign, first operand and result different sign */
2265 generate_exception(ctx, EXCP_OVERFLOW);
2267 gen_store_gpr(t0, rd);
2273 if (rs != 0 && rt != 0) {
2274 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2275 } else if (rs == 0 && rt != 0) {
2276 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2277 } else if (rs != 0 && rt == 0) {
2278 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2280 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2286 if (likely(rs != 0 && rt != 0)) {
2287 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2288 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2290 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2295 (void)opn; /* avoid a compiler warning */
2296 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2299 /* Conditional move */
2300 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2301 int rd, int rs, int rt)
2303 const char *opn = "cond move";
2307 /* If no destination, treat it as a NOP.
2308 For add & sub, we must generate the overflow exception when needed. */
2313 l1 = gen_new_label();
2316 if (likely(rt != 0))
2317 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2323 if (likely(rt != 0))
2324 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2329 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2331 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2334 (void)opn; /* avoid a compiler warning */
2335 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2339 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2340 int rd, int rs, int rt)
2342 const char *opn = "logic";
2345 /* If no destination, treat it as a NOP. */
2352 if (likely(rs != 0 && rt != 0)) {
2353 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2355 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2360 if (rs != 0 && rt != 0) {
2361 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2362 } else if (rs == 0 && rt != 0) {
2363 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2364 } else if (rs != 0 && rt == 0) {
2365 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2367 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2372 if (likely(rs != 0 && rt != 0)) {
2373 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2374 } else if (rs == 0 && rt != 0) {
2375 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2376 } else if (rs != 0 && rt == 0) {
2377 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2379 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2384 if (likely(rs != 0 && rt != 0)) {
2385 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2386 } else if (rs == 0 && rt != 0) {
2387 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2388 } else if (rs != 0 && rt == 0) {
2389 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2391 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2396 (void)opn; /* avoid a compiler warning */
2397 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2400 /* Set on lower than */
2401 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2402 int rd, int rs, int rt)
2404 const char *opn = "slt";
2408 /* If no destination, treat it as a NOP. */
2413 t0 = tcg_temp_new();
2414 t1 = tcg_temp_new();
2415 gen_load_gpr(t0, rs);
2416 gen_load_gpr(t1, rt);
2419 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2423 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2427 (void)opn; /* avoid a compiler warning */
2428 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2434 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2435 int rd, int rs, int rt)
2437 const char *opn = "shifts";
2441 /* If no destination, treat it as a NOP.
2442 For add & sub, we must generate the overflow exception when needed. */
2447 t0 = tcg_temp_new();
2448 t1 = tcg_temp_new();
2449 gen_load_gpr(t0, rs);
2450 gen_load_gpr(t1, rt);
2453 tcg_gen_andi_tl(t0, t0, 0x1f);
2454 tcg_gen_shl_tl(t0, t1, t0);
2455 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2459 tcg_gen_andi_tl(t0, t0, 0x1f);
2460 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2464 tcg_gen_ext32u_tl(t1, t1);
2465 tcg_gen_andi_tl(t0, t0, 0x1f);
2466 tcg_gen_shr_tl(t0, t1, t0);
2467 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2472 TCGv_i32 t2 = tcg_temp_new_i32();
2473 TCGv_i32 t3 = tcg_temp_new_i32();
2475 tcg_gen_trunc_tl_i32(t2, t0);
2476 tcg_gen_trunc_tl_i32(t3, t1);
2477 tcg_gen_andi_i32(t2, t2, 0x1f);
2478 tcg_gen_rotr_i32(t2, t3, t2);
2479 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2480 tcg_temp_free_i32(t2);
2481 tcg_temp_free_i32(t3);
2485 #if defined(TARGET_MIPS64)
2487 tcg_gen_andi_tl(t0, t0, 0x3f);
2488 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2492 tcg_gen_andi_tl(t0, t0, 0x3f);
2493 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2497 tcg_gen_andi_tl(t0, t0, 0x3f);
2498 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2502 tcg_gen_andi_tl(t0, t0, 0x3f);
2503 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2508 (void)opn; /* avoid a compiler warning */
2509 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2514 /* Arithmetic on HI/LO registers */
2515 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2517 const char *opn = "hilo";
2520 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2526 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2527 acc = ((ctx->opcode) >> 21) & 0x03;
2529 acc = ((ctx->opcode) >> 11) & 0x03;
2538 #if defined(TARGET_MIPS64)
2540 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2544 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2549 #if defined(TARGET_MIPS64)
2551 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2555 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2561 #if defined(TARGET_MIPS64)
2563 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2567 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2570 tcg_gen_movi_tl(cpu_HI[acc], 0);
2576 #if defined(TARGET_MIPS64)
2578 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2582 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2585 tcg_gen_movi_tl(cpu_LO[acc], 0);
2590 (void)opn; /* avoid a compiler warning */
2591 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2594 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2597 const char *opn = "mul/div";
2604 #if defined(TARGET_MIPS64)
2608 t0 = tcg_temp_local_new();
2609 t1 = tcg_temp_local_new();
2612 t0 = tcg_temp_new();
2613 t1 = tcg_temp_new();
2617 gen_load_gpr(t0, rs);
2618 gen_load_gpr(t1, rt);
2622 int l1 = gen_new_label();
2623 int l2 = gen_new_label();
2625 tcg_gen_ext32s_tl(t0, t0);
2626 tcg_gen_ext32s_tl(t1, t1);
2627 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2628 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2629 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2631 tcg_gen_mov_tl(cpu_LO[0], t0);
2632 tcg_gen_movi_tl(cpu_HI[0], 0);
2635 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2636 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2637 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2638 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2645 int l1 = gen_new_label();
2647 tcg_gen_ext32u_tl(t0, t0);
2648 tcg_gen_ext32u_tl(t1, t1);
2649 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2650 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2651 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2652 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2653 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2660 TCGv_i64 t2 = tcg_temp_new_i64();
2661 TCGv_i64 t3 = tcg_temp_new_i64();
2662 acc = ((ctx->opcode) >> 11) & 0x03;
2667 tcg_gen_ext_tl_i64(t2, t0);
2668 tcg_gen_ext_tl_i64(t3, t1);
2669 tcg_gen_mul_i64(t2, t2, t3);
2670 tcg_temp_free_i64(t3);
2671 tcg_gen_trunc_i64_tl(t0, t2);
2672 tcg_gen_shri_i64(t2, t2, 32);
2673 tcg_gen_trunc_i64_tl(t1, t2);
2674 tcg_temp_free_i64(t2);
2675 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2676 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2682 TCGv_i64 t2 = tcg_temp_new_i64();
2683 TCGv_i64 t3 = tcg_temp_new_i64();
2684 acc = ((ctx->opcode) >> 11) & 0x03;
2689 tcg_gen_ext32u_tl(t0, t0);
2690 tcg_gen_ext32u_tl(t1, t1);
2691 tcg_gen_extu_tl_i64(t2, t0);
2692 tcg_gen_extu_tl_i64(t3, t1);
2693 tcg_gen_mul_i64(t2, t2, t3);
2694 tcg_temp_free_i64(t3);
2695 tcg_gen_trunc_i64_tl(t0, t2);
2696 tcg_gen_shri_i64(t2, t2, 32);
2697 tcg_gen_trunc_i64_tl(t1, t2);
2698 tcg_temp_free_i64(t2);
2699 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2700 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2704 #if defined(TARGET_MIPS64)
2707 int l1 = gen_new_label();
2708 int l2 = gen_new_label();
2710 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2711 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2712 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2713 tcg_gen_mov_tl(cpu_LO[0], t0);
2714 tcg_gen_movi_tl(cpu_HI[0], 0);
2717 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2718 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2725 int l1 = gen_new_label();
2727 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2728 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2729 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2735 gen_helper_dmult(cpu_env, t0, t1);
2739 gen_helper_dmultu(cpu_env, t0, t1);
2745 TCGv_i64 t2 = tcg_temp_new_i64();
2746 TCGv_i64 t3 = tcg_temp_new_i64();
2747 acc = ((ctx->opcode) >> 11) & 0x03;
2752 tcg_gen_ext_tl_i64(t2, t0);
2753 tcg_gen_ext_tl_i64(t3, t1);
2754 tcg_gen_mul_i64(t2, t2, t3);
2755 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2756 tcg_gen_add_i64(t2, t2, t3);
2757 tcg_temp_free_i64(t3);
2758 tcg_gen_trunc_i64_tl(t0, t2);
2759 tcg_gen_shri_i64(t2, t2, 32);
2760 tcg_gen_trunc_i64_tl(t1, t2);
2761 tcg_temp_free_i64(t2);
2762 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2763 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2769 TCGv_i64 t2 = tcg_temp_new_i64();
2770 TCGv_i64 t3 = tcg_temp_new_i64();
2771 acc = ((ctx->opcode) >> 11) & 0x03;
2776 tcg_gen_ext32u_tl(t0, t0);
2777 tcg_gen_ext32u_tl(t1, t1);
2778 tcg_gen_extu_tl_i64(t2, t0);
2779 tcg_gen_extu_tl_i64(t3, t1);
2780 tcg_gen_mul_i64(t2, t2, t3);
2781 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2782 tcg_gen_add_i64(t2, t2, t3);
2783 tcg_temp_free_i64(t3);
2784 tcg_gen_trunc_i64_tl(t0, t2);
2785 tcg_gen_shri_i64(t2, t2, 32);
2786 tcg_gen_trunc_i64_tl(t1, t2);
2787 tcg_temp_free_i64(t2);
2788 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2789 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2795 TCGv_i64 t2 = tcg_temp_new_i64();
2796 TCGv_i64 t3 = tcg_temp_new_i64();
2797 acc = ((ctx->opcode) >> 11) & 0x03;
2802 tcg_gen_ext_tl_i64(t2, t0);
2803 tcg_gen_ext_tl_i64(t3, t1);
2804 tcg_gen_mul_i64(t2, t2, t3);
2805 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2806 tcg_gen_sub_i64(t2, t3, t2);
2807 tcg_temp_free_i64(t3);
2808 tcg_gen_trunc_i64_tl(t0, t2);
2809 tcg_gen_shri_i64(t2, t2, 32);
2810 tcg_gen_trunc_i64_tl(t1, t2);
2811 tcg_temp_free_i64(t2);
2812 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2813 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2819 TCGv_i64 t2 = tcg_temp_new_i64();
2820 TCGv_i64 t3 = tcg_temp_new_i64();
2821 acc = ((ctx->opcode) >> 11) & 0x03;
2826 tcg_gen_ext32u_tl(t0, t0);
2827 tcg_gen_ext32u_tl(t1, t1);
2828 tcg_gen_extu_tl_i64(t2, t0);
2829 tcg_gen_extu_tl_i64(t3, t1);
2830 tcg_gen_mul_i64(t2, t2, t3);
2831 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2832 tcg_gen_sub_i64(t2, t3, t2);
2833 tcg_temp_free_i64(t3);
2834 tcg_gen_trunc_i64_tl(t0, t2);
2835 tcg_gen_shri_i64(t2, t2, 32);
2836 tcg_gen_trunc_i64_tl(t1, t2);
2837 tcg_temp_free_i64(t2);
2838 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2839 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2845 generate_exception(ctx, EXCP_RI);
2848 (void)opn; /* avoid a compiler warning */
2849 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2855 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2856 int rd, int rs, int rt)
2858 const char *opn = "mul vr54xx";
2859 TCGv t0 = tcg_temp_new();
2860 TCGv t1 = tcg_temp_new();
2862 gen_load_gpr(t0, rs);
2863 gen_load_gpr(t1, rt);
2866 case OPC_VR54XX_MULS:
2867 gen_helper_muls(t0, cpu_env, t0, t1);
2870 case OPC_VR54XX_MULSU:
2871 gen_helper_mulsu(t0, cpu_env, t0, t1);
2874 case OPC_VR54XX_MACC:
2875 gen_helper_macc(t0, cpu_env, t0, t1);
2878 case OPC_VR54XX_MACCU:
2879 gen_helper_maccu(t0, cpu_env, t0, t1);
2882 case OPC_VR54XX_MSAC:
2883 gen_helper_msac(t0, cpu_env, t0, t1);
2886 case OPC_VR54XX_MSACU:
2887 gen_helper_msacu(t0, cpu_env, t0, t1);
2890 case OPC_VR54XX_MULHI:
2891 gen_helper_mulhi(t0, cpu_env, t0, t1);
2894 case OPC_VR54XX_MULHIU:
2895 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2898 case OPC_VR54XX_MULSHI:
2899 gen_helper_mulshi(t0, cpu_env, t0, t1);
2902 case OPC_VR54XX_MULSHIU:
2903 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2906 case OPC_VR54XX_MACCHI:
2907 gen_helper_macchi(t0, cpu_env, t0, t1);
2910 case OPC_VR54XX_MACCHIU:
2911 gen_helper_macchiu(t0, cpu_env, t0, t1);
2914 case OPC_VR54XX_MSACHI:
2915 gen_helper_msachi(t0, cpu_env, t0, t1);
2918 case OPC_VR54XX_MSACHIU:
2919 gen_helper_msachiu(t0, cpu_env, t0, t1);
2923 MIPS_INVAL("mul vr54xx");
2924 generate_exception(ctx, EXCP_RI);
2927 gen_store_gpr(t0, rd);
2928 (void)opn; /* avoid a compiler warning */
2929 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2936 static void gen_cl (DisasContext *ctx, uint32_t opc,
2939 const char *opn = "CLx";
2947 t0 = tcg_temp_new();
2948 gen_load_gpr(t0, rs);
2951 gen_helper_clo(cpu_gpr[rd], t0);
2955 gen_helper_clz(cpu_gpr[rd], t0);
2958 #if defined(TARGET_MIPS64)
2960 gen_helper_dclo(cpu_gpr[rd], t0);
2964 gen_helper_dclz(cpu_gpr[rd], t0);
2969 (void)opn; /* avoid a compiler warning */
2970 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2974 /* Godson integer instructions */
2975 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2976 int rd, int rs, int rt)
2978 const char *opn = "loongson";
2990 case OPC_MULTU_G_2E:
2991 case OPC_MULTU_G_2F:
2992 #if defined(TARGET_MIPS64)
2993 case OPC_DMULT_G_2E:
2994 case OPC_DMULT_G_2F:
2995 case OPC_DMULTU_G_2E:
2996 case OPC_DMULTU_G_2F:
2998 t0 = tcg_temp_new();
2999 t1 = tcg_temp_new();
3002 t0 = tcg_temp_local_new();
3003 t1 = tcg_temp_local_new();
3007 gen_load_gpr(t0, rs);
3008 gen_load_gpr(t1, rt);
3013 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3014 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3017 case OPC_MULTU_G_2E:
3018 case OPC_MULTU_G_2F:
3019 tcg_gen_ext32u_tl(t0, t0);
3020 tcg_gen_ext32u_tl(t1, t1);
3021 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3022 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3028 int l1 = gen_new_label();
3029 int l2 = gen_new_label();
3030 int l3 = gen_new_label();
3031 tcg_gen_ext32s_tl(t0, t0);
3032 tcg_gen_ext32s_tl(t1, t1);
3033 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3034 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3037 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3038 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3039 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3042 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3043 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3051 int l1 = gen_new_label();
3052 int l2 = gen_new_label();
3053 tcg_gen_ext32u_tl(t0, t0);
3054 tcg_gen_ext32u_tl(t1, t1);
3055 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3056 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3059 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3060 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3068 int l1 = gen_new_label();
3069 int l2 = gen_new_label();
3070 int l3 = gen_new_label();
3071 tcg_gen_ext32u_tl(t0, t0);
3072 tcg_gen_ext32u_tl(t1, t1);
3073 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3074 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3075 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3077 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3080 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3081 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3089 int l1 = gen_new_label();
3090 int l2 = gen_new_label();
3091 tcg_gen_ext32u_tl(t0, t0);
3092 tcg_gen_ext32u_tl(t1, t1);
3093 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3094 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3097 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3098 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3103 #if defined(TARGET_MIPS64)
3104 case OPC_DMULT_G_2E:
3105 case OPC_DMULT_G_2F:
3106 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3109 case OPC_DMULTU_G_2E:
3110 case OPC_DMULTU_G_2F:
3111 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3117 int l1 = gen_new_label();
3118 int l2 = gen_new_label();
3119 int l3 = gen_new_label();
3120 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3121 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3124 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3125 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3126 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3129 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3134 case OPC_DDIVU_G_2E:
3135 case OPC_DDIVU_G_2F:
3137 int l1 = gen_new_label();
3138 int l2 = gen_new_label();
3139 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3140 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3143 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3151 int l1 = gen_new_label();
3152 int l2 = gen_new_label();
3153 int l3 = gen_new_label();
3154 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3155 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3156 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3158 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3161 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3166 case OPC_DMODU_G_2E:
3167 case OPC_DMODU_G_2F:
3169 int l1 = gen_new_label();
3170 int l2 = gen_new_label();
3171 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3172 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3175 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3183 (void)opn; /* avoid a compiler warning */
3184 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3189 /* Loongson multimedia instructions */
3190 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3192 const char *opn = "loongson_cp2";
3193 uint32_t opc, shift_max;
3196 opc = MASK_LMI(ctx->opcode);
3202 t0 = tcg_temp_local_new_i64();
3203 t1 = tcg_temp_local_new_i64();
3206 t0 = tcg_temp_new_i64();
3207 t1 = tcg_temp_new_i64();
3211 gen_load_fpr64(ctx, t0, rs);
3212 gen_load_fpr64(ctx, t1, rt);
3214 #define LMI_HELPER(UP, LO) \
3215 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3216 #define LMI_HELPER_1(UP, LO) \
3217 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3218 #define LMI_DIRECT(UP, LO, OP) \
3219 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3222 LMI_HELPER(PADDSH, paddsh);
3223 LMI_HELPER(PADDUSH, paddush);
3224 LMI_HELPER(PADDH, paddh);
3225 LMI_HELPER(PADDW, paddw);
3226 LMI_HELPER(PADDSB, paddsb);
3227 LMI_HELPER(PADDUSB, paddusb);
3228 LMI_HELPER(PADDB, paddb);
3230 LMI_HELPER(PSUBSH, psubsh);
3231 LMI_HELPER(PSUBUSH, psubush);
3232 LMI_HELPER(PSUBH, psubh);
3233 LMI_HELPER(PSUBW, psubw);
3234 LMI_HELPER(PSUBSB, psubsb);
3235 LMI_HELPER(PSUBUSB, psubusb);
3236 LMI_HELPER(PSUBB, psubb);
3238 LMI_HELPER(PSHUFH, pshufh);
3239 LMI_HELPER(PACKSSWH, packsswh);
3240 LMI_HELPER(PACKSSHB, packsshb);
3241 LMI_HELPER(PACKUSHB, packushb);
3243 LMI_HELPER(PUNPCKLHW, punpcklhw);
3244 LMI_HELPER(PUNPCKHHW, punpckhhw);
3245 LMI_HELPER(PUNPCKLBH, punpcklbh);
3246 LMI_HELPER(PUNPCKHBH, punpckhbh);
3247 LMI_HELPER(PUNPCKLWD, punpcklwd);
3248 LMI_HELPER(PUNPCKHWD, punpckhwd);
3250 LMI_HELPER(PAVGH, pavgh);
3251 LMI_HELPER(PAVGB, pavgb);
3252 LMI_HELPER(PMAXSH, pmaxsh);
3253 LMI_HELPER(PMINSH, pminsh);
3254 LMI_HELPER(PMAXUB, pmaxub);
3255 LMI_HELPER(PMINUB, pminub);
3257 LMI_HELPER(PCMPEQW, pcmpeqw);
3258 LMI_HELPER(PCMPGTW, pcmpgtw);
3259 LMI_HELPER(PCMPEQH, pcmpeqh);
3260 LMI_HELPER(PCMPGTH, pcmpgth);
3261 LMI_HELPER(PCMPEQB, pcmpeqb);
3262 LMI_HELPER(PCMPGTB, pcmpgtb);
3264 LMI_HELPER(PSLLW, psllw);
3265 LMI_HELPER(PSLLH, psllh);
3266 LMI_HELPER(PSRLW, psrlw);
3267 LMI_HELPER(PSRLH, psrlh);
3268 LMI_HELPER(PSRAW, psraw);
3269 LMI_HELPER(PSRAH, psrah);
3271 LMI_HELPER(PMULLH, pmullh);
3272 LMI_HELPER(PMULHH, pmulhh);
3273 LMI_HELPER(PMULHUH, pmulhuh);
3274 LMI_HELPER(PMADDHW, pmaddhw);
3276 LMI_HELPER(PASUBUB, pasubub);
3277 LMI_HELPER_1(BIADD, biadd);
3278 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3280 LMI_DIRECT(PADDD, paddd, add);
3281 LMI_DIRECT(PSUBD, psubd, sub);
3282 LMI_DIRECT(XOR_CP2, xor, xor);
3283 LMI_DIRECT(NOR_CP2, nor, nor);
3284 LMI_DIRECT(AND_CP2, and, and);
3285 LMI_DIRECT(PANDN, pandn, andc);
3286 LMI_DIRECT(OR, or, or);
3289 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3293 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3297 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3301 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3306 tcg_gen_andi_i64(t1, t1, 3);
3307 tcg_gen_shli_i64(t1, t1, 4);
3308 tcg_gen_shr_i64(t0, t0, t1);
3309 tcg_gen_ext16u_i64(t0, t0);
3314 tcg_gen_add_i64(t0, t0, t1);
3315 tcg_gen_ext32s_i64(t0, t0);
3319 tcg_gen_sub_i64(t0, t0, t1);
3320 tcg_gen_ext32s_i64(t0, t0);
3349 /* Make sure shift count isn't TCG undefined behaviour. */
3350 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3355 tcg_gen_shl_i64(t0, t0, t1);
3359 /* Since SRA is UndefinedResult without sign-extended inputs,
3360 we can treat SRA and DSRA the same. */
3361 tcg_gen_sar_i64(t0, t0, t1);
3364 /* We want to shift in zeros for SRL; zero-extend first. */
3365 tcg_gen_ext32u_i64(t0, t0);
3368 tcg_gen_shr_i64(t0, t0, t1);
3372 if (shift_max == 32) {
3373 tcg_gen_ext32s_i64(t0, t0);
3376 /* Shifts larger than MAX produce zero. */
3377 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3378 tcg_gen_neg_i64(t1, t1);
3379 tcg_gen_and_i64(t0, t0, t1);
3385 TCGv_i64 t2 = tcg_temp_new_i64();
3386 int lab = gen_new_label();
3388 tcg_gen_mov_i64(t2, t0);
3389 tcg_gen_add_i64(t0, t1, t2);
3390 if (opc == OPC_ADD_CP2) {
3391 tcg_gen_ext32s_i64(t0, t0);
3393 tcg_gen_xor_i64(t1, t1, t2);
3394 tcg_gen_xor_i64(t2, t2, t0);
3395 tcg_gen_andc_i64(t1, t2, t1);
3396 tcg_temp_free_i64(t2);
3397 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3398 generate_exception(ctx, EXCP_OVERFLOW);
3401 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3408 TCGv_i64 t2 = tcg_temp_new_i64();
3409 int lab = gen_new_label();
3411 tcg_gen_mov_i64(t2, t0);
3412 tcg_gen_sub_i64(t0, t1, t2);
3413 if (opc == OPC_SUB_CP2) {
3414 tcg_gen_ext32s_i64(t0, t0);
3416 tcg_gen_xor_i64(t1, t1, t2);
3417 tcg_gen_xor_i64(t2, t2, t0);
3418 tcg_gen_and_i64(t1, t1, t2);
3419 tcg_temp_free_i64(t2);
3420 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3421 generate_exception(ctx, EXCP_OVERFLOW);
3424 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3429 tcg_gen_ext32u_i64(t0, t0);
3430 tcg_gen_ext32u_i64(t1, t1);
3431 tcg_gen_mul_i64(t0, t0, t1);
3441 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3442 FD field is the CC field? */
3445 generate_exception(ctx, EXCP_RI);
3452 gen_store_fpr64(ctx, t0, rd);
3454 (void)opn; /* avoid a compiler warning */
3455 MIPS_DEBUG("%s %s, %s, %s", opn,
3456 fregnames[rd], fregnames[rs], fregnames[rt]);
3457 tcg_temp_free_i64(t0);
3458 tcg_temp_free_i64(t1);
3462 static void gen_trap (DisasContext *ctx, uint32_t opc,
3463 int rs, int rt, int16_t imm)
3466 TCGv t0 = tcg_temp_new();
3467 TCGv t1 = tcg_temp_new();
3470 /* Load needed operands */
3478 /* Compare two registers */
3480 gen_load_gpr(t0, rs);
3481 gen_load_gpr(t1, rt);
3491 /* Compare register to immediate */
3492 if (rs != 0 || imm != 0) {
3493 gen_load_gpr(t0, rs);
3494 tcg_gen_movi_tl(t1, (int32_t)imm);
3501 case OPC_TEQ: /* rs == rs */
3502 case OPC_TEQI: /* r0 == 0 */
3503 case OPC_TGE: /* rs >= rs */
3504 case OPC_TGEI: /* r0 >= 0 */
3505 case OPC_TGEU: /* rs >= rs unsigned */
3506 case OPC_TGEIU: /* r0 >= 0 unsigned */
3508 generate_exception(ctx, EXCP_TRAP);
3510 case OPC_TLT: /* rs < rs */
3511 case OPC_TLTI: /* r0 < 0 */
3512 case OPC_TLTU: /* rs < rs unsigned */
3513 case OPC_TLTIU: /* r0 < 0 unsigned */
3514 case OPC_TNE: /* rs != rs */
3515 case OPC_TNEI: /* r0 != 0 */
3516 /* Never trap: treat as NOP. */
3520 int l1 = gen_new_label();
3525 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3529 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3533 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3537 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3541 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3545 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3548 generate_exception(ctx, EXCP_TRAP);
3555 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3557 TranslationBlock *tb;
3559 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3560 likely(!ctx->singlestep_enabled)) {
3563 tcg_gen_exit_tb((tcg_target_long)tb + n);
3566 if (ctx->singlestep_enabled) {
3567 save_cpu_state(ctx, 0);
3568 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3574 /* Branches (before delay slot) */
3575 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3577 int rs, int rt, int32_t offset)
3579 target_ulong btgt = -1;
3581 int bcond_compute = 0;
3582 TCGv t0 = tcg_temp_new();
3583 TCGv t1 = tcg_temp_new();
3585 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3586 #ifdef MIPS_DEBUG_DISAS
3587 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3589 generate_exception(ctx, EXCP_RI);
3593 /* Load needed operands */
3599 /* Compare two registers */
3601 gen_load_gpr(t0, rs);
3602 gen_load_gpr(t1, rt);
3605 btgt = ctx->pc + insn_bytes + offset;
3621 /* Compare to zero */
3623 gen_load_gpr(t0, rs);
3626 btgt = ctx->pc + insn_bytes + offset;
3629 #if defined(TARGET_MIPS64)
3631 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3633 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3636 btgt = ctx->pc + insn_bytes + offset;
3643 /* Jump to immediate */
3644 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3650 /* Jump to register */
3651 if (offset != 0 && offset != 16) {
3652 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3653 others are reserved. */
3654 MIPS_INVAL("jump hint");
3655 generate_exception(ctx, EXCP_RI);
3658 gen_load_gpr(btarget, rs);
3661 MIPS_INVAL("branch/jump");
3662 generate_exception(ctx, EXCP_RI);
3665 if (bcond_compute == 0) {
3666 /* No condition to be computed */
3668 case OPC_BEQ: /* rx == rx */
3669 case OPC_BEQL: /* rx == rx likely */
3670 case OPC_BGEZ: /* 0 >= 0 */
3671 case OPC_BGEZL: /* 0 >= 0 likely */
3672 case OPC_BLEZ: /* 0 <= 0 */
3673 case OPC_BLEZL: /* 0 <= 0 likely */
3675 ctx->hflags |= MIPS_HFLAG_B;
3676 MIPS_DEBUG("balways");
3679 case OPC_BGEZAL: /* 0 >= 0 */
3680 case OPC_BGEZALL: /* 0 >= 0 likely */
3681 ctx->hflags |= (opc == OPC_BGEZALS
3683 : MIPS_HFLAG_BDS32);
3684 /* Always take and link */
3686 ctx->hflags |= MIPS_HFLAG_B;
3687 MIPS_DEBUG("balways and link");
3689 case OPC_BNE: /* rx != rx */
3690 case OPC_BGTZ: /* 0 > 0 */
3691 case OPC_BLTZ: /* 0 < 0 */
3693 MIPS_DEBUG("bnever (NOP)");
3696 case OPC_BLTZAL: /* 0 < 0 */
3697 ctx->hflags |= (opc == OPC_BLTZALS
3699 : MIPS_HFLAG_BDS32);
3700 /* Handle as an unconditional branch to get correct delay
3703 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3704 ctx->hflags |= MIPS_HFLAG_B;
3705 MIPS_DEBUG("bnever and link");
3707 case OPC_BLTZALL: /* 0 < 0 likely */
3708 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3709 /* Skip the instruction in the delay slot */
3710 MIPS_DEBUG("bnever, link and skip");
3713 case OPC_BNEL: /* rx != rx likely */
3714 case OPC_BGTZL: /* 0 > 0 likely */
3715 case OPC_BLTZL: /* 0 < 0 likely */
3716 /* Skip the instruction in the delay slot */
3717 MIPS_DEBUG("bnever and skip");
3721 ctx->hflags |= MIPS_HFLAG_B;
3722 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3726 ctx->hflags |= MIPS_HFLAG_BX;
3731 ctx->hflags |= MIPS_HFLAG_B;
3732 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3734 : MIPS_HFLAG_BDS32);
3735 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3738 ctx->hflags |= MIPS_HFLAG_BR;
3739 if (insn_bytes == 4)
3740 ctx->hflags |= MIPS_HFLAG_BDS32;
3741 MIPS_DEBUG("jr %s", regnames[rs]);
3747 ctx->hflags |= MIPS_HFLAG_BR;
3748 ctx->hflags |= (opc == OPC_JALRS
3750 : MIPS_HFLAG_BDS32);
3751 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3754 MIPS_INVAL("branch/jump");
3755 generate_exception(ctx, EXCP_RI);
3761 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3762 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3763 regnames[rs], regnames[rt], btgt);
3766 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3767 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3768 regnames[rs], regnames[rt], btgt);
3771 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3772 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3773 regnames[rs], regnames[rt], btgt);
3776 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3777 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3778 regnames[rs], regnames[rt], btgt);
3781 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3782 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3785 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3786 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3790 ctx->hflags |= (opc == OPC_BGEZALS
3792 : MIPS_HFLAG_BDS32);
3793 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3794 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3798 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3800 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3803 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3804 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3807 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3808 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3811 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3812 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3815 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3816 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3819 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3820 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3823 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3824 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3827 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3828 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3830 #if defined(TARGET_MIPS64)
3832 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3833 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3838 ctx->hflags |= (opc == OPC_BLTZALS
3840 : MIPS_HFLAG_BDS32);
3841 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3843 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3845 ctx->hflags |= MIPS_HFLAG_BC;
3848 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3850 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3852 ctx->hflags |= MIPS_HFLAG_BL;
3855 MIPS_INVAL("conditional branch/jump");
3856 generate_exception(ctx, EXCP_RI);
3860 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3861 blink, ctx->hflags, btgt);
3863 ctx->btarget = btgt;
3865 int post_delay = insn_bytes;
3866 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3868 if (opc != OPC_JALRC)
3869 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3871 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3875 if (insn_bytes == 2)
3876 ctx->hflags |= MIPS_HFLAG_B16;
3881 /* special3 bitfield operations */
3882 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3883 int rs, int lsb, int msb)
3885 TCGv t0 = tcg_temp_new();
3886 TCGv t1 = tcg_temp_new();
3889 gen_load_gpr(t1, rs);
3894 tcg_gen_shri_tl(t0, t1, lsb);
3896 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3898 tcg_gen_ext32s_tl(t0, t0);
3901 #if defined(TARGET_MIPS64)
3903 tcg_gen_shri_tl(t0, t1, lsb);
3905 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3909 tcg_gen_shri_tl(t0, t1, lsb + 32);
3910 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3913 tcg_gen_shri_tl(t0, t1, lsb);
3914 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3920 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3921 gen_load_gpr(t0, rt);
3922 tcg_gen_andi_tl(t0, t0, ~mask);
3923 tcg_gen_shli_tl(t1, t1, lsb);
3924 tcg_gen_andi_tl(t1, t1, mask);
3925 tcg_gen_or_tl(t0, t0, t1);
3926 tcg_gen_ext32s_tl(t0, t0);
3928 #if defined(TARGET_MIPS64)
3932 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3933 gen_load_gpr(t0, rt);
3934 tcg_gen_andi_tl(t0, t0, ~mask);
3935 tcg_gen_shli_tl(t1, t1, lsb);
3936 tcg_gen_andi_tl(t1, t1, mask);
3937 tcg_gen_or_tl(t0, t0, t1);
3942 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3943 gen_load_gpr(t0, rt);
3944 tcg_gen_andi_tl(t0, t0, ~mask);
3945 tcg_gen_shli_tl(t1, t1, lsb + 32);
3946 tcg_gen_andi_tl(t1, t1, mask);
3947 tcg_gen_or_tl(t0, t0, t1);
3952 gen_load_gpr(t0, rt);
3953 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3954 gen_load_gpr(t0, rt);
3955 tcg_gen_andi_tl(t0, t0, ~mask);
3956 tcg_gen_shli_tl(t1, t1, lsb);
3957 tcg_gen_andi_tl(t1, t1, mask);
3958 tcg_gen_or_tl(t0, t0, t1);
3963 MIPS_INVAL("bitops");
3964 generate_exception(ctx, EXCP_RI);
3969 gen_store_gpr(t0, rt);
3974 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3979 /* If no destination, treat it as a NOP. */
3984 t0 = tcg_temp_new();
3985 gen_load_gpr(t0, rt);
3989 TCGv t1 = tcg_temp_new();
3991 tcg_gen_shri_tl(t1, t0, 8);
3992 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3993 tcg_gen_shli_tl(t0, t0, 8);
3994 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3995 tcg_gen_or_tl(t0, t0, t1);
3997 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4001 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4004 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4006 #if defined(TARGET_MIPS64)
4009 TCGv t1 = tcg_temp_new();
4011 tcg_gen_shri_tl(t1, t0, 8);
4012 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4013 tcg_gen_shli_tl(t0, t0, 8);
4014 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4015 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4021 TCGv t1 = tcg_temp_new();
4023 tcg_gen_shri_tl(t1, t0, 16);
4024 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4025 tcg_gen_shli_tl(t0, t0, 16);
4026 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4027 tcg_gen_or_tl(t0, t0, t1);
4028 tcg_gen_shri_tl(t1, t0, 32);
4029 tcg_gen_shli_tl(t0, t0, 32);
4030 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4036 MIPS_INVAL("bsfhl");
4037 generate_exception(ctx, EXCP_RI);
4044 #ifndef CONFIG_USER_ONLY
4045 /* CP0 (MMU and control) */
4046 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4048 TCGv_i32 t0 = tcg_temp_new_i32();
4050 tcg_gen_ld_i32(t0, cpu_env, off);
4051 tcg_gen_ext_i32_tl(arg, t0);
4052 tcg_temp_free_i32(t0);
4055 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4057 tcg_gen_ld_tl(arg, cpu_env, off);
4058 tcg_gen_ext32s_tl(arg, arg);
4061 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4063 TCGv_i32 t0 = tcg_temp_new_i32();
4065 tcg_gen_trunc_tl_i32(t0, arg);
4066 tcg_gen_st_i32(t0, cpu_env, off);
4067 tcg_temp_free_i32(t0);
4070 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4072 tcg_gen_ext32s_tl(arg, arg);
4073 tcg_gen_st_tl(arg, cpu_env, off);
4076 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4078 const char *rn = "invalid";
4081 check_insn(env, ctx, ISA_MIPS32);
4087 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4091 check_insn(env, ctx, ASE_MT);
4092 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4096 check_insn(env, ctx, ASE_MT);
4097 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4101 check_insn(env, ctx, ASE_MT);
4102 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4112 gen_helper_mfc0_random(arg, cpu_env);
4116 check_insn(env, ctx, ASE_MT);
4117 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4121 check_insn(env, ctx, ASE_MT);
4122 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4126 check_insn(env, ctx, ASE_MT);
4127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4131 check_insn(env, ctx, ASE_MT);
4132 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4136 check_insn(env, ctx, ASE_MT);
4137 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4141 check_insn(env, ctx, ASE_MT);
4142 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4143 rn = "VPEScheFBack";
4146 check_insn(env, ctx, ASE_MT);
4147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4157 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4158 tcg_gen_ext32s_tl(arg, arg);
4162 check_insn(env, ctx, ASE_MT);
4163 gen_helper_mfc0_tcstatus(arg, cpu_env);
4167 check_insn(env, ctx, ASE_MT);
4168 gen_helper_mfc0_tcbind(arg, cpu_env);
4172 check_insn(env, ctx, ASE_MT);
4173 gen_helper_mfc0_tcrestart(arg, cpu_env);
4177 check_insn(env, ctx, ASE_MT);
4178 gen_helper_mfc0_tchalt(arg, cpu_env);
4182 check_insn(env, ctx, ASE_MT);
4183 gen_helper_mfc0_tccontext(arg, cpu_env);
4187 check_insn(env, ctx, ASE_MT);
4188 gen_helper_mfc0_tcschedule(arg, cpu_env);
4192 check_insn(env, ctx, ASE_MT);
4193 gen_helper_mfc0_tcschefback(arg, cpu_env);
4203 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4204 tcg_gen_ext32s_tl(arg, arg);
4214 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4215 tcg_gen_ext32s_tl(arg, arg);
4219 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4220 rn = "ContextConfig";
4229 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4233 check_insn(env, ctx, ISA_MIPS32R2);
4234 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4244 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4248 check_insn(env, ctx, ISA_MIPS32R2);
4249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4253 check_insn(env, ctx, ISA_MIPS32R2);
4254 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4258 check_insn(env, ctx, ISA_MIPS32R2);
4259 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4263 check_insn(env, ctx, ISA_MIPS32R2);
4264 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4268 check_insn(env, ctx, ISA_MIPS32R2);
4269 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4279 check_insn(env, ctx, ISA_MIPS32R2);
4280 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4290 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4291 tcg_gen_ext32s_tl(arg, arg);
4301 /* Mark as an IO operation because we read the time. */
4304 gen_helper_mfc0_count(arg, cpu_env);
4308 /* Break the TB to be able to take timer interrupts immediately
4309 after reading count. */
4310 ctx->bstate = BS_STOP;
4313 /* 6,7 are implementation dependent */
4321 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4322 tcg_gen_ext32s_tl(arg, arg);
4332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4335 /* 6,7 are implementation dependent */
4343 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4347 check_insn(env, ctx, ISA_MIPS32R2);
4348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4352 check_insn(env, ctx, ISA_MIPS32R2);
4353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4357 check_insn(env, ctx, ISA_MIPS32R2);
4358 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4379 tcg_gen_ext32s_tl(arg, arg);
4389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4393 check_insn(env, ctx, ISA_MIPS32R2);
4394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4404 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4419 /* 4,5 are reserved */
4420 /* 6,7 are implementation dependent */
4422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4426 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4436 gen_helper_mfc0_lladdr(arg, cpu_env);
4446 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4456 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4466 #if defined(TARGET_MIPS64)
4467 check_insn(env, ctx, ISA_MIPS3);
4468 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4469 tcg_gen_ext32s_tl(arg, arg);
4478 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4489 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4490 rn = "'Diagnostic"; /* implementation dependent */
4495 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4499 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4500 rn = "TraceControl";
4503 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4504 rn = "TraceControl2";
4507 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4508 rn = "UserTraceData";
4511 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4522 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4523 tcg_gen_ext32s_tl(arg, arg);
4533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4534 rn = "Performance0";
4537 // gen_helper_mfc0_performance1(arg);
4538 rn = "Performance1";
4541 // gen_helper_mfc0_performance2(arg);
4542 rn = "Performance2";
4545 // gen_helper_mfc0_performance3(arg);
4546 rn = "Performance3";
4549 // gen_helper_mfc0_performance4(arg);
4550 rn = "Performance4";
4553 // gen_helper_mfc0_performance5(arg);
4554 rn = "Performance5";
4557 // gen_helper_mfc0_performance6(arg);
4558 rn = "Performance6";
4561 // gen_helper_mfc0_performance7(arg);
4562 rn = "Performance7";
4569 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4575 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4615 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4625 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4626 tcg_gen_ext32s_tl(arg, arg);
4637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4647 (void)rn; /* avoid a compiler warning */
4648 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4652 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4653 generate_exception(ctx, EXCP_RI);
4656 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4658 const char *rn = "invalid";
4661 check_insn(env, ctx, ISA_MIPS32);
4670 gen_helper_mtc0_index(cpu_env, arg);
4674 check_insn(env, ctx, ASE_MT);
4675 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4679 check_insn(env, ctx, ASE_MT);
4684 check_insn(env, ctx, ASE_MT);
4699 check_insn(env, ctx, ASE_MT);
4700 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4704 check_insn(env, ctx, ASE_MT);
4705 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4709 check_insn(env, ctx, ASE_MT);
4710 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4714 check_insn(env, ctx, ASE_MT);
4715 gen_helper_mtc0_yqmask(cpu_env, arg);
4719 check_insn(env, ctx, ASE_MT);
4720 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4724 check_insn(env, ctx, ASE_MT);
4725 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4726 rn = "VPEScheFBack";
4729 check_insn(env, ctx, ASE_MT);
4730 gen_helper_mtc0_vpeopt(cpu_env, arg);
4740 gen_helper_mtc0_entrylo0(cpu_env, arg);
4744 check_insn(env, ctx, ASE_MT);
4745 gen_helper_mtc0_tcstatus(cpu_env, arg);
4749 check_insn(env, ctx, ASE_MT);
4750 gen_helper_mtc0_tcbind(cpu_env, arg);
4754 check_insn(env, ctx, ASE_MT);
4755 gen_helper_mtc0_tcrestart(cpu_env, arg);
4759 check_insn(env, ctx, ASE_MT);
4760 gen_helper_mtc0_tchalt(cpu_env, arg);
4764 check_insn(env, ctx, ASE_MT);
4765 gen_helper_mtc0_tccontext(cpu_env, arg);
4769 check_insn(env, ctx, ASE_MT);
4770 gen_helper_mtc0_tcschedule(cpu_env, arg);
4774 check_insn(env, ctx, ASE_MT);
4775 gen_helper_mtc0_tcschefback(cpu_env, arg);
4785 gen_helper_mtc0_entrylo1(cpu_env, arg);
4795 gen_helper_mtc0_context(cpu_env, arg);
4799 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4800 rn = "ContextConfig";
4809 gen_helper_mtc0_pagemask(cpu_env, arg);
4813 check_insn(env, ctx, ISA_MIPS32R2);
4814 gen_helper_mtc0_pagegrain(cpu_env, arg);
4824 gen_helper_mtc0_wired(cpu_env, arg);
4828 check_insn(env, ctx, ISA_MIPS32R2);
4829 gen_helper_mtc0_srsconf0(cpu_env, arg);
4833 check_insn(env, ctx, ISA_MIPS32R2);
4834 gen_helper_mtc0_srsconf1(cpu_env, arg);
4838 check_insn(env, ctx, ISA_MIPS32R2);
4839 gen_helper_mtc0_srsconf2(cpu_env, arg);
4843 check_insn(env, ctx, ISA_MIPS32R2);
4844 gen_helper_mtc0_srsconf3(cpu_env, arg);
4848 check_insn(env, ctx, ISA_MIPS32R2);
4849 gen_helper_mtc0_srsconf4(cpu_env, arg);
4859 check_insn(env, ctx, ISA_MIPS32R2);
4860 gen_helper_mtc0_hwrena(cpu_env, arg);
4874 gen_helper_mtc0_count(cpu_env, arg);
4877 /* 6,7 are implementation dependent */
4885 gen_helper_mtc0_entryhi(cpu_env, arg);
4895 gen_helper_mtc0_compare(cpu_env, arg);
4898 /* 6,7 are implementation dependent */
4906 save_cpu_state(ctx, 1);
4907 gen_helper_mtc0_status(cpu_env, arg);
4908 /* BS_STOP isn't good enough here, hflags may have changed. */
4909 gen_save_pc(ctx->pc + 4);
4910 ctx->bstate = BS_EXCP;
4914 check_insn(env, ctx, ISA_MIPS32R2);
4915 gen_helper_mtc0_intctl(cpu_env, arg);
4916 /* Stop translation as we may have switched the execution mode */
4917 ctx->bstate = BS_STOP;
4921 check_insn(env, ctx, ISA_MIPS32R2);
4922 gen_helper_mtc0_srsctl(cpu_env, arg);
4923 /* Stop translation as we may have switched the execution mode */
4924 ctx->bstate = BS_STOP;
4928 check_insn(env, ctx, ISA_MIPS32R2);
4929 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4930 /* Stop translation as we may have switched the execution mode */
4931 ctx->bstate = BS_STOP;
4941 save_cpu_state(ctx, 1);
4942 gen_helper_mtc0_cause(cpu_env, arg);
4952 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4966 check_insn(env, ctx, ISA_MIPS32R2);
4967 gen_helper_mtc0_ebase(cpu_env, arg);
4977 gen_helper_mtc0_config0(cpu_env, arg);
4979 /* Stop translation as we may have switched the execution mode */
4980 ctx->bstate = BS_STOP;
4983 /* ignored, read only */
4987 gen_helper_mtc0_config2(cpu_env, arg);
4989 /* Stop translation as we may have switched the execution mode */
4990 ctx->bstate = BS_STOP;
4993 /* ignored, read only */
4996 /* 4,5 are reserved */
4997 /* 6,7 are implementation dependent */
5007 rn = "Invalid config selector";
5014 gen_helper_mtc0_lladdr(cpu_env, arg);
5024 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5034 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5044 #if defined(TARGET_MIPS64)
5045 check_insn(env, ctx, ISA_MIPS3);
5046 gen_helper_mtc0_xcontext(cpu_env, arg);
5055 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5058 gen_helper_mtc0_framemask(cpu_env, arg);
5067 rn = "Diagnostic"; /* implementation dependent */
5072 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5073 /* BS_STOP isn't good enough here, hflags may have changed. */
5074 gen_save_pc(ctx->pc + 4);
5075 ctx->bstate = BS_EXCP;
5079 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5080 rn = "TraceControl";
5081 /* Stop translation as we may have switched the execution mode */
5082 ctx->bstate = BS_STOP;
5085 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5086 rn = "TraceControl2";
5087 /* Stop translation as we may have switched the execution mode */
5088 ctx->bstate = BS_STOP;
5091 /* Stop translation as we may have switched the execution mode */
5092 ctx->bstate = BS_STOP;
5093 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5094 rn = "UserTraceData";
5095 /* Stop translation as we may have switched the execution mode */
5096 ctx->bstate = BS_STOP;
5099 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5100 /* Stop translation as we may have switched the execution mode */
5101 ctx->bstate = BS_STOP;
5112 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5122 gen_helper_mtc0_performance0(cpu_env, arg);
5123 rn = "Performance0";
5126 // gen_helper_mtc0_performance1(arg);
5127 rn = "Performance1";
5130 // gen_helper_mtc0_performance2(arg);
5131 rn = "Performance2";
5134 // gen_helper_mtc0_performance3(arg);
5135 rn = "Performance3";
5138 // gen_helper_mtc0_performance4(arg);
5139 rn = "Performance4";
5142 // gen_helper_mtc0_performance5(arg);
5143 rn = "Performance5";
5146 // gen_helper_mtc0_performance6(arg);
5147 rn = "Performance6";
5150 // gen_helper_mtc0_performance7(arg);
5151 rn = "Performance7";
5177 gen_helper_mtc0_taglo(cpu_env, arg);
5184 gen_helper_mtc0_datalo(cpu_env, arg);
5197 gen_helper_mtc0_taghi(cpu_env, arg);
5204 gen_helper_mtc0_datahi(cpu_env, arg);
5215 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5226 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5232 /* Stop translation as we may have switched the execution mode */
5233 ctx->bstate = BS_STOP;
5238 (void)rn; /* avoid a compiler warning */
5239 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5240 /* For simplicity assume that all writes can cause interrupts. */
5243 ctx->bstate = BS_STOP;
5248 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5249 generate_exception(ctx, EXCP_RI);
5252 #if defined(TARGET_MIPS64)
5253 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5255 const char *rn = "invalid";
5258 check_insn(env, ctx, ISA_MIPS64);
5264 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5268 check_insn(env, ctx, ASE_MT);
5269 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5273 check_insn(env, ctx, ASE_MT);
5274 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5278 check_insn(env, ctx, ASE_MT);
5279 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5289 gen_helper_mfc0_random(arg, cpu_env);
5293 check_insn(env, ctx, ASE_MT);
5294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5298 check_insn(env, ctx, ASE_MT);
5299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5303 check_insn(env, ctx, ASE_MT);
5304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5308 check_insn(env, ctx, ASE_MT);
5309 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5313 check_insn(env, ctx, ASE_MT);
5314 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5318 check_insn(env, ctx, ASE_MT);
5319 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5320 rn = "VPEScheFBack";
5323 check_insn(env, ctx, ASE_MT);
5324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5334 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5338 check_insn(env, ctx, ASE_MT);
5339 gen_helper_mfc0_tcstatus(arg, cpu_env);
5343 check_insn(env, ctx, ASE_MT);
5344 gen_helper_mfc0_tcbind(arg, cpu_env);
5348 check_insn(env, ctx, ASE_MT);
5349 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5353 check_insn(env, ctx, ASE_MT);
5354 gen_helper_dmfc0_tchalt(arg, cpu_env);
5358 check_insn(env, ctx, ASE_MT);
5359 gen_helper_dmfc0_tccontext(arg, cpu_env);
5363 check_insn(env, ctx, ASE_MT);
5364 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5368 check_insn(env, ctx, ASE_MT);
5369 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5379 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5389 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5393 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5394 rn = "ContextConfig";
5403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5407 check_insn(env, ctx, ISA_MIPS32R2);
5408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5422 check_insn(env, ctx, ISA_MIPS32R2);
5423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5427 check_insn(env, ctx, ISA_MIPS32R2);
5428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5432 check_insn(env, ctx, ISA_MIPS32R2);
5433 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5437 check_insn(env, ctx, ISA_MIPS32R2);
5438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5442 check_insn(env, ctx, ISA_MIPS32R2);
5443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5453 check_insn(env, ctx, ISA_MIPS32R2);
5454 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5464 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5474 /* Mark as an IO operation because we read the time. */
5477 gen_helper_mfc0_count(arg, cpu_env);
5481 /* Break the TB to be able to take timer interrupts immediately
5482 after reading count. */
5483 ctx->bstate = BS_STOP;
5486 /* 6,7 are implementation dependent */
5494 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5504 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5507 /* 6,7 are implementation dependent */
5515 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5519 check_insn(env, ctx, ISA_MIPS32R2);
5520 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5524 check_insn(env, ctx, ISA_MIPS32R2);
5525 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5529 check_insn(env, ctx, ISA_MIPS32R2);
5530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5550 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5564 check_insn(env, ctx, ISA_MIPS32R2);
5565 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5579 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5583 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5590 /* 6,7 are implementation dependent */
5592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5606 gen_helper_dmfc0_lladdr(arg, cpu_env);
5616 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5626 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5636 check_insn(env, ctx, ISA_MIPS3);
5637 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5645 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5648 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5656 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5657 rn = "'Diagnostic"; /* implementation dependent */
5662 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5666 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5667 rn = "TraceControl";
5670 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5671 rn = "TraceControl2";
5674 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5675 rn = "UserTraceData";
5678 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5689 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5699 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5700 rn = "Performance0";
5703 // gen_helper_dmfc0_performance1(arg);
5704 rn = "Performance1";
5707 // gen_helper_dmfc0_performance2(arg);
5708 rn = "Performance2";
5711 // gen_helper_dmfc0_performance3(arg);
5712 rn = "Performance3";
5715 // gen_helper_dmfc0_performance4(arg);
5716 rn = "Performance4";
5719 // gen_helper_dmfc0_performance5(arg);
5720 rn = "Performance5";
5723 // gen_helper_dmfc0_performance6(arg);
5724 rn = "Performance6";
5727 // gen_helper_dmfc0_performance7(arg);
5728 rn = "Performance7";
5735 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5742 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5755 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5762 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5775 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5782 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5792 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5803 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5813 (void)rn; /* avoid a compiler warning */
5814 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5818 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5819 generate_exception(ctx, EXCP_RI);
5822 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5824 const char *rn = "invalid";
5827 check_insn(env, ctx, ISA_MIPS64);
5836 gen_helper_mtc0_index(cpu_env, arg);
5840 check_insn(env, ctx, ASE_MT);
5841 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5845 check_insn(env, ctx, ASE_MT);
5850 check_insn(env, ctx, ASE_MT);
5865 check_insn(env, ctx, ASE_MT);
5866 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5870 check_insn(env, ctx, ASE_MT);
5871 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5875 check_insn(env, ctx, ASE_MT);
5876 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5880 check_insn(env, ctx, ASE_MT);
5881 gen_helper_mtc0_yqmask(cpu_env, arg);
5885 check_insn(env, ctx, ASE_MT);
5886 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5890 check_insn(env, ctx, ASE_MT);
5891 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5892 rn = "VPEScheFBack";
5895 check_insn(env, ctx, ASE_MT);
5896 gen_helper_mtc0_vpeopt(cpu_env, arg);
5906 gen_helper_mtc0_entrylo0(cpu_env, arg);
5910 check_insn(env, ctx, ASE_MT);
5911 gen_helper_mtc0_tcstatus(cpu_env, arg);
5915 check_insn(env, ctx, ASE_MT);
5916 gen_helper_mtc0_tcbind(cpu_env, arg);
5920 check_insn(env, ctx, ASE_MT);
5921 gen_helper_mtc0_tcrestart(cpu_env, arg);
5925 check_insn(env, ctx, ASE_MT);
5926 gen_helper_mtc0_tchalt(cpu_env, arg);
5930 check_insn(env, ctx, ASE_MT);
5931 gen_helper_mtc0_tccontext(cpu_env, arg);
5935 check_insn(env, ctx, ASE_MT);
5936 gen_helper_mtc0_tcschedule(cpu_env, arg);
5940 check_insn(env, ctx, ASE_MT);
5941 gen_helper_mtc0_tcschefback(cpu_env, arg);
5951 gen_helper_mtc0_entrylo1(cpu_env, arg);
5961 gen_helper_mtc0_context(cpu_env, arg);
5965 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5966 rn = "ContextConfig";
5975 gen_helper_mtc0_pagemask(cpu_env, arg);
5979 check_insn(env, ctx, ISA_MIPS32R2);
5980 gen_helper_mtc0_pagegrain(cpu_env, arg);
5990 gen_helper_mtc0_wired(cpu_env, arg);
5994 check_insn(env, ctx, ISA_MIPS32R2);
5995 gen_helper_mtc0_srsconf0(cpu_env, arg);
5999 check_insn(env, ctx, ISA_MIPS32R2);
6000 gen_helper_mtc0_srsconf1(cpu_env, arg);
6004 check_insn(env, ctx, ISA_MIPS32R2);
6005 gen_helper_mtc0_srsconf2(cpu_env, arg);
6009 check_insn(env, ctx, ISA_MIPS32R2);
6010 gen_helper_mtc0_srsconf3(cpu_env, arg);
6014 check_insn(env, ctx, ISA_MIPS32R2);
6015 gen_helper_mtc0_srsconf4(cpu_env, arg);
6025 check_insn(env, ctx, ISA_MIPS32R2);
6026 gen_helper_mtc0_hwrena(cpu_env, arg);
6040 gen_helper_mtc0_count(cpu_env, arg);
6043 /* 6,7 are implementation dependent */
6047 /* Stop translation as we may have switched the execution mode */
6048 ctx->bstate = BS_STOP;
6053 gen_helper_mtc0_entryhi(cpu_env, arg);
6063 gen_helper_mtc0_compare(cpu_env, arg);
6066 /* 6,7 are implementation dependent */
6070 /* Stop translation as we may have switched the execution mode */
6071 ctx->bstate = BS_STOP;
6076 save_cpu_state(ctx, 1);
6077 gen_helper_mtc0_status(cpu_env, arg);
6078 /* BS_STOP isn't good enough here, hflags may have changed. */
6079 gen_save_pc(ctx->pc + 4);
6080 ctx->bstate = BS_EXCP;
6084 check_insn(env, ctx, ISA_MIPS32R2);
6085 gen_helper_mtc0_intctl(cpu_env, arg);
6086 /* Stop translation as we may have switched the execution mode */
6087 ctx->bstate = BS_STOP;
6091 check_insn(env, ctx, ISA_MIPS32R2);
6092 gen_helper_mtc0_srsctl(cpu_env, arg);
6093 /* Stop translation as we may have switched the execution mode */
6094 ctx->bstate = BS_STOP;
6098 check_insn(env, ctx, ISA_MIPS32R2);
6099 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6100 /* Stop translation as we may have switched the execution mode */
6101 ctx->bstate = BS_STOP;
6111 save_cpu_state(ctx, 1);
6112 /* Mark as an IO operation because we may trigger a software
6117 gen_helper_mtc0_cause(cpu_env, arg);
6121 /* Stop translation as we may have triggered an intetrupt */
6122 ctx->bstate = BS_STOP;
6132 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6146 check_insn(env, ctx, ISA_MIPS32R2);
6147 gen_helper_mtc0_ebase(cpu_env, arg);
6157 gen_helper_mtc0_config0(cpu_env, arg);
6159 /* Stop translation as we may have switched the execution mode */
6160 ctx->bstate = BS_STOP;
6163 /* ignored, read only */
6167 gen_helper_mtc0_config2(cpu_env, arg);
6169 /* Stop translation as we may have switched the execution mode */
6170 ctx->bstate = BS_STOP;
6176 /* 6,7 are implementation dependent */
6178 rn = "Invalid config selector";
6185 gen_helper_mtc0_lladdr(cpu_env, arg);
6195 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6205 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6215 check_insn(env, ctx, ISA_MIPS3);
6216 gen_helper_mtc0_xcontext(cpu_env, arg);
6224 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6227 gen_helper_mtc0_framemask(cpu_env, arg);
6236 rn = "Diagnostic"; /* implementation dependent */
6241 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6242 /* BS_STOP isn't good enough here, hflags may have changed. */
6243 gen_save_pc(ctx->pc + 4);
6244 ctx->bstate = BS_EXCP;
6248 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6249 /* Stop translation as we may have switched the execution mode */
6250 ctx->bstate = BS_STOP;
6251 rn = "TraceControl";
6254 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6255 /* Stop translation as we may have switched the execution mode */
6256 ctx->bstate = BS_STOP;
6257 rn = "TraceControl2";
6260 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6261 /* Stop translation as we may have switched the execution mode */
6262 ctx->bstate = BS_STOP;
6263 rn = "UserTraceData";
6266 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6267 /* Stop translation as we may have switched the execution mode */
6268 ctx->bstate = BS_STOP;
6279 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6289 gen_helper_mtc0_performance0(cpu_env, arg);
6290 rn = "Performance0";
6293 // gen_helper_mtc0_performance1(cpu_env, arg);
6294 rn = "Performance1";
6297 // gen_helper_mtc0_performance2(cpu_env, arg);
6298 rn = "Performance2";
6301 // gen_helper_mtc0_performance3(cpu_env, arg);
6302 rn = "Performance3";
6305 // gen_helper_mtc0_performance4(cpu_env, arg);
6306 rn = "Performance4";
6309 // gen_helper_mtc0_performance5(cpu_env, arg);
6310 rn = "Performance5";
6313 // gen_helper_mtc0_performance6(cpu_env, arg);
6314 rn = "Performance6";
6317 // gen_helper_mtc0_performance7(cpu_env, arg);
6318 rn = "Performance7";
6344 gen_helper_mtc0_taglo(cpu_env, arg);
6351 gen_helper_mtc0_datalo(cpu_env, arg);
6364 gen_helper_mtc0_taghi(cpu_env, arg);
6371 gen_helper_mtc0_datahi(cpu_env, arg);
6382 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6393 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6399 /* Stop translation as we may have switched the execution mode */
6400 ctx->bstate = BS_STOP;
6405 (void)rn; /* avoid a compiler warning */
6406 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6407 /* For simplicity assume that all writes can cause interrupts. */
6410 ctx->bstate = BS_STOP;
6415 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6416 generate_exception(ctx, EXCP_RI);
6418 #endif /* TARGET_MIPS64 */
6420 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6421 int u, int sel, int h)
6423 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6424 TCGv t0 = tcg_temp_local_new();
6426 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6427 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6428 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6429 tcg_gen_movi_tl(t0, -1);
6430 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6431 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6432 tcg_gen_movi_tl(t0, -1);
6438 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6441 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6451 gen_helper_mftc0_tcstatus(t0, cpu_env);
6454 gen_helper_mftc0_tcbind(t0, cpu_env);
6457 gen_helper_mftc0_tcrestart(t0, cpu_env);
6460 gen_helper_mftc0_tchalt(t0, cpu_env);
6463 gen_helper_mftc0_tccontext(t0, cpu_env);
6466 gen_helper_mftc0_tcschedule(t0, cpu_env);
6469 gen_helper_mftc0_tcschefback(t0, cpu_env);
6472 gen_mfc0(env, ctx, t0, rt, sel);
6479 gen_helper_mftc0_entryhi(t0, cpu_env);
6482 gen_mfc0(env, ctx, t0, rt, sel);
6488 gen_helper_mftc0_status(t0, cpu_env);
6491 gen_mfc0(env, ctx, t0, rt, sel);
6497 gen_helper_mftc0_cause(t0, cpu_env);
6507 gen_helper_mftc0_epc(t0, cpu_env);
6517 gen_helper_mftc0_ebase(t0, cpu_env);
6527 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6537 gen_helper_mftc0_debug(t0, cpu_env);
6540 gen_mfc0(env, ctx, t0, rt, sel);
6545 gen_mfc0(env, ctx, t0, rt, sel);
6547 } else switch (sel) {
6548 /* GPR registers. */
6550 gen_helper_1e0i(mftgpr, t0, rt);
6552 /* Auxiliary CPU registers */
6556 gen_helper_1e0i(mftlo, t0, 0);
6559 gen_helper_1e0i(mfthi, t0, 0);
6562 gen_helper_1e0i(mftacx, t0, 0);
6565 gen_helper_1e0i(mftlo, t0, 1);
6568 gen_helper_1e0i(mfthi, t0, 1);
6571 gen_helper_1e0i(mftacx, t0, 1);
6574 gen_helper_1e0i(mftlo, t0, 2);
6577 gen_helper_1e0i(mfthi, t0, 2);
6580 gen_helper_1e0i(mftacx, t0, 2);
6583 gen_helper_1e0i(mftlo, t0, 3);
6586 gen_helper_1e0i(mfthi, t0, 3);
6589 gen_helper_1e0i(mftacx, t0, 3);
6592 gen_helper_mftdsp(t0, cpu_env);
6598 /* Floating point (COP1). */
6600 /* XXX: For now we support only a single FPU context. */
6602 TCGv_i32 fp0 = tcg_temp_new_i32();
6604 gen_load_fpr32(fp0, rt);
6605 tcg_gen_ext_i32_tl(t0, fp0);
6606 tcg_temp_free_i32(fp0);
6608 TCGv_i32 fp0 = tcg_temp_new_i32();
6610 gen_load_fpr32h(fp0, rt);
6611 tcg_gen_ext_i32_tl(t0, fp0);
6612 tcg_temp_free_i32(fp0);
6616 /* XXX: For now we support only a single FPU context. */
6617 gen_helper_1e0i(cfc1, t0, rt);
6619 /* COP2: Not implemented. */
6626 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6627 gen_store_gpr(t0, rd);
6633 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6634 generate_exception(ctx, EXCP_RI);
6637 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6638 int u, int sel, int h)
6640 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6641 TCGv t0 = tcg_temp_local_new();
6643 gen_load_gpr(t0, rt);
6644 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6645 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6646 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6648 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6649 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6656 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6659 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6669 gen_helper_mttc0_tcstatus(cpu_env, t0);
6672 gen_helper_mttc0_tcbind(cpu_env, t0);
6675 gen_helper_mttc0_tcrestart(cpu_env, t0);
6678 gen_helper_mttc0_tchalt(cpu_env, t0);
6681 gen_helper_mttc0_tccontext(cpu_env, t0);
6684 gen_helper_mttc0_tcschedule(cpu_env, t0);
6687 gen_helper_mttc0_tcschefback(cpu_env, t0);
6690 gen_mtc0(env, ctx, t0, rd, sel);
6697 gen_helper_mttc0_entryhi(cpu_env, t0);
6700 gen_mtc0(env, ctx, t0, rd, sel);
6706 gen_helper_mttc0_status(cpu_env, t0);
6709 gen_mtc0(env, ctx, t0, rd, sel);
6715 gen_helper_mttc0_cause(cpu_env, t0);
6725 gen_helper_mttc0_ebase(cpu_env, t0);
6735 gen_helper_mttc0_debug(cpu_env, t0);
6738 gen_mtc0(env, ctx, t0, rd, sel);
6743 gen_mtc0(env, ctx, t0, rd, sel);
6745 } else switch (sel) {
6746 /* GPR registers. */
6748 gen_helper_0e1i(mttgpr, t0, rd);
6750 /* Auxiliary CPU registers */
6754 gen_helper_0e1i(mttlo, t0, 0);
6757 gen_helper_0e1i(mtthi, t0, 0);
6760 gen_helper_0e1i(mttacx, t0, 0);
6763 gen_helper_0e1i(mttlo, t0, 1);
6766 gen_helper_0e1i(mtthi, t0, 1);
6769 gen_helper_0e1i(mttacx, t0, 1);
6772 gen_helper_0e1i(mttlo, t0, 2);
6775 gen_helper_0e1i(mtthi, t0, 2);
6778 gen_helper_0e1i(mttacx, t0, 2);
6781 gen_helper_0e1i(mttlo, t0, 3);
6784 gen_helper_0e1i(mtthi, t0, 3);
6787 gen_helper_0e1i(mttacx, t0, 3);
6790 gen_helper_mttdsp(cpu_env, t0);
6796 /* Floating point (COP1). */
6798 /* XXX: For now we support only a single FPU context. */
6800 TCGv_i32 fp0 = tcg_temp_new_i32();
6802 tcg_gen_trunc_tl_i32(fp0, t0);
6803 gen_store_fpr32(fp0, rd);
6804 tcg_temp_free_i32(fp0);
6806 TCGv_i32 fp0 = tcg_temp_new_i32();
6808 tcg_gen_trunc_tl_i32(fp0, t0);
6809 gen_store_fpr32h(fp0, rd);
6810 tcg_temp_free_i32(fp0);
6814 /* XXX: For now we support only a single FPU context. */
6815 gen_helper_0e1i(ctc1, t0, rd);
6817 /* COP2: Not implemented. */
6824 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6830 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6831 generate_exception(ctx, EXCP_RI);
6834 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6836 const char *opn = "ldst";
6838 check_cp0_enabled(ctx);
6845 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6850 TCGv t0 = tcg_temp_new();
6852 gen_load_gpr(t0, rt);
6853 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6858 #if defined(TARGET_MIPS64)
6860 check_insn(env, ctx, ISA_MIPS3);
6865 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6869 check_insn(env, ctx, ISA_MIPS3);
6871 TCGv t0 = tcg_temp_new();
6873 gen_load_gpr(t0, rt);
6874 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6881 check_insn(env, ctx, ASE_MT);
6886 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6887 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6891 check_insn(env, ctx, ASE_MT);
6892 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6893 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6898 if (!env->tlb->helper_tlbwi)
6900 gen_helper_tlbwi(cpu_env);
6904 if (!env->tlb->helper_tlbwr)
6906 gen_helper_tlbwr(cpu_env);
6910 if (!env->tlb->helper_tlbp)
6912 gen_helper_tlbp(cpu_env);
6916 if (!env->tlb->helper_tlbr)
6918 gen_helper_tlbr(cpu_env);
6922 check_insn(env, ctx, ISA_MIPS2);
6923 gen_helper_eret(cpu_env);
6924 ctx->bstate = BS_EXCP;
6928 check_insn(env, ctx, ISA_MIPS32);
6929 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6931 generate_exception(ctx, EXCP_RI);
6933 gen_helper_deret(cpu_env);
6934 ctx->bstate = BS_EXCP;
6939 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6940 /* If we get an exception, we want to restart at next instruction */
6942 save_cpu_state(ctx, 1);
6944 gen_helper_wait(cpu_env);
6945 ctx->bstate = BS_EXCP;
6950 generate_exception(ctx, EXCP_RI);
6953 (void)opn; /* avoid a compiler warning */
6954 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6956 #endif /* !CONFIG_USER_ONLY */
6958 /* CP1 Branches (before delay slot) */
6959 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
6960 int32_t cc, int32_t offset)
6962 target_ulong btarget;
6963 const char *opn = "cp1 cond branch";
6964 TCGv_i32 t0 = tcg_temp_new_i32();
6967 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6969 btarget = ctx->pc + 4 + offset;
6973 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6974 tcg_gen_not_i32(t0, t0);
6975 tcg_gen_andi_i32(t0, t0, 1);
6976 tcg_gen_extu_i32_tl(bcond, t0);
6980 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6981 tcg_gen_not_i32(t0, t0);
6982 tcg_gen_andi_i32(t0, t0, 1);
6983 tcg_gen_extu_i32_tl(bcond, t0);
6987 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6988 tcg_gen_andi_i32(t0, t0, 1);
6989 tcg_gen_extu_i32_tl(bcond, t0);
6993 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6994 tcg_gen_andi_i32(t0, t0, 1);
6995 tcg_gen_extu_i32_tl(bcond, t0);
6998 ctx->hflags |= MIPS_HFLAG_BL;
7002 TCGv_i32 t1 = tcg_temp_new_i32();
7003 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7004 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7005 tcg_gen_nand_i32(t0, t0, t1);
7006 tcg_temp_free_i32(t1);
7007 tcg_gen_andi_i32(t0, t0, 1);
7008 tcg_gen_extu_i32_tl(bcond, t0);
7014 TCGv_i32 t1 = tcg_temp_new_i32();
7015 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7016 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7017 tcg_gen_or_i32(t0, t0, t1);
7018 tcg_temp_free_i32(t1);
7019 tcg_gen_andi_i32(t0, t0, 1);
7020 tcg_gen_extu_i32_tl(bcond, t0);
7026 TCGv_i32 t1 = tcg_temp_new_i32();
7027 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7028 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7029 tcg_gen_and_i32(t0, t0, t1);
7030 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7031 tcg_gen_and_i32(t0, t0, t1);
7032 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7033 tcg_gen_nand_i32(t0, t0, t1);
7034 tcg_temp_free_i32(t1);
7035 tcg_gen_andi_i32(t0, t0, 1);
7036 tcg_gen_extu_i32_tl(bcond, t0);
7042 TCGv_i32 t1 = tcg_temp_new_i32();
7043 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7044 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7045 tcg_gen_or_i32(t0, t0, t1);
7046 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7047 tcg_gen_or_i32(t0, t0, t1);
7048 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7049 tcg_gen_or_i32(t0, t0, t1);
7050 tcg_temp_free_i32(t1);
7051 tcg_gen_andi_i32(t0, t0, 1);
7052 tcg_gen_extu_i32_tl(bcond, t0);
7056 ctx->hflags |= MIPS_HFLAG_BC;
7060 generate_exception (ctx, EXCP_RI);
7063 (void)opn; /* avoid a compiler warning */
7064 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7065 ctx->hflags, btarget);
7066 ctx->btarget = btarget;
7069 tcg_temp_free_i32(t0);
7072 /* Coprocessor 1 (FPU) */
7074 #define FOP(func, fmt) (((fmt) << 21) | (func))
7077 OPC_ADD_S = FOP(0, FMT_S),
7078 OPC_SUB_S = FOP(1, FMT_S),
7079 OPC_MUL_S = FOP(2, FMT_S),
7080 OPC_DIV_S = FOP(3, FMT_S),
7081 OPC_SQRT_S = FOP(4, FMT_S),
7082 OPC_ABS_S = FOP(5, FMT_S),
7083 OPC_MOV_S = FOP(6, FMT_S),
7084 OPC_NEG_S = FOP(7, FMT_S),
7085 OPC_ROUND_L_S = FOP(8, FMT_S),
7086 OPC_TRUNC_L_S = FOP(9, FMT_S),
7087 OPC_CEIL_L_S = FOP(10, FMT_S),
7088 OPC_FLOOR_L_S = FOP(11, FMT_S),
7089 OPC_ROUND_W_S = FOP(12, FMT_S),
7090 OPC_TRUNC_W_S = FOP(13, FMT_S),
7091 OPC_CEIL_W_S = FOP(14, FMT_S),
7092 OPC_FLOOR_W_S = FOP(15, FMT_S),
7093 OPC_MOVCF_S = FOP(17, FMT_S),
7094 OPC_MOVZ_S = FOP(18, FMT_S),
7095 OPC_MOVN_S = FOP(19, FMT_S),
7096 OPC_RECIP_S = FOP(21, FMT_S),
7097 OPC_RSQRT_S = FOP(22, FMT_S),
7098 OPC_RECIP2_S = FOP(28, FMT_S),
7099 OPC_RECIP1_S = FOP(29, FMT_S),
7100 OPC_RSQRT1_S = FOP(30, FMT_S),
7101 OPC_RSQRT2_S = FOP(31, FMT_S),
7102 OPC_CVT_D_S = FOP(33, FMT_S),
7103 OPC_CVT_W_S = FOP(36, FMT_S),
7104 OPC_CVT_L_S = FOP(37, FMT_S),
7105 OPC_CVT_PS_S = FOP(38, FMT_S),
7106 OPC_CMP_F_S = FOP (48, FMT_S),
7107 OPC_CMP_UN_S = FOP (49, FMT_S),
7108 OPC_CMP_EQ_S = FOP (50, FMT_S),
7109 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7110 OPC_CMP_OLT_S = FOP (52, FMT_S),
7111 OPC_CMP_ULT_S = FOP (53, FMT_S),
7112 OPC_CMP_OLE_S = FOP (54, FMT_S),
7113 OPC_CMP_ULE_S = FOP (55, FMT_S),
7114 OPC_CMP_SF_S = FOP (56, FMT_S),
7115 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7116 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7117 OPC_CMP_NGL_S = FOP (59, FMT_S),
7118 OPC_CMP_LT_S = FOP (60, FMT_S),
7119 OPC_CMP_NGE_S = FOP (61, FMT_S),
7120 OPC_CMP_LE_S = FOP (62, FMT_S),
7121 OPC_CMP_NGT_S = FOP (63, FMT_S),
7123 OPC_ADD_D = FOP(0, FMT_D),
7124 OPC_SUB_D = FOP(1, FMT_D),
7125 OPC_MUL_D = FOP(2, FMT_D),
7126 OPC_DIV_D = FOP(3, FMT_D),
7127 OPC_SQRT_D = FOP(4, FMT_D),
7128 OPC_ABS_D = FOP(5, FMT_D),
7129 OPC_MOV_D = FOP(6, FMT_D),
7130 OPC_NEG_D = FOP(7, FMT_D),
7131 OPC_ROUND_L_D = FOP(8, FMT_D),
7132 OPC_TRUNC_L_D = FOP(9, FMT_D),
7133 OPC_CEIL_L_D = FOP(10, FMT_D),
7134 OPC_FLOOR_L_D = FOP(11, FMT_D),
7135 OPC_ROUND_W_D = FOP(12, FMT_D),
7136 OPC_TRUNC_W_D = FOP(13, FMT_D),
7137 OPC_CEIL_W_D = FOP(14, FMT_D),
7138 OPC_FLOOR_W_D = FOP(15, FMT_D),
7139 OPC_MOVCF_D = FOP(17, FMT_D),
7140 OPC_MOVZ_D = FOP(18, FMT_D),
7141 OPC_MOVN_D = FOP(19, FMT_D),
7142 OPC_RECIP_D = FOP(21, FMT_D),
7143 OPC_RSQRT_D = FOP(22, FMT_D),
7144 OPC_RECIP2_D = FOP(28, FMT_D),
7145 OPC_RECIP1_D = FOP(29, FMT_D),
7146 OPC_RSQRT1_D = FOP(30, FMT_D),
7147 OPC_RSQRT2_D = FOP(31, FMT_D),
7148 OPC_CVT_S_D = FOP(32, FMT_D),
7149 OPC_CVT_W_D = FOP(36, FMT_D),
7150 OPC_CVT_L_D = FOP(37, FMT_D),
7151 OPC_CMP_F_D = FOP (48, FMT_D),
7152 OPC_CMP_UN_D = FOP (49, FMT_D),
7153 OPC_CMP_EQ_D = FOP (50, FMT_D),
7154 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7155 OPC_CMP_OLT_D = FOP (52, FMT_D),
7156 OPC_CMP_ULT_D = FOP (53, FMT_D),
7157 OPC_CMP_OLE_D = FOP (54, FMT_D),
7158 OPC_CMP_ULE_D = FOP (55, FMT_D),
7159 OPC_CMP_SF_D = FOP (56, FMT_D),
7160 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7161 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7162 OPC_CMP_NGL_D = FOP (59, FMT_D),
7163 OPC_CMP_LT_D = FOP (60, FMT_D),
7164 OPC_CMP_NGE_D = FOP (61, FMT_D),
7165 OPC_CMP_LE_D = FOP (62, FMT_D),
7166 OPC_CMP_NGT_D = FOP (63, FMT_D),
7168 OPC_CVT_S_W = FOP(32, FMT_W),
7169 OPC_CVT_D_W = FOP(33, FMT_W),
7170 OPC_CVT_S_L = FOP(32, FMT_L),
7171 OPC_CVT_D_L = FOP(33, FMT_L),
7172 OPC_CVT_PS_PW = FOP(38, FMT_W),
7174 OPC_ADD_PS = FOP(0, FMT_PS),
7175 OPC_SUB_PS = FOP(1, FMT_PS),
7176 OPC_MUL_PS = FOP(2, FMT_PS),
7177 OPC_DIV_PS = FOP(3, FMT_PS),
7178 OPC_ABS_PS = FOP(5, FMT_PS),
7179 OPC_MOV_PS = FOP(6, FMT_PS),
7180 OPC_NEG_PS = FOP(7, FMT_PS),
7181 OPC_MOVCF_PS = FOP(17, FMT_PS),
7182 OPC_MOVZ_PS = FOP(18, FMT_PS),
7183 OPC_MOVN_PS = FOP(19, FMT_PS),
7184 OPC_ADDR_PS = FOP(24, FMT_PS),
7185 OPC_MULR_PS = FOP(26, FMT_PS),
7186 OPC_RECIP2_PS = FOP(28, FMT_PS),
7187 OPC_RECIP1_PS = FOP(29, FMT_PS),
7188 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7189 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7191 OPC_CVT_S_PU = FOP(32, FMT_PS),
7192 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7193 OPC_CVT_S_PL = FOP(40, FMT_PS),
7194 OPC_PLL_PS = FOP(44, FMT_PS),
7195 OPC_PLU_PS = FOP(45, FMT_PS),
7196 OPC_PUL_PS = FOP(46, FMT_PS),
7197 OPC_PUU_PS = FOP(47, FMT_PS),
7198 OPC_CMP_F_PS = FOP (48, FMT_PS),
7199 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7200 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7201 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7202 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7203 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7204 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7205 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7206 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7207 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7208 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7209 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7210 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7211 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7212 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7213 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7216 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7218 const char *opn = "cp1 move";
7219 TCGv t0 = tcg_temp_new();
7224 TCGv_i32 fp0 = tcg_temp_new_i32();
7226 gen_load_fpr32(fp0, fs);
7227 tcg_gen_ext_i32_tl(t0, fp0);
7228 tcg_temp_free_i32(fp0);
7230 gen_store_gpr(t0, rt);
7234 gen_load_gpr(t0, rt);
7236 TCGv_i32 fp0 = tcg_temp_new_i32();
7238 tcg_gen_trunc_tl_i32(fp0, t0);
7239 gen_store_fpr32(fp0, fs);
7240 tcg_temp_free_i32(fp0);
7245 gen_helper_1e0i(cfc1, t0, fs);
7246 gen_store_gpr(t0, rt);
7250 gen_load_gpr(t0, rt);
7251 gen_helper_0e1i(ctc1, t0, fs);
7254 #if defined(TARGET_MIPS64)
7256 gen_load_fpr64(ctx, t0, fs);
7257 gen_store_gpr(t0, rt);
7261 gen_load_gpr(t0, rt);
7262 gen_store_fpr64(ctx, t0, fs);
7268 TCGv_i32 fp0 = tcg_temp_new_i32();
7270 gen_load_fpr32h(fp0, fs);
7271 tcg_gen_ext_i32_tl(t0, fp0);
7272 tcg_temp_free_i32(fp0);
7274 gen_store_gpr(t0, rt);
7278 gen_load_gpr(t0, rt);
7280 TCGv_i32 fp0 = tcg_temp_new_i32();
7282 tcg_gen_trunc_tl_i32(fp0, t0);
7283 gen_store_fpr32h(fp0, fs);
7284 tcg_temp_free_i32(fp0);
7290 generate_exception (ctx, EXCP_RI);
7293 (void)opn; /* avoid a compiler warning */
7294 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7300 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7316 l1 = gen_new_label();
7317 t0 = tcg_temp_new_i32();
7318 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7319 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7320 tcg_temp_free_i32(t0);
7322 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7324 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7329 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7332 TCGv_i32 t0 = tcg_temp_new_i32();
7333 int l1 = gen_new_label();
7340 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7341 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7342 gen_load_fpr32(t0, fs);
7343 gen_store_fpr32(t0, fd);
7345 tcg_temp_free_i32(t0);
7348 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7351 TCGv_i32 t0 = tcg_temp_new_i32();
7353 int l1 = gen_new_label();
7360 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7361 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7362 tcg_temp_free_i32(t0);
7363 fp0 = tcg_temp_new_i64();
7364 gen_load_fpr64(ctx, fp0, fs);
7365 gen_store_fpr64(ctx, fp0, fd);
7366 tcg_temp_free_i64(fp0);
7370 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7373 TCGv_i32 t0 = tcg_temp_new_i32();
7374 int l1 = gen_new_label();
7375 int l2 = 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);
7388 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7389 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7390 gen_load_fpr32h(t0, fs);
7391 gen_store_fpr32h(t0, fd);
7392 tcg_temp_free_i32(t0);
7397 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7398 int ft, int fs, int fd, int cc)
7400 const char *opn = "farith";
7401 const char *condnames[] = {
7419 const char *condnames_abs[] = {
7437 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7438 uint32_t func = ctx->opcode & 0x3f;
7443 TCGv_i32 fp0 = tcg_temp_new_i32();
7444 TCGv_i32 fp1 = tcg_temp_new_i32();
7446 gen_load_fpr32(fp0, fs);
7447 gen_load_fpr32(fp1, ft);
7448 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7449 tcg_temp_free_i32(fp1);
7450 gen_store_fpr32(fp0, fd);
7451 tcg_temp_free_i32(fp0);
7458 TCGv_i32 fp0 = tcg_temp_new_i32();
7459 TCGv_i32 fp1 = tcg_temp_new_i32();
7461 gen_load_fpr32(fp0, fs);
7462 gen_load_fpr32(fp1, ft);
7463 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7464 tcg_temp_free_i32(fp1);
7465 gen_store_fpr32(fp0, fd);
7466 tcg_temp_free_i32(fp0);
7473 TCGv_i32 fp0 = tcg_temp_new_i32();
7474 TCGv_i32 fp1 = tcg_temp_new_i32();
7476 gen_load_fpr32(fp0, fs);
7477 gen_load_fpr32(fp1, ft);
7478 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7479 tcg_temp_free_i32(fp1);
7480 gen_store_fpr32(fp0, fd);
7481 tcg_temp_free_i32(fp0);
7488 TCGv_i32 fp0 = tcg_temp_new_i32();
7489 TCGv_i32 fp1 = tcg_temp_new_i32();
7491 gen_load_fpr32(fp0, fs);
7492 gen_load_fpr32(fp1, ft);
7493 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7494 tcg_temp_free_i32(fp1);
7495 gen_store_fpr32(fp0, fd);
7496 tcg_temp_free_i32(fp0);
7503 TCGv_i32 fp0 = tcg_temp_new_i32();
7505 gen_load_fpr32(fp0, fs);
7506 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7507 gen_store_fpr32(fp0, fd);
7508 tcg_temp_free_i32(fp0);
7514 TCGv_i32 fp0 = tcg_temp_new_i32();
7516 gen_load_fpr32(fp0, fs);
7517 gen_helper_float_abs_s(fp0, fp0);
7518 gen_store_fpr32(fp0, fd);
7519 tcg_temp_free_i32(fp0);
7525 TCGv_i32 fp0 = tcg_temp_new_i32();
7527 gen_load_fpr32(fp0, fs);
7528 gen_store_fpr32(fp0, fd);
7529 tcg_temp_free_i32(fp0);
7535 TCGv_i32 fp0 = tcg_temp_new_i32();
7537 gen_load_fpr32(fp0, fs);
7538 gen_helper_float_chs_s(fp0, fp0);
7539 gen_store_fpr32(fp0, fd);
7540 tcg_temp_free_i32(fp0);
7545 check_cp1_64bitmode(ctx);
7547 TCGv_i32 fp32 = tcg_temp_new_i32();
7548 TCGv_i64 fp64 = tcg_temp_new_i64();
7550 gen_load_fpr32(fp32, fs);
7551 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7552 tcg_temp_free_i32(fp32);
7553 gen_store_fpr64(ctx, fp64, fd);
7554 tcg_temp_free_i64(fp64);
7559 check_cp1_64bitmode(ctx);
7561 TCGv_i32 fp32 = tcg_temp_new_i32();
7562 TCGv_i64 fp64 = tcg_temp_new_i64();
7564 gen_load_fpr32(fp32, fs);
7565 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7566 tcg_temp_free_i32(fp32);
7567 gen_store_fpr64(ctx, fp64, fd);
7568 tcg_temp_free_i64(fp64);
7573 check_cp1_64bitmode(ctx);
7575 TCGv_i32 fp32 = tcg_temp_new_i32();
7576 TCGv_i64 fp64 = tcg_temp_new_i64();
7578 gen_load_fpr32(fp32, fs);
7579 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7580 tcg_temp_free_i32(fp32);
7581 gen_store_fpr64(ctx, fp64, fd);
7582 tcg_temp_free_i64(fp64);
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_floorl_s(fp64, cpu_env, fp32);
7594 tcg_temp_free_i32(fp32);
7595 gen_store_fpr64(ctx, fp64, fd);
7596 tcg_temp_free_i64(fp64);
7602 TCGv_i32 fp0 = tcg_temp_new_i32();
7604 gen_load_fpr32(fp0, fs);
7605 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7606 gen_store_fpr32(fp0, fd);
7607 tcg_temp_free_i32(fp0);
7613 TCGv_i32 fp0 = tcg_temp_new_i32();
7615 gen_load_fpr32(fp0, fs);
7616 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7617 gen_store_fpr32(fp0, fd);
7618 tcg_temp_free_i32(fp0);
7624 TCGv_i32 fp0 = tcg_temp_new_i32();
7626 gen_load_fpr32(fp0, fs);
7627 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7628 gen_store_fpr32(fp0, fd);
7629 tcg_temp_free_i32(fp0);
7635 TCGv_i32 fp0 = tcg_temp_new_i32();
7637 gen_load_fpr32(fp0, fs);
7638 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7639 gen_store_fpr32(fp0, fd);
7640 tcg_temp_free_i32(fp0);
7645 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7650 int l1 = gen_new_label();
7654 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7656 fp0 = tcg_temp_new_i32();
7657 gen_load_fpr32(fp0, fs);
7658 gen_store_fpr32(fp0, fd);
7659 tcg_temp_free_i32(fp0);
7666 int l1 = gen_new_label();
7670 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7671 fp0 = tcg_temp_new_i32();
7672 gen_load_fpr32(fp0, fs);
7673 gen_store_fpr32(fp0, fd);
7674 tcg_temp_free_i32(fp0);
7683 TCGv_i32 fp0 = tcg_temp_new_i32();
7685 gen_load_fpr32(fp0, fs);
7686 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7687 gen_store_fpr32(fp0, fd);
7688 tcg_temp_free_i32(fp0);
7695 TCGv_i32 fp0 = tcg_temp_new_i32();
7697 gen_load_fpr32(fp0, fs);
7698 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7699 gen_store_fpr32(fp0, fd);
7700 tcg_temp_free_i32(fp0);
7705 check_cp1_64bitmode(ctx);
7707 TCGv_i32 fp0 = tcg_temp_new_i32();
7708 TCGv_i32 fp1 = tcg_temp_new_i32();
7710 gen_load_fpr32(fp0, fs);
7711 gen_load_fpr32(fp1, ft);
7712 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7713 tcg_temp_free_i32(fp1);
7714 gen_store_fpr32(fp0, fd);
7715 tcg_temp_free_i32(fp0);
7720 check_cp1_64bitmode(ctx);
7722 TCGv_i32 fp0 = tcg_temp_new_i32();
7724 gen_load_fpr32(fp0, fs);
7725 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7726 gen_store_fpr32(fp0, fd);
7727 tcg_temp_free_i32(fp0);
7732 check_cp1_64bitmode(ctx);
7734 TCGv_i32 fp0 = tcg_temp_new_i32();
7736 gen_load_fpr32(fp0, fs);
7737 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7738 gen_store_fpr32(fp0, fd);
7739 tcg_temp_free_i32(fp0);
7744 check_cp1_64bitmode(ctx);
7746 TCGv_i32 fp0 = tcg_temp_new_i32();
7747 TCGv_i32 fp1 = tcg_temp_new_i32();
7749 gen_load_fpr32(fp0, fs);
7750 gen_load_fpr32(fp1, ft);
7751 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7752 tcg_temp_free_i32(fp1);
7753 gen_store_fpr32(fp0, fd);
7754 tcg_temp_free_i32(fp0);
7759 check_cp1_registers(ctx, fd);
7761 TCGv_i32 fp32 = tcg_temp_new_i32();
7762 TCGv_i64 fp64 = tcg_temp_new_i64();
7764 gen_load_fpr32(fp32, fs);
7765 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7766 tcg_temp_free_i32(fp32);
7767 gen_store_fpr64(ctx, fp64, fd);
7768 tcg_temp_free_i64(fp64);
7774 TCGv_i32 fp0 = tcg_temp_new_i32();
7776 gen_load_fpr32(fp0, fs);
7777 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7778 gen_store_fpr32(fp0, fd);
7779 tcg_temp_free_i32(fp0);
7784 check_cp1_64bitmode(ctx);
7786 TCGv_i32 fp32 = tcg_temp_new_i32();
7787 TCGv_i64 fp64 = tcg_temp_new_i64();
7789 gen_load_fpr32(fp32, fs);
7790 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7791 tcg_temp_free_i32(fp32);
7792 gen_store_fpr64(ctx, fp64, fd);
7793 tcg_temp_free_i64(fp64);
7798 check_cp1_64bitmode(ctx);
7800 TCGv_i64 fp64 = tcg_temp_new_i64();
7801 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7802 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7804 gen_load_fpr32(fp32_0, fs);
7805 gen_load_fpr32(fp32_1, ft);
7806 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7807 tcg_temp_free_i32(fp32_1);
7808 tcg_temp_free_i32(fp32_0);
7809 gen_store_fpr64(ctx, fp64, fd);
7810 tcg_temp_free_i64(fp64);
7823 case OPC_CMP_NGLE_S:
7830 if (ctx->opcode & (1 << 6)) {
7831 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7832 opn = condnames_abs[func-48];
7834 gen_cmp_s(ctx, func-48, ft, fs, cc);
7835 opn = condnames[func-48];
7839 check_cp1_registers(ctx, fs | ft | fd);
7841 TCGv_i64 fp0 = tcg_temp_new_i64();
7842 TCGv_i64 fp1 = tcg_temp_new_i64();
7844 gen_load_fpr64(ctx, fp0, fs);
7845 gen_load_fpr64(ctx, fp1, ft);
7846 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7847 tcg_temp_free_i64(fp1);
7848 gen_store_fpr64(ctx, fp0, fd);
7849 tcg_temp_free_i64(fp0);
7855 check_cp1_registers(ctx, fs | ft | fd);
7857 TCGv_i64 fp0 = tcg_temp_new_i64();
7858 TCGv_i64 fp1 = tcg_temp_new_i64();
7860 gen_load_fpr64(ctx, fp0, fs);
7861 gen_load_fpr64(ctx, fp1, ft);
7862 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7863 tcg_temp_free_i64(fp1);
7864 gen_store_fpr64(ctx, fp0, fd);
7865 tcg_temp_free_i64(fp0);
7871 check_cp1_registers(ctx, fs | ft | fd);
7873 TCGv_i64 fp0 = tcg_temp_new_i64();
7874 TCGv_i64 fp1 = tcg_temp_new_i64();
7876 gen_load_fpr64(ctx, fp0, fs);
7877 gen_load_fpr64(ctx, fp1, ft);
7878 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7879 tcg_temp_free_i64(fp1);
7880 gen_store_fpr64(ctx, fp0, fd);
7881 tcg_temp_free_i64(fp0);
7887 check_cp1_registers(ctx, fs | ft | fd);
7889 TCGv_i64 fp0 = tcg_temp_new_i64();
7890 TCGv_i64 fp1 = tcg_temp_new_i64();
7892 gen_load_fpr64(ctx, fp0, fs);
7893 gen_load_fpr64(ctx, fp1, ft);
7894 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7895 tcg_temp_free_i64(fp1);
7896 gen_store_fpr64(ctx, fp0, fd);
7897 tcg_temp_free_i64(fp0);
7903 check_cp1_registers(ctx, fs | fd);
7905 TCGv_i64 fp0 = tcg_temp_new_i64();
7907 gen_load_fpr64(ctx, fp0, fs);
7908 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7909 gen_store_fpr64(ctx, fp0, fd);
7910 tcg_temp_free_i64(fp0);
7915 check_cp1_registers(ctx, fs | fd);
7917 TCGv_i64 fp0 = tcg_temp_new_i64();
7919 gen_load_fpr64(ctx, fp0, fs);
7920 gen_helper_float_abs_d(fp0, fp0);
7921 gen_store_fpr64(ctx, fp0, fd);
7922 tcg_temp_free_i64(fp0);
7927 check_cp1_registers(ctx, fs | fd);
7929 TCGv_i64 fp0 = tcg_temp_new_i64();
7931 gen_load_fpr64(ctx, fp0, fs);
7932 gen_store_fpr64(ctx, fp0, fd);
7933 tcg_temp_free_i64(fp0);
7938 check_cp1_registers(ctx, fs | fd);
7940 TCGv_i64 fp0 = tcg_temp_new_i64();
7942 gen_load_fpr64(ctx, fp0, fs);
7943 gen_helper_float_chs_d(fp0, fp0);
7944 gen_store_fpr64(ctx, fp0, fd);
7945 tcg_temp_free_i64(fp0);
7950 check_cp1_64bitmode(ctx);
7952 TCGv_i64 fp0 = tcg_temp_new_i64();
7954 gen_load_fpr64(ctx, fp0, fs);
7955 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7956 gen_store_fpr64(ctx, fp0, fd);
7957 tcg_temp_free_i64(fp0);
7962 check_cp1_64bitmode(ctx);
7964 TCGv_i64 fp0 = tcg_temp_new_i64();
7966 gen_load_fpr64(ctx, fp0, fs);
7967 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7968 gen_store_fpr64(ctx, fp0, fd);
7969 tcg_temp_free_i64(fp0);
7974 check_cp1_64bitmode(ctx);
7976 TCGv_i64 fp0 = tcg_temp_new_i64();
7978 gen_load_fpr64(ctx, fp0, fs);
7979 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
7980 gen_store_fpr64(ctx, fp0, fd);
7981 tcg_temp_free_i64(fp0);
7986 check_cp1_64bitmode(ctx);
7988 TCGv_i64 fp0 = tcg_temp_new_i64();
7990 gen_load_fpr64(ctx, fp0, fs);
7991 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
7992 gen_store_fpr64(ctx, fp0, fd);
7993 tcg_temp_free_i64(fp0);
7998 check_cp1_registers(ctx, fs);
8000 TCGv_i32 fp32 = tcg_temp_new_i32();
8001 TCGv_i64 fp64 = tcg_temp_new_i64();
8003 gen_load_fpr64(ctx, fp64, fs);
8004 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8005 tcg_temp_free_i64(fp64);
8006 gen_store_fpr32(fp32, fd);
8007 tcg_temp_free_i32(fp32);
8012 check_cp1_registers(ctx, fs);
8014 TCGv_i32 fp32 = tcg_temp_new_i32();
8015 TCGv_i64 fp64 = tcg_temp_new_i64();
8017 gen_load_fpr64(ctx, fp64, fs);
8018 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8019 tcg_temp_free_i64(fp64);
8020 gen_store_fpr32(fp32, fd);
8021 tcg_temp_free_i32(fp32);
8026 check_cp1_registers(ctx, fs);
8028 TCGv_i32 fp32 = tcg_temp_new_i32();
8029 TCGv_i64 fp64 = tcg_temp_new_i64();
8031 gen_load_fpr64(ctx, fp64, fs);
8032 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8033 tcg_temp_free_i64(fp64);
8034 gen_store_fpr32(fp32, fd);
8035 tcg_temp_free_i32(fp32);
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_floorw_d(fp32, cpu_env, fp64);
8047 tcg_temp_free_i64(fp64);
8048 gen_store_fpr32(fp32, fd);
8049 tcg_temp_free_i32(fp32);
8054 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8059 int l1 = gen_new_label();
8063 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8065 fp0 = tcg_temp_new_i64();
8066 gen_load_fpr64(ctx, fp0, fs);
8067 gen_store_fpr64(ctx, fp0, fd);
8068 tcg_temp_free_i64(fp0);
8075 int l1 = gen_new_label();
8079 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8080 fp0 = tcg_temp_new_i64();
8081 gen_load_fpr64(ctx, fp0, fs);
8082 gen_store_fpr64(ctx, fp0, fd);
8083 tcg_temp_free_i64(fp0);
8090 check_cp1_64bitmode(ctx);
8092 TCGv_i64 fp0 = tcg_temp_new_i64();
8094 gen_load_fpr64(ctx, fp0, fs);
8095 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8096 gen_store_fpr64(ctx, fp0, fd);
8097 tcg_temp_free_i64(fp0);
8102 check_cp1_64bitmode(ctx);
8104 TCGv_i64 fp0 = tcg_temp_new_i64();
8106 gen_load_fpr64(ctx, fp0, fs);
8107 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8108 gen_store_fpr64(ctx, fp0, fd);
8109 tcg_temp_free_i64(fp0);
8114 check_cp1_64bitmode(ctx);
8116 TCGv_i64 fp0 = tcg_temp_new_i64();
8117 TCGv_i64 fp1 = tcg_temp_new_i64();
8119 gen_load_fpr64(ctx, fp0, fs);
8120 gen_load_fpr64(ctx, fp1, ft);
8121 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8122 tcg_temp_free_i64(fp1);
8123 gen_store_fpr64(ctx, fp0, fd);
8124 tcg_temp_free_i64(fp0);
8129 check_cp1_64bitmode(ctx);
8131 TCGv_i64 fp0 = tcg_temp_new_i64();
8133 gen_load_fpr64(ctx, fp0, fs);
8134 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8135 gen_store_fpr64(ctx, fp0, fd);
8136 tcg_temp_free_i64(fp0);
8141 check_cp1_64bitmode(ctx);
8143 TCGv_i64 fp0 = tcg_temp_new_i64();
8145 gen_load_fpr64(ctx, fp0, fs);
8146 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8147 gen_store_fpr64(ctx, fp0, fd);
8148 tcg_temp_free_i64(fp0);
8153 check_cp1_64bitmode(ctx);
8155 TCGv_i64 fp0 = tcg_temp_new_i64();
8156 TCGv_i64 fp1 = tcg_temp_new_i64();
8158 gen_load_fpr64(ctx, fp0, fs);
8159 gen_load_fpr64(ctx, fp1, ft);
8160 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8161 tcg_temp_free_i64(fp1);
8162 gen_store_fpr64(ctx, fp0, fd);
8163 tcg_temp_free_i64(fp0);
8176 case OPC_CMP_NGLE_D:
8183 if (ctx->opcode & (1 << 6)) {
8184 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8185 opn = condnames_abs[func-48];
8187 gen_cmp_d(ctx, func-48, ft, fs, cc);
8188 opn = condnames[func-48];
8192 check_cp1_registers(ctx, fs);
8194 TCGv_i32 fp32 = tcg_temp_new_i32();
8195 TCGv_i64 fp64 = tcg_temp_new_i64();
8197 gen_load_fpr64(ctx, fp64, fs);
8198 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8199 tcg_temp_free_i64(fp64);
8200 gen_store_fpr32(fp32, fd);
8201 tcg_temp_free_i32(fp32);
8206 check_cp1_registers(ctx, fs);
8208 TCGv_i32 fp32 = tcg_temp_new_i32();
8209 TCGv_i64 fp64 = tcg_temp_new_i64();
8211 gen_load_fpr64(ctx, fp64, fs);
8212 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8213 tcg_temp_free_i64(fp64);
8214 gen_store_fpr32(fp32, fd);
8215 tcg_temp_free_i32(fp32);
8220 check_cp1_64bitmode(ctx);
8222 TCGv_i64 fp0 = tcg_temp_new_i64();
8224 gen_load_fpr64(ctx, fp0, fs);
8225 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8226 gen_store_fpr64(ctx, fp0, fd);
8227 tcg_temp_free_i64(fp0);
8233 TCGv_i32 fp0 = tcg_temp_new_i32();
8235 gen_load_fpr32(fp0, fs);
8236 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8237 gen_store_fpr32(fp0, fd);
8238 tcg_temp_free_i32(fp0);
8243 check_cp1_registers(ctx, fd);
8245 TCGv_i32 fp32 = tcg_temp_new_i32();
8246 TCGv_i64 fp64 = tcg_temp_new_i64();
8248 gen_load_fpr32(fp32, fs);
8249 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8250 tcg_temp_free_i32(fp32);
8251 gen_store_fpr64(ctx, fp64, fd);
8252 tcg_temp_free_i64(fp64);
8257 check_cp1_64bitmode(ctx);
8259 TCGv_i32 fp32 = tcg_temp_new_i32();
8260 TCGv_i64 fp64 = tcg_temp_new_i64();
8262 gen_load_fpr64(ctx, fp64, fs);
8263 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8264 tcg_temp_free_i64(fp64);
8265 gen_store_fpr32(fp32, fd);
8266 tcg_temp_free_i32(fp32);
8271 check_cp1_64bitmode(ctx);
8273 TCGv_i64 fp0 = tcg_temp_new_i64();
8275 gen_load_fpr64(ctx, fp0, fs);
8276 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8277 gen_store_fpr64(ctx, fp0, fd);
8278 tcg_temp_free_i64(fp0);
8283 check_cp1_64bitmode(ctx);
8285 TCGv_i64 fp0 = tcg_temp_new_i64();
8287 gen_load_fpr64(ctx, fp0, fs);
8288 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8289 gen_store_fpr64(ctx, fp0, fd);
8290 tcg_temp_free_i64(fp0);
8295 check_cp1_64bitmode(ctx);
8297 TCGv_i64 fp0 = tcg_temp_new_i64();
8298 TCGv_i64 fp1 = tcg_temp_new_i64();
8300 gen_load_fpr64(ctx, fp0, fs);
8301 gen_load_fpr64(ctx, fp1, ft);
8302 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8303 tcg_temp_free_i64(fp1);
8304 gen_store_fpr64(ctx, fp0, fd);
8305 tcg_temp_free_i64(fp0);
8310 check_cp1_64bitmode(ctx);
8312 TCGv_i64 fp0 = tcg_temp_new_i64();
8313 TCGv_i64 fp1 = tcg_temp_new_i64();
8315 gen_load_fpr64(ctx, fp0, fs);
8316 gen_load_fpr64(ctx, fp1, ft);
8317 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8318 tcg_temp_free_i64(fp1);
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();
8328 TCGv_i64 fp1 = tcg_temp_new_i64();
8330 gen_load_fpr64(ctx, fp0, fs);
8331 gen_load_fpr64(ctx, fp1, ft);
8332 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8333 tcg_temp_free_i64(fp1);
8334 gen_store_fpr64(ctx, fp0, fd);
8335 tcg_temp_free_i64(fp0);
8340 check_cp1_64bitmode(ctx);
8342 TCGv_i64 fp0 = tcg_temp_new_i64();
8344 gen_load_fpr64(ctx, fp0, fs);
8345 gen_helper_float_abs_ps(fp0, fp0);
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();
8356 gen_load_fpr64(ctx, fp0, fs);
8357 gen_store_fpr64(ctx, fp0, fd);
8358 tcg_temp_free_i64(fp0);
8363 check_cp1_64bitmode(ctx);
8365 TCGv_i64 fp0 = tcg_temp_new_i64();
8367 gen_load_fpr64(ctx, fp0, fs);
8368 gen_helper_float_chs_ps(fp0, fp0);
8369 gen_store_fpr64(ctx, fp0, fd);
8370 tcg_temp_free_i64(fp0);
8375 check_cp1_64bitmode(ctx);
8376 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8380 check_cp1_64bitmode(ctx);
8382 int l1 = gen_new_label();
8386 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8387 fp0 = tcg_temp_new_i64();
8388 gen_load_fpr64(ctx, fp0, fs);
8389 gen_store_fpr64(ctx, fp0, fd);
8390 tcg_temp_free_i64(fp0);
8396 check_cp1_64bitmode(ctx);
8398 int l1 = gen_new_label();
8402 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8403 fp0 = tcg_temp_new_i64();
8404 gen_load_fpr64(ctx, fp0, fs);
8405 gen_store_fpr64(ctx, fp0, fd);
8406 tcg_temp_free_i64(fp0);
8413 check_cp1_64bitmode(ctx);
8415 TCGv_i64 fp0 = tcg_temp_new_i64();
8416 TCGv_i64 fp1 = tcg_temp_new_i64();
8418 gen_load_fpr64(ctx, fp0, ft);
8419 gen_load_fpr64(ctx, fp1, fs);
8420 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8421 tcg_temp_free_i64(fp1);
8422 gen_store_fpr64(ctx, fp0, fd);
8423 tcg_temp_free_i64(fp0);
8428 check_cp1_64bitmode(ctx);
8430 TCGv_i64 fp0 = tcg_temp_new_i64();
8431 TCGv_i64 fp1 = tcg_temp_new_i64();
8433 gen_load_fpr64(ctx, fp0, ft);
8434 gen_load_fpr64(ctx, fp1, fs);
8435 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8436 tcg_temp_free_i64(fp1);
8437 gen_store_fpr64(ctx, fp0, fd);
8438 tcg_temp_free_i64(fp0);
8443 check_cp1_64bitmode(ctx);
8445 TCGv_i64 fp0 = tcg_temp_new_i64();
8446 TCGv_i64 fp1 = tcg_temp_new_i64();
8448 gen_load_fpr64(ctx, fp0, fs);
8449 gen_load_fpr64(ctx, fp1, ft);
8450 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8451 tcg_temp_free_i64(fp1);
8452 gen_store_fpr64(ctx, fp0, fd);
8453 tcg_temp_free_i64(fp0);
8458 check_cp1_64bitmode(ctx);
8460 TCGv_i64 fp0 = tcg_temp_new_i64();
8462 gen_load_fpr64(ctx, fp0, fs);
8463 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
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();
8474 gen_load_fpr64(ctx, fp0, fs);
8475 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8476 gen_store_fpr64(ctx, fp0, fd);
8477 tcg_temp_free_i64(fp0);
8482 check_cp1_64bitmode(ctx);
8484 TCGv_i64 fp0 = tcg_temp_new_i64();
8485 TCGv_i64 fp1 = tcg_temp_new_i64();
8487 gen_load_fpr64(ctx, fp0, fs);
8488 gen_load_fpr64(ctx, fp1, ft);
8489 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8490 tcg_temp_free_i64(fp1);
8491 gen_store_fpr64(ctx, fp0, fd);
8492 tcg_temp_free_i64(fp0);
8497 check_cp1_64bitmode(ctx);
8499 TCGv_i32 fp0 = tcg_temp_new_i32();
8501 gen_load_fpr32h(fp0, fs);
8502 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8503 gen_store_fpr32(fp0, fd);
8504 tcg_temp_free_i32(fp0);
8509 check_cp1_64bitmode(ctx);
8511 TCGv_i64 fp0 = tcg_temp_new_i64();
8513 gen_load_fpr64(ctx, fp0, fs);
8514 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8515 gen_store_fpr64(ctx, fp0, fd);
8516 tcg_temp_free_i64(fp0);
8521 check_cp1_64bitmode(ctx);
8523 TCGv_i32 fp0 = tcg_temp_new_i32();
8525 gen_load_fpr32(fp0, fs);
8526 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8527 gen_store_fpr32(fp0, fd);
8528 tcg_temp_free_i32(fp0);
8533 check_cp1_64bitmode(ctx);
8535 TCGv_i32 fp0 = tcg_temp_new_i32();
8536 TCGv_i32 fp1 = tcg_temp_new_i32();
8538 gen_load_fpr32(fp0, fs);
8539 gen_load_fpr32(fp1, ft);
8540 gen_store_fpr32h(fp0, fd);
8541 gen_store_fpr32(fp1, fd);
8542 tcg_temp_free_i32(fp0);
8543 tcg_temp_free_i32(fp1);
8548 check_cp1_64bitmode(ctx);
8550 TCGv_i32 fp0 = tcg_temp_new_i32();
8551 TCGv_i32 fp1 = tcg_temp_new_i32();
8553 gen_load_fpr32(fp0, fs);
8554 gen_load_fpr32h(fp1, ft);
8555 gen_store_fpr32(fp1, fd);
8556 gen_store_fpr32h(fp0, fd);
8557 tcg_temp_free_i32(fp0);
8558 tcg_temp_free_i32(fp1);
8563 check_cp1_64bitmode(ctx);
8565 TCGv_i32 fp0 = tcg_temp_new_i32();
8566 TCGv_i32 fp1 = tcg_temp_new_i32();
8568 gen_load_fpr32h(fp0, fs);
8569 gen_load_fpr32(fp1, ft);
8570 gen_store_fpr32(fp1, fd);
8571 gen_store_fpr32h(fp0, fd);
8572 tcg_temp_free_i32(fp0);
8573 tcg_temp_free_i32(fp1);
8578 check_cp1_64bitmode(ctx);
8580 TCGv_i32 fp0 = tcg_temp_new_i32();
8581 TCGv_i32 fp1 = tcg_temp_new_i32();
8583 gen_load_fpr32h(fp0, fs);
8584 gen_load_fpr32h(fp1, ft);
8585 gen_store_fpr32(fp1, fd);
8586 gen_store_fpr32h(fp0, fd);
8587 tcg_temp_free_i32(fp0);
8588 tcg_temp_free_i32(fp1);
8595 case OPC_CMP_UEQ_PS:
8596 case OPC_CMP_OLT_PS:
8597 case OPC_CMP_ULT_PS:
8598 case OPC_CMP_OLE_PS:
8599 case OPC_CMP_ULE_PS:
8601 case OPC_CMP_NGLE_PS:
8602 case OPC_CMP_SEQ_PS:
8603 case OPC_CMP_NGL_PS:
8605 case OPC_CMP_NGE_PS:
8607 case OPC_CMP_NGT_PS:
8608 if (ctx->opcode & (1 << 6)) {
8609 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8610 opn = condnames_abs[func-48];
8612 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8613 opn = condnames[func-48];
8618 generate_exception (ctx, EXCP_RI);
8621 (void)opn; /* avoid a compiler warning */
8624 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8627 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8630 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8635 /* Coprocessor 3 (FPU) */
8636 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8637 int fd, int fs, int base, int index)
8639 const char *opn = "extended float load/store";
8641 TCGv t0 = tcg_temp_new();
8644 gen_load_gpr(t0, index);
8645 } else if (index == 0) {
8646 gen_load_gpr(t0, base);
8648 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8650 /* Don't do NOP if destination is zero: we must perform the actual
8656 TCGv_i32 fp0 = tcg_temp_new_i32();
8658 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8659 tcg_gen_trunc_tl_i32(fp0, t0);
8660 gen_store_fpr32(fp0, fd);
8661 tcg_temp_free_i32(fp0);
8667 check_cp1_registers(ctx, fd);
8669 TCGv_i64 fp0 = tcg_temp_new_i64();
8671 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8672 gen_store_fpr64(ctx, fp0, fd);
8673 tcg_temp_free_i64(fp0);
8678 check_cp1_64bitmode(ctx);
8679 tcg_gen_andi_tl(t0, t0, ~0x7);
8681 TCGv_i64 fp0 = tcg_temp_new_i64();
8683 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8684 gen_store_fpr64(ctx, fp0, fd);
8685 tcg_temp_free_i64(fp0);
8692 TCGv_i32 fp0 = tcg_temp_new_i32();
8693 TCGv t1 = tcg_temp_new();
8695 gen_load_fpr32(fp0, fs);
8696 tcg_gen_extu_i32_tl(t1, fp0);
8697 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8698 tcg_temp_free_i32(fp0);
8706 check_cp1_registers(ctx, fs);
8708 TCGv_i64 fp0 = tcg_temp_new_i64();
8710 gen_load_fpr64(ctx, fp0, fs);
8711 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8712 tcg_temp_free_i64(fp0);
8718 check_cp1_64bitmode(ctx);
8719 tcg_gen_andi_tl(t0, t0, ~0x7);
8721 TCGv_i64 fp0 = tcg_temp_new_i64();
8723 gen_load_fpr64(ctx, fp0, fs);
8724 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8725 tcg_temp_free_i64(fp0);
8732 (void)opn; (void)store; /* avoid compiler warnings */
8733 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8734 regnames[index], regnames[base]);
8737 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8738 int fd, int fr, int fs, int ft)
8740 const char *opn = "flt3_arith";
8744 check_cp1_64bitmode(ctx);
8746 TCGv t0 = tcg_temp_local_new();
8747 TCGv_i32 fp = tcg_temp_new_i32();
8748 TCGv_i32 fph = tcg_temp_new_i32();
8749 int l1 = gen_new_label();
8750 int l2 = gen_new_label();
8752 gen_load_gpr(t0, fr);
8753 tcg_gen_andi_tl(t0, t0, 0x7);
8755 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8756 gen_load_fpr32(fp, fs);
8757 gen_load_fpr32h(fph, fs);
8758 gen_store_fpr32(fp, fd);
8759 gen_store_fpr32h(fph, fd);
8762 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8764 #ifdef TARGET_WORDS_BIGENDIAN
8765 gen_load_fpr32(fp, fs);
8766 gen_load_fpr32h(fph, ft);
8767 gen_store_fpr32h(fp, fd);
8768 gen_store_fpr32(fph, fd);
8770 gen_load_fpr32h(fph, fs);
8771 gen_load_fpr32(fp, ft);
8772 gen_store_fpr32(fph, fd);
8773 gen_store_fpr32h(fp, fd);
8776 tcg_temp_free_i32(fp);
8777 tcg_temp_free_i32(fph);
8784 TCGv_i32 fp0 = tcg_temp_new_i32();
8785 TCGv_i32 fp1 = tcg_temp_new_i32();
8786 TCGv_i32 fp2 = tcg_temp_new_i32();
8788 gen_load_fpr32(fp0, fs);
8789 gen_load_fpr32(fp1, ft);
8790 gen_load_fpr32(fp2, fr);
8791 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8792 tcg_temp_free_i32(fp0);
8793 tcg_temp_free_i32(fp1);
8794 gen_store_fpr32(fp2, fd);
8795 tcg_temp_free_i32(fp2);
8801 check_cp1_registers(ctx, fd | fs | ft | fr);
8803 TCGv_i64 fp0 = tcg_temp_new_i64();
8804 TCGv_i64 fp1 = tcg_temp_new_i64();
8805 TCGv_i64 fp2 = tcg_temp_new_i64();
8807 gen_load_fpr64(ctx, fp0, fs);
8808 gen_load_fpr64(ctx, fp1, ft);
8809 gen_load_fpr64(ctx, fp2, fr);
8810 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8811 tcg_temp_free_i64(fp0);
8812 tcg_temp_free_i64(fp1);
8813 gen_store_fpr64(ctx, fp2, fd);
8814 tcg_temp_free_i64(fp2);
8819 check_cp1_64bitmode(ctx);
8821 TCGv_i64 fp0 = tcg_temp_new_i64();
8822 TCGv_i64 fp1 = tcg_temp_new_i64();
8823 TCGv_i64 fp2 = tcg_temp_new_i64();
8825 gen_load_fpr64(ctx, fp0, fs);
8826 gen_load_fpr64(ctx, fp1, ft);
8827 gen_load_fpr64(ctx, fp2, fr);
8828 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8829 tcg_temp_free_i64(fp0);
8830 tcg_temp_free_i64(fp1);
8831 gen_store_fpr64(ctx, fp2, fd);
8832 tcg_temp_free_i64(fp2);
8839 TCGv_i32 fp0 = tcg_temp_new_i32();
8840 TCGv_i32 fp1 = tcg_temp_new_i32();
8841 TCGv_i32 fp2 = tcg_temp_new_i32();
8843 gen_load_fpr32(fp0, fs);
8844 gen_load_fpr32(fp1, ft);
8845 gen_load_fpr32(fp2, fr);
8846 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8847 tcg_temp_free_i32(fp0);
8848 tcg_temp_free_i32(fp1);
8849 gen_store_fpr32(fp2, fd);
8850 tcg_temp_free_i32(fp2);
8856 check_cp1_registers(ctx, fd | fs | ft | fr);
8858 TCGv_i64 fp0 = tcg_temp_new_i64();
8859 TCGv_i64 fp1 = tcg_temp_new_i64();
8860 TCGv_i64 fp2 = tcg_temp_new_i64();
8862 gen_load_fpr64(ctx, fp0, fs);
8863 gen_load_fpr64(ctx, fp1, ft);
8864 gen_load_fpr64(ctx, fp2, fr);
8865 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8866 tcg_temp_free_i64(fp0);
8867 tcg_temp_free_i64(fp1);
8868 gen_store_fpr64(ctx, fp2, fd);
8869 tcg_temp_free_i64(fp2);
8874 check_cp1_64bitmode(ctx);
8876 TCGv_i64 fp0 = tcg_temp_new_i64();
8877 TCGv_i64 fp1 = tcg_temp_new_i64();
8878 TCGv_i64 fp2 = tcg_temp_new_i64();
8880 gen_load_fpr64(ctx, fp0, fs);
8881 gen_load_fpr64(ctx, fp1, ft);
8882 gen_load_fpr64(ctx, fp2, fr);
8883 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8884 tcg_temp_free_i64(fp0);
8885 tcg_temp_free_i64(fp1);
8886 gen_store_fpr64(ctx, fp2, fd);
8887 tcg_temp_free_i64(fp2);
8894 TCGv_i32 fp0 = tcg_temp_new_i32();
8895 TCGv_i32 fp1 = tcg_temp_new_i32();
8896 TCGv_i32 fp2 = tcg_temp_new_i32();
8898 gen_load_fpr32(fp0, fs);
8899 gen_load_fpr32(fp1, ft);
8900 gen_load_fpr32(fp2, fr);
8901 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8902 tcg_temp_free_i32(fp0);
8903 tcg_temp_free_i32(fp1);
8904 gen_store_fpr32(fp2, fd);
8905 tcg_temp_free_i32(fp2);
8911 check_cp1_registers(ctx, fd | fs | ft | fr);
8913 TCGv_i64 fp0 = tcg_temp_new_i64();
8914 TCGv_i64 fp1 = tcg_temp_new_i64();
8915 TCGv_i64 fp2 = tcg_temp_new_i64();
8917 gen_load_fpr64(ctx, fp0, fs);
8918 gen_load_fpr64(ctx, fp1, ft);
8919 gen_load_fpr64(ctx, fp2, fr);
8920 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8921 tcg_temp_free_i64(fp0);
8922 tcg_temp_free_i64(fp1);
8923 gen_store_fpr64(ctx, fp2, fd);
8924 tcg_temp_free_i64(fp2);
8929 check_cp1_64bitmode(ctx);
8931 TCGv_i64 fp0 = tcg_temp_new_i64();
8932 TCGv_i64 fp1 = tcg_temp_new_i64();
8933 TCGv_i64 fp2 = tcg_temp_new_i64();
8935 gen_load_fpr64(ctx, fp0, fs);
8936 gen_load_fpr64(ctx, fp1, ft);
8937 gen_load_fpr64(ctx, fp2, fr);
8938 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8939 tcg_temp_free_i64(fp0);
8940 tcg_temp_free_i64(fp1);
8941 gen_store_fpr64(ctx, fp2, fd);
8942 tcg_temp_free_i64(fp2);
8949 TCGv_i32 fp0 = tcg_temp_new_i32();
8950 TCGv_i32 fp1 = tcg_temp_new_i32();
8951 TCGv_i32 fp2 = tcg_temp_new_i32();
8953 gen_load_fpr32(fp0, fs);
8954 gen_load_fpr32(fp1, ft);
8955 gen_load_fpr32(fp2, fr);
8956 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8957 tcg_temp_free_i32(fp0);
8958 tcg_temp_free_i32(fp1);
8959 gen_store_fpr32(fp2, fd);
8960 tcg_temp_free_i32(fp2);
8966 check_cp1_registers(ctx, fd | fs | ft | fr);
8968 TCGv_i64 fp0 = tcg_temp_new_i64();
8969 TCGv_i64 fp1 = tcg_temp_new_i64();
8970 TCGv_i64 fp2 = tcg_temp_new_i64();
8972 gen_load_fpr64(ctx, fp0, fs);
8973 gen_load_fpr64(ctx, fp1, ft);
8974 gen_load_fpr64(ctx, fp2, fr);
8975 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
8976 tcg_temp_free_i64(fp0);
8977 tcg_temp_free_i64(fp1);
8978 gen_store_fpr64(ctx, fp2, fd);
8979 tcg_temp_free_i64(fp2);
8984 check_cp1_64bitmode(ctx);
8986 TCGv_i64 fp0 = tcg_temp_new_i64();
8987 TCGv_i64 fp1 = tcg_temp_new_i64();
8988 TCGv_i64 fp2 = tcg_temp_new_i64();
8990 gen_load_fpr64(ctx, fp0, fs);
8991 gen_load_fpr64(ctx, fp1, ft);
8992 gen_load_fpr64(ctx, fp2, fr);
8993 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8994 tcg_temp_free_i64(fp0);
8995 tcg_temp_free_i64(fp1);
8996 gen_store_fpr64(ctx, fp2, fd);
8997 tcg_temp_free_i64(fp2);
9003 generate_exception (ctx, EXCP_RI);
9006 (void)opn; /* avoid a compiler warning */
9007 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9008 fregnames[fs], fregnames[ft]);
9012 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9016 #if !defined(CONFIG_USER_ONLY)
9017 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9018 Therefore only check the ISA in system mode. */
9019 check_insn(env, ctx, ISA_MIPS32R2);
9021 t0 = tcg_temp_new();
9025 save_cpu_state(ctx, 1);
9026 gen_helper_rdhwr_cpunum(t0, cpu_env);
9027 gen_store_gpr(t0, rt);
9030 save_cpu_state(ctx, 1);
9031 gen_helper_rdhwr_synci_step(t0, cpu_env);
9032 gen_store_gpr(t0, rt);
9035 save_cpu_state(ctx, 1);
9036 gen_helper_rdhwr_cc(t0, cpu_env);
9037 gen_store_gpr(t0, rt);
9040 save_cpu_state(ctx, 1);
9041 gen_helper_rdhwr_ccres(t0, cpu_env);
9042 gen_store_gpr(t0, rt);
9045 #if defined(CONFIG_USER_ONLY)
9046 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9047 gen_store_gpr(t0, rt);
9050 /* XXX: Some CPUs implement this in hardware.
9051 Not supported yet. */
9053 default: /* Invalid */
9054 MIPS_INVAL("rdhwr");
9055 generate_exception(ctx, EXCP_RI);
9061 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9064 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9065 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9066 /* Branches completion */
9067 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9068 ctx->bstate = BS_BRANCH;
9069 save_cpu_state(ctx, 0);
9070 /* FIXME: Need to clear can_do_io. */
9071 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9073 /* unconditional branch */
9074 MIPS_DEBUG("unconditional branch");
9075 if (proc_hflags & MIPS_HFLAG_BX) {
9076 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9078 gen_goto_tb(ctx, 0, ctx->btarget);
9081 /* blikely taken case */
9082 MIPS_DEBUG("blikely branch taken");
9083 gen_goto_tb(ctx, 0, ctx->btarget);
9086 /* Conditional branch */
9087 MIPS_DEBUG("conditional branch");
9089 int l1 = gen_new_label();
9091 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9092 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9094 gen_goto_tb(ctx, 0, ctx->btarget);
9098 /* unconditional branch to register */
9099 MIPS_DEBUG("branch to register");
9100 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9101 TCGv t0 = tcg_temp_new();
9102 TCGv_i32 t1 = tcg_temp_new_i32();
9104 tcg_gen_andi_tl(t0, btarget, 0x1);
9105 tcg_gen_trunc_tl_i32(t1, t0);
9107 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9108 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9109 tcg_gen_or_i32(hflags, hflags, t1);
9110 tcg_temp_free_i32(t1);
9112 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9114 tcg_gen_mov_tl(cpu_PC, btarget);
9116 if (ctx->singlestep_enabled) {
9117 save_cpu_state(ctx, 0);
9118 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9123 MIPS_DEBUG("unknown branch");
9129 /* ISA extensions (ASEs) */
9130 /* MIPS16 extension to MIPS32 */
9132 /* MIPS16 major opcodes */
9134 M16_OPC_ADDIUSP = 0x00,
9135 M16_OPC_ADDIUPC = 0x01,
9138 M16_OPC_BEQZ = 0x04,
9139 M16_OPC_BNEQZ = 0x05,
9140 M16_OPC_SHIFT = 0x06,
9142 M16_OPC_RRIA = 0x08,
9143 M16_OPC_ADDIU8 = 0x09,
9144 M16_OPC_SLTI = 0x0a,
9145 M16_OPC_SLTIU = 0x0b,
9148 M16_OPC_CMPI = 0x0e,
9152 M16_OPC_LWSP = 0x12,
9156 M16_OPC_LWPC = 0x16,
9160 M16_OPC_SWSP = 0x1a,
9164 M16_OPC_EXTEND = 0x1e,
9168 /* I8 funct field */
9187 /* RR funct field */
9221 /* I64 funct field */
9233 /* RR ry field for CNVT */
9235 RR_RY_CNVT_ZEB = 0x0,
9236 RR_RY_CNVT_ZEH = 0x1,
9237 RR_RY_CNVT_ZEW = 0x2,
9238 RR_RY_CNVT_SEB = 0x4,
9239 RR_RY_CNVT_SEH = 0x5,
9240 RR_RY_CNVT_SEW = 0x6,
9243 static int xlat (int r)
9245 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9250 static void gen_mips16_save (DisasContext *ctx,
9251 int xsregs, int aregs,
9252 int do_ra, int do_s0, int do_s1,
9255 TCGv t0 = tcg_temp_new();
9256 TCGv t1 = tcg_temp_new();
9286 generate_exception(ctx, EXCP_RI);
9292 gen_base_offset_addr(ctx, t0, 29, 12);
9293 gen_load_gpr(t1, 7);
9294 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9297 gen_base_offset_addr(ctx, t0, 29, 8);
9298 gen_load_gpr(t1, 6);
9299 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9302 gen_base_offset_addr(ctx, t0, 29, 4);
9303 gen_load_gpr(t1, 5);
9304 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9307 gen_base_offset_addr(ctx, t0, 29, 0);
9308 gen_load_gpr(t1, 4);
9309 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9312 gen_load_gpr(t0, 29);
9314 #define DECR_AND_STORE(reg) do { \
9315 tcg_gen_subi_tl(t0, t0, 4); \
9316 gen_load_gpr(t1, reg); \
9317 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9381 generate_exception(ctx, EXCP_RI);
9397 #undef DECR_AND_STORE
9399 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9404 static void gen_mips16_restore (DisasContext *ctx,
9405 int xsregs, int aregs,
9406 int do_ra, int do_s0, int do_s1,
9410 TCGv t0 = tcg_temp_new();
9411 TCGv t1 = tcg_temp_new();
9413 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9415 #define DECR_AND_LOAD(reg) do { \
9416 tcg_gen_subi_tl(t0, t0, 4); \
9417 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9418 gen_store_gpr(t1, reg); \
9482 generate_exception(ctx, EXCP_RI);
9498 #undef DECR_AND_LOAD
9500 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9505 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9506 int is_64_bit, int extended)
9510 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9511 generate_exception(ctx, EXCP_RI);
9515 t0 = tcg_temp_new();
9517 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9518 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9520 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9526 #if defined(TARGET_MIPS64)
9527 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9528 int ry, int funct, int16_t offset,
9534 offset = extended ? offset : offset << 3;
9535 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9539 offset = extended ? offset : offset << 3;
9540 gen_st(ctx, OPC_SD, ry, 29, offset);
9544 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9545 gen_st(ctx, OPC_SD, 31, 29, offset);
9549 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9550 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9553 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9554 generate_exception(ctx, EXCP_RI);
9556 offset = extended ? offset : offset << 3;
9557 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9562 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9563 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9567 offset = extended ? offset : offset << 2;
9568 gen_addiupc(ctx, ry, offset, 1, extended);
9572 offset = extended ? offset : offset << 2;
9573 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9579 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9582 int extend = cpu_lduw_code(env, ctx->pc + 2);
9583 int op, rx, ry, funct, sa;
9584 int16_t imm, offset;
9586 ctx->opcode = (ctx->opcode << 16) | extend;
9587 op = (ctx->opcode >> 11) & 0x1f;
9588 sa = (ctx->opcode >> 22) & 0x1f;
9589 funct = (ctx->opcode >> 8) & 0x7;
9590 rx = xlat((ctx->opcode >> 8) & 0x7);
9591 ry = xlat((ctx->opcode >> 5) & 0x7);
9592 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9593 | ((ctx->opcode >> 21) & 0x3f) << 5
9594 | (ctx->opcode & 0x1f));
9596 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9599 case M16_OPC_ADDIUSP:
9600 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9602 case M16_OPC_ADDIUPC:
9603 gen_addiupc(ctx, rx, imm, 0, 1);
9606 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9607 /* No delay slot, so just process as a normal instruction */
9610 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9611 /* No delay slot, so just process as a normal instruction */
9614 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9615 /* No delay slot, so just process as a normal instruction */
9618 switch (ctx->opcode & 0x3) {
9620 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9623 #if defined(TARGET_MIPS64)
9625 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9627 generate_exception(ctx, EXCP_RI);
9631 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9634 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9638 #if defined(TARGET_MIPS64)
9641 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9645 imm = ctx->opcode & 0xf;
9646 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9647 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9648 imm = (int16_t) (imm << 1) >> 1;
9649 if ((ctx->opcode >> 4) & 0x1) {
9650 #if defined(TARGET_MIPS64)
9652 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9654 generate_exception(ctx, EXCP_RI);
9657 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9660 case M16_OPC_ADDIU8:
9661 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9664 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9667 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9672 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9675 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9678 gen_st(ctx, OPC_SW, 31, 29, imm);
9681 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9685 int xsregs = (ctx->opcode >> 24) & 0x7;
9686 int aregs = (ctx->opcode >> 16) & 0xf;
9687 int do_ra = (ctx->opcode >> 6) & 0x1;
9688 int do_s0 = (ctx->opcode >> 5) & 0x1;
9689 int do_s1 = (ctx->opcode >> 4) & 0x1;
9690 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9691 | (ctx->opcode & 0xf)) << 3;
9693 if (ctx->opcode & (1 << 7)) {
9694 gen_mips16_save(ctx, xsregs, aregs,
9695 do_ra, do_s0, do_s1,
9698 gen_mips16_restore(ctx, xsregs, aregs,
9699 do_ra, do_s0, do_s1,
9705 generate_exception(ctx, EXCP_RI);
9710 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9713 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9715 #if defined(TARGET_MIPS64)
9717 gen_st(ctx, OPC_SD, ry, rx, offset);
9721 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9724 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9727 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9730 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9733 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9736 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9739 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9741 #if defined(TARGET_MIPS64)
9743 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9747 gen_st(ctx, OPC_SB, ry, rx, offset);
9750 gen_st(ctx, OPC_SH, ry, rx, offset);
9753 gen_st(ctx, OPC_SW, rx, 29, offset);
9756 gen_st(ctx, OPC_SW, ry, rx, offset);
9758 #if defined(TARGET_MIPS64)
9760 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9764 generate_exception(ctx, EXCP_RI);
9771 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9776 int op, cnvt_op, op1, offset;
9780 op = (ctx->opcode >> 11) & 0x1f;
9781 sa = (ctx->opcode >> 2) & 0x7;
9782 sa = sa == 0 ? 8 : sa;
9783 rx = xlat((ctx->opcode >> 8) & 0x7);
9784 cnvt_op = (ctx->opcode >> 5) & 0x7;
9785 ry = xlat((ctx->opcode >> 5) & 0x7);
9786 op1 = offset = ctx->opcode & 0x1f;
9791 case M16_OPC_ADDIUSP:
9793 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9795 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9798 case M16_OPC_ADDIUPC:
9799 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9802 offset = (ctx->opcode & 0x7ff) << 1;
9803 offset = (int16_t)(offset << 4) >> 4;
9804 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9805 /* No delay slot, so just process as a normal instruction */
9808 offset = cpu_lduw_code(env, ctx->pc + 2);
9809 offset = (((ctx->opcode & 0x1f) << 21)
9810 | ((ctx->opcode >> 5) & 0x1f) << 16
9812 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9813 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9818 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9819 /* No delay slot, so just process as a normal instruction */
9822 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9823 /* No delay slot, so just process as a normal instruction */
9826 switch (ctx->opcode & 0x3) {
9828 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9831 #if defined(TARGET_MIPS64)
9833 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9835 generate_exception(ctx, EXCP_RI);
9839 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9842 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9846 #if defined(TARGET_MIPS64)
9849 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9854 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9856 if ((ctx->opcode >> 4) & 1) {
9857 #if defined(TARGET_MIPS64)
9859 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9861 generate_exception(ctx, EXCP_RI);
9864 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9868 case M16_OPC_ADDIU8:
9870 int16_t imm = (int8_t) ctx->opcode;
9872 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9877 int16_t imm = (uint8_t) ctx->opcode;
9878 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9883 int16_t imm = (uint8_t) ctx->opcode;
9884 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9891 funct = (ctx->opcode >> 8) & 0x7;
9894 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9895 ((int8_t)ctx->opcode) << 1);
9898 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9899 ((int8_t)ctx->opcode) << 1);
9902 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9905 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9906 ((int8_t)ctx->opcode) << 3);
9910 int do_ra = ctx->opcode & (1 << 6);
9911 int do_s0 = ctx->opcode & (1 << 5);
9912 int do_s1 = ctx->opcode & (1 << 4);
9913 int framesize = ctx->opcode & 0xf;
9915 if (framesize == 0) {
9918 framesize = framesize << 3;
9921 if (ctx->opcode & (1 << 7)) {
9922 gen_mips16_save(ctx, 0, 0,
9923 do_ra, do_s0, do_s1, framesize);
9925 gen_mips16_restore(ctx, 0, 0,
9926 do_ra, do_s0, do_s1, framesize);
9932 int rz = xlat(ctx->opcode & 0x7);
9934 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9935 ((ctx->opcode >> 5) & 0x7);
9936 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9940 reg32 = ctx->opcode & 0x1f;
9941 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9944 generate_exception(ctx, EXCP_RI);
9951 int16_t imm = (uint8_t) ctx->opcode;
9953 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9958 int16_t imm = (uint8_t) ctx->opcode;
9959 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
9962 #if defined(TARGET_MIPS64)
9965 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9969 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9972 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9975 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9978 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
9981 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9984 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9987 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9989 #if defined (TARGET_MIPS64)
9992 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
9996 gen_st(ctx, OPC_SB, ry, rx, offset);
9999 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10002 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10005 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10009 int rz = xlat((ctx->opcode >> 2) & 0x7);
10012 switch (ctx->opcode & 0x3) {
10014 mips32_op = OPC_ADDU;
10017 mips32_op = OPC_SUBU;
10019 #if defined(TARGET_MIPS64)
10021 mips32_op = OPC_DADDU;
10022 check_mips_64(ctx);
10025 mips32_op = OPC_DSUBU;
10026 check_mips_64(ctx);
10030 generate_exception(ctx, EXCP_RI);
10034 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10043 int nd = (ctx->opcode >> 7) & 0x1;
10044 int link = (ctx->opcode >> 6) & 0x1;
10045 int ra = (ctx->opcode >> 5) & 0x1;
10048 op = nd ? OPC_JALRC : OPC_JALRS;
10053 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10060 /* XXX: not clear which exception should be raised
10061 * when in debug mode...
10063 check_insn(env, ctx, ISA_MIPS32);
10064 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10065 generate_exception(ctx, EXCP_DBp);
10067 generate_exception(ctx, EXCP_DBp);
10071 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10074 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10077 generate_exception(ctx, EXCP_BREAK);
10080 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10083 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10086 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10088 #if defined (TARGET_MIPS64)
10090 check_mips_64(ctx);
10091 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10095 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10098 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10101 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10104 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10107 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10110 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10113 gen_HILO(ctx, OPC_MFHI, rx);
10117 case RR_RY_CNVT_ZEB:
10118 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10120 case RR_RY_CNVT_ZEH:
10121 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10123 case RR_RY_CNVT_SEB:
10124 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10126 case RR_RY_CNVT_SEH:
10127 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10129 #if defined (TARGET_MIPS64)
10130 case RR_RY_CNVT_ZEW:
10131 check_mips_64(ctx);
10132 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10134 case RR_RY_CNVT_SEW:
10135 check_mips_64(ctx);
10136 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10140 generate_exception(ctx, EXCP_RI);
10145 gen_HILO(ctx, OPC_MFLO, rx);
10147 #if defined (TARGET_MIPS64)
10149 check_mips_64(ctx);
10150 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10153 check_mips_64(ctx);
10154 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10157 check_mips_64(ctx);
10158 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10161 check_mips_64(ctx);
10162 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10166 gen_muldiv(ctx, OPC_MULT, rx, ry);
10169 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10172 gen_muldiv(ctx, OPC_DIV, rx, ry);
10175 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10177 #if defined (TARGET_MIPS64)
10179 check_mips_64(ctx);
10180 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10183 check_mips_64(ctx);
10184 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10187 check_mips_64(ctx);
10188 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10191 check_mips_64(ctx);
10192 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10196 generate_exception(ctx, EXCP_RI);
10200 case M16_OPC_EXTEND:
10201 decode_extended_mips16_opc(env, ctx, is_branch);
10204 #if defined(TARGET_MIPS64)
10206 funct = (ctx->opcode >> 8) & 0x7;
10207 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10211 generate_exception(ctx, EXCP_RI);
10218 /* microMIPS extension to MIPS32 */
10220 /* microMIPS32 major opcodes */
10259 /* 0x20 is reserved */
10269 /* 0x28 and 0x29 are reserved */
10279 /* 0x30 and 0x31 are reserved */
10289 /* 0x38 and 0x39 are reserved */
10300 /* POOL32A encoding of minor opcode field */
10303 /* These opcodes are distinguished only by bits 9..6; those bits are
10304 * what are recorded below. */
10330 /* The following can be distinguished by their lower 6 bits. */
10336 /* POOL32AXF encoding of minor opcode field extension */
10350 /* bits 13..12 for 0x01 */
10356 /* bits 13..12 for 0x2a */
10362 /* bits 13..12 for 0x32 */
10366 /* bits 15..12 for 0x2c */
10382 /* bits 15..12 for 0x34 */
10390 /* bits 15..12 for 0x3c */
10392 JR = 0x0, /* alias */
10397 /* bits 15..12 for 0x05 */
10401 /* bits 15..12 for 0x0d */
10411 /* bits 15..12 for 0x15 */
10417 /* bits 15..12 for 0x1d */
10421 /* bits 15..12 for 0x2d */
10426 /* bits 15..12 for 0x35 */
10433 /* POOL32B encoding of minor opcode field (bits 15..12) */
10449 /* POOL32C encoding of minor opcode field (bits 15..12) */
10457 /* 0xa is reserved */
10464 /* 0x6 is reserved */
10470 /* POOL32F encoding of minor opcode field (bits 5..0) */
10473 /* These are the bit 7..6 values */
10484 /* These are the bit 8..6 values */
10528 CABS_COND_FMT = 0x1c, /* MIPS3D */
10532 /* POOL32Fxf encoding of minor opcode extension field */
10570 /* POOL32I encoding of minor opcode field (bits 25..21) */
10595 /* These overlap and are distinguished by bit16 of the instruction */
10604 /* POOL16A encoding of minor opcode field */
10611 /* POOL16B encoding of minor opcode field */
10618 /* POOL16C encoding of minor opcode field */
10638 /* POOL16D encoding of minor opcode field */
10645 /* POOL16E encoding of minor opcode field */
10652 static int mmreg (int r)
10654 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10659 /* Used for 16-bit store instructions. */
10660 static int mmreg2 (int r)
10662 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10667 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10668 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10669 #define uMIPS_RS2(op) uMIPS_RS(op)
10670 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10671 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10672 #define uMIPS_RS5(op) (op & 0x1f)
10674 /* Signed immediate */
10675 #define SIMM(op, start, width) \
10676 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10679 /* Zero-extended immediate */
10680 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10682 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10684 int rd = mmreg(uMIPS_RD(ctx->opcode));
10686 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10689 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10691 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10692 int rd = mmreg(uMIPS_RD(ctx->opcode));
10693 int rs = mmreg(uMIPS_RS(ctx->opcode));
10695 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10698 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10700 int encoded = ZIMM(ctx->opcode, 1, 9);
10703 if (encoded <= 1) {
10704 decoded = 256 + encoded;
10705 } else if (encoded <= 255) {
10707 } else if (encoded <= 509) {
10708 decoded = encoded - 512;
10710 decoded = encoded - 768;
10713 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10716 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10718 int imm = SIMM(ctx->opcode, 1, 4);
10719 int rd = (ctx->opcode >> 5) & 0x1f;
10721 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10724 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10726 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10727 31, 32, 63, 64, 255, 32768, 65535 };
10728 int rd = mmreg(uMIPS_RD(ctx->opcode));
10729 int rs = mmreg(uMIPS_RS(ctx->opcode));
10730 int encoded = ZIMM(ctx->opcode, 0, 4);
10732 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10735 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10736 int base, int16_t offset)
10738 const char *opn = "ldst_multiple";
10742 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10743 generate_exception(ctx, EXCP_RI);
10747 t0 = tcg_temp_new();
10749 gen_base_offset_addr(ctx, t0, base, offset);
10751 t1 = tcg_const_tl(reglist);
10752 t2 = tcg_const_i32(ctx->mem_idx);
10754 save_cpu_state(ctx, 1);
10757 gen_helper_lwm(cpu_env, t0, t1, t2);
10761 gen_helper_swm(cpu_env, t0, t1, t2);
10764 #ifdef TARGET_MIPS64
10766 gen_helper_ldm(cpu_env, t0, t1, t2);
10770 gen_helper_sdm(cpu_env, t0, t1, t2);
10776 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10779 tcg_temp_free_i32(t2);
10783 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10785 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10786 int rs = mmreg(ctx->opcode & 0x7);
10789 switch (((ctx->opcode) >> 4) & 0x3f) {
10794 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10800 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10806 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10812 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10819 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10820 int offset = ZIMM(ctx->opcode, 0, 4);
10822 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10831 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10832 int offset = ZIMM(ctx->opcode, 0, 4);
10834 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10841 int reg = ctx->opcode & 0x1f;
10843 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10850 int reg = ctx->opcode & 0x1f;
10852 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10853 /* Let normal delay slot handling in our caller take us
10854 to the branch target. */
10866 int reg = ctx->opcode & 0x1f;
10868 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10874 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10878 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10881 generate_exception(ctx, EXCP_BREAK);
10884 /* XXX: not clear which exception should be raised
10885 * when in debug mode...
10887 check_insn(env, ctx, ISA_MIPS32);
10888 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10889 generate_exception(ctx, EXCP_DBp);
10891 generate_exception(ctx, EXCP_DBp);
10894 case JRADDIUSP + 0:
10895 case JRADDIUSP + 1:
10897 int imm = ZIMM(ctx->opcode, 0, 5);
10899 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10900 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10901 /* Let normal delay slot handling in our caller take us
10902 to the branch target. */
10906 generate_exception(ctx, EXCP_RI);
10911 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10913 TCGv t0 = tcg_temp_new();
10914 TCGv t1 = tcg_temp_new();
10916 gen_load_gpr(t0, base);
10919 gen_load_gpr(t1, index);
10920 tcg_gen_shli_tl(t1, t1, 2);
10921 gen_op_addr_add(ctx, t0, t1, t0);
10924 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10925 gen_store_gpr(t1, rd);
10931 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10932 int base, int16_t offset)
10934 const char *opn = "ldst_pair";
10937 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10938 generate_exception(ctx, EXCP_RI);
10942 t0 = tcg_temp_new();
10943 t1 = tcg_temp_new();
10945 gen_base_offset_addr(ctx, t0, base, offset);
10950 generate_exception(ctx, EXCP_RI);
10953 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10954 gen_store_gpr(t1, rd);
10955 tcg_gen_movi_tl(t1, 4);
10956 gen_op_addr_add(ctx, t0, t0, t1);
10957 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10958 gen_store_gpr(t1, rd+1);
10962 gen_load_gpr(t1, rd);
10963 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10964 tcg_gen_movi_tl(t1, 4);
10965 gen_op_addr_add(ctx, t0, t0, t1);
10966 gen_load_gpr(t1, rd+1);
10967 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10970 #ifdef TARGET_MIPS64
10973 generate_exception(ctx, EXCP_RI);
10976 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
10977 gen_store_gpr(t1, rd);
10978 tcg_gen_movi_tl(t1, 8);
10979 gen_op_addr_add(ctx, t0, t0, t1);
10980 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
10981 gen_store_gpr(t1, rd+1);
10985 gen_load_gpr(t1, rd);
10986 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
10987 tcg_gen_movi_tl(t1, 8);
10988 gen_op_addr_add(ctx, t0, t0, t1);
10989 gen_load_gpr(t1, rd+1);
10990 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
10995 (void)opn; /* avoid a compiler warning */
10996 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11001 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11004 int extension = (ctx->opcode >> 6) & 0x3f;
11005 int minor = (ctx->opcode >> 12) & 0xf;
11006 uint32_t mips32_op;
11008 switch (extension) {
11010 mips32_op = OPC_TEQ;
11013 mips32_op = OPC_TGE;
11016 mips32_op = OPC_TGEU;
11019 mips32_op = OPC_TLT;
11022 mips32_op = OPC_TLTU;
11025 mips32_op = OPC_TNE;
11027 gen_trap(ctx, mips32_op, rs, rt, -1);
11029 #ifndef CONFIG_USER_ONLY
11032 check_cp0_enabled(ctx);
11034 /* Treat as NOP. */
11037 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11041 check_cp0_enabled(ctx);
11043 TCGv t0 = tcg_temp_new();
11045 gen_load_gpr(t0, rt);
11046 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11054 gen_bshfl(ctx, OPC_SEB, rs, rt);
11057 gen_bshfl(ctx, OPC_SEH, rs, rt);
11060 mips32_op = OPC_CLO;
11063 mips32_op = OPC_CLZ;
11065 check_insn(env, ctx, ISA_MIPS32);
11066 gen_cl(ctx, mips32_op, rt, rs);
11069 gen_rdhwr(env, ctx, rt, rs);
11072 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11075 mips32_op = OPC_MULT;
11078 mips32_op = OPC_MULTU;
11081 mips32_op = OPC_DIV;
11084 mips32_op = OPC_DIVU;
11087 mips32_op = OPC_MADD;
11090 mips32_op = OPC_MADDU;
11093 mips32_op = OPC_MSUB;
11096 mips32_op = OPC_MSUBU;
11098 check_insn(env, ctx, ISA_MIPS32);
11099 gen_muldiv(ctx, mips32_op, rs, rt);
11102 goto pool32axf_invalid;
11113 generate_exception_err(ctx, EXCP_CpU, 2);
11116 goto pool32axf_invalid;
11123 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11128 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11132 goto pool32axf_invalid;
11138 check_cp0_enabled(ctx);
11139 check_insn(env, ctx, ISA_MIPS32R2);
11140 gen_load_srsgpr(rt, rs);
11143 check_cp0_enabled(ctx);
11144 check_insn(env, ctx, ISA_MIPS32R2);
11145 gen_store_srsgpr(rt, rs);
11148 goto pool32axf_invalid;
11151 #ifndef CONFIG_USER_ONLY
11155 mips32_op = OPC_TLBP;
11158 mips32_op = OPC_TLBR;
11161 mips32_op = OPC_TLBWI;
11164 mips32_op = OPC_TLBWR;
11167 mips32_op = OPC_WAIT;
11170 mips32_op = OPC_DERET;
11173 mips32_op = OPC_ERET;
11175 gen_cp0(env, ctx, mips32_op, rt, rs);
11178 goto pool32axf_invalid;
11184 check_cp0_enabled(ctx);
11186 TCGv t0 = tcg_temp_new();
11188 save_cpu_state(ctx, 1);
11189 gen_helper_di(t0, cpu_env);
11190 gen_store_gpr(t0, rs);
11191 /* Stop translation as we may have switched the execution mode */
11192 ctx->bstate = BS_STOP;
11197 check_cp0_enabled(ctx);
11199 TCGv t0 = tcg_temp_new();
11201 save_cpu_state(ctx, 1);
11202 gen_helper_ei(t0, cpu_env);
11203 gen_store_gpr(t0, rs);
11204 /* Stop translation as we may have switched the execution mode */
11205 ctx->bstate = BS_STOP;
11210 goto pool32axf_invalid;
11220 generate_exception(ctx, EXCP_SYSCALL);
11221 ctx->bstate = BS_STOP;
11224 check_insn(env, ctx, ISA_MIPS32);
11225 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11226 generate_exception(ctx, EXCP_DBp);
11228 generate_exception(ctx, EXCP_DBp);
11232 goto pool32axf_invalid;
11238 gen_HILO(ctx, OPC_MFHI, rs);
11241 gen_HILO(ctx, OPC_MFLO, rs);
11244 gen_HILO(ctx, OPC_MTHI, rs);
11247 gen_HILO(ctx, OPC_MTLO, rs);
11250 goto pool32axf_invalid;
11255 MIPS_INVAL("pool32axf");
11256 generate_exception(ctx, EXCP_RI);
11261 /* Values for microMIPS fmt field. Variable-width, depending on which
11262 formats the instruction supports. */
11281 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11283 int extension = (ctx->opcode >> 6) & 0x3ff;
11284 uint32_t mips32_op;
11286 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11287 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11288 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11290 switch (extension) {
11291 case FLOAT_1BIT_FMT(CFC1, 0):
11292 mips32_op = OPC_CFC1;
11294 case FLOAT_1BIT_FMT(CTC1, 0):
11295 mips32_op = OPC_CTC1;
11297 case FLOAT_1BIT_FMT(MFC1, 0):
11298 mips32_op = OPC_MFC1;
11300 case FLOAT_1BIT_FMT(MTC1, 0):
11301 mips32_op = OPC_MTC1;
11303 case FLOAT_1BIT_FMT(MFHC1, 0):
11304 mips32_op = OPC_MFHC1;
11306 case FLOAT_1BIT_FMT(MTHC1, 0):
11307 mips32_op = OPC_MTHC1;
11309 gen_cp1(ctx, mips32_op, rt, rs);
11312 /* Reciprocal square root */
11313 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11314 mips32_op = OPC_RSQRT_S;
11316 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11317 mips32_op = OPC_RSQRT_D;
11321 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11322 mips32_op = OPC_SQRT_S;
11324 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11325 mips32_op = OPC_SQRT_D;
11329 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11330 mips32_op = OPC_RECIP_S;
11332 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11333 mips32_op = OPC_RECIP_D;
11337 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11338 mips32_op = OPC_FLOOR_L_S;
11340 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11341 mips32_op = OPC_FLOOR_L_D;
11343 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11344 mips32_op = OPC_FLOOR_W_S;
11346 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11347 mips32_op = OPC_FLOOR_W_D;
11351 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11352 mips32_op = OPC_CEIL_L_S;
11354 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11355 mips32_op = OPC_CEIL_L_D;
11357 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11358 mips32_op = OPC_CEIL_W_S;
11360 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11361 mips32_op = OPC_CEIL_W_D;
11365 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11366 mips32_op = OPC_TRUNC_L_S;
11368 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11369 mips32_op = OPC_TRUNC_L_D;
11371 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11372 mips32_op = OPC_TRUNC_W_S;
11374 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11375 mips32_op = OPC_TRUNC_W_D;
11379 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11380 mips32_op = OPC_ROUND_L_S;
11382 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11383 mips32_op = OPC_ROUND_L_D;
11385 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11386 mips32_op = OPC_ROUND_W_S;
11388 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11389 mips32_op = OPC_ROUND_W_D;
11392 /* Integer to floating-point conversion */
11393 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11394 mips32_op = OPC_CVT_L_S;
11396 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11397 mips32_op = OPC_CVT_L_D;
11399 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11400 mips32_op = OPC_CVT_W_S;
11402 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11403 mips32_op = OPC_CVT_W_D;
11406 /* Paired-foo conversions */
11407 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11408 mips32_op = OPC_CVT_S_PL;
11410 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11411 mips32_op = OPC_CVT_S_PU;
11413 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11414 mips32_op = OPC_CVT_PW_PS;
11416 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11417 mips32_op = OPC_CVT_PS_PW;
11420 /* Floating-point moves */
11421 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11422 mips32_op = OPC_MOV_S;
11424 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11425 mips32_op = OPC_MOV_D;
11427 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11428 mips32_op = OPC_MOV_PS;
11431 /* Absolute value */
11432 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11433 mips32_op = OPC_ABS_S;
11435 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11436 mips32_op = OPC_ABS_D;
11438 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11439 mips32_op = OPC_ABS_PS;
11443 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11444 mips32_op = OPC_NEG_S;
11446 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11447 mips32_op = OPC_NEG_D;
11449 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11450 mips32_op = OPC_NEG_PS;
11453 /* Reciprocal square root step */
11454 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11455 mips32_op = OPC_RSQRT1_S;
11457 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11458 mips32_op = OPC_RSQRT1_D;
11460 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11461 mips32_op = OPC_RSQRT1_PS;
11464 /* Reciprocal step */
11465 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11466 mips32_op = OPC_RECIP1_S;
11468 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11469 mips32_op = OPC_RECIP1_S;
11471 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11472 mips32_op = OPC_RECIP1_PS;
11475 /* Conversions from double */
11476 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11477 mips32_op = OPC_CVT_D_S;
11479 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11480 mips32_op = OPC_CVT_D_W;
11482 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11483 mips32_op = OPC_CVT_D_L;
11486 /* Conversions from single */
11487 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11488 mips32_op = OPC_CVT_S_D;
11490 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11491 mips32_op = OPC_CVT_S_W;
11493 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11494 mips32_op = OPC_CVT_S_L;
11496 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11499 /* Conditional moves on floating-point codes */
11500 case COND_FLOAT_MOV(MOVT, 0):
11501 case COND_FLOAT_MOV(MOVT, 1):
11502 case COND_FLOAT_MOV(MOVT, 2):
11503 case COND_FLOAT_MOV(MOVT, 3):
11504 case COND_FLOAT_MOV(MOVT, 4):
11505 case COND_FLOAT_MOV(MOVT, 5):
11506 case COND_FLOAT_MOV(MOVT, 6):
11507 case COND_FLOAT_MOV(MOVT, 7):
11508 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11510 case COND_FLOAT_MOV(MOVF, 0):
11511 case COND_FLOAT_MOV(MOVF, 1):
11512 case COND_FLOAT_MOV(MOVF, 2):
11513 case COND_FLOAT_MOV(MOVF, 3):
11514 case COND_FLOAT_MOV(MOVF, 4):
11515 case COND_FLOAT_MOV(MOVF, 5):
11516 case COND_FLOAT_MOV(MOVF, 6):
11517 case COND_FLOAT_MOV(MOVF, 7):
11518 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11521 MIPS_INVAL("pool32fxf");
11522 generate_exception(ctx, EXCP_RI);
11527 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11528 uint16_t insn_hw1, int *is_branch)
11532 int rt, rs, rd, rr;
11534 uint32_t op, minor, mips32_op;
11535 uint32_t cond, fmt, cc;
11537 insn = cpu_lduw_code(env, ctx->pc + 2);
11538 ctx->opcode = (ctx->opcode << 16) | insn;
11540 rt = (ctx->opcode >> 21) & 0x1f;
11541 rs = (ctx->opcode >> 16) & 0x1f;
11542 rd = (ctx->opcode >> 11) & 0x1f;
11543 rr = (ctx->opcode >> 6) & 0x1f;
11544 imm = (int16_t) ctx->opcode;
11546 op = (ctx->opcode >> 26) & 0x3f;
11549 minor = ctx->opcode & 0x3f;
11552 minor = (ctx->opcode >> 6) & 0xf;
11555 mips32_op = OPC_SLL;
11558 mips32_op = OPC_SRA;
11561 mips32_op = OPC_SRL;
11564 mips32_op = OPC_ROTR;
11566 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11569 goto pool32a_invalid;
11573 minor = (ctx->opcode >> 6) & 0xf;
11577 mips32_op = OPC_ADD;
11580 mips32_op = OPC_ADDU;
11583 mips32_op = OPC_SUB;
11586 mips32_op = OPC_SUBU;
11589 mips32_op = OPC_MUL;
11591 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11595 mips32_op = OPC_SLLV;
11598 mips32_op = OPC_SRLV;
11601 mips32_op = OPC_SRAV;
11604 mips32_op = OPC_ROTRV;
11606 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11608 /* Logical operations */
11610 mips32_op = OPC_AND;
11613 mips32_op = OPC_OR;
11616 mips32_op = OPC_NOR;
11619 mips32_op = OPC_XOR;
11621 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11623 /* Set less than */
11625 mips32_op = OPC_SLT;
11628 mips32_op = OPC_SLTU;
11630 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11633 goto pool32a_invalid;
11637 minor = (ctx->opcode >> 6) & 0xf;
11639 /* Conditional moves */
11641 mips32_op = OPC_MOVN;
11644 mips32_op = OPC_MOVZ;
11646 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11649 gen_ldxs(ctx, rs, rt, rd);
11652 goto pool32a_invalid;
11656 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11659 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11662 gen_pool32axf(env, ctx, rt, rs, is_branch);
11665 generate_exception(ctx, EXCP_BREAK);
11669 MIPS_INVAL("pool32a");
11670 generate_exception(ctx, EXCP_RI);
11675 minor = (ctx->opcode >> 12) & 0xf;
11678 check_cp0_enabled(ctx);
11679 /* Treat as no-op. */
11683 /* COP2: Not implemented. */
11684 generate_exception_err(ctx, EXCP_CpU, 2);
11688 #ifdef TARGET_MIPS64
11692 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11696 #ifdef TARGET_MIPS64
11700 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11703 MIPS_INVAL("pool32b");
11704 generate_exception(ctx, EXCP_RI);
11709 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11710 minor = ctx->opcode & 0x3f;
11711 check_cp1_enabled(ctx);
11714 mips32_op = OPC_ALNV_PS;
11717 mips32_op = OPC_MADD_S;
11720 mips32_op = OPC_MADD_D;
11723 mips32_op = OPC_MADD_PS;
11726 mips32_op = OPC_MSUB_S;
11729 mips32_op = OPC_MSUB_D;
11732 mips32_op = OPC_MSUB_PS;
11735 mips32_op = OPC_NMADD_S;
11738 mips32_op = OPC_NMADD_D;
11741 mips32_op = OPC_NMADD_PS;
11744 mips32_op = OPC_NMSUB_S;
11747 mips32_op = OPC_NMSUB_D;
11750 mips32_op = OPC_NMSUB_PS;
11752 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11754 case CABS_COND_FMT:
11755 cond = (ctx->opcode >> 6) & 0xf;
11756 cc = (ctx->opcode >> 13) & 0x7;
11757 fmt = (ctx->opcode >> 10) & 0x3;
11760 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11763 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11766 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11769 goto pool32f_invalid;
11773 cond = (ctx->opcode >> 6) & 0xf;
11774 cc = (ctx->opcode >> 13) & 0x7;
11775 fmt = (ctx->opcode >> 10) & 0x3;
11778 gen_cmp_s(ctx, cond, rt, rs, cc);
11781 gen_cmp_d(ctx, cond, rt, rs, cc);
11784 gen_cmp_ps(ctx, cond, rt, rs, cc);
11787 goto pool32f_invalid;
11791 gen_pool32fxf(env, ctx, rt, rs);
11795 switch ((ctx->opcode >> 6) & 0x7) {
11797 mips32_op = OPC_PLL_PS;
11800 mips32_op = OPC_PLU_PS;
11803 mips32_op = OPC_PUL_PS;
11806 mips32_op = OPC_PUU_PS;
11809 mips32_op = OPC_CVT_PS_S;
11811 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11814 goto pool32f_invalid;
11819 switch ((ctx->opcode >> 6) & 0x7) {
11821 mips32_op = OPC_LWXC1;
11824 mips32_op = OPC_SWXC1;
11827 mips32_op = OPC_LDXC1;
11830 mips32_op = OPC_SDXC1;
11833 mips32_op = OPC_LUXC1;
11836 mips32_op = OPC_SUXC1;
11838 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11841 goto pool32f_invalid;
11846 fmt = (ctx->opcode >> 9) & 0x3;
11847 switch ((ctx->opcode >> 6) & 0x7) {
11851 mips32_op = OPC_RSQRT2_S;
11854 mips32_op = OPC_RSQRT2_D;
11857 mips32_op = OPC_RSQRT2_PS;
11860 goto pool32f_invalid;
11866 mips32_op = OPC_RECIP2_S;
11869 mips32_op = OPC_RECIP2_D;
11872 mips32_op = OPC_RECIP2_PS;
11875 goto pool32f_invalid;
11879 mips32_op = OPC_ADDR_PS;
11882 mips32_op = OPC_MULR_PS;
11884 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11887 goto pool32f_invalid;
11891 /* MOV[FT].fmt and PREFX */
11892 cc = (ctx->opcode >> 13) & 0x7;
11893 fmt = (ctx->opcode >> 9) & 0x3;
11894 switch ((ctx->opcode >> 6) & 0x7) {
11898 gen_movcf_s(rs, rt, cc, 0);
11901 gen_movcf_d(ctx, rs, rt, cc, 0);
11904 gen_movcf_ps(rs, rt, cc, 0);
11907 goto pool32f_invalid;
11913 gen_movcf_s(rs, rt, cc, 1);
11916 gen_movcf_d(ctx, rs, rt, cc, 1);
11919 gen_movcf_ps(rs, rt, cc, 1);
11922 goto pool32f_invalid;
11928 goto pool32f_invalid;
11931 #define FINSN_3ARG_SDPS(prfx) \
11932 switch ((ctx->opcode >> 8) & 0x3) { \
11934 mips32_op = OPC_##prfx##_S; \
11937 mips32_op = OPC_##prfx##_D; \
11939 case FMT_SDPS_PS: \
11940 mips32_op = OPC_##prfx##_PS; \
11943 goto pool32f_invalid; \
11946 /* regular FP ops */
11947 switch ((ctx->opcode >> 6) & 0x3) {
11949 FINSN_3ARG_SDPS(ADD);
11952 FINSN_3ARG_SDPS(SUB);
11955 FINSN_3ARG_SDPS(MUL);
11958 fmt = (ctx->opcode >> 8) & 0x3;
11960 mips32_op = OPC_DIV_D;
11961 } else if (fmt == 0) {
11962 mips32_op = OPC_DIV_S;
11964 goto pool32f_invalid;
11968 goto pool32f_invalid;
11973 switch ((ctx->opcode >> 6) & 0x3) {
11975 FINSN_3ARG_SDPS(MOVN);
11978 FINSN_3ARG_SDPS(MOVZ);
11981 goto pool32f_invalid;
11985 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11989 MIPS_INVAL("pool32f");
11990 generate_exception(ctx, EXCP_RI);
11994 generate_exception_err(ctx, EXCP_CpU, 1);
11998 minor = (ctx->opcode >> 21) & 0x1f;
12001 mips32_op = OPC_BLTZ;
12004 mips32_op = OPC_BLTZAL;
12007 mips32_op = OPC_BLTZALS;
12010 mips32_op = OPC_BGEZ;
12013 mips32_op = OPC_BGEZAL;
12016 mips32_op = OPC_BGEZALS;
12019 mips32_op = OPC_BLEZ;
12022 mips32_op = OPC_BGTZ;
12024 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12030 mips32_op = OPC_TLTI;
12033 mips32_op = OPC_TGEI;
12036 mips32_op = OPC_TLTIU;
12039 mips32_op = OPC_TGEIU;
12042 mips32_op = OPC_TNEI;
12045 mips32_op = OPC_TEQI;
12047 gen_trap(ctx, mips32_op, rs, -1, imm);
12052 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12053 4, rs, 0, imm << 1);
12054 /* Compact branches don't have a delay slot, so just let
12055 the normal delay slot handling take us to the branch
12059 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12065 /* COP2: Not implemented. */
12066 generate_exception_err(ctx, EXCP_CpU, 2);
12069 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12072 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12075 mips32_op = OPC_BC1FANY4;
12078 mips32_op = OPC_BC1TANY4;
12081 check_insn(env, ctx, ASE_MIPS3D);
12084 gen_compute_branch1(env, ctx, mips32_op,
12085 (ctx->opcode >> 18) & 0x7, imm << 1);
12090 /* MIPS DSP: not implemented */
12093 MIPS_INVAL("pool32i");
12094 generate_exception(ctx, EXCP_RI);
12099 minor = (ctx->opcode >> 12) & 0xf;
12102 mips32_op = OPC_LWL;
12105 mips32_op = OPC_SWL;
12108 mips32_op = OPC_LWR;
12111 mips32_op = OPC_SWR;
12113 #if defined(TARGET_MIPS64)
12115 mips32_op = OPC_LDL;
12118 mips32_op = OPC_SDL;
12121 mips32_op = OPC_LDR;
12124 mips32_op = OPC_SDR;
12127 mips32_op = OPC_LWU;
12130 mips32_op = OPC_LLD;
12134 mips32_op = OPC_LL;
12137 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12140 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12143 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12145 #if defined(TARGET_MIPS64)
12147 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12151 /* Treat as no-op */
12154 MIPS_INVAL("pool32c");
12155 generate_exception(ctx, EXCP_RI);
12160 mips32_op = OPC_ADDI;
12163 mips32_op = OPC_ADDIU;
12165 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12168 /* Logical operations */
12170 mips32_op = OPC_ORI;
12173 mips32_op = OPC_XORI;
12176 mips32_op = OPC_ANDI;
12178 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12181 /* Set less than immediate */
12183 mips32_op = OPC_SLTI;
12186 mips32_op = OPC_SLTIU;
12188 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12191 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12192 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12196 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12197 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12201 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12205 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12209 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12210 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12214 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12215 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12218 /* Floating point (COP1) */
12220 mips32_op = OPC_LWC1;
12223 mips32_op = OPC_LDC1;
12226 mips32_op = OPC_SWC1;
12229 mips32_op = OPC_SDC1;
12231 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12235 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12236 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12238 gen_addiupc(ctx, reg, offset, 0, 0);
12241 /* Loads and stores */
12243 mips32_op = OPC_LB;
12246 mips32_op = OPC_LBU;
12249 mips32_op = OPC_LH;
12252 mips32_op = OPC_LHU;
12255 mips32_op = OPC_LW;
12257 #ifdef TARGET_MIPS64
12259 mips32_op = OPC_LD;
12262 mips32_op = OPC_SD;
12266 mips32_op = OPC_SB;
12269 mips32_op = OPC_SH;
12272 mips32_op = OPC_SW;
12275 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12278 gen_st(ctx, mips32_op, rt, rs, imm);
12281 generate_exception(ctx, EXCP_RI);
12286 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12290 /* make sure instructions are on a halfword boundary */
12291 if (ctx->pc & 0x1) {
12292 env->CP0_BadVAddr = ctx->pc;
12293 generate_exception(ctx, EXCP_AdEL);
12294 ctx->bstate = BS_STOP;
12298 op = (ctx->opcode >> 10) & 0x3f;
12299 /* Enforce properly-sized instructions in a delay slot */
12300 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12301 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12335 case POOL48A: /* ??? */
12340 if (bits & MIPS_HFLAG_BDS16) {
12341 generate_exception(ctx, EXCP_RI);
12342 /* Just stop translation; the user is confused. */
12343 ctx->bstate = BS_STOP;
12368 if (bits & MIPS_HFLAG_BDS32) {
12369 generate_exception(ctx, EXCP_RI);
12370 /* Just stop translation; the user is confused. */
12371 ctx->bstate = BS_STOP;
12382 int rd = mmreg(uMIPS_RD(ctx->opcode));
12383 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12384 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12387 switch (ctx->opcode & 0x1) {
12396 gen_arith(env, ctx, opc, rd, rs1, rs2);
12401 int rd = mmreg(uMIPS_RD(ctx->opcode));
12402 int rs = mmreg(uMIPS_RS(ctx->opcode));
12403 int amount = (ctx->opcode >> 1) & 0x7;
12405 amount = amount == 0 ? 8 : amount;
12407 switch (ctx->opcode & 0x1) {
12416 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12420 gen_pool16c_insn(env, ctx, is_branch);
12424 int rd = mmreg(uMIPS_RD(ctx->opcode));
12425 int rb = 28; /* GP */
12426 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12428 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12432 if (ctx->opcode & 1) {
12433 generate_exception(ctx, EXCP_RI);
12436 int enc_dest = uMIPS_RD(ctx->opcode);
12437 int enc_rt = uMIPS_RS2(ctx->opcode);
12438 int enc_rs = uMIPS_RS1(ctx->opcode);
12439 int rd, rs, re, rt;
12440 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12441 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12442 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12444 rd = rd_enc[enc_dest];
12445 re = re_enc[enc_dest];
12446 rs = rs_rt_enc[enc_rs];
12447 rt = rs_rt_enc[enc_rt];
12449 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12450 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12455 int rd = mmreg(uMIPS_RD(ctx->opcode));
12456 int rb = mmreg(uMIPS_RS(ctx->opcode));
12457 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12458 offset = (offset == 0xf ? -1 : offset);
12460 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12465 int rd = mmreg(uMIPS_RD(ctx->opcode));
12466 int rb = mmreg(uMIPS_RS(ctx->opcode));
12467 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12469 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12474 int rd = (ctx->opcode >> 5) & 0x1f;
12475 int rb = 29; /* SP */
12476 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12478 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12483 int rd = mmreg(uMIPS_RD(ctx->opcode));
12484 int rb = mmreg(uMIPS_RS(ctx->opcode));
12485 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12487 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12492 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12493 int rb = mmreg(uMIPS_RS(ctx->opcode));
12494 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12496 gen_st(ctx, OPC_SB, rd, rb, offset);
12501 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12502 int rb = mmreg(uMIPS_RS(ctx->opcode));
12503 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12505 gen_st(ctx, OPC_SH, rd, rb, offset);
12510 int rd = (ctx->opcode >> 5) & 0x1f;
12511 int rb = 29; /* SP */
12512 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12514 gen_st(ctx, OPC_SW, rd, rb, offset);
12519 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12520 int rb = mmreg(uMIPS_RS(ctx->opcode));
12521 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12523 gen_st(ctx, OPC_SW, rd, rb, offset);
12528 int rd = uMIPS_RD5(ctx->opcode);
12529 int rs = uMIPS_RS5(ctx->opcode);
12531 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12535 gen_andi16(env, ctx);
12538 switch (ctx->opcode & 0x1) {
12540 gen_addius5(env, ctx);
12543 gen_addiusp(env, ctx);
12548 switch (ctx->opcode & 0x1) {
12550 gen_addiur2(env, ctx);
12553 gen_addiur1sp(env, ctx);
12558 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12559 SIMM(ctx->opcode, 0, 10) << 1);
12564 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12565 mmreg(uMIPS_RD(ctx->opcode)),
12566 0, SIMM(ctx->opcode, 0, 7) << 1);
12571 int reg = mmreg(uMIPS_RD(ctx->opcode));
12572 int imm = ZIMM(ctx->opcode, 0, 7);
12574 imm = (imm == 0x7f ? -1 : imm);
12575 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12585 generate_exception(ctx, EXCP_RI);
12588 decode_micromips32_opc (env, ctx, op, is_branch);
12595 /* SmartMIPS extension to MIPS32 */
12597 #if defined(TARGET_MIPS64)
12599 /* MDMX extension to MIPS64 */
12603 /* MIPSDSP functions. */
12604 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12605 int rd, int base, int offset)
12607 const char *opn = "ldx";
12616 t0 = tcg_temp_new();
12619 gen_load_gpr(t0, offset);
12620 } else if (offset == 0) {
12621 gen_load_gpr(t0, base);
12623 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12628 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12629 gen_store_gpr(t0, rd);
12633 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12634 gen_store_gpr(t0, rd);
12638 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12639 gen_store_gpr(t0, rd);
12642 #if defined(TARGET_MIPS64)
12644 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12645 gen_store_gpr(t0, rd);
12650 (void)opn; /* avoid a compiler warning */
12651 MIPS_DEBUG("%s %s, %s(%s)", opn,
12652 regnames[rd], regnames[offset], regnames[base]);
12656 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12657 int ret, int v1, int v2)
12659 const char *opn = "mipsdsp arith";
12664 /* Treat as NOP. */
12669 v1_t = tcg_temp_new();
12670 v2_t = tcg_temp_new();
12672 gen_load_gpr(v1_t, v1);
12673 gen_load_gpr(v2_t, v2);
12676 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12677 case OPC_MULT_G_2E:
12681 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12683 case OPC_ADDUH_R_QB:
12684 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12687 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12689 case OPC_ADDQH_R_PH:
12690 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12693 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12695 case OPC_ADDQH_R_W:
12696 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12699 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12701 case OPC_SUBUH_R_QB:
12702 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12705 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12707 case OPC_SUBQH_R_PH:
12708 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12711 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12713 case OPC_SUBQH_R_W:
12714 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12718 case OPC_ABSQ_S_PH_DSP:
12720 case OPC_ABSQ_S_QB:
12722 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12724 case OPC_ABSQ_S_PH:
12726 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12730 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12732 case OPC_PRECEQ_W_PHL:
12734 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12735 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12737 case OPC_PRECEQ_W_PHR:
12739 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12740 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12741 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12743 case OPC_PRECEQU_PH_QBL:
12745 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12747 case OPC_PRECEQU_PH_QBR:
12749 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12751 case OPC_PRECEQU_PH_QBLA:
12753 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12755 case OPC_PRECEQU_PH_QBRA:
12757 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12759 case OPC_PRECEU_PH_QBL:
12761 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12763 case OPC_PRECEU_PH_QBR:
12765 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12767 case OPC_PRECEU_PH_QBLA:
12769 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12771 case OPC_PRECEU_PH_QBRA:
12773 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12777 case OPC_ADDU_QB_DSP:
12781 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12783 case OPC_ADDQ_S_PH:
12785 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12789 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12793 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12795 case OPC_ADDU_S_QB:
12797 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12801 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12803 case OPC_ADDU_S_PH:
12805 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12809 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12811 case OPC_SUBQ_S_PH:
12813 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12817 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12821 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12823 case OPC_SUBU_S_QB:
12825 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12829 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12831 case OPC_SUBU_S_PH:
12833 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12837 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12841 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12845 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12847 case OPC_RADDU_W_QB:
12849 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12853 case OPC_CMPU_EQ_QB_DSP:
12855 case OPC_PRECR_QB_PH:
12857 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12859 case OPC_PRECRQ_QB_PH:
12861 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12863 case OPC_PRECR_SRA_PH_W:
12866 TCGv_i32 sa_t = tcg_const_i32(v2);
12867 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12869 tcg_temp_free_i32(sa_t);
12872 case OPC_PRECR_SRA_R_PH_W:
12875 TCGv_i32 sa_t = tcg_const_i32(v2);
12876 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12878 tcg_temp_free_i32(sa_t);
12881 case OPC_PRECRQ_PH_W:
12883 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12885 case OPC_PRECRQ_RS_PH_W:
12887 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 case OPC_PRECRQU_S_QB_PH:
12891 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12895 #ifdef TARGET_MIPS64
12896 case OPC_ABSQ_S_QH_DSP:
12898 case OPC_PRECEQ_L_PWL:
12900 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12902 case OPC_PRECEQ_L_PWR:
12904 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12906 case OPC_PRECEQ_PW_QHL:
12908 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12910 case OPC_PRECEQ_PW_QHR:
12912 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12914 case OPC_PRECEQ_PW_QHLA:
12916 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12918 case OPC_PRECEQ_PW_QHRA:
12920 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12922 case OPC_PRECEQU_QH_OBL:
12924 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12926 case OPC_PRECEQU_QH_OBR:
12928 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12930 case OPC_PRECEQU_QH_OBLA:
12932 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12934 case OPC_PRECEQU_QH_OBRA:
12936 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12938 case OPC_PRECEU_QH_OBL:
12940 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12942 case OPC_PRECEU_QH_OBR:
12944 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12946 case OPC_PRECEU_QH_OBLA:
12948 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12950 case OPC_PRECEU_QH_OBRA:
12952 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12954 case OPC_ABSQ_S_OB:
12956 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12958 case OPC_ABSQ_S_PW:
12960 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12962 case OPC_ABSQ_S_QH:
12964 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12968 case OPC_ADDU_OB_DSP:
12970 case OPC_RADDU_L_OB:
12972 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12976 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12978 case OPC_SUBQ_S_PW:
12980 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12984 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12986 case OPC_SUBQ_S_QH:
12988 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12992 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12994 case OPC_SUBU_S_OB:
12996 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13000 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13002 case OPC_SUBU_S_QH:
13004 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13008 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13010 case OPC_SUBUH_R_OB:
13012 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13016 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13018 case OPC_ADDQ_S_PW:
13020 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13024 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13026 case OPC_ADDQ_S_QH:
13028 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13032 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13034 case OPC_ADDU_S_OB:
13036 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13040 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13042 case OPC_ADDU_S_QH:
13044 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13050 case OPC_ADDUH_R_OB:
13052 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13056 case OPC_CMPU_EQ_OB_DSP:
13058 case OPC_PRECR_OB_QH:
13060 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13062 case OPC_PRECR_SRA_QH_PW:
13065 TCGv_i32 ret_t = tcg_const_i32(ret);
13066 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13067 tcg_temp_free_i32(ret_t);
13070 case OPC_PRECR_SRA_R_QH_PW:
13073 TCGv_i32 sa_v = tcg_const_i32(ret);
13074 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13075 tcg_temp_free_i32(sa_v);
13078 case OPC_PRECRQ_OB_QH:
13080 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13082 case OPC_PRECRQ_PW_L:
13084 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13086 case OPC_PRECRQ_QH_PW:
13088 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13090 case OPC_PRECRQ_RS_QH_PW:
13092 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13094 case OPC_PRECRQU_S_OB_QH:
13096 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13103 tcg_temp_free(v1_t);
13104 tcg_temp_free(v2_t);
13106 (void)opn; /* avoid a compiler warning */
13107 MIPS_DEBUG("%s", opn);
13110 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13111 int ret, int v1, int v2)
13114 const char *opn = "mipsdsp shift";
13120 /* Treat as NOP. */
13125 t0 = tcg_temp_new();
13126 v1_t = tcg_temp_new();
13127 v2_t = tcg_temp_new();
13129 tcg_gen_movi_tl(t0, v1);
13130 gen_load_gpr(v1_t, v1);
13131 gen_load_gpr(v2_t, v2);
13134 case OPC_SHLL_QB_DSP:
13136 op2 = MASK_SHLL_QB(ctx->opcode);
13140 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13144 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13148 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13152 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13154 case OPC_SHLL_S_PH:
13156 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13158 case OPC_SHLLV_S_PH:
13160 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13164 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13166 case OPC_SHLLV_S_W:
13168 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13172 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13176 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13180 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13184 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13188 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13190 case OPC_SHRA_R_QB:
13192 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13196 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13198 case OPC_SHRAV_R_QB:
13200 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13204 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13206 case OPC_SHRA_R_PH:
13208 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13212 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13214 case OPC_SHRAV_R_PH:
13216 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13220 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13222 case OPC_SHRAV_R_W:
13224 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13226 default: /* Invalid */
13227 MIPS_INVAL("MASK SHLL.QB");
13228 generate_exception(ctx, EXCP_RI);
13233 #ifdef TARGET_MIPS64
13234 case OPC_SHLL_OB_DSP:
13235 op2 = MASK_SHLL_OB(ctx->opcode);
13239 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13243 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13245 case OPC_SHLL_S_PW:
13247 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13249 case OPC_SHLLV_S_PW:
13251 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13255 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13259 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13263 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13267 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13269 case OPC_SHLL_S_QH:
13271 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13273 case OPC_SHLLV_S_QH:
13275 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13279 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13283 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13285 case OPC_SHRA_R_OB:
13287 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13289 case OPC_SHRAV_R_OB:
13291 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13295 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13299 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13301 case OPC_SHRA_R_PW:
13303 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13305 case OPC_SHRAV_R_PW:
13307 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13311 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13315 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13317 case OPC_SHRA_R_QH:
13319 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13321 case OPC_SHRAV_R_QH:
13323 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13327 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13331 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13335 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13339 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13341 default: /* Invalid */
13342 MIPS_INVAL("MASK SHLL.OB");
13343 generate_exception(ctx, EXCP_RI);
13351 tcg_temp_free(v1_t);
13352 tcg_temp_free(v2_t);
13353 (void)opn; /* avoid a compiler warning */
13354 MIPS_DEBUG("%s", opn);
13357 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13358 int ret, int v1, int v2, int check_ret)
13360 const char *opn = "mipsdsp multiply";
13365 if ((ret == 0) && (check_ret == 1)) {
13366 /* Treat as NOP. */
13371 t0 = tcg_temp_new_i32();
13372 v1_t = tcg_temp_new();
13373 v2_t = tcg_temp_new();
13375 tcg_gen_movi_i32(t0, ret);
13376 gen_load_gpr(v1_t, v1);
13377 gen_load_gpr(v2_t, v2);
13380 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13381 * the same mask and op1. */
13382 case OPC_MULT_G_2E:
13385 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13388 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13391 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13393 case OPC_MULQ_RS_W:
13394 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13398 case OPC_DPA_W_PH_DSP:
13400 case OPC_DPAU_H_QBL:
13402 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13404 case OPC_DPAU_H_QBR:
13406 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13408 case OPC_DPSU_H_QBL:
13410 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13412 case OPC_DPSU_H_QBR:
13414 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13418 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13420 case OPC_DPAX_W_PH:
13422 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13424 case OPC_DPAQ_S_W_PH:
13426 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13428 case OPC_DPAQX_S_W_PH:
13430 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13432 case OPC_DPAQX_SA_W_PH:
13434 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13438 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13440 case OPC_DPSX_W_PH:
13442 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13444 case OPC_DPSQ_S_W_PH:
13446 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13448 case OPC_DPSQX_S_W_PH:
13450 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13452 case OPC_DPSQX_SA_W_PH:
13454 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13456 case OPC_MULSAQ_S_W_PH:
13458 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13460 case OPC_DPAQ_SA_L_W:
13462 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13464 case OPC_DPSQ_SA_L_W:
13466 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13468 case OPC_MAQ_S_W_PHL:
13470 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13472 case OPC_MAQ_S_W_PHR:
13474 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13476 case OPC_MAQ_SA_W_PHL:
13478 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13480 case OPC_MAQ_SA_W_PHR:
13482 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13484 case OPC_MULSA_W_PH:
13486 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13490 #ifdef TARGET_MIPS64
13491 case OPC_DPAQ_W_QH_DSP:
13493 int ac = ret & 0x03;
13494 tcg_gen_movi_i32(t0, ac);
13499 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13503 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13507 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13511 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13515 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13517 case OPC_DPAQ_S_W_QH:
13519 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13521 case OPC_DPAQ_SA_L_PW:
13523 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13525 case OPC_DPAU_H_OBL:
13527 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13529 case OPC_DPAU_H_OBR:
13531 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13535 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13537 case OPC_DPSQ_S_W_QH:
13539 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13541 case OPC_DPSQ_SA_L_PW:
13543 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13545 case OPC_DPSU_H_OBL:
13547 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13549 case OPC_DPSU_H_OBR:
13551 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13553 case OPC_MAQ_S_L_PWL:
13555 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13557 case OPC_MAQ_S_L_PWR:
13559 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13561 case OPC_MAQ_S_W_QHLL:
13563 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13565 case OPC_MAQ_SA_W_QHLL:
13567 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13569 case OPC_MAQ_S_W_QHLR:
13571 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13573 case OPC_MAQ_SA_W_QHLR:
13575 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13577 case OPC_MAQ_S_W_QHRL:
13579 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13581 case OPC_MAQ_SA_W_QHRL:
13583 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13585 case OPC_MAQ_S_W_QHRR:
13587 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13589 case OPC_MAQ_SA_W_QHRR:
13591 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13593 case OPC_MULSAQ_S_L_PW:
13595 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13597 case OPC_MULSAQ_S_W_QH:
13599 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13605 case OPC_ADDU_QB_DSP:
13607 case OPC_MULEU_S_PH_QBL:
13609 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13611 case OPC_MULEU_S_PH_QBR:
13613 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13615 case OPC_MULQ_RS_PH:
13617 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13619 case OPC_MULEQ_S_W_PHL:
13621 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13623 case OPC_MULEQ_S_W_PHR:
13625 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13627 case OPC_MULQ_S_PH:
13629 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13633 #ifdef TARGET_MIPS64
13634 case OPC_ADDU_OB_DSP:
13636 case OPC_MULEQ_S_PW_QHL:
13638 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13640 case OPC_MULEQ_S_PW_QHR:
13642 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13644 case OPC_MULEU_S_QH_OBL:
13646 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13648 case OPC_MULEU_S_QH_OBR:
13650 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13652 case OPC_MULQ_RS_QH:
13654 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13661 tcg_temp_free_i32(t0);
13662 tcg_temp_free(v1_t);
13663 tcg_temp_free(v2_t);
13665 (void)opn; /* avoid a compiler warning */
13666 MIPS_DEBUG("%s", opn);
13670 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13671 uint32_t op1, uint32_t op2,
13674 const char *opn = "mipsdsp Bit/ Manipulation";
13680 /* Treat as NOP. */
13685 t0 = tcg_temp_new();
13686 val_t = tcg_temp_new();
13687 gen_load_gpr(val_t, val);
13690 case OPC_ABSQ_S_PH_DSP:
13694 gen_helper_bitrev(cpu_gpr[ret], val_t);
13699 target_long result;
13700 imm = (ctx->opcode >> 16) & 0xFF;
13701 result = (uint32_t)imm << 24 |
13702 (uint32_t)imm << 16 |
13703 (uint32_t)imm << 8 |
13705 result = (int32_t)result;
13706 tcg_gen_movi_tl(cpu_gpr[ret], result);
13711 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13712 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13713 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13714 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13715 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13716 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13721 imm = (ctx->opcode >> 16) & 0x03FF;
13722 tcg_gen_movi_tl(cpu_gpr[ret], \
13723 (target_long)((int32_t)imm << 16 | \
13724 (uint32_t)(uint16_t)imm));
13729 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13730 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13731 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13732 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13736 #ifdef TARGET_MIPS64
13737 case OPC_ABSQ_S_QH_DSP:
13744 imm = (ctx->opcode >> 16) & 0xFF;
13745 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13746 temp = (temp << 16) | temp;
13747 temp = (temp << 32) | temp;
13748 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13756 imm = (ctx->opcode >> 16) & 0x03FF;
13757 imm = (int16_t)(imm << 6) >> 6;
13758 temp = ((target_long)imm << 32) \
13759 | ((target_long)imm & 0xFFFFFFFF);
13760 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13768 imm = (ctx->opcode >> 16) & 0x03FF;
13769 imm = (int16_t)(imm << 6) >> 6;
13771 temp = ((uint64_t)(uint16_t)imm << 48) |
13772 ((uint64_t)(uint16_t)imm << 32) |
13773 ((uint64_t)(uint16_t)imm << 16) |
13774 (uint64_t)(uint16_t)imm;
13775 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13780 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13781 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13782 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13783 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13784 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13785 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13786 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13790 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13791 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13792 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13796 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13797 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13798 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13799 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13800 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13807 tcg_temp_free(val_t);
13809 (void)opn; /* avoid a compiler warning */
13810 MIPS_DEBUG("%s", opn);
13813 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13814 uint32_t op1, uint32_t op2,
13815 int ret, int v1, int v2, int check_ret)
13817 const char *opn = "mipsdsp add compare pick";
13823 if ((ret == 0) && (check_ret == 1)) {
13824 /* Treat as NOP. */
13829 t0 = tcg_temp_new_i32();
13830 t1 = tcg_temp_new();
13831 v1_t = tcg_temp_new();
13832 v2_t = tcg_temp_new();
13834 gen_load_gpr(v1_t, v1);
13835 gen_load_gpr(v2_t, v2);
13838 case OPC_APPEND_DSP:
13841 tcg_gen_movi_i32(t0, v2);
13842 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13845 tcg_gen_movi_i32(t0, v2);
13846 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13849 tcg_gen_movi_i32(t0, v2);
13850 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13852 default: /* Invid */
13853 MIPS_INVAL("MASK APPEND");
13854 generate_exception(ctx, EXCP_RI);
13858 case OPC_CMPU_EQ_QB_DSP:
13860 case OPC_CMPU_EQ_QB:
13862 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13864 case OPC_CMPU_LT_QB:
13866 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13868 case OPC_CMPU_LE_QB:
13870 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13872 case OPC_CMPGU_EQ_QB:
13874 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13876 case OPC_CMPGU_LT_QB:
13878 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13880 case OPC_CMPGU_LE_QB:
13882 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13884 case OPC_CMPGDU_EQ_QB:
13886 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13887 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13888 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13889 tcg_gen_shli_tl(t1, t1, 24);
13890 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13892 case OPC_CMPGDU_LT_QB:
13894 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13895 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13896 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13897 tcg_gen_shli_tl(t1, t1, 24);
13898 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13900 case OPC_CMPGDU_LE_QB:
13902 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13903 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13904 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13905 tcg_gen_shli_tl(t1, t1, 24);
13906 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13908 case OPC_CMP_EQ_PH:
13910 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13912 case OPC_CMP_LT_PH:
13914 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13916 case OPC_CMP_LE_PH:
13918 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13922 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13926 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13928 case OPC_PACKRL_PH:
13930 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13934 #ifdef TARGET_MIPS64
13935 case OPC_CMPU_EQ_OB_DSP:
13937 case OPC_CMP_EQ_PW:
13939 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13941 case OPC_CMP_LT_PW:
13943 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13945 case OPC_CMP_LE_PW:
13947 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13949 case OPC_CMP_EQ_QH:
13951 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13953 case OPC_CMP_LT_QH:
13955 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13957 case OPC_CMP_LE_QH:
13959 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13961 case OPC_CMPGDU_EQ_OB:
13963 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13965 case OPC_CMPGDU_LT_OB:
13967 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13969 case OPC_CMPGDU_LE_OB:
13971 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13973 case OPC_CMPGU_EQ_OB:
13975 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13977 case OPC_CMPGU_LT_OB:
13979 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13981 case OPC_CMPGU_LE_OB:
13983 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13985 case OPC_CMPU_EQ_OB:
13987 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13989 case OPC_CMPU_LT_OB:
13991 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13993 case OPC_CMPU_LE_OB:
13995 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13997 case OPC_PACKRL_PW:
13999 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14003 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14007 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14011 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14015 case OPC_DAPPEND_DSP:
14018 tcg_gen_movi_i32(t0, v2);
14019 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14022 tcg_gen_movi_i32(t0, v2);
14023 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14026 tcg_gen_movi_i32(t0, v2);
14027 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14030 tcg_gen_movi_i32(t0, v2);
14031 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14033 default: /* Invalid */
14034 MIPS_INVAL("MASK DAPPEND");
14035 generate_exception(ctx, EXCP_RI);
14042 tcg_temp_free_i32(t0);
14044 tcg_temp_free(v1_t);
14045 tcg_temp_free(v2_t);
14047 (void)opn; /* avoid a compiler warning */
14048 MIPS_DEBUG("%s", opn);
14051 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14052 int ret, int v1, int v2, int check_ret)
14055 const char *opn = "mipsdsp accumulator";
14062 if ((ret == 0) && (check_ret == 1)) {
14063 /* Treat as NOP. */
14068 t0 = tcg_temp_new();
14069 t1 = tcg_temp_new();
14070 v1_t = tcg_temp_new();
14071 v2_t = tcg_temp_new();
14073 gen_load_gpr(v1_t, v1);
14074 gen_load_gpr(v2_t, v2);
14077 case OPC_EXTR_W_DSP:
14081 tcg_gen_movi_tl(t0, v2);
14082 tcg_gen_movi_tl(t1, v1);
14083 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14086 tcg_gen_movi_tl(t0, v2);
14087 tcg_gen_movi_tl(t1, v1);
14088 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14090 case OPC_EXTR_RS_W:
14091 tcg_gen_movi_tl(t0, v2);
14092 tcg_gen_movi_tl(t1, v1);
14093 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14096 tcg_gen_movi_tl(t0, v2);
14097 tcg_gen_movi_tl(t1, v1);
14098 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14100 case OPC_EXTRV_S_H:
14101 tcg_gen_movi_tl(t0, v2);
14102 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14105 tcg_gen_movi_tl(t0, v2);
14106 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14108 case OPC_EXTRV_R_W:
14109 tcg_gen_movi_tl(t0, v2);
14110 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14112 case OPC_EXTRV_RS_W:
14113 tcg_gen_movi_tl(t0, v2);
14114 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14117 tcg_gen_movi_tl(t0, v2);
14118 tcg_gen_movi_tl(t1, v1);
14119 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14122 tcg_gen_movi_tl(t0, v2);
14123 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14126 tcg_gen_movi_tl(t0, v2);
14127 tcg_gen_movi_tl(t1, v1);
14128 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14131 tcg_gen_movi_tl(t0, v2);
14132 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14135 imm = (ctx->opcode >> 20) & 0x3F;
14136 tcg_gen_movi_tl(t0, ret);
14137 tcg_gen_movi_tl(t1, imm);
14138 gen_helper_shilo(t0, t1, cpu_env);
14141 tcg_gen_movi_tl(t0, ret);
14142 gen_helper_shilo(t0, v1_t, cpu_env);
14145 tcg_gen_movi_tl(t0, ret);
14146 gen_helper_mthlip(t0, v1_t, cpu_env);
14149 imm = (ctx->opcode >> 11) & 0x3FF;
14150 tcg_gen_movi_tl(t0, imm);
14151 gen_helper_wrdsp(v1_t, t0, cpu_env);
14154 imm = (ctx->opcode >> 16) & 0x03FF;
14155 tcg_gen_movi_tl(t0, imm);
14156 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14160 #ifdef TARGET_MIPS64
14161 case OPC_DEXTR_W_DSP:
14165 tcg_gen_movi_tl(t0, ret);
14166 gen_helper_dmthlip(v1_t, t0, cpu_env);
14170 int shift = (ctx->opcode >> 19) & 0x7F;
14171 int ac = (ctx->opcode >> 11) & 0x03;
14172 tcg_gen_movi_tl(t0, shift);
14173 tcg_gen_movi_tl(t1, ac);
14174 gen_helper_dshilo(t0, t1, cpu_env);
14179 int ac = (ctx->opcode >> 11) & 0x03;
14180 tcg_gen_movi_tl(t0, ac);
14181 gen_helper_dshilo(v1_t, t0, cpu_env);
14185 tcg_gen_movi_tl(t0, v2);
14186 tcg_gen_movi_tl(t1, v1);
14188 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14191 tcg_gen_movi_tl(t0, v2);
14192 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14195 tcg_gen_movi_tl(t0, v2);
14196 tcg_gen_movi_tl(t1, v1);
14197 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14200 tcg_gen_movi_tl(t0, v2);
14201 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14204 tcg_gen_movi_tl(t0, v2);
14205 tcg_gen_movi_tl(t1, v1);
14206 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14208 case OPC_DEXTR_R_L:
14209 tcg_gen_movi_tl(t0, v2);
14210 tcg_gen_movi_tl(t1, v1);
14211 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14213 case OPC_DEXTR_RS_L:
14214 tcg_gen_movi_tl(t0, v2);
14215 tcg_gen_movi_tl(t1, v1);
14216 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14219 tcg_gen_movi_tl(t0, v2);
14220 tcg_gen_movi_tl(t1, v1);
14221 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14223 case OPC_DEXTR_R_W:
14224 tcg_gen_movi_tl(t0, v2);
14225 tcg_gen_movi_tl(t1, v1);
14226 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14228 case OPC_DEXTR_RS_W:
14229 tcg_gen_movi_tl(t0, v2);
14230 tcg_gen_movi_tl(t1, v1);
14231 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14233 case OPC_DEXTR_S_H:
14234 tcg_gen_movi_tl(t0, v2);
14235 tcg_gen_movi_tl(t1, v1);
14236 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14238 case OPC_DEXTRV_S_H:
14239 tcg_gen_movi_tl(t0, v2);
14240 tcg_gen_movi_tl(t1, v1);
14241 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14244 tcg_gen_movi_tl(t0, v2);
14245 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14247 case OPC_DEXTRV_R_L:
14248 tcg_gen_movi_tl(t0, v2);
14249 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14251 case OPC_DEXTRV_RS_L:
14252 tcg_gen_movi_tl(t0, v2);
14253 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14256 tcg_gen_movi_tl(t0, v2);
14257 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14259 case OPC_DEXTRV_R_W:
14260 tcg_gen_movi_tl(t0, v2);
14261 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14263 case OPC_DEXTRV_RS_W:
14264 tcg_gen_movi_tl(t0, v2);
14265 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14274 tcg_temp_free(v1_t);
14275 tcg_temp_free(v2_t);
14277 (void)opn; /* avoid a compiler warning */
14278 MIPS_DEBUG("%s", opn);
14281 /* End MIPSDSP functions. */
14283 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14286 int rs, rt, rd, sa;
14287 uint32_t op, op1, op2;
14290 /* make sure instructions are on a word boundary */
14291 if (ctx->pc & 0x3) {
14292 env->CP0_BadVAddr = ctx->pc;
14293 generate_exception(ctx, EXCP_AdEL);
14297 /* Handle blikely not taken case */
14298 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14299 int l1 = gen_new_label();
14301 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14302 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14303 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14304 gen_goto_tb(ctx, 1, ctx->pc + 4);
14308 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14309 tcg_gen_debug_insn_start(ctx->pc);
14312 op = MASK_OP_MAJOR(ctx->opcode);
14313 rs = (ctx->opcode >> 21) & 0x1f;
14314 rt = (ctx->opcode >> 16) & 0x1f;
14315 rd = (ctx->opcode >> 11) & 0x1f;
14316 sa = (ctx->opcode >> 6) & 0x1f;
14317 imm = (int16_t)ctx->opcode;
14320 op1 = MASK_SPECIAL(ctx->opcode);
14322 case OPC_SLL: /* Shift with immediate */
14324 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14327 switch ((ctx->opcode >> 21) & 0x1f) {
14329 /* rotr is decoded as srl on non-R2 CPUs */
14330 if (env->insn_flags & ISA_MIPS32R2) {
14335 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14338 generate_exception(ctx, EXCP_RI);
14342 case OPC_MOVN: /* Conditional move */
14344 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14345 INSN_LOONGSON2E | INSN_LOONGSON2F);
14346 gen_cond_move(env, ctx, op1, rd, rs, rt);
14348 case OPC_ADD ... OPC_SUBU:
14349 gen_arith(env, ctx, op1, rd, rs, rt);
14351 case OPC_SLLV: /* Shifts */
14353 gen_shift(env, ctx, op1, rd, rs, rt);
14356 switch ((ctx->opcode >> 6) & 0x1f) {
14358 /* rotrv is decoded as srlv on non-R2 CPUs */
14359 if (env->insn_flags & ISA_MIPS32R2) {
14364 gen_shift(env, ctx, op1, rd, rs, rt);
14367 generate_exception(ctx, EXCP_RI);
14371 case OPC_SLT: /* Set on less than */
14373 gen_slt(env, ctx, op1, rd, rs, rt);
14375 case OPC_AND: /* Logic*/
14379 gen_logic(env, ctx, op1, rd, rs, rt);
14381 case OPC_MULT ... OPC_DIVU:
14383 check_insn(env, ctx, INSN_VR54XX);
14384 op1 = MASK_MUL_VR54XX(ctx->opcode);
14385 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14387 gen_muldiv(ctx, op1, rs, rt);
14389 case OPC_JR ... OPC_JALR:
14390 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14393 case OPC_TGE ... OPC_TEQ: /* Traps */
14395 gen_trap(ctx, op1, rs, rt, -1);
14397 case OPC_MFHI: /* Move from HI/LO */
14399 gen_HILO(ctx, op1, rd);
14402 case OPC_MTLO: /* Move to HI/LO */
14403 gen_HILO(ctx, op1, rs);
14405 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14406 #ifdef MIPS_STRICT_STANDARD
14407 MIPS_INVAL("PMON / selsl");
14408 generate_exception(ctx, EXCP_RI);
14410 gen_helper_0e0i(pmon, sa);
14414 generate_exception(ctx, EXCP_SYSCALL);
14415 ctx->bstate = BS_STOP;
14418 generate_exception(ctx, EXCP_BREAK);
14421 #ifdef MIPS_STRICT_STANDARD
14422 MIPS_INVAL("SPIM");
14423 generate_exception(ctx, EXCP_RI);
14425 /* Implemented as RI exception for now. */
14426 MIPS_INVAL("spim (unofficial)");
14427 generate_exception(ctx, EXCP_RI);
14431 /* Treat as NOP. */
14435 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14436 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14437 check_cp1_enabled(ctx);
14438 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14439 (ctx->opcode >> 16) & 1);
14441 generate_exception_err(ctx, EXCP_CpU, 1);
14445 #if defined(TARGET_MIPS64)
14446 /* MIPS64 specific opcodes */
14451 check_insn(env, ctx, ISA_MIPS3);
14452 check_mips_64(ctx);
14453 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14456 switch ((ctx->opcode >> 21) & 0x1f) {
14458 /* drotr is decoded as dsrl on non-R2 CPUs */
14459 if (env->insn_flags & ISA_MIPS32R2) {
14464 check_insn(env, ctx, ISA_MIPS3);
14465 check_mips_64(ctx);
14466 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14469 generate_exception(ctx, EXCP_RI);
14474 switch ((ctx->opcode >> 21) & 0x1f) {
14476 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14477 if (env->insn_flags & ISA_MIPS32R2) {
14482 check_insn(env, ctx, ISA_MIPS3);
14483 check_mips_64(ctx);
14484 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14487 generate_exception(ctx, EXCP_RI);
14491 case OPC_DADD ... OPC_DSUBU:
14492 check_insn(env, ctx, ISA_MIPS3);
14493 check_mips_64(ctx);
14494 gen_arith(env, ctx, op1, rd, rs, rt);
14498 check_insn(env, ctx, ISA_MIPS3);
14499 check_mips_64(ctx);
14500 gen_shift(env, ctx, op1, rd, rs, rt);
14503 switch ((ctx->opcode >> 6) & 0x1f) {
14505 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14506 if (env->insn_flags & ISA_MIPS32R2) {
14511 check_insn(env, ctx, ISA_MIPS3);
14512 check_mips_64(ctx);
14513 gen_shift(env, ctx, op1, rd, rs, rt);
14516 generate_exception(ctx, EXCP_RI);
14520 case OPC_DMULT ... OPC_DDIVU:
14521 check_insn(env, ctx, ISA_MIPS3);
14522 check_mips_64(ctx);
14523 gen_muldiv(ctx, op1, rs, rt);
14526 default: /* Invalid */
14527 MIPS_INVAL("special");
14528 generate_exception(ctx, EXCP_RI);
14533 op1 = MASK_SPECIAL2(ctx->opcode);
14535 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14536 case OPC_MSUB ... OPC_MSUBU:
14537 check_insn(env, ctx, ISA_MIPS32);
14538 gen_muldiv(ctx, op1, rs, rt);
14541 gen_arith(env, ctx, op1, rd, rs, rt);
14545 check_insn(env, ctx, ISA_MIPS32);
14546 gen_cl(ctx, op1, rd, rs);
14549 /* XXX: not clear which exception should be raised
14550 * when in debug mode...
14552 check_insn(env, ctx, ISA_MIPS32);
14553 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14554 generate_exception(ctx, EXCP_DBp);
14556 generate_exception(ctx, EXCP_DBp);
14558 /* Treat as NOP. */
14561 case OPC_DIVU_G_2F:
14562 case OPC_MULT_G_2F:
14563 case OPC_MULTU_G_2F:
14565 case OPC_MODU_G_2F:
14566 check_insn(env, ctx, INSN_LOONGSON2F);
14567 gen_loongson_integer(ctx, op1, rd, rs, rt);
14569 #if defined(TARGET_MIPS64)
14572 check_insn(env, ctx, ISA_MIPS64);
14573 check_mips_64(ctx);
14574 gen_cl(ctx, op1, rd, rs);
14576 case OPC_DMULT_G_2F:
14577 case OPC_DMULTU_G_2F:
14578 case OPC_DDIV_G_2F:
14579 case OPC_DDIVU_G_2F:
14580 case OPC_DMOD_G_2F:
14581 case OPC_DMODU_G_2F:
14582 check_insn(env, ctx, INSN_LOONGSON2F);
14583 gen_loongson_integer(ctx, op1, rd, rs, rt);
14586 default: /* Invalid */
14587 MIPS_INVAL("special2");
14588 generate_exception(ctx, EXCP_RI);
14593 op1 = MASK_SPECIAL3(ctx->opcode);
14597 check_insn(env, ctx, ISA_MIPS32R2);
14598 gen_bitops(ctx, op1, rt, rs, sa, rd);
14601 check_insn(env, ctx, ISA_MIPS32R2);
14602 op2 = MASK_BSHFL(ctx->opcode);
14603 gen_bshfl(ctx, op2, rt, rd);
14606 gen_rdhwr(env, ctx, rt, rd);
14609 check_insn(env, ctx, ASE_MT);
14611 TCGv t0 = tcg_temp_new();
14612 TCGv t1 = tcg_temp_new();
14614 gen_load_gpr(t0, rt);
14615 gen_load_gpr(t1, rs);
14616 gen_helper_fork(t0, t1);
14622 check_insn(env, ctx, ASE_MT);
14624 TCGv t0 = tcg_temp_new();
14626 save_cpu_state(ctx, 1);
14627 gen_load_gpr(t0, rs);
14628 gen_helper_yield(t0, cpu_env, t0);
14629 gen_store_gpr(t0, rd);
14633 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14634 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14635 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14636 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14637 * the same mask and op1. */
14638 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14639 op2 = MASK_ADDUH_QB(ctx->opcode);
14642 case OPC_ADDUH_R_QB:
14644 case OPC_ADDQH_R_PH:
14646 case OPC_ADDQH_R_W:
14648 case OPC_SUBUH_R_QB:
14650 case OPC_SUBQH_R_PH:
14652 case OPC_SUBQH_R_W:
14653 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14658 case OPC_MULQ_RS_W:
14659 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14662 MIPS_INVAL("MASK ADDUH.QB");
14663 generate_exception(ctx, EXCP_RI);
14666 } else if (env->insn_flags & INSN_LOONGSON2E) {
14667 gen_loongson_integer(ctx, op1, rd, rs, rt);
14669 generate_exception(ctx, EXCP_RI);
14673 op2 = MASK_LX(ctx->opcode);
14675 #if defined(TARGET_MIPS64)
14681 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14683 default: /* Invalid */
14684 MIPS_INVAL("MASK LX");
14685 generate_exception(ctx, EXCP_RI);
14689 case OPC_ABSQ_S_PH_DSP:
14690 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14692 case OPC_ABSQ_S_QB:
14693 case OPC_ABSQ_S_PH:
14695 case OPC_PRECEQ_W_PHL:
14696 case OPC_PRECEQ_W_PHR:
14697 case OPC_PRECEQU_PH_QBL:
14698 case OPC_PRECEQU_PH_QBR:
14699 case OPC_PRECEQU_PH_QBLA:
14700 case OPC_PRECEQU_PH_QBRA:
14701 case OPC_PRECEU_PH_QBL:
14702 case OPC_PRECEU_PH_QBR:
14703 case OPC_PRECEU_PH_QBLA:
14704 case OPC_PRECEU_PH_QBRA:
14705 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14712 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14715 MIPS_INVAL("MASK ABSQ_S.PH");
14716 generate_exception(ctx, EXCP_RI);
14720 case OPC_ADDU_QB_DSP:
14721 op2 = MASK_ADDU_QB(ctx->opcode);
14724 case OPC_ADDQ_S_PH:
14727 case OPC_ADDU_S_QB:
14729 case OPC_ADDU_S_PH:
14731 case OPC_SUBQ_S_PH:
14734 case OPC_SUBU_S_QB:
14736 case OPC_SUBU_S_PH:
14740 case OPC_RADDU_W_QB:
14741 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14743 case OPC_MULEU_S_PH_QBL:
14744 case OPC_MULEU_S_PH_QBR:
14745 case OPC_MULQ_RS_PH:
14746 case OPC_MULEQ_S_W_PHL:
14747 case OPC_MULEQ_S_W_PHR:
14748 case OPC_MULQ_S_PH:
14749 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14751 default: /* Invalid */
14752 MIPS_INVAL("MASK ADDU.QB");
14753 generate_exception(ctx, EXCP_RI);
14758 case OPC_CMPU_EQ_QB_DSP:
14759 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14761 case OPC_PRECR_SRA_PH_W:
14762 case OPC_PRECR_SRA_R_PH_W:
14763 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14765 case OPC_PRECR_QB_PH:
14766 case OPC_PRECRQ_QB_PH:
14767 case OPC_PRECRQ_PH_W:
14768 case OPC_PRECRQ_RS_PH_W:
14769 case OPC_PRECRQU_S_QB_PH:
14770 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14772 case OPC_CMPU_EQ_QB:
14773 case OPC_CMPU_LT_QB:
14774 case OPC_CMPU_LE_QB:
14775 case OPC_CMP_EQ_PH:
14776 case OPC_CMP_LT_PH:
14777 case OPC_CMP_LE_PH:
14778 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14780 case OPC_CMPGU_EQ_QB:
14781 case OPC_CMPGU_LT_QB:
14782 case OPC_CMPGU_LE_QB:
14783 case OPC_CMPGDU_EQ_QB:
14784 case OPC_CMPGDU_LT_QB:
14785 case OPC_CMPGDU_LE_QB:
14788 case OPC_PACKRL_PH:
14789 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14791 default: /* Invalid */
14792 MIPS_INVAL("MASK CMPU.EQ.QB");
14793 generate_exception(ctx, EXCP_RI);
14797 case OPC_SHLL_QB_DSP:
14798 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14800 case OPC_DPA_W_PH_DSP:
14801 op2 = MASK_DPA_W_PH(ctx->opcode);
14803 case OPC_DPAU_H_QBL:
14804 case OPC_DPAU_H_QBR:
14805 case OPC_DPSU_H_QBL:
14806 case OPC_DPSU_H_QBR:
14808 case OPC_DPAX_W_PH:
14809 case OPC_DPAQ_S_W_PH:
14810 case OPC_DPAQX_S_W_PH:
14811 case OPC_DPAQX_SA_W_PH:
14813 case OPC_DPSX_W_PH:
14814 case OPC_DPSQ_S_W_PH:
14815 case OPC_DPSQX_S_W_PH:
14816 case OPC_DPSQX_SA_W_PH:
14817 case OPC_MULSAQ_S_W_PH:
14818 case OPC_DPAQ_SA_L_W:
14819 case OPC_DPSQ_SA_L_W:
14820 case OPC_MAQ_S_W_PHL:
14821 case OPC_MAQ_S_W_PHR:
14822 case OPC_MAQ_SA_W_PHL:
14823 case OPC_MAQ_SA_W_PHR:
14824 case OPC_MULSA_W_PH:
14825 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14827 default: /* Invalid */
14828 MIPS_INVAL("MASK DPAW.PH");
14829 generate_exception(ctx, EXCP_RI);
14834 op2 = MASK_INSV(ctx->opcode);
14846 t0 = tcg_temp_new();
14847 t1 = tcg_temp_new();
14849 gen_load_gpr(t0, rt);
14850 gen_load_gpr(t1, rs);
14852 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14858 default: /* Invalid */
14859 MIPS_INVAL("MASK INSV");
14860 generate_exception(ctx, EXCP_RI);
14864 case OPC_APPEND_DSP:
14866 op2 = MASK_APPEND(ctx->opcode);
14867 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14869 case OPC_EXTR_W_DSP:
14870 op2 = MASK_EXTR_W(ctx->opcode);
14874 case OPC_EXTR_RS_W:
14876 case OPC_EXTRV_S_H:
14878 case OPC_EXTRV_R_W:
14879 case OPC_EXTRV_RS_W:
14884 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14887 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14893 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14895 default: /* Invalid */
14896 MIPS_INVAL("MASK EXTR.W");
14897 generate_exception(ctx, EXCP_RI);
14901 #if defined(TARGET_MIPS64)
14902 case OPC_DEXTM ... OPC_DEXT:
14903 case OPC_DINSM ... OPC_DINS:
14904 check_insn(env, ctx, ISA_MIPS64R2);
14905 check_mips_64(ctx);
14906 gen_bitops(ctx, op1, rt, rs, sa, rd);
14909 check_insn(env, ctx, ISA_MIPS64R2);
14910 check_mips_64(ctx);
14911 op2 = MASK_DBSHFL(ctx->opcode);
14912 gen_bshfl(ctx, op2, rt, rd);
14914 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14915 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14916 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14917 check_insn(env, ctx, INSN_LOONGSON2E);
14918 gen_loongson_integer(ctx, op1, rd, rs, rt);
14920 case OPC_ABSQ_S_QH_DSP:
14921 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14923 case OPC_PRECEQ_L_PWL:
14924 case OPC_PRECEQ_L_PWR:
14925 case OPC_PRECEQ_PW_QHL:
14926 case OPC_PRECEQ_PW_QHR:
14927 case OPC_PRECEQ_PW_QHLA:
14928 case OPC_PRECEQ_PW_QHRA:
14929 case OPC_PRECEQU_QH_OBL:
14930 case OPC_PRECEQU_QH_OBR:
14931 case OPC_PRECEQU_QH_OBLA:
14932 case OPC_PRECEQU_QH_OBRA:
14933 case OPC_PRECEU_QH_OBL:
14934 case OPC_PRECEU_QH_OBR:
14935 case OPC_PRECEU_QH_OBLA:
14936 case OPC_PRECEU_QH_OBRA:
14937 case OPC_ABSQ_S_OB:
14938 case OPC_ABSQ_S_PW:
14939 case OPC_ABSQ_S_QH:
14940 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14948 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14950 default: /* Invalid */
14951 MIPS_INVAL("MASK ABSQ_S.QH");
14952 generate_exception(ctx, EXCP_RI);
14956 case OPC_ADDU_OB_DSP:
14957 op2 = MASK_ADDU_OB(ctx->opcode);
14959 case OPC_RADDU_L_OB:
14961 case OPC_SUBQ_S_PW:
14963 case OPC_SUBQ_S_QH:
14965 case OPC_SUBU_S_OB:
14967 case OPC_SUBU_S_QH:
14969 case OPC_SUBUH_R_OB:
14971 case OPC_ADDQ_S_PW:
14973 case OPC_ADDQ_S_QH:
14975 case OPC_ADDU_S_OB:
14977 case OPC_ADDU_S_QH:
14979 case OPC_ADDUH_R_OB:
14980 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14982 case OPC_MULEQ_S_PW_QHL:
14983 case OPC_MULEQ_S_PW_QHR:
14984 case OPC_MULEU_S_QH_OBL:
14985 case OPC_MULEU_S_QH_OBR:
14986 case OPC_MULQ_RS_QH:
14987 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14989 default: /* Invalid */
14990 MIPS_INVAL("MASK ADDU.OB");
14991 generate_exception(ctx, EXCP_RI);
14995 case OPC_CMPU_EQ_OB_DSP:
14996 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14998 case OPC_PRECR_SRA_QH_PW:
14999 case OPC_PRECR_SRA_R_QH_PW:
15000 /* Return value is rt. */
15001 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15003 case OPC_PRECR_OB_QH:
15004 case OPC_PRECRQ_OB_QH:
15005 case OPC_PRECRQ_PW_L:
15006 case OPC_PRECRQ_QH_PW:
15007 case OPC_PRECRQ_RS_QH_PW:
15008 case OPC_PRECRQU_S_OB_QH:
15009 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15011 case OPC_CMPU_EQ_OB:
15012 case OPC_CMPU_LT_OB:
15013 case OPC_CMPU_LE_OB:
15014 case OPC_CMP_EQ_QH:
15015 case OPC_CMP_LT_QH:
15016 case OPC_CMP_LE_QH:
15017 case OPC_CMP_EQ_PW:
15018 case OPC_CMP_LT_PW:
15019 case OPC_CMP_LE_PW:
15020 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15022 case OPC_CMPGDU_EQ_OB:
15023 case OPC_CMPGDU_LT_OB:
15024 case OPC_CMPGDU_LE_OB:
15025 case OPC_CMPGU_EQ_OB:
15026 case OPC_CMPGU_LT_OB:
15027 case OPC_CMPGU_LE_OB:
15028 case OPC_PACKRL_PW:
15032 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15034 default: /* Invalid */
15035 MIPS_INVAL("MASK CMPU_EQ.OB");
15036 generate_exception(ctx, EXCP_RI);
15040 case OPC_DAPPEND_DSP:
15042 op2 = MASK_DAPPEND(ctx->opcode);
15043 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15045 case OPC_DEXTR_W_DSP:
15046 op2 = MASK_DEXTR_W(ctx->opcode);
15053 case OPC_DEXTR_R_L:
15054 case OPC_DEXTR_RS_L:
15056 case OPC_DEXTR_R_W:
15057 case OPC_DEXTR_RS_W:
15058 case OPC_DEXTR_S_H:
15060 case OPC_DEXTRV_R_L:
15061 case OPC_DEXTRV_RS_L:
15062 case OPC_DEXTRV_S_H:
15064 case OPC_DEXTRV_R_W:
15065 case OPC_DEXTRV_RS_W:
15066 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15071 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15073 default: /* Invalid */
15074 MIPS_INVAL("MASK EXTR.W");
15075 generate_exception(ctx, EXCP_RI);
15079 case OPC_DPAQ_W_QH_DSP:
15080 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15082 case OPC_DPAU_H_OBL:
15083 case OPC_DPAU_H_OBR:
15084 case OPC_DPSU_H_OBL:
15085 case OPC_DPSU_H_OBR:
15087 case OPC_DPAQ_S_W_QH:
15089 case OPC_DPSQ_S_W_QH:
15090 case OPC_MULSAQ_S_W_QH:
15091 case OPC_DPAQ_SA_L_PW:
15092 case OPC_DPSQ_SA_L_PW:
15093 case OPC_MULSAQ_S_L_PW:
15094 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15096 case OPC_MAQ_S_W_QHLL:
15097 case OPC_MAQ_S_W_QHLR:
15098 case OPC_MAQ_S_W_QHRL:
15099 case OPC_MAQ_S_W_QHRR:
15100 case OPC_MAQ_SA_W_QHLL:
15101 case OPC_MAQ_SA_W_QHLR:
15102 case OPC_MAQ_SA_W_QHRL:
15103 case OPC_MAQ_SA_W_QHRR:
15104 case OPC_MAQ_S_L_PWL:
15105 case OPC_MAQ_S_L_PWR:
15110 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15112 default: /* Invalid */
15113 MIPS_INVAL("MASK DPAQ.W.QH");
15114 generate_exception(ctx, EXCP_RI);
15118 case OPC_DINSV_DSP:
15119 op2 = MASK_INSV(ctx->opcode);
15131 t0 = tcg_temp_new();
15132 t1 = tcg_temp_new();
15134 gen_load_gpr(t0, rt);
15135 gen_load_gpr(t1, rs);
15137 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15140 default: /* Invalid */
15141 MIPS_INVAL("MASK DINSV");
15142 generate_exception(ctx, EXCP_RI);
15146 case OPC_SHLL_OB_DSP:
15147 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15150 default: /* Invalid */
15151 MIPS_INVAL("special3");
15152 generate_exception(ctx, EXCP_RI);
15157 op1 = MASK_REGIMM(ctx->opcode);
15159 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15160 case OPC_BLTZAL ... OPC_BGEZALL:
15161 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15164 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15166 gen_trap(ctx, op1, rs, -1, imm);
15169 check_insn(env, ctx, ISA_MIPS32R2);
15170 /* Treat as NOP. */
15172 case OPC_BPOSGE32: /* MIPS DSP branch */
15173 #if defined(TARGET_MIPS64)
15177 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15180 default: /* Invalid */
15181 MIPS_INVAL("regimm");
15182 generate_exception(ctx, EXCP_RI);
15187 check_cp0_enabled(ctx);
15188 op1 = MASK_CP0(ctx->opcode);
15194 #if defined(TARGET_MIPS64)
15198 #ifndef CONFIG_USER_ONLY
15199 gen_cp0(env, ctx, op1, rt, rd);
15200 #endif /* !CONFIG_USER_ONLY */
15202 case OPC_C0_FIRST ... OPC_C0_LAST:
15203 #ifndef CONFIG_USER_ONLY
15204 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15205 #endif /* !CONFIG_USER_ONLY */
15208 #ifndef CONFIG_USER_ONLY
15210 TCGv t0 = tcg_temp_new();
15212 op2 = MASK_MFMC0(ctx->opcode);
15215 check_insn(env, ctx, ASE_MT);
15216 gen_helper_dmt(t0);
15217 gen_store_gpr(t0, rt);
15220 check_insn(env, ctx, ASE_MT);
15221 gen_helper_emt(t0);
15222 gen_store_gpr(t0, rt);
15225 check_insn(env, ctx, ASE_MT);
15226 gen_helper_dvpe(t0, cpu_env);
15227 gen_store_gpr(t0, rt);
15230 check_insn(env, ctx, ASE_MT);
15231 gen_helper_evpe(t0, cpu_env);
15232 gen_store_gpr(t0, rt);
15235 check_insn(env, ctx, ISA_MIPS32R2);
15236 save_cpu_state(ctx, 1);
15237 gen_helper_di(t0, cpu_env);
15238 gen_store_gpr(t0, rt);
15239 /* Stop translation as we may have switched the execution mode */
15240 ctx->bstate = BS_STOP;
15243 check_insn(env, ctx, ISA_MIPS32R2);
15244 save_cpu_state(ctx, 1);
15245 gen_helper_ei(t0, cpu_env);
15246 gen_store_gpr(t0, rt);
15247 /* Stop translation as we may have switched the execution mode */
15248 ctx->bstate = BS_STOP;
15250 default: /* Invalid */
15251 MIPS_INVAL("mfmc0");
15252 generate_exception(ctx, EXCP_RI);
15257 #endif /* !CONFIG_USER_ONLY */
15260 check_insn(env, ctx, ISA_MIPS32R2);
15261 gen_load_srsgpr(rt, rd);
15264 check_insn(env, ctx, ISA_MIPS32R2);
15265 gen_store_srsgpr(rt, rd);
15269 generate_exception(ctx, EXCP_RI);
15273 case OPC_ADDI: /* Arithmetic with immediate opcode */
15275 gen_arith_imm(env, ctx, op, rt, rs, imm);
15277 case OPC_SLTI: /* Set on less than with immediate opcode */
15279 gen_slt_imm(env, ctx, op, rt, rs, imm);
15281 case OPC_ANDI: /* Arithmetic with immediate opcode */
15285 gen_logic_imm(env, ctx, op, rt, rs, imm);
15287 case OPC_J ... OPC_JAL: /* Jump */
15288 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15289 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15292 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15293 case OPC_BEQL ... OPC_BGTZL:
15294 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15297 case OPC_LB ... OPC_LWR: /* Load and stores */
15299 gen_ld(env, ctx, op, rt, rs, imm);
15301 case OPC_SB ... OPC_SW:
15303 gen_st(ctx, op, rt, rs, imm);
15306 gen_st_cond(ctx, op, rt, rs, imm);
15309 check_cp0_enabled(ctx);
15310 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15311 /* Treat as NOP. */
15314 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15315 /* Treat as NOP. */
15318 /* Floating point (COP1). */
15323 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15327 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15328 check_cp1_enabled(ctx);
15329 op1 = MASK_CP1(ctx->opcode);
15333 check_insn(env, ctx, ISA_MIPS32R2);
15338 gen_cp1(ctx, op1, rt, rd);
15340 #if defined(TARGET_MIPS64)
15343 check_insn(env, ctx, ISA_MIPS3);
15344 gen_cp1(ctx, op1, rt, rd);
15350 check_insn(env, ctx, ASE_MIPS3D);
15353 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15354 (rt >> 2) & 0x7, imm << 2);
15362 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15367 generate_exception (ctx, EXCP_RI);
15371 generate_exception_err(ctx, EXCP_CpU, 1);
15380 /* COP2: Not implemented. */
15381 generate_exception_err(ctx, EXCP_CpU, 2);
15384 check_insn(env, ctx, INSN_LOONGSON2F);
15385 /* Note that these instructions use different fields. */
15386 gen_loongson_multimedia(ctx, sa, rd, rt);
15390 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15391 check_cp1_enabled(ctx);
15392 op1 = MASK_CP3(ctx->opcode);
15400 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15403 /* Treat as NOP. */
15418 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15422 generate_exception (ctx, EXCP_RI);
15426 generate_exception_err(ctx, EXCP_CpU, 1);
15430 #if defined(TARGET_MIPS64)
15431 /* MIPS64 opcodes */
15433 case OPC_LDL ... OPC_LDR:
15436 check_insn(env, ctx, ISA_MIPS3);
15437 check_mips_64(ctx);
15438 gen_ld(env, ctx, op, rt, rs, imm);
15440 case OPC_SDL ... OPC_SDR:
15442 check_insn(env, ctx, ISA_MIPS3);
15443 check_mips_64(ctx);
15444 gen_st(ctx, op, rt, rs, imm);
15447 check_insn(env, ctx, ISA_MIPS3);
15448 check_mips_64(ctx);
15449 gen_st_cond(ctx, op, rt, rs, imm);
15453 check_insn(env, ctx, ISA_MIPS3);
15454 check_mips_64(ctx);
15455 gen_arith_imm(env, ctx, op, rt, rs, imm);
15459 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15460 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15461 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15465 check_insn(env, ctx, ASE_MDMX);
15466 /* MDMX: Not implemented. */
15467 default: /* Invalid */
15468 MIPS_INVAL("major opcode");
15469 generate_exception(ctx, EXCP_RI);
15475 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15479 target_ulong pc_start;
15480 uint16_t *gen_opc_end;
15489 qemu_log("search pc %d\n", search_pc);
15492 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15495 ctx.singlestep_enabled = env->singlestep_enabled;
15497 ctx.bstate = BS_NONE;
15498 /* Restore delay slot state from the tb context. */
15499 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15500 restore_cpu_state(env, &ctx);
15501 #ifdef CONFIG_USER_ONLY
15502 ctx.mem_idx = MIPS_HFLAG_UM;
15504 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15507 max_insns = tb->cflags & CF_COUNT_MASK;
15508 if (max_insns == 0)
15509 max_insns = CF_COUNT_MASK;
15510 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15511 gen_icount_start();
15512 while (ctx.bstate == BS_NONE) {
15513 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15514 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15515 if (bp->pc == ctx.pc) {
15516 save_cpu_state(&ctx, 1);
15517 ctx.bstate = BS_BRANCH;
15518 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15519 /* Include the breakpoint location or the tb won't
15520 * be flushed when it must be. */
15522 goto done_generating;
15528 j = gen_opc_ptr - gen_opc_buf;
15532 gen_opc_instr_start[lj++] = 0;
15534 gen_opc_pc[lj] = ctx.pc;
15535 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15536 gen_opc_btarget[lj] = ctx.btarget;
15537 gen_opc_instr_start[lj] = 1;
15538 gen_opc_icount[lj] = num_insns;
15540 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15544 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15545 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15547 decode_opc(env, &ctx, &is_branch);
15548 } else if (env->insn_flags & ASE_MICROMIPS) {
15549 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15550 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15551 } else if (env->insn_flags & ASE_MIPS16) {
15552 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15553 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15555 generate_exception(&ctx, EXCP_RI);
15556 ctx.bstate = BS_STOP;
15560 handle_delay_slot(env, &ctx, insn_bytes);
15562 ctx.pc += insn_bytes;
15566 /* Execute a branch and its delay slot as a single instruction.
15567 This is what GDB expects and is consistent with what the
15568 hardware does (e.g. if a delay slot instruction faults, the
15569 reported PC is the PC of the branch). */
15570 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15573 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15576 if (gen_opc_ptr >= gen_opc_end)
15579 if (num_insns >= max_insns)
15585 if (tb->cflags & CF_LAST_IO)
15587 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15588 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15589 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15591 switch (ctx.bstate) {
15593 gen_goto_tb(&ctx, 0, ctx.pc);
15596 save_cpu_state(&ctx, 0);
15597 gen_goto_tb(&ctx, 0, ctx.pc);
15600 tcg_gen_exit_tb(0);
15608 gen_icount_end(tb, num_insns);
15609 *gen_opc_ptr = INDEX_op_end;
15611 j = gen_opc_ptr - gen_opc_buf;
15614 gen_opc_instr_start[lj++] = 0;
15616 tb->size = ctx.pc - pc_start;
15617 tb->icount = num_insns;
15621 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15622 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15623 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15629 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15631 gen_intermediate_code_internal(env, tb, 0);
15634 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15636 gen_intermediate_code_internal(env, tb, 1);
15639 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15643 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15645 #define printfpr(fp) \
15648 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15649 " fd:%13g fs:%13g psu: %13g\n", \
15650 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15651 (double)(fp)->fd, \
15652 (double)(fp)->fs[FP_ENDIAN_IDX], \
15653 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15656 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15657 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15658 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15659 " fd:%13g fs:%13g psu:%13g\n", \
15660 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15662 (double)tmp.fs[FP_ENDIAN_IDX], \
15663 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15668 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15669 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15670 get_float_exception_flags(&env->active_fpu.fp_status));
15671 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15672 fpu_fprintf(f, "%3s: ", fregnames[i]);
15673 printfpr(&env->active_fpu.fpr[i]);
15679 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15680 /* Debug help: The architecture requires 32bit code to maintain proper
15681 sign-extended values on 64bit machines. */
15683 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15686 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15687 fprintf_function cpu_fprintf,
15692 if (!SIGN_EXT_P(env->active_tc.PC))
15693 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15694 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15695 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15696 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15697 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15698 if (!SIGN_EXT_P(env->btarget))
15699 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15701 for (i = 0; i < 32; i++) {
15702 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15703 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15706 if (!SIGN_EXT_P(env->CP0_EPC))
15707 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15708 if (!SIGN_EXT_P(env->lladdr))
15709 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15713 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15718 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15719 " LO=0x" TARGET_FMT_lx " ds %04x "
15720 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15721 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15722 env->hflags, env->btarget, env->bcond);
15723 for (i = 0; i < 32; i++) {
15725 cpu_fprintf(f, "GPR%02d:", i);
15726 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15728 cpu_fprintf(f, "\n");
15731 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15732 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15733 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15734 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15735 if (env->hflags & MIPS_HFLAG_FPU)
15736 fpu_dump_state(env, f, cpu_fprintf, flags);
15737 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15738 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15742 static void mips_tcg_init(void)
15747 /* Initialize various static tables. */
15751 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15752 TCGV_UNUSED(cpu_gpr[0]);
15753 for (i = 1; i < 32; i++)
15754 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15755 offsetof(CPUMIPSState, active_tc.gpr[i]),
15758 for (i = 0; i < 32; i++) {
15759 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15760 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15763 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15764 offsetof(CPUMIPSState, active_tc.PC), "PC");
15765 for (i = 0; i < MIPS_DSP_ACC; i++) {
15766 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15767 offsetof(CPUMIPSState, active_tc.HI[i]),
15769 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15770 offsetof(CPUMIPSState, active_tc.LO[i]),
15772 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15773 offsetof(CPUMIPSState, active_tc.ACX[i]),
15776 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15777 offsetof(CPUMIPSState, active_tc.DSPControl),
15779 bcond = tcg_global_mem_new(TCG_AREG0,
15780 offsetof(CPUMIPSState, bcond), "bcond");
15781 btarget = tcg_global_mem_new(TCG_AREG0,
15782 offsetof(CPUMIPSState, btarget), "btarget");
15783 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15784 offsetof(CPUMIPSState, hflags), "hflags");
15786 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15787 offsetof(CPUMIPSState, active_fpu.fcr0),
15789 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15790 offsetof(CPUMIPSState, active_fpu.fcr31),
15793 /* register helpers */
15794 #define GEN_HELPER 2
15795 #include "helper.h"
15800 #include "translate_init.c"
15802 MIPSCPU *cpu_mips_init(const char *cpu_model)
15806 const mips_def_t *def;
15808 def = cpu_mips_find_by_name(cpu_model);
15811 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15813 env->cpu_model = def;
15814 env->cpu_model_str = cpu_model;
15816 #ifndef CONFIG_USER_ONLY
15817 mmu_init(env, def);
15819 fpu_init(env, def);
15820 mvp_init(env, def);
15822 cpu_reset(CPU(cpu));
15823 qemu_init_vcpu(env);
15827 void cpu_state_reset(CPUMIPSState *env)
15829 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15830 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15831 log_cpu_state(env, 0);
15834 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15837 /* Reset registers to their default values */
15838 env->CP0_PRid = env->cpu_model->CP0_PRid;
15839 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15840 #ifdef TARGET_WORDS_BIGENDIAN
15841 env->CP0_Config0 |= (1 << CP0C0_BE);
15843 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15844 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15845 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15846 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15847 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15848 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15849 << env->cpu_model->CP0_LLAddr_shift;
15850 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15851 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15852 env->CCRes = env->cpu_model->CCRes;
15853 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15854 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15855 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15856 env->current_tc = 0;
15857 env->SEGBITS = env->cpu_model->SEGBITS;
15858 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15859 #if defined(TARGET_MIPS64)
15860 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15861 env->SEGMask |= 3ULL << 62;
15864 env->PABITS = env->cpu_model->PABITS;
15865 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15866 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15867 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15868 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15869 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15870 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15871 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15872 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15873 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15874 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15875 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15876 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15877 env->insn_flags = env->cpu_model->insn_flags;
15879 #if defined(CONFIG_USER_ONLY)
15880 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15881 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15882 hardware registers. */
15883 env->CP0_HWREna |= 0x0000000F;
15884 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15885 env->CP0_Status |= (1 << CP0St_CU1);
15887 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15888 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15889 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15890 env->hflags |= MIPS_HFLAG_DSP;
15893 if (env->hflags & MIPS_HFLAG_BMASK) {
15894 /* If the exception was raised from a delay slot,
15895 come back to the jump. */
15896 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15898 env->CP0_ErrorEPC = env->active_tc.PC;
15900 env->active_tc.PC = (int32_t)0xBFC00000;
15901 env->CP0_Random = env->tlb->nb_tlb - 1;
15902 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15903 env->CP0_Wired = 0;
15904 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15905 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15906 /* vectored interrupts not implemented, timer on int 7,
15907 no performance counters. */
15908 env->CP0_IntCtl = 0xe0000000;
15912 for (i = 0; i < 7; i++) {
15913 env->CP0_WatchLo[i] = 0;
15914 env->CP0_WatchHi[i] = 0x80000000;
15916 env->CP0_WatchLo[7] = 0;
15917 env->CP0_WatchHi[7] = 0;
15919 /* Count register increments in debug mode, EJTAG version 1 */
15920 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15922 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15925 /* Only TC0 on VPE 0 starts as active. */
15926 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15927 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15928 env->tcs[i].CP0_TCHalt = 1;
15930 env->active_tc.CP0_TCHalt = 1;
15933 if (!env->cpu_index) {
15934 /* VPE0 starts up enabled. */
15935 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15936 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15938 /* TC0 starts up unhalted. */
15940 env->active_tc.CP0_TCHalt = 0;
15941 env->tcs[0].CP0_TCHalt = 0;
15942 /* With thread 0 active. */
15943 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15944 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15948 compute_hflags(env);
15949 env->exception_index = EXCP_NONE;
15952 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
15954 env->active_tc.PC = gen_opc_pc[pc_pos];
15955 env->hflags &= ~MIPS_HFLAG_BMASK;
15956 env->hflags |= gen_opc_hflags[pc_pos];
15957 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15958 case MIPS_HFLAG_BR:
15960 case MIPS_HFLAG_BC:
15961 case MIPS_HFLAG_BL:
15963 env->btarget = gen_opc_btarget[pc_pos];