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