vmsvga: don't process more than 1024 fifo commands at once
[qemu.git] / target-mips / translate.c
1 /*
2 * MIPS32 emulation for qemu: main translation routines.
3 *
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)
9 *
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.
14 *
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.
19 *
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/>.
22 */
23
24 #include "qemu/osdep.h"
25 #include "cpu.h"
26 #include "disas/disas.h"
27 #include "exec/exec-all.h"
28 #include "tcg-op.h"
29 #include "exec/cpu_ldst.h"
30
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
33 #include "sysemu/kvm.h"
34 #include "exec/semihost.h"
35
36 #include "trace-tcg.h"
37 #include "exec/log.h"
38
39 #define MIPS_DEBUG_DISAS 0
40
41 /* MIPS major opcodes */
42 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
43
44 enum {
45 /* indirect opcode tables */
46 OPC_SPECIAL = (0x00 << 26),
47 OPC_REGIMM = (0x01 << 26),
48 OPC_CP0 = (0x10 << 26),
49 OPC_CP1 = (0x11 << 26),
50 OPC_CP2 = (0x12 << 26),
51 OPC_CP3 = (0x13 << 26),
52 OPC_SPECIAL2 = (0x1C << 26),
53 OPC_SPECIAL3 = (0x1F << 26),
54 /* arithmetic with immediate */
55 OPC_ADDI = (0x08 << 26),
56 OPC_ADDIU = (0x09 << 26),
57 OPC_SLTI = (0x0A << 26),
58 OPC_SLTIU = (0x0B << 26),
59 /* logic with immediate */
60 OPC_ANDI = (0x0C << 26),
61 OPC_ORI = (0x0D << 26),
62 OPC_XORI = (0x0E << 26),
63 OPC_LUI = (0x0F << 26),
64 /* arithmetic with immediate */
65 OPC_DADDI = (0x18 << 26),
66 OPC_DADDIU = (0x19 << 26),
67 /* Jump and branches */
68 OPC_J = (0x02 << 26),
69 OPC_JAL = (0x03 << 26),
70 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
71 OPC_BEQL = (0x14 << 26),
72 OPC_BNE = (0x05 << 26),
73 OPC_BNEL = (0x15 << 26),
74 OPC_BLEZ = (0x06 << 26),
75 OPC_BLEZL = (0x16 << 26),
76 OPC_BGTZ = (0x07 << 26),
77 OPC_BGTZL = (0x17 << 26),
78 OPC_JALX = (0x1D << 26),
79 OPC_DAUI = (0x1D << 26),
80 /* Load and stores */
81 OPC_LDL = (0x1A << 26),
82 OPC_LDR = (0x1B << 26),
83 OPC_LB = (0x20 << 26),
84 OPC_LH = (0x21 << 26),
85 OPC_LWL = (0x22 << 26),
86 OPC_LW = (0x23 << 26),
87 OPC_LWPC = OPC_LW | 0x5,
88 OPC_LBU = (0x24 << 26),
89 OPC_LHU = (0x25 << 26),
90 OPC_LWR = (0x26 << 26),
91 OPC_LWU = (0x27 << 26),
92 OPC_SB = (0x28 << 26),
93 OPC_SH = (0x29 << 26),
94 OPC_SWL = (0x2A << 26),
95 OPC_SW = (0x2B << 26),
96 OPC_SDL = (0x2C << 26),
97 OPC_SDR = (0x2D << 26),
98 OPC_SWR = (0x2E << 26),
99 OPC_LL = (0x30 << 26),
100 OPC_LLD = (0x34 << 26),
101 OPC_LD = (0x37 << 26),
102 OPC_LDPC = OPC_LD | 0x5,
103 OPC_SC = (0x38 << 26),
104 OPC_SCD = (0x3C << 26),
105 OPC_SD = (0x3F << 26),
106 /* Floating point load/store */
107 OPC_LWC1 = (0x31 << 26),
108 OPC_LWC2 = (0x32 << 26),
109 OPC_LDC1 = (0x35 << 26),
110 OPC_LDC2 = (0x36 << 26),
111 OPC_SWC1 = (0x39 << 26),
112 OPC_SWC2 = (0x3A << 26),
113 OPC_SDC1 = (0x3D << 26),
114 OPC_SDC2 = (0x3E << 26),
115 /* Compact Branches */
116 OPC_BLEZALC = (0x06 << 26),
117 OPC_BGEZALC = (0x06 << 26),
118 OPC_BGEUC = (0x06 << 26),
119 OPC_BGTZALC = (0x07 << 26),
120 OPC_BLTZALC = (0x07 << 26),
121 OPC_BLTUC = (0x07 << 26),
122 OPC_BOVC = (0x08 << 26),
123 OPC_BEQZALC = (0x08 << 26),
124 OPC_BEQC = (0x08 << 26),
125 OPC_BLEZC = (0x16 << 26),
126 OPC_BGEZC = (0x16 << 26),
127 OPC_BGEC = (0x16 << 26),
128 OPC_BGTZC = (0x17 << 26),
129 OPC_BLTZC = (0x17 << 26),
130 OPC_BLTC = (0x17 << 26),
131 OPC_BNVC = (0x18 << 26),
132 OPC_BNEZALC = (0x18 << 26),
133 OPC_BNEC = (0x18 << 26),
134 OPC_BC = (0x32 << 26),
135 OPC_BEQZC = (0x36 << 26),
136 OPC_JIC = (0x36 << 26),
137 OPC_BALC = (0x3A << 26),
138 OPC_BNEZC = (0x3E << 26),
139 OPC_JIALC = (0x3E << 26),
140 /* MDMX ASE specific */
141 OPC_MDMX = (0x1E << 26),
142 /* MSA ASE, same as MDMX */
143 OPC_MSA = OPC_MDMX,
144 /* Cache and prefetch */
145 OPC_CACHE = (0x2F << 26),
146 OPC_PREF = (0x33 << 26),
147 /* PC-relative address computation / loads */
148 OPC_PCREL = (0x3B << 26),
149 };
150
151 /* PC-relative address computation / loads */
152 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
153 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
154 enum {
155 /* Instructions determined by bits 19 and 20 */
156 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
157 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
158 OPC_LWUPC = OPC_PCREL | (2 << 19),
159
160 /* Instructions determined by bits 16 ... 20 */
161 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
162 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
163
164 /* Other */
165 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
166 };
167
168 /* MIPS special opcodes */
169 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
170
171 enum {
172 /* Shifts */
173 OPC_SLL = 0x00 | OPC_SPECIAL,
174 /* NOP is SLL r0, r0, 0 */
175 /* SSNOP is SLL r0, r0, 1 */
176 /* EHB is SLL r0, r0, 3 */
177 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
178 OPC_ROTR = OPC_SRL | (1 << 21),
179 OPC_SRA = 0x03 | OPC_SPECIAL,
180 OPC_SLLV = 0x04 | OPC_SPECIAL,
181 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
182 OPC_ROTRV = OPC_SRLV | (1 << 6),
183 OPC_SRAV = 0x07 | OPC_SPECIAL,
184 OPC_DSLLV = 0x14 | OPC_SPECIAL,
185 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
186 OPC_DROTRV = OPC_DSRLV | (1 << 6),
187 OPC_DSRAV = 0x17 | OPC_SPECIAL,
188 OPC_DSLL = 0x38 | OPC_SPECIAL,
189 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
190 OPC_DROTR = OPC_DSRL | (1 << 21),
191 OPC_DSRA = 0x3B | OPC_SPECIAL,
192 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
193 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
194 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
195 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
196 /* Multiplication / division */
197 OPC_MULT = 0x18 | OPC_SPECIAL,
198 OPC_MULTU = 0x19 | OPC_SPECIAL,
199 OPC_DIV = 0x1A | OPC_SPECIAL,
200 OPC_DIVU = 0x1B | OPC_SPECIAL,
201 OPC_DMULT = 0x1C | OPC_SPECIAL,
202 OPC_DMULTU = 0x1D | OPC_SPECIAL,
203 OPC_DDIV = 0x1E | OPC_SPECIAL,
204 OPC_DDIVU = 0x1F | OPC_SPECIAL,
205
206 /* 2 registers arithmetic / logic */
207 OPC_ADD = 0x20 | OPC_SPECIAL,
208 OPC_ADDU = 0x21 | OPC_SPECIAL,
209 OPC_SUB = 0x22 | OPC_SPECIAL,
210 OPC_SUBU = 0x23 | OPC_SPECIAL,
211 OPC_AND = 0x24 | OPC_SPECIAL,
212 OPC_OR = 0x25 | OPC_SPECIAL,
213 OPC_XOR = 0x26 | OPC_SPECIAL,
214 OPC_NOR = 0x27 | OPC_SPECIAL,
215 OPC_SLT = 0x2A | OPC_SPECIAL,
216 OPC_SLTU = 0x2B | OPC_SPECIAL,
217 OPC_DADD = 0x2C | OPC_SPECIAL,
218 OPC_DADDU = 0x2D | OPC_SPECIAL,
219 OPC_DSUB = 0x2E | OPC_SPECIAL,
220 OPC_DSUBU = 0x2F | OPC_SPECIAL,
221 /* Jumps */
222 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
223 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
224 /* Traps */
225 OPC_TGE = 0x30 | OPC_SPECIAL,
226 OPC_TGEU = 0x31 | OPC_SPECIAL,
227 OPC_TLT = 0x32 | OPC_SPECIAL,
228 OPC_TLTU = 0x33 | OPC_SPECIAL,
229 OPC_TEQ = 0x34 | OPC_SPECIAL,
230 OPC_TNE = 0x36 | OPC_SPECIAL,
231 /* HI / LO registers load & stores */
232 OPC_MFHI = 0x10 | OPC_SPECIAL,
233 OPC_MTHI = 0x11 | OPC_SPECIAL,
234 OPC_MFLO = 0x12 | OPC_SPECIAL,
235 OPC_MTLO = 0x13 | OPC_SPECIAL,
236 /* Conditional moves */
237 OPC_MOVZ = 0x0A | OPC_SPECIAL,
238 OPC_MOVN = 0x0B | OPC_SPECIAL,
239
240 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
241 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
242
243 OPC_MOVCI = 0x01 | OPC_SPECIAL,
244
245 /* Special */
246 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
247 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
248 OPC_BREAK = 0x0D | OPC_SPECIAL,
249 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
250 OPC_SYNC = 0x0F | OPC_SPECIAL,
251
252 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
253 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
254 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
255 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
256 };
257
258 /* R6 Multiply and Divide instructions have the same Opcode
259 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
260 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
261
262 enum {
263 R6_OPC_MUL = OPC_MULT | (2 << 6),
264 R6_OPC_MUH = OPC_MULT | (3 << 6),
265 R6_OPC_MULU = OPC_MULTU | (2 << 6),
266 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
267 R6_OPC_DIV = OPC_DIV | (2 << 6),
268 R6_OPC_MOD = OPC_DIV | (3 << 6),
269 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
270 R6_OPC_MODU = OPC_DIVU | (3 << 6),
271
272 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
273 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
274 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
275 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
276 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
277 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
278 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
279 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
280
281 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
282 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
283 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
284 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
285 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
286
287 OPC_LSA = 0x05 | OPC_SPECIAL,
288 OPC_DLSA = 0x15 | OPC_SPECIAL,
289 };
290
291 /* Multiplication variants of the vr54xx. */
292 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
293
294 enum {
295 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
296 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
297 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
298 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
299 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
300 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
301 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
302 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
303 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
304 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
305 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
306 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
307 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
308 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
309 };
310
311 /* REGIMM (rt field) opcodes */
312 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
313
314 enum {
315 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
316 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
317 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
318 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
319 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
320 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
321 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
322 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
323 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
324 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
325 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
326 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
327 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
328 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
329 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
330 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
331
332 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
333 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
334 };
335
336 /* Special2 opcodes */
337 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
338
339 enum {
340 /* Multiply & xxx operations */
341 OPC_MADD = 0x00 | OPC_SPECIAL2,
342 OPC_MADDU = 0x01 | OPC_SPECIAL2,
343 OPC_MUL = 0x02 | OPC_SPECIAL2,
344 OPC_MSUB = 0x04 | OPC_SPECIAL2,
345 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
346 /* Loongson 2F */
347 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
348 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
349 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
350 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
351 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
352 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
353 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
354 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
355 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
356 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
357 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
358 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
359 /* Misc */
360 OPC_CLZ = 0x20 | OPC_SPECIAL2,
361 OPC_CLO = 0x21 | OPC_SPECIAL2,
362 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
363 OPC_DCLO = 0x25 | OPC_SPECIAL2,
364 /* Special */
365 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
366 };
367
368 /* Special3 opcodes */
369 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
370
371 enum {
372 OPC_EXT = 0x00 | OPC_SPECIAL3,
373 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
374 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
375 OPC_DEXT = 0x03 | OPC_SPECIAL3,
376 OPC_INS = 0x04 | OPC_SPECIAL3,
377 OPC_DINSM = 0x05 | OPC_SPECIAL3,
378 OPC_DINSU = 0x06 | OPC_SPECIAL3,
379 OPC_DINS = 0x07 | OPC_SPECIAL3,
380 OPC_FORK = 0x08 | OPC_SPECIAL3,
381 OPC_YIELD = 0x09 | OPC_SPECIAL3,
382 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
383 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
384 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
385
386 /* Loongson 2E */
387 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
388 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
389 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
390 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
391 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
392 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
393 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
394 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
395 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
396 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
397 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
398 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
399
400 /* MIPS DSP Load */
401 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
402 /* MIPS DSP Arithmetic */
403 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
404 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
405 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
406 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
407 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
408 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
409 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
410 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
411 /* MIPS DSP GPR-Based Shift Sub-class */
412 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
413 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
414 /* MIPS DSP Multiply Sub-class insns */
415 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
416 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
417 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
418 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
419 /* DSP Bit/Manipulation Sub-class */
420 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
421 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
422 /* MIPS DSP Append Sub-class */
423 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
424 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
425 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
426 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
427 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
428
429 /* R6 */
430 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
431 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
432 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
433 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
434 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
435 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
436 };
437
438 /* BSHFL opcodes */
439 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
440
441 enum {
442 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
443 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
444 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
445 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
446 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
447 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
448 };
449
450 /* DBSHFL opcodes */
451 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
452
453 enum {
454 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
455 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
456 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
457 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
458 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
459 };
460
461 /* MIPS DSP REGIMM opcodes */
462 enum {
463 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
464 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
465 };
466
467 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
468 /* MIPS DSP Load */
469 enum {
470 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
471 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
472 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
473 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
474 };
475
476 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
477 enum {
478 /* MIPS DSP Arithmetic Sub-class */
479 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
483 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
484 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
485 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
490 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
491 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
492 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
493 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
494 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
495 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
496 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
497 /* MIPS DSP Multiply Sub-class insns */
498 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
501 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
502 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
503 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
504 };
505
506 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
507 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
508 enum {
509 /* MIPS DSP Arithmetic Sub-class */
510 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
514 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
519 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
520 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
521 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
522 /* MIPS DSP Multiply Sub-class insns */
523 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
524 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
525 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
526 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
527 };
528
529 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
530 enum {
531 /* MIPS DSP Arithmetic Sub-class */
532 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
545 /* DSP Bit/Manipulation Sub-class */
546 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
548 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
549 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
550 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
551 };
552
553 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 enum {
555 /* MIPS DSP Arithmetic Sub-class */
556 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
563 /* DSP Compare-Pick Sub-class */
564 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
579 };
580
581 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
582 enum {
583 /* MIPS DSP GPR-Based Shift Sub-class */
584 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
603 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
605 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
606 };
607
608 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
609 enum {
610 /* MIPS DSP Multiply Sub-class insns */
611 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
624 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
625 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
626 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
627 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
630 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
632 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
633 };
634
635 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636 enum {
637 /* DSP Bit/Manipulation Sub-class */
638 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
639 };
640
641 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
642 enum {
643 /* MIPS DSP Append Sub-class */
644 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
645 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
646 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
647 };
648
649 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
650 enum {
651 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
652 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
661 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
662 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
663 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
664 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
665 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
666 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
667 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
668 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
669 };
670
671 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
672 enum {
673 /* MIPS DSP Arithmetic Sub-class */
674 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
691 /* DSP Bit/Manipulation Sub-class */
692 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
698 };
699
700 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
701 enum {
702 /* MIPS DSP Multiply Sub-class insns */
703 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
705 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
706 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
707 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
708 /* MIPS DSP Arithmetic Sub-class */
709 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
717 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
718 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
719 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
727 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
728 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
729 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
730 };
731
732 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
733 enum {
734 /* DSP Compare-Pick Sub-class */
735 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
754 /* MIPS DSP Arithmetic Sub-class */
755 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
763 };
764
765 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
766 enum {
767 /* DSP Append Sub-class */
768 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
769 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
770 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
771 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
772 };
773
774 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
775 enum {
776 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
777 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
778 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
794 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
795 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
796 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
797 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
798 };
799
800 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
801 enum {
802 /* DSP Bit/Manipulation Sub-class */
803 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
804 };
805
806 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
807 enum {
808 /* MIPS DSP Multiply Sub-class insns */
809 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
835 };
836
837 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
838 enum {
839 /* MIPS DSP GPR-Based Shift Sub-class */
840 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
866 };
867
868 /* Coprocessor 0 (rs field) */
869 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
870
871 enum {
872 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
873 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
874 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
875 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
876 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
877 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
878 OPC_MFTR = (0x08 << 21) | OPC_CP0,
879 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
880 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
881 OPC_MTTR = (0x0C << 21) | OPC_CP0,
882 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
883 OPC_C0 = (0x10 << 21) | OPC_CP0,
884 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
885 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
886 };
887
888 /* MFMC0 opcodes */
889 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
890
891 enum {
892 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
893 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
894 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
895 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
896 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
897 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
898 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
899 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
900 };
901
902 /* Coprocessor 0 (with rs == C0) */
903 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
904
905 enum {
906 OPC_TLBR = 0x01 | OPC_C0,
907 OPC_TLBWI = 0x02 | OPC_C0,
908 OPC_TLBINV = 0x03 | OPC_C0,
909 OPC_TLBINVF = 0x04 | OPC_C0,
910 OPC_TLBWR = 0x06 | OPC_C0,
911 OPC_TLBP = 0x08 | OPC_C0,
912 OPC_RFE = 0x10 | OPC_C0,
913 OPC_ERET = 0x18 | OPC_C0,
914 OPC_DERET = 0x1F | OPC_C0,
915 OPC_WAIT = 0x20 | OPC_C0,
916 };
917
918 /* Coprocessor 1 (rs field) */
919 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
920
921 /* Values for the fmt field in FP instructions */
922 enum {
923 /* 0 - 15 are reserved */
924 FMT_S = 16, /* single fp */
925 FMT_D = 17, /* double fp */
926 FMT_E = 18, /* extended fp */
927 FMT_Q = 19, /* quad fp */
928 FMT_W = 20, /* 32-bit fixed */
929 FMT_L = 21, /* 64-bit fixed */
930 FMT_PS = 22, /* paired single fp */
931 /* 23 - 31 are reserved */
932 };
933
934 enum {
935 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
936 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
937 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
938 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
939 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
940 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
941 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
942 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
943 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
944 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
945 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
946 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
947 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
948 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
949 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
950 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
951 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
952 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
953 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
954 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
955 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
956 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
957 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
958 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
959 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
960 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
961 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
962 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
963 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
964 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
965 };
966
967 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
968 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
969
970 enum {
971 OPC_BC1F = (0x00 << 16) | OPC_BC1,
972 OPC_BC1T = (0x01 << 16) | OPC_BC1,
973 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
974 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
975 };
976
977 enum {
978 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
979 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
980 };
981
982 enum {
983 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
984 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
985 };
986
987 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
988
989 enum {
990 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
991 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
992 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
993 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
994 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
995 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
996 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
997 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
998 OPC_BC2 = (0x08 << 21) | OPC_CP2,
999 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1000 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1001 };
1002
1003 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1004
1005 enum {
1006 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1013 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1014
1015 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1022 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1023
1024 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1027 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1028 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1029 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1030 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1031 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1032
1033 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1036 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1040 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1041
1042 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1043 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1047 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1048
1049 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1054 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1055
1056 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1061 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1062
1063 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1068 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1069
1070 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1071 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1072 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1073 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1074 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1075 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1076
1077 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1078 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1079 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1080 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1081 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1082 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1083
1084 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1085 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1086 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1087 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1088 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1089 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1090
1091 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1092 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1093 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1094 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1095 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1096 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1097 };
1098
1099
1100 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1101
1102 enum {
1103 OPC_LWXC1 = 0x00 | OPC_CP3,
1104 OPC_LDXC1 = 0x01 | OPC_CP3,
1105 OPC_LUXC1 = 0x05 | OPC_CP3,
1106 OPC_SWXC1 = 0x08 | OPC_CP3,
1107 OPC_SDXC1 = 0x09 | OPC_CP3,
1108 OPC_SUXC1 = 0x0D | OPC_CP3,
1109 OPC_PREFX = 0x0F | OPC_CP3,
1110 OPC_ALNV_PS = 0x1E | OPC_CP3,
1111 OPC_MADD_S = 0x20 | OPC_CP3,
1112 OPC_MADD_D = 0x21 | OPC_CP3,
1113 OPC_MADD_PS = 0x26 | OPC_CP3,
1114 OPC_MSUB_S = 0x28 | OPC_CP3,
1115 OPC_MSUB_D = 0x29 | OPC_CP3,
1116 OPC_MSUB_PS = 0x2E | OPC_CP3,
1117 OPC_NMADD_S = 0x30 | OPC_CP3,
1118 OPC_NMADD_D = 0x31 | OPC_CP3,
1119 OPC_NMADD_PS= 0x36 | OPC_CP3,
1120 OPC_NMSUB_S = 0x38 | OPC_CP3,
1121 OPC_NMSUB_D = 0x39 | OPC_CP3,
1122 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1123 };
1124
1125 /* MSA Opcodes */
1126 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1127 enum {
1128 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1129 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1130 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1131 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1132 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1133 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1134 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1135 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1136 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1137 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1138 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1139 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1140 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1141 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1142 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1143 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1144 OPC_MSA_ELM = 0x19 | OPC_MSA,
1145 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1146 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1147 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1148 OPC_MSA_VEC = 0x1E | OPC_MSA,
1149
1150 /* MI10 instruction */
1151 OPC_LD_B = (0x20) | OPC_MSA,
1152 OPC_LD_H = (0x21) | OPC_MSA,
1153 OPC_LD_W = (0x22) | OPC_MSA,
1154 OPC_LD_D = (0x23) | OPC_MSA,
1155 OPC_ST_B = (0x24) | OPC_MSA,
1156 OPC_ST_H = (0x25) | OPC_MSA,
1157 OPC_ST_W = (0x26) | OPC_MSA,
1158 OPC_ST_D = (0x27) | OPC_MSA,
1159 };
1160
1161 enum {
1162 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1163 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1164 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1165 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1166 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1167 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1168 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1169 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1170 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1171 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1172 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1173 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1174 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1175
1176 /* I8 instruction */
1177 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1178 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1179 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1180 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1181 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1182 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1183 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1184 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1185 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1186 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1187
1188 /* VEC/2R/2RF instruction */
1189 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1190 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1191 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1192 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1193 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1194 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1195 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1196
1197 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1198 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1199
1200 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1201 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1202 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1203 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1204 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1205
1206 /* 2RF instruction df(bit 16) = _w, _d */
1207 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1208 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1209 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1210 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1211 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1212 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1213 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1214 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1215 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1216 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1217 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1218 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1219 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1220 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1221 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1222 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1223
1224 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1225 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1226 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1227 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1228 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1229 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1230 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1231 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1232 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1233 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1234 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1235 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1236 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1237 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1238 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1239 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1240 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1241 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1242 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1243 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1244 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1245 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1246 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1247 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1248 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1249 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1250 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1251 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1252 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1253 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1254 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1255 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1256 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1257 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1258 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1259 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1260 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1261 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1262 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1263 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1264 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1265 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1266 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1267 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1268 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1269 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1270 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1271 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1272 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1273 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1274 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1275 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1276 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1277 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1278 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1279 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1280 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1281 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1282 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1283 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1284 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1285 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1286 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1287 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1288
1289 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1290 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1292 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1293 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1294 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1295 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1296 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1297 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1298 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1299
1300 /* 3RF instruction _df(bit 21) = _w, _d */
1301 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1302 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1303 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1304 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1305 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1306 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1307 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1308 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1309 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1310 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1311 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1312 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1313 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1314 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1315 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1316 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1317 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1318 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1319 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1320 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1321 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1322 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1323 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1324 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1325 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1326 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1327 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1328 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1329 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1330 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1331 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1332 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1333 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1334 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1335 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1336 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1337 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1338 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1339 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1340 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1341 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1342
1343 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1344 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1345 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1346 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1347 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1348 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1349 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1350 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1351 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1352 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1353 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1354 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1355 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1356 };
1357
1358 /* global register indices */
1359 static TCGv_env cpu_env;
1360 static TCGv cpu_gpr[32], cpu_PC;
1361 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1362 static TCGv cpu_dspctrl, btarget, bcond;
1363 static TCGv_i32 hflags;
1364 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1365 static TCGv_i64 fpu_f64[32];
1366 static TCGv_i64 msa_wr_d[64];
1367
1368 #include "exec/gen-icount.h"
1369
1370 #define gen_helper_0e0i(name, arg) do { \
1371 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1372 gen_helper_##name(cpu_env, helper_tmp); \
1373 tcg_temp_free_i32(helper_tmp); \
1374 } while(0)
1375
1376 #define gen_helper_0e1i(name, arg1, arg2) do { \
1377 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1378 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1379 tcg_temp_free_i32(helper_tmp); \
1380 } while(0)
1381
1382 #define gen_helper_1e0i(name, ret, arg1) do { \
1383 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1384 gen_helper_##name(ret, cpu_env, helper_tmp); \
1385 tcg_temp_free_i32(helper_tmp); \
1386 } while(0)
1387
1388 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1389 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1390 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1391 tcg_temp_free_i32(helper_tmp); \
1392 } while(0)
1393
1394 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1395 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1396 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1397 tcg_temp_free_i32(helper_tmp); \
1398 } while(0)
1399
1400 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1401 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1402 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1403 tcg_temp_free_i32(helper_tmp); \
1404 } while(0)
1405
1406 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1407 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1408 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1409 tcg_temp_free_i32(helper_tmp); \
1410 } while(0)
1411
1412 typedef struct DisasContext {
1413 struct TranslationBlock *tb;
1414 target_ulong pc, saved_pc;
1415 uint32_t opcode;
1416 int singlestep_enabled;
1417 int insn_flags;
1418 int32_t CP0_Config1;
1419 /* Routine used to access memory */
1420 int mem_idx;
1421 TCGMemOp default_tcg_memop_mask;
1422 uint32_t hflags, saved_hflags;
1423 int bstate;
1424 target_ulong btarget;
1425 bool ulri;
1426 int kscrexist;
1427 bool rxi;
1428 int ie;
1429 bool bi;
1430 bool bp;
1431 uint64_t PAMask;
1432 bool mvh;
1433 int CP0_LLAddr_shift;
1434 bool ps;
1435 bool vp;
1436 bool cmgcr;
1437 bool mrp;
1438 } DisasContext;
1439
1440 enum {
1441 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1442 * exception condition */
1443 BS_STOP = 1, /* We want to stop translation for any reason */
1444 BS_BRANCH = 2, /* We reached a branch condition */
1445 BS_EXCP = 3, /* We reached an exception condition */
1446 };
1447
1448 static const char * const regnames[] = {
1449 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1450 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1451 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1452 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1453 };
1454
1455 static const char * const regnames_HI[] = {
1456 "HI0", "HI1", "HI2", "HI3",
1457 };
1458
1459 static const char * const regnames_LO[] = {
1460 "LO0", "LO1", "LO2", "LO3",
1461 };
1462
1463 static const char * const fregnames[] = {
1464 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1465 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1466 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1467 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1468 };
1469
1470 static const char * const msaregnames[] = {
1471 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1472 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1473 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1474 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1475 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1476 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1477 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1478 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1479 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1480 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1481 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1482 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1483 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1484 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1485 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1486 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1487 };
1488
1489 #define LOG_DISAS(...) \
1490 do { \
1491 if (MIPS_DEBUG_DISAS) { \
1492 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1493 } \
1494 } while (0)
1495
1496 #define MIPS_INVAL(op) \
1497 do { \
1498 if (MIPS_DEBUG_DISAS) { \
1499 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1500 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1501 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1502 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
1503 } \
1504 } while (0)
1505
1506 /* General purpose registers moves. */
1507 static inline void gen_load_gpr (TCGv t, int reg)
1508 {
1509 if (reg == 0)
1510 tcg_gen_movi_tl(t, 0);
1511 else
1512 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1513 }
1514
1515 static inline void gen_store_gpr (TCGv t, int reg)
1516 {
1517 if (reg != 0)
1518 tcg_gen_mov_tl(cpu_gpr[reg], t);
1519 }
1520
1521 /* Moves to/from shadow registers. */
1522 static inline void gen_load_srsgpr (int from, int to)
1523 {
1524 TCGv t0 = tcg_temp_new();
1525
1526 if (from == 0)
1527 tcg_gen_movi_tl(t0, 0);
1528 else {
1529 TCGv_i32 t2 = tcg_temp_new_i32();
1530 TCGv_ptr addr = tcg_temp_new_ptr();
1531
1532 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1533 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1534 tcg_gen_andi_i32(t2, t2, 0xf);
1535 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1536 tcg_gen_ext_i32_ptr(addr, t2);
1537 tcg_gen_add_ptr(addr, cpu_env, addr);
1538
1539 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1540 tcg_temp_free_ptr(addr);
1541 tcg_temp_free_i32(t2);
1542 }
1543 gen_store_gpr(t0, to);
1544 tcg_temp_free(t0);
1545 }
1546
1547 static inline void gen_store_srsgpr (int from, int to)
1548 {
1549 if (to != 0) {
1550 TCGv t0 = tcg_temp_new();
1551 TCGv_i32 t2 = tcg_temp_new_i32();
1552 TCGv_ptr addr = tcg_temp_new_ptr();
1553
1554 gen_load_gpr(t0, from);
1555 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1556 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1557 tcg_gen_andi_i32(t2, t2, 0xf);
1558 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1559 tcg_gen_ext_i32_ptr(addr, t2);
1560 tcg_gen_add_ptr(addr, cpu_env, addr);
1561
1562 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1563 tcg_temp_free_ptr(addr);
1564 tcg_temp_free_i32(t2);
1565 tcg_temp_free(t0);
1566 }
1567 }
1568
1569 /* Tests */
1570 static inline void gen_save_pc(target_ulong pc)
1571 {
1572 tcg_gen_movi_tl(cpu_PC, pc);
1573 }
1574
1575 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1576 {
1577 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1578 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1579 gen_save_pc(ctx->pc);
1580 ctx->saved_pc = ctx->pc;
1581 }
1582 if (ctx->hflags != ctx->saved_hflags) {
1583 tcg_gen_movi_i32(hflags, ctx->hflags);
1584 ctx->saved_hflags = ctx->hflags;
1585 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1586 case MIPS_HFLAG_BR:
1587 break;
1588 case MIPS_HFLAG_BC:
1589 case MIPS_HFLAG_BL:
1590 case MIPS_HFLAG_B:
1591 tcg_gen_movi_tl(btarget, ctx->btarget);
1592 break;
1593 }
1594 }
1595 }
1596
1597 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1598 {
1599 ctx->saved_hflags = ctx->hflags;
1600 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1601 case MIPS_HFLAG_BR:
1602 break;
1603 case MIPS_HFLAG_BC:
1604 case MIPS_HFLAG_BL:
1605 case MIPS_HFLAG_B:
1606 ctx->btarget = env->btarget;
1607 break;
1608 }
1609 }
1610
1611 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1612 {
1613 TCGv_i32 texcp = tcg_const_i32(excp);
1614 TCGv_i32 terr = tcg_const_i32(err);
1615 save_cpu_state(ctx, 1);
1616 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1617 tcg_temp_free_i32(terr);
1618 tcg_temp_free_i32(texcp);
1619 ctx->bstate = BS_EXCP;
1620 }
1621
1622 static inline void generate_exception(DisasContext *ctx, int excp)
1623 {
1624 gen_helper_0e0i(raise_exception, excp);
1625 }
1626
1627 static inline void generate_exception_end(DisasContext *ctx, int excp)
1628 {
1629 generate_exception_err(ctx, excp, 0);
1630 }
1631
1632 /* Floating point register moves. */
1633 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1634 {
1635 if (ctx->hflags & MIPS_HFLAG_FRE) {
1636 generate_exception(ctx, EXCP_RI);
1637 }
1638 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1639 }
1640
1641 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1642 {
1643 TCGv_i64 t64;
1644 if (ctx->hflags & MIPS_HFLAG_FRE) {
1645 generate_exception(ctx, EXCP_RI);
1646 }
1647 t64 = tcg_temp_new_i64();
1648 tcg_gen_extu_i32_i64(t64, t);
1649 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1650 tcg_temp_free_i64(t64);
1651 }
1652
1653 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1654 {
1655 if (ctx->hflags & MIPS_HFLAG_F64) {
1656 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1657 } else {
1658 gen_load_fpr32(ctx, t, reg | 1);
1659 }
1660 }
1661
1662 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1663 {
1664 if (ctx->hflags & MIPS_HFLAG_F64) {
1665 TCGv_i64 t64 = tcg_temp_new_i64();
1666 tcg_gen_extu_i32_i64(t64, t);
1667 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1668 tcg_temp_free_i64(t64);
1669 } else {
1670 gen_store_fpr32(ctx, t, reg | 1);
1671 }
1672 }
1673
1674 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1675 {
1676 if (ctx->hflags & MIPS_HFLAG_F64) {
1677 tcg_gen_mov_i64(t, fpu_f64[reg]);
1678 } else {
1679 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1680 }
1681 }
1682
1683 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1684 {
1685 if (ctx->hflags & MIPS_HFLAG_F64) {
1686 tcg_gen_mov_i64(fpu_f64[reg], t);
1687 } else {
1688 TCGv_i64 t0;
1689 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1690 t0 = tcg_temp_new_i64();
1691 tcg_gen_shri_i64(t0, t, 32);
1692 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1693 tcg_temp_free_i64(t0);
1694 }
1695 }
1696
1697 static inline int get_fp_bit (int cc)
1698 {
1699 if (cc)
1700 return 24 + cc;
1701 else
1702 return 23;
1703 }
1704
1705 /* Addresses computation */
1706 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1707 {
1708 tcg_gen_add_tl(ret, arg0, arg1);
1709
1710 #if defined(TARGET_MIPS64)
1711 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1712 tcg_gen_ext32s_i64(ret, ret);
1713 }
1714 #endif
1715 }
1716
1717 /* Addresses computation (translation time) */
1718 static target_long addr_add(DisasContext *ctx, target_long base,
1719 target_long offset)
1720 {
1721 target_long sum = base + offset;
1722
1723 #if defined(TARGET_MIPS64)
1724 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1725 sum = (int32_t)sum;
1726 }
1727 #endif
1728 return sum;
1729 }
1730
1731 /* Sign-extract the low 32-bits to a target_long. */
1732 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1733 {
1734 #if defined(TARGET_MIPS64)
1735 tcg_gen_ext32s_i64(ret, arg);
1736 #else
1737 tcg_gen_extrl_i64_i32(ret, arg);
1738 #endif
1739 }
1740
1741 /* Sign-extract the high 32-bits to a target_long. */
1742 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1743 {
1744 #if defined(TARGET_MIPS64)
1745 tcg_gen_sari_i64(ret, arg, 32);
1746 #else
1747 tcg_gen_extrh_i64_i32(ret, arg);
1748 #endif
1749 }
1750
1751 static inline void check_cp0_enabled(DisasContext *ctx)
1752 {
1753 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1754 generate_exception_err(ctx, EXCP_CpU, 0);
1755 }
1756
1757 static inline void check_cp1_enabled(DisasContext *ctx)
1758 {
1759 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1760 generate_exception_err(ctx, EXCP_CpU, 1);
1761 }
1762
1763 /* Verify that the processor is running with COP1X instructions enabled.
1764 This is associated with the nabla symbol in the MIPS32 and MIPS64
1765 opcode tables. */
1766
1767 static inline void check_cop1x(DisasContext *ctx)
1768 {
1769 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1770 generate_exception_end(ctx, EXCP_RI);
1771 }
1772
1773 /* Verify that the processor is running with 64-bit floating-point
1774 operations enabled. */
1775
1776 static inline void check_cp1_64bitmode(DisasContext *ctx)
1777 {
1778 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1779 generate_exception_end(ctx, EXCP_RI);
1780 }
1781
1782 /*
1783 * Verify if floating point register is valid; an operation is not defined
1784 * if bit 0 of any register specification is set and the FR bit in the
1785 * Status register equals zero, since the register numbers specify an
1786 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1787 * in the Status register equals one, both even and odd register numbers
1788 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1789 *
1790 * Multiple 64 bit wide registers can be checked by calling
1791 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1792 */
1793 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1794 {
1795 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1796 generate_exception_end(ctx, EXCP_RI);
1797 }
1798
1799 /* Verify that the processor is running with DSP instructions enabled.
1800 This is enabled by CP0 Status register MX(24) bit.
1801 */
1802
1803 static inline void check_dsp(DisasContext *ctx)
1804 {
1805 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1806 if (ctx->insn_flags & ASE_DSP) {
1807 generate_exception_end(ctx, EXCP_DSPDIS);
1808 } else {
1809 generate_exception_end(ctx, EXCP_RI);
1810 }
1811 }
1812 }
1813
1814 static inline void check_dspr2(DisasContext *ctx)
1815 {
1816 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1817 if (ctx->insn_flags & ASE_DSP) {
1818 generate_exception_end(ctx, EXCP_DSPDIS);
1819 } else {
1820 generate_exception_end(ctx, EXCP_RI);
1821 }
1822 }
1823 }
1824
1825 /* This code generates a "reserved instruction" exception if the
1826 CPU does not support the instruction set corresponding to flags. */
1827 static inline void check_insn(DisasContext *ctx, int flags)
1828 {
1829 if (unlikely(!(ctx->insn_flags & flags))) {
1830 generate_exception_end(ctx, EXCP_RI);
1831 }
1832 }
1833
1834 /* This code generates a "reserved instruction" exception if the
1835 CPU has corresponding flag set which indicates that the instruction
1836 has been removed. */
1837 static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1838 {
1839 if (unlikely(ctx->insn_flags & flags)) {
1840 generate_exception_end(ctx, EXCP_RI);
1841 }
1842 }
1843
1844 /* This code generates a "reserved instruction" exception if the
1845 CPU does not support 64-bit paired-single (PS) floating point data type */
1846 static inline void check_ps(DisasContext *ctx)
1847 {
1848 if (unlikely(!ctx->ps)) {
1849 generate_exception(ctx, EXCP_RI);
1850 }
1851 check_cp1_64bitmode(ctx);
1852 }
1853
1854 #ifdef TARGET_MIPS64
1855 /* This code generates a "reserved instruction" exception if 64-bit
1856 instructions are not enabled. */
1857 static inline void check_mips_64(DisasContext *ctx)
1858 {
1859 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1860 generate_exception_end(ctx, EXCP_RI);
1861 }
1862 #endif
1863
1864 #ifndef CONFIG_USER_ONLY
1865 static inline void check_mvh(DisasContext *ctx)
1866 {
1867 if (unlikely(!ctx->mvh)) {
1868 generate_exception(ctx, EXCP_RI);
1869 }
1870 }
1871 #endif
1872
1873 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1874 calling interface for 32 and 64-bit FPRs. No sense in changing
1875 all callers for gen_load_fpr32 when we need the CTX parameter for
1876 this one use. */
1877 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1878 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1879 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1880 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1881 int ft, int fs, int cc) \
1882 { \
1883 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1884 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1885 switch (ifmt) { \
1886 case FMT_PS: \
1887 check_ps(ctx); \
1888 break; \
1889 case FMT_D: \
1890 if (abs) { \
1891 check_cop1x(ctx); \
1892 } \
1893 check_cp1_registers(ctx, fs | ft); \
1894 break; \
1895 case FMT_S: \
1896 if (abs) { \
1897 check_cop1x(ctx); \
1898 } \
1899 break; \
1900 } \
1901 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1902 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1903 switch (n) { \
1904 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1905 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1906 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1907 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1908 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1909 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1910 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1911 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1912 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1913 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1914 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1915 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1916 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1917 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1918 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1919 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1920 default: abort(); \
1921 } \
1922 tcg_temp_free_i##bits (fp0); \
1923 tcg_temp_free_i##bits (fp1); \
1924 }
1925
1926 FOP_CONDS(, 0, d, FMT_D, 64)
1927 FOP_CONDS(abs, 1, d, FMT_D, 64)
1928 FOP_CONDS(, 0, s, FMT_S, 32)
1929 FOP_CONDS(abs, 1, s, FMT_S, 32)
1930 FOP_CONDS(, 0, ps, FMT_PS, 64)
1931 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1932 #undef FOP_CONDS
1933
1934 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1935 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1936 int ft, int fs, int fd) \
1937 { \
1938 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1939 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1940 if (ifmt == FMT_D) { \
1941 check_cp1_registers(ctx, fs | ft | fd); \
1942 } \
1943 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1944 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1945 switch (n) { \
1946 case 0: \
1947 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1948 break; \
1949 case 1: \
1950 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1951 break; \
1952 case 2: \
1953 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1954 break; \
1955 case 3: \
1956 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1957 break; \
1958 case 4: \
1959 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1960 break; \
1961 case 5: \
1962 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1963 break; \
1964 case 6: \
1965 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1966 break; \
1967 case 7: \
1968 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1969 break; \
1970 case 8: \
1971 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1972 break; \
1973 case 9: \
1974 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1975 break; \
1976 case 10: \
1977 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1978 break; \
1979 case 11: \
1980 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1981 break; \
1982 case 12: \
1983 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1984 break; \
1985 case 13: \
1986 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1987 break; \
1988 case 14: \
1989 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1990 break; \
1991 case 15: \
1992 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1993 break; \
1994 case 17: \
1995 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1996 break; \
1997 case 18: \
1998 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1999 break; \
2000 case 19: \
2001 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2002 break; \
2003 case 25: \
2004 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2005 break; \
2006 case 26: \
2007 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2008 break; \
2009 case 27: \
2010 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2011 break; \
2012 default: \
2013 abort(); \
2014 } \
2015 STORE; \
2016 tcg_temp_free_i ## bits (fp0); \
2017 tcg_temp_free_i ## bits (fp1); \
2018 }
2019
2020 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2021 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2022 #undef FOP_CONDNS
2023 #undef gen_ldcmp_fpr32
2024 #undef gen_ldcmp_fpr64
2025
2026 /* load/store instructions. */
2027 #ifdef CONFIG_USER_ONLY
2028 #define OP_LD_ATOMIC(insn,fname) \
2029 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2030 { \
2031 TCGv t0 = tcg_temp_new(); \
2032 tcg_gen_mov_tl(t0, arg1); \
2033 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2034 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2035 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2036 tcg_temp_free(t0); \
2037 }
2038 #else
2039 #define OP_LD_ATOMIC(insn,fname) \
2040 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2041 { \
2042 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
2043 }
2044 #endif
2045 OP_LD_ATOMIC(ll,ld32s);
2046 #if defined(TARGET_MIPS64)
2047 OP_LD_ATOMIC(lld,ld64);
2048 #endif
2049 #undef OP_LD_ATOMIC
2050
2051 #ifdef CONFIG_USER_ONLY
2052 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2053 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2054 { \
2055 TCGv t0 = tcg_temp_new(); \
2056 TCGLabel *l1 = gen_new_label(); \
2057 TCGLabel *l2 = gen_new_label(); \
2058 \
2059 tcg_gen_andi_tl(t0, arg2, almask); \
2060 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2061 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2062 generate_exception(ctx, EXCP_AdES); \
2063 gen_set_label(l1); \
2064 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2065 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2066 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2067 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2068 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2069 generate_exception_end(ctx, EXCP_SC); \
2070 gen_set_label(l2); \
2071 tcg_gen_movi_tl(t0, 0); \
2072 gen_store_gpr(t0, rt); \
2073 tcg_temp_free(t0); \
2074 }
2075 #else
2076 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2077 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2078 { \
2079 TCGv t0 = tcg_temp_new(); \
2080 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2081 gen_store_gpr(t0, rt); \
2082 tcg_temp_free(t0); \
2083 }
2084 #endif
2085 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2086 #if defined(TARGET_MIPS64)
2087 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2088 #endif
2089 #undef OP_ST_ATOMIC
2090
2091 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2092 int base, int16_t offset)
2093 {
2094 if (base == 0) {
2095 tcg_gen_movi_tl(addr, offset);
2096 } else if (offset == 0) {
2097 gen_load_gpr(addr, base);
2098 } else {
2099 tcg_gen_movi_tl(addr, offset);
2100 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2101 }
2102 }
2103
2104 static target_ulong pc_relative_pc (DisasContext *ctx)
2105 {
2106 target_ulong pc = ctx->pc;
2107
2108 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2109 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2110
2111 pc -= branch_bytes;
2112 }
2113
2114 pc &= ~(target_ulong)3;
2115 return pc;
2116 }
2117
2118 /* Load */
2119 static void gen_ld(DisasContext *ctx, uint32_t opc,
2120 int rt, int base, int16_t offset)
2121 {
2122 TCGv t0, t1, t2;
2123
2124 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2125 /* Loongson CPU uses a load to zero register for prefetch.
2126 We emulate it as a NOP. On other CPU we must perform the
2127 actual memory access. */
2128 return;
2129 }
2130
2131 t0 = tcg_temp_new();
2132 gen_base_offset_addr(ctx, t0, base, offset);
2133
2134 switch (opc) {
2135 #if defined(TARGET_MIPS64)
2136 case OPC_LWU:
2137 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2138 ctx->default_tcg_memop_mask);
2139 gen_store_gpr(t0, rt);
2140 break;
2141 case OPC_LD:
2142 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2143 ctx->default_tcg_memop_mask);
2144 gen_store_gpr(t0, rt);
2145 break;
2146 case OPC_LLD:
2147 case R6_OPC_LLD:
2148 op_ld_lld(t0, t0, ctx);
2149 gen_store_gpr(t0, rt);
2150 break;
2151 case OPC_LDL:
2152 t1 = tcg_temp_new();
2153 /* Do a byte access to possibly trigger a page
2154 fault with the unaligned address. */
2155 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2156 tcg_gen_andi_tl(t1, t0, 7);
2157 #ifndef TARGET_WORDS_BIGENDIAN
2158 tcg_gen_xori_tl(t1, t1, 7);
2159 #endif
2160 tcg_gen_shli_tl(t1, t1, 3);
2161 tcg_gen_andi_tl(t0, t0, ~7);
2162 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2163 tcg_gen_shl_tl(t0, t0, t1);
2164 t2 = tcg_const_tl(-1);
2165 tcg_gen_shl_tl(t2, t2, t1);
2166 gen_load_gpr(t1, rt);
2167 tcg_gen_andc_tl(t1, t1, t2);
2168 tcg_temp_free(t2);
2169 tcg_gen_or_tl(t0, t0, t1);
2170 tcg_temp_free(t1);
2171 gen_store_gpr(t0, rt);
2172 break;
2173 case OPC_LDR:
2174 t1 = tcg_temp_new();
2175 /* Do a byte access to possibly trigger a page
2176 fault with the unaligned address. */
2177 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2178 tcg_gen_andi_tl(t1, t0, 7);
2179 #ifdef TARGET_WORDS_BIGENDIAN
2180 tcg_gen_xori_tl(t1, t1, 7);
2181 #endif
2182 tcg_gen_shli_tl(t1, t1, 3);
2183 tcg_gen_andi_tl(t0, t0, ~7);
2184 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2185 tcg_gen_shr_tl(t0, t0, t1);
2186 tcg_gen_xori_tl(t1, t1, 63);
2187 t2 = tcg_const_tl(0xfffffffffffffffeull);
2188 tcg_gen_shl_tl(t2, t2, t1);
2189 gen_load_gpr(t1, rt);
2190 tcg_gen_and_tl(t1, t1, t2);
2191 tcg_temp_free(t2);
2192 tcg_gen_or_tl(t0, t0, t1);
2193 tcg_temp_free(t1);
2194 gen_store_gpr(t0, rt);
2195 break;
2196 case OPC_LDPC:
2197 t1 = tcg_const_tl(pc_relative_pc(ctx));
2198 gen_op_addr_add(ctx, t0, t0, t1);
2199 tcg_temp_free(t1);
2200 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2201 gen_store_gpr(t0, rt);
2202 break;
2203 #endif
2204 case OPC_LWPC:
2205 t1 = tcg_const_tl(pc_relative_pc(ctx));
2206 gen_op_addr_add(ctx, t0, t0, t1);
2207 tcg_temp_free(t1);
2208 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2209 gen_store_gpr(t0, rt);
2210 break;
2211 case OPC_LW:
2212 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2213 ctx->default_tcg_memop_mask);
2214 gen_store_gpr(t0, rt);
2215 break;
2216 case OPC_LH:
2217 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2218 ctx->default_tcg_memop_mask);
2219 gen_store_gpr(t0, rt);
2220 break;
2221 case OPC_LHU:
2222 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2223 ctx->default_tcg_memop_mask);
2224 gen_store_gpr(t0, rt);
2225 break;
2226 case OPC_LB:
2227 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2228 gen_store_gpr(t0, rt);
2229 break;
2230 case OPC_LBU:
2231 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2232 gen_store_gpr(t0, rt);
2233 break;
2234 case OPC_LWL:
2235 t1 = tcg_temp_new();
2236 /* Do a byte access to possibly trigger a page
2237 fault with the unaligned address. */
2238 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2239 tcg_gen_andi_tl(t1, t0, 3);
2240 #ifndef TARGET_WORDS_BIGENDIAN
2241 tcg_gen_xori_tl(t1, t1, 3);
2242 #endif
2243 tcg_gen_shli_tl(t1, t1, 3);
2244 tcg_gen_andi_tl(t0, t0, ~3);
2245 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2246 tcg_gen_shl_tl(t0, t0, t1);
2247 t2 = tcg_const_tl(-1);
2248 tcg_gen_shl_tl(t2, t2, t1);
2249 gen_load_gpr(t1, rt);
2250 tcg_gen_andc_tl(t1, t1, t2);
2251 tcg_temp_free(t2);
2252 tcg_gen_or_tl(t0, t0, t1);
2253 tcg_temp_free(t1);
2254 tcg_gen_ext32s_tl(t0, t0);
2255 gen_store_gpr(t0, rt);
2256 break;
2257 case OPC_LWR:
2258 t1 = tcg_temp_new();
2259 /* Do a byte access to possibly trigger a page
2260 fault with the unaligned address. */
2261 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2262 tcg_gen_andi_tl(t1, t0, 3);
2263 #ifdef TARGET_WORDS_BIGENDIAN
2264 tcg_gen_xori_tl(t1, t1, 3);
2265 #endif
2266 tcg_gen_shli_tl(t1, t1, 3);
2267 tcg_gen_andi_tl(t0, t0, ~3);
2268 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2269 tcg_gen_shr_tl(t0, t0, t1);
2270 tcg_gen_xori_tl(t1, t1, 31);
2271 t2 = tcg_const_tl(0xfffffffeull);
2272 tcg_gen_shl_tl(t2, t2, t1);
2273 gen_load_gpr(t1, rt);
2274 tcg_gen_and_tl(t1, t1, t2);
2275 tcg_temp_free(t2);
2276 tcg_gen_or_tl(t0, t0, t1);
2277 tcg_temp_free(t1);
2278 tcg_gen_ext32s_tl(t0, t0);
2279 gen_store_gpr(t0, rt);
2280 break;
2281 case OPC_LL:
2282 case R6_OPC_LL:
2283 op_ld_ll(t0, t0, ctx);
2284 gen_store_gpr(t0, rt);
2285 break;
2286 }
2287 tcg_temp_free(t0);
2288 }
2289
2290 /* Store */
2291 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2292 int base, int16_t offset)
2293 {
2294 TCGv t0 = tcg_temp_new();
2295 TCGv t1 = tcg_temp_new();
2296
2297 gen_base_offset_addr(ctx, t0, base, offset);
2298 gen_load_gpr(t1, rt);
2299 switch (opc) {
2300 #if defined(TARGET_MIPS64)
2301 case OPC_SD:
2302 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2303 ctx->default_tcg_memop_mask);
2304 break;
2305 case OPC_SDL:
2306 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2307 break;
2308 case OPC_SDR:
2309 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2310 break;
2311 #endif
2312 case OPC_SW:
2313 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2314 ctx->default_tcg_memop_mask);
2315 break;
2316 case OPC_SH:
2317 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2318 ctx->default_tcg_memop_mask);
2319 break;
2320 case OPC_SB:
2321 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2322 break;
2323 case OPC_SWL:
2324 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2325 break;
2326 case OPC_SWR:
2327 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2328 break;
2329 }
2330 tcg_temp_free(t0);
2331 tcg_temp_free(t1);
2332 }
2333
2334
2335 /* Store conditional */
2336 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2337 int base, int16_t offset)
2338 {
2339 TCGv t0, t1;
2340
2341 #ifdef CONFIG_USER_ONLY
2342 t0 = tcg_temp_local_new();
2343 t1 = tcg_temp_local_new();
2344 #else
2345 t0 = tcg_temp_new();
2346 t1 = tcg_temp_new();
2347 #endif
2348 gen_base_offset_addr(ctx, t0, base, offset);
2349 gen_load_gpr(t1, rt);
2350 switch (opc) {
2351 #if defined(TARGET_MIPS64)
2352 case OPC_SCD:
2353 case R6_OPC_SCD:
2354 op_st_scd(t1, t0, rt, ctx);
2355 break;
2356 #endif
2357 case OPC_SC:
2358 case R6_OPC_SC:
2359 op_st_sc(t1, t0, rt, ctx);
2360 break;
2361 }
2362 tcg_temp_free(t1);
2363 tcg_temp_free(t0);
2364 }
2365
2366 /* Load and store */
2367 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2368 int base, int16_t offset)
2369 {
2370 TCGv t0 = tcg_temp_new();
2371
2372 gen_base_offset_addr(ctx, t0, base, offset);
2373 /* Don't do NOP if destination is zero: we must perform the actual
2374 memory access. */
2375 switch (opc) {
2376 case OPC_LWC1:
2377 {
2378 TCGv_i32 fp0 = tcg_temp_new_i32();
2379 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2380 ctx->default_tcg_memop_mask);
2381 gen_store_fpr32(ctx, fp0, ft);
2382 tcg_temp_free_i32(fp0);
2383 }
2384 break;
2385 case OPC_SWC1:
2386 {
2387 TCGv_i32 fp0 = tcg_temp_new_i32();
2388 gen_load_fpr32(ctx, fp0, ft);
2389 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2390 ctx->default_tcg_memop_mask);
2391 tcg_temp_free_i32(fp0);
2392 }
2393 break;
2394 case OPC_LDC1:
2395 {
2396 TCGv_i64 fp0 = tcg_temp_new_i64();
2397 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2398 ctx->default_tcg_memop_mask);
2399 gen_store_fpr64(ctx, fp0, ft);
2400 tcg_temp_free_i64(fp0);
2401 }
2402 break;
2403 case OPC_SDC1:
2404 {
2405 TCGv_i64 fp0 = tcg_temp_new_i64();
2406 gen_load_fpr64(ctx, fp0, ft);
2407 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2408 ctx->default_tcg_memop_mask);
2409 tcg_temp_free_i64(fp0);
2410 }
2411 break;
2412 default:
2413 MIPS_INVAL("flt_ldst");
2414 generate_exception_end(ctx, EXCP_RI);
2415 goto out;
2416 }
2417 out:
2418 tcg_temp_free(t0);
2419 }
2420
2421 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2422 int rs, int16_t imm)
2423 {
2424 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2425 check_cp1_enabled(ctx);
2426 switch (op) {
2427 case OPC_LDC1:
2428 case OPC_SDC1:
2429 check_insn(ctx, ISA_MIPS2);
2430 /* Fallthrough */
2431 default:
2432 gen_flt_ldst(ctx, op, rt, rs, imm);
2433 }
2434 } else {
2435 generate_exception_err(ctx, EXCP_CpU, 1);
2436 }
2437 }
2438
2439 /* Arithmetic with immediate operand */
2440 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2441 int rt, int rs, int16_t imm)
2442 {
2443 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2444
2445 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2446 /* If no destination, treat it as a NOP.
2447 For addi, we must generate the overflow exception when needed. */
2448 return;
2449 }
2450 switch (opc) {
2451 case OPC_ADDI:
2452 {
2453 TCGv t0 = tcg_temp_local_new();
2454 TCGv t1 = tcg_temp_new();
2455 TCGv t2 = tcg_temp_new();
2456 TCGLabel *l1 = gen_new_label();
2457
2458 gen_load_gpr(t1, rs);
2459 tcg_gen_addi_tl(t0, t1, uimm);
2460 tcg_gen_ext32s_tl(t0, t0);
2461
2462 tcg_gen_xori_tl(t1, t1, ~uimm);
2463 tcg_gen_xori_tl(t2, t0, uimm);
2464 tcg_gen_and_tl(t1, t1, t2);
2465 tcg_temp_free(t2);
2466 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2467 tcg_temp_free(t1);
2468 /* operands of same sign, result different sign */
2469 generate_exception(ctx, EXCP_OVERFLOW);
2470 gen_set_label(l1);
2471 tcg_gen_ext32s_tl(t0, t0);
2472 gen_store_gpr(t0, rt);
2473 tcg_temp_free(t0);
2474 }
2475 break;
2476 case OPC_ADDIU:
2477 if (rs != 0) {
2478 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2479 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2480 } else {
2481 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2482 }
2483 break;
2484 #if defined(TARGET_MIPS64)
2485 case OPC_DADDI:
2486 {
2487 TCGv t0 = tcg_temp_local_new();
2488 TCGv t1 = tcg_temp_new();
2489 TCGv t2 = tcg_temp_new();
2490 TCGLabel *l1 = gen_new_label();
2491
2492 gen_load_gpr(t1, rs);
2493 tcg_gen_addi_tl(t0, t1, uimm);
2494
2495 tcg_gen_xori_tl(t1, t1, ~uimm);
2496 tcg_gen_xori_tl(t2, t0, uimm);
2497 tcg_gen_and_tl(t1, t1, t2);
2498 tcg_temp_free(t2);
2499 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2500 tcg_temp_free(t1);
2501 /* operands of same sign, result different sign */
2502 generate_exception(ctx, EXCP_OVERFLOW);
2503 gen_set_label(l1);
2504 gen_store_gpr(t0, rt);
2505 tcg_temp_free(t0);
2506 }
2507 break;
2508 case OPC_DADDIU:
2509 if (rs != 0) {
2510 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2511 } else {
2512 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2513 }
2514 break;
2515 #endif
2516 }
2517 }
2518
2519 /* Logic with immediate operand */
2520 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2521 int rt, int rs, int16_t imm)
2522 {
2523 target_ulong uimm;
2524
2525 if (rt == 0) {
2526 /* If no destination, treat it as a NOP. */
2527 return;
2528 }
2529 uimm = (uint16_t)imm;
2530 switch (opc) {
2531 case OPC_ANDI:
2532 if (likely(rs != 0))
2533 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2534 else
2535 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2536 break;
2537 case OPC_ORI:
2538 if (rs != 0)
2539 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2540 else
2541 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2542 break;
2543 case OPC_XORI:
2544 if (likely(rs != 0))
2545 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2546 else
2547 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2548 break;
2549 case OPC_LUI:
2550 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2551 /* OPC_AUI */
2552 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2553 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2554 } else {
2555 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2556 }
2557 break;
2558
2559 default:
2560 break;
2561 }
2562 }
2563
2564 /* Set on less than with immediate operand */
2565 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2566 int rt, int rs, int16_t imm)
2567 {
2568 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2569 TCGv t0;
2570
2571 if (rt == 0) {
2572 /* If no destination, treat it as a NOP. */
2573 return;
2574 }
2575 t0 = tcg_temp_new();
2576 gen_load_gpr(t0, rs);
2577 switch (opc) {
2578 case OPC_SLTI:
2579 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2580 break;
2581 case OPC_SLTIU:
2582 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2583 break;
2584 }
2585 tcg_temp_free(t0);
2586 }
2587
2588 /* Shifts with immediate operand */
2589 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2590 int rt, int rs, int16_t imm)
2591 {
2592 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2593 TCGv t0;
2594
2595 if (rt == 0) {
2596 /* If no destination, treat it as a NOP. */
2597 return;
2598 }
2599
2600 t0 = tcg_temp_new();
2601 gen_load_gpr(t0, rs);
2602 switch (opc) {
2603 case OPC_SLL:
2604 tcg_gen_shli_tl(t0, t0, uimm);
2605 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2606 break;
2607 case OPC_SRA:
2608 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2609 break;
2610 case OPC_SRL:
2611 if (uimm != 0) {
2612 tcg_gen_ext32u_tl(t0, t0);
2613 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2614 } else {
2615 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2616 }
2617 break;
2618 case OPC_ROTR:
2619 if (uimm != 0) {
2620 TCGv_i32 t1 = tcg_temp_new_i32();
2621
2622 tcg_gen_trunc_tl_i32(t1, t0);
2623 tcg_gen_rotri_i32(t1, t1, uimm);
2624 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2625 tcg_temp_free_i32(t1);
2626 } else {
2627 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2628 }
2629 break;
2630 #if defined(TARGET_MIPS64)
2631 case OPC_DSLL:
2632 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2633 break;
2634 case OPC_DSRA:
2635 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2636 break;
2637 case OPC_DSRL:
2638 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2639 break;
2640 case OPC_DROTR:
2641 if (uimm != 0) {
2642 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2643 } else {
2644 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2645 }
2646 break;
2647 case OPC_DSLL32:
2648 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2649 break;
2650 case OPC_DSRA32:
2651 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2652 break;
2653 case OPC_DSRL32:
2654 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2655 break;
2656 case OPC_DROTR32:
2657 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2658 break;
2659 #endif
2660 }
2661 tcg_temp_free(t0);
2662 }
2663
2664 /* Arithmetic */
2665 static void gen_arith(DisasContext *ctx, uint32_t opc,
2666 int rd, int rs, int rt)
2667 {
2668 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2669 && opc != OPC_DADD && opc != OPC_DSUB) {
2670 /* If no destination, treat it as a NOP.
2671 For add & sub, we must generate the overflow exception when needed. */
2672 return;
2673 }
2674
2675 switch (opc) {
2676 case OPC_ADD:
2677 {
2678 TCGv t0 = tcg_temp_local_new();
2679 TCGv t1 = tcg_temp_new();
2680 TCGv t2 = tcg_temp_new();
2681 TCGLabel *l1 = gen_new_label();
2682
2683 gen_load_gpr(t1, rs);
2684 gen_load_gpr(t2, rt);
2685 tcg_gen_add_tl(t0, t1, t2);
2686 tcg_gen_ext32s_tl(t0, t0);
2687 tcg_gen_xor_tl(t1, t1, t2);
2688 tcg_gen_xor_tl(t2, t0, t2);
2689 tcg_gen_andc_tl(t1, t2, t1);
2690 tcg_temp_free(t2);
2691 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2692 tcg_temp_free(t1);
2693 /* operands of same sign, result different sign */
2694 generate_exception(ctx, EXCP_OVERFLOW);
2695 gen_set_label(l1);
2696 gen_store_gpr(t0, rd);
2697 tcg_temp_free(t0);
2698 }
2699 break;
2700 case OPC_ADDU:
2701 if (rs != 0 && rt != 0) {
2702 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2703 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2704 } else if (rs == 0 && rt != 0) {
2705 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2706 } else if (rs != 0 && rt == 0) {
2707 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2708 } else {
2709 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2710 }
2711 break;
2712 case OPC_SUB:
2713 {
2714 TCGv t0 = tcg_temp_local_new();
2715 TCGv t1 = tcg_temp_new();
2716 TCGv t2 = tcg_temp_new();
2717 TCGLabel *l1 = gen_new_label();
2718
2719 gen_load_gpr(t1, rs);
2720 gen_load_gpr(t2, rt);
2721 tcg_gen_sub_tl(t0, t1, t2);
2722 tcg_gen_ext32s_tl(t0, t0);
2723 tcg_gen_xor_tl(t2, t1, t2);
2724 tcg_gen_xor_tl(t1, t0, t1);
2725 tcg_gen_and_tl(t1, t1, t2);
2726 tcg_temp_free(t2);
2727 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2728 tcg_temp_free(t1);
2729 /* operands of different sign, first operand and result different sign */
2730 generate_exception(ctx, EXCP_OVERFLOW);
2731 gen_set_label(l1);
2732 gen_store_gpr(t0, rd);
2733 tcg_temp_free(t0);
2734 }
2735 break;
2736 case OPC_SUBU:
2737 if (rs != 0 && rt != 0) {
2738 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2739 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2740 } else if (rs == 0 && rt != 0) {
2741 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2742 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2743 } else if (rs != 0 && rt == 0) {
2744 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2745 } else {
2746 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2747 }
2748 break;
2749 #if defined(TARGET_MIPS64)
2750 case OPC_DADD:
2751 {
2752 TCGv t0 = tcg_temp_local_new();
2753 TCGv t1 = tcg_temp_new();
2754 TCGv t2 = tcg_temp_new();
2755 TCGLabel *l1 = gen_new_label();
2756
2757 gen_load_gpr(t1, rs);
2758 gen_load_gpr(t2, rt);
2759 tcg_gen_add_tl(t0, t1, t2);
2760 tcg_gen_xor_tl(t1, t1, t2);
2761 tcg_gen_xor_tl(t2, t0, t2);
2762 tcg_gen_andc_tl(t1, t2, t1);
2763 tcg_temp_free(t2);
2764 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2765 tcg_temp_free(t1);
2766 /* operands of same sign, result different sign */
2767 generate_exception(ctx, EXCP_OVERFLOW);
2768 gen_set_label(l1);
2769 gen_store_gpr(t0, rd);
2770 tcg_temp_free(t0);
2771 }
2772 break;
2773 case OPC_DADDU:
2774 if (rs != 0 && rt != 0) {
2775 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2776 } else if (rs == 0 && rt != 0) {
2777 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2778 } else if (rs != 0 && rt == 0) {
2779 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2780 } else {
2781 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2782 }
2783 break;
2784 case OPC_DSUB:
2785 {
2786 TCGv t0 = tcg_temp_local_new();
2787 TCGv t1 = tcg_temp_new();
2788 TCGv t2 = tcg_temp_new();
2789 TCGLabel *l1 = gen_new_label();
2790
2791 gen_load_gpr(t1, rs);
2792 gen_load_gpr(t2, rt);
2793 tcg_gen_sub_tl(t0, t1, t2);
2794 tcg_gen_xor_tl(t2, t1, t2);
2795 tcg_gen_xor_tl(t1, t0, t1);
2796 tcg_gen_and_tl(t1, t1, t2);
2797 tcg_temp_free(t2);
2798 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2799 tcg_temp_free(t1);
2800 /* operands of different sign, first operand and result different sign */
2801 generate_exception(ctx, EXCP_OVERFLOW);
2802 gen_set_label(l1);
2803 gen_store_gpr(t0, rd);
2804 tcg_temp_free(t0);
2805 }
2806 break;
2807 case OPC_DSUBU:
2808 if (rs != 0 && rt != 0) {
2809 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2810 } else if (rs == 0 && rt != 0) {
2811 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2812 } else if (rs != 0 && rt == 0) {
2813 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2814 } else {
2815 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2816 }
2817 break;
2818 #endif
2819 case OPC_MUL:
2820 if (likely(rs != 0 && rt != 0)) {
2821 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2822 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2823 } else {
2824 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2825 }
2826 break;
2827 }
2828 }
2829
2830 /* Conditional move */
2831 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2832 int rd, int rs, int rt)
2833 {
2834 TCGv t0, t1, t2;
2835
2836 if (rd == 0) {
2837 /* If no destination, treat it as a NOP. */
2838 return;
2839 }
2840
2841 t0 = tcg_temp_new();
2842 gen_load_gpr(t0, rt);
2843 t1 = tcg_const_tl(0);
2844 t2 = tcg_temp_new();
2845 gen_load_gpr(t2, rs);
2846 switch (opc) {
2847 case OPC_MOVN:
2848 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2849 break;
2850 case OPC_MOVZ:
2851 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2852 break;
2853 case OPC_SELNEZ:
2854 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2855 break;
2856 case OPC_SELEQZ:
2857 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2858 break;
2859 }
2860 tcg_temp_free(t2);
2861 tcg_temp_free(t1);
2862 tcg_temp_free(t0);
2863 }
2864
2865 /* Logic */
2866 static void gen_logic(DisasContext *ctx, uint32_t opc,
2867 int rd, int rs, int rt)
2868 {
2869 if (rd == 0) {
2870 /* If no destination, treat it as a NOP. */
2871 return;
2872 }
2873
2874 switch (opc) {
2875 case OPC_AND:
2876 if (likely(rs != 0 && rt != 0)) {
2877 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2878 } else {
2879 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2880 }
2881 break;
2882 case OPC_NOR:
2883 if (rs != 0 && rt != 0) {
2884 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2885 } else if (rs == 0 && rt != 0) {
2886 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2887 } else if (rs != 0 && rt == 0) {
2888 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2889 } else {
2890 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2891 }
2892 break;
2893 case OPC_OR:
2894 if (likely(rs != 0 && rt != 0)) {
2895 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2896 } else if (rs == 0 && rt != 0) {
2897 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2898 } else if (rs != 0 && rt == 0) {
2899 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2900 } else {
2901 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2902 }
2903 break;
2904 case OPC_XOR:
2905 if (likely(rs != 0 && rt != 0)) {
2906 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2907 } else if (rs == 0 && rt != 0) {
2908 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2909 } else if (rs != 0 && rt == 0) {
2910 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2911 } else {
2912 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2913 }
2914 break;
2915 }
2916 }
2917
2918 /* Set on lower than */
2919 static void gen_slt(DisasContext *ctx, uint32_t opc,
2920 int rd, int rs, int rt)
2921 {
2922 TCGv t0, t1;
2923
2924 if (rd == 0) {
2925 /* If no destination, treat it as a NOP. */
2926 return;
2927 }
2928
2929 t0 = tcg_temp_new();
2930 t1 = tcg_temp_new();
2931 gen_load_gpr(t0, rs);
2932 gen_load_gpr(t1, rt);
2933 switch (opc) {
2934 case OPC_SLT:
2935 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2936 break;
2937 case OPC_SLTU:
2938 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2939 break;
2940 }
2941 tcg_temp_free(t0);
2942 tcg_temp_free(t1);
2943 }
2944
2945 /* Shifts */
2946 static void gen_shift(DisasContext *ctx, uint32_t opc,
2947 int rd, int rs, int rt)
2948 {
2949 TCGv t0, t1;
2950
2951 if (rd == 0) {
2952 /* If no destination, treat it as a NOP.
2953 For add & sub, we must generate the overflow exception when needed. */
2954 return;
2955 }
2956
2957 t0 = tcg_temp_new();
2958 t1 = tcg_temp_new();
2959 gen_load_gpr(t0, rs);
2960 gen_load_gpr(t1, rt);
2961 switch (opc) {
2962 case OPC_SLLV:
2963 tcg_gen_andi_tl(t0, t0, 0x1f);
2964 tcg_gen_shl_tl(t0, t1, t0);
2965 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2966 break;
2967 case OPC_SRAV:
2968 tcg_gen_andi_tl(t0, t0, 0x1f);
2969 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2970 break;
2971 case OPC_SRLV:
2972 tcg_gen_ext32u_tl(t1, t1);
2973 tcg_gen_andi_tl(t0, t0, 0x1f);
2974 tcg_gen_shr_tl(t0, t1, t0);
2975 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2976 break;
2977 case OPC_ROTRV:
2978 {
2979 TCGv_i32 t2 = tcg_temp_new_i32();
2980 TCGv_i32 t3 = tcg_temp_new_i32();
2981
2982 tcg_gen_trunc_tl_i32(t2, t0);
2983 tcg_gen_trunc_tl_i32(t3, t1);
2984 tcg_gen_andi_i32(t2, t2, 0x1f);
2985 tcg_gen_rotr_i32(t2, t3, t2);
2986 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2987 tcg_temp_free_i32(t2);