master
c 15,378 lines 487 KB
Raw
1 /*
2 * MIPS 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 * Copyright (c) 2020 Philippe Mathieu-Daudé
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "qemu/osdep.h"
26 #include "translate.h"
27 #include "internal.h"
28 #include "exec/helper-proto.h"
29 #include "exec/translation-block.h"
30 #include "exec/target_page.h"
31 #include "semihosting/semihost.h"
32 #include "trace.h"
33 #include "fpu_helper.h"
34
35 #define HELPER_H "helper.h"
36 #include "exec/helper-info.c.inc"
37 #undef HELPER_H
38
39
40 /*
41 * Many system-only helpers are not reachable for user-only.
42 * Define stub generators here, so that we need not either sprinkle
43 * ifdefs through the translator, nor provide the helper function.
44 */
45 #define STUB_HELPER(NAME, ...) \
46 static inline void gen_helper_##NAME(__VA_ARGS__) \
47 { g_assert_not_reached(); }
48
49 #ifdef CONFIG_USER_ONLY
50 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg)
51 #endif
52
53 enum {
54 /* indirect opcode tables */
55 OPC_SPECIAL = (0x00 << 26),
56 OPC_REGIMM = (0x01 << 26),
57 OPC_CP0 = (0x10 << 26),
58 OPC_CP2 = (0x12 << 26),
59 OPC_CP3 = (0x13 << 26),
60 OPC_SPECIAL2 = (0x1C << 26),
61 OPC_SPECIAL3 = (0x1F << 26),
62 /* arithmetic with immediate */
63 OPC_ADDI = (0x08 << 26),
64 OPC_ADDIU = (0x09 << 26),
65 OPC_SLTI = (0x0A << 26),
66 OPC_SLTIU = (0x0B << 26),
67 /* logic with immediate */
68 OPC_ANDI = (0x0C << 26),
69 OPC_ORI = (0x0D << 26),
70 OPC_XORI = (0x0E << 26),
71 OPC_LUI = (0x0F << 26),
72 /* arithmetic with immediate */
73 OPC_DADDI = (0x18 << 26),
74 OPC_DADDIU = (0x19 << 26),
75 /* Jump and branches */
76 OPC_J = (0x02 << 26),
77 OPC_JAL = (0x03 << 26),
78 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
79 OPC_BEQL = (0x14 << 26),
80 OPC_BNE = (0x05 << 26),
81 OPC_BNEL = (0x15 << 26),
82 OPC_BLEZ = (0x06 << 26),
83 OPC_BLEZL = (0x16 << 26),
84 OPC_BGTZ = (0x07 << 26),
85 OPC_BGTZL = (0x17 << 26),
86 OPC_JALX = (0x1D << 26),
87 OPC_DAUI = (0x1D << 26),
88 /* Load and stores */
89 OPC_LDL = (0x1A << 26),
90 OPC_LDR = (0x1B << 26),
91 OPC_LB = (0x20 << 26),
92 OPC_LH = (0x21 << 26),
93 OPC_LWL = (0x22 << 26),
94 OPC_LW = (0x23 << 26),
95 OPC_LWPC = OPC_LW | 0x5,
96 OPC_LBU = (0x24 << 26),
97 OPC_LHU = (0x25 << 26),
98 OPC_LWR = (0x26 << 26),
99 OPC_LWU = (0x27 << 26),
100 OPC_SB = (0x28 << 26),
101 OPC_SH = (0x29 << 26),
102 OPC_SWL = (0x2A << 26),
103 OPC_SW = (0x2B << 26),
104 OPC_SDL = (0x2C << 26),
105 OPC_SDR = (0x2D << 26),
106 OPC_SWR = (0x2E << 26),
107 OPC_LL = (0x30 << 26),
108 OPC_LLD = (0x34 << 26),
109 OPC_LD = (0x37 << 26),
110 OPC_LDPC = OPC_LD | 0x5,
111 OPC_SC = (0x38 << 26),
112 OPC_SCD = (0x3C << 26),
113 OPC_SD = (0x3F << 26),
114 /* Floating point load/store */
115 OPC_LWC1 = (0x31 << 26),
116 OPC_LWC2 = (0x32 << 26),
117 OPC_LDC1 = (0x35 << 26),
118 OPC_LDC2 = (0x36 << 26),
119 OPC_SWC1 = (0x39 << 26),
120 OPC_SWC2 = (0x3A << 26),
121 OPC_SDC1 = (0x3D << 26),
122 OPC_SDC2 = (0x3E << 26),
123 /* Compact Branches */
124 OPC_BLEZALC = (0x06 << 26),
125 OPC_BGEZALC = (0x06 << 26),
126 OPC_BGEUC = (0x06 << 26),
127 OPC_BGTZALC = (0x07 << 26),
128 OPC_BLTZALC = (0x07 << 26),
129 OPC_BLTUC = (0x07 << 26),
130 OPC_BOVC = (0x08 << 26),
131 OPC_BEQZALC = (0x08 << 26),
132 OPC_BEQC = (0x08 << 26),
133 OPC_BLEZC = (0x16 << 26),
134 OPC_BGEZC = (0x16 << 26),
135 OPC_BGEC = (0x16 << 26),
136 OPC_BGTZC = (0x17 << 26),
137 OPC_BLTZC = (0x17 << 26),
138 OPC_BLTC = (0x17 << 26),
139 OPC_BNVC = (0x18 << 26),
140 OPC_BNEZALC = (0x18 << 26),
141 OPC_BNEC = (0x18 << 26),
142 OPC_BC = (0x32 << 26),
143 OPC_BEQZC = (0x36 << 26),
144 OPC_JIC = (0x36 << 26),
145 OPC_BALC = (0x3A << 26),
146 OPC_BNEZC = (0x3E << 26),
147 OPC_JIALC = (0x3E << 26),
148 /* MDMX ASE specific */
149 OPC_MDMX = (0x1E << 26),
150 /* Cache and prefetch */
151 OPC_CACHE = (0x2F << 26),
152 OPC_PREF = (0x33 << 26),
153 /* PC-relative address computation / loads */
154 OPC_PCREL = (0x3B << 26),
155 };
156
157 /* PC-relative address computation / loads */
158 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
159 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
160 enum {
161 /* Instructions determined by bits 19 and 20 */
162 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
163 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
164 OPC_LWUPC = OPC_PCREL | (2 << 19),
165
166 /* Instructions determined by bits 16 ... 20 */
167 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
168 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
169
170 /* Other */
171 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
172 };
173
174 /* MIPS special opcodes */
175 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
176
177 enum {
178 /* Shifts */
179 OPC_SLL = 0x00 | OPC_SPECIAL,
180 /* NOP is SLL r0, r0, 0 */
181 /* SSNOP is SLL r0, r0, 1 */
182 /* EHB is SLL r0, r0, 3 */
183 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
184 OPC_ROTR = OPC_SRL | (1 << 21),
185 OPC_SRA = 0x03 | OPC_SPECIAL,
186 OPC_SLLV = 0x04 | OPC_SPECIAL,
187 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
188 OPC_ROTRV = OPC_SRLV | (1 << 6),
189 OPC_SRAV = 0x07 | OPC_SPECIAL,
190 OPC_DSLLV = 0x14 | OPC_SPECIAL,
191 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
192 OPC_DROTRV = OPC_DSRLV | (1 << 6),
193 OPC_DSRAV = 0x17 | OPC_SPECIAL,
194 OPC_DSLL = 0x38 | OPC_SPECIAL,
195 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
196 OPC_DROTR = OPC_DSRL | (1 << 21),
197 OPC_DSRA = 0x3B | OPC_SPECIAL,
198 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
199 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
200 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
201 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
202 /* Multiplication / division */
203 OPC_MULT = 0x18 | OPC_SPECIAL,
204 OPC_MULTU = 0x19 | OPC_SPECIAL,
205 OPC_DIV = 0x1A | OPC_SPECIAL,
206 OPC_DIVU = 0x1B | OPC_SPECIAL,
207 OPC_DMULT = 0x1C | OPC_SPECIAL,
208 OPC_DMULTU = 0x1D | OPC_SPECIAL,
209 OPC_DDIV = 0x1E | OPC_SPECIAL,
210 OPC_DDIVU = 0x1F | OPC_SPECIAL,
211
212 /* 2 registers arithmetic / logic */
213 OPC_ADD = 0x20 | OPC_SPECIAL,
214 OPC_ADDU = 0x21 | OPC_SPECIAL,
215 OPC_SUB = 0x22 | OPC_SPECIAL,
216 OPC_SUBU = 0x23 | OPC_SPECIAL,
217 OPC_AND = 0x24 | OPC_SPECIAL,
218 OPC_OR = 0x25 | OPC_SPECIAL,
219 OPC_XOR = 0x26 | OPC_SPECIAL,
220 OPC_NOR = 0x27 | OPC_SPECIAL,
221 OPC_SLT = 0x2A | OPC_SPECIAL,
222 OPC_SLTU = 0x2B | OPC_SPECIAL,
223 OPC_DADD = 0x2C | OPC_SPECIAL,
224 OPC_DADDU = 0x2D | OPC_SPECIAL,
225 OPC_DSUB = 0x2E | OPC_SPECIAL,
226 OPC_DSUBU = 0x2F | OPC_SPECIAL,
227 /* Jumps */
228 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
229 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
230 /* Traps */
231 OPC_TGE = 0x30 | OPC_SPECIAL,
232 OPC_TGEU = 0x31 | OPC_SPECIAL,
233 OPC_TLT = 0x32 | OPC_SPECIAL,
234 OPC_TLTU = 0x33 | OPC_SPECIAL,
235 OPC_TEQ = 0x34 | OPC_SPECIAL,
236 OPC_TNE = 0x36 | OPC_SPECIAL,
237 /* HI / LO registers load & stores */
238 OPC_MFHI = 0x10 | OPC_SPECIAL,
239 OPC_MTHI = 0x11 | OPC_SPECIAL,
240 OPC_MFLO = 0x12 | OPC_SPECIAL,
241 OPC_MTLO = 0x13 | OPC_SPECIAL,
242 /* Conditional moves */
243 OPC_MOVZ = 0x0A | OPC_SPECIAL,
244 OPC_MOVN = 0x0B | OPC_SPECIAL,
245
246 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
247 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
248
249 OPC_MOVCI = 0x01 | OPC_SPECIAL,
250
251 /* Special */
252 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
253 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
254 OPC_BREAK = 0x0D | OPC_SPECIAL,
255 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
256 OPC_SYNC = 0x0F | OPC_SPECIAL,
257
258 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
259 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
260 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
261 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
262 };
263
264 /*
265 * R6 Multiply and Divide instructions have the same opcode
266 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
267 */
268 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
269
270 enum {
271 R6_OPC_MUL = OPC_MULT | (2 << 6),
272 R6_OPC_MUH = OPC_MULT | (3 << 6),
273 R6_OPC_MULU = OPC_MULTU | (2 << 6),
274 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
275 R6_OPC_DIV = OPC_DIV | (2 << 6),
276 R6_OPC_MOD = OPC_DIV | (3 << 6),
277 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
278 R6_OPC_MODU = OPC_DIVU | (3 << 6),
279
280 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
281 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
282 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
283 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
284 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
285 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
286 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
287 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
288
289 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
290 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
291 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
292 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
293 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
294 };
295
296 /* REGIMM (rt field) opcodes */
297 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
298
299 enum {
300 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
301 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
302 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
303 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
304 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
305 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
306 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
307 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
308 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
309 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
310 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
311 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
312 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
313 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
314 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
315 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
316
317 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
318 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
319 };
320
321 /* Special2 opcodes */
322 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
323
324 enum {
325 /* Multiply & xxx operations */
326 OPC_MADD = 0x00 | OPC_SPECIAL2,
327 OPC_MADDU = 0x01 | OPC_SPECIAL2,
328 OPC_MUL = 0x02 | OPC_SPECIAL2,
329 OPC_MSUB = 0x04 | OPC_SPECIAL2,
330 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
331 /* Misc */
332 OPC_CLZ = 0x20 | OPC_SPECIAL2,
333 OPC_CLO = 0x21 | OPC_SPECIAL2,
334 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
335 OPC_DCLO = 0x25 | OPC_SPECIAL2,
336 /* Special */
337 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
338 };
339
340 /* Special3 opcodes */
341 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
342
343 enum {
344 OPC_EXT = 0x00 | OPC_SPECIAL3,
345 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
346 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
347 OPC_DEXT = 0x03 | OPC_SPECIAL3,
348 OPC_INS = 0x04 | OPC_SPECIAL3,
349 OPC_DINSM = 0x05 | OPC_SPECIAL3,
350 OPC_DINSU = 0x06 | OPC_SPECIAL3,
351 OPC_DINS = 0x07 | OPC_SPECIAL3,
352 OPC_FORK = 0x08 | OPC_SPECIAL3,
353 OPC_YIELD = 0x09 | OPC_SPECIAL3,
354 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
355 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
356 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
357 OPC_GINV = 0x3D | OPC_SPECIAL3,
358
359 /* MIPS DSP Load */
360 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
361 /* MIPS DSP Arithmetic */
362 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
363 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
364 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
365 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
366 OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3,
367 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
368 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
369 /* MIPS DSP GPR-Based Shift Sub-class */
370 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
371 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
372 /* MIPS DSP Multiply Sub-class insns */
373 OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3,
374 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
375 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
376 /* DSP Bit/Manipulation Sub-class */
377 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
378 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
379 /* MIPS DSP Append Sub-class */
380 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
381 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
382 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
383 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
384 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
385
386 /* EVA */
387 OPC_LWLE = 0x19 | OPC_SPECIAL3,
388 OPC_LWRE = 0x1A | OPC_SPECIAL3,
389 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
390 OPC_SBE = 0x1C | OPC_SPECIAL3,
391 OPC_SHE = 0x1D | OPC_SPECIAL3,
392 OPC_SCE = 0x1E | OPC_SPECIAL3,
393 OPC_SWE = 0x1F | OPC_SPECIAL3,
394 OPC_SWLE = 0x21 | OPC_SPECIAL3,
395 OPC_SWRE = 0x22 | OPC_SPECIAL3,
396 OPC_PREFE = 0x23 | OPC_SPECIAL3,
397 OPC_LBUE = 0x28 | OPC_SPECIAL3,
398 OPC_LHUE = 0x29 | OPC_SPECIAL3,
399 OPC_LBE = 0x2C | OPC_SPECIAL3,
400 OPC_LHE = 0x2D | OPC_SPECIAL3,
401 OPC_LLE = 0x2E | OPC_SPECIAL3,
402 OPC_LWE = 0x2F | OPC_SPECIAL3,
403
404 /* R6 */
405 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
406 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
407 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
408 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
409 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
410 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
411 };
412
413 /* Loongson EXT load/store quad word opcodes */
414 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
415 enum {
416 OPC_GSLQ = 0x0020 | OPC_LWC2,
417 OPC_GSLQC1 = 0x8020 | OPC_LWC2,
418 OPC_GSSHFL = OPC_LWC2,
419 OPC_GSSQ = 0x0020 | OPC_SWC2,
420 OPC_GSSQC1 = 0x8020 | OPC_SWC2,
421 OPC_GSSHFS = OPC_SWC2,
422 };
423
424 /* Loongson EXT shifted load/store opcodes */
425 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
426 enum {
427 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
428 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
429 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
430 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
431 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
432 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
433 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
434 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
435 };
436
437 /* Loongson EXT LDC2/SDC2 opcodes */
438 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
439
440 enum {
441 OPC_GSLBX = 0x0 | OPC_LDC2,
442 OPC_GSLHX = 0x1 | OPC_LDC2,
443 OPC_GSLWX = 0x2 | OPC_LDC2,
444 OPC_GSLDX = 0x3 | OPC_LDC2,
445 OPC_GSLWXC1 = 0x6 | OPC_LDC2,
446 OPC_GSLDXC1 = 0x7 | OPC_LDC2,
447 OPC_GSSBX = 0x0 | OPC_SDC2,
448 OPC_GSSHX = 0x1 | OPC_SDC2,
449 OPC_GSSWX = 0x2 | OPC_SDC2,
450 OPC_GSSDX = 0x3 | OPC_SDC2,
451 OPC_GSSWXC1 = 0x6 | OPC_SDC2,
452 OPC_GSSDXC1 = 0x7 | OPC_SDC2,
453 };
454
455 /* BSHFL opcodes */
456 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457
458 enum {
459 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
460 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
461 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
462 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
463 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
464 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
465 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
466 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
467 };
468
469 /* DBSHFL opcodes */
470 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
471
472 enum {
473 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
474 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
475 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
476 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
477 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
478 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
479 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
480 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
481 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
482 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
483 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
484 };
485
486 /* MIPS DSP REGIMM opcodes */
487 enum {
488 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
489 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
490 };
491
492 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
493 /* MIPS DSP Load */
494 enum {
495 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
496 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
497 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
498 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
499 };
500
501 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
502 enum {
503 /* MIPS DSP Arithmetic Sub-class */
504 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
505 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
506 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
507 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
508 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
509 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
510 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
511 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
512 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
513 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
514 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
515 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
516 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
517 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
518 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
519 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
520 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
521 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
522 /* MIPS DSP Multiply Sub-class insns */
523 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
524 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
525 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
526 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
527 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
528 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
529 };
530
531 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
532 enum {
533 /* MIPS DSP Arithmetic Sub-class */
534 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
535 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
536 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
537 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
538 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
539 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
540 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
541 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
542 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
543 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
544 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
545 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
546 /* MIPS DSP Multiply Sub-class insns */
547 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
548 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
549 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
550 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
551 };
552
553 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 enum {
555 /* MIPS DSP Arithmetic Sub-class */
556 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
557 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
558 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
559 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
560 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
561 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
562 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
563 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
564 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
565 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
566 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
567 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
568 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
569 /* DSP Bit/Manipulation Sub-class */
570 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
571 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
572 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
573 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
574 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
575 };
576
577 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
578 enum {
579 /* MIPS DSP Arithmetic Sub-class */
580 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
581 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
582 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
583 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
584 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
585 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
586 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
587 /* DSP Compare-Pick Sub-class */
588 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
589 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
590 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
591 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
592 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
593 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
594 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
595 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
596 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
597 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
598 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
599 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
600 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
601 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
602 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
603 };
604
605 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
606 enum {
607 /* MIPS DSP GPR-Based Shift Sub-class */
608 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
609 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
610 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
611 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
612 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
613 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
614 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
615 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
616 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
617 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
618 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
619 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
620 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
621 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
622 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
623 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
624 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
625 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
626 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
627 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
628 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
629 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
630 };
631
632 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
633 enum {
634 /* MIPS DSP Multiply Sub-class insns */
635 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
636 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
637 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
638 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
639 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
640 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
641 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
642 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
643 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
644 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
645 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
646 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
647 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
648 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
649 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
650 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
651 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
652 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
653 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
654 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
655 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
656 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
657 };
658
659 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
660 enum {
661 /* DSP Bit/Manipulation Sub-class */
662 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
663 };
664
665 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
666 enum {
667 /* MIPS DSP Append Sub-class */
668 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
669 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
670 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
671 };
672
673 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
674 enum {
675 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
676 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
677 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
678 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
679 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
680 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
681 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
682 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
683 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
684 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
685 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
686 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
687 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
688 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
689 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
690 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
691 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
692 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
693 };
694
695 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
696 enum {
697 /* MIPS DSP Arithmetic Sub-class */
698 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
699 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
700 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
701 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
702 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
703 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
704 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
705 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
706 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
707 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
708 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
709 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
710 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
711 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
712 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
713 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
714 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
715 /* DSP Bit/Manipulation Sub-class */
716 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
717 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
718 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
719 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
720 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
721 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
722 };
723
724 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
725 enum {
726 /* MIPS DSP Multiply Sub-class insns */
727 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
728 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
729 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
730 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
731 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
732 /* MIPS DSP Arithmetic Sub-class */
733 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
734 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
735 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
736 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
737 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
738 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
739 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
740 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
741 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
742 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
743 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
744 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
745 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
746 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
747 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
748 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
749 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
750 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
751 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
752 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
753 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
754 };
755
756 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
757 enum {
758 /* DSP Compare-Pick Sub-class */
759 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
763 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
764 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
765 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
766 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
767 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
768 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
769 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
770 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
771 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
772 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
773 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
774 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
775 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
776 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
777 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
778 /* MIPS DSP Arithmetic Sub-class */
779 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
780 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
781 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
782 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
783 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
784 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
785 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
786 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
787 };
788
789 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
790 enum {
791 /* DSP Append Sub-class */
792 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
793 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
794 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
795 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
796 };
797
798 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
799 enum {
800 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
801 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
802 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
803 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
804 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
805 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
806 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
807 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
808 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
809 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
810 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
811 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
812 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
813 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
814 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
815 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
816 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
817 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
818 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
819 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
820 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
821 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
822 };
823
824 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
825 enum {
826 /* DSP Bit/Manipulation Sub-class */
827 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
828 };
829
830 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
831 enum {
832 /* MIPS DSP Multiply Sub-class insns */
833 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
835 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
836 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
837 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
838 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
839 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
840 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
841 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
842 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
843 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
844 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
845 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
846 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
847 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
848 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
849 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
850 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
851 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
852 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
853 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
854 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
855 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
856 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
857 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
858 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
859 };
860
861 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
862 enum {
863 /* MIPS DSP GPR-Based Shift Sub-class */
864 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
866 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
867 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
868 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
869 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
870 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
871 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
872 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
873 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
874 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
875 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
876 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
877 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
878 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
879 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
880 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
881 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
882 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
883 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
884 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
885 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
886 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
887 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
888 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
889 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
890 };
891
892 /* Coprocessor 0 (rs field) */
893 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
894
895 enum {
896 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
897 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
898 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
899 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
900 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
901 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
902 OPC_MFTR = (0x08 << 21) | OPC_CP0,
903 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
904 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
905 OPC_MTTR = (0x0C << 21) | OPC_CP0,
906 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
907 OPC_C0 = (0x10 << 21) | OPC_CP0,
908 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
909 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
910 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
911 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
912 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
913 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
914 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
915 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
916 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
917 OPC_C0_A = (0x1A << 21) | OPC_CP0,
918 OPC_C0_B = (0x1B << 21) | OPC_CP0,
919 OPC_C0_C = (0x1C << 21) | OPC_CP0,
920 OPC_C0_D = (0x1D << 21) | OPC_CP0,
921 OPC_C0_E = (0x1E << 21) | OPC_CP0,
922 OPC_C0_F = (0x1F << 21) | OPC_CP0,
923 };
924
925 /* MFMC0 opcodes */
926 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
927
928 enum {
929 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
930 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
931 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
932 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
933 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
934 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
935 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
936 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
937 };
938
939 /* Coprocessor 0 (with rs == C0) */
940 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
941
942 enum {
943 OPC_TLBR = 0x01 | OPC_C0,
944 OPC_TLBWI = 0x02 | OPC_C0,
945 OPC_TLBINV = 0x03 | OPC_C0,
946 OPC_TLBINVF = 0x04 | OPC_C0,
947 OPC_TLBWR = 0x06 | OPC_C0,
948 OPC_TLBP = 0x08 | OPC_C0,
949 OPC_RFE = 0x10 | OPC_C0,
950 OPC_ERET = 0x18 | OPC_C0,
951 OPC_DERET = 0x1F | OPC_C0,
952 OPC_WAIT = 0x20 | OPC_C0,
953 };
954
955 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
956
957 enum {
958 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
959 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
960 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
961 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
962 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
963 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
964 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
965 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
966 OPC_BC2 = (0x08 << 21) | OPC_CP2,
967 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
968 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
969 };
970
971 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
972
973 enum {
974 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
975 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
976 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
977 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
978 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
979 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
980 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
981 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
982
983 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
984 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
985 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
986 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
987 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
988 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
989 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
990 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
991
992 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
993 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
994 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
995 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
996 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
997 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
998 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
999 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1000
1001 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1002 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1003 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1004 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1005 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1006 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1007 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1008 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1009
1010 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1011 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1012 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1013 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1014 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1015 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1016
1017 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1018 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1019 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1020 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1021 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1022 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1023
1024 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1025 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1026 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1027 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1028 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1029 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1030
1031 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1032 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1033 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1034 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1035 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1036 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1037
1038 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1039 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1040 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1041 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1042 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1043 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1044
1045 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1046 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1047 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1048 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1049 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1050 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1051
1052 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1053 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1054 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1055 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1056 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1057 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1058
1059 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1060 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1061 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1062 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1063 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1064 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1065 };
1066
1067
1068 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1069
1070 enum {
1071 OPC_LWXC1 = 0x00 | OPC_CP3,
1072 OPC_LDXC1 = 0x01 | OPC_CP3,
1073 OPC_LUXC1 = 0x05 | OPC_CP3,
1074 OPC_SWXC1 = 0x08 | OPC_CP3,
1075 OPC_SDXC1 = 0x09 | OPC_CP3,
1076 OPC_SUXC1 = 0x0D | OPC_CP3,
1077 OPC_PREFX = 0x0F | OPC_CP3,
1078 OPC_ALNV_PS = 0x1E | OPC_CP3,
1079 OPC_MADD_S = 0x20 | OPC_CP3,
1080 OPC_MADD_D = 0x21 | OPC_CP3,
1081 OPC_MADD_PS = 0x26 | OPC_CP3,
1082 OPC_MSUB_S = 0x28 | OPC_CP3,
1083 OPC_MSUB_D = 0x29 | OPC_CP3,
1084 OPC_MSUB_PS = 0x2E | OPC_CP3,
1085 OPC_NMADD_S = 0x30 | OPC_CP3,
1086 OPC_NMADD_D = 0x31 | OPC_CP3,
1087 OPC_NMADD_PS = 0x36 | OPC_CP3,
1088 OPC_NMSUB_S = 0x38 | OPC_CP3,
1089 OPC_NMSUB_D = 0x39 | OPC_CP3,
1090 OPC_NMSUB_PS = 0x3E | OPC_CP3,
1091 };
1092
1093 /*
1094 * MMI (MultiMedia Instruction) encodings
1095 * ======================================
1096 *
1097 * MMI instructions encoding table keys:
1098 *
1099 * * This code is reserved for future use. An attempt to execute it
1100 * causes a Reserved Instruction exception.
1101 * % This code indicates an instruction class. The instruction word
1102 * must be further decoded by examining additional tables that show
1103 * the values for other instruction fields.
1104 * # This code is reserved for the unsupported instructions DMULT,
1105 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1106 * to execute it causes a Reserved Instruction exception.
1107 *
1108 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1109 *
1110 * 31 26 0
1111 * +--------+----------------------------------------+
1112 * | opcode | |
1113 * +--------+----------------------------------------+
1114 *
1115 * opcode bits 28..26
1116 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1117 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1118 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1119 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1120 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1121 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1122 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1123 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1124 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1125 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1126 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1127 */
1128
1129 enum {
1130 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
1131 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
1132 };
1133
1134 /*
1135 * MMI instructions with opcode field = MMI:
1136 *
1137 * 31 26 5 0
1138 * +--------+-------------------------------+--------+
1139 * | MMI | |function|
1140 * +--------+-------------------------------+--------+
1141 *
1142 * function bits 2..0
1143 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1144 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1145 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1146 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1147 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1148 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1149 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1150 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1151 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1152 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1153 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1154 */
1155
1156 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1157 enum {
1158 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1159 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1160 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1161 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1162 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
1163 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1164 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
1165 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
1166 };
1167
1168 /* global register indices */
1169 TCGv cpu_gpr[32], cpu_PC;
1170 /*
1171 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1172 * and the upper halves in cpu_gpr_hi[].
1173 */
1174 TCGv_i64 cpu_gpr_hi[32];
1175 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1176 static TCGv cpu_dspctrl, btarget;
1177 TCGv bcond;
1178 static TCGv cpu_lladdr, cpu_llval;
1179 static TCGv_i32 hflags;
1180 TCGv_i32 fpu_fcr0, fpu_fcr31;
1181 TCGv_i64 fpu_f64[32];
1182 TCGv_i64 oct_mpl[OCTEON_MULTIPLIER_REGS];
1183 TCGv_i64 oct_p[OCTEON_MULTIPLIER_REGS];
1184
1185 static const char regnames_HI[][4] = {
1186 "HI0", "HI1", "HI2", "HI3",
1187 };
1188
1189 static const char regnames_LO[][4] = {
1190 "LO0", "LO1", "LO2", "LO3",
1191 };
1192
1193 /* General purpose registers moves. */
1194 void gen_load_gpr(TCGv t, int reg)
1195 {
1196 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1197 if (reg == 0) {
1198 tcg_gen_movi_tl(t, 0);
1199 } else {
1200 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1201 }
1202 }
1203
1204 void gen_store_gpr(TCGv t, int reg)
1205 {
1206 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1207 if (reg != 0) {
1208 tcg_gen_mov_tl(cpu_gpr[reg], t);
1209 }
1210 }
1211
1212 #if defined(TARGET_MIPS64)
1213 void gen_load_gpr_hi(TCGv_i64 t, int reg)
1214 {
1215 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1216 if (reg == 0) {
1217 tcg_gen_movi_i64(t, 0);
1218 } else {
1219 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1220 }
1221 }
1222
1223 void gen_store_gpr_hi(TCGv_i64 t, int reg)
1224 {
1225 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1226 if (reg != 0) {
1227 tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1228 }
1229 }
1230 #endif /* TARGET_MIPS64 */
1231
1232 /* Moves to/from shadow registers. */
1233 static inline void gen_load_srsgpr(int from, int to)
1234 {
1235 TCGv t0 = tcg_temp_new();
1236
1237 if (from == 0) {
1238 tcg_gen_movi_tl(t0, 0);
1239 } else {
1240 TCGv_i32 t2 = tcg_temp_new_i32();
1241 TCGv_ptr addr = tcg_temp_new_ptr();
1242
1243 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1244 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1245 tcg_gen_andi_i32(t2, t2, 0xf);
1246 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1247 tcg_gen_ext_i32_ptr(addr, t2);
1248 tcg_gen_add_ptr(addr, tcg_env, addr);
1249
1250 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1251 }
1252 gen_store_gpr(t0, to);
1253 }
1254
1255 static inline void gen_store_srsgpr(int from, int to)
1256 {
1257 if (to != 0) {
1258 TCGv t0 = tcg_temp_new();
1259 TCGv_i32 t2 = tcg_temp_new_i32();
1260 TCGv_ptr addr = tcg_temp_new_ptr();
1261
1262 gen_load_gpr(t0, from);
1263 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1264 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1265 tcg_gen_andi_i32(t2, t2, 0xf);
1266 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1267 tcg_gen_ext_i32_ptr(addr, t2);
1268 tcg_gen_add_ptr(addr, tcg_env, addr);
1269
1270 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1271 }
1272 }
1273
1274 /* Tests */
1275 static inline void gen_save_pc(target_ulong pc)
1276 {
1277 tcg_gen_movi_tl(cpu_PC, pc);
1278 }
1279
1280 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1281 {
1282 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1283 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1284 gen_save_pc(ctx->base.pc_next);
1285 ctx->saved_pc = ctx->base.pc_next;
1286 }
1287 if (ctx->hflags != ctx->saved_hflags) {
1288 tcg_gen_movi_i32(hflags, ctx->hflags);
1289 ctx->saved_hflags = ctx->hflags;
1290 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1291 case MIPS_HFLAG_BR:
1292 break;
1293 case MIPS_HFLAG_BC:
1294 case MIPS_HFLAG_BL:
1295 case MIPS_HFLAG_B:
1296 tcg_gen_movi_tl(btarget, ctx->btarget);
1297 break;
1298 }
1299 }
1300 }
1301
1302 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1303 {
1304 ctx->saved_hflags = ctx->hflags;
1305 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1306 case MIPS_HFLAG_BR:
1307 break;
1308 case MIPS_HFLAG_BC:
1309 case MIPS_HFLAG_BL:
1310 case MIPS_HFLAG_B:
1311 ctx->btarget = env->btarget;
1312 break;
1313 }
1314 }
1315
1316 void generate_exception_err(DisasContext *ctx, int excp, int err)
1317 {
1318 save_cpu_state(ctx, 1);
1319 gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp),
1320 tcg_constant_i32(err));
1321 ctx->base.is_jmp = DISAS_NORETURN;
1322 }
1323
1324 void generate_exception(DisasContext *ctx, int excp)
1325 {
1326 gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp));
1327 }
1328
1329 void generate_exception_end(DisasContext *ctx, int excp)
1330 {
1331 generate_exception_err(ctx, excp, 0);
1332 }
1333
1334 void generate_exception_break(DisasContext *ctx, int code)
1335 {
1336 #ifdef CONFIG_USER_ONLY
1337 /* Pass the break code along to cpu_loop. */
1338 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
1339 offsetof(CPUMIPSState, error_code));
1340 #endif
1341 generate_exception_end(ctx, EXCP_BREAK);
1342 }
1343
1344 void gen_reserved_instruction(DisasContext *ctx)
1345 {
1346 generate_exception_end(ctx, EXCP_RI);
1347 }
1348
1349 /* Floating point register moves. */
1350 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1351 {
1352 if (ctx->hflags & MIPS_HFLAG_FRE) {
1353 generate_exception(ctx, EXCP_RI);
1354 }
1355 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1356 }
1357
1358 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1359 {
1360 TCGv_i64 t64;
1361 if (ctx->hflags & MIPS_HFLAG_FRE) {
1362 generate_exception(ctx, EXCP_RI);
1363 }
1364 t64 = tcg_temp_new_i64();
1365 tcg_gen_extu_i32_i64(t64, t);
1366 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1367 }
1368
1369 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1370 {
1371 if (ctx->hflags & MIPS_HFLAG_F64) {
1372 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1373 } else {
1374 gen_load_fpr32(ctx, t, reg | 1);
1375 }
1376 }
1377
1378 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1379 {
1380 if (ctx->hflags & MIPS_HFLAG_F64) {
1381 TCGv_i64 t64 = tcg_temp_new_i64();
1382 tcg_gen_extu_i32_i64(t64, t);
1383 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1384 } else {
1385 gen_store_fpr32(ctx, t, reg | 1);
1386 }
1387 }
1388
1389 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1390 {
1391 if (ctx->hflags & MIPS_HFLAG_F64) {
1392 tcg_gen_mov_i64(t, fpu_f64[reg]);
1393 } else {
1394 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1395 }
1396 }
1397
1398 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1399 {
1400 if (ctx->hflags & MIPS_HFLAG_F64) {
1401 tcg_gen_mov_i64(fpu_f64[reg], t);
1402 } else {
1403 TCGv_i64 t0;
1404 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1405 t0 = tcg_temp_new_i64();
1406 tcg_gen_shri_i64(t0, t, 32);
1407 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1408 }
1409 }
1410
1411 int get_fp_bit(int cc)
1412 {
1413 if (cc) {
1414 return 24 + cc;
1415 } else {
1416 return 23;
1417 }
1418 }
1419
1420 /* Addresses computation */
1421 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1422 {
1423 tcg_gen_add_tl(ret, arg0, arg1);
1424
1425 #if defined(TARGET_MIPS64)
1426 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1427 tcg_gen_ext32s_i64(ret, ret);
1428 }
1429 #endif
1430 }
1431
1432 void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base, target_long ofs)
1433 {
1434 tcg_gen_addi_tl(ret, base, ofs);
1435
1436 #if defined(TARGET_MIPS64)
1437 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1438 tcg_gen_ext32s_i64(ret, ret);
1439 }
1440 #endif
1441 }
1442
1443 /* Addresses computation (translation time) */
1444 static target_long addr_add(DisasContext *ctx, target_long base,
1445 target_long offset)
1446 {
1447 target_long sum = base + offset;
1448
1449 #if defined(TARGET_MIPS64)
1450 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1451 sum = (int32_t)sum;
1452 }
1453 #endif
1454 return sum;
1455 }
1456
1457 /* Sign-extract the low 32-bits to a target_long. */
1458 void gen_move_low32(TCGv ret, TCGv_i64 arg)
1459 {
1460 #if defined(TARGET_MIPS64)
1461 tcg_gen_ext32s_i64(ret, arg);
1462 #else
1463 tcg_gen_extrl_i64_i32(ret, arg);
1464 #endif
1465 }
1466
1467 /* Sign-extract the high 32-bits to a target_long. */
1468 void gen_move_high32(TCGv ret, TCGv_i64 arg)
1469 {
1470 #if defined(TARGET_MIPS64)
1471 tcg_gen_sari_i64(ret, arg, 32);
1472 #else
1473 tcg_gen_extrh_i64_i32(ret, arg);
1474 #endif
1475 }
1476
1477 bool check_cp0_enabled(DisasContext *ctx)
1478 {
1479 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1480 generate_exception_end(ctx, EXCP_CpU);
1481 return false;
1482 }
1483 return true;
1484 }
1485
1486 void check_cp1_enabled(DisasContext *ctx)
1487 {
1488 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1489 generate_exception_err(ctx, EXCP_CpU, 1);
1490 }
1491 }
1492
1493 /*
1494 * Verify that the processor is running with COP1X instructions enabled.
1495 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1496 * opcode tables.
1497 */
1498 void check_cop1x(DisasContext *ctx)
1499 {
1500 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1501 gen_reserved_instruction(ctx);
1502 }
1503 }
1504
1505 /*
1506 * Verify that the processor is running with 64-bit floating-point
1507 * operations enabled.
1508 */
1509 void check_cp1_64bitmode(DisasContext *ctx)
1510 {
1511 if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) {
1512 gen_reserved_instruction(ctx);
1513 }
1514 }
1515
1516 /*
1517 * Verify if floating point register is valid; an operation is not defined
1518 * if bit 0 of any register specification is set and the FR bit in the
1519 * Status register equals zero, since the register numbers specify an
1520 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1521 * in the Status register equals one, both even and odd register numbers
1522 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1523 *
1524 * Multiple 64 bit wide registers can be checked by calling
1525 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1526 */
1527 void check_cp1_registers(DisasContext *ctx, int regs)
1528 {
1529 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1530 gen_reserved_instruction(ctx);
1531 }
1532 }
1533
1534 /*
1535 * Verify that the processor is running with DSP instructions enabled.
1536 * This is enabled by CP0 Status register MX(24) bit.
1537 */
1538 static inline void check_dsp(DisasContext *ctx)
1539 {
1540 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1541 if (ctx->insn_flags & ASE_DSP) {
1542 generate_exception_end(ctx, EXCP_DSPDIS);
1543 } else {
1544 gen_reserved_instruction(ctx);
1545 }
1546 }
1547 }
1548
1549 static inline void check_dsp_r2(DisasContext *ctx)
1550 {
1551 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1552 if (ctx->insn_flags & ASE_DSP) {
1553 generate_exception_end(ctx, EXCP_DSPDIS);
1554 } else {
1555 gen_reserved_instruction(ctx);
1556 }
1557 }
1558 }
1559
1560 static inline void check_dsp_r3(DisasContext *ctx)
1561 {
1562 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1563 if (ctx->insn_flags & ASE_DSP) {
1564 generate_exception_end(ctx, EXCP_DSPDIS);
1565 } else {
1566 gen_reserved_instruction(ctx);
1567 }
1568 }
1569 }
1570
1571 /*
1572 * This code generates a "reserved instruction" exception if the
1573 * CPU does not support the instruction set corresponding to flags.
1574 */
1575 void check_insn(DisasContext *ctx, uint64_t flags)
1576 {
1577 if (unlikely(!(ctx->insn_flags & flags))) {
1578 gen_reserved_instruction(ctx);
1579 }
1580 }
1581
1582 /*
1583 * This code generates a "reserved instruction" exception if the
1584 * CPU has corresponding flag set which indicates that the instruction
1585 * has been removed.
1586 */
1587 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1588 {
1589 if (unlikely(ctx->insn_flags & flags)) {
1590 gen_reserved_instruction(ctx);
1591 }
1592 }
1593
1594 /*
1595 * The Linux kernel traps certain reserved instruction exceptions to
1596 * emulate the corresponding instructions. QEMU is the kernel in user
1597 * mode, so those traps are emulated by accepting the instructions.
1598 *
1599 * A reserved instruction exception is generated for flagged CPUs if
1600 * QEMU runs in system mode.
1601 */
1602 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1603 {
1604 #ifndef CONFIG_USER_ONLY
1605 check_insn_opc_removed(ctx, flags);
1606 #endif
1607 }
1608
1609 /*
1610 * This code generates a "reserved instruction" exception if the
1611 * CPU does not support 64-bit paired-single (PS) floating point data type.
1612 */
1613 static inline void check_ps(DisasContext *ctx)
1614 {
1615 if (unlikely(!ctx->ps)) {
1616 generate_exception(ctx, EXCP_RI);
1617 }
1618 check_cp1_64bitmode(ctx);
1619 }
1620
1621 bool decode_64bit_enabled(DisasContext *ctx)
1622 {
1623 return ctx->hflags & MIPS_HFLAG_64;
1624 }
1625
1626 /*
1627 * This code generates a "reserved instruction" exception if cpu is not
1628 * 64-bit or 64-bit instructions are not enabled.
1629 */
1630 void check_mips_64(DisasContext *ctx)
1631 {
1632 if (unlikely((TARGET_LONG_BITS != 64) || !decode_64bit_enabled(ctx))) {
1633 gen_reserved_instruction(ctx);
1634 }
1635 }
1636
1637 #ifndef CONFIG_USER_ONLY
1638 static inline void check_mvh(DisasContext *ctx)
1639 {
1640 if (unlikely(!ctx->mvh)) {
1641 generate_exception(ctx, EXCP_RI);
1642 }
1643 }
1644 #endif
1645
1646 /*
1647 * This code generates a "reserved instruction" exception if the
1648 * Config5 XNP bit is set.
1649 */
1650 static inline void check_xnp(DisasContext *ctx)
1651 {
1652 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1653 gen_reserved_instruction(ctx);
1654 }
1655 }
1656
1657 #ifndef CONFIG_USER_ONLY
1658 /*
1659 * This code generates a "reserved instruction" exception if the
1660 * Config3 PW bit is NOT set.
1661 */
1662 static inline void check_pw(DisasContext *ctx)
1663 {
1664 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1665 gen_reserved_instruction(ctx);
1666 }
1667 }
1668 #endif
1669
1670 /*
1671 * This code generates a "reserved instruction" exception if the
1672 * Config3 MT bit is NOT set.
1673 */
1674 static inline void check_mt(DisasContext *ctx)
1675 {
1676 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1677 gen_reserved_instruction(ctx);
1678 }
1679 }
1680
1681 #ifndef CONFIG_USER_ONLY
1682 /*
1683 * This code generates a "coprocessor unusable" exception if CP0 is not
1684 * available, and, if that is not the case, generates a "reserved instruction"
1685 * exception if the Config5 MT bit is NOT set. This is needed for availability
1686 * control of some of MT ASE instructions.
1687 */
1688 static inline void check_cp0_mt(DisasContext *ctx)
1689 {
1690 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1691 generate_exception_end(ctx, EXCP_CpU);
1692 } else {
1693 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1694 gen_reserved_instruction(ctx);
1695 }
1696 }
1697 }
1698 #endif
1699
1700 /*
1701 * This code generates a "reserved instruction" exception if the
1702 * Config5 NMS bit is set.
1703 */
1704 static inline void check_nms(DisasContext *ctx)
1705 {
1706 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1707 gen_reserved_instruction(ctx);
1708 }
1709 }
1710
1711 /*
1712 * This code generates a "reserved instruction" exception if the
1713 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1714 * Config2 TL, and Config5 L2C are unset.
1715 */
1716 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1717 {
1718 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1719 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1720 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1721 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1722 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1723 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1724 gen_reserved_instruction(ctx);
1725 }
1726 }
1727
1728 /*
1729 * This code generates a "reserved instruction" exception if the
1730 * Config5 EVA bit is NOT set.
1731 */
1732 static inline void check_eva(DisasContext *ctx)
1733 {
1734 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1735 gen_reserved_instruction(ctx);
1736 }
1737 }
1738
1739
1740 /*
1741 * Define small wrappers for gen_load_fpr* so that we have a uniform
1742 * calling interface for 32 and 64-bit FPRs. No sense in changing
1743 * all callers for gen_load_fpr32 when we need the CTX parameter for
1744 * this one use.
1745 */
1746 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1747 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1748 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1749 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1750 int ft, int fs, int cc) \
1751 { \
1752 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1753 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
1754 switch (ifmt) { \
1755 case FMT_PS: \
1756 check_ps(ctx); \
1757 break; \
1758 case FMT_D: \
1759 if (abs) { \
1760 check_cop1x(ctx); \
1761 } \
1762 check_cp1_registers(ctx, fs | ft); \
1763 break; \
1764 case FMT_S: \
1765 if (abs) { \
1766 check_cop1x(ctx); \
1767 } \
1768 break; \
1769 } \
1770 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1771 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
1772 switch (n) { \
1773 case 0: \
1774 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1775 break; \
1776 case 1: \
1777 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1778 break; \
1779 case 2: \
1780 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1781 break; \
1782 case 3: \
1783 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1784 break; \
1785 case 4: \
1786 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1787 break; \
1788 case 5: \
1789 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1790 break; \
1791 case 6: \
1792 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1793 break; \
1794 case 7: \
1795 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1796 break; \
1797 case 8: \
1798 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1799 break; \
1800 case 9: \
1801 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1802 break; \
1803 case 10: \
1804 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1805 break; \
1806 case 11: \
1807 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1808 break; \
1809 case 12: \
1810 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1811 break; \
1812 case 13: \
1813 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1814 break; \
1815 case 14: \
1816 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1817 break; \
1818 case 15: \
1819 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1820 break; \
1821 default: \
1822 abort(); \
1823 } \
1824 }
1825
1826 FOP_CONDS(, 0, d, FMT_D, 64)
1827 FOP_CONDS(abs, 1, d, FMT_D, 64)
1828 FOP_CONDS(, 0, s, FMT_S, 32)
1829 FOP_CONDS(abs, 1, s, FMT_S, 32)
1830 FOP_CONDS(, 0, ps, FMT_PS, 64)
1831 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1832 #undef FOP_CONDS
1833
1834 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1835 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
1836 int ft, int fs, int fd) \
1837 { \
1838 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1839 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1840 if (ifmt == FMT_D) { \
1841 check_cp1_registers(ctx, fs | ft | fd); \
1842 } \
1843 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1844 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1845 switch (n) { \
1846 case 0: \
1847 gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1); \
1848 break; \
1849 case 1: \
1850 gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1); \
1851 break; \
1852 case 2: \
1853 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1); \
1854 break; \
1855 case 3: \
1856 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1); \
1857 break; \
1858 case 4: \
1859 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1); \
1860 break; \
1861 case 5: \
1862 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1); \
1863 break; \
1864 case 6: \
1865 gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1); \
1866 break; \
1867 case 7: \
1868 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1); \
1869 break; \
1870 case 8: \
1871 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1); \
1872 break; \
1873 case 9: \
1874 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1); \
1875 break; \
1876 case 10: \
1877 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1); \
1878 break; \
1879 case 11: \
1880 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1); \
1881 break; \
1882 case 12: \
1883 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1); \
1884 break; \
1885 case 13: \
1886 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1); \
1887 break; \
1888 case 14: \
1889 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1); \
1890 break; \
1891 case 15: \
1892 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1); \
1893 break; \
1894 case 17: \
1895 gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1); \
1896 break; \
1897 case 18: \
1898 gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1); \
1899 break; \
1900 case 19: \
1901 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1); \
1902 break; \
1903 case 25: \
1904 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1); \
1905 break; \
1906 case 26: \
1907 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1); \
1908 break; \
1909 case 27: \
1910 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1); \
1911 break; \
1912 default: \
1913 abort(); \
1914 } \
1915 STORE; \
1916 }
1917
1918 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1919 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1920 #undef FOP_CONDNS
1921 #undef gen_ldcmp_fpr32
1922 #undef gen_ldcmp_fpr64
1923
1924 /* load/store instructions. */
1925 #ifdef CONFIG_USER_ONLY
1926 #define OP_LD_ATOMIC(insn, memop) \
1927 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx_ignored, \
1928 DisasContext *ctx) \
1929 { \
1930 TCGv t0 = tcg_temp_new(); \
1931 tcg_gen_mov_tl(t0, arg1); \
1932 tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop); \
1933 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr)); \
1934 tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval)); \
1935 }
1936 #else
1937 #define OP_LD_ATOMIC(insn, memop) \
1938 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1939 DisasContext *ctx) \
1940 { \
1941 MemOpIdx oi = make_memop_idx(memop | MO_ALIGN, mem_idx); \
1942 gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(oi)); \
1943 }
1944 #endif
1945 OP_LD_ATOMIC(ll, mo_endian(ctx) | MO_SL);
1946 #if defined(TARGET_MIPS64)
1947 OP_LD_ATOMIC(lld, mo_endian(ctx) | MO_UQ);
1948 #endif
1949 #undef OP_LD_ATOMIC
1950
1951 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1952 {
1953 if (base == 0) {
1954 tcg_gen_movi_tl(addr, offset);
1955 } else if (offset == 0) {
1956 gen_load_gpr(addr, base);
1957 } else {
1958 tcg_gen_movi_tl(addr, offset);
1959 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1960 }
1961 }
1962
1963 void gen_base_index_addr(DisasContext *ctx, TCGv addr, int base, int index)
1964 {
1965 if (base == 0) {
1966 gen_load_gpr(addr, index);
1967 } else if (index == 0) {
1968 gen_load_gpr(addr, base);
1969 } else {
1970 gen_op_addr_add(ctx, addr, cpu_gpr[base], cpu_gpr[index]);
1971 }
1972 }
1973
1974 static target_ulong pc_relative_pc(DisasContext *ctx)
1975 {
1976 target_ulong pc = ctx->base.pc_next;
1977
1978 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1979 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1980
1981 pc -= branch_bytes;
1982 }
1983
1984 pc &= ~(target_ulong)3;
1985 return pc;
1986 }
1987
1988 /* LWL or LDL, depending on MemOp. */
1989 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr,
1990 int mem_idx, MemOp mop)
1991 {
1992 int sizem1 = memop_size(mop) - 1;
1993 TCGv t0 = tcg_temp_new();
1994 TCGv t1 = tcg_temp_new();
1995
1996 /*
1997 * Do a byte access to possibly trigger a page
1998 * fault with the unaligned address.
1999 */
2000 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2001 tcg_gen_andi_tl(t1, addr, sizem1);
2002 if (!disas_is_bigendian(ctx)) {
2003 tcg_gen_xori_tl(t1, t1, sizem1);
2004 }
2005 tcg_gen_shli_tl(t1, t1, 3);
2006 tcg_gen_andi_tl(t0, addr, ~sizem1);
2007 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2008 tcg_gen_shl_tl(t0, t0, t1);
2009 tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1);
2010 tcg_gen_andc_tl(t1, reg, t1);
2011 tcg_gen_or_tl(reg, t0, t1);
2012 }
2013
2014 /* LWR or LDR, depending on MemOp. */
2015 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr,
2016 int mem_idx, MemOp mop)
2017 {
2018 int size = memop_size(mop);
2019 int sizem1 = size - 1;
2020 TCGv t0 = tcg_temp_new();
2021 TCGv t1 = tcg_temp_new();
2022
2023 /*
2024 * Do a byte access to possibly trigger a page
2025 * fault with the unaligned address.
2026 */
2027 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2028 tcg_gen_andi_tl(t1, addr, sizem1);
2029 if (disas_is_bigendian(ctx)) {
2030 tcg_gen_xori_tl(t1, t1, sizem1);
2031 }
2032 tcg_gen_shli_tl(t1, t1, 3);
2033 tcg_gen_andi_tl(t0, addr, ~sizem1);
2034 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2035 tcg_gen_shr_tl(t0, t0, t1);
2036 tcg_gen_xori_tl(t1, t1, size * 8 - 1);
2037 tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1);
2038 tcg_gen_and_tl(t1, reg, t1);
2039 tcg_gen_or_tl(reg, t0, t1);
2040 }
2041
2042 void gen_lx(DisasContext *ctx, int rd, int base, int index, MemOp mop)
2043 {
2044 TCGv t0 = tcg_temp_new();
2045
2046 gen_base_index_addr(ctx, t0, base, index);
2047 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | mop);
2048 gen_store_gpr(t0, rd);
2049 }
2050
2051 /* Load */
2052 static void gen_ld(DisasContext *ctx, uint32_t opc,
2053 int rt, int base, int offset)
2054 {
2055 TCGv t0, t1;
2056 int mem_idx = ctx->mem_idx;
2057
2058 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2059 INSN_LOONGSON3A)) {
2060 /*
2061 * Loongson CPU uses a load to zero register for prefetch.
2062 * We emulate it as a NOP. On other CPU we must perform the
2063 * actual memory access.
2064 */
2065 return;
2066 }
2067
2068 t0 = tcg_temp_new();
2069 gen_base_offset_addr(ctx, t0, base, offset);
2070
2071 switch (opc) {
2072 #if defined(TARGET_MIPS64)
2073 case OPC_LWU:
2074 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UL |
2075 ctx->default_tcg_memop_mask);
2076 gen_store_gpr(t0, rt);
2077 break;
2078 case OPC_LD:
2079 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ |
2080 ctx->default_tcg_memop_mask);
2081 gen_store_gpr(t0, rt);
2082 break;
2083 case OPC_LLD:
2084 case R6_OPC_LLD:
2085 op_ld_lld(t0, t0, mem_idx, ctx);
2086 gen_store_gpr(t0, rt);
2087 break;
2088 case OPC_LDL:
2089 t1 = tcg_temp_new();
2090 gen_load_gpr(t1, rt);
2091 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2092 gen_store_gpr(t1, rt);
2093 break;
2094 case OPC_LDR:
2095 t1 = tcg_temp_new();
2096 gen_load_gpr(t1, rt);
2097 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2098 gen_store_gpr(t1, rt);
2099 break;
2100 case OPC_LDPC:
2101 t1 = tcg_constant_tl(pc_relative_pc(ctx));
2102 gen_op_addr_add(ctx, t0, t0, t1);
2103 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UQ);
2104 gen_store_gpr(t0, rt);
2105 break;
2106 #endif
2107 case OPC_LWPC:
2108 t1 = tcg_constant_tl(pc_relative_pc(ctx));
2109 gen_op_addr_add(ctx, t0, t0, t1);
2110 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL);
2111 gen_store_gpr(t0, rt);
2112 break;
2113 case OPC_LWE:
2114 mem_idx = MIPS_HFLAG_UM;
2115 /* fall through */
2116 case OPC_LW:
2117 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SL |
2118 ctx->default_tcg_memop_mask);
2119 gen_store_gpr(t0, rt);
2120 break;
2121 case OPC_LHE:
2122 mem_idx = MIPS_HFLAG_UM;
2123 /* fall through */
2124 case OPC_LH:
2125 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_SW |
2126 ctx->default_tcg_memop_mask);
2127 gen_store_gpr(t0, rt);
2128 break;
2129 case OPC_LHUE:
2130 mem_idx = MIPS_HFLAG_UM;
2131 /* fall through */
2132 case OPC_LHU:
2133 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mo_endian(ctx) | MO_UW |
2134 ctx->default_tcg_memop_mask);
2135 gen_store_gpr(t0, rt);
2136 break;
2137 case OPC_LBE:
2138 mem_idx = MIPS_HFLAG_UM;
2139 /* fall through */
2140 case OPC_LB:
2141 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2142 gen_store_gpr(t0, rt);
2143 break;
2144 case OPC_LBUE:
2145 mem_idx = MIPS_HFLAG_UM;
2146 /* fall through */
2147 case OPC_LBU:
2148 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2149 gen_store_gpr(t0, rt);
2150 break;
2151 case OPC_LWLE:
2152 mem_idx = MIPS_HFLAG_UM;
2153 /* fall through */
2154 case OPC_LWL:
2155 t1 = tcg_temp_new();
2156 gen_load_gpr(t1, rt);
2157 gen_lxl(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL);
2158 tcg_gen_ext32s_tl(t1, t1);
2159 gen_store_gpr(t1, rt);
2160 break;
2161 case OPC_LWRE:
2162 mem_idx = MIPS_HFLAG_UM;
2163 /* fall through */
2164 case OPC_LWR:
2165 t1 = tcg_temp_new();
2166 gen_load_gpr(t1, rt);
2167 gen_lxr(ctx, t1, t0, mem_idx, mo_endian(ctx) | MO_UL);
2168 tcg_gen_ext32s_tl(t1, t1);
2169 gen_store_gpr(t1, rt);
2170 break;
2171 case OPC_LLE:
2172 mem_idx = MIPS_HFLAG_UM;
2173 /* fall through */
2174 case OPC_LL:
2175 case R6_OPC_LL:
2176 op_ld_ll(t0, t0, mem_idx, ctx);
2177 gen_store_gpr(t0, rt);
2178 break;
2179 }
2180 }
2181
2182 /* Store */
2183 static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2184 int base, int offset)
2185 {
2186 TCGv t0 = tcg_temp_new();
2187 TCGv t1 = tcg_temp_new();
2188 int mem_idx = ctx->mem_idx;
2189
2190 gen_base_offset_addr(ctx, t0, base, offset);
2191 gen_load_gpr(t1, rt);
2192 switch (opc) {
2193 #if defined(TARGET_MIPS64)
2194 case OPC_SD:
2195 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UQ |
2196 ctx->default_tcg_memop_mask);
2197 break;
2198 case OPC_SDL:
2199 gen_helper_0e2i(sdl, t1, t0, mem_idx);
2200 break;
2201 case OPC_SDR:
2202 gen_helper_0e2i(sdr, t1, t0, mem_idx);
2203 break;
2204 #endif
2205 case OPC_SWE:
2206 mem_idx = MIPS_HFLAG_UM;
2207 /* fall through */
2208 case OPC_SW:
2209 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UL |
2210 ctx->default_tcg_memop_mask);
2211 break;
2212 case OPC_SHE:
2213 mem_idx = MIPS_HFLAG_UM;
2214 /* fall through */
2215 case OPC_SH:
2216 tcg_gen_qemu_st_tl(t1, t0, mem_idx, mo_endian(ctx) | MO_UW |
2217 ctx->default_tcg_memop_mask);
2218 break;
2219 case OPC_SBE:
2220 mem_idx = MIPS_HFLAG_UM;
2221 /* fall through */
2222 case OPC_SB:
2223 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2224 break;
2225 case OPC_SWLE:
2226 mem_idx = MIPS_HFLAG_UM;
2227 /* fall through */
2228 case OPC_SWL:
2229 gen_helper_0e2i(swl, t1, t0, mem_idx);
2230 break;
2231 case OPC_SWRE:
2232 mem_idx = MIPS_HFLAG_UM;
2233 /* fall through */
2234 case OPC_SWR:
2235 gen_helper_0e2i(swr, t1, t0, mem_idx);
2236 break;
2237 }
2238 }
2239
2240
2241 /* Store conditional */
2242 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2243 MemOp tcg_mo, bool eva)
2244 {
2245 TCGv addr, t0, val;
2246 TCGLabel *l1 = gen_new_label();
2247 TCGLabel *done = gen_new_label();
2248
2249 t0 = tcg_temp_new();
2250 addr = tcg_temp_new();
2251 /* compare the address against that of the preceding LL */
2252 gen_base_offset_addr(ctx, addr, base, offset);
2253 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2254 gen_store_gpr(tcg_constant_tl(0), rt);
2255 tcg_gen_br(done);
2256
2257 gen_set_label(l1);
2258 /* generate cmpxchg */
2259 val = tcg_temp_new();
2260 gen_load_gpr(val, rt);
2261 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2262 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2263 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2264 gen_store_gpr(t0, rt);
2265
2266 gen_set_label(done);
2267 }
2268
2269 /* Load and store */
2270 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2271 TCGv t0)
2272 {
2273 /*
2274 * Don't do NOP if destination is zero: we must perform the actual
2275 * memory access.
2276 */
2277 switch (opc) {
2278 case OPC_LWC1:
2279 {
2280 TCGv_i32 fp0 = tcg_temp_new_i32();
2281 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
2282 ctx->default_tcg_memop_mask);
2283 gen_store_fpr32(ctx, fp0, ft);
2284 }
2285 break;
2286 case OPC_SWC1:
2287 {
2288 TCGv_i32 fp0 = tcg_temp_new_i32();
2289 gen_load_fpr32(ctx, fp0, ft);
2290 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
2291 ctx->default_tcg_memop_mask);
2292 }
2293 break;
2294 case OPC_LDC1:
2295 {
2296 TCGv_i64 fp0 = tcg_temp_new_i64();
2297 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
2298 ctx->default_tcg_memop_mask);
2299 gen_store_fpr64(ctx, fp0, ft);
2300 }
2301 break;
2302 case OPC_SDC1:
2303 {
2304 TCGv_i64 fp0 = tcg_temp_new_i64();
2305 gen_load_fpr64(ctx, fp0, ft);
2306 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
2307 ctx->default_tcg_memop_mask);
2308 }
2309 break;
2310 default:
2311 MIPS_INVAL("flt_ldst");
2312 gen_reserved_instruction(ctx);
2313 break;
2314 }
2315 }
2316
2317 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2318 int rs, int16_t imm)
2319 {
2320 TCGv t0 = tcg_temp_new();
2321
2322 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2323 check_cp1_enabled(ctx);
2324 switch (op) {
2325 case OPC_LDC1:
2326 case OPC_SDC1:
2327 check_insn(ctx, ISA_MIPS2);
2328 /* Fallthrough */
2329 default:
2330 gen_base_offset_addr(ctx, t0, rs, imm);
2331 gen_flt_ldst(ctx, op, rt, t0);
2332 }
2333 } else {
2334 generate_exception_err(ctx, EXCP_CpU, 1);
2335 }
2336 }
2337
2338 /* Arithmetic with immediate operand */
2339 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2340 int rt, int rs, int imm)
2341 {
2342 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2343
2344 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2345 /*
2346 * If no destination, treat it as a NOP.
2347 * For addi, we must generate the overflow exception when needed.
2348 */
2349 return;
2350 }
2351 switch (opc) {
2352 case OPC_ADDI:
2353 {
2354 TCGv t0 = tcg_temp_new();
2355 TCGv t1 = tcg_temp_new();
2356 TCGv t2 = tcg_temp_new();
2357 TCGLabel *l1 = gen_new_label();
2358
2359 gen_load_gpr(t1, rs);
2360 tcg_gen_addi_tl(t0, t1, uimm);
2361 tcg_gen_ext32s_tl(t0, t0);
2362
2363 tcg_gen_xori_tl(t1, t1, ~uimm);
2364 tcg_gen_xori_tl(t2, t0, uimm);
2365 tcg_gen_and_tl(t1, t1, t2);
2366 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2367 /* operands of same sign, result different sign */
2368 generate_exception(ctx, EXCP_OVERFLOW);
2369 gen_set_label(l1);
2370 tcg_gen_ext32s_tl(t0, t0);
2371 gen_store_gpr(t0, rt);
2372 }
2373 break;
2374 case OPC_ADDIU:
2375 if (rs != 0) {
2376 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2377 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2378 } else {
2379 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2380 }
2381 break;
2382 #if defined(TARGET_MIPS64)
2383 case OPC_DADDI:
2384 {
2385 TCGv t0 = tcg_temp_new();
2386 TCGv t1 = tcg_temp_new();
2387 TCGv t2 = tcg_temp_new();
2388 TCGLabel *l1 = gen_new_label();
2389
2390 gen_load_gpr(t1, rs);
2391 tcg_gen_addi_tl(t0, t1, uimm);
2392
2393 tcg_gen_xori_tl(t1, t1, ~uimm);
2394 tcg_gen_xori_tl(t2, t0, uimm);
2395 tcg_gen_and_tl(t1, t1, t2);
2396 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2397 /* operands of same sign, result different sign */
2398 generate_exception(ctx, EXCP_OVERFLOW);
2399 gen_set_label(l1);
2400 gen_store_gpr(t0, rt);
2401 }
2402 break;
2403 case OPC_DADDIU:
2404 if (rs != 0) {
2405 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2406 } else {
2407 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2408 }
2409 break;
2410 #endif
2411 }
2412 }
2413
2414 /* Logic with immediate operand */
2415 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2416 int rt, int rs, int16_t imm)
2417 {
2418 target_ulong uimm;
2419
2420 if (rt == 0) {
2421 /* If no destination, treat it as a NOP. */
2422 return;
2423 }
2424 uimm = (uint16_t)imm;
2425 switch (opc) {
2426 case OPC_ANDI:
2427 if (likely(rs != 0)) {
2428 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2429 } else {
2430 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2431 }
2432 break;
2433 case OPC_ORI:
2434 if (rs != 0) {
2435 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2436 } else {
2437 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2438 }
2439 break;
2440 case OPC_XORI:
2441 if (likely(rs != 0)) {
2442 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2443 } else {
2444 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2445 }
2446 break;
2447 case OPC_LUI:
2448 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2449 /* OPC_AUI */
2450 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2451 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2452 } else {
2453 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2454 }
2455 break;
2456
2457 default:
2458 break;
2459 }
2460 }
2461
2462 /* Set on less than with immediate operand */
2463 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2464 int rt, int rs, int16_t imm)
2465 {
2466 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2467 TCGv t0;
2468
2469 if (rt == 0) {
2470 /* If no destination, treat it as a NOP. */
2471 return;
2472 }
2473 t0 = tcg_temp_new();
2474 gen_load_gpr(t0, rs);
2475 switch (opc) {
2476 case OPC_SLTI:
2477 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2478 break;
2479 case OPC_SLTIU:
2480 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2481 break;
2482 }
2483 }
2484
2485 /* Shifts with immediate operand */
2486 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2487 int rt, int rs, int16_t imm)
2488 {
2489 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2490 TCGv t0;
2491
2492 if (rt == 0) {
2493 /* If no destination, treat it as a NOP. */
2494 return;
2495 }
2496
2497 t0 = tcg_temp_new();
2498 gen_load_gpr(t0, rs);
2499 switch (opc) {
2500 case OPC_SLL:
2501 tcg_gen_shli_tl(t0, t0, uimm);
2502 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2503 break;
2504 case OPC_SRA:
2505 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2506 break;
2507 case OPC_SRL:
2508 if (uimm != 0) {
2509 tcg_gen_ext32u_tl(t0, t0);
2510 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2511 } else {
2512 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2513 }
2514 break;
2515 case OPC_ROTR:
2516 if (uimm != 0) {
2517 TCGv_i32 t1 = tcg_temp_new_i32();
2518
2519 tcg_gen_trunc_tl_i32(t1, t0);
2520 tcg_gen_rotri_i32(t1, t1, uimm);
2521 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2522 } else {
2523 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2524 }
2525 break;
2526 #if defined(TARGET_MIPS64)
2527 case OPC_DSLL:
2528 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2529 break;
2530 case OPC_DSRA:
2531 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2532 break;
2533 case OPC_DSRL:
2534 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2535 break;
2536 case OPC_DROTR:
2537 if (uimm != 0) {
2538 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2539 } else {
2540 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2541 }
2542 break;
2543 case OPC_DSLL32:
2544 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2545 break;
2546 case OPC_DSRA32:
2547 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2548 break;
2549 case OPC_DSRL32:
2550 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2551 break;
2552 case OPC_DROTR32:
2553 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2554 break;
2555 #endif
2556 }
2557 }
2558
2559 /* Arithmetic */
2560 static void gen_arith(DisasContext *ctx, uint32_t opc,
2561 int rd, int rs, int rt)
2562 {
2563 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2564 && opc != OPC_DADD && opc != OPC_DSUB) {
2565 /*
2566 * If no destination, treat it as a NOP.
2567 * For add & sub, we must generate the overflow exception when needed.
2568 */
2569 return;
2570 }
2571
2572 switch (opc) {
2573 case OPC_ADD:
2574 {
2575 TCGv t0 = tcg_temp_new();
2576 TCGv t1 = tcg_temp_new();
2577 TCGv t2 = tcg_temp_new();
2578 TCGLabel *l1 = gen_new_label();
2579
2580 gen_load_gpr(t1, rs);
2581 gen_load_gpr(t2, rt);
2582 tcg_gen_add_tl(t0, t1, t2);
2583 tcg_gen_ext32s_tl(t0, t0);
2584 tcg_gen_xor_tl(t1, t1, t2);
2585 tcg_gen_xor_tl(t2, t0, t2);
2586 tcg_gen_andc_tl(t1, t2, t1);
2587 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2588 /* operands of same sign, result different sign */
2589 generate_exception(ctx, EXCP_OVERFLOW);
2590 gen_set_label(l1);
2591 gen_store_gpr(t0, rd);
2592 }
2593 break;
2594 case OPC_ADDU:
2595 if (rs != 0 && rt != 0) {
2596 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2597 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2598 } else if (rs == 0 && rt != 0) {
2599 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2600 } else if (rs != 0 && rt == 0) {
2601 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2602 } else {
2603 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2604 }
2605 break;
2606 case OPC_SUB:
2607 {
2608 TCGv t0 = tcg_temp_new();
2609 TCGv t1 = tcg_temp_new();
2610 TCGv t2 = tcg_temp_new();
2611 TCGLabel *l1 = gen_new_label();
2612
2613 gen_load_gpr(t1, rs);
2614 gen_load_gpr(t2, rt);
2615 tcg_gen_sub_tl(t0, t1, t2);
2616 tcg_gen_ext32s_tl(t0, t0);
2617 tcg_gen_xor_tl(t2, t1, t2);
2618 tcg_gen_xor_tl(t1, t0, t1);
2619 tcg_gen_and_tl(t1, t1, t2);
2620 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2621 /*
2622 * operands of different sign, first operand and the result
2623 * of different sign
2624 */
2625 generate_exception(ctx, EXCP_OVERFLOW);
2626 gen_set_label(l1);
2627 gen_store_gpr(t0, rd);
2628 }
2629 break;
2630 case OPC_SUBU:
2631 if (rs != 0 && rt != 0) {
2632 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2633 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2634 } else if (rs == 0 && rt != 0) {
2635 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2636 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2637 } else if (rs != 0 && rt == 0) {
2638 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2639 } else {
2640 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2641 }
2642 break;
2643 #if defined(TARGET_MIPS64)
2644 case OPC_DADD:
2645 {
2646 TCGv t0 = tcg_temp_new();
2647 TCGv t1 = tcg_temp_new();
2648 TCGv t2 = tcg_temp_new();
2649 TCGLabel *l1 = gen_new_label();
2650
2651 gen_load_gpr(t1, rs);
2652 gen_load_gpr(t2, rt);
2653 tcg_gen_add_tl(t0, t1, t2);
2654 tcg_gen_xor_tl(t1, t1, t2);
2655 tcg_gen_xor_tl(t2, t0, t2);
2656 tcg_gen_andc_tl(t1, t2, t1);
2657 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2658 /* operands of same sign, result different sign */
2659 generate_exception(ctx, EXCP_OVERFLOW);
2660 gen_set_label(l1);
2661 gen_store_gpr(t0, rd);
2662 }
2663 break;
2664 case OPC_DADDU:
2665 if (rs != 0 && rt != 0) {
2666 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2667 } else if (rs == 0 && rt != 0) {
2668 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2669 } else if (rs != 0 && rt == 0) {
2670 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2671 } else {
2672 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2673 }
2674 break;
2675 case OPC_DSUB:
2676 {
2677 TCGv t0 = tcg_temp_new();
2678 TCGv t1 = tcg_temp_new();
2679 TCGv t2 = tcg_temp_new();
2680 TCGLabel *l1 = gen_new_label();
2681
2682 gen_load_gpr(t1, rs);
2683 gen_load_gpr(t2, rt);
2684 tcg_gen_sub_tl(t0, t1, t2);
2685 tcg_gen_xor_tl(t2, t1, t2);
2686 tcg_gen_xor_tl(t1, t0, t1);
2687 tcg_gen_and_tl(t1, t1, t2);
2688 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2689 /*
2690 * Operands of different sign, first operand and result different
2691 * sign.
2692 */
2693 generate_exception(ctx, EXCP_OVERFLOW);
2694 gen_set_label(l1);
2695 gen_store_gpr(t0, rd);
2696 }
2697 break;
2698 case OPC_DSUBU:
2699 if (rs != 0 && rt != 0) {
2700 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2701 } else if (rs == 0 && rt != 0) {
2702 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2703 } else if (rs != 0 && rt == 0) {
2704 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2705 } else {
2706 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2707 }
2708 break;
2709 #endif
2710 case OPC_MUL:
2711 if (likely(rs != 0 && rt != 0)) {
2712 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2713 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2714 } else {
2715 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2716 }
2717 break;
2718 }
2719 }
2720
2721 /* Conditional move */
2722 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2723 int rd, int rs, int rt)
2724 {
2725 TCGv t0, t1, t2;
2726
2727 if (rd == 0) {
2728 /* If no destination, treat it as a NOP. */
2729 return;
2730 }
2731
2732 t0 = tcg_temp_new();
2733 gen_load_gpr(t0, rt);
2734 t1 = tcg_constant_tl(0);
2735 t2 = tcg_temp_new();
2736 gen_load_gpr(t2, rs);
2737 switch (opc) {
2738 case OPC_MOVN:
2739 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2740 break;
2741 case OPC_MOVZ:
2742 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2743 break;
2744 case OPC_SELNEZ:
2745 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2746 break;
2747 case OPC_SELEQZ:
2748 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2749 break;
2750 }
2751 }
2752
2753 /* Logic */
2754 static void gen_logic(DisasContext *ctx, uint32_t opc,
2755 int rd, int rs, int rt)
2756 {
2757 if (rd == 0) {
2758 /* If no destination, treat it as a NOP. */
2759 return;
2760 }
2761
2762 switch (opc) {
2763 case OPC_AND:
2764 if (likely(rs != 0 && rt != 0)) {
2765 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2766 } else {
2767 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2768 }
2769 break;
2770 case OPC_NOR:
2771 if (rs != 0 && rt != 0) {
2772 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2773 } else if (rs == 0 && rt != 0) {
2774 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2775 } else if (rs != 0 && rt == 0) {
2776 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2777 } else {
2778 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2779 }
2780 break;
2781 case OPC_OR:
2782 if (likely(rs != 0 && rt != 0)) {
2783 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2784 } else if (rs == 0 && rt != 0) {
2785 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2786 } else if (rs != 0 && rt == 0) {
2787 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2788 } else {
2789 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2790 }
2791 break;
2792 case OPC_XOR:
2793 if (likely(rs != 0 && rt != 0)) {
2794 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2795 } else if (rs == 0 && rt != 0) {
2796 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2797 } else if (rs != 0 && rt == 0) {
2798 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2799 } else {
2800 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2801 }
2802 break;
2803 }
2804 }
2805
2806 /* Set on lower than */
2807 static void gen_slt(DisasContext *ctx, uint32_t opc,
2808 int rd, int rs, int rt)
2809 {
2810 TCGv t0, t1;
2811
2812 if (rd == 0) {
2813 /* If no destination, treat it as a NOP. */
2814 return;
2815 }
2816
2817 t0 = tcg_temp_new();
2818 t1 = tcg_temp_new();
2819 gen_load_gpr(t0, rs);
2820 gen_load_gpr(t1, rt);
2821 switch (opc) {
2822 case OPC_SLT:
2823 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2824 break;
2825 case OPC_SLTU:
2826 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2827 break;
2828 }
2829 }
2830
2831 /* Shifts */
2832 static void gen_shift(DisasContext *ctx, uint32_t opc,
2833 int rd, int rs, int rt)
2834 {
2835 TCGv t0, t1;
2836
2837 if (rd == 0) {
2838 /*
2839 * If no destination, treat it as a NOP.
2840 * For add & sub, we must generate the overflow exception when needed.
2841 */
2842 return;
2843 }
2844
2845 t0 = tcg_temp_new();
2846 t1 = tcg_temp_new();
2847 gen_load_gpr(t0, rs);
2848 gen_load_gpr(t1, rt);
2849 switch (opc) {
2850 case OPC_SLLV:
2851 tcg_gen_andi_tl(t0, t0, 0x1f);
2852 tcg_gen_shl_tl(t0, t1, t0);
2853 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2854 break;
2855 case OPC_SRAV:
2856 tcg_gen_andi_tl(t0, t0, 0x1f);
2857 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2858 break;
2859 case OPC_SRLV:
2860 tcg_gen_ext32u_tl(t1, t1);
2861 tcg_gen_andi_tl(t0, t0, 0x1f);
2862 tcg_gen_shr_tl(t0, t1, t0);
2863 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2864 break;
2865 case OPC_ROTRV:
2866 {
2867 TCGv_i32 t2 = tcg_temp_new_i32();
2868 TCGv_i32 t3 = tcg_temp_new_i32();
2869
2870 tcg_gen_trunc_tl_i32(t2, t0);
2871 tcg_gen_trunc_tl_i32(t3, t1);
2872 tcg_gen_andi_i32(t2, t2, 0x1f);
2873 tcg_gen_rotr_i32(t2, t3, t2);
2874 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2875 }
2876 break;
2877 #if defined(TARGET_MIPS64)
2878 case OPC_DSLLV:
2879 tcg_gen_andi_tl(t0, t0, 0x3f);
2880 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2881 break;
2882 case OPC_DSRAV:
2883 tcg_gen_andi_tl(t0, t0, 0x3f);
2884 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2885 break;
2886 case OPC_DSRLV:
2887 tcg_gen_andi_tl(t0, t0, 0x3f);
2888 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2889 break;
2890 case OPC_DROTRV:
2891 tcg_gen_andi_tl(t0, t0, 0x3f);
2892 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2893 break;
2894 #endif
2895 }
2896 }
2897
2898 /* Arithmetic on HI/LO registers */
2899 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2900 {
2901 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2902 /* Treat as NOP. */
2903 return;
2904 }
2905
2906 if (acc != 0) {
2907 check_dsp(ctx);
2908 }
2909
2910 switch (opc) {
2911 case OPC_MFHI:
2912 #if defined(TARGET_MIPS64)
2913 if (acc != 0) {
2914 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2915 } else
2916 #endif
2917 {
2918 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2919 }
2920 break;
2921 case OPC_MFLO:
2922 #if defined(TARGET_MIPS64)
2923 if (acc != 0) {
2924 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2925 } else
2926 #endif
2927 {
2928 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2929 }
2930 break;
2931 case OPC_MTHI:
2932 if (reg != 0) {
2933 #if defined(TARGET_MIPS64)
2934 if (acc != 0) {
2935 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2936 } else
2937 #endif
2938 {
2939 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2940 }
2941 } else {
2942 tcg_gen_movi_tl(cpu_HI[acc], 0);
2943 }
2944 break;
2945 case OPC_MTLO:
2946 if (reg != 0) {
2947 #if defined(TARGET_MIPS64)
2948 if (acc != 0) {
2949 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2950 } else
2951 #endif
2952 {
2953 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2954 }
2955 } else {
2956 tcg_gen_movi_tl(cpu_LO[acc], 0);
2957 }
2958 break;
2959 }
2960 }
2961
2962 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
2963 MemOp memop)
2964 {
2965 TCGv t0 = tcg_temp_new();
2966 tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop);
2967 gen_store_gpr(t0, reg);
2968 }
2969
2970 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
2971 int rs)
2972 {
2973 target_long offset;
2974 target_long addr;
2975
2976 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
2977 case OPC_ADDIUPC:
2978 if (rs != 0) {
2979 offset = sextract32(ctx->opcode << 2, 0, 21);
2980 addr = addr_add(ctx, pc, offset);
2981 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2982 }
2983 break;
2984 case R6_OPC_LWPC:
2985 offset = sextract32(ctx->opcode << 2, 0, 21);
2986 addr = addr_add(ctx, pc, offset);
2987 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_SL);
2988 break;
2989 #if defined(TARGET_MIPS64)
2990 case OPC_LWUPC:
2991 check_mips_64(ctx);
2992 offset = sextract32(ctx->opcode << 2, 0, 21);
2993 addr = addr_add(ctx, pc, offset);
2994 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UL);
2995 break;
2996 #endif
2997 default:
2998 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
2999 case OPC_AUIPC:
3000 if (rs != 0) {
3001 offset = sextract32(ctx->opcode, 0, 16) << 16;
3002 addr = addr_add(ctx, pc, offset);
3003 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3004 }
3005 break;
3006 case OPC_ALUIPC:
3007 if (rs != 0) {
3008 offset = sextract32(ctx->opcode, 0, 16) << 16;
3009 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3010 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3011 }
3012 break;
3013 #if defined(TARGET_MIPS64)
3014 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3015 case R6_OPC_LDPC + (1 << 16):
3016 case R6_OPC_LDPC + (2 << 16):
3017 case R6_OPC_LDPC + (3 << 16):
3018 check_mips_64(ctx);
3019 offset = sextract32(ctx->opcode << 3, 0, 21);
3020 addr = addr_add(ctx, (pc & ~0x7), offset);
3021 gen_r6_ld(addr, rs, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
3022 break;
3023 #endif
3024 default:
3025 MIPS_INVAL("OPC_PCREL");
3026 gen_reserved_instruction(ctx);
3027 break;
3028 }
3029 break;
3030 }
3031 }
3032
3033 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3034 {
3035 TCGv t0, t1;
3036
3037 if (rd == 0) {
3038 /* Treat as NOP. */
3039 return;
3040 }
3041
3042 t0 = tcg_temp_new();
3043 t1 = tcg_temp_new();
3044
3045 gen_load_gpr(t0, rs);
3046 gen_load_gpr(t1, rt);
3047
3048 switch (opc) {
3049 case R6_OPC_DIV:
3050 {
3051 TCGv t2 = tcg_temp_new();
3052 TCGv t3 = tcg_temp_new();
3053 tcg_gen_ext32s_tl(t0, t0);
3054 tcg_gen_ext32s_tl(t1, t1);
3055 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3056 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3057 tcg_gen_and_tl(t2, t2, t3);
3058 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3059 tcg_gen_or_tl(t2, t2, t3);
3060 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3061 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3062 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3063 }
3064 break;
3065 case R6_OPC_MOD:
3066 {
3067 TCGv t2 = tcg_temp_new();
3068 TCGv t3 = tcg_temp_new();
3069 tcg_gen_ext32s_tl(t0, t0);
3070 tcg_gen_ext32s_tl(t1, t1);
3071 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3072 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3073 tcg_gen_and_tl(t2, t2, t3);
3074 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3075 tcg_gen_or_tl(t2, t2, t3);
3076 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3077 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3078 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3079 }
3080 break;
3081 case R6_OPC_DIVU:
3082 {
3083 tcg_gen_ext32u_tl(t0, t0);
3084 tcg_gen_ext32u_tl(t1, t1);
3085 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3086 tcg_constant_tl(0), tcg_constant_tl(1), t1);
3087 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3088 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3089 }
3090 break;
3091 case R6_OPC_MODU:
3092 {
3093 tcg_gen_ext32u_tl(t0, t0);
3094 tcg_gen_ext32u_tl(t1, t1);
3095 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3096 tcg_constant_tl(0), tcg_constant_tl(1), t1);
3097 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3098 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3099 }
3100 break;
3101 case R6_OPC_MUL:
3102 {
3103 TCGv_i32 t2 = tcg_temp_new_i32();
3104 TCGv_i32 t3 = tcg_temp_new_i32();
3105 tcg_gen_trunc_tl_i32(t2, t0);
3106 tcg_gen_trunc_tl_i32(t3, t1);
3107 tcg_gen_mul_i32(t2, t2, t3);
3108 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3109 }
3110 break;
3111 case R6_OPC_MUH:
3112 {
3113 TCGv_i32 t2 = tcg_temp_new_i32();
3114 TCGv_i32 t3 = tcg_temp_new_i32();
3115 tcg_gen_trunc_tl_i32(t2, t0);
3116 tcg_gen_trunc_tl_i32(t3, t1);
3117 tcg_gen_muls2_i32(t2, t3, t2, t3);
3118 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3119 }
3120 break;
3121 case R6_OPC_MULU:
3122 {
3123 TCGv_i32 t2 = tcg_temp_new_i32();
3124 TCGv_i32 t3 = tcg_temp_new_i32();
3125 tcg_gen_trunc_tl_i32(t2, t0);
3126 tcg_gen_trunc_tl_i32(t3, t1);
3127 tcg_gen_mul_i32(t2, t2, t3);
3128 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3129 }
3130 break;
3131 case R6_OPC_MUHU:
3132 {
3133 TCGv_i32 t2 = tcg_temp_new_i32();
3134 TCGv_i32 t3 = tcg_temp_new_i32();
3135 tcg_gen_trunc_tl_i32(t2, t0);
3136 tcg_gen_trunc_tl_i32(t3, t1);
3137 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3138 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3139 }
3140 break;
3141 #if defined(TARGET_MIPS64)
3142 case R6_OPC_DDIV:
3143 {
3144 TCGv t2 = tcg_temp_new();
3145 TCGv t3 = tcg_temp_new();
3146 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3147 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3148 tcg_gen_and_tl(t2, t2, t3);
3149 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3150 tcg_gen_or_tl(t2, t2, t3);
3151 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3152 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3153 }
3154 break;
3155 case R6_OPC_DMOD:
3156 {
3157 TCGv t2 = tcg_temp_new();
3158 TCGv t3 = tcg_temp_new();
3159 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3160 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3161 tcg_gen_and_tl(t2, t2, t3);
3162 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3163 tcg_gen_or_tl(t2, t2, t3);
3164 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3165 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3166 }
3167 break;
3168 case R6_OPC_DDIVU:
3169 {
3170 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3171 tcg_constant_tl(0), tcg_constant_tl(1), t1);
3172 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3173 }
3174 break;
3175 case R6_OPC_DMODU:
3176 {
3177 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3178 tcg_constant_tl(0), tcg_constant_tl(1), t1);
3179 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3180 }
3181 break;
3182 case R6_OPC_DMUL:
3183 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3184 break;
3185 case R6_OPC_DMUH:
3186 {
3187 TCGv t2 = tcg_temp_new();
3188 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3189 }
3190 break;
3191 case R6_OPC_DMULU:
3192 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3193 break;
3194 case R6_OPC_DMUHU:
3195 {
3196 TCGv t2 = tcg_temp_new();
3197 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3198 }
3199 break;
3200 #endif
3201 default:
3202 MIPS_INVAL("r6 mul/div");
3203 gen_reserved_instruction(ctx);
3204 break;
3205 }
3206 }
3207
3208 #if defined(TARGET_MIPS64)
3209 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3210 {
3211 TCGv t0, t1;
3212
3213 t0 = tcg_temp_new();
3214 t1 = tcg_temp_new();
3215
3216 gen_load_gpr(t0, rs);
3217 gen_load_gpr(t1, rt);
3218
3219 switch (opc) {
3220 case MMI_OPC_DIV1:
3221 {
3222 TCGv t2 = tcg_temp_new();
3223 TCGv t3 = tcg_temp_new();
3224 tcg_gen_ext32s_tl(t0, t0);
3225 tcg_gen_ext32s_tl(t1, t1);
3226 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3227 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3228 tcg_gen_and_tl(t2, t2, t3);
3229 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3230 tcg_gen_or_tl(t2, t2, t3);
3231 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3232 tcg_gen_div_tl(cpu_LO[1], t0, t1);
3233 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3234 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3235 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3236 }
3237 break;
3238 case MMI_OPC_DIVU1:
3239 {
3240 TCGv t2 = tcg_constant_tl(0);
3241 TCGv t3 = tcg_constant_tl(1);
3242 tcg_gen_ext32u_tl(t0, t0);
3243 tcg_gen_ext32u_tl(t1, t1);
3244 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3245 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3246 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3247 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3248 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3249 }
3250 break;
3251 default:
3252 MIPS_INVAL("div1 TX79");
3253 gen_reserved_instruction(ctx);
3254 break;
3255 }
3256 }
3257 #endif
3258
3259 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3260 int acc, int rs, int rt)
3261 {
3262 TCGv t0, t1;
3263
3264 t0 = tcg_temp_new();
3265 t1 = tcg_temp_new();
3266
3267 gen_load_gpr(t0, rs);
3268 gen_load_gpr(t1, rt);
3269
3270 if (acc != 0) {
3271 check_dsp(ctx);
3272 }
3273
3274 switch (opc) {
3275 case OPC_DIV:
3276 {
3277 TCGv t2 = tcg_temp_new();
3278 TCGv t3 = tcg_temp_new();
3279 tcg_gen_ext32s_tl(t0, t0);
3280 tcg_gen_ext32s_tl(t1, t1);
3281 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3282 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3283 tcg_gen_and_tl(t2, t2, t3);
3284 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3285 tcg_gen_or_tl(t2, t2, t3);
3286 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3287 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3288 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3289 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3290 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3291 }
3292 break;
3293 case OPC_DIVU:
3294 {
3295 TCGv t2 = tcg_constant_tl(0);
3296 TCGv t3 = tcg_constant_tl(1);
3297 tcg_gen_ext32u_tl(t0, t0);
3298 tcg_gen_ext32u_tl(t1, t1);
3299 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3300 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3301 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3302 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3303 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3304 }
3305 break;
3306 case OPC_MULT:
3307 {
3308 TCGv_i32 t2 = tcg_temp_new_i32();
3309 TCGv_i32 t3 = tcg_temp_new_i32();
3310 tcg_gen_trunc_tl_i32(t2, t0);
3311 tcg_gen_trunc_tl_i32(t3, t1);
3312 tcg_gen_muls2_i32(t2, t3, t2, t3);
3313 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3314 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3315 }
3316 break;
3317 case OPC_MULTU:
3318 {
3319 TCGv_i32 t2 = tcg_temp_new_i32();
3320 TCGv_i32 t3 = tcg_temp_new_i32();
3321 tcg_gen_trunc_tl_i32(t2, t0);
3322 tcg_gen_trunc_tl_i32(t3, t1);
3323 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3324 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3325 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3326 }
3327 break;
3328 #if defined(TARGET_MIPS64)
3329 case OPC_DDIV:
3330 {
3331 TCGv t2 = tcg_temp_new();
3332 TCGv t3 = tcg_temp_new();
3333 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3334 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3335 tcg_gen_and_tl(t2, t2, t3);
3336 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3337 tcg_gen_or_tl(t2, t2, t3);
3338 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, tcg_constant_tl(0), t2, t1);
3339 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3340 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3341 }
3342 break;
3343 case OPC_DDIVU:
3344 {
3345 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1,
3346 tcg_constant_tl(0), tcg_constant_tl(1), t1);
3347 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3348 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3349 }
3350 break;
3351 case OPC_DMULT:
3352 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3353 break;
3354 case OPC_DMULTU:
3355 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3356 break;
3357 #endif
3358 case OPC_MADD:
3359 {
3360 TCGv_i64 t2 = tcg_temp_new_i64();
3361 TCGv_i64 t3 = tcg_temp_new_i64();
3362
3363 tcg_gen_ext_tl_i64(t2, t0);
3364 tcg_gen_ext_tl_i64(t3, t1);
3365 tcg_gen_mul_i64(t2, t2, t3);
3366 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3367 tcg_gen_add_i64(t2, t2, t3);
3368 gen_move_low32(cpu_LO[acc], t2);
3369 gen_move_high32(cpu_HI[acc], t2);
3370 }
3371 break;
3372 case OPC_MADDU:
3373 {
3374 TCGv_i64 t2 = tcg_temp_new_i64();
3375 TCGv_i64 t3 = tcg_temp_new_i64();
3376
3377 tcg_gen_ext32u_tl(t0, t0);
3378 tcg_gen_ext32u_tl(t1, t1);
3379 tcg_gen_extu_tl_i64(t2, t0);
3380 tcg_gen_extu_tl_i64(t3, t1);
3381 tcg_gen_mul_i64(t2, t2, t3);
3382 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3383 tcg_gen_add_i64(t2, t2, t3);
3384 gen_move_low32(cpu_LO[acc], t2);
3385 gen_move_high32(cpu_HI[acc], t2);
3386 }
3387 break;
3388 case OPC_MSUB:
3389 {
3390 TCGv_i64 t2 = tcg_temp_new_i64();
3391 TCGv_i64 t3 = tcg_temp_new_i64();
3392
3393 tcg_gen_ext_tl_i64(t2, t0);
3394 tcg_gen_ext_tl_i64(t3, t1);
3395 tcg_gen_mul_i64(t2, t2, t3);
3396 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3397 tcg_gen_sub_i64(t2, t3, t2);
3398 gen_move_low32(cpu_LO[acc], t2);
3399 gen_move_high32(cpu_HI[acc], t2);
3400 }
3401 break;
3402 case OPC_MSUBU:
3403 {
3404 TCGv_i64 t2 = tcg_temp_new_i64();
3405 TCGv_i64 t3 = tcg_temp_new_i64();
3406
3407 tcg_gen_ext32u_tl(t0, t0);
3408 tcg_gen_ext32u_tl(t1, t1);
3409 tcg_gen_extu_tl_i64(t2, t0);
3410 tcg_gen_extu_tl_i64(t3, t1);
3411 tcg_gen_mul_i64(t2, t2, t3);
3412 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3413 tcg_gen_sub_i64(t2, t3, t2);
3414 gen_move_low32(cpu_LO[acc], t2);
3415 gen_move_high32(cpu_HI[acc], t2);
3416 }
3417 break;
3418 default:
3419 MIPS_INVAL("mul/div");
3420 gen_reserved_instruction(ctx);
3421 break;
3422 }
3423 }
3424
3425 /*
3426 * These MULT[U] and MADD[U] instructions implemented in for example
3427 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3428 * architectures are special three-operand variants with the syntax
3429 *
3430 * MULT[U][1] rd, rs, rt
3431 *
3432 * such that
3433 *
3434 * (rd, LO, HI) <- rs * rt
3435 *
3436 * and
3437 *
3438 * MADD[U][1] rd, rs, rt
3439 *
3440 * such that
3441 *
3442 * (rd, LO, HI) <- (LO, HI) + rs * rt
3443 *
3444 * where the low-order 32-bits of the result is placed into both the
3445 * GPR rd and the special register LO. The high-order 32-bits of the
3446 * result is placed into the special register HI.
3447 *
3448 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3449 * which is the zero register that always reads as 0.
3450 */
3451 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3452 int rd, int rs, int rt)
3453 {
3454 TCGv t0 = tcg_temp_new();
3455 TCGv t1 = tcg_temp_new();
3456 int acc = 0;
3457
3458 gen_load_gpr(t0, rs);
3459 gen_load_gpr(t1, rt);
3460
3461 switch (opc) {
3462 case MMI_OPC_MULT1:
3463 acc = 1;
3464 /* Fall through */
3465 case OPC_MULT:
3466 {
3467 TCGv_i32 t2 = tcg_temp_new_i32();
3468 TCGv_i32 t3 = tcg_temp_new_i32();
3469 tcg_gen_trunc_tl_i32(t2, t0);
3470 tcg_gen_trunc_tl_i32(t3, t1);
3471 tcg_gen_muls2_i32(t2, t3, t2, t3);
3472 if (rd) {
3473 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3474 }
3475 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3476 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3477 }
3478 break;
3479 case MMI_OPC_MULTU1:
3480 acc = 1;
3481 /* Fall through */
3482 case OPC_MULTU:
3483 {
3484 TCGv_i32 t2 = tcg_temp_new_i32();
3485 TCGv_i32 t3 = tcg_temp_new_i32();
3486 tcg_gen_trunc_tl_i32(t2, t0);
3487 tcg_gen_trunc_tl_i32(t3, t1);
3488 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3489 if (rd) {
3490 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3491 }
3492 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3493 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3494 }
3495 break;
3496 case MMI_OPC_MADD1:
3497 acc = 1;
3498 /* Fall through */
3499 case MMI_OPC_MADD:
3500 {
3501 TCGv_i64 t2 = tcg_temp_new_i64();
3502 TCGv_i64 t3 = tcg_temp_new_i64();
3503
3504 tcg_gen_ext_tl_i64(t2, t0);
3505 tcg_gen_ext_tl_i64(t3, t1);
3506 tcg_gen_mul_i64(t2, t2, t3);
3507 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3508 tcg_gen_add_i64(t2, t2, t3);
3509 gen_move_low32(cpu_LO[acc], t2);
3510 gen_move_high32(cpu_HI[acc], t2);
3511 if (rd) {
3512 gen_move_low32(cpu_gpr[rd], t2);
3513 }
3514 }
3515 break;
3516 case MMI_OPC_MADDU1:
3517 acc = 1;
3518 /* Fall through */
3519 case MMI_OPC_MADDU:
3520 {
3521 TCGv_i64 t2 = tcg_temp_new_i64();
3522 TCGv_i64 t3 = tcg_temp_new_i64();
3523
3524 tcg_gen_ext32u_tl(t0, t0);
3525 tcg_gen_ext32u_tl(t1, t1);
3526 tcg_gen_extu_tl_i64(t2, t0);
3527 tcg_gen_extu_tl_i64(t3, t1);
3528 tcg_gen_mul_i64(t2, t2, t3);
3529 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3530 tcg_gen_add_i64(t2, t2, t3);
3531 gen_move_low32(cpu_LO[acc], t2);
3532 gen_move_high32(cpu_HI[acc], t2);
3533 if (rd) {
3534 gen_move_low32(cpu_gpr[rd], t2);
3535 }
3536 }
3537 break;
3538 default:
3539 MIPS_INVAL("mul/madd TXx9");
3540 gen_reserved_instruction(ctx);
3541 break;
3542 }
3543 }
3544
3545 static void gen_cl(DisasContext *ctx, uint32_t opc,
3546 int rd, int rs)
3547 {
3548 TCGv t0;
3549
3550 if (rd == 0) {
3551 /* Treat as NOP. */
3552 return;
3553 }
3554 t0 = cpu_gpr[rd];
3555 gen_load_gpr(t0, rs);
3556
3557 switch (opc) {
3558 case OPC_CLO:
3559 case R6_OPC_CLO:
3560 #if defined(TARGET_MIPS64)
3561 case OPC_DCLO:
3562 case R6_OPC_DCLO:
3563 #endif
3564 tcg_gen_not_tl(t0, t0);
3565 break;
3566 }
3567
3568 switch (opc) {
3569 case OPC_CLO:
3570 case R6_OPC_CLO:
3571 case OPC_CLZ:
3572 case R6_OPC_CLZ:
3573 tcg_gen_ext32u_tl(t0, t0);
3574 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3575 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3576 break;
3577 #if defined(TARGET_MIPS64)
3578 case OPC_DCLO:
3579 case R6_OPC_DCLO:
3580 case OPC_DCLZ:
3581 case R6_OPC_DCLZ:
3582 tcg_gen_clzi_i64(t0, t0, 64);
3583 break;
3584 #endif
3585 }
3586 }
3587
3588 /* Loongson multimedia instructions */
3589 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3590 {
3591 uint32_t opc, shift_max;
3592 TCGv_i64 t0, t1;
3593 TCGCond cond;
3594
3595 opc = MASK_LMMI(ctx->opcode);
3596 check_cp1_enabled(ctx);
3597
3598 t0 = tcg_temp_new_i64();
3599 t1 = tcg_temp_new_i64();
3600 gen_load_fpr64(ctx, t0, rs);
3601 gen_load_fpr64(ctx, t1, rt);
3602
3603 switch (opc) {
3604 case OPC_PADDSH:
3605 gen_helper_paddsh(t0, t0, t1);
3606 break;
3607 case OPC_PADDUSH:
3608 gen_helper_paddush(t0, t0, t1);
3609 break;
3610 case OPC_PADDH:
3611 gen_helper_paddh(t0, t0, t1);
3612 break;
3613 case OPC_PADDW:
3614 gen_helper_paddw(t0, t0, t1);
3615 break;
3616 case OPC_PADDSB:
3617 gen_helper_paddsb(t0, t0, t1);
3618 break;
3619 case OPC_PADDUSB:
3620 gen_helper_paddusb(t0, t0, t1);
3621 break;
3622 case OPC_PADDB:
3623 gen_helper_paddb(t0, t0, t1);
3624 break;
3625
3626 case OPC_PSUBSH:
3627 gen_helper_psubsh(t0, t0, t1);
3628 break;
3629 case OPC_PSUBUSH:
3630 gen_helper_psubush(t0, t0, t1);
3631 break;
3632 case OPC_PSUBH:
3633 gen_helper_psubh(t0, t0, t1);
3634 break;
3635 case OPC_PSUBW:
3636 gen_helper_psubw(t0, t0, t1);
3637 break;
3638 case OPC_PSUBSB:
3639 gen_helper_psubsb(t0, t0, t1);
3640 break;
3641 case OPC_PSUBUSB:
3642 gen_helper_psubusb(t0, t0, t1);
3643 break;
3644 case OPC_PSUBB:
3645 gen_helper_psubb(t0, t0, t1);
3646 break;
3647
3648 case OPC_PSHUFH:
3649 gen_helper_pshufh(t0, t0, t1);
3650 break;
3651 case OPC_PACKSSWH:
3652 gen_helper_packsswh(t0, t0, t1);
3653 break;
3654 case OPC_PACKSSHB:
3655 gen_helper_packsshb(t0, t0, t1);
3656 break;
3657 case OPC_PACKUSHB:
3658 gen_helper_packushb(t0, t0, t1);
3659 break;
3660
3661 case OPC_PUNPCKLHW:
3662 gen_helper_punpcklhw(t0, t0, t1);
3663 break;
3664 case OPC_PUNPCKHHW:
3665 gen_helper_punpckhhw(t0, t0, t1);
3666 break;
3667 case OPC_PUNPCKLBH:
3668 gen_helper_punpcklbh(t0, t0, t1);
3669 break;
3670 case OPC_PUNPCKHBH:
3671 gen_helper_punpckhbh(t0, t0, t1);
3672 break;
3673 case OPC_PUNPCKLWD:
3674 gen_helper_punpcklwd(t0, t0, t1);
3675 break;
3676 case OPC_PUNPCKHWD:
3677 gen_helper_punpckhwd(t0, t0, t1);
3678 break;
3679
3680 case OPC_PAVGH:
3681 gen_helper_pavgh(t0, t0, t1);
3682 break;
3683 case OPC_PAVGB:
3684 gen_helper_pavgb(t0, t0, t1);
3685 break;
3686 case OPC_PMAXSH:
3687 gen_helper_pmaxsh(t0, t0, t1);
3688 break;
3689 case OPC_PMINSH:
3690 gen_helper_pminsh(t0, t0, t1);
3691 break;
3692 case OPC_PMAXUB:
3693 gen_helper_pmaxub(t0, t0, t1);
3694 break;
3695 case OPC_PMINUB:
3696 gen_helper_pminub(t0, t0, t1);
3697 break;
3698
3699 case OPC_PCMPEQW:
3700 gen_helper_pcmpeqw(t0, t0, t1);
3701 break;
3702 case OPC_PCMPGTW:
3703 gen_helper_pcmpgtw(t0, t0, t1);
3704 break;
3705 case OPC_PCMPEQH:
3706 gen_helper_pcmpeqh(t0, t0, t1);
3707 break;
3708 case OPC_PCMPGTH:
3709 gen_helper_pcmpgth(t0, t0, t1);
3710 break;
3711 case OPC_PCMPEQB:
3712 gen_helper_pcmpeqb(t0, t0, t1);
3713 break;
3714 case OPC_PCMPGTB:
3715 gen_helper_pcmpgtb(t0, t0, t1);
3716 break;
3717
3718 case OPC_PSLLW:
3719 gen_helper_psllw(t0, t0, t1);
3720 break;
3721 case OPC_PSLLH:
3722 gen_helper_psllh(t0, t0, t1);
3723 break;
3724 case OPC_PSRLW:
3725 gen_helper_psrlw(t0, t0, t1);
3726 break;
3727 case OPC_PSRLH:
3728 gen_helper_psrlh(t0, t0, t1);
3729 break;
3730 case OPC_PSRAW:
3731 gen_helper_psraw(t0, t0, t1);
3732 break;
3733 case OPC_PSRAH:
3734 gen_helper_psrah(t0, t0, t1);
3735 break;
3736
3737 case OPC_PMULLH:
3738 gen_helper_pmullh(t0, t0, t1);
3739 break;
3740 case OPC_PMULHH:
3741 gen_helper_pmulhh(t0, t0, t1);
3742 break;
3743 case OPC_PMULHUH:
3744 gen_helper_pmulhuh(t0, t0, t1);
3745 break;
3746 case OPC_PMADDHW:
3747 gen_helper_pmaddhw(t0, t0, t1);
3748 break;
3749
3750 case OPC_PASUBUB:
3751 gen_helper_pasubub(t0, t0, t1);
3752 break;
3753 case OPC_BIADD:
3754 gen_helper_biadd(t0, t0);
3755 break;
3756 case OPC_PMOVMSKB:
3757 gen_helper_pmovmskb(t0, t0);
3758 break;
3759
3760 case OPC_PADDD:
3761 tcg_gen_add_i64(t0, t0, t1);
3762 break;
3763 case OPC_PSUBD:
3764 tcg_gen_sub_i64(t0, t0, t1);
3765 break;
3766 case OPC_XOR_CP2:
3767 tcg_gen_xor_i64(t0, t0, t1);
3768 break;
3769 case OPC_NOR_CP2:
3770 tcg_gen_nor_i64(t0, t0, t1);
3771 break;
3772 case OPC_AND_CP2:
3773 tcg_gen_and_i64(t0, t0, t1);
3774 break;
3775 case OPC_OR_CP2:
3776 tcg_gen_or_i64(t0, t0, t1);
3777 break;
3778
3779 case OPC_PANDN:
3780 tcg_gen_andc_i64(t0, t1, t0);
3781 break;
3782
3783 case OPC_PINSRH_0:
3784 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3785 break;
3786 case OPC_PINSRH_1:
3787 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3788 break;
3789 case OPC_PINSRH_2:
3790 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3791 break;
3792 case OPC_PINSRH_3:
3793 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3794 break;
3795
3796 case OPC_PEXTRH:
3797 tcg_gen_andi_i64(t1, t1, 3);
3798 tcg_gen_shli_i64(t1, t1, 4);
3799 tcg_gen_shr_i64(t0, t0, t1);
3800 tcg_gen_ext16u_i64(t0, t0);
3801 break;
3802
3803 case OPC_ADDU_CP2:
3804 tcg_gen_add_i64(t0, t0, t1);
3805 tcg_gen_ext32s_i64(t0, t0);
3806 break;
3807 case OPC_SUBU_CP2:
3808 tcg_gen_sub_i64(t0, t0, t1);
3809 tcg_gen_ext32s_i64(t0, t0);
3810 break;
3811
3812 case OPC_SLL_CP2:
3813 shift_max = 32;
3814 goto do_shift;
3815 case OPC_SRL_CP2:
3816 shift_max = 32;
3817 goto do_shift;
3818 case OPC_SRA_CP2:
3819 shift_max = 32;
3820 goto do_shift;
3821 case OPC_DSLL_CP2:
3822 shift_max = 64;
3823 goto do_shift;
3824 case OPC_DSRL_CP2:
3825 shift_max = 64;
3826 goto do_shift;
3827 case OPC_DSRA_CP2:
3828 shift_max = 64;
3829 goto do_shift;
3830 do_shift:
3831 /* Make sure shift count isn't TCG undefined behaviour. */
3832 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3833
3834 switch (opc) {
3835 case OPC_SLL_CP2:
3836 case OPC_DSLL_CP2:
3837 tcg_gen_shl_i64(t0, t0, t1);
3838 break;
3839 case OPC_SRA_CP2:
3840 case OPC_DSRA_CP2:
3841 /*
3842 * Since SRA is UndefinedResult without sign-extended inputs,
3843 * we can treat SRA and DSRA the same.
3844 */
3845 tcg_gen_sar_i64(t0, t0, t1);
3846 break;
3847 case OPC_SRL_CP2:
3848 /* We want to shift in zeros for SRL; zero-extend first. */
3849 tcg_gen_ext32u_i64(t0, t0);
3850 /* FALLTHRU */
3851 case OPC_DSRL_CP2:
3852 tcg_gen_shr_i64(t0, t0, t1);
3853 break;
3854 }
3855
3856 if (shift_max == 32) {
3857 tcg_gen_ext32s_i64(t0, t0);
3858 }
3859
3860 /* Shifts larger than MAX produce zero. */
3861 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3862 tcg_gen_neg_i64(t1, t1);
3863 tcg_gen_and_i64(t0, t0, t1);
3864 break;
3865
3866 case OPC_ADD_CP2:
3867 case OPC_DADD_CP2:
3868 {
3869 TCGv_i64 t2 = tcg_temp_new_i64();
3870 TCGLabel *lab = gen_new_label();
3871
3872 tcg_gen_mov_i64(t2, t0);
3873 tcg_gen_add_i64(t0, t1, t2);
3874 if (opc == OPC_ADD_CP2) {
3875 tcg_gen_ext32s_i64(t0, t0);
3876 }
3877 tcg_gen_xor_i64(t1, t1, t2);
3878 tcg_gen_xor_i64(t2, t2, t0);
3879 tcg_gen_andc_i64(t1, t2, t1);
3880 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3881 generate_exception(ctx, EXCP_OVERFLOW);
3882 gen_set_label(lab);
3883 break;
3884 }
3885
3886 case OPC_SUB_CP2:
3887 case OPC_DSUB_CP2:
3888 {
3889 TCGv_i64 t2 = tcg_temp_new_i64();
3890 TCGLabel *lab = gen_new_label();
3891
3892 tcg_gen_mov_i64(t2, t0);
3893 tcg_gen_sub_i64(t0, t1, t2);
3894 if (opc == OPC_SUB_CP2) {
3895 tcg_gen_ext32s_i64(t0, t0);
3896 }
3897 tcg_gen_xor_i64(t1, t1, t2);
3898 tcg_gen_xor_i64(t2, t2, t0);
3899 tcg_gen_and_i64(t1, t1, t2);
3900 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3901 generate_exception(ctx, EXCP_OVERFLOW);
3902 gen_set_label(lab);
3903 break;
3904 }
3905
3906 case OPC_PMULUW:
3907 tcg_gen_ext32u_i64(t0, t0);
3908 tcg_gen_ext32u_i64(t1, t1);
3909 tcg_gen_mul_i64(t0, t0, t1);
3910 break;
3911
3912 case OPC_SEQU_CP2:
3913 case OPC_SEQ_CP2:
3914 cond = TCG_COND_EQ;
3915 goto do_cc_cond;
3916 break;
3917 case OPC_SLTU_CP2:
3918 cond = TCG_COND_LTU;
3919 goto do_cc_cond;
3920 break;
3921 case OPC_SLT_CP2:
3922 cond = TCG_COND_LT;
3923 goto do_cc_cond;
3924 break;
3925 case OPC_SLEU_CP2:
3926 cond = TCG_COND_LEU;
3927 goto do_cc_cond;
3928 break;
3929 case OPC_SLE_CP2:
3930 cond = TCG_COND_LE;
3931 do_cc_cond:
3932 {
3933 int cc = (ctx->opcode >> 8) & 0x7;
3934 TCGv_i64 t64 = tcg_temp_new_i64();
3935 TCGv_i32 t32 = tcg_temp_new_i32();
3936
3937 tcg_gen_setcond_i64(cond, t64, t0, t1);
3938 tcg_gen_extrl_i64_i32(t32, t64);
3939 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
3940 get_fp_bit(cc), 1);
3941 }
3942 return;
3943 default:
3944 MIPS_INVAL("loongson_cp2");
3945 gen_reserved_instruction(ctx);
3946 return;
3947 }
3948
3949 gen_store_fpr64(ctx, t0, rd);
3950 }
3951
3952 static void gen_loongson_lswc2(DisasContext *ctx, int rt,
3953 int rs, int rd)
3954 {
3955 TCGv t0, t1;
3956 TCGv_i32 fp0;
3957 #if defined(TARGET_MIPS64)
3958 int lsq_rt1 = ctx->opcode & 0x1f;
3959 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
3960 #endif
3961 int shf_offset = sextract32(ctx->opcode, 6, 8);
3962
3963 t0 = tcg_temp_new();
3964
3965 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
3966 #if defined(TARGET_MIPS64)
3967 case OPC_GSLQ:
3968 t1 = tcg_temp_new();
3969 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3970 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3971 ctx->default_tcg_memop_mask);
3972 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3973 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3974 ctx->default_tcg_memop_mask);
3975 gen_store_gpr(t1, rt);
3976 gen_store_gpr(t0, lsq_rt1);
3977 break;
3978 case OPC_GSLQC1:
3979 check_cp1_enabled(ctx);
3980 t1 = tcg_temp_new();
3981 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3982 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3983 ctx->default_tcg_memop_mask);
3984 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3985 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3986 ctx->default_tcg_memop_mask);
3987 gen_store_fpr64(ctx, t1, rt);
3988 gen_store_fpr64(ctx, t0, lsq_rt1);
3989 break;
3990 case OPC_GSSQ:
3991 t1 = tcg_temp_new();
3992 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
3993 gen_load_gpr(t1, rt);
3994 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3995 ctx->default_tcg_memop_mask);
3996 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
3997 gen_load_gpr(t1, lsq_rt1);
3998 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
3999 ctx->default_tcg_memop_mask);
4000 break;
4001 case OPC_GSSQC1:
4002 check_cp1_enabled(ctx);
4003 t1 = tcg_temp_new();
4004 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4005 gen_load_fpr64(ctx, t1, rt);
4006 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4007 ctx->default_tcg_memop_mask);
4008 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4009 gen_load_fpr64(ctx, t1, lsq_rt1);
4010 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4011 ctx->default_tcg_memop_mask);
4012 break;
4013 #endif
4014 case OPC_GSSHFL:
4015 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4016 case OPC_GSLWLC1:
4017 check_cp1_enabled(ctx);
4018 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4019 fp0 = tcg_temp_new_i32();
4020 gen_load_fpr32(ctx, fp0, rt);
4021 t1 = tcg_temp_new();
4022 tcg_gen_ext_i32_tl(t1, fp0);
4023 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
4024 tcg_gen_trunc_tl_i32(fp0, t1);
4025 gen_store_fpr32(ctx, fp0, rt);
4026 break;
4027 case OPC_GSLWRC1:
4028 check_cp1_enabled(ctx);
4029 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4030 fp0 = tcg_temp_new_i32();
4031 gen_load_fpr32(ctx, fp0, rt);
4032 t1 = tcg_temp_new();
4033 tcg_gen_ext_i32_tl(t1, fp0);
4034 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL);
4035 tcg_gen_trunc_tl_i32(fp0, t1);
4036 gen_store_fpr32(ctx, fp0, rt);
4037 break;
4038 #if defined(TARGET_MIPS64)
4039 case OPC_GSLDLC1:
4040 check_cp1_enabled(ctx);
4041 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4042 t1 = tcg_temp_new();
4043 gen_load_fpr64(ctx, t1, rt);
4044 gen_lxl(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
4045 gen_store_fpr64(ctx, t1, rt);
4046 break;
4047 case OPC_GSLDRC1:
4048 check_cp1_enabled(ctx);
4049 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4050 t1 = tcg_temp_new();
4051 gen_load_fpr64(ctx, t1, rt);
4052 gen_lxr(ctx, t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ);
4053 gen_store_fpr64(ctx, t1, rt);
4054 break;
4055 #endif
4056 default:
4057 MIPS_INVAL("loongson_gsshfl");
4058 gen_reserved_instruction(ctx);
4059 break;
4060 }
4061 break;
4062 case OPC_GSSHFS:
4063 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4064 case OPC_GSSWLC1:
4065 check_cp1_enabled(ctx);
4066 t1 = tcg_temp_new();
4067 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4068 fp0 = tcg_temp_new_i32();
4069 gen_load_fpr32(ctx, fp0, rt);
4070 tcg_gen_ext_i32_tl(t1, fp0);
4071 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4072 break;
4073 case OPC_GSSWRC1:
4074 check_cp1_enabled(ctx);
4075 t1 = tcg_temp_new();
4076 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4077 fp0 = tcg_temp_new_i32();
4078 gen_load_fpr32(ctx, fp0, rt);
4079 tcg_gen_ext_i32_tl(t1, fp0);
4080 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4081 break;
4082 #if defined(TARGET_MIPS64)
4083 case OPC_GSSDLC1:
4084 check_cp1_enabled(ctx);
4085 t1 = tcg_temp_new();
4086 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4087 gen_load_fpr64(ctx, t1, rt);
4088 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4089 break;
4090 case OPC_GSSDRC1:
4091 check_cp1_enabled(ctx);
4092 t1 = tcg_temp_new();
4093 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4094 gen_load_fpr64(ctx, t1, rt);
4095 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4096 break;
4097 #endif
4098 default:
4099 MIPS_INVAL("loongson_gsshfs");
4100 gen_reserved_instruction(ctx);
4101 break;
4102 }
4103 break;
4104 default:
4105 MIPS_INVAL("loongson_gslsq");
4106 gen_reserved_instruction(ctx);
4107 break;
4108 }
4109 }
4110
4111 /* Loongson EXT LDC2/SDC2 */
4112 static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4113 int rs, int rd)
4114 {
4115 int offset = sextract32(ctx->opcode, 3, 8);
4116 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4117 TCGv t0, t1;
4118 TCGv_i32 fp0;
4119
4120 /* Pre-conditions */
4121 switch (opc) {
4122 case OPC_GSLBX:
4123 case OPC_GSLHX:
4124 case OPC_GSLWX:
4125 case OPC_GSLDX:
4126 /* prefetch, implement as NOP */
4127 if (rt == 0) {
4128 return;
4129 }
4130 break;
4131 case OPC_GSSBX:
4132 case OPC_GSSHX:
4133 case OPC_GSSWX:
4134 case OPC_GSSDX:
4135 break;
4136 case OPC_GSLWXC1:
4137 #if defined(TARGET_MIPS64)
4138 case OPC_GSLDXC1:
4139 #endif
4140 check_cp1_enabled(ctx);
4141 /* prefetch, implement as NOP */
4142 if (rt == 0) {
4143 return;
4144 }
4145 break;
4146 case OPC_GSSWXC1:
4147 #if defined(TARGET_MIPS64)
4148 case OPC_GSSDXC1:
4149 #endif
4150 check_cp1_enabled(ctx);
4151 break;
4152 default:
4153 MIPS_INVAL("loongson_lsdc2");
4154 gen_reserved_instruction(ctx);
4155 return;
4156 break;
4157 }
4158
4159 t0 = tcg_temp_new();
4160
4161 gen_base_offset_addr(ctx, t0, rs, offset);
4162 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4163
4164 switch (opc) {
4165 case OPC_GSLBX:
4166 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4167 gen_store_gpr(t0, rt);
4168 break;
4169 case OPC_GSLHX:
4170 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SW |
4171 ctx->default_tcg_memop_mask);
4172 gen_store_gpr(t0, rt);
4173 break;
4174 case OPC_GSLWX:
4175 gen_base_offset_addr(ctx, t0, rs, offset);
4176 if (rd) {
4177 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4178 }
4179 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
4180 ctx->default_tcg_memop_mask);
4181 gen_store_gpr(t0, rt);
4182 break;
4183 #if defined(TARGET_MIPS64)
4184 case OPC_GSLDX:
4185 gen_base_offset_addr(ctx, t0, rs, offset);
4186 if (rd) {
4187 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4188 }
4189 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4190 ctx->default_tcg_memop_mask);
4191 gen_store_gpr(t0, rt);
4192 break;
4193 #endif
4194 case OPC_GSLWXC1:
4195 gen_base_offset_addr(ctx, t0, rs, offset);
4196 if (rd) {
4197 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4198 }
4199 fp0 = tcg_temp_new_i32();
4200 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_SL |
4201 ctx->default_tcg_memop_mask);
4202 gen_store_fpr32(ctx, fp0, rt);
4203 break;
4204 #if defined(TARGET_MIPS64)
4205 case OPC_GSLDXC1:
4206 gen_base_offset_addr(ctx, t0, rs, offset);
4207 if (rd) {
4208 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4209 }
4210 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4211 ctx->default_tcg_memop_mask);
4212 gen_store_fpr64(ctx, t0, rt);
4213 break;
4214 #endif
4215 case OPC_GSSBX:
4216 t1 = tcg_temp_new();
4217 gen_load_gpr(t1, rt);
4218 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4219 break;
4220 case OPC_GSSHX:
4221 t1 = tcg_temp_new();
4222 gen_load_gpr(t1, rt);
4223 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UW |
4224 ctx->default_tcg_memop_mask);
4225 break;
4226 case OPC_GSSWX:
4227 t1 = tcg_temp_new();
4228 gen_load_gpr(t1, rt);
4229 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
4230 ctx->default_tcg_memop_mask);
4231 break;
4232 #if defined(TARGET_MIPS64)
4233 case OPC_GSSDX:
4234 t1 = tcg_temp_new();
4235 gen_load_gpr(t1, rt);
4236 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4237 ctx->default_tcg_memop_mask);
4238 break;
4239 #endif
4240 case OPC_GSSWXC1:
4241 fp0 = tcg_temp_new_i32();
4242 gen_load_fpr32(ctx, fp0, rt);
4243 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, mo_endian(ctx) | MO_UL |
4244 ctx->default_tcg_memop_mask);
4245 break;
4246 #if defined(TARGET_MIPS64)
4247 case OPC_GSSDXC1:
4248 t1 = tcg_temp_new();
4249 gen_load_fpr64(ctx, t1, rt);
4250 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, mo_endian(ctx) | MO_UQ |
4251 ctx->default_tcg_memop_mask);
4252 break;
4253 #endif
4254 default:
4255 break;
4256 }
4257 }
4258
4259 /* Traps */
4260 static void gen_trap(DisasContext *ctx, uint32_t opc,
4261 int rs, int rt, int16_t imm, int code)
4262 {
4263 int cond;
4264 TCGv t0 = tcg_temp_new();
4265 TCGv t1 = tcg_temp_new();
4266
4267 cond = 0;
4268 /* Load needed operands */
4269 switch (opc) {
4270 case OPC_TEQ:
4271 case OPC_TGE:
4272 case OPC_TGEU:
4273 case OPC_TLT:
4274 case OPC_TLTU:
4275 case OPC_TNE:
4276 /* Compare two registers */
4277 if (rs != rt) {
4278 gen_load_gpr(t0, rs);
4279 gen_load_gpr(t1, rt);
4280 cond = 1;
4281 }
4282 break;
4283 case OPC_TEQI:
4284 case OPC_TGEI:
4285 case OPC_TGEIU:
4286 case OPC_TLTI:
4287 case OPC_TLTIU:
4288 case OPC_TNEI:
4289 /* Compare register to immediate */
4290 if (rs != 0 || imm != 0) {
4291 gen_load_gpr(t0, rs);
4292 tcg_gen_movi_tl(t1, (int32_t)imm);
4293 cond = 1;
4294 }
4295 break;
4296 }
4297 if (cond == 0) {
4298 switch (opc) {
4299 case OPC_TEQ: /* rs == rs */
4300 case OPC_TEQI: /* r0 == 0 */
4301 case OPC_TGE: /* rs >= rs */
4302 case OPC_TGEI: /* r0 >= 0 */
4303 case OPC_TGEU: /* rs >= rs unsigned */
4304 case OPC_TGEIU: /* r0 >= 0 unsigned */
4305 /* Always trap */
4306 #ifdef CONFIG_USER_ONLY
4307 /* Pass the break code along to cpu_loop. */
4308 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4309 offsetof(CPUMIPSState, error_code));
4310 #endif
4311 generate_exception_end(ctx, EXCP_TRAP);
4312 break;
4313 case OPC_TLT: /* rs < rs */
4314 case OPC_TLTI: /* r0 < 0 */
4315 case OPC_TLTU: /* rs < rs unsigned */
4316 case OPC_TLTIU: /* r0 < 0 unsigned */
4317 case OPC_TNE: /* rs != rs */
4318 case OPC_TNEI: /* r0 != 0 */
4319 /* Never trap: treat as NOP. */
4320 break;
4321 }
4322 } else {
4323 TCGLabel *l1 = gen_new_label();
4324
4325 switch (opc) {
4326 case OPC_TEQ:
4327 case OPC_TEQI:
4328 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4329 break;
4330 case OPC_TGE:
4331 case OPC_TGEI:
4332 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4333 break;
4334 case OPC_TGEU:
4335 case OPC_TGEIU:
4336 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4337 break;
4338 case OPC_TLT:
4339 case OPC_TLTI:
4340 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4341 break;
4342 case OPC_TLTU:
4343 case OPC_TLTIU:
4344 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4345 break;
4346 case OPC_TNE:
4347 case OPC_TNEI:
4348 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4349 break;
4350 }
4351 #ifdef CONFIG_USER_ONLY
4352 /* Pass the break code along to cpu_loop. */
4353 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4354 offsetof(CPUMIPSState, error_code));
4355 #endif
4356 /* Like save_cpu_state, only don't update saved values. */
4357 if (ctx->base.pc_next != ctx->saved_pc) {
4358 gen_save_pc(ctx->base.pc_next);
4359 }
4360 if (ctx->hflags != ctx->saved_hflags) {
4361 tcg_gen_movi_i32(hflags, ctx->hflags);
4362 }
4363 generate_exception(ctx, EXCP_TRAP);
4364 gen_set_label(l1);
4365 }
4366 }
4367
4368 static void gen_goto_tb(DisasContext *ctx, unsigned tb_slot_idx,
4369 target_ulong dest)
4370 {
4371 if (translator_use_goto_tb(&ctx->base, dest)) {
4372 tcg_gen_goto_tb(tb_slot_idx);
4373 gen_save_pc(dest);
4374 tcg_gen_exit_tb(ctx->base.tb, tb_slot_idx);
4375 } else {
4376 gen_save_pc(dest);
4377 tcg_gen_lookup_and_goto_ptr();
4378 }
4379 }
4380
4381 /* Branches (before delay slot) */
4382 static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4383 int insn_bytes,
4384 int rs, int rt, int32_t offset,
4385 int delayslot_size)
4386 {
4387 target_ulong btgt = -1;
4388 int blink = 0;
4389 int bcond_compute = 0;
4390 TCGv t0 = tcg_temp_new();
4391 TCGv t1 = tcg_temp_new();
4392
4393 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4394 #ifdef MIPS_DEBUG_DISAS
4395 LOG_DISAS("Branch in delay / forbidden slot at PC 0x%016"
4396 VADDR_PRIx "\n", ctx->base.pc_next);
4397 #endif
4398 gen_reserved_instruction(ctx);
4399 goto out;
4400 }
4401
4402 /* Load needed operands */
4403 switch (opc) {
4404 case OPC_BEQ:
4405 case OPC_BEQL:
4406 case OPC_BNE:
4407 case OPC_BNEL:
4408 /* Compare two registers */
4409 if (rs != rt) {
4410 gen_load_gpr(t0, rs);
4411 gen_load_gpr(t1, rt);
4412 bcond_compute = 1;
4413 }
4414 btgt = ctx->base.pc_next + insn_bytes + offset;
4415 break;
4416 case OPC_BGEZ:
4417 case OPC_BGEZAL:
4418 case OPC_BGEZALL:
4419 case OPC_BGEZL:
4420 case OPC_BGTZ:
4421 case OPC_BGTZL:
4422 case OPC_BLEZ:
4423 case OPC_BLEZL:
4424 case OPC_BLTZ:
4425 case OPC_BLTZAL:
4426 case OPC_BLTZALL:
4427 case OPC_BLTZL:
4428 /* Compare to zero */
4429 if (rs != 0) {
4430 gen_load_gpr(t0, rs);
4431 bcond_compute = 1;
4432 }
4433 btgt = ctx->base.pc_next + insn_bytes + offset;
4434 break;
4435 case OPC_BPOSGE32:
4436 #if defined(TARGET_MIPS64)
4437 case OPC_BPOSGE64:
4438 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4439 #else
4440 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4441 #endif
4442 bcond_compute = 1;
4443 btgt = ctx->base.pc_next + insn_bytes + offset;
4444 break;
4445 case OPC_J:
4446 case OPC_JAL:
4447 {
4448 /* Jump to immediate */
4449 int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000
4450 : 0xF0000000;
4451 btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask)
4452 | (uint32_t)offset;
4453 break;
4454 }
4455 case OPC_JALX:
4456 /* Jump to immediate */
4457 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4458 (uint32_t)offset;
4459 break;
4460 case OPC_JR:
4461 case OPC_JALR:
4462 /* Jump to register */
4463 if (offset != 0 && offset != 16) {
4464 /*
4465 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4466 * others are reserved.
4467 */
4468 MIPS_INVAL("jump hint");
4469 gen_reserved_instruction(ctx);
4470 goto out;
4471 }
4472 gen_load_gpr(btarget, rs);
4473 break;
4474 default:
4475 MIPS_INVAL("branch/jump");
4476 gen_reserved_instruction(ctx);
4477 goto out;
4478 }
4479 if (bcond_compute == 0) {
4480 /* No condition to be computed */
4481 switch (opc) {
4482 case OPC_BEQ: /* rx == rx */
4483 case OPC_BEQL: /* rx == rx likely */
4484 case OPC_BGEZ: /* 0 >= 0 */
4485 case OPC_BGEZL: /* 0 >= 0 likely */
4486 case OPC_BLEZ: /* 0 <= 0 */
4487 case OPC_BLEZL: /* 0 <= 0 likely */
4488 /* Always take */
4489 ctx->hflags |= MIPS_HFLAG_B;
4490 break;
4491 case OPC_BGEZAL: /* 0 >= 0 */
4492 case OPC_BGEZALL: /* 0 >= 0 likely */
4493 /* Always take and link */
4494 blink = 31;
4495 ctx->hflags |= MIPS_HFLAG_B;
4496 break;
4497 case OPC_BNE: /* rx != rx */
4498 case OPC_BGTZ: /* 0 > 0 */
4499 case OPC_BLTZ: /* 0 < 0 */
4500 /* Treat as NOP. */
4501 goto out;
4502 case OPC_BLTZAL: /* 0 < 0 */
4503 /*
4504 * Handle as an unconditional branch to get correct delay
4505 * slot checking.
4506 */
4507 blink = 31;
4508 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4509 ctx->hflags |= MIPS_HFLAG_B;
4510 break;
4511 case OPC_BLTZALL: /* 0 < 0 likely */
4512 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4513 /* Skip the instruction in the delay slot */
4514 ctx->base.pc_next += 4;
4515 goto out;
4516 case OPC_BNEL: /* rx != rx likely */
4517 case OPC_BGTZL: /* 0 > 0 likely */
4518 case OPC_BLTZL: /* 0 < 0 likely */
4519 /* Skip the instruction in the delay slot */
4520 ctx->base.pc_next += 4;
4521 goto out;
4522 case OPC_J:
4523 ctx->hflags |= MIPS_HFLAG_B;
4524 break;
4525 case OPC_JALX:
4526 ctx->hflags |= MIPS_HFLAG_BX;
4527 /* Fallthrough */
4528 case OPC_JAL:
4529 blink = 31;
4530 ctx->hflags |= MIPS_HFLAG_B;
4531 break;
4532 case OPC_JR:
4533 ctx->hflags |= MIPS_HFLAG_BR;
4534 break;
4535 case OPC_JALR:
4536 blink = rt;
4537 ctx->hflags |= MIPS_HFLAG_BR;
4538 break;
4539 default:
4540 MIPS_INVAL("branch/jump");
4541 gen_reserved_instruction(ctx);
4542 goto out;
4543 }
4544 } else {
4545 switch (opc) {
4546 case OPC_BEQ:
4547 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4548 goto not_likely;
4549 case OPC_BEQL:
4550 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4551 goto likely;
4552 case OPC_BNE:
4553 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4554 goto not_likely;
4555 case OPC_BNEL:
4556 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4557 goto likely;
4558 case OPC_BGEZ:
4559 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4560 goto not_likely;
4561 case OPC_BGEZL:
4562 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4563 goto likely;
4564 case OPC_BGEZAL:
4565 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4566 blink = 31;
4567 goto not_likely;
4568 case OPC_BGEZALL:
4569 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4570 blink = 31;
4571 goto likely;
4572 case OPC_BGTZ:
4573 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4574 goto not_likely;
4575 case OPC_BGTZL:
4576 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4577 goto likely;
4578 case OPC_BLEZ:
4579 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4580 goto not_likely;
4581 case OPC_BLEZL:
4582 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4583 goto likely;
4584 case OPC_BLTZ:
4585 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4586 goto not_likely;
4587 case OPC_BLTZL:
4588 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4589 goto likely;
4590 case OPC_BPOSGE32:
4591 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4592 goto not_likely;
4593 #if defined(TARGET_MIPS64)
4594 case OPC_BPOSGE64:
4595 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4596 goto not_likely;
4597 #endif
4598 case OPC_BLTZAL:
4599 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4600 blink = 31;
4601 not_likely:
4602 ctx->hflags |= MIPS_HFLAG_BC;
4603 break;
4604 case OPC_BLTZALL:
4605 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4606 blink = 31;
4607 likely:
4608 ctx->hflags |= MIPS_HFLAG_BL;
4609 break;
4610 default:
4611 MIPS_INVAL("conditional branch/jump");
4612 gen_reserved_instruction(ctx);
4613 goto out;
4614 }
4615 }
4616
4617 ctx->btarget = btgt;
4618
4619 switch (delayslot_size) {
4620 case 2:
4621 ctx->hflags |= MIPS_HFLAG_BDS16;
4622 break;
4623 case 4:
4624 ctx->hflags |= MIPS_HFLAG_BDS32;
4625 break;
4626 }
4627
4628 if (blink > 0) {
4629 int post_delay = insn_bytes + delayslot_size;
4630 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4631
4632 tcg_gen_movi_tl(cpu_gpr[blink],
4633 ctx->base.pc_next + post_delay + lowbit);
4634 }
4635
4636 out:
4637 if (insn_bytes == 2) {
4638 ctx->hflags |= MIPS_HFLAG_B16;
4639 }
4640 }
4641
4642
4643 /* special3 bitfield operations */
4644 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
4645 int rs, int lsb, int msb)
4646 {
4647 TCGv t0 = tcg_temp_new();
4648 TCGv t1 = tcg_temp_new();
4649
4650 gen_load_gpr(t1, rs);
4651 switch (opc) {
4652 case OPC_EXT:
4653 if (lsb + msb > 31) {
4654 goto fail;
4655 }
4656 if (msb != 31) {
4657 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4658 } else {
4659 /*
4660 * The two checks together imply that lsb == 0,
4661 * so this is a simple sign-extension.
4662 */
4663 tcg_gen_ext32s_tl(t0, t1);
4664 }
4665 break;
4666 #if defined(TARGET_MIPS64)
4667 case OPC_DEXTU:
4668 lsb += 32;
4669 goto do_dext;
4670 case OPC_DEXTM:
4671 msb += 32;
4672 goto do_dext;
4673 case OPC_DEXT:
4674 do_dext:
4675 if (lsb + msb > 63) {
4676 goto fail;
4677 }
4678 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4679 break;
4680 #endif
4681 case OPC_INS:
4682 if (lsb > msb) {
4683 goto fail;
4684 }
4685 gen_load_gpr(t0, rt);
4686 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4687 tcg_gen_ext32s_tl(t0, t0);
4688 break;
4689 #if defined(TARGET_MIPS64)
4690 case OPC_DINSU:
4691 lsb += 32;
4692 /* FALLTHRU */
4693 case OPC_DINSM:
4694 msb += 32;
4695 /* FALLTHRU */
4696 case OPC_DINS:
4697 if (lsb > msb) {
4698 goto fail;
4699 }
4700 gen_load_gpr(t0, rt);
4701 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4702 break;
4703 #endif
4704 default:
4705 fail:
4706 MIPS_INVAL("bitops");
4707 gen_reserved_instruction(ctx);
4708 return;
4709 }
4710 gen_store_gpr(t0, rt);
4711 }
4712
4713 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
4714 {
4715 TCGv t0;
4716
4717 if (rd == 0) {
4718 /* If no destination, treat it as a NOP. */
4719 return;
4720 }
4721
4722 t0 = tcg_temp_new();
4723 gen_load_gpr(t0, rt);
4724 switch (op2) {
4725 case OPC_WSBH:
4726 {
4727 TCGv t1 = tcg_temp_new();
4728 TCGv t2 = tcg_constant_tl(0x00FF00FF);
4729
4730 tcg_gen_shri_tl(t1, t0, 8);
4731 tcg_gen_and_tl(t1, t1, t2);
4732 tcg_gen_and_tl(t0, t0, t2);
4733 tcg_gen_shli_tl(t0, t0, 8);
4734 tcg_gen_or_tl(t0, t0, t1);
4735 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4736 }
4737 break;
4738 case OPC_SEB:
4739 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4740 break;
4741 case OPC_SEH:
4742 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4743 break;
4744 #if defined(TARGET_MIPS64)
4745 case OPC_DSBH:
4746 {
4747 TCGv t1 = tcg_temp_new();
4748 TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL);
4749
4750 tcg_gen_shri_tl(t1, t0, 8);
4751 tcg_gen_and_tl(t1, t1, t2);
4752 tcg_gen_and_tl(t0, t0, t2);
4753 tcg_gen_shli_tl(t0, t0, 8);
4754 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4755 }
4756 break;
4757 case OPC_DSHD:
4758 {
4759 TCGv t1 = tcg_temp_new();
4760 TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL);
4761
4762 tcg_gen_shri_tl(t1, t0, 16);
4763 tcg_gen_and_tl(t1, t1, t2);
4764 tcg_gen_and_tl(t0, t0, t2);
4765 tcg_gen_shli_tl(t0, t0, 16);
4766 tcg_gen_or_tl(t0, t0, t1);
4767 tcg_gen_shri_tl(t1, t0, 32);
4768 tcg_gen_shli_tl(t0, t0, 32);
4769 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4770 }
4771 break;
4772 #endif
4773 default:
4774 MIPS_INVAL("bsfhl");
4775 gen_reserved_instruction(ctx);
4776 return;
4777 }
4778 }
4779
4780 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
4781 int rt, int bits)
4782 {
4783 TCGv t0;
4784 if (rd == 0) {
4785 /* Treat as NOP. */
4786 return;
4787 }
4788 t0 = tcg_temp_new();
4789 if (bits == 0 || bits == wordsz) {
4790 if (bits == 0) {
4791 gen_load_gpr(t0, rt);
4792 } else {
4793 gen_load_gpr(t0, rs);
4794 }
4795 switch (wordsz) {
4796 case 32:
4797 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4798 break;
4799 #if defined(TARGET_MIPS64)
4800 case 64:
4801 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4802 break;
4803 #endif
4804 }
4805 } else {
4806 TCGv t1 = tcg_temp_new();
4807 gen_load_gpr(t0, rt);
4808 gen_load_gpr(t1, rs);
4809 switch (wordsz) {
4810 case 32:
4811 {
4812 TCGv_i64 t2 = tcg_temp_new_i64();
4813 tcg_gen_concat_tl_i64(t2, t1, t0);
4814 tcg_gen_shri_i64(t2, t2, 32 - bits);
4815 gen_move_low32(cpu_gpr[rd], t2);
4816 }
4817 break;
4818 #if defined(TARGET_MIPS64)
4819 case 64:
4820 tcg_gen_shli_tl(t0, t0, bits);
4821 tcg_gen_shri_tl(t1, t1, 64 - bits);
4822 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4823 break;
4824 #endif
4825 }
4826 }
4827 }
4828
4829 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
4830 {
4831 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
4832 }
4833
4834 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4835 {
4836 TCGv t0;
4837 if (rd == 0) {
4838 /* Treat as NOP. */
4839 return;
4840 }
4841 t0 = tcg_temp_new();
4842 gen_load_gpr(t0, rt);
4843 switch (opc) {
4844 case OPC_BITSWAP:
4845 gen_helper_bitswap(cpu_gpr[rd], t0);
4846 break;
4847 #if defined(TARGET_MIPS64)
4848 case OPC_DBITSWAP:
4849 gen_helper_dbitswap(cpu_gpr[rd], t0);
4850 break;
4851 #endif
4852 }
4853 }
4854
4855 #ifndef CONFIG_USER_ONLY
4856 /* CP0 (MMU and control) */
4857 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4858 {
4859 TCGv_i64 t0 = tcg_temp_new_i64();
4860 TCGv_i64 t1 = tcg_temp_new_i64();
4861
4862 tcg_gen_ext_tl_i64(t0, arg);
4863 tcg_gen_ld_i64(t1, tcg_env, off);
4864 #if defined(TARGET_MIPS64)
4865 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4866 #else
4867 tcg_gen_concat32_i64(t1, t1, t0);
4868 #endif
4869 tcg_gen_st_i64(t1, tcg_env, off);
4870 }
4871
4872 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4873 {
4874 TCGv_i64 t0 = tcg_temp_new_i64();
4875 TCGv_i64 t1 = tcg_temp_new_i64();
4876
4877 tcg_gen_ext_tl_i64(t0, arg);
4878 tcg_gen_ld_i64(t1, tcg_env, off);
4879 tcg_gen_concat32_i64(t1, t1, t0);
4880 tcg_gen_st_i64(t1, tcg_env, off);
4881 }
4882
4883 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4884 {
4885 TCGv_i64 t0 = tcg_temp_new_i64();
4886
4887 tcg_gen_ld_i64(t0, tcg_env, off);
4888 #if defined(TARGET_MIPS64)
4889 tcg_gen_shri_i64(t0, t0, 30);
4890 #else
4891 tcg_gen_shri_i64(t0, t0, 32);
4892 #endif
4893 gen_move_low32(arg, t0);
4894 }
4895
4896 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4897 {
4898 TCGv_i64 t0 = tcg_temp_new_i64();
4899
4900 tcg_gen_ld_i64(t0, tcg_env, off);
4901 tcg_gen_shri_i64(t0, t0, 32 + shift);
4902 gen_move_low32(arg, t0);
4903 }
4904
4905 static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
4906 {
4907 TCGv_i32 t0 = tcg_temp_new_i32();
4908
4909 tcg_gen_ld_i32(t0, tcg_env, off);
4910 tcg_gen_ext_i32_tl(arg, t0);
4911 }
4912
4913 static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
4914 {
4915 tcg_gen_ld_tl(arg, tcg_env, off);
4916 tcg_gen_ext32s_tl(arg, arg);
4917 }
4918
4919 static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
4920 {
4921 TCGv_i32 t0 = tcg_temp_new_i32();
4922
4923 tcg_gen_trunc_tl_i32(t0, arg);
4924 tcg_gen_st_i32(t0, tcg_env, off);
4925 }
4926
4927 #define CP0_CHECK(c) \
4928 do { \
4929 if (!(c)) { \
4930 goto cp0_unimplemented; \
4931 } \
4932 } while (0)
4933
4934 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4935 {
4936 const char *register_name = "invalid";
4937
4938 switch (reg) {
4939 case CP0_REGISTER_02:
4940 switch (sel) {
4941 case 0:
4942 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4943 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4944 register_name = "EntryLo0";
4945 break;
4946 default:
4947 goto cp0_unimplemented;
4948 }
4949 break;
4950 case CP0_REGISTER_03:
4951 switch (sel) {
4952 case CP0_REG03__ENTRYLO1:
4953 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4954 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4955 register_name = "EntryLo1";
4956 break;
4957 default:
4958 goto cp0_unimplemented;
4959 }
4960 break;
4961 case CP0_REGISTER_17:
4962 switch (sel) {
4963 case CP0_REG17__LLADDR:
4964 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
4965 ctx->CP0_LLAddr_shift);
4966 register_name = "LLAddr";
4967 break;
4968 case CP0_REG17__MAAR:
4969 CP0_CHECK(ctx->mrp);
4970 gen_helper_mfhc0_maar(arg, tcg_env);
4971 register_name = "MAAR";
4972 break;
4973 default:
4974 goto cp0_unimplemented;
4975 }
4976 break;
4977 case CP0_REGISTER_19:
4978 switch (sel) {
4979 case CP0_REG19__WATCHHI0:
4980 case CP0_REG19__WATCHHI1:
4981 case CP0_REG19__WATCHHI2:
4982 case CP0_REG19__WATCHHI3:
4983 case CP0_REG19__WATCHHI4:
4984 case CP0_REG19__WATCHHI5:
4985 case CP0_REG19__WATCHHI6:
4986 case CP0_REG19__WATCHHI7:
4987 /* upper 32 bits are only available when Config5MI != 0 */
4988 CP0_CHECK(ctx->mi);
4989 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
4990 register_name = "WatchHi";
4991 break;
4992 default:
4993 goto cp0_unimplemented;
4994 }
4995 break;
4996 case CP0_REGISTER_28:
4997 switch (sel) {
4998 case 0:
4999 case 2:
5000 case 4:
Showing first 5,000 of 15,378 lines. View raw