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