]> git.proxmox.com Git - mirror_qemu.git/blob - target/mips/tcg/translate.c
4c4bd0823dec50d7f762fb7b480f3c7765e35e23
[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 "cpu.h"
27 #include "internal.h"
28 #include "tcg/tcg-op.h"
29 #include "exec/translator.h"
30 #include "exec/helper-proto.h"
31 #include "exec/helper-gen.h"
32 #include "semihosting/semihost.h"
33
34 #include "trace.h"
35 #include "exec/translator.h"
36 #include "exec/log.h"
37 #include "qemu/qemu-print.h"
38 #include "fpu_helper.h"
39 #include "translate.h"
40
41 /*
42 * Many sysemu-only helpers are not reachable for user-only.
43 * Define stub generators here, so that we need not either sprinkle
44 * ifdefs through the translator, nor provide the helper function.
45 */
46 #define STUB_HELPER(NAME, ...) \
47 static inline void gen_helper_##NAME(__VA_ARGS__) \
48 { g_assert_not_reached(); }
49
50 #ifdef CONFIG_USER_ONLY
51 STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg)
52 #endif
53
54 enum {
55 /* indirect opcode tables */
56 OPC_SPECIAL = (0x00 << 26),
57 OPC_REGIMM = (0x01 << 26),
58 OPC_CP0 = (0x10 << 26),
59 OPC_CP2 = (0x12 << 26),
60 OPC_CP3 = (0x13 << 26),
61 OPC_SPECIAL2 = (0x1C << 26),
62 OPC_SPECIAL3 = (0x1F << 26),
63 /* arithmetic with immediate */
64 OPC_ADDI = (0x08 << 26),
65 OPC_ADDIU = (0x09 << 26),
66 OPC_SLTI = (0x0A << 26),
67 OPC_SLTIU = (0x0B << 26),
68 /* logic with immediate */
69 OPC_ANDI = (0x0C << 26),
70 OPC_ORI = (0x0D << 26),
71 OPC_XORI = (0x0E << 26),
72 OPC_LUI = (0x0F << 26),
73 /* arithmetic with immediate */
74 OPC_DADDI = (0x18 << 26),
75 OPC_DADDIU = (0x19 << 26),
76 /* Jump and branches */
77 OPC_J = (0x02 << 26),
78 OPC_JAL = (0x03 << 26),
79 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
80 OPC_BEQL = (0x14 << 26),
81 OPC_BNE = (0x05 << 26),
82 OPC_BNEL = (0x15 << 26),
83 OPC_BLEZ = (0x06 << 26),
84 OPC_BLEZL = (0x16 << 26),
85 OPC_BGTZ = (0x07 << 26),
86 OPC_BGTZL = (0x17 << 26),
87 OPC_JALX = (0x1D << 26),
88 OPC_DAUI = (0x1D << 26),
89 /* Load and stores */
90 OPC_LDL = (0x1A << 26),
91 OPC_LDR = (0x1B << 26),
92 OPC_LB = (0x20 << 26),
93 OPC_LH = (0x21 << 26),
94 OPC_LWL = (0x22 << 26),
95 OPC_LW = (0x23 << 26),
96 OPC_LWPC = OPC_LW | 0x5,
97 OPC_LBU = (0x24 << 26),
98 OPC_LHU = (0x25 << 26),
99 OPC_LWR = (0x26 << 26),
100 OPC_LWU = (0x27 << 26),
101 OPC_SB = (0x28 << 26),
102 OPC_SH = (0x29 << 26),
103 OPC_SWL = (0x2A << 26),
104 OPC_SW = (0x2B << 26),
105 OPC_SDL = (0x2C << 26),
106 OPC_SDR = (0x2D << 26),
107 OPC_SWR = (0x2E << 26),
108 OPC_LL = (0x30 << 26),
109 OPC_LLD = (0x34 << 26),
110 OPC_LD = (0x37 << 26),
111 OPC_LDPC = OPC_LD | 0x5,
112 OPC_SC = (0x38 << 26),
113 OPC_SCD = (0x3C << 26),
114 OPC_SD = (0x3F << 26),
115 /* Floating point load/store */
116 OPC_LWC1 = (0x31 << 26),
117 OPC_LWC2 = (0x32 << 26),
118 OPC_LDC1 = (0x35 << 26),
119 OPC_LDC2 = (0x36 << 26),
120 OPC_SWC1 = (0x39 << 26),
121 OPC_SWC2 = (0x3A << 26),
122 OPC_SDC1 = (0x3D << 26),
123 OPC_SDC2 = (0x3E << 26),
124 /* Compact Branches */
125 OPC_BLEZALC = (0x06 << 26),
126 OPC_BGEZALC = (0x06 << 26),
127 OPC_BGEUC = (0x06 << 26),
128 OPC_BGTZALC = (0x07 << 26),
129 OPC_BLTZALC = (0x07 << 26),
130 OPC_BLTUC = (0x07 << 26),
131 OPC_BOVC = (0x08 << 26),
132 OPC_BEQZALC = (0x08 << 26),
133 OPC_BEQC = (0x08 << 26),
134 OPC_BLEZC = (0x16 << 26),
135 OPC_BGEZC = (0x16 << 26),
136 OPC_BGEC = (0x16 << 26),
137 OPC_BGTZC = (0x17 << 26),
138 OPC_BLTZC = (0x17 << 26),
139 OPC_BLTC = (0x17 << 26),
140 OPC_BNVC = (0x18 << 26),
141 OPC_BNEZALC = (0x18 << 26),
142 OPC_BNEC = (0x18 << 26),
143 OPC_BC = (0x32 << 26),
144 OPC_BEQZC = (0x36 << 26),
145 OPC_JIC = (0x36 << 26),
146 OPC_BALC = (0x3A << 26),
147 OPC_BNEZC = (0x3E << 26),
148 OPC_JIALC = (0x3E << 26),
149 /* MDMX ASE specific */
150 OPC_MDMX = (0x1E << 26),
151 /* Cache and prefetch */
152 OPC_CACHE = (0x2F << 26),
153 OPC_PREF = (0x33 << 26),
154 /* PC-relative address computation / loads */
155 OPC_PCREL = (0x3B << 26),
156 };
157
158 /* PC-relative address computation / loads */
159 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
160 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
161 enum {
162 /* Instructions determined by bits 19 and 20 */
163 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
164 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
165 OPC_LWUPC = OPC_PCREL | (2 << 19),
166
167 /* Instructions determined by bits 16 ... 20 */
168 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
169 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
170
171 /* Other */
172 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
173 };
174
175 /* MIPS special opcodes */
176 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
177
178 enum {
179 /* Shifts */
180 OPC_SLL = 0x00 | OPC_SPECIAL,
181 /* NOP is SLL r0, r0, 0 */
182 /* SSNOP is SLL r0, r0, 1 */
183 /* EHB is SLL r0, r0, 3 */
184 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
185 OPC_ROTR = OPC_SRL | (1 << 21),
186 OPC_SRA = 0x03 | OPC_SPECIAL,
187 OPC_SLLV = 0x04 | OPC_SPECIAL,
188 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
189 OPC_ROTRV = OPC_SRLV | (1 << 6),
190 OPC_SRAV = 0x07 | OPC_SPECIAL,
191 OPC_DSLLV = 0x14 | OPC_SPECIAL,
192 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
193 OPC_DROTRV = OPC_DSRLV | (1 << 6),
194 OPC_DSRAV = 0x17 | OPC_SPECIAL,
195 OPC_DSLL = 0x38 | OPC_SPECIAL,
196 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
197 OPC_DROTR = OPC_DSRL | (1 << 21),
198 OPC_DSRA = 0x3B | OPC_SPECIAL,
199 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
200 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
201 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
202 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
203 /* Multiplication / division */
204 OPC_MULT = 0x18 | OPC_SPECIAL,
205 OPC_MULTU = 0x19 | OPC_SPECIAL,
206 OPC_DIV = 0x1A | OPC_SPECIAL,
207 OPC_DIVU = 0x1B | OPC_SPECIAL,
208 OPC_DMULT = 0x1C | OPC_SPECIAL,
209 OPC_DMULTU = 0x1D | OPC_SPECIAL,
210 OPC_DDIV = 0x1E | OPC_SPECIAL,
211 OPC_DDIVU = 0x1F | OPC_SPECIAL,
212
213 /* 2 registers arithmetic / logic */
214 OPC_ADD = 0x20 | OPC_SPECIAL,
215 OPC_ADDU = 0x21 | OPC_SPECIAL,
216 OPC_SUB = 0x22 | OPC_SPECIAL,
217 OPC_SUBU = 0x23 | OPC_SPECIAL,
218 OPC_AND = 0x24 | OPC_SPECIAL,
219 OPC_OR = 0x25 | OPC_SPECIAL,
220 OPC_XOR = 0x26 | OPC_SPECIAL,
221 OPC_NOR = 0x27 | OPC_SPECIAL,
222 OPC_SLT = 0x2A | OPC_SPECIAL,
223 OPC_SLTU = 0x2B | OPC_SPECIAL,
224 OPC_DADD = 0x2C | OPC_SPECIAL,
225 OPC_DADDU = 0x2D | OPC_SPECIAL,
226 OPC_DSUB = 0x2E | OPC_SPECIAL,
227 OPC_DSUBU = 0x2F | OPC_SPECIAL,
228 /* Jumps */
229 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
230 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
231 /* Traps */
232 OPC_TGE = 0x30 | OPC_SPECIAL,
233 OPC_TGEU = 0x31 | OPC_SPECIAL,
234 OPC_TLT = 0x32 | OPC_SPECIAL,
235 OPC_TLTU = 0x33 | OPC_SPECIAL,
236 OPC_TEQ = 0x34 | OPC_SPECIAL,
237 OPC_TNE = 0x36 | OPC_SPECIAL,
238 /* HI / LO registers load & stores */
239 OPC_MFHI = 0x10 | OPC_SPECIAL,
240 OPC_MTHI = 0x11 | OPC_SPECIAL,
241 OPC_MFLO = 0x12 | OPC_SPECIAL,
242 OPC_MTLO = 0x13 | OPC_SPECIAL,
243 /* Conditional moves */
244 OPC_MOVZ = 0x0A | OPC_SPECIAL,
245 OPC_MOVN = 0x0B | OPC_SPECIAL,
246
247 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
248 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
249
250 OPC_MOVCI = 0x01 | OPC_SPECIAL,
251
252 /* Special */
253 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
254 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
255 OPC_BREAK = 0x0D | OPC_SPECIAL,
256 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
257 OPC_SYNC = 0x0F | OPC_SPECIAL,
258
259 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
260 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
261 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
262 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
263 };
264
265 /*
266 * R6 Multiply and Divide instructions have the same opcode
267 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
268 */
269 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
270
271 enum {
272 R6_OPC_MUL = OPC_MULT | (2 << 6),
273 R6_OPC_MUH = OPC_MULT | (3 << 6),
274 R6_OPC_MULU = OPC_MULTU | (2 << 6),
275 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
276 R6_OPC_DIV = OPC_DIV | (2 << 6),
277 R6_OPC_MOD = OPC_DIV | (3 << 6),
278 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
279 R6_OPC_MODU = OPC_DIVU | (3 << 6),
280
281 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
282 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
283 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
284 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
285 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
286 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
287 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
288 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
289
290 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
291 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
292 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
293 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
294 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
295 };
296
297 /* REGIMM (rt field) opcodes */
298 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
299
300 enum {
301 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
302 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
303 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
304 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
305 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
306 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
307 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
308 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
309 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
310 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
311 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
312 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
313 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
314 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
315 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
316 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
317
318 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
319 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
320 };
321
322 /* Special2 opcodes */
323 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
324
325 enum {
326 /* Multiply & xxx operations */
327 OPC_MADD = 0x00 | OPC_SPECIAL2,
328 OPC_MADDU = 0x01 | OPC_SPECIAL2,
329 OPC_MUL = 0x02 | OPC_SPECIAL2,
330 OPC_MSUB = 0x04 | OPC_SPECIAL2,
331 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
332 /* Loongson 2F */
333 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
334 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
335 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
336 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
337 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
338 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
339 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
340 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
341 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
342 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
343 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
344 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
345 /* Misc */
346 OPC_CLZ = 0x20 | OPC_SPECIAL2,
347 OPC_CLO = 0x21 | OPC_SPECIAL2,
348 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
349 OPC_DCLO = 0x25 | OPC_SPECIAL2,
350 /* Special */
351 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
352 };
353
354 /* Special3 opcodes */
355 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
356
357 enum {
358 OPC_EXT = 0x00 | OPC_SPECIAL3,
359 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
360 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
361 OPC_DEXT = 0x03 | OPC_SPECIAL3,
362 OPC_INS = 0x04 | OPC_SPECIAL3,
363 OPC_DINSM = 0x05 | OPC_SPECIAL3,
364 OPC_DINSU = 0x06 | OPC_SPECIAL3,
365 OPC_DINS = 0x07 | OPC_SPECIAL3,
366 OPC_FORK = 0x08 | OPC_SPECIAL3,
367 OPC_YIELD = 0x09 | OPC_SPECIAL3,
368 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
369 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
370 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
371 OPC_GINV = 0x3D | OPC_SPECIAL3,
372
373 /* Loongson 2E */
374 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
375 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
376 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
377 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
378 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
379 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
380 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
381 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
382 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
383 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
384 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
385 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
386
387 /* MIPS DSP Load */
388 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
389 /* MIPS DSP Arithmetic */
390 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
391 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
392 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
393 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
394 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
395 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
396 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
397 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
398 /* MIPS DSP GPR-Based Shift Sub-class */
399 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
400 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
401 /* MIPS DSP Multiply Sub-class insns */
402 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
403 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
404 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
405 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
406 /* DSP Bit/Manipulation Sub-class */
407 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
408 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
409 /* MIPS DSP Append Sub-class */
410 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
411 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
412 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
413 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
414 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
415
416 /* EVA */
417 OPC_LWLE = 0x19 | OPC_SPECIAL3,
418 OPC_LWRE = 0x1A | OPC_SPECIAL3,
419 OPC_CACHEE = 0x1B | OPC_SPECIAL3,
420 OPC_SBE = 0x1C | OPC_SPECIAL3,
421 OPC_SHE = 0x1D | OPC_SPECIAL3,
422 OPC_SCE = 0x1E | OPC_SPECIAL3,
423 OPC_SWE = 0x1F | OPC_SPECIAL3,
424 OPC_SWLE = 0x21 | OPC_SPECIAL3,
425 OPC_SWRE = 0x22 | OPC_SPECIAL3,
426 OPC_PREFE = 0x23 | OPC_SPECIAL3,
427 OPC_LBUE = 0x28 | OPC_SPECIAL3,
428 OPC_LHUE = 0x29 | OPC_SPECIAL3,
429 OPC_LBE = 0x2C | OPC_SPECIAL3,
430 OPC_LHE = 0x2D | OPC_SPECIAL3,
431 OPC_LLE = 0x2E | OPC_SPECIAL3,
432 OPC_LWE = 0x2F | OPC_SPECIAL3,
433
434 /* R6 */
435 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
436 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
437 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
438 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
439 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
440 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
441 };
442
443 /* Loongson EXT load/store quad word opcodes */
444 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
445 enum {
446 OPC_GSLQ = 0x0020 | OPC_LWC2,
447 OPC_GSLQC1 = 0x8020 | OPC_LWC2,
448 OPC_GSSHFL = OPC_LWC2,
449 OPC_GSSQ = 0x0020 | OPC_SWC2,
450 OPC_GSSQC1 = 0x8020 | OPC_SWC2,
451 OPC_GSSHFS = OPC_SWC2,
452 };
453
454 /* Loongson EXT shifted load/store opcodes */
455 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
456 enum {
457 OPC_GSLWLC1 = 0x4 | OPC_GSSHFL,
458 OPC_GSLWRC1 = 0x5 | OPC_GSSHFL,
459 OPC_GSLDLC1 = 0x6 | OPC_GSSHFL,
460 OPC_GSLDRC1 = 0x7 | OPC_GSSHFL,
461 OPC_GSSWLC1 = 0x4 | OPC_GSSHFS,
462 OPC_GSSWRC1 = 0x5 | OPC_GSSHFS,
463 OPC_GSSDLC1 = 0x6 | OPC_GSSHFS,
464 OPC_GSSDRC1 = 0x7 | OPC_GSSHFS,
465 };
466
467 /* Loongson EXT LDC2/SDC2 opcodes */
468 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
469
470 enum {
471 OPC_GSLBX = 0x0 | OPC_LDC2,
472 OPC_GSLHX = 0x1 | OPC_LDC2,
473 OPC_GSLWX = 0x2 | OPC_LDC2,
474 OPC_GSLDX = 0x3 | OPC_LDC2,
475 OPC_GSLWXC1 = 0x6 | OPC_LDC2,
476 OPC_GSLDXC1 = 0x7 | OPC_LDC2,
477 OPC_GSSBX = 0x0 | OPC_SDC2,
478 OPC_GSSHX = 0x1 | OPC_SDC2,
479 OPC_GSSWX = 0x2 | OPC_SDC2,
480 OPC_GSSDX = 0x3 | OPC_SDC2,
481 OPC_GSSWXC1 = 0x6 | OPC_SDC2,
482 OPC_GSSDXC1 = 0x7 | OPC_SDC2,
483 };
484
485 /* BSHFL opcodes */
486 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
487
488 enum {
489 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
490 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
491 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
492 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
493 OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL,
494 OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL,
495 OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL,
496 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
497 };
498
499 /* DBSHFL opcodes */
500 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
501
502 enum {
503 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
504 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
505 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
506 OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL,
507 OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL,
508 OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL,
509 OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL,
510 OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL,
511 OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL,
512 OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL,
513 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
514 };
515
516 /* MIPS DSP REGIMM opcodes */
517 enum {
518 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
519 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
520 };
521
522 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
523 /* MIPS DSP Load */
524 enum {
525 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
526 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
527 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
528 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
529 };
530
531 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
532 enum {
533 /* MIPS DSP Arithmetic Sub-class */
534 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
535 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
536 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
537 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
538 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
539 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
540 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
541 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
542 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
543 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
544 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
545 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
546 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
547 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
548 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
549 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
550 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
551 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
552 /* MIPS DSP Multiply Sub-class insns */
553 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
554 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
555 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
556 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
557 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
558 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
559 };
560
561 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
562 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
563 enum {
564 /* MIPS DSP Arithmetic Sub-class */
565 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
566 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
567 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
568 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
569 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
570 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
571 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
572 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
573 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
574 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
575 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
576 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
577 /* MIPS DSP Multiply Sub-class insns */
578 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
579 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
580 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
581 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
582 };
583
584 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
585 enum {
586 /* MIPS DSP Arithmetic Sub-class */
587 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
588 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
589 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
590 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
591 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
592 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
593 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
594 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
595 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
596 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
597 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
598 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
599 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
600 /* DSP Bit/Manipulation Sub-class */
601 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
602 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
603 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
604 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
605 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
606 };
607
608 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
609 enum {
610 /* MIPS DSP Arithmetic Sub-class */
611 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
612 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
613 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
614 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
615 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
616 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
617 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
618 /* DSP Compare-Pick Sub-class */
619 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
620 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
621 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
622 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
623 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
624 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
625 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
626 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
627 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
628 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
629 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
630 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
631 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
632 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
633 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
634 };
635
636 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 enum {
638 /* MIPS DSP GPR-Based Shift Sub-class */
639 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
640 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
641 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
642 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
643 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
644 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
645 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
646 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
647 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
648 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
649 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
650 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
651 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
652 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
653 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
654 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
655 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
656 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
657 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
658 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
659 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
660 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
661 };
662
663 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
664 enum {
665 /* MIPS DSP Multiply Sub-class insns */
666 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
667 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
668 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
669 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
670 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
671 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
672 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
673 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
674 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
675 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
676 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
677 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
678 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
679 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
680 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
681 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
682 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
683 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
684 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
685 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
686 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
687 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
688 };
689
690 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
691 enum {
692 /* DSP Bit/Manipulation Sub-class */
693 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
694 };
695
696 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
697 enum {
698 /* MIPS DSP Append Sub-class */
699 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
700 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
701 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
702 };
703
704 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 enum {
706 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
707 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
708 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
709 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
710 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
711 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
712 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
713 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
714 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
715 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
716 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
717 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
718 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
719 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
720 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
721 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
722 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
723 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
724 };
725
726 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
727 enum {
728 /* MIPS DSP Arithmetic Sub-class */
729 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
730 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
731 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
732 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
733 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
734 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
735 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
736 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
737 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
738 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
739 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
740 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
741 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
742 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
743 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
744 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
745 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
746 /* DSP Bit/Manipulation Sub-class */
747 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
748 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
749 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
750 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
751 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
752 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
753 };
754
755 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
756 enum {
757 /* MIPS DSP Multiply Sub-class insns */
758 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
759 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
760 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
761 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
762 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
763 /* MIPS DSP Arithmetic Sub-class */
764 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
765 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
766 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
767 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
768 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
769 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
770 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
771 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
772 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
773 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
774 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
775 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
776 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
777 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
778 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
779 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
780 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
781 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
782 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
783 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
784 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
785 };
786
787 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
788 enum {
789 /* DSP Compare-Pick Sub-class */
790 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
791 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
792 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
793 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
794 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
795 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
796 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
797 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
798 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
799 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
800 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
801 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
802 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
803 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
804 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
805 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
806 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
807 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
808 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
809 /* MIPS DSP Arithmetic Sub-class */
810 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
811 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
812 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
813 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
814 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
815 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
816 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
817 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
818 };
819
820 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
821 enum {
822 /* DSP Append Sub-class */
823 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
824 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
825 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
826 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
827 };
828
829 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830 enum {
831 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
832 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
833 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
834 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
835 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
836 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
837 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
838 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
839 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
840 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
841 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
842 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
843 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
844 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
845 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
846 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
847 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
848 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
849 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
850 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
851 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
852 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
853 };
854
855 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
856 enum {
857 /* DSP Bit/Manipulation Sub-class */
858 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
859 };
860
861 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
862 enum {
863 /* MIPS DSP Multiply Sub-class insns */
864 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
865 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
866 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
867 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
868 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
869 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
870 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
871 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
872 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
873 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
874 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
875 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
876 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
877 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
878 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
879 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
880 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
881 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
882 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
883 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
884 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
885 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
886 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
887 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
888 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
889 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
890 };
891
892 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
893 enum {
894 /* MIPS DSP GPR-Based Shift Sub-class */
895 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
896 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
897 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
898 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
899 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
900 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
901 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
902 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
903 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
904 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
905 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
906 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
907 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
908 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
909 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
910 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
911 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
912 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
913 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
914 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
915 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
916 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
917 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
918 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
919 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
920 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
921 };
922
923 /* Coprocessor 0 (rs field) */
924 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
925
926 enum {
927 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
928 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
929 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
930 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
931 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
932 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
933 OPC_MFTR = (0x08 << 21) | OPC_CP0,
934 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
935 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
936 OPC_MTTR = (0x0C << 21) | OPC_CP0,
937 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
938 OPC_C0 = (0x10 << 21) | OPC_CP0,
939 OPC_C0_1 = (0x11 << 21) | OPC_CP0,
940 OPC_C0_2 = (0x12 << 21) | OPC_CP0,
941 OPC_C0_3 = (0x13 << 21) | OPC_CP0,
942 OPC_C0_4 = (0x14 << 21) | OPC_CP0,
943 OPC_C0_5 = (0x15 << 21) | OPC_CP0,
944 OPC_C0_6 = (0x16 << 21) | OPC_CP0,
945 OPC_C0_7 = (0x17 << 21) | OPC_CP0,
946 OPC_C0_8 = (0x18 << 21) | OPC_CP0,
947 OPC_C0_9 = (0x19 << 21) | OPC_CP0,
948 OPC_C0_A = (0x1A << 21) | OPC_CP0,
949 OPC_C0_B = (0x1B << 21) | OPC_CP0,
950 OPC_C0_C = (0x1C << 21) | OPC_CP0,
951 OPC_C0_D = (0x1D << 21) | OPC_CP0,
952 OPC_C0_E = (0x1E << 21) | OPC_CP0,
953 OPC_C0_F = (0x1F << 21) | OPC_CP0,
954 };
955
956 /* MFMC0 opcodes */
957 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
958
959 enum {
960 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
961 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
962 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
963 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
964 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
965 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
966 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
967 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
968 };
969
970 /* Coprocessor 0 (with rs == C0) */
971 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
972
973 enum {
974 OPC_TLBR = 0x01 | OPC_C0,
975 OPC_TLBWI = 0x02 | OPC_C0,
976 OPC_TLBINV = 0x03 | OPC_C0,
977 OPC_TLBINVF = 0x04 | OPC_C0,
978 OPC_TLBWR = 0x06 | OPC_C0,
979 OPC_TLBP = 0x08 | OPC_C0,
980 OPC_RFE = 0x10 | OPC_C0,
981 OPC_ERET = 0x18 | OPC_C0,
982 OPC_DERET = 0x1F | OPC_C0,
983 OPC_WAIT = 0x20 | OPC_C0,
984 };
985
986 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
987
988 enum {
989 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
990 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
991 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
992 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
993 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
994 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
995 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
996 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
997 OPC_BC2 = (0x08 << 21) | OPC_CP2,
998 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
999 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1000 };
1001
1002 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1003
1004 enum {
1005 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1013
1014 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1022
1023 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1024 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1027 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1028 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1029 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1030 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1031
1032 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1033 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1036 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1040
1041 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1042 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1043 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1047
1048 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1049 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1054
1055 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1063 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1070 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1071 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1072 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1073 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1074 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1077 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1078 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1079 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1080 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1081 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1084 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1085 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1086 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1087 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1088 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1091 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1092 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1093 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1094 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1095 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1096 };
1097
1098
1099 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1100
1101 enum {
1102 OPC_LWXC1 = 0x00 | OPC_CP3,
1103 OPC_LDXC1 = 0x01 | OPC_CP3,
1104 OPC_LUXC1 = 0x05 | OPC_CP3,
1105 OPC_SWXC1 = 0x08 | OPC_CP3,
1106 OPC_SDXC1 = 0x09 | OPC_CP3,
1107 OPC_SUXC1 = 0x0D | OPC_CP3,
1108 OPC_PREFX = 0x0F | OPC_CP3,
1109 OPC_ALNV_PS = 0x1E | OPC_CP3,
1110 OPC_MADD_S = 0x20 | OPC_CP3,
1111 OPC_MADD_D = 0x21 | OPC_CP3,
1112 OPC_MADD_PS = 0x26 | OPC_CP3,
1113 OPC_MSUB_S = 0x28 | OPC_CP3,
1114 OPC_MSUB_D = 0x29 | OPC_CP3,
1115 OPC_MSUB_PS = 0x2E | OPC_CP3,
1116 OPC_NMADD_S = 0x30 | OPC_CP3,
1117 OPC_NMADD_D = 0x31 | OPC_CP3,
1118 OPC_NMADD_PS = 0x36 | OPC_CP3,
1119 OPC_NMSUB_S = 0x38 | OPC_CP3,
1120 OPC_NMSUB_D = 0x39 | OPC_CP3,
1121 OPC_NMSUB_PS = 0x3E | OPC_CP3,
1122 };
1123
1124 /*
1125 * MMI (MultiMedia Instruction) encodings
1126 * ======================================
1127 *
1128 * MMI instructions encoding table keys:
1129 *
1130 * * This code is reserved for future use. An attempt to execute it
1131 * causes a Reserved Instruction exception.
1132 * % This code indicates an instruction class. The instruction word
1133 * must be further decoded by examining additional tables that show
1134 * the values for other instruction fields.
1135 * # This code is reserved for the unsupported instructions DMULT,
1136 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1137 * to execute it causes a Reserved Instruction exception.
1138 *
1139 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1140 *
1141 * 31 26 0
1142 * +--------+----------------------------------------+
1143 * | opcode | |
1144 * +--------+----------------------------------------+
1145 *
1146 * opcode bits 28..26
1147 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1148 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1149 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1150 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
1151 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
1152 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
1153 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
1154 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
1155 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
1156 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
1157 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
1158 */
1159
1160 enum {
1161 MMI_OPC_CLASS_MMI = 0x1C << 26, /* Same as OPC_SPECIAL2 */
1162 MMI_OPC_SQ = 0x1F << 26, /* Same as OPC_SPECIAL3 */
1163 };
1164
1165 /*
1166 * MMI instructions with opcode field = MMI:
1167 *
1168 * 31 26 5 0
1169 * +--------+-------------------------------+--------+
1170 * | MMI | |function|
1171 * +--------+-------------------------------+--------+
1172 *
1173 * function bits 2..0
1174 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
1175 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
1176 * -------+-------+-------+-------+-------+-------+-------+-------+-------
1177 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
1178 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
1179 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
1180 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
1181 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
1182 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
1183 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
1184 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
1185 */
1186
1187 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1188 enum {
1189 MMI_OPC_MADD = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1190 MMI_OPC_MADDU = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1191 MMI_OPC_MULT1 = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1192 MMI_OPC_MULTU1 = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1193 MMI_OPC_DIV1 = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV */
1194 MMI_OPC_DIVU1 = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1195 MMI_OPC_MADD1 = 0x20 | MMI_OPC_CLASS_MMI,
1196 MMI_OPC_MADDU1 = 0x21 | MMI_OPC_CLASS_MMI,
1197 };
1198
1199 /* global register indices */
1200 TCGv cpu_gpr[32], cpu_PC;
1201 /*
1202 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1203 * and the upper halves in cpu_gpr_hi[].
1204 */
1205 TCGv_i64 cpu_gpr_hi[32];
1206 TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1207 static TCGv cpu_dspctrl, btarget;
1208 TCGv bcond;
1209 static TCGv cpu_lladdr, cpu_llval;
1210 static TCGv_i32 hflags;
1211 TCGv_i32 fpu_fcr0, fpu_fcr31;
1212 TCGv_i64 fpu_f64[32];
1213
1214 #include "exec/gen-icount.h"
1215
1216 static const char regnames_HI[][4] = {
1217 "HI0", "HI1", "HI2", "HI3",
1218 };
1219
1220 static const char regnames_LO[][4] = {
1221 "LO0", "LO1", "LO2", "LO3",
1222 };
1223
1224 /* General purpose registers moves. */
1225 void gen_load_gpr(TCGv t, int reg)
1226 {
1227 if (reg == 0) {
1228 tcg_gen_movi_tl(t, 0);
1229 } else {
1230 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1231 }
1232 }
1233
1234 void gen_store_gpr(TCGv t, int reg)
1235 {
1236 if (reg != 0) {
1237 tcg_gen_mov_tl(cpu_gpr[reg], t);
1238 }
1239 }
1240
1241 #if defined(TARGET_MIPS64)
1242 void gen_load_gpr_hi(TCGv_i64 t, int reg)
1243 {
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 if (reg != 0) {
1254 tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1255 }
1256 }
1257 #endif /* TARGET_MIPS64 */
1258
1259 /* Moves to/from shadow registers. */
1260 static inline void gen_load_srsgpr(int from, int to)
1261 {
1262 TCGv t0 = tcg_temp_new();
1263
1264 if (from == 0) {
1265 tcg_gen_movi_tl(t0, 0);
1266 } else {
1267 TCGv_i32 t2 = tcg_temp_new_i32();
1268 TCGv_ptr addr = tcg_temp_new_ptr();
1269
1270 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1271 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1272 tcg_gen_andi_i32(t2, t2, 0xf);
1273 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1274 tcg_gen_ext_i32_ptr(addr, t2);
1275 tcg_gen_add_ptr(addr, cpu_env, addr);
1276
1277 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1278 tcg_temp_free_ptr(addr);
1279 tcg_temp_free_i32(t2);
1280 }
1281 gen_store_gpr(t0, to);
1282 tcg_temp_free(t0);
1283 }
1284
1285 static inline void gen_store_srsgpr(int from, int to)
1286 {
1287 if (to != 0) {
1288 TCGv t0 = tcg_temp_new();
1289 TCGv_i32 t2 = tcg_temp_new_i32();
1290 TCGv_ptr addr = tcg_temp_new_ptr();
1291
1292 gen_load_gpr(t0, from);
1293 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1294 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1295 tcg_gen_andi_i32(t2, t2, 0xf);
1296 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1297 tcg_gen_ext_i32_ptr(addr, t2);
1298 tcg_gen_add_ptr(addr, cpu_env, addr);
1299
1300 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1301 tcg_temp_free_ptr(addr);
1302 tcg_temp_free_i32(t2);
1303 tcg_temp_free(t0);
1304 }
1305 }
1306
1307 /* Tests */
1308 static inline void gen_save_pc(target_ulong pc)
1309 {
1310 tcg_gen_movi_tl(cpu_PC, pc);
1311 }
1312
1313 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1314 {
1315 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1316 if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1317 gen_save_pc(ctx->base.pc_next);
1318 ctx->saved_pc = ctx->base.pc_next;
1319 }
1320 if (ctx->hflags != ctx->saved_hflags) {
1321 tcg_gen_movi_i32(hflags, ctx->hflags);
1322 ctx->saved_hflags = ctx->hflags;
1323 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1324 case MIPS_HFLAG_BR:
1325 break;
1326 case MIPS_HFLAG_BC:
1327 case MIPS_HFLAG_BL:
1328 case MIPS_HFLAG_B:
1329 tcg_gen_movi_tl(btarget, ctx->btarget);
1330 break;
1331 }
1332 }
1333 }
1334
1335 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1336 {
1337 ctx->saved_hflags = ctx->hflags;
1338 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1339 case MIPS_HFLAG_BR:
1340 break;
1341 case MIPS_HFLAG_BC:
1342 case MIPS_HFLAG_BL:
1343 case MIPS_HFLAG_B:
1344 ctx->btarget = env->btarget;
1345 break;
1346 }
1347 }
1348
1349 void generate_exception_err(DisasContext *ctx, int excp, int err)
1350 {
1351 save_cpu_state(ctx, 1);
1352 gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp),
1353 tcg_constant_i32(err));
1354 ctx->base.is_jmp = DISAS_NORETURN;
1355 }
1356
1357 void generate_exception(DisasContext *ctx, int excp)
1358 {
1359 gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
1360 }
1361
1362 void generate_exception_end(DisasContext *ctx, int excp)
1363 {
1364 generate_exception_err(ctx, excp, 0);
1365 }
1366
1367 void generate_exception_break(DisasContext *ctx, int code)
1368 {
1369 #ifdef CONFIG_USER_ONLY
1370 /* Pass the break code along to cpu_loop. */
1371 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
1372 offsetof(CPUMIPSState, error_code));
1373 #endif
1374 generate_exception_end(ctx, EXCP_BREAK);
1375 }
1376
1377 void gen_reserved_instruction(DisasContext *ctx)
1378 {
1379 generate_exception_end(ctx, EXCP_RI);
1380 }
1381
1382 /* Floating point register moves. */
1383 void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1384 {
1385 if (ctx->hflags & MIPS_HFLAG_FRE) {
1386 generate_exception(ctx, EXCP_RI);
1387 }
1388 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1389 }
1390
1391 void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1392 {
1393 TCGv_i64 t64;
1394 if (ctx->hflags & MIPS_HFLAG_FRE) {
1395 generate_exception(ctx, EXCP_RI);
1396 }
1397 t64 = tcg_temp_new_i64();
1398 tcg_gen_extu_i32_i64(t64, t);
1399 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1400 tcg_temp_free_i64(t64);
1401 }
1402
1403 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1404 {
1405 if (ctx->hflags & MIPS_HFLAG_F64) {
1406 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1407 } else {
1408 gen_load_fpr32(ctx, t, reg | 1);
1409 }
1410 }
1411
1412 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1413 {
1414 if (ctx->hflags & MIPS_HFLAG_F64) {
1415 TCGv_i64 t64 = tcg_temp_new_i64();
1416 tcg_gen_extu_i32_i64(t64, t);
1417 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1418 tcg_temp_free_i64(t64);
1419 } else {
1420 gen_store_fpr32(ctx, t, reg | 1);
1421 }
1422 }
1423
1424 void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1425 {
1426 if (ctx->hflags & MIPS_HFLAG_F64) {
1427 tcg_gen_mov_i64(t, fpu_f64[reg]);
1428 } else {
1429 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1430 }
1431 }
1432
1433 void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1434 {
1435 if (ctx->hflags & MIPS_HFLAG_F64) {
1436 tcg_gen_mov_i64(fpu_f64[reg], t);
1437 } else {
1438 TCGv_i64 t0;
1439 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1440 t0 = tcg_temp_new_i64();
1441 tcg_gen_shri_i64(t0, t, 32);
1442 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1443 tcg_temp_free_i64(t0);
1444 }
1445 }
1446
1447 int get_fp_bit(int cc)
1448 {
1449 if (cc) {
1450 return 24 + cc;
1451 } else {
1452 return 23;
1453 }
1454 }
1455
1456 /* Addresses computation */
1457 void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1458 {
1459 tcg_gen_add_tl(ret, arg0, arg1);
1460
1461 #if defined(TARGET_MIPS64)
1462 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1463 tcg_gen_ext32s_i64(ret, ret);
1464 }
1465 #endif
1466 }
1467
1468 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1469 target_long ofs)
1470 {
1471 tcg_gen_addi_tl(ret, base, ofs);
1472
1473 #if defined(TARGET_MIPS64)
1474 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1475 tcg_gen_ext32s_i64(ret, ret);
1476 }
1477 #endif
1478 }
1479
1480 /* Addresses computation (translation time) */
1481 static target_long addr_add(DisasContext *ctx, target_long base,
1482 target_long offset)
1483 {
1484 target_long sum = base + offset;
1485
1486 #if defined(TARGET_MIPS64)
1487 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1488 sum = (int32_t)sum;
1489 }
1490 #endif
1491 return sum;
1492 }
1493
1494 /* Sign-extract the low 32-bits to a target_long. */
1495 void gen_move_low32(TCGv ret, TCGv_i64 arg)
1496 {
1497 #if defined(TARGET_MIPS64)
1498 tcg_gen_ext32s_i64(ret, arg);
1499 #else
1500 tcg_gen_extrl_i64_i32(ret, arg);
1501 #endif
1502 }
1503
1504 /* Sign-extract the high 32-bits to a target_long. */
1505 void gen_move_high32(TCGv ret, TCGv_i64 arg)
1506 {
1507 #if defined(TARGET_MIPS64)
1508 tcg_gen_sari_i64(ret, arg, 32);
1509 #else
1510 tcg_gen_extrh_i64_i32(ret, arg);
1511 #endif
1512 }
1513
1514 bool check_cp0_enabled(DisasContext *ctx)
1515 {
1516 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1517 generate_exception_end(ctx, EXCP_CpU);
1518 return false;
1519 }
1520 return true;
1521 }
1522
1523 void check_cp1_enabled(DisasContext *ctx)
1524 {
1525 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1526 generate_exception_err(ctx, EXCP_CpU, 1);
1527 }
1528 }
1529
1530 /*
1531 * Verify that the processor is running with COP1X instructions enabled.
1532 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1533 * opcode tables.
1534 */
1535 void check_cop1x(DisasContext *ctx)
1536 {
1537 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1538 gen_reserved_instruction(ctx);
1539 }
1540 }
1541
1542 /*
1543 * Verify that the processor is running with 64-bit floating-point
1544 * operations enabled.
1545 */
1546 void check_cp1_64bitmode(DisasContext *ctx)
1547 {
1548 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
1549 gen_reserved_instruction(ctx);
1550 }
1551 }
1552
1553 /*
1554 * Verify if floating point register is valid; an operation is not defined
1555 * if bit 0 of any register specification is set and the FR bit in the
1556 * Status register equals zero, since the register numbers specify an
1557 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1558 * in the Status register equals one, both even and odd register numbers
1559 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1560 *
1561 * Multiple 64 bit wide registers can be checked by calling
1562 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1563 */
1564 void check_cp1_registers(DisasContext *ctx, int regs)
1565 {
1566 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1567 gen_reserved_instruction(ctx);
1568 }
1569 }
1570
1571 /*
1572 * Verify that the processor is running with DSP instructions enabled.
1573 * This is enabled by CP0 Status register MX(24) bit.
1574 */
1575 static inline void check_dsp(DisasContext *ctx)
1576 {
1577 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1578 if (ctx->insn_flags & ASE_DSP) {
1579 generate_exception_end(ctx, EXCP_DSPDIS);
1580 } else {
1581 gen_reserved_instruction(ctx);
1582 }
1583 }
1584 }
1585
1586 static inline void check_dsp_r2(DisasContext *ctx)
1587 {
1588 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1589 if (ctx->insn_flags & ASE_DSP) {
1590 generate_exception_end(ctx, EXCP_DSPDIS);
1591 } else {
1592 gen_reserved_instruction(ctx);
1593 }
1594 }
1595 }
1596
1597 static inline void check_dsp_r3(DisasContext *ctx)
1598 {
1599 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1600 if (ctx->insn_flags & ASE_DSP) {
1601 generate_exception_end(ctx, EXCP_DSPDIS);
1602 } else {
1603 gen_reserved_instruction(ctx);
1604 }
1605 }
1606 }
1607
1608 /*
1609 * This code generates a "reserved instruction" exception if the
1610 * CPU does not support the instruction set corresponding to flags.
1611 */
1612 void check_insn(DisasContext *ctx, uint64_t flags)
1613 {
1614 if (unlikely(!(ctx->insn_flags & flags))) {
1615 gen_reserved_instruction(ctx);
1616 }
1617 }
1618
1619 /*
1620 * This code generates a "reserved instruction" exception if the
1621 * CPU has corresponding flag set which indicates that the instruction
1622 * has been removed.
1623 */
1624 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1625 {
1626 if (unlikely(ctx->insn_flags & flags)) {
1627 gen_reserved_instruction(ctx);
1628 }
1629 }
1630
1631 /*
1632 * The Linux kernel traps certain reserved instruction exceptions to
1633 * emulate the corresponding instructions. QEMU is the kernel in user
1634 * mode, so those traps are emulated by accepting the instructions.
1635 *
1636 * A reserved instruction exception is generated for flagged CPUs if
1637 * QEMU runs in system mode.
1638 */
1639 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1640 {
1641 #ifndef CONFIG_USER_ONLY
1642 check_insn_opc_removed(ctx, flags);
1643 #endif
1644 }
1645
1646 /*
1647 * This code generates a "reserved instruction" exception if the
1648 * CPU does not support 64-bit paired-single (PS) floating point data type.
1649 */
1650 static inline void check_ps(DisasContext *ctx)
1651 {
1652 if (unlikely(!ctx->ps)) {
1653 generate_exception(ctx, EXCP_RI);
1654 }
1655 check_cp1_64bitmode(ctx);
1656 }
1657
1658 /*
1659 * This code generates a "reserved instruction" exception if cpu is not
1660 * 64-bit or 64-bit instructions are not enabled.
1661 */
1662 void check_mips_64(DisasContext *ctx)
1663 {
1664 if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1665 gen_reserved_instruction(ctx);
1666 }
1667 }
1668
1669 #ifndef CONFIG_USER_ONLY
1670 static inline void check_mvh(DisasContext *ctx)
1671 {
1672 if (unlikely(!ctx->mvh)) {
1673 generate_exception(ctx, EXCP_RI);
1674 }
1675 }
1676 #endif
1677
1678 /*
1679 * This code generates a "reserved instruction" exception if the
1680 * Config5 XNP bit is set.
1681 */
1682 static inline void check_xnp(DisasContext *ctx)
1683 {
1684 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1685 gen_reserved_instruction(ctx);
1686 }
1687 }
1688
1689 #ifndef CONFIG_USER_ONLY
1690 /*
1691 * This code generates a "reserved instruction" exception if the
1692 * Config3 PW bit is NOT set.
1693 */
1694 static inline void check_pw(DisasContext *ctx)
1695 {
1696 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1697 gen_reserved_instruction(ctx);
1698 }
1699 }
1700 #endif
1701
1702 /*
1703 * This code generates a "reserved instruction" exception if the
1704 * Config3 MT bit is NOT set.
1705 */
1706 static inline void check_mt(DisasContext *ctx)
1707 {
1708 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1709 gen_reserved_instruction(ctx);
1710 }
1711 }
1712
1713 #ifndef CONFIG_USER_ONLY
1714 /*
1715 * This code generates a "coprocessor unusable" exception if CP0 is not
1716 * available, and, if that is not the case, generates a "reserved instruction"
1717 * exception if the Config5 MT bit is NOT set. This is needed for availability
1718 * control of some of MT ASE instructions.
1719 */
1720 static inline void check_cp0_mt(DisasContext *ctx)
1721 {
1722 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1723 generate_exception_end(ctx, EXCP_CpU);
1724 } else {
1725 if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1726 gen_reserved_instruction(ctx);
1727 }
1728 }
1729 }
1730 #endif
1731
1732 /*
1733 * This code generates a "reserved instruction" exception if the
1734 * Config5 NMS bit is set.
1735 */
1736 static inline void check_nms(DisasContext *ctx)
1737 {
1738 if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1739 gen_reserved_instruction(ctx);
1740 }
1741 }
1742
1743 /*
1744 * This code generates a "reserved instruction" exception if the
1745 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1746 * Config2 TL, and Config5 L2C are unset.
1747 */
1748 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1749 {
1750 if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1751 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1752 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1753 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1754 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1755 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1756 gen_reserved_instruction(ctx);
1757 }
1758 }
1759
1760 /*
1761 * This code generates a "reserved instruction" exception if the
1762 * Config5 EVA bit is NOT set.
1763 */
1764 static inline void check_eva(DisasContext *ctx)
1765 {
1766 if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1767 gen_reserved_instruction(ctx);
1768 }
1769 }
1770
1771
1772 /*
1773 * Define small wrappers for gen_load_fpr* so that we have a uniform
1774 * calling interface for 32 and 64-bit FPRs. No sense in changing
1775 * all callers for gen_load_fpr32 when we need the CTX parameter for
1776 * this one use.
1777 */
1778 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1779 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1780 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1781 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1782 int ft, int fs, int cc) \
1783 { \
1784 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
1785 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
1786 switch (ifmt) { \
1787 case FMT_PS: \
1788 check_ps(ctx); \
1789 break; \
1790 case FMT_D: \
1791 if (abs) { \
1792 check_cop1x(ctx); \
1793 } \
1794 check_cp1_registers(ctx, fs | ft); \
1795 break; \
1796 case FMT_S: \
1797 if (abs) { \
1798 check_cop1x(ctx); \
1799 } \
1800 break; \
1801 } \
1802 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
1803 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
1804 switch (n) { \
1805 case 0: \
1806 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
1807 break; \
1808 case 1: \
1809 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
1810 break; \
1811 case 2: \
1812 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
1813 break; \
1814 case 3: \
1815 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
1816 break; \
1817 case 4: \
1818 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
1819 break; \
1820 case 5: \
1821 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
1822 break; \
1823 case 6: \
1824 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
1825 break; \
1826 case 7: \
1827 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
1828 break; \
1829 case 8: \
1830 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
1831 break; \
1832 case 9: \
1833 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
1834 break; \
1835 case 10: \
1836 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
1837 break; \
1838 case 11: \
1839 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
1840 break; \
1841 case 12: \
1842 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
1843 break; \
1844 case 13: \
1845 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
1846 break; \
1847 case 14: \
1848 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
1849 break; \
1850 case 15: \
1851 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
1852 break; \
1853 default: \
1854 abort(); \
1855 } \
1856 tcg_temp_free_i##bits(fp0); \
1857 tcg_temp_free_i##bits(fp1); \
1858 }
1859
1860 FOP_CONDS(, 0, d, FMT_D, 64)
1861 FOP_CONDS(abs, 1, d, FMT_D, 64)
1862 FOP_CONDS(, 0, s, FMT_S, 32)
1863 FOP_CONDS(abs, 1, s, FMT_S, 32)
1864 FOP_CONDS(, 0, ps, FMT_PS, 64)
1865 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1866 #undef FOP_CONDS
1867
1868 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1869 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
1870 int ft, int fs, int fd) \
1871 { \
1872 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1873 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1874 if (ifmt == FMT_D) { \
1875 check_cp1_registers(ctx, fs | ft | fd); \
1876 } \
1877 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1878 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1879 switch (n) { \
1880 case 0: \
1881 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1882 break; \
1883 case 1: \
1884 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1885 break; \
1886 case 2: \
1887 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1888 break; \
1889 case 3: \
1890 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1891 break; \
1892 case 4: \
1893 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1894 break; \
1895 case 5: \
1896 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1897 break; \
1898 case 6: \
1899 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1900 break; \
1901 case 7: \
1902 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1903 break; \
1904 case 8: \
1905 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1906 break; \
1907 case 9: \
1908 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1909 break; \
1910 case 10: \
1911 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1912 break; \
1913 case 11: \
1914 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1915 break; \
1916 case 12: \
1917 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1918 break; \
1919 case 13: \
1920 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1921 break; \
1922 case 14: \
1923 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1924 break; \
1925 case 15: \
1926 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1927 break; \
1928 case 17: \
1929 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1930 break; \
1931 case 18: \
1932 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1933 break; \
1934 case 19: \
1935 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1936 break; \
1937 case 25: \
1938 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1939 break; \
1940 case 26: \
1941 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1942 break; \
1943 case 27: \
1944 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1945 break; \
1946 default: \
1947 abort(); \
1948 } \
1949 STORE; \
1950 tcg_temp_free_i ## bits(fp0); \
1951 tcg_temp_free_i ## bits(fp1); \
1952 }
1953
1954 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1955 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1956 #undef FOP_CONDNS
1957 #undef gen_ldcmp_fpr32
1958 #undef gen_ldcmp_fpr64
1959
1960 /* load/store instructions. */
1961 #ifdef CONFIG_USER_ONLY
1962 #define OP_LD_ATOMIC(insn, fname) \
1963 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1964 DisasContext *ctx) \
1965 { \
1966 TCGv t0 = tcg_temp_new(); \
1967 tcg_gen_mov_tl(t0, arg1); \
1968 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1969 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1970 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1971 tcg_temp_free(t0); \
1972 }
1973 #else
1974 #define OP_LD_ATOMIC(insn, fname) \
1975 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
1976 DisasContext *ctx) \
1977 { \
1978 gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx)); \
1979 }
1980 #endif
1981 OP_LD_ATOMIC(ll, ld32s);
1982 #if defined(TARGET_MIPS64)
1983 OP_LD_ATOMIC(lld, ld64);
1984 #endif
1985 #undef OP_LD_ATOMIC
1986
1987 void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1988 {
1989 if (base == 0) {
1990 tcg_gen_movi_tl(addr, offset);
1991 } else if (offset == 0) {
1992 gen_load_gpr(addr, base);
1993 } else {
1994 tcg_gen_movi_tl(addr, offset);
1995 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1996 }
1997 }
1998
1999 static target_ulong pc_relative_pc(DisasContext *ctx)
2000 {
2001 target_ulong pc = ctx->base.pc_next;
2002
2003 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2004 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2005
2006 pc -= branch_bytes;
2007 }
2008
2009 pc &= ~(target_ulong)3;
2010 return pc;
2011 }
2012
2013 /* Load */
2014 static void gen_ld(DisasContext *ctx, uint32_t opc,
2015 int rt, int base, int offset)
2016 {
2017 TCGv t0, t1, t2;
2018 int mem_idx = ctx->mem_idx;
2019
2020 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2021 INSN_LOONGSON3A)) {
2022 /*
2023 * Loongson CPU uses a load to zero register for prefetch.
2024 * We emulate it as a NOP. On other CPU we must perform the
2025 * actual memory access.
2026 */
2027 return;
2028 }
2029
2030 t0 = tcg_temp_new();
2031 gen_base_offset_addr(ctx, t0, base, offset);
2032
2033 switch (opc) {
2034 #if defined(TARGET_MIPS64)
2035 case OPC_LWU:
2036 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2037 ctx->default_tcg_memop_mask);
2038 gen_store_gpr(t0, rt);
2039 break;
2040 case OPC_LD:
2041 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ |
2042 ctx->default_tcg_memop_mask);
2043 gen_store_gpr(t0, rt);
2044 break;
2045 case OPC_LLD:
2046 case R6_OPC_LLD:
2047 op_ld_lld(t0, t0, mem_idx, ctx);
2048 gen_store_gpr(t0, rt);
2049 break;
2050 case OPC_LDL:
2051 t1 = tcg_temp_new();
2052 /*
2053 * Do a byte access to possibly trigger a page
2054 * fault with the unaligned address.
2055 */
2056 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2057 tcg_gen_andi_tl(t1, t0, 7);
2058 if (!cpu_is_bigendian(ctx)) {
2059 tcg_gen_xori_tl(t1, t1, 7);
2060 }
2061 tcg_gen_shli_tl(t1, t1, 3);
2062 tcg_gen_andi_tl(t0, t0, ~7);
2063 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2064 tcg_gen_shl_tl(t0, t0, t1);
2065 t2 = tcg_const_tl(-1);
2066 tcg_gen_shl_tl(t2, t2, t1);
2067 gen_load_gpr(t1, rt);
2068 tcg_gen_andc_tl(t1, t1, t2);
2069 tcg_temp_free(t2);
2070 tcg_gen_or_tl(t0, t0, t1);
2071 tcg_temp_free(t1);
2072 gen_store_gpr(t0, rt);
2073 break;
2074 case OPC_LDR:
2075 t1 = tcg_temp_new();
2076 /*
2077 * Do a byte access to possibly trigger a page
2078 * fault with the unaligned address.
2079 */
2080 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2081 tcg_gen_andi_tl(t1, t0, 7);
2082 if (cpu_is_bigendian(ctx)) {
2083 tcg_gen_xori_tl(t1, t1, 7);
2084 }
2085 tcg_gen_shli_tl(t1, t1, 3);
2086 tcg_gen_andi_tl(t0, t0, ~7);
2087 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2088 tcg_gen_shr_tl(t0, t0, t1);
2089 tcg_gen_xori_tl(t1, t1, 63);
2090 t2 = tcg_const_tl(0xfffffffffffffffeull);
2091 tcg_gen_shl_tl(t2, t2, t1);
2092 gen_load_gpr(t1, rt);
2093 tcg_gen_and_tl(t1, t1, t2);
2094 tcg_temp_free(t2);
2095 tcg_gen_or_tl(t0, t0, t1);
2096 tcg_temp_free(t1);
2097 gen_store_gpr(t0, rt);
2098 break;
2099 case OPC_LDPC:
2100 t1 = tcg_const_tl(pc_relative_pc(ctx));
2101 gen_op_addr_add(ctx, t0, t0, t1);
2102 tcg_temp_free(t1);
2103 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUQ);
2104 gen_store_gpr(t0, rt);
2105 break;
2106 #endif
2107 case OPC_LWPC:
2108 t1 = tcg_const_tl(pc_relative_pc(ctx));
2109 gen_op_addr_add(ctx, t0, t0, t1);
2110 tcg_temp_free(t1);
2111 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2112 gen_store_gpr(t0, rt);
2113 break;
2114 case OPC_LWE:
2115 mem_idx = MIPS_HFLAG_UM;
2116 /* fall through */
2117 case OPC_LW:
2118 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2119 ctx->default_tcg_memop_mask);
2120 gen_store_gpr(t0, rt);
2121 break;
2122 case OPC_LHE:
2123 mem_idx = MIPS_HFLAG_UM;
2124 /* fall through */
2125 case OPC_LH:
2126 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2127 ctx->default_tcg_memop_mask);
2128 gen_store_gpr(t0, rt);
2129 break;
2130 case OPC_LHUE:
2131 mem_idx = MIPS_HFLAG_UM;
2132 /* fall through */
2133 case OPC_LHU:
2134 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2135 ctx->default_tcg_memop_mask);
2136 gen_store_gpr(t0, rt);
2137 break;
2138 case OPC_LBE:
2139 mem_idx = MIPS_HFLAG_UM;
2140 /* fall through */
2141 case OPC_LB:
2142 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2143 gen_store_gpr(t0, rt);
2144 break;
2145 case OPC_LBUE:
2146 mem_idx = MIPS_HFLAG_UM;
2147 /* fall through */
2148 case OPC_LBU:
2149 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2150 gen_store_gpr(t0, rt);
2151 break;
2152 case OPC_LWLE:
2153 mem_idx = MIPS_HFLAG_UM;
2154 /* fall through */
2155 case OPC_LWL:
2156 t1 = tcg_temp_new();
2157 /*
2158 * Do a byte access to possibly trigger a page
2159 * fault with the unaligned address.
2160 */
2161 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2162 tcg_gen_andi_tl(t1, t0, 3);
2163 if (!cpu_is_bigendian(ctx)) {
2164 tcg_gen_xori_tl(t1, t1, 3);
2165 }
2166 tcg_gen_shli_tl(t1, t1, 3);
2167 tcg_gen_andi_tl(t0, t0, ~3);
2168 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2169 tcg_gen_shl_tl(t0, t0, t1);
2170 t2 = tcg_const_tl(-1);
2171 tcg_gen_shl_tl(t2, t2, t1);
2172 gen_load_gpr(t1, rt);
2173 tcg_gen_andc_tl(t1, t1, t2);
2174 tcg_temp_free(t2);
2175 tcg_gen_or_tl(t0, t0, t1);
2176 tcg_temp_free(t1);
2177 tcg_gen_ext32s_tl(t0, t0);
2178 gen_store_gpr(t0, rt);
2179 break;
2180 case OPC_LWRE:
2181 mem_idx = MIPS_HFLAG_UM;
2182 /* fall through */
2183 case OPC_LWR:
2184 t1 = tcg_temp_new();
2185 /*
2186 * Do a byte access to possibly trigger a page
2187 * fault with the unaligned address.
2188 */
2189 tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2190 tcg_gen_andi_tl(t1, t0, 3);
2191 if (cpu_is_bigendian(ctx)) {
2192 tcg_gen_xori_tl(t1, t1, 3);
2193 }
2194 tcg_gen_shli_tl(t1, t1, 3);
2195 tcg_gen_andi_tl(t0, t0, ~3);
2196 tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2197 tcg_gen_shr_tl(t0, t0, t1);
2198 tcg_gen_xori_tl(t1, t1, 31);
2199 t2 = tcg_const_tl(0xfffffffeull);
2200 tcg_gen_shl_tl(t2, t2, t1);
2201 gen_load_gpr(t1, rt);
2202 tcg_gen_and_tl(t1, t1, t2);
2203 tcg_temp_free(t2);
2204 tcg_gen_or_tl(t0, t0, t1);
2205 tcg_temp_free(t1);
2206 tcg_gen_ext32s_tl(t0, t0);
2207 gen_store_gpr(t0, rt);
2208 break;
2209 case OPC_LLE:
2210 mem_idx = MIPS_HFLAG_UM;
2211 /* fall through */
2212 case OPC_LL:
2213 case R6_OPC_LL:
2214 op_ld_ll(t0, t0, mem_idx, ctx);
2215 gen_store_gpr(t0, rt);
2216 break;
2217 }
2218 tcg_temp_free(t0);
2219 }
2220
2221 /* Store */
2222 static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2223 int base, int offset)
2224 {
2225 TCGv t0 = tcg_temp_new();
2226 TCGv t1 = tcg_temp_new();
2227 int mem_idx = ctx->mem_idx;
2228
2229 gen_base_offset_addr(ctx, t0, base, offset);
2230 gen_load_gpr(t1, rt);
2231 switch (opc) {
2232 #if defined(TARGET_MIPS64)
2233 case OPC_SD:
2234 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUQ |
2235 ctx->default_tcg_memop_mask);
2236 break;
2237 case OPC_SDL:
2238 gen_helper_0e2i(sdl, t1, t0, mem_idx);
2239 break;
2240 case OPC_SDR:
2241 gen_helper_0e2i(sdr, t1, t0, mem_idx);
2242 break;
2243 #endif
2244 case OPC_SWE:
2245 mem_idx = MIPS_HFLAG_UM;
2246 /* fall through */
2247 case OPC_SW:
2248 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2249 ctx->default_tcg_memop_mask);
2250 break;
2251 case OPC_SHE:
2252 mem_idx = MIPS_HFLAG_UM;
2253 /* fall through */
2254 case OPC_SH:
2255 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2256 ctx->default_tcg_memop_mask);
2257 break;
2258 case OPC_SBE:
2259 mem_idx = MIPS_HFLAG_UM;
2260 /* fall through */
2261 case OPC_SB:
2262 tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2263 break;
2264 case OPC_SWLE:
2265 mem_idx = MIPS_HFLAG_UM;
2266 /* fall through */
2267 case OPC_SWL:
2268 gen_helper_0e2i(swl, t1, t0, mem_idx);
2269 break;
2270 case OPC_SWRE:
2271 mem_idx = MIPS_HFLAG_UM;
2272 /* fall through */
2273 case OPC_SWR:
2274 gen_helper_0e2i(swr, t1, t0, mem_idx);
2275 break;
2276 }
2277 tcg_temp_free(t0);
2278 tcg_temp_free(t1);
2279 }
2280
2281
2282 /* Store conditional */
2283 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2284 MemOp tcg_mo, bool eva)
2285 {
2286 TCGv addr, t0, val;
2287 TCGLabel *l1 = gen_new_label();
2288 TCGLabel *done = gen_new_label();
2289
2290 t0 = tcg_temp_new();
2291 addr = tcg_temp_new();
2292 /* compare the address against that of the preceding LL */
2293 gen_base_offset_addr(ctx, addr, base, offset);
2294 tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2295 tcg_temp_free(addr);
2296 tcg_gen_movi_tl(t0, 0);
2297 gen_store_gpr(t0, rt);
2298 tcg_gen_br(done);
2299
2300 gen_set_label(l1);
2301 /* generate cmpxchg */
2302 val = tcg_temp_new();
2303 gen_load_gpr(val, rt);
2304 tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2305 eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2306 tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2307 gen_store_gpr(t0, rt);
2308 tcg_temp_free(val);
2309
2310 gen_set_label(done);
2311 tcg_temp_free(t0);
2312 }
2313
2314 /* Load and store */
2315 static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2316 TCGv t0)
2317 {
2318 /*
2319 * Don't do NOP if destination is zero: we must perform the actual
2320 * memory access.
2321 */
2322 switch (opc) {
2323 case OPC_LWC1:
2324 {
2325 TCGv_i32 fp0 = tcg_temp_new_i32();
2326 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2327 ctx->default_tcg_memop_mask);
2328 gen_store_fpr32(ctx, fp0, ft);
2329 tcg_temp_free_i32(fp0);
2330 }
2331 break;
2332 case OPC_SWC1:
2333 {
2334 TCGv_i32 fp0 = tcg_temp_new_i32();
2335 gen_load_fpr32(ctx, fp0, ft);
2336 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2337 ctx->default_tcg_memop_mask);
2338 tcg_temp_free_i32(fp0);
2339 }
2340 break;
2341 case OPC_LDC1:
2342 {
2343 TCGv_i64 fp0 = tcg_temp_new_i64();
2344 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2345 ctx->default_tcg_memop_mask);
2346 gen_store_fpr64(ctx, fp0, ft);
2347 tcg_temp_free_i64(fp0);
2348 }
2349 break;
2350 case OPC_SDC1:
2351 {
2352 TCGv_i64 fp0 = tcg_temp_new_i64();
2353 gen_load_fpr64(ctx, fp0, ft);
2354 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ |
2355 ctx->default_tcg_memop_mask);
2356 tcg_temp_free_i64(fp0);
2357 }
2358 break;
2359 default:
2360 MIPS_INVAL("flt_ldst");
2361 gen_reserved_instruction(ctx);
2362 break;
2363 }
2364 }
2365
2366 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2367 int rs, int16_t imm)
2368 {
2369 TCGv t0 = tcg_temp_new();
2370
2371 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2372 check_cp1_enabled(ctx);
2373 switch (op) {
2374 case OPC_LDC1:
2375 case OPC_SDC1:
2376 check_insn(ctx, ISA_MIPS2);
2377 /* Fallthrough */
2378 default:
2379 gen_base_offset_addr(ctx, t0, rs, imm);
2380 gen_flt_ldst(ctx, op, rt, t0);
2381 }
2382 } else {
2383 generate_exception_err(ctx, EXCP_CpU, 1);
2384 }
2385 tcg_temp_free(t0);
2386 }
2387
2388 /* Arithmetic with immediate operand */
2389 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2390 int rt, int rs, int imm)
2391 {
2392 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2393
2394 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2395 /*
2396 * If no destination, treat it as a NOP.
2397 * For addi, we must generate the overflow exception when needed.
2398 */
2399 return;
2400 }
2401 switch (opc) {
2402 case OPC_ADDI:
2403 {
2404 TCGv t0 = tcg_temp_local_new();
2405 TCGv t1 = tcg_temp_new();
2406 TCGv t2 = tcg_temp_new();
2407 TCGLabel *l1 = gen_new_label();
2408
2409 gen_load_gpr(t1, rs);
2410 tcg_gen_addi_tl(t0, t1, uimm);
2411 tcg_gen_ext32s_tl(t0, t0);
2412
2413 tcg_gen_xori_tl(t1, t1, ~uimm);
2414 tcg_gen_xori_tl(t2, t0, uimm);
2415 tcg_gen_and_tl(t1, t1, t2);
2416 tcg_temp_free(t2);
2417 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2418 tcg_temp_free(t1);
2419 /* operands of same sign, result different sign */
2420 generate_exception(ctx, EXCP_OVERFLOW);
2421 gen_set_label(l1);
2422 tcg_gen_ext32s_tl(t0, t0);
2423 gen_store_gpr(t0, rt);
2424 tcg_temp_free(t0);
2425 }
2426 break;
2427 case OPC_ADDIU:
2428 if (rs != 0) {
2429 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2430 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2431 } else {
2432 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2433 }
2434 break;
2435 #if defined(TARGET_MIPS64)
2436 case OPC_DADDI:
2437 {
2438 TCGv t0 = tcg_temp_local_new();
2439 TCGv t1 = tcg_temp_new();
2440 TCGv t2 = tcg_temp_new();
2441 TCGLabel *l1 = gen_new_label();
2442
2443 gen_load_gpr(t1, rs);
2444 tcg_gen_addi_tl(t0, t1, uimm);
2445
2446 tcg_gen_xori_tl(t1, t1, ~uimm);
2447 tcg_gen_xori_tl(t2, t0, uimm);
2448 tcg_gen_and_tl(t1, t1, t2);
2449 tcg_temp_free(t2);
2450 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2451 tcg_temp_free(t1);
2452 /* operands of same sign, result different sign */
2453 generate_exception(ctx, EXCP_OVERFLOW);
2454 gen_set_label(l1);
2455 gen_store_gpr(t0, rt);
2456 tcg_temp_free(t0);
2457 }
2458 break;
2459 case OPC_DADDIU:
2460 if (rs != 0) {
2461 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2462 } else {
2463 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2464 }
2465 break;
2466 #endif
2467 }
2468 }
2469
2470 /* Logic with immediate operand */
2471 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2472 int rt, int rs, int16_t imm)
2473 {
2474 target_ulong uimm;
2475
2476 if (rt == 0) {
2477 /* If no destination, treat it as a NOP. */
2478 return;
2479 }
2480 uimm = (uint16_t)imm;
2481 switch (opc) {
2482 case OPC_ANDI:
2483 if (likely(rs != 0)) {
2484 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2485 } else {
2486 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2487 }
2488 break;
2489 case OPC_ORI:
2490 if (rs != 0) {
2491 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2492 } else {
2493 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2494 }
2495 break;
2496 case OPC_XORI:
2497 if (likely(rs != 0)) {
2498 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2499 } else {
2500 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2501 }
2502 break;
2503 case OPC_LUI:
2504 if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2505 /* OPC_AUI */
2506 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2507 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2508 } else {
2509 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2510 }
2511 break;
2512
2513 default:
2514 break;
2515 }
2516 }
2517
2518 /* Set on less than with immediate operand */
2519 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2520 int rt, int rs, int16_t imm)
2521 {
2522 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2523 TCGv t0;
2524
2525 if (rt == 0) {
2526 /* If no destination, treat it as a NOP. */
2527 return;
2528 }
2529 t0 = tcg_temp_new();
2530 gen_load_gpr(t0, rs);
2531 switch (opc) {
2532 case OPC_SLTI:
2533 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2534 break;
2535 case OPC_SLTIU:
2536 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2537 break;
2538 }
2539 tcg_temp_free(t0);
2540 }
2541
2542 /* Shifts with immediate operand */
2543 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2544 int rt, int rs, int16_t imm)
2545 {
2546 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2547 TCGv t0;
2548
2549 if (rt == 0) {
2550 /* If no destination, treat it as a NOP. */
2551 return;
2552 }
2553
2554 t0 = tcg_temp_new();
2555 gen_load_gpr(t0, rs);
2556 switch (opc) {
2557 case OPC_SLL:
2558 tcg_gen_shli_tl(t0, t0, uimm);
2559 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2560 break;
2561 case OPC_SRA:
2562 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2563 break;
2564 case OPC_SRL:
2565 if (uimm != 0) {
2566 tcg_gen_ext32u_tl(t0, t0);
2567 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2568 } else {
2569 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2570 }
2571 break;
2572 case OPC_ROTR:
2573 if (uimm != 0) {
2574 TCGv_i32 t1 = tcg_temp_new_i32();
2575
2576 tcg_gen_trunc_tl_i32(t1, t0);
2577 tcg_gen_rotri_i32(t1, t1, uimm);
2578 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2579 tcg_temp_free_i32(t1);
2580 } else {
2581 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2582 }
2583 break;
2584 #if defined(TARGET_MIPS64)
2585 case OPC_DSLL:
2586 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2587 break;
2588 case OPC_DSRA:
2589 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2590 break;
2591 case OPC_DSRL:
2592 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2593 break;
2594 case OPC_DROTR:
2595 if (uimm != 0) {
2596 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2597 } else {
2598 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2599 }
2600 break;
2601 case OPC_DSLL32:
2602 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2603 break;
2604 case OPC_DSRA32:
2605 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2606 break;
2607 case OPC_DSRL32:
2608 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2609 break;
2610 case OPC_DROTR32:
2611 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2612 break;
2613 #endif
2614 }
2615 tcg_temp_free(t0);
2616 }
2617
2618 /* Arithmetic */
2619 static void gen_arith(DisasContext *ctx, uint32_t opc,
2620 int rd, int rs, int rt)
2621 {
2622 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2623 && opc != OPC_DADD && opc != OPC_DSUB) {
2624 /*
2625 * If no destination, treat it as a NOP.
2626 * For add & sub, we must generate the overflow exception when needed.
2627 */
2628 return;
2629 }
2630
2631 switch (opc) {
2632 case OPC_ADD:
2633 {
2634 TCGv t0 = tcg_temp_local_new();
2635 TCGv t1 = tcg_temp_new();
2636 TCGv t2 = tcg_temp_new();
2637 TCGLabel *l1 = gen_new_label();
2638
2639 gen_load_gpr(t1, rs);
2640 gen_load_gpr(t2, rt);
2641 tcg_gen_add_tl(t0, t1, t2);
2642 tcg_gen_ext32s_tl(t0, t0);
2643 tcg_gen_xor_tl(t1, t1, t2);
2644 tcg_gen_xor_tl(t2, t0, t2);
2645 tcg_gen_andc_tl(t1, t2, t1);
2646 tcg_temp_free(t2);
2647 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2648 tcg_temp_free(t1);
2649 /* operands of same sign, result different sign */
2650 generate_exception(ctx, EXCP_OVERFLOW);
2651 gen_set_label(l1);
2652 gen_store_gpr(t0, rd);
2653 tcg_temp_free(t0);
2654 }
2655 break;
2656 case OPC_ADDU:
2657 if (rs != 0 && rt != 0) {
2658 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2659 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2660 } else if (rs == 0 && rt != 0) {
2661 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2662 } else if (rs != 0 && rt == 0) {
2663 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2664 } else {
2665 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2666 }
2667 break;
2668 case OPC_SUB:
2669 {
2670 TCGv t0 = tcg_temp_local_new();
2671 TCGv t1 = tcg_temp_new();
2672 TCGv t2 = tcg_temp_new();
2673 TCGLabel *l1 = gen_new_label();
2674
2675 gen_load_gpr(t1, rs);
2676 gen_load_gpr(t2, rt);
2677 tcg_gen_sub_tl(t0, t1, t2);
2678 tcg_gen_ext32s_tl(t0, t0);
2679 tcg_gen_xor_tl(t2, t1, t2);
2680 tcg_gen_xor_tl(t1, t0, t1);
2681 tcg_gen_and_tl(t1, t1, t2);
2682 tcg_temp_free(t2);
2683 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2684 tcg_temp_free(t1);
2685 /*
2686 * operands of different sign, first operand and the result
2687 * of different sign
2688 */
2689 generate_exception(ctx, EXCP_OVERFLOW);
2690 gen_set_label(l1);
2691 gen_store_gpr(t0, rd);
2692 tcg_temp_free(t0);
2693 }
2694 break;
2695 case OPC_SUBU:
2696 if (rs != 0 && rt != 0) {
2697 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2698 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2699 } else if (rs == 0 && rt != 0) {
2700 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2701 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2702 } else if (rs != 0 && rt == 0) {
2703 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2704 } else {
2705 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2706 }
2707 break;
2708 #if defined(TARGET_MIPS64)
2709 case OPC_DADD:
2710 {
2711 TCGv t0 = tcg_temp_local_new();
2712 TCGv t1 = tcg_temp_new();
2713 TCGv t2 = tcg_temp_new();
2714 TCGLabel *l1 = gen_new_label();
2715
2716 gen_load_gpr(t1, rs);
2717 gen_load_gpr(t2, rt);
2718 tcg_gen_add_tl(t0, t1, t2);
2719 tcg_gen_xor_tl(t1, t1, t2);
2720 tcg_gen_xor_tl(t2, t0, t2);
2721 tcg_gen_andc_tl(t1, t2, t1);
2722 tcg_temp_free(t2);
2723 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2724 tcg_temp_free(t1);
2725 /* operands of same sign, result different sign */
2726 generate_exception(ctx, EXCP_OVERFLOW);
2727 gen_set_label(l1);
2728 gen_store_gpr(t0, rd);
2729 tcg_temp_free(t0);
2730 }
2731 break;
2732 case OPC_DADDU:
2733 if (rs != 0 && rt != 0) {
2734 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2735 } else if (rs == 0 && rt != 0) {
2736 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2737 } else if (rs != 0 && rt == 0) {
2738 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2739 } else {
2740 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2741 }
2742 break;
2743 case OPC_DSUB:
2744 {
2745 TCGv t0 = tcg_temp_local_new();
2746 TCGv t1 = tcg_temp_new();
2747 TCGv t2 = tcg_temp_new();
2748 TCGLabel *l1 = gen_new_label();
2749
2750 gen_load_gpr(t1, rs);
2751 gen_load_gpr(t2, rt);
2752 tcg_gen_sub_tl(t0, t1, t2);
2753 tcg_gen_xor_tl(t2, t1, t2);
2754 tcg_gen_xor_tl(t1, t0, t1);
2755 tcg_gen_and_tl(t1, t1, t2);
2756 tcg_temp_free(t2);
2757 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2758 tcg_temp_free(t1);
2759 /*
2760 * Operands of different sign, first operand and result different
2761 * sign.
2762 */
2763 generate_exception(ctx, EXCP_OVERFLOW);
2764 gen_set_label(l1);
2765 gen_store_gpr(t0, rd);
2766 tcg_temp_free(t0);
2767 }
2768 break;
2769 case OPC_DSUBU:
2770 if (rs != 0 && rt != 0) {
2771 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2772 } else if (rs == 0 && rt != 0) {
2773 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2774 } else if (rs != 0 && rt == 0) {
2775 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2776 } else {
2777 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2778 }
2779 break;
2780 #endif
2781 case OPC_MUL:
2782 if (likely(rs != 0 && rt != 0)) {
2783 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2784 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2785 } else {
2786 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2787 }
2788 break;
2789 }
2790 }
2791
2792 /* Conditional move */
2793 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2794 int rd, int rs, int rt)
2795 {
2796 TCGv t0, t1, t2;
2797
2798 if (rd == 0) {
2799 /* If no destination, treat it as a NOP. */
2800 return;
2801 }
2802
2803 t0 = tcg_temp_new();
2804 gen_load_gpr(t0, rt);
2805 t1 = tcg_const_tl(0);
2806 t2 = tcg_temp_new();
2807 gen_load_gpr(t2, rs);
2808 switch (opc) {
2809 case OPC_MOVN:
2810 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2811 break;
2812 case OPC_MOVZ:
2813 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2814 break;
2815 case OPC_SELNEZ:
2816 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2817 break;
2818 case OPC_SELEQZ:
2819 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2820 break;
2821 }
2822 tcg_temp_free(t2);
2823 tcg_temp_free(t1);
2824 tcg_temp_free(t0);
2825 }
2826
2827 /* Logic */
2828 static void gen_logic(DisasContext *ctx, uint32_t opc,
2829 int rd, int rs, int rt)
2830 {
2831 if (rd == 0) {
2832 /* If no destination, treat it as a NOP. */
2833 return;
2834 }
2835
2836 switch (opc) {
2837 case OPC_AND:
2838 if (likely(rs != 0 && rt != 0)) {
2839 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2840 } else {
2841 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2842 }
2843 break;
2844 case OPC_NOR:
2845 if (rs != 0 && rt != 0) {
2846 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2847 } else if (rs == 0 && rt != 0) {
2848 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2849 } else if (rs != 0 && rt == 0) {
2850 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2851 } else {
2852 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2853 }
2854 break;
2855 case OPC_OR:
2856 if (likely(rs != 0 && rt != 0)) {
2857 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2858 } else if (rs == 0 && rt != 0) {
2859 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2860 } else if (rs != 0 && rt == 0) {
2861 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2862 } else {
2863 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2864 }
2865 break;
2866 case OPC_XOR:
2867 if (likely(rs != 0 && rt != 0)) {
2868 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2869 } else if (rs == 0 && rt != 0) {
2870 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2871 } else if (rs != 0 && rt == 0) {
2872 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2873 } else {
2874 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2875 }
2876 break;
2877 }
2878 }
2879
2880 /* Set on lower than */
2881 static void gen_slt(DisasContext *ctx, uint32_t opc,
2882 int rd, int rs, int rt)
2883 {
2884 TCGv t0, t1;
2885
2886 if (rd == 0) {
2887 /* If no destination, treat it as a NOP. */
2888 return;
2889 }
2890
2891 t0 = tcg_temp_new();
2892 t1 = tcg_temp_new();
2893 gen_load_gpr(t0, rs);
2894 gen_load_gpr(t1, rt);
2895 switch (opc) {
2896 case OPC_SLT:
2897 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2898 break;
2899 case OPC_SLTU:
2900 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2901 break;
2902 }
2903 tcg_temp_free(t0);
2904 tcg_temp_free(t1);
2905 }
2906
2907 /* Shifts */
2908 static void gen_shift(DisasContext *ctx, uint32_t opc,
2909 int rd, int rs, int rt)
2910 {
2911 TCGv t0, t1;
2912
2913 if (rd == 0) {
2914 /*
2915 * If no destination, treat it as a NOP.
2916 * For add & sub, we must generate the overflow exception when needed.
2917 */
2918 return;
2919 }
2920
2921 t0 = tcg_temp_new();
2922 t1 = tcg_temp_new();
2923 gen_load_gpr(t0, rs);
2924 gen_load_gpr(t1, rt);
2925 switch (opc) {
2926 case OPC_SLLV:
2927 tcg_gen_andi_tl(t0, t0, 0x1f);
2928 tcg_gen_shl_tl(t0, t1, t0);
2929 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2930 break;
2931 case OPC_SRAV:
2932 tcg_gen_andi_tl(t0, t0, 0x1f);
2933 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2934 break;
2935 case OPC_SRLV:
2936 tcg_gen_ext32u_tl(t1, t1);
2937 tcg_gen_andi_tl(t0, t0, 0x1f);
2938 tcg_gen_shr_tl(t0, t1, t0);
2939 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2940 break;
2941 case OPC_ROTRV:
2942 {
2943 TCGv_i32 t2 = tcg_temp_new_i32();
2944 TCGv_i32 t3 = tcg_temp_new_i32();
2945
2946 tcg_gen_trunc_tl_i32(t2, t0);
2947 tcg_gen_trunc_tl_i32(t3, t1);
2948 tcg_gen_andi_i32(t2, t2, 0x1f);
2949 tcg_gen_rotr_i32(t2, t3, t2);
2950 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2951 tcg_temp_free_i32(t2);
2952 tcg_temp_free_i32(t3);
2953 }
2954 break;
2955 #if defined(TARGET_MIPS64)
2956 case OPC_DSLLV:
2957 tcg_gen_andi_tl(t0, t0, 0x3f);
2958 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2959 break;
2960 case OPC_DSRAV:
2961 tcg_gen_andi_tl(t0, t0, 0x3f);
2962 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2963 break;
2964 case OPC_DSRLV:
2965 tcg_gen_andi_tl(t0, t0, 0x3f);
2966 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2967 break;
2968 case OPC_DROTRV:
2969 tcg_gen_andi_tl(t0, t0, 0x3f);
2970 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2971 break;
2972 #endif
2973 }
2974 tcg_temp_free(t0);
2975 tcg_temp_free(t1);
2976 }
2977
2978 /* Arithmetic on HI/LO registers */
2979 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2980 {
2981 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2982 /* Treat as NOP. */
2983 return;
2984 }
2985
2986 if (acc != 0) {
2987 check_dsp(ctx);
2988 }
2989
2990 switch (opc) {
2991 case OPC_MFHI:
2992 #if defined(TARGET_MIPS64)
2993 if (acc != 0) {
2994 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2995 } else
2996 #endif
2997 {
2998 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2999 }
3000 break;
3001 case OPC_MFLO:
3002 #if defined(TARGET_MIPS64)
3003 if (acc != 0) {
3004 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3005 } else
3006 #endif
3007 {
3008 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3009 }
3010 break;
3011 case OPC_MTHI:
3012 if (reg != 0) {
3013 #if defined(TARGET_MIPS64)
3014 if (acc != 0) {
3015 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3016 } else
3017 #endif
3018 {
3019 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3020 }
3021 } else {
3022 tcg_gen_movi_tl(cpu_HI[acc], 0);
3023 }
3024 break;
3025 case OPC_MTLO:
3026 if (reg != 0) {
3027 #if defined(TARGET_MIPS64)
3028 if (acc != 0) {
3029 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3030 } else
3031 #endif
3032 {
3033 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3034 }
3035 } else {
3036 tcg_gen_movi_tl(cpu_LO[acc], 0);
3037 }
3038 break;
3039 }
3040 }
3041
3042 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3043 MemOp memop)
3044 {
3045 TCGv t0 = tcg_const_tl(addr);
3046 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3047 gen_store_gpr(t0, reg);
3048 tcg_temp_free(t0);
3049 }
3050
3051 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3052 int rs)
3053 {
3054 target_long offset;
3055 target_long addr;
3056
3057 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3058 case OPC_ADDIUPC:
3059 if (rs != 0) {
3060 offset = sextract32(ctx->opcode << 2, 0, 21);
3061 addr = addr_add(ctx, pc, offset);
3062 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3063 }
3064 break;
3065 case R6_OPC_LWPC:
3066 offset = sextract32(ctx->opcode << 2, 0, 21);
3067 addr = addr_add(ctx, pc, offset);
3068 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3069 break;
3070 #if defined(TARGET_MIPS64)
3071 case OPC_LWUPC:
3072 check_mips_64(ctx);
3073 offset = sextract32(ctx->opcode << 2, 0, 21);
3074 addr = addr_add(ctx, pc, offset);
3075 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3076 break;
3077 #endif
3078 default:
3079 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3080 case OPC_AUIPC:
3081 if (rs != 0) {
3082 offset = sextract32(ctx->opcode, 0, 16) << 16;
3083 addr = addr_add(ctx, pc, offset);
3084 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3085 }
3086 break;
3087 case OPC_ALUIPC:
3088 if (rs != 0) {
3089 offset = sextract32(ctx->opcode, 0, 16) << 16;
3090 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3091 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3092 }
3093 break;
3094 #if defined(TARGET_MIPS64)
3095 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3096 case R6_OPC_LDPC + (1 << 16):
3097 case R6_OPC_LDPC + (2 << 16):
3098 case R6_OPC_LDPC + (3 << 16):
3099 check_mips_64(ctx);
3100 offset = sextract32(ctx->opcode << 3, 0, 21);
3101 addr = addr_add(ctx, (pc & ~0x7), offset);
3102 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUQ);
3103 break;
3104 #endif
3105 default:
3106 MIPS_INVAL("OPC_PCREL");
3107 gen_reserved_instruction(ctx);
3108 break;
3109 }
3110 break;
3111 }
3112 }
3113
3114 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3115 {
3116 TCGv t0, t1;
3117
3118 if (rd == 0) {
3119 /* Treat as NOP. */
3120 return;
3121 }
3122
3123 t0 = tcg_temp_new();
3124 t1 = tcg_temp_new();
3125
3126 gen_load_gpr(t0, rs);
3127 gen_load_gpr(t1, rt);
3128
3129 switch (opc) {
3130 case R6_OPC_DIV:
3131 {
3132 TCGv t2 = tcg_temp_new();
3133 TCGv t3 = tcg_temp_new();
3134 tcg_gen_ext32s_tl(t0, t0);
3135 tcg_gen_ext32s_tl(t1, t1);
3136 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3137 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3138 tcg_gen_and_tl(t2, t2, t3);
3139 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3140 tcg_gen_or_tl(t2, t2, t3);
3141 tcg_gen_movi_tl(t3, 0);
3142 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3143 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3144 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3145 tcg_temp_free(t3);
3146 tcg_temp_free(t2);
3147 }
3148 break;
3149 case R6_OPC_MOD:
3150 {
3151 TCGv t2 = tcg_temp_new();
3152 TCGv t3 = tcg_temp_new();
3153 tcg_gen_ext32s_tl(t0, t0);
3154 tcg_gen_ext32s_tl(t1, t1);
3155 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3156 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3157 tcg_gen_and_tl(t2, t2, t3);
3158 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3159 tcg_gen_or_tl(t2, t2, t3);
3160 tcg_gen_movi_tl(t3, 0);
3161 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3162 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3163 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3164 tcg_temp_free(t3);
3165 tcg_temp_free(t2);
3166 }
3167 break;
3168 case R6_OPC_DIVU:
3169 {
3170 TCGv t2 = tcg_const_tl(0);
3171 TCGv t3 = tcg_const_tl(1);
3172 tcg_gen_ext32u_tl(t0, t0);
3173 tcg_gen_ext32u_tl(t1, t1);
3174 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3175 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3176 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3177 tcg_temp_free(t3);
3178 tcg_temp_free(t2);
3179 }
3180 break;
3181 case R6_OPC_MODU:
3182 {
3183 TCGv t2 = tcg_const_tl(0);
3184 TCGv t3 = tcg_const_tl(1);
3185 tcg_gen_ext32u_tl(t0, t0);
3186 tcg_gen_ext32u_tl(t1, t1);
3187 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3188 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3189 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3190 tcg_temp_free(t3);
3191 tcg_temp_free(t2);
3192 }
3193 break;
3194 case R6_OPC_MUL:
3195 {
3196 TCGv_i32 t2 = tcg_temp_new_i32();
3197 TCGv_i32 t3 = tcg_temp_new_i32();
3198 tcg_gen_trunc_tl_i32(t2, t0);
3199 tcg_gen_trunc_tl_i32(t3, t1);
3200 tcg_gen_mul_i32(t2, t2, t3);
3201 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3202 tcg_temp_free_i32(t2);
3203 tcg_temp_free_i32(t3);
3204 }
3205 break;
3206 case R6_OPC_MUH:
3207 {
3208 TCGv_i32 t2 = tcg_temp_new_i32();
3209 TCGv_i32 t3 = tcg_temp_new_i32();
3210 tcg_gen_trunc_tl_i32(t2, t0);
3211 tcg_gen_trunc_tl_i32(t3, t1);
3212 tcg_gen_muls2_i32(t2, t3, t2, t3);
3213 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3214 tcg_temp_free_i32(t2);
3215 tcg_temp_free_i32(t3);
3216 }
3217 break;
3218 case R6_OPC_MULU:
3219 {
3220 TCGv_i32 t2 = tcg_temp_new_i32();
3221 TCGv_i32 t3 = tcg_temp_new_i32();
3222 tcg_gen_trunc_tl_i32(t2, t0);
3223 tcg_gen_trunc_tl_i32(t3, t1);
3224 tcg_gen_mul_i32(t2, t2, t3);
3225 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3226 tcg_temp_free_i32(t2);
3227 tcg_temp_free_i32(t3);
3228 }
3229 break;
3230 case R6_OPC_MUHU:
3231 {
3232 TCGv_i32 t2 = tcg_temp_new_i32();
3233 TCGv_i32 t3 = tcg_temp_new_i32();
3234 tcg_gen_trunc_tl_i32(t2, t0);
3235 tcg_gen_trunc_tl_i32(t3, t1);
3236 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3237 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3238 tcg_temp_free_i32(t2);
3239 tcg_temp_free_i32(t3);
3240 }
3241 break;
3242 #if defined(TARGET_MIPS64)
3243 case R6_OPC_DDIV:
3244 {
3245 TCGv t2 = tcg_temp_new();
3246 TCGv t3 = tcg_temp_new();
3247 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3248 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3249 tcg_gen_and_tl(t2, t2, t3);
3250 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3251 tcg_gen_or_tl(t2, t2, t3);
3252 tcg_gen_movi_tl(t3, 0);
3253 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3254 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3255 tcg_temp_free(t3);
3256 tcg_temp_free(t2);
3257 }
3258 break;
3259 case R6_OPC_DMOD:
3260 {
3261 TCGv t2 = tcg_temp_new();
3262 TCGv t3 = tcg_temp_new();
3263 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3264 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3265 tcg_gen_and_tl(t2, t2, t3);
3266 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3267 tcg_gen_or_tl(t2, t2, t3);
3268 tcg_gen_movi_tl(t3, 0);
3269 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3270 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3271 tcg_temp_free(t3);
3272 tcg_temp_free(t2);
3273 }
3274 break;
3275 case R6_OPC_DDIVU:
3276 {
3277 TCGv t2 = tcg_const_tl(0);
3278 TCGv t3 = tcg_const_tl(1);
3279 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3280 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3281 tcg_temp_free(t3);
3282 tcg_temp_free(t2);
3283 }
3284 break;
3285 case R6_OPC_DMODU:
3286 {
3287 TCGv t2 = tcg_const_tl(0);
3288 TCGv t3 = tcg_const_tl(1);
3289 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3290 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3291 tcg_temp_free(t3);
3292 tcg_temp_free(t2);
3293 }
3294 break;
3295 case R6_OPC_DMUL:
3296 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3297 break;
3298 case R6_OPC_DMUH:
3299 {
3300 TCGv t2 = tcg_temp_new();
3301 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3302 tcg_temp_free(t2);
3303 }
3304 break;
3305 case R6_OPC_DMULU:
3306 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3307 break;
3308 case R6_OPC_DMUHU:
3309 {
3310 TCGv t2 = tcg_temp_new();
3311 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3312 tcg_temp_free(t2);
3313 }
3314 break;
3315 #endif
3316 default:
3317 MIPS_INVAL("r6 mul/div");
3318 gen_reserved_instruction(ctx);
3319 goto out;
3320 }
3321 out:
3322 tcg_temp_free(t0);
3323 tcg_temp_free(t1);
3324 }
3325
3326 #if defined(TARGET_MIPS64)
3327 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3328 {
3329 TCGv t0, t1;
3330
3331 t0 = tcg_temp_new();
3332 t1 = tcg_temp_new();
3333
3334 gen_load_gpr(t0, rs);
3335 gen_load_gpr(t1, rt);
3336
3337 switch (opc) {
3338 case MMI_OPC_DIV1:
3339 {
3340 TCGv t2 = tcg_temp_new();
3341 TCGv t3 = tcg_temp_new();
3342 tcg_gen_ext32s_tl(t0, t0);
3343 tcg_gen_ext32s_tl(t1, t1);
3344 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3345 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3346 tcg_gen_and_tl(t2, t2, t3);
3347 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3348 tcg_gen_or_tl(t2, t2, t3);
3349 tcg_gen_movi_tl(t3, 0);
3350 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3351 tcg_gen_div_tl(cpu_LO[1], t0, t1);
3352 tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3353 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3354 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3355 tcg_temp_free(t3);
3356 tcg_temp_free(t2);
3357 }
3358 break;
3359 case MMI_OPC_DIVU1:
3360 {
3361 TCGv t2 = tcg_const_tl(0);
3362 TCGv t3 = tcg_const_tl(1);
3363 tcg_gen_ext32u_tl(t0, t0);
3364 tcg_gen_ext32u_tl(t1, t1);
3365 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3366 tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3367 tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3368 tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3369 tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3370 tcg_temp_free(t3);
3371 tcg_temp_free(t2);
3372 }
3373 break;
3374 default:
3375 MIPS_INVAL("div1 TX79");
3376 gen_reserved_instruction(ctx);
3377 goto out;
3378 }
3379 out:
3380 tcg_temp_free(t0);
3381 tcg_temp_free(t1);
3382 }
3383 #endif
3384
3385 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3386 int acc, int rs, int rt)
3387 {
3388 TCGv t0, t1;
3389
3390 t0 = tcg_temp_new();
3391 t1 = tcg_temp_new();
3392
3393 gen_load_gpr(t0, rs);
3394 gen_load_gpr(t1, rt);
3395
3396 if (acc != 0) {
3397 check_dsp(ctx);
3398 }
3399
3400 switch (opc) {
3401 case OPC_DIV:
3402 {
3403 TCGv t2 = tcg_temp_new();
3404 TCGv t3 = tcg_temp_new();
3405 tcg_gen_ext32s_tl(t0, t0);
3406 tcg_gen_ext32s_tl(t1, t1);
3407 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3408 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3409 tcg_gen_and_tl(t2, t2, t3);
3410 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3411 tcg_gen_or_tl(t2, t2, t3);
3412 tcg_gen_movi_tl(t3, 0);
3413 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3414 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3415 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3416 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3417 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3418 tcg_temp_free(t3);
3419 tcg_temp_free(t2);
3420 }
3421 break;
3422 case OPC_DIVU:
3423 {
3424 TCGv t2 = tcg_const_tl(0);
3425 TCGv t3 = tcg_const_tl(1);
3426 tcg_gen_ext32u_tl(t0, t0);
3427 tcg_gen_ext32u_tl(t1, t1);
3428 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3429 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3430 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3431 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3432 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3433 tcg_temp_free(t3);
3434 tcg_temp_free(t2);
3435 }
3436 break;
3437 case OPC_MULT:
3438 {
3439 TCGv_i32 t2 = tcg_temp_new_i32();
3440 TCGv_i32 t3 = tcg_temp_new_i32();
3441 tcg_gen_trunc_tl_i32(t2, t0);
3442 tcg_gen_trunc_tl_i32(t3, t1);
3443 tcg_gen_muls2_i32(t2, t3, t2, t3);
3444 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3445 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3446 tcg_temp_free_i32(t2);
3447 tcg_temp_free_i32(t3);
3448 }
3449 break;
3450 case OPC_MULTU:
3451 {
3452 TCGv_i32 t2 = tcg_temp_new_i32();
3453 TCGv_i32 t3 = tcg_temp_new_i32();
3454 tcg_gen_trunc_tl_i32(t2, t0);
3455 tcg_gen_trunc_tl_i32(t3, t1);
3456 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3457 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3458 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3459 tcg_temp_free_i32(t2);
3460 tcg_temp_free_i32(t3);
3461 }
3462 break;
3463 #if defined(TARGET_MIPS64)
3464 case OPC_DDIV:
3465 {
3466 TCGv t2 = tcg_temp_new();
3467 TCGv t3 = tcg_temp_new();
3468 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3469 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3470 tcg_gen_and_tl(t2, t2, t3);
3471 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3472 tcg_gen_or_tl(t2, t2, t3);
3473 tcg_gen_movi_tl(t3, 0);
3474 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3475 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3476 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3477 tcg_temp_free(t3);
3478 tcg_temp_free(t2);
3479 }
3480 break;
3481 case OPC_DDIVU:
3482 {
3483 TCGv t2 = tcg_const_tl(0);
3484 TCGv t3 = tcg_const_tl(1);
3485 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3486 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3487 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3488 tcg_temp_free(t3);
3489 tcg_temp_free(t2);
3490 }
3491 break;
3492 case OPC_DMULT:
3493 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3494 break;
3495 case OPC_DMULTU:
3496 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3497 break;
3498 #endif
3499 case OPC_MADD:
3500 {
3501 TCGv_i64 t2 = tcg_temp_new_i64();
3502 TCGv_i64 t3 = tcg_temp_new_i64();
3503
3504 tcg_gen_ext_tl_i64(t2, t0);
3505 tcg_gen_ext_tl_i64(t3, t1);
3506 tcg_gen_mul_i64(t2, t2, t3);
3507 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3508 tcg_gen_add_i64(t2, t2, t3);
3509 tcg_temp_free_i64(t3);
3510 gen_move_low32(cpu_LO[acc], t2);
3511 gen_move_high32(cpu_HI[acc], t2);
3512 tcg_temp_free_i64(t2);
3513 }
3514 break;
3515 case OPC_MADDU:
3516 {
3517 TCGv_i64 t2 = tcg_temp_new_i64();
3518 TCGv_i64 t3 = tcg_temp_new_i64();
3519
3520 tcg_gen_ext32u_tl(t0, t0);
3521 tcg_gen_ext32u_tl(t1, t1);
3522 tcg_gen_extu_tl_i64(t2, t0);
3523 tcg_gen_extu_tl_i64(t3, t1);
3524 tcg_gen_mul_i64(t2, t2, t3);
3525 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3526 tcg_gen_add_i64(t2, t2, t3);
3527 tcg_temp_free_i64(t3);
3528 gen_move_low32(cpu_LO[acc], t2);
3529 gen_move_high32(cpu_HI[acc], t2);
3530 tcg_temp_free_i64(t2);
3531 }
3532 break;
3533 case OPC_MSUB:
3534 {
3535 TCGv_i64 t2 = tcg_temp_new_i64();
3536 TCGv_i64 t3 = tcg_temp_new_i64();
3537
3538 tcg_gen_ext_tl_i64(t2, t0);
3539 tcg_gen_ext_tl_i64(t3, t1);
3540 tcg_gen_mul_i64(t2, t2, t3);
3541 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3542 tcg_gen_sub_i64(t2, t3, t2);
3543 tcg_temp_free_i64(t3);
3544 gen_move_low32(cpu_LO[acc], t2);
3545 gen_move_high32(cpu_HI[acc], t2);
3546 tcg_temp_free_i64(t2);
3547 }
3548 break;
3549 case OPC_MSUBU:
3550 {
3551 TCGv_i64 t2 = tcg_temp_new_i64();
3552 TCGv_i64 t3 = tcg_temp_new_i64();
3553
3554 tcg_gen_ext32u_tl(t0, t0);
3555 tcg_gen_ext32u_tl(t1, t1);
3556 tcg_gen_extu_tl_i64(t2, t0);
3557 tcg_gen_extu_tl_i64(t3, t1);
3558 tcg_gen_mul_i64(t2, t2, t3);
3559 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3560 tcg_gen_sub_i64(t2, t3, t2);
3561 tcg_temp_free_i64(t3);
3562 gen_move_low32(cpu_LO[acc], t2);
3563 gen_move_high32(cpu_HI[acc], t2);
3564 tcg_temp_free_i64(t2);
3565 }
3566 break;
3567 default:
3568 MIPS_INVAL("mul/div");
3569 gen_reserved_instruction(ctx);
3570 goto out;
3571 }
3572 out:
3573 tcg_temp_free(t0);
3574 tcg_temp_free(t1);
3575 }
3576
3577 /*
3578 * These MULT[U] and MADD[U] instructions implemented in for example
3579 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3580 * architectures are special three-operand variants with the syntax
3581 *
3582 * MULT[U][1] rd, rs, rt
3583 *
3584 * such that
3585 *
3586 * (rd, LO, HI) <- rs * rt
3587 *
3588 * and
3589 *
3590 * MADD[U][1] rd, rs, rt
3591 *
3592 * such that
3593 *
3594 * (rd, LO, HI) <- (LO, HI) + rs * rt
3595 *
3596 * where the low-order 32-bits of the result is placed into both the
3597 * GPR rd and the special register LO. The high-order 32-bits of the
3598 * result is placed into the special register HI.
3599 *
3600 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3601 * which is the zero register that always reads as 0.
3602 */
3603 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3604 int rd, int rs, int rt)
3605 {
3606 TCGv t0 = tcg_temp_new();
3607 TCGv t1 = tcg_temp_new();
3608 int acc = 0;
3609
3610 gen_load_gpr(t0, rs);
3611 gen_load_gpr(t1, rt);
3612
3613 switch (opc) {
3614 case MMI_OPC_MULT1:
3615 acc = 1;
3616 /* Fall through */
3617 case OPC_MULT:
3618 {
3619 TCGv_i32 t2 = tcg_temp_new_i32();
3620 TCGv_i32 t3 = tcg_temp_new_i32();
3621 tcg_gen_trunc_tl_i32(t2, t0);
3622 tcg_gen_trunc_tl_i32(t3, t1);
3623 tcg_gen_muls2_i32(t2, t3, t2, t3);
3624 if (rd) {
3625 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3626 }
3627 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3628 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3629 tcg_temp_free_i32(t2);
3630 tcg_temp_free_i32(t3);
3631 }
3632 break;
3633 case MMI_OPC_MULTU1:
3634 acc = 1;
3635 /* Fall through */
3636 case OPC_MULTU:
3637 {
3638 TCGv_i32 t2 = tcg_temp_new_i32();
3639 TCGv_i32 t3 = tcg_temp_new_i32();
3640 tcg_gen_trunc_tl_i32(t2, t0);
3641 tcg_gen_trunc_tl_i32(t3, t1);
3642 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3643 if (rd) {
3644 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3645 }
3646 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3647 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3648 tcg_temp_free_i32(t2);
3649 tcg_temp_free_i32(t3);
3650 }
3651 break;
3652 case MMI_OPC_MADD1:
3653 acc = 1;
3654 /* Fall through */
3655 case MMI_OPC_MADD:
3656 {
3657 TCGv_i64 t2 = tcg_temp_new_i64();
3658 TCGv_i64 t3 = tcg_temp_new_i64();
3659
3660 tcg_gen_ext_tl_i64(t2, t0);
3661 tcg_gen_ext_tl_i64(t3, t1);
3662 tcg_gen_mul_i64(t2, t2, t3);
3663 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3664 tcg_gen_add_i64(t2, t2, t3);
3665 tcg_temp_free_i64(t3);
3666 gen_move_low32(cpu_LO[acc], t2);
3667 gen_move_high32(cpu_HI[acc], t2);
3668 if (rd) {
3669 gen_move_low32(cpu_gpr[rd], t2);
3670 }
3671 tcg_temp_free_i64(t2);
3672 }
3673 break;
3674 case MMI_OPC_MADDU1:
3675 acc = 1;
3676 /* Fall through */
3677 case MMI_OPC_MADDU:
3678 {
3679 TCGv_i64 t2 = tcg_temp_new_i64();
3680 TCGv_i64 t3 = tcg_temp_new_i64();
3681
3682 tcg_gen_ext32u_tl(t0, t0);
3683 tcg_gen_ext32u_tl(t1, t1);
3684 tcg_gen_extu_tl_i64(t2, t0);
3685 tcg_gen_extu_tl_i64(t3, t1);
3686 tcg_gen_mul_i64(t2, t2, t3);
3687 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3688 tcg_gen_add_i64(t2, t2, t3);
3689 tcg_temp_free_i64(t3);
3690 gen_move_low32(cpu_LO[acc], t2);
3691 gen_move_high32(cpu_HI[acc], t2);
3692 if (rd) {
3693 gen_move_low32(cpu_gpr[rd], t2);
3694 }
3695 tcg_temp_free_i64(t2);
3696 }
3697 break;
3698 default:
3699 MIPS_INVAL("mul/madd TXx9");
3700 gen_reserved_instruction(ctx);
3701 goto out;
3702 }
3703
3704 out:
3705 tcg_temp_free(t0);
3706 tcg_temp_free(t1);
3707 }
3708
3709 static void gen_cl(DisasContext *ctx, uint32_t opc,
3710 int rd, int rs)
3711 {
3712 TCGv t0;
3713
3714 if (rd == 0) {
3715 /* Treat as NOP. */
3716 return;
3717 }
3718 t0 = cpu_gpr[rd];
3719 gen_load_gpr(t0, rs);
3720
3721 switch (opc) {
3722 case OPC_CLO:
3723 case R6_OPC_CLO:
3724 #if defined(TARGET_MIPS64)
3725 case OPC_DCLO:
3726 case R6_OPC_DCLO:
3727 #endif
3728 tcg_gen_not_tl(t0, t0);
3729 break;
3730 }
3731
3732 switch (opc) {
3733 case OPC_CLO:
3734 case R6_OPC_CLO:
3735 case OPC_CLZ:
3736 case R6_OPC_CLZ:
3737 tcg_gen_ext32u_tl(t0, t0);
3738 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3739 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3740 break;
3741 #if defined(TARGET_MIPS64)
3742 case OPC_DCLO:
3743 case R6_OPC_DCLO:
3744 case OPC_DCLZ:
3745 case R6_OPC_DCLZ:
3746 tcg_gen_clzi_i64(t0, t0, 64);
3747 break;
3748 #endif
3749 }
3750 }
3751
3752 /* Godson integer instructions */
3753 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3754 int rd, int rs, int rt)
3755 {
3756 TCGv t0, t1;
3757
3758 if (rd == 0) {
3759 /* Treat as NOP. */
3760 return;
3761 }
3762
3763 switch (opc) {
3764 case OPC_MULT_G_2E:
3765 case OPC_MULT_G_2F:
3766 case OPC_MULTU_G_2E:
3767 case OPC_MULTU_G_2F:
3768 #if defined(TARGET_MIPS64)
3769 case OPC_DMULT_G_2E:
3770 case OPC_DMULT_G_2F:
3771 case OPC_DMULTU_G_2E:
3772 case OPC_DMULTU_G_2F:
3773 #endif
3774 t0 = tcg_temp_new();
3775 t1 = tcg_temp_new();
3776 break;
3777 default:
3778 t0 = tcg_temp_local_new();
3779 t1 = tcg_temp_local_new();
3780 break;
3781 }
3782
3783 gen_load_gpr(t0, rs);
3784 gen_load_gpr(t1, rt);
3785
3786 switch (opc) {
3787 case OPC_MULT_G_2E:
3788 case OPC_MULT_G_2F:
3789 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3790 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3791 break;
3792 case OPC_MULTU_G_2E:
3793 case OPC_MULTU_G_2F:
3794 tcg_gen_ext32u_tl(t0, t0);
3795 tcg_gen_ext32u_tl(t1, t1);
3796 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3797 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3798 break;
3799 case OPC_DIV_G_2E:
3800 case OPC_DIV_G_2F:
3801 {
3802 TCGLabel *l1 = gen_new_label();
3803 TCGLabel *l2 = gen_new_label();
3804 TCGLabel *l3 = gen_new_label();
3805 tcg_gen_ext32s_tl(t0, t0);
3806 tcg_gen_ext32s_tl(t1, t1);
3807 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3808 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3809 tcg_gen_br(l3);
3810 gen_set_label(l1);
3811 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3812 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3813 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3814 tcg_gen_br(l3);
3815 gen_set_label(l2);
3816 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3817 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3818 gen_set_label(l3);
3819 }
3820 break;
3821 case OPC_DIVU_G_2E:
3822 case OPC_DIVU_G_2F:
3823 {
3824 TCGLabel *l1 = gen_new_label();
3825 TCGLabel *l2 = gen_new_label();
3826 tcg_gen_ext32u_tl(t0, t0);
3827 tcg_gen_ext32u_tl(t1, t1);
3828 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3829 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3830 tcg_gen_br(l2);
3831 gen_set_label(l1);
3832 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3833 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3834 gen_set_label(l2);
3835 }
3836 break;
3837 case OPC_MOD_G_2E:
3838 case OPC_MOD_G_2F:
3839 {
3840 TCGLabel *l1 = gen_new_label();
3841 TCGLabel *l2 = gen_new_label();
3842 TCGLabel *l3 = gen_new_label();
3843 tcg_gen_ext32u_tl(t0, t0);
3844 tcg_gen_ext32u_tl(t1, t1);
3845 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3846 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3847 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3848 gen_set_label(l1);
3849 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3850 tcg_gen_br(l3);
3851 gen_set_label(l2);
3852 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3853 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3854 gen_set_label(l3);
3855 }
3856 break;
3857 case OPC_MODU_G_2E:
3858 case OPC_MODU_G_2F:
3859 {
3860 TCGLabel *l1 = gen_new_label();
3861 TCGLabel *l2 = gen_new_label();
3862 tcg_gen_ext32u_tl(t0, t0);
3863 tcg_gen_ext32u_tl(t1, t1);
3864 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3865 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3866 tcg_gen_br(l2);
3867 gen_set_label(l1);
3868 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3869 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3870 gen_set_label(l2);
3871 }
3872 break;
3873 #if defined(TARGET_MIPS64)
3874 case OPC_DMULT_G_2E:
3875 case OPC_DMULT_G_2F:
3876 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3877 break;
3878 case OPC_DMULTU_G_2E:
3879 case OPC_DMULTU_G_2F:
3880 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3881 break;
3882 case OPC_DDIV_G_2E:
3883 case OPC_DDIV_G_2F:
3884 {
3885 TCGLabel *l1 = gen_new_label();
3886 TCGLabel *l2 = gen_new_label();
3887 TCGLabel *l3 = gen_new_label();
3888 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3889 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3890 tcg_gen_br(l3);
3891 gen_set_label(l1);
3892 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3893 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3894 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3895 tcg_gen_br(l3);
3896 gen_set_label(l2);
3897 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3898 gen_set_label(l3);
3899 }
3900 break;
3901 case OPC_DDIVU_G_2E:
3902 case OPC_DDIVU_G_2F:
3903 {
3904 TCGLabel *l1 = gen_new_label();
3905 TCGLabel *l2 = gen_new_label();
3906 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3907 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3908 tcg_gen_br(l2);
3909 gen_set_label(l1);
3910 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3911 gen_set_label(l2);
3912 }
3913 break;
3914 case OPC_DMOD_G_2E:
3915 case OPC_DMOD_G_2F:
3916 {
3917 TCGLabel *l1 = gen_new_label();
3918 TCGLabel *l2 = gen_new_label();
3919 TCGLabel *l3 = gen_new_label();
3920 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3921 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3922 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3923 gen_set_label(l1);
3924 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3925 tcg_gen_br(l3);
3926 gen_set_label(l2);
3927 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3928 gen_set_label(l3);
3929 }
3930 break;
3931 case OPC_DMODU_G_2E:
3932 case OPC_DMODU_G_2F:
3933 {
3934 TCGLabel *l1 = gen_new_label();
3935 TCGLabel *l2 = gen_new_label();
3936 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3937 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3938 tcg_gen_br(l2);
3939 gen_set_label(l1);
3940 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3941 gen_set_label(l2);
3942 }
3943 break;
3944 #endif
3945 }
3946
3947 tcg_temp_free(t0);
3948 tcg_temp_free(t1);
3949 }
3950
3951 /* Loongson multimedia instructions */
3952 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3953 {
3954 uint32_t opc, shift_max;
3955 TCGv_i64 t0, t1;
3956 TCGCond cond;
3957
3958 opc = MASK_LMMI(ctx->opcode);
3959 switch (opc) {
3960 case OPC_ADD_CP2:
3961 case OPC_SUB_CP2:
3962 case OPC_DADD_CP2:
3963 case OPC_DSUB_CP2:
3964 t0 = tcg_temp_local_new_i64();
3965 t1 = tcg_temp_local_new_i64();
3966 break;
3967 default:
3968 t0 = tcg_temp_new_i64();
3969 t1 = tcg_temp_new_i64();
3970 break;
3971 }
3972
3973 check_cp1_enabled(ctx);
3974 gen_load_fpr64(ctx, t0, rs);
3975 gen_load_fpr64(ctx, t1, rt);
3976
3977 switch (opc) {
3978 case OPC_PADDSH:
3979 gen_helper_paddsh(t0, t0, t1);
3980 break;
3981 case OPC_PADDUSH:
3982 gen_helper_paddush(t0, t0, t1);
3983 break;
3984 case OPC_PADDH:
3985 gen_helper_paddh(t0, t0, t1);
3986 break;
3987 case OPC_PADDW:
3988 gen_helper_paddw(t0, t0, t1);
3989 break;
3990 case OPC_PADDSB:
3991 gen_helper_paddsb(t0, t0, t1);
3992 break;
3993 case OPC_PADDUSB:
3994 gen_helper_paddusb(t0, t0, t1);
3995 break;
3996 case OPC_PADDB:
3997 gen_helper_paddb(t0, t0, t1);
3998 break;
3999
4000 case OPC_PSUBSH:
4001 gen_helper_psubsh(t0, t0, t1);
4002 break;
4003 case OPC_PSUBUSH:
4004 gen_helper_psubush(t0, t0, t1);
4005 break;
4006 case OPC_PSUBH:
4007 gen_helper_psubh(t0, t0, t1);
4008 break;
4009 case OPC_PSUBW:
4010 gen_helper_psubw(t0, t0, t1);
4011 break;
4012 case OPC_PSUBSB:
4013 gen_helper_psubsb(t0, t0, t1);
4014 break;
4015 case OPC_PSUBUSB:
4016 gen_helper_psubusb(t0, t0, t1);
4017 break;
4018 case OPC_PSUBB:
4019 gen_helper_psubb(t0, t0, t1);
4020 break;
4021
4022 case OPC_PSHUFH:
4023 gen_helper_pshufh(t0, t0, t1);
4024 break;
4025 case OPC_PACKSSWH:
4026 gen_helper_packsswh(t0, t0, t1);
4027 break;
4028 case OPC_PACKSSHB:
4029 gen_helper_packsshb(t0, t0, t1);
4030 break;
4031 case OPC_PACKUSHB:
4032 gen_helper_packushb(t0, t0, t1);
4033 break;
4034
4035 case OPC_PUNPCKLHW:
4036 gen_helper_punpcklhw(t0, t0, t1);
4037 break;
4038 case OPC_PUNPCKHHW:
4039 gen_helper_punpckhhw(t0, t0, t1);
4040 break;
4041 case OPC_PUNPCKLBH:
4042 gen_helper_punpcklbh(t0, t0, t1);
4043 break;
4044 case OPC_PUNPCKHBH:
4045 gen_helper_punpckhbh(t0, t0, t1);
4046 break;
4047 case OPC_PUNPCKLWD:
4048 gen_helper_punpcklwd(t0, t0, t1);
4049 break;
4050 case OPC_PUNPCKHWD:
4051 gen_helper_punpckhwd(t0, t0, t1);
4052 break;
4053
4054 case OPC_PAVGH:
4055 gen_helper_pavgh(t0, t0, t1);
4056 break;
4057 case OPC_PAVGB:
4058 gen_helper_pavgb(t0, t0, t1);
4059 break;
4060 case OPC_PMAXSH:
4061 gen_helper_pmaxsh(t0, t0, t1);
4062 break;
4063 case OPC_PMINSH:
4064 gen_helper_pminsh(t0, t0, t1);
4065 break;
4066 case OPC_PMAXUB:
4067 gen_helper_pmaxub(t0, t0, t1);
4068 break;
4069 case OPC_PMINUB:
4070 gen_helper_pminub(t0, t0, t1);
4071 break;
4072
4073 case OPC_PCMPEQW:
4074 gen_helper_pcmpeqw(t0, t0, t1);
4075 break;
4076 case OPC_PCMPGTW:
4077 gen_helper_pcmpgtw(t0, t0, t1);
4078 break;
4079 case OPC_PCMPEQH:
4080 gen_helper_pcmpeqh(t0, t0, t1);
4081 break;
4082 case OPC_PCMPGTH:
4083 gen_helper_pcmpgth(t0, t0, t1);
4084 break;
4085 case OPC_PCMPEQB:
4086 gen_helper_pcmpeqb(t0, t0, t1);
4087 break;
4088 case OPC_PCMPGTB:
4089 gen_helper_pcmpgtb(t0, t0, t1);
4090 break;
4091
4092 case OPC_PSLLW:
4093 gen_helper_psllw(t0, t0, t1);
4094 break;
4095 case OPC_PSLLH:
4096 gen_helper_psllh(t0, t0, t1);
4097 break;
4098 case OPC_PSRLW:
4099 gen_helper_psrlw(t0, t0, t1);
4100 break;
4101 case OPC_PSRLH:
4102 gen_helper_psrlh(t0, t0, t1);
4103 break;
4104 case OPC_PSRAW:
4105 gen_helper_psraw(t0, t0, t1);
4106 break;
4107 case OPC_PSRAH:
4108 gen_helper_psrah(t0, t0, t1);
4109 break;
4110
4111 case OPC_PMULLH:
4112 gen_helper_pmullh(t0, t0, t1);
4113 break;
4114 case OPC_PMULHH:
4115 gen_helper_pmulhh(t0, t0, t1);
4116 break;
4117 case OPC_PMULHUH:
4118 gen_helper_pmulhuh(t0, t0, t1);
4119 break;
4120 case OPC_PMADDHW:
4121 gen_helper_pmaddhw(t0, t0, t1);
4122 break;
4123
4124 case OPC_PASUBUB:
4125 gen_helper_pasubub(t0, t0, t1);
4126 break;
4127 case OPC_BIADD:
4128 gen_helper_biadd(t0, t0);
4129 break;
4130 case OPC_PMOVMSKB:
4131 gen_helper_pmovmskb(t0, t0);
4132 break;
4133
4134 case OPC_PADDD:
4135 tcg_gen_add_i64(t0, t0, t1);
4136 break;
4137 case OPC_PSUBD:
4138 tcg_gen_sub_i64(t0, t0, t1);
4139 break;
4140 case OPC_XOR_CP2:
4141 tcg_gen_xor_i64(t0, t0, t1);
4142 break;
4143 case OPC_NOR_CP2:
4144 tcg_gen_nor_i64(t0, t0, t1);
4145 break;
4146 case OPC_AND_CP2:
4147 tcg_gen_and_i64(t0, t0, t1);
4148 break;
4149 case OPC_OR_CP2:
4150 tcg_gen_or_i64(t0, t0, t1);
4151 break;
4152
4153 case OPC_PANDN:
4154 tcg_gen_andc_i64(t0, t1, t0);
4155 break;
4156
4157 case OPC_PINSRH_0:
4158 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4159 break;
4160 case OPC_PINSRH_1:
4161 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4162 break;
4163 case OPC_PINSRH_2:
4164 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4165 break;
4166 case OPC_PINSRH_3:
4167 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4168 break;
4169
4170 case OPC_PEXTRH:
4171 tcg_gen_andi_i64(t1, t1, 3);
4172 tcg_gen_shli_i64(t1, t1, 4);
4173 tcg_gen_shr_i64(t0, t0, t1);
4174 tcg_gen_ext16u_i64(t0, t0);
4175 break;
4176
4177 case OPC_ADDU_CP2:
4178 tcg_gen_add_i64(t0, t0, t1);
4179 tcg_gen_ext32s_i64(t0, t0);
4180 break;
4181 case OPC_SUBU_CP2:
4182 tcg_gen_sub_i64(t0, t0, t1);
4183 tcg_gen_ext32s_i64(t0, t0);
4184 break;
4185
4186 case OPC_SLL_CP2:
4187 shift_max = 32;
4188 goto do_shift;
4189 case OPC_SRL_CP2:
4190 shift_max = 32;
4191 goto do_shift;
4192 case OPC_SRA_CP2:
4193 shift_max = 32;
4194 goto do_shift;
4195 case OPC_DSLL_CP2:
4196 shift_max = 64;
4197 goto do_shift;
4198 case OPC_DSRL_CP2:
4199 shift_max = 64;
4200 goto do_shift;
4201 case OPC_DSRA_CP2:
4202 shift_max = 64;
4203 goto do_shift;
4204 do_shift:
4205 /* Make sure shift count isn't TCG undefined behaviour. */
4206 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4207
4208 switch (opc) {
4209 case OPC_SLL_CP2:
4210 case OPC_DSLL_CP2:
4211 tcg_gen_shl_i64(t0, t0, t1);
4212 break;
4213 case OPC_SRA_CP2:
4214 case OPC_DSRA_CP2:
4215 /*
4216 * Since SRA is UndefinedResult without sign-extended inputs,
4217 * we can treat SRA and DSRA the same.
4218 */
4219 tcg_gen_sar_i64(t0, t0, t1);
4220 break;
4221 case OPC_SRL_CP2:
4222 /* We want to shift in zeros for SRL; zero-extend first. */
4223 tcg_gen_ext32u_i64(t0, t0);
4224 /* FALLTHRU */
4225 case OPC_DSRL_CP2:
4226 tcg_gen_shr_i64(t0, t0, t1);
4227 break;
4228 }
4229
4230 if (shift_max == 32) {
4231 tcg_gen_ext32s_i64(t0, t0);
4232 }
4233
4234 /* Shifts larger than MAX produce zero. */
4235 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4236 tcg_gen_neg_i64(t1, t1);
4237 tcg_gen_and_i64(t0, t0, t1);
4238 break;
4239
4240 case OPC_ADD_CP2:
4241 case OPC_DADD_CP2:
4242 {
4243 TCGv_i64 t2 = tcg_temp_new_i64();
4244 TCGLabel *lab = gen_new_label();
4245
4246 tcg_gen_mov_i64(t2, t0);
4247 tcg_gen_add_i64(t0, t1, t2);
4248 if (opc == OPC_ADD_CP2) {
4249 tcg_gen_ext32s_i64(t0, t0);
4250 }
4251 tcg_gen_xor_i64(t1, t1, t2);
4252 tcg_gen_xor_i64(t2, t2, t0);
4253 tcg_gen_andc_i64(t1, t2, t1);
4254 tcg_temp_free_i64(t2);
4255 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4256 generate_exception(ctx, EXCP_OVERFLOW);
4257 gen_set_label(lab);
4258 break;
4259 }
4260
4261 case OPC_SUB_CP2:
4262 case OPC_DSUB_CP2:
4263 {
4264 TCGv_i64 t2 = tcg_temp_new_i64();
4265 TCGLabel *lab = gen_new_label();
4266
4267 tcg_gen_mov_i64(t2, t0);
4268 tcg_gen_sub_i64(t0, t1, t2);
4269 if (opc == OPC_SUB_CP2) {
4270 tcg_gen_ext32s_i64(t0, t0);
4271 }
4272 tcg_gen_xor_i64(t1, t1, t2);
4273 tcg_gen_xor_i64(t2, t2, t0);
4274 tcg_gen_and_i64(t1, t1, t2);
4275 tcg_temp_free_i64(t2);
4276 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4277 generate_exception(ctx, EXCP_OVERFLOW);
4278 gen_set_label(lab);
4279 break;
4280 }
4281
4282 case OPC_PMULUW:
4283 tcg_gen_ext32u_i64(t0, t0);
4284 tcg_gen_ext32u_i64(t1, t1);
4285 tcg_gen_mul_i64(t0, t0, t1);
4286 break;
4287
4288 case OPC_SEQU_CP2:
4289 case OPC_SEQ_CP2:
4290 cond = TCG_COND_EQ;
4291 goto do_cc_cond;
4292 break;
4293 case OPC_SLTU_CP2:
4294 cond = TCG_COND_LTU;
4295 goto do_cc_cond;
4296 break;
4297 case OPC_SLT_CP2:
4298 cond = TCG_COND_LT;
4299 goto do_cc_cond;
4300 break;
4301 case OPC_SLEU_CP2:
4302 cond = TCG_COND_LEU;
4303 goto do_cc_cond;
4304 break;
4305 case OPC_SLE_CP2:
4306 cond = TCG_COND_LE;
4307 do_cc_cond:
4308 {
4309 int cc = (ctx->opcode >> 8) & 0x7;
4310 TCGv_i64 t64 = tcg_temp_new_i64();
4311 TCGv_i32 t32 = tcg_temp_new_i32();
4312
4313 tcg_gen_setcond_i64(cond, t64, t0, t1);
4314 tcg_gen_extrl_i64_i32(t32, t64);
4315 tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4316 get_fp_bit(cc), 1);
4317
4318 tcg_temp_free_i32(t32);
4319 tcg_temp_free_i64(t64);
4320 }
4321 goto no_rd;
4322 break;
4323 default:
4324 MIPS_INVAL("loongson_cp2");
4325 gen_reserved_instruction(ctx);
4326 return;
4327 }
4328
4329 gen_store_fpr64(ctx, t0, rd);
4330
4331 no_rd:
4332 tcg_temp_free_i64(t0);
4333 tcg_temp_free_i64(t1);
4334 }
4335
4336 static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4337 int rs, int rd)
4338 {
4339 TCGv t0, t1, t2;
4340 TCGv_i32 fp0;
4341 #if defined(TARGET_MIPS64)
4342 int lsq_rt1 = ctx->opcode & 0x1f;
4343 int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4344 #endif
4345 int shf_offset = sextract32(ctx->opcode, 6, 8);
4346
4347 t0 = tcg_temp_new();
4348
4349 switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4350 #if defined(TARGET_MIPS64)
4351 case OPC_GSLQ:
4352 t1 = tcg_temp_new();
4353 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4354 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4355 ctx->default_tcg_memop_mask);
4356 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4357 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4358 ctx->default_tcg_memop_mask);
4359 gen_store_gpr(t1, rt);
4360 gen_store_gpr(t0, lsq_rt1);
4361 tcg_temp_free(t1);
4362 break;
4363 case OPC_GSLQC1:
4364 check_cp1_enabled(ctx);
4365 t1 = tcg_temp_new();
4366 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4367 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4368 ctx->default_tcg_memop_mask);
4369 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4370 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4371 ctx->default_tcg_memop_mask);
4372 gen_store_fpr64(ctx, t1, rt);
4373 gen_store_fpr64(ctx, t0, lsq_rt1);
4374 tcg_temp_free(t1);
4375 break;
4376 case OPC_GSSQ:
4377 t1 = tcg_temp_new();
4378 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4379 gen_load_gpr(t1, rt);
4380 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4381 ctx->default_tcg_memop_mask);
4382 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4383 gen_load_gpr(t1, lsq_rt1);
4384 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4385 ctx->default_tcg_memop_mask);
4386 tcg_temp_free(t1);
4387 break;
4388 case OPC_GSSQC1:
4389 check_cp1_enabled(ctx);
4390 t1 = tcg_temp_new();
4391 gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4392 gen_load_fpr64(ctx, t1, rt);
4393 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4394 ctx->default_tcg_memop_mask);
4395 gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4396 gen_load_fpr64(ctx, t1, lsq_rt1);
4397 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4398 ctx->default_tcg_memop_mask);
4399 tcg_temp_free(t1);
4400 break;
4401 #endif
4402 case OPC_GSSHFL:
4403 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4404 case OPC_GSLWLC1:
4405 check_cp1_enabled(ctx);
4406 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4407 t1 = tcg_temp_new();
4408 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4409 tcg_gen_andi_tl(t1, t0, 3);
4410 if (!cpu_is_bigendian(ctx)) {
4411 tcg_gen_xori_tl(t1, t1, 3);
4412 }
4413 tcg_gen_shli_tl(t1, t1, 3);
4414 tcg_gen_andi_tl(t0, t0, ~3);
4415 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4416 tcg_gen_shl_tl(t0, t0, t1);
4417 t2 = tcg_const_tl(-1);
4418 tcg_gen_shl_tl(t2, t2, t1);
4419 fp0 = tcg_temp_new_i32();
4420 gen_load_fpr32(ctx, fp0, rt);
4421 tcg_gen_ext_i32_tl(t1, fp0);
4422 tcg_gen_andc_tl(t1, t1, t2);
4423 tcg_temp_free(t2);
4424 tcg_gen_or_tl(t0, t0, t1);
4425 tcg_temp_free(t1);
4426 #if defined(TARGET_MIPS64)
4427 tcg_gen_extrl_i64_i32(fp0, t0);
4428 #else
4429 tcg_gen_ext32s_tl(fp0, t0);
4430 #endif
4431 gen_store_fpr32(ctx, fp0, rt);
4432 tcg_temp_free_i32(fp0);
4433 break;
4434 case OPC_GSLWRC1:
4435 check_cp1_enabled(ctx);
4436 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4437 t1 = tcg_temp_new();
4438 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4439 tcg_gen_andi_tl(t1, t0, 3);
4440 if (cpu_is_bigendian(ctx)) {
4441 tcg_gen_xori_tl(t1, t1, 3);
4442 }
4443 tcg_gen_shli_tl(t1, t1, 3);
4444 tcg_gen_andi_tl(t0, t0, ~3);
4445 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4446 tcg_gen_shr_tl(t0, t0, t1);
4447 tcg_gen_xori_tl(t1, t1, 31);
4448 t2 = tcg_const_tl(0xfffffffeull);
4449 tcg_gen_shl_tl(t2, t2, t1);
4450 fp0 = tcg_temp_new_i32();
4451 gen_load_fpr32(ctx, fp0, rt);
4452 tcg_gen_ext_i32_tl(t1, fp0);
4453 tcg_gen_and_tl(t1, t1, t2);
4454 tcg_temp_free(t2);
4455 tcg_gen_or_tl(t0, t0, t1);
4456 tcg_temp_free(t1);
4457 #if defined(TARGET_MIPS64)
4458 tcg_gen_extrl_i64_i32(fp0, t0);
4459 #else
4460 tcg_gen_ext32s_tl(fp0, t0);
4461 #endif
4462 gen_store_fpr32(ctx, fp0, rt);
4463 tcg_temp_free_i32(fp0);
4464 break;
4465 #if defined(TARGET_MIPS64)
4466 case OPC_GSLDLC1:
4467 check_cp1_enabled(ctx);
4468 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4469 t1 = tcg_temp_new();
4470 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4471 tcg_gen_andi_tl(t1, t0, 7);
4472 if (!cpu_is_bigendian(ctx)) {
4473 tcg_gen_xori_tl(t1, t1, 7);
4474 }
4475 tcg_gen_shli_tl(t1, t1, 3);
4476 tcg_gen_andi_tl(t0, t0, ~7);
4477 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
4478 tcg_gen_shl_tl(t0, t0, t1);
4479 t2 = tcg_const_tl(-1);
4480 tcg_gen_shl_tl(t2, t2, t1);
4481 gen_load_fpr64(ctx, t1, rt);
4482 tcg_gen_andc_tl(t1, t1, t2);
4483 tcg_temp_free(t2);
4484 tcg_gen_or_tl(t0, t0, t1);
4485 tcg_temp_free(t1);
4486 gen_store_fpr64(ctx, t0, rt);
4487 break;
4488 case OPC_GSLDRC1:
4489 check_cp1_enabled(ctx);
4490 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4491 t1 = tcg_temp_new();
4492 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4493 tcg_gen_andi_tl(t1, t0, 7);
4494 if (cpu_is_bigendian(ctx)) {
4495 tcg_gen_xori_tl(t1, t1, 7);
4496 }
4497 tcg_gen_shli_tl(t1, t1, 3);
4498 tcg_gen_andi_tl(t0, t0, ~7);
4499 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
4500 tcg_gen_shr_tl(t0, t0, t1);
4501 tcg_gen_xori_tl(t1, t1, 63);
4502 t2 = tcg_const_tl(0xfffffffffffffffeull);
4503 tcg_gen_shl_tl(t2, t2, t1);
4504 gen_load_fpr64(ctx, t1, rt);
4505 tcg_gen_and_tl(t1, t1, t2);
4506 tcg_temp_free(t2);
4507 tcg_gen_or_tl(t0, t0, t1);
4508 tcg_temp_free(t1);
4509 gen_store_fpr64(ctx, t0, rt);
4510 break;
4511 #endif
4512 default:
4513 MIPS_INVAL("loongson_gsshfl");
4514 gen_reserved_instruction(ctx);
4515 break;
4516 }
4517 break;
4518 case OPC_GSSHFS:
4519 switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4520 case OPC_GSSWLC1:
4521 check_cp1_enabled(ctx);
4522 t1 = tcg_temp_new();
4523 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4524 fp0 = tcg_temp_new_i32();
4525 gen_load_fpr32(ctx, fp0, rt);
4526 tcg_gen_ext_i32_tl(t1, fp0);
4527 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4528 tcg_temp_free_i32(fp0);
4529 tcg_temp_free(t1);
4530 break;
4531 case OPC_GSSWRC1:
4532 check_cp1_enabled(ctx);
4533 t1 = tcg_temp_new();
4534 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4535 fp0 = tcg_temp_new_i32();
4536 gen_load_fpr32(ctx, fp0, rt);
4537 tcg_gen_ext_i32_tl(t1, fp0);
4538 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4539 tcg_temp_free_i32(fp0);
4540 tcg_temp_free(t1);
4541 break;
4542 #if defined(TARGET_MIPS64)
4543 case OPC_GSSDLC1:
4544 check_cp1_enabled(ctx);
4545 t1 = tcg_temp_new();
4546 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4547 gen_load_fpr64(ctx, t1, rt);
4548 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4549 tcg_temp_free(t1);
4550 break;
4551 case OPC_GSSDRC1:
4552 check_cp1_enabled(ctx);
4553 t1 = tcg_temp_new();
4554 gen_base_offset_addr(ctx, t0, rs, shf_offset);
4555 gen_load_fpr64(ctx, t1, rt);
4556 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4557 tcg_temp_free(t1);
4558 break;
4559 #endif
4560 default:
4561 MIPS_INVAL("loongson_gsshfs");
4562 gen_reserved_instruction(ctx);
4563 break;
4564 }
4565 break;
4566 default:
4567 MIPS_INVAL("loongson_gslsq");
4568 gen_reserved_instruction(ctx);
4569 break;
4570 }
4571 tcg_temp_free(t0);
4572 }
4573
4574 /* Loongson EXT LDC2/SDC2 */
4575 static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4576 int rs, int rd)
4577 {
4578 int offset = sextract32(ctx->opcode, 3, 8);
4579 uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4580 TCGv t0, t1;
4581 TCGv_i32 fp0;
4582
4583 /* Pre-conditions */
4584 switch (opc) {
4585 case OPC_GSLBX:
4586 case OPC_GSLHX:
4587 case OPC_GSLWX:
4588 case OPC_GSLDX:
4589 /* prefetch, implement as NOP */
4590 if (rt == 0) {
4591 return;
4592 }
4593 break;
4594 case OPC_GSSBX:
4595 case OPC_GSSHX:
4596 case OPC_GSSWX:
4597 case OPC_GSSDX:
4598 break;
4599 case OPC_GSLWXC1:
4600 #if defined(TARGET_MIPS64)
4601 case OPC_GSLDXC1:
4602 #endif
4603 check_cp1_enabled(ctx);
4604 /* prefetch, implement as NOP */
4605 if (rt == 0) {
4606 return;
4607 }
4608 break;
4609 case OPC_GSSWXC1:
4610 #if defined(TARGET_MIPS64)
4611 case OPC_GSSDXC1:
4612 #endif
4613 check_cp1_enabled(ctx);
4614 break;
4615 default:
4616 MIPS_INVAL("loongson_lsdc2");
4617 gen_reserved_instruction(ctx);
4618 return;
4619 break;
4620 }
4621
4622 t0 = tcg_temp_new();
4623
4624 gen_base_offset_addr(ctx, t0, rs, offset);
4625 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4626
4627 switch (opc) {
4628 case OPC_GSLBX:
4629 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4630 gen_store_gpr(t0, rt);
4631 break;
4632 case OPC_GSLHX:
4633 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4634 ctx->default_tcg_memop_mask);
4635 gen_store_gpr(t0, rt);
4636 break;
4637 case OPC_GSLWX:
4638 gen_base_offset_addr(ctx, t0, rs, offset);
4639 if (rd) {
4640 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4641 }
4642 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4643 ctx->default_tcg_memop_mask);
4644 gen_store_gpr(t0, rt);
4645 break;
4646 #if defined(TARGET_MIPS64)
4647 case OPC_GSLDX:
4648 gen_base_offset_addr(ctx, t0, rs, offset);
4649 if (rd) {
4650 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4651 }
4652 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4653 ctx->default_tcg_memop_mask);
4654 gen_store_gpr(t0, rt);
4655 break;
4656 #endif
4657 case OPC_GSLWXC1:
4658 gen_base_offset_addr(ctx, t0, rs, offset);
4659 if (rd) {
4660 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4661 }
4662 fp0 = tcg_temp_new_i32();
4663 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4664 ctx->default_tcg_memop_mask);
4665 gen_store_fpr32(ctx, fp0, rt);
4666 tcg_temp_free_i32(fp0);
4667 break;
4668 #if defined(TARGET_MIPS64)
4669 case OPC_GSLDXC1:
4670 gen_base_offset_addr(ctx, t0, rs, offset);
4671 if (rd) {
4672 gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4673 }
4674 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ |
4675 ctx->default_tcg_memop_mask);
4676 gen_store_fpr64(ctx, t0, rt);
4677 break;
4678 #endif
4679 case OPC_GSSBX:
4680 t1 = tcg_temp_new();
4681 gen_load_gpr(t1, rt);
4682 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4683 tcg_temp_free(t1);
4684 break;
4685 case OPC_GSSHX:
4686 t1 = tcg_temp_new();
4687 gen_load_gpr(t1, rt);
4688 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4689 ctx->default_tcg_memop_mask);
4690 tcg_temp_free(t1);
4691 break;
4692 case OPC_GSSWX:
4693 t1 = tcg_temp_new();
4694 gen_load_gpr(t1, rt);
4695 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4696 ctx->default_tcg_memop_mask);
4697 tcg_temp_free(t1);
4698 break;
4699 #if defined(TARGET_MIPS64)
4700 case OPC_GSSDX:
4701 t1 = tcg_temp_new();
4702 gen_load_gpr(t1, rt);
4703 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUQ |
4704 ctx->default_tcg_memop_mask);
4705 tcg_temp_free(t1);
4706 break;
4707 #endif
4708 case OPC_GSSWXC1:
4709 fp0 = tcg_temp_new_i32();
4710 gen_load_fpr32(ctx, fp0, rt);
4711 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4712 ctx->default_tcg_memop_mask);
4713 tcg_temp_free_i32(fp0);
4714 break;
4715 #if defined(TARGET_MIPS64)
4716 case OPC_GSSDXC1:
4717 t1 = tcg_temp_new();
4718 gen_load_fpr64(ctx, t1, rt);
4719 tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEUQ |
4720 ctx->default_tcg_memop_mask);
4721 tcg_temp_free(t1);
4722 break;
4723 #endif
4724 default:
4725 break;
4726 }
4727
4728 tcg_temp_free(t0);
4729 }
4730
4731 /* Traps */
4732 static void gen_trap(DisasContext *ctx, uint32_t opc,
4733 int rs, int rt, int16_t imm, int code)
4734 {
4735 int cond;
4736 TCGv t0 = tcg_temp_new();
4737 TCGv t1 = tcg_temp_new();
4738
4739 cond = 0;
4740 /* Load needed operands */
4741 switch (opc) {
4742 case OPC_TEQ:
4743 case OPC_TGE:
4744 case OPC_TGEU:
4745 case OPC_TLT:
4746 case OPC_TLTU:
4747 case OPC_TNE:
4748 /* Compare two registers */
4749 if (rs != rt) {
4750 gen_load_gpr(t0, rs);
4751 gen_load_gpr(t1, rt);
4752 cond = 1;
4753 }
4754 break;
4755 case OPC_TEQI:
4756 case OPC_TGEI:
4757 case OPC_TGEIU:
4758 case OPC_TLTI:
4759 case OPC_TLTIU:
4760 case OPC_TNEI:
4761 /* Compare register to immediate */
4762 if (rs != 0 || imm != 0) {
4763 gen_load_gpr(t0, rs);
4764 tcg_gen_movi_tl(t1, (int32_t)imm);
4765 cond = 1;
4766 }
4767 break;
4768 }
4769 if (cond == 0) {
4770 switch (opc) {
4771 case OPC_TEQ: /* rs == rs */
4772 case OPC_TEQI: /* r0 == 0 */
4773 case OPC_TGE: /* rs >= rs */
4774 case OPC_TGEI: /* r0 >= 0 */
4775 case OPC_TGEU: /* rs >= rs unsigned */
4776 case OPC_TGEIU: /* r0 >= 0 unsigned */
4777 /* Always trap */
4778 #ifdef CONFIG_USER_ONLY
4779 /* Pass the break code along to cpu_loop. */
4780 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
4781 offsetof(CPUMIPSState, error_code));
4782 #endif
4783 generate_exception_end(ctx, EXCP_TRAP);
4784 break;
4785 case OPC_TLT: /* rs < rs */
4786 case OPC_TLTI: /* r0 < 0 */
4787 case OPC_TLTU: /* rs < rs unsigned */
4788 case OPC_TLTIU: /* r0 < 0 unsigned */
4789 case OPC_TNE: /* rs != rs */
4790 case OPC_TNEI: /* r0 != 0 */
4791 /* Never trap: treat as NOP. */
4792 break;
4793 }
4794 } else {
4795 TCGLabel *l1 = gen_new_label();
4796
4797 switch (opc) {
4798 case OPC_TEQ:
4799 case OPC_TEQI:
4800 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4801 break;
4802 case OPC_TGE:
4803 case OPC_TGEI:
4804 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4805 break;
4806 case OPC_TGEU:
4807 case OPC_TGEIU:
4808 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4809 break;
4810 case OPC_TLT:
4811 case OPC_TLTI:
4812 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4813 break;
4814 case OPC_TLTU:
4815 case OPC_TLTIU:
4816 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4817 break;
4818 case OPC_TNE:
4819 case OPC_TNEI:
4820 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4821 break;
4822 }
4823 #ifdef CONFIG_USER_ONLY
4824 /* Pass the break code along to cpu_loop. */
4825 tcg_gen_st_i32(tcg_constant_i32(code), cpu_env,
4826 offsetof(CPUMIPSState, error_code));
4827 #endif
4828 /* Like save_cpu_state, only don't update saved values. */
4829 if (ctx->base.pc_next != ctx->saved_pc) {
4830 gen_save_pc(ctx->base.pc_next);
4831 }
4832 if (ctx->hflags != ctx->saved_hflags) {
4833 tcg_gen_movi_i32(hflags, ctx->hflags);
4834 }
4835 generate_exception(ctx, EXCP_TRAP);
4836 gen_set_label(l1);
4837 }
4838 tcg_temp_free(t0);
4839 tcg_temp_free(t1);
4840 }
4841
4842 static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4843 {
4844 if (translator_use_goto_tb(&ctx->base, dest)) {
4845 tcg_gen_goto_tb(n);
4846 gen_save_pc(dest);
4847 tcg_gen_exit_tb(ctx->base.tb, n);
4848 } else {
4849 gen_save_pc(dest);
4850 tcg_gen_lookup_and_goto_ptr();
4851 }
4852 }
4853
4854 /* Branches (before delay slot) */
4855 static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4856 int insn_bytes,
4857 int rs, int rt, int32_t offset,
4858 int delayslot_size)
4859 {
4860 target_ulong btgt = -1;
4861 int blink = 0;
4862 int bcond_compute = 0;
4863 TCGv t0 = tcg_temp_new();
4864 TCGv t1 = tcg_temp_new();
4865
4866 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4867 #ifdef MIPS_DEBUG_DISAS
4868 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4869 TARGET_FMT_lx "\n", ctx->base.pc_next);
4870 #endif
4871 gen_reserved_instruction(ctx);
4872 goto out;
4873 }
4874
4875 /* Load needed operands */
4876 switch (opc) {
4877 case OPC_BEQ:
4878 case OPC_BEQL:
4879 case OPC_BNE:
4880 case OPC_BNEL:
4881 /* Compare two registers */
4882 if (rs != rt) {
4883 gen_load_gpr(t0, rs);
4884 gen_load_gpr(t1, rt);
4885 bcond_compute = 1;
4886 }
4887 btgt = ctx->base.pc_next + insn_bytes + offset;
4888 break;
4889 case OPC_BGEZ:
4890 case OPC_BGEZAL:
4891 case OPC_BGEZALL:
4892 case OPC_BGEZL:
4893 case OPC_BGTZ:
4894 case OPC_BGTZL:
4895 case OPC_BLEZ:
4896 case OPC_BLEZL:
4897 case OPC_BLTZ:
4898 case OPC_BLTZAL:
4899 case OPC_BLTZALL:
4900 case OPC_BLTZL:
4901 /* Compare to zero */
4902 if (rs != 0) {
4903 gen_load_gpr(t0, rs);
4904 bcond_compute = 1;
4905 }
4906 btgt = ctx->base.pc_next + insn_bytes + offset;
4907 break;
4908 case OPC_BPOSGE32:
4909 #if defined(TARGET_MIPS64)
4910 case OPC_BPOSGE64:
4911 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4912 #else
4913 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4914 #endif
4915 bcond_compute = 1;
4916 btgt = ctx->base.pc_next + insn_bytes + offset;
4917 break;
4918 case OPC_J:
4919 case OPC_JAL:
4920 case OPC_JALX:
4921 /* Jump to immediate */
4922 btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4923 (uint32_t)offset;
4924 break;
4925 case OPC_JR:
4926 case OPC_JALR:
4927 /* Jump to register */
4928 if (offset != 0 && offset != 16) {
4929 /*
4930 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4931 * others are reserved.
4932 */
4933 MIPS_INVAL("jump hint");
4934 gen_reserved_instruction(ctx);
4935 goto out;
4936 }
4937 gen_load_gpr(btarget, rs);
4938 break;
4939 default:
4940 MIPS_INVAL("branch/jump");
4941 gen_reserved_instruction(ctx);
4942 goto out;
4943 }
4944 if (bcond_compute == 0) {
4945 /* No condition to be computed */
4946 switch (opc) {
4947 case OPC_BEQ: /* rx == rx */
4948 case OPC_BEQL: /* rx == rx likely */
4949 case OPC_BGEZ: /* 0 >= 0 */
4950 case OPC_BGEZL: /* 0 >= 0 likely */
4951 case OPC_BLEZ: /* 0 <= 0 */
4952 case OPC_BLEZL: /* 0 <= 0 likely */
4953 /* Always take */
4954 ctx->hflags |= MIPS_HFLAG_B;
4955 break;
4956 case OPC_BGEZAL: /* 0 >= 0 */
4957 case OPC_BGEZALL: /* 0 >= 0 likely */
4958 /* Always take and link */
4959 blink = 31;
4960 ctx->hflags |= MIPS_HFLAG_B;
4961 break;
4962 case OPC_BNE: /* rx != rx */
4963 case OPC_BGTZ: /* 0 > 0 */
4964 case OPC_BLTZ: /* 0 < 0 */
4965 /* Treat as NOP. */
4966 goto out;
4967 case OPC_BLTZAL: /* 0 < 0 */
4968 /*
4969 * Handle as an unconditional branch to get correct delay
4970 * slot checking.
4971 */
4972 blink = 31;
4973 btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4974 ctx->hflags |= MIPS_HFLAG_B;
4975 break;
4976 case OPC_BLTZALL: /* 0 < 0 likely */
4977 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4978 /* Skip the instruction in the delay slot */
4979 ctx->base.pc_next += 4;
4980 goto out;
4981 case OPC_BNEL: /* rx != rx likely */
4982 case OPC_BGTZL: /* 0 > 0 likely */
4983 case OPC_BLTZL: /* 0 < 0 likely */
4984 /* Skip the instruction in the delay slot */
4985 ctx->base.pc_next += 4;
4986 goto out;
4987 case OPC_J:
4988 ctx->hflags |= MIPS_HFLAG_B;
4989 break;
4990 case OPC_JALX:
4991 ctx->hflags |= MIPS_HFLAG_BX;
4992 /* Fallthrough */
4993 case OPC_JAL:
4994 blink = 31;
4995 ctx->hflags |= MIPS_HFLAG_B;
4996 break;
4997 case OPC_JR:
4998 ctx->hflags |= MIPS_HFLAG_BR;
4999 break;
5000 case OPC_JALR:
5001 blink = rt;
5002 ctx->hflags |= MIPS_HFLAG_BR;
5003 break;
5004 default:
5005 MIPS_INVAL("branch/jump");
5006 gen_reserved_instruction(ctx);
5007 goto out;
5008 }
5009 } else {
5010 switch (opc) {
5011 case OPC_BEQ:
5012 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5013 goto not_likely;
5014 case OPC_BEQL:
5015 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5016 goto likely;
5017 case OPC_BNE:
5018 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5019 goto not_likely;
5020 case OPC_BNEL:
5021 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5022 goto likely;
5023 case OPC_BGEZ:
5024 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5025 goto not_likely;
5026 case OPC_BGEZL:
5027 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5028 goto likely;
5029 case OPC_BGEZAL:
5030 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5031 blink = 31;
5032 goto not_likely;
5033 case OPC_BGEZALL:
5034 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5035 blink = 31;
5036 goto likely;
5037 case OPC_BGTZ:
5038 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5039 goto not_likely;
5040 case OPC_BGTZL:
5041 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5042 goto likely;
5043 case OPC_BLEZ:
5044 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5045 goto not_likely;
5046 case OPC_BLEZL:
5047 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5048 goto likely;
5049 case OPC_BLTZ:
5050 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5051 goto not_likely;
5052 case OPC_BLTZL:
5053 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5054 goto likely;
5055 case OPC_BPOSGE32:
5056 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5057 goto not_likely;
5058 #if defined(TARGET_MIPS64)
5059 case OPC_BPOSGE64:
5060 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5061 goto not_likely;
5062 #endif
5063 case OPC_BLTZAL:
5064 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5065 blink = 31;
5066 not_likely:
5067 ctx->hflags |= MIPS_HFLAG_BC;
5068 break;
5069 case OPC_BLTZALL:
5070 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5071 blink = 31;
5072 likely:
5073 ctx->hflags |= MIPS_HFLAG_BL;
5074 break;
5075 default:
5076 MIPS_INVAL("conditional branch/jump");
5077 gen_reserved_instruction(ctx);
5078 goto out;
5079 }
5080 }
5081
5082 ctx->btarget = btgt;
5083
5084 switch (delayslot_size) {
5085 case 2:
5086 ctx->hflags |= MIPS_HFLAG_BDS16;
5087 break;
5088 case 4:
5089 ctx->hflags |= MIPS_HFLAG_BDS32;
5090 break;
5091 }
5092
5093 if (blink > 0) {
5094 int post_delay = insn_bytes + delayslot_size;
5095 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5096
5097 tcg_gen_movi_tl(cpu_gpr[blink],
5098 ctx->base.pc_next + post_delay + lowbit);
5099 }
5100
5101 out:
5102 if (insn_bytes == 2) {
5103 ctx->hflags |= MIPS_HFLAG_B16;
5104 }
5105 tcg_temp_free(t0);
5106 tcg_temp_free(t1);
5107 }
5108
5109
5110 /* special3 bitfield operations */
5111 static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
5112 int rs, int lsb, int msb)
5113 {
5114 TCGv t0 = tcg_temp_new();
5115 TCGv t1 = tcg_temp_new();
5116
5117 gen_load_gpr(t1, rs);
5118 switch (opc) {
5119 case OPC_EXT:
5120 if (lsb + msb > 31) {
5121 goto fail;
5122 }
5123 if (msb != 31) {
5124 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5125 } else {
5126 /*
5127 * The two checks together imply that lsb == 0,
5128 * so this is a simple sign-extension.
5129 */
5130 tcg_gen_ext32s_tl(t0, t1);
5131 }
5132 break;
5133 #if defined(TARGET_MIPS64)
5134 case OPC_DEXTU:
5135 lsb += 32;
5136 goto do_dext;
5137 case OPC_DEXTM:
5138 msb += 32;
5139 goto do_dext;
5140 case OPC_DEXT:
5141 do_dext:
5142 if (lsb + msb > 63) {
5143 goto fail;
5144 }
5145 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5146 break;
5147 #endif
5148 case OPC_INS:
5149 if (lsb > msb) {
5150 goto fail;
5151 }
5152 gen_load_gpr(t0, rt);
5153 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5154 tcg_gen_ext32s_tl(t0, t0);
5155 break;
5156 #if defined(TARGET_MIPS64)
5157 case OPC_DINSU:
5158 lsb += 32;
5159 /* FALLTHRU */
5160 case OPC_DINSM:
5161 msb += 32;
5162 /* FALLTHRU */
5163 case OPC_DINS:
5164 if (lsb > msb) {
5165 goto fail;
5166 }
5167 gen_load_gpr(t0, rt);
5168 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5169 break;
5170 #endif
5171 default:
5172 fail:
5173 MIPS_INVAL("bitops");
5174 gen_reserved_instruction(ctx);
5175 tcg_temp_free(t0);
5176 tcg_temp_free(t1);
5177 return;
5178 }
5179 gen_store_gpr(t0, rt);
5180 tcg_temp_free(t0);
5181 tcg_temp_free(t1);
5182 }
5183
5184 static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
5185 {
5186 TCGv t0;
5187
5188 if (rd == 0) {
5189 /* If no destination, treat it as a NOP. */
5190 return;
5191 }
5192
5193 t0 = tcg_temp_new();
5194 gen_load_gpr(t0, rt);
5195 switch (op2) {
5196 case OPC_WSBH:
5197 {
5198 TCGv t1 = tcg_temp_new();
5199 TCGv t2 = tcg_const_tl(0x00FF00FF);
5200
5201 tcg_gen_shri_tl(t1, t0, 8);
5202 tcg_gen_and_tl(t1, t1, t2);
5203 tcg_gen_and_tl(t0, t0, t2);
5204 tcg_gen_shli_tl(t0, t0, 8);
5205 tcg_gen_or_tl(t0, t0, t1);
5206 tcg_temp_free(t2);
5207 tcg_temp_free(t1);
5208 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5209 }
5210 break;
5211 case OPC_SEB:
5212 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5213 break;
5214 case OPC_SEH:
5215 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5216 break;
5217 #if defined(TARGET_MIPS64)
5218 case OPC_DSBH:
5219 {
5220 TCGv t1 = tcg_temp_new();
5221 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5222
5223 tcg_gen_shri_tl(t1, t0, 8);
5224 tcg_gen_and_tl(t1, t1, t2);
5225 tcg_gen_and_tl(t0, t0, t2);
5226 tcg_gen_shli_tl(t0, t0, 8);
5227 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5228 tcg_temp_free(t2);
5229 tcg_temp_free(t1);
5230 }
5231 break;
5232 case OPC_DSHD:
5233 {
5234 TCGv t1 = tcg_temp_new();
5235 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5236
5237 tcg_gen_shri_tl(t1, t0, 16);
5238 tcg_gen_and_tl(t1, t1, t2);
5239 tcg_gen_and_tl(t0, t0, t2);
5240 tcg_gen_shli_tl(t0, t0, 16);
5241 tcg_gen_or_tl(t0, t0, t1);
5242 tcg_gen_shri_tl(t1, t0, 32);
5243 tcg_gen_shli_tl(t0, t0, 32);
5244 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5245 tcg_temp_free(t2);
5246 tcg_temp_free(t1);
5247 }
5248 break;
5249 #endif
5250 default:
5251 MIPS_INVAL("bsfhl");
5252 gen_reserved_instruction(ctx);
5253 tcg_temp_free(t0);
5254 return;
5255 }
5256 tcg_temp_free(t0);
5257 }
5258
5259 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5260 int rt, int bits)
5261 {
5262 TCGv t0;
5263 if (rd == 0) {
5264 /* Treat as NOP. */
5265 return;
5266 }
5267 t0 = tcg_temp_new();
5268 if (bits == 0 || bits == wordsz) {
5269 if (bits == 0) {
5270 gen_load_gpr(t0, rt);
5271 } else {
5272 gen_load_gpr(t0, rs);
5273 }
5274 switch (wordsz) {
5275 case 32:
5276 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5277 break;
5278 #if defined(TARGET_MIPS64)
5279 case 64:
5280 tcg_gen_mov_tl(cpu_gpr[rd], t0);
5281 break;
5282 #endif
5283 }
5284 } else {
5285 TCGv t1 = tcg_temp_new();
5286 gen_load_gpr(t0, rt);
5287 gen_load_gpr(t1, rs);
5288 switch (wordsz) {
5289 case 32:
5290 {
5291 TCGv_i64 t2 = tcg_temp_new_i64();
5292 tcg_gen_concat_tl_i64(t2, t1, t0);
5293 tcg_gen_shri_i64(t2, t2, 32 - bits);
5294 gen_move_low32(cpu_gpr[rd], t2);
5295 tcg_temp_free_i64(t2);
5296 }
5297 break;
5298 #if defined(TARGET_MIPS64)
5299 case 64:
5300 tcg_gen_shli_tl(t0, t0, bits);
5301 tcg_gen_shri_tl(t1, t1, 64 - bits);
5302 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5303 break;
5304 #endif
5305 }
5306 tcg_temp_free(t1);
5307 }
5308
5309 tcg_temp_free(t0);
5310 }
5311
5312 void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
5313 {
5314 gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5315 }
5316
5317 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5318 {
5319 TCGv t0;
5320 if (rd == 0) {
5321 /* Treat as NOP. */
5322 return;
5323 }
5324 t0 = tcg_temp_new();
5325 gen_load_gpr(t0, rt);
5326 switch (opc) {
5327 case OPC_BITSWAP:
5328 gen_helper_bitswap(cpu_gpr[rd], t0);
5329 break;
5330 #if defined(TARGET_MIPS64)
5331 case OPC_DBITSWAP:
5332 gen_helper_dbitswap(cpu_gpr[rd], t0);
5333 break;
5334 #endif
5335 }
5336 tcg_temp_free(t0);
5337 }
5338
5339 #ifndef CONFIG_USER_ONLY
5340 /* CP0 (MMU and control) */
5341 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5342 {
5343 TCGv_i64 t0 = tcg_temp_new_i64();
5344 TCGv_i64 t1 = tcg_temp_new_i64();
5345
5346 tcg_gen_ext_tl_i64(t0, arg);
5347 tcg_gen_ld_i64(t1, cpu_env, off);
5348 #if defined(TARGET_MIPS64)
5349 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5350 #else
5351 tcg_gen_concat32_i64(t1, t1, t0);
5352 #endif
5353 tcg_gen_st_i64(t1, cpu_env, off);
5354 tcg_temp_free_i64(t1);
5355 tcg_temp_free_i64(t0);
5356 }
5357
5358 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5359 {
5360 TCGv_i64 t0 = tcg_temp_new_i64();
5361 TCGv_i64 t1 = tcg_temp_new_i64();
5362
5363 tcg_gen_ext_tl_i64(t0, arg);
5364 tcg_gen_ld_i64(t1, cpu_env, off);
5365 tcg_gen_concat32_i64(t1, t1, t0);
5366 tcg_gen_st_i64(t1, cpu_env, off);
5367 tcg_temp_free_i64(t1);
5368 tcg_temp_free_i64(t0);
5369 }
5370
5371 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5372 {
5373 TCGv_i64 t0 = tcg_temp_new_i64();
5374
5375 tcg_gen_ld_i64(t0, cpu_env, off);
5376 #if defined(TARGET_MIPS64)
5377 tcg_gen_shri_i64(t0, t0, 30);
5378 #else
5379 tcg_gen_shri_i64(t0, t0, 32);
5380 #endif
5381 gen_move_low32(arg, t0);
5382 tcg_temp_free_i64(t0);
5383 }
5384
5385 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5386 {
5387 TCGv_i64 t0 = tcg_temp_new_i64();
5388
5389 tcg_gen_ld_i64(t0, cpu_env, off);
5390 tcg_gen_shri_i64(t0, t0, 32 + shift);
5391 gen_move_low32(arg, t0);
5392 tcg_temp_free_i64(t0);
5393 }
5394
5395 static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5396 {
5397 TCGv_i32 t0 = tcg_temp_new_i32();
5398
5399 tcg_gen_ld_i32(t0, cpu_env, off);
5400 tcg_gen_ext_i32_tl(arg, t0);
5401 tcg_temp_free_i32(t0);
5402 }
5403
5404 static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5405 {
5406 tcg_gen_ld_tl(arg, cpu_env, off);
5407 tcg_gen_ext32s_tl(arg, arg);
5408 }
5409
5410 static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5411 {
5412 TCGv_i32 t0 = tcg_temp_new_i32();
5413
5414 tcg_gen_trunc_tl_i32(t0, arg);
5415 tcg_gen_st_i32(t0, cpu_env, off);
5416 tcg_temp_free_i32(t0);
5417 }
5418
5419 #define CP0_CHECK(c) \
5420 do { \
5421 if (!(c)) { \
5422 goto cp0_unimplemented; \
5423 } \
5424 } while (0)
5425
5426 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5427 {
5428 const char *register_name = "invalid";
5429
5430 switch (reg) {
5431 case CP0_REGISTER_02:
5432 switch (sel) {
5433 case 0:
5434 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5435 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5436 register_name = "EntryLo0";
5437 break;
5438 default:
5439 goto cp0_unimplemented;
5440 }
5441 break;
5442 case CP0_REGISTER_03:
5443 switch (sel) {
5444 case CP0_REG03__ENTRYLO1:
5445 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5446 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5447 register_name = "EntryLo1";
5448 break;
5449 default:
5450 goto cp0_unimplemented;
5451 }
5452 break;
5453 case CP0_REGISTER_09:
5454 switch (sel) {
5455 case CP0_REG09__SAAR:
5456 CP0_CHECK(ctx->saar);
5457 gen_helper_mfhc0_saar(arg, cpu_env);
5458 register_name = "SAAR";
5459 break;
5460 default:
5461 goto cp0_unimplemented;
5462 }
5463 break;
5464 case CP0_REGISTER_17:
5465 switch (sel) {
5466 case CP0_REG17__LLADDR:
5467 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5468 ctx->CP0_LLAddr_shift);
5469 register_name = "LLAddr";
5470 break;
5471 case CP0_REG17__MAAR:
5472 CP0_CHECK(ctx->mrp);
5473 gen_helper_mfhc0_maar(arg, cpu_env);
5474 register_name = "MAAR";
5475 break;
5476 default:
5477 goto cp0_unimplemented;
5478 }
5479 break;
5480 case CP0_REGISTER_19:
5481 switch (sel) {
5482 case CP0_REG19__WATCHHI0:
5483 case CP0_REG19__WATCHHI1:
5484 case CP0_REG19__WATCHHI2:
5485 case CP0_REG19__WATCHHI3:
5486 case CP0_REG19__WATCHHI4:
5487 case CP0_REG19__WATCHHI5:
5488 case CP0_REG19__WATCHHI6:
5489 case CP0_REG19__WATCHHI7:
5490 /* upper 32 bits are only available when Config5MI != 0 */
5491 CP0_CHECK(ctx->mi);
5492 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5493 register_name = "WatchHi";
5494 break;
5495 default:
5496 goto cp0_unimplemented;
5497 }
5498 break;
5499 case CP0_REGISTER_28:
5500 switch (sel) {
5501 case 0:
5502 case 2:
5503 case 4:
5504 case 6:
5505 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5506 register_name = "TagLo";
5507 break;
5508 default:
5509 goto cp0_unimplemented;
5510 }
5511 break;
5512 default:
5513 goto cp0_unimplemented;
5514 }
5515 trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5516 return;
5517
5518 cp0_unimplemented:
5519 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5520 register_name, reg, sel);
5521 tcg_gen_movi_tl(arg, 0);
5522 }
5523
5524 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5525 {
5526 const char *register_name = "invalid";
5527 uint64_t mask = ctx->PAMask >> 36;
5528
5529 switch (reg) {
5530 case CP0_REGISTER_02:
5531 switch (sel) {
5532 case 0:
5533 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5534 tcg_gen_andi_tl(arg, arg, mask);
5535 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5536 register_name = "EntryLo0";
5537 break;
5538 default:
5539 goto cp0_unimplemented;
5540 }
5541 break;
5542 case CP0_REGISTER_03:
5543 switch (sel) {
5544 case CP0_REG03__ENTRYLO1:
5545 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5546 tcg_gen_andi_tl(arg, arg, mask);
5547 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5548 register_name = "EntryLo1";
5549 break;
5550 default:
5551 goto cp0_unimplemented;
5552 }
5553 break;
5554 case CP0_REGISTER_09:
5555 switch (sel) {
5556 case CP0_REG09__SAAR:
5557 CP0_CHECK(ctx->saar);
5558 gen_helper_mthc0_saar(cpu_env, arg);
5559 register_name = "SAAR";
5560 break;
5561 default:
5562 goto cp0_unimplemented;
5563 }
5564 break;
5565 case CP0_REGISTER_17:
5566 switch (sel) {
5567 case CP0_REG17__LLADDR:
5568 /*
5569 * LLAddr is read-only (the only exception is bit 0 if LLB is
5570 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5571 * relevant for modern MIPS cores supporting MTHC0, therefore
5572 * treating MTHC0 to LLAddr as NOP.
5573 */
5574 register_name = "LLAddr";
5575 break;
5576 case CP0_REG17__MAAR:
5577 CP0_CHECK(ctx->mrp);
5578 gen_helper_mthc0_maar(cpu_env, arg);
5579 register_name = "MAAR";
5580 break;
5581 default:
5582 goto cp0_unimplemented;
5583 }
5584 break;
5585 case CP0_REGISTER_19:
5586 switch (sel) {
5587 case CP0_REG19__WATCHHI0:
5588 case CP0_REG19__WATCHHI1:
5589 case CP0_REG19__WATCHHI2:
5590 case CP0_REG19__WATCHHI3:
5591 case CP0_REG19__WATCHHI4:
5592 case CP0_REG19__WATCHHI5:
5593 case CP0_REG19__WATCHHI6:
5594 case CP0_REG19__WATCHHI7:
5595 /* upper 32 bits are only available when Config5MI != 0 */
5596 CP0_CHECK(ctx->mi);
5597 gen_helper_0e1i(mthc0_watchhi, arg, sel);
5598 register_name = "WatchHi";
5599 break;
5600 default:
5601 goto cp0_unimplemented;
5602 }
5603 break;
5604 case CP0_REGISTER_28:
5605 switch (sel) {
5606 case 0:
5607 case 2:
5608 case 4:
5609 case 6:
5610 tcg_gen_andi_tl(arg, arg, mask);
5611 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5612 register_name = "TagLo";
5613 break;
5614 default:
5615 goto cp0_unimplemented;
5616 }
5617 break;
5618 default:
5619 goto cp0_unimplemented;
5620 }
5621 trace_mips_translate_c0("mthc0", register_name, reg, sel);
5622 return;
5623
5624 cp0_unimplemented:
5625 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5626 register_name, reg, sel);
5627 }
5628
5629 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5630 {
5631 if (ctx->insn_flags & ISA_MIPS_R6) {
5632 tcg_gen_movi_tl(arg, 0);
5633 } else {
5634 tcg_gen_movi_tl(arg, ~0);
5635 }
5636 }
5637
5638 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5639 {
5640 const char *register_name = "invalid";
5641
5642 if (sel != 0) {
5643 check_insn(ctx, ISA_MIPS_R1);
5644 }
5645
5646 switch (reg) {
5647 case CP0_REGISTER_00:
5648 switch (sel) {
5649 case CP0_REG00__INDEX:
5650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5651 register_name = "Index";
5652 break;
5653 case CP0_REG00__MVPCONTROL:
5654 CP0_CHECK(ctx->insn_flags & ASE_MT);
5655 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5656 register_name = "MVPControl";
5657 break;
5658 case CP0_REG00__MVPCONF0:
5659 CP0_CHECK(ctx->insn_flags & ASE_MT);
5660 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5661 register_name = "MVPConf0";
5662 break;
5663 case CP0_REG00__MVPCONF1:
5664 CP0_CHECK(ctx->insn_flags & ASE_MT);
5665 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5666 register_name = "MVPConf1";
5667 break;
5668 case CP0_REG00__VPCONTROL:
5669 CP0_CHECK(ctx->vp);
5670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5671 register_name = "VPControl";
5672 break;
5673 default:
5674 goto cp0_unimplemented;
5675 }
5676 break;
5677 case CP0_REGISTER_01:
5678 switch (sel) {
5679 case CP0_REG01__RANDOM:
5680 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5681 gen_helper_mfc0_random(arg, cpu_env);
5682 register_name = "Random";
5683 break;
5684 case CP0_REG01__VPECONTROL:
5685 CP0_CHECK(ctx->insn_flags & ASE_MT);
5686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5687 register_name = "VPEControl";
5688 break;
5689 case CP0_REG01__VPECONF0:
5690 CP0_CHECK(ctx->insn_flags & ASE_MT);
5691 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5692 register_name = "VPEConf0";
5693 break;
5694 case CP0_REG01__VPECONF1:
5695 CP0_CHECK(ctx->insn_flags & ASE_MT);
5696 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5697 register_name = "VPEConf1";
5698 break;
5699 case CP0_REG01__YQMASK:
5700 CP0_CHECK(ctx->insn_flags & ASE_MT);
5701 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5702 register_name = "YQMask";
5703 break;
5704 case CP0_REG01__VPESCHEDULE:
5705 CP0_CHECK(ctx->insn_flags & ASE_MT);
5706 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5707 register_name = "VPESchedule";
5708 break;
5709 case CP0_REG01__VPESCHEFBACK:
5710 CP0_CHECK(ctx->insn_flags & ASE_MT);
5711 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5712 register_name = "VPEScheFBack";
5713 break;
5714 case CP0_REG01__VPEOPT:
5715 CP0_CHECK(ctx->insn_flags & ASE_MT);
5716 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5717 register_name = "VPEOpt";
5718 break;
5719 default:
5720 goto cp0_unimplemented;
5721 }
5722 break;
5723 case CP0_REGISTER_02:
5724 switch (sel) {
5725 case CP0_REG02__ENTRYLO0:
5726 {
5727 TCGv_i64 tmp = tcg_temp_new_i64();
5728 tcg_gen_ld_i64(tmp, cpu_env,
5729 offsetof(CPUMIPSState, CP0_EntryLo0));
5730 #if defined(TARGET_MIPS64)
5731 if (ctx->rxi) {
5732 /* Move RI/XI fields to bits 31:30 */
5733 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5734 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5735 }
5736 #endif
5737 gen_move_low32(arg, tmp);
5738 tcg_temp_free_i64(tmp);
5739 }
5740 register_name = "EntryLo0";
5741 break;
5742 case CP0_REG02__TCSTATUS:
5743 CP0_CHECK(ctx->insn_flags & ASE_MT);
5744 gen_helper_mfc0_tcstatus(arg, cpu_env);
5745 register_name = "TCStatus";
5746 break;
5747 case CP0_REG02__TCBIND:
5748 CP0_CHECK(ctx->insn_flags & ASE_MT);
5749 gen_helper_mfc0_tcbind(arg, cpu_env);
5750 register_name = "TCBind";
5751 break;
5752 case CP0_REG02__TCRESTART:
5753 CP0_CHECK(ctx->insn_flags & ASE_MT);
5754 gen_helper_mfc0_tcrestart(arg, cpu_env);
5755 register_name = "TCRestart";
5756 break;
5757 case CP0_REG02__TCHALT:
5758 CP0_CHECK(ctx->insn_flags & ASE_MT);
5759 gen_helper_mfc0_tchalt(arg, cpu_env);
5760 register_name = "TCHalt";
5761 break;
5762 case CP0_REG02__TCCONTEXT:
5763 CP0_CHECK(ctx->insn_flags & ASE_MT);
5764 gen_helper_mfc0_tccontext(arg, cpu_env);
5765 register_name = "TCContext";
5766 break;
5767 case CP0_REG02__TCSCHEDULE:
5768 CP0_CHECK(ctx->insn_flags & ASE_MT);
5769 gen_helper_mfc0_tcschedule(arg, cpu_env);
5770 register_name = "TCSchedule";
5771 break;
5772 case CP0_REG02__TCSCHEFBACK:
5773 CP0_CHECK(ctx->insn_flags & ASE_MT);
5774 gen_helper_mfc0_tcschefback(arg, cpu_env);
5775 register_name = "TCScheFBack";
5776 break;
5777 default:
5778 goto cp0_unimplemented;
5779 }
5780 break;
5781 case CP0_REGISTER_03:
5782 switch (sel) {
5783 case CP0_REG03__ENTRYLO1:
5784 {
5785 TCGv_i64 tmp = tcg_temp_new_i64();
5786 tcg_gen_ld_i64(tmp, cpu_env,
5787 offsetof(CPUMIPSState, CP0_EntryLo1));
5788 #if defined(TARGET_MIPS64)
5789 if (ctx->rxi) {
5790 /* Move RI/XI fields to bits 31:30 */
5791 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5792 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5793 }
5794 #endif
5795 gen_move_low32(arg, tmp);
5796 tcg_temp_free_i64(tmp);
5797 }
5798 register_name = "EntryLo1";
5799 break;
5800 case CP0_REG03__GLOBALNUM:
5801 CP0_CHECK(ctx->vp);
5802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5803 register_name = "GlobalNumber";
5804 break;
5805 default:
5806 goto cp0_unimplemented;
5807 }
5808 break;
5809 case CP0_REGISTER_04:
5810 switch (sel) {
5811 case CP0_REG04__CONTEXT:
5812 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5813 tcg_gen_ext32s_tl(arg, arg);
5814 register_name = "Context";
5815 break;
5816 case CP0_REG04__CONTEXTCONFIG:
5817 /* SmartMIPS ASE */
5818 /* gen_helper_mfc0_contextconfig(arg); */
5819 register_name = "ContextConfig";
5820 goto cp0_unimplemented;
5821 case CP0_REG04__USERLOCAL:
5822 CP0_CHECK(ctx->ulri);
5823 tcg_gen_ld_tl(arg, cpu_env,
5824 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5825 tcg_gen_ext32s_tl(arg, arg);
5826 register_name = "UserLocal";
5827 break;
5828 case CP0_REG04__MMID:
5829 CP0_CHECK(ctx->mi);
5830 gen_helper_mtc0_memorymapid(cpu_env, arg);
5831 register_name = "MMID";
5832 break;
5833 default:
5834 goto cp0_unimplemented;
5835 }
5836 break;
5837 case CP0_REGISTER_05:
5838 switch (sel) {
5839 case CP0_REG05__PAGEMASK:
5840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5841 register_name = "PageMask";
5842 break;
5843 case CP0_REG05__PAGEGRAIN:
5844 check_insn(ctx, ISA_MIPS_R2);
5845 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5846 register_name = "PageGrain";
5847 break;
5848 case CP0_REG05__SEGCTL0:
5849 CP0_CHECK(ctx->sc);
5850 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5851 tcg_gen_ext32s_tl(arg, arg);
5852 register_name = "SegCtl0";
5853 break;
5854 case CP0_REG05__SEGCTL1:
5855 CP0_CHECK(ctx->sc);
5856 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5857 tcg_gen_ext32s_tl(arg, arg);
5858 register_name = "SegCtl1";
5859 break;
5860 case CP0_REG05__SEGCTL2:
5861 CP0_CHECK(ctx->sc);
5862 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5863 tcg_gen_ext32s_tl(arg, arg);
5864 register_name = "SegCtl2";
5865 break;
5866 case CP0_REG05__PWBASE:
5867 check_pw(ctx);
5868 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5869 register_name = "PWBase";
5870 break;
5871 case CP0_REG05__PWFIELD:
5872 check_pw(ctx);
5873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5874 register_name = "PWField";
5875 break;
5876 case CP0_REG05__PWSIZE:
5877 check_pw(ctx);
5878 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5879 register_name = "PWSize";
5880 break;
5881 default:
5882 goto cp0_unimplemented;
5883 }
5884 break;
5885 case CP0_REGISTER_06:
5886 switch (sel) {
5887 case CP0_REG06__WIRED:
5888 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5889 register_name = "Wired";
5890 break;
5891 case CP0_REG06__SRSCONF0:
5892 check_insn(ctx, ISA_MIPS_R2);
5893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5894 register_name = "SRSConf0";
5895 break;
5896 case CP0_REG06__SRSCONF1:
5897 check_insn(ctx, ISA_MIPS_R2);
5898 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5899 register_name = "SRSConf1";
5900 break;
5901 case CP0_REG06__SRSCONF2:
5902 check_insn(ctx, ISA_MIPS_R2);
5903 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5904 register_name = "SRSConf2";
5905 break;
5906 case CP0_REG06__SRSCONF3:
5907 check_insn(ctx, ISA_MIPS_R2);
5908 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5909 register_name = "SRSConf3";
5910 break;
5911 case CP0_REG06__SRSCONF4:
5912 check_insn(ctx, ISA_MIPS_R2);
5913 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5914 register_name = "SRSConf4";
5915 break;
5916 case CP0_REG06__PWCTL:
5917 check_pw(ctx);
5918 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5919 register_name = "PWCtl";
5920 break;
5921 default:
5922 goto cp0_unimplemented;
5923 }
5924 break;
5925 case CP0_REGISTER_07:
5926 switch (sel) {
5927 case CP0_REG07__HWRENA:
5928 check_insn(ctx, ISA_MIPS_R2);
5929 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5930 register_name = "HWREna";
5931 break;
5932 default:
5933 goto cp0_unimplemented;
5934 }
5935 break;
5936 case CP0_REGISTER_08:
5937 switch (sel) {
5938 case CP0_REG08__BADVADDR:
5939 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5940 tcg_gen_ext32s_tl(arg, arg);
5941 register_name = "BadVAddr";
5942 break;
5943 case CP0_REG08__BADINSTR:
5944 CP0_CHECK(ctx->bi);
5945 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5946 register_name = "BadInstr";
5947 break;
5948 case CP0_REG08__BADINSTRP:
5949 CP0_CHECK(ctx->bp);
5950 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5951 register_name = "BadInstrP";
5952 break;
5953 case CP0_REG08__BADINSTRX:
5954 CP0_CHECK(ctx->bi);
5955 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5956 tcg_gen_andi_tl(arg, arg, ~0xffff);
5957 register_name = "BadInstrX";
5958 break;
5959 default:
5960 goto cp0_unimplemented;
5961 }
5962 break;
5963 case CP0_REGISTER_09:
5964 switch (sel) {
5965 case CP0_REG09__COUNT:
5966 /* Mark as an IO operation because we read the time. */
5967 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
5968 gen_io_start();
5969 }
5970 gen_helper_mfc0_count(arg, cpu_env);
5971 /*
5972 * Break the TB to be able to take timer interrupts immediately
5973 * after reading count. DISAS_STOP isn't sufficient, we need to
5974 * ensure we break completely out of translated code.
5975 */
5976 gen_save_pc(ctx->base.pc_next + 4);
5977 ctx->base.is_jmp = DISAS_EXIT;
5978 register_name = "Count";
5979 break;
5980 case CP0_REG09__SAARI:
5981 CP0_CHECK(ctx->saar);
5982 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
5983 register_name = "SAARI";
5984 break;
5985 case CP0_REG09__SAAR:
5986 CP0_CHECK(ctx->saar);
5987 gen_helper_mfc0_saar(arg, cpu_env);
5988 register_name = "SAAR";
5989 break;
5990 default:
5991 goto cp0_unimplemented;
5992 }
5993 break;
5994 case CP0_REGISTER_10:
5995 switch (sel) {
5996 case CP0_REG10__ENTRYHI:
5997 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5998 tcg_gen_ext32s_tl(arg, arg);
5999 register_name = "EntryHi";
6000 break;
6001 default:
6002 goto cp0_unimplemented;
6003 }
6004 break;
6005 case CP0_REGISTER_11:
6006 switch (sel) {
6007 case CP0_REG11__COMPARE:
6008 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6009 register_name = "Compare";
6010 break;
6011 /* 6,7 are implementation dependent */
6012 default:
6013 goto cp0_unimplemented;
6014 }
6015 break;
6016 case CP0_REGISTER_12:
6017 switch (sel) {
6018 case CP0_REG12__STATUS:
6019 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6020 register_name = "Status";
6021 break;
6022 case CP0_REG12__INTCTL:
6023 check_insn(ctx, ISA_MIPS_R2);
6024 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6025 register_name = "IntCtl";
6026 break;
6027 case CP0_REG12__SRSCTL:
6028 check_insn(ctx, ISA_MIPS_R2);
6029 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6030 register_name = "SRSCtl";
6031 break;
6032 case CP0_REG12__SRSMAP:
6033 check_insn(ctx, ISA_MIPS_R2);
6034 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6035 register_name = "SRSMap";
6036 break;
6037 default:
6038 goto cp0_unimplemented;
6039 }
6040 break;
6041 case CP0_REGISTER_13:
6042 switch (sel) {
6043 case CP0_REG13__CAUSE:
6044 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6045 register_name = "Cause";
6046 break;
6047 default:
6048 goto cp0_unimplemented;
6049 }
6050 break;
6051 case CP0_REGISTER_14:
6052 switch (sel) {
6053 case CP0_REG14__EPC:
6054 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6055 tcg_gen_ext32s_tl(arg, arg);
6056 register_name = "EPC";
6057 break;
6058 default:
6059 goto cp0_unimplemented;
6060 }
6061 break;
6062 case CP0_REGISTER_15:
6063 switch (sel) {
6064 case CP0_REG15__PRID:
6065 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6066 register_name = "PRid";
6067 break;
6068 case CP0_REG15__EBASE:
6069 check_insn(ctx, ISA_MIPS_R2);
6070 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6071 tcg_gen_ext32s_tl(arg, arg);
6072 register_name = "EBase";
6073 break;
6074 case CP0_REG15__CMGCRBASE:
6075 check_insn(ctx, ISA_MIPS_R2);
6076 CP0_CHECK(ctx->cmgcr);
6077 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6078 tcg_gen_ext32s_tl(arg, arg);
6079 register_name = "CMGCRBase";
6080 break;
6081 default:
6082 goto cp0_unimplemented;
6083 }
6084 break;
6085 case CP0_REGISTER_16:
6086 switch (sel) {
6087 case CP0_REG16__CONFIG:
6088 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6089 register_name = "Config";
6090 break;
6091 case CP0_REG16__CONFIG1:
6092 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6093 register_name = "Config1";
6094 break;
6095 case CP0_REG16__CONFIG2:
6096 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6097 register_name = "Config2";
6098 break;
6099 case CP0_REG16__CONFIG3:
6100 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6101 register_name = "Config3";
6102 break;
6103 case CP0_REG16__CONFIG4:
6104 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6105 register_name = "Config4";
6106 break;
6107 case CP0_REG16__CONFIG5:
6108 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6109 register_name = "Config5";
6110 break;
6111 /* 6,7 are implementation dependent */
6112 case CP0_REG16__CONFIG6:
6113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6114 register_name = "Config6";
6115 break;
6116 case CP0_REG16__CONFIG7:
6117 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6118 register_name = "Config7";
6119 break;
6120 default:
6121 goto cp0_unimplemented;
6122 }
6123 break;
6124 case CP0_REGISTER_17:
6125 switch (sel) {
6126 case CP0_REG17__LLADDR:
6127 gen_helper_mfc0_lladdr(arg, cpu_env);
6128 register_name = "LLAddr";
6129 break;
6130 case CP0_REG17__MAAR:
6131 CP0_CHECK(ctx->mrp);
6132 gen_helper_mfc0_maar(arg, cpu_env);
6133 register_name = "MAAR";
6134 break;
6135 case CP0_REG17__MAARI:
6136 CP0_CHECK(ctx->mrp);
6137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6138 register_name = "MAARI";
6139 break;
6140 default:
6141 goto cp0_unimplemented;
6142 }
6143 break;
6144 case CP0_REGISTER_18:
6145 switch (sel) {
6146 case CP0_REG18__WATCHLO0:
6147 case CP0_REG18__WATCHLO1:
6148 case CP0_REG18__WATCHLO2:
6149 case CP0_REG18__WATCHLO3:
6150 case CP0_REG18__WATCHLO4:
6151 case CP0_REG18__WATCHLO5:
6152 case CP0_REG18__WATCHLO6:
6153 case CP0_REG18__WATCHLO7:
6154 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6155 gen_helper_1e0i(mfc0_watchlo, arg, sel);
6156 register_name = "WatchLo";
6157 break;
6158 default:
6159 goto cp0_unimplemented;
6160 }
6161 break;
6162 case CP0_REGISTER_19:
6163 switch (sel) {
6164 case CP0_REG19__WATCHHI0:
6165 case CP0_REG19__WATCHHI1:
6166 case CP0_REG19__WATCHHI2:
6167 case CP0_REG19__WATCHHI3:
6168 case CP0_REG19__WATCHHI4:
6169 case CP0_REG19__WATCHHI5:
6170 case CP0_REG19__WATCHHI6:
6171 case CP0_REG19__WATCHHI7:
6172 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6173 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6174 register_name = "WatchHi";
6175 break;
6176 default:
6177 goto cp0_unimplemented;
6178 }
6179 break;
6180 case CP0_REGISTER_20:
6181 switch (sel) {
6182 case CP0_REG20__XCONTEXT:
6183 #if defined(TARGET_MIPS64)
6184 check_insn(ctx, ISA_MIPS3);
6185 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6186 tcg_gen_ext32s_tl(arg, arg);
6187 register_name = "XContext";
6188 break;
6189 #endif
6190 default:
6191 goto cp0_unimplemented;
6192 }
6193 break;
6194 case CP0_REGISTER_21:
6195 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6196 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6197 switch (sel) {
6198 case 0:
6199 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6200 register_name = "Framemask";
6201 break;
6202 default:
6203 goto cp0_unimplemented;
6204 }
6205 break;
6206 case CP0_REGISTER_22:
6207 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6208 register_name = "'Diagnostic"; /* implementation dependent */
6209 break;
6210 case CP0_REGISTER_23:
6211 switch (sel) {
6212 case CP0_REG23__DEBUG:
6213 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6214 register_name = "Debug";
6215 break;
6216 case CP0_REG23__TRACECONTROL:
6217 /* PDtrace support */
6218 /* gen_helper_mfc0_tracecontrol(arg); */
6219 register_name = "TraceControl";
6220 goto cp0_unimplemented;
6221 case CP0_REG23__TRACECONTROL2:
6222 /* PDtrace support */
6223 /* gen_helper_mfc0_tracecontrol2(arg); */
6224 register_name = "TraceControl2";
6225 goto cp0_unimplemented;
6226 case CP0_REG23__USERTRACEDATA1:
6227 /* PDtrace support */
6228 /* gen_helper_mfc0_usertracedata1(arg);*/
6229 register_name = "UserTraceData1";
6230 goto cp0_unimplemented;
6231 case CP0_REG23__TRACEIBPC:
6232 /* PDtrace support */
6233 /* gen_helper_mfc0_traceibpc(arg); */
6234 register_name = "TraceIBPC";
6235 goto cp0_unimplemented;
6236 case CP0_REG23__TRACEDBPC:
6237 /* PDtrace support */
6238 /* gen_helper_mfc0_tracedbpc(arg); */
6239 register_name = "TraceDBPC";
6240 goto cp0_unimplemented;
6241 default:
6242 goto cp0_unimplemented;
6243 }
6244 break;
6245 case CP0_REGISTER_24:
6246 switch (sel) {
6247 case CP0_REG24__DEPC:
6248 /* EJTAG support */
6249 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6250 tcg_gen_ext32s_tl(arg, arg);
6251 register_name = "DEPC";
6252 break;
6253 default:
6254 goto cp0_unimplemented;
6255 }
6256 break;
6257 case CP0_REGISTER_25:
6258 switch (sel) {
6259 case CP0_REG25__PERFCTL0:
6260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6261 register_name = "Performance0";
6262 break;
6263 case CP0_REG25__PERFCNT0:
6264 /* gen_helper_mfc0_performance1(arg); */
6265 register_name = "Performance1";
6266 goto cp0_unimplemented;
6267 case CP0_REG25__PERFCTL1:
6268 /* gen_helper_mfc0_performance2(arg); */
6269 register_name = "Performance2";
6270 goto cp0_unimplemented;
6271 case CP0_REG25__PERFCNT1:
6272 /* gen_helper_mfc0_performance3(arg); */
6273 register_name = "Performance3";
6274 goto cp0_unimplemented;
6275 case CP0_REG25__PERFCTL2:
6276 /* gen_helper_mfc0_performance4(arg); */
6277 register_name = "Performance4";
6278 goto cp0_unimplemented;
6279 case CP0_REG25__PERFCNT2:
6280 /* gen_helper_mfc0_performance5(arg); */
6281 register_name = "Performance5";
6282 goto cp0_unimplemented;
6283 case CP0_REG25__PERFCTL3:
6284 /* gen_helper_mfc0_performance6(arg); */
6285 register_name = "Performance6";
6286 goto cp0_unimplemented;
6287 case CP0_REG25__PERFCNT3:
6288 /* gen_helper_mfc0_performance7(arg); */
6289 register_name = "Performance7";
6290 goto cp0_unimplemented;
6291 default:
6292 goto cp0_unimplemented;
6293 }
6294 break;
6295 case CP0_REGISTER_26:
6296 switch (sel) {
6297 case CP0_REG26__ERRCTL:
6298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6299 register_name = "ErrCtl";
6300 break;
6301 default:
6302 goto cp0_unimplemented;
6303 }
6304 break;
6305 case CP0_REGISTER_27:
6306 switch (sel) {
6307 case CP0_REG27__CACHERR:
6308 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6309 register_name = "CacheErr";
6310 break;
6311 default:
6312 goto cp0_unimplemented;
6313 }
6314 break;
6315 case CP0_REGISTER_28:
6316 switch (sel) {
6317 case CP0_REG28__TAGLO:
6318 case CP0_REG28__TAGLO1:
6319 case CP0_REG28__TAGLO2:
6320 case CP0_REG28__TAGLO3:
6321 {
6322 TCGv_i64 tmp = tcg_temp_new_i64();
6323 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6324 gen_move_low32(arg, tmp);
6325 tcg_temp_free_i64(tmp);
6326 }
6327 register_name = "TagLo";
6328 break;
6329 case CP0_REG28__DATALO:
6330 case CP0_REG28__DATALO1:
6331 case CP0_REG28__DATALO2:
6332 case CP0_REG28__DATALO3:
6333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6334 register_name = "DataLo";
6335 break;
6336 default:
6337 goto cp0_unimplemented;
6338 }
6339 break;
6340 case CP0_REGISTER_29:
6341 switch (sel) {
6342 case CP0_REG29__TAGHI:
6343 case CP0_REG29__TAGHI1:
6344 case CP0_REG29__TAGHI2:
6345 case CP0_REG29__TAGHI3:
6346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6347 register_name = "TagHi";
6348 break;
6349 case CP0_REG29__DATAHI:
6350 case CP0_REG29__DATAHI1:
6351 case CP0_REG29__DATAHI2:
6352 case CP0_REG29__DATAHI3:
6353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6354 register_name = "DataHi";
6355 break;
6356 default:
6357 goto cp0_unimplemented;
6358 }
6359 break;
6360 case CP0_REGISTER_30:
6361 switch (sel) {
6362 case CP0_REG30__ERROREPC:
6363 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6364 tcg_gen_ext32s_tl(arg, arg);
6365 register_name = "ErrorEPC";
6366 break;
6367 default:
6368 goto cp0_unimplemented;
6369 }
6370 break;
6371 case CP0_REGISTER_31:
6372 switch (sel) {
6373 case CP0_REG31__DESAVE:
6374 /* EJTAG support */
6375 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6376 register_name = "DESAVE";
6377 break;
6378 case CP0_REG31__KSCRATCH1:
6379 case CP0_REG31__KSCRATCH2:
6380 case CP0_REG31__KSCRATCH3:
6381 case CP0_REG31__KSCRATCH4:
6382 case CP0_REG31__KSCRATCH5:
6383 case CP0_REG31__KSCRATCH6:
6384 CP0_CHECK(ctx->kscrexist & (1 << sel));
6385 tcg_gen_ld_tl(arg, cpu_env,
6386 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6387 tcg_gen_ext32s_tl(arg, arg);
6388 register_name = "KScratch";
6389 break;
6390 default:
6391 goto cp0_unimplemented;
6392 }
6393 break;
6394 default:
6395 goto cp0_unimplemented;
6396 }
6397 trace_mips_translate_c0("mfc0", register_name, reg, sel);
6398 return;
6399
6400 cp0_unimplemented:
6401 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6402 register_name, reg, sel);
6403 gen_mfc0_unimplemented(ctx, arg);
6404 }
6405
6406 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6407 {
6408 const char *register_name = "invalid";
6409
6410 if (sel != 0) {
6411 check_insn(ctx, ISA_MIPS_R1);
6412 }
6413
6414 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6415 gen_io_start();
6416 }
6417
6418 switch (reg) {
6419 case CP0_REGISTER_00:
6420 switch (sel) {
6421 case CP0_REG00__INDEX:
6422 gen_helper_mtc0_index(cpu_env, arg);
6423 register_name = "Index";
6424 break;
6425 case CP0_REG00__MVPCONTROL:
6426 CP0_CHECK(ctx->insn_flags & ASE_MT);
6427 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6428 register_name = "MVPControl";
6429 break;
6430 case CP0_REG00__MVPCONF0:
6431 CP0_CHECK(ctx->insn_flags & ASE_MT);
6432 /* ignored */
6433 register_name = "MVPConf0";
6434 break;
6435 case CP0_REG00__MVPCONF1:
6436 CP0_CHECK(ctx->insn_flags & ASE_MT);
6437 /* ignored */
6438 register_name = "MVPConf1";
6439 break;
6440 case CP0_REG00__VPCONTROL:
6441 CP0_CHECK(ctx->vp);
6442 /* ignored */
6443 register_name = "VPControl";
6444 break;
6445 default:
6446 goto cp0_unimplemented;
6447 }
6448 break;
6449 case CP0_REGISTER_01:
6450 switch (sel) {
6451 case CP0_REG01__RANDOM:
6452 /* ignored */
6453 register_name = "Random";
6454 break;
6455 case CP0_REG01__VPECONTROL:
6456 CP0_CHECK(ctx->insn_flags & ASE_MT);
6457 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6458 register_name = "VPEControl";
6459 break;
6460 case CP0_REG01__VPECONF0:
6461 CP0_CHECK(ctx->insn_flags & ASE_MT);
6462 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6463 register_name = "VPEConf0";
6464 break;
6465 case CP0_REG01__VPECONF1:
6466 CP0_CHECK(ctx->insn_flags & ASE_MT);
6467 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6468 register_name = "VPEConf1";
6469 break;
6470 case CP0_REG01__YQMASK:
6471 CP0_CHECK(ctx->insn_flags & ASE_MT);
6472 gen_helper_mtc0_yqmask(cpu_env, arg);
6473 register_name = "YQMask";
6474 break;
6475 case CP0_REG01__VPESCHEDULE:
6476 CP0_CHECK(ctx->insn_flags & ASE_MT);
6477 tcg_gen_st_tl(arg, cpu_env,
6478 offsetof(CPUMIPSState, CP0_VPESchedule));
6479 register_name = "VPESchedule";
6480 break;
6481 case CP0_REG01__VPESCHEFBACK:
6482 CP0_CHECK(ctx->insn_flags & ASE_MT);
6483 tcg_gen_st_tl(arg, cpu_env,
6484 offsetof(CPUMIPSState, CP0_VPEScheFBack));
6485 register_name = "VPEScheFBack";
6486 break;
6487 case CP0_REG01__VPEOPT:
6488 CP0_CHECK(ctx->insn_flags & ASE_MT);
6489 gen_helper_mtc0_vpeopt(cpu_env, arg);
6490 register_name = "VPEOpt";
6491 break;
6492 default:
6493 goto cp0_unimplemented;
6494 }
6495 break;
6496 case CP0_REGISTER_02:
6497 switch (sel) {
6498 case CP0_REG02__ENTRYLO0:
6499 gen_helper_mtc0_entrylo0(cpu_env, arg);
6500 register_name = "EntryLo0";
6501 break;
6502 case CP0_REG02__TCSTATUS:
6503 CP0_CHECK(ctx->insn_flags & ASE_MT);
6504 gen_helper_mtc0_tcstatus(cpu_env, arg);
6505 register_name = "TCStatus";
6506 break;
6507 case CP0_REG02__TCBIND:
6508 CP0_CHECK(ctx->insn_flags & ASE_MT);
6509 gen_helper_mtc0_tcbind(cpu_env, arg);
6510 register_name = "TCBind";
6511 break;
6512 case CP0_REG02__TCRESTART:
6513 CP0_CHECK(ctx->insn_flags & ASE_MT);
6514 gen_helper_mtc0_tcrestart(cpu_env, arg);
6515 register_name = "TCRestart";
6516 break;
6517 case CP0_REG02__TCHALT:
6518 CP0_CHECK(ctx->insn_flags & ASE_MT);
6519 gen_helper_mtc0_tchalt(cpu_env, arg);
6520 register_name = "TCHalt";
6521 break;
6522 case CP0_REG02__TCCONTEXT:
6523 CP0_CHECK(ctx->insn_flags & ASE_MT);
6524 gen_helper_mtc0_tccontext(cpu_env, arg);
6525 register_name = "TCContext";
6526 break;
6527 case CP0_REG02__TCSCHEDULE:
6528 CP0_CHECK(ctx->insn_flags & ASE_MT);
6529 gen_helper_mtc0_tcschedule(cpu_env, arg);
6530 register_name = "TCSchedule";
6531 break;
6532 case CP0_REG02__TCSCHEFBACK:
6533 CP0_CHECK(ctx->insn_flags & ASE_MT);
6534 gen_helper_mtc0_tcschefback(cpu_env, arg);
6535 register_name = "TCScheFBack";
6536 break;
6537 default:
6538 goto cp0_unimplemented;
6539 }
6540 break;
6541 case CP0_REGISTER_03:
6542 switch (sel) {
6543 case CP0_REG03__ENTRYLO1:
6544 gen_helper_mtc0_entrylo1(cpu_env, arg);
6545 register_name = "EntryLo1";
6546 break;
6547 case CP0_REG03__GLOBALNUM:
6548 CP0_CHECK(ctx->vp);
6549 /* ignored */
6550 register_name = "GlobalNumber";
6551 break;
6552 default:
6553 goto cp0_unimplemented;
6554 }
6555 break;
6556 case CP0_REGISTER_04:
6557 switch (sel) {
6558 case CP0_REG04__CONTEXT:
6559 gen_helper_mtc0_context(cpu_env, arg);
6560 register_name = "Context";
6561 break;
6562 case CP0_REG04__CONTEXTCONFIG:
6563 /* SmartMIPS ASE */
6564 /* gen_helper_mtc0_contextconfig(arg); */
6565 register_name = "ContextConfig";
6566 goto cp0_unimplemented;
6567 case CP0_REG04__USERLOCAL:
6568 CP0_CHECK(ctx->ulri);
6569 tcg_gen_st_tl(arg, cpu_env,
6570 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6571 register_name = "UserLocal";
6572 break;
6573 case CP0_REG04__MMID:
6574 CP0_CHECK(ctx->mi);
6575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6576 register_name = "MMID";
6577 break;
6578 default:
6579 goto cp0_unimplemented;
6580 }
6581 break;
6582 case CP0_REGISTER_05:
6583 switch (sel) {
6584 case CP0_REG05__PAGEMASK:
6585 gen_helper_mtc0_pagemask(cpu_env, arg);
6586 register_name = "PageMask";
6587 break;
6588 case CP0_REG05__PAGEGRAIN:
6589 check_insn(ctx, ISA_MIPS_R2);
6590 gen_helper_mtc0_pagegrain(cpu_env, arg);
6591 register_name = "PageGrain";
6592 ctx->base.is_jmp = DISAS_STOP;
6593 break;
6594 case CP0_REG05__SEGCTL0:
6595 CP0_CHECK(ctx->sc);
6596 gen_helper_mtc0_segctl0(cpu_env, arg);
6597 register_name = "SegCtl0";
6598 break;
6599 case CP0_REG05__SEGCTL1:
6600 CP0_CHECK(ctx->sc);
6601 gen_helper_mtc0_segctl1(cpu_env, arg);
6602 register_name = "SegCtl1";
6603 break;
6604 case CP0_REG05__SEGCTL2:
6605 CP0_CHECK(ctx->sc);
6606 gen_helper_mtc0_segctl2(cpu_env, arg);
6607 register_name = "SegCtl2";
6608 break;
6609 case CP0_REG05__PWBASE:
6610 check_pw(ctx);
6611 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6612 register_name = "PWBase";
6613 break;
6614 case CP0_REG05__PWFIELD:
6615 check_pw(ctx);
6616 gen_helper_mtc0_pwfield(cpu_env, arg);
6617 register_name = "PWField";
6618 break;
6619 case CP0_REG05__PWSIZE:
6620 check_pw(ctx);
6621 gen_helper_mtc0_pwsize(cpu_env, arg);
6622 register_name = "PWSize";
6623 break;
6624 default:
6625 goto cp0_unimplemented;
6626 }
6627 break;
6628 case CP0_REGISTER_06:
6629 switch (sel) {
6630 case CP0_REG06__WIRED:
6631 gen_helper_mtc0_wired(cpu_env, arg);
6632 register_name = "Wired";
6633 break;
6634 case CP0_REG06__SRSCONF0:
6635 check_insn(ctx, ISA_MIPS_R2);
6636 gen_helper_mtc0_srsconf0(cpu_env, arg);
6637 register_name = "SRSConf0";
6638 break;
6639 case CP0_REG06__SRSCONF1:
6640 check_insn(ctx, ISA_MIPS_R2);
6641 gen_helper_mtc0_srsconf1(cpu_env, arg);
6642 register_name = "SRSConf1";
6643 break;
6644 case CP0_REG06__SRSCONF2:
6645 check_insn(ctx, ISA_MIPS_R2);
6646 gen_helper_mtc0_srsconf2(cpu_env, arg);
6647 register_name = "SRSConf2";
6648 break;
6649 case CP0_REG06__SRSCONF3:
6650 check_insn(ctx, ISA_MIPS_R2);
6651 gen_helper_mtc0_srsconf3(cpu_env, arg);
6652 register_name = "SRSConf3";
6653 break;
6654 case CP0_REG06__SRSCONF4:
6655 check_insn(ctx, ISA_MIPS_R2);
6656 gen_helper_mtc0_srsconf4(cpu_env, arg);
6657 register_name = "SRSConf4";
6658 break;
6659 case CP0_REG06__PWCTL:
6660 check_pw(ctx);
6661 gen_helper_mtc0_pwctl(cpu_env, arg);
6662 register_name = "PWCtl";
6663 break;
6664 default:
6665 goto cp0_unimplemented;
6666 }
6667 break;
6668 case CP0_REGISTER_07:
6669 switch (sel) {
6670 case CP0_REG07__HWRENA:
6671 check_insn(ctx, ISA_MIPS_R2);
6672 gen_helper_mtc0_hwrena(cpu_env, arg);
6673 ctx->base.is_jmp = DISAS_STOP;
6674 register_name = "HWREna";
6675 break;
6676 default:
6677 goto cp0_unimplemented;
6678 }
6679 break;
6680 case CP0_REGISTER_08:
6681 switch (sel) {
6682 case CP0_REG08__BADVADDR:
6683 /* ignored */
6684 register_name = "BadVAddr";
6685 break;
6686 case CP0_REG08__BADINSTR:
6687 /* ignored */
6688 register_name = "BadInstr";
6689 break;
6690 case CP0_REG08__BADINSTRP:
6691 /* ignored */
6692 register_name = "BadInstrP";
6693 break;
6694 case CP0_REG08__BADINSTRX:
6695 /* ignored */
6696 register_name = "BadInstrX";
6697 break;
6698 default:
6699 goto cp0_unimplemented;
6700 }
6701 break;
6702 case CP0_REGISTER_09:
6703 switch (sel) {
6704 case CP0_REG09__COUNT:
6705 gen_helper_mtc0_count(cpu_env, arg);
6706 register_name = "Count";
6707 break;
6708 case CP0_REG09__SAARI:
6709 CP0_CHECK(ctx->saar);
6710 gen_helper_mtc0_saari(cpu_env, arg);
6711 register_name = "SAARI";
6712 break;
6713 case CP0_REG09__SAAR:
6714 CP0_CHECK(ctx->saar);
6715 gen_helper_mtc0_saar(cpu_env, arg);
6716 register_name = "SAAR";
6717 break;
6718 default:
6719 goto cp0_unimplemented;
6720 }
6721 break;
6722 case CP0_REGISTER_10:
6723 switch (sel) {
6724 case CP0_REG10__ENTRYHI:
6725 gen_helper_mtc0_entryhi(cpu_env, arg);
6726 register_name = "EntryHi";
6727 break;
6728 default:
6729 goto cp0_unimplemented;
6730 }
6731 break;
6732 case CP0_REGISTER_11:
6733 switch (sel) {
6734 case CP0_REG11__COMPARE:
6735 gen_helper_mtc0_compare(cpu_env, arg);
6736 register_name = "Compare";
6737 break;
6738 /* 6,7 are implementation dependent */
6739 default:
6740 goto cp0_unimplemented;
6741 }
6742 break;
6743 case CP0_REGISTER_12:
6744 switch (sel) {
6745 case CP0_REG12__STATUS:
6746 save_cpu_state(ctx, 1);
6747 gen_helper_mtc0_status(cpu_env, arg);
6748 /* DISAS_STOP isn't good enough here, hflags may have changed. */
6749 gen_save_pc(ctx->base.pc_next + 4);
6750 ctx->base.is_jmp = DISAS_EXIT;
6751 register_name = "Status";
6752 break;
6753 case CP0_REG12__INTCTL:
6754 check_insn(ctx, ISA_MIPS_R2);
6755 gen_helper_mtc0_intctl(cpu_env, arg);
6756 /* Stop translation as we may have switched the execution mode */
6757 ctx->base.is_jmp = DISAS_STOP;
6758 register_name = "IntCtl";
6759 break;
6760 case CP0_REG12__SRSCTL:
6761 check_insn(ctx, ISA_MIPS_R2);
6762 gen_helper_mtc0_srsctl(cpu_env, arg);
6763 /* Stop translation as we may have switched the execution mode */
6764 ctx->base.is_jmp = DISAS_STOP;
6765 register_name = "SRSCtl";
6766 break;
6767 case CP0_REG12__SRSMAP:
6768 check_insn(ctx, ISA_MIPS_R2);
6769 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6770 /* Stop translation as we may have switched the execution mode */
6771 ctx->base.is_jmp = DISAS_STOP;
6772 register_name = "SRSMap";
6773 break;
6774 default:
6775 goto cp0_unimplemented;
6776 }
6777 break;
6778 case CP0_REGISTER_13:
6779 switch (sel) {
6780 case CP0_REG13__CAUSE:
6781 save_cpu_state(ctx, 1);
6782 gen_helper_mtc0_cause(cpu_env, arg);
6783 /*
6784 * Stop translation as we may have triggered an interrupt.
6785 * DISAS_STOP isn't sufficient, we need to ensure we break out of
6786 * translated code to check for pending interrupts.
6787 */
6788 gen_save_pc(ctx->base.pc_next + 4);
6789 ctx->base.is_jmp = DISAS_EXIT;
6790 register_name = "Cause";
6791 break;
6792 default:
6793 goto cp0_unimplemented;
6794 }
6795 break;
6796 case CP0_REGISTER_14:
6797 switch (sel) {
6798 case CP0_REG14__EPC:
6799 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6800 register_name = "EPC";
6801 break;
6802 default:
6803 goto cp0_unimplemented;
6804 }
6805 break;
6806 case CP0_REGISTER_15:
6807 switch (sel) {
6808 case CP0_REG15__PRID:
6809 /* ignored */
6810 register_name = "PRid";
6811 break;
6812 case CP0_REG15__EBASE:
6813 check_insn(ctx, ISA_MIPS_R2);
6814 gen_helper_mtc0_ebase(cpu_env, arg);
6815 register_name = "EBase";
6816 break;
6817 default:
6818 goto cp0_unimplemented;
6819 }
6820 break;
6821 case CP0_REGISTER_16:
6822 switch (sel) {
6823 case CP0_REG16__CONFIG:
6824 gen_helper_mtc0_config0(cpu_env, arg);
6825 register_name = "Config";
6826 /* Stop translation as we may have switched the execution mode */
6827 ctx->base.is_jmp = DISAS_STOP;
6828 break;
6829 case CP0_REG16__CONFIG1:
6830 /* ignored, read only */
6831 register_name = "Config1";
6832 break;
6833 case CP0_REG16__CONFIG2:
6834 gen_helper_mtc0_config2(cpu_env, arg);
6835 register_name = "Config2";
6836 /* Stop translation as we may have switched the execution mode */
6837 ctx->base.is_jmp = DISAS_STOP;
6838 break;
6839 case CP0_REG16__CONFIG3:
6840 gen_helper_mtc0_config3(cpu_env, arg);
6841 register_name = "Config3";
6842 /* Stop translation as we may have switched the execution mode */
6843 ctx->base.is_jmp = DISAS_STOP;
6844 break;
6845 case CP0_REG16__CONFIG4:
6846 gen_helper_mtc0_config4(cpu_env, arg);
6847 register_name = "Config4";
6848 ctx->base.is_jmp = DISAS_STOP;
6849 break;
6850 case CP0_REG16__CONFIG5:
6851 gen_helper_mtc0_config5(cpu_env, arg);
6852 register_name = "Config5";
6853 /* Stop translation as we may have switched the execution mode */
6854 ctx->base.is_jmp = DISAS_STOP;
6855 break;
6856 /* 6,7 are implementation dependent */
6857 case CP0_REG16__CONFIG6:
6858 /* ignored */
6859 register_name = "Config6";
6860 break;
6861 case CP0_REG16__CONFIG7:
6862 /* ignored */
6863 register_name = "Config7";
6864 break;
6865 default:
6866 register_name = "Invalid config selector";
6867 goto cp0_unimplemented;
6868 }
6869 break;
6870 case CP0_REGISTER_17:
6871 switch (sel) {
6872 case CP0_REG17__LLADDR:
6873 gen_helper_mtc0_lladdr(cpu_env, arg);
6874 register_name = "LLAddr";
6875 break;
6876 case CP0_REG17__MAAR:
6877 CP0_CHECK(ctx->mrp);
6878 gen_helper_mtc0_maar(cpu_env, arg);
6879 register_name = "MAAR";
6880 break;
6881 case CP0_REG17__MAARI:
6882 CP0_CHECK(ctx->mrp);
6883 gen_helper_mtc0_maari(cpu_env, arg);
6884 register_name = "MAARI";
6885 break;
6886 default:
6887 goto cp0_unimplemented;
6888 }
6889 break;
6890 case CP0_REGISTER_18:
6891 switch (sel) {
6892 case CP0_REG18__WATCHLO0:
6893 case CP0_REG18__WATCHLO1:
6894 case CP0_REG18__WATCHLO2:
6895 case CP0_REG18__WATCHLO3:
6896 case CP0_REG18__WATCHLO4:
6897 case CP0_REG18__WATCHLO5:
6898 case CP0_REG18__WATCHLO6:
6899 case CP0_REG18__WATCHLO7:
6900 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6901 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6902 register_name = "WatchLo";
6903 break;
6904 default:
6905 goto cp0_unimplemented;
6906 }
6907 break;
6908 case CP0_REGISTER_19:
6909 switch (sel) {
6910 case CP0_REG19__WATCHHI0:
6911 case CP0_REG19__WATCHHI1:
6912 case CP0_REG19__WATCHHI2:
6913 case CP0_REG19__WATCHHI3:
6914 case CP0_REG19__WATCHHI4:
6915 case CP0_REG19__WATCHHI5:
6916 case CP0_REG19__WATCHHI6:
6917 case CP0_REG19__WATCHHI7:
6918 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6919 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6920 register_name = "WatchHi";
6921 break;
6922 default:
6923 goto cp0_unimplemented;
6924 }
6925 break;
6926 case CP0_REGISTER_20:
6927 switch (sel) {
6928 case CP0_REG20__XCONTEXT:
6929 #if defined(TARGET_MIPS64)
6930 check_insn(ctx, ISA_MIPS3);
6931 gen_helper_mtc0_xcontext(cpu_env, arg);
6932 register_name = "XContext";
6933 break;
6934 #endif
6935 default:
6936 goto cp0_unimplemented;
6937 }
6938 break;
6939 case CP0_REGISTER_21:
6940 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6941 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6942 switch (sel) {
6943 case 0:
6944 gen_helper_mtc0_framemask(cpu_env, arg);
6945 register_name = "Framemask";
6946 break;
6947 default:
6948 goto cp0_unimplemented;
6949 }
6950 break;
6951 case CP0_REGISTER_22:
6952 /* ignored */
6953 register_name = "Diagnostic"; /* implementation dependent */
6954 break;
6955 case CP0_REGISTER_23:
6956 switch (sel) {
6957 case CP0_REG23__DEBUG:
6958 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6959 /* DISAS_STOP isn't good enough here, hflags may have changed. */
6960 gen_save_pc(ctx->base.pc_next + 4);
6961 ctx->base.is_jmp = DISAS_EXIT;
6962 register_name = "Debug";
6963 break;
6964 case CP0_REG23__TRACECONTROL:
6965 /* PDtrace support */
6966 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
6967 register_name = "TraceControl";
6968 /* Stop translation as we may have switched the execution mode */
6969 ctx->base.is_jmp = DISAS_STOP;
6970 goto cp0_unimplemented;
6971 case CP0_REG23__TRACECONTROL2:
6972 /* PDtrace support */
6973 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
6974 register_name = "TraceControl2";
6975 /* Stop translation as we may have switched the execution mode */
6976 ctx->base.is_jmp = DISAS_STOP;
6977 goto cp0_unimplemented;
6978 case CP0_REG23__USERTRACEDATA1:
6979 /* Stop translation as we may have switched the execution mode */
6980 ctx->base.is_jmp = DISAS_STOP;
6981 /* PDtrace support */
6982 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
6983 register_name = "UserTraceData";
6984 /* Stop translation as we may have switched the execution mode */
6985 ctx->base.is_jmp = DISAS_STOP;
6986 goto cp0_unimplemented;
6987 case CP0_REG23__TRACEIBPC:
6988 /* PDtrace support */
6989 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
6990 /* Stop translation as we may have switched the execution mode */
6991 ctx->base.is_jmp = DISAS_STOP;
6992 register_name = "TraceIBPC";
6993 goto cp0_unimplemented;
6994 case CP0_REG23__TRACEDBPC:
6995 /* PDtrace support */
6996 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
6997 /* Stop translation as we may have switched the execution mode */
6998 ctx->base.is_jmp = DISAS_STOP;
6999 register_name = "TraceDBPC";
7000 goto cp0_unimplemented;
7001 default:
7002 goto cp0_unimplemented;
7003 }
7004 break;
7005 case CP0_REGISTER_24:
7006 switch (sel) {
7007 case CP0_REG24__DEPC:
7008 /* EJTAG support */
7009 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7010 register_name = "DEPC";
7011 break;
7012 default:
7013 goto cp0_unimplemented;
7014 }
7015 break;
7016 case CP0_REGISTER_25:
7017 switch (sel) {
7018 case CP0_REG25__PERFCTL0:
7019 gen_helper_mtc0_performance0(cpu_env, arg);
7020 register_name = "Performance0";
7021 break;
7022 case CP0_REG25__PERFCNT0:
7023 /* gen_helper_mtc0_performance1(arg); */
7024 register_name = "Performance1";
7025 goto cp0_unimplemented;
7026 case CP0_REG25__PERFCTL1:
7027 /* gen_helper_mtc0_performance2(arg); */
7028 register_name = "Performance2";
7029 goto cp0_unimplemented;
7030 case CP0_REG25__PERFCNT1:
7031 /* gen_helper_mtc0_performance3(arg); */
7032 register_name = "Performance3";
7033 goto cp0_unimplemented;
7034 case CP0_REG25__PERFCTL2:
7035 /* gen_helper_mtc0_performance4(arg); */
7036 register_name = "Performance4";
7037 goto cp0_unimplemented;
7038 case CP0_REG25__PERFCNT2:
7039 /* gen_helper_mtc0_performance5(arg); */
7040 register_name = "Performance5";
7041 goto cp0_unimplemented;
7042 case CP0_REG25__PERFCTL3:
7043 /* gen_helper_mtc0_performance6(arg); */
7044 register_name = "Performance6";
7045 goto cp0_unimplemented;
7046 case CP0_REG25__PERFCNT3:
7047 /* gen_helper_mtc0_performance7(arg); */
7048 register_name = "Performance7";
7049 goto cp0_unimplemented;
7050 default:
7051 goto cp0_unimplemented;
7052 }
7053 break;
7054 case CP0_REGISTER_26:
7055 switch (sel) {
7056 case CP0_REG26__ERRCTL:
7057 gen_helper_mtc0_errctl(cpu_env, arg);
7058 ctx->base.is_jmp = DISAS_STOP;
7059 register_name = "ErrCtl";
7060 break;
7061 default:
7062 goto cp0_unimplemented;
7063 }
7064 break;
7065 case CP0_REGISTER_27:
7066 switch (sel) {
7067 case CP0_REG27__CACHERR:
7068 /* ignored */
7069 register_name = "CacheErr";
7070 break;
7071 default:
7072 goto cp0_unimplemented;
7073 }
7074 break;
7075 case CP0_REGISTER_28:
7076 switch (sel) {
7077 case CP0_REG28__TAGLO:
7078 case CP0_REG28__TAGLO1:
7079 case CP0_REG28__TAGLO2:
7080 case CP0_REG28__TAGLO3:
7081 gen_helper_mtc0_taglo(cpu_env, arg);
7082 register_name = "TagLo";
7083 break;
7084 case CP0_REG28__DATALO:
7085 case CP0_REG28__DATALO1:
7086 case CP0_REG28__DATALO2:
7087 case CP0_REG28__DATALO3:
7088 gen_helper_mtc0_datalo(cpu_env, arg);
7089 register_name = "DataLo";
7090 break;
7091 default:
7092 goto cp0_unimplemented;
7093 }
7094 break;
7095 case CP0_REGISTER_29:
7096 switch (sel) {
7097 case CP0_REG29__TAGHI:
7098 case CP0_REG29__TAGHI1:
7099 case CP0_REG29__TAGHI2:
7100 case CP0_REG29__TAGHI3:
7101 gen_helper_mtc0_taghi(cpu_env, arg);
7102 register_name = "TagHi";
7103 break;
7104 case CP0_REG29__DATAHI:
7105 case CP0_REG29__DATAHI1:
7106 case CP0_REG29__DATAHI2:
7107 case CP0_REG29__DATAHI3:
7108 gen_helper_mtc0_datahi(cpu_env, arg);
7109 register_name = "DataHi";
7110 break;
7111 default:
7112 register_name = "invalid sel";
7113 goto cp0_unimplemented;
7114 }
7115 break;
7116 case CP0_REGISTER_30:
7117 switch (sel) {
7118 case CP0_REG30__ERROREPC:
7119 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7120 register_name = "ErrorEPC";
7121 break;
7122 default:
7123 goto cp0_unimplemented;
7124 }
7125 break;
7126 case CP0_REGISTER_31:
7127 switch (sel) {
7128 case CP0_REG31__DESAVE:
7129 /* EJTAG support */
7130 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7131 register_name = "DESAVE";
7132 break;
7133 case CP0_REG31__KSCRATCH1:
7134 case CP0_REG31__KSCRATCH2:
7135 case CP0_REG31__KSCRATCH3:
7136 case CP0_REG31__KSCRATCH4:
7137 case CP0_REG31__KSCRATCH5:
7138 case CP0_REG31__KSCRATCH6:
7139 CP0_CHECK(ctx->kscrexist & (1 << sel));
7140 tcg_gen_st_tl(arg, cpu_env,
7141 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7142 register_name = "KScratch";
7143 break;
7144 default:
7145 goto cp0_unimplemented;
7146 }
7147 break;
7148 default:
7149 goto cp0_unimplemented;
7150 }
7151 trace_mips_translate_c0("mtc0", register_name, reg, sel);
7152
7153 /* For simplicity assume that all writes can cause interrupts. */
7154 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7155 /*
7156 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7157 * translated code to check for pending interrupts.
7158 */
7159 gen_save_pc(ctx->base.pc_next + 4);
7160 ctx->base.is_jmp = DISAS_EXIT;
7161 }
7162 return;
7163
7164 cp0_unimplemented:
7165 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
7166 register_name, reg, sel);
7167 }
7168
7169 #if defined(TARGET_MIPS64)
7170 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7171 {
7172 const char *register_name = "invalid";
7173
7174 if (sel != 0) {
7175 check_insn(ctx, ISA_MIPS_R1);
7176 }
7177
7178 switch (reg) {
7179 case CP0_REGISTER_00:
7180 switch (sel) {
7181 case CP0_REG00__INDEX:
7182 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7183 register_name = "Index";
7184 break;
7185 case CP0_REG00__MVPCONTROL:
7186 CP0_CHECK(ctx->insn_flags & ASE_MT);
7187 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7188 register_name = "MVPControl";
7189 break;
7190 case CP0_REG00__MVPCONF0:
7191 CP0_CHECK(ctx->insn_flags & ASE_MT);
7192 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7193 register_name = "MVPConf0";
7194 break;
7195 case CP0_REG00__MVPCONF1:
7196 CP0_CHECK(ctx->insn_flags & ASE_MT);
7197 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7198 register_name = "MVPConf1";
7199 break;
7200 case CP0_REG00__VPCONTROL:
7201 CP0_CHECK(ctx->vp);
7202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7203 register_name = "VPControl";
7204 break;
7205 default:
7206 goto cp0_unimplemented;
7207 }
7208 break;
7209 case CP0_REGISTER_01:
7210 switch (sel) {
7211 case CP0_REG01__RANDOM:
7212 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7213 gen_helper_mfc0_random(arg, cpu_env);
7214 register_name = "Random";
7215 break;
7216 case CP0_REG01__VPECONTROL:
7217 CP0_CHECK(ctx->insn_flags & ASE_MT);
7218 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7219 register_name = "VPEControl";
7220 break;
7221 case CP0_REG01__VPECONF0:
7222 CP0_CHECK(ctx->insn_flags & ASE_MT);
7223 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7224 register_name = "VPEConf0";
7225 break;
7226 case CP0_REG01__VPECONF1:
7227 CP0_CHECK(ctx->insn_flags & ASE_MT);
7228 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7229 register_name = "VPEConf1";
7230 break;
7231 case CP0_REG01__YQMASK:
7232 CP0_CHECK(ctx->insn_flags & ASE_MT);
7233 tcg_gen_ld_tl(arg, cpu_env,
7234 offsetof(CPUMIPSState, CP0_YQMask));
7235 register_name = "YQMask";
7236 break;
7237 case CP0_REG01__VPESCHEDULE:
7238 CP0_CHECK(ctx->insn_flags & ASE_MT);
7239 tcg_gen_ld_tl(arg, cpu_env,
7240 offsetof(CPUMIPSState, CP0_VPESchedule));
7241 register_name = "VPESchedule";
7242 break;
7243 case CP0_REG01__VPESCHEFBACK:
7244 CP0_CHECK(ctx->insn_flags & ASE_MT);
7245 tcg_gen_ld_tl(arg, cpu_env,
7246 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7247 register_name = "VPEScheFBack";
7248 break;
7249 case CP0_REG01__VPEOPT:
7250 CP0_CHECK(ctx->insn_flags & ASE_MT);
7251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7252 register_name = "VPEOpt";
7253 break;
7254 default:
7255 goto cp0_unimplemented;
7256 }
7257 break;
7258 case CP0_REGISTER_02:
7259 switch (sel) {
7260 case CP0_REG02__ENTRYLO0:
7261 tcg_gen_ld_tl(arg, cpu_env,
7262 offsetof(CPUMIPSState, CP0_EntryLo0));
7263 register_name = "EntryLo0";
7264 break;
7265 case CP0_REG02__TCSTATUS:
7266 CP0_CHECK(ctx->insn_flags & ASE_MT);
7267 gen_helper_mfc0_tcstatus(arg, cpu_env);
7268 register_name = "TCStatus";
7269 break;
7270 case CP0_REG02__TCBIND:
7271 CP0_CHECK(ctx->insn_flags & ASE_MT);
7272 gen_helper_mfc0_tcbind(arg, cpu_env);
7273 register_name = "TCBind";
7274 break;
7275 case CP0_REG02__TCRESTART:
7276 CP0_CHECK(ctx->insn_flags & ASE_MT);
7277 gen_helper_dmfc0_tcrestart(arg, cpu_env);
7278 register_name = "TCRestart";
7279 break;
7280 case CP0_REG02__TCHALT:
7281 CP0_CHECK(ctx->insn_flags & ASE_MT);
7282 gen_helper_dmfc0_tchalt(arg, cpu_env);
7283 register_name = "TCHalt";
7284 break;
7285 case CP0_REG02__TCCONTEXT:
7286 CP0_CHECK(ctx->insn_flags & ASE_MT);
7287 gen_helper_dmfc0_tccontext(arg, cpu_env);
7288 register_name = "TCContext";
7289 break;
7290 case CP0_REG02__TCSCHEDULE:
7291 CP0_CHECK(ctx->insn_flags & ASE_MT);
7292 gen_helper_dmfc0_tcschedule(arg, cpu_env);
7293 register_name = "TCSchedule";
7294 break;
7295 case CP0_REG02__TCSCHEFBACK:
7296 CP0_CHECK(ctx->insn_flags & ASE_MT);
7297 gen_helper_dmfc0_tcschefback(arg, cpu_env);
7298 register_name = "TCScheFBack";
7299 break;
7300 default:
7301 goto cp0_unimplemented;
7302 }
7303 break;
7304 case CP0_REGISTER_03:
7305 switch (sel) {
7306 case CP0_REG03__ENTRYLO1:
7307 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7308 register_name = "EntryLo1";
7309 break;
7310 case CP0_REG03__GLOBALNUM:
7311 CP0_CHECK(ctx->vp);
7312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7313 register_name = "GlobalNumber";
7314 break;
7315 default:
7316 goto cp0_unimplemented;
7317 }
7318 break;
7319 case CP0_REGISTER_04:
7320 switch (sel) {
7321 case CP0_REG04__CONTEXT:
7322 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7323 register_name = "Context";
7324 break;
7325 case CP0_REG04__CONTEXTCONFIG:
7326 /* SmartMIPS ASE */
7327 /* gen_helper_dmfc0_contextconfig(arg); */
7328 register_name = "ContextConfig";
7329 goto cp0_unimplemented;
7330 case CP0_REG04__USERLOCAL:
7331 CP0_CHECK(ctx->ulri);
7332 tcg_gen_ld_tl(arg, cpu_env,
7333 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7334 register_name = "UserLocal";
7335 break;
7336 case CP0_REG04__MMID:
7337 CP0_CHECK(ctx->mi);
7338 gen_helper_mtc0_memorymapid(cpu_env, arg);
7339 register_name = "MMID";
7340 break;
7341 default:
7342 goto cp0_unimplemented;
7343 }
7344 break;
7345 case CP0_REGISTER_05:
7346 switch (sel) {
7347 case CP0_REG05__PAGEMASK:
7348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7349 register_name = "PageMask";
7350 break;
7351 case CP0_REG05__PAGEGRAIN:
7352 check_insn(ctx, ISA_MIPS_R2);
7353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7354 register_name = "PageGrain";
7355 break;
7356 case CP0_REG05__SEGCTL0:
7357 CP0_CHECK(ctx->sc);
7358 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7359 register_name = "SegCtl0";
7360 break;
7361 case CP0_REG05__SEGCTL1:
7362 CP0_CHECK(ctx->sc);
7363 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7364 register_name = "SegCtl1";
7365 break;
7366 case CP0_REG05__SEGCTL2:
7367 CP0_CHECK(ctx->sc);
7368 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7369 register_name = "SegCtl2";
7370 break;
7371 case CP0_REG05__PWBASE:
7372 check_pw(ctx);
7373 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7374 register_name = "PWBase";
7375 break;
7376 case CP0_REG05__PWFIELD:
7377 check_pw(ctx);
7378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7379 register_name = "PWField";
7380 break;
7381 case CP0_REG05__PWSIZE:
7382 check_pw(ctx);
7383 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7384 register_name = "PWSize";
7385 break;
7386 default:
7387 goto cp0_unimplemented;
7388 }
7389 break;
7390 case CP0_REGISTER_06:
7391 switch (sel) {
7392 case CP0_REG06__WIRED:
7393 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7394 register_name = "Wired";
7395 break;
7396 case CP0_REG06__SRSCONF0:
7397 check_insn(ctx, ISA_MIPS_R2);
7398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7399 register_name = "SRSConf0";
7400 break;
7401 case CP0_REG06__SRSCONF1:
7402 check_insn(ctx, ISA_MIPS_R2);
7403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7404 register_name = "SRSConf1";
7405 break;
7406 case CP0_REG06__SRSCONF2:
7407 check_insn(ctx, ISA_MIPS_R2);
7408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7409 register_name = "SRSConf2";
7410 break;
7411 case CP0_REG06__SRSCONF3:
7412 check_insn(ctx, ISA_MIPS_R2);
7413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7414 register_name = "SRSConf3";
7415 break;
7416 case CP0_REG06__SRSCONF4:
7417 check_insn(ctx, ISA_MIPS_R2);
7418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7419 register_name = "SRSConf4";
7420 break;
7421 case CP0_REG06__PWCTL:
7422 check_pw(ctx);
7423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7424 register_name = "PWCtl";
7425 break;
7426 default:
7427 goto cp0_unimplemented;
7428 }
7429 break;
7430 case CP0_REGISTER_07:
7431 switch (sel) {
7432 case CP0_REG07__HWRENA:
7433 check_insn(ctx, ISA_MIPS_R2);
7434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7435 register_name = "HWREna";
7436 break;
7437 default:
7438 goto cp0_unimplemented;
7439 }
7440 break;
7441 case CP0_REGISTER_08:
7442 switch (sel) {
7443 case CP0_REG08__BADVADDR:
7444 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7445 register_name = "BadVAddr";
7446 break;
7447 case CP0_REG08__BADINSTR:
7448 CP0_CHECK(ctx->bi);
7449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7450 register_name = "BadInstr";
7451 break;
7452 case CP0_REG08__BADINSTRP:
7453 CP0_CHECK(ctx->bp);
7454 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7455 register_name = "BadInstrP";
7456 break;
7457 case CP0_REG08__BADINSTRX:
7458 CP0_CHECK(ctx->bi);
7459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7460 tcg_gen_andi_tl(arg, arg, ~0xffff);
7461 register_name = "BadInstrX";
7462 break;
7463 default:
7464 goto cp0_unimplemented;
7465 }
7466 break;
7467 case CP0_REGISTER_09:
7468 switch (sel) {
7469 case CP0_REG09__COUNT:
7470 /* Mark as an IO operation because we read the time. */
7471 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7472 gen_io_start();
7473 }
7474 gen_helper_mfc0_count(arg, cpu_env);
7475 /*
7476 * Break the TB to be able to take timer interrupts immediately
7477 * after reading count. DISAS_STOP isn't sufficient, we need to
7478 * ensure we break completely out of translated code.
7479 */
7480 gen_save_pc(ctx->base.pc_next + 4);
7481 ctx->base.is_jmp = DISAS_EXIT;
7482 register_name = "Count";
7483 break;
7484 case CP0_REG09__SAARI:
7485 CP0_CHECK(ctx->saar);
7486 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7487 register_name = "SAARI";
7488 break;
7489 case CP0_REG09__SAAR:
7490 CP0_CHECK(ctx->saar);
7491 gen_helper_dmfc0_saar(arg, cpu_env);
7492 register_name = "SAAR";
7493 break;
7494 default:
7495 goto cp0_unimplemented;
7496 }
7497 break;
7498 case CP0_REGISTER_10:
7499 switch (sel) {
7500 case CP0_REG10__ENTRYHI:
7501 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7502 register_name = "EntryHi";
7503 break;
7504 default:
7505 goto cp0_unimplemented;
7506 }
7507 break;
7508 case CP0_REGISTER_11:
7509 switch (sel) {
7510 case CP0_REG11__COMPARE:
7511 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7512 register_name = "Compare";
7513 break;
7514 /* 6,7 are implementation dependent */
7515 default:
7516 goto cp0_unimplemented;
7517 }
7518 break;
7519 case CP0_REGISTER_12:
7520 switch (sel) {
7521 case CP0_REG12__STATUS:
7522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7523 register_name = "Status";
7524 break;
7525 case CP0_REG12__INTCTL:
7526 check_insn(ctx, ISA_MIPS_R2);
7527 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7528 register_name = "IntCtl";
7529 break;
7530 case CP0_REG12__SRSCTL:
7531 check_insn(ctx, ISA_MIPS_R2);
7532 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7533 register_name = "SRSCtl";
7534 break;
7535 case CP0_REG12__SRSMAP:
7536 check_insn(ctx, ISA_MIPS_R2);
7537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7538 register_name = "SRSMap";
7539 break;
7540 default:
7541 goto cp0_unimplemented;
7542 }
7543 break;
7544 case CP0_REGISTER_13:
7545 switch (sel) {
7546 case CP0_REG13__CAUSE:
7547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7548 register_name = "Cause";
7549 break;
7550 default:
7551 goto cp0_unimplemented;
7552 }
7553 break;
7554 case CP0_REGISTER_14:
7555 switch (sel) {
7556 case CP0_REG14__EPC:
7557 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7558 register_name = "EPC";
7559 break;
7560 default:
7561 goto cp0_unimplemented;
7562 }
7563 break;
7564 case CP0_REGISTER_15:
7565 switch (sel) {
7566 case CP0_REG15__PRID:
7567 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7568 register_name = "PRid";
7569 break;
7570 case CP0_REG15__EBASE:
7571 check_insn(ctx, ISA_MIPS_R2);
7572 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7573 register_name = "EBase";
7574 break;
7575 case CP0_REG15__CMGCRBASE:
7576 check_insn(ctx, ISA_MIPS_R2);
7577 CP0_CHECK(ctx->cmgcr);
7578 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7579 register_name = "CMGCRBase";
7580 break;
7581 default:
7582 goto cp0_unimplemented;
7583 }
7584 break;
7585 case CP0_REGISTER_16:
7586 switch (sel) {
7587 case CP0_REG16__CONFIG:
7588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7589 register_name = "Config";
7590 break;
7591 case CP0_REG16__CONFIG1:
7592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7593 register_name = "Config1";
7594 break;
7595 case CP0_REG16__CONFIG2:
7596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7597 register_name = "Config2";
7598 break;
7599 case CP0_REG16__CONFIG3:
7600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7601 register_name = "Config3";
7602 break;
7603 case CP0_REG16__CONFIG4:
7604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7605 register_name = "Config4";
7606 break;
7607 case CP0_REG16__CONFIG5:
7608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7609 register_name = "Config5";
7610 break;
7611 /* 6,7 are implementation dependent */
7612 case CP0_REG16__CONFIG6:
7613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7614 register_name = "Config6";
7615 break;
7616 case CP0_REG16__CONFIG7:
7617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7618 register_name = "Config7";
7619 break;
7620 default:
7621 goto cp0_unimplemented;
7622 }
7623 break;
7624 case CP0_REGISTER_17:
7625 switch (sel) {
7626 case CP0_REG17__LLADDR:
7627 gen_helper_dmfc0_lladdr(arg, cpu_env);
7628 register_name = "LLAddr";
7629 break;
7630 case CP0_REG17__MAAR:
7631 CP0_CHECK(ctx->mrp);
7632 gen_helper_dmfc0_maar(arg, cpu_env);
7633 register_name = "MAAR";
7634 break;
7635 case CP0_REG17__MAARI:
7636 CP0_CHECK(ctx->mrp);
7637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7638 register_name = "MAARI";
7639 break;
7640 default:
7641 goto cp0_unimplemented;
7642 }
7643 break;
7644 case CP0_REGISTER_18:
7645 switch (sel) {
7646 case CP0_REG18__WATCHLO0:
7647 case CP0_REG18__WATCHLO1:
7648 case CP0_REG18__WATCHLO2:
7649 case CP0_REG18__WATCHLO3:
7650 case CP0_REG18__WATCHLO4:
7651 case CP0_REG18__WATCHLO5:
7652 case CP0_REG18__WATCHLO6:
7653 case CP0_REG18__WATCHLO7:
7654 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7655 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7656 register_name = "WatchLo";
7657 break;
7658 default:
7659 goto cp0_unimplemented;
7660 }
7661 break;
7662 case CP0_REGISTER_19:
7663 switch (sel) {
7664 case CP0_REG19__WATCHHI0:
7665 case CP0_REG19__WATCHHI1:
7666 case CP0_REG19__WATCHHI2:
7667 case CP0_REG19__WATCHHI3:
7668 case CP0_REG19__WATCHHI4:
7669 case CP0_REG19__WATCHHI5:
7670 case CP0_REG19__WATCHHI6:
7671 case CP0_REG19__WATCHHI7:
7672 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7673 gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7674 register_name = "WatchHi";
7675 break;
7676 default:
7677 goto cp0_unimplemented;
7678 }
7679 break;
7680 case CP0_REGISTER_20:
7681 switch (sel) {
7682 case CP0_REG20__XCONTEXT:
7683 check_insn(ctx, ISA_MIPS3);
7684 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7685 register_name = "XContext";
7686 break;
7687 default:
7688 goto cp0_unimplemented;
7689 }
7690 break;
7691 case CP0_REGISTER_21:
7692 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7693 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7694 switch (sel) {
7695 case 0:
7696 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7697 register_name = "Framemask";
7698 break;
7699 default:
7700 goto cp0_unimplemented;
7701 }
7702 break;
7703 case CP0_REGISTER_22:
7704 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7705 register_name = "'Diagnostic"; /* implementation dependent */
7706 break;
7707 case CP0_REGISTER_23:
7708 switch (sel) {
7709 case CP0_REG23__DEBUG:
7710 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7711 register_name = "Debug";
7712 break;
7713 case CP0_REG23__TRACECONTROL:
7714 /* PDtrace support */
7715 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
7716 register_name = "TraceControl";
7717 goto cp0_unimplemented;
7718 case CP0_REG23__TRACECONTROL2:
7719 /* PDtrace support */
7720 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
7721 register_name = "TraceControl2";
7722 goto cp0_unimplemented;
7723 case CP0_REG23__USERTRACEDATA1:
7724 /* PDtrace support */
7725 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
7726 register_name = "UserTraceData1";
7727 goto cp0_unimplemented;
7728 case CP0_REG23__TRACEIBPC:
7729 /* PDtrace support */
7730 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
7731 register_name = "TraceIBPC";
7732 goto cp0_unimplemented;
7733 case CP0_REG23__TRACEDBPC:
7734 /* PDtrace support */
7735 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
7736 register_name = "TraceDBPC";
7737 goto cp0_unimplemented;
7738 default:
7739 goto cp0_unimplemented;
7740 }
7741 break;
7742 case CP0_REGISTER_24:
7743 switch (sel) {
7744 case CP0_REG24__DEPC:
7745 /* EJTAG support */
7746 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7747 register_name = "DEPC";
7748 break;
7749 default:
7750 goto cp0_unimplemented;
7751 }
7752 break;
7753 case CP0_REGISTER_25:
7754 switch (sel) {
7755 case CP0_REG25__PERFCTL0:
7756 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7757 register_name = "Performance0";
7758 break;
7759 case CP0_REG25__PERFCNT0:
7760 /* gen_helper_dmfc0_performance1(arg); */
7761 register_name = "Performance1";
7762 goto cp0_unimplemented;
7763 case CP0_REG25__PERFCTL1:
7764 /* gen_helper_dmfc0_performance2(arg); */
7765 register_name = "Performance2";
7766 goto cp0_unimplemented;
7767 case CP0_REG25__PERFCNT1:
7768 /* gen_helper_dmfc0_performance3(arg); */
7769 register_name = "Performance3";
7770 goto cp0_unimplemented;
7771 case CP0_REG25__PERFCTL2:
7772 /* gen_helper_dmfc0_performance4(arg); */
7773 register_name = "Performance4";
7774 goto cp0_unimplemented;
7775 case CP0_REG25__PERFCNT2:
7776 /* gen_helper_dmfc0_performance5(arg); */
7777 register_name = "Performance5";
7778 goto cp0_unimplemented;
7779 case CP0_REG25__PERFCTL3:
7780 /* gen_helper_dmfc0_performance6(arg); */
7781 register_name = "Performance6";
7782 goto cp0_unimplemented;
7783 case CP0_REG25__PERFCNT3:
7784 /* gen_helper_dmfc0_performance7(arg); */
7785 register_name = "Performance7";
7786 goto cp0_unimplemented;
7787 default:
7788 goto cp0_unimplemented;
7789 }
7790 break;
7791 case CP0_REGISTER_26:
7792 switch (sel) {
7793 case CP0_REG26__ERRCTL:
7794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7795 register_name = "ErrCtl";
7796 break;
7797 default:
7798 goto cp0_unimplemented;
7799 }
7800 break;
7801 case CP0_REGISTER_27:
7802 switch (sel) {
7803 /* ignored */
7804 case CP0_REG27__CACHERR:
7805 tcg_gen_movi_tl(arg, 0); /* unimplemented */
7806 register_name = "CacheErr";
7807 break;
7808 default:
7809 goto cp0_unimplemented;
7810 }
7811 break;
7812 case CP0_REGISTER_28:
7813 switch (sel) {
7814 case CP0_REG28__TAGLO:
7815 case CP0_REG28__TAGLO1:
7816 case CP0_REG28__TAGLO2:
7817 case CP0_REG28__TAGLO3:
7818 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7819 register_name = "TagLo";
7820 break;
7821 case CP0_REG28__DATALO:
7822 case CP0_REG28__DATALO1:
7823 case CP0_REG28__DATALO2:
7824 case CP0_REG28__DATALO3:
7825 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7826 register_name = "DataLo";
7827 break;
7828 default:
7829 goto cp0_unimplemented;
7830 }
7831 break;
7832 case CP0_REGISTER_29:
7833 switch (sel) {
7834 case CP0_REG29__TAGHI:
7835 case CP0_REG29__TAGHI1:
7836 case CP0_REG29__TAGHI2:
7837 case CP0_REG29__TAGHI3:
7838 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7839 register_name = "TagHi";
7840 break;
7841 case CP0_REG29__DATAHI:
7842 case CP0_REG29__DATAHI1:
7843 case CP0_REG29__DATAHI2:
7844 case CP0_REG29__DATAHI3:
7845 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7846 register_name = "DataHi";
7847 break;
7848 default:
7849 goto cp0_unimplemented;
7850 }
7851 break;
7852 case CP0_REGISTER_30:
7853 switch (sel) {
7854 case CP0_REG30__ERROREPC:
7855 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7856 register_name = "ErrorEPC";
7857 break;
7858 default:
7859 goto cp0_unimplemented;
7860 }
7861 break;
7862 case CP0_REGISTER_31:
7863 switch (sel) {
7864 case CP0_REG31__DESAVE:
7865 /* EJTAG support */
7866 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7867 register_name = "DESAVE";
7868 break;
7869 case CP0_REG31__KSCRATCH1:
7870 case CP0_REG31__KSCRATCH2:
7871 case CP0_REG31__KSCRATCH3:
7872 case CP0_REG31__KSCRATCH4:
7873 case CP0_REG31__KSCRATCH5:
7874 case CP0_REG31__KSCRATCH6:
7875 CP0_CHECK(ctx->kscrexist & (1 << sel));
7876 tcg_gen_ld_tl(arg, cpu_env,
7877 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7878 register_name = "KScratch";
7879 break;
7880 default:
7881 goto cp0_unimplemented;
7882 }
7883 break;
7884 default:
7885 goto cp0_unimplemented;
7886 }
7887 trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7888 return;
7889
7890 cp0_unimplemented:
7891 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7892 register_name, reg, sel);
7893 gen_mfc0_unimplemented(ctx, arg);
7894 }
7895
7896 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7897 {
7898 const char *register_name = "invalid";
7899
7900 if (sel != 0) {
7901 check_insn(ctx, ISA_MIPS_R1);
7902 }
7903
7904 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7905 gen_io_start();
7906 }
7907
7908 switch (reg) {
7909 case CP0_REGISTER_00:
7910 switch (sel) {
7911 case CP0_REG00__INDEX:
7912 gen_helper_mtc0_index(cpu_env, arg);
7913 register_name = "Index";
7914 break;
7915 case CP0_REG00__MVPCONTROL:
7916 CP0_CHECK(ctx->insn_flags & ASE_MT);
7917 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7918 register_name = "MVPControl";
7919 break;
7920 case CP0_REG00__MVPCONF0:
7921 CP0_CHECK(ctx->insn_flags & ASE_MT);
7922 /* ignored */
7923 register_name = "MVPConf0";
7924 break;
7925 case CP0_REG00__MVPCONF1:
7926 CP0_CHECK(ctx->insn_flags & ASE_MT);
7927 /* ignored */
7928 register_name = "MVPConf1";
7929 break;
7930 case CP0_REG00__VPCONTROL:
7931 CP0_CHECK(ctx->vp);
7932 /* ignored */
7933 register_name = "VPControl";
7934 break;
7935 default:
7936 goto cp0_unimplemented;
7937 }
7938 break;
7939 case CP0_REGISTER_01:
7940 switch (sel) {
7941 case CP0_REG01__RANDOM:
7942 /* ignored */
7943 register_name = "Random";
7944 break;
7945 case CP0_REG01__VPECONTROL:
7946 CP0_CHECK(ctx->insn_flags & ASE_MT);
7947 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7948 register_name = "VPEControl";
7949 break;
7950 case CP0_REG01__VPECONF0:
7951 CP0_CHECK(ctx->insn_flags & ASE_MT);
7952 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7953 register_name = "VPEConf0";
7954 break;
7955 case CP0_REG01__VPECONF1:
7956 CP0_CHECK(ctx->insn_flags & ASE_MT);
7957 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7958 register_name = "VPEConf1";
7959 break;
7960 case CP0_REG01__YQMASK:
7961 CP0_CHECK(ctx->insn_flags & ASE_MT);
7962 gen_helper_mtc0_yqmask(cpu_env, arg);
7963 register_name = "YQMask";
7964 break;
7965 case CP0_REG01__VPESCHEDULE:
7966 CP0_CHECK(ctx->insn_flags & ASE_MT);
7967 tcg_gen_st_tl(arg, cpu_env,
7968 offsetof(CPUMIPSState, CP0_VPESchedule));
7969 register_name = "VPESchedule";
7970 break;
7971 case CP0_REG01__VPESCHEFBACK:
7972 CP0_CHECK(ctx->insn_flags & ASE_MT);
7973 tcg_gen_st_tl(arg, cpu_env,
7974 offsetof(CPUMIPSState, CP0_VPEScheFBack));
7975 register_name = "VPEScheFBack";
7976 break;
7977 case CP0_REG01__VPEOPT:
7978 CP0_CHECK(ctx->insn_flags & ASE_MT);
7979 gen_helper_mtc0_vpeopt(cpu_env, arg);
7980 register_name = "VPEOpt";
7981 break;
7982 default:
7983 goto cp0_unimplemented;
7984 }
7985 break;
7986 case CP0_REGISTER_02:
7987 switch (sel) {
7988 case CP0_REG02__ENTRYLO0:
7989 gen_helper_dmtc0_entrylo0(cpu_env, arg);
7990 register_name = "EntryLo0";
7991 break;
7992 case CP0_REG02__TCSTATUS:
7993 CP0_CHECK(ctx->insn_flags & ASE_MT);
7994 gen_helper_mtc0_tcstatus(cpu_env, arg);
7995 register_name = "TCStatus";
7996 break;
7997 case CP0_REG02__TCBIND:
7998 CP0_CHECK(ctx->insn_flags & ASE_MT);
7999 gen_helper_mtc0_tcbind(cpu_env, arg);
8000 register_name = "TCBind";
8001 break;
8002 case CP0_REG02__TCRESTART:
8003 CP0_CHECK(ctx->insn_flags & ASE_MT);
8004 gen_helper_mtc0_tcrestart(cpu_env, arg);
8005 register_name = "TCRestart";
8006 break;
8007 case CP0_REG02__TCHALT:
8008 CP0_CHECK(ctx->insn_flags & ASE_MT);
8009 gen_helper_mtc0_tchalt(cpu_env, arg);
8010 register_name = "TCHalt";
8011 break;
8012 case CP0_REG02__TCCONTEXT:
8013 CP0_CHECK(ctx->insn_flags & ASE_MT);
8014 gen_helper_mtc0_tccontext(cpu_env, arg);
8015 register_name = "TCContext";
8016 break;
8017 case CP0_REG02__TCSCHEDULE:
8018 CP0_CHECK(ctx->insn_flags & ASE_MT);
8019 gen_helper_mtc0_tcschedule(cpu_env, arg);
8020 register_name = "TCSchedule";
8021 break;
8022 case CP0_REG02__TCSCHEFBACK:
8023 CP0_CHECK(ctx->insn_flags & ASE_MT);
8024 gen_helper_mtc0_tcschefback(cpu_env, arg);
8025 register_name = "TCScheFBack";
8026 break;
8027 default:
8028 goto cp0_unimplemented;
8029 }
8030 break;
8031 case CP0_REGISTER_03:
8032 switch (sel) {
8033 case CP0_REG03__ENTRYLO1:
8034 gen_helper_dmtc0_entrylo1(cpu_env, arg);
8035 register_name = "EntryLo1";
8036 break;
8037 case CP0_REG03__GLOBALNUM:
8038 CP0_CHECK(ctx->vp);
8039 /* ignored */
8040 register_name = "GlobalNumber";
8041 break;
8042 default:
8043 goto cp0_unimplemented;
8044 }
8045 break;
8046 case CP0_REGISTER_04:
8047 switch (sel) {
8048 case CP0_REG04__CONTEXT:
8049 gen_helper_mtc0_context(cpu_env, arg);
8050 register_name = "Context";
8051 break;
8052 case CP0_REG04__CONTEXTCONFIG:
8053 /* SmartMIPS ASE */
8054 /* gen_helper_dmtc0_contextconfig(arg); */
8055 register_name = "ContextConfig";
8056 goto cp0_unimplemented;
8057 case CP0_REG04__USERLOCAL:
8058 CP0_CHECK(ctx->ulri);
8059 tcg_gen_st_tl(arg, cpu_env,
8060 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8061 register_name = "UserLocal";
8062 break;
8063 case CP0_REG04__MMID:
8064 CP0_CHECK(ctx->mi);
8065 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8066 register_name = "MMID";
8067 break;
8068 default:
8069 goto cp0_unimplemented;
8070 }
8071 break;
8072 case CP0_REGISTER_05:
8073 switch (sel) {
8074 case CP0_REG05__PAGEMASK:
8075 gen_helper_mtc0_pagemask(cpu_env, arg);
8076 register_name = "PageMask";
8077 break;
8078 case CP0_REG05__PAGEGRAIN:
8079 check_insn(ctx, ISA_MIPS_R2);
8080 gen_helper_mtc0_pagegrain(cpu_env, arg);
8081 register_name = "PageGrain";
8082 break;
8083 case CP0_REG05__SEGCTL0:
8084 CP0_CHECK(ctx->sc);
8085 gen_helper_mtc0_segctl0(cpu_env, arg);
8086 register_name = "SegCtl0";
8087 break;
8088 case CP0_REG05__SEGCTL1:
8089 CP0_CHECK(ctx->sc);
8090 gen_helper_mtc0_segctl1(cpu_env, arg);
8091 register_name = "SegCtl1";
8092 break;
8093 case CP0_REG05__SEGCTL2:
8094 CP0_CHECK(ctx->sc);
8095 gen_helper_mtc0_segctl2(cpu_env, arg);
8096 register_name = "SegCtl2";
8097 break;
8098 case CP0_REG05__PWBASE:
8099 check_pw(ctx);
8100 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8101 register_name = "PWBase";
8102 break;
8103 case CP0_REG05__PWFIELD:
8104 check_pw(ctx);
8105 gen_helper_mtc0_pwfield(cpu_env, arg);
8106 register_name = "PWField";
8107 break;
8108 case CP0_REG05__PWSIZE:
8109 check_pw(ctx);
8110 gen_helper_mtc0_pwsize(cpu_env, arg);
8111 register_name = "PWSize";
8112 break;
8113 default:
8114 goto cp0_unimplemented;
8115 }
8116 break;
8117 case CP0_REGISTER_06:
8118 switch (sel) {
8119 case CP0_REG06__WIRED:
8120 gen_helper_mtc0_wired(cpu_env, arg);
8121 register_name = "Wired";
8122 break;
8123 case CP0_REG06__SRSCONF0:
8124 check_insn(ctx, ISA_MIPS_R2);
8125 gen_helper_mtc0_srsconf0(cpu_env, arg);
8126 register_name = "SRSConf0";
8127 break;
8128 case CP0_REG06__SRSCONF1:
8129 check_insn(ctx, ISA_MIPS_R2);
8130 gen_helper_mtc0_srsconf1(cpu_env, arg);
8131 register_name = "SRSConf1";
8132 break;
8133 case CP0_REG06__SRSCONF2:
8134 check_insn(ctx, ISA_MIPS_R2);
8135 gen_helper_mtc0_srsconf2(cpu_env, arg);
8136 register_name = "SRSConf2";
8137 break;
8138 case CP0_REG06__SRSCONF3:
8139 check_insn(ctx, ISA_MIPS_R2);
8140 gen_helper_mtc0_srsconf3(cpu_env, arg);
8141 register_name = "SRSConf3";
8142 break;
8143 case CP0_REG06__SRSCONF4:
8144 check_insn(ctx, ISA_MIPS_R2);
8145 gen_helper_mtc0_srsconf4(cpu_env, arg);
8146 register_name = "SRSConf4";
8147 break;
8148 case CP0_REG06__PWCTL:
8149 check_pw(ctx);
8150 gen_helper_mtc0_pwctl(cpu_env, arg);
8151 register_name = "PWCtl";
8152 break;
8153 default:
8154 goto cp0_unimplemented;
8155 }
8156 break;
8157 case CP0_REGISTER_07:
8158 switch (sel) {
8159 case CP0_REG07__HWRENA:
8160 check_insn(ctx, ISA_MIPS_R2);
8161 gen_helper_mtc0_hwrena(cpu_env, arg);
8162 ctx->base.is_jmp = DISAS_STOP;
8163 register_name = "HWREna";
8164 break;
8165 default:
8166 goto cp0_unimplemented;
8167 }
8168 break;
8169 case CP0_REGISTER_08:
8170 switch (sel) {
8171 case CP0_REG08__BADVADDR:
8172 /* ignored */
8173 register_name = "BadVAddr";
8174 break;
8175 case CP0_REG08__BADINSTR:
8176 /* ignored */
8177 register_name = "BadInstr";
8178 break;
8179 case CP0_REG08__BADINSTRP:
8180 /* ignored */
8181 register_name = "BadInstrP";
8182 break;
8183 case CP0_REG08__BADINSTRX:
8184 /* ignored */
8185 register_name = "BadInstrX";
8186 break;
8187 default:
8188 goto cp0_unimplemented;
8189 }
8190 break;
8191 case CP0_REGISTER_09:
8192 switch (sel) {
8193 case CP0_REG09__COUNT:
8194 gen_helper_mtc0_count(cpu_env, arg);
8195 register_name = "Count";
8196 break;
8197 case CP0_REG09__SAARI:
8198 CP0_CHECK(ctx->saar);
8199 gen_helper_mtc0_saari(cpu_env, arg);
8200 register_name = "SAARI";
8201 break;
8202 case CP0_REG09__SAAR:
8203 CP0_CHECK(ctx->saar);
8204 gen_helper_mtc0_saar(cpu_env, arg);
8205 register_name = "SAAR";
8206 break;
8207 default:
8208 goto cp0_unimplemented;
8209 }
8210 /* Stop translation as we may have switched the execution mode */
8211 ctx->base.is_jmp = DISAS_STOP;
8212 break;
8213 case CP0_REGISTER_10:
8214 switch (sel) {
8215 case CP0_REG10__ENTRYHI:
8216 gen_helper_mtc0_entryhi(cpu_env, arg);
8217 register_name = "EntryHi";
8218 break;
8219 default:
8220 goto cp0_unimplemented;
8221 }
8222 break;
8223 case CP0_REGISTER_11:
8224 switch (sel) {
8225 case CP0_REG11__COMPARE:
8226 gen_helper_mtc0_compare(cpu_env, arg);
8227 register_name = "Compare";
8228 break;
8229 /* 6,7 are implementation dependent */
8230 default:
8231 goto cp0_unimplemented;
8232 }
8233 /* Stop translation as we may have switched the execution mode */
8234 ctx->base.is_jmp = DISAS_STOP;
8235 break;
8236 case CP0_REGISTER_12:
8237 switch (sel) {
8238 case CP0_REG12__STATUS:
8239 save_cpu_state(ctx, 1);
8240 gen_helper_mtc0_status(cpu_env, arg);
8241 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8242 gen_save_pc(ctx->base.pc_next + 4);
8243 ctx->base.is_jmp = DISAS_EXIT;
8244 register_name = "Status";
8245 break;
8246 case CP0_REG12__INTCTL:
8247 check_insn(ctx, ISA_MIPS_R2);
8248 gen_helper_mtc0_intctl(cpu_env, arg);
8249 /* Stop translation as we may have switched the execution mode */
8250 ctx->base.is_jmp = DISAS_STOP;
8251 register_name = "IntCtl";
8252 break;
8253 case CP0_REG12__SRSCTL:
8254 check_insn(ctx, ISA_MIPS_R2);
8255 gen_helper_mtc0_srsctl(cpu_env, arg);
8256 /* Stop translation as we may have switched the execution mode */
8257 ctx->base.is_jmp = DISAS_STOP;
8258 register_name = "SRSCtl";
8259 break;
8260 case CP0_REG12__SRSMAP:
8261 check_insn(ctx, ISA_MIPS_R2);
8262 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8263 /* Stop translation as we may have switched the execution mode */
8264 ctx->base.is_jmp = DISAS_STOP;
8265 register_name = "SRSMap";
8266 break;
8267 default:
8268 goto cp0_unimplemented;
8269 }
8270 break;
8271 case CP0_REGISTER_13:
8272 switch (sel) {
8273 case CP0_REG13__CAUSE:
8274 save_cpu_state(ctx, 1);
8275 gen_helper_mtc0_cause(cpu_env, arg);
8276 /*
8277 * Stop translation as we may have triggered an interrupt.
8278 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8279 * translated code to check for pending interrupts.
8280 */
8281 gen_save_pc(ctx->base.pc_next + 4);
8282 ctx->base.is_jmp = DISAS_EXIT;
8283 register_name = "Cause";
8284 break;
8285 default:
8286 goto cp0_unimplemented;
8287 }
8288 break;
8289 case CP0_REGISTER_14:
8290 switch (sel) {
8291 case CP0_REG14__EPC:
8292 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8293 register_name = "EPC";
8294 break;
8295 default:
8296 goto cp0_unimplemented;
8297 }
8298 break;
8299 case CP0_REGISTER_15:
8300 switch (sel) {
8301 case CP0_REG15__PRID:
8302 /* ignored */
8303 register_name = "PRid";
8304 break;
8305 case CP0_REG15__EBASE:
8306 check_insn(ctx, ISA_MIPS_R2);
8307 gen_helper_mtc0_ebase(cpu_env, arg);
8308 register_name = "EBase";
8309 break;
8310 default:
8311 goto cp0_unimplemented;
8312 }
8313 break;
8314 case CP0_REGISTER_16:
8315 switch (sel) {
8316 case CP0_REG16__CONFIG:
8317 gen_helper_mtc0_config0(cpu_env, arg);
8318 register_name = "Config";
8319 /* Stop translation as we may have switched the execution mode */
8320 ctx->base.is_jmp = DISAS_STOP;
8321 break;
8322 case CP0_REG16__CONFIG1:
8323 /* ignored, read only */
8324 register_name = "Config1";
8325 break;
8326 case CP0_REG16__CONFIG2:
8327 gen_helper_mtc0_config2(cpu_env, arg);
8328 register_name = "Config2";
8329 /* Stop translation as we may have switched the execution mode */
8330 ctx->base.is_jmp = DISAS_STOP;
8331 break;
8332 case CP0_REG16__CONFIG3:
8333 gen_helper_mtc0_config3(cpu_env, arg);
8334 register_name = "Config3";
8335 /* Stop translation as we may have switched the execution mode */
8336 ctx->base.is_jmp = DISAS_STOP;
8337 break;
8338 case CP0_REG16__CONFIG4:
8339 /* currently ignored */
8340 register_name = "Config4";
8341 break;
8342 case CP0_REG16__CONFIG5:
8343 gen_helper_mtc0_config5(cpu_env, arg);
8344 register_name = "Config5";
8345 /* Stop translation as we may have switched the execution mode */
8346 ctx->base.is_jmp = DISAS_STOP;
8347 break;
8348 /* 6,7 are implementation dependent */
8349 default:
8350 register_name = "Invalid config selector";
8351 goto cp0_unimplemented;
8352 }
8353 break;
8354 case CP0_REGISTER_17:
8355 switch (sel) {
8356 case CP0_REG17__LLADDR:
8357 gen_helper_mtc0_lladdr(cpu_env, arg);
8358 register_name = "LLAddr";
8359 break;
8360 case CP0_REG17__MAAR:
8361 CP0_CHECK(ctx->mrp);
8362 gen_helper_mtc0_maar(cpu_env, arg);
8363 register_name = "MAAR";
8364 break;
8365 case CP0_REG17__MAARI:
8366 CP0_CHECK(ctx->mrp);
8367 gen_helper_mtc0_maari(cpu_env, arg);
8368 register_name = "MAARI";
8369 break;
8370 default:
8371 goto cp0_unimplemented;
8372 }
8373 break;
8374 case CP0_REGISTER_18:
8375 switch (sel) {
8376 case CP0_REG18__WATCHLO0:
8377 case CP0_REG18__WATCHLO1:
8378 case CP0_REG18__WATCHLO2:
8379 case CP0_REG18__WATCHLO3:
8380 case CP0_REG18__WATCHLO4:
8381 case CP0_REG18__WATCHLO5:
8382 case CP0_REG18__WATCHLO6:
8383 case CP0_REG18__WATCHLO7:
8384 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8385 gen_helper_0e1i(mtc0_watchlo, arg, sel);
8386 register_name = "WatchLo";
8387 break;
8388 default:
8389 goto cp0_unimplemented;
8390 }
8391 break;
8392 case CP0_REGISTER_19:
8393 switch (sel) {
8394 case CP0_REG19__WATCHHI0:
8395 case CP0_REG19__WATCHHI1:
8396 case CP0_REG19__WATCHHI2:
8397 case CP0_REG19__WATCHHI3:
8398 case CP0_REG19__WATCHHI4:
8399 case CP0_REG19__WATCHHI5:
8400 case CP0_REG19__WATCHHI6:
8401 case CP0_REG19__WATCHHI7:
8402 CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8403 gen_helper_0e1i(mtc0_watchhi, arg, sel);
8404 register_name = "WatchHi";
8405 break;
8406 default:
8407 goto cp0_unimplemented;
8408 }
8409 break;
8410 case CP0_REGISTER_20:
8411 switch (sel) {
8412 case CP0_REG20__XCONTEXT:
8413 check_insn(ctx, ISA_MIPS3);
8414 gen_helper_mtc0_xcontext(cpu_env, arg);
8415 register_name = "XContext";
8416 break;
8417 default:
8418 goto cp0_unimplemented;
8419 }
8420 break;
8421 case CP0_REGISTER_21:
8422 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8423 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8424 switch (sel) {
8425 case 0:
8426 gen_helper_mtc0_framemask(cpu_env, arg);
8427 register_name = "Framemask";
8428 break;
8429 default:
8430 goto cp0_unimplemented;
8431 }
8432 break;
8433 case CP0_REGISTER_22:
8434 /* ignored */
8435 register_name = "Diagnostic"; /* implementation dependent */
8436 break;
8437 case CP0_REGISTER_23:
8438 switch (sel) {
8439 case CP0_REG23__DEBUG:
8440 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8441 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8442 gen_save_pc(ctx->base.pc_next + 4);
8443 ctx->base.is_jmp = DISAS_EXIT;
8444 register_name = "Debug";
8445 break;
8446 case CP0_REG23__TRACECONTROL:
8447 /* PDtrace support */
8448 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8449 /* Stop translation as we may have switched the execution mode */
8450 ctx->base.is_jmp = DISAS_STOP;
8451 register_name = "TraceControl";
8452 goto cp0_unimplemented;
8453 case CP0_REG23__TRACECONTROL2:
8454 /* PDtrace support */
8455 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8456 /* Stop translation as we may have switched the execution mode */
8457 ctx->base.is_jmp = DISAS_STOP;
8458 register_name = "TraceControl2";
8459 goto cp0_unimplemented;
8460 case CP0_REG23__USERTRACEDATA1:
8461 /* PDtrace support */
8462 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8463 /* Stop translation as we may have switched the execution mode */
8464 ctx->base.is_jmp = DISAS_STOP;
8465 register_name = "UserTraceData1";
8466 goto cp0_unimplemented;
8467 case CP0_REG23__TRACEIBPC:
8468 /* PDtrace support */
8469 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8470 /* Stop translation as we may have switched the execution mode */
8471 ctx->base.is_jmp = DISAS_STOP;
8472 register_name = "TraceIBPC";
8473 goto cp0_unimplemented;
8474 case CP0_REG23__TRACEDBPC:
8475 /* PDtrace support */
8476 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8477 /* Stop translation as we may have switched the execution mode */
8478 ctx->base.is_jmp = DISAS_STOP;
8479 register_name = "TraceDBPC";
8480 goto cp0_unimplemented;
8481 default:
8482 goto cp0_unimplemented;
8483 }
8484 break;
8485 case CP0_REGISTER_24:
8486 switch (sel) {
8487 case CP0_REG24__DEPC:
8488 /* EJTAG support */
8489 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8490 register_name = "DEPC";
8491 break;
8492 default:
8493 goto cp0_unimplemented;
8494 }
8495 break;
8496 case CP0_REGISTER_25:
8497 switch (sel) {
8498 case CP0_REG25__PERFCTL0:
8499 gen_helper_mtc0_performance0(cpu_env, arg);
8500 register_name = "Performance0";
8501 break;
8502 case CP0_REG25__PERFCNT0:
8503 /* gen_helper_mtc0_performance1(cpu_env, arg); */
8504 register_name = "Performance1";
8505 goto cp0_unimplemented;
8506 case CP0_REG25__PERFCTL1:
8507 /* gen_helper_mtc0_performance2(cpu_env, arg); */
8508 register_name = "Performance2";
8509 goto cp0_unimplemented;
8510 case CP0_REG25__PERFCNT1:
8511 /* gen_helper_mtc0_performance3(cpu_env, arg); */
8512 register_name = "Performance3";
8513 goto cp0_unimplemented;
8514 case CP0_REG25__PERFCTL2:
8515 /* gen_helper_mtc0_performance4(cpu_env, arg); */
8516 register_name = "Performance4";
8517 goto cp0_unimplemented;
8518 case CP0_REG25__PERFCNT2:
8519 /* gen_helper_mtc0_performance5(cpu_env, arg); */
8520 register_name = "Performance5";
8521 goto cp0_unimplemented;
8522 case CP0_REG25__PERFCTL3:
8523 /* gen_helper_mtc0_performance6(cpu_env, arg); */
8524 register_name = "Performance6";
8525 goto cp0_unimplemented;
8526 case CP0_REG25__PERFCNT3:
8527 /* gen_helper_mtc0_performance7(cpu_env, arg); */
8528 register_name = "Performance7";
8529 goto cp0_unimplemented;
8530 default:
8531 goto cp0_unimplemented;
8532 }
8533 break;
8534 case CP0_REGISTER_26:
8535 switch (sel) {
8536 case CP0_REG26__ERRCTL:
8537 gen_helper_mtc0_errctl(cpu_env, arg);
8538 ctx->base.is_jmp = DISAS_STOP;
8539 register_name = "ErrCtl";
8540 break;
8541 default:
8542 goto cp0_unimplemented;
8543 }
8544 break;
8545 case CP0_REGISTER_27:
8546 switch (sel) {
8547 case CP0_REG27__CACHERR:
8548 /* ignored */
8549 register_name = "CacheErr";
8550 break;
8551 default:
8552 goto cp0_unimplemented;
8553 }
8554 break;
8555 case CP0_REGISTER_28:
8556 switch (sel) {
8557 case CP0_REG28__TAGLO:
8558 case CP0_REG28__TAGLO1:
8559 case CP0_REG28__TAGLO2:
8560 case CP0_REG28__TAGLO3:
8561 gen_helper_mtc0_taglo(cpu_env, arg);
8562 register_name = "TagLo";
8563 break;
8564 case CP0_REG28__DATALO:
8565 case CP0_REG28__DATALO1:
8566 case CP0_REG28__DATALO2:
8567 case CP0_REG28__DATALO3:
8568 gen_helper_mtc0_datalo(cpu_env, arg);
8569 register_name = "DataLo";
8570 break;
8571 default:
8572 goto cp0_unimplemented;
8573 }
8574 break;
8575 case CP0_REGISTER_29:
8576 switch (sel) {
8577 case CP0_REG29__TAGHI:
8578 case CP0_REG29__TAGHI1:
8579 case CP0_REG29__TAGHI2:
8580 case CP0_REG29__TAGHI3:
8581 gen_helper_mtc0_taghi(cpu_env, arg);
8582 register_name = "TagHi";
8583 break;
8584 case CP0_REG29__DATAHI:
8585 case CP0_REG29__DATAHI1:
8586 case CP0_REG29__DATAHI2:
8587 case CP0_REG29__DATAHI3:
8588 gen_helper_mtc0_datahi(cpu_env, arg);
8589 register_name = "DataHi";
8590 break;
8591 default:
8592 register_name = "invalid sel";
8593 goto cp0_unimplemented;
8594 }
8595 break;
8596 case CP0_REGISTER_30:
8597 switch (sel) {
8598 case CP0_REG30__ERROREPC:
8599 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8600 register_name = "ErrorEPC";
8601 break;
8602 default:
8603 goto cp0_unimplemented;
8604 }
8605 break;
8606 case CP0_REGISTER_31:
8607 switch (sel) {
8608 case CP0_REG31__DESAVE:
8609 /* EJTAG support */
8610 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8611 register_name = "DESAVE";
8612 break;
8613 case CP0_REG31__KSCRATCH1:
8614 case CP0_REG31__KSCRATCH2:
8615 case CP0_REG31__KSCRATCH3:
8616 case CP0_REG31__KSCRATCH4:
8617 case CP0_REG31__KSCRATCH5:
8618 case CP0_REG31__KSCRATCH6:
8619 CP0_CHECK(ctx->kscrexist & (1 << sel));
8620 tcg_gen_st_tl(arg, cpu_env,
8621 offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8622 register_name = "KScratch";
8623 break;
8624 default:
8625 goto cp0_unimplemented;
8626 }
8627 break;
8628 default:
8629 goto cp0_unimplemented;
8630 }
8631 trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8632
8633 /* For simplicity assume that all writes can cause interrupts. */
8634 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8635 /*
8636 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8637 * translated code to check for pending interrupts.
8638 */
8639 gen_save_pc(ctx->base.pc_next + 4);
8640 ctx->base.is_jmp = DISAS_EXIT;
8641 }
8642 return;
8643
8644 cp0_unimplemented:
8645 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8646 register_name, reg, sel);
8647 }
8648 #endif /* TARGET_MIPS64 */
8649
8650 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8651 int u, int sel, int h)
8652 {
8653 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8654 TCGv t0 = tcg_temp_local_new();
8655
8656 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8657 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8658 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8659 tcg_gen_movi_tl(t0, -1);
8660 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8661 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8662 tcg_gen_movi_tl(t0, -1);
8663 } else if (u == 0) {
8664 switch (rt) {
8665 case 1:
8666 switch (sel) {
8667 case 1:
8668 gen_helper_mftc0_vpecontrol(t0, cpu_env);
8669 break;
8670 case 2:
8671 gen_helper_mftc0_vpeconf0(t0, cpu_env);
8672 break;
8673 default:
8674 goto die;
8675 break;
8676 }
8677 break;
8678 case 2:
8679 switch (sel) {
8680 case 1:
8681 gen_helper_mftc0_tcstatus(t0, cpu_env);
8682 break;
8683 case 2:
8684 gen_helper_mftc0_tcbind(t0, cpu_env);
8685 break;
8686 case 3:
8687 gen_helper_mftc0_tcrestart(t0, cpu_env);
8688 break;
8689 case 4:
8690 gen_helper_mftc0_tchalt(t0, cpu_env);
8691 break;
8692 case 5:
8693 gen_helper_mftc0_tccontext(t0, cpu_env);
8694 break;
8695 case 6:
8696 gen_helper_mftc0_tcschedule(t0, cpu_env);
8697 break;
8698 case 7:
8699 gen_helper_mftc0_tcschefback(t0, cpu_env);
8700 break;
8701 default:
8702 gen_mfc0(ctx, t0, rt, sel);
8703 break;
8704 }
8705 break;
8706 case 10:
8707 switch (sel) {
8708 case 0:
8709 gen_helper_mftc0_entryhi(t0, cpu_env);
8710 break;
8711 default:
8712 gen_mfc0(ctx, t0, rt, sel);
8713 break;
8714 }
8715 break;
8716 case 12:
8717 switch (sel) {
8718 case 0:
8719 gen_helper_mftc0_status(t0, cpu_env);
8720 break;
8721 default:
8722 gen_mfc0(ctx, t0, rt, sel);
8723 break;
8724 }
8725 break;
8726 case 13:
8727 switch (sel) {
8728 case 0:
8729 gen_helper_mftc0_cause(t0, cpu_env);
8730 break;
8731 default:
8732 goto die;
8733 break;
8734 }
8735 break;
8736 case 14:
8737 switch (sel) {
8738 case 0:
8739 gen_helper_mftc0_epc(t0, cpu_env);
8740 break;
8741 default:
8742 goto die;
8743 break;
8744 }
8745 break;
8746 case 15:
8747 switch (sel) {
8748 case 1:
8749 gen_helper_mftc0_ebase(t0, cpu_env);
8750 break;
8751 default:
8752 goto die;
8753 break;
8754 }
8755 break;
8756 case 16:
8757 switch (sel) {
8758 case 0:
8759 case 1:
8760 case 2:
8761 case 3:
8762 case 4:
8763 case 5:
8764 case 6:
8765 case 7:
8766 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8767 break;
8768 default:
8769 goto die;
8770 break;
8771 }
8772 break;
8773 case 23:
8774 switch (sel) {
8775 case 0:
8776 gen_helper_mftc0_debug(t0, cpu_env);
8777 break;
8778 default:
8779 gen_mfc0(ctx, t0, rt, sel);
8780 break;
8781 }
8782 break;
8783 default:
8784 gen_mfc0(ctx, t0, rt, sel);
8785 }
8786 } else {
8787 switch (sel) {
8788 /* GPR registers. */
8789 case 0:
8790 gen_helper_1e0i(mftgpr, t0, rt);
8791 break;
8792 /* Auxiliary CPU registers */
8793 case 1:
8794 switch (rt) {
8795 case 0:
8796 gen_helper_1e0i(mftlo, t0, 0);
8797 break;
8798 case 1:
8799 gen_helper_1e0i(mfthi, t0, 0);
8800 break;
8801 case 2:
8802 gen_helper_1e0i(mftacx, t0, 0);
8803 break;
8804 case 4:
8805 gen_helper_1e0i(mftlo, t0, 1);
8806 break;
8807 case 5:
8808 gen_helper_1e0i(mfthi, t0, 1);
8809 break;
8810 case 6:
8811 gen_helper_1e0i(mftacx, t0, 1);
8812 break;
8813 case 8:
8814 gen_helper_1e0i(mftlo, t0, 2);
8815 break;
8816 case 9:
8817 gen_helper_1e0i(mfthi, t0, 2);
8818 break;
8819 case 10:
8820 gen_helper_1e0i(mftacx, t0, 2);
8821 break;
8822 case 12:
8823 gen_helper_1e0i(mftlo, t0, 3);
8824 break;
8825 case 13:
8826 gen_helper_1e0i(mfthi, t0, 3);
8827 break;
8828 case 14:
8829 gen_helper_1e0i(mftacx, t0, 3);
8830 break;
8831 case 16:
8832 gen_helper_mftdsp(t0, cpu_env);
8833 break;
8834 default:
8835 goto die;
8836 }
8837 break;
8838 /* Floating point (COP1). */
8839 case 2:
8840 /* XXX: For now we support only a single FPU context. */
8841 if (h == 0) {
8842 TCGv_i32 fp0 = tcg_temp_new_i32();
8843
8844 gen_load_fpr32(ctx, fp0, rt);
8845 tcg_gen_ext_i32_tl(t0, fp0);
8846 tcg_temp_free_i32(fp0);
8847 } else {
8848 TCGv_i32 fp0 = tcg_temp_new_i32();
8849
8850 gen_load_fpr32h(ctx, fp0, rt);
8851 tcg_gen_ext_i32_tl(t0, fp0);
8852 tcg_temp_free_i32(fp0);
8853 }
8854 break;
8855 case 3:
8856 /* XXX: For now we support only a single FPU context. */
8857 gen_helper_1e0i(cfc1, t0, rt);
8858 break;
8859 /* COP2: Not implemented. */
8860 case 4:
8861 case 5:
8862 /* fall through */
8863 default:
8864 goto die;
8865 }
8866 }
8867 trace_mips_translate_tr("mftr", rt, u, sel, h);
8868 gen_store_gpr(t0, rd);
8869 tcg_temp_free(t0);
8870 return;
8871
8872 die:
8873 tcg_temp_free(t0);
8874 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8875 gen_reserved_instruction(ctx);
8876 }
8877
8878 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8879 int u, int sel, int h)
8880 {
8881 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8882 TCGv t0 = tcg_temp_local_new();
8883
8884 gen_load_gpr(t0, rt);
8885 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8886 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8887 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8888 /* NOP */
8889 ;
8890 } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8891 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8892 /* NOP */
8893 ;
8894 } else if (u == 0) {
8895 switch (rd) {
8896 case 1:
8897 switch (sel) {
8898 case 1:
8899 gen_helper_mttc0_vpecontrol(cpu_env, t0);
8900 break;
8901 case 2:
8902 gen_helper_mttc0_vpeconf0(cpu_env, t0);
8903 break;
8904 default:
8905 goto die;
8906 break;
8907 }
8908 break;
8909 case 2:
8910 switch (sel) {
8911 case 1:
8912 gen_helper_mttc0_tcstatus(cpu_env, t0);
8913 break;
8914 case 2:
8915 gen_helper_mttc0_tcbind(cpu_env, t0);
8916 break;
8917 case 3:
8918 gen_helper_mttc0_tcrestart(cpu_env, t0);
8919 break;
8920 case 4:
8921 gen_helper_mttc0_tchalt(cpu_env, t0);
8922 break;
8923 case 5:
8924 gen_helper_mttc0_tccontext(cpu_env, t0);
8925 break;
8926 case 6:
8927 gen_helper_mttc0_tcschedule(cpu_env, t0);
8928 break;
8929 case 7:
8930 gen_helper_mttc0_tcschefback(cpu_env, t0);
8931 break;
8932 default:
8933 gen_mtc0(ctx, t0, rd, sel);
8934 break;
8935 }
8936 break;
8937 case 10:
8938 switch (sel) {
8939 case 0:
8940 gen_helper_mttc0_entryhi(cpu_env, t0);
8941 break;
8942 default:
8943 gen_mtc0(ctx, t0, rd, sel);
8944 break;
8945 }
8946 break;
8947 case 12:
8948 switch (sel) {
8949 case 0:
8950 gen_helper_mttc0_status(cpu_env, t0);
8951 break;
8952 default:
8953 gen_mtc0(ctx, t0, rd, sel);
8954 break;
8955 }
8956 break;
8957 case 13:
8958 switch (sel) {
8959 case 0:
8960 gen_helper_mttc0_cause(cpu_env, t0);
8961 break;
8962 default:
8963 goto die;
8964 break;
8965 }
8966 break;
8967 case 15:
8968 switch (sel) {
8969 case 1:
8970 gen_helper_mttc0_ebase(cpu_env, t0);
8971 break;
8972 default:
8973 goto die;
8974 break;
8975 }
8976 break;
8977 case 23:
8978 switch (sel) {
8979 case 0:
8980 gen_helper_mttc0_debug(cpu_env, t0);
8981 break;
8982 default:
8983 gen_mtc0(ctx, t0, rd, sel);
8984 break;
8985 }
8986 break;
8987 default:
8988 gen_mtc0(ctx, t0, rd, sel);
8989 }
8990 } else {
8991 switch (sel) {
8992 /* GPR registers. */
8993 case 0:
8994 gen_helper_0e1i(mttgpr, t0, rd);
8995 break;
8996 /* Auxiliary CPU registers */
8997 case 1:
8998 switch (rd) {
8999 case 0:
9000 gen_helper_0e1i(mttlo, t0, 0);
9001 break;
9002 case 1:
9003 gen_helper_0e1i(mtthi, t0, 0);
9004 break;
9005 case 2:
9006 gen_helper_0e1i(mttacx, t0, 0);
9007 break;
9008 case 4:
9009 gen_helper_0e1i(mttlo, t0, 1);
9010 break;
9011 case 5:
9012 gen_helper_0e1i(mtthi, t0, 1);
9013 break;
9014 case 6:
9015 gen_helper_0e1i(mttacx, t0, 1);
9016 break;
9017 case 8:
9018 gen_helper_0e1i(mttlo, t0, 2);
9019 break;
9020 case 9:
9021 gen_helper_0e1i(mtthi, t0, 2);
9022 break;
9023 case 10:
9024 gen_helper_0e1i(mttacx, t0, 2);
9025 break;
9026 case 12:
9027 gen_helper_0e1i(mttlo, t0, 3);
9028 break;
9029 case 13:
9030 gen_helper_0e1i(mtthi, t0, 3);
9031 break;
9032 case 14:
9033 gen_helper_0e1i(mttacx, t0, 3);
9034 break;
9035 case 16:
9036 gen_helper_mttdsp(cpu_env, t0);
9037 break;
9038 default:
9039 goto die;
9040 }
9041 break;
9042 /* Floating point (COP1). */
9043 case 2:
9044 /* XXX: For now we support only a single FPU context. */
9045 if (h == 0) {
9046 TCGv_i32 fp0 = tcg_temp_new_i32();
9047
9048 tcg_gen_trunc_tl_i32(fp0, t0);
9049 gen_store_fpr32(ctx, fp0, rd);
9050 tcg_temp_free_i32(fp0);
9051 } else {
9052 TCGv_i32 fp0 = tcg_temp_new_i32();
9053
9054 tcg_gen_trunc_tl_i32(fp0, t0);
9055 gen_store_fpr32h(ctx, fp0, rd);
9056 tcg_temp_free_i32(fp0);
9057 }
9058 break;
9059 case 3:
9060 /* XXX: For now we support only a single FPU context. */
9061 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
9062 /* Stop translation as we may have changed hflags */
9063 ctx->base.is_jmp = DISAS_STOP;
9064 break;
9065 /* COP2: Not implemented. */
9066 case 4:
9067 case 5:
9068 /* fall through */
9069 default:
9070 goto die;
9071 }
9072 }
9073 trace_mips_translate_tr("mttr", rd, u, sel, h);
9074 tcg_temp_free(t0);
9075 return;
9076
9077 die:
9078 tcg_temp_free(t0);
9079 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9080 gen_reserved_instruction(ctx);
9081 }
9082
9083 static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
9084 int rt, int rd)
9085 {
9086 const char *opn = "ldst";
9087
9088 check_cp0_enabled(ctx);
9089 switch (opc) {
9090 case OPC_MFC0:
9091 if (rt == 0) {
9092 /* Treat as NOP. */
9093 return;
9094 }
9095 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9096 opn = "mfc0";
9097 break;
9098 case OPC_MTC0:
9099 {
9100 TCGv t0 = tcg_temp_new();
9101
9102 gen_load_gpr(t0, rt);
9103 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9104 tcg_temp_free(t0);
9105 }
9106 opn = "mtc0";
9107 break;
9108 #if defined(TARGET_MIPS64)
9109 case OPC_DMFC0:
9110 check_insn(ctx, ISA_MIPS3);
9111 if (rt == 0) {
9112 /* Treat as NOP. */
9113 return;
9114 }
9115 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9116 opn = "dmfc0";
9117 break;
9118 case OPC_DMTC0:
9119 check_insn(ctx, ISA_MIPS3);
9120 {
9121 TCGv t0 = tcg_temp_new();
9122
9123 gen_load_gpr(t0, rt);
9124 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9125 tcg_temp_free(t0);
9126 }
9127 opn = "dmtc0";
9128 break;
9129 #endif
9130 case OPC_MFHC0:
9131 check_mvh(ctx);
9132 if (rt == 0) {
9133 /* Treat as NOP. */
9134 return;
9135 }
9136 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9137 opn = "mfhc0";
9138 break;
9139 case OPC_MTHC0:
9140 check_mvh(ctx);
9141 {
9142 TCGv t0 = tcg_temp_new();
9143 gen_load_gpr(t0, rt);
9144 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9145 tcg_temp_free(t0);
9146 }
9147 opn = "mthc0";
9148 break;
9149 case OPC_MFTR:
9150 check_cp0_enabled(ctx);
9151 if (rd == 0) {
9152 /* Treat as NOP. */
9153 return;
9154 }
9155 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9156 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9157 opn = "mftr";
9158 break;
9159 case OPC_MTTR:
9160 check_cp0_enabled(ctx);
9161 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9162 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9163 opn = "mttr";
9164 break;
9165 case OPC_TLBWI:
9166 opn = "tlbwi";
9167 if (!env->tlb->helper_tlbwi) {
9168 goto die;
9169 }
9170 gen_helper_tlbwi(cpu_env);
9171 break;
9172 case OPC_TLBINV:
9173 opn = "tlbinv";
9174 if (ctx->ie >= 2) {
9175 if (!env->tlb->helper_tlbinv) {
9176 goto die;
9177 }
9178 gen_helper_tlbinv(cpu_env);
9179 } /* treat as nop if TLBINV not supported */
9180 break;
9181 case OPC_TLBINVF:
9182 opn = "tlbinvf";
9183 if (ctx->ie >= 2) {
9184 if (!env->tlb->helper_tlbinvf) {
9185 goto die;
9186 }
9187 gen_helper_tlbinvf(cpu_env);
9188 } /* treat as nop if TLBINV not supported */
9189 break;
9190 case OPC_TLBWR:
9191 opn = "tlbwr";
9192 if (!env->tlb->helper_tlbwr) {
9193 goto die;
9194 }
9195 gen_helper_tlbwr(cpu_env);
9196 break;
9197 case OPC_TLBP:
9198 opn = "tlbp";
9199 if (!env->tlb->helper_tlbp) {
9200 goto die;
9201 }
9202 gen_helper_tlbp(cpu_env);
9203 break;
9204 case OPC_TLBR:
9205 opn = "tlbr";
9206 if (!env->tlb->helper_tlbr) {
9207 goto die;
9208 }
9209 gen_helper_tlbr(cpu_env);
9210 break;
9211 case OPC_ERET: /* OPC_ERETNC */
9212 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9213 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9214 goto die;
9215 } else {
9216 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9217 if (ctx->opcode & (1 << bit_shift)) {
9218 /* OPC_ERETNC */
9219 opn = "eretnc";
9220 check_insn(ctx, ISA_MIPS_R5);
9221 gen_helper_eretnc(cpu_env);
9222 } else {
9223 /* OPC_ERET */
9224 opn = "eret";
9225 check_insn(ctx, ISA_MIPS2);
9226 gen_helper_eret(cpu_env);
9227 }
9228 ctx->base.is_jmp = DISAS_EXIT;
9229 }
9230 break;
9231 case OPC_DERET:
9232 opn = "deret";
9233 check_insn(ctx, ISA_MIPS_R1);
9234 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9235 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9236 goto die;
9237 }
9238 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9239 MIPS_INVAL(opn);
9240 gen_reserved_instruction(ctx);
9241 } else {
9242 gen_helper_deret(cpu_env);
9243 ctx->base.is_jmp = DISAS_EXIT;
9244 }
9245 break;
9246 case OPC_WAIT:
9247 opn = "wait";
9248 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
9249 if ((ctx->insn_flags & ISA_MIPS_R6) &&
9250 (ctx->hflags & MIPS_HFLAG_BMASK)) {
9251 goto die;
9252 }
9253 /* If we get an exception, we want to restart at next instruction */
9254 ctx->base.pc_next += 4;
9255 save_cpu_state(ctx, 1);
9256 ctx->base.pc_next -= 4;
9257 gen_helper_wait(cpu_env);
9258 ctx->base.is_jmp = DISAS_NORETURN;
9259 break;
9260 default:
9261 die:
9262 MIPS_INVAL(opn);
9263 gen_reserved_instruction(ctx);
9264 return;
9265 }
9266 (void)opn; /* avoid a compiler warning */
9267 }
9268 #endif /* !CONFIG_USER_ONLY */
9269
9270 /* CP1 Branches (before delay slot) */
9271 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9272 int32_t cc, int32_t offset)
9273 {
9274 target_ulong btarget;
9275 TCGv_i32 t0 = tcg_temp_new_i32();
9276
9277 if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9278 gen_reserved_instruction(ctx);
9279 goto out;
9280 }
9281
9282 if (cc != 0) {
9283 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
9284 }
9285
9286 btarget = ctx->base.pc_next + 4 + offset;
9287
9288 switch (op) {
9289 case OPC_BC1F:
9290 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9291 tcg_gen_not_i32(t0, t0);
9292 tcg_gen_andi_i32(t0, t0, 1);
9293 tcg_gen_extu_i32_tl(bcond, t0);
9294 goto not_likely;
9295 case OPC_BC1FL:
9296 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9297 tcg_gen_not_i32(t0, t0);
9298 tcg_gen_andi_i32(t0, t0, 1);
9299 tcg_gen_extu_i32_tl(bcond, t0);
9300 goto likely;
9301 case OPC_BC1T:
9302 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9303 tcg_gen_andi_i32(t0, t0, 1);
9304 tcg_gen_extu_i32_tl(bcond, t0);
9305 goto not_likely;
9306 case OPC_BC1TL:
9307 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9308 tcg_gen_andi_i32(t0, t0, 1);
9309 tcg_gen_extu_i32_tl(bcond, t0);
9310 likely:
9311 ctx->hflags |= MIPS_HFLAG_BL;
9312 break;
9313 case OPC_BC1FANY2:
9314 {
9315 TCGv_i32 t1 = tcg_temp_new_i32();
9316 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9317 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9318 tcg_gen_nand_i32(t0, t0, t1);
9319 tcg_temp_free_i32(t1);
9320 tcg_gen_andi_i32(t0, t0, 1);
9321 tcg_gen_extu_i32_tl(bcond, t0);
9322 }
9323 goto not_likely;
9324 case OPC_BC1TANY2:
9325 {
9326 TCGv_i32 t1 = tcg_temp_new_i32();
9327 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9328 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9329 tcg_gen_or_i32(t0, t0, t1);
9330 tcg_temp_free_i32(t1);
9331 tcg_gen_andi_i32(t0, t0, 1);
9332 tcg_gen_extu_i32_tl(bcond, t0);
9333 }
9334 goto not_likely;
9335 case OPC_BC1FANY4:
9336 {
9337 TCGv_i32 t1 = tcg_temp_new_i32();
9338 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9339 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9340 tcg_gen_and_i32(t0, t0, t1);
9341 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9342 tcg_gen_and_i32(t0, t0, t1);
9343 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9344 tcg_gen_nand_i32(t0, t0, t1);
9345 tcg_temp_free_i32(t1);
9346 tcg_gen_andi_i32(t0, t0, 1);
9347 tcg_gen_extu_i32_tl(bcond, t0);
9348 }
9349 goto not_likely;
9350 case OPC_BC1TANY4:
9351 {
9352 TCGv_i32 t1 = tcg_temp_new_i32();
9353 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9354 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9355 tcg_gen_or_i32(t0, t0, t1);
9356 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9357 tcg_gen_or_i32(t0, t0, t1);
9358 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9359 tcg_gen_or_i32(t0, t0, t1);
9360 tcg_temp_free_i32(t1);
9361 tcg_gen_andi_i32(t0, t0, 1);
9362 tcg_gen_extu_i32_tl(bcond, t0);
9363 }
9364 not_likely:
9365 ctx->hflags |= MIPS_HFLAG_BC;
9366 break;
9367 default:
9368 MIPS_INVAL("cp1 cond branch");
9369 gen_reserved_instruction(ctx);
9370 goto out;
9371 }
9372 ctx->btarget = btarget;
9373 ctx->hflags |= MIPS_HFLAG_BDS32;
9374 out:
9375 tcg_temp_free_i32(t0);
9376 }
9377
9378 /* R6 CP1 Branches */
9379 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9380 int32_t ft, int32_t offset,
9381 int delayslot_size)
9382 {
9383 target_ulong btarget;
9384 TCGv_i64 t0 = tcg_temp_new_i64();
9385
9386 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9387 #ifdef MIPS_DEBUG_DISAS
9388 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9389 "\n", ctx->base.pc_next);
9390 #endif
9391 gen_reserved_instruction(ctx);
9392 goto out;
9393 }
9394
9395 gen_load_fpr64(ctx, t0, ft);
9396 tcg_gen_andi_i64(t0, t0, 1);
9397
9398 btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9399
9400 switch (op) {
9401 case OPC_BC1EQZ:
9402 tcg_gen_xori_i64(t0, t0, 1);
9403 ctx->hflags |= MIPS_HFLAG_BC;
9404 break;
9405 case OPC_BC1NEZ:
9406 /* t0 already set */
9407 ctx->hflags |= MIPS_HFLAG_BC;
9408 break;
9409 default:
9410 MIPS_INVAL("cp1 cond branch");
9411 gen_reserved_instruction(ctx);
9412 goto out;
9413 }
9414
9415 tcg_gen_trunc_i64_tl(bcond, t0);
9416
9417 ctx->btarget = btarget;
9418
9419 switch (delayslot_size) {
9420 case 2:
9421 ctx->hflags |= MIPS_HFLAG_BDS16;
9422 break;
9423 case 4:
9424 ctx->hflags |= MIPS_HFLAG_BDS32;
9425 break;
9426 }
9427
9428 out:
9429 tcg_temp_free_i64(t0);
9430 }
9431
9432 /* Coprocessor 1 (FPU) */
9433
9434 #define FOP(func, fmt) (((fmt) << 21) | (func))
9435
9436 enum fopcode {
9437 OPC_ADD_S = FOP(0, FMT_S),
9438 OPC_SUB_S = FOP(1, FMT_S),
9439 OPC_MUL_S = FOP(2, FMT_S),
9440 OPC_DIV_S = FOP(3, FMT_S),
9441 OPC_SQRT_S = FOP(4, FMT_S),
9442 OPC_ABS_S = FOP(5, FMT_S),
9443 OPC_MOV_S = FOP(6, FMT_S),
9444 OPC_NEG_S = FOP(7, FMT_S),
9445 OPC_ROUND_L_S = FOP(8, FMT_S),
9446 OPC_TRUNC_L_S = FOP(9, FMT_S),
9447 OPC_CEIL_L_S = FOP(10, FMT_S),
9448 OPC_FLOOR_L_S = FOP(11, FMT_S),
9449 OPC_ROUND_W_S = FOP(12, FMT_S),
9450 OPC_TRUNC_W_S = FOP(13, FMT_S),
9451 OPC_CEIL_W_S = FOP(14, FMT_S),
9452 OPC_FLOOR_W_S = FOP(15, FMT_S),
9453 OPC_SEL_S = FOP(16, FMT_S),
9454 OPC_MOVCF_S = FOP(17, FMT_S),
9455 OPC_MOVZ_S = FOP(18, FMT_S),
9456 OPC_MOVN_S = FOP(19, FMT_S),
9457 OPC_SELEQZ_S = FOP(20, FMT_S),
9458 OPC_RECIP_S = FOP(21, FMT_S),
9459 OPC_RSQRT_S = FOP(22, FMT_S),
9460 OPC_SELNEZ_S = FOP(23, FMT_S),
9461 OPC_MADDF_S = FOP(24, FMT_S),
9462 OPC_MSUBF_S = FOP(25, FMT_S),
9463 OPC_RINT_S = FOP(26, FMT_S),
9464 OPC_CLASS_S = FOP(27, FMT_S),
9465 OPC_MIN_S = FOP(28, FMT_S),
9466 OPC_RECIP2_S = FOP(28, FMT_S),
9467 OPC_MINA_S = FOP(29, FMT_S),
9468 OPC_RECIP1_S = FOP(29, FMT_S),
9469 OPC_MAX_S = FOP(30, FMT_S),
9470 OPC_RSQRT1_S = FOP(30, FMT_S),
9471 OPC_MAXA_S = FOP(31, FMT_S),
9472 OPC_RSQRT2_S = FOP(31, FMT_S),
9473 OPC_CVT_D_S = FOP(33, FMT_S),
9474 OPC_CVT_W_S = FOP(36, FMT_S),
9475 OPC_CVT_L_S = FOP(37, FMT_S),
9476 OPC_CVT_PS_S = FOP(38, FMT_S),
9477 OPC_CMP_F_S = FOP(48, FMT_S),
9478 OPC_CMP_UN_S = FOP(49, FMT_S),
9479 OPC_CMP_EQ_S = FOP(50, FMT_S),
9480 OPC_CMP_UEQ_S = FOP(51, FMT_S),
9481 OPC_CMP_OLT_S = FOP(52, FMT_S),
9482 OPC_CMP_ULT_S = FOP(53, FMT_S),
9483 OPC_CMP_OLE_S = FOP(54, FMT_S),
9484 OPC_CMP_ULE_S = FOP(55, FMT_S),
9485 OPC_CMP_SF_S = FOP(56, FMT_S),
9486 OPC_CMP_NGLE_S = FOP(57, FMT_S),
9487 OPC_CMP_SEQ_S = FOP(58, FMT_S),
9488 OPC_CMP_NGL_S = FOP(59, FMT_S),
9489 OPC_CMP_LT_S = FOP(60, FMT_S),
9490 OPC_CMP_NGE_S = FOP(61, FMT_S),
9491 OPC_CMP_LE_S = FOP(62, FMT_S),
9492 OPC_CMP_NGT_S = FOP(63, FMT_S),
9493
9494 OPC_ADD_D = FOP(0, FMT_D),
9495 OPC_SUB_D = FOP(1, FMT_D),
9496 OPC_MUL_D = FOP(2, FMT_D),
9497 OPC_DIV_D = FOP(3, FMT_D),
9498 OPC_SQRT_D = FOP(4, FMT_D),
9499 OPC_ABS_D = FOP(5, FMT_D),
9500 OPC_MOV_D = FOP(6, FMT_D),
9501 OPC_NEG_D = FOP(7, FMT_D),
9502 OPC_ROUND_L_D = FOP(8, FMT_D),
9503 OPC_TRUNC_L_D = FOP(9, FMT_D),
9504 OPC_CEIL_L_D = FOP(10, FMT_D),
9505 OPC_FLOOR_L_D = FOP(11, FMT_D),
9506 OPC_ROUND_W_D = FOP(12, FMT_D),
9507 OPC_TRUNC_W_D = FOP(13, FMT_D),
9508 OPC_CEIL_W_D = FOP(14, FMT_D),
9509 OPC_FLOOR_W_D = FOP(15, FMT_D),
9510 OPC_SEL_D = FOP(16, FMT_D),
9511 OPC_MOVCF_D = FOP(17, FMT_D),
9512 OPC_MOVZ_D = FOP(18, FMT_D),
9513 OPC_MOVN_D = FOP(19, FMT_D),
9514 OPC_SELEQZ_D = FOP(20, FMT_D),
9515 OPC_RECIP_D = FOP(21, FMT_D),
9516 OPC_RSQRT_D = FOP(22, FMT_D),
9517 OPC_SELNEZ_D = FOP(23, FMT_D),
9518 OPC_MADDF_D = FOP(24, FMT_D),
9519 OPC_MSUBF_D = FOP(25, FMT_D),
9520 OPC_RINT_D = FOP(26, FMT_D),
9521 OPC_CLASS_D = FOP(27, FMT_D),
9522 OPC_MIN_D = FOP(28, FMT_D),
9523 OPC_RECIP2_D = FOP(28, FMT_D),
9524 OPC_MINA_D = FOP(29, FMT_D),
9525 OPC_RECIP1_D = FOP(29, FMT_D),
9526 OPC_MAX_D = FOP(30, FMT_D),
9527 OPC_RSQRT1_D = FOP(30, FMT_D),
9528 OPC_MAXA_D = FOP(31, FMT_D),
9529 OPC_RSQRT2_D = FOP(31, FMT_D),
9530 OPC_CVT_S_D = FOP(32, FMT_D),
9531 OPC_CVT_W_D = FOP(36, FMT_D),
9532 OPC_CVT_L_D = FOP(37, FMT_D),
9533 OPC_CMP_F_D = FOP(48, FMT_D),
9534 OPC_CMP_UN_D = FOP(49, FMT_D),
9535 OPC_CMP_EQ_D = FOP(50, FMT_D),
9536 OPC_CMP_UEQ_D = FOP(51, FMT_D),
9537 OPC_CMP_OLT_D = FOP(52, FMT_D),
9538 OPC_CMP_ULT_D = FOP(53, FMT_D),
9539 OPC_CMP_OLE_D = FOP(54, FMT_D),
9540 OPC_CMP_ULE_D = FOP(55, FMT_D),
9541 OPC_CMP_SF_D = FOP(56, FMT_D),
9542 OPC_CMP_NGLE_D = FOP(57, FMT_D),
9543 OPC_CMP_SEQ_D = FOP(58, FMT_D),
9544 OPC_CMP_NGL_D = FOP(59, FMT_D),
9545 OPC_CMP_LT_D = FOP(60, FMT_D),
9546 OPC_CMP_NGE_D = FOP(61, FMT_D),
9547 OPC_CMP_LE_D = FOP(62, FMT_D),
9548 OPC_CMP_NGT_D = FOP(63, FMT_D),
9549
9550 OPC_CVT_S_W = FOP(32, FMT_W),
9551 OPC_CVT_D_W = FOP(33, FMT_W),
9552 OPC_CVT_S_L = FOP(32, FMT_L),
9553 OPC_CVT_D_L = FOP(33, FMT_L),
9554 OPC_CVT_PS_PW = FOP(38, FMT_W),
9555
9556 OPC_ADD_PS = FOP(0, FMT_PS),
9557 OPC_SUB_PS = FOP(1, FMT_PS),
9558 OPC_MUL_PS = FOP(2, FMT_PS),
9559 OPC_DIV_PS = FOP(3, FMT_PS),
9560 OPC_ABS_PS = FOP(5, FMT_PS),
9561 OPC_MOV_PS = FOP(6, FMT_PS),
9562 OPC_NEG_PS = FOP(7, FMT_PS),
9563 OPC_MOVCF_PS = FOP(17, FMT_PS),
9564 OPC_MOVZ_PS = FOP(18, FMT_PS),
9565 OPC_MOVN_PS = FOP(19, FMT_PS),
9566 OPC_ADDR_PS = FOP(24, FMT_PS),
9567 OPC_MULR_PS = FOP(26, FMT_PS),
9568 OPC_RECIP2_PS = FOP(28, FMT_PS),
9569 OPC_RECIP1_PS = FOP(29, FMT_PS),
9570 OPC_RSQRT1_PS = FOP(30, FMT_PS),
9571 OPC_RSQRT2_PS = FOP(31, FMT_PS),
9572
9573 OPC_CVT_S_PU = FOP(32, FMT_PS),
9574 OPC_CVT_PW_PS = FOP(36, FMT_PS),
9575 OPC_CVT_S_PL = FOP(40, FMT_PS),
9576 OPC_PLL_PS = FOP(44, FMT_PS),
9577 OPC_PLU_PS = FOP(45, FMT_PS),
9578 OPC_PUL_PS = FOP(46, FMT_PS),
9579 OPC_PUU_PS = FOP(47, FMT_PS),
9580 OPC_CMP_F_PS = FOP(48, FMT_PS),
9581 OPC_CMP_UN_PS = FOP(49, FMT_PS),
9582 OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9583 OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9584 OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9585 OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9586 OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9587 OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9588 OPC_CMP_SF_PS = FOP(56, FMT_PS),
9589 OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9590 OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9591 OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9592 OPC_CMP_LT_PS = FOP(60, FMT_PS),
9593 OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9594 OPC_CMP_LE_PS = FOP(62, FMT_PS),
9595 OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9596 };
9597
9598 enum r6_f_cmp_op {
9599 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
9600 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
9601 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
9602 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
9603 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
9604 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
9605 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
9606 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
9607 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
9608 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
9609 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
9610 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9611 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
9612 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9613 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
9614 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9615 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
9616 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
9617 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
9618 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
9619 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9620 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
9621
9622 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
9623 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
9624 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
9625 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
9626 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
9627 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
9628 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
9629 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
9630 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
9631 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
9632 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
9633 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9634 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
9635 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9636 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
9637 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9638 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
9639 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
9640 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
9641 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
9642 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9643 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
9644 };
9645
9646 static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9647 {
9648 TCGv t0 = tcg_temp_new();
9649
9650 switch (opc) {
9651 case OPC_MFC1:
9652 {
9653 TCGv_i32 fp0 = tcg_temp_new_i32();
9654
9655 gen_load_fpr32(ctx, fp0, fs);
9656 tcg_gen_ext_i32_tl(t0, fp0);
9657 tcg_temp_free_i32(fp0);
9658 }
9659 gen_store_gpr(t0, rt);
9660 break;
9661 case OPC_MTC1:
9662 gen_load_gpr(t0, rt);
9663 {
9664 TCGv_i32 fp0 = tcg_temp_new_i32();
9665
9666 tcg_gen_trunc_tl_i32(fp0, t0);
9667 gen_store_fpr32(ctx, fp0, fs);
9668 tcg_temp_free_i32(fp0);
9669 }
9670 break;
9671 case OPC_CFC1:
9672 gen_helper_1e0i(cfc1, t0, fs);
9673 gen_store_gpr(t0, rt);
9674 break;
9675 case OPC_CTC1:
9676 gen_load_gpr(t0, rt);
9677 save_cpu_state(ctx, 0);
9678 gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9679 /* Stop translation as we may have changed hflags */
9680 ctx->base.is_jmp = DISAS_STOP;
9681 break;
9682 #if defined(TARGET_MIPS64)
9683 case OPC_DMFC1:
9684 gen_load_fpr64(ctx, t0, fs);
9685 gen_store_gpr(t0, rt);
9686 break;
9687 case OPC_DMTC1:
9688 gen_load_gpr(t0, rt);
9689 gen_store_fpr64(ctx, t0, fs);
9690 break;
9691 #endif
9692 case OPC_MFHC1:
9693 {
9694 TCGv_i32 fp0 = tcg_temp_new_i32();
9695
9696 gen_load_fpr32h(ctx, fp0, fs);
9697 tcg_gen_ext_i32_tl(t0, fp0);
9698 tcg_temp_free_i32(fp0);
9699 }
9700 gen_store_gpr(t0, rt);
9701 break;
9702 case OPC_MTHC1:
9703 gen_load_gpr(t0, rt);
9704 {
9705 TCGv_i32 fp0 = tcg_temp_new_i32();
9706
9707 tcg_gen_trunc_tl_i32(fp0, t0);
9708 gen_store_fpr32h(ctx, fp0, fs);
9709 tcg_temp_free_i32(fp0);
9710 }
9711 break;
9712 default:
9713 MIPS_INVAL("cp1 move");
9714 gen_reserved_instruction(ctx);
9715 goto out;
9716 }
9717
9718 out:
9719 tcg_temp_free(t0);
9720 }
9721
9722 static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9723 {
9724 TCGLabel *l1;
9725 TCGCond cond;
9726 TCGv_i32 t0;
9727
9728 if (rd == 0) {
9729 /* Treat as NOP. */
9730 return;
9731 }
9732
9733 if (tf) {
9734 cond = TCG_COND_EQ;
9735 } else {
9736 cond = TCG_COND_NE;
9737 }
9738
9739 l1 = gen_new_label();
9740 t0 = tcg_temp_new_i32();
9741 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9742 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9743 tcg_temp_free_i32(t0);
9744 gen_load_gpr(cpu_gpr[rd], rs);
9745 gen_set_label(l1);
9746 }
9747
9748 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9749 int tf)
9750 {
9751 int cond;
9752 TCGv_i32 t0 = tcg_temp_new_i32();
9753 TCGLabel *l1 = gen_new_label();
9754
9755 if (tf) {
9756 cond = TCG_COND_EQ;
9757 } else {
9758 cond = TCG_COND_NE;
9759 }
9760
9761 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9762 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9763 gen_load_fpr32(ctx, t0, fs);
9764 gen_store_fpr32(ctx, t0, fd);
9765 gen_set_label(l1);
9766 tcg_temp_free_i32(t0);
9767 }
9768
9769 static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9770 int tf)
9771 {
9772 int cond;
9773 TCGv_i32 t0 = tcg_temp_new_i32();
9774 TCGv_i64 fp0;
9775 TCGLabel *l1 = gen_new_label();
9776
9777 if (tf) {
9778 cond = TCG_COND_EQ;
9779 } else {
9780 cond = TCG_COND_NE;
9781 }
9782
9783 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9784 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9785 tcg_temp_free_i32(t0);
9786 fp0 = tcg_temp_new_i64();
9787 gen_load_fpr64(ctx, fp0, fs);
9788 gen_store_fpr64(ctx, fp0, fd);
9789 tcg_temp_free_i64(fp0);
9790 gen_set_label(l1);
9791 }
9792
9793 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9794 int cc, int tf)
9795 {
9796 int cond;
9797 TCGv_i32 t0 = tcg_temp_new_i32();
9798 TCGLabel *l1 = gen_new_label();
9799 TCGLabel *l2 = gen_new_label();
9800
9801 if (tf) {
9802 cond = TCG_COND_EQ;
9803 } else {
9804 cond = TCG_COND_NE;
9805 }
9806
9807 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9808 tcg_gen_brcondi_i32(cond, t0, 0, l1);
9809 gen_load_fpr32(ctx, t0, fs);
9810 gen_store_fpr32(ctx, t0, fd);
9811 gen_set_label(l1);
9812
9813 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9814 tcg_gen_brcondi_i32(cond, t0, 0, l2);
9815 gen_load_fpr32h(ctx, t0, fs);
9816 gen_store_fpr32h(ctx, t0, fd);
9817 tcg_temp_free_i32(t0);
9818 gen_set_label(l2);
9819 }
9820
9821 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9822 int fs)
9823 {
9824 TCGv_i32 t1 = tcg_const_i32(0);
9825 TCGv_i32 fp0 = tcg_temp_new_i32();
9826 TCGv_i32 fp1 = tcg_temp_new_i32();
9827 TCGv_i32 fp2 = tcg_temp_new_i32();
9828 gen_load_fpr32(ctx, fp0, fd);
9829 gen_load_fpr32(ctx, fp1, ft);
9830 gen_load_fpr32(ctx, fp2, fs);
9831
9832 switch (op1) {
9833 case OPC_SEL_S:
9834 tcg_gen_andi_i32(fp0, fp0, 1);
9835 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9836 break;
9837 case OPC_SELEQZ_S:
9838 tcg_gen_andi_i32(fp1, fp1, 1);
9839 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9840 break;
9841 case OPC_SELNEZ_S:
9842 tcg_gen_andi_i32(fp1, fp1, 1);
9843 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9844 break;
9845 default:
9846 MIPS_INVAL("gen_sel_s");
9847 gen_reserved_instruction(ctx);
9848 break;
9849 }
9850
9851 gen_store_fpr32(ctx, fp0, fd);
9852 tcg_temp_free_i32(fp2);
9853 tcg_temp_free_i32(fp1);
9854 tcg_temp_free_i32(fp0);
9855 tcg_temp_free_i32(t1);
9856 }
9857
9858 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9859 int fs)
9860 {
9861 TCGv_i64 t1 = tcg_const_i64(0);
9862 TCGv_i64 fp0 = tcg_temp_new_i64();
9863 TCGv_i64 fp1 = tcg_temp_new_i64();
9864 TCGv_i64 fp2 = tcg_temp_new_i64();
9865 gen_load_fpr64(ctx, fp0, fd);
9866 gen_load_fpr64(ctx, fp1, ft);
9867 gen_load_fpr64(ctx, fp2, fs);
9868
9869 switch (op1) {
9870 case OPC_SEL_D:
9871 tcg_gen_andi_i64(fp0, fp0, 1);
9872 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9873 break;
9874 case OPC_SELEQZ_D:
9875 tcg_gen_andi_i64(fp1, fp1, 1);
9876 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9877 break;
9878 case OPC_SELNEZ_D:
9879 tcg_gen_andi_i64(fp1, fp1, 1);
9880 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9881 break;
9882 default:
9883 MIPS_INVAL("gen_sel_d");
9884 gen_reserved_instruction(ctx);
9885 break;
9886 }
9887
9888 gen_store_fpr64(ctx, fp0, fd);
9889 tcg_temp_free_i64(fp2);
9890 tcg_temp_free_i64(fp1);
9891 tcg_temp_free_i64(fp0);
9892 tcg_temp_free_i64(t1);
9893 }
9894
9895 static void gen_farith(DisasContext *ctx, enum fopcode op1,
9896 int ft, int fs, int fd, int cc)
9897 {
9898 uint32_t func = ctx->opcode & 0x3f;
9899 switch (op1) {
9900 case OPC_ADD_S:
9901 {
9902 TCGv_i32 fp0 = tcg_temp_new_i32();
9903 TCGv_i32 fp1 = tcg_temp_new_i32();
9904
9905 gen_load_fpr32(ctx, fp0, fs);
9906 gen_load_fpr32(ctx, fp1, ft);
9907 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
9908 tcg_temp_free_i32(fp1);
9909 gen_store_fpr32(ctx, fp0, fd);
9910 tcg_temp_free_i32(fp0);
9911 }
9912 break;
9913 case OPC_SUB_S:
9914 {
9915 TCGv_i32 fp0 = tcg_temp_new_i32();
9916 TCGv_i32 fp1 = tcg_temp_new_i32();
9917
9918 gen_load_fpr32(ctx, fp0, fs);
9919 gen_load_fpr32(ctx, fp1, ft);
9920 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
9921 tcg_temp_free_i32(fp1);
9922 gen_store_fpr32(ctx, fp0, fd);
9923 tcg_temp_free_i32(fp0);
9924 }
9925 break;
9926 case OPC_MUL_S:
9927 {
9928 TCGv_i32 fp0 = tcg_temp_new_i32();
9929 TCGv_i32 fp1 = tcg_temp_new_i32();
9930
9931 gen_load_fpr32(ctx, fp0, fs);
9932 gen_load_fpr32(ctx, fp1, ft);
9933 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9934 tcg_temp_free_i32(fp1);
9935 gen_store_fpr32(ctx, fp0, fd);
9936 tcg_temp_free_i32(fp0);
9937 }
9938 break;
9939 case OPC_DIV_S:
9940 {
9941 TCGv_i32 fp0 = tcg_temp_new_i32();
9942 TCGv_i32 fp1 = tcg_temp_new_i32();
9943
9944 gen_load_fpr32(ctx, fp0, fs);
9945 gen_load_fpr32(ctx, fp1, ft);
9946 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9947 tcg_temp_free_i32(fp1);
9948 gen_store_fpr32(ctx, fp0, fd);
9949 tcg_temp_free_i32(fp0);
9950 }
9951 break;
9952 case OPC_SQRT_S:
9953 {
9954 TCGv_i32 fp0 = tcg_temp_new_i32();
9955
9956 gen_load_fpr32(ctx, fp0, fs);
9957 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9958 gen_store_fpr32(ctx, fp0, fd);
9959 tcg_temp_free_i32(fp0);
9960 }
9961 break;
9962 case OPC_ABS_S:
9963 {
9964 TCGv_i32 fp0 = tcg_temp_new_i32();
9965
9966 gen_load_fpr32(ctx, fp0, fs);
9967 if (ctx->abs2008) {
9968 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9969 } else {
9970 gen_helper_float_abs_s(fp0, fp0);
9971 }
9972 gen_store_fpr32(ctx, fp0, fd);
9973 tcg_temp_free_i32(fp0);
9974 }
9975 break;
9976 case OPC_MOV_S:
9977 {
9978 TCGv_i32 fp0 = tcg_temp_new_i32();
9979
9980 gen_load_fpr32(ctx, fp0, fs);
9981 gen_store_fpr32(ctx, fp0, fd);
9982 tcg_temp_free_i32(fp0);
9983 }
9984 break;
9985 case OPC_NEG_S:
9986 {
9987 TCGv_i32 fp0 = tcg_temp_new_i32();
9988
9989 gen_load_fpr32(ctx, fp0, fs);
9990 if (ctx->abs2008) {
9991 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9992 } else {
9993 gen_helper_float_chs_s(fp0, fp0);
9994 }
9995 gen_store_fpr32(ctx, fp0, fd);
9996 tcg_temp_free_i32(fp0);
9997 }
9998 break;
9999 case OPC_ROUND_L_S:
10000 check_cp1_64bitmode(ctx);
10001 {
10002 TCGv_i32 fp32 = tcg_temp_new_i32();
10003 TCGv_i64 fp64 = tcg_temp_new_i64();
10004
10005 gen_load_fpr32(ctx, fp32, fs);
10006 if (ctx->nan2008) {
10007 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10008 } else {
10009 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10010 }
10011 tcg_temp_free_i32(fp32);
10012 gen_store_fpr64(ctx, fp64, fd);
10013 tcg_temp_free_i64(fp64);
10014 }
10015 break;
10016 case OPC_TRUNC_L_S:
10017 check_cp1_64bitmode(ctx);
10018 {
10019 TCGv_i32 fp32 = tcg_temp_new_i32();
10020 TCGv_i64 fp64 = tcg_temp_new_i64();
10021
10022 gen_load_fpr32(ctx, fp32, fs);
10023 if (ctx->nan2008) {
10024 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10025 } else {
10026 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10027 }
10028 tcg_temp_free_i32(fp32);
10029 gen_store_fpr64(ctx, fp64, fd);
10030 tcg_temp_free_i64(fp64);
10031 }
10032 break;
10033 case OPC_CEIL_L_S:
10034 check_cp1_64bitmode(ctx);
10035 {
10036 TCGv_i32 fp32 = tcg_temp_new_i32();
10037 TCGv_i64 fp64 = tcg_temp_new_i64();
10038
10039 gen_load_fpr32(ctx, fp32, fs);
10040 if (ctx->nan2008) {
10041 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10042 } else {
10043 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10044 }
10045 tcg_temp_free_i32(fp32);
10046 gen_store_fpr64(ctx, fp64, fd);
10047 tcg_temp_free_i64(fp64);
10048 }
10049 break;
10050 case OPC_FLOOR_L_S:
10051 check_cp1_64bitmode(ctx);
10052 {
10053 TCGv_i32 fp32 = tcg_temp_new_i32();
10054 TCGv_i64 fp64 = tcg_temp_new_i64();
10055
10056 gen_load_fpr32(ctx, fp32, fs);
10057 if (ctx->nan2008) {
10058 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10059 } else {
10060 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10061 }
10062 tcg_temp_free_i32(fp32);
10063 gen_store_fpr64(ctx, fp64, fd);
10064 tcg_temp_free_i64(fp64);
10065 }
10066 break;
10067 case OPC_ROUND_W_S:
10068 {
10069 TCGv_i32 fp0 = tcg_temp_new_i32();
10070
10071 gen_load_fpr32(ctx, fp0, fs);
10072 if (ctx->nan2008) {
10073 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10074 } else {
10075 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10076 }
10077 gen_store_fpr32(ctx, fp0, fd);
10078 tcg_temp_free_i32(fp0);
10079 }
10080 break;
10081 case OPC_TRUNC_W_S:
10082 {
10083 TCGv_i32 fp0 = tcg_temp_new_i32();
10084
10085 gen_load_fpr32(ctx, fp0, fs);
10086 if (ctx->nan2008) {
10087 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10088 } else {
10089 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10090 }
10091 gen_store_fpr32(ctx, fp0, fd);
10092 tcg_temp_free_i32(fp0);
10093 }
10094 break;
10095 case OPC_CEIL_W_S:
10096 {
10097 TCGv_i32 fp0 = tcg_temp_new_i32();
10098
10099 gen_load_fpr32(ctx, fp0, fs);
10100 if (ctx->nan2008) {
10101 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10102 } else {
10103 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10104 }
10105 gen_store_fpr32(ctx, fp0, fd);
10106 tcg_temp_free_i32(fp0);
10107 }
10108 break;
10109 case OPC_FLOOR_W_S:
10110 {
10111 TCGv_i32 fp0 = tcg_temp_new_i32();
10112
10113 gen_load_fpr32(ctx, fp0, fs);
10114 if (ctx->nan2008) {
10115 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10116 } else {
10117 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10118 }
10119 gen_store_fpr32(ctx, fp0, fd);
10120 tcg_temp_free_i32(fp0);
10121 }
10122 break;
10123 case OPC_SEL_S:
10124 check_insn(ctx, ISA_MIPS_R6);
10125 gen_sel_s(ctx, op1, fd, ft, fs);
10126 break;
10127 case OPC_SELEQZ_S:
10128 check_insn(ctx, ISA_MIPS_R6);
10129 gen_sel_s(ctx, op1, fd, ft, fs);
10130 break;
10131 case OPC_SELNEZ_S:
10132 check_insn(ctx, ISA_MIPS_R6);
10133 gen_sel_s(ctx, op1, fd, ft, fs);
10134 break;
10135 case OPC_MOVCF_S:
10136 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10137 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10138 break;
10139 case OPC_MOVZ_S:
10140 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10141 {
10142 TCGLabel *l1 = gen_new_label();
10143 TCGv_i32 fp0;
10144
10145 if (ft != 0) {
10146 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10147 }
10148 fp0 = tcg_temp_new_i32();
10149 gen_load_fpr32(ctx, fp0, fs);
10150 gen_store_fpr32(ctx, fp0, fd);
10151 tcg_temp_free_i32(fp0);
10152 gen_set_label(l1);
10153 }
10154 break;
10155 case OPC_MOVN_S:
10156 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10157 {
10158 TCGLabel *l1 = gen_new_label();
10159 TCGv_i32 fp0;
10160
10161 if (ft != 0) {
10162 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10163 fp0 = tcg_temp_new_i32();
10164 gen_load_fpr32(ctx, fp0, fs);
10165 gen_store_fpr32(ctx, fp0, fd);
10166 tcg_temp_free_i32(fp0);
10167 gen_set_label(l1);
10168 }
10169 }
10170 break;
10171 case OPC_RECIP_S:
10172 {
10173 TCGv_i32 fp0 = tcg_temp_new_i32();
10174
10175 gen_load_fpr32(ctx, fp0, fs);
10176 gen_helper_float_recip_s(fp0, cpu_env, fp0);
10177 gen_store_fpr32(ctx, fp0, fd);
10178 tcg_temp_free_i32(fp0);
10179 }
10180 break;
10181 case OPC_RSQRT_S:
10182 {
10183 TCGv_i32 fp0 = tcg_temp_new_i32();
10184
10185 gen_load_fpr32(ctx, fp0, fs);
10186 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10187 gen_store_fpr32(ctx, fp0, fd);
10188 tcg_temp_free_i32(fp0);
10189 }
10190 break;
10191 case OPC_MADDF_S:
10192 check_insn(ctx, ISA_MIPS_R6);
10193 {
10194 TCGv_i32 fp0 = tcg_temp_new_i32();
10195 TCGv_i32 fp1 = tcg_temp_new_i32();
10196 TCGv_i32 fp2 = tcg_temp_new_i32();
10197 gen_load_fpr32(ctx, fp0, fs);
10198 gen_load_fpr32(ctx, fp1, ft);
10199 gen_load_fpr32(ctx, fp2, fd);
10200 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10201 gen_store_fpr32(ctx, fp2, fd);
10202 tcg_temp_free_i32(fp2);
10203 tcg_temp_free_i32(fp1);
10204 tcg_temp_free_i32(fp0);
10205 }
10206 break;
10207 case OPC_MSUBF_S:
10208 check_insn(ctx, ISA_MIPS_R6);
10209 {
10210 TCGv_i32 fp0 = tcg_temp_new_i32();
10211 TCGv_i32 fp1 = tcg_temp_new_i32();
10212 TCGv_i32 fp2 = tcg_temp_new_i32();
10213 gen_load_fpr32(ctx, fp0, fs);
10214 gen_load_fpr32(ctx, fp1, ft);
10215 gen_load_fpr32(ctx, fp2, fd);
10216 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10217 gen_store_fpr32(ctx, fp2, fd);
10218 tcg_temp_free_i32(fp2);
10219 tcg_temp_free_i32(fp1);
10220 tcg_temp_free_i32(fp0);
10221 }
10222 break;
10223 case OPC_RINT_S:
10224 check_insn(ctx, ISA_MIPS_R6);
10225 {
10226 TCGv_i32 fp0 = tcg_temp_new_i32();
10227 gen_load_fpr32(ctx, fp0, fs);
10228 gen_helper_float_rint_s(fp0, cpu_env, fp0);
10229 gen_store_fpr32(ctx, fp0, fd);
10230 tcg_temp_free_i32(fp0);
10231 }
10232 break;
10233 case OPC_CLASS_S:
10234 check_insn(ctx, ISA_MIPS_R6);
10235 {
10236 TCGv_i32 fp0 = tcg_temp_new_i32();
10237 gen_load_fpr32(ctx, fp0, fs);
10238 gen_helper_float_class_s(fp0, cpu_env, fp0);
10239 gen_store_fpr32(ctx, fp0, fd);
10240 tcg_temp_free_i32(fp0);
10241 }
10242 break;
10243 case OPC_MIN_S: /* OPC_RECIP2_S */
10244 if (ctx->insn_flags & ISA_MIPS_R6) {
10245 /* OPC_MIN_S */
10246 TCGv_i32 fp0 = tcg_temp_new_i32();
10247 TCGv_i32 fp1 = tcg_temp_new_i32();
10248 TCGv_i32 fp2 = tcg_temp_new_i32();
10249 gen_load_fpr32(ctx, fp0, fs);
10250 gen_load_fpr32(ctx, fp1, ft);
10251 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10252 gen_store_fpr32(ctx, fp2, fd);
10253 tcg_temp_free_i32(fp2);
10254 tcg_temp_free_i32(fp1);
10255 tcg_temp_free_i32(fp0);
10256 } else {
10257 /* OPC_RECIP2_S */
10258 check_cp1_64bitmode(ctx);
10259 {
10260 TCGv_i32 fp0 = tcg_temp_new_i32();
10261 TCGv_i32 fp1 = tcg_temp_new_i32();
10262
10263 gen_load_fpr32(ctx, fp0, fs);
10264 gen_load_fpr32(ctx, fp1, ft);
10265 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10266 tcg_temp_free_i32(fp1);
10267 gen_store_fpr32(ctx, fp0, fd);
10268 tcg_temp_free_i32(fp0);
10269 }
10270 }
10271 break;
10272 case OPC_MINA_S: /* OPC_RECIP1_S */
10273 if (ctx->insn_flags & ISA_MIPS_R6) {
10274 /* OPC_MINA_S */
10275 TCGv_i32 fp0 = tcg_temp_new_i32();
10276 TCGv_i32 fp1 = tcg_temp_new_i32();
10277 TCGv_i32 fp2 = tcg_temp_new_i32();
10278 gen_load_fpr32(ctx, fp0, fs);
10279 gen_load_fpr32(ctx, fp1, ft);
10280 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10281 gen_store_fpr32(ctx, fp2, fd);
10282 tcg_temp_free_i32(fp2);
10283 tcg_temp_free_i32(fp1);
10284 tcg_temp_free_i32(fp0);
10285 } else {
10286 /* OPC_RECIP1_S */
10287 check_cp1_64bitmode(ctx);
10288 {
10289 TCGv_i32 fp0 = tcg_temp_new_i32();
10290
10291 gen_load_fpr32(ctx, fp0, fs);
10292 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10293 gen_store_fpr32(ctx, fp0, fd);
10294 tcg_temp_free_i32(fp0);
10295 }
10296 }
10297 break;
10298 case OPC_MAX_S: /* OPC_RSQRT1_S */
10299 if (ctx->insn_flags & ISA_MIPS_R6) {
10300 /* OPC_MAX_S */
10301 TCGv_i32 fp0 = tcg_temp_new_i32();
10302 TCGv_i32 fp1 = tcg_temp_new_i32();
10303 gen_load_fpr32(ctx, fp0, fs);
10304 gen_load_fpr32(ctx, fp1, ft);
10305 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10306 gen_store_fpr32(ctx, fp1, fd);
10307 tcg_temp_free_i32(fp1);
10308 tcg_temp_free_i32(fp0);
10309 } else {
10310 /* OPC_RSQRT1_S */
10311 check_cp1_64bitmode(ctx);
10312 {
10313 TCGv_i32 fp0 = tcg_temp_new_i32();
10314
10315 gen_load_fpr32(ctx, fp0, fs);
10316 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10317 gen_store_fpr32(ctx, fp0, fd);
10318 tcg_temp_free_i32(fp0);
10319 }
10320 }
10321 break;
10322 case OPC_MAXA_S: /* OPC_RSQRT2_S */
10323 if (ctx->insn_flags & ISA_MIPS_R6) {
10324 /* OPC_MAXA_S */
10325 TCGv_i32 fp0 = tcg_temp_new_i32();
10326 TCGv_i32 fp1 = tcg_temp_new_i32();
10327 gen_load_fpr32(ctx, fp0, fs);
10328 gen_load_fpr32(ctx, fp1, ft);
10329 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10330 gen_store_fpr32(ctx, fp1, fd);
10331 tcg_temp_free_i32(fp1);
10332 tcg_temp_free_i32(fp0);
10333 } else {
10334 /* OPC_RSQRT2_S */
10335 check_cp1_64bitmode(ctx);
10336 {
10337 TCGv_i32 fp0 = tcg_temp_new_i32();
10338 TCGv_i32 fp1 = tcg_temp_new_i32();
10339
10340 gen_load_fpr32(ctx, fp0, fs);
10341 gen_load_fpr32(ctx, fp1, ft);
10342 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10343 tcg_temp_free_i32(fp1);
10344 gen_store_fpr32(ctx, fp0, fd);
10345 tcg_temp_free_i32(fp0);
10346 }
10347 }
10348 break;
10349 case OPC_CVT_D_S:
10350 check_cp1_registers(ctx, fd);
10351 {
10352 TCGv_i32 fp32 = tcg_temp_new_i32();
10353 TCGv_i64 fp64 = tcg_temp_new_i64();
10354
10355 gen_load_fpr32(ctx, fp32, fs);
10356 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10357 tcg_temp_free_i32(fp32);
10358 gen_store_fpr64(ctx, fp64, fd);
10359 tcg_temp_free_i64(fp64);
10360 }
10361 break;
10362 case OPC_CVT_W_S:
10363 {
10364 TCGv_i32 fp0 = tcg_temp_new_i32();
10365
10366 gen_load_fpr32(ctx, fp0, fs);
10367 if (ctx->nan2008) {
10368 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10369 } else {
10370 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10371 }
10372 gen_store_fpr32(ctx, fp0, fd);
10373 tcg_temp_free_i32(fp0);
10374 }
10375 break;
10376 case OPC_CVT_L_S:
10377 check_cp1_64bitmode(ctx);
10378 {
10379 TCGv_i32 fp32 = tcg_temp_new_i32();
10380 TCGv_i64 fp64 = tcg_temp_new_i64();
10381
10382 gen_load_fpr32(ctx, fp32, fs);
10383 if (ctx->nan2008) {
10384 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10385 } else {
10386 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10387 }
10388 tcg_temp_free_i32(fp32);
10389 gen_store_fpr64(ctx, fp64, fd);
10390 tcg_temp_free_i64(fp64);
10391 }
10392 break;
10393 case OPC_CVT_PS_S:
10394 check_ps(ctx);
10395 {
10396 TCGv_i64 fp64 = tcg_temp_new_i64();
10397 TCGv_i32 fp32_0 = tcg_temp_new_i32();
10398 TCGv_i32 fp32_1 = tcg_temp_new_i32();
10399
10400 gen_load_fpr32(ctx, fp32_0, fs);
10401 gen_load_fpr32(ctx, fp32_1, ft);
10402 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10403 tcg_temp_free_i32(fp32_1);
10404 tcg_temp_free_i32(fp32_0);
10405 gen_store_fpr64(ctx, fp64, fd);
10406 tcg_temp_free_i64(fp64);
10407 }
10408 break;
10409 case OPC_CMP_F_S:
10410 case OPC_CMP_UN_S:
10411 case OPC_CMP_EQ_S:
10412 case OPC_CMP_UEQ_S:
10413 case OPC_CMP_OLT_S:
10414 case OPC_CMP_ULT_S:
10415 case OPC_CMP_OLE_S:
10416 case OPC_CMP_ULE_S:
10417 case OPC_CMP_SF_S:
10418 case OPC_CMP_NGLE_S:
10419 case OPC_CMP_SEQ_S:
10420 case OPC_CMP_NGL_S:
10421 case OPC_CMP_LT_S:
10422 case OPC_CMP_NGE_S:
10423 case OPC_CMP_LE_S:
10424 case OPC_CMP_NGT_S:
10425 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10426 if (ctx->opcode & (1 << 6)) {
10427 gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
10428 } else {
10429 gen_cmp_s(ctx, func - 48, ft, fs, cc);
10430 }
10431 break;
10432 case OPC_ADD_D:
10433 check_cp1_registers(ctx, fs | ft | fd);
10434 {
10435 TCGv_i64 fp0 = tcg_temp_new_i64();
10436 TCGv_i64 fp1 = tcg_temp_new_i64();
10437
10438 gen_load_fpr64(ctx, fp0, fs);
10439 gen_load_fpr64(ctx, fp1, ft);
10440 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10441 tcg_temp_free_i64(fp1);
10442 gen_store_fpr64(ctx, fp0, fd);
10443 tcg_temp_free_i64(fp0);
10444 }
10445 break;
10446 case OPC_SUB_D:
10447 check_cp1_registers(ctx, fs | ft | fd);
10448 {
10449 TCGv_i64 fp0 = tcg_temp_new_i64();
10450 TCGv_i64 fp1 = tcg_temp_new_i64();
10451
10452 gen_load_fpr64(ctx, fp0, fs);
10453 gen_load_fpr64(ctx, fp1, ft);
10454 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10455 tcg_temp_free_i64(fp1);
10456 gen_store_fpr64(ctx, fp0, fd);
10457 tcg_temp_free_i64(fp0);
10458 }
10459 break;
10460 case OPC_MUL_D:
10461 check_cp1_registers(ctx, fs | ft | fd);
10462 {
10463 TCGv_i64 fp0 = tcg_temp_new_i64();
10464 TCGv_i64 fp1 = tcg_temp_new_i64();
10465
10466 gen_load_fpr64(ctx, fp0, fs);
10467 gen_load_fpr64(ctx, fp1, ft);
10468 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10469 tcg_temp_free_i64(fp1);
10470 gen_store_fpr64(ctx, fp0, fd);
10471 tcg_temp_free_i64(fp0);
10472 }
10473 break;
10474 case OPC_DIV_D:
10475 check_cp1_registers(ctx, fs | ft | fd);
10476 {
10477 TCGv_i64 fp0 = tcg_temp_new_i64();
10478 TCGv_i64 fp1 = tcg_temp_new_i64();
10479
10480 gen_load_fpr64(ctx, fp0, fs);
10481 gen_load_fpr64(ctx, fp1, ft);
10482 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10483 tcg_temp_free_i64(fp1);
10484 gen_store_fpr64(ctx, fp0, fd);
10485 tcg_temp_free_i64(fp0);
10486 }
10487 break;
10488 case OPC_SQRT_D:
10489 check_cp1_registers(ctx, fs | fd);
10490 {
10491 TCGv_i64 fp0 = tcg_temp_new_i64();
10492
10493 gen_load_fpr64(ctx, fp0, fs);
10494 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10495 gen_store_fpr64(ctx, fp0, fd);
10496 tcg_temp_free_i64(fp0);
10497 }
10498 break;
10499 case OPC_ABS_D:
10500 check_cp1_registers(ctx, fs | fd);
10501 {
10502 TCGv_i64 fp0 = tcg_temp_new_i64();
10503
10504 gen_load_fpr64(ctx, fp0, fs);
10505 if (ctx->abs2008) {
10506 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10507 } else {
10508 gen_helper_float_abs_d(fp0, fp0);
10509 }
10510 gen_store_fpr64(ctx, fp0, fd);
10511 tcg_temp_free_i64(fp0);
10512 }
10513 break;
10514 case OPC_MOV_D:
10515 check_cp1_registers(ctx, fs | fd);
10516 {
10517 TCGv_i64 fp0 = tcg_temp_new_i64();
10518
10519 gen_load_fpr64(ctx, fp0, fs);
10520 gen_store_fpr64(ctx, fp0, fd);
10521 tcg_temp_free_i64(fp0);
10522 }
10523 break;
10524 case OPC_NEG_D:
10525 check_cp1_registers(ctx, fs | fd);
10526 {
10527 TCGv_i64 fp0 = tcg_temp_new_i64();
10528
10529 gen_load_fpr64(ctx, fp0, fs);
10530 if (ctx->abs2008) {
10531 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10532 } else {
10533 gen_helper_float_chs_d(fp0, fp0);
10534 }
10535 gen_store_fpr64(ctx, fp0, fd);
10536 tcg_temp_free_i64(fp0);
10537 }
10538 break;
10539 case OPC_ROUND_L_D:
10540 check_cp1_64bitmode(ctx);
10541 {
10542 TCGv_i64 fp0 = tcg_temp_new_i64();
10543
10544 gen_load_fpr64(ctx, fp0, fs);
10545 if (ctx->nan2008) {
10546 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10547 } else {
10548 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10549 }
10550 gen_store_fpr64(ctx, fp0, fd);
10551 tcg_temp_free_i64(fp0);
10552 }
10553 break;
10554 case OPC_TRUNC_L_D:
10555 check_cp1_64bitmode(ctx);
10556 {
10557 TCGv_i64 fp0 = tcg_temp_new_i64();
10558
10559 gen_load_fpr64(ctx, fp0, fs);
10560 if (ctx->nan2008) {
10561 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10562 } else {
10563 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10564 }
10565 gen_store_fpr64(ctx, fp0, fd);
10566 tcg_temp_free_i64(fp0);
10567 }
10568 break;
10569 case OPC_CEIL_L_D:
10570 check_cp1_64bitmode(ctx);
10571 {
10572 TCGv_i64 fp0 = tcg_temp_new_i64();
10573
10574 gen_load_fpr64(ctx, fp0, fs);
10575 if (ctx->nan2008) {
10576 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10577 } else {
10578 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10579 }
10580 gen_store_fpr64(ctx, fp0, fd);
10581 tcg_temp_free_i64(fp0);
10582 }
10583 break;
10584 case OPC_FLOOR_L_D:
10585 check_cp1_64bitmode(ctx);
10586 {
10587 TCGv_i64 fp0 = tcg_temp_new_i64();
10588
10589 gen_load_fpr64(ctx, fp0, fs);
10590 if (ctx->nan2008) {
10591 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10592 } else {
10593 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10594 }
10595 gen_store_fpr64(ctx, fp0, fd);
10596 tcg_temp_free_i64(fp0);
10597 }
10598 break;
10599 case OPC_ROUND_W_D:
10600 check_cp1_registers(ctx, fs);
10601 {
10602 TCGv_i32 fp32 = tcg_temp_new_i32();
10603 TCGv_i64 fp64 = tcg_temp_new_i64();
10604
10605 gen_load_fpr64(ctx, fp64, fs);
10606 if (ctx->nan2008) {
10607 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10608 } else {
10609 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10610 }
10611 tcg_temp_free_i64(fp64);
10612 gen_store_fpr32(ctx, fp32, fd);
10613 tcg_temp_free_i32(fp32);
10614 }
10615 break;
10616 case OPC_TRUNC_W_D:
10617 check_cp1_registers(ctx, fs);
10618 {
10619 TCGv_i32 fp32 = tcg_temp_new_i32();
10620 TCGv_i64 fp64 = tcg_temp_new_i64();
10621
10622 gen_load_fpr64(ctx, fp64, fs);
10623 if (ctx->nan2008) {
10624 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10625 } else {
10626 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10627 }
10628 tcg_temp_free_i64(fp64);
10629 gen_store_fpr32(ctx, fp32, fd);
10630 tcg_temp_free_i32(fp32);
10631 }
10632 break;
10633 case OPC_CEIL_W_D:
10634 check_cp1_registers(ctx, fs);
10635 {
10636 TCGv_i32 fp32 = tcg_temp_new_i32();
10637 TCGv_i64 fp64 = tcg_temp_new_i64();
10638
10639 gen_load_fpr64(ctx, fp64, fs);
10640 if (ctx->nan2008) {
10641 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10642 } else {
10643 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10644 }
10645 tcg_temp_free_i64(fp64);
10646 gen_store_fpr32(ctx, fp32, fd);
10647 tcg_temp_free_i32(fp32);
10648 }
10649 break;
10650 case OPC_FLOOR_W_D:
10651 check_cp1_registers(ctx, fs);
10652 {
10653 TCGv_i32 fp32 = tcg_temp_new_i32();
10654 TCGv_i64 fp64 = tcg_temp_new_i64();
10655
10656 gen_load_fpr64(ctx, fp64, fs);
10657 if (ctx->nan2008) {
10658 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10659 } else {
10660 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10661 }
10662 tcg_temp_free_i64(fp64);
10663 gen_store_fpr32(ctx, fp32, fd);
10664 tcg_temp_free_i32(fp32);
10665 }
10666 break;
10667 case OPC_SEL_D:
10668 check_insn(ctx, ISA_MIPS_R6);
10669 gen_sel_d(ctx, op1, fd, ft, fs);
10670 break;
10671 case OPC_SELEQZ_D:
10672 check_insn(ctx, ISA_MIPS_R6);
10673 gen_sel_d(ctx, op1, fd, ft, fs);
10674 break;
10675 case OPC_SELNEZ_D:
10676 check_insn(ctx, ISA_MIPS_R6);
10677 gen_sel_d(ctx, op1, fd, ft, fs);
10678 break;
10679 case OPC_MOVCF_D:
10680 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10681 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10682 break;
10683 case OPC_MOVZ_D:
10684 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10685 {
10686 TCGLabel *l1 = gen_new_label();
10687 TCGv_i64 fp0;
10688
10689 if (ft != 0) {
10690 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10691 }
10692 fp0 = tcg_temp_new_i64();
10693 gen_load_fpr64(ctx, fp0, fs);
10694 gen_store_fpr64(ctx, fp0, fd);
10695 tcg_temp_free_i64(fp0);
10696 gen_set_label(l1);
10697 }
10698 break;
10699 case OPC_MOVN_D:
10700 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10701 {
10702 TCGLabel *l1 = gen_new_label();
10703 TCGv_i64 fp0;
10704
10705 if (ft != 0) {
10706 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10707 fp0 = tcg_temp_new_i64();
10708 gen_load_fpr64(ctx, fp0, fs);
10709 gen_store_fpr64(ctx, fp0, fd);
10710 tcg_temp_free_i64(fp0);
10711 gen_set_label(l1);
10712 }
10713 }
10714 break;
10715 case OPC_RECIP_D:
10716 check_cp1_registers(ctx, fs | fd);
10717 {
10718 TCGv_i64 fp0 = tcg_temp_new_i64();
10719
10720 gen_load_fpr64(ctx, fp0, fs);
10721 gen_helper_float_recip_d(fp0, cpu_env, fp0);
10722 gen_store_fpr64(ctx, fp0, fd);
10723 tcg_temp_free_i64(fp0);
10724 }
10725 break;
10726 case OPC_RSQRT_D:
10727 check_cp1_registers(ctx, fs | fd);
10728 {
10729 TCGv_i64 fp0 = tcg_temp_new_i64();
10730
10731 gen_load_fpr64(ctx, fp0, fs);
10732 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10733 gen_store_fpr64(ctx, fp0, fd);
10734 tcg_temp_free_i64(fp0);
10735 }
10736 break;
10737 case OPC_MADDF_D:
10738 check_insn(ctx, ISA_MIPS_R6);
10739 {
10740 TCGv_i64 fp0 = tcg_temp_new_i64();
10741 TCGv_i64 fp1 = tcg_temp_new_i64();
10742 TCGv_i64 fp2 = tcg_temp_new_i64();
10743 gen_load_fpr64(ctx, fp0, fs);
10744 gen_load_fpr64(ctx, fp1, ft);
10745 gen_load_fpr64(ctx, fp2, fd);
10746 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10747 gen_store_fpr64(ctx, fp2, fd);
10748 tcg_temp_free_i64(fp2);
10749 tcg_temp_free_i64(fp1);
10750 tcg_temp_free_i64(fp0);
10751 }
10752 break;
10753 case OPC_MSUBF_D:
10754 check_insn(ctx, ISA_MIPS_R6);
10755 {
10756 TCGv_i64 fp0 = tcg_temp_new_i64();
10757 TCGv_i64 fp1 = tcg_temp_new_i64();
10758 TCGv_i64 fp2 = tcg_temp_new_i64();
10759 gen_load_fpr64(ctx, fp0, fs);
10760 gen_load_fpr64(ctx, fp1, ft);
10761 gen_load_fpr64(ctx, fp2, fd);
10762 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10763 gen_store_fpr64(ctx, fp2, fd);
10764 tcg_temp_free_i64(fp2);
10765 tcg_temp_free_i64(fp1);
10766 tcg_temp_free_i64(fp0);
10767 }
10768 break;
10769 case OPC_RINT_D:
10770 check_insn(ctx, ISA_MIPS_R6);
10771 {
10772 TCGv_i64 fp0 = tcg_temp_new_i64();
10773 gen_load_fpr64(ctx, fp0, fs);
10774 gen_helper_float_rint_d(fp0, cpu_env, fp0);
10775 gen_store_fpr64(ctx, fp0, fd);
10776 tcg_temp_free_i64(fp0);
10777 }
10778 break;
10779 case OPC_CLASS_D:
10780 check_insn(ctx, ISA_MIPS_R6);
10781 {
10782 TCGv_i64 fp0 = tcg_temp_new_i64();
10783 gen_load_fpr64(ctx, fp0, fs);
10784 gen_helper_float_class_d(fp0, cpu_env, fp0);
10785 gen_store_fpr64(ctx, fp0, fd);
10786 tcg_temp_free_i64(fp0);
10787 }
10788 break;
10789 case OPC_MIN_D: /* OPC_RECIP2_D */
10790 if (ctx->insn_flags & ISA_MIPS_R6) {
10791 /* OPC_MIN_D */
10792 TCGv_i64 fp0 = tcg_temp_new_i64();
10793 TCGv_i64 fp1 = tcg_temp_new_i64();
10794 gen_load_fpr64(ctx, fp0, fs);
10795 gen_load_fpr64(ctx, fp1, ft);
10796 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10797 gen_store_fpr64(ctx, fp1, fd);
10798 tcg_temp_free_i64(fp1);
10799 tcg_temp_free_i64(fp0);
10800 } else {
10801 /* OPC_RECIP2_D */
10802 check_cp1_64bitmode(ctx);
10803 {
10804 TCGv_i64 fp0 = tcg_temp_new_i64();
10805 TCGv_i64 fp1 = tcg_temp_new_i64();
10806
10807 gen_load_fpr64(ctx, fp0, fs);
10808 gen_load_fpr64(ctx, fp1, ft);
10809 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10810 tcg_temp_free_i64(fp1);
10811 gen_store_fpr64(ctx, fp0, fd);
10812 tcg_temp_free_i64(fp0);
10813 }
10814 }
10815 break;
10816 case OPC_MINA_D: /* OPC_RECIP1_D */
10817 if (ctx->insn_flags & ISA_MIPS_R6) {
10818 /* OPC_MINA_D */
10819 TCGv_i64 fp0 = tcg_temp_new_i64();
10820 TCGv_i64 fp1 = tcg_temp_new_i64();
10821 gen_load_fpr64(ctx, fp0, fs);
10822 gen_load_fpr64(ctx, fp1, ft);
10823 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10824 gen_store_fpr64(ctx, fp1, fd);
10825 tcg_temp_free_i64(fp1);
10826 tcg_temp_free_i64(fp0);
10827 } else {
10828 /* OPC_RECIP1_D */
10829 check_cp1_64bitmode(ctx);
10830 {
10831 TCGv_i64 fp0 = tcg_temp_new_i64();
10832
10833 gen_load_fpr64(ctx, fp0, fs);
10834 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10835 gen_store_fpr64(ctx, fp0, fd);
10836 tcg_temp_free_i64(fp0);
10837 }
10838 }
10839 break;
10840 case OPC_MAX_D: /* OPC_RSQRT1_D */
10841 if (ctx->insn_flags & ISA_MIPS_R6) {
10842 /* OPC_MAX_D */
10843 TCGv_i64 fp0 = tcg_temp_new_i64();
10844 TCGv_i64 fp1 = tcg_temp_new_i64();
10845 gen_load_fpr64(ctx, fp0, fs);
10846 gen_load_fpr64(ctx, fp1, ft);
10847 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10848 gen_store_fpr64(ctx, fp1, fd);
10849 tcg_temp_free_i64(fp1);
10850 tcg_temp_free_i64(fp0);
10851 } else {
10852 /* OPC_RSQRT1_D */
10853 check_cp1_64bitmode(ctx);
10854 {
10855 TCGv_i64 fp0 = tcg_temp_new_i64();
10856
10857 gen_load_fpr64(ctx, fp0, fs);
10858 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10859 gen_store_fpr64(ctx, fp0, fd);
10860 tcg_temp_free_i64(fp0);
10861 }
10862 }
10863 break;
10864 case OPC_MAXA_D: /* OPC_RSQRT2_D */
10865 if (ctx->insn_flags & ISA_MIPS_R6) {
10866 /* OPC_MAXA_D */
10867 TCGv_i64 fp0 = tcg_temp_new_i64();
10868 TCGv_i64 fp1 = tcg_temp_new_i64();
10869 gen_load_fpr64(ctx, fp0, fs);
10870 gen_load_fpr64(ctx, fp1, ft);
10871 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
10872 gen_store_fpr64(ctx, fp1, fd);
10873 tcg_temp_free_i64(fp1);
10874 tcg_temp_free_i64(fp0);
10875 } else {
10876 /* OPC_RSQRT2_D */
10877 check_cp1_64bitmode(ctx);
10878 {
10879 TCGv_i64 fp0 = tcg_temp_new_i64();
10880 TCGv_i64 fp1 = tcg_temp_new_i64();
10881
10882 gen_load_fpr64(ctx, fp0, fs);
10883 gen_load_fpr64(ctx, fp1, ft);
10884 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10885 tcg_temp_free_i64(fp1);
10886 gen_store_fpr64(ctx, fp0, fd);
10887 tcg_temp_free_i64(fp0);
10888 }
10889 }
10890 break;
10891 case OPC_CMP_F_D:
10892 case OPC_CMP_UN_D:
10893 case OPC_CMP_EQ_D:
10894 case OPC_CMP_UEQ_D:
10895 case OPC_CMP_OLT_D:
10896 case OPC_CMP_ULT_D:
10897 case OPC_CMP_OLE_D:
10898 case OPC_CMP_ULE_D:
10899 case OPC_CMP_SF_D:
10900 case OPC_CMP_NGLE_D:
10901 case OPC_CMP_SEQ_D:
10902 case OPC_CMP_NGL_D:
10903 case OPC_CMP_LT_D:
10904 case OPC_CMP_NGE_D:
10905 case OPC_CMP_LE_D:
10906 case OPC_CMP_NGT_D:
10907 check_insn_opc_removed(ctx, ISA_MIPS_R6);
10908 if (ctx->opcode & (1 << 6)) {
10909 gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10910 } else {
10911 gen_cmp_d(ctx, func - 48, ft, fs, cc);
10912 }
10913 break;
10914 case OPC_CVT_S_D:
10915 check_cp1_registers(ctx, fs);
10916 {
10917 TCGv_i32 fp32 = tcg_temp_new_i32();
10918 TCGv_i64 fp64 = tcg_temp_new_i64();
10919
10920 gen_load_fpr64(ctx, fp64, fs);
10921 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
10922 tcg_temp_free_i64(fp64);
10923 gen_store_fpr32(ctx, fp32, fd);
10924 tcg_temp_free_i32(fp32);
10925 }
10926 break;
10927 case OPC_CVT_W_D:
10928 check_cp1_registers(ctx, fs);
10929 {
10930 TCGv_i32 fp32 = tcg_temp_new_i32();
10931 TCGv_i64 fp64 = tcg_temp_new_i64();
10932
10933 gen_load_fpr64(ctx, fp64, fs);
10934 if (ctx->nan2008) {
10935 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10936 } else {
10937 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10938 }
10939 tcg_temp_free_i64(fp64);
10940 gen_store_fpr32(ctx, fp32, fd);
10941 tcg_temp_free_i32(fp32);
10942 }
10943 break;
10944 case OPC_CVT_L_D:
10945 check_cp1_64bitmode(ctx);
10946 {
10947 TCGv_i64 fp0 = tcg_temp_new_i64();
10948
10949 gen_load_fpr64(ctx, fp0, fs);
10950 if (ctx->nan2008) {
10951 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10952 } else {
10953 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10954 }
10955 gen_store_fpr64(ctx, fp0, fd);
10956 tcg_temp_free_i64(fp0);
10957 }
10958 break;
10959 case OPC_CVT_S_W:
10960 {
10961 TCGv_i32 fp0 = tcg_temp_new_i32();
10962
10963 gen_load_fpr32(ctx, fp0, fs);
10964 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
10965 gen_store_fpr32(ctx, fp0, fd);
10966 tcg_temp_free_i32(fp0);
10967 }
10968 break;
10969 case OPC_CVT_D_W:
10970 check_cp1_registers(ctx, fd);
10971 {
10972 TCGv_i32 fp32 = tcg_temp_new_i32();
10973 TCGv_i64 fp64 = tcg_temp_new_i64();
10974
10975 gen_load_fpr32(ctx, fp32, fs);
10976 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
10977 tcg_temp_free_i32(fp32);
10978 gen_store_fpr64(ctx, fp64, fd);
10979 tcg_temp_free_i64(fp64);
10980 }
10981 break;
10982 case OPC_CVT_S_L:
10983 check_cp1_64bitmode(ctx);
10984 {
10985 TCGv_i32 fp32 = tcg_temp_new_i32();
10986 TCGv_i64 fp64 = tcg_temp_new_i64();
10987
10988 gen_load_fpr64(ctx, fp64, fs);
10989 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
10990 tcg_temp_free_i64(fp64);
10991 gen_store_fpr32(ctx, fp32, fd);
10992 tcg_temp_free_i32(fp32);
10993 }
10994 break;
10995 case OPC_CVT_D_L:
10996 check_cp1_64bitmode(ctx);
10997 {
10998 TCGv_i64 fp0 = tcg_temp_new_i64();
10999
11000 gen_load_fpr64(ctx, fp0, fs);
11001 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11002 gen_store_fpr64(ctx, fp0, fd);
11003 tcg_temp_free_i64(fp0);
11004 }
11005 break;
11006 case OPC_CVT_PS_PW:
11007 check_ps(ctx);
11008 {
11009 TCGv_i64 fp0 = tcg_temp_new_i64();
11010
11011 gen_load_fpr64(ctx, fp0, fs);
11012 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11013 gen_store_fpr64(ctx, fp0, fd);
11014 tcg_temp_free_i64(fp0);
11015 }
11016 break;
11017 case OPC_ADD_PS:
11018 check_ps(ctx);
11019 {
11020 TCGv_i64 fp0 = tcg_temp_new_i64();
11021 TCGv_i64 fp1 = tcg_temp_new_i64();
11022
11023 gen_load_fpr64(ctx, fp0, fs);
11024 gen_load_fpr64(ctx, fp1, ft);
11025 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11026 tcg_temp_free_i64(fp1);
11027 gen_store_fpr64(ctx, fp0, fd);
11028 tcg_temp_free_i64(fp0);
11029 }
11030 break;
11031 case OPC_SUB_PS:
11032 check_ps(ctx);
11033 {
11034 TCGv_i64 fp0 = tcg_temp_new_i64();
11035 TCGv_i64 fp1 = tcg_temp_new_i64();
11036
11037 gen_load_fpr64(ctx, fp0, fs);
11038 gen_load_fpr64(ctx, fp1, ft);
11039 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11040 tcg_temp_free_i64(fp1);
11041 gen_store_fpr64(ctx, fp0, fd);
11042 tcg_temp_free_i64(fp0);
11043 }
11044 break;
11045 case OPC_MUL_PS:
11046 check_ps(ctx);
11047 {
11048 TCGv_i64 fp0 = tcg_temp_new_i64();
11049 TCGv_i64 fp1 = tcg_temp_new_i64();
11050
11051 gen_load_fpr64(ctx, fp0, fs);
11052 gen_load_fpr64(ctx, fp1, ft);
11053 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11054 tcg_temp_free_i64(fp1);
11055 gen_store_fpr64(ctx, fp0, fd);
11056 tcg_temp_free_i64(fp0);
11057 }
11058 break;
11059 case OPC_ABS_PS:
11060 check_ps(ctx);
11061 {
11062 TCGv_i64 fp0 = tcg_temp_new_i64();
11063
11064 gen_load_fpr64(ctx, fp0, fs);
11065 gen_helper_float_abs_ps(fp0, fp0);
11066 gen_store_fpr64(ctx, fp0, fd);
11067 tcg_temp_free_i64(fp0);
11068 }
11069 break;
11070 case OPC_MOV_PS:
11071 check_ps(ctx);
11072 {
11073 TCGv_i64 fp0 = tcg_temp_new_i64();
11074
11075 gen_load_fpr64(ctx, fp0, fs);
11076 gen_store_fpr64(ctx, fp0, fd);
11077 tcg_temp_free_i64(fp0);
11078 }
11079 break;
11080 case OPC_NEG_PS:
11081 check_ps(ctx);
11082 {
11083 TCGv_i64 fp0 = tcg_temp_new_i64();
11084
11085 gen_load_fpr64(ctx, fp0, fs);
11086 gen_helper_float_chs_ps(fp0, fp0);
11087 gen_store_fpr64(ctx, fp0, fd);
11088 tcg_temp_free_i64(fp0);
11089 }
11090 break;
11091 case OPC_MOVCF_PS:
11092 check_ps(ctx);
11093 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11094 break;
11095 case OPC_MOVZ_PS:
11096 check_ps(ctx);
11097 {
11098 TCGLabel *l1 = gen_new_label();
11099 TCGv_i64 fp0;
11100
11101 if (ft != 0) {
11102 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11103 }
11104 fp0 = tcg_temp_new_i64();
11105 gen_load_fpr64(ctx, fp0, fs);
11106 gen_store_fpr64(ctx, fp0, fd);
11107 tcg_temp_free_i64(fp0);
11108 gen_set_label(l1);
11109 }
11110 break;
11111 case OPC_MOVN_PS:
11112 check_ps(ctx);
11113 {
11114 TCGLabel *l1 = gen_new_label();
11115 TCGv_i64 fp0;
11116
11117 if (ft != 0) {
11118 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11119 fp0 = tcg_temp_new_i64();
11120 gen_load_fpr64(ctx, fp0, fs);
11121 gen_store_fpr64(ctx, fp0, fd);
11122 tcg_temp_free_i64(fp0);
11123 gen_set_label(l1);
11124 }
11125 }
11126 break;
11127 case OPC_ADDR_PS:
11128 check_ps(ctx);
11129 {
11130 TCGv_i64 fp0 = tcg_temp_new_i64();
11131 TCGv_i64 fp1 = tcg_temp_new_i64();
11132
11133 gen_load_fpr64(ctx, fp0, ft);
11134 gen_load_fpr64(ctx, fp1, fs);
11135 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11136 tcg_temp_free_i64(fp1);
11137 gen_store_fpr64(ctx, fp0, fd);
11138 tcg_temp_free_i64(fp0);
11139 }
11140 break;
11141 case OPC_MULR_PS:
11142 check_ps(ctx);
11143 {
11144 TCGv_i64 fp0 = tcg_temp_new_i64();
11145 TCGv_i64 fp1 = tcg_temp_new_i64();
11146
11147 gen_load_fpr64(ctx, fp0, ft);
11148 gen_load_fpr64(ctx, fp1, fs);
11149 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11150 tcg_temp_free_i64(fp1);
11151 gen_store_fpr64(ctx, fp0, fd);
11152 tcg_temp_free_i64(fp0);
11153 }
11154 break;
11155 case OPC_RECIP2_PS:
11156 check_ps(ctx);
11157 {
11158 TCGv_i64 fp0 = tcg_temp_new_i64();
11159 TCGv_i64 fp1 = tcg_temp_new_i64();
11160
11161 gen_load_fpr64(ctx, fp0, fs);
11162 gen_load_fpr64(ctx, fp1, ft);
11163 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11164 tcg_temp_free_i64(fp1);
11165 gen_store_fpr64(ctx, fp0, fd);
11166 tcg_temp_free_i64(fp0);
11167 }
11168 break;
11169 case OPC_RECIP1_PS:
11170 check_ps(ctx);
11171 {
11172 TCGv_i64 fp0 = tcg_temp_new_i64();
11173
11174 gen_load_fpr64(ctx, fp0, fs);
11175 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11176 gen_store_fpr64(ctx, fp0, fd);
11177 tcg_temp_free_i64(fp0);
11178 }
11179 break;
11180 case OPC_RSQRT1_PS:
11181 check_ps(ctx);
11182 {
11183 TCGv_i64 fp0 = tcg_temp_new_i64();
11184
11185 gen_load_fpr64(ctx, fp0, fs);
11186 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11187 gen_store_fpr64(ctx, fp0, fd);
11188 tcg_temp_free_i64(fp0);
11189 }
11190 break;
11191 case OPC_RSQRT2_PS:
11192 check_ps(ctx);
11193 {
11194 TCGv_i64 fp0 = tcg_temp_new_i64();
11195 TCGv_i64 fp1 = tcg_temp_new_i64();
11196
11197 gen_load_fpr64(ctx, fp0, fs);
11198 gen_load_fpr64(ctx, fp1, ft);
11199 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11200 tcg_temp_free_i64(fp1);
11201 gen_store_fpr64(ctx, fp0, fd);
11202 tcg_temp_free_i64(fp0);
11203 }
11204 break;
11205 case OPC_CVT_S_PU:
11206 check_cp1_64bitmode(ctx);
11207 {
11208 TCGv_i32 fp0 = tcg_temp_new_i32();
11209
11210 gen_load_fpr32h(ctx, fp0, fs);
11211 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11212 gen_store_fpr32(ctx, fp0, fd);
11213 tcg_temp_free_i32(fp0);
11214 }
11215 break;
11216 case OPC_CVT_PW_PS:
11217 check_ps(ctx);
11218 {
11219 TCGv_i64 fp0 = tcg_temp_new_i64();
11220
11221 gen_load_fpr64(ctx, fp0, fs);
11222 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11223 gen_store_fpr64(ctx, fp0, fd);
11224 tcg_temp_free_i64(fp0);
11225 }
11226 break;
11227 case OPC_CVT_S_PL:
11228 check_cp1_64bitmode(ctx);
11229 {
11230 TCGv_i32 fp0 = tcg_temp_new_i32();
11231
11232 gen_load_fpr32(ctx, fp0, fs);
11233 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11234 gen_store_fpr32(ctx, fp0, fd);
11235 tcg_temp_free_i32(fp0);
11236 }
11237 break;
11238 case OPC_PLL_PS:
11239 check_ps(ctx);
11240 {
11241 TCGv_i32 fp0 = tcg_temp_new_i32();
11242 TCGv_i32 fp1 = tcg_temp_new_i32();
11243
11244 gen_load_fpr32(ctx, fp0, fs);
11245 gen_load_fpr32(ctx, fp1, ft);
11246 gen_store_fpr32h(ctx, fp0, fd);
11247 gen_store_fpr32(ctx, fp1, fd);
11248 tcg_temp_free_i32(fp0);
11249 tcg_temp_free_i32(fp1);
11250 }
11251 break;
11252 case OPC_PLU_PS:
11253 check_ps(ctx);
11254 {
11255 TCGv_i32 fp0 = tcg_temp_new_i32();
11256 TCGv_i32 fp1 = tcg_temp_new_i32();
11257
11258 gen_load_fpr32(ctx, fp0, fs);
11259 gen_load_fpr32h(ctx, fp1, ft);
11260 gen_store_fpr32(ctx, fp1, fd);
11261 gen_store_fpr32h(ctx, fp0, fd);
11262 tcg_temp_free_i32(fp0);
11263 tcg_temp_free_i32(fp1);
11264 }
11265 break;
11266 case OPC_PUL_PS:
11267 check_ps(ctx);
11268 {
11269 TCGv_i32 fp0 = tcg_temp_new_i32();
11270 TCGv_i32 fp1 = tcg_temp_new_i32();
11271
11272 gen_load_fpr32h(ctx, fp0, fs);
11273 gen_load_fpr32(ctx, fp1, ft);
11274 gen_store_fpr32(ctx, fp1, fd);
11275 gen_store_fpr32h(ctx, fp0, fd);
11276 tcg_temp_free_i32(fp0);
11277 tcg_temp_free_i32(fp1);
11278 }
11279 break;
11280 case OPC_PUU_PS:
11281 check_ps(ctx);
11282 {
11283 TCGv_i32 fp0 = tcg_temp_new_i32();
11284 TCGv_i32 fp1 = tcg_temp_new_i32();
11285
11286 gen_load_fpr32h(ctx, fp0, fs);
11287 gen_load_fpr32h(ctx, fp1, ft);
11288 gen_store_fpr32(ctx, fp1, fd);
11289 gen_store_fpr32h(ctx, fp0, fd);
11290 tcg_temp_free_i32(fp0);
11291 tcg_temp_free_i32(fp1);
11292 }
11293 break;
11294 case OPC_CMP_F_PS:
11295 case OPC_CMP_UN_PS:
11296 case OPC_CMP_EQ_PS:
11297 case OPC_CMP_UEQ_PS:
11298 case OPC_CMP_OLT_PS:
11299 case OPC_CMP_ULT_PS:
11300 case OPC_CMP_OLE_PS:
11301 case OPC_CMP_ULE_PS:
11302 case OPC_CMP_SF_PS:
11303 case OPC_CMP_NGLE_PS:
11304 case OPC_CMP_SEQ_PS:
11305 case OPC_CMP_NGL_PS:
11306 case OPC_CMP_LT_PS:
11307 case OPC_CMP_NGE_PS:
11308 case OPC_CMP_LE_PS:
11309 case OPC_CMP_NGT_PS:
11310 if (ctx->opcode & (1 << 6)) {
11311 gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
11312 } else {
11313 gen_cmp_ps(ctx, func - 48, ft, fs, cc);
11314 }
11315 break;
11316 default:
11317 MIPS_INVAL("farith");
11318 gen_reserved_instruction(ctx);
11319 return;
11320 }
11321 }
11322
11323 /* Coprocessor 3 (FPU) */
11324 static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
11325 int fd, int fs, int base, int index)
11326 {
11327 TCGv t0 = tcg_temp_new();
11328
11329 if (base == 0) {
11330 gen_load_gpr(t0, index);
11331 } else if (index == 0) {
11332 gen_load_gpr(t0, base);
11333 } else {
11334 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11335 }
11336 /*
11337 * Don't do NOP if destination is zero: we must perform the actual
11338 * memory access.
11339 */
11340 switch (opc) {
11341 case OPC_LWXC1:
11342 check_cop1x(ctx);
11343 {
11344 TCGv_i32 fp0 = tcg_temp_new_i32();
11345
11346 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11347 tcg_gen_trunc_tl_i32(fp0, t0);
11348 gen_store_fpr32(ctx, fp0, fd);
11349 tcg_temp_free_i32(fp0);
11350 }
11351 break;
11352 case OPC_LDXC1:
11353 check_cop1x(ctx);
11354 check_cp1_registers(ctx, fd);
11355 {
11356 TCGv_i64 fp0 = tcg_temp_new_i64();
11357 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11358 gen_store_fpr64(ctx, fp0, fd);
11359 tcg_temp_free_i64(fp0);
11360 }
11361 break;
11362 case OPC_LUXC1:
11363 check_cp1_64bitmode(ctx);
11364 tcg_gen_andi_tl(t0, t0, ~0x7);
11365 {
11366 TCGv_i64 fp0 = tcg_temp_new_i64();
11367
11368 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11369 gen_store_fpr64(ctx, fp0, fd);
11370 tcg_temp_free_i64(fp0);
11371 }
11372 break;
11373 case OPC_SWXC1:
11374 check_cop1x(ctx);
11375 {
11376 TCGv_i32 fp0 = tcg_temp_new_i32();
11377 gen_load_fpr32(ctx, fp0, fs);
11378 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11379 tcg_temp_free_i32(fp0);
11380 }
11381 break;
11382 case OPC_SDXC1:
11383 check_cop1x(ctx);
11384 check_cp1_registers(ctx, fs);
11385 {
11386 TCGv_i64 fp0 = tcg_temp_new_i64();
11387 gen_load_fpr64(ctx, fp0, fs);
11388 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11389 tcg_temp_free_i64(fp0);
11390 }
11391 break;
11392 case OPC_SUXC1:
11393 check_cp1_64bitmode(ctx);
11394 tcg_gen_andi_tl(t0, t0, ~0x7);
11395 {
11396 TCGv_i64 fp0 = tcg_temp_new_i64();
11397 gen_load_fpr64(ctx, fp0, fs);
11398 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEUQ);
11399 tcg_temp_free_i64(fp0);
11400 }
11401 break;
11402 }
11403 tcg_temp_free(t0);
11404 }
11405
11406 static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
11407 int fd, int fr, int fs, int ft)
11408 {
11409 switch (opc) {
11410 case OPC_ALNV_PS:
11411 check_ps(ctx);
11412 {
11413 TCGv t0 = tcg_temp_local_new();
11414 TCGv_i32 fp = tcg_temp_new_i32();
11415 TCGv_i32 fph = tcg_temp_new_i32();
11416 TCGLabel *l1 = gen_new_label();
11417 TCGLabel *l2 = gen_new_label();
11418
11419 gen_load_gpr(t0, fr);
11420 tcg_gen_andi_tl(t0, t0, 0x7);
11421
11422 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11423 gen_load_fpr32(ctx, fp, fs);
11424 gen_load_fpr32h(ctx, fph, fs);
11425 gen_store_fpr32(ctx, fp, fd);
11426 gen_store_fpr32h(ctx, fph, fd);
11427 tcg_gen_br(l2);
11428 gen_set_label(l1);
11429 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11430 tcg_temp_free(t0);
11431 if (cpu_is_bigendian(ctx)) {
11432 gen_load_fpr32(ctx, fp, fs);
11433 gen_load_fpr32h(ctx, fph, ft);
11434 gen_store_fpr32h(ctx, fp, fd);
11435 gen_store_fpr32(ctx, fph, fd);
11436 } else {
11437 gen_load_fpr32h(ctx, fph, fs);
11438 gen_load_fpr32(ctx, fp, ft);
11439 gen_store_fpr32(ctx, fph, fd);
11440 gen_store_fpr32h(ctx, fp, fd);
11441 }
11442 gen_set_label(l2);
11443 tcg_temp_free_i32(fp);
11444 tcg_temp_free_i32(fph);
11445 }
11446 break;
11447 case OPC_MADD_S:
11448 check_cop1x(ctx);
11449 {
11450 TCGv_i32 fp0 = tcg_temp_new_i32();
11451 TCGv_i32 fp1 = tcg_temp_new_i32();
11452 TCGv_i32 fp2 = tcg_temp_new_i32();
11453
11454 gen_load_fpr32(ctx, fp0, fs);
11455 gen_load_fpr32(ctx, fp1, ft);
11456 gen_load_fpr32(ctx, fp2, fr);
11457 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11458 tcg_temp_free_i32(fp0);
11459 tcg_temp_free_i32(fp1);
11460 gen_store_fpr32(ctx, fp2, fd);
11461 tcg_temp_free_i32(fp2);
11462 }
11463 break;
11464 case OPC_MADD_D:
11465 check_cop1x(ctx);
11466 check_cp1_registers(ctx, fd | fs | ft | fr);
11467 {
11468 TCGv_i64 fp0 = tcg_temp_new_i64();
11469 TCGv_i64 fp1 = tcg_temp_new_i64();
11470 TCGv_i64 fp2 = tcg_temp_new_i64();
11471
11472 gen_load_fpr64(ctx, fp0, fs);
11473 gen_load_fpr64(ctx, fp1, ft);
11474 gen_load_fpr64(ctx, fp2, fr);
11475 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11476 tcg_temp_free_i64(fp0);
11477 tcg_temp_free_i64(fp1);
11478 gen_store_fpr64(ctx, fp2, fd);
11479 tcg_temp_free_i64(fp2);
11480 }
11481 break;
11482 case OPC_MADD_PS:
11483 check_ps(ctx);
11484 {
11485 TCGv_i64 fp0 = tcg_temp_new_i64();
11486 TCGv_i64 fp1 = tcg_temp_new_i64();
11487 TCGv_i64 fp2 = tcg_temp_new_i64();
11488
11489 gen_load_fpr64(ctx, fp0, fs);
11490 gen_load_fpr64(ctx, fp1, ft);
11491 gen_load_fpr64(ctx, fp2, fr);
11492 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11493 tcg_temp_free_i64(fp0);
11494 tcg_temp_free_i64(fp1);
11495 gen_store_fpr64(ctx, fp2, fd);
11496 tcg_temp_free_i64(fp2);
11497 }
11498 break;
11499 case OPC_MSUB_S:
11500 check_cop1x(ctx);
11501 {
11502 TCGv_i32 fp0 = tcg_temp_new_i32();
11503 TCGv_i32 fp1 = tcg_temp_new_i32();
11504 TCGv_i32 fp2 = tcg_temp_new_i32();
11505
11506 gen_load_fpr32(ctx, fp0, fs);
11507 gen_load_fpr32(ctx, fp1, ft);
11508 gen_load_fpr32(ctx, fp2, fr);
11509 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11510 tcg_temp_free_i32(fp0);
11511 tcg_temp_free_i32(fp1);
11512 gen_store_fpr32(ctx, fp2, fd);
11513 tcg_temp_free_i32(fp2);
11514 }
11515 break;
11516 case OPC_MSUB_D:
11517 check_cop1x(ctx);
11518 check_cp1_registers(ctx, fd | fs | ft | fr);
11519 {
11520 TCGv_i64 fp0 = tcg_temp_new_i64();
11521 TCGv_i64 fp1 = tcg_temp_new_i64();
11522 TCGv_i64 fp2 = tcg_temp_new_i64();
11523
11524 gen_load_fpr64(ctx, fp0, fs);
11525 gen_load_fpr64(ctx, fp1, ft);
11526 gen_load_fpr64(ctx, fp2, fr);
11527 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11528 tcg_temp_free_i64(fp0);
11529 tcg_temp_free_i64(fp1);
11530 gen_store_fpr64(ctx, fp2, fd);
11531 tcg_temp_free_i64(fp2);
11532 }
11533 break;
11534 case OPC_MSUB_PS:
11535 check_ps(ctx);
11536 {
11537 TCGv_i64 fp0 = tcg_temp_new_i64();
11538 TCGv_i64 fp1 = tcg_temp_new_i64();
11539 TCGv_i64 fp2 = tcg_temp_new_i64();
11540
11541 gen_load_fpr64(ctx, fp0, fs);
11542 gen_load_fpr64(ctx, fp1, ft);
11543 gen_load_fpr64(ctx, fp2, fr);
11544 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11545 tcg_temp_free_i64(fp0);
11546 tcg_temp_free_i64(fp1);
11547 gen_store_fpr64(ctx, fp2, fd);
11548 tcg_temp_free_i64(fp2);
11549 }
11550 break;
11551 case OPC_NMADD_S:
11552 check_cop1x(ctx);
11553 {
11554 TCGv_i32 fp0 = tcg_temp_new_i32();
11555 TCGv_i32 fp1 = tcg_temp_new_i32();
11556 TCGv_i32 fp2 = tcg_temp_new_i32();
11557
11558 gen_load_fpr32(ctx, fp0, fs);
11559 gen_load_fpr32(ctx, fp1, ft);
11560 gen_load_fpr32(ctx, fp2, fr);
11561 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11562 tcg_temp_free_i32(fp0);
11563 tcg_temp_free_i32(fp1);
11564 gen_store_fpr32(ctx, fp2, fd);
11565 tcg_temp_free_i32(fp2);
11566 }
11567 break;
11568 case OPC_NMADD_D:
11569 check_cop1x(ctx);
11570 check_cp1_registers(ctx, fd | fs | ft | fr);
11571 {
11572 TCGv_i64 fp0 = tcg_temp_new_i64();
11573 TCGv_i64 fp1 = tcg_temp_new_i64();
11574 TCGv_i64 fp2 = tcg_temp_new_i64();
11575
11576 gen_load_fpr64(ctx, fp0, fs);
11577 gen_load_fpr64(ctx, fp1, ft);
11578 gen_load_fpr64(ctx, fp2, fr);
11579 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11580 tcg_temp_free_i64(fp0);
11581 tcg_temp_free_i64(fp1);
11582 gen_store_fpr64(ctx, fp2, fd);
11583 tcg_temp_free_i64(fp2);
11584 }
11585 break;
11586 case OPC_NMADD_PS:
11587 check_ps(ctx);
11588 {
11589 TCGv_i64 fp0 = tcg_temp_new_i64();
11590 TCGv_i64 fp1 = tcg_temp_new_i64();
11591 TCGv_i64 fp2 = tcg_temp_new_i64();
11592
11593 gen_load_fpr64(ctx, fp0, fs);
11594 gen_load_fpr64(ctx, fp1, ft);
11595 gen_load_fpr64(ctx, fp2, fr);
11596 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11597 tcg_temp_free_i64(fp0);
11598 tcg_temp_free_i64(fp1);
11599 gen_store_fpr64(ctx, fp2, fd);
11600 tcg_temp_free_i64(fp2);
11601 }
11602 break;
11603 case OPC_NMSUB_S:
11604 check_cop1x(ctx);
11605 {
11606 TCGv_i32 fp0 = tcg_temp_new_i32();
11607 TCGv_i32 fp1 = tcg_temp_new_i32();
11608 TCGv_i32 fp2 = tcg_temp_new_i32();
11609
11610 gen_load_fpr32(ctx, fp0, fs);
11611 gen_load_fpr32(ctx, fp1, ft);
11612 gen_load_fpr32(ctx, fp2, fr);
11613 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11614 tcg_temp_free_i32(fp0);
11615 tcg_temp_free_i32(fp1);
11616 gen_store_fpr32(ctx, fp2, fd);
11617 tcg_temp_free_i32(fp2);
11618 }
11619 break;
11620 case OPC_NMSUB_D:
11621 check_cop1x(ctx);
11622 check_cp1_registers(ctx, fd | fs | ft | fr);
11623 {
11624 TCGv_i64 fp0 = tcg_temp_new_i64();
11625 TCGv_i64 fp1 = tcg_temp_new_i64();
11626 TCGv_i64 fp2 = tcg_temp_new_i64();
11627
11628 gen_load_fpr64(ctx, fp0, fs);
11629 gen_load_fpr64(ctx, fp1, ft);
11630 gen_load_fpr64(ctx, fp2, fr);
11631 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11632 tcg_temp_free_i64(fp0);
11633 tcg_temp_free_i64(fp1);
11634 gen_store_fpr64(ctx, fp2, fd);
11635 tcg_temp_free_i64(fp2);
11636 }
11637 break;
11638 case OPC_NMSUB_PS:
11639 check_ps(ctx);
11640 {
11641 TCGv_i64 fp0 = tcg_temp_new_i64();
11642 TCGv_i64 fp1 = tcg_temp_new_i64();
11643 TCGv_i64 fp2 = tcg_temp_new_i64();
11644
11645 gen_load_fpr64(ctx, fp0, fs);
11646 gen_load_fpr64(ctx, fp1, ft);
11647 gen_load_fpr64(ctx, fp2, fr);
11648 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11649 tcg_temp_free_i64(fp0);
11650 tcg_temp_free_i64(fp1);
11651 gen_store_fpr64(ctx, fp2, fd);
11652 tcg_temp_free_i64(fp2);
11653 }
11654 break;
11655 default:
11656 MIPS_INVAL("flt3_arith");
11657 gen_reserved_instruction(ctx);
11658 return;
11659 }
11660 }
11661
11662 void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11663 {
11664 TCGv t0;
11665
11666 #if !defined(CONFIG_USER_ONLY)
11667 /*
11668 * The Linux kernel will emulate rdhwr if it's not supported natively.
11669 * Therefore only check the ISA in system mode.
11670 */
11671 check_insn(ctx, ISA_MIPS_R2);
11672 #endif
11673 t0 = tcg_temp_new();
11674
11675 switch (rd) {
11676 case 0:
11677 gen_helper_rdhwr_cpunum(t0, cpu_env);
11678 gen_store_gpr(t0, rt);
11679 break;
11680 case 1:
11681 gen_helper_rdhwr_synci_step(t0, cpu_env);
11682 gen_store_gpr(t0, rt);
11683 break;
11684 case 2:
11685 if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11686 gen_io_start();
11687 }
11688 gen_helper_rdhwr_cc(t0, cpu_env);
11689 gen_store_gpr(t0, rt);
11690 /*
11691 * Break the TB to be able to take timer interrupts immediately
11692 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
11693 * we break completely out of translated code.
11694 */
11695 gen_save_pc(ctx->base.pc_next + 4);
11696 ctx->base.is_jmp = DISAS_EXIT;
11697 break;
11698 case 3:
11699 gen_helper_rdhwr_ccres(t0, cpu_env);
11700 gen_store_gpr(t0, rt);
11701 break;
11702 case 4:
11703 check_insn(ctx, ISA_MIPS_R6);
11704 if (sel != 0) {
11705 /*
11706 * Performance counter registers are not implemented other than
11707 * control register 0.
11708 */
11709 generate_exception(ctx, EXCP_RI);
11710 }
11711 gen_helper_rdhwr_performance(t0, cpu_env);
11712 gen_store_gpr(t0, rt);
11713 break;
11714 case 5:
11715 check_insn(ctx, ISA_MIPS_R6);
11716 gen_helper_rdhwr_xnp(t0, cpu_env);
11717 gen_store_gpr(t0, rt);
11718 break;
11719 case 29:
11720 #if defined(CONFIG_USER_ONLY)
11721 tcg_gen_ld_tl(t0, cpu_env,
11722 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11723 gen_store_gpr(t0, rt);
11724 break;
11725 #else
11726 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11727 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11728 tcg_gen_ld_tl(t0, cpu_env,
11729 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11730 gen_store_gpr(t0, rt);
11731 } else {
11732 gen_reserved_instruction(ctx);
11733 }
11734 break;
11735 #endif
11736 default: /* Invalid */
11737 MIPS_INVAL("rdhwr");
11738 gen_reserved_instruction(ctx);
11739 break;
11740 }
11741 tcg_temp_free(t0);
11742 }
11743
11744 static inline void clear_branch_hflags(DisasContext *ctx)
11745 {
11746 ctx->hflags &= ~MIPS_HFLAG_BMASK;
11747 if (ctx->base.is_jmp == DISAS_NEXT) {
11748 save_cpu_state(ctx, 0);
11749 } else {
11750 /*
11751 * It is not safe to save ctx->hflags as hflags may be changed
11752 * in execution time by the instruction in delay / forbidden slot.
11753 */
11754 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11755 }
11756 }
11757
11758 static void gen_branch(DisasContext *ctx, int insn_bytes)
11759 {
11760 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11761 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11762 /* Branches completion */
11763 clear_branch_hflags(ctx);
11764 ctx->base.is_jmp = DISAS_NORETURN;
11765 /* FIXME: Need to clear can_do_io. */
11766 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11767 case MIPS_HFLAG_FBNSLOT:
11768 gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11769 break;
11770 case MIPS_HFLAG_B:
11771 /* unconditional branch */
11772 if (proc_hflags & MIPS_HFLAG_BX) {
11773 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11774 }
11775 gen_goto_tb(ctx, 0, ctx->btarget);
11776 break;
11777 case MIPS_HFLAG_BL:
11778 /* blikely taken case */
11779 gen_goto_tb(ctx, 0, ctx->btarget);
11780 break;
11781 case MIPS_HFLAG_BC:
11782 /* Conditional branch */
11783 {
11784 TCGLabel *l1 = gen_new_label();
11785
11786 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11787 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11788 gen_set_label(l1);
11789 gen_goto_tb(ctx, 0, ctx->btarget);
11790 }
11791 break;
11792 case MIPS_HFLAG_BR:
11793 /* unconditional branch to register */
11794 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11795 TCGv t0 = tcg_temp_new();
11796 TCGv_i32 t1 = tcg_temp_new_i32();
11797
11798 tcg_gen_andi_tl(t0, btarget, 0x1);
11799 tcg_gen_trunc_tl_i32(t1, t0);
11800 tcg_temp_free(t0);
11801 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11802 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11803 tcg_gen_or_i32(hflags, hflags, t1);
11804 tcg_temp_free_i32(t1);
11805
11806 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11807 } else {
11808 tcg_gen_mov_tl(cpu_PC, btarget);
11809 }
11810 tcg_gen_lookup_and_goto_ptr();
11811 break;
11812 default:
11813 LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11814 gen_reserved_instruction(ctx);
11815 }
11816 }
11817 }
11818
11819 /* Compact Branches */
11820 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11821 int rs, int rt, int32_t offset)
11822 {
11823 int bcond_compute = 0;
11824 TCGv t0 = tcg_temp_new();
11825 TCGv t1 = tcg_temp_new();
11826 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11827
11828 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11829 #ifdef MIPS_DEBUG_DISAS
11830 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11831 "\n", ctx->base.pc_next);
11832 #endif
11833 gen_reserved_instruction(ctx);
11834 goto out;
11835 }
11836
11837 /* Load needed operands and calculate btarget */
11838 switch (opc) {
11839 /* compact branch */
11840 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11841 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11842 gen_load_gpr(t0, rs);
11843 gen_load_gpr(t1, rt);
11844 bcond_compute = 1;
11845 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11846 if (rs <= rt && rs == 0) {
11847 /* OPC_BEQZALC, OPC_BNEZALC */
11848 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11849 }
11850 break;
11851 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11852 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11853 gen_load_gpr(t0, rs);
11854 gen_load_gpr(t1, rt);
11855 bcond_compute = 1;
11856 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11857 break;
11858 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11859 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11860 if (rs == 0 || rs == rt) {
11861 /* OPC_BLEZALC, OPC_BGEZALC */
11862 /* OPC_BGTZALC, OPC_BLTZALC */
11863 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11864 }
11865 gen_load_gpr(t0, rs);
11866 gen_load_gpr(t1, rt);
11867 bcond_compute = 1;
11868 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11869 break;
11870 case OPC_BC:
11871 case OPC_BALC:
11872 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11873 break;
11874 case OPC_BEQZC:
11875 case OPC_BNEZC:
11876 if (rs != 0) {
11877 /* OPC_BEQZC, OPC_BNEZC */
11878 gen_load_gpr(t0, rs);
11879 bcond_compute = 1;
11880 ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11881 } else {
11882 /* OPC_JIC, OPC_JIALC */
11883 TCGv tbase = tcg_temp_new();
11884 TCGv toffset = tcg_constant_tl(offset);
11885
11886 gen_load_gpr(tbase, rt);
11887 gen_op_addr_add(ctx, btarget, tbase, toffset);
11888 tcg_temp_free(tbase);
11889 }
11890 break;
11891 default:
11892 MIPS_INVAL("Compact branch/jump");
11893 gen_reserved_instruction(ctx);
11894 goto out;
11895 }
11896
11897 if (bcond_compute == 0) {
11898 /* Unconditional compact branch */
11899 switch (opc) {
11900 case OPC_JIALC:
11901 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11902 /* Fallthrough */
11903 case OPC_JIC:
11904 ctx->hflags |= MIPS_HFLAG_BR;
11905 break;
11906 case OPC_BALC:
11907 tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11908 /* Fallthrough */
11909 case OPC_BC:
11910 ctx->hflags |= MIPS_HFLAG_B;
11911 break;
11912 default:
11913 MIPS_INVAL("Compact branch/jump");
11914 gen_reserved_instruction(ctx);
11915 goto out;
11916 }
11917
11918 /* Generating branch here as compact branches don't have delay slot */
11919 gen_branch(ctx, 4);
11920 } else {
11921 /* Conditional compact branch */
11922 TCGLabel *fs = gen_new_label();
11923 save_cpu_state(ctx, 0);
11924
11925 switch (opc) {
11926 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11927 if (rs == 0 && rt != 0) {
11928 /* OPC_BLEZALC */
11929 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11930 } else if (rs != 0 && rt != 0 && rs == rt) {
11931 /* OPC_BGEZALC */
11932 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11933 } else {
11934 /* OPC_BGEUC */
11935 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11936 }
11937 break;
11938 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11939 if (rs == 0 && rt != 0) {
11940 /* OPC_BGTZALC */
11941 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11942 } else if (rs != 0 && rt != 0 && rs == rt) {
11943 /* OPC_BLTZALC */
11944 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11945 } else {
11946 /* OPC_BLTUC */
11947 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11948 }
11949 break;
11950 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11951 if (rs == 0 && rt != 0) {
11952 /* OPC_BLEZC */
11953 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11954 } else if (rs != 0 && rt != 0 && rs == rt) {
11955 /* OPC_BGEZC */
11956 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11957 } else {
11958 /* OPC_BGEC */
11959 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11960 }
11961 break;
11962 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11963 if (rs == 0 && rt != 0) {
11964 /* OPC_BGTZC */
11965 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11966 } else if (rs != 0 && rt != 0 && rs == rt) {
11967 /* OPC_BLTZC */
11968 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11969 } else {
11970 /* OPC_BLTC */
11971 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11972 }
11973 break;
11974 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11975 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11976 if (rs >= rt) {
11977 /* OPC_BOVC, OPC_BNVC */
11978 TCGv t2 = tcg_temp_new();
11979 TCGv t3 = tcg_temp_new();
11980 TCGv t4 = tcg_temp_new();
11981 TCGv input_overflow = tcg_temp_new();
11982
11983 gen_load_gpr(t0, rs);
11984 gen_load_gpr(t1, rt);
11985 tcg_gen_ext32s_tl(t2, t0);
11986 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11987 tcg_gen_ext32s_tl(t3, t1);
11988 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11989 tcg_gen_or_tl(input_overflow, input_overflow, t4);
11990
11991 tcg_gen_add_tl(t4, t2, t3);
11992 tcg_gen_ext32s_tl(t4, t4);
11993 tcg_gen_xor_tl(t2, t2, t3);
11994 tcg_gen_xor_tl(t3, t4, t3);
11995 tcg_gen_andc_tl(t2, t3, t2);
11996 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11997 tcg_gen_or_tl(t4, t4, input_overflow);
11998 if (opc == OPC_BOVC) {
11999 /* OPC_BOVC */
12000 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12001 } else {
12002 /* OPC_BNVC */
12003 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12004 }
12005 tcg_temp_free(input_overflow);
12006 tcg_temp_free(t4);
12007 tcg_temp_free(t3);
12008 tcg_temp_free(t2);
12009 } else if (rs < rt && rs == 0) {
12010 /* OPC_BEQZALC, OPC_BNEZALC */
12011 if (opc == OPC_BEQZALC) {
12012 /* OPC_BEQZALC */
12013 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12014 } else {
12015 /* OPC_BNEZALC */
12016 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12017 }
12018 } else {
12019 /* OPC_BEQC, OPC_BNEC */
12020 if (opc == OPC_BEQC) {
12021 /* OPC_BEQC */
12022 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12023 } else {
12024 /* OPC_BNEC */
12025 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12026 }
12027 }
12028 break;
12029 case OPC_BEQZC:
12030 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12031 break;
12032 case OPC_BNEZC:
12033 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12034 break;
12035 default:
12036 MIPS_INVAL("Compact conditional branch/jump");
12037 gen_reserved_instruction(ctx);
12038 goto out;
12039 }
12040
12041 /* Generating branch here as compact branches don't have delay slot */
12042 gen_goto_tb(ctx, 1, ctx->btarget);
12043 gen_set_label(fs);
12044
12045 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12046 }
12047
12048 out:
12049 tcg_temp_free(t0);
12050 tcg_temp_free(t1);
12051 }
12052
12053 void gen_addiupc(DisasContext *ctx, int rx, int imm,
12054 int is_64_bit, int extended)
12055 {
12056 TCGv t0;
12057
12058 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12059 gen_reserved_instruction(ctx);
12060 return;
12061 }
12062
12063 t0 = tcg_temp_new();
12064
12065 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12066 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12067 if (!is_64_bit) {
12068 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12069 }
12070
12071 tcg_temp_free(t0);
12072 }
12073
12074 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12075 int16_t offset)
12076 {
12077 TCGv_i32 t0 = tcg_const_i32(op);
12078 TCGv t1 = tcg_temp_new();
12079 gen_base_offset_addr(ctx, t1, base, offset);
12080 gen_helper_cache(cpu_env, t1, t0);
12081 tcg_temp_free(t1);
12082 tcg_temp_free_i32(t0);
12083 }
12084
12085 static inline bool is_uhi(DisasContext *ctx, int sdbbp_code)
12086 {
12087 #ifdef CONFIG_USER_ONLY
12088 return false;
12089 #else
12090 bool is_user = (ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM;
12091 return semihosting_enabled(is_user) && sdbbp_code == 1;
12092 #endif
12093 }
12094
12095 void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
12096 {
12097 TCGv t0 = tcg_temp_new();
12098 TCGv t1 = tcg_temp_new();
12099
12100 gen_load_gpr(t0, base);
12101
12102 if (index != 0) {
12103 gen_load_gpr(t1, index);
12104 tcg_gen_shli_tl(t1, t1, 2);
12105 gen_op_addr_add(ctx, t0, t1, t0);
12106 }
12107
12108 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12109 gen_store_gpr(t1, rd);
12110
12111 tcg_temp_free(t0);
12112 tcg_temp_free(t1);
12113 }
12114
12115 static void gen_sync(int stype)
12116 {
12117 TCGBar tcg_mo = TCG_BAR_SC;
12118
12119 switch (stype) {
12120 case 0x4: /* SYNC_WMB */
12121 tcg_mo |= TCG_MO_ST_ST;
12122 break;
12123 case 0x10: /* SYNC_MB */
12124 tcg_mo |= TCG_MO_ALL;
12125 break;
12126 case 0x11: /* SYNC_ACQUIRE */
12127 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
12128 break;
12129 case 0x12: /* SYNC_RELEASE */
12130 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
12131 break;
12132 case 0x13: /* SYNC_RMB */
12133 tcg_mo |= TCG_MO_LD_LD;
12134 break;
12135 default:
12136 tcg_mo |= TCG_MO_ALL;
12137 break;
12138 }
12139
12140 tcg_gen_mb(tcg_mo);
12141 }
12142
12143 /* ISA extensions (ASEs) */
12144
12145 /* MIPS16 extension to MIPS32 */
12146 #include "mips16e_translate.c.inc"
12147
12148 /* microMIPS extension to MIPS32/MIPS64 */
12149
12150 /*
12151 * Values for microMIPS fmt field. Variable-width, depending on which
12152 * formats the instruction supports.
12153 */
12154 enum {
12155 FMT_SD_S = 0,
12156 FMT_SD_D = 1,
12157
12158 FMT_SDPS_S = 0,
12159 FMT_SDPS_D = 1,
12160 FMT_SDPS_PS = 2,
12161
12162 FMT_SWL_S = 0,
12163 FMT_SWL_W = 1,
12164 FMT_SWL_L = 2,
12165
12166 FMT_DWL_D = 0,
12167 FMT_DWL_W = 1,
12168 FMT_DWL_L = 2
12169 };
12170
12171 #include "micromips_translate.c.inc"
12172
12173 #include "nanomips_translate.c.inc"
12174
12175 /* MIPSDSP functions. */
12176
12177 /* Indexed load is not for DSP only */
12178 static void gen_mips_lx(DisasContext *ctx, uint32_t opc,
12179 int rd, int base, int offset)
12180 {
12181 TCGv t0;
12182
12183 if (!(ctx->insn_flags & INSN_OCTEON)) {
12184 check_dsp(ctx);
12185 }
12186 t0 = tcg_temp_new();
12187
12188 if (base == 0) {
12189 gen_load_gpr(t0, offset);
12190 } else if (offset == 0) {
12191 gen_load_gpr(t0, base);
12192 } else {
12193 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12194 }
12195
12196 switch (opc) {
12197 case OPC_LBUX:
12198 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12199 gen_store_gpr(t0, rd);
12200 break;
12201 case OPC_LHX:
12202 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12203 gen_store_gpr(t0, rd);
12204 break;
12205 case OPC_LWX:
12206 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12207 gen_store_gpr(t0, rd);
12208 break;
12209 #if defined(TARGET_MIPS64)
12210 case OPC_LDX:
12211 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUQ);
12212 gen_store_gpr(t0, rd);
12213 break;
12214 #endif
12215 }
12216 tcg_temp_free(t0);
12217 }
12218
12219 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12220 int ret, int v1, int v2)
12221 {
12222 TCGv v1_t;
12223 TCGv v2_t;
12224
12225 if (ret == 0) {
12226 /* Treat as NOP. */
12227 return;
12228 }
12229
12230 v1_t = tcg_temp_new();
12231 v2_t = tcg_temp_new();
12232
12233 gen_load_gpr(v1_t, v1);
12234 gen_load_gpr(v2_t, v2);
12235
12236 switch (op1) {
12237 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12238 case OPC_MULT_G_2E:
12239 check_dsp_r2(ctx);
12240 switch (op2) {
12241 case OPC_ADDUH_QB:
12242 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12243 break;
12244 case OPC_ADDUH_R_QB:
12245 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12246 break;
12247 case OPC_ADDQH_PH:
12248 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12249 break;
12250 case OPC_ADDQH_R_PH:
12251 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12252 break;
12253 case OPC_ADDQH_W:
12254 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12255 break;
12256 case OPC_ADDQH_R_W:
12257 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12258 break;
12259 case OPC_SUBUH_QB:
12260 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12261 break;
12262 case OPC_SUBUH_R_QB:
12263 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12264 break;
12265 case OPC_SUBQH_PH:
12266 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12267 break;
12268 case OPC_SUBQH_R_PH:
12269 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12270 break;
12271 case OPC_SUBQH_W:
12272 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12273 break;
12274 case OPC_SUBQH_R_W:
12275 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12276 break;
12277 }
12278 break;
12279 case OPC_ABSQ_S_PH_DSP:
12280 switch (op2) {
12281 case OPC_ABSQ_S_QB:
12282 check_dsp_r2(ctx);
12283 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12284 break;
12285 case OPC_ABSQ_S_PH:
12286 check_dsp(ctx);
12287 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12288 break;
12289 case OPC_ABSQ_S_W:
12290 check_dsp(ctx);
12291 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12292 break;
12293 case OPC_PRECEQ_W_PHL:
12294 check_dsp(ctx);
12295 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12296 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12297 break;
12298 case OPC_PRECEQ_W_PHR:
12299 check_dsp(ctx);
12300 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12301 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12302 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12303 break;
12304 case OPC_PRECEQU_PH_QBL:
12305 check_dsp(ctx);
12306 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12307 break;
12308 case OPC_PRECEQU_PH_QBR:
12309 check_dsp(ctx);
12310 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12311 break;
12312 case OPC_PRECEQU_PH_QBLA:
12313 check_dsp(ctx);
12314 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12315 break;
12316 case OPC_PRECEQU_PH_QBRA:
12317 check_dsp(ctx);
12318 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12319 break;
12320 case OPC_PRECEU_PH_QBL:
12321 check_dsp(ctx);
12322 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12323 break;
12324 case OPC_PRECEU_PH_QBR:
12325 check_dsp(ctx);
12326 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12327 break;
12328 case OPC_PRECEU_PH_QBLA:
12329 check_dsp(ctx);
12330 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12331 break;
12332 case OPC_PRECEU_PH_QBRA:
12333 check_dsp(ctx);
12334 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12335 break;
12336 }
12337 break;
12338 case OPC_ADDU_QB_DSP:
12339 switch (op2) {
12340 case OPC_ADDQ_PH:
12341 check_dsp(ctx);
12342 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12343 break;
12344 case OPC_ADDQ_S_PH:
12345 check_dsp(ctx);
12346 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12347 break;
12348 case OPC_ADDQ_S_W:
12349 check_dsp(ctx);
12350 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12351 break;
12352 case OPC_ADDU_QB:
12353 check_dsp(ctx);
12354 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12355 break;
12356 case OPC_ADDU_S_QB:
12357 check_dsp(ctx);
12358 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12359 break;
12360 case OPC_ADDU_PH:
12361 check_dsp_r2(ctx);
12362 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12363 break;
12364 case OPC_ADDU_S_PH:
12365 check_dsp_r2(ctx);
12366 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12367 break;
12368 case OPC_SUBQ_PH:
12369 check_dsp(ctx);
12370 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12371 break;
12372 case OPC_SUBQ_S_PH:
12373 check_dsp(ctx);
12374 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12375 break;
12376 case OPC_SUBQ_S_W:
12377 check_dsp(ctx);
12378 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12379 break;
12380 case OPC_SUBU_QB:
12381 check_dsp(ctx);
12382 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12383 break;
12384 case OPC_SUBU_S_QB:
12385 check_dsp(ctx);
12386 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12387 break;
12388 case OPC_SUBU_PH:
12389 check_dsp_r2(ctx);
12390 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12391 break;
12392 case OPC_SUBU_S_PH:
12393 check_dsp_r2(ctx);
12394 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12395 break;
12396 case OPC_ADDSC:
12397 check_dsp(ctx);
12398 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12399 break;
12400 case OPC_ADDWC:
12401 check_dsp(ctx);
12402 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12403 break;
12404 case OPC_MODSUB:
12405 check_dsp(ctx);
12406 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12407 break;
12408 case OPC_RADDU_W_QB:
12409 check_dsp(ctx);
12410 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12411 break;
12412 }
12413 break;
12414 case OPC_CMPU_EQ_QB_DSP:
12415 switch (op2) {
12416 case OPC_PRECR_QB_PH:
12417 check_dsp_r2(ctx);
12418 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12419 break;
12420 case OPC_PRECRQ_QB_PH:
12421 check_dsp(ctx);
12422 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12423 break;
12424 case OPC_PRECR_SRA_PH_W:
12425 check_dsp_r2(ctx);
12426 {
12427 TCGv_i32 sa_t = tcg_const_i32(v2);
12428 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12429 cpu_gpr[ret]);
12430 tcg_temp_free_i32(sa_t);
12431 break;
12432 }
12433 case OPC_PRECR_SRA_R_PH_W:
12434 check_dsp_r2(ctx);
12435 {
12436 TCGv_i32 sa_t = tcg_const_i32(v2);
12437 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12438 cpu_gpr[ret]);
12439 tcg_temp_free_i32(sa_t);
12440 break;
12441 }
12442 case OPC_PRECRQ_PH_W:
12443 check_dsp(ctx);
12444 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12445 break;
12446 case OPC_PRECRQ_RS_PH_W:
12447 check_dsp(ctx);
12448 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12449 break;
12450 case OPC_PRECRQU_S_QB_PH:
12451 check_dsp(ctx);
12452 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12453 break;
12454 }
12455 break;
12456 #ifdef TARGET_MIPS64
12457 case OPC_ABSQ_S_QH_DSP:
12458 switch (op2) {
12459 case OPC_PRECEQ_L_PWL:
12460 check_dsp(ctx);
12461 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12462 break;
12463 case OPC_PRECEQ_L_PWR:
12464 check_dsp(ctx);
12465 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12466 break;
12467 case OPC_PRECEQ_PW_QHL:
12468 check_dsp(ctx);
12469 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12470 break;
12471 case OPC_PRECEQ_PW_QHR:
12472 check_dsp(ctx);
12473 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12474 break;
12475 case OPC_PRECEQ_PW_QHLA:
12476 check_dsp(ctx);
12477 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12478 break;
12479 case OPC_PRECEQ_PW_QHRA:
12480 check_dsp(ctx);
12481 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12482 break;
12483 case OPC_PRECEQU_QH_OBL:
12484 check_dsp(ctx);
12485 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12486 break;
12487 case OPC_PRECEQU_QH_OBR:
12488 check_dsp(ctx);
12489 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12490 break;
12491 case OPC_PRECEQU_QH_OBLA:
12492 check_dsp(ctx);
12493 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12494 break;
12495 case OPC_PRECEQU_QH_OBRA:
12496 check_dsp(ctx);
12497 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12498 break;
12499 case OPC_PRECEU_QH_OBL:
12500 check_dsp(ctx);
12501 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12502 break;
12503 case OPC_PRECEU_QH_OBR:
12504 check_dsp(ctx);
12505 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12506 break;
12507 case OPC_PRECEU_QH_OBLA:
12508 check_dsp(ctx);
12509 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12510 break;
12511 case OPC_PRECEU_QH_OBRA:
12512 check_dsp(ctx);
12513 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12514 break;
12515 case OPC_ABSQ_S_OB:
12516 check_dsp_r2(ctx);
12517 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12518 break;
12519 case OPC_ABSQ_S_PW:
12520 check_dsp(ctx);
12521 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12522 break;
12523 case OPC_ABSQ_S_QH:
12524 check_dsp(ctx);
12525 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12526 break;
12527 }
12528 break;
12529 case OPC_ADDU_OB_DSP:
12530 switch (op2) {
12531 case OPC_RADDU_L_OB:
12532 check_dsp(ctx);
12533 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12534 break;
12535 case OPC_SUBQ_PW:
12536 check_dsp(ctx);
12537 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12538 break;
12539 case OPC_SUBQ_S_PW:
12540 check_dsp(ctx);
12541 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12542 break;
12543 case OPC_SUBQ_QH:
12544 check_dsp(ctx);
12545 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12546 break;
12547 case OPC_SUBQ_S_QH:
12548 check_dsp(ctx);
12549 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12550 break;
12551 case OPC_SUBU_OB:
12552 check_dsp(ctx);
12553 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12554 break;
12555 case OPC_SUBU_S_OB:
12556 check_dsp(ctx);
12557 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12558 break;
12559 case OPC_SUBU_QH:
12560 check_dsp_r2(ctx);
12561 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12562 break;
12563 case OPC_SUBU_S_QH:
12564 check_dsp_r2(ctx);
12565 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12566 break;
12567 case OPC_SUBUH_OB:
12568 check_dsp_r2(ctx);
12569 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
12570 break;
12571 case OPC_SUBUH_R_OB:
12572 check_dsp_r2(ctx);
12573 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12574 break;
12575 case OPC_ADDQ_PW:
12576 check_dsp(ctx);
12577 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12578 break;
12579 case OPC_ADDQ_S_PW:
12580 check_dsp(ctx);
12581 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12582 break;
12583 case OPC_ADDQ_QH:
12584 check_dsp(ctx);
12585 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12586 break;
12587 case OPC_ADDQ_S_QH:
12588 check_dsp(ctx);
12589 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12590 break;
12591 case OPC_ADDU_OB:
12592 check_dsp(ctx);
12593 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12594 break;
12595 case OPC_ADDU_S_OB:
12596 check_dsp(ctx);
12597 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12598 break;
12599 case OPC_ADDU_QH:
12600 check_dsp_r2(ctx);
12601 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12602 break;
12603 case OPC_ADDU_S_QH:
12604 check_dsp_r2(ctx);
12605 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12606 break;
12607 case OPC_ADDUH_OB:
12608 check_dsp_r2(ctx);
12609 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12610 break;
12611 case OPC_ADDUH_R_OB:
12612 check_dsp_r2(ctx);
12613 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12614 break;
12615 }
12616 break;
12617 case OPC_CMPU_EQ_OB_DSP:
12618 switch (op2) {
12619 case OPC_PRECR_OB_QH:
12620 check_dsp_r2(ctx);
12621 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12622 break;
12623 case OPC_PRECR_SRA_QH_PW:
12624 check_dsp_r2(ctx);
12625 {
12626 TCGv_i32 ret_t = tcg_const_i32(ret);
12627 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12628 tcg_temp_free_i32(ret_t);
12629 break;
12630 }
12631 case OPC_PRECR_SRA_R_QH_PW:
12632 check_dsp_r2(ctx);
12633 {
12634 TCGv_i32 sa_v = tcg_const_i32(ret);
12635 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12636 tcg_temp_free_i32(sa_v);
12637 break;
12638 }
12639 case OPC_PRECRQ_OB_QH:
12640 check_dsp(ctx);
12641 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12642 break;
12643 case OPC_PRECRQ_PW_L:
12644 check_dsp(ctx);
12645 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12646 break;
12647 case OPC_PRECRQ_QH_PW:
12648 check_dsp(ctx);
12649 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12650 break;
12651 case OPC_PRECRQ_RS_QH_PW:
12652 check_dsp(ctx);
12653 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12654 break;
12655 case OPC_PRECRQU_S_OB_QH:
12656 check_dsp(ctx);
12657 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12658 break;
12659 }
12660 break;
12661 #endif
12662 }
12663
12664 tcg_temp_free(v1_t);
12665 tcg_temp_free(v2_t);
12666 }
12667
12668 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12669 int ret, int v1, int v2)
12670 {
12671 uint32_t op2;
12672 TCGv t0;
12673 TCGv v1_t;
12674 TCGv v2_t;
12675
12676 if (ret == 0) {
12677 /* Treat as NOP. */
12678 return;
12679 }
12680
12681 t0 = tcg_temp_new();
12682 v1_t = tcg_temp_new();
12683 v2_t = tcg_temp_new();
12684
12685 tcg_gen_movi_tl(t0, v1);
12686 gen_load_gpr(v1_t, v1);
12687 gen_load_gpr(v2_t, v2);
12688
12689 switch (opc) {
12690 case OPC_SHLL_QB_DSP:
12691 {
12692 op2 = MASK_SHLL_QB(ctx->opcode);
12693 switch (op2) {
12694 case OPC_SHLL_QB:
12695 check_dsp(ctx);
12696 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
12697 break;
12698 case OPC_SHLLV_QB:
12699 check_dsp(ctx);
12700 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12701 break;
12702 case OPC_SHLL_PH:
12703 check_dsp(ctx);
12704 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12705 break;
12706 case OPC_SHLLV_PH:
12707 check_dsp(ctx);
12708 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12709 break;
12710 case OPC_SHLL_S_PH:
12711 check_dsp(ctx);
12712 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12713 break;
12714 case OPC_SHLLV_S_PH:
12715 check_dsp(ctx);
12716 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12717 break;
12718 case OPC_SHLL_S_W:
12719 check_dsp(ctx);
12720 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
12721 break;
12722 case OPC_SHLLV_S_W:
12723 check_dsp(ctx);
12724 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12725 break;
12726 case OPC_SHRL_QB:
12727 check_dsp(ctx);
12728 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12729 break;
12730 case OPC_SHRLV_QB:
12731 check_dsp(ctx);
12732 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12733 break;
12734 case OPC_SHRL_PH:
12735 check_dsp_r2(ctx);
12736 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12737 break;
12738 case OPC_SHRLV_PH:
12739 check_dsp_r2(ctx);
12740 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12741 break;
12742 case OPC_SHRA_QB:
12743 check_dsp_r2(ctx);
12744 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12745 break;
12746 case OPC_SHRA_R_QB:
12747 check_dsp_r2(ctx);
12748 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12749 break;
12750 case OPC_SHRAV_QB:
12751 check_dsp_r2(ctx);
12752 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12753 break;
12754 case OPC_SHRAV_R_QB:
12755 check_dsp_r2(ctx);
12756 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12757 break;
12758 case OPC_SHRA_PH:
12759 check_dsp(ctx);
12760 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12761 break;
12762 case OPC_SHRA_R_PH:
12763 check_dsp(ctx);
12764 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12765 break;
12766 case OPC_SHRAV_PH:
12767 check_dsp(ctx);
12768 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12769 break;
12770 case OPC_SHRAV_R_PH:
12771 check_dsp(ctx);
12772 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12773 break;
12774 case OPC_SHRA_R_W:
12775 check_dsp(ctx);
12776 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12777 break;
12778 case OPC_SHRAV_R_W:
12779 check_dsp(ctx);
12780 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12781 break;
12782 default: /* Invalid */
12783 MIPS_INVAL("MASK SHLL.QB");
12784 gen_reserved_instruction(ctx);
12785 break;
12786 }
12787 break;
12788 }
12789 #ifdef TARGET_MIPS64
12790 case OPC_SHLL_OB_DSP:
12791 op2 = MASK_SHLL_OB(ctx->opcode);
12792 switch (op2) {
12793 case OPC_SHLL_PW:
12794 check_dsp(ctx);
12795 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12796 break;
12797 case OPC_SHLLV_PW:
12798 check_dsp(ctx);
12799 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12800 break;
12801 case OPC_SHLL_S_PW:
12802 check_dsp(ctx);
12803 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12804 break;
12805 case OPC_SHLLV_S_PW:
12806 check_dsp(ctx);
12807 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12808 break;
12809 case OPC_SHLL_OB:
12810 check_dsp(ctx);
12811 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
12812 break;
12813 case OPC_SHLLV_OB:
12814 check_dsp(ctx);
12815 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12816 break;
12817 case OPC_SHLL_QH:
12818 check_dsp(ctx);
12819 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12820 break;
12821 case OPC_SHLLV_QH:
12822 check_dsp(ctx);
12823 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12824 break;
12825 case OPC_SHLL_S_QH:
12826 check_dsp(ctx);
12827 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12828 break;
12829 case OPC_SHLLV_S_QH:
12830 check_dsp(ctx);
12831 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12832 break;
12833 case OPC_SHRA_OB:
12834 check_dsp_r2(ctx);
12835 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12836 break;
12837 case OPC_SHRAV_OB:
12838 check_dsp_r2(ctx);
12839 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12840 break;
12841 case OPC_SHRA_R_OB:
12842 check_dsp_r2(ctx);
12843 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12844 break;
12845 case OPC_SHRAV_R_OB:
12846 check_dsp_r2(ctx);
12847 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12848 break;
12849 case OPC_SHRA_PW:
12850 check_dsp(ctx);
12851 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12852 break;
12853 case OPC_SHRAV_PW:
12854 check_dsp(ctx);
12855 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12856 break;
12857 case OPC_SHRA_R_PW:
12858 check_dsp(ctx);
12859 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12860 break;
12861 case OPC_SHRAV_R_PW:
12862 check_dsp(ctx);
12863 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12864 break;
12865 case OPC_SHRA_QH:
12866 check_dsp(ctx);
12867 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12868 break;
12869 case OPC_SHRAV_QH:
12870 check_dsp(ctx);
12871 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12872 break;
12873 case OPC_SHRA_R_QH:
12874 check_dsp(ctx);
12875 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12876 break;
12877 case OPC_SHRAV_R_QH:
12878 check_dsp(ctx);
12879 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12880 break;
12881 case OPC_SHRL_OB:
12882 check_dsp(ctx);
12883 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12884 break;
12885 case OPC_SHRLV_OB:
12886 check_dsp(ctx);
12887 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12888 break;
12889 case OPC_SHRL_QH:
12890 check_dsp_r2(ctx);
12891 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12892 break;
12893 case OPC_SHRLV_QH:
12894 check_dsp_r2(ctx);
12895 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12896 break;
12897 default: /* Invalid */
12898 MIPS_INVAL("MASK SHLL.OB");
12899 gen_reserved_instruction(ctx);
12900 break;
12901 }
12902 break;
12903 #endif
12904 }
12905
12906 tcg_temp_free(t0);
12907 tcg_temp_free(v1_t);
12908 tcg_temp_free(v2_t);
12909 }
12910
12911 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12912 int ret, int v1, int v2, int check_ret)
12913 {
12914 TCGv_i32 t0;
12915 TCGv v1_t;
12916 TCGv v2_t;
12917
12918 if ((ret == 0) && (check_ret == 1)) {
12919 /* Treat as NOP. */
12920 return;
12921 }
12922
12923 t0 = tcg_temp_new_i32();
12924 v1_t = tcg_temp_new();
12925 v2_t = tcg_temp_new();
12926
12927 tcg_gen_movi_i32(t0, ret);
12928 gen_load_gpr(v1_t, v1);
12929 gen_load_gpr(v2_t, v2);
12930
12931 switch (op1) {
12932 /*
12933 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
12934 * the same mask and op1.
12935 */
12936 case OPC_MULT_G_2E:
12937 check_dsp_r2(ctx);
12938 switch (op2) {
12939 case OPC_MUL_PH:
12940 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12941 break;
12942 case OPC_MUL_S_PH:
12943 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12944 break;
12945 case OPC_MULQ_S_W:
12946 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12947 break;
12948 case OPC_MULQ_RS_W:
12949 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12950 break;
12951 }
12952 break;
12953 case OPC_DPA_W_PH_DSP:
12954 switch (op2) {
12955 case OPC_DPAU_H_QBL:
12956 check_dsp(ctx);
12957 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
12958 break;
12959 case OPC_DPAU_H_QBR:
12960 check_dsp(ctx);
12961 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
12962 break;
12963 case OPC_DPSU_H_QBL:
12964 check_dsp(ctx);
12965 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
12966 break;
12967 case OPC_DPSU_H_QBR:
12968 check_dsp(ctx);
12969 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
12970 break;
12971 case OPC_DPA_W_PH:
12972 check_dsp_r2(ctx);
12973 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
12974 break;
12975 case OPC_DPAX_W_PH:
12976 check_dsp_r2(ctx);
12977 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
12978 break;
12979 case OPC_DPAQ_S_W_PH:
12980 check_dsp(ctx);
12981 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12982 break;
12983 case OPC_DPAQX_S_W_PH:
12984 check_dsp_r2(ctx);
12985 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12986 break;
12987 case OPC_DPAQX_SA_W_PH:
12988 check_dsp_r2(ctx);
12989 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12990 break;
12991 case OPC_DPS_W_PH:
12992 check_dsp_r2(ctx);
12993 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
12994 break;
12995 case OPC_DPSX_W_PH:
12996 check_dsp_r2(ctx);
12997 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
12998 break;
12999 case OPC_DPSQ_S_W_PH:
13000 check_dsp(ctx);
13001 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13002 break;
13003 case OPC_DPSQX_S_W_PH:
13004 check_dsp_r2(ctx);
13005 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13006 break;
13007 case OPC_DPSQX_SA_W_PH:
13008 check_dsp_r2(ctx);
13009 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13010 break;
13011 case OPC_MULSAQ_S_W_PH:
13012 check_dsp(ctx);
13013 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13014 break;
13015 case OPC_DPAQ_SA_L_W:
13016 check_dsp(ctx);
13017 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13018 break;
13019 case OPC_DPSQ_SA_L_W:
13020 check_dsp(ctx);
13021 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13022 break;
13023 case OPC_MAQ_S_W_PHL:
13024 check_dsp(ctx);
13025 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13026 break;
13027 case OPC_MAQ_S_W_PHR:
13028 check_dsp(ctx);
13029 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13030 break;
13031 case OPC_MAQ_SA_W_PHL:
13032 check_dsp(ctx);
13033 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13034 break;
13035 case OPC_MAQ_SA_W_PHR:
13036 check_dsp(ctx);
13037 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13038 break;
13039 case OPC_MULSA_W_PH:
13040 check_dsp_r2(ctx);
13041 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13042 break;
13043 }
13044 break;
13045 #ifdef TARGET_MIPS64
13046 case OPC_DPAQ_W_QH_DSP:
13047 {
13048 int ac = ret & 0x03;
13049 tcg_gen_movi_i32(t0, ac);
13050
13051 switch (op2) {
13052 case OPC_DMADD:
13053 check_dsp(ctx);
13054 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13055 break;
13056 case OPC_DMADDU:
13057 check_dsp(ctx);
13058 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13059 break;
13060 case OPC_DMSUB:
13061 check_dsp(ctx);
13062 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13063 break;
13064 case OPC_DMSUBU:
13065 check_dsp(ctx);
13066 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13067 break;
13068 case OPC_DPA_W_QH:
13069 check_dsp_r2(ctx);
13070 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13071 break;
13072 case OPC_DPAQ_S_W_QH:
13073 check_dsp(ctx);
13074 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13075 break;
13076 case OPC_DPAQ_SA_L_PW:
13077 check_dsp(ctx);
13078 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13079 break;
13080 case OPC_DPAU_H_OBL:
13081 check_dsp(ctx);
13082 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13083 break;
13084 case OPC_DPAU_H_OBR:
13085 check_dsp(ctx);
13086 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13087 break;
13088 case OPC_DPS_W_QH:
13089 check_dsp_r2(ctx);
13090 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13091 break;
13092 case OPC_DPSQ_S_W_QH:
13093 check_dsp(ctx);
13094 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13095 break;
13096 case OPC_DPSQ_SA_L_PW:
13097 check_dsp(ctx);
13098 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13099 break;
13100 case OPC_DPSU_H_OBL:
13101 check_dsp(ctx);
13102 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13103 break;
13104 case OPC_DPSU_H_OBR:
13105 check_dsp(ctx);
13106 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13107 break;
13108 case OPC_MAQ_S_L_PWL:
13109 check_dsp(ctx);
13110 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13111 break;
13112 case OPC_MAQ_S_L_PWR:
13113 check_dsp(ctx);
13114 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13115 break;
13116 case OPC_MAQ_S_W_QHLL:
13117 check_dsp(ctx);
13118 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13119 break;
13120 case OPC_MAQ_SA_W_QHLL:
13121 check_dsp(ctx);
13122 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13123 break;
13124 case OPC_MAQ_S_W_QHLR:
13125 check_dsp(ctx);
13126 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13127 break;
13128 case OPC_MAQ_SA_W_QHLR:
13129 check_dsp(ctx);
13130 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13131 break;
13132 case OPC_MAQ_S_W_QHRL:
13133 check_dsp(ctx);
13134 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13135 break;
13136 case OPC_MAQ_SA_W_QHRL:
13137 check_dsp(ctx);
13138 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13139 break;
13140 case OPC_MAQ_S_W_QHRR:
13141 check_dsp(ctx);
13142 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13143 break;
13144 case OPC_MAQ_SA_W_QHRR:
13145 check_dsp(ctx);
13146 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13147 break;
13148 case OPC_MULSAQ_S_L_PW:
13149 check_dsp(ctx);
13150 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13151 break;
13152 case OPC_MULSAQ_S_W_QH:
13153 check_dsp(ctx);
13154 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13155 break;
13156 }
13157 }
13158 break;
13159 #endif
13160 case OPC_ADDU_QB_DSP:
13161 switch (op2) {
13162 case OPC_MULEU_S_PH_QBL:
13163 check_dsp(ctx);
13164 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13165 break;
13166 case OPC_MULEU_S_PH_QBR:
13167 check_dsp(ctx);
13168 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13169 break;
13170 case OPC_MULQ_RS_PH:
13171 check_dsp(ctx);
13172 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13173 break;
13174 case OPC_MULEQ_S_W_PHL:
13175 check_dsp(ctx);
13176 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13177 break;
13178 case OPC_MULEQ_S_W_PHR:
13179 check_dsp(ctx);
13180 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13181 break;
13182 case OPC_MULQ_S_PH:
13183 check_dsp_r2(ctx);
13184 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13185 break;
13186 }
13187 break;
13188 #ifdef TARGET_MIPS64
13189 case OPC_ADDU_OB_DSP:
13190 switch (op2) {
13191 case OPC_MULEQ_S_PW_QHL:
13192 check_dsp(ctx);
13193 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13194 break;
13195 case OPC_MULEQ_S_PW_QHR:
13196 check_dsp(ctx);
13197 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13198 break;
13199 case OPC_MULEU_S_QH_OBL:
13200 check_dsp(ctx);
13201 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13202 break;
13203 case OPC_MULEU_S_QH_OBR:
13204 check_dsp(ctx);
13205 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13206 break;
13207 case OPC_MULQ_RS_QH:
13208 check_dsp(ctx);
13209 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13210 break;
13211 }
13212 break;
13213 #endif
13214 }
13215
13216 tcg_temp_free_i32(t0);
13217 tcg_temp_free(v1_t);
13218 tcg_temp_free(v2_t);
13219 }
13220
13221 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13222 int ret, int val)
13223 {
13224 int16_t imm;
13225 TCGv t0;
13226 TCGv val_t;
13227
13228 if (ret == 0) {
13229 /* Treat as NOP. */
13230 return;
13231 }
13232
13233 t0 = tcg_temp_new();
13234 val_t = tcg_temp_new();
13235 gen_load_gpr(val_t, val);
13236
13237 switch (op1) {
13238 case OPC_ABSQ_S_PH_DSP:
13239 switch (op2) {
13240 case OPC_BITREV:
13241 check_dsp(ctx);
13242 gen_helper_bitrev(cpu_gpr[ret], val_t);
13243 break;
13244 case OPC_REPL_QB:
13245 check_dsp(ctx);
13246 {
13247 target_long result;
13248 imm = (ctx->opcode >> 16) & 0xFF;
13249 result = (uint32_t)imm << 24 |
13250 (uint32_t)imm << 16 |
13251 (uint32_t)imm << 8 |
13252 (uint32_t)imm;
13253 result = (int32_t)result;
13254 tcg_gen_movi_tl(cpu_gpr[ret], result);
13255 }
13256 break;
13257 case OPC_REPLV_QB:
13258 check_dsp(ctx);
13259 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13260 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13261 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13262 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13263 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13264 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13265 break;
13266 case OPC_REPL_PH:
13267 check_dsp(ctx);
13268 {
13269 imm = (ctx->opcode >> 16) & 0x03FF;
13270 imm = (int16_t)(imm << 6) >> 6;
13271 tcg_gen_movi_tl(cpu_gpr[ret], \
13272 (target_long)((int32_t)imm << 16 | \
13273 (uint16_t)imm));
13274 }
13275 break;
13276 case OPC_REPLV_PH:
13277 check_dsp(ctx);
13278 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13279 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13280 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13281 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13282 break;
13283 }
13284 break;
13285 #ifdef TARGET_MIPS64
13286 case OPC_ABSQ_S_QH_DSP:
13287 switch (op2) {
13288 case OPC_REPL_OB:
13289 check_dsp(ctx);
13290 {
13291 target_long temp;
13292
13293 imm = (ctx->opcode >> 16) & 0xFF;
13294 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13295 temp = (temp << 16) | temp;
13296 temp = (temp << 32) | temp;
13297 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13298 break;
13299 }
13300 case OPC_REPL_PW:
13301 check_dsp(ctx);
13302 {
13303 target_long temp;
13304
13305 imm = (ctx->opcode >> 16) & 0x03FF;
13306 imm = (int16_t)(imm << 6) >> 6;
13307 temp = ((target_long)imm << 32) \
13308 | ((target_long)imm & 0xFFFFFFFF);
13309 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13310 break;
13311 }
13312 case OPC_REPL_QH:
13313 check_dsp(ctx);
13314 {
13315 target_long temp;
13316
13317 imm = (ctx->opcode >> 16) & 0x03FF;
13318 imm = (int16_t)(imm << 6) >> 6;
13319
13320 temp = ((uint64_t)(uint16_t)imm << 48) |
13321 ((uint64_t)(uint16_t)imm << 32) |
13322 ((uint64_t)(uint16_t)imm << 16) |
13323 (uint64_t)(uint16_t)imm;
13324 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13325 break;
13326 }
13327 case OPC_REPLV_OB:
13328 check_dsp(ctx);
13329 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13330 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13331 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13332 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13333 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13334 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13335 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13336 break;
13337 case OPC_REPLV_PW:
13338 check_dsp(ctx);
13339 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13340 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13341 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13342 break;
13343 case OPC_REPLV_QH:
13344 check_dsp(ctx);
13345 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13346 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13347 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13348 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13349 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13350 break;
13351 }
13352 break;
13353 #endif
13354 }
13355 tcg_temp_free(t0);
13356 tcg_temp_free(val_t);
13357 }
13358
13359 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13360 uint32_t op1, uint32_t op2,
13361 int ret, int v1, int v2, int check_ret)
13362 {
13363 TCGv t1;
13364 TCGv v1_t;
13365 TCGv v2_t;
13366
13367 if ((ret == 0) && (check_ret == 1)) {
13368 /* Treat as NOP. */
13369 return;
13370 }
13371
13372 t1 = tcg_temp_new();
13373 v1_t = tcg_temp_new();
13374 v2_t = tcg_temp_new();
13375
13376 gen_load_gpr(v1_t, v1);
13377 gen_load_gpr(v2_t, v2);
13378
13379 switch (op1) {
13380 case OPC_CMPU_EQ_QB_DSP:
13381 switch (op2) {
13382 case OPC_CMPU_EQ_QB:
13383 check_dsp(ctx);
13384 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13385 break;
13386 case OPC_CMPU_LT_QB:
13387 check_dsp(ctx);
13388 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13389 break;
13390 case OPC_CMPU_LE_QB:
13391 check_dsp(ctx);
13392 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13393 break;
13394 case OPC_CMPGU_EQ_QB:
13395 check_dsp(ctx);
13396 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13397 break;
13398 case OPC_CMPGU_LT_QB:
13399 check_dsp(ctx);
13400 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13401 break;
13402 case OPC_CMPGU_LE_QB:
13403 check_dsp(ctx);
13404 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13405 break;
13406 case OPC_CMPGDU_EQ_QB:
13407 check_dsp_r2(ctx);
13408 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13409 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13410 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13411 tcg_gen_shli_tl(t1, t1, 24);
13412 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13413 break;
13414 case OPC_CMPGDU_LT_QB:
13415 check_dsp_r2(ctx);
13416 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13417 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13418 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13419 tcg_gen_shli_tl(t1, t1, 24);
13420 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13421 break;
13422 case OPC_CMPGDU_LE_QB:
13423 check_dsp_r2(ctx);
13424 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13425 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13426 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13427 tcg_gen_shli_tl(t1, t1, 24);
13428 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13429 break;
13430 case OPC_CMP_EQ_PH:
13431 check_dsp(ctx);
13432 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13433 break;
13434 case OPC_CMP_LT_PH:
13435 check_dsp(ctx);
13436 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13437 break;
13438 case OPC_CMP_LE_PH:
13439 check_dsp(ctx);
13440 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13441 break;
13442 case OPC_PICK_QB:
13443 check_dsp(ctx);
13444 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13445 break;
13446 case OPC_PICK_PH:
13447 check_dsp(ctx);
13448 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13449 break;
13450 case OPC_PACKRL_PH:
13451 check_dsp(ctx);
13452 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13453 break;
13454 }
13455 break;
13456 #ifdef TARGET_MIPS64
13457 case OPC_CMPU_EQ_OB_DSP:
13458 switch (op2) {
13459 case OPC_CMP_EQ_PW:
13460 check_dsp(ctx);
13461 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13462 break;
13463 case OPC_CMP_LT_PW:
13464 check_dsp(ctx);
13465 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13466 break;
13467 case OPC_CMP_LE_PW:
13468 check_dsp(ctx);
13469 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13470 break;
13471 case OPC_CMP_EQ_QH:
13472 check_dsp(ctx);
13473 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13474 break;
13475 case OPC_CMP_LT_QH:
13476 check_dsp(ctx);
13477 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13478 break;
13479 case OPC_CMP_LE_QH:
13480 check_dsp(ctx);
13481 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13482 break;
13483 case OPC_CMPGDU_EQ_OB:
13484 check_dsp_r2(ctx);
13485 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13486 break;
13487 case OPC_CMPGDU_LT_OB:
13488 check_dsp_r2(ctx);
13489 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13490 break;
13491 case OPC_CMPGDU_LE_OB:
13492 check_dsp_r2(ctx);
13493 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13494 break;
13495 case OPC_CMPGU_EQ_OB:
13496 check_dsp(ctx);
13497 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13498 break;
13499 case OPC_CMPGU_LT_OB:
13500 check_dsp(ctx);
13501 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13502 break;
13503 case OPC_CMPGU_LE_OB:
13504 check_dsp(ctx);
13505 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13506 break;
13507 case OPC_CMPU_EQ_OB:
13508 check_dsp(ctx);
13509 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13510 break;
13511 case OPC_CMPU_LT_OB:
13512 check_dsp(ctx);
13513 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13514 break;
13515 case OPC_CMPU_LE_OB:
13516 check_dsp(ctx);
13517 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13518 break;
13519 case OPC_PACKRL_PW:
13520 check_dsp(ctx);
13521 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
13522 break;
13523 case OPC_PICK_OB:
13524 check_dsp(ctx);
13525 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13526 break;
13527 case OPC_PICK_PW:
13528 check_dsp(ctx);
13529 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13530 break;
13531 case OPC_PICK_QH:
13532 check_dsp(ctx);
13533 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13534 break;
13535 }
13536 break;
13537 #endif
13538 }
13539
13540 tcg_temp_free(t1);
13541 tcg_temp_free(v1_t);
13542 tcg_temp_free(v2_t);
13543 }
13544
13545 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
13546 uint32_t op1, int rt, int rs, int sa)
13547 {
13548 TCGv t0;
13549
13550 check_dsp_r2(ctx);
13551
13552 if (rt == 0) {
13553 /* Treat as NOP. */
13554 return;
13555 }
13556
13557 t0 = tcg_temp_new();
13558 gen_load_gpr(t0, rs);
13559
13560 switch (op1) {
13561 case OPC_APPEND_DSP:
13562 switch (MASK_APPEND(ctx->opcode)) {
13563 case OPC_APPEND:
13564 if (sa != 0) {
13565 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
13566 }
13567 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13568 break;
13569 case OPC_PREPEND:
13570 if (sa != 0) {
13571 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
13572 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13573 tcg_gen_shli_tl(t0, t0, 32 - sa);
13574 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13575 }
13576 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13577 break;
13578 case OPC_BALIGN:
13579 sa &= 3;
13580 if (sa != 0 && sa != 2) {
13581 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13582 tcg_gen_ext32u_tl(t0, t0);
13583 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
13584 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13585 }
13586 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13587 break;
13588 default: /* Invalid */
13589 MIPS_INVAL("MASK APPEND");
13590 gen_reserved_instruction(ctx);
13591 break;
13592 }
13593 break;
13594 #ifdef TARGET_MIPS64
13595 case OPC_DAPPEND_DSP:
13596 switch (MASK_DAPPEND(ctx->opcode)) {
13597 case OPC_DAPPEND:
13598 if (sa != 0) {
13599 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13600 }
13601 break;
13602 case OPC_PREPENDD:
13603 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13604 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13605 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
13606 break;
13607 case OPC_PREPENDW:
13608 if (sa != 0) {
13609 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13610 tcg_gen_shli_tl(t0, t0, 64 - sa);
13611 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13612 }
13613 break;
13614 case OPC_DBALIGN:
13615 sa &= 7;
13616 if (sa != 0 && sa != 2 && sa != 4) {
13617 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13618 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13619 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13620 }
13621 break;
13622 default: /* Invalid */
13623 MIPS_INVAL("MASK DAPPEND");
13624 gen_reserved_instruction(ctx);
13625 break;
13626 }
13627 break;
13628 #endif
13629 }
13630 tcg_temp_free(t0);
13631 }
13632
13633 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13634 int ret, int v1, int v2, int check_ret)
13635
13636 {
13637 TCGv t0;
13638 TCGv t1;
13639 TCGv v1_t;
13640 int16_t imm;
13641
13642 if ((ret == 0) && (check_ret == 1)) {
13643 /* Treat as NOP. */
13644 return;
13645 }
13646
13647 t0 = tcg_temp_new();
13648 t1 = tcg_temp_new();
13649 v1_t = tcg_temp_new();
13650
13651 gen_load_gpr(v1_t, v1);
13652
13653 switch (op1) {
13654 case OPC_EXTR_W_DSP:
13655 check_dsp(ctx);
13656 switch (op2) {
13657 case OPC_EXTR_W:
13658 tcg_gen_movi_tl(t0, v2);
13659 tcg_gen_movi_tl(t1, v1);
13660 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
13661 break;
13662 case OPC_EXTR_R_W:
13663 tcg_gen_movi_tl(t0, v2);
13664 tcg_gen_movi_tl(t1, v1);
13665 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13666 break;
13667 case OPC_EXTR_RS_W:
13668 tcg_gen_movi_tl(t0, v2);
13669 tcg_gen_movi_tl(t1, v1);
13670 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13671 break;
13672 case OPC_EXTR_S_H:
13673 tcg_gen_movi_tl(t0, v2);
13674 tcg_gen_movi_tl(t1, v1);
13675 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13676 break;
13677 case OPC_EXTRV_S_H:
13678 tcg_gen_movi_tl(t0, v2);
13679 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13680 break;
13681 case OPC_EXTRV_W:
13682 tcg_gen_movi_tl(t0, v2);
13683 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13684 break;
13685 case OPC_EXTRV_R_W:
13686 tcg_gen_movi_tl(t0, v2);
13687 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13688 break;
13689 case OPC_EXTRV_RS_W:
13690 tcg_gen_movi_tl(t0, v2);
13691 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13692 break;
13693 case OPC_EXTP:
13694 tcg_gen_movi_tl(t0, v2);
13695 tcg_gen_movi_tl(t1, v1);
13696 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
13697 break;
13698 case OPC_EXTPV:
13699 tcg_gen_movi_tl(t0, v2);
13700 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
13701 break;
13702 case OPC_EXTPDP:
13703 tcg_gen_movi_tl(t0, v2);
13704 tcg_gen_movi_tl(t1, v1);
13705 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
13706 break;
13707 case OPC_EXTPDPV:
13708 tcg_gen_movi_tl(t0, v2);
13709 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13710 break;
13711 case OPC_SHILO:
13712 imm = (ctx->opcode >> 20) & 0x3F;
13713 tcg_gen_movi_tl(t0, ret);
13714 tcg_gen_movi_tl(t1, imm);
13715 gen_helper_shilo(t0, t1, cpu_env);
13716 break;
13717 case OPC_SHILOV:
13718 tcg_gen_movi_tl(t0, ret);
13719 gen_helper_shilo(t0, v1_t, cpu_env);
13720 break;
13721 case OPC_MTHLIP:
13722 tcg_gen_movi_tl(t0, ret);
13723 gen_helper_mthlip(t0, v1_t, cpu_env);
13724 break;
13725 case OPC_WRDSP:
13726 imm = (ctx->opcode >> 11) & 0x3FF;
13727 tcg_gen_movi_tl(t0, imm);
13728 gen_helper_wrdsp(v1_t, t0, cpu_env);
13729 break;
13730 case OPC_RDDSP:
13731 imm = (ctx->opcode >> 16) & 0x03FF;
13732 tcg_gen_movi_tl(t0, imm);
13733 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
13734 break;
13735 }
13736 break;
13737 #ifdef TARGET_MIPS64
13738 case OPC_DEXTR_W_DSP:
13739 check_dsp(ctx);
13740 switch (op2) {
13741 case OPC_DMTHLIP:
13742 tcg_gen_movi_tl(t0, ret);
13743 gen_helper_dmthlip(v1_t, t0, cpu_env);
13744 break;
13745 case OPC_DSHILO:
13746 {
13747 int shift = (ctx->opcode >> 19) & 0x7F;
13748 int ac = (ctx->opcode >> 11) & 0x03;
13749 tcg_gen_movi_tl(t0, shift);
13750 tcg_gen_movi_tl(t1, ac);
13751 gen_helper_dshilo(t0, t1, cpu_env);
13752 break;
13753 }
13754 case OPC_DSHILOV:
13755 {
13756 int ac = (ctx->opcode >> 11) & 0x03;
13757 tcg_gen_movi_tl(t0, ac);
13758 gen_helper_dshilo(v1_t, t0, cpu_env);
13759 break;
13760 }
13761 case OPC_DEXTP:
13762 tcg_gen_movi_tl(t0, v2);
13763 tcg_gen_movi_tl(t1, v1);
13764
13765 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
13766 break;
13767 case OPC_DEXTPV:
13768 tcg_gen_movi_tl(t0, v2);
13769 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
13770 break;
13771 case OPC_DEXTPDP:
13772 tcg_gen_movi_tl(t0, v2);
13773 tcg_gen_movi_tl(t1, v1);
13774 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
13775 break;
13776 case OPC_DEXTPDPV:
13777 tcg_gen_movi_tl(t0, v2);
13778 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13779 break;
13780 case OPC_DEXTR_L:
13781 tcg_gen_movi_tl(t0, v2);
13782 tcg_gen_movi_tl(t1, v1);
13783 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
13784 break;
13785 case OPC_DEXTR_R_L:
13786 tcg_gen_movi_tl(t0, v2);
13787 tcg_gen_movi_tl(t1, v1);
13788 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
13789 break;
13790 case OPC_DEXTR_RS_L:
13791 tcg_gen_movi_tl(t0, v2);
13792 tcg_gen_movi_tl(t1, v1);
13793 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
13794 break;
13795 case OPC_DEXTR_W:
13796 tcg_gen_movi_tl(t0, v2);
13797 tcg_gen_movi_tl(t1, v1);
13798 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
13799 break;
13800 case OPC_DEXTR_R_W:
13801 tcg_gen_movi_tl(t0, v2);
13802 tcg_gen_movi_tl(t1, v1);
13803 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13804 break;
13805 case OPC_DEXTR_RS_W:
13806 tcg_gen_movi_tl(t0, v2);
13807 tcg_gen_movi_tl(t1, v1);
13808 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13809 break;
13810 case OPC_DEXTR_S_H:
13811 tcg_gen_movi_tl(t0, v2);
13812 tcg_gen_movi_tl(t1, v1);
13813 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13814 break;
13815 case OPC_DEXTRV_S_H:
13816 tcg_gen_movi_tl(t0, v2);
13817 gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13818 break;
13819 case OPC_DEXTRV_L:
13820 tcg_gen_movi_tl(t0, v2);
13821 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13822 break;
13823 case OPC_DEXTRV_R_L:
13824 tcg_gen_movi_tl(t0, v2);
13825 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13826 break;
13827 case OPC_DEXTRV_RS_L:
13828 tcg_gen_movi_tl(t0, v2);
13829 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13830 break;
13831 case OPC_DEXTRV_W:
13832 tcg_gen_movi_tl(t0, v2);
13833 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13834 break;
13835 case OPC_DEXTRV_R_W:
13836 tcg_gen_movi_tl(t0, v2);
13837 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13838 break;
13839 case OPC_DEXTRV_RS_W:
13840 tcg_gen_movi_tl(t0, v2);
13841 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13842 break;
13843 }
13844 break;
13845 #endif
13846 }
13847
13848 tcg_temp_free(t0);
13849 tcg_temp_free(t1);
13850 tcg_temp_free(v1_t);
13851 }
13852
13853 /* End MIPSDSP functions. */
13854
13855 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13856 {
13857 int rs, rt, rd, sa;
13858 uint32_t op1, op2;
13859
13860 rs = (ctx->opcode >> 21) & 0x1f;
13861 rt = (ctx->opcode >> 16) & 0x1f;
13862 rd = (ctx->opcode >> 11) & 0x1f;
13863 sa = (ctx->opcode >> 6) & 0x1f;
13864
13865 op1 = MASK_SPECIAL(ctx->opcode);
13866 switch (op1) {
13867 case OPC_MULT:
13868 case OPC_MULTU:
13869 case OPC_DIV:
13870 case OPC_DIVU:
13871 op2 = MASK_R6_MULDIV(ctx->opcode);
13872 switch (op2) {
13873 case R6_OPC_MUL:
13874 case R6_OPC_MUH:
13875 case R6_OPC_MULU:
13876 case R6_OPC_MUHU:
13877 case R6_OPC_DIV:
13878 case R6_OPC_MOD:
13879 case R6_OPC_DIVU:
13880 case R6_OPC_MODU:
13881 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13882 break;
13883 default:
13884 MIPS_INVAL("special_r6 muldiv");
13885 gen_reserved_instruction(ctx);
13886 break;
13887 }
13888 break;
13889 case OPC_SELEQZ:
13890 case OPC_SELNEZ:
13891 gen_cond_move(ctx, op1, rd, rs, rt);
13892 break;
13893 case R6_OPC_CLO:
13894 case R6_OPC_CLZ:
13895 if (rt == 0 && sa == 1) {
13896 /*
13897 * Major opcode and function field is shared with preR6 MFHI/MTHI.
13898 * We need additionally to check other fields.
13899 */
13900 gen_cl(ctx, op1, rd, rs);
13901 } else {
13902 gen_reserved_instruction(ctx);
13903 }
13904 break;
13905 case R6_OPC_SDBBP:
13906 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
13907 ctx->base.is_jmp = DISAS_SEMIHOST;
13908 } else {
13909 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13910 gen_reserved_instruction(ctx);
13911 } else {
13912 generate_exception_end(ctx, EXCP_DBp);
13913 }
13914 }
13915 break;
13916 #if defined(TARGET_MIPS64)
13917 case R6_OPC_DCLO:
13918 case R6_OPC_DCLZ:
13919 if (rt == 0 && sa == 1) {
13920 /*
13921 * Major opcode and function field is shared with preR6 MFHI/MTHI.
13922 * We need additionally to check other fields.
13923 */
13924 check_mips_64(ctx);
13925 gen_cl(ctx, op1, rd, rs);
13926 } else {
13927 gen_reserved_instruction(ctx);
13928 }
13929 break;
13930 case OPC_DMULT:
13931 case OPC_DMULTU:
13932 case OPC_DDIV:
13933 case OPC_DDIVU:
13934
13935 op2 = MASK_R6_MULDIV(ctx->opcode);
13936 switch (op2) {
13937 case R6_OPC_DMUL:
13938 case R6_OPC_DMUH:
13939 case R6_OPC_DMULU:
13940 case R6_OPC_DMUHU:
13941 case R6_OPC_DDIV:
13942 case R6_OPC_DMOD:
13943 case R6_OPC_DDIVU:
13944 case R6_OPC_DMODU:
13945 check_mips_64(ctx);
13946 gen_r6_muldiv(ctx, op2, rd, rs, rt);
13947 break;
13948 default:
13949 MIPS_INVAL("special_r6 muldiv");
13950 gen_reserved_instruction(ctx);
13951 break;
13952 }
13953 break;
13954 #endif
13955 default: /* Invalid */
13956 MIPS_INVAL("special_r6");
13957 gen_reserved_instruction(ctx);
13958 break;
13959 }
13960 }
13961
13962 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13963 {
13964 int rs = extract32(ctx->opcode, 21, 5);
13965 int rt = extract32(ctx->opcode, 16, 5);
13966 int rd = extract32(ctx->opcode, 11, 5);
13967 uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13968
13969 switch (op1) {
13970 case OPC_MOVN: /* Conditional move */
13971 case OPC_MOVZ:
13972 gen_cond_move(ctx, op1, rd, rs, rt);
13973 break;
13974 case OPC_MFHI: /* Move from HI/LO */
13975 case OPC_MFLO:
13976 gen_HILO(ctx, op1, 0, rd);
13977 break;
13978 case OPC_MTHI:
13979 case OPC_MTLO: /* Move to HI/LO */
13980 gen_HILO(ctx, op1, 0, rs);
13981 break;
13982 case OPC_MULT:
13983 case OPC_MULTU:
13984 gen_mul_txx9(ctx, op1, rd, rs, rt);
13985 break;
13986 case OPC_DIV:
13987 case OPC_DIVU:
13988 gen_muldiv(ctx, op1, 0, rs, rt);
13989 break;
13990 #if defined(TARGET_MIPS64)
13991 case OPC_DMULT:
13992 case OPC_DMULTU:
13993 case OPC_DDIV:
13994 case OPC_DDIVU:
13995 check_insn_opc_user_only(ctx, INSN_R5900);
13996 gen_muldiv(ctx, op1, 0, rs, rt);
13997 break;
13998 #endif
13999 case OPC_JR:
14000 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14001 break;
14002 default: /* Invalid */
14003 MIPS_INVAL("special_tx79");
14004 gen_reserved_instruction(ctx);
14005 break;
14006 }
14007 }
14008
14009 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
14010 {
14011 int rs, rt, rd;
14012 uint32_t op1;
14013
14014 rs = (ctx->opcode >> 21) & 0x1f;
14015 rt = (ctx->opcode >> 16) & 0x1f;
14016 rd = (ctx->opcode >> 11) & 0x1f;
14017
14018 op1 = MASK_SPECIAL(ctx->opcode);
14019 switch (op1) {
14020 case OPC_MOVN: /* Conditional move */
14021 case OPC_MOVZ:
14022 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
14023 INSN_LOONGSON2E | INSN_LOONGSON2F);
14024 gen_cond_move(ctx, op1, rd, rs, rt);
14025 break;
14026 case OPC_MFHI: /* Move from HI/LO */
14027 case OPC_MFLO:
14028 gen_HILO(ctx, op1, rs & 3, rd);
14029 break;
14030 case OPC_MTHI:
14031 case OPC_MTLO: /* Move to HI/LO */
14032 gen_HILO(ctx, op1, rd & 3, rs);
14033 break;
14034 case OPC_MOVCI:
14035 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
14036 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14037 check_cp1_enabled(ctx);
14038 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14039 (ctx->opcode >> 16) & 1);
14040 } else {
14041 generate_exception_err(ctx, EXCP_CpU, 1);
14042 }
14043 break;
14044 case OPC_MULT:
14045 case OPC_MULTU:
14046 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14047 break;
14048 case OPC_DIV:
14049 case OPC_DIVU:
14050 gen_muldiv(ctx, op1, 0, rs, rt);
14051 break;
14052 #if defined(TARGET_MIPS64)
14053 case OPC_DMULT:
14054 case OPC_DMULTU:
14055 case OPC_DDIV:
14056 case OPC_DDIVU:
14057 check_insn(ctx, ISA_MIPS3);
14058 check_mips_64(ctx);
14059 gen_muldiv(ctx, op1, 0, rs, rt);
14060 break;
14061 #endif
14062 case OPC_JR:
14063 gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14064 break;
14065 case OPC_SPIM:
14066 #ifdef MIPS_STRICT_STANDARD
14067 MIPS_INVAL("SPIM");
14068 gen_reserved_instruction(ctx);
14069 #else
14070 /* Implemented as RI exception for now. */
14071 MIPS_INVAL("spim (unofficial)");
14072 gen_reserved_instruction(ctx);
14073 #endif
14074 break;
14075 default: /* Invalid */
14076 MIPS_INVAL("special_legacy");
14077 gen_reserved_instruction(ctx);
14078 break;
14079 }
14080 }
14081
14082 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
14083 {
14084 int rs, rt, rd, sa;
14085 uint32_t op1;
14086
14087 rs = (ctx->opcode >> 21) & 0x1f;
14088 rt = (ctx->opcode >> 16) & 0x1f;
14089 rd = (ctx->opcode >> 11) & 0x1f;
14090 sa = (ctx->opcode >> 6) & 0x1f;
14091
14092 op1 = MASK_SPECIAL(ctx->opcode);
14093 switch (op1) {
14094 case OPC_SLL: /* Shift with immediate */
14095 if (sa == 5 && rd == 0 &&
14096 rs == 0 && rt == 0) { /* PAUSE */
14097 if ((ctx->insn_flags & ISA_MIPS_R6) &&
14098 (ctx->hflags & MIPS_HFLAG_BMASK)) {
14099 gen_reserved_instruction(ctx);
14100 break;
14101 }
14102 }
14103 /* Fallthrough */
14104 case OPC_SRA:
14105 gen_shift_imm(ctx, op1, rd, rt, sa);
14106 break;
14107 case OPC_SRL:
14108 switch ((ctx->opcode >> 21) & 0x1f) {
14109 case 1:
14110 /* rotr is decoded as srl on non-R2 CPUs */
14111 if (ctx->insn_flags & ISA_MIPS_R2) {
14112 op1 = OPC_ROTR;
14113 }
14114 /* Fallthrough */
14115 case 0:
14116 gen_shift_imm(ctx, op1, rd, rt, sa);
14117 break;
14118 default:
14119 gen_reserved_instruction(ctx);
14120 break;
14121 }
14122 break;
14123 case OPC_ADD:
14124 case OPC_ADDU:
14125 case OPC_SUB:
14126 case OPC_SUBU:
14127 gen_arith(ctx, op1, rd, rs, rt);
14128 break;
14129 case OPC_SLLV: /* Shifts */
14130 case OPC_SRAV:
14131 gen_shift(ctx, op1, rd, rs, rt);
14132 break;
14133 case OPC_SRLV:
14134 switch ((ctx->opcode >> 6) & 0x1f) {
14135 case 1:
14136 /* rotrv is decoded as srlv on non-R2 CPUs */
14137 if (ctx->insn_flags & ISA_MIPS_R2) {
14138 op1 = OPC_ROTRV;
14139 }
14140 /* Fallthrough */
14141 case 0:
14142 gen_shift(ctx, op1, rd, rs, rt);
14143 break;
14144 default:
14145 gen_reserved_instruction(ctx);
14146 break;
14147 }
14148 break;
14149 case OPC_SLT: /* Set on less than */
14150 case OPC_SLTU:
14151 gen_slt(ctx, op1, rd, rs, rt);
14152 break;
14153 case OPC_AND: /* Logic*/
14154 case OPC_OR:
14155 case OPC_NOR:
14156 case OPC_XOR:
14157 gen_logic(ctx, op1, rd, rs, rt);
14158 break;
14159 case OPC_JALR:
14160 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
14161 break;
14162 case OPC_TGE: /* Traps */
14163 case OPC_TGEU:
14164 case OPC_TLT:
14165 case OPC_TLTU:
14166 case OPC_TEQ:
14167 case OPC_TNE:
14168 check_insn(ctx, ISA_MIPS2);
14169 gen_trap(ctx, op1, rs, rt, -1, extract32(ctx->opcode, 6, 10));
14170 break;
14171 case OPC_PMON:
14172 /* Pmon entry point, also R4010 selsl */
14173 #ifdef MIPS_STRICT_STANDARD
14174 MIPS_INVAL("PMON / selsl");
14175 gen_reserved_instruction(ctx);
14176 #else
14177 gen_helper_pmon(cpu_env, tcg_constant_i32(sa));
14178 #endif
14179 break;
14180 case OPC_SYSCALL:
14181 generate_exception_end(ctx, EXCP_SYSCALL);
14182 break;
14183 case OPC_BREAK:
14184 generate_exception_break(ctx, extract32(ctx->opcode, 6, 20));
14185 break;
14186 case OPC_SYNC:
14187 check_insn(ctx, ISA_MIPS2);
14188 gen_sync(extract32(ctx->opcode, 6, 5));
14189 break;
14190
14191 #if defined(TARGET_MIPS64)
14192 /* MIPS64 specific opcodes */
14193 case OPC_DSLL:
14194 case OPC_DSRA:
14195 case OPC_DSLL32:
14196 case OPC_DSRA32:
14197 check_insn(ctx, ISA_MIPS3);
14198 check_mips_64(ctx);
14199 gen_shift_imm(ctx, op1, rd, rt, sa);
14200 break;
14201 case OPC_DSRL:
14202 switch ((ctx->opcode >> 21) & 0x1f) {
14203 case 1:
14204 /* drotr is decoded as dsrl on non-R2 CPUs */
14205 if (ctx->insn_flags & ISA_MIPS_R2) {
14206 op1 = OPC_DROTR;
14207 }
14208 /* Fallthrough */
14209 case 0:
14210 check_insn(ctx, ISA_MIPS3);
14211 check_mips_64(ctx);
14212 gen_shift_imm(ctx, op1, rd, rt, sa);
14213 break;
14214 default:
14215 gen_reserved_instruction(ctx);
14216 break;
14217 }
14218 break;
14219 case OPC_DSRL32:
14220 switch ((ctx->opcode >> 21) & 0x1f) {
14221 case 1:
14222 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14223 if (ctx->insn_flags & ISA_MIPS_R2) {
14224 op1 = OPC_DROTR32;
14225 }
14226 /* Fallthrough */
14227 case 0:
14228 check_insn(ctx, ISA_MIPS3);
14229 check_mips_64(ctx);
14230 gen_shift_imm(ctx, op1, rd, rt, sa);
14231 break;
14232 default:
14233 gen_reserved_instruction(ctx);
14234 break;
14235 }
14236 break;
14237 case OPC_DADD:
14238 case OPC_DADDU:
14239 case OPC_DSUB:
14240 case OPC_DSUBU:
14241 check_insn(ctx, ISA_MIPS3);
14242 check_mips_64(ctx);
14243 gen_arith(ctx, op1, rd, rs, rt);
14244 break;
14245 case OPC_DSLLV:
14246 case OPC_DSRAV:
14247 check_insn(ctx, ISA_MIPS3);
14248 check_mips_64(ctx);
14249 gen_shift(ctx, op1, rd, rs, rt);
14250 break;
14251 case OPC_DSRLV:
14252 switch ((ctx->opcode >> 6) & 0x1f) {
14253 case 1:
14254 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14255 if (ctx->insn_flags & ISA_MIPS_R2) {
14256 op1 = OPC_DROTRV;
14257 }
14258 /* Fallthrough */
14259 case 0:
14260 check_insn(ctx, ISA_MIPS3);
14261 check_mips_64(ctx);
14262 gen_shift(ctx, op1, rd, rs, rt);
14263 break;
14264 default:
14265 gen_reserved_instruction(ctx);
14266 break;
14267 }
14268 break;
14269 #endif
14270 default:
14271 if (ctx->insn_flags & ISA_MIPS_R6) {
14272 decode_opc_special_r6(env, ctx);
14273 } else if (ctx->insn_flags & INSN_R5900) {
14274 decode_opc_special_tx79(env, ctx);
14275 } else {
14276 decode_opc_special_legacy(env, ctx);
14277 }
14278 }
14279 }
14280
14281
14282 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
14283 {
14284 int rs, rt, rd;
14285 uint32_t op1;
14286
14287 rs = (ctx->opcode >> 21) & 0x1f;
14288 rt = (ctx->opcode >> 16) & 0x1f;
14289 rd = (ctx->opcode >> 11) & 0x1f;
14290
14291 op1 = MASK_SPECIAL2(ctx->opcode);
14292 switch (op1) {
14293 case OPC_MADD: /* Multiply and add/sub */
14294 case OPC_MADDU:
14295 case OPC_MSUB:
14296 case OPC_MSUBU:
14297 check_insn(ctx, ISA_MIPS_R1);
14298 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14299 break;
14300 case OPC_MUL:
14301 gen_arith(ctx, op1, rd, rs, rt);
14302 break;
14303 case OPC_DIV_G_2F:
14304 case OPC_DIVU_G_2F:
14305 case OPC_MULT_G_2F:
14306 case OPC_MULTU_G_2F:
14307 case OPC_MOD_G_2F:
14308 case OPC_MODU_G_2F:
14309 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14310 gen_loongson_integer(ctx, op1, rd, rs, rt);
14311 break;
14312 case OPC_CLO:
14313 case OPC_CLZ:
14314 check_insn(ctx, ISA_MIPS_R1);
14315 gen_cl(ctx, op1, rd, rs);
14316 break;
14317 case OPC_SDBBP:
14318 if (is_uhi(ctx, extract32(ctx->opcode, 6, 20))) {
14319 ctx->base.is_jmp = DISAS_SEMIHOST;
14320 } else {
14321 /*
14322 * XXX: not clear which exception should be raised
14323 * when in debug mode...
14324 */
14325 check_insn(ctx, ISA_MIPS_R1);
14326 generate_exception_end(ctx, EXCP_DBp);
14327 }
14328 break;
14329 #if defined(TARGET_MIPS64)
14330 case OPC_DCLO:
14331 case OPC_DCLZ:
14332 check_insn(ctx, ISA_MIPS_R1);
14333 check_mips_64(ctx);
14334 gen_cl(ctx, op1, rd, rs);
14335 break;
14336 case OPC_DMULT_G_2F:
14337 case OPC_DMULTU_G_2F:
14338 case OPC_DDIV_G_2F:
14339 case OPC_DDIVU_G_2F:
14340 case OPC_DMOD_G_2F:
14341 case OPC_DMODU_G_2F:
14342 check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14343 gen_loongson_integer(ctx, op1, rd, rs, rt);
14344 break;
14345 #endif
14346 default: /* Invalid */
14347 MIPS_INVAL("special2_legacy");
14348 gen_reserved_instruction(ctx);
14349 break;
14350 }
14351 }
14352
14353 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
14354 {
14355 int rs, rt, rd, sa;
14356 uint32_t op1, op2;
14357 int16_t imm;
14358
14359 rs = (ctx->opcode >> 21) & 0x1f;
14360 rt = (ctx->opcode >> 16) & 0x1f;
14361 rd = (ctx->opcode >> 11) & 0x1f;
14362 sa = (ctx->opcode >> 6) & 0x1f;
14363 imm = (int16_t)ctx->opcode >> 7;
14364
14365 op1 = MASK_SPECIAL3(ctx->opcode);
14366 switch (op1) {
14367 case R6_OPC_PREF:
14368 if (rt >= 24) {
14369 /* hint codes 24-31 are reserved and signal RI */
14370 gen_reserved_instruction(ctx);
14371 }
14372 /* Treat as NOP. */
14373 break;
14374 case R6_OPC_CACHE:
14375 check_cp0_enabled(ctx);
14376 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14377 gen_cache_operation(ctx, rt, rs, imm);
14378 }
14379 break;
14380 case R6_OPC_SC:
14381 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
14382 break;
14383 case R6_OPC_LL:
14384 gen_ld(ctx, op1, rt, rs, imm);
14385 break;
14386 case OPC_BSHFL:
14387 {
14388 if (rd == 0) {
14389 /* Treat as NOP. */
14390 break;
14391 }
14392 op2 = MASK_BSHFL(ctx->opcode);
14393 switch (op2) {
14394 case OPC_ALIGN:
14395 case OPC_ALIGN_1:
14396 case OPC_ALIGN_2:
14397 case OPC_ALIGN_3:
14398 gen_align(ctx, 32, rd, rs, rt, sa & 3);
14399 break;
14400 case OPC_BITSWAP:
14401 gen_bitswap(ctx, op2, rd, rt);
14402 break;
14403 }
14404 }
14405 break;
14406 #ifndef CONFIG_USER_ONLY
14407 case OPC_GINV:
14408 if (unlikely(ctx->gi <= 1)) {
14409 gen_reserved_instruction(ctx);
14410 }
14411 check_cp0_enabled(ctx);
14412 switch ((ctx->opcode >> 6) & 3) {
14413 case 0: /* GINVI */
14414 /* Treat as NOP. */
14415 break;
14416 case 2: /* GINVT */
14417 gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
14418 break;
14419 default:
14420 gen_reserved_instruction(ctx);
14421 break;
14422 }
14423 break;
14424 #endif
14425 #if defined(TARGET_MIPS64)
14426 case R6_OPC_SCD:
14427 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
14428 break;
14429 case R6_OPC_LLD:
14430 gen_ld(ctx, op1, rt, rs, imm);
14431 break;
14432 case OPC_DBSHFL:
14433 check_mips_64(ctx);
14434 {
14435 if (rd == 0) {
14436 /* Treat as NOP. */
14437 break;
14438 }
14439 op2 = MASK_DBSHFL(ctx->opcode);
14440 switch (op2) {
14441 case OPC_DALIGN:
14442 case OPC_DALIGN_1:
14443 case OPC_DALIGN_2:
14444 case OPC_DALIGN_3:
14445 case OPC_DALIGN_4:
14446 case OPC_DALIGN_5:
14447 case OPC_DALIGN_6:
14448 case OPC_DALIGN_7:
14449 gen_align(ctx, 64, rd, rs, rt, sa & 7);
14450 break;
14451 case OPC_DBITSWAP:
14452 gen_bitswap(ctx, op2, rd, rt);
14453 break;
14454 }
14455
14456 }
14457 break;
14458 #endif
14459 default: /* Invalid */
14460 MIPS_INVAL("special3_r6");
14461 gen_reserved_instruction(ctx);
14462 break;
14463 }
14464 }
14465
14466 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
14467 {
14468 int rs, rt, rd;
14469 uint32_t op1, op2;
14470
14471 rs = (ctx->opcode >> 21) & 0x1f;
14472 rt = (ctx->opcode >> 16) & 0x1f;
14473 rd = (ctx->opcode >> 11) & 0x1f;
14474
14475 op1 = MASK_SPECIAL3(ctx->opcode);
14476 switch (op1) {
14477 case OPC_DIV_G_2E:
14478 case OPC_DIVU_G_2E:
14479 case OPC_MOD_G_2E:
14480 case OPC_MODU_G_2E:
14481 case OPC_MULT_G_2E:
14482 case OPC_MULTU_G_2E:
14483 /*
14484 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14485 * the same mask and op1.
14486 */
14487 if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
14488 op2 = MASK_ADDUH_QB(ctx->opcode);
14489 switch (op2) {
14490 case OPC_ADDUH_QB:
14491 case OPC_ADDUH_R_QB:
14492 case OPC_ADDQH_PH:
14493 case OPC_ADDQH_R_PH:
14494 case OPC_ADDQH_W:
14495 case OPC_ADDQH_R_W:
14496 case OPC_SUBUH_QB:
14497 case OPC_SUBUH_R_QB:
14498 case OPC_SUBQH_PH:
14499 case OPC_SUBQH_R_PH:
14500 case OPC_SUBQH_W:
14501 case OPC_SUBQH_R_W:
14502 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14503 break;
14504 case OPC_MUL_PH:
14505 case OPC_MUL_S_PH:
14506 case OPC_MULQ_S_W:
14507 case OPC_MULQ_RS_W:
14508 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14509 break;
14510 default:
14511 MIPS_INVAL("MASK ADDUH.QB");
14512 gen_reserved_instruction(ctx);
14513 break;
14514 }
14515 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14516 gen_loongson_integer(ctx, op1, rd, rs, rt);
14517 } else {
14518 gen_reserved_instruction(ctx);
14519 }
14520 break;
14521 case OPC_LX_DSP:
14522 op2 = MASK_LX(ctx->opcode);
14523 switch (op2) {
14524 #if defined(TARGET_MIPS64)
14525 case OPC_LDX:
14526 #endif
14527 case OPC_LBUX:
14528 case OPC_LHX:
14529 case OPC_LWX:
14530 gen_mips_lx(ctx, op2, rd, rs, rt);
14531 break;
14532 default: /* Invalid */
14533 MIPS_INVAL("MASK LX");
14534 gen_reserved_instruction(ctx);
14535 break;
14536 }
14537 break;
14538 case OPC_ABSQ_S_PH_DSP:
14539 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14540 switch (op2) {
14541 case OPC_ABSQ_S_QB:
14542 case OPC_ABSQ_S_PH:
14543 case OPC_ABSQ_S_W:
14544 case OPC_PRECEQ_W_PHL:
14545 case OPC_PRECEQ_W_PHR:
14546 case OPC_PRECEQU_PH_QBL:
14547 case OPC_PRECEQU_PH_QBR:
14548 case OPC_PRECEQU_PH_QBLA:
14549 case OPC_PRECEQU_PH_QBRA:
14550 case OPC_PRECEU_PH_QBL:
14551 case OPC_PRECEU_PH_QBR:
14552 case OPC_PRECEU_PH_QBLA:
14553 case OPC_PRECEU_PH_QBRA:
14554 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14555 break;
14556 case OPC_BITREV:
14557 case OPC_REPL_QB:
14558 case OPC_REPLV_QB:
14559 case OPC_REPL_PH:
14560 case OPC_REPLV_PH:
14561 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14562 break;
14563 default:
14564 MIPS_INVAL("MASK ABSQ_S.PH");
14565 gen_reserved_instruction(ctx);
14566 break;
14567 }
14568 break;
14569 case OPC_ADDU_QB_DSP:
14570 op2 = MASK_ADDU_QB(ctx->opcode);
14571 switch (op2) {
14572 case OPC_ADDQ_PH:
14573 case OPC_ADDQ_S_PH:
14574 case OPC_ADDQ_S_W:
14575 case OPC_ADDU_QB:
14576 case OPC_ADDU_S_QB:
14577 case OPC_ADDU_PH:
14578 case OPC_ADDU_S_PH:
14579 case OPC_SUBQ_PH:
14580 case OPC_SUBQ_S_PH:
14581 case OPC_SUBQ_S_W:
14582 case OPC_SUBU_QB:
14583 case OPC_SUBU_S_QB:
14584 case OPC_SUBU_PH:
14585 case OPC_SUBU_S_PH:
14586 case OPC_ADDSC:
14587 case OPC_ADDWC:
14588 case OPC_MODSUB:
14589 case OPC_RADDU_W_QB:
14590 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14591 break;
14592 case OPC_MULEU_S_PH_QBL:
14593 case OPC_MULEU_S_PH_QBR:
14594 case OPC_MULQ_RS_PH:
14595 case OPC_MULEQ_S_W_PHL:
14596 case OPC_MULEQ_S_W_PHR:
14597 case OPC_MULQ_S_PH:
14598 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14599 break;
14600 default: /* Invalid */
14601 MIPS_INVAL("MASK ADDU.QB");
14602 gen_reserved_instruction(ctx);
14603 break;
14604
14605 }
14606 break;
14607 case OPC_CMPU_EQ_QB_DSP:
14608 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14609 switch (op2) {
14610 case OPC_PRECR_SRA_PH_W:
14611 case OPC_PRECR_SRA_R_PH_W:
14612 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14613 break;
14614 case OPC_PRECR_QB_PH:
14615 case OPC_PRECRQ_QB_PH:
14616 case OPC_PRECRQ_PH_W:
14617 case OPC_PRECRQ_RS_PH_W:
14618 case OPC_PRECRQU_S_QB_PH:
14619 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14620 break;
14621 case OPC_CMPU_EQ_QB:
14622 case OPC_CMPU_LT_QB:
14623 case OPC_CMPU_LE_QB:
14624 case OPC_CMP_EQ_PH:
14625 case OPC_CMP_LT_PH:
14626 case OPC_CMP_LE_PH:
14627 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14628 break;
14629 case OPC_CMPGU_EQ_QB:
14630 case OPC_CMPGU_LT_QB:
14631 case OPC_CMPGU_LE_QB:
14632 case OPC_CMPGDU_EQ_QB:
14633 case OPC_CMPGDU_LT_QB:
14634 case OPC_CMPGDU_LE_QB:
14635 case OPC_PICK_QB:
14636 case OPC_PICK_PH:
14637 case OPC_PACKRL_PH:
14638 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14639 break;
14640 default: /* Invalid */
14641 MIPS_INVAL("MASK CMPU.EQ.QB");
14642 gen_reserved_instruction(ctx);
14643 break;
14644 }
14645 break;
14646 case OPC_SHLL_QB_DSP:
14647 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14648 break;
14649 case OPC_DPA_W_PH_DSP:
14650 op2 = MASK_DPA_W_PH(ctx->opcode);
14651 switch (op2) {
14652 case OPC_DPAU_H_QBL:
14653 case OPC_DPAU_H_QBR:
14654 case OPC_DPSU_H_QBL:
14655 case OPC_DPSU_H_QBR:
14656 case OPC_DPA_W_PH:
14657 case OPC_DPAX_W_PH:
14658 case OPC_DPAQ_S_W_PH:
14659 case OPC_DPAQX_S_W_PH:
14660 case OPC_DPAQX_SA_W_PH:
14661 case OPC_DPS_W_PH:
14662 case OPC_DPSX_W_PH:
14663 case OPC_DPSQ_S_W_PH:
14664 case OPC_DPSQX_S_W_PH:
14665 case OPC_DPSQX_SA_W_PH:
14666 case OPC_MULSAQ_S_W_PH:
14667 case OPC_DPAQ_SA_L_W:
14668 case OPC_DPSQ_SA_L_W:
14669 case OPC_MAQ_S_W_PHL:
14670 case OPC_MAQ_S_W_PHR:
14671 case OPC_MAQ_SA_W_PHL:
14672 case OPC_MAQ_SA_W_PHR:
14673 case OPC_MULSA_W_PH:
14674 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14675 break;
14676 default: /* Invalid */
14677 MIPS_INVAL("MASK DPAW.PH");
14678 gen_reserved_instruction(ctx);
14679 break;
14680 }
14681 break;
14682 case OPC_INSV_DSP:
14683 op2 = MASK_INSV(ctx->opcode);
14684 switch (op2) {
14685 case OPC_INSV:
14686 check_dsp(ctx);
14687 {
14688 TCGv t0, t1;
14689
14690 if (rt == 0) {
14691 break;
14692 }
14693
14694 t0 = tcg_temp_new();
14695 t1 = tcg_temp_new();
14696
14697 gen_load_gpr(t0, rt);
14698 gen_load_gpr(t1, rs);
14699
14700 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14701
14702 tcg_temp_free(t0);
14703 tcg_temp_free(t1);
14704 break;
14705 }
14706 default: /* Invalid */
14707 MIPS_INVAL("MASK INSV");
14708 gen_reserved_instruction(ctx);
14709 break;
14710 }
14711 break;
14712 case OPC_APPEND_DSP:
14713 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14714 break;
14715 case OPC_EXTR_W_DSP:
14716 op2 = MASK_EXTR_W(ctx->opcode);
14717 switch (op2) {
14718 case OPC_EXTR_W:
14719 case OPC_EXTR_R_W:
14720 case OPC_EXTR_RS_W:
14721 case OPC_EXTR_S_H:
14722 case OPC_EXTRV_S_H:
14723 case OPC_EXTRV_W:
14724 case OPC_EXTRV_R_W:
14725 case OPC_EXTRV_RS_W:
14726 case OPC_EXTP:
14727 case OPC_EXTPV:
14728 case OPC_EXTPDP:
14729 case OPC_EXTPDPV:
14730 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14731 break;
14732 case OPC_RDDSP:
14733 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14734 break;
14735 case OPC_SHILO:
14736 case OPC_SHILOV:
14737 case OPC_MTHLIP:
14738 case OPC_WRDSP:
14739 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14740 break;
14741 default: /* Invalid */
14742 MIPS_INVAL("MASK EXTR.W");
14743 gen_reserved_instruction(ctx);
14744 break;
14745 }
14746 break;
14747 #if defined(TARGET_MIPS64)
14748 case OPC_DDIV_G_2E:
14749 case OPC_DDIVU_G_2E:
14750 case OPC_DMULT_G_2E:
14751 case OPC_DMULTU_G_2E:
14752 case OPC_DMOD_G_2E:
14753 case OPC_DMODU_G_2E:
14754 check_insn(ctx, INSN_LOONGSON2E);
14755 gen_loongson_integer(ctx, op1, rd, rs, rt);
14756 break;
14757 case OPC_ABSQ_S_QH_DSP:
14758 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14759 switch (op2) {
14760 case OPC_PRECEQ_L_PWL:
14761 case OPC_PRECEQ_L_PWR:
14762 case OPC_PRECEQ_PW_QHL:
14763 case OPC_PRECEQ_PW_QHR:
14764 case OPC_PRECEQ_PW_QHLA:
14765 case OPC_PRECEQ_PW_QHRA:
14766 case OPC_PRECEQU_QH_OBL:
14767 case OPC_PRECEQU_QH_OBR:
14768 case OPC_PRECEQU_QH_OBLA:
14769 case OPC_PRECEQU_QH_OBRA:
14770 case OPC_PRECEU_QH_OBL:
14771 case OPC_PRECEU_QH_OBR:
14772 case OPC_PRECEU_QH_OBLA:
14773 case OPC_PRECEU_QH_OBRA:
14774 case OPC_ABSQ_S_OB:
14775 case OPC_ABSQ_S_PW:
14776 case OPC_ABSQ_S_QH:
14777 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14778 break;
14779 case OPC_REPL_OB:
14780 case OPC_REPL_PW:
14781 case OPC_REPL_QH:
14782 case OPC_REPLV_OB:
14783 case OPC_REPLV_PW:
14784 case OPC_REPLV_QH:
14785 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14786 break;
14787 default: /* Invalid */
14788 MIPS_INVAL("MASK ABSQ_S.QH");
14789 gen_reserved_instruction(ctx);
14790 break;
14791 }
14792 break;
14793 case OPC_ADDU_OB_DSP:
14794 op2 = MASK_ADDU_OB(ctx->opcode);
14795 switch (op2) {
14796 case OPC_RADDU_L_OB:
14797 case OPC_SUBQ_PW:
14798 case OPC_SUBQ_S_PW:
14799 case OPC_SUBQ_QH:
14800 case OPC_SUBQ_S_QH:
14801 case OPC_SUBU_OB:
14802 case OPC_SUBU_S_OB:
14803 case OPC_SUBU_QH:
14804 case OPC_SUBU_S_QH:
14805 case OPC_SUBUH_OB:
14806 case OPC_SUBUH_R_OB:
14807 case OPC_ADDQ_PW:
14808 case OPC_ADDQ_S_PW:
14809 case OPC_ADDQ_QH:
14810 case OPC_ADDQ_S_QH:
14811 case OPC_ADDU_OB:
14812 case OPC_ADDU_S_OB:
14813 case OPC_ADDU_QH:
14814 case OPC_ADDU_S_QH:
14815 case OPC_ADDUH_OB:
14816 case OPC_ADDUH_R_OB:
14817 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14818 break;
14819 case OPC_MULEQ_S_PW_QHL:
14820 case OPC_MULEQ_S_PW_QHR:
14821 case OPC_MULEU_S_QH_OBL:
14822 case OPC_MULEU_S_QH_OBR:
14823 case OPC_MULQ_RS_QH:
14824 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14825 break;
14826 default: /* Invalid */
14827 MIPS_INVAL("MASK ADDU.OB");
14828 gen_reserved_instruction(ctx);
14829 break;
14830 }
14831 break;
14832 case OPC_CMPU_EQ_OB_DSP:
14833 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14834 switch (op2) {
14835 case OPC_PRECR_SRA_QH_PW:
14836 case OPC_PRECR_SRA_R_QH_PW:
14837 /* Return value is rt. */
14838 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14839 break;
14840 case OPC_PRECR_OB_QH:
14841 case OPC_PRECRQ_OB_QH:
14842 case OPC_PRECRQ_PW_L:
14843 case OPC_PRECRQ_QH_PW:
14844 case OPC_PRECRQ_RS_QH_PW:
14845 case OPC_PRECRQU_S_OB_QH:
14846 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14847 break;
14848 case OPC_CMPU_EQ_OB:
14849 case OPC_CMPU_LT_OB:
14850 case OPC_CMPU_LE_OB:
14851 case OPC_CMP_EQ_QH:
14852 case OPC_CMP_LT_QH:
14853 case OPC_CMP_LE_QH:
14854 case OPC_CMP_EQ_PW:
14855 case OPC_CMP_LT_PW:
14856 case OPC_CMP_LE_PW:
14857 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14858 break;
14859 case OPC_CMPGDU_EQ_OB:
14860 case OPC_CMPGDU_LT_OB:
14861 case OPC_CMPGDU_LE_OB:
14862 case OPC_CMPGU_EQ_OB:
14863 case OPC_CMPGU_LT_OB:
14864 case OPC_CMPGU_LE_OB:
14865 case OPC_PACKRL_PW:
14866 case OPC_PICK_OB:
14867 case OPC_PICK_PW:
14868 case OPC_PICK_QH:
14869 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14870 break;
14871 default: /* Invalid */
14872 MIPS_INVAL("MASK CMPU_EQ.OB");
14873 gen_reserved_instruction(ctx);
14874 break;
14875 }
14876 break;
14877 case OPC_DAPPEND_DSP:
14878 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14879 break;
14880 case OPC_DEXTR_W_DSP:
14881 op2 = MASK_DEXTR_W(ctx->opcode);
14882 switch (op2) {
14883 case OPC_DEXTP:
14884 case OPC_DEXTPDP:
14885 case OPC_DEXTPDPV:
14886 case OPC_DEXTPV:
14887 case OPC_DEXTR_L:
14888 case OPC_DEXTR_R_L:
14889 case OPC_DEXTR_RS_L:
14890 case OPC_DEXTR_W:
14891 case OPC_DEXTR_R_W:
14892 case OPC_DEXTR_RS_W:
14893 case OPC_DEXTR_S_H:
14894 case OPC_DEXTRV_L:
14895 case OPC_DEXTRV_R_L:
14896 case OPC_DEXTRV_RS_L:
14897 case OPC_DEXTRV_S_H:
14898 case OPC_DEXTRV_W:
14899 case OPC_DEXTRV_R_W:
14900 case OPC_DEXTRV_RS_W:
14901 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14902 break;
14903 case OPC_DMTHLIP:
14904 case OPC_DSHILO:
14905 case OPC_DSHILOV:
14906 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14907 break;
14908 default: /* Invalid */
14909 MIPS_INVAL("MASK EXTR.W");
14910 gen_reserved_instruction(ctx);
14911 break;
14912 }
14913 break;
14914 case OPC_DPAQ_W_QH_DSP:
14915 op2 = MASK_DPAQ_W_QH(ctx->opcode);
14916 switch (op2) {
14917 case OPC_DPAU_H_OBL:
14918 case OPC_DPAU_H_OBR:
14919 case OPC_DPSU_H_OBL:
14920 case OPC_DPSU_H_OBR:
14921 case OPC_DPA_W_QH:
14922 case OPC_DPAQ_S_W_QH:
14923 case OPC_DPS_W_QH:
14924 case OPC_DPSQ_S_W_QH:
14925 case OPC_MULSAQ_S_W_QH:
14926 case OPC_DPAQ_SA_L_PW:
14927 case OPC_DPSQ_SA_L_PW:
14928 case OPC_MULSAQ_S_L_PW:
14929 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14930 break;
14931 case OPC_MAQ_S_W_QHLL:
14932 case OPC_MAQ_S_W_QHLR:
14933 case OPC_MAQ_S_W_QHRL:
14934 case OPC_MAQ_S_W_QHRR:
14935 case OPC_MAQ_SA_W_QHLL:
14936 case OPC_MAQ_SA_W_QHLR:
14937 case OPC_MAQ_SA_W_QHRL:
14938 case OPC_MAQ_SA_W_QHRR:
14939 case OPC_MAQ_S_L_PWL:
14940 case OPC_MAQ_S_L_PWR:
14941 case OPC_DMADD:
14942 case OPC_DMADDU:
14943 case OPC_DMSUB:
14944 case OPC_DMSUBU:
14945 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14946 break;
14947 default: /* Invalid */
14948 MIPS_INVAL("MASK DPAQ.W.QH");
14949 gen_reserved_instruction(ctx);
14950 break;
14951 }
14952 break;
14953 case OPC_DINSV_DSP:
14954 op2 = MASK_INSV(ctx->opcode);
14955 switch (op2) {
14956 case OPC_DINSV:
14957 {
14958 TCGv t0, t1;
14959
14960 check_dsp(ctx);
14961
14962 if (rt == 0) {
14963 break;
14964 }
14965
14966 t0 = tcg_temp_new();
14967 t1 = tcg_temp_new();
14968
14969 gen_load_gpr(t0, rt);
14970 gen_load_gpr(t1, rs);
14971
14972 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
14973
14974 tcg_temp_free(t0);
14975 tcg_temp_free(t1);
14976 break;
14977 }
14978 default: /* Invalid */
14979 MIPS_INVAL("MASK DINSV");
14980 gen_reserved_instruction(ctx);
14981 break;
14982 }
14983 break;
14984 case OPC_SHLL_OB_DSP:
14985 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14986 break;
14987 #endif
14988 default: /* Invalid */
14989 MIPS_INVAL("special3_legacy");
14990 gen_reserved_instruction(ctx);
14991 break;
14992 }
14993 }
14994
14995
14996 #if defined(TARGET_MIPS64)
14997
14998 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
14999 {
15000 uint32_t opc = MASK_MMI(ctx->opcode);
15001 int rs = extract32(ctx->opcode, 21, 5);
15002 int rt = extract32(ctx->opcode, 16, 5);
15003 int rd = extract32(ctx->opcode, 11, 5);
15004
15005 switch (opc) {
15006 case MMI_OPC_MULT1:
15007 case MMI_OPC_MULTU1:
15008 case MMI_OPC_MADD:
15009 case MMI_OPC_MADDU:
15010 case MMI_OPC_MADD1:
15011 case MMI_OPC_MADDU1:
15012 gen_mul_txx9(ctx, opc, rd, rs, rt);
15013 break;
15014 case MMI_OPC_DIV1:
15015 case MMI_OPC_DIVU1:
15016 gen_div1_tx79(ctx, opc, rs, rt);
15017 break;
15018 default:
15019 MIPS_INVAL("TX79 MMI class");
15020 gen_reserved_instruction(ctx);
15021 break;
15022 }
15023 }
15024
15025 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
15026 {
15027 gen_reserved_instruction(ctx); /* TODO: MMI_OPC_SQ */
15028 }
15029
15030 /*
15031 * The TX79-specific instruction Store Quadword
15032 *
15033 * +--------+-------+-------+------------------------+
15034 * | 011111 | base | rt | offset | SQ
15035 * +--------+-------+-------+------------------------+
15036 * 6 5 5 16
15037 *
15038 * has the same opcode as the Read Hardware Register instruction
15039 *
15040 * +--------+-------+-------+-------+-------+--------+
15041 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
15042 * +--------+-------+-------+-------+-------+--------+
15043 * 6 5 5 5 5 6
15044 *
15045 * that is required, trapped and emulated by the Linux kernel. However, all
15046 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
15047 * offset is odd. Therefore all valid SQ instructions can execute normally.
15048 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
15049 * between SQ and RDHWR, as the Linux kernel does.
15050 */
15051 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
15052 {
15053 int base = extract32(ctx->opcode, 21, 5);
15054 int rt = extract32(ctx->opcode, 16, 5);
15055 int offset = extract32(ctx->opcode, 0, 16);
15056
15057 #ifdef CONFIG_USER_ONLY
15058 uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
15059 uint32_t op2 = extract32(ctx->opcode, 6, 5);
15060
15061 if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
15062 int rd = extract32(ctx->opcode, 11, 5);
15063
15064 gen_rdhwr(ctx, rt, rd, 0);
15065 return;
15066 }
15067 #endif
15068
15069 gen_mmi_sq(ctx, base, rt, offset);
15070 }
15071
15072 #endif
15073
15074 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15075 {
15076 int rs, rt, rd, sa;
15077 uint32_t op1, op2;
15078 int16_t imm;
15079
15080 rs = (ctx->opcode >> 21) & 0x1f;
15081 rt = (ctx->opcode >> 16) & 0x1f;
15082 rd = (ctx->opcode >> 11) & 0x1f;
15083 sa = (ctx->opcode >> 6) & 0x1f;
15084 imm = sextract32(ctx->opcode, 7, 9);
15085
15086 op1 = MASK_SPECIAL3(ctx->opcode);
15087
15088 /*
15089 * EVA loads and stores overlap Loongson 2E instructions decoded by
15090 * decode_opc_special3_legacy(), so be careful to allow their decoding when
15091 * EVA is absent.
15092 */
15093 if (ctx->eva) {
15094 switch (op1) {
15095 case OPC_LWLE:
15096 case OPC_LWRE:
15097 case OPC_LBUE:
15098 case OPC_LHUE:
15099 case OPC_LBE:
15100 case OPC_LHE:
15101 case OPC_LLE:
15102 case OPC_LWE:
15103 check_cp0_enabled(ctx);
15104 gen_ld(ctx, op1, rt, rs, imm);
15105 return;
15106 case OPC_SWLE:
15107 case OPC_SWRE:
15108 case OPC_SBE:
15109 case OPC_SHE:
15110 case OPC_SWE:
15111 check_cp0_enabled(ctx);
15112 gen_st(ctx, op1, rt, rs, imm);
15113 return;
15114 case OPC_SCE:
15115 check_cp0_enabled(ctx);
15116 gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
15117 return;
15118 case OPC_CACHEE:
15119 check_eva(ctx);
15120 check_cp0_enabled(ctx);
15121 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15122 gen_cache_operation(ctx, rt, rs, imm);
15123 }
15124 return;
15125 case OPC_PREFE:
15126 check_cp0_enabled(ctx);
15127 /* Treat as NOP. */
15128 return;
15129 }
15130 }
15131
15132 switch (op1) {
15133 case OPC_EXT:
15134 case OPC_INS:
15135 check_insn(ctx, ISA_MIPS_R2);
15136 gen_bitops(ctx, op1, rt, rs, sa, rd);
15137 break;
15138 case OPC_BSHFL:
15139 op2 = MASK_BSHFL(ctx->opcode);
15140 switch (op2) {
15141 case OPC_ALIGN:
15142 case OPC_ALIGN_1:
15143 case OPC_ALIGN_2:
15144 case OPC_ALIGN_3:
15145 case OPC_BITSWAP:
15146 check_insn(ctx, ISA_MIPS_R6);
15147 decode_opc_special3_r6(env, ctx);
15148 break;
15149 default:
15150 check_insn(ctx, ISA_MIPS_R2);
15151 gen_bshfl(ctx, op2, rt, rd);
15152 break;
15153 }
15154 break;
15155 #if defined(TARGET_MIPS64)
15156 case OPC_DEXTM:
15157 case OPC_DEXTU:
15158 case OPC_DEXT:
15159 case OPC_DINSM:
15160 case OPC_DINSU:
15161 case OPC_DINS:
15162 check_insn(ctx, ISA_MIPS_R2);
15163 check_mips_64(ctx);
15164 gen_bitops(ctx, op1, rt, rs, sa, rd);
15165 break;
15166 case OPC_DBSHFL:
15167 op2 = MASK_DBSHFL(ctx->opcode);
15168 switch (op2) {
15169 case OPC_DALIGN:
15170 case OPC_DALIGN_1:
15171 case OPC_DALIGN_2:
15172 case OPC_DALIGN_3:
15173 case OPC_DALIGN_4:
15174 case OPC_DALIGN_5:
15175 case OPC_DALIGN_6:
15176 case OPC_DALIGN_7:
15177 case OPC_DBITSWAP:
15178 check_insn(ctx, ISA_MIPS_R6);
15179 decode_opc_special3_r6(env, ctx);
15180 break;
15181 default:
15182 check_insn(ctx, ISA_MIPS_R2);
15183 check_mips_64(ctx);
15184 op2 = MASK_DBSHFL(ctx->opcode);
15185 gen_bshfl(ctx, op2, rt, rd);
15186 break;
15187 }
15188 break;
15189 #endif
15190 case OPC_RDHWR:
15191 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
15192 break;
15193 case OPC_FORK:
15194 check_mt(ctx);
15195 {
15196 TCGv t0 = tcg_temp_new();
15197 TCGv t1 = tcg_temp_new();
15198
15199 gen_load_gpr(t0, rt);
15200 gen_load_gpr(t1, rs);
15201 gen_helper_fork(t0, t1);
15202 tcg_temp_free(t0);
15203 tcg_temp_free(t1);
15204 }
15205 break;
15206 case OPC_YIELD:
15207 check_mt(ctx);
15208 {
15209 TCGv t0 = tcg_temp_new();
15210
15211 gen_load_gpr(t0, rs);
15212 gen_helper_yield(t0, cpu_env, t0);
15213 gen_store_gpr(t0, rd);
15214 tcg_temp_free(t0);
15215 }
15216 break;
15217 default:
15218 if (ctx->insn_flags & ISA_MIPS_R6) {
15219 decode_opc_special3_r6(env, ctx);
15220 } else {
15221 decode_opc_special3_legacy(env, ctx);
15222 }
15223 }
15224 }
15225
15226 static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
15227 {
15228 int32_t offset;
15229 int rs, rt, rd, sa;
15230 uint32_t op, op1;
15231 int16_t imm;
15232
15233 op = MASK_OP_MAJOR(ctx->opcode);
15234 rs = (ctx->opcode >> 21) & 0x1f;
15235 rt = (ctx->opcode >> 16) & 0x1f;
15236 rd = (ctx->opcode >> 11) & 0x1f;
15237 sa = (ctx->opcode >> 6) & 0x1f;
15238 imm = (int16_t)ctx->opcode;
15239 switch (op) {
15240 case OPC_SPECIAL:
15241 decode_opc_special(env, ctx);
15242 break;
15243 case OPC_SPECIAL2:
15244 #if defined(TARGET_MIPS64)
15245 if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
15246 decode_mmi(env, ctx);
15247 break;
15248 }
15249 #endif
15250 if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
15251 if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
15252 gen_arith(ctx, OPC_MUL, rd, rs, rt);
15253 } else {
15254 decode_ase_mxu(ctx, ctx->opcode);
15255 }
15256 break;
15257 }
15258 decode_opc_special2_legacy(env, ctx);
15259 break;
15260 case OPC_SPECIAL3:
15261 #if defined(TARGET_MIPS64)
15262 if (ctx->insn_flags & INSN_R5900) {
15263 decode_mmi_sq(env, ctx); /* MMI_OPC_SQ */
15264 } else {
15265 decode_opc_special3(env, ctx);
15266 }
15267 #else
15268 decode_opc_special3(env, ctx);
15269 #endif
15270 break;
15271 case OPC_REGIMM:
15272 op1 = MASK_REGIMM(ctx->opcode);
15273 switch (op1) {
15274 case OPC_BLTZL: /* REGIMM branches */
15275 case OPC_BGEZL:
15276 case OPC_BLTZALL:
15277 case OPC_BGEZALL:
15278 check_insn(ctx, ISA_MIPS2);
15279 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15280 /* Fallthrough */
15281 case OPC_BLTZ:
15282 case OPC_BGEZ:
15283 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15284 break;
15285 case OPC_BLTZAL:
15286 case OPC_BGEZAL:
15287 if (ctx->insn_flags & ISA_MIPS_R6) {
15288 if (rs == 0) {
15289 /* OPC_NAL, OPC_BAL */
15290 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
15291 } else {
15292 gen_reserved_instruction(ctx);
15293 }
15294 } else {
15295 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15296 }
15297 break;
15298 case OPC_TGEI: /* REGIMM traps */
15299 case OPC_TGEIU:
15300 case OPC_TLTI:
15301 case OPC_TLTIU:
15302 case OPC_TEQI:
15303 case OPC_TNEI:
15304 check_insn(ctx, ISA_MIPS2);
15305 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15306 gen_trap(ctx, op1, rs, -1, imm, 0);
15307 break;
15308 case OPC_SIGRIE:
15309 check_insn(ctx, ISA_MIPS_R6);
15310 gen_reserved_instruction(ctx);
15311 break;
15312 case OPC_SYNCI:
15313 check_insn(ctx, ISA_MIPS_R2);
15314 /*
15315 * Break the TB to be able to sync copied instructions
15316 * immediately.
15317 */
15318 ctx->base.is_jmp = DISAS_STOP;
15319 break;
15320 case OPC_BPOSGE32: /* MIPS DSP branch */
15321 #if defined(TARGET_MIPS64)
15322 case OPC_BPOSGE64:
15323 #endif
15324 check_dsp(ctx);
15325 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
15326 break;
15327 #if defined(TARGET_MIPS64)
15328 case OPC_DAHI:
15329 check_insn(ctx, ISA_MIPS_R6);
15330 check_mips_64(ctx);
15331 if (rs != 0) {
15332 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
15333 }
15334 break;
15335 case OPC_DATI:
15336 check_insn(ctx, ISA_MIPS_R6);
15337 check_mips_64(ctx);
15338 if (rs != 0) {
15339 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
15340 }
15341 break;
15342 #endif
15343 default: /* Invalid */
15344 MIPS_INVAL("regimm");
15345 gen_reserved_instruction(ctx);
15346 break;
15347 }
15348 break;
15349 case OPC_CP0:
15350 check_cp0_enabled(ctx);
15351 op1 = MASK_CP0(ctx->opcode);
15352 switch (op1) {
15353 case OPC_MFC0:
15354 case OPC_MTC0:
15355 case OPC_MFTR:
15356 case OPC_MTTR:
15357 case OPC_MFHC0:
15358 case OPC_MTHC0:
15359 #if defined(TARGET_MIPS64)
15360 case OPC_DMFC0:
15361 case OPC_DMTC0:
15362 #endif
15363 #ifndef CONFIG_USER_ONLY
15364 gen_cp0(env, ctx, op1, rt, rd);
15365 #endif /* !CONFIG_USER_ONLY */
15366 break;
15367 case OPC_C0:
15368 case OPC_C0_1:
15369 case OPC_C0_2:
15370 case OPC_C0_3:
15371 case OPC_C0_4:
15372 case OPC_C0_5:
15373 case OPC_C0_6:
15374 case OPC_C0_7:
15375 case OPC_C0_8:
15376 case OPC_C0_9:
15377 case OPC_C0_A:
15378 case OPC_C0_B:
15379 case OPC_C0_C:
15380 case OPC_C0_D:
15381 case OPC_C0_E:
15382 case OPC_C0_F:
15383 #ifndef CONFIG_USER_ONLY
15384 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15385 #endif /* !CONFIG_USER_ONLY */
15386 break;
15387 case OPC_MFMC0:
15388 #ifndef CONFIG_USER_ONLY
15389 {
15390 uint32_t op2;
15391 TCGv t0 = tcg_temp_new();
15392
15393 op2 = MASK_MFMC0(ctx->opcode);
15394 switch (op2) {
15395 case OPC_DMT:
15396 check_cp0_mt(ctx);
15397 gen_helper_dmt(t0);
15398 gen_store_gpr(t0, rt);
15399 break;
15400 case OPC_EMT:
15401 check_cp0_mt(ctx);
15402 gen_helper_emt(t0);
15403 gen_store_gpr(t0, rt);
15404 break;
15405 case OPC_DVPE:
15406 check_cp0_mt(ctx);
15407 gen_helper_dvpe(t0, cpu_env);
15408 gen_store_gpr(t0, rt);
15409 break;
15410 case OPC_EVPE:
15411 check_cp0_mt(ctx);
15412 gen_helper_evpe(t0, cpu_env);
15413 gen_store_gpr(t0, rt);
15414 break;
15415 case OPC_DVP:
15416 check_insn(ctx, ISA_MIPS_R6);
15417 if (ctx->vp) {
15418 gen_helper_dvp(t0, cpu_env);
15419 gen_store_gpr(t0, rt);
15420 }
15421 break;
15422 case OPC_EVP:
15423 check_insn(ctx, ISA_MIPS_R6);
15424 if (ctx->vp) {
15425 gen_helper_evp(t0, cpu_env);
15426 gen_store_gpr(t0, rt);
15427 }
15428 break;
15429 case OPC_DI:
15430 check_insn(ctx, ISA_MIPS_R2);
15431 save_cpu_state(ctx, 1);
15432 gen_helper_di(t0, cpu_env);
15433 gen_store_gpr(t0, rt);
15434 /*
15435 * Stop translation as we may have switched
15436 * the execution mode.
15437 */
15438 ctx->base.is_jmp = DISAS_STOP;
15439 break;
15440 case OPC_EI:
15441 check_insn(ctx, ISA_MIPS_R2);
15442 save_cpu_state(ctx, 1);
15443 gen_helper_ei(t0, cpu_env);
15444 gen_store_gpr(t0, rt);
15445 /*
15446 * DISAS_STOP isn't sufficient, we need to ensure we break
15447 * out of translated code to check for pending interrupts.
15448 */
15449 gen_save_pc(ctx->base.pc_next + 4);
15450 ctx->base.is_jmp = DISAS_EXIT;
15451 break;
15452 default: /* Invalid */
15453 MIPS_INVAL("mfmc0");
15454 gen_reserved_instruction(ctx);
15455 break;
15456 }
15457 tcg_temp_free(t0);
15458 }
15459 #endif /* !CONFIG_USER_ONLY */
15460 break;
15461 case OPC_RDPGPR:
15462 check_insn(ctx, ISA_MIPS_R2);
15463 gen_load_srsgpr(rt, rd);
15464 break;
15465 case OPC_WRPGPR:
15466 check_insn(ctx, ISA_MIPS_R2);
15467 gen_store_srsgpr(rt, rd);
15468 break;
15469 default:
15470 MIPS_INVAL("cp0");
15471 gen_reserved_instruction(ctx);
15472 break;
15473 }
15474 break;
15475 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
15476 if (ctx->insn_flags & ISA_MIPS_R6) {
15477 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
15478 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15479 } else {
15480 /* OPC_ADDI */
15481 /* Arithmetic with immediate opcode */
15482 gen_arith_imm(ctx, op, rt, rs, imm);
15483 }
15484 break;
15485 case OPC_ADDIU:
15486 gen_arith_imm(ctx, op, rt, rs, imm);
15487 break;
15488 case OPC_SLTI: /* Set on less than with immediate opcode */
15489 case OPC_SLTIU:
15490 gen_slt_imm(ctx, op, rt, rs, imm);
15491 break;
15492 case OPC_ANDI: /* Arithmetic with immediate opcode */
15493 case OPC_LUI: /* OPC_AUI */
15494 case OPC_ORI:
15495 case OPC_XORI:
15496 gen_logic_imm(ctx, op, rt, rs, imm);
15497 break;
15498 case OPC_J: /* Jump */
15499 case OPC_JAL:
15500 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15501 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15502 break;
15503 /* Branch */
15504 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
15505 if (ctx->insn_flags & ISA_MIPS_R6) {
15506 if (rt == 0) {
15507 gen_reserved_instruction(ctx);
15508 break;
15509 }
15510 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
15511 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15512 } else {
15513 /* OPC_BLEZL */
15514 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15515 }
15516 break;
15517 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
15518 if (ctx->insn_flags & ISA_MIPS_R6) {
15519 if (rt == 0) {
15520 gen_reserved_instruction(ctx);
15521 break;
15522 }
15523 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
15524 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15525 } else {
15526 /* OPC_BGTZL */
15527 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15528 }
15529 break;
15530 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
15531 if (rt == 0) {
15532 /* OPC_BLEZ */
15533 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15534 } else {
15535 check_insn(ctx, ISA_MIPS_R6);
15536 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
15537 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15538 }
15539 break;
15540 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
15541 if (rt == 0) {
15542 /* OPC_BGTZ */
15543 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15544 } else {
15545 check_insn(ctx, ISA_MIPS_R6);
15546 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
15547 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15548 }
15549 break;
15550 case OPC_BEQL:
15551 case OPC_BNEL:
15552 check_insn(ctx, ISA_MIPS2);
15553 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15554 /* Fallthrough */
15555 case OPC_BEQ:
15556 case OPC_BNE:
15557 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15558 break;
15559 case OPC_LL: /* Load and stores */
15560 check_insn(ctx, ISA_MIPS2);
15561 if (ctx->insn_flags & INSN_R5900) {
15562 check_insn_opc_user_only(ctx, INSN_R5900);
15563 }
15564 /* Fallthrough */
15565 case OPC_LWL:
15566 case OPC_LWR:
15567 case OPC_LB:
15568 case OPC_LH:
15569 case OPC_LW:
15570 case OPC_LWPC:
15571 case OPC_LBU:
15572 case OPC_LHU:
15573 gen_ld(ctx, op, rt, rs, imm);
15574 break;
15575 case OPC_SWL:
15576 case OPC_SWR:
15577 case OPC_SB:
15578 case OPC_SH:
15579 case OPC_SW:
15580 gen_st(ctx, op, rt, rs, imm);
15581 break;
15582 case OPC_SC:
15583 check_insn(ctx, ISA_MIPS2);
15584 if (ctx->insn_flags & INSN_R5900) {
15585 check_insn_opc_user_only(ctx, INSN_R5900);
15586 }
15587 gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
15588 break;
15589 case OPC_CACHE:
15590 check_cp0_enabled(ctx);
15591 check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
15592 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15593 gen_cache_operation(ctx, rt, rs, imm);
15594 }
15595 /* Treat as NOP. */
15596 break;
15597 case OPC_PREF:
15598 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
15599 /* Treat as NOP. */
15600 break;
15601
15602 /* Floating point (COP1). */
15603 case OPC_LWC1:
15604 case OPC_LDC1:
15605 case OPC_SWC1:
15606 case OPC_SDC1:
15607 gen_cop1_ldst(ctx, op, rt, rs, imm);
15608 break;
15609
15610 case OPC_CP1:
15611 op1 = MASK_CP1(ctx->opcode);
15612
15613 switch (op1) {
15614 case OPC_MFHC1:
15615 case OPC_MTHC1:
15616 check_cp1_enabled(ctx);
15617 check_insn(ctx, ISA_MIPS_R2);
15618 /* fall through */
15619 case OPC_MFC1:
15620 case OPC_CFC1:
15621 case OPC_MTC1:
15622 case OPC_CTC1:
15623 check_cp1_enabled(ctx);
15624 gen_cp1(ctx, op1, rt, rd);
15625 break;
15626 #if defined(TARGET_MIPS64)
15627 case OPC_DMFC1:
15628 case OPC_DMTC1:
15629 check_cp1_enabled(ctx);
15630 check_insn(ctx, ISA_MIPS3);
15631 check_mips_64(ctx);
15632 gen_cp1(ctx, op1, rt, rd);
15633 break;
15634 #endif
15635 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
15636 check_cp1_enabled(ctx);
15637 if (ctx->insn_flags & ISA_MIPS_R6) {
15638 /* OPC_BC1EQZ */
15639 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15640 rt, imm << 2, 4);
15641 } else {
15642 /* OPC_BC1ANY2 */
15643 check_cop1x(ctx);
15644 check_insn(ctx, ASE_MIPS3D);
15645 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15646 (rt >> 2) & 0x7, imm << 2);
15647 }
15648 break;
15649 case OPC_BC1NEZ:
15650 check_cp1_enabled(ctx);
15651 check_insn(ctx, ISA_MIPS_R6);
15652 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15653 rt, imm << 2, 4);
15654 break;
15655 case OPC_BC1ANY4:
15656 check_cp1_enabled(ctx);
15657 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15658 check_cop1x(ctx);
15659 check_insn(ctx, ASE_MIPS3D);
15660 /* fall through */
15661 case OPC_BC1:
15662 check_cp1_enabled(ctx);
15663 check_insn_opc_removed(ctx, ISA_MIPS_R6);
15664 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15665 (rt >> 2) & 0x7, imm << 2);
15666 break;
15667 case OPC_PS_FMT:
15668 check_ps(ctx);
15669 /* fall through */
15670 case OPC_S_FMT:
15671 case OPC_D_FMT:
15672 check_cp1_enabled(ctx);
15673 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15674 (imm >> 8) & 0x7);
15675 break;
15676 case OPC_W_FMT:
15677 case OPC_L_FMT:
15678 {
15679 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15680 check_cp1_enabled(ctx);
15681 if (ctx->insn_flags & ISA_MIPS_R6) {
15682 switch (r6_op) {
15683 case R6_OPC_CMP_AF_S:
15684 case R6_OPC_CMP_UN_S:
15685 case R6_OPC_CMP_EQ_S:
15686 case R6_OPC_CMP_UEQ_S:
15687 case R6_OPC_CMP_LT_S:
15688 case R6_OPC_CMP_ULT_S:
15689 case R6_OPC_CMP_LE_S:
15690 case R6_OPC_CMP_ULE_S:
15691 case R6_OPC_CMP_SAF_S:
15692 case R6_OPC_CMP_SUN_S:
15693 case R6_OPC_CMP_SEQ_S:
15694 case R6_OPC_CMP_SEUQ_S:
15695 case R6_OPC_CMP_SLT_S:
15696 case R6_OPC_CMP_SULT_S:
15697 case R6_OPC_CMP_SLE_S:
15698 case R6_OPC_CMP_SULE_S:
15699 case R6_OPC_CMP_OR_S:
15700 case R6_OPC_CMP_UNE_S:
15701 case R6_OPC_CMP_NE_S:
15702 case R6_OPC_CMP_SOR_S:
15703 case R6_OPC_CMP_SUNE_S:
15704 case R6_OPC_CMP_SNE_S:
15705 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15706 break;
15707 case R6_OPC_CMP_AF_D:
15708 case R6_OPC_CMP_UN_D:
15709 case R6_OPC_CMP_EQ_D:
15710 case R6_OPC_CMP_UEQ_D:
15711 case R6_OPC_CMP_LT_D:
15712 case R6_OPC_CMP_ULT_D:
15713 case R6_OPC_CMP_LE_D:
15714 case R6_OPC_CMP_ULE_D:
15715 case R6_OPC_CMP_SAF_D:
15716 case R6_OPC_CMP_SUN_D:
15717 case R6_OPC_CMP_SEQ_D:
15718 case R6_OPC_CMP_SEUQ_D:
15719 case R6_OPC_CMP_SLT_D:
15720 case R6_OPC_CMP_SULT_D:
15721 case R6_OPC_CMP_SLE_D:
15722 case R6_OPC_CMP_SULE_D:
15723 case R6_OPC_CMP_OR_D:
15724 case R6_OPC_CMP_UNE_D:
15725 case R6_OPC_CMP_NE_D:
15726 case R6_OPC_CMP_SOR_D:
15727 case R6_OPC_CMP_SUNE_D:
15728 case R6_OPC_CMP_SNE_D:
15729 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15730 break;
15731 default:
15732 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15733 rt, rd, sa, (imm >> 8) & 0x7);
15734
15735 break;
15736 }
15737 } else {
15738 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15739 (imm >> 8) & 0x7);
15740 }
15741 break;
15742 }
15743 default:
15744 MIPS_INVAL("cp1");
15745 gen_reserved_instruction(ctx);
15746 break;
15747 }
15748 break;
15749
15750 /* Compact branches [R6] and COP2 [non-R6] */
15751 case OPC_BC: /* OPC_LWC2 */
15752 case OPC_BALC: /* OPC_SWC2 */
15753 if (ctx->insn_flags & ISA_MIPS_R6) {
15754 /* OPC_BC, OPC_BALC */
15755 gen_compute_compact_branch(ctx, op, 0, 0,
15756 sextract32(ctx->opcode << 2, 0, 28));
15757 } else if (ctx->insn_flags & ASE_LEXT) {
15758 gen_loongson_lswc2(ctx, rt, rs, rd);
15759 } else {
15760 /* OPC_LWC2, OPC_SWC2 */
15761 /* COP2: Not implemented. */
15762 generate_exception_err(ctx, EXCP_CpU, 2);
15763 }
15764 break;
15765 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
15766 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
15767 if (ctx->insn_flags & ISA_MIPS_R6) {
15768 if (rs != 0) {
15769 /* OPC_BEQZC, OPC_BNEZC */
15770 gen_compute_compact_branch(ctx, op, rs, 0,
15771 sextract32(ctx->opcode << 2, 0, 23));
15772 } else {
15773 /* OPC_JIC, OPC_JIALC */
15774 gen_compute_compact_branch(ctx, op, 0, rt, imm);
15775 }
15776 } else if (ctx->insn_flags & ASE_LEXT) {
15777 gen_loongson_lsdc2(ctx, rt, rs, rd);
15778 } else {
15779 /* OPC_LWC2, OPC_SWC2 */
15780 /* COP2: Not implemented. */
15781 generate_exception_err(ctx, EXCP_CpU, 2);
15782 }
15783 break;
15784 case OPC_CP2:
15785 check_insn(ctx, ASE_LMMI);
15786 /* Note that these instructions use different fields. */
15787 gen_loongson_multimedia(ctx, sa, rd, rt);
15788 break;
15789
15790 case OPC_CP3:
15791 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15792 check_cp1_enabled(ctx);
15793 op1 = MASK_CP3(ctx->opcode);
15794 switch (op1) {
15795 case OPC_LUXC1:
15796 case OPC_SUXC1:
15797 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15798 /* Fallthrough */
15799 case OPC_LWXC1:
15800 case OPC_LDXC1:
15801 case OPC_SWXC1:
15802 case OPC_SDXC1:
15803 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15804 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15805 break;
15806 case OPC_PREFX:
15807 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15808 /* Treat as NOP. */
15809 break;
15810 case OPC_ALNV_PS:
15811 check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15812 /* Fallthrough */
15813 case OPC_MADD_S:
15814 case OPC_MADD_D:
15815 case OPC_MADD_PS:
15816 case OPC_MSUB_S:
15817 case OPC_MSUB_D:
15818 case OPC_MSUB_PS:
15819 case OPC_NMADD_S:
15820 case OPC_NMADD_D:
15821 case OPC_NMADD_PS:
15822 case OPC_NMSUB_S:
15823 case OPC_NMSUB_D:
15824 case OPC_NMSUB_PS:
15825 check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15826 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15827 break;
15828 default:
15829 MIPS_INVAL("cp3");
15830 gen_reserved_instruction(ctx);
15831 break;
15832 }
15833 } else {
15834 generate_exception_err(ctx, EXCP_CpU, 1);
15835 }
15836 break;
15837
15838 #if defined(TARGET_MIPS64)
15839 /* MIPS64 opcodes */
15840 case OPC_LLD:
15841 if (ctx->insn_flags & INSN_R5900) {
15842 check_insn_opc_user_only(ctx, INSN_R5900);
15843 }
15844 /* fall through */
15845 case OPC_LDL:
15846 case OPC_LDR:
15847 case OPC_LWU:
15848 case OPC_LD:
15849 check_insn(ctx, ISA_MIPS3);
15850 check_mips_64(ctx);
15851 gen_ld(ctx, op, rt, rs, imm);
15852 break;
15853 case OPC_SDL:
15854 case OPC_SDR:
15855 case OPC_SD:
15856 check_insn(ctx, ISA_MIPS3);
15857 check_mips_64(ctx);
15858 gen_st(ctx, op, rt, rs, imm);
15859 break;
15860 case OPC_SCD:
15861 check_insn(ctx, ISA_MIPS3);
15862 if (ctx->insn_flags & INSN_R5900) {
15863 check_insn_opc_user_only(ctx, INSN_R5900);
15864 }
15865 check_mips_64(ctx);
15866 gen_st_cond(ctx, rt, rs, imm, MO_TEUQ, false);
15867 break;
15868 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
15869 if (ctx->insn_flags & ISA_MIPS_R6) {
15870 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
15871 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15872 } else {
15873 /* OPC_DADDI */
15874 check_insn(ctx, ISA_MIPS3);
15875 check_mips_64(ctx);
15876 gen_arith_imm(ctx, op, rt, rs, imm);
15877 }
15878 break;
15879 case OPC_DADDIU:
15880 check_insn(ctx, ISA_MIPS3);
15881 check_mips_64(ctx);
15882 gen_arith_imm(ctx, op, rt, rs, imm);
15883 break;
15884 #else
15885 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15886 if (ctx->insn_flags & ISA_MIPS_R6) {
15887 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15888 } else {
15889 MIPS_INVAL("major opcode");
15890 gen_reserved_instruction(ctx);
15891 }
15892 break;
15893 #endif
15894 case OPC_DAUI: /* OPC_JALX */
15895 if (ctx->insn_flags & ISA_MIPS_R6) {
15896 #if defined(TARGET_MIPS64)
15897 /* OPC_DAUI */
15898 check_mips_64(ctx);
15899 if (rs == 0) {
15900 generate_exception(ctx, EXCP_RI);
15901 } else if (rt != 0) {
15902 TCGv t0 = tcg_temp_new();
15903 gen_load_gpr(t0, rs);
15904 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15905 tcg_temp_free(t0);
15906 }
15907 #else
15908 gen_reserved_instruction(ctx);
15909 MIPS_INVAL("major opcode");
15910 #endif
15911 } else {
15912 /* OPC_JALX */
15913 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15914 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15915 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15916 }
15917 break;
15918 case OPC_MDMX:
15919 /* MDMX: Not implemented. */
15920 break;
15921 case OPC_PCREL:
15922 check_insn(ctx, ISA_MIPS_R6);
15923 gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
15924 break;
15925 default: /* Invalid */
15926 MIPS_INVAL("major opcode");
15927 return false;
15928 }
15929 return true;
15930 }
15931
15932 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15933 {
15934 /* make sure instructions are on a word boundary */
15935 if (ctx->base.pc_next & 0x3) {
15936 env->CP0_BadVAddr = ctx->base.pc_next;
15937 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15938 return;
15939 }
15940
15941 /* Handle blikely not taken case */
15942 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15943 TCGLabel *l1 = gen_new_label();
15944
15945 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15946 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15947 gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15948 gen_set_label(l1);
15949 }
15950
15951 /* Transition to the auto-generated decoder. */
15952
15953 /* Vendor specific extensions */
15954 if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15955 return;
15956 }
15957 if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15958 return;
15959 }
15960 #if defined(TARGET_MIPS64)
15961 if (cpu_supports_isa(env, INSN_OCTEON) && decode_ext_octeon(ctx, ctx->opcode)) {
15962 return;
15963 }
15964 #endif
15965
15966 /* ISA extensions */
15967 if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15968 return;
15969 }
15970
15971 /* ISA (from latest to oldest) */
15972 if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15973 return;
15974 }
15975
15976 if (decode_opc_legacy(env, ctx)) {
15977 return;
15978 }
15979
15980 gen_reserved_instruction(ctx);
15981 }
15982
15983 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15984 {
15985 DisasContext *ctx = container_of(dcbase, DisasContext, base);
15986 CPUMIPSState *env = cs->env_ptr;
15987
15988 ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15989 ctx->saved_pc = -1;
15990 ctx->insn_flags = env->insn_flags;
15991 ctx->CP0_Config0 = env->CP0_Config0;
15992 ctx->CP0_Config1 = env->CP0_Config1;
15993 ctx->CP0_Config2 = env->CP0_Config2;
15994 ctx->CP0_Config3 = env->CP0_Config3;
15995 ctx->CP0_Config5 = env->CP0_Config5;
15996 ctx->btarget = 0;
15997 ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15998 ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15999 ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
16000 ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
16001 ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
16002 ctx->PAMask = env->PAMask;
16003 ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
16004 ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
16005 ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
16006 ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
16007 ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
16008 /* Restore delay slot state from the tb context. */
16009 ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
16010 ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
16011 ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
16012 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
16013 ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
16014 ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
16015 ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
16016 ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
16017 ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
16018 ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
16019 restore_cpu_state(env, ctx);
16020 #ifdef CONFIG_USER_ONLY
16021 ctx->mem_idx = MIPS_HFLAG_UM;
16022 #else
16023 ctx->mem_idx = hflags_mmu_index(ctx->hflags);
16024 #endif
16025 ctx->default_tcg_memop_mask = (!(ctx->insn_flags & ISA_NANOMIPS32) &&
16026 (ctx->insn_flags & (ISA_MIPS_R6 |
16027 INSN_LOONGSON3A))) ? MO_UNALN : MO_ALIGN;
16028
16029 /*
16030 * Execute a branch and its delay slot as a single instruction.
16031 * This is what GDB expects and is consistent with what the
16032 * hardware does (e.g. if a delay slot instruction faults, the
16033 * reported PC is the PC of the branch).
16034 */
16035 if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
16036 ctx->base.max_insns = 2;
16037 }
16038
16039 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
16040 ctx->hflags);
16041 }
16042
16043 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
16044 {
16045 }
16046
16047 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
16048 {
16049 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16050
16051 tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
16052 ctx->btarget);
16053 }
16054
16055 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
16056 {
16057 CPUMIPSState *env = cs->env_ptr;
16058 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16059 int insn_bytes;
16060 int is_slot;
16061
16062 is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
16063 if (ctx->insn_flags & ISA_NANOMIPS32) {
16064 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16065 insn_bytes = decode_isa_nanomips(env, ctx);
16066 } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
16067 ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
16068 insn_bytes = 4;
16069 decode_opc(env, ctx);
16070 } else if (ctx->insn_flags & ASE_MICROMIPS) {
16071 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16072 insn_bytes = decode_isa_micromips(env, ctx);
16073 } else if (ctx->insn_flags & ASE_MIPS16) {
16074 ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16075 insn_bytes = decode_ase_mips16e(env, ctx);
16076 } else {
16077 gen_reserved_instruction(ctx);
16078 g_assert(ctx->base.is_jmp == DISAS_NORETURN);
16079 return;
16080 }
16081
16082 if (ctx->hflags & MIPS_HFLAG_BMASK) {
16083 if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
16084 MIPS_HFLAG_FBNSLOT))) {
16085 /*
16086 * Force to generate branch as there is neither delay nor
16087 * forbidden slot.
16088 */
16089 is_slot = 1;
16090 }
16091 if ((ctx->hflags & MIPS_HFLAG_M16) &&
16092 (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
16093 /*
16094 * Force to generate branch as microMIPS R6 doesn't restrict
16095 * branches in the forbidden slot.
16096 */
16097 is_slot = 1;
16098 }
16099 }
16100 if (is_slot) {
16101 gen_branch(ctx, insn_bytes);
16102 }
16103 if (ctx->base.is_jmp == DISAS_SEMIHOST) {
16104 generate_exception_err(ctx, EXCP_SEMIHOST, insn_bytes);
16105 }
16106 ctx->base.pc_next += insn_bytes;
16107
16108 if (ctx->base.is_jmp != DISAS_NEXT) {
16109 return;
16110 }
16111
16112 /*
16113 * End the TB on (most) page crossings.
16114 * See mips_tr_init_disas_context about single-stepping a branch
16115 * together with its delay slot.
16116 */
16117 if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
16118 && !ctx->base.singlestep_enabled) {
16119 ctx->base.is_jmp = DISAS_TOO_MANY;
16120 }
16121 }
16122
16123 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
16124 {
16125 DisasContext *ctx = container_of(dcbase, DisasContext, base);
16126
16127 switch (ctx->base.is_jmp) {
16128 case DISAS_STOP:
16129 gen_save_pc(ctx->base.pc_next);
16130 tcg_gen_lookup_and_goto_ptr();
16131 break;
16132 case DISAS_NEXT:
16133 case DISAS_TOO_MANY:
16134 save_cpu_state(ctx, 0);
16135 gen_goto_tb(ctx, 0, ctx->base.pc_next);
16136 break;
16137 case DISAS_EXIT:
16138 tcg_gen_exit_tb(NULL, 0);
16139 break;
16140 case DISAS_NORETURN:
16141 break;
16142 default:
16143 g_assert_not_reached();
16144 }
16145 }
16146
16147 static void mips_tr_disas_log(const DisasContextBase *dcbase,
16148 CPUState *cs, FILE *logfile)
16149 {
16150 fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
16151 target_disas(logfile, cs, dcbase->pc_first, dcbase->tb->size);
16152 }
16153
16154 static const TranslatorOps mips_tr_ops = {
16155 .init_disas_context = mips_tr_init_disas_context,
16156 .tb_start = mips_tr_tb_start,
16157 .insn_start = mips_tr_insn_start,
16158 .translate_insn = mips_tr_translate_insn,
16159 .tb_stop = mips_tr_tb_stop,
16160 .disas_log = mips_tr_disas_log,
16161 };
16162
16163 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
16164 target_ulong pc, void *host_pc)
16165 {
16166 DisasContext ctx;
16167
16168 translator_loop(cs, tb, max_insns, pc, host_pc, &mips_tr_ops, &ctx.base);
16169 }
16170
16171 void mips_tcg_init(void)
16172 {
16173 int i;
16174
16175 cpu_gpr[0] = NULL;
16176 for (i = 1; i < 32; i++)
16177 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
16178 offsetof(CPUMIPSState,
16179 active_tc.gpr[i]),
16180 regnames[i]);
16181 #if defined(TARGET_MIPS64)
16182 cpu_gpr_hi[0] = NULL;
16183
16184 for (unsigned i = 1; i < 32; i++) {
16185 g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
16186
16187 cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
16188 offsetof(CPUMIPSState,
16189 active_tc.gpr_hi[i]),
16190 rname);
16191 }
16192 #endif /* !TARGET_MIPS64 */
16193 for (i = 0; i < 32; i++) {
16194 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
16195
16196 fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
16197 }
16198 msa_translate_init();
16199 cpu_PC = tcg_global_mem_new(cpu_env,
16200 offsetof(CPUMIPSState, active_tc.PC), "PC");
16201 for (i = 0; i < MIPS_DSP_ACC; i++) {
16202 cpu_HI[i] = tcg_global_mem_new(cpu_env,
16203 offsetof(CPUMIPSState, active_tc.HI[i]),
16204 regnames_HI[i]);
16205 cpu_LO[i] = tcg_global_mem_new(cpu_env,
16206 offsetof(CPUMIPSState, active_tc.LO[i]),
16207 regnames_LO[i]);
16208 }
16209 cpu_dspctrl = tcg_global_mem_new(cpu_env,
16210 offsetof(CPUMIPSState,
16211 active_tc.DSPControl),
16212 "DSPControl");
16213 bcond = tcg_global_mem_new(cpu_env,
16214 offsetof(CPUMIPSState, bcond), "bcond");
16215 btarget = tcg_global_mem_new(cpu_env,
16216 offsetof(CPUMIPSState, btarget), "btarget");
16217 hflags = tcg_global_mem_new_i32(cpu_env,
16218 offsetof(CPUMIPSState, hflags), "hflags");
16219
16220 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
16221 offsetof(CPUMIPSState, active_fpu.fcr0),
16222 "fcr0");
16223 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
16224 offsetof(CPUMIPSState, active_fpu.fcr31),
16225 "fcr31");
16226 cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
16227 "lladdr");
16228 cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
16229 "llval");
16230
16231 if (TARGET_LONG_BITS == 32) {
16232 mxu_translate_init();
16233 }
16234 }
16235
16236 void mips_restore_state_to_opc(CPUState *cs,
16237 const TranslationBlock *tb,
16238 const uint64_t *data)
16239 {
16240 MIPSCPU *cpu = MIPS_CPU(cs);
16241 CPUMIPSState *env = &cpu->env;
16242
16243 env->active_tc.PC = data[0];
16244 env->hflags &= ~MIPS_HFLAG_BMASK;
16245 env->hflags |= data[1];
16246 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16247 case MIPS_HFLAG_BR:
16248 break;
16249 case MIPS_HFLAG_BC:
16250 case MIPS_HFLAG_BL:
16251 case MIPS_HFLAG_B:
16252 env->btarget = data[2];
16253 break;
16254 }
16255 }