]> git.proxmox.com Git - mirror_qemu.git/blob - target/mips/tcg/translate.c
target: Use vaddr in gen_intermediate_code
[mirror_qemu.git] / target / mips / tcg / translate.c
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 "semihosting/semihost.h"
31 #include "trace.h"
32 #include "disas/disas.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 sysemu-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 /* Loongson 2F */
332 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
333 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
334 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
335 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
336 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
337 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
338 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
339 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
340 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
341 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
342 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
343 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
344 /* Misc */
345 OPC_CLZ = 0x20 | OPC_SPECIAL2,
346 OPC_CLO = 0x21 | OPC_SPECIAL2,
347 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
348 OPC_DCLO = 0x25 | OPC_SPECIAL2,
349 /* Special */
350 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
351 };
352
353 /* Special3 opcodes */
354 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
355
356 enum {
357 OPC_EXT = 0x00 | OPC_SPECIAL3,
358 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
359 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
360 OPC_DEXT = 0x03 | OPC_SPECIAL3,
361 OPC_INS = 0x04 | OPC_SPECIAL3,
362 OPC_DINSM = 0x05 | OPC_SPECIAL3,
363 OPC_DINSU = 0x06 | OPC_SPECIAL3,
364 OPC_DINS = 0x07 | OPC_SPECIAL3,
365 OPC_FORK = 0x08 | OPC_SPECIAL3,
366 OPC_YIELD = 0x09 | OPC_SPECIAL3,
367 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
368 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
369 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
370 OPC_GINV = 0x3D | OPC_SPECIAL3,
371
372 /* Loongson 2E */
373 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
374 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
375 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
376 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
377 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
378 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
379 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
380 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
381 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
382 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
383 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
384 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
385
386 /* MIPS DSP Load */
387 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
388 /* MIPS DSP Arithmetic */
389 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
390 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
391 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
392 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
393 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
394 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
395 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
396 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
397 /* MIPS DSP GPR-Based Shift Sub-class */
398 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
399 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
400 /* MIPS DSP Multiply Sub-class insns */
401 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
402 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
403 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
404 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
405 /* DSP Bit/Manipulation Sub-class */
406 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
407 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
408 /* MIPS DSP Append Sub-class */
409 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
410 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
411 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
412 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
413 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
414
415 /* EVA */
416 OPC_LWLE = 0x19 | OPC_SPECIAL3,
417 OPC_LWRE = 0x1A | OPC_SPECIAL3,
418 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
419 OPC_SBE = 0x1C | OPC_SPECIAL3,
420 OPC_SHE = 0x1D | OPC_SPECIAL3,
421 OPC_SCE = 0x1E | OPC_SPECIAL3,
422 OPC_SWE = 0x1F | OPC_SPECIAL3,
423 OPC_SWLE = 0x21 | OPC_SPECIAL3,
424 OPC_SWRE = 0x22 | OPC_SPECIAL3,
425 OPC_PREFE = 0x23 | OPC_SPECIAL3,
426 OPC_LBUE = 0x28 | OPC_SPECIAL3,
427 OPC_LHUE = 0x29 | OPC_SPECIAL3,
428 OPC_LBE = 0x2C | OPC_SPECIAL3,
429 OPC_LHE = 0x2D | OPC_SPECIAL3,
430 OPC_LLE = 0x2E | OPC_SPECIAL3,
431 OPC_LWE = 0x2F | OPC_SPECIAL3,
432
433 /* R6 */
434 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
435 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
436 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
437 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
438 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
439 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
440 };
441
442 /* Loongson EXT load/store quad word opcodes */
443 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
444 enum {
445 OPC_GSLQ = 0x0020 | OPC_LWC2,
446 OPC_GSLQC1 = 0x8020 | OPC_LWC2,
447 OPC_GSSHFL = OPC_LWC2,
448 OPC_GSSQ = 0x0020 | OPC_SWC2,
449 OPC_GSSQC1 = 0x8020 | OPC_SWC2,
450 OPC_GSSHFS = OPC_SWC2,
451 };
452
453 /* Loongson EXT shifted load/store opcodes */
454 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
455 enum {
456 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
457 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
458 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
459 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
460 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
461 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
462 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
463 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
464 };
465
466 /* Loongson EXT LDC2/SDC2 opcodes */
467 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
468
469 enum {
470 OPC_GSLBX = 0x0 | OPC_LDC2,
471 OPC_GSLHX = 0x1 | OPC_LDC2,
472 OPC_GSLWX = 0x2 | OPC_LDC2,
473 OPC_GSLDX = 0x3 | OPC_LDC2,
474 OPC_GSLWXC1 = 0x6 | OPC_LDC2,
475 OPC_GSLDXC1 = 0x7 | OPC_LDC2,
476 OPC_GSSBX = 0x0 | OPC_SDC2,
477 OPC_GSSHX = 0x1 | OPC_SDC2,
478 OPC_GSSWX = 0x2 | OPC_SDC2,
479 OPC_GSSDX = 0x3 | OPC_SDC2,
480 OPC_GSSWXC1 = 0x6 | OPC_SDC2,
481 OPC_GSSDXC1 = 0x7 | OPC_SDC2,
482 };
483
484 /* BSHFL opcodes */
485 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486
487 enum {
488 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
489 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
490 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
491 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
492 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
493 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
494 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
495 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
496 };
497
498 /* DBSHFL opcodes */
499 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
500
501 enum {
502 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
503 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
504 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
505 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
506 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
507 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
508 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
509 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
510 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
511 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
512 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
513 };
514
515 /* MIPS DSP REGIMM opcodes */
516 enum {
517 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
518 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
519 };
520
521 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
522 /* MIPS DSP Load */
523 enum {
524 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
525 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
526 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
527 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
528 };
529
530 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
531 enum {
532 /* MIPS DSP Arithmetic Sub-class */
533 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
534 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
535 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
536 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
537 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
538 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
539 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
540 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
541 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
542 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
543 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
544 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
545 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
546 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
547 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
548 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
549 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
550 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
551 /* MIPS DSP Multiply Sub-class insns */
552 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
553 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
554 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
555 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
556 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
557 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
558 };
559
560 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
561 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
562 enum {
563 /* MIPS DSP Arithmetic Sub-class */
564 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
565 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
566 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
567 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
568 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
569 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
570 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
571 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
572 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
573 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
574 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
575 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
576 /* MIPS DSP Multiply Sub-class insns */
577 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
578 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
579 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
580 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
581 };
582
583 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
584 enum {
585 /* MIPS DSP Arithmetic Sub-class */
586 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
587 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
588 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
589 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
590 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
591 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
592 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
593 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
594 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
595 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
596 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
597 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
598 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
599 /* DSP Bit/Manipulation Sub-class */
600 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
601 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
602 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
603 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
604 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
605 };
606
607 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
608 enum {
609 /* MIPS DSP Arithmetic Sub-class */
610 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
611 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
612 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
613 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
614 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
615 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
616 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
617 /* DSP Compare-Pick Sub-class */
618 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
619 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
620 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
621 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
622 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
623 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
624 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
625 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
626 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
627 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
628 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
629 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
630 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
631 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
632 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
633 };
634
635 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636 enum {
637 /* MIPS DSP GPR-Based Shift Sub-class */
638 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
639 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
640 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
641 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
642 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
643 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
644 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
645 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
646 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
647 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
648 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
649 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
650 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
651 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
652 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
653 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
654 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
655 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
656 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
657 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
658 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
659 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
660 };
661
662 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
663 enum {
664 /* MIPS DSP Multiply Sub-class insns */
665 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
666 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
667 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
668 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
669 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
670 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
671 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
672 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
673 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
674 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
675 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
676 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
677 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
678 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
679 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
680 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
681 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
682 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
683 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
684 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
685 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
686 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
687 };
688
689 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
690 enum {
691 /* DSP Bit/Manipulation Sub-class */
692 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
693 };
694
695 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
696 enum {
697 /* MIPS DSP Append Sub-class */
698 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
699 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
700 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
701 };
702
703 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704 enum {
705 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
706 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
707 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
708 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
709 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
710 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
711 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
712 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
713 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
714 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
715 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
716 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
717 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
718 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
719 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
720 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
721 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
722 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
723 };
724
725 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
726 enum {
727 /* MIPS DSP Arithmetic Sub-class */
728 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
729 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
730 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
731 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
732 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
733 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
734 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
735 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
736 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
737 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
738 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
739 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
740 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
741 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
742 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
743 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
744 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
745 /* DSP Bit/Manipulation Sub-class */
746 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
747 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
748 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
749 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
750 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
751 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
752 };
753
754 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
755 enum {
756 /* MIPS DSP Multiply Sub-class insns */
757 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
758 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
759 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
760 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
761 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
762 /* MIPS DSP Arithmetic Sub-class */
763 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
764 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
765 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
766 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
767 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
768 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
769 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
770 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
771 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
772 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
773 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
774 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
775 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
776 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
777 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
778 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
779 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
780 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
781 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
782 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
783 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
784 };
785
786 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
787 enum {
788 /* DSP Compare-Pick Sub-class */
789 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
790 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
792 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
793 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
794 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
795 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
796 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
797 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
798 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
799 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
800 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
801 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
802 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
803 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
804 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
805 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
806 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
807 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
808 /* MIPS DSP Arithmetic Sub-class */
809 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
810 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
811 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
812 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
813 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
814 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
815 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
816 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
817 };
818
819 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
820 enum {
821 /* DSP Append Sub-class */
822 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
823 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
824 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
825 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
826 };
827
828 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
829 enum {
830 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
831 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
832 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
833 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
834 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
835 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
836 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
837 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
838 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
839 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
840 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
841 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
842 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
843 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
844 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
845 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
846 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
847 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
848 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
849 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
850 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
851 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
852 };
853
854 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
855 enum {
856 /* DSP Bit/Manipulation Sub-class */
857 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
858 };
859
860 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
861 enum {
862 /* MIPS DSP Multiply Sub-class insns */
863 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
864 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
865 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
866 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
867 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
868 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
869 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
870 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
871 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
872 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
873 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
874 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
875 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
876 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
877 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
878 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
879 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
880 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
881 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
882 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
883 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
884 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
885 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
886 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
887 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
888 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
889 };
890
891 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
892 enum {
893 /* MIPS DSP GPR-Based Shift Sub-class */
894 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
895 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
896 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
897 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
898 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
899 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
900 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
901 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
902 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
903 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
904 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
905 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
906 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
907 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
908 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
909 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
910 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
911 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
912 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
913 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
914 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
915 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
916 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
917 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
918 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
919 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
920 };
921
922 /* Coprocessor 0 (rs field) */
923 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
924
925 enum {
926 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
927 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
928 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
929 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
930 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
931 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
932 OPC_MFTR = (0x08 << 21) | OPC_CP0,
933 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
934 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
935 OPC_MTTR = (0x0C << 21) | OPC_CP0,
936 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
937 OPC_C0 = (0x10 << 21) | OPC_CP0,
938 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
939 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
940 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
941 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
942 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
943 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
944 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
945 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
946 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
947 OPC_C0_A = (0x1A << 21) | OPC_CP0,
948 OPC_C0_B = (0x1B << 21) | OPC_CP0,
949 OPC_C0_C = (0x1C << 21) | OPC_CP0,
950 OPC_C0_D = (0x1D << 21) | OPC_CP0,
951 OPC_C0_E = (0x1E << 21) | OPC_CP0,
952 OPC_C0_F = (0x1F << 21) | OPC_CP0,
953 };
954
955 /* MFMC0 opcodes */
956 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
957
958 enum {
959 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
960 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
961 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
962 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
963 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
964 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
965 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
966 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
967 };
968
969 /* Coprocessor 0 (with rs == C0) */
970 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
971
972 enum {
973 OPC_TLBR = 0x01 | OPC_C0,
974 OPC_TLBWI = 0x02 | OPC_C0,
975 OPC_TLBINV = 0x03 | OPC_C0,
976 OPC_TLBINVF = 0x04 | OPC_C0,
977 OPC_TLBWR = 0x06 | OPC_C0,
978 OPC_TLBP = 0x08 | OPC_C0,
979 OPC_RFE = 0x10 | OPC_C0,
980 OPC_ERET = 0x18 | OPC_C0,
981 OPC_DERET = 0x1F | OPC_C0,
982 OPC_WAIT = 0x20 | OPC_C0,
983 };
984
985 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
986
987 enum {
988 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
989 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
990 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
991 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
992 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
993 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
994 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
995 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
996 OPC_BC2 = (0x08 << 21) | OPC_CP2,
997 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
998 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
999 };
1000
1001 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1002
1003 enum {
1004 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1005 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1012
1013 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1014 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1021
1022 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1023 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1024 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1026 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1027 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1028 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1029 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1030
1031 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1032 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1033 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1035 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1036 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1039
1040 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1041 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1042 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1043 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1046
1047 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1048 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1049 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1053
1054 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1055 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1060
1061 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1062 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1063 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1067
1068 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1069 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1070 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1071 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1072 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1073 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1074
1075 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1076 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1077 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1078 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1079 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1080 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1081
1082 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1083 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1084 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1085 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1086 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1087 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1088
1089 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1090 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1091 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1092 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1093 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1094 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1095 };
1096
1097
1098 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1099
1100 enum {
1101 OPC_LWXC1 = 0x00 | OPC_CP3,
1102 OPC_LDXC1 = 0x01 | OPC_CP3,
1103 OPC_LUXC1 = 0x05 | OPC_CP3,
1104 OPC_SWXC1 = 0x08 | OPC_CP3,
1105 OPC_SDXC1 = 0x09 | OPC_CP3,
1106 OPC_SUXC1 = 0x0D | OPC_CP3,
1107 OPC_PREFX = 0x0F | OPC_CP3,
1108 OPC_ALNV_PS = 0x1E | OPC_CP3,
1109 OPC_MADD_S = 0x20 | OPC_CP3,
1110 OPC_MADD_D = 0x21 | OPC_CP3,
1111 OPC_MADD_PS = 0x26 | OPC_CP3,
1112 OPC_MSUB_S = 0x28 | OPC_CP3,
1113 OPC_MSUB_D = 0x29 | OPC_CP3,
1114 OPC_MSUB_PS = 0x2E | OPC_CP3,
1115 OPC_NMADD_S = 0x30 | OPC_CP3,
1116 OPC_NMADD_D = 0x31 | OPC_CP3,
1117 OPC_NMADD_PS = 0x36 | OPC_CP3,
1118 OPC_NMSUB_S = 0x38 | OPC_CP3,
1119 OPC_NMSUB_D = 0x39 | OPC_CP3,
1120 OPC_NMSUB_PS = 0x3E | OPC_CP3,
1121 };
1122
1123 /*
1124 * MMI (MultiMedia Instruction) encodings
1125 * ======================================
1126 *
1127 * MMI instructions encoding table keys:
1128 *
1129 * * This code is reserved for future use. An attempt to execute it
1130 * causes a Reserved Instruction exception.
1131 * % This code indicates an instruction class. The instruction word
1132 * must be further decoded by examining additional tables that show
1133 * the values for other instruction fields.
1134 * # This code is reserved for the unsupported instructions DMULT,
1135 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1136 * to execute it causes a Reserved Instruction exception.
1137 *
1138 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1139 *
1140 * 31 26 0
1141 * +--------+----------------------------------------+
1142 * | opcode | |
1143 * +--------+----------------------------------------+
1144 *
1145 * opcode bits 28..26
1146 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1147 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1148 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1149 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1150 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1151 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1152 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1153 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1154 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1155 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1156 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1157 */
1158
1159 enum {
1160 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
1161 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
1162 };
1163
1164 /*
1165 * MMI instructions with opcode field = MMI:
1166 *
1167 * 31 26 5 0
1168 * +--------+-------------------------------+--------+
1169 * | MMI | |function|
1170 * +--------+-------------------------------+--------+
1171 *
1172 * function bits 2..0
1173 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1174 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1175 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1176 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1177 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1178 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1179 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1180 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1181 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1182 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1183 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1184 */
1185
1186 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1187 enum {
1188 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1189 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1190 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1191 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1192 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
1193 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1194 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
1195 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
1196 };
1197
1198 /* global register indices */
1199 TCGv cpu_gpr[32], cpu_PC;
1200 /*
1201 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1202 * and the upper halves in cpu_gpr_hi[].
1203 */
1204 TCGv_i64 cpu_gpr_hi[32];
1205 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1206 static TCGv cpu_dspctrl, btarget;
1207 TCGv bcond;
1208 static TCGv cpu_lladdr, cpu_llval;
1209 static TCGv_i32 hflags;
1210 TCGv_i32 fpu_fcr0, fpu_fcr31;
1211 TCGv_i64 fpu_f64[32];
1212
1213 static const char regnames_HI[][4] = {
1214 "HI0", "HI1", "HI2", "HI3",
1215 };
1216
1217 static const char regnames_LO[][4] = {
1218 "LO0", "LO1", "LO2", "LO3",
1219 };
1220
1221 /* General purpose registers moves. */
1222 void gen_load_gpr(TCGv t, int reg)
1223 {
1224 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1225 if (reg == 0) {
1226 tcg_gen_movi_tl(t, 0);
1227 } else {
1228 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1229 }
1230 }
1231
1232 void gen_store_gpr(TCGv t, int reg)
1233 {
1234 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr));
1235 if (reg != 0) {
1236 tcg_gen_mov_tl(cpu_gpr[reg], t);
1237 }
1238 }
1239
1240 #if defined(TARGET_MIPS64)
1241 void gen_load_gpr_hi(TCGv_i64 t, int reg)
1242 {
1243 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1244 if (reg == 0) {
1245 tcg_gen_movi_i64(t, 0);
1246 } else {
1247 tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1248 }
1249 }
1250
1251 void gen_store_gpr_hi(TCGv_i64 t, int reg)
1252 {
1253 assert(reg >= 0 && reg <= ARRAY_SIZE(cpu_gpr_hi));
1254 if (reg != 0) {
1255 tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1256 }
1257 }
1258 #endif /* TARGET_MIPS64 */
1259
1260 /* Moves to/from shadow registers. */
1261 static inline void gen_load_srsgpr(int from, int to)
1262 {
1263 TCGv t0 = tcg_temp_new();
1264
1265 if (from == 0) {
1266 tcg_gen_movi_tl(t0, 0);
1267 } else {
1268 TCGv_i32 t2 = tcg_temp_new_i32();
1269 TCGv_ptr addr = tcg_temp_new_ptr();
1270
1271 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1272 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1273 tcg_gen_andi_i32(t2, t2, 0xf);
1274 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1275 tcg_gen_ext_i32_ptr(addr, t2);
1276 tcg_gen_add_ptr(addr, tcg_env, addr);
1277
1278 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1279 }
1280 gen_store_gpr(t0, to);
1281 }
1282
1283 static inline void gen_store_srsgpr(int from, int to)
1284 {
1285 if (to != 0) {
1286 TCGv t0 = tcg_temp_new();
1287 TCGv_i32 t2 = tcg_temp_new_i32();
1288 TCGv_ptr addr = tcg_temp_new_ptr();
1289
1290 gen_load_gpr(t0, from);
1291 tcg_gen_ld_i32(t2, tcg_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1292 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1293 tcg_gen_andi_i32(t2, t2, 0xf);
1294 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1295 tcg_gen_ext_i32_ptr(addr, t2);
1296 tcg_gen_add_ptr(addr, tcg_env, addr);
1297
1298 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1299 }
1300 }
1301
1302 /* Tests */
1303 static inline void gen_save_pc(target_ulong pc)
1304 {
1305 tcg_gen_movi_tl(cpu_PC, pc);
1306 }
1307
1308 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1309 {
1310 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1311 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1312 gen_save_pc(ctx->base.pc_next);
1313 ctx->saved_pc = ctx->base.pc_next;
1314 }
1315 if (ctx->hflags != ctx->saved_hflags) {
1316 tcg_gen_movi_i32(hflags, ctx->hflags);
1317 ctx->saved_hflags = ctx->hflags;
1318 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1319 case MIPS_HFLAG_BR:
1320 break;
1321 case MIPS_HFLAG_BC:
1322 case MIPS_HFLAG_BL:
1323 case MIPS_HFLAG_B:
1324 tcg_gen_movi_tl(btarget, ctx->btarget);
1325 break;
1326 }
1327 }
1328 }
1329
1330 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1331 {
1332 ctx->saved_hflags = ctx->hflags;
1333 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1334 case MIPS_HFLAG_BR:
1335 break;
1336 case MIPS_HFLAG_BC:
1337 case MIPS_HFLAG_BL:
1338 case MIPS_HFLAG_B:
1339 ctx->btarget = env->btarget;
1340 break;
1341 }
1342 }
1343
1344 void generate_exception_err(DisasContext *ctx, int excp, int err)
1345 {
1346 save_cpu_state(ctx, 1);
1347 gen_helper_raise_exception_err(tcg_env, tcg_constant_i32(excp),
1348 tcg_constant_i32(err));
1349 ctx->base.is_jmp = DISAS_NORETURN;
1350 }
1351
1352 void generate_exception(DisasContext *ctx, int excp)
1353 {
1354 gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp));
1355 }
1356
1357 void generate_exception_end(DisasContext *ctx, int excp)
1358 {
1359 generate_exception_err(ctx, excp, 0);
1360 }
1361
1362 void generate_exception_break(DisasContext *ctx, int code)
1363 {
1364 #ifdef CONFIG_USER_ONLY
1365 /* Pass the break code along to cpu_loop. */
1366 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
1367 offsetof(CPUMIPSState, error_code));
1368 #endif
1369 generate_exception_end(ctx, EXCP_BREAK);
1370 }
1371
1372 void gen_reserved_instruction(DisasContext *ctx)
1373 {
1374 generate_exception_end(ctx, EXCP_RI);
1375 }
1376
1377 /* Floating point register moves. */
1378 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1379 {
1380 if (ctx->hflags & MIPS_HFLAG_FRE) {
1381 generate_exception(ctx, EXCP_RI);
1382 }
1383 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1384 }
1385
1386 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1387 {
1388 TCGv_i64 t64;
1389 if (ctx->hflags & MIPS_HFLAG_FRE) {
1390 generate_exception(ctx, EXCP_RI);
1391 }
1392 t64 = tcg_temp_new_i64();
1393 tcg_gen_extu_i32_i64(t64, t);
1394 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1395 }
1396
1397 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1398 {
1399 if (ctx->hflags & MIPS_HFLAG_F64) {
1400 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1401 } else {
1402 gen_load_fpr32(ctx, t, reg | 1);
1403 }
1404 }
1405
1406 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1407 {
1408 if (ctx->hflags & MIPS_HFLAG_F64) {
1409 TCGv_i64 t64 = tcg_temp_new_i64();
1410 tcg_gen_extu_i32_i64(t64, t);
1411 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1412 } else {
1413 gen_store_fpr32(ctx, t, reg | 1);
1414 }
1415 }
1416
1417 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1418 {
1419 if (ctx->hflags & MIPS_HFLAG_F64) {
1420 tcg_gen_mov_i64(t, fpu_f64[reg]);
1421 } else {
1422 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1423 }
1424 }
1425
1426 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1427 {
1428 if (ctx->hflags & MIPS_HFLAG_F64) {
1429 tcg_gen_mov_i64(fpu_f64[reg], t);
1430 } else {
1431 TCGv_i64 t0;
1432 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1433 t0 = tcg_temp_new_i64();
1434 tcg_gen_shri_i64(t0, t, 32);
1435 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1436 }
1437 }
1438
1439 int get_fp_bit(int cc)
1440 {
1441 if (cc) {
1442 return 24 + cc;
1443 } else {
1444 return 23;
1445 }
1446 }
1447
1448 /* Addresses computation */
1449 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1450 {
1451 tcg_gen_add_tl(ret, arg0, arg1);
1452
1453 #if defined(TARGET_MIPS64)
1454 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1455 tcg_gen_ext32s_i64(ret, ret);
1456 }
1457 #endif
1458 }
1459
1460 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1461 target_long ofs)
1462 {
1463 tcg_gen_addi_tl(ret, base, ofs);
1464
1465 #if defined(TARGET_MIPS64)
1466 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1467 tcg_gen_ext32s_i64(ret, ret);
1468 }
1469 #endif
1470 }
1471
1472 /* Addresses computation (translation time) */
1473 static target_long addr_add(DisasContext *ctx, target_long base,
1474 target_long offset)
1475 {
1476 target_long sum = base + offset;
1477
1478 #if defined(TARGET_MIPS64)
1479 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1480 sum = (int32_t)sum;
1481 }
1482 #endif
1483 return sum;
1484 }
1485
1486 /* Sign-extract the low 32-bits to a target_long. */
1487 void gen_move_low32(TCGv ret, TCGv_i64 arg)
1488 {
1489 #if defined(TARGET_MIPS64)
1490 tcg_gen_ext32s_i64(ret, arg);
1491 #else
1492 tcg_gen_extrl_i64_i32(ret, arg);
1493 #endif
1494 }
1495
1496 /* Sign-extract the high 32-bits to a target_long. */
1497 void gen_move_high32(TCGv ret, TCGv_i64 arg)
1498 {
1499 #if defined(TARGET_MIPS64)
1500 tcg_gen_sari_i64(ret, arg, 32);
1501 #else
1502 tcg_gen_extrh_i64_i32(ret, arg);
1503 #endif
1504 }
1505
1506 bool check_cp0_enabled(DisasContext *ctx)
1507 {
1508 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1509 generate_exception_end(ctx, EXCP_CpU);
1510 return false;
1511 }
1512 return true;
1513 }
1514
1515 void check_cp1_enabled(DisasContext *ctx)
1516 {
1517 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1518 generate_exception_err(ctx, EXCP_CpU, 1);
1519 }
1520 }
1521
1522 /*
1523 * Verify that the processor is running with COP1X instructions enabled.
1524 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1525 * opcode tables.
1526 */
1527 void check_cop1x(DisasContext *ctx)
1528 {
1529 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1530 gen_reserved_instruction(ctx);
1531 }
1532 }
1533
1534 /*
1535 * Verify that the processor is running with 64-bit floating-point
1536 * operations enabled.
1537 */
1538 void check_cp1_64bitmode(DisasContext *ctx)
1539 {
1540 if (unlikely(~ctx->hflags & MIPS_HFLAG_F64)) {
1541 gen_reserved_instruction(ctx);
1542 }
1543 }
1544
1545 /*
1546 * Verify if floating point register is valid; an operation is not defined
1547 * if bit 0 of any register specification is set and the FR bit in the
1548 * Status register equals zero, since the register numbers specify an
1549 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1550 * in the Status register equals one, both even and odd register numbers
1551 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1552 *
1553 * Multiple 64 bit wide registers can be checked by calling
1554 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1555 */
1556 void check_cp1_registers(DisasContext *ctx, int regs)
1557 {
1558 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1559 gen_reserved_instruction(ctx);
1560 }
1561 }
1562
1563 /*
1564 * Verify that the processor is running with DSP instructions enabled.
1565 * This is enabled by CP0 Status register MX(24) bit.
1566 */
1567 static inline void check_dsp(DisasContext *ctx)
1568 {
1569 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1570 if (ctx->insn_flags & ASE_DSP) {
1571 generate_exception_end(ctx, EXCP_DSPDIS);
1572 } else {
1573 gen_reserved_instruction(ctx);
1574 }
1575 }
1576 }
1577
1578 static inline void check_dsp_r2(DisasContext *ctx)
1579 {
1580 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1581 if (ctx->insn_flags & ASE_DSP) {
1582 generate_exception_end(ctx, EXCP_DSPDIS);
1583 } else {
1584 gen_reserved_instruction(ctx);
1585 }
1586 }
1587 }
1588
1589 static inline void check_dsp_r3(DisasContext *ctx)
1590 {
1591 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1592 if (ctx->insn_flags & ASE_DSP) {
1593 generate_exception_end(ctx, EXCP_DSPDIS);
1594 } else {
1595 gen_reserved_instruction(ctx);
1596 }
1597 }
1598 }
1599
1600 /*
1601 * This code generates a "reserved instruction" exception if the
1602 * CPU does not support the instruction set corresponding to flags.
1603 */
1604 void check_insn(DisasContext *ctx, uint64_t flags)
1605 {
1606 if (unlikely(!(ctx->insn_flags & flags))) {
1607 gen_reserved_instruction(ctx);
1608 }
1609 }
1610
1611 /*
1612 * This code generates a "reserved instruction" exception if the
1613 * CPU has corresponding flag set which indicates that the instruction
1614 * has been removed.
1615 */
1616 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1617 {
1618 if (unlikely(ctx->insn_flags & flags)) {
1619 gen_reserved_instruction(ctx);
1620 }
1621 }
1622
1623 /*
1624 * The Linux kernel traps certain reserved instruction exceptions to
1625 * emulate the corresponding instructions. QEMU is the kernel in user
1626 * mode, so those traps are emulated by accepting the instructions.
1627 *
1628 * A reserved instruction exception is generated for flagged CPUs if
1629 * QEMU runs in system mode.
1630 */
1631 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1632 {
1633 #ifndef CONFIG_USER_ONLY
1634 check_insn_opc_removed(ctx, flags);
1635 #endif
1636 }
1637
1638 /*
1639 * This code generates a "reserved instruction" exception if the
1640 * CPU does not support 64-bit paired-single (PS) floating point data type.
1641 */
1642 static inline void check_ps(DisasContext *ctx)
1643 {
1644 if (unlikely(!ctx->ps)) {
1645 generate_exception(ctx, EXCP_RI);
1646 }
1647 check_cp1_64bitmode(ctx);
1648 }
1649
1650 /*
1651 * This code generates a "reserved instruction" exception if cpu is not
1652 * 64-bit or 64-bit instructions are not enabled.
1653 */
1654 void check_mips_64(DisasContext *ctx)
1655 {
1656 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1657 gen_reserved_instruction(ctx);
1658 }
1659 }
1660
1661 #ifndef CONFIG_USER_ONLY
1662 static inline void check_mvh(DisasContext *ctx)
1663 {
1664 if (unlikely(!ctx->mvh)) {
1665 generate_exception(ctx, EXCP_RI);
1666 }
1667 }
1668 #endif
1669
1670 /*
1671 * This code generates a "reserved instruction" exception if the
1672 * Config5 XNP bit is set.
1673 */
1674 static inline void check_xnp(DisasContext *ctx)
1675 {
1676 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1677 gen_reserved_instruction(ctx);
1678 }
1679 }
1680
1681 #ifndef CONFIG_USER_ONLY
1682 /*
1683 * This code generates a "reserved instruction" exception if the
1684 * Config3 PW bit is NOT set.
1685 */
1686 static inline void check_pw(DisasContext *ctx)
1687 {
1688 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1689 gen_reserved_instruction(ctx);
1690 }
1691 }
1692 #endif
1693
1694 /*
1695 * This code generates a "reserved instruction" exception if the
1696 * Config3 MT bit is NOT set.
1697 */
1698 static inline void check_mt(DisasContext *ctx)
1699 {
1700 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1701 gen_reserved_instruction(ctx);
1702 }
1703 }
1704
1705 #ifndef CONFIG_USER_ONLY
1706 /*
1707 * This code generates a "coprocessor unusable" exception if CP0 is not
1708 * available, and, if that is not the case, generates a "reserved instruction"
1709 * exception if the Config5 MT bit is NOT set. This is needed for availability
1710 * control of some of MT ASE instructions.
1711 */
1712 static inline void check_cp0_mt(DisasContext *ctx)
1713 {
1714 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1715 generate_exception_end(ctx, EXCP_CpU);
1716 } else {
1717 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1718 gen_reserved_instruction(ctx);
1719 }
1720 }
1721 }
1722 #endif
1723
1724 /*
1725 * This code generates a "reserved instruction" exception if the
1726 * Config5 NMS bit is set.
1727 */
1728 static inline void check_nms(DisasContext *ctx)
1729 {
1730 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1731 gen_reserved_instruction(ctx);
1732 }
1733 }
1734
1735 /*
1736 * This code generates a "reserved instruction" exception if the
1737 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1738 * Config2 TL, and Config5 L2C are unset.
1739 */
1740 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1741 {
1742 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1743 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1744 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1745 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1746 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1747 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1748 gen_reserved_instruction(ctx);
1749 }
1750 }
1751
1752 /*
1753 * This code generates a "reserved instruction" exception if the
1754 * Config5 EVA bit is NOT set.
1755 */
1756 static inline void check_eva(DisasContext *ctx)
1757 {
1758 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1759 gen_reserved_instruction(ctx);
1760 }
1761 }
1762
1763
1764 /*
1765 * Define small wrappers for gen_load_fpr* so that we have a uniform
1766 * calling interface for 32 and 64-bit FPRs. No sense in changing
1767 * all callers for gen_load_fpr32 when we need the CTX parameter for
1768 * this one use.
1769 */
1770 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1771 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1772 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1773 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1774 int ft, int fs, int cc) \
1775 { \
1776 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1777 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
1778 switch (ifmt) { \
1779 case FMT_PS: \
1780 check_ps(ctx); \
1781 break; \
1782 case FMT_D: \
1783 if (abs) { \
1784 check_cop1x(ctx); \
1785 } \
1786 check_cp1_registers(ctx, fs | ft); \
1787 break; \
1788 case FMT_S: \
1789 if (abs) { \
1790 check_cop1x(ctx); \
1791 } \
1792 break; \
1793 } \
1794 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1795 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
1796 switch (n) { \
1797 case 0: \
1798 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1799 break; \
1800 case 1: \
1801 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1802 break; \
1803 case 2: \
1804 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1805 break; \
1806 case 3: \
1807 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1808 break; \
1809 case 4: \
1810 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1811 break; \
1812 case 5: \
1813 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1814 break; \
1815 case 6: \
1816 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1817 break; \
1818 case 7: \
1819 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1820 break; \
1821 case 8: \
1822 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1823 break; \
1824 case 9: \
1825 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1826 break; \
1827 case 10: \
1828 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1829 break; \
1830 case 11: \
1831 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1832 break; \
1833 case 12: \
1834 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1835 break; \
1836 case 13: \
1837 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1838 break; \
1839 case 14: \
1840 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1841 break; \
1842 case 15: \
1843 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1844 break; \
1845 default: \
1846 abort(); \
1847 } \
1848 }
1849
1850 FOP_CONDS(, 0, d, FMT_D, 64)
1851 FOP_CONDS(abs, 1, d, FMT_D, 64)
1852 FOP_CONDS(, 0, s, FMT_S, 32)
1853 FOP_CONDS(abs, 1, s, FMT_S, 32)
1854 FOP_CONDS(, 0, ps, FMT_PS, 64)
1855 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1856 #undef FOP_CONDS
1857
1858 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1859 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
1860 int ft, int fs, int fd) \
1861 { \
1862 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1863 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1864 if (ifmt == FMT_D) { \
1865 check_cp1_registers(ctx, fs | ft | fd); \
1866 } \
1867 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1868 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1869 switch (n) { \
1870 case 0: \
1871 gen_helper_r6_cmp_ ## fmt ## _af(fp0, tcg_env, fp0, fp1); \
1872 break; \
1873 case 1: \
1874 gen_helper_r6_cmp_ ## fmt ## _un(fp0, tcg_env, fp0, fp1); \
1875 break; \
1876 case 2: \
1877 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, tcg_env, fp0, fp1); \
1878 break; \
1879 case 3: \
1880 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, tcg_env, fp0, fp1); \
1881 break; \
1882 case 4: \
1883 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, tcg_env, fp0, fp1); \
1884 break; \
1885 case 5: \
1886 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, tcg_env, fp0, fp1); \
1887 break; \
1888 case 6: \
1889 gen_helper_r6_cmp_ ## fmt ## _le(fp0, tcg_env, fp0, fp1); \
1890 break; \
1891 case 7: \
1892 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, tcg_env, fp0, fp1); \
1893 break; \
1894 case 8: \
1895 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, tcg_env, fp0, fp1); \
1896 break; \
1897 case 9: \
1898 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, tcg_env, fp0, fp1); \
1899 break; \
1900 case 10: \
1901 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, tcg_env, fp0, fp1); \
1902 break; \
1903 case 11: \
1904 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, tcg_env, fp0, fp1); \
1905 break; \
1906 case 12: \
1907 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, tcg_env, fp0, fp1); \
1908 break; \
1909 case 13: \
1910 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, tcg_env, fp0, fp1); \
1911 break; \
1912 case 14: \
1913 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, tcg_env, fp0, fp1); \
1914 break; \
1915 case 15: \
1916 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, tcg_env, fp0, fp1); \
1917 break; \
1918 case 17: \
1919 gen_helper_r6_cmp_ ## fmt ## _or(fp0, tcg_env, fp0, fp1); \
1920 break; \
1921 case 18: \
1922 gen_helper_r6_cmp_ ## fmt ## _une(fp0, tcg_env, fp0, fp1); \
1923 break; \
1924 case 19: \
1925 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, tcg_env, fp0, fp1); \
1926 break; \
1927 case 25: \
1928 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, tcg_env, fp0, fp1); \
1929 break; \
1930 case 26: \
1931 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, tcg_env, fp0, fp1); \
1932 break; \
1933 case 27: \
1934 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, tcg_env, fp0, fp1); \
1935 break; \
1936 default: \
1937 abort(); \
1938 } \
1939 STORE; \
1940 }
1941
1942 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1943 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1944 #undef FOP_CONDNS
1945 #undef gen_ldcmp_fpr32
1946 #undef gen_ldcmp_fpr64
1947
1948 /* load/store instructions. */
1949 #ifdef CONFIG_USER_ONLY
1950 #define OP_LD_ATOMIC(insn, memop) \
1951 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1952 DisasContext *ctx) \
1953 { \
1954 TCGv t0 = tcg_temp_new(); \
1955 tcg_gen_mov_tl(t0, arg1); \
1956 tcg_gen_qemu_ld_tl(ret, arg1, ctx->mem_idx, memop); \
1957 tcg_gen_st_tl(t0, tcg_env, offsetof(CPUMIPSState, lladdr)); \
1958 tcg_gen_st_tl(ret, tcg_env, offsetof(CPUMIPSState, llval)); \
1959 }
1960 #else
1961 #define OP_LD_ATOMIC(insn, fname) \
1962 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1963 DisasContext *ctx) \
1964 { \
1965 gen_helper_##insn(ret, tcg_env, arg1, tcg_constant_i32(mem_idx)); \
1966 }
1967 #endif
1968 OP_LD_ATOMIC(ll, MO_TESL);
1969 #if defined(TARGET_MIPS64)
1970 OP_LD_ATOMIC(lld, MO_TEUQ);
1971 #endif
1972 #undef OP_LD_ATOMIC
1973
1974 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1975 {
1976 if (base == 0) {
1977 tcg_gen_movi_tl(addr, offset);
1978 } else if (offset == 0) {
1979 gen_load_gpr(addr, base);
1980 } else {
1981 tcg_gen_movi_tl(addr, offset);
1982 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1983 }
1984 }
1985
1986 static target_ulong pc_relative_pc(DisasContext *ctx)
1987 {
1988 target_ulong pc = ctx->base.pc_next;
1989
1990 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1991 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1992
1993 pc -= branch_bytes;
1994 }
1995
1996 pc &= ~(target_ulong)3;
1997 return pc;
1998 }
1999
2000 /* LWL or LDL, depending on MemOp. */
2001 static void gen_lxl(DisasContext *ctx, TCGv reg, TCGv addr,
2002 int mem_idx, MemOp mop)
2003 {
2004 int sizem1 = memop_size(mop) - 1;
2005 TCGv t0 = tcg_temp_new();
2006 TCGv t1 = tcg_temp_new();
2007
2008 /*
2009 * Do a byte access to possibly trigger a page
2010 * fault with the unaligned address.
2011 */
2012 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2013 tcg_gen_andi_tl(t1, addr, sizem1);
2014 if (!cpu_is_bigendian(ctx)) {
2015 tcg_gen_xori_tl(t1, t1, sizem1);
2016 }
2017 tcg_gen_shli_tl(t1, t1, 3);
2018 tcg_gen_andi_tl(t0, addr, ~sizem1);
2019 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2020 tcg_gen_shl_tl(t0, t0, t1);
2021 tcg_gen_shl_tl(t1, tcg_constant_tl(-1), t1);
2022 tcg_gen_andc_tl(t1, reg, t1);
2023 tcg_gen_or_tl(reg, t0, t1);
2024 }
2025
2026 /* LWR or LDR, depending on MemOp. */
2027 static void gen_lxr(DisasContext *ctx, TCGv reg, TCGv addr,
2028 int mem_idx, MemOp mop)
2029 {
2030 int size = memop_size(mop);
2031 int sizem1 = size - 1;
2032 TCGv t0 = tcg_temp_new();
2033 TCGv t1 = tcg_temp_new();
2034
2035 /*
2036 * Do a byte access to possibly trigger a page
2037 * fault with the unaligned address.
2038 */
2039 tcg_gen_qemu_ld_tl(t1, addr, mem_idx, MO_UB);
2040 tcg_gen_andi_tl(t1, addr, sizem1);
2041 if (cpu_is_bigendian(ctx)) {
2042 tcg_gen_xori_tl(t1, t1, sizem1);
2043 }
2044 tcg_gen_shli_tl(t1, t1, 3);
2045 tcg_gen_andi_tl(t0, addr, ~sizem1);
2046 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, mop);
2047 tcg_gen_shr_tl(t0, t0, t1);
2048 tcg_gen_xori_tl(t1, t1, size * 8 - 1);
2049 tcg_gen_shl_tl(t1, tcg_constant_tl(~1), t1);
2050 tcg_gen_and_tl(t1, reg, t1);
2051 tcg_gen_or_tl(reg, t0, t1);
2052 }
2053
2054 /* Load */
2055 static void gen_ld(DisasContext *ctx, uint32_t opc,
2056 int rt, int base, int offset)
2057 {
2058 TCGv t0, t1;
2059 int mem_idx = ctx->mem_idx;
2060
2061 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2062 INSN_LOONGSON3A)) {
2063 /*
2064 * Loongson CPU uses a load to zero register for prefetch.
2065 * We emulate it as a NOP. On other CPU we must perform the
2066 * actual memory access.
2067 */
2068 return;
2069 }
2070
2071 t0 = tcg_temp_new();
2072 gen_base_offset_addr(ctx, t0, base, offset);
2073
2074 switch (opc) {
2075 #if defined(TARGET_MIPS64)
2076 case OPC_LWU:
2077 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2078 ctx->default_tcg_memop_mask);
2079 gen_store_gpr(t0, rt);
2080 break;
2081 case OPC_LD:
2082 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ |
2083 ctx->default_tcg_memop_mask);
2084 gen_store_gpr(t0, rt);
2085 break;
2086 case OPC_LLD:
2087 case R6_OPC_LLD:
2088 op_ld_lld(t0, t0, mem_idx, ctx);
2089 gen_store_gpr(t0, rt);
2090 break;
2091 case OPC_LDL:
2092 t1 = tcg_temp_new();
2093 gen_load_gpr(t1, rt);
2094 gen_lxl(ctx, t1, t0, mem_idx, MO_TEUQ);
2095 gen_store_gpr(t1, rt);
2096 break;
2097 case OPC_LDR:
2098 t1 = tcg_temp_new();
2099 gen_load_gpr(t1, rt);
2100 gen_lxr(ctx, t1, t0, mem_idx, MO_TEUQ);
2101 gen_store_gpr(t1, rt);
2102 break;
2103 case OPC_LDPC:
2104 t1 = tcg_constant_tl(pc_relative_pc(ctx));
2105 gen_op_addr_add(ctx, t0, t0, t1);
2106 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2107 gen_store_gpr(t0, rt);
2108 break;
2109 #endif
2110 case OPC_LWPC:
2111 t1 = tcg_constant_tl(pc_relative_pc(ctx));
2112 gen_op_addr_add(ctx, t0, t0, t1);
2113 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2114 gen_store_gpr(t0, rt);
2115 break;
2116 case OPC_LWE:
2117 mem_idx = MIPS_HFLAG_UM;
2118 /* fall through */
2119 case OPC_LW:
2120 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2121 ctx->default_tcg_memop_mask);
2122 gen_store_gpr(t0, rt);
2123 break;
2124 case OPC_LHE:
2125 mem_idx = MIPS_HFLAG_UM;
2126 /* fall through */
2127 case OPC_LH:
2128 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2129 ctx->default_tcg_memop_mask);
2130 gen_store_gpr(t0, rt);
2131 break;
2132 case OPC_LHUE:
2133 mem_idx = MIPS_HFLAG_UM;
2134 /* fall through */
2135 case OPC_LHU:
2136 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2137 ctx->default_tcg_memop_mask);
2138 gen_store_gpr(t0, rt);
2139 break;
2140 case OPC_LBE:
2141 mem_idx = MIPS_HFLAG_UM;
2142 /* fall through */
2143 case OPC_LB:
2144 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2145 gen_store_gpr(t0, rt);
2146 break;
2147 case OPC_LBUE:
2148 mem_idx = MIPS_HFLAG_UM;
2149 /* fall through */
2150 case OPC_LBU:
2151 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2152 gen_store_gpr(t0, rt);
2153 break;
2154 case OPC_LWLE:
2155 mem_idx = MIPS_HFLAG_UM;
2156 /* fall through */
2157 case OPC_LWL:
2158 t1 = tcg_temp_new();
2159 gen_load_gpr(t1, rt);
2160 gen_lxl(ctx, t1, t0, mem_idx, MO_TEUL);
2161 tcg_gen_ext32s_tl(t1, t1);
2162 gen_store_gpr(t1, rt);
2163 break;
2164 case OPC_LWRE:
2165 mem_idx = MIPS_HFLAG_UM;
2166 /* fall through */
2167 case OPC_LWR:
2168 t1 = tcg_temp_new();
2169 gen_load_gpr(t1, rt);
2170 gen_lxr(ctx, t1, t0, mem_idx, MO_TEUL);
2171 tcg_gen_ext32s_tl(t1, t1);
2172 gen_store_gpr(t1, rt);
2173 break;
2174 case OPC_LLE:
2175 mem_idx = MIPS_HFLAG_UM;
2176 /* fall through */
2177 case OPC_LL:
2178 case R6_OPC_LL:
2179 op_ld_ll(t0, t0, mem_idx, ctx);
2180 gen_store_gpr(t0, rt);
2181 break;
2182 }
2183 }
2184
2185 /* Store */
2186 static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2187 int base, int offset)
2188 {
2189 TCGv t0 = tcg_temp_new();
2190 TCGv t1 = tcg_temp_new();
2191 int mem_idx = ctx->mem_idx;
2192
2193 gen_base_offset_addr(ctx, t0, base, offset);
2194 gen_load_gpr(t1, rt);
2195 switch (opc) {
2196 #if defined(TARGET_MIPS64)
2197 case OPC_SD:
2198 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ |
2199 ctx->default_tcg_memop_mask);
2200 break;
2201 case OPC_SDL:
2202 gen_helper_0e2i(sdl, t1, t0, mem_idx);
2203 break;
2204 case OPC_SDR:
2205 gen_helper_0e2i(sdr, t1, t0, mem_idx);
2206 break;
2207 #endif
2208 case OPC_SWE:
2209 mem_idx = MIPS_HFLAG_UM;
2210 /* fall through */
2211 case OPC_SW:
2212 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2213 ctx->default_tcg_memop_mask);
2214 break;
2215 case OPC_SHE:
2216 mem_idx = MIPS_HFLAG_UM;
2217 /* fall through */
2218 case OPC_SH:
2219 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2220 ctx->default_tcg_memop_mask);
2221 break;
2222 case OPC_SBE:
2223 mem_idx = MIPS_HFLAG_UM;
2224 /* fall through */
2225 case OPC_SB:
2226 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2227 break;
2228 case OPC_SWLE:
2229 mem_idx = MIPS_HFLAG_UM;
2230 /* fall through */
2231 case OPC_SWL:
2232 gen_helper_0e2i(swl, t1, t0, mem_idx);
2233 break;
2234 case OPC_SWRE:
2235 mem_idx = MIPS_HFLAG_UM;
2236 /* fall through */
2237 case OPC_SWR:
2238 gen_helper_0e2i(swr, t1, t0, mem_idx);
2239 break;
2240 }
2241 }
2242
2243
2244 /* Store conditional */
2245 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2246 MemOp tcg_mo, bool eva)
2247 {
2248 TCGv addr, t0, val;
2249 TCGLabel *l1 = gen_new_label();
2250 TCGLabel *done = gen_new_label();
2251
2252 t0 = tcg_temp_new();
2253 addr = tcg_temp_new();
2254 /* compare the address against that of the preceding LL */
2255 gen_base_offset_addr(ctx, addr, base, offset);
2256 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2257 tcg_gen_movi_tl(t0, 0);
2258 gen_store_gpr(t0, rt);
2259 tcg_gen_br(done);
2260
2261 gen_set_label(l1);
2262 /* generate cmpxchg */
2263 val = tcg_temp_new();
2264 gen_load_gpr(val, rt);
2265 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2266 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2267 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2268 gen_store_gpr(t0, rt);
2269
2270 gen_set_label(done);
2271 }
2272
2273 /* Load and store */
2274 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2275 TCGv t0)
2276 {
2277 /*
2278 * Don't do NOP if destination is zero: we must perform the actual
2279 * memory access.
2280 */
2281 switch (opc) {
2282 case OPC_LWC1:
2283 {
2284 TCGv_i32 fp0 = tcg_temp_new_i32();
2285 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2286 ctx->default_tcg_memop_mask);
2287 gen_store_fpr32(ctx, fp0, ft);
2288 }
2289 break;
2290 case OPC_SWC1:
2291 {
2292 TCGv_i32 fp0 = tcg_temp_new_i32();
2293 gen_load_fpr32(ctx, fp0, ft);
2294 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2295 ctx->default_tcg_memop_mask);
2296 }
2297 break;
2298 case OPC_LDC1:
2299 {
2300 TCGv_i64 fp0 = tcg_temp_new_i64();
2301 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2302 ctx->default_tcg_memop_mask);
2303 gen_store_fpr64(ctx, fp0, ft);
2304 }
2305 break;
2306 case OPC_SDC1:
2307 {
2308 TCGv_i64 fp0 = tcg_temp_new_i64();
2309 gen_load_fpr64(ctx, fp0, ft);
2310 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2311 ctx->default_tcg_memop_mask);
2312 }
2313 break;
2314 default:
2315 MIPS_INVAL("flt_ldst");
2316 gen_reserved_instruction(ctx);
2317 break;
2318 }
2319 }
2320
2321 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2322 int rs, int16_t imm)
2323 {
2324 TCGv t0 = tcg_temp_new();
2325
2326 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2327 check_cp1_enabled(ctx);
2328 switch (op) {
2329 case OPC_LDC1:
2330 case OPC_SDC1:
2331 check_insn(ctx, ISA_MIPS2);
2332 /* Fallthrough */
2333 default:
2334 gen_base_offset_addr(ctx, t0, rs, imm);
2335 gen_flt_ldst(ctx, op, rt, t0);
2336 }
2337 } else {
2338 generate_exception_err(ctx, EXCP_CpU, 1);
2339 }
2340 }
2341
2342 /* Arithmetic with immediate operand */
2343 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2344 int rt, int rs, int imm)
2345 {
2346 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2347
2348 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2349 /*
2350 * If no destination, treat it as a NOP.
2351 * For addi, we must generate the overflow exception when needed.
2352 */
2353 return;
2354 }
2355 switch (opc) {
2356 case OPC_ADDI:
2357 {
2358 TCGv t0 = tcg_temp_new();
2359 TCGv t1 = tcg_temp_new();
2360 TCGv t2 = tcg_temp_new();
2361 TCGLabel *l1 = gen_new_label();
2362
2363 gen_load_gpr(t1, rs);
2364 tcg_gen_addi_tl(t0, t1, uimm);
2365 tcg_gen_ext32s_tl(t0, t0);
2366
2367 tcg_gen_xori_tl(t1, t1, ~uimm);
2368 tcg_gen_xori_tl(t2, t0, uimm);
2369 tcg_gen_and_tl(t1, t1, t2);
2370 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2371 /* operands of same sign, result different sign */
2372 generate_exception(ctx, EXCP_OVERFLOW);
2373 gen_set_label(l1);
2374 tcg_gen_ext32s_tl(t0, t0);
2375 gen_store_gpr(t0, rt);
2376 }
2377 break;
2378 case OPC_ADDIU:
2379 if (rs != 0) {
2380 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2381 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2382 } else {
2383 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2384 }
2385 break;
2386 #if defined(TARGET_MIPS64)
2387 case OPC_DADDI:
2388 {
2389 TCGv t0 = tcg_temp_new();
2390 TCGv t1 = tcg_temp_new();
2391 TCGv t2 = tcg_temp_new();
2392 TCGLabel *l1 = gen_new_label();
2393
2394 gen_load_gpr(t1, rs);
2395 tcg_gen_addi_tl(t0, t1, uimm);
2396
2397 tcg_gen_xori_tl(t1, t1, ~uimm);
2398 tcg_gen_xori_tl(t2, t0, uimm);
2399 tcg_gen_and_tl(t1, t1, t2);
2400 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2401 /* operands of same sign, result different sign */
2402 generate_exception(ctx, EXCP_OVERFLOW);
2403 gen_set_label(l1);
2404 gen_store_gpr(t0, rt);
2405 }
2406 break;
2407 case OPC_DADDIU:
2408 if (rs != 0) {
2409 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2410 } else {
2411 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2412 }
2413 break;
2414 #endif
2415 }
2416 }
2417
2418 /* Logic with immediate operand */
2419 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2420 int rt, int rs, int16_t imm)
2421 {
2422 target_ulong uimm;
2423
2424 if (rt == 0) {
2425 /* If no destination, treat it as a NOP. */
2426 return;
2427 }
2428 uimm = (uint16_t)imm;
2429 switch (opc) {
2430 case OPC_ANDI:
2431 if (likely(rs != 0)) {
2432 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2433 } else {
2434 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2435 }
2436 break;
2437 case OPC_ORI:
2438 if (rs != 0) {
2439 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2440 } else {
2441 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2442 }
2443 break;
2444 case OPC_XORI:
2445 if (likely(rs != 0)) {
2446 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2447 } else {
2448 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2449 }
2450 break;
2451 case OPC_LUI:
2452 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2453 /* OPC_AUI */
2454 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2455 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2456 } else {
2457 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2458 }
2459 break;
2460
2461 default:
2462 break;
2463 }
2464 }
2465
2466 /* Set on less than with immediate operand */
2467 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2468 int rt, int rs, int16_t imm)
2469 {
2470 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2471 TCGv t0;
2472
2473 if (rt == 0) {
2474 /* If no destination, treat it as a NOP. */
2475 return;
2476 }
2477 t0 = tcg_temp_new();
2478 gen_load_gpr(t0, rs);
2479 switch (opc) {
2480 case OPC_SLTI:
2481 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2482 break;
2483 case OPC_SLTIU:
2484 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2485 break;
2486 }
2487 }
2488
2489 /* Shifts with immediate operand */
2490 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2491 int rt, int rs, int16_t imm)
2492 {
2493 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2494 TCGv t0;
2495
2496 if (rt == 0) {
2497 /* If no destination, treat it as a NOP. */
2498 return;
2499 }
2500
2501 t0 = tcg_temp_new();
2502 gen_load_gpr(t0, rs);
2503 switch (opc) {
2504 case OPC_SLL:
2505 tcg_gen_shli_tl(t0, t0, uimm);
2506 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2507 break;
2508 case OPC_SRA:
2509 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2510 break;
2511 case OPC_SRL:
2512 if (uimm != 0) {
2513 tcg_gen_ext32u_tl(t0, t0);
2514 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2515 } else {
2516 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2517 }
2518 break;
2519 case OPC_ROTR:
2520 if (uimm != 0) {
2521 TCGv_i32 t1 = tcg_temp_new_i32();
2522
2523 tcg_gen_trunc_tl_i32(t1, t0);
2524 tcg_gen_rotri_i32(t1, t1, uimm);
2525 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2526 } else {
2527 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2528 }
2529 break;
2530 #if defined(TARGET_MIPS64)
2531 case OPC_DSLL:
2532 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2533 break;
2534 case OPC_DSRA:
2535 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2536 break;
2537 case OPC_DSRL:
2538 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2539 break;
2540 case OPC_DROTR:
2541 if (uimm != 0) {
2542 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2543 } else {
2544 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2545 }
2546 break;
2547 case OPC_DSLL32:
2548 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2549 break;
2550 case OPC_DSRA32:
2551 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2552 break;
2553 case OPC_DSRL32:
2554 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2555 break;
2556 case OPC_DROTR32:
2557 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2558 break;
2559 #endif
2560 }
2561 }
2562
2563 /* Arithmetic */
2564 static void gen_arith(DisasContext *ctx, uint32_t opc,
2565 int rd, int rs, int rt)
2566 {
2567 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2568 && opc != OPC_DADD && opc != OPC_DSUB) {
2569 /*
2570 * If no destination, treat it as a NOP.
2571 * For add & sub, we must generate the overflow exception when needed.
2572 */
2573 return;
2574 }
2575
2576 switch (opc) {
2577 case OPC_ADD:
2578 {
2579 TCGv t0 = tcg_temp_new();
2580 TCGv t1 = tcg_temp_new();
2581 TCGv t2 = tcg_temp_new();
2582 TCGLabel *l1 = gen_new_label();
2583
2584 gen_load_gpr(t1, rs);
2585 gen_load_gpr(t2, rt);
2586 tcg_gen_add_tl(t0, t1, t2);
2587 tcg_gen_ext32s_tl(t0, t0);
2588 tcg_gen_xor_tl(t1, t1, t2);
2589 tcg_gen_xor_tl(t2, t0, t2);
2590 tcg_gen_andc_tl(t1, t2, t1);
2591 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2592 /* operands of same sign, result different sign */
2593 generate_exception(ctx, EXCP_OVERFLOW);
2594 gen_set_label(l1);
2595 gen_store_gpr(t0, rd);
2596 }
2597 break;
2598 case OPC_ADDU:
2599 if (rs != 0 && rt != 0) {
2600 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2601 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2602 } else if (rs == 0 && rt != 0) {
2603 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2604 } else if (rs != 0 && rt == 0) {
2605 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2606 } else {
2607 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2608 }
2609 break;
2610 case OPC_SUB:
2611 {
2612 TCGv t0 = tcg_temp_new();
2613 TCGv t1 = tcg_temp_new();
2614 TCGv t2 = tcg_temp_new();
2615 TCGLabel *l1 = gen_new_label();
2616
2617 gen_load_gpr(t1, rs);
2618 gen_load_gpr(t2, rt);
2619 tcg_gen_sub_tl(t0, t1, t2);
2620 tcg_gen_ext32s_tl(t0, t0);
2621 tcg_gen_xor_tl(t2, t1, t2);
2622 tcg_gen_xor_tl(t1, t0, t1);
2623 tcg_gen_and_tl(t1, t1, t2);
2624 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2625 /*
2626 * operands of different sign, first operand and the result
2627 * of different sign
2628 */
2629 generate_exception(ctx, EXCP_OVERFLOW);
2630 gen_set_label(l1);
2631 gen_store_gpr(t0, rd);
2632 }
2633 break;
2634 case OPC_SUBU:
2635 if (rs != 0 && rt != 0) {
2636 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2637 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2638 } else if (rs == 0 && rt != 0) {
2639 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2640 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2641 } else if (rs != 0 && rt == 0) {
2642 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2643 } else {
2644 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2645 }
2646 break;
2647 #if defined(TARGET_MIPS64)
2648 case OPC_DADD:
2649 {
2650 TCGv t0 = tcg_temp_new();
2651 TCGv t1 = tcg_temp_new();
2652 TCGv t2 = tcg_temp_new();
2653 TCGLabel *l1 = gen_new_label();
2654
2655 gen_load_gpr(t1, rs);
2656 gen_load_gpr(t2, rt);
2657 tcg_gen_add_tl(t0, t1, t2);
2658 tcg_gen_xor_tl(t1, t1, t2);
2659 tcg_gen_xor_tl(t2, t0, t2);
2660 tcg_gen_andc_tl(t1, t2, t1);
2661 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2662 /* operands of same sign, result different sign */
2663 generate_exception(ctx, EXCP_OVERFLOW);
2664 gen_set_label(l1);
2665 gen_store_gpr(t0, rd);
2666 }
2667 break;
2668 case OPC_DADDU:
2669 if (rs != 0 && rt != 0) {
2670 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2671 } else if (rs == 0 && rt != 0) {
2672 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2673 } else if (rs != 0 && rt == 0) {
2674 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2675 } else {
2676 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2677 }
2678 break;
2679 case OPC_DSUB:
2680 {
2681 TCGv t0 = tcg_temp_new();
2682 TCGv t1 = tcg_temp_new();
2683 TCGv t2 = tcg_temp_new();
2684 TCGLabel *l1 = gen_new_label();
2685
2686 gen_load_gpr(t1, rs);
2687 gen_load_gpr(t2, rt);
2688 tcg_gen_sub_tl(t0, t1, t2);
2689 tcg_gen_xor_tl(t2, t1, t2);
2690 tcg_gen_xor_tl(t1, t0, t1);
2691 tcg_gen_and_tl(t1, t1, t2);
2692 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2693 /*
2694 * Operands of different sign, first operand and result different
2695 * sign.
2696 */
2697 generate_exception(ctx, EXCP_OVERFLOW);
2698 gen_set_label(l1);
2699 gen_store_gpr(t0, rd);
2700 }
2701 break;
2702 case OPC_DSUBU:
2703 if (rs != 0 && rt != 0) {
2704 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2705 } else if (rs == 0 && rt != 0) {
2706 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2707 } else if (rs != 0 && rt == 0) {
2708 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2709 } else {
2710 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2711 }
2712 break;
2713 #endif
2714 case OPC_MUL:
2715 if (likely(rs != 0 && rt != 0)) {
2716 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2717 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2718 } else {
2719 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2720 }
2721 break;
2722 }
2723 }
2724
2725 /* Conditional move */
2726 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2727 int rd, int rs, int rt)
2728 {
2729 TCGv t0, t1, t2;
2730
2731 if (rd == 0) {
2732 /* If no destination, treat it as a NOP. */
2733 return;
2734 }
2735
2736 t0 = tcg_temp_new();
2737 gen_load_gpr(t0, rt);
2738 t1 = tcg_constant_tl(0);
2739 t2 = tcg_temp_new();
2740 gen_load_gpr(t2, rs);
2741 switch (opc) {
2742 case OPC_MOVN:
2743 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2744 break;
2745 case OPC_MOVZ:
2746 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2747 break;
2748 case OPC_SELNEZ:
2749 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2750 break;
2751 case OPC_SELEQZ:
2752 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2753 break;
2754 }
2755 }
2756
2757 /* Logic */
2758 static void gen_logic(DisasContext *ctx, uint32_t opc,
2759 int rd, int rs, int rt)
2760 {
2761 if (rd == 0) {
2762 /* If no destination, treat it as a NOP. */
2763 return;
2764 }
2765
2766 switch (opc) {
2767 case OPC_AND:
2768 if (likely(rs != 0 && rt != 0)) {
2769 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2770 } else {
2771 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2772 }
2773 break;
2774 case OPC_NOR:
2775 if (rs != 0 && rt != 0) {
2776 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2777 } else if (rs == 0 && rt != 0) {
2778 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2779 } else if (rs != 0 && rt == 0) {
2780 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2781 } else {
2782 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2783 }
2784 break;
2785 case OPC_OR:
2786 if (likely(rs != 0 && rt != 0)) {
2787 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2788 } else if (rs == 0 && rt != 0) {
2789 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2790 } else if (rs != 0 && rt == 0) {
2791 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2792 } else {
2793 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2794 }
2795 break;
2796 case OPC_XOR:
2797 if (likely(rs != 0 && rt != 0)) {
2798 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2799 } else if (rs == 0 && rt != 0) {
2800 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2801 } else if (rs != 0 && rt == 0) {
2802 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2803 } else {
2804 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2805 }
2806 break;
2807 }
2808 }
2809
2810 /* Set on lower than */
2811 static void gen_slt(DisasContext *ctx, uint32_t opc,
2812 int rd, int rs, int rt)
2813 {
2814 TCGv t0, t1;
2815
2816 if (rd == 0) {
2817 /* If no destination, treat it as a NOP. */
2818 return;
2819 }
2820
2821 t0 = tcg_temp_new();
2822 t1 = tcg_temp_new();
2823 gen_load_gpr(t0, rs);
2824 gen_load_gpr(t1, rt);
2825 switch (opc) {
2826 case OPC_SLT:
2827 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2828 break;
2829 case OPC_SLTU:
2830 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2831 break;
2832 }
2833 }
2834
2835 /* Shifts */
2836 static void gen_shift(DisasContext *ctx, uint32_t opc,
2837 int rd, int rs, int rt)
2838 {
2839 TCGv t0, t1;
2840
2841 if (rd == 0) {
2842 /*
2843 * If no destination, treat it as a NOP.
2844 * For add & sub, we must generate the overflow exception when needed.
2845 */
2846 return;
2847 }
2848
2849 t0 = tcg_temp_new();
2850 t1 = tcg_temp_new();
2851 gen_load_gpr(t0, rs);
2852 gen_load_gpr(t1, rt);
2853 switch (opc) {
2854 case OPC_SLLV:
2855 tcg_gen_andi_tl(t0, t0, 0x1f);
2856 tcg_gen_shl_tl(t0, t1, t0);
2857 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2858 break;
2859 case OPC_SRAV:
2860 tcg_gen_andi_tl(t0, t0, 0x1f);
2861 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2862 break;
2863 case OPC_SRLV:
2864 tcg_gen_ext32u_tl(t1, t1);
2865 tcg_gen_andi_tl(t0, t0, 0x1f);
2866 tcg_gen_shr_tl(t0, t1, t0);
2867 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2868 break;
2869 case OPC_ROTRV:
2870 {
2871 TCGv_i32 t2 = tcg_temp_new_i32();
2872 TCGv_i32 t3 = tcg_temp_new_i32();
2873
2874 tcg_gen_trunc_tl_i32(t2, t0);
2875 tcg_gen_trunc_tl_i32(t3, t1);
2876 tcg_gen_andi_i32(t2, t2, 0x1f);
2877 tcg_gen_rotr_i32(t2, t3, t2);
2878 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2879 }
2880 break;
2881 #if defined(TARGET_MIPS64)
2882 case OPC_DSLLV:
2883 tcg_gen_andi_tl(t0, t0, 0x3f);
2884 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2885 break;
2886 case OPC_DSRAV:
2887 tcg_gen_andi_tl(t0, t0, 0x3f);
2888 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2889 break;
2890 case OPC_DSRLV:
2891 tcg_gen_andi_tl(t0, t0, 0x3f);
2892 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2893 break;
2894 case OPC_DROTRV:
2895 tcg_gen_andi_tl(t0, t0, 0x3f);
2896 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2897 break;
2898 #endif
2899 }
2900 }
2901
2902 /* Arithmetic on HI/LO registers */
2903 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2904 {
2905 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2906 /* Treat as NOP. */
2907 return;
2908 }
2909
2910 if (acc != 0) {
2911 check_dsp(ctx);
2912 }
2913
2914 switch (opc) {
2915 case OPC_MFHI:
2916 #if defined(TARGET_MIPS64)
2917 if (acc != 0) {
2918 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2919 } else
2920 #endif
2921 {
2922 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2923 }
2924 break;
2925 case OPC_MFLO:
2926 #if defined(TARGET_MIPS64)
2927 if (acc != 0) {
2928 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2929 } else
2930 #endif
2931 {
2932 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2933 }
2934 break;
2935 case OPC_MTHI:
2936 if (reg != 0) {
2937 #if defined(TARGET_MIPS64)
2938 if (acc != 0) {
2939 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2940 } else
2941 #endif
2942 {
2943 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2944 }
2945 } else {
2946 tcg_gen_movi_tl(cpu_HI[acc], 0);
2947 }
2948 break;
2949 case OPC_MTLO:
2950 if (reg != 0) {
2951 #if defined(TARGET_MIPS64)
2952 if (acc != 0) {
2953 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2954 } else
2955 #endif
2956 {
2957 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2958 }
2959 } else {
2960 tcg_gen_movi_tl(cpu_LO[acc], 0);
2961 }
2962 break;
2963 }
2964 }
2965
2966 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
2967 MemOp memop)
2968 {
2969 TCGv t0 = tcg_temp_new();
2970 tcg_gen_qemu_ld_tl(t0, tcg_constant_tl(addr), memidx, memop);
2971 gen_store_gpr(t0, reg);
2972 }
2973
2974 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
2975 int rs)
2976 {
2977 target_long offset;
2978 target_long addr;
2979
2980 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
2981 case OPC_ADDIUPC:
2982 if (rs != 0) {
2983 offset = sextract32(ctx->opcode << 2, 0, 21);
2984 addr = addr_add(ctx, pc, offset);
2985 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2986 }
2987 break;
2988 case R6_OPC_LWPC:
2989 offset = sextract32(ctx->opcode << 2, 0, 21);
2990 addr = addr_add(ctx, pc, offset);
2991 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
2992 break;
2993 #if defined(TARGET_MIPS64)
2994 case OPC_LWUPC:
2995 check_mips_64(ctx);
2996 offset = sextract32(ctx->opcode << 2, 0, 21);
2997 addr = addr_add(ctx, pc, offset);
2998 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
2999 break;
3000 #endif
3001 default:
3002 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3003 case OPC_AUIPC:
3004 if (rs != 0) {
3005 offset = sextract32(ctx->opcode, 0, 16) << 16;
3006 addr = addr_add(ctx, pc, offset);
3007 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3008 }
3009 break;
3010 case OPC_ALUIPC:
3011 if (rs != 0) {
3012 offset = sextract32(ctx->opcode, 0, 16) << 16;
3013 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3014 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3015 }
3016 break;
3017 #if defined(TARGET_MIPS64)
3018 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3019 case R6_OPC_LDPC + (1 << 16):
3020 case R6_OPC_LDPC + (2 << 16):
3021 case R6_OPC_LDPC + (3 << 16):
3022 check_mips_64(ctx);
3023 offset = sextract32(ctx->opcode << 3, 0, 21);
3024 addr = addr_add(ctx, (pc & ~0x7), offset);
3025 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ);
3026 break;
3027 #endif
3028 default:
3029 MIPS_INVAL("OPC_PCREL");
3030 gen_reserved_instruction(ctx);
3031 break;
3032 }
3033 break;
3034 }
3035 }
3036
3037 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3038 {
3039 TCGv t0, t1;
3040
3041 if (rd == 0) {
3042 /* Treat as NOP. */
3043 return;
3044 }
3045
3046 t0 = tcg_temp_new();
3047 t1 = tcg_temp_new();
3048
3049 gen_load_gpr(t0, rs);
3050 gen_load_gpr(t1, rt);
3051
3052 switch (opc) {
3053 case R6_OPC_DIV:
3054 {
3055 TCGv t2 = tcg_temp_new();
3056 TCGv t3 = tcg_temp_new();
3057 tcg_gen_ext32s_tl(t0, t0);
3058 tcg_gen_ext32s_tl(t1, t1);
3059 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3060 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3061 tcg_gen_and_tl(t2, t2, t3);
3062 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3063 tcg_gen_or_tl(t2, t2, t3);
3064 tcg_gen_movi_tl(t3, 0);
3065 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3066 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3067 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3068 }
3069 break;
3070 case R6_OPC_MOD:
3071 {
3072 TCGv t2 = tcg_temp_new();
3073 TCGv t3 = tcg_temp_new();
3074 tcg_gen_ext32s_tl(t0, t0);
3075 tcg_gen_ext32s_tl(t1, t1);
3076 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3077 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3078 tcg_gen_and_tl(t2, t2, t3);
3079 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3080 tcg_gen_or_tl(t2, t2, t3);
3081 tcg_gen_movi_tl(t3, 0);
3082 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3083 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3084 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3085 }
3086 break;
3087 case R6_OPC_DIVU:
3088 {
3089 TCGv t2 = tcg_constant_tl(0);
3090 TCGv t3 = tcg_constant_tl(1);
3091 tcg_gen_ext32u_tl(t0, t0);
3092 tcg_gen_ext32u_tl(t1, t1);
3093 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3094 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3095 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3096 }
3097 break;
3098 case R6_OPC_MODU:
3099 {
3100 TCGv t2 = tcg_constant_tl(0);
3101 TCGv t3 = tcg_constant_tl(1);
3102 tcg_gen_ext32u_tl(t0, t0);
3103 tcg_gen_ext32u_tl(t1, t1);
3104 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3105 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3106 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3107 }
3108 break;
3109 case R6_OPC_MUL:
3110 {
3111 TCGv_i32 t2 = tcg_temp_new_i32();
3112 TCGv_i32 t3 = tcg_temp_new_i32();
3113 tcg_gen_trunc_tl_i32(t2, t0);
3114 tcg_gen_trunc_tl_i32(t3, t1);
3115 tcg_gen_mul_i32(t2, t2, t3);
3116 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3117 }
3118 break;
3119 case R6_OPC_MUH:
3120 {
3121 TCGv_i32 t2 = tcg_temp_new_i32();
3122 TCGv_i32 t3 = tcg_temp_new_i32();
3123 tcg_gen_trunc_tl_i32(t2, t0);
3124 tcg_gen_trunc_tl_i32(t3, t1);
3125 tcg_gen_muls2_i32(t2, t3, t2, t3);
3126 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3127 }
3128 break;
3129 case R6_OPC_MULU:
3130 {
3131 TCGv_i32 t2 = tcg_temp_new_i32();
3132 TCGv_i32 t3 = tcg_temp_new_i32();
3133 tcg_gen_trunc_tl_i32(t2, t0);
3134 tcg_gen_trunc_tl_i32(t3, t1);
3135 tcg_gen_mul_i32(t2, t2, t3);
3136 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3137 }
3138 break;
3139 case R6_OPC_MUHU:
3140 {
3141 TCGv_i32 t2 = tcg_temp_new_i32();
3142 TCGv_i32 t3 = tcg_temp_new_i32();
3143 tcg_gen_trunc_tl_i32(t2, t0);
3144 tcg_gen_trunc_tl_i32(t3, t1);
3145 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3146 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3147 }
3148 break;
3149 #if defined(TARGET_MIPS64)
3150 case R6_OPC_DDIV:
3151 {
3152 TCGv t2 = tcg_temp_new();
3153 TCGv t3 = tcg_temp_new();
3154 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3155 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3156 tcg_gen_and_tl(t2, t2, t3);
3157 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3158 tcg_gen_or_tl(t2, t2, t3);
3159 tcg_gen_movi_tl(t3, 0);
3160 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3161 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3162 }
3163 break;
3164 case R6_OPC_DMOD:
3165 {
3166 TCGv t2 = tcg_temp_new();
3167 TCGv t3 = tcg_temp_new();
3168 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3169 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3170 tcg_gen_and_tl(t2, t2, t3);
3171 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3172 tcg_gen_or_tl(t2, t2, t3);
3173 tcg_gen_movi_tl(t3, 0);
3174 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3175 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3176 }
3177 break;
3178 case R6_OPC_DDIVU:
3179 {
3180 TCGv t2 = tcg_constant_tl(0);
3181 TCGv t3 = tcg_constant_tl(1);
3182 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3183 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3184 }
3185 break;
3186 case R6_OPC_DMODU:
3187 {
3188 TCGv t2 = tcg_constant_tl(0);
3189 TCGv t3 = tcg_constant_tl(1);
3190 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3191 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3192 }
3193 break;
3194 case R6_OPC_DMUL:
3195 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3196 break;
3197 case R6_OPC_DMUH:
3198 {
3199 TCGv t2 = tcg_temp_new();
3200 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3201 }
3202 break;
3203 case R6_OPC_DMULU:
3204 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3205 break;
3206 case R6_OPC_DMUHU:
3207 {
3208 TCGv t2 = tcg_temp_new();
3209 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3210 }
3211 break;
3212 #endif
3213 default:
3214 MIPS_INVAL("r6 mul/div");
3215 gen_reserved_instruction(ctx);
3216 break;
3217 }
3218 }
3219
3220 #if defined(TARGET_MIPS64)
3221 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3222 {
3223 TCGv t0, t1;
3224
3225 t0 = tcg_temp_new();
3226 t1 = tcg_temp_new();
3227
3228 gen_load_gpr(t0, rs);
3229 gen_load_gpr(t1, rt);
3230
3231 switch (opc) {
3232 case MMI_OPC_DIV1:
3233 {
3234 TCGv t2 = tcg_temp_new();
3235 TCGv t3 = tcg_temp_new();
3236 tcg_gen_ext32s_tl(t0, t0);
3237 tcg_gen_ext32s_tl(t1, t1);
3238 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3239 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3240 tcg_gen_and_tl(t2, t2, t3);
3241 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3242 tcg_gen_or_tl(t2, t2, t3);
3243 tcg_gen_movi_tl(t3, 0);
3244 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3245 tcg_gen_div_tl(cpu_LO[1], t0, t1);
3246 tcg_gen_rem_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 case MMI_OPC_DIVU1:
3252 {
3253 TCGv t2 = tcg_constant_tl(0);
3254 TCGv t3 = tcg_constant_tl(1);
3255 tcg_gen_ext32u_tl(t0, t0);
3256 tcg_gen_ext32u_tl(t1, t1);
3257 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3258 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3259 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3260 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3261 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3262 }
3263 break;
3264 default:
3265 MIPS_INVAL("div1 TX79");
3266 gen_reserved_instruction(ctx);
3267 break;
3268 }
3269 }
3270 #endif
3271
3272 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3273 int acc, int rs, int rt)
3274 {
3275 TCGv t0, t1;
3276
3277 t0 = tcg_temp_new();
3278 t1 = tcg_temp_new();
3279
3280 gen_load_gpr(t0, rs);
3281 gen_load_gpr(t1, rt);
3282
3283 if (acc != 0) {
3284 check_dsp(ctx);
3285 }
3286
3287 switch (opc) {
3288 case OPC_DIV:
3289 {
3290 TCGv t2 = tcg_temp_new();
3291 TCGv t3 = tcg_temp_new();
3292 tcg_gen_ext32s_tl(t0, t0);
3293 tcg_gen_ext32s_tl(t1, t1);
3294 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3295 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3296 tcg_gen_and_tl(t2, t2, t3);
3297 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3298 tcg_gen_or_tl(t2, t2, t3);
3299 tcg_gen_movi_tl(t3, 0);
3300 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3301 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3302 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3303 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3304 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3305 }
3306 break;
3307 case OPC_DIVU:
3308 {
3309 TCGv t2 = tcg_constant_tl(0);
3310 TCGv t3 = tcg_constant_tl(1);
3311 tcg_gen_ext32u_tl(t0, t0);
3312 tcg_gen_ext32u_tl(t1, t1);
3313 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3314 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3315 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3316 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3317 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3318 }
3319 break;
3320 case OPC_MULT:
3321 {
3322 TCGv_i32 t2 = tcg_temp_new_i32();
3323 TCGv_i32 t3 = tcg_temp_new_i32();
3324 tcg_gen_trunc_tl_i32(t2, t0);
3325 tcg_gen_trunc_tl_i32(t3, t1);
3326 tcg_gen_muls2_i32(t2, t3, t2, t3);
3327 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3328 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3329 }
3330 break;
3331 case OPC_MULTU:
3332 {
3333 TCGv_i32 t2 = tcg_temp_new_i32();
3334 TCGv_i32 t3 = tcg_temp_new_i32();
3335 tcg_gen_trunc_tl_i32(t2, t0);
3336 tcg_gen_trunc_tl_i32(t3, t1);
3337 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3338 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3339 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3340 }
3341 break;
3342 #if defined(TARGET_MIPS64)
3343 case OPC_DDIV:
3344 {
3345 TCGv t2 = tcg_temp_new();
3346 TCGv t3 = tcg_temp_new();
3347 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3348 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3349 tcg_gen_and_tl(t2, t2, t3);
3350 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3351 tcg_gen_or_tl(t2, t2, t3);
3352 tcg_gen_movi_tl(t3, 0);
3353 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3354 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3355 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3356 }
3357 break;
3358 case OPC_DDIVU:
3359 {
3360 TCGv t2 = tcg_constant_tl(0);
3361 TCGv t3 = tcg_constant_tl(1);
3362 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3363 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3364 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3365 }
3366 break;
3367 case OPC_DMULT:
3368 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3369 break;
3370 case OPC_DMULTU:
3371 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3372 break;
3373 #endif
3374 case OPC_MADD:
3375 {
3376 TCGv_i64 t2 = tcg_temp_new_i64();
3377 TCGv_i64 t3 = tcg_temp_new_i64();
3378
3379 tcg_gen_ext_tl_i64(t2, t0);
3380 tcg_gen_ext_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_MADDU:
3389 {
3390 TCGv_i64 t2 = tcg_temp_new_i64();
3391 TCGv_i64 t3 = tcg_temp_new_i64();
3392
3393 tcg_gen_ext32u_tl(t0, t0);
3394 tcg_gen_ext32u_tl(t1, t1);
3395 tcg_gen_extu_tl_i64(t2, t0);
3396 tcg_gen_extu_tl_i64(t3, t1);
3397 tcg_gen_mul_i64(t2, t2, t3);
3398 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3399 tcg_gen_add_i64(t2, t2, t3);
3400 gen_move_low32(cpu_LO[acc], t2);
3401 gen_move_high32(cpu_HI[acc], t2);
3402 }
3403 break;
3404 case OPC_MSUB:
3405 {
3406 TCGv_i64 t2 = tcg_temp_new_i64();
3407 TCGv_i64 t3 = tcg_temp_new_i64();
3408
3409 tcg_gen_ext_tl_i64(t2, t0);
3410 tcg_gen_ext_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 case OPC_MSUBU:
3419 {
3420 TCGv_i64 t2 = tcg_temp_new_i64();
3421 TCGv_i64 t3 = tcg_temp_new_i64();
3422
3423 tcg_gen_ext32u_tl(t0, t0);
3424 tcg_gen_ext32u_tl(t1, t1);
3425 tcg_gen_extu_tl_i64(t2, t0);
3426 tcg_gen_extu_tl_i64(t3, t1);
3427 tcg_gen_mul_i64(t2, t2, t3);
3428 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3429 tcg_gen_sub_i64(t2, t3, t2);
3430 gen_move_low32(cpu_LO[acc], t2);
3431 gen_move_high32(cpu_HI[acc], t2);
3432 }
3433 break;
3434 default:
3435 MIPS_INVAL("mul/div");
3436 gen_reserved_instruction(ctx);
3437 break;
3438 }
3439 }
3440
3441 /*
3442 * These MULT[U] and MADD[U] instructions implemented in for example
3443 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3444 * architectures are special three-operand variants with the syntax
3445 *
3446 * MULT[U][1] rd, rs, rt
3447 *
3448 * such that
3449 *
3450 * (rd, LO, HI) <- rs * rt
3451 *
3452 * and
3453 *
3454 * MADD[U][1] rd, rs, rt
3455 *
3456 * such that
3457 *
3458 * (rd, LO, HI) <- (LO, HI) + rs * rt
3459 *
3460 * where the low-order 32-bits of the result is placed into both the
3461 * GPR rd and the special register LO. The high-order 32-bits of the
3462 * result is placed into the special register HI.
3463 *
3464 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3465 * which is the zero register that always reads as 0.
3466 */
3467 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3468 int rd, int rs, int rt)
3469 {
3470 TCGv t0 = tcg_temp_new();
3471 TCGv t1 = tcg_temp_new();
3472 int acc = 0;
3473
3474 gen_load_gpr(t0, rs);
3475 gen_load_gpr(t1, rt);
3476
3477 switch (opc) {
3478 case MMI_OPC_MULT1:
3479 acc = 1;
3480 /* Fall through */
3481 case OPC_MULT:
3482 {
3483 TCGv_i32 t2 = tcg_temp_new_i32();
3484 TCGv_i32 t3 = tcg_temp_new_i32();
3485 tcg_gen_trunc_tl_i32(t2, t0);
3486 tcg_gen_trunc_tl_i32(t3, t1);
3487 tcg_gen_muls2_i32(t2, t3, t2, t3);
3488 if (rd) {
3489 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3490 }
3491 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3492 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3493 }
3494 break;
3495 case MMI_OPC_MULTU1:
3496 acc = 1;
3497 /* Fall through */
3498 case OPC_MULTU:
3499 {
3500 TCGv_i32 t2 = tcg_temp_new_i32();
3501 TCGv_i32 t3 = tcg_temp_new_i32();
3502 tcg_gen_trunc_tl_i32(t2, t0);
3503 tcg_gen_trunc_tl_i32(t3, t1);
3504 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3505 if (rd) {
3506 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3507 }
3508 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3509 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3510 }
3511 break;
3512 case MMI_OPC_MADD1:
3513 acc = 1;
3514 /* Fall through */
3515 case MMI_OPC_MADD:
3516 {
3517 TCGv_i64 t2 = tcg_temp_new_i64();
3518 TCGv_i64 t3 = tcg_temp_new_i64();
3519
3520 tcg_gen_ext_tl_i64(t2, t0);
3521 tcg_gen_ext_tl_i64(t3, t1);
3522 tcg_gen_mul_i64(t2, t2, t3);
3523 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3524 tcg_gen_add_i64(t2, t2, t3);
3525 gen_move_low32(cpu_LO[acc], t2);
3526 gen_move_high32(cpu_HI[acc], t2);
3527 if (rd) {
3528 gen_move_low32(cpu_gpr[rd], t2);
3529 }
3530 }
3531 break;
3532 case MMI_OPC_MADDU1:
3533 acc = 1;
3534 /* Fall through */
3535 case MMI_OPC_MADDU:
3536 {
3537 TCGv_i64 t2 = tcg_temp_new_i64();
3538 TCGv_i64 t3 = tcg_temp_new_i64();
3539
3540 tcg_gen_ext32u_tl(t0, t0);
3541 tcg_gen_ext32u_tl(t1, t1);
3542 tcg_gen_extu_tl_i64(t2, t0);
3543 tcg_gen_extu_tl_i64(t3, t1);
3544 tcg_gen_mul_i64(t2, t2, t3);
3545 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3546 tcg_gen_add_i64(t2, t2, t3);
3547 gen_move_low32(cpu_LO[acc], t2);
3548 gen_move_high32(cpu_HI[acc], t2);
3549 if (rd) {
3550 gen_move_low32(cpu_gpr[rd], t2);
3551 }
3552 }
3553 break;
3554 default:
3555 MIPS_INVAL("mul/madd TXx9");
3556 gen_reserved_instruction(ctx);
3557 break;
3558 }
3559 }
3560
3561 static void gen_cl(DisasContext *ctx, uint32_t opc,
3562 int rd, int rs)
3563 {
3564 TCGv t0;
3565
3566 if (rd == 0) {
3567 /* Treat as NOP. */
3568 return;
3569 }
3570 t0 = cpu_gpr[rd];
3571 gen_load_gpr(t0, rs);
3572
3573 switch (opc) {
3574 case OPC_CLO:
3575 case R6_OPC_CLO:
3576 #if defined(TARGET_MIPS64)
3577 case OPC_DCLO:
3578 case R6_OPC_DCLO:
3579 #endif
3580 tcg_gen_not_tl(t0, t0);
3581 break;
3582 }
3583
3584 switch (opc) {
3585 case OPC_CLO:
3586 case R6_OPC_CLO:
3587 case OPC_CLZ:
3588 case R6_OPC_CLZ:
3589 tcg_gen_ext32u_tl(t0, t0);
3590 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3591 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3592 break;
3593 #if defined(TARGET_MIPS64)
3594 case OPC_DCLO:
3595 case R6_OPC_DCLO:
3596 case OPC_DCLZ:
3597 case R6_OPC_DCLZ:
3598 tcg_gen_clzi_i64(t0, t0, 64);
3599 break;
3600 #endif
3601 }
3602 }
3603
3604 /* Godson integer instructions */
3605 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3606 int rd, int rs, int rt)
3607 {
3608 TCGv t0, t1;
3609
3610 if (rd == 0) {
3611 /* Treat as NOP. */
3612 return;
3613 }
3614
3615 t0 = tcg_temp_new();
3616 t1 = tcg_temp_new();
3617 gen_load_gpr(t0, rs);
3618 gen_load_gpr(t1, rt);
3619
3620 switch (opc) {
3621 case OPC_MULT_G_2E:
3622 case OPC_MULT_G_2F:
3623 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3624 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3625 break;
3626 case OPC_MULTU_G_2E:
3627 case OPC_MULTU_G_2F:
3628 tcg_gen_ext32u_tl(t0, t0);
3629 tcg_gen_ext32u_tl(t1, t1);
3630 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3631 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3632 break;
3633 case OPC_DIV_G_2E:
3634 case OPC_DIV_G_2F:
3635 {
3636 TCGLabel *l1 = gen_new_label();
3637 TCGLabel *l2 = gen_new_label();
3638 TCGLabel *l3 = gen_new_label();
3639 tcg_gen_ext32s_tl(t0, t0);
3640 tcg_gen_ext32s_tl(t1, t1);
3641 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3642 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3643 tcg_gen_br(l3);
3644 gen_set_label(l1);
3645 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3646 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3647 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3648 tcg_gen_br(l3);
3649 gen_set_label(l2);
3650 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3651 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3652 gen_set_label(l3);
3653 }
3654 break;
3655 case OPC_DIVU_G_2E:
3656 case OPC_DIVU_G_2F:
3657 {
3658 TCGLabel *l1 = gen_new_label();
3659 TCGLabel *l2 = gen_new_label();
3660 tcg_gen_ext32u_tl(t0, t0);
3661 tcg_gen_ext32u_tl(t1, t1);
3662 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3663 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3664 tcg_gen_br(l2);
3665 gen_set_label(l1);
3666 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3667 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3668 gen_set_label(l2);
3669 }
3670 break;
3671 case OPC_MOD_G_2E:
3672 case OPC_MOD_G_2F:
3673 {
3674 TCGLabel *l1 = gen_new_label();
3675 TCGLabel *l2 = gen_new_label();
3676 TCGLabel *l3 = gen_new_label();
3677 tcg_gen_ext32u_tl(t0, t0);
3678 tcg_gen_ext32u_tl(t1, t1);
3679 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3680 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3681 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3682 gen_set_label(l1);
3683 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3684 tcg_gen_br(l3);
3685 gen_set_label(l2);
3686 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3687 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3688 gen_set_label(l3);
3689 }
3690 break;
3691 case OPC_MODU_G_2E:
3692 case OPC_MODU_G_2F:
3693 {
3694 TCGLabel *l1 = gen_new_label();
3695 TCGLabel *l2 = gen_new_label();
3696 tcg_gen_ext32u_tl(t0, t0);
3697 tcg_gen_ext32u_tl(t1, t1);
3698 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3699 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3700 tcg_gen_br(l2);
3701 gen_set_label(l1);
3702 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3703 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3704 gen_set_label(l2);
3705 }
3706 break;
3707 #if defined(TARGET_MIPS64)
3708 case OPC_DMULT_G_2E:
3709 case OPC_DMULT_G_2F:
3710 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3711 break;
3712 case OPC_DMULTU_G_2E:
3713 case OPC_DMULTU_G_2F:
3714 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3715 break;
3716 case OPC_DDIV_G_2E:
3717 case OPC_DDIV_G_2F:
3718 {
3719 TCGLabel *l1 = gen_new_label();
3720 TCGLabel *l2 = gen_new_label();
3721 TCGLabel *l3 = gen_new_label();
3722 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3723 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3724 tcg_gen_br(l3);
3725 gen_set_label(l1);
3726 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3727 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3728 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3729 tcg_gen_br(l3);
3730 gen_set_label(l2);
3731 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3732 gen_set_label(l3);
3733 }
3734 break;
3735 case OPC_DDIVU_G_2E:
3736 case OPC_DDIVU_G_2F:
3737 {
3738 TCGLabel *l1 = gen_new_label();
3739 TCGLabel *l2 = gen_new_label();
3740 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3741 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3742 tcg_gen_br(l2);
3743 gen_set_label(l1);
3744 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3745 gen_set_label(l2);
3746 }
3747 break;
3748 case OPC_DMOD_G_2E:
3749 case OPC_DMOD_G_2F:
3750 {
3751 TCGLabel *l1 = gen_new_label();
3752 TCGLabel *l2 = gen_new_label();
3753 TCGLabel *l3 = gen_new_label();
3754 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3755 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3756 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3757 gen_set_label(l1);
3758 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3759 tcg_gen_br(l3);
3760 gen_set_label(l2);
3761 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3762 gen_set_label(l3);
3763 }
3764 break;
3765 case OPC_DMODU_G_2E:
3766 case OPC_DMODU_G_2F:
3767 {
3768 TCGLabel *l1 = gen_new_label();
3769 TCGLabel *l2 = gen_new_label();
3770 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3771 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3772 tcg_gen_br(l2);
3773 gen_set_label(l1);
3774 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3775 gen_set_label(l2);
3776 }
3777 break;
3778 #endif
3779 }
3780 }
3781
3782 /* Loongson multimedia instructions */
3783 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3784 {
3785 uint32_t opc, shift_max;
3786 TCGv_i64 t0, t1;
3787 TCGCond cond;
3788
3789 opc = MASK_LMMI(ctx->opcode);
3790 check_cp1_enabled(ctx);
3791
3792 t0 = tcg_temp_new_i64();
3793 t1 = tcg_temp_new_i64();
3794 gen_load_fpr64(ctx, t0, rs);
3795 gen_load_fpr64(ctx, t1, rt);
3796
3797 switch (opc) {
3798 case OPC_PADDSH:
3799 gen_helper_paddsh(t0, t0, t1);
3800 break;
3801 case OPC_PADDUSH:
3802 gen_helper_paddush(t0, t0, t1);
3803 break;
3804 case OPC_PADDH:
3805 gen_helper_paddh(t0, t0, t1);
3806 break;
3807 case OPC_PADDW:
3808 gen_helper_paddw(t0, t0, t1);
3809 break;
3810 case OPC_PADDSB:
3811 gen_helper_paddsb(t0, t0, t1);
3812 break;
3813 case OPC_PADDUSB:
3814 gen_helper_paddusb(t0, t0, t1);
3815 break;
3816 case OPC_PADDB:
3817 gen_helper_paddb(t0, t0, t1);
3818 break;
3819
3820 case OPC_PSUBSH:
3821 gen_helper_psubsh(t0, t0, t1);
3822 break;
3823 case OPC_PSUBUSH:
3824 gen_helper_psubush(t0, t0, t1);
3825 break;
3826 case OPC_PSUBH:
3827 gen_helper_psubh(t0, t0, t1);
3828 break;
3829 case OPC_PSUBW:
3830 gen_helper_psubw(t0, t0, t1);
3831 break;
3832 case OPC_PSUBSB:
3833 gen_helper_psubsb(t0, t0, t1);
3834 break;
3835 case OPC_PSUBUSB:
3836 gen_helper_psubusb(t0, t0, t1);
3837 break;
3838 case OPC_PSUBB:
3839 gen_helper_psubb(t0, t0, t1);
3840 break;
3841
3842 case OPC_PSHUFH:
3843 gen_helper_pshufh(t0, t0, t1);
3844 break;
3845 case OPC_PACKSSWH:
3846 gen_helper_packsswh(t0, t0, t1);
3847 break;
3848 case OPC_PACKSSHB:
3849 gen_helper_packsshb(t0, t0, t1);
3850 break;
3851 case OPC_PACKUSHB:
3852 gen_helper_packushb(t0, t0, t1);
3853 break;
3854
3855 case OPC_PUNPCKLHW:
3856 gen_helper_punpcklhw(t0, t0, t1);
3857 break;
3858 case OPC_PUNPCKHHW:
3859 gen_helper_punpckhhw(t0, t0, t1);
3860 break;
3861 case OPC_PUNPCKLBH:
3862 gen_helper_punpcklbh(t0, t0, t1);
3863 break;
3864 case OPC_PUNPCKHBH:
3865 gen_helper_punpckhbh(t0, t0, t1);
3866 break;
3867 case OPC_PUNPCKLWD:
3868 gen_helper_punpcklwd(t0, t0, t1);
3869 break;
3870 case OPC_PUNPCKHWD:
3871 gen_helper_punpckhwd(t0, t0, t1);
3872 break;
3873
3874 case OPC_PAVGH:
3875 gen_helper_pavgh(t0, t0, t1);
3876 break;
3877 case OPC_PAVGB:
3878 gen_helper_pavgb(t0, t0, t1);
3879 break;
3880 case OPC_PMAXSH:
3881 gen_helper_pmaxsh(t0, t0, t1);
3882 break;
3883 case OPC_PMINSH:
3884 gen_helper_pminsh(t0, t0, t1);
3885 break;
3886 case OPC_PMAXUB:
3887 gen_helper_pmaxub(t0, t0, t1);
3888 break;
3889 case OPC_PMINUB:
3890 gen_helper_pminub(t0, t0, t1);
3891 break;
3892
3893 case OPC_PCMPEQW:
3894 gen_helper_pcmpeqw(t0, t0, t1);
3895 break;
3896 case OPC_PCMPGTW:
3897 gen_helper_pcmpgtw(t0, t0, t1);
3898 break;
3899 case OPC_PCMPEQH:
3900 gen_helper_pcmpeqh(t0, t0, t1);
3901 break;
3902 case OPC_PCMPGTH:
3903 gen_helper_pcmpgth(t0, t0, t1);
3904 break;
3905 case OPC_PCMPEQB:
3906 gen_helper_pcmpeqb(t0, t0, t1);
3907 break;
3908 case OPC_PCMPGTB:
3909 gen_helper_pcmpgtb(t0, t0, t1);
3910 break;
3911
3912 case OPC_PSLLW:
3913 gen_helper_psllw(t0, t0, t1);
3914 break;
3915 case OPC_PSLLH:
3916 gen_helper_psllh(t0, t0, t1);
3917 break;
3918 case OPC_PSRLW:
3919 gen_helper_psrlw(t0, t0, t1);
3920 break;
3921 case OPC_PSRLH:
3922 gen_helper_psrlh(t0, t0, t1);
3923 break;
3924 case OPC_PSRAW:
3925 gen_helper_psraw(t0, t0, t1);
3926 break;
3927 case OPC_PSRAH:
3928 gen_helper_psrah(t0, t0, t1);
3929 break;
3930
3931 case OPC_PMULLH:
3932 gen_helper_pmullh(t0, t0, t1);
3933 break;
3934 case OPC_PMULHH:
3935 gen_helper_pmulhh(t0, t0, t1);
3936 break;
3937 case OPC_PMULHUH:
3938 gen_helper_pmulhuh(t0, t0, t1);
3939 break;
3940 case OPC_PMADDHW:
3941 gen_helper_pmaddhw(t0, t0, t1);
3942 break;
3943
3944 case OPC_PASUBUB:
3945 gen_helper_pasubub(t0, t0, t1);
3946 break;
3947 case OPC_BIADD:
3948 gen_helper_biadd(t0, t0);
3949 break;
3950 case OPC_PMOVMSKB:
3951 gen_helper_pmovmskb(t0, t0);
3952 break;
3953
3954 case OPC_PADDD:
3955 tcg_gen_add_i64(t0, t0, t1);
3956 break;
3957 case OPC_PSUBD:
3958 tcg_gen_sub_i64(t0, t0, t1);
3959 break;
3960 case OPC_XOR_CP2:
3961 tcg_gen_xor_i64(t0, t0, t1);
3962 break;
3963 case OPC_NOR_CP2:
3964 tcg_gen_nor_i64(t0, t0, t1);
3965 break;
3966 case OPC_AND_CP2:
3967 tcg_gen_and_i64(t0, t0, t1);
3968 break;
3969 case OPC_OR_CP2:
3970 tcg_gen_or_i64(t0, t0, t1);
3971 break;
3972
3973 case OPC_PANDN:
3974 tcg_gen_andc_i64(t0, t1, t0);
3975 break;
3976
3977 case OPC_PINSRH_0:
3978 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3979 break;
3980 case OPC_PINSRH_1:
3981 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3982 break;
3983 case OPC_PINSRH_2:
3984 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3985 break;
3986 case OPC_PINSRH_3:
3987 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3988 break;
3989
3990 case OPC_PEXTRH:
3991 tcg_gen_andi_i64(t1, t1, 3);
3992 tcg_gen_shli_i64(t1, t1, 4);
3993 tcg_gen_shr_i64(t0, t0, t1);
3994 tcg_gen_ext16u_i64(t0, t0);
3995 break;
3996
3997 case OPC_ADDU_CP2:
3998 tcg_gen_add_i64(t0, t0, t1);
3999 tcg_gen_ext32s_i64(t0, t0);
4000 break;
4001 case OPC_SUBU_CP2:
4002 tcg_gen_sub_i64(t0, t0, t1);
4003 tcg_gen_ext32s_i64(t0, t0);
4004 break;
4005
4006 case OPC_SLL_CP2:
4007 shift_max = 32;
4008 goto do_shift;
4009 case OPC_SRL_CP2:
4010 shift_max = 32;
4011 goto do_shift;
4012 case OPC_SRA_CP2:
4013 shift_max = 32;
4014 goto do_shift;
4015 case OPC_DSLL_CP2:
4016 shift_max = 64;
4017 goto do_shift;
4018 case OPC_DSRL_CP2:
4019 shift_max = 64;
4020 goto do_shift;
4021 case OPC_DSRA_CP2:
4022 shift_max = 64;
4023 goto do_shift;
4024 do_shift:
4025 /* Make sure shift count isn't TCG undefined behaviour. */
4026 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4027
4028 switch (opc) {
4029 case OPC_SLL_CP2:
4030 case OPC_DSLL_CP2:
4031 tcg_gen_shl_i64(t0, t0, t1);
4032 break;
4033 case OPC_SRA_CP2:
4034 case OPC_DSRA_CP2:
4035 /*
4036 * Since SRA is UndefinedResult without sign-extended inputs,
4037 * we can treat SRA and DSRA the same.
4038 */
4039 tcg_gen_sar_i64(t0, t0, t1);
4040 break;
4041 case OPC_SRL_CP2:
4042 /* We want to shift in zeros for SRL; zero-extend first. */
4043 tcg_gen_ext32u_i64(t0, t0);
4044 /* FALLTHRU */
4045 case OPC_DSRL_CP2:
4046 tcg_gen_shr_i64(t0, t0, t1);
4047 break;
4048 }
4049
4050 if (shift_max == 32) {
4051 tcg_gen_ext32s_i64(t0, t0);
4052 }
4053
4054 /* Shifts larger than MAX produce zero. */
4055 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4056 tcg_gen_neg_i64(t1, t1);
4057 tcg_gen_and_i64(t0, t0, t1);
4058 break;
4059
4060 case OPC_ADD_CP2:
4061 case OPC_DADD_CP2:
4062 {
4063 TCGv_i64 t2 = tcg_temp_new_i64();
4064 TCGLabel *lab = gen_new_label();
4065
4066 tcg_gen_mov_i64(t2, t0);
4067 tcg_gen_add_i64(t0, t1, t2);
4068 if (opc == OPC_ADD_CP2) {
4069 tcg_gen_ext32s_i64(t0, t0);
4070 }
4071 tcg_gen_xor_i64(t1, t1, t2);
4072 tcg_gen_xor_i64(t2, t2, t0);
4073 tcg_gen_andc_i64(t1, t2, t1);
4074 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4075 generate_exception(ctx, EXCP_OVERFLOW);
4076 gen_set_label(lab);
4077 break;
4078 }
4079
4080 case OPC_SUB_CP2:
4081 case OPC_DSUB_CP2:
4082 {
4083 TCGv_i64 t2 = tcg_temp_new_i64();
4084 TCGLabel *lab = gen_new_label();
4085
4086 tcg_gen_mov_i64(t2, t0);
4087 tcg_gen_sub_i64(t0, t1, t2);
4088 if (opc == OPC_SUB_CP2) {
4089 tcg_gen_ext32s_i64(t0, t0);
4090 }
4091 tcg_gen_xor_i64(t1, t1, t2);
4092 tcg_gen_xor_i64(t2, t2, t0);
4093 tcg_gen_and_i64(t1, t1, t2);
4094 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4095 generate_exception(ctx, EXCP_OVERFLOW);
4096 gen_set_label(lab);
4097 break;
4098 }
4099
4100 case OPC_PMULUW:
4101 tcg_gen_ext32u_i64(t0, t0);
4102 tcg_gen_ext32u_i64(t1, t1);
4103 tcg_gen_mul_i64(t0, t0, t1);
4104 break;
4105
4106 case OPC_SEQU_CP2:
4107 case OPC_SEQ_CP2:
4108 cond = TCG_COND_EQ;
4109 goto do_cc_cond;
4110 break;
4111 case OPC_SLTU_CP2:
4112 cond = TCG_COND_LTU;
4113 goto do_cc_cond;
4114 break;
4115 case OPC_SLT_CP2:
4116 cond = TCG_COND_LT;
4117 goto do_cc_cond;
4118 break;
4119 case OPC_SLEU_CP2:
4120 cond = TCG_COND_LEU;
4121 goto do_cc_cond;
4122 break;
4123 case OPC_SLE_CP2:
4124 cond = TCG_COND_LE;
4125 do_cc_cond:
4126 {
4127 int cc = (ctx->opcode >> 8) & 0x7;
4128 TCGv_i64 t64 = tcg_temp_new_i64();
4129 TCGv_i32 t32 = tcg_temp_new_i32();
4130
4131 tcg_gen_setcond_i64(cond, t64, t0, t1);
4132 tcg_gen_extrl_i64_i32(t32, t64);
4133 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4134 get_fp_bit(cc), 1);
4135 }
4136 return;
4137 default:
4138 MIPS_INVAL("loongson_cp2");
4139 gen_reserved_instruction(ctx);
4140 return;
4141 }
4142
4143 gen_store_fpr64(ctx, t0, rd);
4144 }
4145
4146 static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4147 int rs, int rd)
4148 {
4149 TCGv t0, t1;
4150 TCGv_i32 fp0;
4151 #if defined(TARGET_MIPS64)
4152 int lsq_rt1 = ctx->opcode & 0x1f;
4153 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4154 #endif
4155 int shf_offset = sextract32(ctx->opcode, 6, 8);
4156
4157 t0 = tcg_temp_new();
4158
4159 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4160 #if defined(TARGET_MIPS64)
4161 case OPC_GSLQ:
4162 t1 = tcg_temp_new();
4163 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4164 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4165 ctx->default_tcg_memop_mask);
4166 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4167 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4168 ctx->default_tcg_memop_mask);
4169 gen_store_gpr(t1, rt);
4170 gen_store_gpr(t0, lsq_rt1);
4171 break;
4172 case OPC_GSLQC1:
4173 check_cp1_enabled(ctx);
4174 t1 = tcg_temp_new();
4175 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4176 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4177 ctx->default_tcg_memop_mask);
4178 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4179 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4180 ctx->default_tcg_memop_mask);
4181 gen_store_fpr64(ctx, t1, rt);
4182 gen_store_fpr64(ctx, t0, lsq_rt1);
4183 break;
4184 case OPC_GSSQ:
4185 t1 = tcg_temp_new();
4186 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4187 gen_load_gpr(t1, rt);
4188 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4189 ctx->default_tcg_memop_mask);
4190 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4191 gen_load_gpr(t1, lsq_rt1);
4192 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4193 ctx->default_tcg_memop_mask);
4194 break;
4195 case OPC_GSSQC1:
4196 check_cp1_enabled(ctx);
4197 t1 = tcg_temp_new();
4198 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4199 gen_load_fpr64(ctx, t1, rt);
4200 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4201 ctx->default_tcg_memop_mask);
4202 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4203 gen_load_fpr64(ctx, t1, lsq_rt1);
4204 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4205 ctx->default_tcg_memop_mask);
4206 break;
4207 #endif
4208 case OPC_GSSHFL:
4209 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4210 case OPC_GSLWLC1:
4211 check_cp1_enabled(ctx);
4212 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4213 fp0 = tcg_temp_new_i32();
4214 gen_load_fpr32(ctx, fp0, rt);
4215 t1 = tcg_temp_new();
4216 tcg_gen_ext_i32_tl(t1, fp0);
4217 gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUL);
4218 tcg_gen_trunc_tl_i32(fp0, t1);
4219 gen_store_fpr32(ctx, fp0, rt);
4220 break;
4221 case OPC_GSLWRC1:
4222 check_cp1_enabled(ctx);
4223 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4224 fp0 = tcg_temp_new_i32();
4225 gen_load_fpr32(ctx, fp0, rt);
4226 t1 = tcg_temp_new();
4227 tcg_gen_ext_i32_tl(t1, fp0);
4228 gen_lxr(ctx, t1, t0, ctx->mem_idx, MO_TEUL);
4229 tcg_gen_trunc_tl_i32(fp0, t1);
4230 gen_store_fpr32(ctx, fp0, rt);
4231 break;
4232 #if defined(TARGET_MIPS64)
4233 case OPC_GSLDLC1:
4234 check_cp1_enabled(ctx);
4235 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4236 t1 = tcg_temp_new();
4237 gen_load_fpr64(ctx, t1, rt);
4238 gen_lxl(ctx, t1, t0, ctx->mem_idx, MO_TEUQ);
4239 gen_store_fpr64(ctx, t1, rt);
4240 break;
4241 case OPC_GSLDRC1:
4242 check_cp1_enabled(ctx);
4243 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4244 t1 = tcg_temp_new();
4245 gen_load_fpr64(ctx, t1, rt);
4246 gen_lxr(ctx, t1, t0, ctx->mem_idx, MO_TEUQ);
4247 gen_store_fpr64(ctx, t1, rt);
4248 break;
4249 #endif
4250 default:
4251 MIPS_INVAL("loongson_gsshfl");
4252 gen_reserved_instruction(ctx);
4253 break;
4254 }
4255 break;
4256 case OPC_GSSHFS:
4257 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4258 case OPC_GSSWLC1:
4259 check_cp1_enabled(ctx);
4260 t1 = tcg_temp_new();
4261 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4262 fp0 = tcg_temp_new_i32();
4263 gen_load_fpr32(ctx, fp0, rt);
4264 tcg_gen_ext_i32_tl(t1, fp0);
4265 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4266 break;
4267 case OPC_GSSWRC1:
4268 check_cp1_enabled(ctx);
4269 t1 = tcg_temp_new();
4270 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4271 fp0 = tcg_temp_new_i32();
4272 gen_load_fpr32(ctx, fp0, rt);
4273 tcg_gen_ext_i32_tl(t1, fp0);
4274 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4275 break;
4276 #if defined(TARGET_MIPS64)
4277 case OPC_GSSDLC1:
4278 check_cp1_enabled(ctx);
4279 t1 = tcg_temp_new();
4280 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4281 gen_load_fpr64(ctx, t1, rt);
4282 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4283 break;
4284 case OPC_GSSDRC1:
4285 check_cp1_enabled(ctx);
4286 t1 = tcg_temp_new();
4287 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4288 gen_load_fpr64(ctx, t1, rt);
4289 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4290 break;
4291 #endif
4292 default:
4293 MIPS_INVAL("loongson_gsshfs");
4294 gen_reserved_instruction(ctx);
4295 break;
4296 }
4297 break;
4298 default:
4299 MIPS_INVAL("loongson_gslsq");
4300 gen_reserved_instruction(ctx);
4301 break;
4302 }
4303 }
4304
4305 /* Loongson EXT LDC2/SDC2 */
4306 static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4307 int rs, int rd)
4308 {
4309 int offset = sextract32(ctx->opcode, 3, 8);
4310 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4311 TCGv t0, t1;
4312 TCGv_i32 fp0;
4313
4314 /* Pre-conditions */
4315 switch (opc) {
4316 case OPC_GSLBX:
4317 case OPC_GSLHX:
4318 case OPC_GSLWX:
4319 case OPC_GSLDX:
4320 /* prefetch, implement as NOP */
4321 if (rt == 0) {
4322 return;
4323 }
4324 break;
4325 case OPC_GSSBX:
4326 case OPC_GSSHX:
4327 case OPC_GSSWX:
4328 case OPC_GSSDX:
4329 break;
4330 case OPC_GSLWXC1:
4331 #if defined(TARGET_MIPS64)
4332 case OPC_GSLDXC1:
4333 #endif
4334 check_cp1_enabled(ctx);
4335 /* prefetch, implement as NOP */
4336 if (rt == 0) {
4337 return;
4338 }
4339 break;
4340 case OPC_GSSWXC1:
4341 #if defined(TARGET_MIPS64)
4342 case OPC_GSSDXC1:
4343 #endif
4344 check_cp1_enabled(ctx);
4345 break;
4346 default:
4347 MIPS_INVAL("loongson_lsdc2");
4348 gen_reserved_instruction(ctx);
4349 return;
4350 break;
4351 }
4352
4353 t0 = tcg_temp_new();
4354
4355 gen_base_offset_addr(ctx, t0, rs, offset);
4356 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4357
4358 switch (opc) {
4359 case OPC_GSLBX:
4360 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4361 gen_store_gpr(t0, rt);
4362 break;
4363 case OPC_GSLHX:
4364 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4365 ctx->default_tcg_memop_mask);
4366 gen_store_gpr(t0, rt);
4367 break;
4368 case OPC_GSLWX:
4369 gen_base_offset_addr(ctx, t0, rs, offset);
4370 if (rd) {
4371 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4372 }
4373 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4374 ctx->default_tcg_memop_mask);
4375 gen_store_gpr(t0, rt);
4376 break;
4377 #if defined(TARGET_MIPS64)
4378 case OPC_GSLDX:
4379 gen_base_offset_addr(ctx, t0, rs, offset);
4380 if (rd) {
4381 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4382 }
4383 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4384 ctx->default_tcg_memop_mask);
4385 gen_store_gpr(t0, rt);
4386 break;
4387 #endif
4388 case OPC_GSLWXC1:
4389 gen_base_offset_addr(ctx, t0, rs, offset);
4390 if (rd) {
4391 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4392 }
4393 fp0 = tcg_temp_new_i32();
4394 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4395 ctx->default_tcg_memop_mask);
4396 gen_store_fpr32(ctx, fp0, rt);
4397 break;
4398 #if defined(TARGET_MIPS64)
4399 case OPC_GSLDXC1:
4400 gen_base_offset_addr(ctx, t0, rs, offset);
4401 if (rd) {
4402 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4403 }
4404 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4405 ctx->default_tcg_memop_mask);
4406 gen_store_fpr64(ctx, t0, rt);
4407 break;
4408 #endif
4409 case OPC_GSSBX:
4410 t1 = tcg_temp_new();
4411 gen_load_gpr(t1, rt);
4412 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4413 break;
4414 case OPC_GSSHX:
4415 t1 = tcg_temp_new();
4416 gen_load_gpr(t1, rt);
4417 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4418 ctx->default_tcg_memop_mask);
4419 break;
4420 case OPC_GSSWX:
4421 t1 = tcg_temp_new();
4422 gen_load_gpr(t1, rt);
4423 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4424 ctx->default_tcg_memop_mask);
4425 break;
4426 #if defined(TARGET_MIPS64)
4427 case OPC_GSSDX:
4428 t1 = tcg_temp_new();
4429 gen_load_gpr(t1, rt);
4430 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4431 ctx->default_tcg_memop_mask);
4432 break;
4433 #endif
4434 case OPC_GSSWXC1:
4435 fp0 = tcg_temp_new_i32();
4436 gen_load_fpr32(ctx, fp0, rt);
4437 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4438 ctx->default_tcg_memop_mask);
4439 break;
4440 #if defined(TARGET_MIPS64)
4441 case OPC_GSSDXC1:
4442 t1 = tcg_temp_new();
4443 gen_load_fpr64(ctx, t1, rt);
4444 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ |
4445 ctx->default_tcg_memop_mask);
4446 break;
4447 #endif
4448 default:
4449 break;
4450 }
4451 }
4452
4453 /* Traps */
4454 static void gen_trap(DisasContext *ctx, uint32_t opc,
4455 int rs, int rt, int16_t imm, int code)
4456 {
4457 int cond;
4458 TCGv t0 = tcg_temp_new();
4459 TCGv t1 = tcg_temp_new();
4460
4461 cond = 0;
4462 /* Load needed operands */
4463 switch (opc) {
4464 case OPC_TEQ:
4465 case OPC_TGE:
4466 case OPC_TGEU:
4467 case OPC_TLT:
4468 case OPC_TLTU:
4469 case OPC_TNE:
4470 /* Compare two registers */
4471 if (rs != rt) {
4472 gen_load_gpr(t0, rs);
4473 gen_load_gpr(t1, rt);
4474 cond = 1;
4475 }
4476 break;
4477 case OPC_TEQI:
4478 case OPC_TGEI:
4479 case OPC_TGEIU:
4480 case OPC_TLTI:
4481 case OPC_TLTIU:
4482 case OPC_TNEI:
4483 /* Compare register to immediate */
4484 if (rs != 0 || imm != 0) {
4485 gen_load_gpr(t0, rs);
4486 tcg_gen_movi_tl(t1, (int32_t)imm);
4487 cond = 1;
4488 }
4489 break;
4490 }
4491 if (cond == 0) {
4492 switch (opc) {
4493 case OPC_TEQ: /* rs == rs */
4494 case OPC_TEQI: /* r0 == 0 */
4495 case OPC_TGE: /* rs >= rs */
4496 case OPC_TGEI: /* r0 >= 0 */
4497 case OPC_TGEU: /* rs >= rs unsigned */
4498 case OPC_TGEIU: /* r0 >= 0 unsigned */
4499 /* Always trap */
4500 #ifdef CONFIG_USER_ONLY
4501 /* Pass the break code along to cpu_loop. */
4502 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4503 offsetof(CPUMIPSState, error_code));
4504 #endif
4505 generate_exception_end(ctx, EXCP_TRAP);
4506 break;
4507 case OPC_TLT: /* rs < rs */
4508 case OPC_TLTI: /* r0 < 0 */
4509 case OPC_TLTU: /* rs < rs unsigned */
4510 case OPC_TLTIU: /* r0 < 0 unsigned */
4511 case OPC_TNE: /* rs != rs */
4512 case OPC_TNEI: /* r0 != 0 */
4513 /* Never trap: treat as NOP. */
4514 break;
4515 }
4516 } else {
4517 TCGLabel *l1 = gen_new_label();
4518
4519 switch (opc) {
4520 case OPC_TEQ:
4521 case OPC_TEQI:
4522 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4523 break;
4524 case OPC_TGE:
4525 case OPC_TGEI:
4526 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4527 break;
4528 case OPC_TGEU:
4529 case OPC_TGEIU:
4530 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4531 break;
4532 case OPC_TLT:
4533 case OPC_TLTI:
4534 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4535 break;
4536 case OPC_TLTU:
4537 case OPC_TLTIU:
4538 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4539 break;
4540 case OPC_TNE:
4541 case OPC_TNEI:
4542 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4543 break;
4544 }
4545 #ifdef CONFIG_USER_ONLY
4546 /* Pass the break code along to cpu_loop. */
4547 tcg_gen_st_i32(tcg_constant_i32(code), tcg_env,
4548 offsetof(CPUMIPSState, error_code));
4549 #endif
4550 /* Like save_cpu_state, only don't update saved values. */
4551 if (ctx->base.pc_next != ctx->saved_pc) {
4552 gen_save_pc(ctx->base.pc_next);
4553 }
4554 if (ctx->hflags != ctx->saved_hflags) {
4555 tcg_gen_movi_i32(hflags, ctx->hflags);
4556 }
4557 generate_exception(ctx, EXCP_TRAP);
4558 gen_set_label(l1);
4559 }
4560 }
4561
4562 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4563 {
4564 if (translator_use_goto_tb(&ctx->base, dest)) {
4565 tcg_gen_goto_tb(n);
4566 gen_save_pc(dest);
4567 tcg_gen_exit_tb(ctx->base.tb, n);
4568 } else {
4569 gen_save_pc(dest);
4570 tcg_gen_lookup_and_goto_ptr();
4571 }
4572 }
4573
4574 /* Branches (before delay slot) */
4575 static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4576 int insn_bytes,
4577 int rs, int rt, int32_t offset,
4578 int delayslot_size)
4579 {
4580 target_ulong btgt = -1;
4581 int blink = 0;
4582 int bcond_compute = 0;
4583 TCGv t0 = tcg_temp_new();
4584 TCGv t1 = tcg_temp_new();
4585
4586 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4587 #ifdef MIPS_DEBUG_DISAS
4588 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4589 TARGET_FMT_lx "\n", ctx->base.pc_next);
4590 #endif
4591 gen_reserved_instruction(ctx);
4592 goto out;
4593 }
4594
4595 /* Load needed operands */
4596 switch (opc) {
4597 case OPC_BEQ:
4598 case OPC_BEQL:
4599 case OPC_BNE:
4600 case OPC_BNEL:
4601 /* Compare two registers */
4602 if (rs != rt) {
4603 gen_load_gpr(t0, rs);
4604 gen_load_gpr(t1, rt);
4605 bcond_compute = 1;
4606 }
4607 btgt = ctx->base.pc_next + insn_bytes + offset;
4608 break;
4609 case OPC_BGEZ:
4610 case OPC_BGEZAL:
4611 case OPC_BGEZALL:
4612 case OPC_BGEZL:
4613 case OPC_BGTZ:
4614 case OPC_BGTZL:
4615 case OPC_BLEZ:
4616 case OPC_BLEZL:
4617 case OPC_BLTZ:
4618 case OPC_BLTZAL:
4619 case OPC_BLTZALL:
4620 case OPC_BLTZL:
4621 /* Compare to zero */
4622 if (rs != 0) {
4623 gen_load_gpr(t0, rs);
4624 bcond_compute = 1;
4625 }
4626 btgt = ctx->base.pc_next + insn_bytes + offset;
4627 break;
4628 case OPC_BPOSGE32:
4629 #if defined(TARGET_MIPS64)
4630 case OPC_BPOSGE64:
4631 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4632 #else
4633 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4634 #endif
4635 bcond_compute = 1;
4636 btgt = ctx->base.pc_next + insn_bytes + offset;
4637 break;
4638 case OPC_J:
4639 case OPC_JAL:
4640 {
4641 /* Jump to immediate */
4642 int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000
4643 : 0xF0000000;
4644 btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask)
4645 | (uint32_t)offset;
4646 break;
4647 }
4648 case OPC_JALX:
4649 /* Jump to immediate */
4650 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4651 (uint32_t)offset;
4652 break;
4653 case OPC_JR:
4654 case OPC_JALR:
4655 /* Jump to register */
4656 if (offset != 0 && offset != 16) {
4657 /*
4658 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4659 * others are reserved.
4660 */
4661 MIPS_INVAL("jump hint");
4662 gen_reserved_instruction(ctx);
4663 goto out;
4664 }
4665 gen_load_gpr(btarget, rs);
4666 break;
4667 default:
4668 MIPS_INVAL("branch/jump");
4669 gen_reserved_instruction(ctx);
4670 goto out;
4671 }
4672 if (bcond_compute == 0) {
4673 /* No condition to be computed */
4674 switch (opc) {
4675 case OPC_BEQ: /* rx == rx */
4676 case OPC_BEQL: /* rx == rx likely */
4677 case OPC_BGEZ: /* 0 >= 0 */
4678 case OPC_BGEZL: /* 0 >= 0 likely */
4679 case OPC_BLEZ: /* 0 <= 0 */
4680 case OPC_BLEZL: /* 0 <= 0 likely */
4681 /* Always take */
4682 ctx->hflags |= MIPS_HFLAG_B;
4683 break;
4684 case OPC_BGEZAL: /* 0 >= 0 */
4685 case OPC_BGEZALL: /* 0 >= 0 likely */
4686 /* Always take and link */
4687 blink = 31;
4688 ctx->hflags |= MIPS_HFLAG_B;
4689 break;
4690 case OPC_BNE: /* rx != rx */
4691 case OPC_BGTZ: /* 0 > 0 */
4692 case OPC_BLTZ: /* 0 < 0 */
4693 /* Treat as NOP. */
4694 goto out;
4695 case OPC_BLTZAL: /* 0 < 0 */
4696 /*
4697 * Handle as an unconditional branch to get correct delay
4698 * slot checking.
4699 */
4700 blink = 31;
4701 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4702 ctx->hflags |= MIPS_HFLAG_B;
4703 break;
4704 case OPC_BLTZALL: /* 0 < 0 likely */
4705 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4706 /* Skip the instruction in the delay slot */
4707 ctx->base.pc_next += 4;
4708 goto out;
4709 case OPC_BNEL: /* rx != rx likely */
4710 case OPC_BGTZL: /* 0 > 0 likely */
4711 case OPC_BLTZL: /* 0 < 0 likely */
4712 /* Skip the instruction in the delay slot */
4713 ctx->base.pc_next += 4;
4714 goto out;
4715 case OPC_J:
4716 ctx->hflags |= MIPS_HFLAG_B;
4717 break;
4718 case OPC_JALX:
4719 ctx->hflags |= MIPS_HFLAG_BX;
4720 /* Fallthrough */
4721 case OPC_JAL:
4722 blink = 31;
4723 ctx->hflags |= MIPS_HFLAG_B;
4724 break;
4725 case OPC_JR:
4726 ctx->hflags |= MIPS_HFLAG_BR;
4727 break;
4728 case OPC_JALR:
4729 blink = rt;
4730 ctx->hflags |= MIPS_HFLAG_BR;
4731 break;
4732 default:
4733 MIPS_INVAL("branch/jump");
4734 gen_reserved_instruction(ctx);
4735 goto out;
4736 }
4737 } else {
4738 switch (opc) {
4739 case OPC_BEQ:
4740 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4741 goto not_likely;
4742 case OPC_BEQL:
4743 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4744 goto likely;
4745 case OPC_BNE:
4746 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4747 goto not_likely;
4748 case OPC_BNEL:
4749 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4750 goto likely;
4751 case OPC_BGEZ:
4752 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4753 goto not_likely;
4754 case OPC_BGEZL:
4755 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4756 goto likely;
4757 case OPC_BGEZAL:
4758 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4759 blink = 31;
4760 goto not_likely;
4761 case OPC_BGEZALL:
4762 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4763 blink = 31;
4764 goto likely;
4765 case OPC_BGTZ:
4766 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4767 goto not_likely;
4768 case OPC_BGTZL:
4769 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4770 goto likely;
4771 case OPC_BLEZ:
4772 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4773 goto not_likely;
4774 case OPC_BLEZL:
4775 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4776 goto likely;
4777 case OPC_BLTZ:
4778 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4779 goto not_likely;
4780 case OPC_BLTZL:
4781 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4782 goto likely;
4783 case OPC_BPOSGE32:
4784 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4785 goto not_likely;
4786 #if defined(TARGET_MIPS64)
4787 case OPC_BPOSGE64:
4788 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4789 goto not_likely;
4790 #endif
4791 case OPC_BLTZAL:
4792 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4793 blink = 31;
4794 not_likely:
4795 ctx->hflags |= MIPS_HFLAG_BC;
4796 break;
4797 case OPC_BLTZALL:
4798 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4799 blink = 31;
4800 likely:
4801 ctx->hflags |= MIPS_HFLAG_BL;
4802 break;
4803 default:
4804 MIPS_INVAL("conditional branch/jump");
4805 gen_reserved_instruction(ctx);
4806 goto out;
4807 }
4808 }
4809
4810 ctx->btarget = btgt;
4811
4812 switch (delayslot_size) {
4813 case 2:
4814 ctx->hflags |= MIPS_HFLAG_BDS16;
4815 break;
4816 case 4:
4817 ctx->hflags |= MIPS_HFLAG_BDS32;
4818 break;
4819 }
4820
4821 if (blink > 0) {
4822 int post_delay = insn_bytes + delayslot_size;
4823 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4824
4825 tcg_gen_movi_tl(cpu_gpr[blink],
4826 ctx->base.pc_next + post_delay + lowbit);
4827 }
4828
4829 out:
4830 if (insn_bytes == 2) {
4831 ctx->hflags |= MIPS_HFLAG_B16;
4832 }
4833 }
4834
4835
4836 /* special3 bitfield operations */
4837 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
4838 int rs, int lsb, int msb)
4839 {
4840 TCGv t0 = tcg_temp_new();
4841 TCGv t1 = tcg_temp_new();
4842
4843 gen_load_gpr(t1, rs);
4844 switch (opc) {
4845 case OPC_EXT:
4846 if (lsb + msb > 31) {
4847 goto fail;
4848 }
4849 if (msb != 31) {
4850 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4851 } else {
4852 /*
4853 * The two checks together imply that lsb == 0,
4854 * so this is a simple sign-extension.
4855 */
4856 tcg_gen_ext32s_tl(t0, t1);
4857 }
4858 break;
4859 #if defined(TARGET_MIPS64)
4860 case OPC_DEXTU:
4861 lsb += 32;
4862 goto do_dext;
4863 case OPC_DEXTM:
4864 msb += 32;
4865 goto do_dext;
4866 case OPC_DEXT:
4867 do_dext:
4868 if (lsb + msb > 63) {
4869 goto fail;
4870 }
4871 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4872 break;
4873 #endif
4874 case OPC_INS:
4875 if (lsb > msb) {
4876 goto fail;
4877 }
4878 gen_load_gpr(t0, rt);
4879 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4880 tcg_gen_ext32s_tl(t0, t0);
4881 break;
4882 #if defined(TARGET_MIPS64)
4883 case OPC_DINSU:
4884 lsb += 32;
4885 /* FALLTHRU */
4886 case OPC_DINSM:
4887 msb += 32;
4888 /* FALLTHRU */
4889 case OPC_DINS:
4890 if (lsb > msb) {
4891 goto fail;
4892 }
4893 gen_load_gpr(t0, rt);
4894 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4895 break;
4896 #endif
4897 default:
4898 fail:
4899 MIPS_INVAL("bitops");
4900 gen_reserved_instruction(ctx);
4901 return;
4902 }
4903 gen_store_gpr(t0, rt);
4904 }
4905
4906 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
4907 {
4908 TCGv t0;
4909
4910 if (rd == 0) {
4911 /* If no destination, treat it as a NOP. */
4912 return;
4913 }
4914
4915 t0 = tcg_temp_new();
4916 gen_load_gpr(t0, rt);
4917 switch (op2) {
4918 case OPC_WSBH:
4919 {
4920 TCGv t1 = tcg_temp_new();
4921 TCGv t2 = tcg_constant_tl(0x00FF00FF);
4922
4923 tcg_gen_shri_tl(t1, t0, 8);
4924 tcg_gen_and_tl(t1, t1, t2);
4925 tcg_gen_and_tl(t0, t0, t2);
4926 tcg_gen_shli_tl(t0, t0, 8);
4927 tcg_gen_or_tl(t0, t0, t1);
4928 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4929 }
4930 break;
4931 case OPC_SEB:
4932 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4933 break;
4934 case OPC_SEH:
4935 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4936 break;
4937 #if defined(TARGET_MIPS64)
4938 case OPC_DSBH:
4939 {
4940 TCGv t1 = tcg_temp_new();
4941 TCGv t2 = tcg_constant_tl(0x00FF00FF00FF00FFULL);
4942
4943 tcg_gen_shri_tl(t1, t0, 8);
4944 tcg_gen_and_tl(t1, t1, t2);
4945 tcg_gen_and_tl(t0, t0, t2);
4946 tcg_gen_shli_tl(t0, t0, 8);
4947 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4948 }
4949 break;
4950 case OPC_DSHD:
4951 {
4952 TCGv t1 = tcg_temp_new();
4953 TCGv t2 = tcg_constant_tl(0x0000FFFF0000FFFFULL);
4954
4955 tcg_gen_shri_tl(t1, t0, 16);
4956 tcg_gen_and_tl(t1, t1, t2);
4957 tcg_gen_and_tl(t0, t0, t2);
4958 tcg_gen_shli_tl(t0, t0, 16);
4959 tcg_gen_or_tl(t0, t0, t1);
4960 tcg_gen_shri_tl(t1, t0, 32);
4961 tcg_gen_shli_tl(t0, t0, 32);
4962 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4963 }
4964 break;
4965 #endif
4966 default:
4967 MIPS_INVAL("bsfhl");
4968 gen_reserved_instruction(ctx);
4969 return;
4970 }
4971 }
4972
4973 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
4974 int rt, int bits)
4975 {
4976 TCGv t0;
4977 if (rd == 0) {
4978 /* Treat as NOP. */
4979 return;
4980 }
4981 t0 = tcg_temp_new();
4982 if (bits == 0 || bits == wordsz) {
4983 if (bits == 0) {
4984 gen_load_gpr(t0, rt);
4985 } else {
4986 gen_load_gpr(t0, rs);
4987 }
4988 switch (wordsz) {
4989 case 32:
4990 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4991 break;
4992 #if defined(TARGET_MIPS64)
4993 case 64:
4994 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4995 break;
4996 #endif
4997 }
4998 } else {
4999 TCGv t1 = tcg_temp_new();
5000 gen_load_gpr(t0, rt);
5001 gen_load_gpr(t1, rs);
5002 switch (wordsz) {
5003 case 32:
5004 {
5005 TCGv_i64 t2 = tcg_temp_new_i64();
5006 tcg_gen_concat_tl_i64(t2, t1, t0);
5007 tcg_gen_shri_i64(t2, t2, 32 - bits);
5008 gen_move_low32(cpu_gpr[rd], t2);
5009 }
5010 break;
5011 #if defined(TARGET_MIPS64)
5012 case 64:
5013 tcg_gen_shli_tl(t0, t0, bits);
5014 tcg_gen_shri_tl(t1, t1, 64 - bits);
5015 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5016 break;
5017 #endif
5018 }
5019 }
5020 }
5021
5022 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
5023 {
5024 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5025 }
5026
5027 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5028 {
5029 TCGv t0;
5030 if (rd == 0) {
5031 /* Treat as NOP. */
5032 return;
5033 }
5034 t0 = tcg_temp_new();
5035 gen_load_gpr(t0, rt);
5036 switch (opc) {
5037 case OPC_BITSWAP:
5038 gen_helper_bitswap(cpu_gpr[rd], t0);
5039 break;
5040 #if defined(TARGET_MIPS64)
5041 case OPC_DBITSWAP:
5042 gen_helper_dbitswap(cpu_gpr[rd], t0);
5043 break;
5044 #endif
5045 }
5046 }
5047
5048 #ifndef CONFIG_USER_ONLY
5049 /* CP0 (MMU and control) */
5050 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5051 {
5052 TCGv_i64 t0 = tcg_temp_new_i64();
5053 TCGv_i64 t1 = tcg_temp_new_i64();
5054
5055 tcg_gen_ext_tl_i64(t0, arg);
5056 tcg_gen_ld_i64(t1, tcg_env, off);
5057 #if defined(TARGET_MIPS64)
5058 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5059 #else
5060 tcg_gen_concat32_i64(t1, t1, t0);
5061 #endif
5062 tcg_gen_st_i64(t1, tcg_env, off);
5063 }
5064
5065 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5066 {
5067 TCGv_i64 t0 = tcg_temp_new_i64();
5068 TCGv_i64 t1 = tcg_temp_new_i64();
5069
5070 tcg_gen_ext_tl_i64(t0, arg);
5071 tcg_gen_ld_i64(t1, tcg_env, off);
5072 tcg_gen_concat32_i64(t1, t1, t0);
5073 tcg_gen_st_i64(t1, tcg_env, off);
5074 }
5075
5076 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5077 {
5078 TCGv_i64 t0 = tcg_temp_new_i64();
5079
5080 tcg_gen_ld_i64(t0, tcg_env, off);
5081 #if defined(TARGET_MIPS64)
5082 tcg_gen_shri_i64(t0, t0, 30);
5083 #else
5084 tcg_gen_shri_i64(t0, t0, 32);
5085 #endif
5086 gen_move_low32(arg, t0);
5087 }
5088
5089 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5090 {
5091 TCGv_i64 t0 = tcg_temp_new_i64();
5092
5093 tcg_gen_ld_i64(t0, tcg_env, off);
5094 tcg_gen_shri_i64(t0, t0, 32 + shift);
5095 gen_move_low32(arg, t0);
5096 }
5097
5098 static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5099 {
5100 TCGv_i32 t0 = tcg_temp_new_i32();
5101
5102 tcg_gen_ld_i32(t0, tcg_env, off);
5103 tcg_gen_ext_i32_tl(arg, t0);
5104 }
5105
5106 static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5107 {
5108 tcg_gen_ld_tl(arg, tcg_env, off);
5109 tcg_gen_ext32s_tl(arg, arg);
5110 }
5111
5112 static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5113 {
5114 TCGv_i32 t0 = tcg_temp_new_i32();
5115
5116 tcg_gen_trunc_tl_i32(t0, arg);
5117 tcg_gen_st_i32(t0, tcg_env, off);
5118 }
5119
5120 #define CP0_CHECK(c) \
5121 do { \
5122 if (!(c)) { \
5123 goto cp0_unimplemented; \
5124 } \
5125 } while (0)
5126
5127 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5128 {
5129 const char *register_name = "invalid";
5130
5131 switch (reg) {
5132 case CP0_REGISTER_02:
5133 switch (sel) {
5134 case 0:
5135 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5136 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5137 register_name = "EntryLo0";
5138 break;
5139 default:
5140 goto cp0_unimplemented;
5141 }
5142 break;
5143 case CP0_REGISTER_03:
5144 switch (sel) {
5145 case CP0_REG03__ENTRYLO1:
5146 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5147 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5148 register_name = "EntryLo1";
5149 break;
5150 default:
5151 goto cp0_unimplemented;
5152 }
5153 break;
5154 case CP0_REGISTER_09:
5155 switch (sel) {
5156 case CP0_REG09__SAAR:
5157 CP0_CHECK(ctx->saar);
5158 gen_helper_mfhc0_saar(arg, tcg_env);
5159 register_name = "SAAR";
5160 break;
5161 default:
5162 goto cp0_unimplemented;
5163 }
5164 break;
5165 case CP0_REGISTER_17:
5166 switch (sel) {
5167 case CP0_REG17__LLADDR:
5168 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5169 ctx->CP0_LLAddr_shift);
5170 register_name = "LLAddr";
5171 break;
5172 case CP0_REG17__MAAR:
5173 CP0_CHECK(ctx->mrp);
5174 gen_helper_mfhc0_maar(arg, tcg_env);
5175 register_name = "MAAR";
5176 break;
5177 default:
5178 goto cp0_unimplemented;
5179 }
5180 break;
5181 case CP0_REGISTER_19:
5182 switch (sel) {
5183 case CP0_REG19__WATCHHI0:
5184 case CP0_REG19__WATCHHI1:
5185 case CP0_REG19__WATCHHI2:
5186 case CP0_REG19__WATCHHI3:
5187 case CP0_REG19__WATCHHI4:
5188 case CP0_REG19__WATCHHI5:
5189 case CP0_REG19__WATCHHI6:
5190 case CP0_REG19__WATCHHI7:
5191 /* upper 32 bits are only available when Config5MI != 0 */
5192 CP0_CHECK(ctx->mi);
5193 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5194 register_name = "WatchHi";
5195 break;
5196 default:
5197 goto cp0_unimplemented;
5198 }
5199 break;
5200 case CP0_REGISTER_28:
5201 switch (sel) {
5202 case 0:
5203 case 2:
5204 case 4:
5205 case 6:
5206 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5207 register_name = "TagLo";
5208 break;
5209 default:
5210 goto cp0_unimplemented;
5211 }
5212 break;
5213 default:
5214 goto cp0_unimplemented;
5215 }
5216 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5217 return;
5218
5219 cp0_unimplemented:
5220 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5221 register_name, reg, sel);
5222 tcg_gen_movi_tl(arg, 0);
5223 }
5224
5225 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5226 {
5227 const char *register_name = "invalid";
5228 uint64_t mask = ctx->PAMask >> 36;
5229
5230 switch (reg) {
5231 case CP0_REGISTER_02:
5232 switch (sel) {
5233 case 0:
5234 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5235 tcg_gen_andi_tl(arg, arg, mask);
5236 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5237 register_name = "EntryLo0";
5238 break;
5239 default:
5240 goto cp0_unimplemented;
5241 }
5242 break;
5243 case CP0_REGISTER_03:
5244 switch (sel) {
5245 case CP0_REG03__ENTRYLO1:
5246 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5247 tcg_gen_andi_tl(arg, arg, mask);
5248 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5249 register_name = "EntryLo1";
5250 break;
5251 default:
5252 goto cp0_unimplemented;
5253 }
5254 break;
5255 case CP0_REGISTER_09:
5256 switch (sel) {
5257 case CP0_REG09__SAAR:
5258 CP0_CHECK(ctx->saar);
5259 gen_helper_mthc0_saar(tcg_env, arg);
5260 register_name = "SAAR";
5261 break;
5262 default:
5263 goto cp0_unimplemented;
5264 }
5265 break;
5266 case CP0_REGISTER_17:
5267 switch (sel) {
5268 case CP0_REG17__LLADDR:
5269 /*
5270 * LLAddr is read-only (the only exception is bit 0 if LLB is
5271 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5272 * relevant for modern MIPS cores supporting MTHC0, therefore
5273 * treating MTHC0 to LLAddr as NOP.
5274 */
5275 register_name = "LLAddr";
5276 break;
5277 case CP0_REG17__MAAR:
5278 CP0_CHECK(ctx->mrp);
5279 gen_helper_mthc0_maar(tcg_env, arg);
5280 register_name = "MAAR";
5281 break;
5282 default:
5283 goto cp0_unimplemented;
5284 }
5285 break;
5286 case CP0_REGISTER_19:
5287 switch (sel) {
5288 case CP0_REG19__WATCHHI0:
5289 case CP0_REG19__WATCHHI1:
5290 case CP0_REG19__WATCHHI2:
5291 case CP0_REG19__WATCHHI3:
5292 case CP0_REG19__WATCHHI4:
5293 case CP0_REG19__WATCHHI5:
5294 case CP0_REG19__WATCHHI6:
5295 case CP0_REG19__WATCHHI7:
5296 /* upper 32 bits are only available when Config5MI != 0 */
5297 CP0_CHECK(ctx->mi);
5298 gen_helper_0e1i(mthc0_watchhi, arg, sel);
5299 register_name = "WatchHi";
5300 break;
5301 default:
5302 goto cp0_unimplemented;
5303 }
5304 break;
5305 case CP0_REGISTER_28:
5306 switch (sel) {
5307 case 0:
5308 case 2:
5309 case 4:
5310 case 6:
5311 tcg_gen_andi_tl(arg, arg, mask);
5312 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5313 register_name = "TagLo";
5314 break;
5315 default:
5316 goto cp0_unimplemented;
5317 }
5318 break;
5319 default:
5320 goto cp0_unimplemented;
5321 }
5322 trace_mips_translate_c0("mthc0", register_name, reg, sel);
5323 return;
5324
5325 cp0_unimplemented:
5326 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5327 register_name, reg, sel);
5328 }
5329
5330 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5331 {
5332 if (ctx->insn_flags & ISA_MIPS_R6) {
5333 tcg_gen_movi_tl(arg, 0);
5334 } else {
5335 tcg_gen_movi_tl(arg, ~0);
5336 }
5337 }
5338
5339 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5340 {
5341 const char *register_name = "invalid";
5342
5343 if (sel != 0) {
5344 check_insn(ctx, ISA_MIPS_R1);
5345 }
5346
5347 switch (reg) {
5348 case CP0_REGISTER_00:
5349 switch (sel) {
5350 case CP0_REG00__INDEX:
5351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5352 register_name = "Index";
5353 break;
5354 case CP0_REG00__MVPCONTROL:
5355 CP0_CHECK(ctx->insn_flags & ASE_MT);
5356 gen_helper_mfc0_mvpcontrol(arg, tcg_env);
5357 register_name = "MVPControl";
5358 break;
5359 case CP0_REG00__MVPCONF0:
5360 CP0_CHECK(ctx->insn_flags & ASE_MT);
5361 gen_helper_mfc0_mvpconf0(arg, tcg_env);
5362 register_name = "MVPConf0";
5363 break;
5364 case CP0_REG00__MVPCONF1:
5365 CP0_CHECK(ctx->insn_flags & ASE_MT);
5366 gen_helper_mfc0_mvpconf1(arg, tcg_env);
5367 register_name = "MVPConf1";
5368 break;
5369 case CP0_REG00__VPCONTROL:
5370 CP0_CHECK(ctx->vp);
5371 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5372 register_name = "VPControl";
5373 break;
5374 default:
5375 goto cp0_unimplemented;
5376 }
5377 break;
5378 case CP0_REGISTER_01:
5379 switch (sel) {
5380 case CP0_REG01__RANDOM:
5381 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5382 gen_helper_mfc0_random(arg, tcg_env);
5383 register_name = "Random";
5384 break;
5385 case CP0_REG01__VPECONTROL:
5386 CP0_CHECK(ctx->insn_flags & ASE_MT);
5387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5388 register_name = "VPEControl";
5389 break;
5390 case CP0_REG01__VPECONF0:
5391 CP0_CHECK(ctx->insn_flags & ASE_MT);
5392 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5393 register_name = "VPEConf0";
5394 break;
5395 case CP0_REG01__VPECONF1:
5396 CP0_CHECK(ctx->insn_flags & ASE_MT);
5397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5398 register_name = "VPEConf1";
5399 break;
5400 case CP0_REG01__YQMASK:
5401 CP0_CHECK(ctx->insn_flags & ASE_MT);
5402 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5403 register_name = "YQMask";
5404 break;
5405 case CP0_REG01__VPESCHEDULE:
5406 CP0_CHECK(ctx->insn_flags & ASE_MT);
5407 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5408 register_name = "VPESchedule";
5409 break;
5410 case CP0_REG01__VPESCHEFBACK:
5411 CP0_CHECK(ctx->insn_flags & ASE_MT);
5412 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5413 register_name = "VPEScheFBack";
5414 break;
5415 case CP0_REG01__VPEOPT:
5416 CP0_CHECK(ctx->insn_flags & ASE_MT);
5417 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5418 register_name = "VPEOpt";
5419 break;
5420 default:
5421 goto cp0_unimplemented;
5422 }
5423 break;
5424 case CP0_REGISTER_02:
5425 switch (sel) {
5426 case CP0_REG02__ENTRYLO0:
5427 {
5428 TCGv_i64 tmp = tcg_temp_new_i64();
5429 tcg_gen_ld_i64(tmp, tcg_env,
5430 offsetof(CPUMIPSState, CP0_EntryLo0));
5431 #if defined(TARGET_MIPS64)
5432 if (ctx->rxi) {
5433 /* Move RI/XI fields to bits 31:30 */
5434 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5435 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5436 }
5437 #endif
5438 gen_move_low32(arg, tmp);
5439 }
5440 register_name = "EntryLo0";
5441 break;
5442 case CP0_REG02__TCSTATUS:
5443 CP0_CHECK(ctx->insn_flags & ASE_MT);
5444 gen_helper_mfc0_tcstatus(arg, tcg_env);
5445 register_name = "TCStatus";
5446 break;
5447 case CP0_REG02__TCBIND:
5448 CP0_CHECK(ctx->insn_flags & ASE_MT);
5449 gen_helper_mfc0_tcbind(arg, tcg_env);
5450 register_name = "TCBind";
5451 break;
5452 case CP0_REG02__TCRESTART:
5453 CP0_CHECK(ctx->insn_flags & ASE_MT);
5454 gen_helper_mfc0_tcrestart(arg, tcg_env);
5455 register_name = "TCRestart";
5456 break;
5457 case CP0_REG02__TCHALT:
5458 CP0_CHECK(ctx->insn_flags & ASE_MT);
5459 gen_helper_mfc0_tchalt(arg, tcg_env);
5460 register_name = "TCHalt";
5461 break;
5462 case CP0_REG02__TCCONTEXT:
5463 CP0_CHECK(ctx->insn_flags & ASE_MT);
5464 gen_helper_mfc0_tccontext(arg, tcg_env);
5465 register_name = "TCContext";
5466 break;
5467 case CP0_REG02__TCSCHEDULE:
5468 CP0_CHECK(ctx->insn_flags & ASE_MT);
5469 gen_helper_mfc0_tcschedule(arg, tcg_env);
5470 register_name = "TCSchedule";
5471 break;
5472 case CP0_REG02__TCSCHEFBACK:
5473 CP0_CHECK(ctx->insn_flags & ASE_MT);
5474 gen_helper_mfc0_tcschefback(arg, tcg_env);
5475 register_name = "TCScheFBack";
5476 break;
5477 default:
5478 goto cp0_unimplemented;
5479 }
5480 break;
5481 case CP0_REGISTER_03:
5482 switch (sel) {
5483 case CP0_REG03__ENTRYLO1:
5484 {
5485 TCGv_i64 tmp = tcg_temp_new_i64();
5486 tcg_gen_ld_i64(tmp, tcg_env,
5487 offsetof(CPUMIPSState, CP0_EntryLo1));
5488 #if defined(TARGET_MIPS64)
5489 if (ctx->rxi) {
5490 /* Move RI/XI fields to bits 31:30 */
5491 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5492 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5493 }
5494 #endif
5495 gen_move_low32(arg, tmp);
5496 }
5497 register_name = "EntryLo1";
5498 break;
5499 case CP0_REG03__GLOBALNUM:
5500 CP0_CHECK(ctx->vp);
5501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5502 register_name = "GlobalNumber";
5503 break;
5504 default:
5505 goto cp0_unimplemented;
5506 }
5507 break;
5508 case CP0_REGISTER_04:
5509 switch (sel) {
5510 case CP0_REG04__CONTEXT:
5511 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context));
5512 tcg_gen_ext32s_tl(arg, arg);
5513 register_name = "Context";
5514 break;
5515 case CP0_REG04__CONTEXTCONFIG:
5516 /* SmartMIPS ASE */
5517 /* gen_helper_mfc0_contextconfig(arg); */
5518 register_name = "ContextConfig";
5519 goto cp0_unimplemented;
5520 case CP0_REG04__USERLOCAL:
5521 CP0_CHECK(ctx->ulri);
5522 tcg_gen_ld_tl(arg, tcg_env,
5523 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5524 tcg_gen_ext32s_tl(arg, arg);
5525 register_name = "UserLocal";
5526 break;
5527 case CP0_REG04__MMID:
5528 CP0_CHECK(ctx->mi);
5529 gen_helper_mtc0_memorymapid(tcg_env, arg);
5530 register_name = "MMID";
5531 break;
5532 default:
5533 goto cp0_unimplemented;
5534 }
5535 break;
5536 case CP0_REGISTER_05:
5537 switch (sel) {
5538 case CP0_REG05__PAGEMASK:
5539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5540 register_name = "PageMask";
5541 break;
5542 case CP0_REG05__PAGEGRAIN:
5543 check_insn(ctx, ISA_MIPS_R2);
5544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5545 register_name = "PageGrain";
5546 break;
5547 case CP0_REG05__SEGCTL0:
5548 CP0_CHECK(ctx->sc);
5549 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5550 tcg_gen_ext32s_tl(arg, arg);
5551 register_name = "SegCtl0";
5552 break;
5553 case CP0_REG05__SEGCTL1:
5554 CP0_CHECK(ctx->sc);
5555 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5556 tcg_gen_ext32s_tl(arg, arg);
5557 register_name = "SegCtl1";
5558 break;
5559 case CP0_REG05__SEGCTL2:
5560 CP0_CHECK(ctx->sc);
5561 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5562 tcg_gen_ext32s_tl(arg, arg);
5563 register_name = "SegCtl2";
5564 break;
5565 case CP0_REG05__PWBASE:
5566 check_pw(ctx);
5567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5568 register_name = "PWBase";
5569 break;
5570 case CP0_REG05__PWFIELD:
5571 check_pw(ctx);
5572 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5573 register_name = "PWField";
5574 break;
5575 case CP0_REG05__PWSIZE:
5576 check_pw(ctx);
5577 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5578 register_name = "PWSize";
5579 break;
5580 default:
5581 goto cp0_unimplemented;
5582 }
5583 break;
5584 case CP0_REGISTER_06:
5585 switch (sel) {
5586 case CP0_REG06__WIRED:
5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5588 register_name = "Wired";
5589 break;
5590 case CP0_REG06__SRSCONF0:
5591 check_insn(ctx, ISA_MIPS_R2);
5592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5593 register_name = "SRSConf0";
5594 break;
5595 case CP0_REG06__SRSCONF1:
5596 check_insn(ctx, ISA_MIPS_R2);
5597 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5598 register_name = "SRSConf1";
5599 break;
5600 case CP0_REG06__SRSCONF2:
5601 check_insn(ctx, ISA_MIPS_R2);
5602 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5603 register_name = "SRSConf2";
5604 break;
5605 case CP0_REG06__SRSCONF3:
5606 check_insn(ctx, ISA_MIPS_R2);
5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5608 register_name = "SRSConf3";
5609 break;
5610 case CP0_REG06__SRSCONF4:
5611 check_insn(ctx, ISA_MIPS_R2);
5612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5613 register_name = "SRSConf4";
5614 break;
5615 case CP0_REG06__PWCTL:
5616 check_pw(ctx);
5617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5618 register_name = "PWCtl";
5619 break;
5620 default:
5621 goto cp0_unimplemented;
5622 }
5623 break;
5624 case CP0_REGISTER_07:
5625 switch (sel) {
5626 case CP0_REG07__HWRENA:
5627 check_insn(ctx, ISA_MIPS_R2);
5628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5629 register_name = "HWREna";
5630 break;
5631 default:
5632 goto cp0_unimplemented;
5633 }
5634 break;
5635 case CP0_REGISTER_08:
5636 switch (sel) {
5637 case CP0_REG08__BADVADDR:
5638 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5639 tcg_gen_ext32s_tl(arg, arg);
5640 register_name = "BadVAddr";
5641 break;
5642 case CP0_REG08__BADINSTR:
5643 CP0_CHECK(ctx->bi);
5644 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5645 register_name = "BadInstr";
5646 break;
5647 case CP0_REG08__BADINSTRP:
5648 CP0_CHECK(ctx->bp);
5649 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5650 register_name = "BadInstrP";
5651 break;
5652 case CP0_REG08__BADINSTRX:
5653 CP0_CHECK(ctx->bi);
5654 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5655 tcg_gen_andi_tl(arg, arg, ~0xffff);
5656 register_name = "BadInstrX";
5657 break;
5658 default:
5659 goto cp0_unimplemented;
5660 }
5661 break;
5662 case CP0_REGISTER_09:
5663 switch (sel) {
5664 case CP0_REG09__COUNT:
5665 /* Mark as an IO operation because we read the time. */
5666 translator_io_start(&ctx->base);
5667
5668 gen_helper_mfc0_count(arg, tcg_env);
5669 /*
5670 * Break the TB to be able to take timer interrupts immediately
5671 * after reading count. DISAS_STOP isn't sufficient, we need to
5672 * ensure we break completely out of translated code.
5673 */
5674 gen_save_pc(ctx->base.pc_next + 4);
5675 ctx->base.is_jmp = DISAS_EXIT;
5676 register_name = "Count";
5677 break;
5678 case CP0_REG09__SAARI:
5679 CP0_CHECK(ctx->saar);
5680 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
5681 register_name = "SAARI";
5682 break;
5683 case CP0_REG09__SAAR:
5684 CP0_CHECK(ctx->saar);
5685 gen_helper_mfc0_saar(arg, tcg_env);
5686 register_name = "SAAR";
5687 break;
5688 default:
5689 goto cp0_unimplemented;
5690 }
5691 break;
5692 case CP0_REGISTER_10:
5693 switch (sel) {
5694 case CP0_REG10__ENTRYHI:
5695 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi));
5696 tcg_gen_ext32s_tl(arg, arg);
5697 register_name = "EntryHi";
5698 break;
5699 default:
5700 goto cp0_unimplemented;
5701 }
5702 break;
5703 case CP0_REGISTER_11:
5704 switch (sel) {
5705 case CP0_REG11__COMPARE:
5706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5707 register_name = "Compare";
5708 break;
5709 /* 6,7 are implementation dependent */
5710 default:
5711 goto cp0_unimplemented;
5712 }
5713 break;
5714 case CP0_REGISTER_12:
5715 switch (sel) {
5716 case CP0_REG12__STATUS:
5717 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5718 register_name = "Status";
5719 break;
5720 case CP0_REG12__INTCTL:
5721 check_insn(ctx, ISA_MIPS_R2);
5722 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5723 register_name = "IntCtl";
5724 break;
5725 case CP0_REG12__SRSCTL:
5726 check_insn(ctx, ISA_MIPS_R2);
5727 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5728 register_name = "SRSCtl";
5729 break;
5730 case CP0_REG12__SRSMAP:
5731 check_insn(ctx, ISA_MIPS_R2);
5732 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5733 register_name = "SRSMap";
5734 break;
5735 default:
5736 goto cp0_unimplemented;
5737 }
5738 break;
5739 case CP0_REGISTER_13:
5740 switch (sel) {
5741 case CP0_REG13__CAUSE:
5742 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5743 register_name = "Cause";
5744 break;
5745 default:
5746 goto cp0_unimplemented;
5747 }
5748 break;
5749 case CP0_REGISTER_14:
5750 switch (sel) {
5751 case CP0_REG14__EPC:
5752 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
5753 tcg_gen_ext32s_tl(arg, arg);
5754 register_name = "EPC";
5755 break;
5756 default:
5757 goto cp0_unimplemented;
5758 }
5759 break;
5760 case CP0_REGISTER_15:
5761 switch (sel) {
5762 case CP0_REG15__PRID:
5763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5764 register_name = "PRid";
5765 break;
5766 case CP0_REG15__EBASE:
5767 check_insn(ctx, ISA_MIPS_R2);
5768 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase));
5769 tcg_gen_ext32s_tl(arg, arg);
5770 register_name = "EBase";
5771 break;
5772 case CP0_REG15__CMGCRBASE:
5773 check_insn(ctx, ISA_MIPS_R2);
5774 CP0_CHECK(ctx->cmgcr);
5775 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5776 tcg_gen_ext32s_tl(arg, arg);
5777 register_name = "CMGCRBase";
5778 break;
5779 default:
5780 goto cp0_unimplemented;
5781 }
5782 break;
5783 case CP0_REGISTER_16:
5784 switch (sel) {
5785 case CP0_REG16__CONFIG:
5786 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5787 register_name = "Config";
5788 break;
5789 case CP0_REG16__CONFIG1:
5790 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5791 register_name = "Config1";
5792 break;
5793 case CP0_REG16__CONFIG2:
5794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5795 register_name = "Config2";
5796 break;
5797 case CP0_REG16__CONFIG3:
5798 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5799 register_name = "Config3";
5800 break;
5801 case CP0_REG16__CONFIG4:
5802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5803 register_name = "Config4";
5804 break;
5805 case CP0_REG16__CONFIG5:
5806 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5807 register_name = "Config5";
5808 break;
5809 /* 6,7 are implementation dependent */
5810 case CP0_REG16__CONFIG6:
5811 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5812 register_name = "Config6";
5813 break;
5814 case CP0_REG16__CONFIG7:
5815 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5816 register_name = "Config7";
5817 break;
5818 default:
5819 goto cp0_unimplemented;
5820 }
5821 break;
5822 case CP0_REGISTER_17:
5823 switch (sel) {
5824 case CP0_REG17__LLADDR:
5825 gen_helper_mfc0_lladdr(arg, tcg_env);
5826 register_name = "LLAddr";
5827 break;
5828 case CP0_REG17__MAAR:
5829 CP0_CHECK(ctx->mrp);
5830 gen_helper_mfc0_maar(arg, tcg_env);
5831 register_name = "MAAR";
5832 break;
5833 case CP0_REG17__MAARI:
5834 CP0_CHECK(ctx->mrp);
5835 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5836 register_name = "MAARI";
5837 break;
5838 default:
5839 goto cp0_unimplemented;
5840 }
5841 break;
5842 case CP0_REGISTER_18:
5843 switch (sel) {
5844 case CP0_REG18__WATCHLO0:
5845 case CP0_REG18__WATCHLO1:
5846 case CP0_REG18__WATCHLO2:
5847 case CP0_REG18__WATCHLO3:
5848 case CP0_REG18__WATCHLO4:
5849 case CP0_REG18__WATCHLO5:
5850 case CP0_REG18__WATCHLO6:
5851 case CP0_REG18__WATCHLO7:
5852 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5853 gen_helper_1e0i(mfc0_watchlo, arg, sel);
5854 register_name = "WatchLo";
5855 break;
5856 default:
5857 goto cp0_unimplemented;
5858 }
5859 break;
5860 case CP0_REGISTER_19:
5861 switch (sel) {
5862 case CP0_REG19__WATCHHI0:
5863 case CP0_REG19__WATCHHI1:
5864 case CP0_REG19__WATCHHI2:
5865 case CP0_REG19__WATCHHI3:
5866 case CP0_REG19__WATCHHI4:
5867 case CP0_REG19__WATCHHI5:
5868 case CP0_REG19__WATCHHI6:
5869 case CP0_REG19__WATCHHI7:
5870 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
5871 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5872 register_name = "WatchHi";
5873 break;
5874 default:
5875 goto cp0_unimplemented;
5876 }
5877 break;
5878 case CP0_REGISTER_20:
5879 switch (sel) {
5880 case CP0_REG20__XCONTEXT:
5881 #if defined(TARGET_MIPS64)
5882 check_insn(ctx, ISA_MIPS3);
5883 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext));
5884 tcg_gen_ext32s_tl(arg, arg);
5885 register_name = "XContext";
5886 break;
5887 #endif
5888 default:
5889 goto cp0_unimplemented;
5890 }
5891 break;
5892 case CP0_REGISTER_21:
5893 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5894 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5895 switch (sel) {
5896 case 0:
5897 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5898 register_name = "Framemask";
5899 break;
5900 default:
5901 goto cp0_unimplemented;
5902 }
5903 break;
5904 case CP0_REGISTER_22:
5905 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5906 register_name = "'Diagnostic"; /* implementation dependent */
5907 break;
5908 case CP0_REGISTER_23:
5909 switch (sel) {
5910 case CP0_REG23__DEBUG:
5911 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */
5912 register_name = "Debug";
5913 break;
5914 case CP0_REG23__TRACECONTROL:
5915 /* PDtrace support */
5916 /* gen_helper_mfc0_tracecontrol(arg); */
5917 register_name = "TraceControl";
5918 goto cp0_unimplemented;
5919 case CP0_REG23__TRACECONTROL2:
5920 /* PDtrace support */
5921 /* gen_helper_mfc0_tracecontrol2(arg); */
5922 register_name = "TraceControl2";
5923 goto cp0_unimplemented;
5924 case CP0_REG23__USERTRACEDATA1:
5925 /* PDtrace support */
5926 /* gen_helper_mfc0_usertracedata1(arg);*/
5927 register_name = "UserTraceData1";
5928 goto cp0_unimplemented;
5929 case CP0_REG23__TRACEIBPC:
5930 /* PDtrace support */
5931 /* gen_helper_mfc0_traceibpc(arg); */
5932 register_name = "TraceIBPC";
5933 goto cp0_unimplemented;
5934 case CP0_REG23__TRACEDBPC:
5935 /* PDtrace support */
5936 /* gen_helper_mfc0_tracedbpc(arg); */
5937 register_name = "TraceDBPC";
5938 goto cp0_unimplemented;
5939 default:
5940 goto cp0_unimplemented;
5941 }
5942 break;
5943 case CP0_REGISTER_24:
5944 switch (sel) {
5945 case CP0_REG24__DEPC:
5946 /* EJTAG support */
5947 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
5948 tcg_gen_ext32s_tl(arg, arg);
5949 register_name = "DEPC";
5950 break;
5951 default:
5952 goto cp0_unimplemented;
5953 }
5954 break;
5955 case CP0_REGISTER_25:
5956 switch (sel) {
5957 case CP0_REG25__PERFCTL0:
5958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5959 register_name = "Performance0";
5960 break;
5961 case CP0_REG25__PERFCNT0:
5962 /* gen_helper_mfc0_performance1(arg); */
5963 register_name = "Performance1";
5964 goto cp0_unimplemented;
5965 case CP0_REG25__PERFCTL1:
5966 /* gen_helper_mfc0_performance2(arg); */
5967 register_name = "Performance2";
5968 goto cp0_unimplemented;
5969 case CP0_REG25__PERFCNT1:
5970 /* gen_helper_mfc0_performance3(arg); */
5971 register_name = "Performance3";
5972 goto cp0_unimplemented;
5973 case CP0_REG25__PERFCTL2:
5974 /* gen_helper_mfc0_performance4(arg); */
5975 register_name = "Performance4";
5976 goto cp0_unimplemented;
5977 case CP0_REG25__PERFCNT2:
5978 /* gen_helper_mfc0_performance5(arg); */
5979 register_name = "Performance5";
5980 goto cp0_unimplemented;
5981 case CP0_REG25__PERFCTL3:
5982 /* gen_helper_mfc0_performance6(arg); */
5983 register_name = "Performance6";
5984 goto cp0_unimplemented;
5985 case CP0_REG25__PERFCNT3:
5986 /* gen_helper_mfc0_performance7(arg); */
5987 register_name = "Performance7";
5988 goto cp0_unimplemented;
5989 default:
5990 goto cp0_unimplemented;
5991 }
5992 break;
5993 case CP0_REGISTER_26:
5994 switch (sel) {
5995 case CP0_REG26__ERRCTL:
5996 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5997 register_name = "ErrCtl";
5998 break;
5999 default:
6000 goto cp0_unimplemented;
6001 }
6002 break;
6003 case CP0_REGISTER_27:
6004 switch (sel) {
6005 case CP0_REG27__CACHERR:
6006 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6007 register_name = "CacheErr";
6008 break;
6009 default:
6010 goto cp0_unimplemented;
6011 }
6012 break;
6013 case CP0_REGISTER_28:
6014 switch (sel) {
6015 case CP0_REG28__TAGLO:
6016 case CP0_REG28__TAGLO1:
6017 case CP0_REG28__TAGLO2:
6018 case CP0_REG28__TAGLO3:
6019 {
6020 TCGv_i64 tmp = tcg_temp_new_i64();
6021 tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUMIPSState, CP0_TagLo));
6022 gen_move_low32(arg, tmp);
6023 }
6024 register_name = "TagLo";
6025 break;
6026 case CP0_REG28__DATALO:
6027 case CP0_REG28__DATALO1:
6028 case CP0_REG28__DATALO2:
6029 case CP0_REG28__DATALO3:
6030 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6031 register_name = "DataLo";
6032 break;
6033 default:
6034 goto cp0_unimplemented;
6035 }
6036 break;
6037 case CP0_REGISTER_29:
6038 switch (sel) {
6039 case CP0_REG29__TAGHI:
6040 case CP0_REG29__TAGHI1:
6041 case CP0_REG29__TAGHI2:
6042 case CP0_REG29__TAGHI3:
6043 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6044 register_name = "TagHi";
6045 break;
6046 case CP0_REG29__DATAHI:
6047 case CP0_REG29__DATAHI1:
6048 case CP0_REG29__DATAHI2:
6049 case CP0_REG29__DATAHI3:
6050 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6051 register_name = "DataHi";
6052 break;
6053 default:
6054 goto cp0_unimplemented;
6055 }
6056 break;
6057 case CP0_REGISTER_30:
6058 switch (sel) {
6059 case CP0_REG30__ERROREPC:
6060 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6061 tcg_gen_ext32s_tl(arg, arg);
6062 register_name = "ErrorEPC";
6063 break;
6064 default:
6065 goto cp0_unimplemented;
6066 }
6067 break;
6068 case CP0_REGISTER_31:
6069 switch (sel) {
6070 case CP0_REG31__DESAVE:
6071 /* EJTAG support */
6072 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6073 register_name = "DESAVE";
6074 break;
6075 case CP0_REG31__KSCRATCH1:
6076 case CP0_REG31__KSCRATCH2:
6077 case CP0_REG31__KSCRATCH3:
6078 case CP0_REG31__KSCRATCH4:
6079 case CP0_REG31__KSCRATCH5:
6080 case CP0_REG31__KSCRATCH6:
6081 CP0_CHECK(ctx->kscrexist & (1 << sel));
6082 tcg_gen_ld_tl(arg, tcg_env,
6083 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6084 tcg_gen_ext32s_tl(arg, arg);
6085 register_name = "KScratch";
6086 break;
6087 default:
6088 goto cp0_unimplemented;
6089 }
6090 break;
6091 default:
6092 goto cp0_unimplemented;
6093 }
6094 trace_mips_translate_c0("mfc0", register_name, reg, sel);
6095 return;
6096
6097 cp0_unimplemented:
6098 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6099 register_name, reg, sel);
6100 gen_mfc0_unimplemented(ctx, arg);
6101 }
6102
6103 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6104 {
6105 const char *register_name = "invalid";
6106 bool icount;
6107
6108 if (sel != 0) {
6109 check_insn(ctx, ISA_MIPS_R1);
6110 }
6111
6112 icount = translator_io_start(&ctx->base);
6113
6114 switch (reg) {
6115 case CP0_REGISTER_00:
6116 switch (sel) {
6117 case CP0_REG00__INDEX:
6118 gen_helper_mtc0_index(tcg_env, arg);
6119 register_name = "Index";
6120 break;
6121 case CP0_REG00__MVPCONTROL:
6122 CP0_CHECK(ctx->insn_flags & ASE_MT);
6123 gen_helper_mtc0_mvpcontrol(tcg_env, arg);
6124 register_name = "MVPControl";
6125 break;
6126 case CP0_REG00__MVPCONF0:
6127 CP0_CHECK(ctx->insn_flags & ASE_MT);
6128 /* ignored */
6129 register_name = "MVPConf0";
6130 break;
6131 case CP0_REG00__MVPCONF1:
6132 CP0_CHECK(ctx->insn_flags & ASE_MT);
6133 /* ignored */
6134 register_name = "MVPConf1";
6135 break;
6136 case CP0_REG00__VPCONTROL:
6137 CP0_CHECK(ctx->vp);
6138 /* ignored */
6139 register_name = "VPControl";
6140 break;
6141 default:
6142 goto cp0_unimplemented;
6143 }
6144 break;
6145 case CP0_REGISTER_01:
6146 switch (sel) {
6147 case CP0_REG01__RANDOM:
6148 /* ignored */
6149 register_name = "Random";
6150 break;
6151 case CP0_REG01__VPECONTROL:
6152 CP0_CHECK(ctx->insn_flags & ASE_MT);
6153 gen_helper_mtc0_vpecontrol(tcg_env, arg);
6154 register_name = "VPEControl";
6155 break;
6156 case CP0_REG01__VPECONF0:
6157 CP0_CHECK(ctx->insn_flags & ASE_MT);
6158 gen_helper_mtc0_vpeconf0(tcg_env, arg);
6159 register_name = "VPEConf0";
6160 break;
6161 case CP0_REG01__VPECONF1:
6162 CP0_CHECK(ctx->insn_flags & ASE_MT);
6163 gen_helper_mtc0_vpeconf1(tcg_env, arg);
6164 register_name = "VPEConf1";
6165 break;
6166 case CP0_REG01__YQMASK:
6167 CP0_CHECK(ctx->insn_flags & ASE_MT);
6168 gen_helper_mtc0_yqmask(tcg_env, arg);
6169 register_name = "YQMask";
6170 break;
6171 case CP0_REG01__VPESCHEDULE:
6172 CP0_CHECK(ctx->insn_flags & ASE_MT);
6173 tcg_gen_st_tl(arg, tcg_env,
6174 offsetof(CPUMIPSState, CP0_VPESchedule));
6175 register_name = "VPESchedule";
6176 break;
6177 case CP0_REG01__VPESCHEFBACK:
6178 CP0_CHECK(ctx->insn_flags & ASE_MT);
6179 tcg_gen_st_tl(arg, tcg_env,
6180 offsetof(CPUMIPSState, CP0_VPEScheFBack));
6181 register_name = "VPEScheFBack";
6182 break;
6183 case CP0_REG01__VPEOPT:
6184 CP0_CHECK(ctx->insn_flags & ASE_MT);
6185 gen_helper_mtc0_vpeopt(tcg_env, arg);
6186 register_name = "VPEOpt";
6187 break;
6188 default:
6189 goto cp0_unimplemented;
6190 }
6191 break;
6192 case CP0_REGISTER_02:
6193 switch (sel) {
6194 case CP0_REG02__ENTRYLO0:
6195 gen_helper_mtc0_entrylo0(tcg_env, arg);
6196 register_name = "EntryLo0";
6197 break;
6198 case CP0_REG02__TCSTATUS:
6199 CP0_CHECK(ctx->insn_flags & ASE_MT);
6200 gen_helper_mtc0_tcstatus(tcg_env, arg);
6201 register_name = "TCStatus";
6202 break;
6203 case CP0_REG02__TCBIND:
6204 CP0_CHECK(ctx->insn_flags & ASE_MT);
6205 gen_helper_mtc0_tcbind(tcg_env, arg);
6206 register_name = "TCBind";
6207 break;
6208 case CP0_REG02__TCRESTART:
6209 CP0_CHECK(ctx->insn_flags & ASE_MT);
6210 gen_helper_mtc0_tcrestart(tcg_env, arg);
6211 register_name = "TCRestart";
6212 break;
6213 case CP0_REG02__TCHALT:
6214 CP0_CHECK(ctx->insn_flags & ASE_MT);
6215 gen_helper_mtc0_tchalt(tcg_env, arg);
6216 register_name = "TCHalt";
6217 break;
6218 case CP0_REG02__TCCONTEXT:
6219 CP0_CHECK(ctx->insn_flags & ASE_MT);
6220 gen_helper_mtc0_tccontext(tcg_env, arg);
6221 register_name = "TCContext";
6222 break;
6223 case CP0_REG02__TCSCHEDULE:
6224 CP0_CHECK(ctx->insn_flags & ASE_MT);
6225 gen_helper_mtc0_tcschedule(tcg_env, arg);
6226 register_name = "TCSchedule";
6227 break;
6228 case CP0_REG02__TCSCHEFBACK:
6229 CP0_CHECK(ctx->insn_flags & ASE_MT);
6230 gen_helper_mtc0_tcschefback(tcg_env, arg);
6231 register_name = "TCScheFBack";
6232 break;
6233 default:
6234 goto cp0_unimplemented;
6235 }
6236 break;
6237 case CP0_REGISTER_03:
6238 switch (sel) {
6239 case CP0_REG03__ENTRYLO1:
6240 gen_helper_mtc0_entrylo1(tcg_env, arg);
6241 register_name = "EntryLo1";
6242 break;
6243 case CP0_REG03__GLOBALNUM:
6244 CP0_CHECK(ctx->vp);
6245 /* ignored */
6246 register_name = "GlobalNumber";
6247 break;
6248 default:
6249 goto cp0_unimplemented;
6250 }
6251 break;
6252 case CP0_REGISTER_04:
6253 switch (sel) {
6254 case CP0_REG04__CONTEXT:
6255 gen_helper_mtc0_context(tcg_env, arg);
6256 register_name = "Context";
6257 break;
6258 case CP0_REG04__CONTEXTCONFIG:
6259 /* SmartMIPS ASE */
6260 /* gen_helper_mtc0_contextconfig(arg); */
6261 register_name = "ContextConfig";
6262 goto cp0_unimplemented;
6263 case CP0_REG04__USERLOCAL:
6264 CP0_CHECK(ctx->ulri);
6265 tcg_gen_st_tl(arg, tcg_env,
6266 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6267 register_name = "UserLocal";
6268 break;
6269 case CP0_REG04__MMID:
6270 CP0_CHECK(ctx->mi);
6271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6272 register_name = "MMID";
6273 break;
6274 default:
6275 goto cp0_unimplemented;
6276 }
6277 break;
6278 case CP0_REGISTER_05:
6279 switch (sel) {
6280 case CP0_REG05__PAGEMASK:
6281 gen_helper_mtc0_pagemask(tcg_env, arg);
6282 register_name = "PageMask";
6283 break;
6284 case CP0_REG05__PAGEGRAIN:
6285 check_insn(ctx, ISA_MIPS_R2);
6286 gen_helper_mtc0_pagegrain(tcg_env, arg);
6287 register_name = "PageGrain";
6288 ctx->base.is_jmp = DISAS_STOP;
6289 break;
6290 case CP0_REG05__SEGCTL0:
6291 CP0_CHECK(ctx->sc);
6292 gen_helper_mtc0_segctl0(tcg_env, arg);
6293 register_name = "SegCtl0";
6294 break;
6295 case CP0_REG05__SEGCTL1:
6296 CP0_CHECK(ctx->sc);
6297 gen_helper_mtc0_segctl1(tcg_env, arg);
6298 register_name = "SegCtl1";
6299 break;
6300 case CP0_REG05__SEGCTL2:
6301 CP0_CHECK(ctx->sc);
6302 gen_helper_mtc0_segctl2(tcg_env, arg);
6303 register_name = "SegCtl2";
6304 break;
6305 case CP0_REG05__PWBASE:
6306 check_pw(ctx);
6307 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6308 register_name = "PWBase";
6309 break;
6310 case CP0_REG05__PWFIELD:
6311 check_pw(ctx);
6312 gen_helper_mtc0_pwfield(tcg_env, arg);
6313 register_name = "PWField";
6314 break;
6315 case CP0_REG05__PWSIZE:
6316 check_pw(ctx);
6317 gen_helper_mtc0_pwsize(tcg_env, arg);
6318 register_name = "PWSize";
6319 break;
6320 default:
6321 goto cp0_unimplemented;
6322 }
6323 break;
6324 case CP0_REGISTER_06:
6325 switch (sel) {
6326 case CP0_REG06__WIRED:
6327 gen_helper_mtc0_wired(tcg_env, arg);
6328 register_name = "Wired";
6329 break;
6330 case CP0_REG06__SRSCONF0:
6331 check_insn(ctx, ISA_MIPS_R2);
6332 gen_helper_mtc0_srsconf0(tcg_env, arg);
6333 register_name = "SRSConf0";
6334 break;
6335 case CP0_REG06__SRSCONF1:
6336 check_insn(ctx, ISA_MIPS_R2);
6337 gen_helper_mtc0_srsconf1(tcg_env, arg);
6338 register_name = "SRSConf1";
6339 break;
6340 case CP0_REG06__SRSCONF2:
6341 check_insn(ctx, ISA_MIPS_R2);
6342 gen_helper_mtc0_srsconf2(tcg_env, arg);
6343 register_name = "SRSConf2";
6344 break;
6345 case CP0_REG06__SRSCONF3:
6346 check_insn(ctx, ISA_MIPS_R2);
6347 gen_helper_mtc0_srsconf3(tcg_env, arg);
6348 register_name = "SRSConf3";
6349 break;
6350 case CP0_REG06__SRSCONF4:
6351 check_insn(ctx, ISA_MIPS_R2);
6352 gen_helper_mtc0_srsconf4(tcg_env, arg);
6353 register_name = "SRSConf4";
6354 break;
6355 case CP0_REG06__PWCTL:
6356 check_pw(ctx);
6357 gen_helper_mtc0_pwctl(tcg_env, arg);
6358 register_name = "PWCtl";
6359 break;
6360 default:
6361 goto cp0_unimplemented;
6362 }
6363 break;
6364 case CP0_REGISTER_07:
6365 switch (sel) {
6366 case CP0_REG07__HWRENA:
6367 check_insn(ctx, ISA_MIPS_R2);
6368 gen_helper_mtc0_hwrena(tcg_env, arg);
6369 ctx->base.is_jmp = DISAS_STOP;
6370 register_name = "HWREna";
6371 break;
6372 default:
6373 goto cp0_unimplemented;
6374 }
6375 break;
6376 case CP0_REGISTER_08:
6377 switch (sel) {
6378 case CP0_REG08__BADVADDR:
6379 /* ignored */
6380 register_name = "BadVAddr";
6381 break;
6382 case CP0_REG08__BADINSTR:
6383 /* ignored */
6384 register_name = "BadInstr";
6385 break;
6386 case CP0_REG08__BADINSTRP:
6387 /* ignored */
6388 register_name = "BadInstrP";
6389 break;
6390 case CP0_REG08__BADINSTRX:
6391 /* ignored */
6392 register_name = "BadInstrX";
6393 break;
6394 default:
6395 goto cp0_unimplemented;
6396 }
6397 break;
6398 case CP0_REGISTER_09:
6399 switch (sel) {
6400 case CP0_REG09__COUNT:
6401 gen_helper_mtc0_count(tcg_env, arg);
6402 register_name = "Count";
6403 break;
6404 case CP0_REG09__SAARI:
6405 CP0_CHECK(ctx->saar);
6406 gen_helper_mtc0_saari(tcg_env, arg);
6407 register_name = "SAARI";
6408 break;
6409 case CP0_REG09__SAAR:
6410 CP0_CHECK(ctx->saar);
6411 gen_helper_mtc0_saar(tcg_env, arg);
6412 register_name = "SAAR";
6413 break;
6414 default:
6415 goto cp0_unimplemented;
6416 }
6417 break;
6418 case CP0_REGISTER_10:
6419 switch (sel) {
6420 case CP0_REG10__ENTRYHI:
6421 gen_helper_mtc0_entryhi(tcg_env, arg);
6422 register_name = "EntryHi";
6423 break;
6424 default:
6425 goto cp0_unimplemented;
6426 }
6427 break;
6428 case CP0_REGISTER_11:
6429 switch (sel) {
6430 case CP0_REG11__COMPARE:
6431 gen_helper_mtc0_compare(tcg_env, arg);
6432 register_name = "Compare";
6433 break;
6434 /* 6,7 are implementation dependent */
6435 default:
6436 goto cp0_unimplemented;
6437 }
6438 break;
6439 case CP0_REGISTER_12:
6440 switch (sel) {
6441 case CP0_REG12__STATUS:
6442 save_cpu_state(ctx, 1);
6443 gen_helper_mtc0_status(tcg_env, arg);
6444 /* DISAS_STOP isn't good enough here, hflags may have changed. */
6445 gen_save_pc(ctx->base.pc_next + 4);
6446 ctx->base.is_jmp = DISAS_EXIT;
6447 register_name = "Status";
6448 break;
6449 case CP0_REG12__INTCTL:
6450 check_insn(ctx, ISA_MIPS_R2);
6451 gen_helper_mtc0_intctl(tcg_env, arg);
6452 /* Stop translation as we may have switched the execution mode */
6453 ctx->base.is_jmp = DISAS_STOP;
6454 register_name = "IntCtl";
6455 break;
6456 case CP0_REG12__SRSCTL:
6457 check_insn(ctx, ISA_MIPS_R2);
6458 gen_helper_mtc0_srsctl(tcg_env, arg);
6459 /* Stop translation as we may have switched the execution mode */
6460 ctx->base.is_jmp = DISAS_STOP;
6461 register_name = "SRSCtl";
6462 break;
6463 case CP0_REG12__SRSMAP:
6464 check_insn(ctx, ISA_MIPS_R2);
6465 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6466 /* Stop translation as we may have switched the execution mode */
6467 ctx->base.is_jmp = DISAS_STOP;
6468 register_name = "SRSMap";
6469 break;
6470 default:
6471 goto cp0_unimplemented;
6472 }
6473 break;
6474 case CP0_REGISTER_13:
6475 switch (sel) {
6476 case CP0_REG13__CAUSE:
6477 save_cpu_state(ctx, 1);
6478 gen_helper_mtc0_cause(tcg_env, arg);
6479 /*
6480 * Stop translation as we may have triggered an interrupt.
6481 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6482 * translated code to check for pending interrupts.
6483 */
6484 gen_save_pc(ctx->base.pc_next + 4);
6485 ctx->base.is_jmp = DISAS_EXIT;
6486 register_name = "Cause";
6487 break;
6488 default:
6489 goto cp0_unimplemented;
6490 }
6491 break;
6492 case CP0_REGISTER_14:
6493 switch (sel) {
6494 case CP0_REG14__EPC:
6495 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
6496 register_name = "EPC";
6497 break;
6498 default:
6499 goto cp0_unimplemented;
6500 }
6501 break;
6502 case CP0_REGISTER_15:
6503 switch (sel) {
6504 case CP0_REG15__PRID:
6505 /* ignored */
6506 register_name = "PRid";
6507 break;
6508 case CP0_REG15__EBASE:
6509 check_insn(ctx, ISA_MIPS_R2);
6510 gen_helper_mtc0_ebase(tcg_env, arg);
6511 register_name = "EBase";
6512 break;
6513 default:
6514 goto cp0_unimplemented;
6515 }
6516 break;
6517 case CP0_REGISTER_16:
6518 switch (sel) {
6519 case CP0_REG16__CONFIG:
6520 gen_helper_mtc0_config0(tcg_env, arg);
6521 register_name = "Config";
6522 /* Stop translation as we may have switched the execution mode */
6523 ctx->base.is_jmp = DISAS_STOP;
6524 break;
6525 case CP0_REG16__CONFIG1:
6526 /* ignored, read only */
6527 register_name = "Config1";
6528 break;
6529 case CP0_REG16__CONFIG2:
6530 gen_helper_mtc0_config2(tcg_env, arg);
6531 register_name = "Config2";
6532 /* Stop translation as we may have switched the execution mode */
6533 ctx->base.is_jmp = DISAS_STOP;
6534 break;
6535 case CP0_REG16__CONFIG3:
6536 gen_helper_mtc0_config3(tcg_env, arg);
6537 register_name = "Config3";
6538 /* Stop translation as we may have switched the execution mode */
6539 ctx->base.is_jmp = DISAS_STOP;
6540 break;
6541 case CP0_REG16__CONFIG4:
6542 gen_helper_mtc0_config4(tcg_env, arg);
6543 register_name = "Config4";
6544 ctx->base.is_jmp = DISAS_STOP;
6545 break;
6546 case CP0_REG16__CONFIG5:
6547 gen_helper_mtc0_config5(tcg_env, arg);
6548 register_name = "Config5";
6549 /* Stop translation as we may have switched the execution mode */
6550 ctx->base.is_jmp = DISAS_STOP;
6551 break;
6552 /* 6,7 are implementation dependent */
6553 case CP0_REG16__CONFIG6:
6554 /* ignored */
6555 register_name = "Config6";
6556 break;
6557 case CP0_REG16__CONFIG7:
6558 /* ignored */
6559 register_name = "Config7";
6560 break;
6561 default:
6562 register_name = "Invalid config selector";
6563 goto cp0_unimplemented;
6564 }
6565 break;
6566 case CP0_REGISTER_17:
6567 switch (sel) {
6568 case CP0_REG17__LLADDR:
6569 gen_helper_mtc0_lladdr(tcg_env, arg);
6570 register_name = "LLAddr";
6571 break;
6572 case CP0_REG17__MAAR:
6573 CP0_CHECK(ctx->mrp);
6574 gen_helper_mtc0_maar(tcg_env, arg);
6575 register_name = "MAAR";
6576 break;
6577 case CP0_REG17__MAARI:
6578 CP0_CHECK(ctx->mrp);
6579 gen_helper_mtc0_maari(tcg_env, arg);
6580 register_name = "MAARI";
6581 break;
6582 default:
6583 goto cp0_unimplemented;
6584 }
6585 break;
6586 case CP0_REGISTER_18:
6587 switch (sel) {
6588 case CP0_REG18__WATCHLO0:
6589 case CP0_REG18__WATCHLO1:
6590 case CP0_REG18__WATCHLO2:
6591 case CP0_REG18__WATCHLO3:
6592 case CP0_REG18__WATCHLO4:
6593 case CP0_REG18__WATCHLO5:
6594 case CP0_REG18__WATCHLO6:
6595 case CP0_REG18__WATCHLO7:
6596 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6597 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6598 register_name = "WatchLo";
6599 break;
6600 default:
6601 goto cp0_unimplemented;
6602 }
6603 break;
6604 case CP0_REGISTER_19:
6605 switch (sel) {
6606 case CP0_REG19__WATCHHI0:
6607 case CP0_REG19__WATCHHI1:
6608 case CP0_REG19__WATCHHI2:
6609 case CP0_REG19__WATCHHI3:
6610 case CP0_REG19__WATCHHI4:
6611 case CP0_REG19__WATCHHI5:
6612 case CP0_REG19__WATCHHI6:
6613 case CP0_REG19__WATCHHI7:
6614 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6615 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6616 register_name = "WatchHi";
6617 break;
6618 default:
6619 goto cp0_unimplemented;
6620 }
6621 break;
6622 case CP0_REGISTER_20:
6623 switch (sel) {
6624 case CP0_REG20__XCONTEXT:
6625 #if defined(TARGET_MIPS64)
6626 check_insn(ctx, ISA_MIPS3);
6627 gen_helper_mtc0_xcontext(tcg_env, arg);
6628 register_name = "XContext";
6629 break;
6630 #endif
6631 default:
6632 goto cp0_unimplemented;
6633 }
6634 break;
6635 case CP0_REGISTER_21:
6636 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6637 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6638 switch (sel) {
6639 case 0:
6640 gen_helper_mtc0_framemask(tcg_env, arg);
6641 register_name = "Framemask";
6642 break;
6643 default:
6644 goto cp0_unimplemented;
6645 }
6646 break;
6647 case CP0_REGISTER_22:
6648 /* ignored */
6649 register_name = "Diagnostic"; /* implementation dependent */
6650 break;
6651 case CP0_REGISTER_23:
6652 switch (sel) {
6653 case CP0_REG23__DEBUG:
6654 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */
6655 /* DISAS_STOP isn't good enough here, hflags may have changed. */
6656 gen_save_pc(ctx->base.pc_next + 4);
6657 ctx->base.is_jmp = DISAS_EXIT;
6658 register_name = "Debug";
6659 break;
6660 case CP0_REG23__TRACECONTROL:
6661 /* PDtrace support */
6662 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */
6663 register_name = "TraceControl";
6664 /* Stop translation as we may have switched the execution mode */
6665 ctx->base.is_jmp = DISAS_STOP;
6666 goto cp0_unimplemented;
6667 case CP0_REG23__TRACECONTROL2:
6668 /* PDtrace support */
6669 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */
6670 register_name = "TraceControl2";
6671 /* Stop translation as we may have switched the execution mode */
6672 ctx->base.is_jmp = DISAS_STOP;
6673 goto cp0_unimplemented;
6674 case CP0_REG23__USERTRACEDATA1:
6675 /* Stop translation as we may have switched the execution mode */
6676 ctx->base.is_jmp = DISAS_STOP;
6677 /* PDtrace support */
6678 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/
6679 register_name = "UserTraceData";
6680 /* Stop translation as we may have switched the execution mode */
6681 ctx->base.is_jmp = DISAS_STOP;
6682 goto cp0_unimplemented;
6683 case CP0_REG23__TRACEIBPC:
6684 /* PDtrace support */
6685 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */
6686 /* Stop translation as we may have switched the execution mode */
6687 ctx->base.is_jmp = DISAS_STOP;
6688 register_name = "TraceIBPC";
6689 goto cp0_unimplemented;
6690 case CP0_REG23__TRACEDBPC:
6691 /* PDtrace support */
6692 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */
6693 /* Stop translation as we may have switched the execution mode */
6694 ctx->base.is_jmp = DISAS_STOP;
6695 register_name = "TraceDBPC";
6696 goto cp0_unimplemented;
6697 default:
6698 goto cp0_unimplemented;
6699 }
6700 break;
6701 case CP0_REGISTER_24:
6702 switch (sel) {
6703 case CP0_REG24__DEPC:
6704 /* EJTAG support */
6705 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
6706 register_name = "DEPC";
6707 break;
6708 default:
6709 goto cp0_unimplemented;
6710 }
6711 break;
6712 case CP0_REGISTER_25:
6713 switch (sel) {
6714 case CP0_REG25__PERFCTL0:
6715 gen_helper_mtc0_performance0(tcg_env, arg);
6716 register_name = "Performance0";
6717 break;
6718 case CP0_REG25__PERFCNT0:
6719 /* gen_helper_mtc0_performance1(arg); */
6720 register_name = "Performance1";
6721 goto cp0_unimplemented;
6722 case CP0_REG25__PERFCTL1:
6723 /* gen_helper_mtc0_performance2(arg); */
6724 register_name = "Performance2";
6725 goto cp0_unimplemented;
6726 case CP0_REG25__PERFCNT1:
6727 /* gen_helper_mtc0_performance3(arg); */
6728 register_name = "Performance3";
6729 goto cp0_unimplemented;
6730 case CP0_REG25__PERFCTL2:
6731 /* gen_helper_mtc0_performance4(arg); */
6732 register_name = "Performance4";
6733 goto cp0_unimplemented;
6734 case CP0_REG25__PERFCNT2:
6735 /* gen_helper_mtc0_performance5(arg); */
6736 register_name = "Performance5";
6737 goto cp0_unimplemented;
6738 case CP0_REG25__PERFCTL3:
6739 /* gen_helper_mtc0_performance6(arg); */
6740 register_name = "Performance6";
6741 goto cp0_unimplemented;
6742 case CP0_REG25__PERFCNT3:
6743 /* gen_helper_mtc0_performance7(arg); */
6744 register_name = "Performance7";
6745 goto cp0_unimplemented;
6746 default:
6747 goto cp0_unimplemented;
6748 }
6749 break;
6750 case CP0_REGISTER_26:
6751 switch (sel) {
6752 case CP0_REG26__ERRCTL:
6753 gen_helper_mtc0_errctl(tcg_env, arg);
6754 ctx->base.is_jmp = DISAS_STOP;
6755 register_name = "ErrCtl";
6756 break;
6757 default:
6758 goto cp0_unimplemented;
6759 }
6760 break;
6761 case CP0_REGISTER_27:
6762 switch (sel) {
6763 case CP0_REG27__CACHERR:
6764 /* ignored */
6765 register_name = "CacheErr";
6766 break;
6767 default:
6768 goto cp0_unimplemented;
6769 }
6770 break;
6771 case CP0_REGISTER_28:
6772 switch (sel) {
6773 case CP0_REG28__TAGLO:
6774 case CP0_REG28__TAGLO1:
6775 case CP0_REG28__TAGLO2:
6776 case CP0_REG28__TAGLO3:
6777 gen_helper_mtc0_taglo(tcg_env, arg);
6778 register_name = "TagLo";
6779 break;
6780 case CP0_REG28__DATALO:
6781 case CP0_REG28__DATALO1:
6782 case CP0_REG28__DATALO2:
6783 case CP0_REG28__DATALO3:
6784 gen_helper_mtc0_datalo(tcg_env, arg);
6785 register_name = "DataLo";
6786 break;
6787 default:
6788 goto cp0_unimplemented;
6789 }
6790 break;
6791 case CP0_REGISTER_29:
6792 switch (sel) {
6793 case CP0_REG29__TAGHI:
6794 case CP0_REG29__TAGHI1:
6795 case CP0_REG29__TAGHI2:
6796 case CP0_REG29__TAGHI3:
6797 gen_helper_mtc0_taghi(tcg_env, arg);
6798 register_name = "TagHi";
6799 break;
6800 case CP0_REG29__DATAHI:
6801 case CP0_REG29__DATAHI1:
6802 case CP0_REG29__DATAHI2:
6803 case CP0_REG29__DATAHI3:
6804 gen_helper_mtc0_datahi(tcg_env, arg);
6805 register_name = "DataHi";
6806 break;
6807 default:
6808 register_name = "invalid sel";
6809 goto cp0_unimplemented;
6810 }
6811 break;
6812 case CP0_REGISTER_30:
6813 switch (sel) {
6814 case CP0_REG30__ERROREPC:
6815 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6816 register_name = "ErrorEPC";
6817 break;
6818 default:
6819 goto cp0_unimplemented;
6820 }
6821 break;
6822 case CP0_REGISTER_31:
6823 switch (sel) {
6824 case CP0_REG31__DESAVE:
6825 /* EJTAG support */
6826 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6827 register_name = "DESAVE";
6828 break;
6829 case CP0_REG31__KSCRATCH1:
6830 case CP0_REG31__KSCRATCH2:
6831 case CP0_REG31__KSCRATCH3:
6832 case CP0_REG31__KSCRATCH4:
6833 case CP0_REG31__KSCRATCH5:
6834 case CP0_REG31__KSCRATCH6:
6835 CP0_CHECK(ctx->kscrexist & (1 << sel));
6836 tcg_gen_st_tl(arg, tcg_env,
6837 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6838 register_name = "KScratch";
6839 break;
6840 default:
6841 goto cp0_unimplemented;
6842 }
6843 break;
6844 default:
6845 goto cp0_unimplemented;
6846 }
6847 trace_mips_translate_c0("mtc0", register_name, reg, sel);
6848
6849 /* For simplicity assume that all writes can cause interrupts. */
6850 if (icount) {
6851 /*
6852 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6853 * translated code to check for pending interrupts.
6854 */
6855 gen_save_pc(ctx->base.pc_next + 4);
6856 ctx->base.is_jmp = DISAS_EXIT;
6857 }
6858 return;
6859
6860 cp0_unimplemented:
6861 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
6862 register_name, reg, sel);
6863 }
6864
6865 #if defined(TARGET_MIPS64)
6866 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6867 {
6868 const char *register_name = "invalid";
6869
6870 if (sel != 0) {
6871 check_insn(ctx, ISA_MIPS_R1);
6872 }
6873
6874 switch (reg) {
6875 case CP0_REGISTER_00:
6876 switch (sel) {
6877 case CP0_REG00__INDEX:
6878 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6879 register_name = "Index";
6880 break;
6881 case CP0_REG00__MVPCONTROL:
6882 CP0_CHECK(ctx->insn_flags & ASE_MT);
6883 gen_helper_mfc0_mvpcontrol(arg, tcg_env);
6884 register_name = "MVPControl";
6885 break;
6886 case CP0_REG00__MVPCONF0:
6887 CP0_CHECK(ctx->insn_flags & ASE_MT);
6888 gen_helper_mfc0_mvpconf0(arg, tcg_env);
6889 register_name = "MVPConf0";
6890 break;
6891 case CP0_REG00__MVPCONF1:
6892 CP0_CHECK(ctx->insn_flags & ASE_MT);
6893 gen_helper_mfc0_mvpconf1(arg, tcg_env);
6894 register_name = "MVPConf1";
6895 break;
6896 case CP0_REG00__VPCONTROL:
6897 CP0_CHECK(ctx->vp);
6898 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6899 register_name = "VPControl";
6900 break;
6901 default:
6902 goto cp0_unimplemented;
6903 }
6904 break;
6905 case CP0_REGISTER_01:
6906 switch (sel) {
6907 case CP0_REG01__RANDOM:
6908 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6909 gen_helper_mfc0_random(arg, tcg_env);
6910 register_name = "Random";
6911 break;
6912 case CP0_REG01__VPECONTROL:
6913 CP0_CHECK(ctx->insn_flags & ASE_MT);
6914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6915 register_name = "VPEControl";
6916 break;
6917 case CP0_REG01__VPECONF0:
6918 CP0_CHECK(ctx->insn_flags & ASE_MT);
6919 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6920 register_name = "VPEConf0";
6921 break;
6922 case CP0_REG01__VPECONF1:
6923 CP0_CHECK(ctx->insn_flags & ASE_MT);
6924 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6925 register_name = "VPEConf1";
6926 break;
6927 case CP0_REG01__YQMASK:
6928 CP0_CHECK(ctx->insn_flags & ASE_MT);
6929 tcg_gen_ld_tl(arg, tcg_env,
6930 offsetof(CPUMIPSState, CP0_YQMask));
6931 register_name = "YQMask";
6932 break;
6933 case CP0_REG01__VPESCHEDULE:
6934 CP0_CHECK(ctx->insn_flags & ASE_MT);
6935 tcg_gen_ld_tl(arg, tcg_env,
6936 offsetof(CPUMIPSState, CP0_VPESchedule));
6937 register_name = "VPESchedule";
6938 break;
6939 case CP0_REG01__VPESCHEFBACK:
6940 CP0_CHECK(ctx->insn_flags & ASE_MT);
6941 tcg_gen_ld_tl(arg, tcg_env,
6942 offsetof(CPUMIPSState, CP0_VPEScheFBack));
6943 register_name = "VPEScheFBack";
6944 break;
6945 case CP0_REG01__VPEOPT:
6946 CP0_CHECK(ctx->insn_flags & ASE_MT);
6947 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6948 register_name = "VPEOpt";
6949 break;
6950 default:
6951 goto cp0_unimplemented;
6952 }
6953 break;
6954 case CP0_REGISTER_02:
6955 switch (sel) {
6956 case CP0_REG02__ENTRYLO0:
6957 tcg_gen_ld_tl(arg, tcg_env,
6958 offsetof(CPUMIPSState, CP0_EntryLo0));
6959 register_name = "EntryLo0";
6960 break;
6961 case CP0_REG02__TCSTATUS:
6962 CP0_CHECK(ctx->insn_flags & ASE_MT);
6963 gen_helper_mfc0_tcstatus(arg, tcg_env);
6964 register_name = "TCStatus";
6965 break;
6966 case CP0_REG02__TCBIND:
6967 CP0_CHECK(ctx->insn_flags & ASE_MT);
6968 gen_helper_mfc0_tcbind(arg, tcg_env);
6969 register_name = "TCBind";
6970 break;
6971 case CP0_REG02__TCRESTART:
6972 CP0_CHECK(ctx->insn_flags & ASE_MT);
6973 gen_helper_dmfc0_tcrestart(arg, tcg_env);
6974 register_name = "TCRestart";
6975 break;
6976 case CP0_REG02__TCHALT:
6977 CP0_CHECK(ctx->insn_flags & ASE_MT);
6978 gen_helper_dmfc0_tchalt(arg, tcg_env);
6979 register_name = "TCHalt";
6980 break;
6981 case CP0_REG02__TCCONTEXT:
6982 CP0_CHECK(ctx->insn_flags & ASE_MT);
6983 gen_helper_dmfc0_tccontext(arg, tcg_env);
6984 register_name = "TCContext";
6985 break;
6986 case CP0_REG02__TCSCHEDULE:
6987 CP0_CHECK(ctx->insn_flags & ASE_MT);
6988 gen_helper_dmfc0_tcschedule(arg, tcg_env);
6989 register_name = "TCSchedule";
6990 break;
6991 case CP0_REG02__TCSCHEFBACK:
6992 CP0_CHECK(ctx->insn_flags & ASE_MT);
6993 gen_helper_dmfc0_tcschefback(arg, tcg_env);
6994 register_name = "TCScheFBack";
6995 break;
6996 default:
6997 goto cp0_unimplemented;
6998 }
6999 break;
7000 case CP0_REGISTER_03:
7001 switch (sel) {
7002 case CP0_REG03__ENTRYLO1:
7003 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7004 register_name = "EntryLo1";
7005 break;
7006 case CP0_REG03__GLOBALNUM:
7007 CP0_CHECK(ctx->vp);
7008 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7009 register_name = "GlobalNumber";
7010 break;
7011 default:
7012 goto cp0_unimplemented;
7013 }
7014 break;
7015 case CP0_REGISTER_04:
7016 switch (sel) {
7017 case CP0_REG04__CONTEXT:
7018 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_Context));
7019 register_name = "Context";
7020 break;
7021 case CP0_REG04__CONTEXTCONFIG:
7022 /* SmartMIPS ASE */
7023 /* gen_helper_dmfc0_contextconfig(arg); */
7024 register_name = "ContextConfig";
7025 goto cp0_unimplemented;
7026 case CP0_REG04__USERLOCAL:
7027 CP0_CHECK(ctx->ulri);
7028 tcg_gen_ld_tl(arg, tcg_env,
7029 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7030 register_name = "UserLocal";
7031 break;
7032 case CP0_REG04__MMID:
7033 CP0_CHECK(ctx->mi);
7034 gen_helper_mtc0_memorymapid(tcg_env, arg);
7035 register_name = "MMID";
7036 break;
7037 default:
7038 goto cp0_unimplemented;
7039 }
7040 break;
7041 case CP0_REGISTER_05:
7042 switch (sel) {
7043 case CP0_REG05__PAGEMASK:
7044 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7045 register_name = "PageMask";
7046 break;
7047 case CP0_REG05__PAGEGRAIN:
7048 check_insn(ctx, ISA_MIPS_R2);
7049 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7050 register_name = "PageGrain";
7051 break;
7052 case CP0_REG05__SEGCTL0:
7053 CP0_CHECK(ctx->sc);
7054 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7055 register_name = "SegCtl0";
7056 break;
7057 case CP0_REG05__SEGCTL1:
7058 CP0_CHECK(ctx->sc);
7059 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7060 register_name = "SegCtl1";
7061 break;
7062 case CP0_REG05__SEGCTL2:
7063 CP0_CHECK(ctx->sc);
7064 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7065 register_name = "SegCtl2";
7066 break;
7067 case CP0_REG05__PWBASE:
7068 check_pw(ctx);
7069 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase));
7070 register_name = "PWBase";
7071 break;
7072 case CP0_REG05__PWFIELD:
7073 check_pw(ctx);
7074 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWField));
7075 register_name = "PWField";
7076 break;
7077 case CP0_REG05__PWSIZE:
7078 check_pw(ctx);
7079 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWSize));
7080 register_name = "PWSize";
7081 break;
7082 default:
7083 goto cp0_unimplemented;
7084 }
7085 break;
7086 case CP0_REGISTER_06:
7087 switch (sel) {
7088 case CP0_REG06__WIRED:
7089 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7090 register_name = "Wired";
7091 break;
7092 case CP0_REG06__SRSCONF0:
7093 check_insn(ctx, ISA_MIPS_R2);
7094 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7095 register_name = "SRSConf0";
7096 break;
7097 case CP0_REG06__SRSCONF1:
7098 check_insn(ctx, ISA_MIPS_R2);
7099 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7100 register_name = "SRSConf1";
7101 break;
7102 case CP0_REG06__SRSCONF2:
7103 check_insn(ctx, ISA_MIPS_R2);
7104 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7105 register_name = "SRSConf2";
7106 break;
7107 case CP0_REG06__SRSCONF3:
7108 check_insn(ctx, ISA_MIPS_R2);
7109 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7110 register_name = "SRSConf3";
7111 break;
7112 case CP0_REG06__SRSCONF4:
7113 check_insn(ctx, ISA_MIPS_R2);
7114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7115 register_name = "SRSConf4";
7116 break;
7117 case CP0_REG06__PWCTL:
7118 check_pw(ctx);
7119 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7120 register_name = "PWCtl";
7121 break;
7122 default:
7123 goto cp0_unimplemented;
7124 }
7125 break;
7126 case CP0_REGISTER_07:
7127 switch (sel) {
7128 case CP0_REG07__HWRENA:
7129 check_insn(ctx, ISA_MIPS_R2);
7130 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7131 register_name = "HWREna";
7132 break;
7133 default:
7134 goto cp0_unimplemented;
7135 }
7136 break;
7137 case CP0_REGISTER_08:
7138 switch (sel) {
7139 case CP0_REG08__BADVADDR:
7140 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7141 register_name = "BadVAddr";
7142 break;
7143 case CP0_REG08__BADINSTR:
7144 CP0_CHECK(ctx->bi);
7145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7146 register_name = "BadInstr";
7147 break;
7148 case CP0_REG08__BADINSTRP:
7149 CP0_CHECK(ctx->bp);
7150 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7151 register_name = "BadInstrP";
7152 break;
7153 case CP0_REG08__BADINSTRX:
7154 CP0_CHECK(ctx->bi);
7155 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7156 tcg_gen_andi_tl(arg, arg, ~0xffff);
7157 register_name = "BadInstrX";
7158 break;
7159 default:
7160 goto cp0_unimplemented;
7161 }
7162 break;
7163 case CP0_REGISTER_09:
7164 switch (sel) {
7165 case CP0_REG09__COUNT:
7166 /* Mark as an IO operation because we read the time. */
7167 translator_io_start(&ctx->base);
7168 gen_helper_mfc0_count(arg, tcg_env);
7169 /*
7170 * Break the TB to be able to take timer interrupts immediately
7171 * after reading count. DISAS_STOP isn't sufficient, we need to
7172 * ensure we break completely out of translated code.
7173 */
7174 gen_save_pc(ctx->base.pc_next + 4);
7175 ctx->base.is_jmp = DISAS_EXIT;
7176 register_name = "Count";
7177 break;
7178 case CP0_REG09__SAARI:
7179 CP0_CHECK(ctx->saar);
7180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7181 register_name = "SAARI";
7182 break;
7183 case CP0_REG09__SAAR:
7184 CP0_CHECK(ctx->saar);
7185 gen_helper_dmfc0_saar(arg, tcg_env);
7186 register_name = "SAAR";
7187 break;
7188 default:
7189 goto cp0_unimplemented;
7190 }
7191 break;
7192 case CP0_REGISTER_10:
7193 switch (sel) {
7194 case CP0_REG10__ENTRYHI:
7195 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EntryHi));
7196 register_name = "EntryHi";
7197 break;
7198 default:
7199 goto cp0_unimplemented;
7200 }
7201 break;
7202 case CP0_REGISTER_11:
7203 switch (sel) {
7204 case CP0_REG11__COMPARE:
7205 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7206 register_name = "Compare";
7207 break;
7208 /* 6,7 are implementation dependent */
7209 default:
7210 goto cp0_unimplemented;
7211 }
7212 break;
7213 case CP0_REGISTER_12:
7214 switch (sel) {
7215 case CP0_REG12__STATUS:
7216 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7217 register_name = "Status";
7218 break;
7219 case CP0_REG12__INTCTL:
7220 check_insn(ctx, ISA_MIPS_R2);
7221 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7222 register_name = "IntCtl";
7223 break;
7224 case CP0_REG12__SRSCTL:
7225 check_insn(ctx, ISA_MIPS_R2);
7226 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7227 register_name = "SRSCtl";
7228 break;
7229 case CP0_REG12__SRSMAP:
7230 check_insn(ctx, ISA_MIPS_R2);
7231 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7232 register_name = "SRSMap";
7233 break;
7234 default:
7235 goto cp0_unimplemented;
7236 }
7237 break;
7238 case CP0_REGISTER_13:
7239 switch (sel) {
7240 case CP0_REG13__CAUSE:
7241 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7242 register_name = "Cause";
7243 break;
7244 default:
7245 goto cp0_unimplemented;
7246 }
7247 break;
7248 case CP0_REGISTER_14:
7249 switch (sel) {
7250 case CP0_REG14__EPC:
7251 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
7252 register_name = "EPC";
7253 break;
7254 default:
7255 goto cp0_unimplemented;
7256 }
7257 break;
7258 case CP0_REGISTER_15:
7259 switch (sel) {
7260 case CP0_REG15__PRID:
7261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7262 register_name = "PRid";
7263 break;
7264 case CP0_REG15__EBASE:
7265 check_insn(ctx, ISA_MIPS_R2);
7266 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EBase));
7267 register_name = "EBase";
7268 break;
7269 case CP0_REG15__CMGCRBASE:
7270 check_insn(ctx, ISA_MIPS_R2);
7271 CP0_CHECK(ctx->cmgcr);
7272 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7273 register_name = "CMGCRBase";
7274 break;
7275 default:
7276 goto cp0_unimplemented;
7277 }
7278 break;
7279 case CP0_REGISTER_16:
7280 switch (sel) {
7281 case CP0_REG16__CONFIG:
7282 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7283 register_name = "Config";
7284 break;
7285 case CP0_REG16__CONFIG1:
7286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7287 register_name = "Config1";
7288 break;
7289 case CP0_REG16__CONFIG2:
7290 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7291 register_name = "Config2";
7292 break;
7293 case CP0_REG16__CONFIG3:
7294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7295 register_name = "Config3";
7296 break;
7297 case CP0_REG16__CONFIG4:
7298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7299 register_name = "Config4";
7300 break;
7301 case CP0_REG16__CONFIG5:
7302 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7303 register_name = "Config5";
7304 break;
7305 /* 6,7 are implementation dependent */
7306 case CP0_REG16__CONFIG6:
7307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7308 register_name = "Config6";
7309 break;
7310 case CP0_REG16__CONFIG7:
7311 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7312 register_name = "Config7";
7313 break;
7314 default:
7315 goto cp0_unimplemented;
7316 }
7317 break;
7318 case CP0_REGISTER_17:
7319 switch (sel) {
7320 case CP0_REG17__LLADDR:
7321 gen_helper_dmfc0_lladdr(arg, tcg_env);
7322 register_name = "LLAddr";
7323 break;
7324 case CP0_REG17__MAAR:
7325 CP0_CHECK(ctx->mrp);
7326 gen_helper_dmfc0_maar(arg, tcg_env);
7327 register_name = "MAAR";
7328 break;
7329 case CP0_REG17__MAARI:
7330 CP0_CHECK(ctx->mrp);
7331 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7332 register_name = "MAARI";
7333 break;
7334 default:
7335 goto cp0_unimplemented;
7336 }
7337 break;
7338 case CP0_REGISTER_18:
7339 switch (sel) {
7340 case CP0_REG18__WATCHLO0:
7341 case CP0_REG18__WATCHLO1:
7342 case CP0_REG18__WATCHLO2:
7343 case CP0_REG18__WATCHLO3:
7344 case CP0_REG18__WATCHLO4:
7345 case CP0_REG18__WATCHLO5:
7346 case CP0_REG18__WATCHLO6:
7347 case CP0_REG18__WATCHLO7:
7348 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7349 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7350 register_name = "WatchLo";
7351 break;
7352 default:
7353 goto cp0_unimplemented;
7354 }
7355 break;
7356 case CP0_REGISTER_19:
7357 switch (sel) {
7358 case CP0_REG19__WATCHHI0:
7359 case CP0_REG19__WATCHHI1:
7360 case CP0_REG19__WATCHHI2:
7361 case CP0_REG19__WATCHHI3:
7362 case CP0_REG19__WATCHHI4:
7363 case CP0_REG19__WATCHHI5:
7364 case CP0_REG19__WATCHHI6:
7365 case CP0_REG19__WATCHHI7:
7366 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7367 gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7368 register_name = "WatchHi";
7369 break;
7370 default:
7371 goto cp0_unimplemented;
7372 }
7373 break;
7374 case CP0_REGISTER_20:
7375 switch (sel) {
7376 case CP0_REG20__XCONTEXT:
7377 check_insn(ctx, ISA_MIPS3);
7378 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_XContext));
7379 register_name = "XContext";
7380 break;
7381 default:
7382 goto cp0_unimplemented;
7383 }
7384 break;
7385 case CP0_REGISTER_21:
7386 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7387 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7388 switch (sel) {
7389 case 0:
7390 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7391 register_name = "Framemask";
7392 break;
7393 default:
7394 goto cp0_unimplemented;
7395 }
7396 break;
7397 case CP0_REGISTER_22:
7398 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7399 register_name = "'Diagnostic"; /* implementation dependent */
7400 break;
7401 case CP0_REGISTER_23:
7402 switch (sel) {
7403 case CP0_REG23__DEBUG:
7404 gen_helper_mfc0_debug(arg, tcg_env); /* EJTAG support */
7405 register_name = "Debug";
7406 break;
7407 case CP0_REG23__TRACECONTROL:
7408 /* PDtrace support */
7409 /* gen_helper_dmfc0_tracecontrol(arg, tcg_env); */
7410 register_name = "TraceControl";
7411 goto cp0_unimplemented;
7412 case CP0_REG23__TRACECONTROL2:
7413 /* PDtrace support */
7414 /* gen_helper_dmfc0_tracecontrol2(arg, tcg_env); */
7415 register_name = "TraceControl2";
7416 goto cp0_unimplemented;
7417 case CP0_REG23__USERTRACEDATA1:
7418 /* PDtrace support */
7419 /* gen_helper_dmfc0_usertracedata1(arg, tcg_env);*/
7420 register_name = "UserTraceData1";
7421 goto cp0_unimplemented;
7422 case CP0_REG23__TRACEIBPC:
7423 /* PDtrace support */
7424 /* gen_helper_dmfc0_traceibpc(arg, tcg_env); */
7425 register_name = "TraceIBPC";
7426 goto cp0_unimplemented;
7427 case CP0_REG23__TRACEDBPC:
7428 /* PDtrace support */
7429 /* gen_helper_dmfc0_tracedbpc(arg, tcg_env); */
7430 register_name = "TraceDBPC";
7431 goto cp0_unimplemented;
7432 default:
7433 goto cp0_unimplemented;
7434 }
7435 break;
7436 case CP0_REGISTER_24:
7437 switch (sel) {
7438 case CP0_REG24__DEPC:
7439 /* EJTAG support */
7440 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
7441 register_name = "DEPC";
7442 break;
7443 default:
7444 goto cp0_unimplemented;
7445 }
7446 break;
7447 case CP0_REGISTER_25:
7448 switch (sel) {
7449 case CP0_REG25__PERFCTL0:
7450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7451 register_name = "Performance0";
7452 break;
7453 case CP0_REG25__PERFCNT0:
7454 /* gen_helper_dmfc0_performance1(arg); */
7455 register_name = "Performance1";
7456 goto cp0_unimplemented;
7457 case CP0_REG25__PERFCTL1:
7458 /* gen_helper_dmfc0_performance2(arg); */
7459 register_name = "Performance2";
7460 goto cp0_unimplemented;
7461 case CP0_REG25__PERFCNT1:
7462 /* gen_helper_dmfc0_performance3(arg); */
7463 register_name = "Performance3";
7464 goto cp0_unimplemented;
7465 case CP0_REG25__PERFCTL2:
7466 /* gen_helper_dmfc0_performance4(arg); */
7467 register_name = "Performance4";
7468 goto cp0_unimplemented;
7469 case CP0_REG25__PERFCNT2:
7470 /* gen_helper_dmfc0_performance5(arg); */
7471 register_name = "Performance5";
7472 goto cp0_unimplemented;
7473 case CP0_REG25__PERFCTL3:
7474 /* gen_helper_dmfc0_performance6(arg); */
7475 register_name = "Performance6";
7476 goto cp0_unimplemented;
7477 case CP0_REG25__PERFCNT3:
7478 /* gen_helper_dmfc0_performance7(arg); */
7479 register_name = "Performance7";
7480 goto cp0_unimplemented;
7481 default:
7482 goto cp0_unimplemented;
7483 }
7484 break;
7485 case CP0_REGISTER_26:
7486 switch (sel) {
7487 case CP0_REG26__ERRCTL:
7488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7489 register_name = "ErrCtl";
7490 break;
7491 default:
7492 goto cp0_unimplemented;
7493 }
7494 break;
7495 case CP0_REGISTER_27:
7496 switch (sel) {
7497 /* ignored */
7498 case CP0_REG27__CACHERR:
7499 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7500 register_name = "CacheErr";
7501 break;
7502 default:
7503 goto cp0_unimplemented;
7504 }
7505 break;
7506 case CP0_REGISTER_28:
7507 switch (sel) {
7508 case CP0_REG28__TAGLO:
7509 case CP0_REG28__TAGLO1:
7510 case CP0_REG28__TAGLO2:
7511 case CP0_REG28__TAGLO3:
7512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7513 register_name = "TagLo";
7514 break;
7515 case CP0_REG28__DATALO:
7516 case CP0_REG28__DATALO1:
7517 case CP0_REG28__DATALO2:
7518 case CP0_REG28__DATALO3:
7519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7520 register_name = "DataLo";
7521 break;
7522 default:
7523 goto cp0_unimplemented;
7524 }
7525 break;
7526 case CP0_REGISTER_29:
7527 switch (sel) {
7528 case CP0_REG29__TAGHI:
7529 case CP0_REG29__TAGHI1:
7530 case CP0_REG29__TAGHI2:
7531 case CP0_REG29__TAGHI3:
7532 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7533 register_name = "TagHi";
7534 break;
7535 case CP0_REG29__DATAHI:
7536 case CP0_REG29__DATAHI1:
7537 case CP0_REG29__DATAHI2:
7538 case CP0_REG29__DATAHI3:
7539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7540 register_name = "DataHi";
7541 break;
7542 default:
7543 goto cp0_unimplemented;
7544 }
7545 break;
7546 case CP0_REGISTER_30:
7547 switch (sel) {
7548 case CP0_REG30__ERROREPC:
7549 tcg_gen_ld_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7550 register_name = "ErrorEPC";
7551 break;
7552 default:
7553 goto cp0_unimplemented;
7554 }
7555 break;
7556 case CP0_REGISTER_31:
7557 switch (sel) {
7558 case CP0_REG31__DESAVE:
7559 /* EJTAG support */
7560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7561 register_name = "DESAVE";
7562 break;
7563 case CP0_REG31__KSCRATCH1:
7564 case CP0_REG31__KSCRATCH2:
7565 case CP0_REG31__KSCRATCH3:
7566 case CP0_REG31__KSCRATCH4:
7567 case CP0_REG31__KSCRATCH5:
7568 case CP0_REG31__KSCRATCH6:
7569 CP0_CHECK(ctx->kscrexist & (1 << sel));
7570 tcg_gen_ld_tl(arg, tcg_env,
7571 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7572 register_name = "KScratch";
7573 break;
7574 default:
7575 goto cp0_unimplemented;
7576 }
7577 break;
7578 default:
7579 goto cp0_unimplemented;
7580 }
7581 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7582 return;
7583
7584 cp0_unimplemented:
7585 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7586 register_name, reg, sel);
7587 gen_mfc0_unimplemented(ctx, arg);
7588 }
7589
7590 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7591 {
7592 const char *register_name = "invalid";
7593 bool icount;
7594
7595 if (sel != 0) {
7596 check_insn(ctx, ISA_MIPS_R1);
7597 }
7598
7599 icount = translator_io_start(&ctx->base);
7600
7601 switch (reg) {
7602 case CP0_REGISTER_00:
7603 switch (sel) {
7604 case CP0_REG00__INDEX:
7605 gen_helper_mtc0_index(tcg_env, arg);
7606 register_name = "Index";
7607 break;
7608 case CP0_REG00__MVPCONTROL:
7609 CP0_CHECK(ctx->insn_flags & ASE_MT);
7610 gen_helper_mtc0_mvpcontrol(tcg_env, arg);
7611 register_name = "MVPControl";
7612 break;
7613 case CP0_REG00__MVPCONF0:
7614 CP0_CHECK(ctx->insn_flags & ASE_MT);
7615 /* ignored */
7616 register_name = "MVPConf0";
7617 break;
7618 case CP0_REG00__MVPCONF1:
7619 CP0_CHECK(ctx->insn_flags & ASE_MT);
7620 /* ignored */
7621 register_name = "MVPConf1";
7622 break;
7623 case CP0_REG00__VPCONTROL:
7624 CP0_CHECK(ctx->vp);
7625 /* ignored */
7626 register_name = "VPControl";
7627 break;
7628 default:
7629 goto cp0_unimplemented;
7630 }
7631 break;
7632 case CP0_REGISTER_01:
7633 switch (sel) {
7634 case CP0_REG01__RANDOM:
7635 /* ignored */
7636 register_name = "Random";
7637 break;
7638 case CP0_REG01__VPECONTROL:
7639 CP0_CHECK(ctx->insn_flags & ASE_MT);
7640 gen_helper_mtc0_vpecontrol(tcg_env, arg);
7641 register_name = "VPEControl";
7642 break;
7643 case CP0_REG01__VPECONF0:
7644 CP0_CHECK(ctx->insn_flags & ASE_MT);
7645 gen_helper_mtc0_vpeconf0(tcg_env, arg);
7646 register_name = "VPEConf0";
7647 break;
7648 case CP0_REG01__VPECONF1:
7649 CP0_CHECK(ctx->insn_flags & ASE_MT);
7650 gen_helper_mtc0_vpeconf1(tcg_env, arg);
7651 register_name = "VPEConf1";
7652 break;
7653 case CP0_REG01__YQMASK:
7654 CP0_CHECK(ctx->insn_flags & ASE_MT);
7655 gen_helper_mtc0_yqmask(tcg_env, arg);
7656 register_name = "YQMask";
7657 break;
7658 case CP0_REG01__VPESCHEDULE:
7659 CP0_CHECK(ctx->insn_flags & ASE_MT);
7660 tcg_gen_st_tl(arg, tcg_env,
7661 offsetof(CPUMIPSState, CP0_VPESchedule));
7662 register_name = "VPESchedule";
7663 break;
7664 case CP0_REG01__VPESCHEFBACK:
7665 CP0_CHECK(ctx->insn_flags & ASE_MT);
7666 tcg_gen_st_tl(arg, tcg_env,
7667 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7668 register_name = "VPEScheFBack";
7669 break;
7670 case CP0_REG01__VPEOPT:
7671 CP0_CHECK(ctx->insn_flags & ASE_MT);
7672 gen_helper_mtc0_vpeopt(tcg_env, arg);
7673 register_name = "VPEOpt";
7674 break;
7675 default:
7676 goto cp0_unimplemented;
7677 }
7678 break;
7679 case CP0_REGISTER_02:
7680 switch (sel) {
7681 case CP0_REG02__ENTRYLO0:
7682 gen_helper_dmtc0_entrylo0(tcg_env, arg);
7683 register_name = "EntryLo0";
7684 break;
7685 case CP0_REG02__TCSTATUS:
7686 CP0_CHECK(ctx->insn_flags & ASE_MT);
7687 gen_helper_mtc0_tcstatus(tcg_env, arg);
7688 register_name = "TCStatus";
7689 break;
7690 case CP0_REG02__TCBIND:
7691 CP0_CHECK(ctx->insn_flags & ASE_MT);
7692 gen_helper_mtc0_tcbind(tcg_env, arg);
7693 register_name = "TCBind";
7694 break;
7695 case CP0_REG02__TCRESTART:
7696 CP0_CHECK(ctx->insn_flags & ASE_MT);
7697 gen_helper_mtc0_tcrestart(tcg_env, arg);
7698 register_name = "TCRestart";
7699 break;
7700 case CP0_REG02__TCHALT:
7701 CP0_CHECK(ctx->insn_flags & ASE_MT);
7702 gen_helper_mtc0_tchalt(tcg_env, arg);
7703 register_name = "TCHalt";
7704 break;
7705 case CP0_REG02__TCCONTEXT:
7706 CP0_CHECK(ctx->insn_flags & ASE_MT);
7707 gen_helper_mtc0_tccontext(tcg_env, arg);
7708 register_name = "TCContext";
7709 break;
7710 case CP0_REG02__TCSCHEDULE:
7711 CP0_CHECK(ctx->insn_flags & ASE_MT);
7712 gen_helper_mtc0_tcschedule(tcg_env, arg);
7713 register_name = "TCSchedule";
7714 break;
7715 case CP0_REG02__TCSCHEFBACK:
7716 CP0_CHECK(ctx->insn_flags & ASE_MT);
7717 gen_helper_mtc0_tcschefback(tcg_env, arg);
7718 register_name = "TCScheFBack";
7719 break;
7720 default:
7721 goto cp0_unimplemented;
7722 }
7723 break;
7724 case CP0_REGISTER_03:
7725 switch (sel) {
7726 case CP0_REG03__ENTRYLO1:
7727 gen_helper_dmtc0_entrylo1(tcg_env, arg);
7728 register_name = "EntryLo1";
7729 break;
7730 case CP0_REG03__GLOBALNUM:
7731 CP0_CHECK(ctx->vp);
7732 /* ignored */
7733 register_name = "GlobalNumber";
7734 break;
7735 default:
7736 goto cp0_unimplemented;
7737 }
7738 break;
7739 case CP0_REGISTER_04:
7740 switch (sel) {
7741 case CP0_REG04__CONTEXT:
7742 gen_helper_mtc0_context(tcg_env, arg);
7743 register_name = "Context";
7744 break;
7745 case CP0_REG04__CONTEXTCONFIG:
7746 /* SmartMIPS ASE */
7747 /* gen_helper_dmtc0_contextconfig(arg); */
7748 register_name = "ContextConfig";
7749 goto cp0_unimplemented;
7750 case CP0_REG04__USERLOCAL:
7751 CP0_CHECK(ctx->ulri);
7752 tcg_gen_st_tl(arg, tcg_env,
7753 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7754 register_name = "UserLocal";
7755 break;
7756 case CP0_REG04__MMID:
7757 CP0_CHECK(ctx->mi);
7758 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
7759 register_name = "MMID";
7760 break;
7761 default:
7762 goto cp0_unimplemented;
7763 }
7764 break;
7765 case CP0_REGISTER_05:
7766 switch (sel) {
7767 case CP0_REG05__PAGEMASK:
7768 gen_helper_mtc0_pagemask(tcg_env, arg);
7769 register_name = "PageMask";
7770 break;
7771 case CP0_REG05__PAGEGRAIN:
7772 check_insn(ctx, ISA_MIPS_R2);
7773 gen_helper_mtc0_pagegrain(tcg_env, arg);
7774 register_name = "PageGrain";
7775 break;
7776 case CP0_REG05__SEGCTL0:
7777 CP0_CHECK(ctx->sc);
7778 gen_helper_mtc0_segctl0(tcg_env, arg);
7779 register_name = "SegCtl0";
7780 break;
7781 case CP0_REG05__SEGCTL1:
7782 CP0_CHECK(ctx->sc);
7783 gen_helper_mtc0_segctl1(tcg_env, arg);
7784 register_name = "SegCtl1";
7785 break;
7786 case CP0_REG05__SEGCTL2:
7787 CP0_CHECK(ctx->sc);
7788 gen_helper_mtc0_segctl2(tcg_env, arg);
7789 register_name = "SegCtl2";
7790 break;
7791 case CP0_REG05__PWBASE:
7792 check_pw(ctx);
7793 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_PWBase));
7794 register_name = "PWBase";
7795 break;
7796 case CP0_REG05__PWFIELD:
7797 check_pw(ctx);
7798 gen_helper_mtc0_pwfield(tcg_env, arg);
7799 register_name = "PWField";
7800 break;
7801 case CP0_REG05__PWSIZE:
7802 check_pw(ctx);
7803 gen_helper_mtc0_pwsize(tcg_env, arg);
7804 register_name = "PWSize";
7805 break;
7806 default:
7807 goto cp0_unimplemented;
7808 }
7809 break;
7810 case CP0_REGISTER_06:
7811 switch (sel) {
7812 case CP0_REG06__WIRED:
7813 gen_helper_mtc0_wired(tcg_env, arg);
7814 register_name = "Wired";
7815 break;
7816 case CP0_REG06__SRSCONF0:
7817 check_insn(ctx, ISA_MIPS_R2);
7818 gen_helper_mtc0_srsconf0(tcg_env, arg);
7819 register_name = "SRSConf0";
7820 break;
7821 case CP0_REG06__SRSCONF1:
7822 check_insn(ctx, ISA_MIPS_R2);
7823 gen_helper_mtc0_srsconf1(tcg_env, arg);
7824 register_name = "SRSConf1";
7825 break;
7826 case CP0_REG06__SRSCONF2:
7827 check_insn(ctx, ISA_MIPS_R2);
7828 gen_helper_mtc0_srsconf2(tcg_env, arg);
7829 register_name = "SRSConf2";
7830 break;
7831 case CP0_REG06__SRSCONF3:
7832 check_insn(ctx, ISA_MIPS_R2);
7833 gen_helper_mtc0_srsconf3(tcg_env, arg);
7834 register_name = "SRSConf3";
7835 break;
7836 case CP0_REG06__SRSCONF4:
7837 check_insn(ctx, ISA_MIPS_R2);
7838 gen_helper_mtc0_srsconf4(tcg_env, arg);
7839 register_name = "SRSConf4";
7840 break;
7841 case CP0_REG06__PWCTL:
7842 check_pw(ctx);
7843 gen_helper_mtc0_pwctl(tcg_env, arg);
7844 register_name = "PWCtl";
7845 break;
7846 default:
7847 goto cp0_unimplemented;
7848 }
7849 break;
7850 case CP0_REGISTER_07:
7851 switch (sel) {
7852 case CP0_REG07__HWRENA:
7853 check_insn(ctx, ISA_MIPS_R2);
7854 gen_helper_mtc0_hwrena(tcg_env, arg);
7855 ctx->base.is_jmp = DISAS_STOP;
7856 register_name = "HWREna";
7857 break;
7858 default:
7859 goto cp0_unimplemented;
7860 }
7861 break;
7862 case CP0_REGISTER_08:
7863 switch (sel) {
7864 case CP0_REG08__BADVADDR:
7865 /* ignored */
7866 register_name = "BadVAddr";
7867 break;
7868 case CP0_REG08__BADINSTR:
7869 /* ignored */
7870 register_name = "BadInstr";
7871 break;
7872 case CP0_REG08__BADINSTRP:
7873 /* ignored */
7874 register_name = "BadInstrP";
7875 break;
7876 case CP0_REG08__BADINSTRX:
7877 /* ignored */
7878 register_name = "BadInstrX";
7879 break;
7880 default:
7881 goto cp0_unimplemented;
7882 }
7883 break;
7884 case CP0_REGISTER_09:
7885 switch (sel) {
7886 case CP0_REG09__COUNT:
7887 gen_helper_mtc0_count(tcg_env, arg);
7888 register_name = "Count";
7889 break;
7890 case CP0_REG09__SAARI:
7891 CP0_CHECK(ctx->saar);
7892 gen_helper_mtc0_saari(tcg_env, arg);
7893 register_name = "SAARI";
7894 break;
7895 case CP0_REG09__SAAR:
7896 CP0_CHECK(ctx->saar);
7897 gen_helper_mtc0_saar(tcg_env, arg);
7898 register_name = "SAAR";
7899 break;
7900 default:
7901 goto cp0_unimplemented;
7902 }
7903 /* Stop translation as we may have switched the execution mode */
7904 ctx->base.is_jmp = DISAS_STOP;
7905 break;
7906 case CP0_REGISTER_10:
7907 switch (sel) {
7908 case CP0_REG10__ENTRYHI:
7909 gen_helper_mtc0_entryhi(tcg_env, arg);
7910 register_name = "EntryHi";
7911 break;
7912 default:
7913 goto cp0_unimplemented;
7914 }
7915 break;
7916 case CP0_REGISTER_11:
7917 switch (sel) {
7918 case CP0_REG11__COMPARE:
7919 gen_helper_mtc0_compare(tcg_env, arg);
7920 register_name = "Compare";
7921 break;
7922 /* 6,7 are implementation dependent */
7923 default:
7924 goto cp0_unimplemented;
7925 }
7926 /* Stop translation as we may have switched the execution mode */
7927 ctx->base.is_jmp = DISAS_STOP;
7928 break;
7929 case CP0_REGISTER_12:
7930 switch (sel) {
7931 case CP0_REG12__STATUS:
7932 save_cpu_state(ctx, 1);
7933 gen_helper_mtc0_status(tcg_env, arg);
7934 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7935 gen_save_pc(ctx->base.pc_next + 4);
7936 ctx->base.is_jmp = DISAS_EXIT;
7937 register_name = "Status";
7938 break;
7939 case CP0_REG12__INTCTL:
7940 check_insn(ctx, ISA_MIPS_R2);
7941 gen_helper_mtc0_intctl(tcg_env, arg);
7942 /* Stop translation as we may have switched the execution mode */
7943 ctx->base.is_jmp = DISAS_STOP;
7944 register_name = "IntCtl";
7945 break;
7946 case CP0_REG12__SRSCTL:
7947 check_insn(ctx, ISA_MIPS_R2);
7948 gen_helper_mtc0_srsctl(tcg_env, arg);
7949 /* Stop translation as we may have switched the execution mode */
7950 ctx->base.is_jmp = DISAS_STOP;
7951 register_name = "SRSCtl";
7952 break;
7953 case CP0_REG12__SRSMAP:
7954 check_insn(ctx, ISA_MIPS_R2);
7955 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7956 /* Stop translation as we may have switched the execution mode */
7957 ctx->base.is_jmp = DISAS_STOP;
7958 register_name = "SRSMap";
7959 break;
7960 default:
7961 goto cp0_unimplemented;
7962 }
7963 break;
7964 case CP0_REGISTER_13:
7965 switch (sel) {
7966 case CP0_REG13__CAUSE:
7967 save_cpu_state(ctx, 1);
7968 gen_helper_mtc0_cause(tcg_env, arg);
7969 /*
7970 * Stop translation as we may have triggered an interrupt.
7971 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7972 * translated code to check for pending interrupts.
7973 */
7974 gen_save_pc(ctx->base.pc_next + 4);
7975 ctx->base.is_jmp = DISAS_EXIT;
7976 register_name = "Cause";
7977 break;
7978 default:
7979 goto cp0_unimplemented;
7980 }
7981 break;
7982 case CP0_REGISTER_14:
7983 switch (sel) {
7984 case CP0_REG14__EPC:
7985 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_EPC));
7986 register_name = "EPC";
7987 break;
7988 default:
7989 goto cp0_unimplemented;
7990 }
7991 break;
7992 case CP0_REGISTER_15:
7993 switch (sel) {
7994 case CP0_REG15__PRID:
7995 /* ignored */
7996 register_name = "PRid";
7997 break;
7998 case CP0_REG15__EBASE:
7999 check_insn(ctx, ISA_MIPS_R2);
8000 gen_helper_mtc0_ebase(tcg_env, arg);
8001 register_name = "EBase";
8002 break;
8003 default:
8004 goto cp0_unimplemented;
8005 }
8006 break;
8007 case CP0_REGISTER_16:
8008 switch (sel) {
8009 case CP0_REG16__CONFIG:
8010 gen_helper_mtc0_config0(tcg_env, arg);
8011 register_name = "Config";
8012 /* Stop translation as we may have switched the execution mode */
8013 ctx->base.is_jmp = DISAS_STOP;
8014 break;
8015 case CP0_REG16__CONFIG1:
8016 /* ignored, read only */
8017 register_name = "Config1";
8018 break;
8019 case CP0_REG16__CONFIG2:
8020 gen_helper_mtc0_config2(tcg_env, arg);
8021 register_name = "Config2";
8022 /* Stop translation as we may have switched the execution mode */
8023 ctx->base.is_jmp = DISAS_STOP;
8024 break;
8025 case CP0_REG16__CONFIG3:
8026 gen_helper_mtc0_config3(tcg_env, arg);
8027 register_name = "Config3";
8028 /* Stop translation as we may have switched the execution mode */
8029 ctx->base.is_jmp = DISAS_STOP;
8030 break;
8031 case CP0_REG16__CONFIG4:
8032 /* currently ignored */
8033 register_name = "Config4";
8034 break;
8035 case CP0_REG16__CONFIG5:
8036 gen_helper_mtc0_config5(tcg_env, arg);
8037 register_name = "Config5";
8038 /* Stop translation as we may have switched the execution mode */
8039 ctx->base.is_jmp = DISAS_STOP;
8040 break;
8041 /* 6,7 are implementation dependent */
8042 default:
8043 register_name = "Invalid config selector";
8044 goto cp0_unimplemented;
8045 }
8046 break;
8047 case CP0_REGISTER_17:
8048 switch (sel) {
8049 case CP0_REG17__LLADDR:
8050 gen_helper_mtc0_lladdr(tcg_env, arg);
8051 register_name = "LLAddr";
8052 break;
8053 case CP0_REG17__MAAR:
8054 CP0_CHECK(ctx->mrp);
8055 gen_helper_mtc0_maar(tcg_env, arg);
8056 register_name = "MAAR";
8057 break;
8058 case CP0_REG17__MAARI:
8059 CP0_CHECK(ctx->mrp);
8060 gen_helper_mtc0_maari(tcg_env, arg);
8061 register_name = "MAARI";
8062 break;
8063 default:
8064 goto cp0_unimplemented;
8065 }
8066 break;
8067 case CP0_REGISTER_18:
8068 switch (sel) {
8069 case CP0_REG18__WATCHLO0:
8070 case CP0_REG18__WATCHLO1:
8071 case CP0_REG18__WATCHLO2:
8072 case CP0_REG18__WATCHLO3:
8073 case CP0_REG18__WATCHLO4:
8074 case CP0_REG18__WATCHLO5:
8075 case CP0_REG18__WATCHLO6:
8076 case CP0_REG18__WATCHLO7:
8077 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8078 gen_helper_0e1i(mtc0_watchlo, arg, sel);
8079 register_name = "WatchLo";
8080 break;
8081 default:
8082 goto cp0_unimplemented;
8083 }
8084 break;
8085 case CP0_REGISTER_19:
8086 switch (sel) {
8087 case CP0_REG19__WATCHHI0:
8088 case CP0_REG19__WATCHHI1:
8089 case CP0_REG19__WATCHHI2:
8090 case CP0_REG19__WATCHHI3:
8091 case CP0_REG19__WATCHHI4:
8092 case CP0_REG19__WATCHHI5:
8093 case CP0_REG19__WATCHHI6:
8094 case CP0_REG19__WATCHHI7:
8095 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8096 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8097 register_name = "WatchHi";
8098 break;
8099 default:
8100 goto cp0_unimplemented;
8101 }
8102 break;
8103 case CP0_REGISTER_20:
8104 switch (sel) {
8105 case CP0_REG20__XCONTEXT:
8106 check_insn(ctx, ISA_MIPS3);
8107 gen_helper_mtc0_xcontext(tcg_env, arg);
8108 register_name = "XContext";
8109 break;
8110 default:
8111 goto cp0_unimplemented;
8112 }
8113 break;
8114 case CP0_REGISTER_21:
8115 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8116 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8117 switch (sel) {
8118 case 0:
8119 gen_helper_mtc0_framemask(tcg_env, arg);
8120 register_name = "Framemask";
8121 break;
8122 default:
8123 goto cp0_unimplemented;
8124 }
8125 break;
8126 case CP0_REGISTER_22:
8127 /* ignored */
8128 register_name = "Diagnostic"; /* implementation dependent */
8129 break;
8130 case CP0_REGISTER_23:
8131 switch (sel) {
8132 case CP0_REG23__DEBUG:
8133 gen_helper_mtc0_debug(tcg_env, arg); /* EJTAG support */
8134 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8135 gen_save_pc(ctx->base.pc_next + 4);
8136 ctx->base.is_jmp = DISAS_EXIT;
8137 register_name = "Debug";
8138 break;
8139 case CP0_REG23__TRACECONTROL:
8140 /* PDtrace support */
8141 /* gen_helper_mtc0_tracecontrol(tcg_env, arg); */
8142 /* Stop translation as we may have switched the execution mode */
8143 ctx->base.is_jmp = DISAS_STOP;
8144 register_name = "TraceControl";
8145 goto cp0_unimplemented;
8146 case CP0_REG23__TRACECONTROL2:
8147 /* PDtrace support */
8148 /* gen_helper_mtc0_tracecontrol2(tcg_env, arg); */
8149 /* Stop translation as we may have switched the execution mode */
8150 ctx->base.is_jmp = DISAS_STOP;
8151 register_name = "TraceControl2";
8152 goto cp0_unimplemented;
8153 case CP0_REG23__USERTRACEDATA1:
8154 /* PDtrace support */
8155 /* gen_helper_mtc0_usertracedata1(tcg_env, arg);*/
8156 /* Stop translation as we may have switched the execution mode */
8157 ctx->base.is_jmp = DISAS_STOP;
8158 register_name = "UserTraceData1";
8159 goto cp0_unimplemented;
8160 case CP0_REG23__TRACEIBPC:
8161 /* PDtrace support */
8162 /* gen_helper_mtc0_traceibpc(tcg_env, arg); */
8163 /* Stop translation as we may have switched the execution mode */
8164 ctx->base.is_jmp = DISAS_STOP;
8165 register_name = "TraceIBPC";
8166 goto cp0_unimplemented;
8167 case CP0_REG23__TRACEDBPC:
8168 /* PDtrace support */
8169 /* gen_helper_mtc0_tracedbpc(tcg_env, arg); */
8170 /* Stop translation as we may have switched the execution mode */
8171 ctx->base.is_jmp = DISAS_STOP;
8172 register_name = "TraceDBPC";
8173 goto cp0_unimplemented;
8174 default:
8175 goto cp0_unimplemented;
8176 }
8177 break;
8178 case CP0_REGISTER_24:
8179 switch (sel) {
8180 case CP0_REG24__DEPC:
8181 /* EJTAG support */
8182 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_DEPC));
8183 register_name = "DEPC";
8184 break;
8185 default:
8186 goto cp0_unimplemented;
8187 }
8188 break;
8189 case CP0_REGISTER_25:
8190 switch (sel) {
8191 case CP0_REG25__PERFCTL0:
8192 gen_helper_mtc0_performance0(tcg_env, arg);
8193 register_name = "Performance0";
8194 break;
8195 case CP0_REG25__PERFCNT0:
8196 /* gen_helper_mtc0_performance1(tcg_env, arg); */
8197 register_name = "Performance1";
8198 goto cp0_unimplemented;
8199 case CP0_REG25__PERFCTL1:
8200 /* gen_helper_mtc0_performance2(tcg_env, arg); */
8201 register_name = "Performance2";
8202 goto cp0_unimplemented;
8203 case CP0_REG25__PERFCNT1:
8204 /* gen_helper_mtc0_performance3(tcg_env, arg); */
8205 register_name = "Performance3";
8206 goto cp0_unimplemented;
8207 case CP0_REG25__PERFCTL2:
8208 /* gen_helper_mtc0_performance4(tcg_env, arg); */
8209 register_name = "Performance4";
8210 goto cp0_unimplemented;
8211 case CP0_REG25__PERFCNT2:
8212 /* gen_helper_mtc0_performance5(tcg_env, arg); */
8213 register_name = "Performance5";
8214 goto cp0_unimplemented;
8215 case CP0_REG25__PERFCTL3:
8216 /* gen_helper_mtc0_performance6(tcg_env, arg); */
8217 register_name = "Performance6";
8218 goto cp0_unimplemented;
8219 case CP0_REG25__PERFCNT3:
8220 /* gen_helper_mtc0_performance7(tcg_env, arg); */
8221 register_name = "Performance7";
8222 goto cp0_unimplemented;
8223 default:
8224 goto cp0_unimplemented;
8225 }
8226 break;
8227 case CP0_REGISTER_26:
8228 switch (sel) {
8229 case CP0_REG26__ERRCTL:
8230 gen_helper_mtc0_errctl(tcg_env, arg);
8231 ctx->base.is_jmp = DISAS_STOP;
8232 register_name = "ErrCtl";
8233 break;
8234 default:
8235 goto cp0_unimplemented;
8236 }
8237 break;
8238 case CP0_REGISTER_27:
8239 switch (sel) {
8240 case CP0_REG27__CACHERR:
8241 /* ignored */
8242 register_name = "CacheErr";
8243 break;
8244 default:
8245 goto cp0_unimplemented;
8246 }
8247 break;
8248 case CP0_REGISTER_28:
8249 switch (sel) {
8250 case CP0_REG28__TAGLO:
8251 case CP0_REG28__TAGLO1:
8252 case CP0_REG28__TAGLO2:
8253 case CP0_REG28__TAGLO3:
8254 gen_helper_mtc0_taglo(tcg_env, arg);
8255 register_name = "TagLo";
8256 break;
8257 case CP0_REG28__DATALO:
8258 case CP0_REG28__DATALO1:
8259 case CP0_REG28__DATALO2:
8260 case CP0_REG28__DATALO3:
8261 gen_helper_mtc0_datalo(tcg_env, arg);
8262 register_name = "DataLo";
8263 break;
8264 default:
8265 goto cp0_unimplemented;
8266 }
8267 break;
8268 case CP0_REGISTER_29:
8269 switch (sel) {
8270 case CP0_REG29__TAGHI:
8271 case CP0_REG29__TAGHI1:
8272 case CP0_REG29__TAGHI2:
8273 case CP0_REG29__TAGHI3:
8274 gen_helper_mtc0_taghi(tcg_env, arg);
8275 register_name = "TagHi";
8276 break;
8277 case CP0_REG29__DATAHI:
8278 case CP0_REG29__DATAHI1:
8279 case CP0_REG29__DATAHI2:
8280 case CP0_REG29__DATAHI3:
8281 gen_helper_mtc0_datahi(tcg_env, arg);
8282 register_name = "DataHi";
8283 break;
8284 default:
8285 register_name = "invalid sel";
8286 goto cp0_unimplemented;
8287 }
8288 break;
8289 case CP0_REGISTER_30:
8290 switch (sel) {
8291 case CP0_REG30__ERROREPC:
8292 tcg_gen_st_tl(arg, tcg_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8293 register_name = "ErrorEPC";
8294 break;
8295 default:
8296 goto cp0_unimplemented;
8297 }
8298 break;
8299 case CP0_REGISTER_31:
8300 switch (sel) {
8301 case CP0_REG31__DESAVE:
8302 /* EJTAG support */
8303 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8304 register_name = "DESAVE";
8305 break;
8306 case CP0_REG31__KSCRATCH1:
8307 case CP0_REG31__KSCRATCH2:
8308 case CP0_REG31__KSCRATCH3:
8309 case CP0_REG31__KSCRATCH4:
8310 case CP0_REG31__KSCRATCH5:
8311 case CP0_REG31__KSCRATCH6:
8312 CP0_CHECK(ctx->kscrexist & (1 << sel));
8313 tcg_gen_st_tl(arg, tcg_env,
8314 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8315 register_name = "KScratch";
8316 break;
8317 default:
8318 goto cp0_unimplemented;
8319 }
8320 break;
8321 default:
8322 goto cp0_unimplemented;
8323 }
8324 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8325
8326 /* For simplicity assume that all writes can cause interrupts. */
8327 if (icount) {
8328 /*
8329 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8330 * translated code to check for pending interrupts.
8331 */
8332 gen_save_pc(ctx->base.pc_next + 4);
8333 ctx->base.is_jmp = DISAS_EXIT;
8334 }
8335 return;
8336
8337 cp0_unimplemented:
8338 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8339 register_name, reg, sel);
8340 }
8341 #endif /* TARGET_MIPS64 */
8342
8343 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8344 int u, int sel, int h)
8345 {
8346 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8347 TCGv t0 = tcg_temp_new();
8348
8349 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8350 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8351 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8352 tcg_gen_movi_tl(t0, -1);
8353 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8354 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8355 tcg_gen_movi_tl(t0, -1);
8356 } else if (u == 0) {
8357 switch (rt) {
8358 case 1:
8359 switch (sel) {
8360 case 1:
8361 gen_helper_mftc0_vpecontrol(t0, tcg_env);
8362 break;
8363 case 2:
8364 gen_helper_mftc0_vpeconf0(t0, tcg_env);
8365 break;
8366 default:
8367 goto die;
8368 break;
8369 }
8370 break;
8371 case 2:
8372 switch (sel) {
8373 case 1:
8374 gen_helper_mftc0_tcstatus(t0, tcg_env);
8375 break;
8376 case 2:
8377 gen_helper_mftc0_tcbind(t0, tcg_env);
8378 break;
8379 case 3:
8380 gen_helper_mftc0_tcrestart(t0, tcg_env);
8381 break;
8382 case 4:
8383 gen_helper_mftc0_tchalt(t0, tcg_env);
8384 break;
8385 case 5:
8386 gen_helper_mftc0_tccontext(t0, tcg_env);
8387 break;
8388 case 6:
8389 gen_helper_mftc0_tcschedule(t0, tcg_env);
8390 break;
8391 case 7:
8392 gen_helper_mftc0_tcschefback(t0, tcg_env);
8393 break;
8394 default:
8395 gen_mfc0(ctx, t0, rt, sel);
8396 break;
8397 }
8398 break;
8399 case 10:
8400 switch (sel) {
8401 case 0:
8402 gen_helper_mftc0_entryhi(t0, tcg_env);
8403 break;
8404 default:
8405 gen_mfc0(ctx, t0, rt, sel);
8406 break;
8407 }
8408 break;
8409 case 12:
8410 switch (sel) {
8411 case 0:
8412 gen_helper_mftc0_status(t0, tcg_env);
8413 break;
8414 default:
8415 gen_mfc0(ctx, t0, rt, sel);
8416 break;
8417 }
8418 break;
8419 case 13:
8420 switch (sel) {
8421 case 0:
8422 gen_helper_mftc0_cause(t0, tcg_env);
8423 break;
8424 default:
8425 goto die;
8426 break;
8427 }
8428 break;
8429 case 14:
8430 switch (sel) {
8431 case 0:
8432 gen_helper_mftc0_epc(t0, tcg_env);
8433 break;
8434 default:
8435 goto die;
8436 break;
8437 }
8438 break;
8439 case 15:
8440 switch (sel) {
8441 case 1:
8442 gen_helper_mftc0_ebase(t0, tcg_env);
8443 break;
8444 default:
8445 goto die;
8446 break;
8447 }
8448 break;
8449 case 16:
8450 switch (sel) {
8451 case 0:
8452 case 1:
8453 case 2:
8454 case 3:
8455 case 4:
8456 case 5:
8457 case 6:
8458 case 7:
8459 gen_helper_mftc0_configx(t0, tcg_env, tcg_constant_tl(sel));
8460 break;
8461 default:
8462 goto die;
8463 break;
8464 }
8465 break;
8466 case 23:
8467 switch (sel) {
8468 case 0:
8469 gen_helper_mftc0_debug(t0, tcg_env);
8470 break;
8471 default:
8472 gen_mfc0(ctx, t0, rt, sel);
8473 break;
8474 }
8475 break;
8476 default:
8477 gen_mfc0(ctx, t0, rt, sel);
8478 }
8479 } else {
8480 switch (sel) {
8481 /* GPR registers. */
8482 case 0:
8483 gen_helper_1e0i(mftgpr, t0, rt);
8484 break;
8485 /* Auxiliary CPU registers */
8486 case 1:
8487 switch (rt) {
8488 case 0:
8489 gen_helper_1e0i(mftlo, t0, 0);
8490 break;
8491 case 1:
8492 gen_helper_1e0i(mfthi, t0, 0);
8493 break;
8494 case 2:
8495 gen_helper_1e0i(mftacx, t0, 0);
8496 break;
8497 case 4:
8498 gen_helper_1e0i(mftlo, t0, 1);
8499 break;
8500 case 5:
8501 gen_helper_1e0i(mfthi, t0, 1);
8502 break;
8503 case 6:
8504 gen_helper_1e0i(mftacx, t0, 1);
8505 break;
8506 case 8:
8507 gen_helper_1e0i(mftlo, t0, 2);
8508 break;
8509 case 9:
8510 gen_helper_1e0i(mfthi, t0, 2);
8511 break;
8512 case 10:
8513 gen_helper_1e0i(mftacx, t0, 2);
8514 break;
8515 case 12:
8516 gen_helper_1e0i(mftlo, t0, 3);
8517 break;
8518 case 13:
8519 gen_helper_1e0i(mfthi, t0, 3);
8520 break;
8521 case 14:
8522 gen_helper_1e0i(mftacx, t0, 3);
8523 break;
8524 case 16:
8525 gen_helper_mftdsp(t0, tcg_env);
8526 break;
8527 default:
8528 goto die;
8529 }
8530 break;
8531 /* Floating point (COP1). */
8532 case 2:
8533 /* XXX: For now we support only a single FPU context. */
8534 if (h == 0) {
8535 TCGv_i32 fp0 = tcg_temp_new_i32();
8536
8537 gen_load_fpr32(ctx, fp0, rt);
8538 tcg_gen_ext_i32_tl(t0, fp0);
8539 } else {
8540 TCGv_i32 fp0 = tcg_temp_new_i32();
8541
8542 gen_load_fpr32h(ctx, fp0, rt);
8543 tcg_gen_ext_i32_tl(t0, fp0);
8544 }
8545 break;
8546 case 3:
8547 /* XXX: For now we support only a single FPU context. */
8548 gen_helper_1e0i(cfc1, t0, rt);
8549 break;
8550 /* COP2: Not implemented. */
8551 case 4:
8552 case 5:
8553 /* fall through */
8554 default:
8555 goto die;
8556 }
8557 }
8558 trace_mips_translate_tr("mftr", rt, u, sel, h);
8559 gen_store_gpr(t0, rd);
8560 return;
8561
8562 die:
8563 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8564 gen_reserved_instruction(ctx);
8565 }
8566
8567 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8568 int u, int sel, int h)
8569 {
8570 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8571 TCGv t0 = tcg_temp_new();
8572
8573 gen_load_gpr(t0, rt);
8574 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8575 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8576 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8577 /* NOP */
8578 ;
8579 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8580 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8581 /* NOP */
8582 ;
8583 } else if (u == 0) {
8584 switch (rd) {
8585 case 1:
8586 switch (sel) {
8587 case 1:
8588 gen_helper_mttc0_vpecontrol(tcg_env, t0);
8589 break;
8590 case 2:
8591 gen_helper_mttc0_vpeconf0(tcg_env, t0);
8592 break;
8593 default:
8594 goto die;
8595 break;
8596 }
8597 break;
8598 case 2:
8599 switch (sel) {
8600 case 1:
8601 gen_helper_mttc0_tcstatus(tcg_env, t0);
8602 break;
8603 case 2:
8604 gen_helper_mttc0_tcbind(tcg_env, t0);
8605 break;
8606 case 3:
8607 gen_helper_mttc0_tcrestart(tcg_env, t0);
8608 break;
8609 case 4:
8610 gen_helper_mttc0_tchalt(tcg_env, t0);
8611 break;
8612 case 5:
8613 gen_helper_mttc0_tccontext(tcg_env, t0);
8614 break;
8615 case 6:
8616 gen_helper_mttc0_tcschedule(tcg_env, t0);
8617 break;
8618 case 7:
8619 gen_helper_mttc0_tcschefback(tcg_env, t0);
8620 break;
8621 default:
8622 gen_mtc0(ctx, t0, rd, sel);
8623 break;
8624 }
8625 break;
8626 case 10:
8627 switch (sel) {
8628 case 0:
8629 gen_helper_mttc0_entryhi(tcg_env, t0);
8630 break;
8631 default:
8632 gen_mtc0(ctx, t0, rd, sel);
8633 break;
8634 }
8635 break;
8636 case 12:
8637 switch (sel) {
8638 case 0:
8639 gen_helper_mttc0_status(tcg_env, t0);
8640 break;
8641 default:
8642 gen_mtc0(ctx, t0, rd, sel);
8643 break;
8644 }
8645 break;
8646 case 13:
8647 switch (sel) {
8648 case 0:
8649 gen_helper_mttc0_cause(tcg_env, t0);
8650 break;
8651 default:
8652 goto die;
8653 break;
8654 }
8655 break;
8656 case 15:
8657 switch (sel) {
8658 case 1:
8659 gen_helper_mttc0_ebase(tcg_env, t0);
8660 break;
8661 default:
8662 goto die;
8663 break;
8664 }
8665 break;
8666 case 23:
8667 switch (sel) {
8668 case 0:
8669 gen_helper_mttc0_debug(tcg_env, t0);
8670 break;
8671 default:
8672 gen_mtc0(ctx, t0, rd, sel);
8673 break;
8674 }
8675 break;
8676 default:
8677 gen_mtc0(ctx, t0, rd, sel);
8678 }
8679 } else {
8680 switch (sel) {
8681 /* GPR registers. */
8682 case 0:
8683 gen_helper_0e1i(mttgpr, t0, rd);
8684 break;
8685 /* Auxiliary CPU registers */
8686 case 1:
8687 switch (rd) {
8688 case 0:
8689 gen_helper_0e1i(mttlo, t0, 0);
8690 break;
8691 case 1:
8692 gen_helper_0e1i(mtthi, t0, 0);
8693 break;
8694 case 2:
8695 gen_helper_0e1i(mttacx, t0, 0);
8696 break;
8697 case 4:
8698 gen_helper_0e1i(mttlo, t0, 1);
8699 break;
8700 case 5:
8701 gen_helper_0e1i(mtthi, t0, 1);
8702 break;
8703 case 6:
8704 gen_helper_0e1i(mttacx, t0, 1);
8705 break;
8706 case 8:
8707 gen_helper_0e1i(mttlo, t0, 2);
8708 break;
8709 case 9:
8710 gen_helper_0e1i(mtthi, t0, 2);
8711 break;
8712 case 10:
8713 gen_helper_0e1i(mttacx, t0, 2);
8714 break;
8715 case 12:
8716 gen_helper_0e1i(mttlo, t0, 3);
8717 break;
8718 case 13:
8719 gen_helper_0e1i(mtthi, t0, 3);
8720 break;
8721 case 14:
8722 gen_helper_0e1i(mttacx, t0, 3);
8723 break;
8724 case 16:
8725 gen_helper_mttdsp(tcg_env, t0);
8726 break;
8727 default:
8728 goto die;
8729 }
8730 break;
8731 /* Floating point (COP1). */
8732 case 2:
8733 /* XXX: For now we support only a single FPU context. */
8734 if (h == 0) {
8735 TCGv_i32 fp0 = tcg_temp_new_i32();
8736
8737 tcg_gen_trunc_tl_i32(fp0, t0);
8738 gen_store_fpr32(ctx, fp0, rd);
8739 } else {
8740 TCGv_i32 fp0 = tcg_temp_new_i32();
8741
8742 tcg_gen_trunc_tl_i32(fp0, t0);
8743 gen_store_fpr32h(ctx, fp0, rd);
8744 }
8745 break;
8746 case 3:
8747 /* XXX: For now we support only a single FPU context. */
8748 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
8749 /* Stop translation as we may have changed hflags */
8750 ctx->base.is_jmp = DISAS_STOP;
8751 break;
8752 /* COP2: Not implemented. */
8753 case 4:
8754 case 5:
8755 /* fall through */
8756 default:
8757 goto die;
8758 }
8759 }
8760 trace_mips_translate_tr("mttr", rd, u, sel, h);
8761 return;
8762
8763 die:
8764 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8765 gen_reserved_instruction(ctx);
8766 }
8767
8768 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
8769 int rt, int rd)
8770 {
8771 const char *opn = "ldst";
8772
8773 check_cp0_enabled(ctx);
8774 switch (opc) {
8775 case OPC_MFC0:
8776 if (rt == 0) {
8777 /* Treat as NOP. */
8778 return;
8779 }
8780 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8781 opn = "mfc0";
8782 break;
8783 case OPC_MTC0:
8784 {
8785 TCGv t0 = tcg_temp_new();
8786
8787 gen_load_gpr(t0, rt);
8788 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8789 }
8790 opn = "mtc0";
8791 break;
8792 #if defined(TARGET_MIPS64)
8793 case OPC_DMFC0:
8794 check_insn(ctx, ISA_MIPS3);
8795 if (rt == 0) {
8796 /* Treat as NOP. */
8797 return;
8798 }
8799 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8800 opn = "dmfc0";
8801 break;
8802 case OPC_DMTC0:
8803 check_insn(ctx, ISA_MIPS3);
8804 {
8805 TCGv t0 = tcg_temp_new();
8806
8807 gen_load_gpr(t0, rt);
8808 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8809 }
8810 opn = "dmtc0";
8811 break;
8812 #endif
8813 case OPC_MFHC0:
8814 check_mvh(ctx);
8815 if (rt == 0) {
8816 /* Treat as NOP. */
8817 return;
8818 }
8819 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8820 opn = "mfhc0";
8821 break;
8822 case OPC_MTHC0:
8823 check_mvh(ctx);
8824 {
8825 TCGv t0 = tcg_temp_new();
8826 gen_load_gpr(t0, rt);
8827 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8828 }
8829 opn = "mthc0";
8830 break;
8831 case OPC_MFTR:
8832 check_cp0_enabled(ctx);
8833 if (rd == 0) {
8834 /* Treat as NOP. */
8835 return;
8836 }
8837 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8838 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8839 opn = "mftr";
8840 break;
8841 case OPC_MTTR:
8842 check_cp0_enabled(ctx);
8843 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8844 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8845 opn = "mttr";
8846 break;
8847 case OPC_TLBWI:
8848 opn = "tlbwi";
8849 if (!env->tlb->helper_tlbwi) {
8850 goto die;
8851 }
8852 gen_helper_tlbwi(tcg_env);
8853 break;
8854 case OPC_TLBINV:
8855 opn = "tlbinv";
8856 if (ctx->ie >= 2) {
8857 if (!env->tlb->helper_tlbinv) {
8858 goto die;
8859 }
8860 gen_helper_tlbinv(tcg_env);
8861 } /* treat as nop if TLBINV not supported */
8862 break;
8863 case OPC_TLBINVF:
8864 opn = "tlbinvf";
8865 if (ctx->ie >= 2) {
8866 if (!env->tlb->helper_tlbinvf) {
8867 goto die;
8868 }
8869 gen_helper_tlbinvf(tcg_env);
8870 } /* treat as nop if TLBINV not supported */
8871 break;
8872 case OPC_TLBWR:
8873 opn = "tlbwr";
8874 if (!env->tlb->helper_tlbwr) {
8875 goto die;
8876 }
8877 gen_helper_tlbwr(tcg_env);
8878 break;
8879 case OPC_TLBP:
8880 opn = "tlbp";
8881 if (!env->tlb->helper_tlbp) {
8882 goto die;
8883 }
8884 gen_helper_tlbp(tcg_env);
8885 break;
8886 case OPC_TLBR:
8887 opn = "tlbr";
8888 if (!env->tlb->helper_tlbr) {
8889 goto die;
8890 }
8891 gen_helper_tlbr(tcg_env);
8892 break;
8893 case OPC_ERET: /* OPC_ERETNC */
8894 if ((ctx->insn_flags & ISA_MIPS_R6) &&
8895 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8896 goto die;
8897 } else {
8898 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8899 if (ctx->opcode & (1 << bit_shift)) {
8900 /* OPC_ERETNC */
8901 opn = "eretnc";
8902 check_insn(ctx, ISA_MIPS_R5);
8903 gen_helper_eretnc(tcg_env);
8904 } else {
8905 /* OPC_ERET */
8906 opn = "eret";
8907 check_insn(ctx, ISA_MIPS2);
8908 gen_helper_eret(tcg_env);
8909 }
8910 ctx->base.is_jmp = DISAS_EXIT;
8911 }
8912 break;
8913 case OPC_DERET:
8914 opn = "deret";
8915 check_insn(ctx, ISA_MIPS_R1);
8916 if ((ctx->insn_flags & ISA_MIPS_R6) &&
8917 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8918 goto die;
8919 }
8920 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8921 MIPS_INVAL(opn);
8922 gen_reserved_instruction(ctx);
8923 } else {
8924 gen_helper_deret(tcg_env);
8925 ctx->base.is_jmp = DISAS_EXIT;
8926 }
8927 break;
8928 case OPC_WAIT:
8929 opn = "wait";
8930 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
8931 if ((ctx->insn_flags & ISA_MIPS_R6) &&
8932 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8933 goto die;
8934 }
8935 /* If we get an exception, we want to restart at next instruction */
8936 ctx->base.pc_next += 4;
8937 save_cpu_state(ctx, 1);
8938 ctx->base.pc_next -= 4;
8939 gen_helper_wait(tcg_env);
8940 ctx->base.is_jmp = DISAS_NORETURN;
8941 break;
8942 default:
8943 die:
8944 MIPS_INVAL(opn);
8945 gen_reserved_instruction(ctx);
8946 return;
8947 }
8948 (void)opn; /* avoid a compiler warning */
8949 }
8950 #endif /* !CONFIG_USER_ONLY */
8951
8952 /* CP1 Branches (before delay slot) */
8953 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8954 int32_t cc, int32_t offset)
8955 {
8956 target_ulong btarget;
8957 TCGv_i32 t0 = tcg_temp_new_i32();
8958
8959 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8960 gen_reserved_instruction(ctx);
8961 return;
8962 }
8963
8964 if (cc != 0) {
8965 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
8966 }
8967
8968 btarget = ctx->base.pc_next + 4 + offset;
8969
8970 switch (op) {
8971 case OPC_BC1F:
8972 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8973 tcg_gen_not_i32(t0, t0);
8974 tcg_gen_andi_i32(t0, t0, 1);
8975 tcg_gen_extu_i32_tl(bcond, t0);
8976 goto not_likely;
8977 case OPC_BC1FL:
8978 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8979 tcg_gen_not_i32(t0, t0);
8980 tcg_gen_andi_i32(t0, t0, 1);
8981 tcg_gen_extu_i32_tl(bcond, t0);
8982 goto likely;
8983 case OPC_BC1T:
8984 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8985 tcg_gen_andi_i32(t0, t0, 1);
8986 tcg_gen_extu_i32_tl(bcond, t0);
8987 goto not_likely;
8988 case OPC_BC1TL:
8989 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8990 tcg_gen_andi_i32(t0, t0, 1);
8991 tcg_gen_extu_i32_tl(bcond, t0);
8992 likely:
8993 ctx->hflags |= MIPS_HFLAG_BL;
8994 break;
8995 case OPC_BC1FANY2:
8996 {
8997 TCGv_i32 t1 = tcg_temp_new_i32();
8998 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8999 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9000 tcg_gen_nand_i32(t0, t0, t1);
9001 tcg_gen_andi_i32(t0, t0, 1);
9002 tcg_gen_extu_i32_tl(bcond, t0);
9003 }
9004 goto not_likely;
9005 case OPC_BC1TANY2:
9006 {
9007 TCGv_i32 t1 = tcg_temp_new_i32();
9008 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9009 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9010 tcg_gen_or_i32(t0, t0, t1);
9011 tcg_gen_andi_i32(t0, t0, 1);
9012 tcg_gen_extu_i32_tl(bcond, t0);
9013 }
9014 goto not_likely;
9015 case OPC_BC1FANY4:
9016 {
9017 TCGv_i32 t1 = tcg_temp_new_i32();
9018 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9019 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9020 tcg_gen_and_i32(t0, t0, t1);
9021 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9022 tcg_gen_and_i32(t0, t0, t1);
9023 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9024 tcg_gen_nand_i32(t0, t0, t1);
9025 tcg_gen_andi_i32(t0, t0, 1);
9026 tcg_gen_extu_i32_tl(bcond, t0);
9027 }
9028 goto not_likely;
9029 case OPC_BC1TANY4:
9030 {
9031 TCGv_i32 t1 = tcg_temp_new_i32();
9032 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9033 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9034 tcg_gen_or_i32(t0, t0, t1);
9035 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9036 tcg_gen_or_i32(t0, t0, t1);
9037 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9038 tcg_gen_or_i32(t0, t0, t1);
9039 tcg_gen_andi_i32(t0, t0, 1);
9040 tcg_gen_extu_i32_tl(bcond, t0);
9041 }
9042 not_likely:
9043 ctx->hflags |= MIPS_HFLAG_BC;
9044 break;
9045 default:
9046 MIPS_INVAL("cp1 cond branch");
9047 gen_reserved_instruction(ctx);
9048 return;
9049 }
9050 ctx->btarget = btarget;
9051 ctx->hflags |= MIPS_HFLAG_BDS32;
9052 }
9053
9054 /* R6 CP1 Branches */
9055 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9056 int32_t ft, int32_t offset,
9057 int delayslot_size)
9058 {
9059 target_ulong btarget;
9060 TCGv_i64 t0 = tcg_temp_new_i64();
9061
9062 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9063 #ifdef MIPS_DEBUG_DISAS
9064 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9065 "\n", ctx->base.pc_next);
9066 #endif
9067 gen_reserved_instruction(ctx);
9068 return;
9069 }
9070
9071 gen_load_fpr64(ctx, t0, ft);
9072 tcg_gen_andi_i64(t0, t0, 1);
9073
9074 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9075
9076 switch (op) {
9077 case OPC_BC1EQZ:
9078 tcg_gen_xori_i64(t0, t0, 1);
9079 ctx->hflags |= MIPS_HFLAG_BC;
9080 break;
9081 case OPC_BC1NEZ:
9082 /* t0 already set */
9083 ctx->hflags |= MIPS_HFLAG_BC;
9084 break;
9085 default:
9086 MIPS_INVAL("cp1 cond branch");
9087 gen_reserved_instruction(ctx);
9088 return;
9089 }
9090
9091 tcg_gen_trunc_i64_tl(bcond, t0);
9092
9093 ctx->btarget = btarget;
9094
9095 switch (delayslot_size) {
9096 case 2:
9097 ctx->hflags |= MIPS_HFLAG_BDS16;
9098 break;
9099 case 4:
9100 ctx->hflags |= MIPS_HFLAG_BDS32;
9101 break;
9102 }
9103 }
9104
9105 /* Coprocessor 1 (FPU) */
9106
9107 #define FOP(func, fmt) (((fmt) << 21) | (func))
9108
9109 enum fopcode {
9110 OPC_ADD_S = FOP(0, FMT_S),
9111 OPC_SUB_S = FOP(1, FMT_S),
9112 OPC_MUL_S = FOP(2, FMT_S),
9113 OPC_DIV_S = FOP(3, FMT_S),
9114 OPC_SQRT_S = FOP(4, FMT_S),
9115 OPC_ABS_S = FOP(5, FMT_S),
9116 OPC_MOV_S = FOP(6, FMT_S),
9117 OPC_NEG_S = FOP(7, FMT_S),
9118 OPC_ROUND_L_S = FOP(8, FMT_S),
9119 OPC_TRUNC_L_S = FOP(9, FMT_S),
9120 OPC_CEIL_L_S = FOP(10, FMT_S),
9121 OPC_FLOOR_L_S = FOP(11, FMT_S),
9122 OPC_ROUND_W_S = FOP(12, FMT_S),
9123 OPC_TRUNC_W_S = FOP(13, FMT_S),
9124 OPC_CEIL_W_S = FOP(14, FMT_S),
9125 OPC_FLOOR_W_S = FOP(15, FMT_S),
9126 OPC_SEL_S = FOP(16, FMT_S),
9127 OPC_MOVCF_S = FOP(17, FMT_S),
9128 OPC_MOVZ_S = FOP(18, FMT_S),
9129 OPC_MOVN_S = FOP(19, FMT_S),
9130 OPC_SELEQZ_S = FOP(20, FMT_S),
9131 OPC_RECIP_S = FOP(21, FMT_S),
9132 OPC_RSQRT_S = FOP(22, FMT_S),
9133 OPC_SELNEZ_S = FOP(23, FMT_S),
9134 OPC_MADDF_S = FOP(24, FMT_S),
9135 OPC_MSUBF_S = FOP(25, FMT_S),
9136 OPC_RINT_S = FOP(26, FMT_S),
9137 OPC_CLASS_S = FOP(27, FMT_S),
9138 OPC_MIN_S = FOP(28, FMT_S),
9139 OPC_RECIP2_S = FOP(28, FMT_S),
9140 OPC_MINA_S = FOP(29, FMT_S),
9141 OPC_RECIP1_S = FOP(29, FMT_S),
9142 OPC_MAX_S = FOP(30, FMT_S),
9143 OPC_RSQRT1_S = FOP(30, FMT_S),
9144 OPC_MAXA_S = FOP(31, FMT_S),
9145 OPC_RSQRT2_S = FOP(31, FMT_S),
9146 OPC_CVT_D_S = FOP(33, FMT_S),
9147 OPC_CVT_W_S = FOP(36, FMT_S),
9148 OPC_CVT_L_S = FOP(37, FMT_S),
9149 OPC_CVT_PS_S = FOP(38, FMT_S),
9150 OPC_CMP_F_S = FOP(48, FMT_S),
9151 OPC_CMP_UN_S = FOP(49, FMT_S),
9152 OPC_CMP_EQ_S = FOP(50, FMT_S),
9153 OPC_CMP_UEQ_S = FOP(51, FMT_S),
9154 OPC_CMP_OLT_S = FOP(52, FMT_S),
9155 OPC_CMP_ULT_S = FOP(53, FMT_S),
9156 OPC_CMP_OLE_S = FOP(54, FMT_S),
9157 OPC_CMP_ULE_S = FOP(55, FMT_S),
9158 OPC_CMP_SF_S = FOP(56, FMT_S),
9159 OPC_CMP_NGLE_S = FOP(57, FMT_S),
9160 OPC_CMP_SEQ_S = FOP(58, FMT_S),
9161 OPC_CMP_NGL_S = FOP(59, FMT_S),
9162 OPC_CMP_LT_S = FOP(60, FMT_S),
9163 OPC_CMP_NGE_S = FOP(61, FMT_S),
9164 OPC_CMP_LE_S = FOP(62, FMT_S),
9165 OPC_CMP_NGT_S = FOP(63, FMT_S),
9166
9167 OPC_ADD_D = FOP(0, FMT_D),
9168 OPC_SUB_D = FOP(1, FMT_D),
9169 OPC_MUL_D = FOP(2, FMT_D),
9170 OPC_DIV_D = FOP(3, FMT_D),
9171 OPC_SQRT_D = FOP(4, FMT_D),
9172 OPC_ABS_D = FOP(5, FMT_D),
9173 OPC_MOV_D = FOP(6, FMT_D),
9174 OPC_NEG_D = FOP(7, FMT_D),
9175 OPC_ROUND_L_D = FOP(8, FMT_D),
9176 OPC_TRUNC_L_D = FOP(9, FMT_D),
9177 OPC_CEIL_L_D = FOP(10, FMT_D),
9178 OPC_FLOOR_L_D = FOP(11, FMT_D),
9179 OPC_ROUND_W_D = FOP(12, FMT_D),
9180 OPC_TRUNC_W_D = FOP(13, FMT_D),
9181 OPC_CEIL_W_D = FOP(14, FMT_D),
9182 OPC_FLOOR_W_D = FOP(15, FMT_D),
9183 OPC_SEL_D = FOP(16, FMT_D),
9184 OPC_MOVCF_D = FOP(17, FMT_D),
9185 OPC_MOVZ_D = FOP(18, FMT_D),
9186 OPC_MOVN_D = FOP(19, FMT_D),
9187 OPC_SELEQZ_D = FOP(20, FMT_D),
9188 OPC_RECIP_D = FOP(21, FMT_D),
9189 OPC_RSQRT_D = FOP(22, FMT_D),
9190 OPC_SELNEZ_D = FOP(23, FMT_D),
9191 OPC_MADDF_D = FOP(24, FMT_D),
9192 OPC_MSUBF_D = FOP(25, FMT_D),
9193 OPC_RINT_D = FOP(26, FMT_D),
9194 OPC_CLASS_D = FOP(27, FMT_D),
9195 OPC_MIN_D = FOP(28, FMT_D),
9196 OPC_RECIP2_D = FOP(28, FMT_D),
9197 OPC_MINA_D = FOP(29, FMT_D),
9198 OPC_RECIP1_D = FOP(29, FMT_D),
9199 OPC_MAX_D = FOP(30, FMT_D),
9200 OPC_RSQRT1_D = FOP(30, FMT_D),
9201 OPC_MAXA_D = FOP(31, FMT_D),
9202 OPC_RSQRT2_D = FOP(31, FMT_D),
9203 OPC_CVT_S_D = FOP(32, FMT_D),
9204 OPC_CVT_W_D = FOP(36, FMT_D),
9205 OPC_CVT_L_D = FOP(37, FMT_D),
9206 OPC_CMP_F_D = FOP(48, FMT_D),
9207 OPC_CMP_UN_D = FOP(49, FMT_D),
9208 OPC_CMP_EQ_D = FOP(50, FMT_D),
9209 OPC_CMP_UEQ_D = FOP(51, FMT_D),
9210 OPC_CMP_OLT_D = FOP(52, FMT_D),
9211 OPC_CMP_ULT_D = FOP(53, FMT_D),
9212 OPC_CMP_OLE_D = FOP(54, FMT_D),
9213 OPC_CMP_ULE_D = FOP(55, FMT_D),
9214 OPC_CMP_SF_D = FOP(56, FMT_D),
9215 OPC_CMP_NGLE_D = FOP(57, FMT_D),
9216 OPC_CMP_SEQ_D = FOP(58, FMT_D),
9217 OPC_CMP_NGL_D = FOP(59, FMT_D),
9218 OPC_CMP_LT_D = FOP(60, FMT_D),
9219 OPC_CMP_NGE_D = FOP(61, FMT_D),
9220 OPC_CMP_LE_D = FOP(62, FMT_D),
9221 OPC_CMP_NGT_D = FOP(63, FMT_D),
9222
9223 OPC_CVT_S_W = FOP(32, FMT_W),
9224 OPC_CVT_D_W = FOP(33, FMT_W),
9225 OPC_CVT_S_L = FOP(32, FMT_L),
9226 OPC_CVT_D_L = FOP(33, FMT_L),
9227 OPC_CVT_PS_PW = FOP(38, FMT_W),
9228
9229 OPC_ADD_PS = FOP(0, FMT_PS),
9230 OPC_SUB_PS = FOP(1, FMT_PS),
9231 OPC_MUL_PS = FOP(2, FMT_PS),
9232 OPC_DIV_PS = FOP(3, FMT_PS),
9233 OPC_ABS_PS = FOP(5, FMT_PS),
9234 OPC_MOV_PS = FOP(6, FMT_PS),
9235 OPC_NEG_PS = FOP(7, FMT_PS),
9236 OPC_MOVCF_PS = FOP(17, FMT_PS),
9237 OPC_MOVZ_PS = FOP(18, FMT_PS),
9238 OPC_MOVN_PS = FOP(19, FMT_PS),
9239 OPC_ADDR_PS = FOP(24, FMT_PS),
9240 OPC_MULR_PS = FOP(26, FMT_PS),
9241 OPC_RECIP2_PS = FOP(28, FMT_PS),
9242 OPC_RECIP1_PS = FOP(29, FMT_PS),
9243 OPC_RSQRT1_PS = FOP(30, FMT_PS),
9244 OPC_RSQRT2_PS = FOP(31, FMT_PS),
9245
9246 OPC_CVT_S_PU = FOP(32, FMT_PS),
9247 OPC_CVT_PW_PS = FOP(36, FMT_PS),
9248 OPC_CVT_S_PL = FOP(40, FMT_PS),
9249 OPC_PLL_PS = FOP(44, FMT_PS),
9250 OPC_PLU_PS = FOP(45, FMT_PS),
9251 OPC_PUL_PS = FOP(46, FMT_PS),
9252 OPC_PUU_PS = FOP(47, FMT_PS),
9253 OPC_CMP_F_PS = FOP(48, FMT_PS),
9254 OPC_CMP_UN_PS = FOP(49, FMT_PS),
9255 OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9256 OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9257 OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9258 OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9259 OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9260 OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9261 OPC_CMP_SF_PS = FOP(56, FMT_PS),
9262 OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9263 OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9264 OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9265 OPC_CMP_LT_PS = FOP(60, FMT_PS),
9266 OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9267 OPC_CMP_LE_PS = FOP(62, FMT_PS),
9268 OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9269 };
9270
9271 enum r6_f_cmp_op {
9272 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
9273 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
9274 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
9275 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
9276 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
9277 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
9278 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
9279 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
9280 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
9281 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
9282 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
9283 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9284 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
9285 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9286 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
9287 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9288 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
9289 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
9290 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
9291 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
9292 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9293 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
9294
9295 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
9296 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
9297 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
9298 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
9299 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
9300 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
9301 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
9302 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
9303 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
9304 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
9305 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
9306 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9307 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
9308 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9309 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
9310 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9311 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
9312 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
9313 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
9314 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
9315 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9316 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
9317 };
9318
9319 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9320 {
9321 TCGv t0 = tcg_temp_new();
9322
9323 switch (opc) {
9324 case OPC_MFC1:
9325 {
9326 TCGv_i32 fp0 = tcg_temp_new_i32();
9327
9328 gen_load_fpr32(ctx, fp0, fs);
9329 tcg_gen_ext_i32_tl(t0, fp0);
9330 }
9331 gen_store_gpr(t0, rt);
9332 break;
9333 case OPC_MTC1:
9334 gen_load_gpr(t0, rt);
9335 {
9336 TCGv_i32 fp0 = tcg_temp_new_i32();
9337
9338 tcg_gen_trunc_tl_i32(fp0, t0);
9339 gen_store_fpr32(ctx, fp0, fs);
9340 }
9341 break;
9342 case OPC_CFC1:
9343 gen_helper_1e0i(cfc1, t0, fs);
9344 gen_store_gpr(t0, rt);
9345 break;
9346 case OPC_CTC1:
9347 gen_load_gpr(t0, rt);
9348 save_cpu_state(ctx, 0);
9349 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9350 /* Stop translation as we may have changed hflags */
9351 ctx->base.is_jmp = DISAS_STOP;
9352 break;
9353 #if defined(TARGET_MIPS64)
9354 case OPC_DMFC1:
9355 gen_load_fpr64(ctx, t0, fs);
9356 gen_store_gpr(t0, rt);
9357 break;
9358 case OPC_DMTC1:
9359 gen_load_gpr(t0, rt);
9360 gen_store_fpr64(ctx, t0, fs);
9361 break;
9362 #endif
9363 case OPC_MFHC1:
9364 {
9365 TCGv_i32 fp0 = tcg_temp_new_i32();
9366
9367 gen_load_fpr32h(ctx, fp0, fs);
9368 tcg_gen_ext_i32_tl(t0, fp0);
9369 }
9370 gen_store_gpr(t0, rt);
9371 break;
9372 case OPC_MTHC1:
9373 gen_load_gpr(t0, rt);
9374 {
9375 TCGv_i32 fp0 = tcg_temp_new_i32();
9376
9377 tcg_gen_trunc_tl_i32(fp0, t0);
9378 gen_store_fpr32h(ctx, fp0, fs);
9379 }
9380 break;
9381 default:
9382 MIPS_INVAL("cp1 move");
9383 gen_reserved_instruction(ctx);
9384 return;
9385 }
9386 }
9387
9388 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9389 {
9390 TCGLabel *l1;
9391 TCGCond cond;
9392 TCGv_i32 t0;
9393
9394 if (rd == 0) {
9395 /* Treat as NOP. */
9396 return;
9397 }
9398
9399 if (tf) {
9400 cond = TCG_COND_EQ;
9401 } else {
9402 cond = TCG_COND_NE;
9403 }
9404
9405 l1 = gen_new_label();
9406 t0 = tcg_temp_new_i32();
9407 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9408 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9409 gen_load_gpr(cpu_gpr[rd], rs);
9410 gen_set_label(l1);
9411 }
9412
9413 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9414 int tf)
9415 {
9416 int cond;
9417 TCGv_i32 t0 = tcg_temp_new_i32();
9418 TCGLabel *l1 = gen_new_label();
9419
9420 if (tf) {
9421 cond = TCG_COND_EQ;
9422 } else {
9423 cond = TCG_COND_NE;
9424 }
9425
9426 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9427 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9428 gen_load_fpr32(ctx, t0, fs);
9429 gen_store_fpr32(ctx, t0, fd);
9430 gen_set_label(l1);
9431 }
9432
9433 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9434 int tf)
9435 {
9436 int cond;
9437 TCGv_i32 t0 = tcg_temp_new_i32();
9438 TCGv_i64 fp0;
9439 TCGLabel *l1 = gen_new_label();
9440
9441 if (tf) {
9442 cond = TCG_COND_EQ;
9443 } else {
9444 cond = TCG_COND_NE;
9445 }
9446
9447 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9448 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9449 fp0 = tcg_temp_new_i64();
9450 gen_load_fpr64(ctx, fp0, fs);
9451 gen_store_fpr64(ctx, fp0, fd);
9452 gen_set_label(l1);
9453 }
9454
9455 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9456 int cc, int tf)
9457 {
9458 int cond;
9459 TCGv_i32 t0 = tcg_temp_new_i32();
9460 TCGLabel *l1 = gen_new_label();
9461 TCGLabel *l2 = gen_new_label();
9462
9463 if (tf) {
9464 cond = TCG_COND_EQ;
9465 } else {
9466 cond = TCG_COND_NE;
9467 }
9468
9469 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9470 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9471 gen_load_fpr32(ctx, t0, fs);
9472 gen_store_fpr32(ctx, t0, fd);
9473 gen_set_label(l1);
9474
9475 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9476 tcg_gen_brcondi_i32(cond, t0, 0, l2);
9477 gen_load_fpr32h(ctx, t0, fs);
9478 gen_store_fpr32h(ctx, t0, fd);
9479 gen_set_label(l2);
9480 }
9481
9482 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9483 int fs)
9484 {
9485 TCGv_i32 t1 = tcg_constant_i32(0);
9486 TCGv_i32 fp0 = tcg_temp_new_i32();
9487 TCGv_i32 fp1 = tcg_temp_new_i32();
9488 TCGv_i32 fp2 = tcg_temp_new_i32();
9489 gen_load_fpr32(ctx, fp0, fd);
9490 gen_load_fpr32(ctx, fp1, ft);
9491 gen_load_fpr32(ctx, fp2, fs);
9492
9493 switch (op1) {
9494 case OPC_SEL_S:
9495 tcg_gen_andi_i32(fp0, fp0, 1);
9496 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9497 break;
9498 case OPC_SELEQZ_S:
9499 tcg_gen_andi_i32(fp1, fp1, 1);
9500 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9501 break;
9502 case OPC_SELNEZ_S:
9503 tcg_gen_andi_i32(fp1, fp1, 1);
9504 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9505 break;
9506 default:
9507 MIPS_INVAL("gen_sel_s");
9508 gen_reserved_instruction(ctx);
9509 break;
9510 }
9511
9512 gen_store_fpr32(ctx, fp0, fd);
9513 }
9514
9515 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9516 int fs)
9517 {
9518 TCGv_i64 t1 = tcg_constant_i64(0);
9519 TCGv_i64 fp0 = tcg_temp_new_i64();
9520 TCGv_i64 fp1 = tcg_temp_new_i64();
9521 TCGv_i64 fp2 = tcg_temp_new_i64();
9522 gen_load_fpr64(ctx, fp0, fd);
9523 gen_load_fpr64(ctx, fp1, ft);
9524 gen_load_fpr64(ctx, fp2, fs);
9525
9526 switch (op1) {
9527 case OPC_SEL_D:
9528 tcg_gen_andi_i64(fp0, fp0, 1);
9529 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9530 break;
9531 case OPC_SELEQZ_D:
9532 tcg_gen_andi_i64(fp1, fp1, 1);
9533 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9534 break;
9535 case OPC_SELNEZ_D:
9536 tcg_gen_andi_i64(fp1, fp1, 1);
9537 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9538 break;
9539 default:
9540 MIPS_INVAL("gen_sel_d");
9541 gen_reserved_instruction(ctx);
9542 break;
9543 }
9544
9545 gen_store_fpr64(ctx, fp0, fd);
9546 }
9547
9548 static void gen_farith(DisasContext *ctx, enum fopcode op1,
9549 int ft, int fs, int fd, int cc)
9550 {
9551 uint32_t func = ctx->opcode & 0x3f;
9552 switch (op1) {
9553 case OPC_ADD_S:
9554 {
9555 TCGv_i32 fp0 = tcg_temp_new_i32();
9556 TCGv_i32 fp1 = tcg_temp_new_i32();
9557
9558 gen_load_fpr32(ctx, fp0, fs);
9559 gen_load_fpr32(ctx, fp1, ft);
9560 gen_helper_float_add_s(fp0, tcg_env, fp0, fp1);
9561 gen_store_fpr32(ctx, fp0, fd);
9562 }
9563 break;
9564 case OPC_SUB_S:
9565 {
9566 TCGv_i32 fp0 = tcg_temp_new_i32();
9567 TCGv_i32 fp1 = tcg_temp_new_i32();
9568
9569 gen_load_fpr32(ctx, fp0, fs);
9570 gen_load_fpr32(ctx, fp1, ft);
9571 gen_helper_float_sub_s(fp0, tcg_env, fp0, fp1);
9572 gen_store_fpr32(ctx, fp0, fd);
9573 }
9574 break;
9575 case OPC_MUL_S:
9576 {
9577 TCGv_i32 fp0 = tcg_temp_new_i32();
9578 TCGv_i32 fp1 = tcg_temp_new_i32();
9579
9580 gen_load_fpr32(ctx, fp0, fs);
9581 gen_load_fpr32(ctx, fp1, ft);
9582 gen_helper_float_mul_s(fp0, tcg_env, fp0, fp1);
9583 gen_store_fpr32(ctx, fp0, fd);
9584 }
9585 break;
9586 case OPC_DIV_S:
9587 {
9588 TCGv_i32 fp0 = tcg_temp_new_i32();
9589 TCGv_i32 fp1 = tcg_temp_new_i32();
9590
9591 gen_load_fpr32(ctx, fp0, fs);
9592 gen_load_fpr32(ctx, fp1, ft);
9593 gen_helper_float_div_s(fp0, tcg_env, fp0, fp1);
9594 gen_store_fpr32(ctx, fp0, fd);
9595 }
9596 break;
9597 case OPC_SQRT_S:
9598 {
9599 TCGv_i32 fp0 = tcg_temp_new_i32();
9600
9601 gen_load_fpr32(ctx, fp0, fs);
9602 gen_helper_float_sqrt_s(fp0, tcg_env, fp0);
9603 gen_store_fpr32(ctx, fp0, fd);
9604 }
9605 break;
9606 case OPC_ABS_S:
9607 {
9608 TCGv_i32 fp0 = tcg_temp_new_i32();
9609
9610 gen_load_fpr32(ctx, fp0, fs);
9611 if (ctx->abs2008) {
9612 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9613 } else {
9614 gen_helper_float_abs_s(fp0, fp0);
9615 }
9616 gen_store_fpr32(ctx, fp0, fd);
9617 }
9618 break;
9619 case OPC_MOV_S:
9620 {
9621 TCGv_i32 fp0 = tcg_temp_new_i32();
9622
9623 gen_load_fpr32(ctx, fp0, fs);
9624 gen_store_fpr32(ctx, fp0, fd);
9625 }
9626 break;
9627 case OPC_NEG_S:
9628 {
9629 TCGv_i32 fp0 = tcg_temp_new_i32();
9630
9631 gen_load_fpr32(ctx, fp0, fs);
9632 if (ctx->abs2008) {
9633 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9634 } else {
9635 gen_helper_float_chs_s(fp0, fp0);
9636 }
9637 gen_store_fpr32(ctx, fp0, fd);
9638 }
9639 break;
9640 case OPC_ROUND_L_S:
9641 check_cp1_64bitmode(ctx);
9642 {
9643 TCGv_i32 fp32 = tcg_temp_new_i32();
9644 TCGv_i64 fp64 = tcg_temp_new_i64();
9645
9646 gen_load_fpr32(ctx, fp32, fs);
9647 if (ctx->nan2008) {
9648 gen_helper_float_round_2008_l_s(fp64, tcg_env, fp32);
9649 } else {
9650 gen_helper_float_round_l_s(fp64, tcg_env, fp32);
9651 }
9652 gen_store_fpr64(ctx, fp64, fd);
9653 }
9654 break;
9655 case OPC_TRUNC_L_S:
9656 check_cp1_64bitmode(ctx);
9657 {
9658 TCGv_i32 fp32 = tcg_temp_new_i32();
9659 TCGv_i64 fp64 = tcg_temp_new_i64();
9660
9661 gen_load_fpr32(ctx, fp32, fs);
9662 if (ctx->nan2008) {
9663 gen_helper_float_trunc_2008_l_s(fp64, tcg_env, fp32);
9664 } else {
9665 gen_helper_float_trunc_l_s(fp64, tcg_env, fp32);
9666 }
9667 gen_store_fpr64(ctx, fp64, fd);
9668 }
9669 break;
9670 case OPC_CEIL_L_S:
9671 check_cp1_64bitmode(ctx);
9672 {
9673 TCGv_i32 fp32 = tcg_temp_new_i32();
9674 TCGv_i64 fp64 = tcg_temp_new_i64();
9675
9676 gen_load_fpr32(ctx, fp32, fs);
9677 if (ctx->nan2008) {
9678 gen_helper_float_ceil_2008_l_s(fp64, tcg_env, fp32);
9679 } else {
9680 gen_helper_float_ceil_l_s(fp64, tcg_env, fp32);
9681 }
9682 gen_store_fpr64(ctx, fp64, fd);
9683 }
9684 break;
9685 case OPC_FLOOR_L_S:
9686 check_cp1_64bitmode(ctx);
9687 {
9688 TCGv_i32 fp32 = tcg_temp_new_i32();
9689 TCGv_i64 fp64 = tcg_temp_new_i64();
9690
9691 gen_load_fpr32(ctx, fp32, fs);
9692 if (ctx->nan2008) {
9693 gen_helper_float_floor_2008_l_s(fp64, tcg_env, fp32);
9694 } else {
9695 gen_helper_float_floor_l_s(fp64, tcg_env, fp32);
9696 }
9697 gen_store_fpr64(ctx, fp64, fd);
9698 }
9699 break;
9700 case OPC_ROUND_W_S:
9701 {
9702 TCGv_i32 fp0 = tcg_temp_new_i32();
9703
9704 gen_load_fpr32(ctx, fp0, fs);
9705 if (ctx->nan2008) {
9706 gen_helper_float_round_2008_w_s(fp0, tcg_env, fp0);
9707 } else {
9708 gen_helper_float_round_w_s(fp0, tcg_env, fp0);
9709 }
9710 gen_store_fpr32(ctx, fp0, fd);
9711 }
9712 break;
9713 case OPC_TRUNC_W_S:
9714 {
9715 TCGv_i32 fp0 = tcg_temp_new_i32();
9716
9717 gen_load_fpr32(ctx, fp0, fs);
9718 if (ctx->nan2008) {
9719 gen_helper_float_trunc_2008_w_s(fp0, tcg_env, fp0);
9720 } else {
9721 gen_helper_float_trunc_w_s(fp0, tcg_env, fp0);
9722 }
9723 gen_store_fpr32(ctx, fp0, fd);
9724 }
9725 break;
9726 case OPC_CEIL_W_S:
9727 {
9728 TCGv_i32 fp0 = tcg_temp_new_i32();
9729
9730 gen_load_fpr32(ctx, fp0, fs);
9731 if (ctx->nan2008) {
9732 gen_helper_float_ceil_2008_w_s(fp0, tcg_env, fp0);
9733 } else {
9734 gen_helper_float_ceil_w_s(fp0, tcg_env, fp0);
9735 }
9736 gen_store_fpr32(ctx, fp0, fd);
9737 }
9738 break;
9739 case OPC_FLOOR_W_S:
9740 {
9741 TCGv_i32 fp0 = tcg_temp_new_i32();
9742
9743 gen_load_fpr32(ctx, fp0, fs);
9744 if (ctx->nan2008) {
9745 gen_helper_float_floor_2008_w_s(fp0, tcg_env, fp0);
9746 } else {
9747 gen_helper_float_floor_w_s(fp0, tcg_env, fp0);
9748 }
9749 gen_store_fpr32(ctx, fp0, fd);
9750 }
9751 break;
9752 case OPC_SEL_S:
9753 check_insn(ctx, ISA_MIPS_R6);
9754 gen_sel_s(ctx, op1, fd, ft, fs);
9755 break;
9756 case OPC_SELEQZ_S:
9757 check_insn(ctx, ISA_MIPS_R6);
9758 gen_sel_s(ctx, op1, fd, ft, fs);
9759 break;
9760 case OPC_SELNEZ_S:
9761 check_insn(ctx, ISA_MIPS_R6);
9762 gen_sel_s(ctx, op1, fd, ft, fs);
9763 break;
9764 case OPC_MOVCF_S:
9765 check_insn_opc_removed(ctx, ISA_MIPS_R6);
9766 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9767 break;
9768 case OPC_MOVZ_S:
9769 check_insn_opc_removed(ctx, ISA_MIPS_R6);
9770 {
9771 TCGLabel *l1 = gen_new_label();
9772 TCGv_i32 fp0;
9773
9774 if (ft != 0) {
9775 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9776 }
9777 fp0 = tcg_temp_new_i32();
9778 gen_load_fpr32(ctx, fp0, fs);
9779 gen_store_fpr32(ctx, fp0, fd);
9780 gen_set_label(l1);
9781 }
9782 break;
9783 case OPC_MOVN_S:
9784 check_insn_opc_removed(ctx, ISA_MIPS_R6);
9785 {
9786 TCGLabel *l1 = gen_new_label();
9787 TCGv_i32 fp0;
9788
9789 if (ft != 0) {
9790 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9791 fp0 = tcg_temp_new_i32();
9792 gen_load_fpr32(ctx, fp0, fs);
9793 gen_store_fpr32(ctx, fp0, fd);
9794 gen_set_label(l1);
9795 }
9796 }
9797 break;
9798 case OPC_RECIP_S:
9799 {
9800 TCGv_i32 fp0 = tcg_temp_new_i32();
9801
9802 gen_load_fpr32(ctx, fp0, fs);
9803 gen_helper_float_recip_s(fp0, tcg_env, fp0);
9804 gen_store_fpr32(ctx, fp0, fd);
9805 }
9806 break;
9807 case OPC_RSQRT_S:
9808 {
9809 TCGv_i32 fp0 = tcg_temp_new_i32();
9810
9811 gen_load_fpr32(ctx, fp0, fs);
9812 gen_helper_float_rsqrt_s(fp0, tcg_env, fp0);
9813 gen_store_fpr32(ctx, fp0, fd);
9814 }
9815 break;
9816 case OPC_MADDF_S:
9817 check_insn(ctx, ISA_MIPS_R6);
9818 {
9819 TCGv_i32 fp0 = tcg_temp_new_i32();
9820 TCGv_i32 fp1 = tcg_temp_new_i32();
9821 TCGv_i32 fp2 = tcg_temp_new_i32();
9822 gen_load_fpr32(ctx, fp0, fs);
9823 gen_load_fpr32(ctx, fp1, ft);
9824 gen_load_fpr32(ctx, fp2, fd);
9825 gen_helper_float_maddf_s(fp2, tcg_env, fp0, fp1, fp2);
9826 gen_store_fpr32(ctx, fp2, fd);
9827 }
9828 break;
9829 case OPC_MSUBF_S:
9830 check_insn(ctx, ISA_MIPS_R6);
9831 {
9832 TCGv_i32 fp0 = tcg_temp_new_i32();
9833 TCGv_i32 fp1 = tcg_temp_new_i32();
9834 TCGv_i32 fp2 = tcg_temp_new_i32();
9835 gen_load_fpr32(ctx, fp0, fs);
9836 gen_load_fpr32(ctx, fp1, ft);
9837 gen_load_fpr32(ctx, fp2, fd);
9838 gen_helper_float_msubf_s(fp2, tcg_env, fp0, fp1, fp2);
9839 gen_store_fpr32(ctx, fp2, fd);
9840 }
9841 break;
9842 case OPC_RINT_S:
9843 check_insn(ctx, ISA_MIPS_R6);
9844 {
9845 TCGv_i32 fp0 = tcg_temp_new_i32();
9846 gen_load_fpr32(ctx, fp0, fs);
9847 gen_helper_float_rint_s(fp0, tcg_env, fp0);
9848 gen_store_fpr32(ctx, fp0, fd);
9849 }
9850 break;
9851 case OPC_CLASS_S:
9852 check_insn(ctx, ISA_MIPS_R6);
9853 {
9854 TCGv_i32 fp0 = tcg_temp_new_i32();
9855 gen_load_fpr32(ctx, fp0, fs);
9856 gen_helper_float_class_s(fp0, tcg_env, fp0);
9857 gen_store_fpr32(ctx, fp0, fd);
9858 }
9859 break;
9860 case OPC_MIN_S: /* OPC_RECIP2_S */
9861 if (ctx->insn_flags & ISA_MIPS_R6) {
9862 /* OPC_MIN_S */
9863 TCGv_i32 fp0 = tcg_temp_new_i32();
9864 TCGv_i32 fp1 = tcg_temp_new_i32();
9865 TCGv_i32 fp2 = tcg_temp_new_i32();
9866 gen_load_fpr32(ctx, fp0, fs);
9867 gen_load_fpr32(ctx, fp1, ft);
9868 gen_helper_float_min_s(fp2, tcg_env, fp0, fp1);
9869 gen_store_fpr32(ctx, fp2, fd);
9870 } else {
9871 /* OPC_RECIP2_S */
9872 check_cp1_64bitmode(ctx);
9873 {
9874 TCGv_i32 fp0 = tcg_temp_new_i32();
9875 TCGv_i32 fp1 = tcg_temp_new_i32();
9876
9877 gen_load_fpr32(ctx, fp0, fs);
9878 gen_load_fpr32(ctx, fp1, ft);
9879 gen_helper_float_recip2_s(fp0, tcg_env, fp0, fp1);
9880 gen_store_fpr32(ctx, fp0, fd);
9881 }
9882 }
9883 break;
9884 case OPC_MINA_S: /* OPC_RECIP1_S */
9885 if (ctx->insn_flags & ISA_MIPS_R6) {
9886 /* OPC_MINA_S */
9887 TCGv_i32 fp0 = tcg_temp_new_i32();
9888 TCGv_i32 fp1 = tcg_temp_new_i32();
9889 TCGv_i32 fp2 = tcg_temp_new_i32();
9890 gen_load_fpr32(ctx, fp0, fs);
9891 gen_load_fpr32(ctx, fp1, ft);
9892 gen_helper_float_mina_s(fp2, tcg_env, fp0, fp1);
9893 gen_store_fpr32(ctx, fp2, fd);
9894 } else {
9895 /* OPC_RECIP1_S */
9896 check_cp1_64bitmode(ctx);
9897 {
9898 TCGv_i32 fp0 = tcg_temp_new_i32();
9899
9900 gen_load_fpr32(ctx, fp0, fs);
9901 gen_helper_float_recip1_s(fp0, tcg_env, fp0);
9902 gen_store_fpr32(ctx, fp0, fd);
9903 }
9904 }
9905 break;
9906 case OPC_MAX_S: /* OPC_RSQRT1_S */
9907 if (ctx->insn_flags & ISA_MIPS_R6) {
9908 /* OPC_MAX_S */
9909 TCGv_i32 fp0 = tcg_temp_new_i32();
9910 TCGv_i32 fp1 = tcg_temp_new_i32();
9911 gen_load_fpr32(ctx, fp0, fs);
9912 gen_load_fpr32(ctx, fp1, ft);
9913 gen_helper_float_max_s(fp1, tcg_env, fp0, fp1);
9914 gen_store_fpr32(ctx, fp1, fd);
9915 } else {
9916 /* OPC_RSQRT1_S */
9917 check_cp1_64bitmode(ctx);
9918 {
9919 TCGv_i32 fp0 = tcg_temp_new_i32();
9920
9921 gen_load_fpr32(ctx, fp0, fs);
9922 gen_helper_float_rsqrt1_s(fp0, tcg_env, fp0);
9923 gen_store_fpr32(ctx, fp0, fd);
9924 }
9925 }
9926 break;
9927 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9928 if (ctx->insn_flags & ISA_MIPS_R6) {
9929 /* OPC_MAXA_S */
9930 TCGv_i32 fp0 = tcg_temp_new_i32();
9931 TCGv_i32 fp1 = tcg_temp_new_i32();
9932 gen_load_fpr32(ctx, fp0, fs);
9933 gen_load_fpr32(ctx, fp1, ft);
9934 gen_helper_float_maxa_s(fp1, tcg_env, fp0, fp1);
9935 gen_store_fpr32(ctx, fp1, fd);
9936 } else {
9937 /* OPC_RSQRT2_S */
9938 check_cp1_64bitmode(ctx);
9939 {
9940 TCGv_i32 fp0 = tcg_temp_new_i32();
9941 TCGv_i32 fp1 = tcg_temp_new_i32();
9942
9943 gen_load_fpr32(ctx, fp0, fs);
9944 gen_load_fpr32(ctx, fp1, ft);
9945 gen_helper_float_rsqrt2_s(fp0, tcg_env, fp0, fp1);
9946 gen_store_fpr32(ctx, fp0, fd);
9947 }
9948 }
9949 break;
9950 case OPC_CVT_D_S:
9951 check_cp1_registers(ctx, fd);
9952 {
9953 TCGv_i32 fp32 = tcg_temp_new_i32();
9954 TCGv_i64 fp64 = tcg_temp_new_i64();
9955
9956 gen_load_fpr32(ctx, fp32, fs);
9957 gen_helper_float_cvtd_s(fp64, tcg_env, fp32);
9958 gen_store_fpr64(ctx, fp64, fd);
9959 }
9960 break;
9961 case OPC_CVT_W_S:
9962 {
9963 TCGv_i32 fp0 = tcg_temp_new_i32();
9964
9965 gen_load_fpr32(ctx, fp0, fs);
9966 if (ctx->nan2008) {
9967 gen_helper_float_cvt_2008_w_s(fp0, tcg_env, fp0);
9968 } else {
9969 gen_helper_float_cvt_w_s(fp0, tcg_env, fp0);
9970 }
9971 gen_store_fpr32(ctx, fp0, fd);
9972 }
9973 break;
9974 case OPC_CVT_L_S:
9975 check_cp1_64bitmode(ctx);
9976 {
9977 TCGv_i32 fp32 = tcg_temp_new_i32();
9978 TCGv_i64 fp64 = tcg_temp_new_i64();
9979
9980 gen_load_fpr32(ctx, fp32, fs);
9981 if (ctx->nan2008) {
9982 gen_helper_float_cvt_2008_l_s(fp64, tcg_env, fp32);
9983 } else {
9984 gen_helper_float_cvt_l_s(fp64, tcg_env, fp32);
9985 }
9986 gen_store_fpr64(ctx, fp64, fd);
9987 }
9988 break;
9989 case OPC_CVT_PS_S:
9990 check_ps(ctx);
9991 {
9992 TCGv_i64 fp64 = tcg_temp_new_i64();
9993 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9994 TCGv_i32 fp32_1 = tcg_temp_new_i32();
9995
9996 gen_load_fpr32(ctx, fp32_0, fs);
9997 gen_load_fpr32(ctx, fp32_1, ft);
9998 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9999 gen_store_fpr64(ctx, fp64, fd);
10000 }
10001 break;
10002 case OPC_CMP_F_S:
10003 case OPC_CMP_UN_S:
10004 case OPC_CMP_EQ_S:
10005 case OPC_CMP_UEQ_S:
10006 case OPC_CMP_OLT_S:
10007 case OPC_CMP_ULT_S:
10008 case OPC_CMP_OLE_S:
10009 case OPC_CMP_ULE_S:
10010 case OPC_CMP_SF_S:
10011 case OPC_CMP_NGLE_S:
10012 case OPC_CMP_SEQ_S:
10013 case OPC_CMP_NGL_S:
10014 case OPC_CMP_LT_S:
10015 case OPC_CMP_NGE_S:
10016 case OPC_CMP_LE_S:
10017 case OPC_CMP_NGT_S:
10018 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10019 if (ctx->opcode & (1 << 6)) {
10020 gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
10021 } else {
10022 gen_cmp_s(ctx, func - 48, ft, fs, cc);
10023 }
10024 break;
10025 case OPC_ADD_D:
10026 check_cp1_registers(ctx, fs | ft | fd);
10027 {
10028 TCGv_i64 fp0 = tcg_temp_new_i64();
10029 TCGv_i64 fp1 = tcg_temp_new_i64();
10030
10031 gen_load_fpr64(ctx, fp0, fs);
10032 gen_load_fpr64(ctx, fp1, ft);
10033 gen_helper_float_add_d(fp0, tcg_env, fp0, fp1);
10034 gen_store_fpr64(ctx, fp0, fd);
10035 }
10036 break;
10037 case OPC_SUB_D:
10038 check_cp1_registers(ctx, fs | ft | fd);
10039 {
10040 TCGv_i64 fp0 = tcg_temp_new_i64();
10041 TCGv_i64 fp1 = tcg_temp_new_i64();
10042
10043 gen_load_fpr64(ctx, fp0, fs);
10044 gen_load_fpr64(ctx, fp1, ft);
10045 gen_helper_float_sub_d(fp0, tcg_env, fp0, fp1);
10046 gen_store_fpr64(ctx, fp0, fd);
10047 }
10048 break;
10049 case OPC_MUL_D:
10050 check_cp1_registers(ctx, fs | ft | fd);
10051 {
10052 TCGv_i64 fp0 = tcg_temp_new_i64();
10053 TCGv_i64 fp1 = tcg_temp_new_i64();
10054
10055 gen_load_fpr64(ctx, fp0, fs);
10056 gen_load_fpr64(ctx, fp1, ft);
10057 gen_helper_float_mul_d(fp0, tcg_env, fp0, fp1);
10058 gen_store_fpr64(ctx, fp0, fd);
10059 }
10060 break;
10061 case OPC_DIV_D:
10062 check_cp1_registers(ctx, fs | ft | fd);
10063 {
10064 TCGv_i64 fp0 = tcg_temp_new_i64();
10065 TCGv_i64 fp1 = tcg_temp_new_i64();
10066
10067 gen_load_fpr64(ctx, fp0, fs);
10068 gen_load_fpr64(ctx, fp1, ft);
10069 gen_helper_float_div_d(fp0, tcg_env, fp0, fp1);
10070 gen_store_fpr64(ctx, fp0, fd);
10071 }
10072 break;
10073 case OPC_SQRT_D:
10074 check_cp1_registers(ctx, fs | fd);
10075 {
10076 TCGv_i64 fp0 = tcg_temp_new_i64();
10077
10078 gen_load_fpr64(ctx, fp0, fs);
10079 gen_helper_float_sqrt_d(fp0, tcg_env, fp0);
10080 gen_store_fpr64(ctx, fp0, fd);
10081 }
10082 break;
10083 case OPC_ABS_D:
10084 check_cp1_registers(ctx, fs | fd);
10085 {
10086 TCGv_i64 fp0 = tcg_temp_new_i64();
10087
10088 gen_load_fpr64(ctx, fp0, fs);
10089 if (ctx->abs2008) {
10090 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10091 } else {
10092 gen_helper_float_abs_d(fp0, fp0);
10093 }
10094 gen_store_fpr64(ctx, fp0, fd);
10095 }
10096 break;
10097 case OPC_MOV_D:
10098 check_cp1_registers(ctx, fs | fd);
10099 {
10100 TCGv_i64 fp0 = tcg_temp_new_i64();
10101
10102 gen_load_fpr64(ctx, fp0, fs);
10103 gen_store_fpr64(ctx, fp0, fd);
10104 }
10105 break;
10106 case OPC_NEG_D:
10107 check_cp1_registers(ctx, fs | fd);
10108 {
10109 TCGv_i64 fp0 = tcg_temp_new_i64();
10110
10111 gen_load_fpr64(ctx, fp0, fs);
10112 if (ctx->abs2008) {
10113 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10114 } else {
10115 gen_helper_float_chs_d(fp0, fp0);
10116 }
10117 gen_store_fpr64(ctx, fp0, fd);
10118 }
10119 break;
10120 case OPC_ROUND_L_D:
10121 check_cp1_64bitmode(ctx);
10122 {
10123 TCGv_i64 fp0 = tcg_temp_new_i64();
10124
10125 gen_load_fpr64(ctx, fp0, fs);
10126 if (ctx->nan2008) {
10127 gen_helper_float_round_2008_l_d(fp0, tcg_env, fp0);
10128 } else {
10129 gen_helper_float_round_l_d(fp0, tcg_env, fp0);
10130 }
10131 gen_store_fpr64(ctx, fp0, fd);
10132 }
10133 break;
10134 case OPC_TRUNC_L_D:
10135 check_cp1_64bitmode(ctx);
10136 {
10137 TCGv_i64 fp0 = tcg_temp_new_i64();
10138
10139 gen_load_fpr64(ctx, fp0, fs);
10140 if (ctx->nan2008) {
10141 gen_helper_float_trunc_2008_l_d(fp0, tcg_env, fp0);
10142 } else {
10143 gen_helper_float_trunc_l_d(fp0, tcg_env, fp0);
10144 }
10145 gen_store_fpr64(ctx, fp0, fd);
10146 }
10147 break;
10148 case OPC_CEIL_L_D:
10149 check_cp1_64bitmode(ctx);
10150 {
10151 TCGv_i64 fp0 = tcg_temp_new_i64();
10152
10153 gen_load_fpr64(ctx, fp0, fs);
10154 if (ctx->nan2008) {
10155 gen_helper_float_ceil_2008_l_d(fp0, tcg_env, fp0);
10156 } else {
10157 gen_helper_float_ceil_l_d(fp0, tcg_env, fp0);
10158 }
10159 gen_store_fpr64(ctx, fp0, fd);
10160 }
10161 break;
10162 case OPC_FLOOR_L_D:
10163 check_cp1_64bitmode(ctx);
10164 {
10165 TCGv_i64 fp0 = tcg_temp_new_i64();
10166
10167 gen_load_fpr64(ctx, fp0, fs);
10168 if (ctx->nan2008) {
10169 gen_helper_float_floor_2008_l_d(fp0, tcg_env, fp0);
10170 } else {
10171 gen_helper_float_floor_l_d(fp0, tcg_env, fp0);
10172 }
10173 gen_store_fpr64(ctx, fp0, fd);
10174 }
10175 break;
10176 case OPC_ROUND_W_D:
10177 check_cp1_registers(ctx, fs);
10178 {
10179 TCGv_i32 fp32 = tcg_temp_new_i32();
10180 TCGv_i64 fp64 = tcg_temp_new_i64();
10181
10182 gen_load_fpr64(ctx, fp64, fs);
10183 if (ctx->nan2008) {
10184 gen_helper_float_round_2008_w_d(fp32, tcg_env, fp64);
10185 } else {
10186 gen_helper_float_round_w_d(fp32, tcg_env, fp64);
10187 }
10188 gen_store_fpr32(ctx, fp32, fd);
10189 }
10190 break;
10191 case OPC_TRUNC_W_D:
10192 check_cp1_registers(ctx, fs);
10193 {
10194 TCGv_i32 fp32 = tcg_temp_new_i32();
10195 TCGv_i64 fp64 = tcg_temp_new_i64();
10196
10197 gen_load_fpr64(ctx, fp64, fs);
10198 if (ctx->nan2008) {
10199 gen_helper_float_trunc_2008_w_d(fp32, tcg_env, fp64);
10200 } else {
10201 gen_helper_float_trunc_w_d(fp32, tcg_env, fp64);
10202 }
10203 gen_store_fpr32(ctx, fp32, fd);
10204 }
10205 break;
10206 case OPC_CEIL_W_D:
10207 check_cp1_registers(ctx, fs);
10208 {
10209 TCGv_i32 fp32 = tcg_temp_new_i32();
10210 TCGv_i64 fp64 = tcg_temp_new_i64();
10211
10212 gen_load_fpr64(ctx, fp64, fs);
10213 if (ctx->nan2008) {
10214 gen_helper_float_ceil_2008_w_d(fp32, tcg_env, fp64);
10215 } else {
10216 gen_helper_float_ceil_w_d(fp32, tcg_env, fp64);
10217 }
10218 gen_store_fpr32(ctx, fp32, fd);
10219 }
10220 break;
10221 case OPC_FLOOR_W_D:
10222 check_cp1_registers(ctx, fs);
10223 {
10224 TCGv_i32 fp32 = tcg_temp_new_i32();
10225 TCGv_i64 fp64 = tcg_temp_new_i64();
10226
10227 gen_load_fpr64(ctx, fp64, fs);
10228 if (ctx->nan2008) {
10229 gen_helper_float_floor_2008_w_d(fp32, tcg_env, fp64);
10230 } else {
10231 gen_helper_float_floor_w_d(fp32, tcg_env, fp64);
10232 }
10233 gen_store_fpr32(ctx, fp32, fd);
10234 }
10235 break;
10236 case OPC_SEL_D:
10237 check_insn(ctx, ISA_MIPS_R6);
10238 gen_sel_d(ctx, op1, fd, ft, fs);
10239 break;
10240 case OPC_SELEQZ_D:
10241 check_insn(ctx, ISA_MIPS_R6);
10242 gen_sel_d(ctx, op1, fd, ft, fs);
10243 break;
10244 case OPC_SELNEZ_D:
10245 check_insn(ctx, ISA_MIPS_R6);
10246 gen_sel_d(ctx, op1, fd, ft, fs);
10247 break;
10248 case OPC_MOVCF_D:
10249 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10250 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10251 break;
10252 case OPC_MOVZ_D:
10253 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10254 {
10255 TCGLabel *l1 = gen_new_label();
10256 TCGv_i64 fp0;
10257
10258 if (ft != 0) {
10259 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10260 }
10261 fp0 = tcg_temp_new_i64();
10262 gen_load_fpr64(ctx, fp0, fs);
10263 gen_store_fpr64(ctx, fp0, fd);
10264 gen_set_label(l1);
10265 }
10266 break;
10267 case OPC_MOVN_D:
10268 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10269 {
10270 TCGLabel *l1 = gen_new_label();
10271 TCGv_i64 fp0;
10272
10273 if (ft != 0) {
10274 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10275 fp0 = tcg_temp_new_i64();
10276 gen_load_fpr64(ctx, fp0, fs);
10277 gen_store_fpr64(ctx, fp0, fd);
10278 gen_set_label(l1);
10279 }
10280 }
10281 break;
10282 case OPC_RECIP_D:
10283 check_cp1_registers(ctx, fs | fd);
10284 {
10285 TCGv_i64 fp0 = tcg_temp_new_i64();
10286
10287 gen_load_fpr64(ctx, fp0, fs);
10288 gen_helper_float_recip_d(fp0, tcg_env, fp0);
10289 gen_store_fpr64(ctx, fp0, fd);
10290 }
10291 break;
10292 case OPC_RSQRT_D:
10293 check_cp1_registers(ctx, fs | fd);
10294 {
10295 TCGv_i64 fp0 = tcg_temp_new_i64();
10296
10297 gen_load_fpr64(ctx, fp0, fs);
10298 gen_helper_float_rsqrt_d(fp0, tcg_env, fp0);
10299 gen_store_fpr64(ctx, fp0, fd);
10300 }
10301 break;
10302 case OPC_MADDF_D:
10303 check_insn(ctx, ISA_MIPS_R6);
10304 {
10305 TCGv_i64 fp0 = tcg_temp_new_i64();
10306 TCGv_i64 fp1 = tcg_temp_new_i64();
10307 TCGv_i64 fp2 = tcg_temp_new_i64();
10308 gen_load_fpr64(ctx, fp0, fs);
10309 gen_load_fpr64(ctx, fp1, ft);
10310 gen_load_fpr64(ctx, fp2, fd);
10311 gen_helper_float_maddf_d(fp2, tcg_env, fp0, fp1, fp2);
10312 gen_store_fpr64(ctx, fp2, fd);
10313 }
10314 break;
10315 case OPC_MSUBF_D:
10316 check_insn(ctx, ISA_MIPS_R6);
10317 {
10318 TCGv_i64 fp0 = tcg_temp_new_i64();
10319 TCGv_i64 fp1 = tcg_temp_new_i64();
10320 TCGv_i64 fp2 = tcg_temp_new_i64();
10321 gen_load_fpr64(ctx, fp0, fs);
10322 gen_load_fpr64(ctx, fp1, ft);
10323 gen_load_fpr64(ctx, fp2, fd);
10324 gen_helper_float_msubf_d(fp2, tcg_env, fp0, fp1, fp2);
10325 gen_store_fpr64(ctx, fp2, fd);
10326 }
10327 break;
10328 case OPC_RINT_D:
10329 check_insn(ctx, ISA_MIPS_R6);
10330 {
10331 TCGv_i64 fp0 = tcg_temp_new_i64();
10332 gen_load_fpr64(ctx, fp0, fs);
10333 gen_helper_float_rint_d(fp0, tcg_env, fp0);
10334 gen_store_fpr64(ctx, fp0, fd);
10335 }
10336 break;
10337 case OPC_CLASS_D:
10338 check_insn(ctx, ISA_MIPS_R6);
10339 {
10340 TCGv_i64 fp0 = tcg_temp_new_i64();
10341 gen_load_fpr64(ctx, fp0, fs);
10342 gen_helper_float_class_d(fp0, tcg_env, fp0);
10343 gen_store_fpr64(ctx, fp0, fd);
10344 }
10345 break;
10346 case OPC_MIN_D: /* OPC_RECIP2_D */
10347 if (ctx->insn_flags & ISA_MIPS_R6) {
10348 /* OPC_MIN_D */
10349 TCGv_i64 fp0 = tcg_temp_new_i64();
10350 TCGv_i64 fp1 = tcg_temp_new_i64();
10351 gen_load_fpr64(ctx, fp0, fs);
10352 gen_load_fpr64(ctx, fp1, ft);
10353 gen_helper_float_min_d(fp1, tcg_env, fp0, fp1);
10354 gen_store_fpr64(ctx, fp1, fd);
10355 } else {
10356 /* OPC_RECIP2_D */
10357 check_cp1_64bitmode(ctx);
10358 {
10359 TCGv_i64 fp0 = tcg_temp_new_i64();
10360 TCGv_i64 fp1 = tcg_temp_new_i64();
10361
10362 gen_load_fpr64(ctx, fp0, fs);
10363 gen_load_fpr64(ctx, fp1, ft);
10364 gen_helper_float_recip2_d(fp0, tcg_env, fp0, fp1);
10365 gen_store_fpr64(ctx, fp0, fd);
10366 }
10367 }
10368 break;
10369 case OPC_MINA_D: /* OPC_RECIP1_D */
10370 if (ctx->insn_flags & ISA_MIPS_R6) {
10371 /* OPC_MINA_D */
10372 TCGv_i64 fp0 = tcg_temp_new_i64();
10373 TCGv_i64 fp1 = tcg_temp_new_i64();
10374 gen_load_fpr64(ctx, fp0, fs);
10375 gen_load_fpr64(ctx, fp1, ft);
10376 gen_helper_float_mina_d(fp1, tcg_env, fp0, fp1);
10377 gen_store_fpr64(ctx, fp1, fd);
10378 } else {
10379 /* OPC_RECIP1_D */
10380 check_cp1_64bitmode(ctx);
10381 {
10382 TCGv_i64 fp0 = tcg_temp_new_i64();
10383
10384 gen_load_fpr64(ctx, fp0, fs);
10385 gen_helper_float_recip1_d(fp0, tcg_env, fp0);
10386 gen_store_fpr64(ctx, fp0, fd);
10387 }
10388 }
10389 break;
10390 case OPC_MAX_D: /* OPC_RSQRT1_D */
10391 if (ctx->insn_flags & ISA_MIPS_R6) {
10392 /* OPC_MAX_D */
10393 TCGv_i64 fp0 = tcg_temp_new_i64();
10394 TCGv_i64 fp1 = tcg_temp_new_i64();
10395 gen_load_fpr64(ctx, fp0, fs);
10396 gen_load_fpr64(ctx, fp1, ft);
10397 gen_helper_float_max_d(fp1, tcg_env, fp0, fp1);
10398 gen_store_fpr64(ctx, fp1, fd);
10399 } else {
10400 /* OPC_RSQRT1_D */
10401 check_cp1_64bitmode(ctx);
10402 {
10403 TCGv_i64 fp0 = tcg_temp_new_i64();
10404
10405 gen_load_fpr64(ctx, fp0, fs);
10406 gen_helper_float_rsqrt1_d(fp0, tcg_env, fp0);
10407 gen_store_fpr64(ctx, fp0, fd);
10408 }
10409 }
10410 break;
10411 case OPC_MAXA_D: /* OPC_RSQRT2_D */
10412 if (ctx->insn_flags & ISA_MIPS_R6) {
10413 /* OPC_MAXA_D */
10414 TCGv_i64 fp0 = tcg_temp_new_i64();
10415 TCGv_i64 fp1 = tcg_temp_new_i64();
10416 gen_load_fpr64(ctx, fp0, fs);
10417 gen_load_fpr64(ctx, fp1, ft);
10418 gen_helper_float_maxa_d(fp1, tcg_env, fp0, fp1);
10419 gen_store_fpr64(ctx, fp1, fd);
10420 } else {
10421 /* OPC_RSQRT2_D */
10422 check_cp1_64bitmode(ctx);
10423 {
10424 TCGv_i64 fp0 = tcg_temp_new_i64();
10425 TCGv_i64 fp1 = tcg_temp_new_i64();
10426
10427 gen_load_fpr64(ctx, fp0, fs);
10428 gen_load_fpr64(ctx, fp1, ft);
10429 gen_helper_float_rsqrt2_d(fp0, tcg_env, fp0, fp1);
10430 gen_store_fpr64(ctx, fp0, fd);
10431 }
10432 }
10433 break;
10434 case OPC_CMP_F_D:
10435 case OPC_CMP_UN_D:
10436 case OPC_CMP_EQ_D:
10437 case OPC_CMP_UEQ_D:
10438 case OPC_CMP_OLT_D:
10439 case OPC_CMP_ULT_D:
10440 case OPC_CMP_OLE_D:
10441 case OPC_CMP_ULE_D:
10442 case OPC_CMP_SF_D:
10443 case OPC_CMP_NGLE_D:
10444 case OPC_CMP_SEQ_D:
10445 case OPC_CMP_NGL_D:
10446 case OPC_CMP_LT_D:
10447 case OPC_CMP_NGE_D:
10448 case OPC_CMP_LE_D:
10449 case OPC_CMP_NGT_D:
10450 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10451 if (ctx->opcode & (1 << 6)) {
10452 gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10453 } else {
10454 gen_cmp_d(ctx, func - 48, ft, fs, cc);
10455 }
10456 break;
10457 case OPC_CVT_S_D:
10458 check_cp1_registers(ctx, fs);
10459 {
10460 TCGv_i32 fp32 = tcg_temp_new_i32();
10461 TCGv_i64 fp64 = tcg_temp_new_i64();
10462
10463 gen_load_fpr64(ctx, fp64, fs);
10464 gen_helper_float_cvts_d(fp32, tcg_env, fp64);
10465 gen_store_fpr32(ctx, fp32, fd);
10466 }
10467 break;
10468 case OPC_CVT_W_D:
10469 check_cp1_registers(ctx, fs);
10470 {
10471 TCGv_i32 fp32 = tcg_temp_new_i32();
10472 TCGv_i64 fp64 = tcg_temp_new_i64();
10473
10474 gen_load_fpr64(ctx, fp64, fs);
10475 if (ctx->nan2008) {
10476 gen_helper_float_cvt_2008_w_d(fp32, tcg_env, fp64);
10477 } else {
10478 gen_helper_float_cvt_w_d(fp32, tcg_env, fp64);
10479 }
10480 gen_store_fpr32(ctx, fp32, fd);
10481 }
10482 break;
10483 case OPC_CVT_L_D:
10484 check_cp1_64bitmode(ctx);
10485 {
10486 TCGv_i64 fp0 = tcg_temp_new_i64();
10487
10488 gen_load_fpr64(ctx, fp0, fs);
10489 if (ctx->nan2008) {
10490 gen_helper_float_cvt_2008_l_d(fp0, tcg_env, fp0);
10491 } else {
10492 gen_helper_float_cvt_l_d(fp0, tcg_env, fp0);
10493 }
10494 gen_store_fpr64(ctx, fp0, fd);
10495 }
10496 break;
10497 case OPC_CVT_S_W:
10498 {
10499 TCGv_i32 fp0 = tcg_temp_new_i32();
10500
10501 gen_load_fpr32(ctx, fp0, fs);
10502 gen_helper_float_cvts_w(fp0, tcg_env, fp0);
10503 gen_store_fpr32(ctx, fp0, fd);
10504 }
10505 break;
10506 case OPC_CVT_D_W:
10507 check_cp1_registers(ctx, fd);
10508 {
10509 TCGv_i32 fp32 = tcg_temp_new_i32();
10510 TCGv_i64 fp64 = tcg_temp_new_i64();
10511
10512 gen_load_fpr32(ctx, fp32, fs);
10513 gen_helper_float_cvtd_w(fp64, tcg_env, fp32);
10514 gen_store_fpr64(ctx, fp64, fd);
10515 }
10516 break;
10517 case OPC_CVT_S_L:
10518 check_cp1_64bitmode(ctx);
10519 {
10520 TCGv_i32 fp32 = tcg_temp_new_i32();
10521 TCGv_i64 fp64 = tcg_temp_new_i64();
10522
10523 gen_load_fpr64(ctx, fp64, fs);
10524 gen_helper_float_cvts_l(fp32, tcg_env, fp64);
10525 gen_store_fpr32(ctx, fp32, fd);
10526 }
10527 break;
10528 case OPC_CVT_D_L:
10529 check_cp1_64bitmode(ctx);
10530 {
10531 TCGv_i64 fp0 = tcg_temp_new_i64();
10532
10533 gen_load_fpr64(ctx, fp0, fs);
10534 gen_helper_float_cvtd_l(fp0, tcg_env, fp0);
10535 gen_store_fpr64(ctx, fp0, fd);
10536 }
10537 break;
10538 case OPC_CVT_PS_PW:
10539 check_ps(ctx);
10540 {
10541 TCGv_i64 fp0 = tcg_temp_new_i64();
10542
10543 gen_load_fpr64(ctx, fp0, fs);
10544 gen_helper_float_cvtps_pw(fp0, tcg_env, fp0);
10545 gen_store_fpr64(ctx, fp0, fd);
10546 }
10547 break;
10548 case OPC_ADD_PS:
10549 check_ps(ctx);
10550 {
10551 TCGv_i64 fp0 = tcg_temp_new_i64();
10552 TCGv_i64 fp1 = tcg_temp_new_i64();
10553
10554 gen_load_fpr64(ctx, fp0, fs);
10555 gen_load_fpr64(ctx, fp1, ft);
10556 gen_helper_float_add_ps(fp0, tcg_env, fp0, fp1);
10557 gen_store_fpr64(ctx, fp0, fd);
10558 }
10559 break;
10560 case OPC_SUB_PS:
10561 check_ps(ctx);
10562 {
10563 TCGv_i64 fp0 = tcg_temp_new_i64();
10564 TCGv_i64 fp1 = tcg_temp_new_i64();
10565
10566 gen_load_fpr64(ctx, fp0, fs);
10567 gen_load_fpr64(ctx, fp1, ft);
10568 gen_helper_float_sub_ps(fp0, tcg_env, fp0, fp1);
10569 gen_store_fpr64(ctx, fp0, fd);
10570 }
10571 break;
10572 case OPC_MUL_PS:
10573 check_ps(ctx);
10574 {
10575 TCGv_i64 fp0 = tcg_temp_new_i64();
10576 TCGv_i64 fp1 = tcg_temp_new_i64();
10577
10578 gen_load_fpr64(ctx, fp0, fs);
10579 gen_load_fpr64(ctx, fp1, ft);
10580 gen_helper_float_mul_ps(fp0, tcg_env, fp0, fp1);
10581 gen_store_fpr64(ctx, fp0, fd);
10582 }
10583 break;
10584 case OPC_ABS_PS:
10585 check_ps(ctx);
10586 {
10587 TCGv_i64 fp0 = tcg_temp_new_i64();
10588
10589 gen_load_fpr64(ctx, fp0, fs);
10590 gen_helper_float_abs_ps(fp0, fp0);
10591 gen_store_fpr64(ctx, fp0, fd);
10592 }
10593 break;
10594 case OPC_MOV_PS:
10595 check_ps(ctx);
10596 {
10597 TCGv_i64 fp0 = tcg_temp_new_i64();
10598
10599 gen_load_fpr64(ctx, fp0, fs);
10600 gen_store_fpr64(ctx, fp0, fd);
10601 }
10602 break;
10603 case OPC_NEG_PS:
10604 check_ps(ctx);
10605 {
10606 TCGv_i64 fp0 = tcg_temp_new_i64();
10607
10608 gen_load_fpr64(ctx, fp0, fs);
10609 gen_helper_float_chs_ps(fp0, fp0);
10610 gen_store_fpr64(ctx, fp0, fd);
10611 }
10612 break;
10613 case OPC_MOVCF_PS:
10614 check_ps(ctx);
10615 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10616 break;
10617 case OPC_MOVZ_PS:
10618 check_ps(ctx);
10619 {
10620 TCGLabel *l1 = gen_new_label();
10621 TCGv_i64 fp0;
10622
10623 if (ft != 0) {
10624 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10625 }
10626 fp0 = tcg_temp_new_i64();
10627 gen_load_fpr64(ctx, fp0, fs);
10628 gen_store_fpr64(ctx, fp0, fd);
10629 gen_set_label(l1);
10630 }
10631 break;
10632 case OPC_MOVN_PS:
10633 check_ps(ctx);
10634 {
10635 TCGLabel *l1 = gen_new_label();
10636 TCGv_i64 fp0;
10637
10638 if (ft != 0) {
10639 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10640 fp0 = tcg_temp_new_i64();
10641 gen_load_fpr64(ctx, fp0, fs);
10642 gen_store_fpr64(ctx, fp0, fd);
10643 gen_set_label(l1);
10644 }
10645 }
10646 break;
10647 case OPC_ADDR_PS:
10648 check_ps(ctx);
10649 {
10650 TCGv_i64 fp0 = tcg_temp_new_i64();
10651 TCGv_i64 fp1 = tcg_temp_new_i64();
10652
10653 gen_load_fpr64(ctx, fp0, ft);
10654 gen_load_fpr64(ctx, fp1, fs);
10655 gen_helper_float_addr_ps(fp0, tcg_env, fp0, fp1);
10656 gen_store_fpr64(ctx, fp0, fd);
10657 }
10658 break;
10659 case OPC_MULR_PS:
10660 check_ps(ctx);
10661 {
10662 TCGv_i64 fp0 = tcg_temp_new_i64();
10663 TCGv_i64 fp1 = tcg_temp_new_i64();
10664
10665 gen_load_fpr64(ctx, fp0, ft);
10666 gen_load_fpr64(ctx, fp1, fs);
10667 gen_helper_float_mulr_ps(fp0, tcg_env, fp0, fp1);
10668 gen_store_fpr64(ctx, fp0, fd);
10669 }
10670 break;
10671 case OPC_RECIP2_PS:
10672 check_ps(ctx);
10673 {
10674 TCGv_i64 fp0 = tcg_temp_new_i64();
10675 TCGv_i64 fp1 = tcg_temp_new_i64();
10676
10677 gen_load_fpr64(ctx, fp0, fs);
10678 gen_load_fpr64(ctx, fp1, ft);
10679 gen_helper_float_recip2_ps(fp0, tcg_env, fp0, fp1);
10680 gen_store_fpr64(ctx, fp0, fd);
10681 }
10682 break;
10683 case OPC_RECIP1_PS:
10684 check_ps(ctx);
10685 {
10686 TCGv_i64 fp0 = tcg_temp_new_i64();
10687
10688 gen_load_fpr64(ctx, fp0, fs);
10689 gen_helper_float_recip1_ps(fp0, tcg_env, fp0);
10690 gen_store_fpr64(ctx, fp0, fd);
10691 }
10692 break;
10693 case OPC_RSQRT1_PS:
10694 check_ps(ctx);
10695 {
10696 TCGv_i64 fp0 = tcg_temp_new_i64();
10697
10698 gen_load_fpr64(ctx, fp0, fs);
10699 gen_helper_float_rsqrt1_ps(fp0, tcg_env, fp0);
10700 gen_store_fpr64(ctx, fp0, fd);
10701 }
10702 break;
10703 case OPC_RSQRT2_PS:
10704 check_ps(ctx);
10705 {
10706 TCGv_i64 fp0 = tcg_temp_new_i64();
10707 TCGv_i64 fp1 = tcg_temp_new_i64();
10708
10709 gen_load_fpr64(ctx, fp0, fs);
10710 gen_load_fpr64(ctx, fp1, ft);
10711 gen_helper_float_rsqrt2_ps(fp0, tcg_env, fp0, fp1);
10712 gen_store_fpr64(ctx, fp0, fd);
10713 }
10714 break;
10715 case OPC_CVT_S_PU:
10716 check_cp1_64bitmode(ctx);
10717 {
10718 TCGv_i32 fp0 = tcg_temp_new_i32();
10719
10720 gen_load_fpr32h(ctx, fp0, fs);
10721 gen_helper_float_cvts_pu(fp0, tcg_env, fp0);
10722 gen_store_fpr32(ctx, fp0, fd);
10723 }
10724 break;
10725 case OPC_CVT_PW_PS:
10726 check_ps(ctx);
10727 {
10728 TCGv_i64 fp0 = tcg_temp_new_i64();
10729
10730 gen_load_fpr64(ctx, fp0, fs);
10731 gen_helper_float_cvtpw_ps(fp0, tcg_env, fp0);
10732 gen_store_fpr64(ctx, fp0, fd);
10733 }
10734 break;
10735 case OPC_CVT_S_PL:
10736 check_cp1_64bitmode(ctx);
10737 {
10738 TCGv_i32 fp0 = tcg_temp_new_i32();
10739
10740 gen_load_fpr32(ctx, fp0, fs);
10741 gen_helper_float_cvts_pl(fp0, tcg_env, fp0);
10742 gen_store_fpr32(ctx, fp0, fd);
10743 }
10744 break;
10745 case OPC_PLL_PS:
10746 check_ps(ctx);
10747 {
10748 TCGv_i32 fp0 = tcg_temp_new_i32();
10749 TCGv_i32 fp1 = tcg_temp_new_i32();
10750
10751 gen_load_fpr32(ctx, fp0, fs);
10752 gen_load_fpr32(ctx, fp1, ft);
10753 gen_store_fpr32h(ctx, fp0, fd);
10754 gen_store_fpr32(ctx, fp1, fd);
10755 }
10756 break;
10757 case OPC_PLU_PS:
10758 check_ps(ctx);
10759 {
10760 TCGv_i32 fp0 = tcg_temp_new_i32();
10761 TCGv_i32 fp1 = tcg_temp_new_i32();
10762
10763 gen_load_fpr32(ctx, fp0, fs);
10764 gen_load_fpr32h(ctx, fp1, ft);
10765 gen_store_fpr32(ctx, fp1, fd);
10766 gen_store_fpr32h(ctx, fp0, fd);
10767 }
10768 break;
10769 case OPC_PUL_PS:
10770 check_ps(ctx);
10771 {
10772 TCGv_i32 fp0 = tcg_temp_new_i32();
10773 TCGv_i32 fp1 = tcg_temp_new_i32();
10774
10775 gen_load_fpr32h(ctx, fp0, fs);
10776 gen_load_fpr32(ctx, fp1, ft);
10777 gen_store_fpr32(ctx, fp1, fd);
10778 gen_store_fpr32h(ctx, fp0, fd);
10779 }
10780 break;
10781 case OPC_PUU_PS:
10782 check_ps(ctx);
10783 {
10784 TCGv_i32 fp0 = tcg_temp_new_i32();
10785 TCGv_i32 fp1 = tcg_temp_new_i32();
10786
10787 gen_load_fpr32h(ctx, fp0, fs);
10788 gen_load_fpr32h(ctx, fp1, ft);
10789 gen_store_fpr32(ctx, fp1, fd);
10790 gen_store_fpr32h(ctx, fp0, fd);
10791 }
10792 break;
10793 case OPC_CMP_F_PS:
10794 case OPC_CMP_UN_PS:
10795 case OPC_CMP_EQ_PS:
10796 case OPC_CMP_UEQ_PS:
10797 case OPC_CMP_OLT_PS:
10798 case OPC_CMP_ULT_PS:
10799 case OPC_CMP_OLE_PS:
10800 case OPC_CMP_ULE_PS:
10801 case OPC_CMP_SF_PS:
10802 case OPC_CMP_NGLE_PS:
10803 case OPC_CMP_SEQ_PS:
10804 case OPC_CMP_NGL_PS:
10805 case OPC_CMP_LT_PS:
10806 case OPC_CMP_NGE_PS:
10807 case OPC_CMP_LE_PS:
10808 case OPC_CMP_NGT_PS:
10809 if (ctx->opcode & (1 << 6)) {
10810 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
10811 } else {
10812 gen_cmp_ps(ctx, func - 48, ft, fs, cc);
10813 }
10814 break;
10815 default:
10816 MIPS_INVAL("farith");
10817 gen_reserved_instruction(ctx);
10818 return;
10819 }
10820 }
10821
10822 /* Coprocessor 3 (FPU) */
10823 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
10824 int fd, int fs, int base, int index)
10825 {
10826 TCGv t0 = tcg_temp_new();
10827
10828 if (base == 0) {
10829 gen_load_gpr(t0, index);
10830 } else if (index == 0) {
10831 gen_load_gpr(t0, base);
10832 } else {
10833 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10834 }
10835 /*
10836 * Don't do NOP if destination is zero: we must perform the actual
10837 * memory access.
10838 */
10839 switch (opc) {
10840 case OPC_LWXC1:
10841 check_cop1x(ctx);
10842 {
10843 TCGv_i32 fp0 = tcg_temp_new_i32();
10844
10845 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10846 tcg_gen_trunc_tl_i32(fp0, t0);
10847 gen_store_fpr32(ctx, fp0, fd);
10848 }
10849 break;
10850 case OPC_LDXC1:
10851 check_cop1x(ctx);
10852 check_cp1_registers(ctx, fd);
10853 {
10854 TCGv_i64 fp0 = tcg_temp_new_i64();
10855 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10856 gen_store_fpr64(ctx, fp0, fd);
10857 }
10858 break;
10859 case OPC_LUXC1:
10860 check_cp1_64bitmode(ctx);
10861 tcg_gen_andi_tl(t0, t0, ~0x7);
10862 {
10863 TCGv_i64 fp0 = tcg_temp_new_i64();
10864
10865 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10866 gen_store_fpr64(ctx, fp0, fd);
10867 }
10868 break;
10869 case OPC_SWXC1:
10870 check_cop1x(ctx);
10871 {
10872 TCGv_i32 fp0 = tcg_temp_new_i32();
10873 gen_load_fpr32(ctx, fp0, fs);
10874 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10875 }
10876 break;
10877 case OPC_SDXC1:
10878 check_cop1x(ctx);
10879 check_cp1_registers(ctx, fs);
10880 {
10881 TCGv_i64 fp0 = tcg_temp_new_i64();
10882 gen_load_fpr64(ctx, fp0, fs);
10883 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10884 }
10885 break;
10886 case OPC_SUXC1:
10887 check_cp1_64bitmode(ctx);
10888 tcg_gen_andi_tl(t0, t0, ~0x7);
10889 {
10890 TCGv_i64 fp0 = tcg_temp_new_i64();
10891 gen_load_fpr64(ctx, fp0, fs);
10892 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
10893 }
10894 break;
10895 }
10896 }
10897
10898 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
10899 int fd, int fr, int fs, int ft)
10900 {
10901 switch (opc) {
10902 case OPC_ALNV_PS:
10903 check_ps(ctx);
10904 {
10905 TCGv t0 = tcg_temp_new();
10906 TCGv_i32 fp = tcg_temp_new_i32();
10907 TCGv_i32 fph = tcg_temp_new_i32();
10908 TCGLabel *l1 = gen_new_label();
10909 TCGLabel *l2 = gen_new_label();
10910
10911 gen_load_gpr(t0, fr);
10912 tcg_gen_andi_tl(t0, t0, 0x7);
10913
10914 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10915 gen_load_fpr32(ctx, fp, fs);
10916 gen_load_fpr32h(ctx, fph, fs);
10917 gen_store_fpr32(ctx, fp, fd);
10918 gen_store_fpr32h(ctx, fph, fd);
10919 tcg_gen_br(l2);
10920 gen_set_label(l1);
10921 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10922 if (cpu_is_bigendian(ctx)) {
10923 gen_load_fpr32(ctx, fp, fs);
10924 gen_load_fpr32h(ctx, fph, ft);
10925 gen_store_fpr32h(ctx, fp, fd);
10926 gen_store_fpr32(ctx, fph, fd);
10927 } else {
10928 gen_load_fpr32h(ctx, fph, fs);
10929 gen_load_fpr32(ctx, fp, ft);
10930 gen_store_fpr32(ctx, fph, fd);
10931 gen_store_fpr32h(ctx, fp, fd);
10932 }
10933 gen_set_label(l2);
10934 }
10935 break;
10936 case OPC_MADD_S:
10937 check_cop1x(ctx);
10938 {
10939 TCGv_i32 fp0 = tcg_temp_new_i32();
10940 TCGv_i32 fp1 = tcg_temp_new_i32();
10941 TCGv_i32 fp2 = tcg_temp_new_i32();
10942
10943 gen_load_fpr32(ctx, fp0, fs);
10944 gen_load_fpr32(ctx, fp1, ft);
10945 gen_load_fpr32(ctx, fp2, fr);
10946 gen_helper_float_madd_s(fp2, tcg_env, fp0, fp1, fp2);
10947 gen_store_fpr32(ctx, fp2, fd);
10948 }
10949 break;
10950 case OPC_MADD_D:
10951 check_cop1x(ctx);
10952 check_cp1_registers(ctx, fd | fs | ft | fr);
10953 {
10954 TCGv_i64 fp0 = tcg_temp_new_i64();
10955 TCGv_i64 fp1 = tcg_temp_new_i64();
10956 TCGv_i64 fp2 = tcg_temp_new_i64();
10957
10958 gen_load_fpr64(ctx, fp0, fs);
10959 gen_load_fpr64(ctx, fp1, ft);
10960 gen_load_fpr64(ctx, fp2, fr);
10961 gen_helper_float_madd_d(fp2, tcg_env, fp0, fp1, fp2);
10962 gen_store_fpr64(ctx, fp2, fd);
10963 }
10964 break;
10965 case OPC_MADD_PS:
10966 check_ps(ctx);
10967 {
10968 TCGv_i64 fp0 = tcg_temp_new_i64();
10969 TCGv_i64 fp1 = tcg_temp_new_i64();
10970 TCGv_i64 fp2 = tcg_temp_new_i64();
10971
10972 gen_load_fpr64(ctx, fp0, fs);
10973 gen_load_fpr64(ctx, fp1, ft);
10974 gen_load_fpr64(ctx, fp2, fr);
10975 gen_helper_float_madd_ps(fp2, tcg_env, fp0, fp1, fp2);
10976 gen_store_fpr64(ctx, fp2, fd);
10977 }
10978 break;
10979 case OPC_MSUB_S:
10980 check_cop1x(ctx);
10981 {
10982 TCGv_i32 fp0 = tcg_temp_new_i32();
10983 TCGv_i32 fp1 = tcg_temp_new_i32();
10984 TCGv_i32 fp2 = tcg_temp_new_i32();
10985
10986 gen_load_fpr32(ctx, fp0, fs);
10987 gen_load_fpr32(ctx, fp1, ft);
10988 gen_load_fpr32(ctx, fp2, fr);
10989 gen_helper_float_msub_s(fp2, tcg_env, fp0, fp1, fp2);
10990 gen_store_fpr32(ctx, fp2, fd);
10991 }
10992 break;
10993 case OPC_MSUB_D:
10994 check_cop1x(ctx);
10995 check_cp1_registers(ctx, fd | fs | ft | fr);
10996 {
10997 TCGv_i64 fp0 = tcg_temp_new_i64();
10998 TCGv_i64 fp1 = tcg_temp_new_i64();
10999 TCGv_i64 fp2 = tcg_temp_new_i64();
11000
11001 gen_load_fpr64(ctx, fp0, fs);
11002 gen_load_fpr64(ctx, fp1, ft);
11003 gen_load_fpr64(ctx, fp2, fr);
11004 gen_helper_float_msub_d(fp2, tcg_env, fp0, fp1, fp2);
11005 gen_store_fpr64(ctx, fp2, fd);
11006 }
11007 break;
11008 case OPC_MSUB_PS:
11009 check_ps(ctx);
11010 {
11011 TCGv_i64 fp0 = tcg_temp_new_i64();
11012 TCGv_i64 fp1 = tcg_temp_new_i64();
11013 TCGv_i64 fp2 = tcg_temp_new_i64();
11014
11015 gen_load_fpr64(ctx, fp0, fs);
11016 gen_load_fpr64(ctx, fp1, ft);
11017 gen_load_fpr64(ctx, fp2, fr);
11018 gen_helper_float_msub_ps(fp2, tcg_env, fp0, fp1, fp2);
11019 gen_store_fpr64(ctx, fp2, fd);
11020 }
11021 break;
11022 case OPC_NMADD_S:
11023 check_cop1x(ctx);
11024 {
11025 TCGv_i32 fp0 = tcg_temp_new_i32();
11026 TCGv_i32 fp1 = tcg_temp_new_i32();
11027 TCGv_i32 fp2 = tcg_temp_new_i32();
11028
11029 gen_load_fpr32(ctx, fp0, fs);
11030 gen_load_fpr32(ctx, fp1, ft);
11031 gen_load_fpr32(ctx, fp2, fr);
11032 gen_helper_float_nmadd_s(fp2, tcg_env, fp0, fp1, fp2);
11033 gen_store_fpr32(ctx, fp2, fd);
11034 }
11035 break;
11036 case OPC_NMADD_D:
11037 check_cop1x(ctx);
11038 check_cp1_registers(ctx, fd | fs | ft | fr);
11039 {
11040 TCGv_i64 fp0 = tcg_temp_new_i64();
11041 TCGv_i64 fp1 = tcg_temp_new_i64();
11042 TCGv_i64 fp2 = tcg_temp_new_i64();
11043
11044 gen_load_fpr64(ctx, fp0, fs);
11045 gen_load_fpr64(ctx, fp1, ft);
11046 gen_load_fpr64(ctx, fp2, fr);
11047 gen_helper_float_nmadd_d(fp2, tcg_env, fp0, fp1, fp2);
11048 gen_store_fpr64(ctx, fp2, fd);
11049 }
11050 break;
11051 case OPC_NMADD_PS:
11052 check_ps(ctx);
11053 {
11054 TCGv_i64 fp0 = tcg_temp_new_i64();
11055 TCGv_i64 fp1 = tcg_temp_new_i64();
11056 TCGv_i64 fp2 = tcg_temp_new_i64();
11057
11058 gen_load_fpr64(ctx, fp0, fs);
11059 gen_load_fpr64(ctx, fp1, ft);
11060 gen_load_fpr64(ctx, fp2, fr);
11061 gen_helper_float_nmadd_ps(fp2, tcg_env, fp0, fp1, fp2);
11062 gen_store_fpr64(ctx, fp2, fd);
11063 }
11064 break;
11065 case OPC_NMSUB_S:
11066 check_cop1x(ctx);
11067 {
11068 TCGv_i32 fp0 = tcg_temp_new_i32();
11069 TCGv_i32 fp1 = tcg_temp_new_i32();
11070 TCGv_i32 fp2 = tcg_temp_new_i32();
11071
11072 gen_load_fpr32(ctx, fp0, fs);
11073 gen_load_fpr32(ctx, fp1, ft);
11074 gen_load_fpr32(ctx, fp2, fr);
11075 gen_helper_float_nmsub_s(fp2, tcg_env, fp0, fp1, fp2);
11076 gen_store_fpr32(ctx, fp2, fd);
11077 }
11078 break;
11079 case OPC_NMSUB_D:
11080 check_cop1x(ctx);
11081 check_cp1_registers(ctx, fd | fs | ft | fr);
11082 {
11083 TCGv_i64 fp0 = tcg_temp_new_i64();
11084 TCGv_i64 fp1 = tcg_temp_new_i64();
11085 TCGv_i64 fp2 = tcg_temp_new_i64();
11086
11087 gen_load_fpr64(ctx, fp0, fs);
11088 gen_load_fpr64(ctx, fp1, ft);
11089 gen_load_fpr64(ctx, fp2, fr);
11090 gen_helper_float_nmsub_d(fp2, tcg_env, fp0, fp1, fp2);
11091 gen_store_fpr64(ctx, fp2, fd);
11092 }
11093 break;
11094 case OPC_NMSUB_PS:
11095 check_ps(ctx);
11096 {
11097 TCGv_i64 fp0 = tcg_temp_new_i64();
11098 TCGv_i64 fp1 = tcg_temp_new_i64();
11099 TCGv_i64 fp2 = tcg_temp_new_i64();
11100
11101 gen_load_fpr64(ctx, fp0, fs);
11102 gen_load_fpr64(ctx, fp1, ft);
11103 gen_load_fpr64(ctx, fp2, fr);
11104 gen_helper_float_nmsub_ps(fp2, tcg_env, fp0, fp1, fp2);
11105 gen_store_fpr64(ctx, fp2, fd);
11106 }
11107 break;
11108 default:
11109 MIPS_INVAL("flt3_arith");
11110 gen_reserved_instruction(ctx);
11111 return;
11112 }
11113 }
11114
11115 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11116 {
11117 TCGv t0;
11118
11119 #if !defined(CONFIG_USER_ONLY)
11120 /*
11121 * The Linux kernel will emulate rdhwr if it's not supported natively.
11122 * Therefore only check the ISA in system mode.
11123 */
11124 check_insn(ctx, ISA_MIPS_R2);
11125 #endif
11126 t0 = tcg_temp_new();
11127
11128 switch (rd) {
11129 case 0:
11130 gen_helper_rdhwr_cpunum(t0, tcg_env);
11131 gen_store_gpr(t0, rt);
11132 break;
11133 case 1:
11134 gen_helper_rdhwr_synci_step(t0, tcg_env);
11135 gen_store_gpr(t0, rt);
11136 break;
11137 case 2:
11138 translator_io_start(&ctx->base);
11139 gen_helper_rdhwr_cc(t0, tcg_env);
11140 gen_store_gpr(t0, rt);
11141 /*
11142 * Break the TB to be able to take timer interrupts immediately
11143 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
11144 * we break completely out of translated code.
11145 */
11146 gen_save_pc(ctx->base.pc_next + 4);
11147 ctx->base.is_jmp = DISAS_EXIT;
11148 break;
11149 case 3:
11150 gen_helper_rdhwr_ccres(t0, tcg_env);
11151 gen_store_gpr(t0, rt);
11152 break;
11153 case 4:
11154 check_insn(ctx, ISA_MIPS_R6);
11155 if (sel != 0) {
11156 /*
11157 * Performance counter registers are not implemented other than
11158 * control register 0.
11159 */
11160 generate_exception(ctx, EXCP_RI);
11161 }
11162 gen_helper_rdhwr_performance(t0, tcg_env);
11163 gen_store_gpr(t0, rt);
11164 break;
11165 case 5:
11166 check_insn(ctx, ISA_MIPS_R6);
11167 gen_helper_rdhwr_xnp(t0, tcg_env);
11168 gen_store_gpr(t0, rt);
11169 break;
11170 case 29:
11171 #if defined(CONFIG_USER_ONLY)
11172 tcg_gen_ld_tl(t0, tcg_env,
11173 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11174 gen_store_gpr(t0, rt);
11175 break;
11176 #else
11177 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11178 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11179 tcg_gen_ld_tl(t0, tcg_env,
11180 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11181 gen_store_gpr(t0, rt);
11182 } else {
11183 gen_reserved_instruction(ctx);
11184 }
11185 break;
11186 #endif
11187 default: /* Invalid */
11188 MIPS_INVAL("rdhwr");
11189 gen_reserved_instruction(ctx);
11190 break;
11191 }
11192 }
11193
11194 static inline void clear_branch_hflags(DisasContext *ctx)
11195 {
11196 ctx->hflags &= ~MIPS_HFLAG_BMASK;
11197 if (ctx->base.is_jmp == DISAS_NEXT) {
11198 save_cpu_state(ctx, 0);
11199 } else {
11200 /*
11201 * It is not safe to save ctx->hflags as hflags may be changed
11202 * in execution time by the instruction in delay / forbidden slot.
11203 */
11204 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11205 }
11206 }
11207
11208 static void gen_branch(DisasContext *ctx, int insn_bytes)
11209 {
11210 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11211 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11212 /* Branches completion */
11213 clear_branch_hflags(ctx);
11214 ctx->base.is_jmp = DISAS_NORETURN;
11215 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11216 case MIPS_HFLAG_FBNSLOT:
11217 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11218 break;
11219 case MIPS_HFLAG_B:
11220 /* unconditional branch */
11221 if (proc_hflags & MIPS_HFLAG_BX) {
11222 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11223 }
11224 gen_goto_tb(ctx, 0, ctx->btarget);
11225 break;
11226 case MIPS_HFLAG_BL:
11227 /* blikely taken case */
11228 gen_goto_tb(ctx, 0, ctx->btarget);
11229 break;
11230 case MIPS_HFLAG_BC:
11231 /* Conditional branch */
11232 {
11233 TCGLabel *l1 = gen_new_label();
11234
11235 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11236 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11237 gen_set_label(l1);
11238 gen_goto_tb(ctx, 0, ctx->btarget);
11239 }
11240 break;
11241 case MIPS_HFLAG_BR:
11242 /* unconditional branch to register */
11243 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11244 TCGv t0 = tcg_temp_new();
11245 TCGv_i32 t1 = tcg_temp_new_i32();
11246
11247 tcg_gen_andi_tl(t0, btarget, 0x1);
11248 tcg_gen_trunc_tl_i32(t1, t0);
11249 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11250 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11251 tcg_gen_or_i32(hflags, hflags, t1);
11252
11253 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11254 } else {
11255 tcg_gen_mov_tl(cpu_PC, btarget);
11256 }
11257 tcg_gen_lookup_and_goto_ptr();
11258 break;
11259 default:
11260 LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11261 gen_reserved_instruction(ctx);
11262 }
11263 }
11264 }
11265
11266 /* Compact Branches */
11267 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11268 int rs, int rt, int32_t offset)
11269 {
11270 int bcond_compute = 0;
11271 TCGv t0 = tcg_temp_new();
11272 TCGv t1 = tcg_temp_new();
11273 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11274
11275 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11276 #ifdef MIPS_DEBUG_DISAS
11277 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11278 "\n", ctx->base.pc_next);
11279 #endif
11280 gen_reserved_instruction(ctx);
11281 return;
11282 }
11283
11284 /* Load needed operands and calculate btarget */
11285 switch (opc) {
11286 /* compact branch */
11287 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11288 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11289 gen_load_gpr(t0, rs);
11290 gen_load_gpr(t1, rt);
11291 bcond_compute = 1;
11292 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11293 if (rs <= rt && rs == 0) {
11294 /* OPC_BEQZALC, OPC_BNEZALC */
11295 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11296 }
11297 break;
11298 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11299 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11300 gen_load_gpr(t0, rs);
11301 gen_load_gpr(t1, rt);
11302 bcond_compute = 1;
11303 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11304 break;
11305 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11306 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11307 if (rs == 0 || rs == rt) {
11308 /* OPC_BLEZALC, OPC_BGEZALC */
11309 /* OPC_BGTZALC, OPC_BLTZALC */
11310 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11311 }
11312 gen_load_gpr(t0, rs);
11313 gen_load_gpr(t1, rt);
11314 bcond_compute = 1;
11315 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11316 break;
11317 case OPC_BC:
11318 case OPC_BALC:
11319 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11320 break;
11321 case OPC_BEQZC:
11322 case OPC_BNEZC:
11323 if (rs != 0) {
11324 /* OPC_BEQZC, OPC_BNEZC */
11325 gen_load_gpr(t0, rs);
11326 bcond_compute = 1;
11327 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11328 } else {
11329 /* OPC_JIC, OPC_JIALC */
11330 TCGv tbase = tcg_temp_new();
11331 TCGv toffset = tcg_constant_tl(offset);
11332
11333 gen_load_gpr(tbase, rt);
11334 gen_op_addr_add(ctx, btarget, tbase, toffset);
11335 }
11336 break;
11337 default:
11338 MIPS_INVAL("Compact branch/jump");
11339 gen_reserved_instruction(ctx);
11340 return;
11341 }
11342
11343 if (bcond_compute == 0) {
11344 /* Unconditional compact branch */
11345 switch (opc) {
11346 case OPC_JIALC:
11347 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11348 /* Fallthrough */
11349 case OPC_JIC:
11350 ctx->hflags |= MIPS_HFLAG_BR;
11351 break;
11352 case OPC_BALC:
11353 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11354 /* Fallthrough */
11355 case OPC_BC:
11356 ctx->hflags |= MIPS_HFLAG_B;
11357 break;
11358 default:
11359 MIPS_INVAL("Compact branch/jump");
11360 gen_reserved_instruction(ctx);
11361 return;
11362 }
11363
11364 /* Generating branch here as compact branches don't have delay slot */
11365 gen_branch(ctx, 4);
11366 } else {
11367 /* Conditional compact branch */
11368 TCGLabel *fs = gen_new_label();
11369 save_cpu_state(ctx, 0);
11370
11371 switch (opc) {
11372 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11373 if (rs == 0 && rt != 0) {
11374 /* OPC_BLEZALC */
11375 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11376 } else if (rs != 0 && rt != 0 && rs == rt) {
11377 /* OPC_BGEZALC */
11378 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11379 } else {
11380 /* OPC_BGEUC */
11381 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11382 }
11383 break;
11384 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11385 if (rs == 0 && rt != 0) {
11386 /* OPC_BGTZALC */
11387 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11388 } else if (rs != 0 && rt != 0 && rs == rt) {
11389 /* OPC_BLTZALC */
11390 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11391 } else {
11392 /* OPC_BLTUC */
11393 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11394 }
11395 break;
11396 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11397 if (rs == 0 && rt != 0) {
11398 /* OPC_BLEZC */
11399 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11400 } else if (rs != 0 && rt != 0 && rs == rt) {
11401 /* OPC_BGEZC */
11402 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11403 } else {
11404 /* OPC_BGEC */
11405 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11406 }
11407 break;
11408 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11409 if (rs == 0 && rt != 0) {
11410 /* OPC_BGTZC */
11411 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11412 } else if (rs != 0 && rt != 0 && rs == rt) {
11413 /* OPC_BLTZC */
11414 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11415 } else {
11416 /* OPC_BLTC */
11417 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11418 }
11419 break;
11420 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11421 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11422 if (rs >= rt) {
11423 /* OPC_BOVC, OPC_BNVC */
11424 TCGv t2 = tcg_temp_new();
11425 TCGv t3 = tcg_temp_new();
11426 TCGv t4 = tcg_temp_new();
11427 TCGv input_overflow = tcg_temp_new();
11428
11429 gen_load_gpr(t0, rs);
11430 gen_load_gpr(t1, rt);
11431 tcg_gen_ext32s_tl(t2, t0);
11432 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11433 tcg_gen_ext32s_tl(t3, t1);
11434 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11435 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11436
11437 tcg_gen_add_tl(t4, t2, t3);
11438 tcg_gen_ext32s_tl(t4, t4);
11439 tcg_gen_xor_tl(t2, t2, t3);
11440 tcg_gen_xor_tl(t3, t4, t3);
11441 tcg_gen_andc_tl(t2, t3, t2);
11442 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11443 tcg_gen_or_tl(t4, t4, input_overflow);
11444 if (opc == OPC_BOVC) {
11445 /* OPC_BOVC */
11446 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11447 } else {
11448 /* OPC_BNVC */
11449 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11450 }
11451 } else if (rs < rt && rs == 0) {
11452 /* OPC_BEQZALC, OPC_BNEZALC */
11453 if (opc == OPC_BEQZALC) {
11454 /* OPC_BEQZALC */
11455 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11456 } else {
11457 /* OPC_BNEZALC */
11458 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11459 }
11460 } else {
11461 /* OPC_BEQC, OPC_BNEC */
11462 if (opc == OPC_BEQC) {
11463 /* OPC_BEQC */
11464 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11465 } else {
11466 /* OPC_BNEC */
11467 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
11468 }
11469 }
11470 break;
11471 case OPC_BEQZC:
11472 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
11473 break;
11474 case OPC_BNEZC:
11475 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
11476 break;
11477 default:
11478 MIPS_INVAL("Compact conditional branch/jump");
11479 gen_reserved_instruction(ctx);
11480 return;
11481 }
11482
11483 /* Generating branch here as compact branches don't have delay slot */
11484 gen_goto_tb(ctx, 1, ctx->btarget);
11485 gen_set_label(fs);
11486
11487 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
11488 }
11489 }
11490
11491 void gen_addiupc(DisasContext *ctx, int rx, int imm,
11492 int is_64_bit, int extended)
11493 {
11494 TCGv t0;
11495
11496 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11497 gen_reserved_instruction(ctx);
11498 return;
11499 }
11500
11501 t0 = tcg_temp_new();
11502
11503 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11504 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11505 if (!is_64_bit) {
11506 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11507 }
11508 }
11509
11510 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11511 int16_t offset)
11512 {
11513 TCGv_i32 t0 = tcg_constant_i32(op);
11514 TCGv t1 = tcg_temp_new();
11515 gen_base_offset_addr(ctx, t1, base, offset);
11516 gen_helper_cache(tcg_env, t1, t0);
11517 }
11518
11519 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code)
11520 {
11521 #ifdef CONFIG_USER_ONLY
11522 return false;
11523 #else
11524 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM;
11525 return semihosting_enabled(is_user) && sdbbp_code == 1;
11526 #endif
11527 }
11528
11529 void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
11530 {
11531 TCGv t0 = tcg_temp_new();
11532 TCGv t1 = tcg_temp_new();
11533
11534 gen_load_gpr(t0, base);
11535
11536 if (index != 0) {
11537 gen_load_gpr(t1, index);
11538 tcg_gen_shli_tl(t1, t1, 2);
11539 gen_op_addr_add(ctx, t0, t1, t0);
11540 }
11541
11542 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
11543 gen_store_gpr(t1, rd);
11544 }
11545
11546 static void gen_sync(int stype)
11547 {
11548 TCGBar tcg_mo = TCG_BAR_SC;
11549
11550 switch (stype) {
11551 case 0x4: /* SYNC_WMB */
11552 tcg_mo |= TCG_MO_ST_ST;
11553 break;
11554 case 0x10: /* SYNC_MB */
11555 tcg_mo |= TCG_MO_ALL;
11556 break;
11557 case 0x11: /* SYNC_ACQUIRE */
11558 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
11559 break;
11560 case 0x12: /* SYNC_RELEASE */
11561 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
11562 break;
11563 case 0x13: /* SYNC_RMB */
11564 tcg_mo |= TCG_MO_LD_LD;
11565 break;
11566 default:
11567 tcg_mo |= TCG_MO_ALL;
11568 break;
11569 }
11570
11571 tcg_gen_mb(tcg_mo);
11572 }
11573
11574 /* ISA extensions (ASEs) */
11575
11576 /* MIPS16 extension to MIPS32 */
11577 #include "mips16e_translate.c.inc"
11578
11579 /* microMIPS extension to MIPS32/MIPS64 */
11580
11581 /*
11582 * Values for microMIPS fmt field. Variable-width, depending on which
11583 * formats the instruction supports.
11584 */
11585 enum {
11586 FMT_SD_S = 0,
11587 FMT_SD_D = 1,
11588
11589 FMT_SDPS_S = 0,
11590 FMT_SDPS_D = 1,
11591 FMT_SDPS_PS = 2,
11592
11593 FMT_SWL_S = 0,
11594 FMT_SWL_W = 1,
11595 FMT_SWL_L = 2,
11596
11597 FMT_DWL_D = 0,
11598 FMT_DWL_W = 1,
11599 FMT_DWL_L = 2
11600 };
11601
11602 #include "micromips_translate.c.inc"
11603
11604 #include "nanomips_translate.c.inc"
11605
11606 /* MIPSDSP functions. */
11607
11608 /* Indexed load is not for DSP only */
11609 static void gen_mips_lx(DisasContext *ctx, uint32_t opc,
11610 int rd, int base, int offset)
11611 {
11612 TCGv t0;
11613
11614 if (!(ctx->insn_flags & INSN_OCTEON)) {
11615 check_dsp(ctx);
11616 }
11617 t0 = tcg_temp_new();
11618
11619 if (base == 0) {
11620 gen_load_gpr(t0, offset);
11621 } else if (offset == 0) {
11622 gen_load_gpr(t0, base);
11623 } else {
11624 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
11625 }
11626
11627 switch (opc) {
11628 case OPC_LBUX:
11629 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
11630 gen_store_gpr(t0, rd);
11631 break;
11632 case OPC_LHX:
11633 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
11634 gen_store_gpr(t0, rd);
11635 break;
11636 case OPC_LWX:
11637 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11638 gen_store_gpr(t0, rd);
11639 break;
11640 #if defined(TARGET_MIPS64)
11641 case OPC_LDX:
11642 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
11643 gen_store_gpr(t0, rd);
11644 break;
11645 #endif
11646 }
11647 }
11648
11649 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
11650 int ret, int v1, int v2)
11651 {
11652 TCGv v1_t;
11653 TCGv v2_t;
11654
11655 if (ret == 0) {
11656 /* Treat as NOP. */
11657 return;
11658 }
11659
11660 v1_t = tcg_temp_new();
11661 v2_t = tcg_temp_new();
11662
11663 gen_load_gpr(v1_t, v1);
11664 gen_load_gpr(v2_t, v2);
11665
11666 switch (op1) {
11667 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
11668 case OPC_MULT_G_2E:
11669 check_dsp_r2(ctx);
11670 switch (op2) {
11671 case OPC_ADDUH_QB:
11672 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
11673 break;
11674 case OPC_ADDUH_R_QB:
11675 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11676 break;
11677 case OPC_ADDQH_PH:
11678 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
11679 break;
11680 case OPC_ADDQH_R_PH:
11681 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11682 break;
11683 case OPC_ADDQH_W:
11684 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
11685 break;
11686 case OPC_ADDQH_R_W:
11687 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11688 break;
11689 case OPC_SUBUH_QB:
11690 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
11691 break;
11692 case OPC_SUBUH_R_QB:
11693 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
11694 break;
11695 case OPC_SUBQH_PH:
11696 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
11697 break;
11698 case OPC_SUBQH_R_PH:
11699 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
11700 break;
11701 case OPC_SUBQH_W:
11702 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
11703 break;
11704 case OPC_SUBQH_R_W:
11705 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
11706 break;
11707 }
11708 break;
11709 case OPC_ABSQ_S_PH_DSP:
11710 switch (op2) {
11711 case OPC_ABSQ_S_QB:
11712 check_dsp_r2(ctx);
11713 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, tcg_env);
11714 break;
11715 case OPC_ABSQ_S_PH:
11716 check_dsp(ctx);
11717 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, tcg_env);
11718 break;
11719 case OPC_ABSQ_S_W:
11720 check_dsp(ctx);
11721 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, tcg_env);
11722 break;
11723 case OPC_PRECEQ_W_PHL:
11724 check_dsp(ctx);
11725 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
11726 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11727 break;
11728 case OPC_PRECEQ_W_PHR:
11729 check_dsp(ctx);
11730 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
11731 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
11732 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
11733 break;
11734 case OPC_PRECEQU_PH_QBL:
11735 check_dsp(ctx);
11736 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
11737 break;
11738 case OPC_PRECEQU_PH_QBR:
11739 check_dsp(ctx);
11740 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
11741 break;
11742 case OPC_PRECEQU_PH_QBLA:
11743 check_dsp(ctx);
11744 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
11745 break;
11746 case OPC_PRECEQU_PH_QBRA:
11747 check_dsp(ctx);
11748 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
11749 break;
11750 case OPC_PRECEU_PH_QBL:
11751 check_dsp(ctx);
11752 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
11753 break;
11754 case OPC_PRECEU_PH_QBR:
11755 check_dsp(ctx);
11756 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
11757 break;
11758 case OPC_PRECEU_PH_QBLA:
11759 check_dsp(ctx);
11760 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
11761 break;
11762 case OPC_PRECEU_PH_QBRA:
11763 check_dsp(ctx);
11764 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
11765 break;
11766 }
11767 break;
11768 case OPC_ADDU_QB_DSP:
11769 switch (op2) {
11770 case OPC_ADDQ_PH:
11771 check_dsp(ctx);
11772 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11773 break;
11774 case OPC_ADDQ_S_PH:
11775 check_dsp(ctx);
11776 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11777 break;
11778 case OPC_ADDQ_S_W:
11779 check_dsp(ctx);
11780 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11781 break;
11782 case OPC_ADDU_QB:
11783 check_dsp(ctx);
11784 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11785 break;
11786 case OPC_ADDU_S_QB:
11787 check_dsp(ctx);
11788 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11789 break;
11790 case OPC_ADDU_PH:
11791 check_dsp_r2(ctx);
11792 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11793 break;
11794 case OPC_ADDU_S_PH:
11795 check_dsp_r2(ctx);
11796 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11797 break;
11798 case OPC_SUBQ_PH:
11799 check_dsp(ctx);
11800 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11801 break;
11802 case OPC_SUBQ_S_PH:
11803 check_dsp(ctx);
11804 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11805 break;
11806 case OPC_SUBQ_S_W:
11807 check_dsp(ctx);
11808 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11809 break;
11810 case OPC_SUBU_QB:
11811 check_dsp(ctx);
11812 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11813 break;
11814 case OPC_SUBU_S_QB:
11815 check_dsp(ctx);
11816 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11817 break;
11818 case OPC_SUBU_PH:
11819 check_dsp_r2(ctx);
11820 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11821 break;
11822 case OPC_SUBU_S_PH:
11823 check_dsp_r2(ctx);
11824 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11825 break;
11826 case OPC_ADDSC:
11827 check_dsp(ctx);
11828 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11829 break;
11830 case OPC_ADDWC:
11831 check_dsp(ctx);
11832 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11833 break;
11834 case OPC_MODSUB:
11835 check_dsp(ctx);
11836 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
11837 break;
11838 case OPC_RADDU_W_QB:
11839 check_dsp(ctx);
11840 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
11841 break;
11842 }
11843 break;
11844 case OPC_CMPU_EQ_QB_DSP:
11845 switch (op2) {
11846 case OPC_PRECR_QB_PH:
11847 check_dsp_r2(ctx);
11848 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11849 break;
11850 case OPC_PRECRQ_QB_PH:
11851 check_dsp(ctx);
11852 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
11853 break;
11854 case OPC_PRECR_SRA_PH_W:
11855 check_dsp_r2(ctx);
11856 {
11857 TCGv_i32 sa_t = tcg_constant_i32(v2);
11858 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
11859 cpu_gpr[ret]);
11860 break;
11861 }
11862 case OPC_PRECR_SRA_R_PH_W:
11863 check_dsp_r2(ctx);
11864 {
11865 TCGv_i32 sa_t = tcg_constant_i32(v2);
11866 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
11867 cpu_gpr[ret]);
11868 break;
11869 }
11870 case OPC_PRECRQ_PH_W:
11871 check_dsp(ctx);
11872 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
11873 break;
11874 case OPC_PRECRQ_RS_PH_W:
11875 check_dsp(ctx);
11876 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11877 break;
11878 case OPC_PRECRQU_S_QB_PH:
11879 check_dsp(ctx);
11880 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11881 break;
11882 }
11883 break;
11884 #ifdef TARGET_MIPS64
11885 case OPC_ABSQ_S_QH_DSP:
11886 switch (op2) {
11887 case OPC_PRECEQ_L_PWL:
11888 check_dsp(ctx);
11889 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
11890 break;
11891 case OPC_PRECEQ_L_PWR:
11892 check_dsp(ctx);
11893 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
11894 break;
11895 case OPC_PRECEQ_PW_QHL:
11896 check_dsp(ctx);
11897 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
11898 break;
11899 case OPC_PRECEQ_PW_QHR:
11900 check_dsp(ctx);
11901 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
11902 break;
11903 case OPC_PRECEQ_PW_QHLA:
11904 check_dsp(ctx);
11905 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
11906 break;
11907 case OPC_PRECEQ_PW_QHRA:
11908 check_dsp(ctx);
11909 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
11910 break;
11911 case OPC_PRECEQU_QH_OBL:
11912 check_dsp(ctx);
11913 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
11914 break;
11915 case OPC_PRECEQU_QH_OBR:
11916 check_dsp(ctx);
11917 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
11918 break;
11919 case OPC_PRECEQU_QH_OBLA:
11920 check_dsp(ctx);
11921 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
11922 break;
11923 case OPC_PRECEQU_QH_OBRA:
11924 check_dsp(ctx);
11925 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
11926 break;
11927 case OPC_PRECEU_QH_OBL:
11928 check_dsp(ctx);
11929 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
11930 break;
11931 case OPC_PRECEU_QH_OBR:
11932 check_dsp(ctx);
11933 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
11934 break;
11935 case OPC_PRECEU_QH_OBLA:
11936 check_dsp(ctx);
11937 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
11938 break;
11939 case OPC_PRECEU_QH_OBRA:
11940 check_dsp(ctx);
11941 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
11942 break;
11943 case OPC_ABSQ_S_OB:
11944 check_dsp_r2(ctx);
11945 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, tcg_env);
11946 break;
11947 case OPC_ABSQ_S_PW:
11948 check_dsp(ctx);
11949 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, tcg_env);
11950 break;
11951 case OPC_ABSQ_S_QH:
11952 check_dsp(ctx);
11953 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, tcg_env);
11954 break;
11955 }
11956 break;
11957 case OPC_ADDU_OB_DSP:
11958 switch (op2) {
11959 case OPC_RADDU_L_OB:
11960 check_dsp(ctx);
11961 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
11962 break;
11963 case OPC_SUBQ_PW:
11964 check_dsp(ctx);
11965 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11966 break;
11967 case OPC_SUBQ_S_PW:
11968 check_dsp(ctx);
11969 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11970 break;
11971 case OPC_SUBQ_QH:
11972 check_dsp(ctx);
11973 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11974 break;
11975 case OPC_SUBQ_S_QH:
11976 check_dsp(ctx);
11977 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11978 break;
11979 case OPC_SUBU_OB:
11980 check_dsp(ctx);
11981 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11982 break;
11983 case OPC_SUBU_S_OB:
11984 check_dsp(ctx);
11985 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11986 break;
11987 case OPC_SUBU_QH:
11988 check_dsp_r2(ctx);
11989 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11990 break;
11991 case OPC_SUBU_S_QH:
11992 check_dsp_r2(ctx);
11993 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
11994 break;
11995 case OPC_SUBUH_OB:
11996 check_dsp_r2(ctx);
11997 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
11998 break;
11999 case OPC_SUBUH_R_OB:
12000 check_dsp_r2(ctx);
12001 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12002 break;
12003 case OPC_ADDQ_PW:
12004 check_dsp(ctx);
12005 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12006 break;
12007 case OPC_ADDQ_S_PW:
12008 check_dsp(ctx);
12009 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12010 break;
12011 case OPC_ADDQ_QH:
12012 check_dsp(ctx);
12013 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12014 break;
12015 case OPC_ADDQ_S_QH:
12016 check_dsp(ctx);
12017 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12018 break;
12019 case OPC_ADDU_OB:
12020 check_dsp(ctx);
12021 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12022 break;
12023 case OPC_ADDU_S_OB:
12024 check_dsp(ctx);
12025 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12026 break;
12027 case OPC_ADDU_QH:
12028 check_dsp_r2(ctx);
12029 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12030 break;
12031 case OPC_ADDU_S_QH:
12032 check_dsp_r2(ctx);
12033 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12034 break;
12035 case OPC_ADDUH_OB:
12036 check_dsp_r2(ctx);
12037 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12038 break;
12039 case OPC_ADDUH_R_OB:
12040 check_dsp_r2(ctx);
12041 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12042 break;
12043 }
12044 break;
12045 case OPC_CMPU_EQ_OB_DSP:
12046 switch (op2) {
12047 case OPC_PRECR_OB_QH:
12048 check_dsp_r2(ctx);
12049 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12050 break;
12051 case OPC_PRECR_SRA_QH_PW:
12052 check_dsp_r2(ctx);
12053 {
12054 TCGv_i32 ret_t = tcg_constant_i32(ret);
12055 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12056 break;
12057 }
12058 case OPC_PRECR_SRA_R_QH_PW:
12059 check_dsp_r2(ctx);
12060 {
12061 TCGv_i32 sa_v = tcg_constant_i32(ret);
12062 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12063 break;
12064 }
12065 case OPC_PRECRQ_OB_QH:
12066 check_dsp(ctx);
12067 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12068 break;
12069 case OPC_PRECRQ_PW_L:
12070 check_dsp(ctx);
12071 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12072 break;
12073 case OPC_PRECRQ_QH_PW:
12074 check_dsp(ctx);
12075 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12076 break;
12077 case OPC_PRECRQ_RS_QH_PW:
12078 check_dsp(ctx);
12079 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12080 break;
12081 case OPC_PRECRQU_S_OB_QH:
12082 check_dsp(ctx);
12083 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12084 break;
12085 }
12086 break;
12087 #endif
12088 }
12089 }
12090
12091 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12092 int ret, int v1, int v2)
12093 {
12094 uint32_t op2;
12095 TCGv t0;
12096 TCGv v1_t;
12097 TCGv v2_t;
12098
12099 if (ret == 0) {
12100 /* Treat as NOP. */
12101 return;
12102 }
12103
12104 t0 = tcg_temp_new();
12105 v1_t = tcg_temp_new();
12106 v2_t = tcg_temp_new();
12107
12108 tcg_gen_movi_tl(t0, v1);
12109 gen_load_gpr(v1_t, v1);
12110 gen_load_gpr(v2_t, v2);
12111
12112 switch (opc) {
12113 case OPC_SHLL_QB_DSP:
12114 {
12115 op2 = MASK_SHLL_QB(ctx->opcode);
12116 switch (op2) {
12117 case OPC_SHLL_QB:
12118 check_dsp(ctx);
12119 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, tcg_env);
12120 break;
12121 case OPC_SHLLV_QB:
12122 check_dsp(ctx);
12123 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12124 break;
12125 case OPC_SHLL_PH:
12126 check_dsp(ctx);
12127 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, tcg_env);
12128 break;
12129 case OPC_SHLLV_PH:
12130 check_dsp(ctx);
12131 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12132 break;
12133 case OPC_SHLL_S_PH:
12134 check_dsp(ctx);
12135 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, tcg_env);
12136 break;
12137 case OPC_SHLLV_S_PH:
12138 check_dsp(ctx);
12139 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12140 break;
12141 case OPC_SHLL_S_W:
12142 check_dsp(ctx);
12143 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, tcg_env);
12144 break;
12145 case OPC_SHLLV_S_W:
12146 check_dsp(ctx);
12147 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12148 break;
12149 case OPC_SHRL_QB:
12150 check_dsp(ctx);
12151 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12152 break;
12153 case OPC_SHRLV_QB:
12154 check_dsp(ctx);
12155 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12156 break;
12157 case OPC_SHRL_PH:
12158 check_dsp_r2(ctx);
12159 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12160 break;
12161 case OPC_SHRLV_PH:
12162 check_dsp_r2(ctx);
12163 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12164 break;
12165 case OPC_SHRA_QB:
12166 check_dsp_r2(ctx);
12167 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12168 break;
12169 case OPC_SHRA_R_QB:
12170 check_dsp_r2(ctx);
12171 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12172 break;
12173 case OPC_SHRAV_QB:
12174 check_dsp_r2(ctx);
12175 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12176 break;
12177 case OPC_SHRAV_R_QB:
12178 check_dsp_r2(ctx);
12179 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12180 break;
12181 case OPC_SHRA_PH:
12182 check_dsp(ctx);
12183 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12184 break;
12185 case OPC_SHRA_R_PH:
12186 check_dsp(ctx);
12187 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12188 break;
12189 case OPC_SHRAV_PH:
12190 check_dsp(ctx);
12191 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12192 break;
12193 case OPC_SHRAV_R_PH:
12194 check_dsp(ctx);
12195 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12196 break;
12197 case OPC_SHRA_R_W:
12198 check_dsp(ctx);
12199 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12200 break;
12201 case OPC_SHRAV_R_W:
12202 check_dsp(ctx);
12203 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12204 break;
12205 default: /* Invalid */
12206 MIPS_INVAL("MASK SHLL.QB");
12207 gen_reserved_instruction(ctx);
12208 break;
12209 }
12210 break;
12211 }
12212 #ifdef TARGET_MIPS64
12213 case OPC_SHLL_OB_DSP:
12214 op2 = MASK_SHLL_OB(ctx->opcode);
12215 switch (op2) {
12216 case OPC_SHLL_PW:
12217 check_dsp(ctx);
12218 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, tcg_env);
12219 break;
12220 case OPC_SHLLV_PW:
12221 check_dsp(ctx);
12222 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env);
12223 break;
12224 case OPC_SHLL_S_PW:
12225 check_dsp(ctx);
12226 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, tcg_env);
12227 break;
12228 case OPC_SHLLV_S_PW:
12229 check_dsp(ctx);
12230 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, tcg_env);
12231 break;
12232 case OPC_SHLL_OB:
12233 check_dsp(ctx);
12234 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, tcg_env);
12235 break;
12236 case OPC_SHLLV_OB:
12237 check_dsp(ctx);
12238 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, tcg_env);
12239 break;
12240 case OPC_SHLL_QH:
12241 check_dsp(ctx);
12242 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, tcg_env);
12243 break;
12244 case OPC_SHLLV_QH:
12245 check_dsp(ctx);
12246 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env);
12247 break;
12248 case OPC_SHLL_S_QH:
12249 check_dsp(ctx);
12250 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, tcg_env);
12251 break;
12252 case OPC_SHLLV_S_QH:
12253 check_dsp(ctx);
12254 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, tcg_env);
12255 break;
12256 case OPC_SHRA_OB:
12257 check_dsp_r2(ctx);
12258 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12259 break;
12260 case OPC_SHRAV_OB:
12261 check_dsp_r2(ctx);
12262 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12263 break;
12264 case OPC_SHRA_R_OB:
12265 check_dsp_r2(ctx);
12266 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12267 break;
12268 case OPC_SHRAV_R_OB:
12269 check_dsp_r2(ctx);
12270 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12271 break;
12272 case OPC_SHRA_PW:
12273 check_dsp(ctx);
12274 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12275 break;
12276 case OPC_SHRAV_PW:
12277 check_dsp(ctx);
12278 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12279 break;
12280 case OPC_SHRA_R_PW:
12281 check_dsp(ctx);
12282 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12283 break;
12284 case OPC_SHRAV_R_PW:
12285 check_dsp(ctx);
12286 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12287 break;
12288 case OPC_SHRA_QH:
12289 check_dsp(ctx);
12290 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12291 break;
12292 case OPC_SHRAV_QH:
12293 check_dsp(ctx);
12294 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12295 break;
12296 case OPC_SHRA_R_QH:
12297 check_dsp(ctx);
12298 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12299 break;
12300 case OPC_SHRAV_R_QH:
12301 check_dsp(ctx);
12302 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12303 break;
12304 case OPC_SHRL_OB:
12305 check_dsp(ctx);
12306 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12307 break;
12308 case OPC_SHRLV_OB:
12309 check_dsp(ctx);
12310 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12311 break;
12312 case OPC_SHRL_QH:
12313 check_dsp_r2(ctx);
12314 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12315 break;
12316 case OPC_SHRLV_QH:
12317 check_dsp_r2(ctx);
12318 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12319 break;
12320 default: /* Invalid */
12321 MIPS_INVAL("MASK SHLL.OB");
12322 gen_reserved_instruction(ctx);
12323 break;
12324 }
12325 break;
12326 #endif
12327 }
12328 }
12329
12330 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12331 int ret, int v1, int v2, int check_ret)
12332 {
12333 TCGv_i32 t0;
12334 TCGv v1_t;
12335 TCGv v2_t;
12336
12337 if ((ret == 0) && (check_ret == 1)) {
12338 /* Treat as NOP. */
12339 return;
12340 }
12341
12342 t0 = tcg_temp_new_i32();
12343 v1_t = tcg_temp_new();
12344 v2_t = tcg_temp_new();
12345
12346 tcg_gen_movi_i32(t0, ret);
12347 gen_load_gpr(v1_t, v1);
12348 gen_load_gpr(v2_t, v2);
12349
12350 switch (op1) {
12351 /*
12352 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
12353 * the same mask and op1.
12354 */
12355 case OPC_MULT_G_2E:
12356 check_dsp_r2(ctx);
12357 switch (op2) {
12358 case OPC_MUL_PH:
12359 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12360 break;
12361 case OPC_MUL_S_PH:
12362 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12363 break;
12364 case OPC_MULQ_S_W:
12365 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12366 break;
12367 case OPC_MULQ_RS_W:
12368 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12369 break;
12370 }
12371 break;
12372 case OPC_DPA_W_PH_DSP:
12373 switch (op2) {
12374 case OPC_DPAU_H_QBL:
12375 check_dsp(ctx);
12376 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, tcg_env);
12377 break;
12378 case OPC_DPAU_H_QBR:
12379 check_dsp(ctx);
12380 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, tcg_env);
12381 break;
12382 case OPC_DPSU_H_QBL:
12383 check_dsp(ctx);
12384 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, tcg_env);
12385 break;
12386 case OPC_DPSU_H_QBR:
12387 check_dsp(ctx);
12388 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, tcg_env);
12389 break;
12390 case OPC_DPA_W_PH:
12391 check_dsp_r2(ctx);
12392 gen_helper_dpa_w_ph(t0, v1_t, v2_t, tcg_env);
12393 break;
12394 case OPC_DPAX_W_PH:
12395 check_dsp_r2(ctx);
12396 gen_helper_dpax_w_ph(t0, v1_t, v2_t, tcg_env);
12397 break;
12398 case OPC_DPAQ_S_W_PH:
12399 check_dsp(ctx);
12400 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12401 break;
12402 case OPC_DPAQX_S_W_PH:
12403 check_dsp_r2(ctx);
12404 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, tcg_env);
12405 break;
12406 case OPC_DPAQX_SA_W_PH:
12407 check_dsp_r2(ctx);
12408 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, tcg_env);
12409 break;
12410 case OPC_DPS_W_PH:
12411 check_dsp_r2(ctx);
12412 gen_helper_dps_w_ph(t0, v1_t, v2_t, tcg_env);
12413 break;
12414 case OPC_DPSX_W_PH:
12415 check_dsp_r2(ctx);
12416 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, tcg_env);
12417 break;
12418 case OPC_DPSQ_S_W_PH:
12419 check_dsp(ctx);
12420 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12421 break;
12422 case OPC_DPSQX_S_W_PH:
12423 check_dsp_r2(ctx);
12424 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, tcg_env);
12425 break;
12426 case OPC_DPSQX_SA_W_PH:
12427 check_dsp_r2(ctx);
12428 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, tcg_env);
12429 break;
12430 case OPC_MULSAQ_S_W_PH:
12431 check_dsp(ctx);
12432 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, tcg_env);
12433 break;
12434 case OPC_DPAQ_SA_L_W:
12435 check_dsp(ctx);
12436 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, tcg_env);
12437 break;
12438 case OPC_DPSQ_SA_L_W:
12439 check_dsp(ctx);
12440 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, tcg_env);
12441 break;
12442 case OPC_MAQ_S_W_PHL:
12443 check_dsp(ctx);
12444 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, tcg_env);
12445 break;
12446 case OPC_MAQ_S_W_PHR:
12447 check_dsp(ctx);
12448 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, tcg_env);
12449 break;
12450 case OPC_MAQ_SA_W_PHL:
12451 check_dsp(ctx);
12452 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, tcg_env);
12453 break;
12454 case OPC_MAQ_SA_W_PHR:
12455 check_dsp(ctx);
12456 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, tcg_env);
12457 break;
12458 case OPC_MULSA_W_PH:
12459 check_dsp_r2(ctx);
12460 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, tcg_env);
12461 break;
12462 }
12463 break;
12464 #ifdef TARGET_MIPS64
12465 case OPC_DPAQ_W_QH_DSP:
12466 {
12467 int ac = ret & 0x03;
12468 tcg_gen_movi_i32(t0, ac);
12469
12470 switch (op2) {
12471 case OPC_DMADD:
12472 check_dsp(ctx);
12473 gen_helper_dmadd(v1_t, v2_t, t0, tcg_env);
12474 break;
12475 case OPC_DMADDU:
12476 check_dsp(ctx);
12477 gen_helper_dmaddu(v1_t, v2_t, t0, tcg_env);
12478 break;
12479 case OPC_DMSUB:
12480 check_dsp(ctx);
12481 gen_helper_dmsub(v1_t, v2_t, t0, tcg_env);
12482 break;
12483 case OPC_DMSUBU:
12484 check_dsp(ctx);
12485 gen_helper_dmsubu(v1_t, v2_t, t0, tcg_env);
12486 break;
12487 case OPC_DPA_W_QH:
12488 check_dsp_r2(ctx);
12489 gen_helper_dpa_w_qh(v1_t, v2_t, t0, tcg_env);
12490 break;
12491 case OPC_DPAQ_S_W_QH:
12492 check_dsp(ctx);
12493 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12494 break;
12495 case OPC_DPAQ_SA_L_PW:
12496 check_dsp(ctx);
12497 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, tcg_env);
12498 break;
12499 case OPC_DPAU_H_OBL:
12500 check_dsp(ctx);
12501 gen_helper_dpau_h_obl(v1_t, v2_t, t0, tcg_env);
12502 break;
12503 case OPC_DPAU_H_OBR:
12504 check_dsp(ctx);
12505 gen_helper_dpau_h_obr(v1_t, v2_t, t0, tcg_env);
12506 break;
12507 case OPC_DPS_W_QH:
12508 check_dsp_r2(ctx);
12509 gen_helper_dps_w_qh(v1_t, v2_t, t0, tcg_env);
12510 break;
12511 case OPC_DPSQ_S_W_QH:
12512 check_dsp(ctx);
12513 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12514 break;
12515 case OPC_DPSQ_SA_L_PW:
12516 check_dsp(ctx);
12517 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, tcg_env);
12518 break;
12519 case OPC_DPSU_H_OBL:
12520 check_dsp(ctx);
12521 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, tcg_env);
12522 break;
12523 case OPC_DPSU_H_OBR:
12524 check_dsp(ctx);
12525 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, tcg_env);
12526 break;
12527 case OPC_MAQ_S_L_PWL:
12528 check_dsp(ctx);
12529 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, tcg_env);
12530 break;
12531 case OPC_MAQ_S_L_PWR:
12532 check_dsp(ctx);
12533 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, tcg_env);
12534 break;
12535 case OPC_MAQ_S_W_QHLL:
12536 check_dsp(ctx);
12537 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, tcg_env);
12538 break;
12539 case OPC_MAQ_SA_W_QHLL:
12540 check_dsp(ctx);
12541 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, tcg_env);
12542 break;
12543 case OPC_MAQ_S_W_QHLR:
12544 check_dsp(ctx);
12545 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, tcg_env);
12546 break;
12547 case OPC_MAQ_SA_W_QHLR:
12548 check_dsp(ctx);
12549 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, tcg_env);
12550 break;
12551 case OPC_MAQ_S_W_QHRL:
12552 check_dsp(ctx);
12553 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, tcg_env);
12554 break;
12555 case OPC_MAQ_SA_W_QHRL:
12556 check_dsp(ctx);
12557 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, tcg_env);
12558 break;
12559 case OPC_MAQ_S_W_QHRR:
12560 check_dsp(ctx);
12561 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, tcg_env);
12562 break;
12563 case OPC_MAQ_SA_W_QHRR:
12564 check_dsp(ctx);
12565 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, tcg_env);
12566 break;
12567 case OPC_MULSAQ_S_L_PW:
12568 check_dsp(ctx);
12569 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, tcg_env);
12570 break;
12571 case OPC_MULSAQ_S_W_QH:
12572 check_dsp(ctx);
12573 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, tcg_env);
12574 break;
12575 }
12576 }
12577 break;
12578 #endif
12579 case OPC_ADDU_QB_DSP:
12580 switch (op2) {
12581 case OPC_MULEU_S_PH_QBL:
12582 check_dsp(ctx);
12583 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12584 break;
12585 case OPC_MULEU_S_PH_QBR:
12586 check_dsp(ctx);
12587 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12588 break;
12589 case OPC_MULQ_RS_PH:
12590 check_dsp(ctx);
12591 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12592 break;
12593 case OPC_MULEQ_S_W_PHL:
12594 check_dsp(ctx);
12595 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12596 break;
12597 case OPC_MULEQ_S_W_PHR:
12598 check_dsp(ctx);
12599 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12600 break;
12601 case OPC_MULQ_S_PH:
12602 check_dsp_r2(ctx);
12603 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12604 break;
12605 }
12606 break;
12607 #ifdef TARGET_MIPS64
12608 case OPC_ADDU_OB_DSP:
12609 switch (op2) {
12610 case OPC_MULEQ_S_PW_QHL:
12611 check_dsp(ctx);
12612 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12613 break;
12614 case OPC_MULEQ_S_PW_QHR:
12615 check_dsp(ctx);
12616 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12617 break;
12618 case OPC_MULEU_S_QH_OBL:
12619 check_dsp(ctx);
12620 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12621 break;
12622 case OPC_MULEU_S_QH_OBR:
12623 check_dsp(ctx);
12624 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12625 break;
12626 case OPC_MULQ_RS_QH:
12627 check_dsp(ctx);
12628 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12629 break;
12630 }
12631 break;
12632 #endif
12633 }
12634 }
12635
12636 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
12637 int ret, int val)
12638 {
12639 int16_t imm;
12640 TCGv t0;
12641 TCGv val_t;
12642
12643 if (ret == 0) {
12644 /* Treat as NOP. */
12645 return;
12646 }
12647
12648 t0 = tcg_temp_new();
12649 val_t = tcg_temp_new();
12650 gen_load_gpr(val_t, val);
12651
12652 switch (op1) {
12653 case OPC_ABSQ_S_PH_DSP:
12654 switch (op2) {
12655 case OPC_BITREV:
12656 check_dsp(ctx);
12657 gen_helper_bitrev(cpu_gpr[ret], val_t);
12658 break;
12659 case OPC_REPL_QB:
12660 check_dsp(ctx);
12661 {
12662 target_long result;
12663 imm = (ctx->opcode >> 16) & 0xFF;
12664 result = (uint32_t)imm << 24 |
12665 (uint32_t)imm << 16 |
12666 (uint32_t)imm << 8 |
12667 (uint32_t)imm;
12668 result = (int32_t)result;
12669 tcg_gen_movi_tl(cpu_gpr[ret], result);
12670 }
12671 break;
12672 case OPC_REPLV_QB:
12673 check_dsp(ctx);
12674 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12675 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12676 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12677 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12678 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12679 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12680 break;
12681 case OPC_REPL_PH:
12682 check_dsp(ctx);
12683 {
12684 imm = (ctx->opcode >> 16) & 0x03FF;
12685 imm = (int16_t)(imm << 6) >> 6;
12686 tcg_gen_movi_tl(cpu_gpr[ret], \
12687 (target_long)((int32_t)imm << 16 | \
12688 (uint16_t)imm));
12689 }
12690 break;
12691 case OPC_REPLV_PH:
12692 check_dsp(ctx);
12693 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12694 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12695 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12696 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12697 break;
12698 }
12699 break;
12700 #ifdef TARGET_MIPS64
12701 case OPC_ABSQ_S_QH_DSP:
12702 switch (op2) {
12703 case OPC_REPL_OB:
12704 check_dsp(ctx);
12705 {
12706 target_long temp;
12707
12708 imm = (ctx->opcode >> 16) & 0xFF;
12709 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
12710 temp = (temp << 16) | temp;
12711 temp = (temp << 32) | temp;
12712 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12713 break;
12714 }
12715 case OPC_REPL_PW:
12716 check_dsp(ctx);
12717 {
12718 target_long temp;
12719
12720 imm = (ctx->opcode >> 16) & 0x03FF;
12721 imm = (int16_t)(imm << 6) >> 6;
12722 temp = ((target_long)imm << 32) \
12723 | ((target_long)imm & 0xFFFFFFFF);
12724 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12725 break;
12726 }
12727 case OPC_REPL_QH:
12728 check_dsp(ctx);
12729 {
12730 target_long temp;
12731
12732 imm = (ctx->opcode >> 16) & 0x03FF;
12733 imm = (int16_t)(imm << 6) >> 6;
12734
12735 temp = ((uint64_t)(uint16_t)imm << 48) |
12736 ((uint64_t)(uint16_t)imm << 32) |
12737 ((uint64_t)(uint16_t)imm << 16) |
12738 (uint64_t)(uint16_t)imm;
12739 tcg_gen_movi_tl(cpu_gpr[ret], temp);
12740 break;
12741 }
12742 case OPC_REPLV_OB:
12743 check_dsp(ctx);
12744 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
12745 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
12746 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12747 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12748 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12749 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12750 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12751 break;
12752 case OPC_REPLV_PW:
12753 check_dsp(ctx);
12754 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
12755 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12756 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12757 break;
12758 case OPC_REPLV_QH:
12759 check_dsp(ctx);
12760 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
12761 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
12762 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12763 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
12764 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
12765 break;
12766 }
12767 break;
12768 #endif
12769 }
12770 }
12771
12772 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
12773 uint32_t op1, uint32_t op2,
12774 int ret, int v1, int v2, int check_ret)
12775 {
12776 TCGv t1;
12777 TCGv v1_t;
12778 TCGv v2_t;
12779
12780 if ((ret == 0) && (check_ret == 1)) {
12781 /* Treat as NOP. */
12782 return;
12783 }
12784
12785 t1 = tcg_temp_new();
12786 v1_t = tcg_temp_new();
12787 v2_t = tcg_temp_new();
12788
12789 gen_load_gpr(v1_t, v1);
12790 gen_load_gpr(v2_t, v2);
12791
12792 switch (op1) {
12793 case OPC_CMPU_EQ_QB_DSP:
12794 switch (op2) {
12795 case OPC_CMPU_EQ_QB:
12796 check_dsp(ctx);
12797 gen_helper_cmpu_eq_qb(v1_t, v2_t, tcg_env);
12798 break;
12799 case OPC_CMPU_LT_QB:
12800 check_dsp(ctx);
12801 gen_helper_cmpu_lt_qb(v1_t, v2_t, tcg_env);
12802 break;
12803 case OPC_CMPU_LE_QB:
12804 check_dsp(ctx);
12805 gen_helper_cmpu_le_qb(v1_t, v2_t, tcg_env);
12806 break;
12807 case OPC_CMPGU_EQ_QB:
12808 check_dsp(ctx);
12809 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
12810 break;
12811 case OPC_CMPGU_LT_QB:
12812 check_dsp(ctx);
12813 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
12814 break;
12815 case OPC_CMPGU_LE_QB:
12816 check_dsp(ctx);
12817 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
12818 break;
12819 case OPC_CMPGDU_EQ_QB:
12820 check_dsp_r2(ctx);
12821 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
12822 tcg_gen_mov_tl(cpu_gpr[ret], t1);
12823 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12824 tcg_gen_shli_tl(t1, t1, 24);
12825 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12826 break;
12827 case OPC_CMPGDU_LT_QB:
12828 check_dsp_r2(ctx);
12829 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
12830 tcg_gen_mov_tl(cpu_gpr[ret], t1);
12831 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12832 tcg_gen_shli_tl(t1, t1, 24);
12833 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12834 break;
12835 case OPC_CMPGDU_LE_QB:
12836 check_dsp_r2(ctx);
12837 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
12838 tcg_gen_mov_tl(cpu_gpr[ret], t1);
12839 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
12840 tcg_gen_shli_tl(t1, t1, 24);
12841 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
12842 break;
12843 case OPC_CMP_EQ_PH:
12844 check_dsp(ctx);
12845 gen_helper_cmp_eq_ph(v1_t, v2_t, tcg_env);
12846 break;
12847 case OPC_CMP_LT_PH:
12848 check_dsp(ctx);
12849 gen_helper_cmp_lt_ph(v1_t, v2_t, tcg_env);
12850 break;
12851 case OPC_CMP_LE_PH:
12852 check_dsp(ctx);
12853 gen_helper_cmp_le_ph(v1_t, v2_t, tcg_env);
12854 break;
12855 case OPC_PICK_QB:
12856 check_dsp(ctx);
12857 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12858 break;
12859 case OPC_PICK_PH:
12860 check_dsp(ctx);
12861 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12862 break;
12863 case OPC_PACKRL_PH:
12864 check_dsp(ctx);
12865 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
12866 break;
12867 }
12868 break;
12869 #ifdef TARGET_MIPS64
12870 case OPC_CMPU_EQ_OB_DSP:
12871 switch (op2) {
12872 case OPC_CMP_EQ_PW:
12873 check_dsp(ctx);
12874 gen_helper_cmp_eq_pw(v1_t, v2_t, tcg_env);
12875 break;
12876 case OPC_CMP_LT_PW:
12877 check_dsp(ctx);
12878 gen_helper_cmp_lt_pw(v1_t, v2_t, tcg_env);
12879 break;
12880 case OPC_CMP_LE_PW:
12881 check_dsp(ctx);
12882 gen_helper_cmp_le_pw(v1_t, v2_t, tcg_env);
12883 break;
12884 case OPC_CMP_EQ_QH:
12885 check_dsp(ctx);
12886 gen_helper_cmp_eq_qh(v1_t, v2_t, tcg_env);
12887 break;
12888 case OPC_CMP_LT_QH:
12889 check_dsp(ctx);
12890 gen_helper_cmp_lt_qh(v1_t, v2_t, tcg_env);
12891 break;
12892 case OPC_CMP_LE_QH:
12893 check_dsp(ctx);
12894 gen_helper_cmp_le_qh(v1_t, v2_t, tcg_env);
12895 break;
12896 case OPC_CMPGDU_EQ_OB:
12897 check_dsp_r2(ctx);
12898 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12899 break;
12900 case OPC_CMPGDU_LT_OB:
12901 check_dsp_r2(ctx);
12902 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12903 break;
12904 case OPC_CMPGDU_LE_OB:
12905 check_dsp_r2(ctx);
12906 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12907 break;
12908 case OPC_CMPGU_EQ_OB:
12909 check_dsp(ctx);
12910 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
12911 break;
12912 case OPC_CMPGU_LT_OB:
12913 check_dsp(ctx);
12914 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
12915 break;
12916 case OPC_CMPGU_LE_OB:
12917 check_dsp(ctx);
12918 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
12919 break;
12920 case OPC_CMPU_EQ_OB:
12921 check_dsp(ctx);
12922 gen_helper_cmpu_eq_ob(v1_t, v2_t, tcg_env);
12923 break;
12924 case OPC_CMPU_LT_OB:
12925 check_dsp(ctx);
12926 gen_helper_cmpu_lt_ob(v1_t, v2_t, tcg_env);
12927 break;
12928 case OPC_CMPU_LE_OB:
12929 check_dsp(ctx);
12930 gen_helper_cmpu_le_ob(v1_t, v2_t, tcg_env);
12931 break;
12932 case OPC_PACKRL_PW:
12933 check_dsp(ctx);
12934 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
12935 break;
12936 case OPC_PICK_OB:
12937 check_dsp(ctx);
12938 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12939 break;
12940 case OPC_PICK_PW:
12941 check_dsp(ctx);
12942 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12943 break;
12944 case OPC_PICK_QH:
12945 check_dsp(ctx);
12946 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, tcg_env);
12947 break;
12948 }
12949 break;
12950 #endif
12951 }
12952 }
12953
12954 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
12955 uint32_t op1, int rt, int rs, int sa)
12956 {
12957 TCGv t0;
12958
12959 check_dsp_r2(ctx);
12960
12961 if (rt == 0) {
12962 /* Treat as NOP. */
12963 return;
12964 }
12965
12966 t0 = tcg_temp_new();
12967 gen_load_gpr(t0, rs);
12968
12969 switch (op1) {
12970 case OPC_APPEND_DSP:
12971 switch (MASK_APPEND(ctx->opcode)) {
12972 case OPC_APPEND:
12973 if (sa != 0) {
12974 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
12975 }
12976 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12977 break;
12978 case OPC_PREPEND:
12979 if (sa != 0) {
12980 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
12981 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
12982 tcg_gen_shli_tl(t0, t0, 32 - sa);
12983 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12984 }
12985 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12986 break;
12987 case OPC_BALIGN:
12988 sa &= 3;
12989 if (sa != 0 && sa != 2) {
12990 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
12991 tcg_gen_ext32u_tl(t0, t0);
12992 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
12993 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
12994 }
12995 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
12996 break;
12997 default: /* Invalid */
12998 MIPS_INVAL("MASK APPEND");
12999 gen_reserved_instruction(ctx);
13000 break;
13001 }
13002 break;
13003 #ifdef TARGET_MIPS64
13004 case OPC_DAPPEND_DSP:
13005 switch (MASK_DAPPEND(ctx->opcode)) {
13006 case OPC_DAPPEND:
13007 if (sa != 0) {
13008 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13009 }
13010 break;
13011 case OPC_PREPENDD:
13012 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13013 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13014 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
13015 break;
13016 case OPC_PREPENDW:
13017 if (sa != 0) {
13018 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13019 tcg_gen_shli_tl(t0, t0, 64 - sa);
13020 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13021 }
13022 break;
13023 case OPC_DBALIGN:
13024 sa &= 7;
13025 if (sa != 0 && sa != 2 && sa != 4) {
13026 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13027 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13028 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13029 }
13030 break;
13031 default: /* Invalid */
13032 MIPS_INVAL("MASK DAPPEND");
13033 gen_reserved_instruction(ctx);
13034 break;
13035 }
13036 break;
13037 #endif
13038 }
13039 }
13040
13041 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13042 int ret, int v1, int v2, int check_ret)
13043
13044 {
13045 TCGv t0;
13046 TCGv t1;
13047 TCGv v1_t;
13048 int16_t imm;
13049
13050 if ((ret == 0) && (check_ret == 1)) {
13051 /* Treat as NOP. */
13052 return;
13053 }
13054
13055 t0 = tcg_temp_new();
13056 t1 = tcg_temp_new();
13057 v1_t = tcg_temp_new();
13058
13059 gen_load_gpr(v1_t, v1);
13060
13061 switch (op1) {
13062 case OPC_EXTR_W_DSP:
13063 check_dsp(ctx);
13064 switch (op2) {
13065 case OPC_EXTR_W:
13066 tcg_gen_movi_tl(t0, v2);
13067 tcg_gen_movi_tl(t1, v1);
13068 gen_helper_extr_w(cpu_gpr[ret], t0, t1, tcg_env);
13069 break;
13070 case OPC_EXTR_R_W:
13071 tcg_gen_movi_tl(t0, v2);
13072 tcg_gen_movi_tl(t1, v1);
13073 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, tcg_env);
13074 break;
13075 case OPC_EXTR_RS_W:
13076 tcg_gen_movi_tl(t0, v2);
13077 tcg_gen_movi_tl(t1, v1);
13078 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, tcg_env);
13079 break;
13080 case OPC_EXTR_S_H:
13081 tcg_gen_movi_tl(t0, v2);
13082 tcg_gen_movi_tl(t1, v1);
13083 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, tcg_env);
13084 break;
13085 case OPC_EXTRV_S_H:
13086 tcg_gen_movi_tl(t0, v2);
13087 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env);
13088 break;
13089 case OPC_EXTRV_W:
13090 tcg_gen_movi_tl(t0, v2);
13091 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13092 break;
13093 case OPC_EXTRV_R_W:
13094 tcg_gen_movi_tl(t0, v2);
13095 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13096 break;
13097 case OPC_EXTRV_RS_W:
13098 tcg_gen_movi_tl(t0, v2);
13099 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13100 break;
13101 case OPC_EXTP:
13102 tcg_gen_movi_tl(t0, v2);
13103 tcg_gen_movi_tl(t1, v1);
13104 gen_helper_extp(cpu_gpr[ret], t0, t1, tcg_env);
13105 break;
13106 case OPC_EXTPV:
13107 tcg_gen_movi_tl(t0, v2);
13108 gen_helper_extp(cpu_gpr[ret], t0, v1_t, tcg_env);
13109 break;
13110 case OPC_EXTPDP:
13111 tcg_gen_movi_tl(t0, v2);
13112 tcg_gen_movi_tl(t1, v1);
13113 gen_helper_extpdp(cpu_gpr[ret], t0, t1, tcg_env);
13114 break;
13115 case OPC_EXTPDPV:
13116 tcg_gen_movi_tl(t0, v2);
13117 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, tcg_env);
13118 break;
13119 case OPC_SHILO:
13120 imm = (ctx->opcode >> 20) & 0x3F;
13121 tcg_gen_movi_tl(t0, ret);
13122 tcg_gen_movi_tl(t1, imm);
13123 gen_helper_shilo(t0, t1, tcg_env);
13124 break;
13125 case OPC_SHILOV:
13126 tcg_gen_movi_tl(t0, ret);
13127 gen_helper_shilo(t0, v1_t, tcg_env);
13128 break;
13129 case OPC_MTHLIP:
13130 tcg_gen_movi_tl(t0, ret);
13131 gen_helper_mthlip(t0, v1_t, tcg_env);
13132 break;
13133 case OPC_WRDSP:
13134 imm = (ctx->opcode >> 11) & 0x3FF;
13135 tcg_gen_movi_tl(t0, imm);
13136 gen_helper_wrdsp(v1_t, t0, tcg_env);
13137 break;
13138 case OPC_RDDSP:
13139 imm = (ctx->opcode >> 16) & 0x03FF;
13140 tcg_gen_movi_tl(t0, imm);
13141 gen_helper_rddsp(cpu_gpr[ret], t0, tcg_env);
13142 break;
13143 }
13144 break;
13145 #ifdef TARGET_MIPS64
13146 case OPC_DEXTR_W_DSP:
13147 check_dsp(ctx);
13148 switch (op2) {
13149 case OPC_DMTHLIP:
13150 tcg_gen_movi_tl(t0, ret);
13151 gen_helper_dmthlip(v1_t, t0, tcg_env);
13152 break;
13153 case OPC_DSHILO:
13154 {
13155 int shift = (ctx->opcode >> 19) & 0x7F;
13156 int ac = (ctx->opcode >> 11) & 0x03;
13157 tcg_gen_movi_tl(t0, shift);
13158 tcg_gen_movi_tl(t1, ac);
13159 gen_helper_dshilo(t0, t1, tcg_env);
13160 break;
13161 }
13162 case OPC_DSHILOV:
13163 {
13164 int ac = (ctx->opcode >> 11) & 0x03;
13165 tcg_gen_movi_tl(t0, ac);
13166 gen_helper_dshilo(v1_t, t0, tcg_env);
13167 break;
13168 }
13169 case OPC_DEXTP:
13170 tcg_gen_movi_tl(t0, v2);
13171 tcg_gen_movi_tl(t1, v1);
13172
13173 gen_helper_dextp(cpu_gpr[ret], t0, t1, tcg_env);
13174 break;
13175 case OPC_DEXTPV:
13176 tcg_gen_movi_tl(t0, v2);
13177 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, tcg_env);
13178 break;
13179 case OPC_DEXTPDP:
13180 tcg_gen_movi_tl(t0, v2);
13181 tcg_gen_movi_tl(t1, v1);
13182 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, tcg_env);
13183 break;
13184 case OPC_DEXTPDPV:
13185 tcg_gen_movi_tl(t0, v2);
13186 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, tcg_env);
13187 break;
13188 case OPC_DEXTR_L:
13189 tcg_gen_movi_tl(t0, v2);
13190 tcg_gen_movi_tl(t1, v1);
13191 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, tcg_env);
13192 break;
13193 case OPC_DEXTR_R_L:
13194 tcg_gen_movi_tl(t0, v2);
13195 tcg_gen_movi_tl(t1, v1);
13196 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, tcg_env);
13197 break;
13198 case OPC_DEXTR_RS_L:
13199 tcg_gen_movi_tl(t0, v2);
13200 tcg_gen_movi_tl(t1, v1);
13201 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, tcg_env);
13202 break;
13203 case OPC_DEXTR_W:
13204 tcg_gen_movi_tl(t0, v2);
13205 tcg_gen_movi_tl(t1, v1);
13206 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, tcg_env);
13207 break;
13208 case OPC_DEXTR_R_W:
13209 tcg_gen_movi_tl(t0, v2);
13210 tcg_gen_movi_tl(t1, v1);
13211 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, tcg_env);
13212 break;
13213 case OPC_DEXTR_RS_W:
13214 tcg_gen_movi_tl(t0, v2);
13215 tcg_gen_movi_tl(t1, v1);
13216 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, tcg_env);
13217 break;
13218 case OPC_DEXTR_S_H:
13219 tcg_gen_movi_tl(t0, v2);
13220 tcg_gen_movi_tl(t1, v1);
13221 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, tcg_env);
13222 break;
13223 case OPC_DEXTRV_S_H:
13224 tcg_gen_movi_tl(t0, v2);
13225 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, tcg_env);
13226 break;
13227 case OPC_DEXTRV_L:
13228 tcg_gen_movi_tl(t0, v2);
13229 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, tcg_env);
13230 break;
13231 case OPC_DEXTRV_R_L:
13232 tcg_gen_movi_tl(t0, v2);
13233 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, tcg_env);
13234 break;
13235 case OPC_DEXTRV_RS_L:
13236 tcg_gen_movi_tl(t0, v2);
13237 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, tcg_env);
13238 break;
13239 case OPC_DEXTRV_W:
13240 tcg_gen_movi_tl(t0, v2);
13241 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13242 break;
13243 case OPC_DEXTRV_R_W:
13244 tcg_gen_movi_tl(t0, v2);
13245 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13246 break;
13247 case OPC_DEXTRV_RS_W:
13248 tcg_gen_movi_tl(t0, v2);
13249 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, tcg_env);
13250 break;
13251 }
13252 break;
13253 #endif
13254 }
13255 }
13256
13257 /* End MIPSDSP functions. */
13258
13259 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13260 {
13261 int rs, rt, rd, sa;
13262 uint32_t op1, op2;
13263
13264 rs = (ctx->opcode >> 21) & 0x1f;
13265 rt = (ctx->opcode >> 16) & 0x1f;
13266 rd = (ctx->opcode >> 11) & 0x1f;
13267 sa = (ctx->opcode >> 6) & 0x1f;
13268
13269 op1 = MASK_SPECIAL(ctx->opcode);
13270 switch (op1) {
13271 case OPC_MULT:
13272 case OPC_MULTU:
13273 case OPC_DIV:
13274 case OPC_DIVU:
13275 op2 = MASK_R6_MULDIV(ctx->opcode);
13276 switch (op2) {
13277 case R6_OPC_MUL:
13278 case R6_OPC_MUH:
13279 case R6_OPC_MULU:
13280 case R6_OPC_MUHU:
13281 case R6_OPC_DIV:
13282 case R6_OPC_MOD:
13283 case R6_OPC_DIVU:
13284 case R6_OPC_MODU:
13285 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13286 break;
13287 default:
13288 MIPS_INVAL("special_r6 muldiv");
13289 gen_reserved_instruction(ctx);
13290 break;
13291 }
13292 break;
13293 case OPC_SELEQZ:
13294 case OPC_SELNEZ:
13295 gen_cond_move(ctx, op1, rd, rs, rt);
13296 break;
13297 case R6_OPC_CLO:
13298 case R6_OPC_CLZ:
13299 if (rt == 0 && sa == 1) {
13300 /*
13301 * Major opcode and function field is shared with preR6 MFHI/MTHI.
13302 * We need additionally to check other fields.
13303 */
13304 gen_cl(ctx, op1, rd, rs);
13305 } else {
13306 gen_reserved_instruction(ctx);
13307 }
13308 break;
13309 case R6_OPC_SDBBP:
13310 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13311 ctx->base.is_jmp = DISAS_SEMIHOST;
13312 } else {
13313 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13314 gen_reserved_instruction(ctx);
13315 } else {
13316 generate_exception_end(ctx, EXCP_DBp);
13317 }
13318 }
13319 break;
13320 #if defined(TARGET_MIPS64)
13321 case R6_OPC_DCLO:
13322 case R6_OPC_DCLZ:
13323 if (rt == 0 && sa == 1) {
13324 /*
13325 * Major opcode and function field is shared with preR6 MFHI/MTHI.
13326 * We need additionally to check other fields.
13327 */
13328 check_mips_64(ctx);
13329 gen_cl(ctx, op1, rd, rs);
13330 } else {
13331 gen_reserved_instruction(ctx);
13332 }
13333 break;
13334 case OPC_DMULT:
13335 case OPC_DMULTU:
13336 case OPC_DDIV:
13337 case OPC_DDIVU:
13338
13339 op2 = MASK_R6_MULDIV(ctx->opcode);
13340 switch (op2) {
13341 case R6_OPC_DMUL:
13342 case R6_OPC_DMUH:
13343 case R6_OPC_DMULU:
13344 case R6_OPC_DMUHU:
13345 case R6_OPC_DDIV:
13346 case R6_OPC_DMOD:
13347 case R6_OPC_DDIVU:
13348 case R6_OPC_DMODU:
13349 check_mips_64(ctx);
13350 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13351 break;
13352 default:
13353 MIPS_INVAL("special_r6 muldiv");
13354 gen_reserved_instruction(ctx);
13355 break;
13356 }
13357 break;
13358 #endif
13359 default: /* Invalid */
13360 MIPS_INVAL("special_r6");
13361 gen_reserved_instruction(ctx);
13362 break;
13363 }
13364 }
13365
13366 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13367 {
13368 int rs = extract32(ctx->opcode, 21, 5);
13369 int rt = extract32(ctx->opcode, 16, 5);
13370 int rd = extract32(ctx->opcode, 11, 5);
13371 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13372
13373 switch (op1) {
13374 case OPC_MOVN: /* Conditional move */
13375 case OPC_MOVZ:
13376 gen_cond_move(ctx, op1, rd, rs, rt);
13377 break;
13378 case OPC_MFHI: /* Move from HI/LO */
13379 case OPC_MFLO:
13380 gen_HILO(ctx, op1, 0, rd);
13381 break;
13382 case OPC_MTHI:
13383 case OPC_MTLO: /* Move to HI/LO */
13384 gen_HILO(ctx, op1, 0, rs);
13385 break;
13386 case OPC_MULT:
13387 case OPC_MULTU:
13388 gen_mul_txx9(ctx, op1, rd, rs, rt);
13389 break;
13390 case OPC_DIV:
13391 case OPC_DIVU:
13392 gen_muldiv(ctx, op1, 0, rs, rt);
13393 break;
13394 #if defined(TARGET_MIPS64)
13395 case OPC_DMULT:
13396 case OPC_DMULTU:
13397 case OPC_DDIV:
13398 case OPC_DDIVU:
13399 check_insn_opc_user_only(ctx, INSN_R5900);
13400 gen_muldiv(ctx, op1, 0, rs, rt);
13401 break;
13402 #endif
13403 case OPC_JR:
13404 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13405 break;
13406 default: /* Invalid */
13407 MIPS_INVAL("special_tx79");
13408 gen_reserved_instruction(ctx);
13409 break;
13410 }
13411 }
13412
13413 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
13414 {
13415 int rs, rt, rd;
13416 uint32_t op1;
13417
13418 rs = (ctx->opcode >> 21) & 0x1f;
13419 rt = (ctx->opcode >> 16) & 0x1f;
13420 rd = (ctx->opcode >> 11) & 0x1f;
13421
13422 op1 = MASK_SPECIAL(ctx->opcode);
13423 switch (op1) {
13424 case OPC_MOVN: /* Conditional move */
13425 case OPC_MOVZ:
13426 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
13427 INSN_LOONGSON2E | INSN_LOONGSON2F);
13428 gen_cond_move(ctx, op1, rd, rs, rt);
13429 break;
13430 case OPC_MFHI: /* Move from HI/LO */
13431 case OPC_MFLO:
13432 gen_HILO(ctx, op1, rs & 3, rd);
13433 break;
13434 case OPC_MTHI:
13435 case OPC_MTLO: /* Move to HI/LO */
13436 gen_HILO(ctx, op1, rd & 3, rs);
13437 break;
13438 case OPC_MOVCI:
13439 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
13440 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13441 check_cp1_enabled(ctx);
13442 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
13443 (ctx->opcode >> 16) & 1);
13444 } else {
13445 generate_exception_err(ctx, EXCP_CpU, 1);
13446 }
13447 break;
13448 case OPC_MULT:
13449 case OPC_MULTU:
13450 gen_muldiv(ctx, op1, rd & 3, rs, rt);
13451 break;
13452 case OPC_DIV:
13453 case OPC_DIVU:
13454 gen_muldiv(ctx, op1, 0, rs, rt);
13455 break;
13456 #if defined(TARGET_MIPS64)
13457 case OPC_DMULT:
13458 case OPC_DMULTU:
13459 case OPC_DDIV:
13460 case OPC_DDIVU:
13461 check_insn(ctx, ISA_MIPS3);
13462 check_mips_64(ctx);
13463 gen_muldiv(ctx, op1, 0, rs, rt);
13464 break;
13465 #endif
13466 case OPC_JR:
13467 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13468 break;
13469 case OPC_SPIM:
13470 #ifdef MIPS_STRICT_STANDARD
13471 MIPS_INVAL("SPIM");
13472 gen_reserved_instruction(ctx);
13473 #else
13474 /* Implemented as RI exception for now. */
13475 MIPS_INVAL("spim (unofficial)");
13476 gen_reserved_instruction(ctx);
13477 #endif
13478 break;
13479 default: /* Invalid */
13480 MIPS_INVAL("special_legacy");
13481 gen_reserved_instruction(ctx);
13482 break;
13483 }
13484 }
13485
13486 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
13487 {
13488 int rs, rt, rd, sa;
13489 uint32_t op1;
13490
13491 rs = (ctx->opcode >> 21) & 0x1f;
13492 rt = (ctx->opcode >> 16) & 0x1f;
13493 rd = (ctx->opcode >> 11) & 0x1f;
13494 sa = (ctx->opcode >> 6) & 0x1f;
13495
13496 op1 = MASK_SPECIAL(ctx->opcode);
13497 switch (op1) {
13498 case OPC_SLL: /* Shift with immediate */
13499 if (sa == 5 && rd == 0 &&
13500 rs == 0 && rt == 0) { /* PAUSE */
13501 if ((ctx->insn_flags & ISA_MIPS_R6) &&
13502 (ctx->hflags & MIPS_HFLAG_BMASK)) {
13503 gen_reserved_instruction(ctx);
13504 break;
13505 }
13506 }
13507 /* Fallthrough */
13508 case OPC_SRA:
13509 gen_shift_imm(ctx, op1, rd, rt, sa);
13510 break;
13511 case OPC_SRL:
13512 switch ((ctx->opcode >> 21) & 0x1f) {
13513 case 1:
13514 /* rotr is decoded as srl on non-R2 CPUs */
13515 if (ctx->insn_flags & ISA_MIPS_R2) {
13516 op1 = OPC_ROTR;
13517 }
13518 /* Fallthrough */
13519 case 0:
13520 gen_shift_imm(ctx, op1, rd, rt, sa);
13521 break;
13522 default:
13523 gen_reserved_instruction(ctx);
13524 break;
13525 }
13526 break;
13527 case OPC_ADD:
13528 case OPC_ADDU:
13529 case OPC_SUB:
13530 case OPC_SUBU:
13531 gen_arith(ctx, op1, rd, rs, rt);
13532 break;
13533 case OPC_SLLV: /* Shifts */
13534 case OPC_SRAV:
13535 gen_shift(ctx, op1, rd, rs, rt);
13536 break;
13537 case OPC_SRLV:
13538 switch ((ctx->opcode >> 6) & 0x1f) {
13539 case 1:
13540 /* rotrv is decoded as srlv on non-R2 CPUs */
13541 if (ctx->insn_flags & ISA_MIPS_R2) {
13542 op1 = OPC_ROTRV;
13543 }
13544 /* Fallthrough */
13545 case 0:
13546 gen_shift(ctx, op1, rd, rs, rt);
13547 break;
13548 default:
13549 gen_reserved_instruction(ctx);
13550 break;
13551 }
13552 break;
13553 case OPC_SLT: /* Set on less than */
13554 case OPC_SLTU:
13555 gen_slt(ctx, op1, rd, rs, rt);
13556 break;
13557 case OPC_AND: /* Logic*/
13558 case OPC_OR:
13559 case OPC_NOR:
13560 case OPC_XOR:
13561 gen_logic(ctx, op1, rd, rs, rt);
13562 break;
13563 case OPC_JALR:
13564 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
13565 break;
13566 case OPC_TGE: /* Traps */
13567 case OPC_TGEU:
13568 case OPC_TLT:
13569 case OPC_TLTU:
13570 case OPC_TEQ:
13571 case OPC_TNE:
13572 check_insn(ctx, ISA_MIPS2);
13573 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
13574 break;
13575 case OPC_PMON:
13576 /* Pmon entry point, also R4010 selsl */
13577 #ifdef MIPS_STRICT_STANDARD
13578 MIPS_INVAL("PMON / selsl");
13579 gen_reserved_instruction(ctx);
13580 #else
13581 gen_helper_pmon(tcg_env, tcg_constant_i32(sa));
13582 #endif
13583 break;
13584 case OPC_SYSCALL:
13585 generate_exception_end(ctx, EXCP_SYSCALL);
13586 break;
13587 case OPC_BREAK:
13588 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
13589 break;
13590 case OPC_SYNC:
13591 check_insn(ctx, ISA_MIPS2);
13592 gen_sync(extract32(ctx->opcode, 6, 5));
13593 break;
13594
13595 #if defined(TARGET_MIPS64)
13596 /* MIPS64 specific opcodes */
13597 case OPC_DSLL:
13598 case OPC_DSRA:
13599 case OPC_DSLL32:
13600 case OPC_DSRA32:
13601 check_insn(ctx, ISA_MIPS3);
13602 check_mips_64(ctx);
13603 gen_shift_imm(ctx, op1, rd, rt, sa);
13604 break;
13605 case OPC_DSRL:
13606 switch ((ctx->opcode >> 21) & 0x1f) {
13607 case 1:
13608 /* drotr is decoded as dsrl on non-R2 CPUs */
13609 if (ctx->insn_flags & ISA_MIPS_R2) {
13610 op1 = OPC_DROTR;
13611 }
13612 /* Fallthrough */
13613 case 0:
13614 check_insn(ctx, ISA_MIPS3);
13615 check_mips_64(ctx);
13616 gen_shift_imm(ctx, op1, rd, rt, sa);
13617 break;
13618 default:
13619 gen_reserved_instruction(ctx);
13620 break;
13621 }
13622 break;
13623 case OPC_DSRL32:
13624 switch ((ctx->opcode >> 21) & 0x1f) {
13625 case 1:
13626 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
13627 if (ctx->insn_flags & ISA_MIPS_R2) {
13628 op1 = OPC_DROTR32;
13629 }
13630 /* Fallthrough */
13631 case 0:
13632 check_insn(ctx, ISA_MIPS3);
13633 check_mips_64(ctx);
13634 gen_shift_imm(ctx, op1, rd, rt, sa);
13635 break;
13636 default:
13637 gen_reserved_instruction(ctx);
13638 break;
13639 }
13640 break;
13641 case OPC_DADD:
13642 case OPC_DADDU:
13643 case OPC_DSUB:
13644 case OPC_DSUBU:
13645 check_insn(ctx, ISA_MIPS3);
13646 check_mips_64(ctx);
13647 gen_arith(ctx, op1, rd, rs, rt);
13648 break;
13649 case OPC_DSLLV:
13650 case OPC_DSRAV:
13651 check_insn(ctx, ISA_MIPS3);
13652 check_mips_64(ctx);
13653 gen_shift(ctx, op1, rd, rs, rt);
13654 break;
13655 case OPC_DSRLV:
13656 switch ((ctx->opcode >> 6) & 0x1f) {
13657 case 1:
13658 /* drotrv is decoded as dsrlv on non-R2 CPUs */
13659 if (ctx->insn_flags & ISA_MIPS_R2) {
13660 op1 = OPC_DROTRV;
13661 }
13662 /* Fallthrough */
13663 case 0:
13664 check_insn(ctx, ISA_MIPS3);
13665 check_mips_64(ctx);
13666 gen_shift(ctx, op1, rd, rs, rt);
13667 break;
13668 default:
13669 gen_reserved_instruction(ctx);
13670 break;
13671 }
13672 break;
13673 #endif
13674 default:
13675 if (ctx->insn_flags & ISA_MIPS_R6) {
13676 decode_opc_special_r6(env, ctx);
13677 } else if (ctx->insn_flags & INSN_R5900) {
13678 decode_opc_special_tx79(env, ctx);
13679 } else {
13680 decode_opc_special_legacy(env, ctx);
13681 }
13682 }
13683 }
13684
13685
13686 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
13687 {
13688 int rs, rt, rd;
13689 uint32_t op1;
13690
13691 rs = (ctx->opcode >> 21) & 0x1f;
13692 rt = (ctx->opcode >> 16) & 0x1f;
13693 rd = (ctx->opcode >> 11) & 0x1f;
13694
13695 op1 = MASK_SPECIAL2(ctx->opcode);
13696 switch (op1) {
13697 case OPC_MADD: /* Multiply and add/sub */
13698 case OPC_MADDU:
13699 case OPC_MSUB:
13700 case OPC_MSUBU:
13701 check_insn(ctx, ISA_MIPS_R1);
13702 gen_muldiv(ctx, op1, rd & 3, rs, rt);
13703 break;
13704 case OPC_MUL:
13705 gen_arith(ctx, op1, rd, rs, rt);
13706 break;
13707 case OPC_DIV_G_2F:
13708 case OPC_DIVU_G_2F:
13709 case OPC_MULT_G_2F:
13710 case OPC_MULTU_G_2F:
13711 case OPC_MOD_G_2F:
13712 case OPC_MODU_G_2F:
13713 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
13714 gen_loongson_integer(ctx, op1, rd, rs, rt);
13715 break;
13716 case OPC_CLO:
13717 case OPC_CLZ:
13718 check_insn(ctx, ISA_MIPS_R1);
13719 gen_cl(ctx, op1, rd, rs);
13720 break;
13721 case OPC_SDBBP:
13722 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13723 ctx->base.is_jmp = DISAS_SEMIHOST;
13724 } else {
13725 /*
13726 * XXX: not clear which exception should be raised
13727 * when in debug mode...
13728 */
13729 check_insn(ctx, ISA_MIPS_R1);
13730 generate_exception_end(ctx, EXCP_DBp);
13731 }
13732 break;
13733 #if defined(TARGET_MIPS64)
13734 case OPC_DCLO:
13735 case OPC_DCLZ:
13736 check_insn(ctx, ISA_MIPS_R1);
13737 check_mips_64(ctx);
13738 gen_cl(ctx, op1, rd, rs);
13739 break;
13740 case OPC_DMULT_G_2F:
13741 case OPC_DMULTU_G_2F:
13742 case OPC_DDIV_G_2F:
13743 case OPC_DDIVU_G_2F:
13744 case OPC_DMOD_G_2F:
13745 case OPC_DMODU_G_2F:
13746 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
13747 gen_loongson_integer(ctx, op1, rd, rs, rt);
13748 break;
13749 #endif
13750 default: /* Invalid */
13751 MIPS_INVAL("special2_legacy");
13752 gen_reserved_instruction(ctx);
13753 break;
13754 }
13755 }
13756
13757 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
13758 {
13759 int rs, rt, rd, sa;
13760 uint32_t op1, op2;
13761 int16_t imm;
13762
13763 rs = (ctx->opcode >> 21) & 0x1f;
13764 rt = (ctx->opcode >> 16) & 0x1f;
13765 rd = (ctx->opcode >> 11) & 0x1f;
13766 sa = (ctx->opcode >> 6) & 0x1f;
13767 imm = (int16_t)ctx->opcode >> 7;
13768
13769 op1 = MASK_SPECIAL3(ctx->opcode);
13770 switch (op1) {
13771 case R6_OPC_PREF:
13772 if (rt >= 24) {
13773 /* hint codes 24-31 are reserved and signal RI */
13774 gen_reserved_instruction(ctx);
13775 }
13776 /* Treat as NOP. */
13777 break;
13778 case R6_OPC_CACHE:
13779 check_cp0_enabled(ctx);
13780 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13781 gen_cache_operation(ctx, rt, rs, imm);
13782 }
13783 break;
13784 case R6_OPC_SC:
13785 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
13786 break;
13787 case R6_OPC_LL:
13788 gen_ld(ctx, op1, rt, rs, imm);
13789 break;
13790 case OPC_BSHFL:
13791 {
13792 if (rd == 0) {
13793 /* Treat as NOP. */
13794 break;
13795 }
13796 op2 = MASK_BSHFL(ctx->opcode);
13797 switch (op2) {
13798 case OPC_ALIGN:
13799 case OPC_ALIGN_1:
13800 case OPC_ALIGN_2:
13801 case OPC_ALIGN_3:
13802 gen_align(ctx, 32, rd, rs, rt, sa & 3);
13803 break;
13804 case OPC_BITSWAP:
13805 gen_bitswap(ctx, op2, rd, rt);
13806 break;
13807 }
13808 }
13809 break;
13810 #ifndef CONFIG_USER_ONLY
13811 case OPC_GINV:
13812 if (unlikely(ctx->gi <= 1)) {
13813 gen_reserved_instruction(ctx);
13814 }
13815 check_cp0_enabled(ctx);
13816 switch ((ctx->opcode >> 6) & 3) {
13817 case 0: /* GINVI */
13818 /* Treat as NOP. */
13819 break;
13820 case 2: /* GINVT */
13821 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
13822 break;
13823 default:
13824 gen_reserved_instruction(ctx);
13825 break;
13826 }
13827 break;
13828 #endif
13829 #if defined(TARGET_MIPS64)
13830 case R6_OPC_SCD:
13831 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
13832 break;
13833 case R6_OPC_LLD:
13834 gen_ld(ctx, op1, rt, rs, imm);
13835 break;
13836 case OPC_DBSHFL:
13837 check_mips_64(ctx);
13838 {
13839 if (rd == 0) {
13840 /* Treat as NOP. */
13841 break;
13842 }
13843 op2 = MASK_DBSHFL(ctx->opcode);
13844 switch (op2) {
13845 case OPC_DALIGN:
13846 case OPC_DALIGN_1:
13847 case OPC_DALIGN_2:
13848 case OPC_DALIGN_3:
13849 case OPC_DALIGN_4:
13850 case OPC_DALIGN_5:
13851 case OPC_DALIGN_6:
13852 case OPC_DALIGN_7:
13853 gen_align(ctx, 64, rd, rs, rt, sa & 7);
13854 break;
13855 case OPC_DBITSWAP:
13856 gen_bitswap(ctx, op2, rd, rt);
13857 break;
13858 }
13859
13860 }
13861 break;
13862 #endif
13863 default: /* Invalid */
13864 MIPS_INVAL("special3_r6");
13865 gen_reserved_instruction(ctx);
13866 break;
13867 }
13868 }
13869
13870 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
13871 {
13872 int rs, rt, rd;
13873 uint32_t op1, op2;
13874
13875 rs = (ctx->opcode >> 21) & 0x1f;
13876 rt = (ctx->opcode >> 16) & 0x1f;
13877 rd = (ctx->opcode >> 11) & 0x1f;
13878
13879 op1 = MASK_SPECIAL3(ctx->opcode);
13880 switch (op1) {
13881 case OPC_DIV_G_2E:
13882 case OPC_DIVU_G_2E:
13883 case OPC_MOD_G_2E:
13884 case OPC_MODU_G_2E:
13885 case OPC_MULT_G_2E:
13886 case OPC_MULTU_G_2E:
13887 /*
13888 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13889 * the same mask and op1.
13890 */
13891 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
13892 op2 = MASK_ADDUH_QB(ctx->opcode);
13893 switch (op2) {
13894 case OPC_ADDUH_QB:
13895 case OPC_ADDUH_R_QB:
13896 case OPC_ADDQH_PH:
13897 case OPC_ADDQH_R_PH:
13898 case OPC_ADDQH_W:
13899 case OPC_ADDQH_R_W:
13900 case OPC_SUBUH_QB:
13901 case OPC_SUBUH_R_QB:
13902 case OPC_SUBQH_PH:
13903 case OPC_SUBQH_R_PH:
13904 case OPC_SUBQH_W:
13905 case OPC_SUBQH_R_W:
13906 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13907 break;
13908 case OPC_MUL_PH:
13909 case OPC_MUL_S_PH:
13910 case OPC_MULQ_S_W:
13911 case OPC_MULQ_RS_W:
13912 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
13913 break;
13914 default:
13915 MIPS_INVAL("MASK ADDUH.QB");
13916 gen_reserved_instruction(ctx);
13917 break;
13918 }
13919 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
13920 gen_loongson_integer(ctx, op1, rd, rs, rt);
13921 } else {
13922 gen_reserved_instruction(ctx);
13923 }
13924 break;
13925 case OPC_LX_DSP:
13926 op2 = MASK_LX(ctx->opcode);
13927 switch (op2) {
13928 #if defined(TARGET_MIPS64)
13929 case OPC_LDX:
13930 #endif
13931 case OPC_LBUX:
13932 case OPC_LHX:
13933 case OPC_LWX:
13934 gen_mips_lx(ctx, op2, rd, rs, rt);
13935 break;
13936 default: /* Invalid */
13937 MIPS_INVAL("MASK LX");
13938 gen_reserved_instruction(ctx);
13939 break;
13940 }
13941 break;
13942 case OPC_ABSQ_S_PH_DSP:
13943 op2 = MASK_ABSQ_S_PH(ctx->opcode);
13944 switch (op2) {
13945 case OPC_ABSQ_S_QB:
13946 case OPC_ABSQ_S_PH:
13947 case OPC_ABSQ_S_W:
13948 case OPC_PRECEQ_W_PHL:
13949 case OPC_PRECEQ_W_PHR:
13950 case OPC_PRECEQU_PH_QBL:
13951 case OPC_PRECEQU_PH_QBR:
13952 case OPC_PRECEQU_PH_QBLA:
13953 case OPC_PRECEQU_PH_QBRA:
13954 case OPC_PRECEU_PH_QBL:
13955 case OPC_PRECEU_PH_QBR:
13956 case OPC_PRECEU_PH_QBLA:
13957 case OPC_PRECEU_PH_QBRA:
13958 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13959 break;
13960 case OPC_BITREV:
13961 case OPC_REPL_QB:
13962 case OPC_REPLV_QB:
13963 case OPC_REPL_PH:
13964 case OPC_REPLV_PH:
13965 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
13966 break;
13967 default:
13968 MIPS_INVAL("MASK ABSQ_S.PH");
13969 gen_reserved_instruction(ctx);
13970 break;
13971 }
13972 break;
13973 case OPC_ADDU_QB_DSP:
13974 op2 = MASK_ADDU_QB(ctx->opcode);
13975 switch (op2) {
13976 case OPC_ADDQ_PH:
13977 case OPC_ADDQ_S_PH:
13978 case OPC_ADDQ_S_W:
13979 case OPC_ADDU_QB:
13980 case OPC_ADDU_S_QB:
13981 case OPC_ADDU_PH:
13982 case OPC_ADDU_S_PH:
13983 case OPC_SUBQ_PH:
13984 case OPC_SUBQ_S_PH:
13985 case OPC_SUBQ_S_W:
13986 case OPC_SUBU_QB:
13987 case OPC_SUBU_S_QB:
13988 case OPC_SUBU_PH:
13989 case OPC_SUBU_S_PH:
13990 case OPC_ADDSC:
13991 case OPC_ADDWC:
13992 case OPC_MODSUB:
13993 case OPC_RADDU_W_QB:
13994 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
13995 break;
13996 case OPC_MULEU_S_PH_QBL:
13997 case OPC_MULEU_S_PH_QBR:
13998 case OPC_MULQ_RS_PH:
13999 case OPC_MULEQ_S_W_PHL:
14000 case OPC_MULEQ_S_W_PHR:
14001 case OPC_MULQ_S_PH:
14002 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14003 break;
14004 default: /* Invalid */
14005 MIPS_INVAL("MASK ADDU.QB");
14006 gen_reserved_instruction(ctx);
14007 break;
14008
14009 }
14010 break;
14011 case OPC_CMPU_EQ_QB_DSP:
14012 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14013 switch (op2) {
14014 case OPC_PRECR_SRA_PH_W:
14015 case OPC_PRECR_SRA_R_PH_W:
14016 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14017 break;
14018 case OPC_PRECR_QB_PH:
14019 case OPC_PRECRQ_QB_PH:
14020 case OPC_PRECRQ_PH_W:
14021 case OPC_PRECRQ_RS_PH_W:
14022 case OPC_PRECRQU_S_QB_PH:
14023 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14024 break;
14025 case OPC_CMPU_EQ_QB:
14026 case OPC_CMPU_LT_QB:
14027 case OPC_CMPU_LE_QB:
14028 case OPC_CMP_EQ_PH:
14029 case OPC_CMP_LT_PH:
14030 case OPC_CMP_LE_PH:
14031 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14032 break;
14033 case OPC_CMPGU_EQ_QB:
14034 case OPC_CMPGU_LT_QB:
14035 case OPC_CMPGU_LE_QB:
14036 case OPC_CMPGDU_EQ_QB:
14037 case OPC_CMPGDU_LT_QB:
14038 case OPC_CMPGDU_LE_QB:
14039 case OPC_PICK_QB:
14040 case OPC_PICK_PH:
14041 case OPC_PACKRL_PH:
14042 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14043 break;
14044 default: /* Invalid */
14045 MIPS_INVAL("MASK CMPU.EQ.QB");
14046 gen_reserved_instruction(ctx);
14047 break;
14048 }
14049 break;
14050 case OPC_SHLL_QB_DSP:
14051 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14052 break;
14053 case OPC_DPA_W_PH_DSP:
14054 op2 = MASK_DPA_W_PH(ctx->opcode);
14055 switch (op2) {
14056 case OPC_DPAU_H_QBL:
14057 case OPC_DPAU_H_QBR:
14058 case OPC_DPSU_H_QBL:
14059 case OPC_DPSU_H_QBR:
14060 case OPC_DPA_W_PH:
14061 case OPC_DPAX_W_PH:
14062 case OPC_DPAQ_S_W_PH:
14063 case OPC_DPAQX_S_W_PH:
14064 case OPC_DPAQX_SA_W_PH:
14065 case OPC_DPS_W_PH:
14066 case OPC_DPSX_W_PH:
14067 case OPC_DPSQ_S_W_PH:
14068 case OPC_DPSQX_S_W_PH:
14069 case OPC_DPSQX_SA_W_PH:
14070 case OPC_MULSAQ_S_W_PH:
14071 case OPC_DPAQ_SA_L_W:
14072 case OPC_DPSQ_SA_L_W:
14073 case OPC_MAQ_S_W_PHL:
14074 case OPC_MAQ_S_W_PHR:
14075 case OPC_MAQ_SA_W_PHL:
14076 case OPC_MAQ_SA_W_PHR:
14077 case OPC_MULSA_W_PH:
14078 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14079 break;
14080 default: /* Invalid */
14081 MIPS_INVAL("MASK DPAW.PH");
14082 gen_reserved_instruction(ctx);
14083 break;
14084 }
14085 break;
14086 case OPC_INSV_DSP:
14087 op2 = MASK_INSV(ctx->opcode);
14088 switch (op2) {
14089 case OPC_INSV:
14090 check_dsp(ctx);
14091 {
14092 TCGv t0, t1;
14093
14094 if (rt == 0) {
14095 break;
14096 }
14097
14098 t0 = tcg_temp_new();
14099 t1 = tcg_temp_new();
14100
14101 gen_load_gpr(t0, rt);
14102 gen_load_gpr(t1, rs);
14103
14104 gen_helper_insv(cpu_gpr[rt], tcg_env, t1, t0);
14105 break;
14106 }
14107 default: /* Invalid */
14108 MIPS_INVAL("MASK INSV");
14109 gen_reserved_instruction(ctx);
14110 break;
14111 }
14112 break;
14113 case OPC_APPEND_DSP:
14114 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14115 break;
14116 case OPC_EXTR_W_DSP:
14117 op2 = MASK_EXTR_W(ctx->opcode);
14118 switch (op2) {
14119 case OPC_EXTR_W:
14120 case OPC_EXTR_R_W:
14121 case OPC_EXTR_RS_W:
14122 case OPC_EXTR_S_H:
14123 case OPC_EXTRV_S_H:
14124 case OPC_EXTRV_W:
14125 case OPC_EXTRV_R_W:
14126 case OPC_EXTRV_RS_W:
14127 case OPC_EXTP:
14128 case OPC_EXTPV:
14129 case OPC_EXTPDP:
14130 case OPC_EXTPDPV:
14131 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14132 break;
14133 case OPC_RDDSP:
14134 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14135 break;
14136 case OPC_SHILO:
14137 case OPC_SHILOV:
14138 case OPC_MTHLIP:
14139 case OPC_WRDSP:
14140 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14141 break;
14142 default: /* Invalid */
14143 MIPS_INVAL("MASK EXTR.W");
14144 gen_reserved_instruction(ctx);
14145 break;
14146 }
14147 break;
14148 #if defined(TARGET_MIPS64)
14149 case OPC_DDIV_G_2E:
14150 case OPC_DDIVU_G_2E:
14151 case OPC_DMULT_G_2E:
14152 case OPC_DMULTU_G_2E:
14153 case OPC_DMOD_G_2E:
14154 case OPC_DMODU_G_2E:
14155 check_insn(ctx, INSN_LOONGSON2E);
14156 gen_loongson_integer(ctx, op1, rd, rs, rt);
14157 break;
14158 case OPC_ABSQ_S_QH_DSP:
14159 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14160 switch (op2) {
14161 case OPC_PRECEQ_L_PWL:
14162 case OPC_PRECEQ_L_PWR:
14163 case OPC_PRECEQ_PW_QHL:
14164 case OPC_PRECEQ_PW_QHR:
14165 case OPC_PRECEQ_PW_QHLA:
14166 case OPC_PRECEQ_PW_QHRA:
14167 case OPC_PRECEQU_QH_OBL:
14168 case OPC_PRECEQU_QH_OBR:
14169 case OPC_PRECEQU_QH_OBLA:
14170 case OPC_PRECEQU_QH_OBRA:
14171 case OPC_PRECEU_QH_OBL:
14172 case OPC_PRECEU_QH_OBR:
14173 case OPC_PRECEU_QH_OBLA:
14174 case OPC_PRECEU_QH_OBRA:
14175 case OPC_ABSQ_S_OB:
14176 case OPC_ABSQ_S_PW:
14177 case OPC_ABSQ_S_QH:
14178 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14179 break;
14180 case OPC_REPL_OB:
14181 case OPC_REPL_PW:
14182 case OPC_REPL_QH:
14183 case OPC_REPLV_OB:
14184 case OPC_REPLV_PW:
14185 case OPC_REPLV_QH:
14186 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14187 break;
14188 default: /* Invalid */
14189 MIPS_INVAL("MASK ABSQ_S.QH");
14190 gen_reserved_instruction(ctx);
14191 break;
14192 }
14193 break;
14194 case OPC_ADDU_OB_DSP:
14195 op2 = MASK_ADDU_OB(ctx->opcode);
14196 switch (op2) {
14197 case OPC_RADDU_L_OB:
14198 case OPC_SUBQ_PW:
14199 case OPC_SUBQ_S_PW:
14200 case OPC_SUBQ_QH:
14201 case OPC_SUBQ_S_QH:
14202 case OPC_SUBU_OB:
14203 case OPC_SUBU_S_OB:
14204 case OPC_SUBU_QH:
14205 case OPC_SUBU_S_QH:
14206 case OPC_SUBUH_OB:
14207 case OPC_SUBUH_R_OB:
14208 case OPC_ADDQ_PW:
14209 case OPC_ADDQ_S_PW:
14210 case OPC_ADDQ_QH:
14211 case OPC_ADDQ_S_QH:
14212 case OPC_ADDU_OB:
14213 case OPC_ADDU_S_OB:
14214 case OPC_ADDU_QH:
14215 case OPC_ADDU_S_QH:
14216 case OPC_ADDUH_OB:
14217 case OPC_ADDUH_R_OB:
14218 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14219 break;
14220 case OPC_MULEQ_S_PW_QHL:
14221 case OPC_MULEQ_S_PW_QHR:
14222 case OPC_MULEU_S_QH_OBL:
14223 case OPC_MULEU_S_QH_OBR:
14224 case OPC_MULQ_RS_QH:
14225 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14226 break;
14227 default: /* Invalid */
14228 MIPS_INVAL("MASK ADDU.OB");
14229 gen_reserved_instruction(ctx);
14230 break;
14231 }
14232 break;
14233 case OPC_CMPU_EQ_OB_DSP:
14234 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14235 switch (op2) {
14236 case OPC_PRECR_SRA_QH_PW:
14237 case OPC_PRECR_SRA_R_QH_PW:
14238 /* Return value is rt. */
14239 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14240 break;
14241 case OPC_PRECR_OB_QH:
14242 case OPC_PRECRQ_OB_QH:
14243 case OPC_PRECRQ_PW_L:
14244 case OPC_PRECRQ_QH_PW:
14245 case OPC_PRECRQ_RS_QH_PW:
14246 case OPC_PRECRQU_S_OB_QH:
14247 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14248 break;
14249 case OPC_CMPU_EQ_OB:
14250 case OPC_CMPU_LT_OB:
14251 case OPC_CMPU_LE_OB:
14252 case OPC_CMP_EQ_QH:
14253 case OPC_CMP_LT_QH:
14254 case OPC_CMP_LE_QH:
14255 case OPC_CMP_EQ_PW:
14256 case OPC_CMP_LT_PW:
14257 case OPC_CMP_LE_PW:
14258 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14259 break;
14260 case OPC_CMPGDU_EQ_OB:
14261 case OPC_CMPGDU_LT_OB:
14262 case OPC_CMPGDU_LE_OB:
14263 case OPC_CMPGU_EQ_OB:
14264 case OPC_CMPGU_LT_OB:
14265 case OPC_CMPGU_LE_OB:
14266 case OPC_PACKRL_PW:
14267 case OPC_PICK_OB:
14268 case OPC_PICK_PW:
14269 case OPC_PICK_QH:
14270 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14271 break;
14272 default: /* Invalid */
14273 MIPS_INVAL("MASK CMPU_EQ.OB");
14274 gen_reserved_instruction(ctx);
14275 break;
14276 }
14277 break;
14278 case OPC_DAPPEND_DSP:
14279 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14280 break;
14281 case OPC_DEXTR_W_DSP:
14282 op2 = MASK_DEXTR_W(ctx->opcode);
14283 switch (op2) {
14284 case OPC_DEXTP:
14285 case OPC_DEXTPDP:
14286 case OPC_DEXTPDPV:
14287 case OPC_DEXTPV:
14288 case OPC_DEXTR_L:
14289 case OPC_DEXTR_R_L:
14290 case OPC_DEXTR_RS_L:
14291 case OPC_DEXTR_W:
14292 case OPC_DEXTR_R_W:
14293 case OPC_DEXTR_RS_W:
14294 case OPC_DEXTR_S_H:
14295 case OPC_DEXTRV_L:
14296 case OPC_DEXTRV_R_L:
14297 case OPC_DEXTRV_RS_L:
14298 case OPC_DEXTRV_S_H:
14299 case OPC_DEXTRV_W:
14300 case OPC_DEXTRV_R_W:
14301 case OPC_DEXTRV_RS_W:
14302 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14303 break;
14304 case OPC_DMTHLIP:
14305 case OPC_DSHILO:
14306 case OPC_DSHILOV:
14307 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14308 break;
14309 default: /* Invalid */
14310 MIPS_INVAL("MASK EXTR.W");
14311 gen_reserved_instruction(ctx);
14312 break;
14313 }
14314 break;
14315 case OPC_DPAQ_W_QH_DSP:
14316 op2 = MASK_DPAQ_W_QH(ctx->opcode);
14317 switch (op2) {
14318 case OPC_DPAU_H_OBL:
14319 case OPC_DPAU_H_OBR:
14320 case OPC_DPSU_H_OBL:
14321 case OPC_DPSU_H_OBR:
14322 case OPC_DPA_W_QH:
14323 case OPC_DPAQ_S_W_QH:
14324 case OPC_DPS_W_QH:
14325 case OPC_DPSQ_S_W_QH:
14326 case OPC_MULSAQ_S_W_QH:
14327 case OPC_DPAQ_SA_L_PW:
14328 case OPC_DPSQ_SA_L_PW:
14329 case OPC_MULSAQ_S_L_PW:
14330 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14331 break;
14332 case OPC_MAQ_S_W_QHLL:
14333 case OPC_MAQ_S_W_QHLR:
14334 case OPC_MAQ_S_W_QHRL:
14335 case OPC_MAQ_S_W_QHRR:
14336 case OPC_MAQ_SA_W_QHLL:
14337 case OPC_MAQ_SA_W_QHLR:
14338 case OPC_MAQ_SA_W_QHRL:
14339 case OPC_MAQ_SA_W_QHRR:
14340 case OPC_MAQ_S_L_PWL:
14341 case OPC_MAQ_S_L_PWR:
14342 case OPC_DMADD:
14343 case OPC_DMADDU:
14344 case OPC_DMSUB:
14345 case OPC_DMSUBU:
14346 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14347 break;
14348 default: /* Invalid */
14349 MIPS_INVAL("MASK DPAQ.W.QH");
14350 gen_reserved_instruction(ctx);
14351 break;
14352 }
14353 break;
14354 case OPC_DINSV_DSP:
14355 op2 = MASK_INSV(ctx->opcode);
14356 switch (op2) {
14357 case OPC_DINSV:
14358 {
14359 TCGv t0, t1;
14360
14361 check_dsp(ctx);
14362
14363 if (rt == 0) {
14364 break;
14365 }
14366
14367 t0 = tcg_temp_new();
14368 t1 = tcg_temp_new();
14369
14370 gen_load_gpr(t0, rt);
14371 gen_load_gpr(t1, rs);
14372
14373 gen_helper_dinsv(cpu_gpr[rt], tcg_env, t1, t0);
14374 break;
14375 }
14376 default: /* Invalid */
14377 MIPS_INVAL("MASK DINSV");
14378 gen_reserved_instruction(ctx);
14379 break;
14380 }
14381 break;
14382 case OPC_SHLL_OB_DSP:
14383 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14384 break;
14385 #endif
14386 default: /* Invalid */
14387 MIPS_INVAL("special3_legacy");
14388 gen_reserved_instruction(ctx);
14389 break;
14390 }
14391 }
14392
14393
14394 #if defined(TARGET_MIPS64)
14395
14396 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
14397 {
14398 uint32_t opc = MASK_MMI(ctx->opcode);
14399 int rs = extract32(ctx->opcode, 21, 5);
14400 int rt = extract32(ctx->opcode, 16, 5);
14401 int rd = extract32(ctx->opcode, 11, 5);
14402
14403 switch (opc) {
14404 case MMI_OPC_MULT1:
14405 case MMI_OPC_MULTU1:
14406 case MMI_OPC_MADD:
14407 case MMI_OPC_MADDU:
14408 case MMI_OPC_MADD1:
14409 case MMI_OPC_MADDU1:
14410 gen_mul_txx9(ctx, opc, rd, rs, rt);
14411 break;
14412 case MMI_OPC_DIV1:
14413 case MMI_OPC_DIVU1:
14414 gen_div1_tx79(ctx, opc, rs, rt);
14415 break;
14416 default:
14417 MIPS_INVAL("TX79 MMI class");
14418 gen_reserved_instruction(ctx);
14419 break;
14420 }
14421 }
14422
14423 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
14424 {
14425 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */
14426 }
14427
14428 /*
14429 * The TX79-specific instruction Store Quadword
14430 *
14431 * +--------+-------+-------+------------------------+
14432 * | 011111 | base | rt | offset | SQ
14433 * +--------+-------+-------+------------------------+
14434 * 6 5 5 16
14435 *
14436 * has the same opcode as the Read Hardware Register instruction
14437 *
14438 * +--------+-------+-------+-------+-------+--------+
14439 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
14440 * +--------+-------+-------+-------+-------+--------+
14441 * 6 5 5 5 5 6
14442 *
14443 * that is required, trapped and emulated by the Linux kernel. However, all
14444 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
14445 * offset is odd. Therefore all valid SQ instructions can execute normally.
14446 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
14447 * between SQ and RDHWR, as the Linux kernel does.
14448 */
14449 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
14450 {
14451 int base = extract32(ctx->opcode, 21, 5);
14452 int rt = extract32(ctx->opcode, 16, 5);
14453 int offset = extract32(ctx->opcode, 0, 16);
14454
14455 #ifdef CONFIG_USER_ONLY
14456 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
14457 uint32_t op2 = extract32(ctx->opcode, 6, 5);
14458
14459 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
14460 int rd = extract32(ctx->opcode, 11, 5);
14461
14462 gen_rdhwr(ctx, rt, rd, 0);
14463 return;
14464 }
14465 #endif
14466
14467 gen_mmi_sq(ctx, base, rt, offset);
14468 }
14469
14470 #endif
14471
14472 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
14473 {
14474 int rs, rt, rd, sa;
14475 uint32_t op1, op2;
14476 int16_t imm;
14477
14478 rs = (ctx->opcode >> 21) & 0x1f;
14479 rt = (ctx->opcode >> 16) & 0x1f;
14480 rd = (ctx->opcode >> 11) & 0x1f;
14481 sa = (ctx->opcode >> 6) & 0x1f;
14482 imm = sextract32(ctx->opcode, 7, 9);
14483
14484 op1 = MASK_SPECIAL3(ctx->opcode);
14485
14486 /*
14487 * EVA loads and stores overlap Loongson 2E instructions decoded by
14488 * decode_opc_special3_legacy(), so be careful to allow their decoding when
14489 * EVA is absent.
14490 */
14491 if (ctx->eva) {
14492 switch (op1) {
14493 case OPC_LWLE:
14494 case OPC_LWRE:
14495 case OPC_LBUE:
14496 case OPC_LHUE:
14497 case OPC_LBE:
14498 case OPC_LHE:
14499 case OPC_LLE:
14500 case OPC_LWE:
14501 check_cp0_enabled(ctx);
14502 gen_ld(ctx, op1, rt, rs, imm);
14503 return;
14504 case OPC_SWLE:
14505 case OPC_SWRE:
14506 case OPC_SBE:
14507 case OPC_SHE:
14508 case OPC_SWE:
14509 check_cp0_enabled(ctx);
14510 gen_st(ctx, op1, rt, rs, imm);
14511 return;
14512 case OPC_SCE:
14513 check_cp0_enabled(ctx);
14514 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
14515 return;
14516 case OPC_CACHEE:
14517 check_eva(ctx);
14518 check_cp0_enabled(ctx);
14519 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14520 gen_cache_operation(ctx, rt, rs, imm);
14521 }
14522 return;
14523 case OPC_PREFE:
14524 check_cp0_enabled(ctx);
14525 /* Treat as NOP. */
14526 return;
14527 }
14528 }
14529
14530 switch (op1) {
14531 case OPC_EXT:
14532 case OPC_INS:
14533 check_insn(ctx, ISA_MIPS_R2);
14534 gen_bitops(ctx, op1, rt, rs, sa, rd);
14535 break;
14536 case OPC_BSHFL:
14537 op2 = MASK_BSHFL(ctx->opcode);
14538 switch (op2) {
14539 case OPC_ALIGN:
14540 case OPC_ALIGN_1:
14541 case OPC_ALIGN_2:
14542 case OPC_ALIGN_3:
14543 case OPC_BITSWAP:
14544 check_insn(ctx, ISA_MIPS_R6);
14545 decode_opc_special3_r6(env, ctx);
14546 break;
14547 default:
14548 check_insn(ctx, ISA_MIPS_R2);
14549 gen_bshfl(ctx, op2, rt, rd);
14550 break;
14551 }
14552 break;
14553 #if defined(TARGET_MIPS64)
14554 case OPC_DEXTM:
14555 case OPC_DEXTU:
14556 case OPC_DEXT:
14557 case OPC_DINSM:
14558 case OPC_DINSU:
14559 case OPC_DINS:
14560 check_insn(ctx, ISA_MIPS_R2);
14561 check_mips_64(ctx);
14562 gen_bitops(ctx, op1, rt, rs, sa, rd);
14563 break;
14564 case OPC_DBSHFL:
14565 op2 = MASK_DBSHFL(ctx->opcode);
14566 switch (op2) {
14567 case OPC_DALIGN:
14568 case OPC_DALIGN_1:
14569 case OPC_DALIGN_2:
14570 case OPC_DALIGN_3:
14571 case OPC_DALIGN_4:
14572 case OPC_DALIGN_5:
14573 case OPC_DALIGN_6:
14574 case OPC_DALIGN_7:
14575 case OPC_DBITSWAP:
14576 check_insn(ctx, ISA_MIPS_R6);
14577 decode_opc_special3_r6(env, ctx);
14578 break;
14579 default:
14580 check_insn(ctx, ISA_MIPS_R2);
14581 check_mips_64(ctx);
14582 op2 = MASK_DBSHFL(ctx->opcode);
14583 gen_bshfl(ctx, op2, rt, rd);
14584 break;
14585 }
14586 break;
14587 #endif
14588 case OPC_RDHWR:
14589 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
14590 break;
14591 case OPC_FORK:
14592 check_mt(ctx);
14593 {
14594 TCGv t0 = tcg_temp_new();
14595 TCGv t1 = tcg_temp_new();
14596
14597 gen_load_gpr(t0, rt);
14598 gen_load_gpr(t1, rs);
14599 gen_helper_fork(t0, t1);
14600 }
14601 break;
14602 case OPC_YIELD:
14603 check_mt(ctx);
14604 {
14605 TCGv t0 = tcg_temp_new();
14606
14607 gen_load_gpr(t0, rs);
14608 gen_helper_yield(t0, tcg_env, t0);
14609 gen_store_gpr(t0, rd);
14610 }
14611 break;
14612 default:
14613 if (ctx->insn_flags & ISA_MIPS_R6) {
14614 decode_opc_special3_r6(env, ctx);
14615 } else {
14616 decode_opc_special3_legacy(env, ctx);
14617 }
14618 }
14619 }
14620
14621 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
14622 {
14623 int32_t offset;
14624 int rs, rt, rd, sa;
14625 uint32_t op, op1;
14626 int16_t imm;
14627
14628 op = MASK_OP_MAJOR(ctx->opcode);
14629 rs = (ctx->opcode >> 21) & 0x1f;
14630 rt = (ctx->opcode >> 16) & 0x1f;
14631 rd = (ctx->opcode >> 11) & 0x1f;
14632 sa = (ctx->opcode >> 6) & 0x1f;
14633 imm = (int16_t)ctx->opcode;
14634 switch (op) {
14635 case OPC_SPECIAL:
14636 decode_opc_special(env, ctx);
14637 break;
14638 case OPC_SPECIAL2:
14639 #if defined(TARGET_MIPS64)
14640 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
14641 decode_mmi(env, ctx);
14642 break;
14643 }
14644 #endif
14645 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
14646 if (decode_ase_mxu(ctx, ctx->opcode)) {
14647 break;
14648 }
14649 }
14650 decode_opc_special2_legacy(env, ctx);
14651 break;
14652 case OPC_SPECIAL3:
14653 #if defined(TARGET_MIPS64)
14654 if (ctx->insn_flags & INSN_R5900) {
14655 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
14656 } else {
14657 decode_opc_special3(env, ctx);
14658 }
14659 #else
14660 decode_opc_special3(env, ctx);
14661 #endif
14662 break;
14663 case OPC_REGIMM:
14664 op1 = MASK_REGIMM(ctx->opcode);
14665 switch (op1) {
14666 case OPC_BLTZL: /* REGIMM branches */
14667 case OPC_BGEZL:
14668 case OPC_BLTZALL:
14669 case OPC_BGEZALL:
14670 check_insn(ctx, ISA_MIPS2);
14671 check_insn_opc_removed(ctx, ISA_MIPS_R6);
14672 /* Fallthrough */
14673 case OPC_BLTZ:
14674 case OPC_BGEZ:
14675 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14676 break;
14677 case OPC_BLTZAL:
14678 case OPC_BGEZAL:
14679 if (ctx->insn_flags & ISA_MIPS_R6) {
14680 if (rs == 0) {
14681 /* OPC_NAL, OPC_BAL */
14682 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
14683 } else {
14684 gen_reserved_instruction(ctx);
14685 }
14686 } else {
14687 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
14688 }
14689 break;
14690 case OPC_TGEI: /* REGIMM traps */
14691 case OPC_TGEIU:
14692 case OPC_TLTI:
14693 case OPC_TLTIU:
14694 case OPC_TEQI:
14695 case OPC_TNEI:
14696 check_insn(ctx, ISA_MIPS2);
14697 check_insn_opc_removed(ctx, ISA_MIPS_R6);
14698 gen_trap(ctx, op1, rs, -1, imm, 0);
14699 break;
14700 case OPC_SIGRIE:
14701 check_insn(ctx, ISA_MIPS_R6);
14702 gen_reserved_instruction(ctx);
14703 break;
14704 case OPC_SYNCI:
14705 check_insn(ctx, ISA_MIPS_R2);
14706 /*
14707 * Break the TB to be able to sync copied instructions
14708 * immediately.
14709 */
14710 ctx->base.is_jmp = DISAS_STOP;
14711 break;
14712 case OPC_BPOSGE32: /* MIPS DSP branch */
14713 #if defined(TARGET_MIPS64)
14714 case OPC_BPOSGE64:
14715 #endif
14716 check_dsp(ctx);
14717 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
14718 break;
14719 #if defined(TARGET_MIPS64)
14720 case OPC_DAHI:
14721 check_insn(ctx, ISA_MIPS_R6);
14722 check_mips_64(ctx);
14723 if (rs != 0) {
14724 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
14725 }
14726 break;
14727 case OPC_DATI:
14728 check_insn(ctx, ISA_MIPS_R6);
14729 check_mips_64(ctx);
14730 if (rs != 0) {
14731 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
14732 }
14733 break;
14734 #endif
14735 default: /* Invalid */
14736 MIPS_INVAL("regimm");
14737 gen_reserved_instruction(ctx);
14738 break;
14739 }
14740 break;
14741 case OPC_CP0:
14742 check_cp0_enabled(ctx);
14743 op1 = MASK_CP0(ctx->opcode);
14744 switch (op1) {
14745 case OPC_MFC0:
14746 case OPC_MTC0:
14747 case OPC_MFTR:
14748 case OPC_MTTR:
14749 case OPC_MFHC0:
14750 case OPC_MTHC0:
14751 #if defined(TARGET_MIPS64)
14752 case OPC_DMFC0:
14753 case OPC_DMTC0:
14754 #endif
14755 #ifndef CONFIG_USER_ONLY
14756 gen_cp0(env, ctx, op1, rt, rd);
14757 #endif /* !CONFIG_USER_ONLY */
14758 break;
14759 case OPC_C0:
14760 case OPC_C0_1:
14761 case OPC_C0_2:
14762 case OPC_C0_3:
14763 case OPC_C0_4:
14764 case OPC_C0_5:
14765 case OPC_C0_6:
14766 case OPC_C0_7:
14767 case OPC_C0_8:
14768 case OPC_C0_9:
14769 case OPC_C0_A:
14770 case OPC_C0_B:
14771 case OPC_C0_C:
14772 case OPC_C0_D:
14773 case OPC_C0_E:
14774 case OPC_C0_F:
14775 #ifndef CONFIG_USER_ONLY
14776 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
14777 #endif /* !CONFIG_USER_ONLY */
14778 break;
14779 case OPC_MFMC0:
14780 #ifndef CONFIG_USER_ONLY
14781 {
14782 uint32_t op2;
14783 TCGv t0 = tcg_temp_new();
14784
14785 op2 = MASK_MFMC0(ctx->opcode);
14786 switch (op2) {
14787 case OPC_DMT:
14788 check_cp0_mt(ctx);
14789 gen_helper_dmt(t0);
14790 gen_store_gpr(t0, rt);
14791 break;
14792 case OPC_EMT:
14793 check_cp0_mt(ctx);
14794 gen_helper_emt(t0);
14795 gen_store_gpr(t0, rt);
14796 break;
14797 case OPC_DVPE:
14798 check_cp0_mt(ctx);
14799 gen_helper_dvpe(t0, tcg_env);
14800 gen_store_gpr(t0, rt);
14801 break;
14802 case OPC_EVPE:
14803 check_cp0_mt(ctx);
14804 gen_helper_evpe(t0, tcg_env);
14805 gen_store_gpr(t0, rt);
14806 break;
14807 case OPC_DVP:
14808 check_insn(ctx, ISA_MIPS_R6);
14809 if (ctx->vp) {
14810 gen_helper_dvp(t0, tcg_env);
14811 gen_store_gpr(t0, rt);
14812 }
14813 break;
14814 case OPC_EVP:
14815 check_insn(ctx, ISA_MIPS_R6);
14816 if (ctx->vp) {
14817 gen_helper_evp(t0, tcg_env);
14818 gen_store_gpr(t0, rt);
14819 }
14820 break;
14821 case OPC_DI:
14822 check_insn(ctx, ISA_MIPS_R2);
14823 save_cpu_state(ctx, 1);
14824 gen_helper_di(t0, tcg_env);
14825 gen_store_gpr(t0, rt);
14826 /*
14827 * Stop translation as we may have switched
14828 * the execution mode.
14829 */
14830 ctx->base.is_jmp = DISAS_STOP;
14831 break;
14832 case OPC_EI:
14833 check_insn(ctx, ISA_MIPS_R2);
14834 save_cpu_state(ctx, 1);
14835 gen_helper_ei(t0, tcg_env);
14836 gen_store_gpr(t0, rt);
14837 /*
14838 * DISAS_STOP isn't sufficient, we need to ensure we break
14839 * out of translated code to check for pending interrupts.
14840 */
14841 gen_save_pc(ctx->base.pc_next + 4);
14842 ctx->base.is_jmp = DISAS_EXIT;
14843 break;
14844 default: /* Invalid */
14845 MIPS_INVAL("mfmc0");
14846 gen_reserved_instruction(ctx);
14847 break;
14848 }
14849 }
14850 #endif /* !CONFIG_USER_ONLY */
14851 break;
14852 case OPC_RDPGPR:
14853 check_insn(ctx, ISA_MIPS_R2);
14854 gen_load_srsgpr(rt, rd);
14855 break;
14856 case OPC_WRPGPR:
14857 check_insn(ctx, ISA_MIPS_R2);
14858 gen_store_srsgpr(rt, rd);
14859 break;
14860 default:
14861 MIPS_INVAL("cp0");
14862 gen_reserved_instruction(ctx);
14863 break;
14864 }
14865 break;
14866 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
14867 if (ctx->insn_flags & ISA_MIPS_R6) {
14868 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
14869 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14870 } else {
14871 /* OPC_ADDI */
14872 /* Arithmetic with immediate opcode */
14873 gen_arith_imm(ctx, op, rt, rs, imm);
14874 }
14875 break;
14876 case OPC_ADDIU:
14877 gen_arith_imm(ctx, op, rt, rs, imm);
14878 break;
14879 case OPC_SLTI: /* Set on less than with immediate opcode */
14880 case OPC_SLTIU:
14881 gen_slt_imm(ctx, op, rt, rs, imm);
14882 break;
14883 case OPC_ANDI: /* Arithmetic with immediate opcode */
14884 case OPC_LUI: /* OPC_AUI */
14885 case OPC_ORI:
14886 case OPC_XORI:
14887 gen_logic_imm(ctx, op, rt, rs, imm);
14888 break;
14889 case OPC_J: /* Jump */
14890 case OPC_JAL:
14891 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14892 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
14893 break;
14894 /* Branch */
14895 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
14896 if (ctx->insn_flags & ISA_MIPS_R6) {
14897 if (rt == 0) {
14898 gen_reserved_instruction(ctx);
14899 break;
14900 }
14901 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
14902 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14903 } else {
14904 /* OPC_BLEZL */
14905 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14906 }
14907 break;
14908 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
14909 if (ctx->insn_flags & ISA_MIPS_R6) {
14910 if (rt == 0) {
14911 gen_reserved_instruction(ctx);
14912 break;
14913 }
14914 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
14915 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14916 } else {
14917 /* OPC_BGTZL */
14918 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14919 }
14920 break;
14921 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
14922 if (rt == 0) {
14923 /* OPC_BLEZ */
14924 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14925 } else {
14926 check_insn(ctx, ISA_MIPS_R6);
14927 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
14928 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14929 }
14930 break;
14931 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
14932 if (rt == 0) {
14933 /* OPC_BGTZ */
14934 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14935 } else {
14936 check_insn(ctx, ISA_MIPS_R6);
14937 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
14938 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
14939 }
14940 break;
14941 case OPC_BEQL:
14942 case OPC_BNEL:
14943 check_insn(ctx, ISA_MIPS2);
14944 check_insn_opc_removed(ctx, ISA_MIPS_R6);
14945 /* Fallthrough */
14946 case OPC_BEQ:
14947 case OPC_BNE:
14948 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
14949 break;
14950 case OPC_LL: /* Load and stores */
14951 check_insn(ctx, ISA_MIPS2);
14952 if (ctx->insn_flags & INSN_R5900) {
14953 check_insn_opc_user_only(ctx, INSN_R5900);
14954 }
14955 /* Fallthrough */
14956 case OPC_LWL:
14957 case OPC_LWR:
14958 case OPC_LB:
14959 case OPC_LH:
14960 case OPC_LW:
14961 case OPC_LWPC:
14962 case OPC_LBU:
14963 case OPC_LHU:
14964 gen_ld(ctx, op, rt, rs, imm);
14965 break;
14966 case OPC_SWL:
14967 case OPC_SWR:
14968 case OPC_SB:
14969 case OPC_SH:
14970 case OPC_SW:
14971 gen_st(ctx, op, rt, rs, imm);
14972 break;
14973 case OPC_SC:
14974 check_insn(ctx, ISA_MIPS2);
14975 if (ctx->insn_flags & INSN_R5900) {
14976 check_insn_opc_user_only(ctx, INSN_R5900);
14977 }
14978 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
14979 break;
14980 case OPC_CACHE:
14981 check_cp0_enabled(ctx);
14982 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
14983 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14984 gen_cache_operation(ctx, rt, rs, imm);
14985 }
14986 /* Treat as NOP. */
14987 break;
14988 case OPC_PREF:
14989 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
14990 /* Treat as NOP. */
14991 break;
14992
14993 /* Floating point (COP1). */
14994 case OPC_LWC1:
14995 case OPC_LDC1:
14996 case OPC_SWC1:
14997 case OPC_SDC1:
14998 gen_cop1_ldst(ctx, op, rt, rs, imm);
14999 break;
15000
15001 case OPC_CP1:
15002 op1 = MASK_CP1(ctx->opcode);
15003
15004 switch (op1) {
15005 case OPC_MFHC1:
15006 case OPC_MTHC1:
15007 check_cp1_enabled(ctx);
15008 check_insn(ctx, ISA_MIPS_R2);
15009 /* fall through */
15010 case OPC_MFC1:
15011 case OPC_CFC1:
15012 case OPC_MTC1:
15013 case OPC_CTC1:
15014 check_cp1_enabled(ctx);
15015 gen_cp1(ctx, op1, rt, rd);
15016 break;
15017 #if defined(TARGET_MIPS64)
15018 case OPC_DMFC1:
15019 case OPC_DMTC1:
15020 check_cp1_enabled(ctx);
15021 check_insn(ctx, ISA_MIPS3);
15022 check_mips_64(ctx);
15023 gen_cp1(ctx, op1, rt, rd);
15024 break;
15025 #endif
15026 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
15027 check_cp1_enabled(ctx);
15028 if (ctx->insn_flags & ISA_MIPS_R6) {
15029 /* OPC_BC1EQZ */
15030 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15031 rt, imm << 2, 4);
15032 } else {
15033 /* OPC_BC1ANY2 */
15034 check_cop1x(ctx);
15035 check_insn(ctx, ASE_MIPS3D);
15036 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15037 (rt >> 2) & 0x7, imm << 2);
15038 }
15039 break;
15040 case OPC_BC1NEZ:
15041 check_cp1_enabled(ctx);
15042 check_insn(ctx, ISA_MIPS_R6);
15043 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15044 rt, imm << 2, 4);
15045 break;
15046 case OPC_BC1ANY4:
15047 check_cp1_enabled(ctx);
15048 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15049 check_cop1x(ctx);
15050 check_insn(ctx, ASE_MIPS3D);
15051 /* fall through */
15052 case OPC_BC1:
15053 check_cp1_enabled(ctx);
15054 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15055 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15056 (rt >> 2) & 0x7, imm << 2);
15057 break;
15058 case OPC_PS_FMT:
15059 check_ps(ctx);
15060 /* fall through */
15061 case OPC_S_FMT:
15062 case OPC_D_FMT:
15063 check_cp1_enabled(ctx);
15064 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15065 (imm >> 8) & 0x7);
15066 break;
15067 case OPC_W_FMT:
15068 case OPC_L_FMT:
15069 {
15070 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15071 check_cp1_enabled(ctx);
15072 if (ctx->insn_flags & ISA_MIPS_R6) {
15073 switch (r6_op) {
15074 case R6_OPC_CMP_AF_S:
15075 case R6_OPC_CMP_UN_S:
15076 case R6_OPC_CMP_EQ_S:
15077 case R6_OPC_CMP_UEQ_S:
15078 case R6_OPC_CMP_LT_S:
15079 case R6_OPC_CMP_ULT_S:
15080 case R6_OPC_CMP_LE_S:
15081 case R6_OPC_CMP_ULE_S:
15082 case R6_OPC_CMP_SAF_S:
15083 case R6_OPC_CMP_SUN_S:
15084 case R6_OPC_CMP_SEQ_S:
15085 case R6_OPC_CMP_SEUQ_S:
15086 case R6_OPC_CMP_SLT_S:
15087 case R6_OPC_CMP_SULT_S:
15088 case R6_OPC_CMP_SLE_S:
15089 case R6_OPC_CMP_SULE_S:
15090 case R6_OPC_CMP_OR_S:
15091 case R6_OPC_CMP_UNE_S:
15092 case R6_OPC_CMP_NE_S:
15093 case R6_OPC_CMP_SOR_S:
15094 case R6_OPC_CMP_SUNE_S:
15095 case R6_OPC_CMP_SNE_S:
15096 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15097 break;
15098 case R6_OPC_CMP_AF_D:
15099 case R6_OPC_CMP_UN_D:
15100 case R6_OPC_CMP_EQ_D:
15101 case R6_OPC_CMP_UEQ_D:
15102 case R6_OPC_CMP_LT_D:
15103 case R6_OPC_CMP_ULT_D:
15104 case R6_OPC_CMP_LE_D:
15105 case R6_OPC_CMP_ULE_D:
15106 case R6_OPC_CMP_SAF_D:
15107 case R6_OPC_CMP_SUN_D:
15108 case R6_OPC_CMP_SEQ_D:
15109 case R6_OPC_CMP_SEUQ_D:
15110 case R6_OPC_CMP_SLT_D:
15111 case R6_OPC_CMP_SULT_D:
15112 case R6_OPC_CMP_SLE_D:
15113 case R6_OPC_CMP_SULE_D:
15114 case R6_OPC_CMP_OR_D:
15115 case R6_OPC_CMP_UNE_D:
15116 case R6_OPC_CMP_NE_D:
15117 case R6_OPC_CMP_SOR_D:
15118 case R6_OPC_CMP_SUNE_D:
15119 case R6_OPC_CMP_SNE_D:
15120 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15121 break;
15122 default:
15123 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15124 rt, rd, sa, (imm >> 8) & 0x7);
15125
15126 break;
15127 }
15128 } else {
15129 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15130 (imm >> 8) & 0x7);
15131 }
15132 break;
15133 }
15134 default:
15135 MIPS_INVAL("cp1");
15136 gen_reserved_instruction(ctx);
15137 break;
15138 }
15139 break;
15140
15141 /* Compact branches [R6] and COP2 [non-R6] */
15142 case OPC_BC: /* OPC_LWC2 */
15143 case OPC_BALC: /* OPC_SWC2 */
15144 if (ctx->insn_flags & ISA_MIPS_R6) {
15145 /* OPC_BC, OPC_BALC */
15146 gen_compute_compact_branch(ctx, op, 0, 0,
15147 sextract32(ctx->opcode << 2, 0, 28));
15148 } else if (ctx->insn_flags & ASE_LEXT) {
15149 gen_loongson_lswc2(ctx, rt, rs, rd);
15150 } else {
15151 /* OPC_LWC2, OPC_SWC2 */
15152 /* COP2: Not implemented. */
15153 generate_exception_err(ctx, EXCP_CpU, 2);
15154 }
15155 break;
15156 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
15157 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
15158 if (ctx->insn_flags & ISA_MIPS_R6) {
15159 if (rs != 0) {
15160 /* OPC_BEQZC, OPC_BNEZC */
15161 gen_compute_compact_branch(ctx, op, rs, 0,
15162 sextract32(ctx->opcode << 2, 0, 23));
15163 } else {
15164 /* OPC_JIC, OPC_JIALC */
15165 gen_compute_compact_branch(ctx, op, 0, rt, imm);
15166 }
15167 } else if (ctx->insn_flags & ASE_LEXT) {
15168 gen_loongson_lsdc2(ctx, rt, rs, rd);
15169 } else {
15170 /* OPC_LWC2, OPC_SWC2 */
15171 /* COP2: Not implemented. */
15172 generate_exception_err(ctx, EXCP_CpU, 2);
15173 }
15174 break;
15175 case OPC_CP2:
15176 check_insn(ctx, ASE_LMMI);
15177 /* Note that these instructions use different fields. */
15178 gen_loongson_multimedia(ctx, sa, rd, rt);
15179 break;
15180
15181 case OPC_CP3:
15182 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15183 check_cp1_enabled(ctx);
15184 op1 = MASK_CP3(ctx->opcode);
15185 switch (op1) {
15186 case OPC_LUXC1:
15187 case OPC_SUXC1:
15188 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15189 /* Fallthrough */
15190 case OPC_LWXC1:
15191 case OPC_LDXC1:
15192 case OPC_SWXC1:
15193 case OPC_SDXC1:
15194 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15195 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15196 break;
15197 case OPC_PREFX:
15198 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15199 /* Treat as NOP. */
15200 break;
15201 case OPC_ALNV_PS:
15202 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15203 /* Fallthrough */
15204 case OPC_MADD_S:
15205 case OPC_MADD_D:
15206 case OPC_MADD_PS:
15207 case OPC_MSUB_S:
15208 case OPC_MSUB_D:
15209 case OPC_MSUB_PS:
15210 case OPC_NMADD_S:
15211 case OPC_NMADD_D:
15212 case OPC_NMADD_PS:
15213 case OPC_NMSUB_S:
15214 case OPC_NMSUB_D:
15215 case OPC_NMSUB_PS:
15216 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15217 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15218 break;
15219 default:
15220 MIPS_INVAL("cp3");
15221 gen_reserved_instruction(ctx);
15222 break;
15223 }
15224 } else {
15225 generate_exception_err(ctx, EXCP_CpU, 1);
15226 }
15227 break;
15228
15229 #if defined(TARGET_MIPS64)
15230 /* MIPS64 opcodes */
15231 case OPC_LLD:
15232 if (ctx->insn_flags & INSN_R5900) {
15233 check_insn_opc_user_only(ctx, INSN_R5900);
15234 }
15235 /* fall through */
15236 case OPC_LDL:
15237 case OPC_LDR:
15238 case OPC_LWU:
15239 case OPC_LD:
15240 check_insn(ctx, ISA_MIPS3);
15241 check_mips_64(ctx);
15242 gen_ld(ctx, op, rt, rs, imm);
15243 break;
15244 case OPC_SDL:
15245 case OPC_SDR:
15246 case OPC_SD:
15247 check_insn(ctx, ISA_MIPS3);
15248 check_mips_64(ctx);
15249 gen_st(ctx, op, rt, rs, imm);
15250 break;
15251 case OPC_SCD:
15252 check_insn(ctx, ISA_MIPS3);
15253 if (ctx->insn_flags & INSN_R5900) {
15254 check_insn_opc_user_only(ctx, INSN_R5900);
15255 }
15256 check_mips_64(ctx);
15257 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
15258 break;
15259 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
15260 if (ctx->insn_flags & ISA_MIPS_R6) {
15261 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
15262 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15263 } else {
15264 /* OPC_DADDI */
15265 check_insn(ctx, ISA_MIPS3);
15266 check_mips_64(ctx);
15267 gen_arith_imm(ctx, op, rt, rs, imm);
15268 }
15269 break;
15270 case OPC_DADDIU:
15271 check_insn(ctx, ISA_MIPS3);
15272 check_mips_64(ctx);
15273 gen_arith_imm(ctx, op, rt, rs, imm);
15274 break;
15275 #else
15276 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15277 if (ctx->insn_flags & ISA_MIPS_R6) {
15278 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15279 } else {
15280 MIPS_INVAL("major opcode");
15281 gen_reserved_instruction(ctx);
15282 }
15283 break;
15284 #endif
15285 case OPC_DAUI: /* OPC_JALX */
15286 if (ctx->insn_flags & ISA_MIPS_R6) {
15287 #if defined(TARGET_MIPS64)
15288 /* OPC_DAUI */
15289 check_mips_64(ctx);
15290 if (rs == 0) {
15291 generate_exception(ctx, EXCP_RI);
15292 } else if (rt != 0) {
15293 TCGv t0 = tcg_temp_new();
15294 gen_load_gpr(t0, rs);
15295 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15296 }
15297 #else
15298 gen_reserved_instruction(ctx);
15299 MIPS_INVAL("major opcode");
15300 #endif
15301 } else {
15302 /* OPC_JALX */
15303 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15304 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15305 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15306 }
15307 break;
15308 case OPC_MDMX:
15309 /* MDMX: Not implemented. */
15310 break;
15311 case OPC_PCREL:
15312 check_insn(ctx, ISA_MIPS_R6);
15313 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
15314 break;
15315 default: /* Invalid */
15316 MIPS_INVAL("major opcode");
15317 return false;
15318 }
15319 return true;
15320 }
15321
15322 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15323 {
15324 /* make sure instructions are on a word boundary */
15325 if (ctx->base.pc_next & 0x3) {
15326 env->CP0_BadVAddr = ctx->base.pc_next;
15327 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15328 return;
15329 }
15330
15331 /* Handle blikely not taken case */
15332 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15333 TCGLabel *l1 = gen_new_label();
15334
15335 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15336 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15337 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15338 gen_set_label(l1);
15339 }
15340
15341 /* Transition to the auto-generated decoder. */
15342
15343 /* Vendor specific extensions */
15344 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15345 return;
15346 }
15347 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15348 return;
15349 }
15350 #if defined(TARGET_MIPS64)
15351 if (ase_lcsr_available(env) && decode_ase_lcsr(ctx, ctx->opcode)) {
15352 return;
15353 }
15354 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) {
15355 return;
15356 }
15357 #endif
15358
15359 /* ISA extensions */
15360 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15361 return;
15362 }
15363
15364 /* ISA (from latest to oldest) */
15365 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15366 return;
15367 }
15368
15369 if (decode_opc_legacy(env, ctx)) {
15370 return;
15371 }
15372
15373 gen_reserved_instruction(ctx);
15374 }
15375
15376 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15377 {
15378 DisasContext *ctx = container_of(dcbase, DisasContext, base);
15379 CPUMIPSState *env = cpu_env(cs);
15380
15381 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15382 ctx->saved_pc = -1;
15383 ctx->insn_flags = env->insn_flags;
15384 ctx->CP0_Config0 = env->CP0_Config0;
15385 ctx->CP0_Config1 = env->CP0_Config1;
15386 ctx->CP0_Config2 = env->CP0_Config2;
15387 ctx->CP0_Config3 = env->CP0_Config3;
15388 ctx->CP0_Config5 = env->CP0_Config5;
15389 ctx->btarget = 0;
15390 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15391 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15392 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
15393 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
15394 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
15395 ctx->PAMask = env->PAMask;
15396 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
15397 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
15398 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
15399 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
15400 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
15401 /* Restore delay slot state from the tb context. */
15402 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
15403 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
15404 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
15405 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
15406 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
15407 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
15408 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
15409 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
15410 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
15411 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
15412 restore_cpu_state(env, ctx);
15413 #ifdef CONFIG_USER_ONLY
15414 ctx->mem_idx = MIPS_HFLAG_UM;
15415 #else
15416 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
15417 #endif
15418 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) &&
15419 (ctx->insn_flags & (ISA_MIPS_R6 |
15420 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN;
15421
15422 /*
15423 * Execute a branch and its delay slot as a single instruction.
15424 * This is what GDB expects and is consistent with what the
15425 * hardware does (e.g. if a delay slot instruction faults, the
15426 * reported PC is the PC of the branch).
15427 */
15428 if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
15429 ctx->base.max_insns = 2;
15430 }
15431
15432 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
15433 ctx->hflags);
15434 }
15435
15436 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
15437 {
15438 }
15439
15440 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
15441 {
15442 DisasContext *ctx = container_of(dcbase, DisasContext, base);
15443
15444 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
15445 ctx->btarget);
15446 }
15447
15448 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
15449 {
15450 CPUMIPSState *env = cpu_env(cs);
15451 DisasContext *ctx = container_of(dcbase, DisasContext, base);
15452 int insn_bytes;
15453 int is_slot;
15454
15455 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
15456 if (ctx->insn_flags & ISA_NANOMIPS32) {
15457 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15458 insn_bytes = decode_isa_nanomips(env, ctx);
15459 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
15460 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
15461 insn_bytes = 4;
15462 decode_opc(env, ctx);
15463 } else if (ctx->insn_flags & ASE_MICROMIPS) {
15464 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15465 insn_bytes = decode_isa_micromips(env, ctx);
15466 } else if (ctx->insn_flags & ASE_MIPS16) {
15467 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
15468 insn_bytes = decode_ase_mips16e(env, ctx);
15469 } else {
15470 gen_reserved_instruction(ctx);
15471 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
15472 return;
15473 }
15474
15475 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15476 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
15477 MIPS_HFLAG_FBNSLOT))) {
15478 /*
15479 * Force to generate branch as there is neither delay nor
15480 * forbidden slot.
15481 */
15482 is_slot = 1;
15483 }
15484 if ((ctx->hflags & MIPS_HFLAG_M16) &&
15485 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
15486 /*
15487 * Force to generate branch as microMIPS R6 doesn't restrict
15488 * branches in the forbidden slot.
15489 */
15490 is_slot = 1;
15491 }
15492 }
15493 if (is_slot) {
15494 gen_branch(ctx, insn_bytes);
15495 }
15496 if (ctx->base.is_jmp == DISAS_SEMIHOST) {
15497 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes);
15498 }
15499 ctx->base.pc_next += insn_bytes;
15500
15501 if (ctx->base.is_jmp != DISAS_NEXT) {
15502 return;
15503 }
15504
15505 /*
15506 * End the TB on (most) page crossings.
15507 * See mips_tr_init_disas_context about single-stepping a branch
15508 * together with its delay slot.
15509 */
15510 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
15511 && !ctx->base.singlestep_enabled) {
15512 ctx->base.is_jmp = DISAS_TOO_MANY;
15513 }
15514 }
15515
15516 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
15517 {
15518 DisasContext *ctx = container_of(dcbase, DisasContext, base);
15519
15520 switch (ctx->base.is_jmp) {
15521 case DISAS_STOP:
15522 gen_save_pc(ctx->base.pc_next);
15523 tcg_gen_lookup_and_goto_ptr();
15524 break;
15525 case DISAS_NEXT:
15526 case DISAS_TOO_MANY:
15527 save_cpu_state(ctx, 0);
15528 gen_goto_tb(ctx, 0, ctx->base.pc_next);
15529 break;
15530 case DISAS_EXIT:
15531 tcg_gen_exit_tb(NULL, 0);
15532 break;
15533 case DISAS_NORETURN:
15534 break;
15535 default:
15536 g_assert_not_reached();
15537 }
15538 }
15539
15540 static void mips_tr_disas_log(const DisasContextBase *dcbase,
15541 CPUState *cs, FILE *logfile)
15542 {
15543 fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
15544 target_disas(logfile, cs, dcbase->pc_first, dcbase->tb->size);
15545 }
15546
15547 static const TranslatorOps mips_tr_ops = {
15548 .init_disas_context = mips_tr_init_disas_context,
15549 .tb_start = mips_tr_tb_start,
15550 .insn_start = mips_tr_insn_start,
15551 .translate_insn = mips_tr_translate_insn,
15552 .tb_stop = mips_tr_tb_stop,
15553 .disas_log = mips_tr_disas_log,
15554 };
15555
15556 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
15557 vaddr pc, void *host_pc)
15558 {
15559 DisasContext ctx;
15560
15561 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base);
15562 }
15563
15564 void mips_tcg_init(void)
15565 {
15566 cpu_gpr[0] = NULL;
15567 for (unsigned i = 1; i < 32; i++)
15568 cpu_gpr[i] = tcg_global_mem_new(tcg_env,
15569 offsetof(CPUMIPSState,
15570 active_tc.gpr[i]),
15571 regnames[i]);
15572 #if defined(TARGET_MIPS64)
15573 cpu_gpr_hi[0] = NULL;
15574
15575 for (unsigned i = 1; i < 32; i++) {
15576 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
15577
15578 cpu_gpr_hi[i] = tcg_global_mem_new_i64(tcg_env,
15579 offsetof(CPUMIPSState,
15580 active_tc.gpr_hi[i]),
15581 rname);
15582 }
15583 #endif /* !TARGET_MIPS64 */
15584 for (unsigned i = 0; i < 32; i++) {
15585 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
15586
15587 fpu_f64[i] = tcg_global_mem_new_i64(tcg_env, off, fregnames[i]);
15588 }
15589 msa_translate_init();
15590 cpu_PC = tcg_global_mem_new(tcg_env,
15591 offsetof(CPUMIPSState, active_tc.PC), "PC");
15592 for (unsigned i = 0; i < MIPS_DSP_ACC; i++) {
15593 cpu_HI[i] = tcg_global_mem_new(tcg_env,
15594 offsetof(CPUMIPSState, active_tc.HI[i]),
15595 regnames_HI[i]);
15596 cpu_LO[i] = tcg_global_mem_new(tcg_env,
15597 offsetof(CPUMIPSState, active_tc.LO[i]),
15598 regnames_LO[i]);
15599 }
15600 cpu_dspctrl = tcg_global_mem_new(tcg_env,
15601 offsetof(CPUMIPSState,
15602 active_tc.DSPControl),
15603 "DSPControl");
15604 bcond = tcg_global_mem_new(tcg_env,
15605 offsetof(CPUMIPSState, bcond), "bcond");
15606 btarget = tcg_global_mem_new(tcg_env,
15607 offsetof(CPUMIPSState, btarget), "btarget");
15608 hflags = tcg_global_mem_new_i32(tcg_env,
15609 offsetof(CPUMIPSState, hflags), "hflags");
15610
15611 fpu_fcr0 = tcg_global_mem_new_i32(tcg_env,
15612 offsetof(CPUMIPSState, active_fpu.fcr0),
15613 "fcr0");
15614 fpu_fcr31 = tcg_global_mem_new_i32(tcg_env,
15615 offsetof(CPUMIPSState, active_fpu.fcr31),
15616 "fcr31");
15617 cpu_lladdr = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, lladdr),
15618 "lladdr");
15619 cpu_llval = tcg_global_mem_new(tcg_env, offsetof(CPUMIPSState, llval),
15620 "llval");
15621
15622 if (TARGET_LONG_BITS == 32) {
15623 mxu_translate_init();
15624 }
15625 }
15626
15627 void mips_restore_state_to_opc(CPUState *cs,
15628 const TranslationBlock *tb,
15629 const uint64_t *data)
15630 {
15631 MIPSCPU *cpu = MIPS_CPU(cs);
15632 CPUMIPSState *env = &cpu->env;
15633
15634 env->active_tc.PC = data[0];
15635 env->hflags &= ~MIPS_HFLAG_BMASK;
15636 env->hflags |= data[1];
15637 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15638 case MIPS_HFLAG_BR:
15639 break;
15640 case MIPS_HFLAG_BC:
15641 case MIPS_HFLAG_BL:
15642 case MIPS_HFLAG_B:
15643 env->btarget = data[2];
15644 break;
15645 }
15646 }