]> git.proxmox.com Git - mirror_qemu.git/blob - target/mips/translate.c
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
[mirror_qemu.git] / target / mips / translate.c
1 /*
2 * MIPS32 emulation for qemu: main translation routines.
3 *
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "qemu/osdep.h"
25 #include "cpu.h"
26 #include "disas/disas.h"
27 #include "exec/exec-all.h"
28 #include "tcg-op.h"
29 #include "exec/cpu_ldst.h"
30
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
33 #include "sysemu/kvm.h"
34 #include "exec/semihost.h"
35
36 #include "target/mips/trace.h"
37 #include "trace-tcg.h"
38 #include "exec/log.h"
39
40 #define MIPS_DEBUG_DISAS 0
41
42 /* MIPS major opcodes */
43 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
44
45 enum {
46 /* indirect opcode tables */
47 OPC_SPECIAL = (0x00 << 26),
48 OPC_REGIMM = (0x01 << 26),
49 OPC_CP0 = (0x10 << 26),
50 OPC_CP1 = (0x11 << 26),
51 OPC_CP2 = (0x12 << 26),
52 OPC_CP3 = (0x13 << 26),
53 OPC_SPECIAL2 = (0x1C << 26),
54 OPC_SPECIAL3 = (0x1F << 26),
55 /* arithmetic with immediate */
56 OPC_ADDI = (0x08 << 26),
57 OPC_ADDIU = (0x09 << 26),
58 OPC_SLTI = (0x0A << 26),
59 OPC_SLTIU = (0x0B << 26),
60 /* logic with immediate */
61 OPC_ANDI = (0x0C << 26),
62 OPC_ORI = (0x0D << 26),
63 OPC_XORI = (0x0E << 26),
64 OPC_LUI = (0x0F << 26),
65 /* arithmetic with immediate */
66 OPC_DADDI = (0x18 << 26),
67 OPC_DADDIU = (0x19 << 26),
68 /* Jump and branches */
69 OPC_J = (0x02 << 26),
70 OPC_JAL = (0x03 << 26),
71 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
72 OPC_BEQL = (0x14 << 26),
73 OPC_BNE = (0x05 << 26),
74 OPC_BNEL = (0x15 << 26),
75 OPC_BLEZ = (0x06 << 26),
76 OPC_BLEZL = (0x16 << 26),
77 OPC_BGTZ = (0x07 << 26),
78 OPC_BGTZL = (0x17 << 26),
79 OPC_JALX = (0x1D << 26),
80 OPC_DAUI = (0x1D << 26),
81 /* Load and stores */
82 OPC_LDL = (0x1A << 26),
83 OPC_LDR = (0x1B << 26),
84 OPC_LB = (0x20 << 26),
85 OPC_LH = (0x21 << 26),
86 OPC_LWL = (0x22 << 26),
87 OPC_LW = (0x23 << 26),
88 OPC_LWPC = OPC_LW | 0x5,
89 OPC_LBU = (0x24 << 26),
90 OPC_LHU = (0x25 << 26),
91 OPC_LWR = (0x26 << 26),
92 OPC_LWU = (0x27 << 26),
93 OPC_SB = (0x28 << 26),
94 OPC_SH = (0x29 << 26),
95 OPC_SWL = (0x2A << 26),
96 OPC_SW = (0x2B << 26),
97 OPC_SDL = (0x2C << 26),
98 OPC_SDR = (0x2D << 26),
99 OPC_SWR = (0x2E << 26),
100 OPC_LL = (0x30 << 26),
101 OPC_LLD = (0x34 << 26),
102 OPC_LD = (0x37 << 26),
103 OPC_LDPC = OPC_LD | 0x5,
104 OPC_SC = (0x38 << 26),
105 OPC_SCD = (0x3C << 26),
106 OPC_SD = (0x3F << 26),
107 /* Floating point load/store */
108 OPC_LWC1 = (0x31 << 26),
109 OPC_LWC2 = (0x32 << 26),
110 OPC_LDC1 = (0x35 << 26),
111 OPC_LDC2 = (0x36 << 26),
112 OPC_SWC1 = (0x39 << 26),
113 OPC_SWC2 = (0x3A << 26),
114 OPC_SDC1 = (0x3D << 26),
115 OPC_SDC2 = (0x3E << 26),
116 /* Compact Branches */
117 OPC_BLEZALC = (0x06 << 26),
118 OPC_BGEZALC = (0x06 << 26),
119 OPC_BGEUC = (0x06 << 26),
120 OPC_BGTZALC = (0x07 << 26),
121 OPC_BLTZALC = (0x07 << 26),
122 OPC_BLTUC = (0x07 << 26),
123 OPC_BOVC = (0x08 << 26),
124 OPC_BEQZALC = (0x08 << 26),
125 OPC_BEQC = (0x08 << 26),
126 OPC_BLEZC = (0x16 << 26),
127 OPC_BGEZC = (0x16 << 26),
128 OPC_BGEC = (0x16 << 26),
129 OPC_BGTZC = (0x17 << 26),
130 OPC_BLTZC = (0x17 << 26),
131 OPC_BLTC = (0x17 << 26),
132 OPC_BNVC = (0x18 << 26),
133 OPC_BNEZALC = (0x18 << 26),
134 OPC_BNEC = (0x18 << 26),
135 OPC_BC = (0x32 << 26),
136 OPC_BEQZC = (0x36 << 26),
137 OPC_JIC = (0x36 << 26),
138 OPC_BALC = (0x3A << 26),
139 OPC_BNEZC = (0x3E << 26),
140 OPC_JIALC = (0x3E << 26),
141 /* MDMX ASE specific */
142 OPC_MDMX = (0x1E << 26),
143 /* MSA ASE, same as MDMX */
144 OPC_MSA = OPC_MDMX,
145 /* Cache and prefetch */
146 OPC_CACHE = (0x2F << 26),
147 OPC_PREF = (0x33 << 26),
148 /* PC-relative address computation / loads */
149 OPC_PCREL = (0x3B << 26),
150 };
151
152 /* PC-relative address computation / loads */
153 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
154 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
155 enum {
156 /* Instructions determined by bits 19 and 20 */
157 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
158 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
159 OPC_LWUPC = OPC_PCREL | (2 << 19),
160
161 /* Instructions determined by bits 16 ... 20 */
162 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
163 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
164
165 /* Other */
166 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
167 };
168
169 /* MIPS special opcodes */
170 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
171
172 enum {
173 /* Shifts */
174 OPC_SLL = 0x00 | OPC_SPECIAL,
175 /* NOP is SLL r0, r0, 0 */
176 /* SSNOP is SLL r0, r0, 1 */
177 /* EHB is SLL r0, r0, 3 */
178 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
179 OPC_ROTR = OPC_SRL | (1 << 21),
180 OPC_SRA = 0x03 | OPC_SPECIAL,
181 OPC_SLLV = 0x04 | OPC_SPECIAL,
182 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
183 OPC_ROTRV = OPC_SRLV | (1 << 6),
184 OPC_SRAV = 0x07 | OPC_SPECIAL,
185 OPC_DSLLV = 0x14 | OPC_SPECIAL,
186 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
187 OPC_DROTRV = OPC_DSRLV | (1 << 6),
188 OPC_DSRAV = 0x17 | OPC_SPECIAL,
189 OPC_DSLL = 0x38 | OPC_SPECIAL,
190 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
191 OPC_DROTR = OPC_DSRL | (1 << 21),
192 OPC_DSRA = 0x3B | OPC_SPECIAL,
193 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
194 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
195 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
196 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
197 /* Multiplication / division */
198 OPC_MULT = 0x18 | OPC_SPECIAL,
199 OPC_MULTU = 0x19 | OPC_SPECIAL,
200 OPC_DIV = 0x1A | OPC_SPECIAL,
201 OPC_DIVU = 0x1B | OPC_SPECIAL,
202 OPC_DMULT = 0x1C | OPC_SPECIAL,
203 OPC_DMULTU = 0x1D | OPC_SPECIAL,
204 OPC_DDIV = 0x1E | OPC_SPECIAL,
205 OPC_DDIVU = 0x1F | OPC_SPECIAL,
206
207 /* 2 registers arithmetic / logic */
208 OPC_ADD = 0x20 | OPC_SPECIAL,
209 OPC_ADDU = 0x21 | OPC_SPECIAL,
210 OPC_SUB = 0x22 | OPC_SPECIAL,
211 OPC_SUBU = 0x23 | OPC_SPECIAL,
212 OPC_AND = 0x24 | OPC_SPECIAL,
213 OPC_OR = 0x25 | OPC_SPECIAL,
214 OPC_XOR = 0x26 | OPC_SPECIAL,
215 OPC_NOR = 0x27 | OPC_SPECIAL,
216 OPC_SLT = 0x2A | OPC_SPECIAL,
217 OPC_SLTU = 0x2B | OPC_SPECIAL,
218 OPC_DADD = 0x2C | OPC_SPECIAL,
219 OPC_DADDU = 0x2D | OPC_SPECIAL,
220 OPC_DSUB = 0x2E | OPC_SPECIAL,
221 OPC_DSUBU = 0x2F | OPC_SPECIAL,
222 /* Jumps */
223 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
224 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
225 /* Traps */
226 OPC_TGE = 0x30 | OPC_SPECIAL,
227 OPC_TGEU = 0x31 | OPC_SPECIAL,
228 OPC_TLT = 0x32 | OPC_SPECIAL,
229 OPC_TLTU = 0x33 | OPC_SPECIAL,
230 OPC_TEQ = 0x34 | OPC_SPECIAL,
231 OPC_TNE = 0x36 | OPC_SPECIAL,
232 /* HI / LO registers load & stores */
233 OPC_MFHI = 0x10 | OPC_SPECIAL,
234 OPC_MTHI = 0x11 | OPC_SPECIAL,
235 OPC_MFLO = 0x12 | OPC_SPECIAL,
236 OPC_MTLO = 0x13 | OPC_SPECIAL,
237 /* Conditional moves */
238 OPC_MOVZ = 0x0A | OPC_SPECIAL,
239 OPC_MOVN = 0x0B | OPC_SPECIAL,
240
241 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
242 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
243
244 OPC_MOVCI = 0x01 | OPC_SPECIAL,
245
246 /* Special */
247 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
248 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
249 OPC_BREAK = 0x0D | OPC_SPECIAL,
250 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
251 OPC_SYNC = 0x0F | OPC_SPECIAL,
252
253 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
254 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
255 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
256 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
257 };
258
259 /* R6 Multiply and Divide instructions have the same Opcode
260 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
261 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
262
263 enum {
264 R6_OPC_MUL = OPC_MULT | (2 << 6),
265 R6_OPC_MUH = OPC_MULT | (3 << 6),
266 R6_OPC_MULU = OPC_MULTU | (2 << 6),
267 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
268 R6_OPC_DIV = OPC_DIV | (2 << 6),
269 R6_OPC_MOD = OPC_DIV | (3 << 6),
270 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
271 R6_OPC_MODU = OPC_DIVU | (3 << 6),
272
273 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
274 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
275 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
276 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
277 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
278 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
279 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
280 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
281
282 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
283 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
284 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
285 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
286 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
287
288 OPC_LSA = 0x05 | OPC_SPECIAL,
289 OPC_DLSA = 0x15 | OPC_SPECIAL,
290 };
291
292 /* Multiplication variants of the vr54xx. */
293 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
294
295 enum {
296 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
297 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
298 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
299 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
300 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
301 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
302 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
303 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
304 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
305 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
306 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
307 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
308 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
309 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
310 };
311
312 /* REGIMM (rt field) opcodes */
313 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
314
315 enum {
316 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
317 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
318 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
319 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
320 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
321 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
322 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
323 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
324 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
325 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
326 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
327 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
328 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
329 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
330 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
331 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
332
333 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
334 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
335 };
336
337 /* Special2 opcodes */
338 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
339
340 enum {
341 /* Multiply & xxx operations */
342 OPC_MADD = 0x00 | OPC_SPECIAL2,
343 OPC_MADDU = 0x01 | OPC_SPECIAL2,
344 OPC_MUL = 0x02 | OPC_SPECIAL2,
345 OPC_MSUB = 0x04 | OPC_SPECIAL2,
346 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
347 /* Loongson 2F */
348 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
349 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
350 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
351 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
352 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
353 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
354 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
355 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
356 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
357 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
358 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
359 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
360 /* Misc */
361 OPC_CLZ = 0x20 | OPC_SPECIAL2,
362 OPC_CLO = 0x21 | OPC_SPECIAL2,
363 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
364 OPC_DCLO = 0x25 | OPC_SPECIAL2,
365 /* Special */
366 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
367 };
368
369 /* Special3 opcodes */
370 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
371
372 enum {
373 OPC_EXT = 0x00 | OPC_SPECIAL3,
374 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
375 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
376 OPC_DEXT = 0x03 | OPC_SPECIAL3,
377 OPC_INS = 0x04 | OPC_SPECIAL3,
378 OPC_DINSM = 0x05 | OPC_SPECIAL3,
379 OPC_DINSU = 0x06 | OPC_SPECIAL3,
380 OPC_DINS = 0x07 | OPC_SPECIAL3,
381 OPC_FORK = 0x08 | OPC_SPECIAL3,
382 OPC_YIELD = 0x09 | OPC_SPECIAL3,
383 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
384 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
385 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
386
387 /* Loongson 2E */
388 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
389 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
390 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
391 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
392 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
393 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
394 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
395 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
396 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
397 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
398 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
399 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
400
401 /* MIPS DSP Load */
402 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
403 /* MIPS DSP Arithmetic */
404 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
405 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
406 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
407 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
408 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
409 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
410 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
411 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
412 /* MIPS DSP GPR-Based Shift Sub-class */
413 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
414 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
415 /* MIPS DSP Multiply Sub-class insns */
416 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
417 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
418 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
419 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
420 /* DSP Bit/Manipulation Sub-class */
421 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
422 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
423 /* MIPS DSP Append Sub-class */
424 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
425 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
426 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
427 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
428 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
429
430 /* R6 */
431 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
432 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
433 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
434 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
435 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
436 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
437 };
438
439 /* BSHFL opcodes */
440 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
441
442 enum {
443 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
444 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
445 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
446 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
447 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
448 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
449 };
450
451 /* DBSHFL opcodes */
452 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
453
454 enum {
455 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
456 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
457 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
458 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
459 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
460 };
461
462 /* MIPS DSP REGIMM opcodes */
463 enum {
464 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
465 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
466 };
467
468 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
469 /* MIPS DSP Load */
470 enum {
471 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
472 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
473 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
474 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
475 };
476
477 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
478 enum {
479 /* MIPS DSP Arithmetic Sub-class */
480 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
483 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
484 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
485 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
486 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
490 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
491 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
492 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
493 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
494 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
495 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
496 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
497 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
498 /* MIPS DSP Multiply Sub-class insns */
499 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
501 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
502 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
503 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
504 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
505 };
506
507 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
508 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
509 enum {
510 /* MIPS DSP Arithmetic Sub-class */
511 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
515 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
519 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
520 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
521 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
522 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
523 /* MIPS DSP Multiply Sub-class insns */
524 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
525 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
526 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
527 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
528 };
529
530 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
531 enum {
532 /* MIPS DSP Arithmetic Sub-class */
533 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
546 /* DSP Bit/Manipulation Sub-class */
547 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
548 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
549 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
550 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
551 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
552 };
553
554 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
555 enum {
556 /* MIPS DSP Arithmetic Sub-class */
557 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
564 /* DSP Compare-Pick Sub-class */
565 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
579 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
580 };
581
582 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583 enum {
584 /* MIPS DSP GPR-Based Shift Sub-class */
585 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
603 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
605 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
606 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
607 };
608
609 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
610 enum {
611 /* MIPS DSP Multiply Sub-class insns */
612 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
624 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
628 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
630 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
632 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
633 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
634 };
635
636 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 enum {
638 /* DSP Bit/Manipulation Sub-class */
639 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
640 };
641
642 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
643 enum {
644 /* MIPS DSP Append Sub-class */
645 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
646 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
647 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
648 };
649
650 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
651 enum {
652 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
653 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
661 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
662 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
663 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
664 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
665 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
666 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
667 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
668 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
669 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
670 };
671
672 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673 enum {
674 /* MIPS DSP Arithmetic Sub-class */
675 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
692 /* DSP Bit/Manipulation Sub-class */
693 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
698 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
699 };
700
701 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
702 enum {
703 /* MIPS DSP Multiply Sub-class insns */
704 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
705 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
706 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
707 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
708 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
709 /* MIPS DSP Arithmetic Sub-class */
710 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
717 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
718 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
719 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
720 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
727 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
728 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
729 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
730 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
731 };
732
733 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
734 enum {
735 /* DSP Compare-Pick Sub-class */
736 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
755 /* MIPS DSP Arithmetic Sub-class */
756 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
763 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
764 };
765
766 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
767 enum {
768 /* DSP Append Sub-class */
769 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
770 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
771 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
772 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
773 };
774
775 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
776 enum {
777 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
778 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
779 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
795 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
796 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
797 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
798 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
799 };
800
801 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
802 enum {
803 /* DSP Bit/Manipulation Sub-class */
804 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
805 };
806
807 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
808 enum {
809 /* MIPS DSP Multiply Sub-class insns */
810 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
835 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
836 };
837
838 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
839 enum {
840 /* MIPS DSP GPR-Based Shift Sub-class */
841 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
866 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
867 };
868
869 /* Coprocessor 0 (rs field) */
870 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
871
872 enum {
873 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
874 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
875 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
876 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
877 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
878 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
879 OPC_MFTR = (0x08 << 21) | OPC_CP0,
880 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
881 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
882 OPC_MTTR = (0x0C << 21) | OPC_CP0,
883 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
884 OPC_C0 = (0x10 << 21) | OPC_CP0,
885 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
886 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
887 };
888
889 /* MFMC0 opcodes */
890 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
891
892 enum {
893 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
894 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
895 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
896 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
897 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
898 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
899 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
900 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
901 };
902
903 /* Coprocessor 0 (with rs == C0) */
904 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
905
906 enum {
907 OPC_TLBR = 0x01 | OPC_C0,
908 OPC_TLBWI = 0x02 | OPC_C0,
909 OPC_TLBINV = 0x03 | OPC_C0,
910 OPC_TLBINVF = 0x04 | OPC_C0,
911 OPC_TLBWR = 0x06 | OPC_C0,
912 OPC_TLBP = 0x08 | OPC_C0,
913 OPC_RFE = 0x10 | OPC_C0,
914 OPC_ERET = 0x18 | OPC_C0,
915 OPC_DERET = 0x1F | OPC_C0,
916 OPC_WAIT = 0x20 | OPC_C0,
917 };
918
919 /* Coprocessor 1 (rs field) */
920 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
921
922 /* Values for the fmt field in FP instructions */
923 enum {
924 /* 0 - 15 are reserved */
925 FMT_S = 16, /* single fp */
926 FMT_D = 17, /* double fp */
927 FMT_E = 18, /* extended fp */
928 FMT_Q = 19, /* quad fp */
929 FMT_W = 20, /* 32-bit fixed */
930 FMT_L = 21, /* 64-bit fixed */
931 FMT_PS = 22, /* paired single fp */
932 /* 23 - 31 are reserved */
933 };
934
935 enum {
936 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
937 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
938 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
939 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
940 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
941 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
942 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
943 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
944 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
945 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
946 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
947 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
948 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
949 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
950 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
951 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
952 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
953 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
954 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
955 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
956 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
957 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
958 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
959 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
960 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
961 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
962 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
963 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
964 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
965 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
966 };
967
968 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
969 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
970
971 enum {
972 OPC_BC1F = (0x00 << 16) | OPC_BC1,
973 OPC_BC1T = (0x01 << 16) | OPC_BC1,
974 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
975 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
976 };
977
978 enum {
979 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
980 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
981 };
982
983 enum {
984 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
985 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
986 };
987
988 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
989
990 enum {
991 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
992 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
993 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
994 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
995 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
996 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
997 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
998 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
999 OPC_BC2 = (0x08 << 21) | OPC_CP2,
1000 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
1001 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1002 };
1003
1004 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1005
1006 enum {
1007 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1013 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1014 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1015
1016 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1022 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1023 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1024
1025 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1027 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1028 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1029 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1030 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1031 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1032 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1033
1034 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1036 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1037 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1040 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1041 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1042
1043 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1044 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1047 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1048 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1049
1050 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1054 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1055 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1056
1057 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1061 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1062 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1063
1064 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1068 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1069 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1070
1071 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1072 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1073 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1074 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1075 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1076 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1077
1078 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1079 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1080 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1081 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1082 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1083 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1084
1085 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1086 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1087 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1088 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1089 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1090 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1091
1092 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1093 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1094 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1095 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1096 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1097 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1098 };
1099
1100
1101 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1102
1103 enum {
1104 OPC_LWXC1 = 0x00 | OPC_CP3,
1105 OPC_LDXC1 = 0x01 | OPC_CP3,
1106 OPC_LUXC1 = 0x05 | OPC_CP3,
1107 OPC_SWXC1 = 0x08 | OPC_CP3,
1108 OPC_SDXC1 = 0x09 | OPC_CP3,
1109 OPC_SUXC1 = 0x0D | OPC_CP3,
1110 OPC_PREFX = 0x0F | OPC_CP3,
1111 OPC_ALNV_PS = 0x1E | OPC_CP3,
1112 OPC_MADD_S = 0x20 | OPC_CP3,
1113 OPC_MADD_D = 0x21 | OPC_CP3,
1114 OPC_MADD_PS = 0x26 | OPC_CP3,
1115 OPC_MSUB_S = 0x28 | OPC_CP3,
1116 OPC_MSUB_D = 0x29 | OPC_CP3,
1117 OPC_MSUB_PS = 0x2E | OPC_CP3,
1118 OPC_NMADD_S = 0x30 | OPC_CP3,
1119 OPC_NMADD_D = 0x31 | OPC_CP3,
1120 OPC_NMADD_PS= 0x36 | OPC_CP3,
1121 OPC_NMSUB_S = 0x38 | OPC_CP3,
1122 OPC_NMSUB_D = 0x39 | OPC_CP3,
1123 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1124 };
1125
1126 /* MSA Opcodes */
1127 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1128 enum {
1129 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1130 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1131 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1132 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1133 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1134 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1135 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1136 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1137 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1138 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1139 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1140 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1141 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1142 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1143 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1144 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1145 OPC_MSA_ELM = 0x19 | OPC_MSA,
1146 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1147 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1148 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1149 OPC_MSA_VEC = 0x1E | OPC_MSA,
1150
1151 /* MI10 instruction */
1152 OPC_LD_B = (0x20) | OPC_MSA,
1153 OPC_LD_H = (0x21) | OPC_MSA,
1154 OPC_LD_W = (0x22) | OPC_MSA,
1155 OPC_LD_D = (0x23) | OPC_MSA,
1156 OPC_ST_B = (0x24) | OPC_MSA,
1157 OPC_ST_H = (0x25) | OPC_MSA,
1158 OPC_ST_W = (0x26) | OPC_MSA,
1159 OPC_ST_D = (0x27) | OPC_MSA,
1160 };
1161
1162 enum {
1163 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1164 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1165 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1166 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1167 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1168 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1169 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1170 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1171 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1172 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1173 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1174 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1175 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1176
1177 /* I8 instruction */
1178 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1179 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1180 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1181 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1182 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1183 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1184 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1185 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1186 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1187 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1188
1189 /* VEC/2R/2RF instruction */
1190 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1191 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1192 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1193 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1194 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1195 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1196 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1197
1198 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1199 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1200
1201 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1202 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1203 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1204 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1205 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1206
1207 /* 2RF instruction df(bit 16) = _w, _d */
1208 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1209 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1210 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1211 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1212 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1213 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1214 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1215 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1216 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1217 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1218 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1219 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1220 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1221 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1222 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1223 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1224
1225 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1226 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1227 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1228 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1229 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1230 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1231 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1232 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1233 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1234 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1235 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1236 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1237 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1238 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1239 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1240 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1241 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1242 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1243 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1244 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1245 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1246 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1247 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1248 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1249 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1250 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1251 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1252 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1253 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1254 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1255 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1256 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1257 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1258 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1259 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1260 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1261 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1262 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1263 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1264 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1265 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1266 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1267 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1268 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1269 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1270 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1271 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1272 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1273 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1274 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1275 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1276 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1277 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1278 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1279 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1280 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1281 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1282 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1283 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1284 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1285 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1286 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1287 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1288 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1289
1290 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1291 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1293 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1294 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1295 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1296 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1297 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1298 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1299 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1300
1301 /* 3RF instruction _df(bit 21) = _w, _d */
1302 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1303 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1304 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1305 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1306 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1307 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1308 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1309 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1310 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1311 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1312 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1313 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1314 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1315 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1316 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1317 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1318 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1319 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1320 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1321 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1322 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1323 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1324 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1325 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1326 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1327 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1328 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1329 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1330 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1331 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1332 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1333 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1334 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1335 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1336 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1337 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1338 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1339 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1340 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1341 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1342 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1343
1344 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1345 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1346 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1347 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1348 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1349 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1350 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1351 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1352 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1353 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1354 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1355 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1356 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1357 };
1358
1359 /* global register indices */
1360 static TCGv_env cpu_env;
1361 static TCGv cpu_gpr[32], cpu_PC;
1362 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1363 static TCGv cpu_dspctrl, btarget, bcond;
1364 static TCGv_i32 hflags;
1365 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1366 static TCGv_i64 fpu_f64[32];
1367 static TCGv_i64 msa_wr_d[64];
1368
1369 #include "exec/gen-icount.h"
1370
1371 #define gen_helper_0e0i(name, arg) do { \
1372 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1373 gen_helper_##name(cpu_env, helper_tmp); \
1374 tcg_temp_free_i32(helper_tmp); \
1375 } while(0)
1376
1377 #define gen_helper_0e1i(name, arg1, arg2) do { \
1378 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1379 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1380 tcg_temp_free_i32(helper_tmp); \
1381 } while(0)
1382
1383 #define gen_helper_1e0i(name, ret, arg1) do { \
1384 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1385 gen_helper_##name(ret, cpu_env, helper_tmp); \
1386 tcg_temp_free_i32(helper_tmp); \
1387 } while(0)
1388
1389 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1390 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1391 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1392 tcg_temp_free_i32(helper_tmp); \
1393 } while(0)
1394
1395 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1396 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1397 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1398 tcg_temp_free_i32(helper_tmp); \
1399 } while(0)
1400
1401 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1402 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1403 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1404 tcg_temp_free_i32(helper_tmp); \
1405 } while(0)
1406
1407 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1408 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1409 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1410 tcg_temp_free_i32(helper_tmp); \
1411 } while(0)
1412
1413 typedef struct DisasContext {
1414 struct TranslationBlock *tb;
1415 target_ulong pc, saved_pc;
1416 uint32_t opcode;
1417 int singlestep_enabled;
1418 int insn_flags;
1419 int32_t CP0_Config1;
1420 /* Routine used to access memory */
1421 int mem_idx;
1422 TCGMemOp default_tcg_memop_mask;
1423 uint32_t hflags, saved_hflags;
1424 int bstate;
1425 target_ulong btarget;
1426 bool ulri;
1427 int kscrexist;
1428 bool rxi;
1429 int ie;
1430 bool bi;
1431 bool bp;
1432 uint64_t PAMask;
1433 bool mvh;
1434 int CP0_LLAddr_shift;
1435 bool ps;
1436 bool vp;
1437 bool cmgcr;
1438 bool mrp;
1439 bool nan2008;
1440 bool abs2008;
1441 } DisasContext;
1442
1443 enum {
1444 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1445 * exception condition */
1446 BS_STOP = 1, /* We want to stop translation for any reason */
1447 BS_BRANCH = 2, /* We reached a branch condition */
1448 BS_EXCP = 3, /* We reached an exception condition */
1449 };
1450
1451 static const char * const regnames[] = {
1452 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1453 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1454 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1455 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1456 };
1457
1458 static const char * const regnames_HI[] = {
1459 "HI0", "HI1", "HI2", "HI3",
1460 };
1461
1462 static const char * const regnames_LO[] = {
1463 "LO0", "LO1", "LO2", "LO3",
1464 };
1465
1466 static const char * const fregnames[] = {
1467 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1468 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1469 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1470 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1471 };
1472
1473 static const char * const msaregnames[] = {
1474 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1475 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1476 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1477 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1478 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1479 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1480 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1481 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1482 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1483 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1484 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1485 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1486 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1487 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1488 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1489 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1490 };
1491
1492 #define LOG_DISAS(...) \
1493 do { \
1494 if (MIPS_DEBUG_DISAS) { \
1495 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1496 } \
1497 } while (0)
1498
1499 #define MIPS_INVAL(op) \
1500 do { \
1501 if (MIPS_DEBUG_DISAS) { \
1502 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1503 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1504 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1505 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
1506 } \
1507 } while (0)
1508
1509 /* General purpose registers moves. */
1510 static inline void gen_load_gpr (TCGv t, int reg)
1511 {
1512 if (reg == 0)
1513 tcg_gen_movi_tl(t, 0);
1514 else
1515 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1516 }
1517
1518 static inline void gen_store_gpr (TCGv t, int reg)
1519 {
1520 if (reg != 0)
1521 tcg_gen_mov_tl(cpu_gpr[reg], t);
1522 }
1523
1524 /* Moves to/from shadow registers. */
1525 static inline void gen_load_srsgpr (int from, int to)
1526 {
1527 TCGv t0 = tcg_temp_new();
1528
1529 if (from == 0)
1530 tcg_gen_movi_tl(t0, 0);
1531 else {
1532 TCGv_i32 t2 = tcg_temp_new_i32();
1533 TCGv_ptr addr = tcg_temp_new_ptr();
1534
1535 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1536 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1537 tcg_gen_andi_i32(t2, t2, 0xf);
1538 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1539 tcg_gen_ext_i32_ptr(addr, t2);
1540 tcg_gen_add_ptr(addr, cpu_env, addr);
1541
1542 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1543 tcg_temp_free_ptr(addr);
1544 tcg_temp_free_i32(t2);
1545 }
1546 gen_store_gpr(t0, to);
1547 tcg_temp_free(t0);
1548 }
1549
1550 static inline void gen_store_srsgpr (int from, int to)
1551 {
1552 if (to != 0) {
1553 TCGv t0 = tcg_temp_new();
1554 TCGv_i32 t2 = tcg_temp_new_i32();
1555 TCGv_ptr addr = tcg_temp_new_ptr();
1556
1557 gen_load_gpr(t0, from);
1558 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1559 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1560 tcg_gen_andi_i32(t2, t2, 0xf);
1561 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1562 tcg_gen_ext_i32_ptr(addr, t2);
1563 tcg_gen_add_ptr(addr, cpu_env, addr);
1564
1565 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1566 tcg_temp_free_ptr(addr);
1567 tcg_temp_free_i32(t2);
1568 tcg_temp_free(t0);
1569 }
1570 }
1571
1572 /* Tests */
1573 static inline void gen_save_pc(target_ulong pc)
1574 {
1575 tcg_gen_movi_tl(cpu_PC, pc);
1576 }
1577
1578 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1579 {
1580 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1581 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1582 gen_save_pc(ctx->pc);
1583 ctx->saved_pc = ctx->pc;
1584 }
1585 if (ctx->hflags != ctx->saved_hflags) {
1586 tcg_gen_movi_i32(hflags, ctx->hflags);
1587 ctx->saved_hflags = ctx->hflags;
1588 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1589 case MIPS_HFLAG_BR:
1590 break;
1591 case MIPS_HFLAG_BC:
1592 case MIPS_HFLAG_BL:
1593 case MIPS_HFLAG_B:
1594 tcg_gen_movi_tl(btarget, ctx->btarget);
1595 break;
1596 }
1597 }
1598 }
1599
1600 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1601 {
1602 ctx->saved_hflags = ctx->hflags;
1603 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1604 case MIPS_HFLAG_BR:
1605 break;
1606 case MIPS_HFLAG_BC:
1607 case MIPS_HFLAG_BL:
1608 case MIPS_HFLAG_B:
1609 ctx->btarget = env->btarget;
1610 break;
1611 }
1612 }
1613
1614 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1615 {
1616 TCGv_i32 texcp = tcg_const_i32(excp);
1617 TCGv_i32 terr = tcg_const_i32(err);
1618 save_cpu_state(ctx, 1);
1619 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1620 tcg_temp_free_i32(terr);
1621 tcg_temp_free_i32(texcp);
1622 ctx->bstate = BS_EXCP;
1623 }
1624
1625 static inline void generate_exception(DisasContext *ctx, int excp)
1626 {
1627 gen_helper_0e0i(raise_exception, excp);
1628 }
1629
1630 static inline void generate_exception_end(DisasContext *ctx, int excp)
1631 {
1632 generate_exception_err(ctx, excp, 0);
1633 }
1634
1635 /* Floating point register moves. */
1636 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1637 {
1638 if (ctx->hflags & MIPS_HFLAG_FRE) {
1639 generate_exception(ctx, EXCP_RI);
1640 }
1641 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1642 }
1643
1644 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1645 {
1646 TCGv_i64 t64;
1647 if (ctx->hflags & MIPS_HFLAG_FRE) {
1648 generate_exception(ctx, EXCP_RI);
1649 }
1650 t64 = tcg_temp_new_i64();
1651 tcg_gen_extu_i32_i64(t64, t);
1652 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1653 tcg_temp_free_i64(t64);
1654 }
1655
1656 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1657 {
1658 if (ctx->hflags & MIPS_HFLAG_F64) {
1659 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1660 } else {
1661 gen_load_fpr32(ctx, t, reg | 1);
1662 }
1663 }
1664
1665 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1666 {
1667 if (ctx->hflags & MIPS_HFLAG_F64) {
1668 TCGv_i64 t64 = tcg_temp_new_i64();
1669 tcg_gen_extu_i32_i64(t64, t);
1670 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1671 tcg_temp_free_i64(t64);
1672 } else {
1673 gen_store_fpr32(ctx, t, reg | 1);
1674 }
1675 }
1676
1677 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1678 {
1679 if (ctx->hflags & MIPS_HFLAG_F64) {
1680 tcg_gen_mov_i64(t, fpu_f64[reg]);
1681 } else {
1682 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1683 }
1684 }
1685
1686 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1687 {
1688 if (ctx->hflags & MIPS_HFLAG_F64) {
1689 tcg_gen_mov_i64(fpu_f64[reg], t);
1690 } else {
1691 TCGv_i64 t0;
1692 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1693 t0 = tcg_temp_new_i64();
1694 tcg_gen_shri_i64(t0, t, 32);
1695 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1696 tcg_temp_free_i64(t0);
1697 }
1698 }
1699
1700 static inline int get_fp_bit (int cc)
1701 {
1702 if (cc)
1703 return 24 + cc;
1704 else
1705 return 23;
1706 }
1707
1708 /* Addresses computation */
1709 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1710 {
1711 tcg_gen_add_tl(ret, arg0, arg1);
1712
1713 #if defined(TARGET_MIPS64)
1714 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1715 tcg_gen_ext32s_i64(ret, ret);
1716 }
1717 #endif
1718 }
1719
1720 /* Addresses computation (translation time) */
1721 static target_long addr_add(DisasContext *ctx, target_long base,
1722 target_long offset)
1723 {
1724 target_long sum = base + offset;
1725
1726 #if defined(TARGET_MIPS64)
1727 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1728 sum = (int32_t)sum;
1729 }
1730 #endif
1731 return sum;
1732 }
1733
1734 /* Sign-extract the low 32-bits to a target_long. */
1735 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1736 {
1737 #if defined(TARGET_MIPS64)
1738 tcg_gen_ext32s_i64(ret, arg);
1739 #else
1740 tcg_gen_extrl_i64_i32(ret, arg);
1741 #endif
1742 }
1743
1744 /* Sign-extract the high 32-bits to a target_long. */
1745 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1746 {
1747 #if defined(TARGET_MIPS64)
1748 tcg_gen_sari_i64(ret, arg, 32);
1749 #else
1750 tcg_gen_extrh_i64_i32(ret, arg);
1751 #endif
1752 }
1753
1754 static inline void check_cp0_enabled(DisasContext *ctx)
1755 {
1756 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1757 generate_exception_err(ctx, EXCP_CpU, 0);
1758 }
1759
1760 static inline void check_cp1_enabled(DisasContext *ctx)
1761 {
1762 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1763 generate_exception_err(ctx, EXCP_CpU, 1);
1764 }
1765
1766 /* Verify that the processor is running with COP1X instructions enabled.
1767 This is associated with the nabla symbol in the MIPS32 and MIPS64
1768 opcode tables. */
1769
1770 static inline void check_cop1x(DisasContext *ctx)
1771 {
1772 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1773 generate_exception_end(ctx, EXCP_RI);
1774 }
1775
1776 /* Verify that the processor is running with 64-bit floating-point
1777 operations enabled. */
1778
1779 static inline void check_cp1_64bitmode(DisasContext *ctx)
1780 {
1781 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1782 generate_exception_end(ctx, EXCP_RI);
1783 }
1784
1785 /*
1786 * Verify if floating point register is valid; an operation is not defined
1787 * if bit 0 of any register specification is set and the FR bit in the
1788 * Status register equals zero, since the register numbers specify an
1789 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1790 * in the Status register equals one, both even and odd register numbers
1791 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1792 *
1793 * Multiple 64 bit wide registers can be checked by calling
1794 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1795 */
1796 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1797 {
1798 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1799 generate_exception_end(ctx, EXCP_RI);
1800 }
1801
1802 /* Verify that the processor is running with DSP instructions enabled.
1803 This is enabled by CP0 Status register MX(24) bit.
1804 */
1805
1806 static inline void check_dsp(DisasContext *ctx)
1807 {
1808 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1809 if (ctx->insn_flags & ASE_DSP) {
1810 generate_exception_end(ctx, EXCP_DSPDIS);
1811 } else {
1812 generate_exception_end(ctx, EXCP_RI);
1813 }
1814 }
1815 }
1816
1817 static inline void check_dspr2(DisasContext *ctx)
1818 {
1819 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1820 if (ctx->insn_flags & ASE_DSP) {
1821 generate_exception_end(ctx, EXCP_DSPDIS);
1822 } else {
1823 generate_exception_end(ctx, EXCP_RI);
1824 }
1825 }
1826 }
1827
1828 /* This code generates a "reserved instruction" exception if the
1829 CPU does not support the instruction set corresponding to flags. */
1830 static inline void check_insn(DisasContext *ctx, int flags)
1831 {
1832 if (unlikely(!(ctx->insn_flags & flags))) {
1833 generate_exception_end(ctx, EXCP_RI);
1834 }
1835 }
1836
1837 /* This code generates a "reserved instruction" exception if the
1838 CPU has corresponding flag set which indicates that the instruction
1839 has been removed. */
1840 static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1841 {
1842 if (unlikely(ctx->insn_flags & flags)) {
1843 generate_exception_end(ctx, EXCP_RI);
1844 }
1845 }
1846
1847 /* This code generates a "reserved instruction" exception if the
1848 CPU does not support 64-bit paired-single (PS) floating point data type */
1849 static inline void check_ps(DisasContext *ctx)
1850 {
1851 if (unlikely(!ctx->ps)) {
1852 generate_exception(ctx, EXCP_RI);
1853 }
1854 check_cp1_64bitmode(ctx);
1855 }
1856
1857 #ifdef TARGET_MIPS64
1858 /* This code generates a "reserved instruction" exception if 64-bit
1859 instructions are not enabled. */
1860 static inline void check_mips_64(DisasContext *ctx)
1861 {
1862 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1863 generate_exception_end(ctx, EXCP_RI);
1864 }
1865 #endif
1866
1867 #ifndef CONFIG_USER_ONLY
1868 static inline void check_mvh(DisasContext *ctx)
1869 {
1870 if (unlikely(!ctx->mvh)) {
1871 generate_exception(ctx, EXCP_RI);
1872 }
1873 }
1874 #endif
1875
1876 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1877 calling interface for 32 and 64-bit FPRs. No sense in changing
1878 all callers for gen_load_fpr32 when we need the CTX parameter for
1879 this one use. */
1880 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1881 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1882 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1883 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1884 int ft, int fs, int cc) \
1885 { \
1886 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1887 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1888 switch (ifmt) { \
1889 case FMT_PS: \
1890 check_ps(ctx); \
1891 break; \
1892 case FMT_D: \
1893 if (abs) { \
1894 check_cop1x(ctx); \
1895 } \
1896 check_cp1_registers(ctx, fs | ft); \
1897 break; \
1898 case FMT_S: \
1899 if (abs) { \
1900 check_cop1x(ctx); \
1901 } \
1902 break; \
1903 } \
1904 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1905 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1906 switch (n) { \
1907 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1908 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1909 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1910 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1911 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1912 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1913 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1914 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1915 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1916 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1917 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1918 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1919 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1920 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1921 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1922 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1923 default: abort(); \
1924 } \
1925 tcg_temp_free_i##bits (fp0); \
1926 tcg_temp_free_i##bits (fp1); \
1927 }
1928
1929 FOP_CONDS(, 0, d, FMT_D, 64)
1930 FOP_CONDS(abs, 1, d, FMT_D, 64)
1931 FOP_CONDS(, 0, s, FMT_S, 32)
1932 FOP_CONDS(abs, 1, s, FMT_S, 32)
1933 FOP_CONDS(, 0, ps, FMT_PS, 64)
1934 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1935 #undef FOP_CONDS
1936
1937 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1938 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1939 int ft, int fs, int fd) \
1940 { \
1941 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1942 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1943 if (ifmt == FMT_D) { \
1944 check_cp1_registers(ctx, fs | ft | fd); \
1945 } \
1946 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1947 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1948 switch (n) { \
1949 case 0: \
1950 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1951 break; \
1952 case 1: \
1953 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1954 break; \
1955 case 2: \
1956 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1957 break; \
1958 case 3: \
1959 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1960 break; \
1961 case 4: \
1962 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1963 break; \
1964 case 5: \
1965 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1966 break; \
1967 case 6: \
1968 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1969 break; \
1970 case 7: \
1971 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1972 break; \
1973 case 8: \
1974 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1975 break; \
1976 case 9: \
1977 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1978 break; \
1979 case 10: \
1980 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1981 break; \
1982 case 11: \
1983 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1984 break; \
1985 case 12: \
1986 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1987 break; \
1988 case 13: \
1989 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1990 break; \
1991 case 14: \
1992 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1993 break; \
1994 case 15: \
1995 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1996 break; \
1997 case 17: \
1998 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1999 break; \
2000 case 18: \
2001 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2002 break; \
2003 case 19: \
2004 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2005 break; \
2006 case 25: \
2007 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2008 break; \
2009 case 26: \
2010 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2011 break; \
2012 case 27: \
2013 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2014 break; \
2015 default: \
2016 abort(); \
2017 } \
2018 STORE; \
2019 tcg_temp_free_i ## bits (fp0); \
2020 tcg_temp_free_i ## bits (fp1); \
2021 }
2022
2023 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2024 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2025 #undef FOP_CONDNS
2026 #undef gen_ldcmp_fpr32
2027 #undef gen_ldcmp_fpr64
2028
2029 /* load/store instructions. */
2030 #ifdef CONFIG_USER_ONLY
2031 #define OP_LD_ATOMIC(insn,fname) \
2032 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2033 { \
2034 TCGv t0 = tcg_temp_new(); \
2035 tcg_gen_mov_tl(t0, arg1); \
2036 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2037 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2038 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2039 tcg_temp_free(t0); \
2040 }
2041 #else
2042 #define OP_LD_ATOMIC(insn,fname) \
2043 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2044 { \
2045 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
2046 }
2047 #endif
2048 OP_LD_ATOMIC(ll,ld32s);
2049 #if defined(TARGET_MIPS64)
2050 OP_LD_ATOMIC(lld,ld64);
2051 #endif
2052 #undef OP_LD_ATOMIC
2053
2054 #ifdef CONFIG_USER_ONLY
2055 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2056 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2057 { \
2058 TCGv t0 = tcg_temp_new(); \
2059 TCGLabel *l1 = gen_new_label(); \
2060 TCGLabel *l2 = gen_new_label(); \
2061 \
2062 tcg_gen_andi_tl(t0, arg2, almask); \
2063 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2064 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2065 generate_exception(ctx, EXCP_AdES); \
2066 gen_set_label(l1); \
2067 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2068 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2069 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2070 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2071 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2072 generate_exception_end(ctx, EXCP_SC); \
2073 gen_set_label(l2); \
2074 tcg_gen_movi_tl(t0, 0); \
2075 gen_store_gpr(t0, rt); \
2076 tcg_temp_free(t0); \
2077 }
2078 #else
2079 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2080 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2081 { \
2082 TCGv t0 = tcg_temp_new(); \
2083 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2084 gen_store_gpr(t0, rt); \
2085 tcg_temp_free(t0); \
2086 }
2087 #endif
2088 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2089 #if defined(TARGET_MIPS64)
2090 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2091 #endif
2092 #undef OP_ST_ATOMIC
2093
2094 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2095 int base, int16_t offset)
2096 {
2097 if (base == 0) {
2098 tcg_gen_movi_tl(addr, offset);
2099 } else if (offset == 0) {
2100 gen_load_gpr(addr, base);
2101 } else {
2102 tcg_gen_movi_tl(addr, offset);
2103 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2104 }
2105 }
2106
2107 static target_ulong pc_relative_pc (DisasContext *ctx)
2108 {
2109 target_ulong pc = ctx->pc;
2110
2111 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2112 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2113
2114 pc -= branch_bytes;
2115 }
2116
2117 pc &= ~(target_ulong)3;
2118 return pc;
2119 }
2120
2121 /* Load */
2122 static void gen_ld(DisasContext *ctx, uint32_t opc,
2123 int rt, int base, int16_t offset)
2124 {
2125 TCGv t0, t1, t2;
2126
2127 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2128 /* Loongson CPU uses a load to zero register for prefetch.
2129 We emulate it as a NOP. On other CPU we must perform the
2130 actual memory access. */
2131 return;
2132 }
2133
2134 t0 = tcg_temp_new();
2135 gen_base_offset_addr(ctx, t0, base, offset);
2136
2137 switch (opc) {
2138 #if defined(TARGET_MIPS64)
2139 case OPC_LWU:
2140 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2141 ctx->default_tcg_memop_mask);
2142 gen_store_gpr(t0, rt);
2143 break;
2144 case OPC_LD:
2145 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2146 ctx->default_tcg_memop_mask);
2147 gen_store_gpr(t0, rt);
2148 break;
2149 case OPC_LLD:
2150 case R6_OPC_LLD:
2151 op_ld_lld(t0, t0, ctx);
2152 gen_store_gpr(t0, rt);
2153 break;
2154 case OPC_LDL:
2155 t1 = tcg_temp_new();
2156 /* Do a byte access to possibly trigger a page
2157 fault with the unaligned address. */
2158 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2159 tcg_gen_andi_tl(t1, t0, 7);
2160 #ifndef TARGET_WORDS_BIGENDIAN
2161 tcg_gen_xori_tl(t1, t1, 7);
2162 #endif
2163 tcg_gen_shli_tl(t1, t1, 3);
2164 tcg_gen_andi_tl(t0, t0, ~7);
2165 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2166 tcg_gen_shl_tl(t0, t0, t1);
2167 t2 = tcg_const_tl(-1);
2168 tcg_gen_shl_tl(t2, t2, t1);
2169 gen_load_gpr(t1, rt);
2170 tcg_gen_andc_tl(t1, t1, t2);
2171 tcg_temp_free(t2);
2172 tcg_gen_or_tl(t0, t0, t1);
2173 tcg_temp_free(t1);
2174 gen_store_gpr(t0, rt);
2175 break;
2176 case OPC_LDR:
2177 t1 = tcg_temp_new();
2178 /* Do a byte access to possibly trigger a page
2179 fault with the unaligned address. */
2180 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2181 tcg_gen_andi_tl(t1, t0, 7);
2182 #ifdef TARGET_WORDS_BIGENDIAN
2183 tcg_gen_xori_tl(t1, t1, 7);
2184 #endif
2185 tcg_gen_shli_tl(t1, t1, 3);
2186 tcg_gen_andi_tl(t0, t0, ~7);
2187 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2188 tcg_gen_shr_tl(t0, t0, t1);
2189 tcg_gen_xori_tl(t1, t1, 63);
2190 t2 = tcg_const_tl(0xfffffffffffffffeull);
2191 tcg_gen_shl_tl(t2, t2, t1);
2192 gen_load_gpr(t1, rt);
2193 tcg_gen_and_tl(t1, t1, t2);
2194 tcg_temp_free(t2);
2195 tcg_gen_or_tl(t0, t0, t1);
2196 tcg_temp_free(t1);
2197 gen_store_gpr(t0, rt);
2198 break;
2199 case OPC_LDPC:
2200 t1 = tcg_const_tl(pc_relative_pc(ctx));
2201 gen_op_addr_add(ctx, t0, t0, t1);
2202 tcg_temp_free(t1);
2203 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2204 gen_store_gpr(t0, rt);
2205 break;
2206 #endif
2207 case OPC_LWPC:
2208 t1 = tcg_const_tl(pc_relative_pc(ctx));
2209 gen_op_addr_add(ctx, t0, t0, t1);
2210 tcg_temp_free(t1);
2211 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2212 gen_store_gpr(t0, rt);
2213 break;
2214 case OPC_LW:
2215 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2216 ctx->default_tcg_memop_mask);
2217 gen_store_gpr(t0, rt);
2218 break;
2219 case OPC_LH:
2220 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2221 ctx->default_tcg_memop_mask);
2222 gen_store_gpr(t0, rt);
2223 break;
2224 case OPC_LHU:
2225 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2226 ctx->default_tcg_memop_mask);
2227 gen_store_gpr(t0, rt);
2228 break;
2229 case OPC_LB:
2230 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2231 gen_store_gpr(t0, rt);
2232 break;
2233 case OPC_LBU:
2234 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2235 gen_store_gpr(t0, rt);
2236 break;
2237 case OPC_LWL:
2238 t1 = tcg_temp_new();
2239 /* Do a byte access to possibly trigger a page
2240 fault with the unaligned address. */
2241 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2242 tcg_gen_andi_tl(t1, t0, 3);
2243 #ifndef TARGET_WORDS_BIGENDIAN
2244 tcg_gen_xori_tl(t1, t1, 3);
2245 #endif
2246 tcg_gen_shli_tl(t1, t1, 3);
2247 tcg_gen_andi_tl(t0, t0, ~3);
2248 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2249 tcg_gen_shl_tl(t0, t0, t1);
2250 t2 = tcg_const_tl(-1);
2251 tcg_gen_shl_tl(t2, t2, t1);
2252 gen_load_gpr(t1, rt);
2253 tcg_gen_andc_tl(t1, t1, t2);
2254 tcg_temp_free(t2);
2255 tcg_gen_or_tl(t0, t0, t1);
2256 tcg_temp_free(t1);
2257 tcg_gen_ext32s_tl(t0, t0);
2258 gen_store_gpr(t0, rt);
2259 break;
2260 case OPC_LWR:
2261 t1 = tcg_temp_new();
2262 /* Do a byte access to possibly trigger a page
2263 fault with the unaligned address. */
2264 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2265 tcg_gen_andi_tl(t1, t0, 3);
2266 #ifdef TARGET_WORDS_BIGENDIAN
2267 tcg_gen_xori_tl(t1, t1, 3);
2268 #endif
2269 tcg_gen_shli_tl(t1, t1, 3);
2270 tcg_gen_andi_tl(t0, t0, ~3);
2271 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2272 tcg_gen_shr_tl(t0, t0, t1);
2273 tcg_gen_xori_tl(t1, t1, 31);
2274 t2 = tcg_const_tl(0xfffffffeull);
2275 tcg_gen_shl_tl(t2, t2, t1);
2276 gen_load_gpr(t1, rt);
2277 tcg_gen_and_tl(t1, t1, t2);
2278 tcg_temp_free(t2);
2279 tcg_gen_or_tl(t0, t0, t1);
2280 tcg_temp_free(t1);
2281 tcg_gen_ext32s_tl(t0, t0);
2282 gen_store_gpr(t0, rt);
2283 break;
2284 case OPC_LL:
2285 case R6_OPC_LL:
2286 op_ld_ll(t0, t0, ctx);
2287 gen_store_gpr(t0, rt);
2288 break;
2289 }
2290 tcg_temp_free(t0);
2291 }
2292
2293 /* Store */
2294 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2295 int base, int16_t offset)
2296 {
2297 TCGv t0 = tcg_temp_new();
2298 TCGv t1 = tcg_temp_new();
2299
2300 gen_base_offset_addr(ctx, t0, base, offset);
2301 gen_load_gpr(t1, rt);
2302 switch (opc) {
2303 #if defined(TARGET_MIPS64)
2304 case OPC_SD:
2305 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2306 ctx->default_tcg_memop_mask);
2307 break;
2308 case OPC_SDL:
2309 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2310 break;
2311 case OPC_SDR:
2312 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2313 break;
2314 #endif
2315 case OPC_SW:
2316 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2317 ctx->default_tcg_memop_mask);
2318 break;
2319 case OPC_SH:
2320 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2321 ctx->default_tcg_memop_mask);
2322 break;
2323 case OPC_SB:
2324 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2325 break;
2326 case OPC_SWL:
2327 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2328 break;
2329 case OPC_SWR:
2330 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2331 break;
2332 }
2333 tcg_temp_free(t0);
2334 tcg_temp_free(t1);
2335 }
2336
2337
2338 /* Store conditional */
2339 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2340 int base, int16_t offset)
2341 {
2342 TCGv t0, t1;
2343
2344 #ifdef CONFIG_USER_ONLY
2345 t0 = tcg_temp_local_new();
2346 t1 = tcg_temp_local_new();
2347 #else
2348 t0 = tcg_temp_new();
2349 t1 = tcg_temp_new();
2350 #endif
2351 gen_base_offset_addr(ctx, t0, base, offset);
2352 gen_load_gpr(t1, rt);
2353 switch (opc) {
2354 #if defined(TARGET_MIPS64)
2355 case OPC_SCD:
2356 case R6_OPC_SCD:
2357 op_st_scd(t1, t0, rt, ctx);
2358 break;
2359 #endif
2360 case OPC_SC:
2361 case R6_OPC_SC:
2362 op_st_sc(t1, t0, rt, ctx);
2363 break;
2364 }
2365 tcg_temp_free(t1);
2366 tcg_temp_free(t0);
2367 }
2368
2369 /* Load and store */
2370 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2371 int base, int16_t offset)
2372 {
2373 TCGv t0 = tcg_temp_new();
2374
2375 gen_base_offset_addr(ctx, t0, base, offset);
2376 /* Don't do NOP if destination is zero: we must perform the actual
2377 memory access. */
2378 switch (opc) {
2379 case OPC_LWC1:
2380 {
2381 TCGv_i32 fp0 = tcg_temp_new_i32();
2382 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2383 ctx->default_tcg_memop_mask);
2384 gen_store_fpr32(ctx, fp0, ft);
2385 tcg_temp_free_i32(fp0);
2386 }
2387 break;
2388 case OPC_SWC1:
2389 {
2390 TCGv_i32 fp0 = tcg_temp_new_i32();
2391 gen_load_fpr32(ctx, fp0, ft);
2392 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2393 ctx->default_tcg_memop_mask);
2394 tcg_temp_free_i32(fp0);
2395 }
2396 break;
2397 case OPC_LDC1:
2398 {
2399 TCGv_i64 fp0 = tcg_temp_new_i64();
2400 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2401 ctx->default_tcg_memop_mask);
2402 gen_store_fpr64(ctx, fp0, ft);
2403 tcg_temp_free_i64(fp0);
2404 }
2405 break;
2406 case OPC_SDC1:
2407 {
2408 TCGv_i64 fp0 = tcg_temp_new_i64();
2409 gen_load_fpr64(ctx, fp0, ft);
2410 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2411 ctx->default_tcg_memop_mask);
2412 tcg_temp_free_i64(fp0);
2413 }
2414 break;
2415 default:
2416 MIPS_INVAL("flt_ldst");
2417 generate_exception_end(ctx, EXCP_RI);
2418 goto out;
2419 }
2420 out:
2421 tcg_temp_free(t0);
2422 }
2423
2424 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2425 int rs, int16_t imm)
2426 {
2427 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2428 check_cp1_enabled(ctx);
2429 switch (op) {
2430 case OPC_LDC1:
2431 case OPC_SDC1:
2432 check_insn(ctx, ISA_MIPS2);
2433 /* Fallthrough */
2434 default:
2435 gen_flt_ldst(ctx, op, rt, rs, imm);
2436 }
2437 } else {
2438 generate_exception_err(ctx, EXCP_CpU, 1);
2439 }
2440 }
2441
2442 /* Arithmetic with immediate operand */
2443 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2444 int rt, int rs, int16_t imm)
2445 {
2446 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2447
2448 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2449 /* If no destination, treat it as a NOP.
2450 For addi, we must generate the overflow exception when needed. */
2451 return;
2452 }
2453 switch (opc) {
2454 case OPC_ADDI:
2455 {
2456 TCGv t0 = tcg_temp_local_new();
2457 TCGv t1 = tcg_temp_new();
2458 TCGv t2 = tcg_temp_new();
2459 TCGLabel *l1 = gen_new_label();
2460
2461 gen_load_gpr(t1, rs);
2462 tcg_gen_addi_tl(t0, t1, uimm);
2463 tcg_gen_ext32s_tl(t0, t0);
2464
2465 tcg_gen_xori_tl(t1, t1, ~uimm);
2466 tcg_gen_xori_tl(t2, t0, uimm);
2467 tcg_gen_and_tl(t1, t1, t2);
2468 tcg_temp_free(t2);
2469 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2470 tcg_temp_free(t1);
2471 /* operands of same sign, result different sign */
2472 generate_exception(ctx, EXCP_OVERFLOW);
2473 gen_set_label(l1);
2474 tcg_gen_ext32s_tl(t0, t0);
2475 gen_store_gpr(t0, rt);
2476 tcg_temp_free(t0);
2477 }
2478 break;
2479 case OPC_ADDIU:
2480 if (rs != 0) {
2481 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2482 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2483 } else {
2484 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2485 }
2486 break;
2487 #if defined(TARGET_MIPS64)
2488 case OPC_DADDI:
2489 {
2490 TCGv t0 = tcg_temp_local_new();
2491 TCGv t1 = tcg_temp_new();
2492 TCGv t2 = tcg_temp_new();
2493 TCGLabel *l1 = gen_new_label();
2494
2495 gen_load_gpr(t1, rs);
2496 tcg_gen_addi_tl(t0, t1, uimm);
2497
2498 tcg_gen_xori_tl(t1, t1, ~uimm);
2499 tcg_gen_xori_tl(t2, t0, uimm);
2500 tcg_gen_and_tl(t1, t1, t2);
2501 tcg_temp_free(t2);
2502 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2503 tcg_temp_free(t1);
2504 /* operands of same sign, result different sign */
2505 generate_exception(ctx, EXCP_OVERFLOW);
2506 gen_set_label(l1);
2507 gen_store_gpr(t0, rt);
2508 tcg_temp_free(t0);
2509 }
2510 break;
2511 case OPC_DADDIU:
2512 if (rs != 0) {
2513 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2514 } else {
2515 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2516 }
2517 break;
2518 #endif
2519 }
2520 }
2521
2522 /* Logic with immediate operand */
2523 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2524 int rt, int rs, int16_t imm)
2525 {
2526 target_ulong uimm;
2527
2528 if (rt == 0) {
2529 /* If no destination, treat it as a NOP. */
2530 return;
2531 }
2532 uimm = (uint16_t)imm;
2533 switch (opc) {
2534 case OPC_ANDI:
2535 if (likely(rs != 0))
2536 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2537 else
2538 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2539 break;
2540 case OPC_ORI:
2541 if (rs != 0)
2542 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2543 else
2544 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2545 break;
2546 case OPC_XORI:
2547 if (likely(rs != 0))
2548 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2549 else
2550 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2551 break;
2552 case OPC_LUI:
2553 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2554 /* OPC_AUI */
2555 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2556 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2557 } else {
2558 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2559 }
2560 break;
2561
2562 default:
2563 break;
2564 }
2565 }
2566
2567 /* Set on less than with immediate operand */
2568 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2569 int rt, int rs, int16_t imm)
2570 {
2571 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2572 TCGv t0;
2573
2574 if (rt == 0) {
2575 /* If no destination, treat it as a NOP. */
2576 return;
2577 }
2578 t0 = tcg_temp_new();
2579 gen_load_gpr(t0, rs);
2580 switch (opc) {
2581 case OPC_SLTI:
2582 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2583 break;
2584 case OPC_SLTIU:
2585 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2586 break;
2587 }
2588 tcg_temp_free(t0);
2589 }
2590
2591 /* Shifts with immediate operand */
2592 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2593 int rt, int rs, int16_t imm)
2594 {
2595 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2596 TCGv t0;
2597
2598 if (rt == 0) {
2599 /* If no destination, treat it as a NOP. */
2600 return;
2601 }
2602
2603 t0 = tcg_temp_new();
2604 gen_load_gpr(t0, rs);
2605 switch (opc) {
2606 case OPC_SLL:
2607 tcg_gen_shli_tl(t0, t0, uimm);
2608 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2609 break;
2610 case OPC_SRA:
2611 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2612 break;
2613 case OPC_SRL:
2614 if (uimm != 0) {
2615 tcg_gen_ext32u_tl(t0, t0);
2616 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2617 } else {
2618 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2619 }
2620 break;
2621 case OPC_ROTR:
2622 if (uimm != 0) {
2623 TCGv_i32 t1 = tcg_temp_new_i32();
2624
2625 tcg_gen_trunc_tl_i32(t1, t0);
2626 tcg_gen_rotri_i32(t1, t1, uimm);
2627 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2628 tcg_temp_free_i32(t1);
2629 } else {
2630 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2631 }
2632 break;
2633 #if defined(TARGET_MIPS64)
2634 case OPC_DSLL:
2635 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2636 break;
2637 case OPC_DSRA:
2638 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2639 break;
2640 case OPC_DSRL:
2641 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2642 break;
2643 case OPC_DROTR:
2644 if (uimm != 0) {
2645 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2646 } else {
2647 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2648 }
2649 break;
2650 case OPC_DSLL32:
2651 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2652 break;
2653 case OPC_DSRA32:
2654 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2655 break;
2656 case OPC_DSRL32:
2657 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2658 break;
2659 case OPC_DROTR32:
2660 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2661 break;
2662 #endif
2663 }
2664 tcg_temp_free(t0);
2665 }
2666
2667 /* Arithmetic */
2668 static void gen_arith(DisasContext *ctx, uint32_t opc,
2669 int rd, int rs, int rt)
2670 {
2671 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2672 && opc != OPC_DADD && opc != OPC_DSUB) {
2673 /* If no destination, treat it as a NOP.
2674 For add & sub, we must generate the overflow exception when needed. */
2675 return;
2676 }
2677
2678 switch (opc) {
2679 case OPC_ADD:
2680 {
2681 TCGv t0 = tcg_temp_local_new();
2682 TCGv t1 = tcg_temp_new();
2683 TCGv t2 = tcg_temp_new();
2684 TCGLabel *l1 = gen_new_label();
2685
2686 gen_load_gpr(t1, rs);
2687 gen_load_gpr(t2, rt);
2688 tcg_gen_add_tl(t0, t1, t2);
2689 tcg_gen_ext32s_tl(t0, t0);
2690 tcg_gen_xor_tl(t1, t1, t2);
2691 tcg_gen_xor_tl(t2, t0, t2);
2692 tcg_gen_andc_tl(t1, t2, t1);
2693 tcg_temp_free(t2);
2694 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2695 tcg_temp_free(t1);
2696 /* operands of same sign, result different sign */
2697 generate_exception(ctx, EXCP_OVERFLOW);
2698 gen_set_label(l1);
2699 gen_store_gpr(t0, rd);
2700 tcg_temp_free(t0);
2701 }
2702 break;
2703 case OPC_ADDU:
2704 if (rs != 0 && rt != 0) {
2705 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2706 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2707 } else if (rs == 0 && rt != 0) {
2708 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2709 } else if (rs != 0 && rt == 0) {
2710 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2711 } else {
2712 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2713 }
2714 break;
2715 case OPC_SUB:
2716 {
2717 TCGv t0 = tcg_temp_local_new();
2718 TCGv t1 = tcg_temp_new();
2719 TCGv t2 = tcg_temp_new();
2720 TCGLabel *l1 = gen_new_label();
2721
2722 gen_load_gpr(t1, rs);
2723 gen_load_gpr(t2, rt);
2724 tcg_gen_sub_tl(t0, t1, t2);
2725 tcg_gen_ext32s_tl(t0, t0);
2726 tcg_gen_xor_tl(t2, t1, t2);
2727 tcg_gen_xor_tl(t1, t0, t1);
2728 tcg_gen_and_tl(t1, t1, t2);
2729 tcg_temp_free(t2);
2730 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2731 tcg_temp_free(t1);
2732 /* operands of different sign, first operand and result different sign */
2733 generate_exception(ctx, EXCP_OVERFLOW);
2734 gen_set_label(l1);
2735 gen_store_gpr(t0, rd);
2736 tcg_temp_free(t0);
2737 }
2738 break;
2739 case OPC_SUBU:
2740 if (rs != 0 && rt != 0) {
2741 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2742 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2743 } else if (rs == 0 && rt != 0) {
2744 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2745 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2746 } else if (rs != 0 && rt == 0) {
2747 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2748 } else {
2749 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2750 }
2751 break;
2752 #if defined(TARGET_MIPS64)
2753 case OPC_DADD:
2754 {
2755 TCGv t0 = tcg_temp_local_new();
2756 TCGv t1 = tcg_temp_new();
2757 TCGv t2 = tcg_temp_new();
2758 TCGLabel *l1 = gen_new_label();
2759
2760 gen_load_gpr(t1, rs);
2761 gen_load_gpr(t2, rt);
2762 tcg_gen_add_tl(t0, t1, t2);
2763 tcg_gen_xor_tl(t1, t1, t2);
2764 tcg_gen_xor_tl(t2, t0, t2);
2765 tcg_gen_andc_tl(t1, t2, t1);
2766 tcg_temp_free(t2);
2767 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2768 tcg_temp_free(t1);
2769 /* operands of same sign, result different sign */
2770 generate_exception(ctx, EXCP_OVERFLOW);
2771 gen_set_label(l1);
2772 gen_store_gpr(t0, rd);
2773 tcg_temp_free(t0);
2774 }
2775 break;
2776 case OPC_DADDU:
2777 if (rs != 0 && rt != 0) {
2778 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2779 } else if (rs == 0 && rt != 0) {
2780 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2781 } else if (rs != 0 && rt == 0) {
2782 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2783 } else {
2784 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2785 }
2786 break;
2787 case OPC_DSUB:
2788 {
2789 TCGv t0 = tcg_temp_local_new();
2790 TCGv t1 = tcg_temp_new();
2791 TCGv t2 = tcg_temp_new();
2792 TCGLabel *l1 = gen_new_label();
2793
2794 gen_load_gpr(t1, rs);
2795 gen_load_gpr(t2, rt);
2796 tcg_gen_sub_tl(t0, t1, t2);
2797 tcg_gen_xor_tl(t2, t1, t2);
2798 tcg_gen_xor_tl(t1, t0, t1);
2799 tcg_gen_and_tl(t1, t1, t2);
2800 tcg_temp_free(t2);
2801 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2802 tcg_temp_free(t1);
2803 /* operands of different sign, first operand and result different sign */
2804 generate_exception(ctx, EXCP_OVERFLOW);
2805 gen_set_label(l1);
2806 gen_store_gpr(t0, rd);
2807 tcg_temp_free(t0);
2808 }
2809 break;
2810 case OPC_DSUBU:
2811 if (rs != 0 && rt != 0) {
2812 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2813 } else if (rs == 0 && rt != 0) {
2814 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2815 } else if (rs != 0 && rt == 0) {
2816 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2817 } else {
2818 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2819 }
2820 break;
2821 #endif
2822 case OPC_MUL:
2823 if (likely(rs != 0 && rt != 0)) {
2824 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2825 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2826 } else {
2827 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2828 }
2829 break;
2830 }
2831 }
2832
2833 /* Conditional move */
2834 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2835 int rd, int rs, int rt)
2836 {
2837 TCGv t0, t1, t2;
2838
2839 if (rd == 0) {
2840 /* If no destination, treat it as a NOP. */
2841 return;
2842 }
2843
2844 t0 = tcg_temp_new();
2845 gen_load_gpr(t0, rt);
2846 t1 = tcg_const_tl(0);
2847 t2 = tcg_temp_new();
2848 gen_load_gpr(t2, rs);
2849 switch (opc) {
2850 case OPC_MOVN:
2851 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2852 break;
2853 case OPC_MOVZ:
2854 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2855 break;
2856 case OPC_SELNEZ:
2857 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2858 break;
2859 case OPC_SELEQZ:
2860 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2861 break;
2862 }
2863 tcg_temp_free(t2);
2864 tcg_temp_free(t1);
2865 tcg_temp_free(t0);
2866 }
2867
2868 /* Logic */
2869 static void gen_logic(DisasContext *ctx, uint32_t opc,
2870 int rd, int rs, int rt)
2871 {
2872 if (rd == 0) {
2873 /* If no destination, treat it as a NOP. */
2874 return;
2875 }
2876
2877 switch (opc) {
2878 case OPC_AND:
2879 if (likely(rs != 0 && rt != 0)) {
2880 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2881 } else {
2882 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2883 }
2884 break;
2885 case OPC_NOR:
2886 if (rs != 0 && rt != 0) {
2887 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2888 } else if (rs == 0 && rt != 0) {
2889 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2890 } else if (rs != 0 && rt == 0) {
2891 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2892 } else {
2893 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2894 }
2895 break;
2896 case OPC_OR:
2897 if (likely(rs != 0 && rt != 0)) {
2898 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2899 } else if (rs == 0 && rt != 0) {
2900 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2901 } else if (rs != 0 && rt == 0) {
2902 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2903 } else {
2904 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2905 }
2906 break;
2907 case OPC_XOR:
2908 if (likely(rs != 0 && rt != 0)) {
2909 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2910 } else if (rs == 0 && rt != 0) {
2911 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2912 } else if (rs != 0 && rt == 0) {
2913 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2914 } else {
2915 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2916 }
2917 break;
2918 }
2919 }
2920
2921 /* Set on lower than */
2922 static void gen_slt(DisasContext *ctx, uint32_t opc,
2923 int rd, int rs, int rt)
2924 {
2925 TCGv t0, t1;
2926
2927 if (rd == 0) {
2928 /* If no destination, treat it as a NOP. */
2929 return;
2930 }
2931
2932 t0 = tcg_temp_new();
2933 t1 = tcg_temp_new();
2934 gen_load_gpr(t0, rs);
2935 gen_load_gpr(t1, rt);
2936 switch (opc) {
2937 case OPC_SLT:
2938 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2939 break;
2940 case OPC_SLTU:
2941 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2942 break;
2943 }
2944 tcg_temp_free(t0);
2945 tcg_temp_free(t1);
2946 }
2947
2948 /* Shifts */
2949 static void gen_shift(DisasContext *ctx, uint32_t opc,
2950 int rd, int rs, int rt)
2951 {
2952 TCGv t0, t1;
2953
2954 if (rd == 0) {
2955 /* If no destination, treat it as a NOP.
2956 For add & sub, we must generate the overflow exception when needed. */
2957 return;
2958 }
2959
2960 t0 = tcg_temp_new();
2961 t1 = tcg_temp_new();
2962 gen_load_gpr(t0, rs);
2963 gen_load_gpr(t1, rt);
2964 switch (opc) {
2965 case OPC_SLLV:
2966 tcg_gen_andi_tl(t0, t0, 0x1f);
2967 tcg_gen_shl_tl(t0, t1, t0);
2968 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2969 break;
2970 case OPC_SRAV:
2971 tcg_gen_andi_tl(t0, t0, 0x1f);
2972 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2973 break;
2974 case OPC_SRLV:
2975 tcg_gen_ext32u_tl(t1, t1);
2976 tcg_gen_andi_tl(t0, t0, 0x1f);
2977 tcg_gen_shr_tl(t0, t1, t0);
2978 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2979 break;
2980 case OPC_ROTRV:
2981 {
2982 TCGv_i32 t2 = tcg_temp_new_i32();
2983 TCGv_i32 t3 = tcg_temp_new_i32();
2984
2985 tcg_gen_trunc_tl_i32(t2, t0);
2986 tcg_gen_trunc_tl_i32(t3, t1);
2987 tcg_gen_andi_i32(t2, t2, 0x1f);
2988 tcg_gen_rotr_i32(t2, t3, t2);
2989 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2990 tcg_temp_free_i32(t2);
2991 tcg_temp_free_i32(t3);
2992 }
2993 break;
2994 #if defined(TARGET_MIPS64)
2995 case OPC_DSLLV:
2996 tcg_gen_andi_tl(t0, t0, 0x3f);
2997 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2998 break;
2999 case OPC_DSRAV:
3000 tcg_gen_andi_tl(t0, t0, 0x3f);
3001 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3002 break;
3003 case OPC_DSRLV:
3004 tcg_gen_andi_tl(t0, t0, 0x3f);
3005 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3006 break;
3007 case OPC_DROTRV:
3008 tcg_gen_andi_tl(t0, t0, 0x3f);
3009 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3010 break;
3011 #endif
3012 }
3013 tcg_temp_free(t0);
3014 tcg_temp_free(t1);
3015 }
3016
3017 /* Arithmetic on HI/LO registers */
3018 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3019 {
3020 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3021 /* Treat as NOP. */
3022 return;
3023 }
3024
3025 if (acc != 0) {
3026 check_dsp(ctx);
3027 }
3028
3029 switch (opc) {
3030 case OPC_MFHI:
3031 #if defined(TARGET_MIPS64)
3032 if (acc != 0) {
3033 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3034 } else
3035 #endif
3036 {
3037 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3038 }
3039 break;
3040 case OPC_MFLO:
3041 #if defined(TARGET_MIPS64)
3042 if (acc != 0) {
3043 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3044 } else
3045 #endif
3046 {
3047 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3048 }
3049 break;
3050 case OPC_MTHI:
3051 if (reg != 0) {
3052 #if defined(TARGET_MIPS64)
3053 if (acc != 0) {
3054 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3055 } else
3056 #endif
3057 {
3058 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3059 }
3060 } else {
3061 tcg_gen_movi_tl(cpu_HI[acc], 0);
3062 }
3063 break;
3064 case OPC_MTLO:
3065 if (reg != 0) {
3066 #if defined(TARGET_MIPS64)
3067 if (acc != 0) {
3068 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3069 } else
3070 #endif
3071 {
3072 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3073 }
3074 } else {
3075 tcg_gen_movi_tl(cpu_LO[acc], 0);
3076 }
3077 break;
3078 }
3079 }
3080
3081 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3082 TCGMemOp memop)
3083 {
3084 TCGv t0 = tcg_const_tl(addr);
3085 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3086 gen_store_gpr(t0, reg);
3087 tcg_temp_free(t0);
3088 }
3089
3090 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3091 int rs)
3092 {
3093 target_long offset;
3094 target_long addr;
3095
3096 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3097 case OPC_ADDIUPC:
3098 if (rs != 0) {
3099 offset = sextract32(ctx->opcode << 2, 0, 21);
3100 addr = addr_add(ctx, pc, offset);
3101 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3102 }
3103 break;
3104 case R6_OPC_LWPC:
3105 offset = sextract32(ctx->opcode << 2, 0, 21);
3106 addr = addr_add(ctx, pc, offset);
3107 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3108 break;
3109 #if defined(TARGET_MIPS64)
3110 case OPC_LWUPC:
3111 check_mips_64(ctx);
3112 offset = sextract32(ctx->opcode << 2, 0, 21);
3113 addr = addr_add(ctx, pc, offset);
3114 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3115 break;
3116 #endif
3117 default:
3118 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3119 case OPC_AUIPC:
3120 if (rs != 0) {
3121 offset = sextract32(ctx->opcode, 0, 16) << 16;
3122 addr = addr_add(ctx, pc, offset);
3123 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3124 }
3125 break;
3126 case OPC_ALUIPC:
3127 if (rs != 0) {
3128 offset = sextract32(ctx->opcode, 0, 16) << 16;
3129 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3130 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3131 }
3132 break;
3133 #if defined(TARGET_MIPS64)
3134 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3135 case R6_OPC_LDPC + (1 << 16):
3136 case R6_OPC_LDPC + (2 << 16):
3137 case R6_OPC_LDPC + (3 << 16):
3138 check_mips_64(ctx);
3139 offset = sextract32(ctx->opcode << 3, 0, 21);
3140 addr = addr_add(ctx, (pc & ~0x7), offset);
3141 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3142 break;
3143 #endif
3144 default:
3145 MIPS_INVAL("OPC_PCREL");
3146 generate_exception_end(ctx, EXCP_RI);
3147 break;
3148 }
3149 break;
3150 }
3151 }
3152
3153 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3154 {
3155 TCGv t0, t1;
3156
3157 if (rd == 0) {
3158 /* Treat as NOP. */
3159 return;
3160 }
3161
3162 t0 = tcg_temp_new();
3163 t1 = tcg_temp_new();
3164
3165 gen_load_gpr(t0, rs);
3166 gen_load_gpr(t1, rt);
3167
3168 switch (opc) {
3169 case R6_OPC_DIV:
3170 {
3171 TCGv t2 = tcg_temp_new();
3172 TCGv t3 = tcg_temp_new();
3173 tcg_gen_ext32s_tl(t0, t0);
3174 tcg_gen_ext32s_tl(t1, t1);
3175 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3176 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3177 tcg_gen_and_tl(t2, t2, t3);
3178 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3179 tcg_gen_or_tl(t2, t2, t3);
3180 tcg_gen_movi_tl(t3, 0);
3181 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3182 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3183 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3184 tcg_temp_free(t3);
3185 tcg_temp_free(t2);
3186 }
3187 break;
3188 case R6_OPC_MOD:
3189 {
3190 TCGv t2 = tcg_temp_new();
3191 TCGv t3 = tcg_temp_new();
3192 tcg_gen_ext32s_tl(t0, t0);
3193 tcg_gen_ext32s_tl(t1, t1);
3194 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3195 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3196 tcg_gen_and_tl(t2, t2, t3);
3197 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3198 tcg_gen_or_tl(t2, t2, t3);
3199 tcg_gen_movi_tl(t3, 0);
3200 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3201 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3202 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3203 tcg_temp_free(t3);
3204 tcg_temp_free(t2);
3205 }
3206 break;
3207 case R6_OPC_DIVU:
3208 {
3209 TCGv t2 = tcg_const_tl(0);
3210 TCGv t3 = tcg_const_tl(1);
3211 tcg_gen_ext32u_tl(t0, t0);
3212 tcg_gen_ext32u_tl(t1, t1);
3213 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3214 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3215 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3216 tcg_temp_free(t3);
3217 tcg_temp_free(t2);
3218 }
3219 break;
3220 case R6_OPC_MODU:
3221 {
3222 TCGv t2 = tcg_const_tl(0);
3223 TCGv t3 = tcg_const_tl(1);
3224 tcg_gen_ext32u_tl(t0, t0);
3225 tcg_gen_ext32u_tl(t1, t1);
3226 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3227 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3228 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3229 tcg_temp_free(t3);
3230 tcg_temp_free(t2);
3231 }
3232 break;
3233 case R6_OPC_MUL:
3234 {
3235 TCGv_i32 t2 = tcg_temp_new_i32();
3236 TCGv_i32 t3 = tcg_temp_new_i32();
3237 tcg_gen_trunc_tl_i32(t2, t0);
3238 tcg_gen_trunc_tl_i32(t3, t1);
3239 tcg_gen_mul_i32(t2, t2, t3);
3240 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3241 tcg_temp_free_i32(t2);
3242 tcg_temp_free_i32(t3);
3243 }
3244 break;
3245 case R6_OPC_MUH:
3246 {
3247 TCGv_i32 t2 = tcg_temp_new_i32();
3248 TCGv_i32 t3 = tcg_temp_new_i32();
3249 tcg_gen_trunc_tl_i32(t2, t0);
3250 tcg_gen_trunc_tl_i32(t3, t1);
3251 tcg_gen_muls2_i32(t2, t3, t2, t3);
3252 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3253 tcg_temp_free_i32(t2);
3254 tcg_temp_free_i32(t3);
3255 }
3256 break;
3257 case R6_OPC_MULU:
3258 {
3259 TCGv_i32 t2 = tcg_temp_new_i32();
3260 TCGv_i32 t3 = tcg_temp_new_i32();
3261 tcg_gen_trunc_tl_i32(t2, t0);
3262 tcg_gen_trunc_tl_i32(t3, t1);
3263 tcg_gen_mul_i32(t2, t2, t3);
3264 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3265 tcg_temp_free_i32(t2);
3266 tcg_temp_free_i32(t3);
3267 }
3268 break;
3269 case R6_OPC_MUHU:
3270 {
3271 TCGv_i32 t2 = tcg_temp_new_i32();
3272 TCGv_i32 t3 = tcg_temp_new_i32();
3273 tcg_gen_trunc_tl_i32(t2, t0);
3274 tcg_gen_trunc_tl_i32(t3, t1);
3275 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3276 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3277 tcg_temp_free_i32(t2);
3278 tcg_temp_free_i32(t3);
3279 }
3280 break;
3281 #if defined(TARGET_MIPS64)
3282 case R6_OPC_DDIV:
3283 {
3284 TCGv t2 = tcg_temp_new();
3285 TCGv t3 = tcg_temp_new();
3286 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3287 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3288 tcg_gen_and_tl(t2, t2, t3);
3289 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3290 tcg_gen_or_tl(t2, t2, t3);
3291 tcg_gen_movi_tl(t3, 0);
3292 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3293 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3294 tcg_temp_free(t3);
3295 tcg_temp_free(t2);
3296 }
3297 break;
3298 case R6_OPC_DMOD:
3299 {
3300 TCGv t2 = tcg_temp_new();
3301 TCGv t3 = tcg_temp_new();
3302 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3303 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3304 tcg_gen_and_tl(t2, t2, t3);
3305 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3306 tcg_gen_or_tl(t2, t2, t3);
3307 tcg_gen_movi_tl(t3, 0);
3308 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3309 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3310 tcg_temp_free(t3);
3311 tcg_temp_free(t2);
3312 }
3313 break;
3314 case R6_OPC_DDIVU:
3315 {
3316 TCGv t2 = tcg_const_tl(0);
3317 TCGv t3 = tcg_const_tl(1);
3318 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3319 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3320 tcg_temp_free(t3);
3321 tcg_temp_free(t2);
3322 }
3323 break;
3324 case R6_OPC_DMODU:
3325 {
3326 TCGv t2 = tcg_const_tl(0);
3327 TCGv t3 = tcg_const_tl(1);
3328 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3329 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3330 tcg_temp_free(t3);
3331 tcg_temp_free(t2);
3332 }
3333 break;
3334 case R6_OPC_DMUL:
3335 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3336 break;
3337 case R6_OPC_DMUH:
3338 {
3339 TCGv t2 = tcg_temp_new();
3340 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3341 tcg_temp_free(t2);
3342 }
3343 break;
3344 case R6_OPC_DMULU:
3345 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3346 break;
3347 case R6_OPC_DMUHU:
3348 {
3349 TCGv t2 = tcg_temp_new();
3350 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3351 tcg_temp_free(t2);
3352 }
3353 break;
3354 #endif
3355 default:
3356 MIPS_INVAL("r6 mul/div");
3357 generate_exception_end(ctx, EXCP_RI);
3358 goto out;
3359 }
3360 out:
3361 tcg_temp_free(t0);
3362 tcg_temp_free(t1);
3363 }
3364
3365 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3366 int acc, int rs, int rt)
3367 {
3368 TCGv t0, t1;
3369
3370 t0 = tcg_temp_new();
3371 t1 = tcg_temp_new();
3372
3373 gen_load_gpr(t0, rs);
3374 gen_load_gpr(t1, rt);
3375
3376 if (acc != 0) {
3377 check_dsp(ctx);
3378 }
3379
3380 switch (opc) {
3381 case OPC_DIV:
3382 {
3383 TCGv t2 = tcg_temp_new();
3384 TCGv t3 = tcg_temp_new();
3385 tcg_gen_ext32s_tl(t0, t0);
3386 tcg_gen_ext32s_tl(t1, t1);
3387 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3388 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3389 tcg_gen_and_tl(t2, t2, t3);
3390 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3391 tcg_gen_or_tl(t2, t2, t3);
3392 tcg_gen_movi_tl(t3, 0);
3393 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3394 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3395 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3396 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3397 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3398 tcg_temp_free(t3);
3399 tcg_temp_free(t2);
3400 }
3401 break;
3402 case OPC_DIVU:
3403 {
3404 TCGv t2 = tcg_const_tl(0);
3405 TCGv t3 = tcg_const_tl(1);
3406 tcg_gen_ext32u_tl(t0, t0);
3407 tcg_gen_ext32u_tl(t1, t1);
3408 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3409 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3410 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3411 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3412 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3413 tcg_temp_free(t3);
3414 tcg_temp_free(t2);
3415 }
3416 break;
3417 case OPC_MULT:
3418 {
3419 TCGv_i32 t2 = tcg_temp_new_i32();
3420 TCGv_i32 t3 = tcg_temp_new_i32();
3421 tcg_gen_trunc_tl_i32(t2, t0);
3422 tcg_gen_trunc_tl_i32(t3, t1);
3423 tcg_gen_muls2_i32(t2, t3, t2, t3);
3424 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3425 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3426 tcg_temp_free_i32(t2);
3427 tcg_temp_free_i32(t3);
3428 }
3429 break;
3430 case OPC_MULTU:
3431 {
3432 TCGv_i32 t2 = tcg_temp_new_i32();
3433 TCGv_i32 t3 = tcg_temp_new_i32();
3434 tcg_gen_trunc_tl_i32(t2, t0);
3435 tcg_gen_trunc_tl_i32(t3, t1);
3436 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3437 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3438 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3439 tcg_temp_free_i32(t2);
3440 tcg_temp_free_i32(t3);
3441 }
3442 break;
3443 #if defined(TARGET_MIPS64)
3444 case OPC_DDIV:
3445 {
3446 TCGv t2 = tcg_temp_new();
3447 TCGv t3 = tcg_temp_new();
3448 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3449 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3450 tcg_gen_and_tl(t2, t2, t3);
3451 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3452 tcg_gen_or_tl(t2, t2, t3);
3453 tcg_gen_movi_tl(t3, 0);
3454 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3455 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3456 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3457 tcg_temp_free(t3);
3458 tcg_temp_free(t2);
3459 }
3460 break;
3461 case OPC_DDIVU:
3462 {
3463 TCGv t2 = tcg_const_tl(0);
3464 TCGv t3 = tcg_const_tl(1);
3465 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3466 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3467 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3468 tcg_temp_free(t3);
3469 tcg_temp_free(t2);
3470 }
3471 break;
3472 case OPC_DMULT:
3473 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3474 break;
3475 case OPC_DMULTU:
3476 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3477 break;
3478 #endif
3479 case OPC_MADD:
3480 {
3481 TCGv_i64 t2 = tcg_temp_new_i64();
3482 TCGv_i64 t3 = tcg_temp_new_i64();
3483
3484 tcg_gen_ext_tl_i64(t2, t0);
3485 tcg_gen_ext_tl_i64(t3, t1);
3486 tcg_gen_mul_i64(t2, t2, t3);
3487 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3488 tcg_gen_add_i64(t2, t2, t3);
3489 tcg_temp_free_i64(t3);
3490 gen_move_low32(cpu_LO[acc], t2);
3491 gen_move_high32(cpu_HI[acc], t2);
3492 tcg_temp_free_i64(t2);
3493 }
3494 break;
3495 case OPC_MADDU:
3496 {
3497 TCGv_i64 t2 = tcg_temp_new_i64();
3498 TCGv_i64 t3 = tcg_temp_new_i64();
3499
3500 tcg_gen_ext32u_tl(t0, t0);
3501 tcg_gen_ext32u_tl(t1, t1);
3502 tcg_gen_extu_tl_i64(t2, t0);
3503 tcg_gen_extu_tl_i64(t3, t1);
3504 tcg_gen_mul_i64(t2, t2, t3);
3505 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3506 tcg_gen_add_i64(t2, t2, t3);
3507 tcg_temp_free_i64(t3);
3508 gen_move_low32(cpu_LO[acc], t2);
3509 gen_move_high32(cpu_HI[acc], t2);
3510 tcg_temp_free_i64(t2);
3511 }
3512 break;
3513 case OPC_MSUB:
3514 {
3515 TCGv_i64 t2 = tcg_temp_new_i64();
3516 TCGv_i64 t3 = tcg_temp_new_i64();
3517
3518 tcg_gen_ext_tl_i64(t2, t0);
3519 tcg_gen_ext_tl_i64(t3, t1);
3520 tcg_gen_mul_i64(t2, t2, t3);
3521 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3522 tcg_gen_sub_i64(t2, t3, t2);
3523 tcg_temp_free_i64(t3);
3524 gen_move_low32(cpu_LO[acc], t2);
3525 gen_move_high32(cpu_HI[acc], t2);
3526 tcg_temp_free_i64(t2);
3527 }
3528 break;
3529 case OPC_MSUBU:
3530 {
3531 TCGv_i64 t2 = tcg_temp_new_i64();
3532 TCGv_i64 t3 = tcg_temp_new_i64();
3533
3534 tcg_gen_ext32u_tl(t0, t0);
3535 tcg_gen_ext32u_tl(t1, t1);
3536 tcg_gen_extu_tl_i64(t2, t0);
3537 tcg_gen_extu_tl_i64(t3, t1);
3538 tcg_gen_mul_i64(t2, t2, t3);
3539 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3540 tcg_gen_sub_i64(t2, t3, t2);
3541 tcg_temp_free_i64(t3);
3542 gen_move_low32(cpu_LO[acc], t2);
3543 gen_move_high32(cpu_HI[acc], t2);
3544 tcg_temp_free_i64(t2);
3545 }
3546 break;
3547 default:
3548 MIPS_INVAL("mul/div");
3549 generate_exception_end(ctx, EXCP_RI);
3550 goto out;
3551 }
3552 out:
3553 tcg_temp_free(t0);
3554 tcg_temp_free(t1);
3555 }
3556
3557 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3558 int rd, int rs, int rt)
3559 {
3560 TCGv t0 = tcg_temp_new();
3561 TCGv t1 = tcg_temp_new();
3562
3563 gen_load_gpr(t0, rs);
3564 gen_load_gpr(t1, rt);
3565
3566 switch (opc) {
3567 case OPC_VR54XX_MULS:
3568 gen_helper_muls(t0, cpu_env, t0, t1);
3569 break;
3570 case OPC_VR54XX_MULSU:
3571 gen_helper_mulsu(t0, cpu_env, t0, t1);
3572 break;
3573 case OPC_VR54XX_MACC:
3574 gen_helper_macc(t0, cpu_env, t0, t1);
3575 break;
3576 case OPC_VR54XX_MACCU:
3577 gen_helper_maccu(t0, cpu_env, t0, t1);
3578 break;
3579 case OPC_VR54XX_MSAC:
3580 gen_helper_msac(t0, cpu_env, t0, t1);
3581 break;
3582 case OPC_VR54XX_MSACU:
3583 gen_helper_msacu(t0, cpu_env, t0, t1);
3584 break;
3585 case OPC_VR54XX_MULHI:
3586 gen_helper_mulhi(t0, cpu_env, t0, t1);
3587 break;
3588 case OPC_VR54XX_MULHIU:
3589 gen_helper_mulhiu(t0, cpu_env, t0, t1);
3590 break;
3591 case OPC_VR54XX_MULSHI:
3592 gen_helper_mulshi(t0, cpu_env, t0, t1);
3593 break;
3594 case OPC_VR54XX_MULSHIU:
3595 gen_helper_mulshiu(t0, cpu_env, t0, t1);
3596 break;
3597 case OPC_VR54XX_MACCHI:
3598 gen_helper_macchi(t0, cpu_env, t0, t1);
3599 break;
3600 case OPC_VR54XX_MACCHIU:
3601 gen_helper_macchiu(t0, cpu_env, t0, t1);
3602 break;
3603 case OPC_VR54XX_MSACHI:
3604 gen_helper_msachi(t0, cpu_env, t0, t1);
3605 break;
3606 case OPC_VR54XX_MSACHIU:
3607 gen_helper_msachiu(t0, cpu_env, t0, t1);
3608 break;
3609 default:
3610 MIPS_INVAL("mul vr54xx");
3611 generate_exception_end(ctx, EXCP_RI);
3612 goto out;
3613 }
3614 gen_store_gpr(t0, rd);
3615
3616 out:
3617 tcg_temp_free(t0);
3618 tcg_temp_free(t1);
3619 }
3620
3621 static void gen_cl (DisasContext *ctx, uint32_t opc,
3622 int rd, int rs)
3623 {
3624 TCGv t0;
3625
3626 if (rd == 0) {
3627 /* Treat as NOP. */
3628 return;
3629 }
3630 t0 = cpu_gpr[rd];
3631 gen_load_gpr(t0, rs);
3632
3633 switch (opc) {
3634 case OPC_CLO:
3635 case R6_OPC_CLO:
3636 #if defined(TARGET_MIPS64)
3637 case OPC_DCLO:
3638 case R6_OPC_DCLO:
3639 #endif
3640 tcg_gen_not_tl(t0, t0);
3641 break;
3642 }
3643
3644 switch (opc) {
3645 case OPC_CLO:
3646 case R6_OPC_CLO:
3647 case OPC_CLZ:
3648 case R6_OPC_CLZ:
3649 tcg_gen_ext32u_tl(t0, t0);
3650 tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3651 tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3652 break;
3653 #if defined(TARGET_MIPS64)
3654 case OPC_DCLO:
3655 case R6_OPC_DCLO:
3656 case OPC_DCLZ:
3657 case R6_OPC_DCLZ:
3658 tcg_gen_clzi_i64(t0, t0, 64);
3659 break;
3660 #endif
3661 }
3662 }
3663
3664 /* Godson integer instructions */
3665 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3666 int rd, int rs, int rt)
3667 {
3668 TCGv t0, t1;
3669
3670 if (rd == 0) {
3671 /* Treat as NOP. */
3672 return;
3673 }
3674
3675 switch (opc) {
3676 case OPC_MULT_G_2E:
3677 case OPC_MULT_G_2F:
3678 case OPC_MULTU_G_2E:
3679 case OPC_MULTU_G_2F:
3680 #if defined(TARGET_MIPS64)
3681 case OPC_DMULT_G_2E:
3682 case OPC_DMULT_G_2F:
3683 case OPC_DMULTU_G_2E:
3684 case OPC_DMULTU_G_2F:
3685 #endif
3686 t0 = tcg_temp_new();
3687 t1 = tcg_temp_new();
3688 break;
3689 default:
3690 t0 = tcg_temp_local_new();
3691 t1 = tcg_temp_local_new();
3692 break;
3693 }
3694
3695 gen_load_gpr(t0, rs);
3696 gen_load_gpr(t1, rt);
3697
3698 switch (opc) {
3699 case OPC_MULT_G_2E:
3700 case OPC_MULT_G_2F:
3701 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3702 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3703 break;
3704 case OPC_MULTU_G_2E:
3705 case OPC_MULTU_G_2F:
3706 tcg_gen_ext32u_tl(t0, t0);
3707 tcg_gen_ext32u_tl(t1, t1);
3708 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3709 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3710 break;
3711 case OPC_DIV_G_2E:
3712 case OPC_DIV_G_2F:
3713 {
3714 TCGLabel *l1 = gen_new_label();
3715 TCGLabel *l2 = gen_new_label();
3716 TCGLabel *l3 = gen_new_label();
3717 tcg_gen_ext32s_tl(t0, t0);
3718 tcg_gen_ext32s_tl(t1, t1);
3719 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3720 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3721 tcg_gen_br(l3);
3722 gen_set_label(l1);
3723 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3724 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3725 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3726 tcg_gen_br(l3);
3727 gen_set_label(l2);
3728 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3729 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3730 gen_set_label(l3);
3731 }
3732 break;
3733 case OPC_DIVU_G_2E:
3734 case OPC_DIVU_G_2F:
3735 {
3736 TCGLabel *l1 = gen_new_label();
3737 TCGLabel *l2 = gen_new_label();
3738 tcg_gen_ext32u_tl(t0, t0);
3739 tcg_gen_ext32u_tl(t1, t1);
3740 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3741 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3742 tcg_gen_br(l2);
3743 gen_set_label(l1);
3744 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3745 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3746 gen_set_label(l2);
3747 }
3748 break;
3749 case OPC_MOD_G_2E:
3750 case OPC_MOD_G_2F:
3751 {
3752 TCGLabel *l1 = gen_new_label();
3753 TCGLabel *l2 = gen_new_label();
3754 TCGLabel *l3 = gen_new_label();
3755 tcg_gen_ext32u_tl(t0, t0);
3756 tcg_gen_ext32u_tl(t1, t1);
3757 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3758 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3759 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3760 gen_set_label(l1);
3761 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3762 tcg_gen_br(l3);
3763 gen_set_label(l2);
3764 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3765 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3766 gen_set_label(l3);
3767 }
3768 break;
3769 case OPC_MODU_G_2E:
3770 case OPC_MODU_G_2F:
3771 {
3772 TCGLabel *l1 = gen_new_label();
3773 TCGLabel *l2 = gen_new_label();
3774 tcg_gen_ext32u_tl(t0, t0);
3775 tcg_gen_ext32u_tl(t1, t1);
3776 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3777 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3778 tcg_gen_br(l2);
3779 gen_set_label(l1);
3780 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3781 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3782 gen_set_label(l2);
3783 }
3784 break;
3785 #if defined(TARGET_MIPS64)
3786 case OPC_DMULT_G_2E:
3787 case OPC_DMULT_G_2F:
3788 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3789 break;
3790 case OPC_DMULTU_G_2E:
3791 case OPC_DMULTU_G_2F:
3792 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3793 break;
3794 case OPC_DDIV_G_2E:
3795 case OPC_DDIV_G_2F:
3796 {
3797 TCGLabel *l1 = gen_new_label();
3798 TCGLabel *l2 = gen_new_label();
3799 TCGLabel *l3 = gen_new_label();
3800 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3801 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3802 tcg_gen_br(l3);
3803 gen_set_label(l1);
3804 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3805 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3806 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3807 tcg_gen_br(l3);
3808 gen_set_label(l2);
3809 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3810 gen_set_label(l3);
3811 }
3812 break;
3813 case OPC_DDIVU_G_2E:
3814 case OPC_DDIVU_G_2F:
3815 {
3816 TCGLabel *l1 = gen_new_label();
3817 TCGLabel *l2 = gen_new_label();
3818 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3819 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3820 tcg_gen_br(l2);
3821 gen_set_label(l1);
3822 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3823 gen_set_label(l2);
3824 }
3825 break;
3826 case OPC_DMOD_G_2E:
3827 case OPC_DMOD_G_2F:
3828 {
3829 TCGLabel *l1 = gen_new_label();
3830 TCGLabel *l2 = gen_new_label();
3831 TCGLabel *l3 = gen_new_label();
3832 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3833 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3834 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3835 gen_set_label(l1);
3836 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3837 tcg_gen_br(l3);
3838 gen_set_label(l2);
3839 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3840 gen_set_label(l3);
3841 }
3842 break;
3843 case OPC_DMODU_G_2E:
3844 case OPC_DMODU_G_2F:
3845 {
3846 TCGLabel *l1 = gen_new_label();
3847 TCGLabel *l2 = gen_new_label();
3848 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3849 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3850 tcg_gen_br(l2);
3851 gen_set_label(l1);
3852 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3853 gen_set_label(l2);
3854 }
3855 break;
3856 #endif
3857 }
3858
3859 tcg_temp_free(t0);
3860 tcg_temp_free(t1);
3861 }
3862
3863 /* Loongson multimedia instructions */
3864 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3865 {
3866 uint32_t opc, shift_max;
3867 TCGv_i64 t0, t1;
3868
3869 opc = MASK_LMI(ctx->opcode);
3870 switch (opc) {
3871 case OPC_ADD_CP2:
3872 case OPC_SUB_CP2:
3873 case OPC_DADD_CP2:
3874 case OPC_DSUB_CP2:
3875 t0 = tcg_temp_local_new_i64();
3876 t1 = tcg_temp_local_new_i64();
3877 break;
3878 default:
3879 t0 = tcg_temp_new_i64();
3880 t1 = tcg_temp_new_i64();
3881 break;
3882 }
3883
3884 check_cp1_enabled(ctx);
3885 gen_load_fpr64(ctx, t0, rs);
3886 gen_load_fpr64(ctx, t1, rt);
3887
3888 #define LMI_HELPER(UP, LO) \
3889 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3890 #define LMI_HELPER_1(UP, LO) \
3891 case OPC_##UP: gen_helper_##LO(t0, t0); break
3892 #define LMI_DIRECT(UP, LO, OP) \
3893 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3894
3895 switch (opc) {
3896 LMI_HELPER(PADDSH, paddsh);
3897 LMI_HELPER(PADDUSH, paddush);
3898 LMI_HELPER(PADDH, paddh);
3899 LMI_HELPER(PADDW, paddw);
3900 LMI_HELPER(PADDSB, paddsb);
3901 LMI_HELPER(PADDUSB, paddusb);
3902 LMI_HELPER(PADDB, paddb);
3903
3904 LMI_HELPER(PSUBSH, psubsh);
3905 LMI_HELPER(PSUBUSH, psubush);
3906 LMI_HELPER(PSUBH, psubh);
3907 LMI_HELPER(PSUBW, psubw);
3908 LMI_HELPER(PSUBSB, psubsb);
3909 LMI_HELPER(PSUBUSB, psubusb);
3910 LMI_HELPER(PSUBB, psubb);
3911
3912 LMI_HELPER(PSHUFH, pshufh);
3913 LMI_HELPER(PACKSSWH, packsswh);
3914 LMI_HELPER(PACKSSHB, packsshb);
3915 LMI_HELPER(PACKUSHB, packushb);
3916
3917 LMI_HELPER(PUNPCKLHW, punpcklhw);
3918 LMI_HELPER(PUNPCKHHW, punpckhhw);
3919 LMI_HELPER(PUNPCKLBH, punpcklbh);
3920 LMI_HELPER(PUNPCKHBH, punpckhbh);
3921 LMI_HELPER(PUNPCKLWD, punpcklwd);
3922 LMI_HELPER(PUNPCKHWD, punpckhwd);
3923
3924 LMI_HELPER(PAVGH, pavgh);
3925 LMI_HELPER(PAVGB, pavgb);
3926 LMI_HELPER(PMAXSH, pmaxsh);
3927 LMI_HELPER(PMINSH, pminsh);
3928 LMI_HELPER(PMAXUB, pmaxub);
3929 LMI_HELPER(PMINUB, pminub);
3930
3931 LMI_HELPER(PCMPEQW, pcmpeqw);
3932 LMI_HELPER(PCMPGTW, pcmpgtw);
3933 LMI_HELPER(PCMPEQH, pcmpeqh);
3934 LMI_HELPER(PCMPGTH, pcmpgth);
3935 LMI_HELPER(PCMPEQB, pcmpeqb);
3936 LMI_HELPER(PCMPGTB, pcmpgtb);
3937
3938 LMI_HELPER(PSLLW, psllw);
3939 LMI_HELPER(PSLLH, psllh);
3940 LMI_HELPER(PSRLW, psrlw);
3941 LMI_HELPER(PSRLH, psrlh);
3942 LMI_HELPER(PSRAW, psraw);
3943 LMI_HELPER(PSRAH, psrah);
3944
3945 LMI_HELPER(PMULLH, pmullh);
3946 LMI_HELPER(PMULHH, pmulhh);
3947 LMI_HELPER(PMULHUH, pmulhuh);
3948 LMI_HELPER(PMADDHW, pmaddhw);
3949
3950 LMI_HELPER(PASUBUB, pasubub);
3951 LMI_HELPER_1(BIADD, biadd);
3952 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3953
3954 LMI_DIRECT(PADDD, paddd, add);
3955 LMI_DIRECT(PSUBD, psubd, sub);
3956 LMI_DIRECT(XOR_CP2, xor, xor);
3957 LMI_DIRECT(NOR_CP2, nor, nor);
3958 LMI_DIRECT(AND_CP2, and, and);
3959 LMI_DIRECT(OR_CP2, or, or);
3960
3961 case OPC_PANDN:
3962 tcg_gen_andc_i64(t0, t1, t0);
3963 break;
3964
3965 case OPC_PINSRH_0:
3966 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3967 break;
3968 case OPC_PINSRH_1:
3969 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3970 break;
3971 case OPC_PINSRH_2:
3972 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3973 break;
3974 case OPC_PINSRH_3:
3975 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3976 break;
3977
3978 case OPC_PEXTRH:
3979 tcg_gen_andi_i64(t1, t1, 3);
3980 tcg_gen_shli_i64(t1, t1, 4);
3981 tcg_gen_shr_i64(t0, t0, t1);
3982 tcg_gen_ext16u_i64(t0, t0);
3983 break;
3984
3985 case OPC_ADDU_CP2:
3986 tcg_gen_add_i64(t0, t0, t1);
3987 tcg_gen_ext32s_i64(t0, t0);
3988 break;
3989 case OPC_SUBU_CP2:
3990 tcg_gen_sub_i64(t0, t0, t1);
3991 tcg_gen_ext32s_i64(t0, t0);
3992 break;
3993
3994 case OPC_SLL_CP2:
3995 shift_max = 32;
3996 goto do_shift;
3997 case OPC_SRL_CP2:
3998 shift_max = 32;
3999 goto do_shift;
4000 case OPC_SRA_CP2:
4001 shift_max = 32;
4002 goto do_shift;
4003 case OPC_DSLL_CP2:
4004 shift_max = 64;
4005 goto do_shift;
4006 case OPC_DSRL_CP2:
4007 shift_max = 64;
4008 goto do_shift;
4009 case OPC_DSRA_CP2:
4010 shift_max = 64;
4011 goto do_shift;
4012 do_shift:
4013 /* Make sure shift count isn't TCG undefined behaviour. */
4014 tcg_gen_andi_i64(t1, t1, shift_max - 1);
4015
4016 switch (opc) {
4017 case OPC_SLL_CP2:
4018 case OPC_DSLL_CP2:
4019 tcg_gen_shl_i64(t0, t0, t1);
4020 break;
4021 case OPC_SRA_CP2:
4022 case OPC_DSRA_CP2:
4023 /* Since SRA is UndefinedResult without sign-extended inputs,
4024 we can treat SRA and DSRA the same. */
4025 tcg_gen_sar_i64(t0, t0, t1);
4026 break;
4027 case OPC_SRL_CP2:
4028 /* We want to shift in zeros for SRL; zero-extend first. */
4029 tcg_gen_ext32u_i64(t0, t0);
4030 /* FALLTHRU */
4031 case OPC_DSRL_CP2:
4032 tcg_gen_shr_i64(t0, t0, t1);
4033 break;
4034 }
4035
4036 if (shift_max == 32) {
4037 tcg_gen_ext32s_i64(t0, t0);
4038 }
4039
4040 /* Shifts larger than MAX produce zero. */
4041 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4042 tcg_gen_neg_i64(t1, t1);
4043 tcg_gen_and_i64(t0, t0, t1);
4044 break;
4045
4046 case OPC_ADD_CP2:
4047 case OPC_DADD_CP2:
4048 {
4049 TCGv_i64 t2 = tcg_temp_new_i64();
4050 TCGLabel *lab = gen_new_label();
4051
4052 tcg_gen_mov_i64(t2, t0);
4053 tcg_gen_add_i64(t0, t1, t2);
4054 if (opc == OPC_ADD_CP2) {
4055 tcg_gen_ext32s_i64(t0, t0);
4056 }
4057 tcg_gen_xor_i64(t1, t1, t2);
4058 tcg_gen_xor_i64(t2, t2, t0);
4059 tcg_gen_andc_i64(t1, t2, t1);
4060 tcg_temp_free_i64(t2);
4061 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4062 generate_exception(ctx, EXCP_OVERFLOW);
4063 gen_set_label(lab);
4064 break;
4065 }
4066
4067 case OPC_SUB_CP2:
4068 case OPC_DSUB_CP2:
4069 {
4070 TCGv_i64 t2 = tcg_temp_new_i64();
4071 TCGLabel *lab = gen_new_label();
4072
4073 tcg_gen_mov_i64(t2, t0);
4074 tcg_gen_sub_i64(t0, t1, t2);
4075 if (opc == OPC_SUB_CP2) {
4076 tcg_gen_ext32s_i64(t0, t0);
4077 }
4078 tcg_gen_xor_i64(t1, t1, t2);
4079 tcg_gen_xor_i64(t2, t2, t0);
4080 tcg_gen_and_i64(t1, t1, t2);
4081 tcg_temp_free_i64(t2);
4082 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4083 generate_exception(ctx, EXCP_OVERFLOW);
4084 gen_set_label(lab);
4085 break;
4086 }
4087
4088 case OPC_PMULUW:
4089 tcg_gen_ext32u_i64(t0, t0);
4090 tcg_gen_ext32u_i64(t1, t1);
4091 tcg_gen_mul_i64(t0, t0, t1);
4092 break;
4093
4094 case OPC_SEQU_CP2:
4095 case OPC_SEQ_CP2:
4096 case OPC_SLTU_CP2:
4097 case OPC_SLT_CP2:
4098 case OPC_SLEU_CP2:
4099 case OPC_SLE_CP2:
4100 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4101 FD field is the CC field? */
4102 default:
4103 MIPS_INVAL("loongson_cp2");
4104 generate_exception_end(ctx, EXCP_RI);
4105 return;
4106 }
4107
4108 #undef LMI_HELPER
4109 #undef LMI_DIRECT
4110
4111 gen_store_fpr64(ctx, t0, rd);
4112
4113 tcg_temp_free_i64(t0);
4114 tcg_temp_free_i64(t1);
4115 }
4116
4117 /* Traps */
4118 static void gen_trap (DisasContext *ctx, uint32_t opc,
4119 int rs, int rt, int16_t imm)
4120 {
4121 int cond;
4122 TCGv t0 = tcg_temp_new();
4123 TCGv t1 = tcg_temp_new();
4124
4125 cond = 0;
4126 /* Load needed operands */
4127 switch (opc) {
4128 case OPC_TEQ:
4129 case OPC_TGE:
4130 case OPC_TGEU:
4131 case OPC_TLT:
4132 case OPC_TLTU:
4133 case OPC_TNE:
4134 /* Compare two registers */
4135 if (rs != rt) {
4136 gen_load_gpr(t0, rs);
4137 gen_load_gpr(t1, rt);
4138 cond = 1;
4139 }
4140 break;
4141 case OPC_TEQI:
4142 case OPC_TGEI:
4143 case OPC_TGEIU:
4144 case OPC_TLTI:
4145 case OPC_TLTIU:
4146 case OPC_TNEI:
4147 /* Compare register to immediate */
4148 if (rs != 0 || imm != 0) {
4149 gen_load_gpr(t0, rs);
4150 tcg_gen_movi_tl(t1, (int32_t)imm);
4151 cond = 1;
4152 }
4153 break;
4154 }
4155 if (cond == 0) {
4156 switch (opc) {
4157 case OPC_TEQ: /* rs == rs */
4158 case OPC_TEQI: /* r0 == 0 */
4159 case OPC_TGE: /* rs >= rs */
4160 case OPC_TGEI: /* r0 >= 0 */
4161 case OPC_TGEU: /* rs >= rs unsigned */
4162 case OPC_TGEIU: /* r0 >= 0 unsigned */
4163 /* Always trap */
4164 generate_exception_end(ctx, EXCP_TRAP);
4165 break;
4166 case OPC_TLT: /* rs < rs */
4167 case OPC_TLTI: /* r0 < 0 */
4168 case OPC_TLTU: /* rs < rs unsigned */
4169 case OPC_TLTIU: /* r0 < 0 unsigned */
4170 case OPC_TNE: /* rs != rs */
4171 case OPC_TNEI: /* r0 != 0 */
4172 /* Never trap: treat as NOP. */
4173 break;
4174 }
4175 } else {
4176 TCGLabel *l1 = gen_new_label();
4177
4178 switch (opc) {
4179 case OPC_TEQ:
4180 case OPC_TEQI:
4181 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4182 break;
4183 case OPC_TGE:
4184 case OPC_TGEI:
4185 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4186 break;
4187 case OPC_TGEU:
4188 case OPC_TGEIU:
4189 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4190 break;
4191 case OPC_TLT:
4192 case OPC_TLTI:
4193 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4194 break;
4195 case OPC_TLTU:
4196 case OPC_TLTIU:
4197 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4198 break;
4199 case OPC_TNE:
4200 case OPC_TNEI:
4201 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4202 break;
4203 }
4204 generate_exception(ctx, EXCP_TRAP);
4205 gen_set_label(l1);
4206 }
4207 tcg_temp_free(t0);
4208 tcg_temp_free(t1);
4209 }
4210
4211 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4212 {
4213 if (unlikely(ctx->singlestep_enabled)) {
4214 return false;
4215 }
4216
4217 #ifndef CONFIG_USER_ONLY
4218 return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4219 #else
4220 return true;
4221 #endif
4222 }
4223
4224 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4225 {
4226 if (use_goto_tb(ctx, dest)) {
4227 tcg_gen_goto_tb(n);
4228 gen_save_pc(dest);
4229 tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
4230 } else {
4231 gen_save_pc(dest);
4232 if (ctx->singlestep_enabled) {
4233 save_cpu_state(ctx, 0);
4234 gen_helper_raise_exception_debug(cpu_env);
4235 }
4236 tcg_gen_lookup_and_goto_ptr(cpu_PC);
4237 }
4238 }
4239
4240 /* Branches (before delay slot) */
4241 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4242 int insn_bytes,
4243 int rs, int rt, int32_t offset,
4244 int delayslot_size)
4245 {
4246 target_ulong btgt = -1;
4247 int blink = 0;
4248 int bcond_compute = 0;
4249 TCGv t0 = tcg_temp_new();
4250 TCGv t1 = tcg_temp_new();
4251
4252 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4253 #ifdef MIPS_DEBUG_DISAS
4254 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4255 TARGET_FMT_lx "\n", ctx->pc);
4256 #endif
4257 generate_exception_end(ctx, EXCP_RI);
4258 goto out;
4259 }
4260
4261 /* Load needed operands */
4262 switch (opc) {
4263 case OPC_BEQ:
4264 case OPC_BEQL:
4265 case OPC_BNE:
4266 case OPC_BNEL:
4267 /* Compare two registers */
4268 if (rs != rt) {
4269 gen_load_gpr(t0, rs);
4270 gen_load_gpr(t1, rt);
4271 bcond_compute = 1;
4272 }
4273 btgt = ctx->pc + insn_bytes + offset;
4274 break;
4275 case OPC_BGEZ:
4276 case OPC_BGEZAL:
4277 case OPC_BGEZALL:
4278 case OPC_BGEZL:
4279 case OPC_BGTZ:
4280 case OPC_BGTZL:
4281 case OPC_BLEZ:
4282 case OPC_BLEZL:
4283 case OPC_BLTZ:
4284 case OPC_BLTZAL:
4285 case OPC_BLTZALL:
4286 case OPC_BLTZL:
4287 /* Compare to zero */
4288 if (rs != 0) {
4289 gen_load_gpr(t0, rs);
4290 bcond_compute = 1;
4291 }
4292 btgt = ctx->pc + insn_bytes + offset;
4293 break;
4294 case OPC_BPOSGE32:
4295 #if defined(TARGET_MIPS64)
4296 case OPC_BPOSGE64:
4297 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4298 #else
4299 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4300 #endif
4301 bcond_compute = 1;
4302 btgt = ctx->pc + insn_bytes + offset;
4303 break;
4304 case OPC_J:
4305 case OPC_JAL:
4306 case OPC_JALX:
4307 /* Jump to immediate */
4308 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4309 break;
4310 case OPC_JR:
4311 case OPC_JALR:
4312 /* Jump to register */
4313 if (offset != 0 && offset != 16) {
4314 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4315 others are reserved. */
4316 MIPS_INVAL("jump hint");
4317 generate_exception_end(ctx, EXCP_RI);
4318 goto out;
4319 }
4320 gen_load_gpr(btarget, rs);
4321 break;
4322 default:
4323 MIPS_INVAL("branch/jump");
4324 generate_exception_end(ctx, EXCP_RI);
4325 goto out;
4326 }
4327 if (bcond_compute == 0) {
4328 /* No condition to be computed */
4329 switch (opc) {
4330 case OPC_BEQ: /* rx == rx */
4331 case OPC_BEQL: /* rx == rx likely */
4332 case OPC_BGEZ: /* 0 >= 0 */
4333 case OPC_BGEZL: /* 0 >= 0 likely */
4334 case OPC_BLEZ: /* 0 <= 0 */
4335 case OPC_BLEZL: /* 0 <= 0 likely */
4336 /* Always take */
4337 ctx->hflags |= MIPS_HFLAG_B;
4338 break;
4339 case OPC_BGEZAL: /* 0 >= 0 */
4340 case OPC_BGEZALL: /* 0 >= 0 likely */
4341 /* Always take and link */
4342 blink = 31;
4343 ctx->hflags |= MIPS_HFLAG_B;
4344 break;
4345 case OPC_BNE: /* rx != rx */
4346 case OPC_BGTZ: /* 0 > 0 */
4347 case OPC_BLTZ: /* 0 < 0 */
4348 /* Treat as NOP. */
4349 goto out;
4350 case OPC_BLTZAL: /* 0 < 0 */
4351 /* Handle as an unconditional branch to get correct delay
4352 slot checking. */
4353 blink = 31;
4354 btgt = ctx->pc + insn_bytes + delayslot_size;
4355 ctx->hflags |= MIPS_HFLAG_B;
4356 break;
4357 case OPC_BLTZALL: /* 0 < 0 likely */
4358 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4359 /* Skip the instruction in the delay slot */
4360 ctx->pc += 4;
4361 goto out;
4362 case OPC_BNEL: /* rx != rx likely */
4363 case OPC_BGTZL: /* 0 > 0 likely */
4364 case OPC_BLTZL: /* 0 < 0 likely */
4365 /* Skip the instruction in the delay slot */
4366 ctx->pc += 4;
4367 goto out;
4368 case OPC_J:
4369 ctx->hflags |= MIPS_HFLAG_B;
4370 break;
4371 case OPC_JALX:
4372 ctx->hflags |= MIPS_HFLAG_BX;
4373 /* Fallthrough */
4374 case OPC_JAL:
4375 blink = 31;
4376 ctx->hflags |= MIPS_HFLAG_B;
4377 break;
4378 case OPC_JR:
4379 ctx->hflags |= MIPS_HFLAG_BR;
4380 break;
4381 case OPC_JALR:
4382 blink = rt;
4383 ctx->hflags |= MIPS_HFLAG_BR;
4384 break;
4385 default:
4386 MIPS_INVAL("branch/jump");
4387 generate_exception_end(ctx, EXCP_RI);
4388 goto out;
4389 }
4390 } else {
4391 switch (opc) {
4392 case OPC_BEQ:
4393 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4394 goto not_likely;
4395 case OPC_BEQL:
4396 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4397 goto likely;
4398 case OPC_BNE:
4399 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4400 goto not_likely;
4401 case OPC_BNEL:
4402 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4403 goto likely;
4404 case OPC_BGEZ:
4405 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4406 goto not_likely;
4407 case OPC_BGEZL:
4408 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4409 goto likely;
4410 case OPC_BGEZAL:
4411 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4412 blink = 31;
4413 goto not_likely;
4414 case OPC_BGEZALL:
4415 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4416 blink = 31;
4417 goto likely;
4418 case OPC_BGTZ:
4419 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4420 goto not_likely;
4421 case OPC_BGTZL:
4422 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4423 goto likely;
4424 case OPC_BLEZ:
4425 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4426 goto not_likely;
4427 case OPC_BLEZL:
4428 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4429 goto likely;
4430 case OPC_BLTZ:
4431 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4432 goto not_likely;
4433 case OPC_BLTZL:
4434 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4435 goto likely;
4436 case OPC_BPOSGE32:
4437 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4438 goto not_likely;
4439 #if defined(TARGET_MIPS64)
4440 case OPC_BPOSGE64:
4441 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4442 goto not_likely;
4443 #endif
4444 case OPC_BLTZAL:
4445 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4446 blink = 31;
4447 not_likely:
4448 ctx->hflags |= MIPS_HFLAG_BC;
4449 break;
4450 case OPC_BLTZALL:
4451 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4452 blink = 31;
4453 likely:
4454 ctx->hflags |= MIPS_HFLAG_BL;
4455 break;
4456 default:
4457 MIPS_INVAL("conditional branch/jump");
4458 generate_exception_end(ctx, EXCP_RI);
4459 goto out;
4460 }
4461 }
4462
4463 ctx->btarget = btgt;
4464
4465 switch (delayslot_size) {
4466 case 2:
4467 ctx->hflags |= MIPS_HFLAG_BDS16;
4468 break;
4469 case 4:
4470 ctx->hflags |= MIPS_HFLAG_BDS32;
4471 break;
4472 }
4473
4474 if (blink > 0) {
4475 int post_delay = insn_bytes + delayslot_size;
4476 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4477
4478 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4479 }
4480
4481 out:
4482 if (insn_bytes == 2)
4483 ctx->hflags |= MIPS_HFLAG_B16;
4484 tcg_temp_free(t0);
4485 tcg_temp_free(t1);
4486 }
4487
4488 /* special3 bitfield operations */
4489 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4490 int rs, int lsb, int msb)
4491 {
4492 TCGv t0 = tcg_temp_new();
4493 TCGv t1 = tcg_temp_new();
4494
4495 gen_load_gpr(t1, rs);
4496 switch (opc) {
4497 case OPC_EXT:
4498 if (lsb + msb > 31) {
4499 goto fail;
4500 }
4501 if (msb != 31) {
4502 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4503 } else {
4504 /* The two checks together imply that lsb == 0,
4505 so this is a simple sign-extension. */
4506 tcg_gen_ext32s_tl(t0, t1);
4507 }
4508 break;
4509 #if defined(TARGET_MIPS64)
4510 case OPC_DEXTU:
4511 lsb += 32;
4512 goto do_dext;
4513 case OPC_DEXTM:
4514 msb += 32;
4515 goto do_dext;
4516 case OPC_DEXT:
4517 do_dext:
4518 if (lsb + msb > 63) {
4519 goto fail;
4520 }
4521 tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
4522 break;
4523 #endif
4524 case OPC_INS:
4525 if (lsb > msb) {
4526 goto fail;
4527 }
4528 gen_load_gpr(t0, rt);
4529 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4530 tcg_gen_ext32s_tl(t0, t0);
4531 break;
4532 #if defined(TARGET_MIPS64)
4533 case OPC_DINSU:
4534 lsb += 32;
4535 /* FALLTHRU */
4536 case OPC_DINSM:
4537 msb += 32;
4538 /* FALLTHRU */
4539 case OPC_DINS:
4540 if (lsb > msb) {
4541 goto fail;
4542 }
4543 gen_load_gpr(t0, rt);
4544 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4545 break;
4546 #endif
4547 default:
4548 fail:
4549 MIPS_INVAL("bitops");
4550 generate_exception_end(ctx, EXCP_RI);
4551 tcg_temp_free(t0);
4552 tcg_temp_free(t1);
4553 return;
4554 }
4555 gen_store_gpr(t0, rt);
4556 tcg_temp_free(t0);
4557 tcg_temp_free(t1);
4558 }
4559
4560 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4561 {
4562 TCGv t0;
4563
4564 if (rd == 0) {
4565 /* If no destination, treat it as a NOP. */
4566 return;
4567 }
4568
4569 t0 = tcg_temp_new();
4570 gen_load_gpr(t0, rt);
4571 switch (op2) {
4572 case OPC_WSBH:
4573 {
4574 TCGv t1 = tcg_temp_new();
4575 TCGv t2 = tcg_const_tl(0x00FF00FF);
4576
4577 tcg_gen_shri_tl(t1, t0, 8);
4578 tcg_gen_and_tl(t1, t1, t2);
4579 tcg_gen_and_tl(t0, t0, t2);
4580 tcg_gen_shli_tl(t0, t0, 8);
4581 tcg_gen_or_tl(t0, t0, t1);
4582 tcg_temp_free(t2);
4583 tcg_temp_free(t1);
4584 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4585 }
4586 break;
4587 case OPC_SEB:
4588 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4589 break;
4590 case OPC_SEH:
4591 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4592 break;
4593 #if defined(TARGET_MIPS64)
4594 case OPC_DSBH:
4595 {
4596 TCGv t1 = tcg_temp_new();
4597 TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
4598
4599 tcg_gen_shri_tl(t1, t0, 8);
4600 tcg_gen_and_tl(t1, t1, t2);
4601 tcg_gen_and_tl(t0, t0, t2);
4602 tcg_gen_shli_tl(t0, t0, 8);
4603 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4604 tcg_temp_free(t2);
4605 tcg_temp_free(t1);
4606 }
4607 break;
4608 case OPC_DSHD:
4609 {
4610 TCGv t1 = tcg_temp_new();
4611 TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
4612
4613 tcg_gen_shri_tl(t1, t0, 16);
4614 tcg_gen_and_tl(t1, t1, t2);
4615 tcg_gen_and_tl(t0, t0, t2);
4616 tcg_gen_shli_tl(t0, t0, 16);
4617 tcg_gen_or_tl(t0, t0, t1);
4618 tcg_gen_shri_tl(t1, t0, 32);
4619 tcg_gen_shli_tl(t0, t0, 32);
4620 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4621 tcg_temp_free(t2);
4622 tcg_temp_free(t1);
4623 }
4624 break;
4625 #endif
4626 default:
4627 MIPS_INVAL("bsfhl");
4628 generate_exception_end(ctx, EXCP_RI);
4629 tcg_temp_free(t0);
4630 return;
4631 }
4632 tcg_temp_free(t0);
4633 }
4634
4635 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4636 int imm2)
4637 {
4638 TCGv t0;
4639 TCGv t1;
4640 if (rd == 0) {
4641 /* Treat as NOP. */
4642 return;
4643 }
4644 t0 = tcg_temp_new();
4645 t1 = tcg_temp_new();
4646 gen_load_gpr(t0, rs);
4647 gen_load_gpr(t1, rt);
4648 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4649 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4650 if (opc == OPC_LSA) {
4651 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4652 }
4653
4654 tcg_temp_free(t1);
4655 tcg_temp_free(t0);
4656
4657 return;
4658 }
4659
4660 static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4661 int bp)
4662 {
4663 TCGv t0;
4664 if (rd == 0) {
4665 /* Treat as NOP. */
4666 return;
4667 }
4668 t0 = tcg_temp_new();
4669 gen_load_gpr(t0, rt);
4670 if (bp == 0) {
4671 switch (opc) {
4672 case OPC_ALIGN:
4673 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4674 break;
4675 #if defined(TARGET_MIPS64)
4676 case OPC_DALIGN:
4677 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4678 break;
4679 #endif
4680 }
4681 } else {
4682 TCGv t1 = tcg_temp_new();
4683 gen_load_gpr(t1, rs);
4684 switch (opc) {
4685 case OPC_ALIGN:
4686 {
4687 TCGv_i64 t2 = tcg_temp_new_i64();
4688 tcg_gen_concat_tl_i64(t2, t1, t0);
4689 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4690 gen_move_low32(cpu_gpr[rd], t2);
4691 tcg_temp_free_i64(t2);
4692 }
4693 break;
4694 #if defined(TARGET_MIPS64)
4695 case OPC_DALIGN:
4696 tcg_gen_shli_tl(t0, t0, 8 * bp);
4697 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4698 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4699 break;
4700 #endif
4701 }
4702 tcg_temp_free(t1);
4703 }
4704
4705 tcg_temp_free(t0);
4706 }
4707
4708 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4709 {
4710 TCGv t0;
4711 if (rd == 0) {
4712 /* Treat as NOP. */
4713 return;
4714 }
4715 t0 = tcg_temp_new();
4716 gen_load_gpr(t0, rt);
4717 switch (opc) {
4718 case OPC_BITSWAP:
4719 gen_helper_bitswap(cpu_gpr[rd], t0);
4720 break;
4721 #if defined(TARGET_MIPS64)
4722 case OPC_DBITSWAP:
4723 gen_helper_dbitswap(cpu_gpr[rd], t0);
4724 break;
4725 #endif
4726 }
4727 tcg_temp_free(t0);
4728 }
4729
4730 #ifndef CONFIG_USER_ONLY
4731 /* CP0 (MMU and control) */
4732 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4733 {
4734 TCGv_i64 t0 = tcg_temp_new_i64();
4735 TCGv_i64 t1 = tcg_temp_new_i64();
4736
4737 tcg_gen_ext_tl_i64(t0, arg);
4738 tcg_gen_ld_i64(t1, cpu_env, off);
4739 #if defined(TARGET_MIPS64)
4740 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4741 #else
4742 tcg_gen_concat32_i64(t1, t1, t0);
4743 #endif
4744 tcg_gen_st_i64(t1, cpu_env, off);
4745 tcg_temp_free_i64(t1);
4746 tcg_temp_free_i64(t0);
4747 }
4748
4749 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4750 {
4751 TCGv_i64 t0 = tcg_temp_new_i64();
4752 TCGv_i64 t1 = tcg_temp_new_i64();
4753
4754 tcg_gen_ext_tl_i64(t0, arg);
4755 tcg_gen_ld_i64(t1, cpu_env, off);
4756 tcg_gen_concat32_i64(t1, t1, t0);
4757 tcg_gen_st_i64(t1, cpu_env, off);
4758 tcg_temp_free_i64(t1);
4759 tcg_temp_free_i64(t0);
4760 }
4761
4762 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4763 {
4764 TCGv_i64 t0 = tcg_temp_new_i64();
4765
4766 tcg_gen_ld_i64(t0, cpu_env, off);
4767 #if defined(TARGET_MIPS64)
4768 tcg_gen_shri_i64(t0, t0, 30);
4769 #else
4770 tcg_gen_shri_i64(t0, t0, 32);
4771 #endif
4772 gen_move_low32(arg, t0);
4773 tcg_temp_free_i64(t0);
4774 }
4775
4776 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4777 {
4778 TCGv_i64 t0 = tcg_temp_new_i64();
4779
4780 tcg_gen_ld_i64(t0, cpu_env, off);
4781 tcg_gen_shri_i64(t0, t0, 32 + shift);
4782 gen_move_low32(arg, t0);
4783 tcg_temp_free_i64(t0);
4784 }
4785
4786 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4787 {
4788 TCGv_i32 t0 = tcg_temp_new_i32();
4789
4790 tcg_gen_ld_i32(t0, cpu_env, off);
4791 tcg_gen_ext_i32_tl(arg, t0);
4792 tcg_temp_free_i32(t0);
4793 }
4794
4795 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4796 {
4797 tcg_gen_ld_tl(arg, cpu_env, off);
4798 tcg_gen_ext32s_tl(arg, arg);
4799 }
4800
4801 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4802 {
4803 TCGv_i32 t0 = tcg_temp_new_i32();
4804
4805 tcg_gen_trunc_tl_i32(t0, arg);
4806 tcg_gen_st_i32(t0, cpu_env, off);
4807 tcg_temp_free_i32(t0);
4808 }
4809
4810 #define CP0_CHECK(c) \
4811 do { \
4812 if (!(c)) { \
4813 goto cp0_unimplemented; \
4814 } \
4815 } while (0)
4816
4817 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4818 {
4819 const char *rn = "invalid";
4820
4821 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4822
4823 switch (reg) {
4824 case 2:
4825 switch (sel) {
4826 case 0:
4827 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4828 rn = "EntryLo0";
4829 break;
4830 default:
4831 goto cp0_unimplemented;
4832 }
4833 break;
4834 case 3:
4835 switch (sel) {
4836 case 0:
4837 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4838 rn = "EntryLo1";
4839 break;
4840 default:
4841 goto cp0_unimplemented;
4842 }
4843 break;
4844 case 17:
4845 switch (sel) {
4846 case 0:
4847 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4848 ctx->CP0_LLAddr_shift);
4849 rn = "LLAddr";
4850 break;
4851 case 1:
4852 CP0_CHECK(ctx->mrp);
4853 gen_helper_mfhc0_maar(arg, cpu_env);
4854 rn = "MAAR";
4855 break;
4856 default:
4857 goto cp0_unimplemented;
4858 }
4859 break;
4860 case 28:
4861 switch (sel) {
4862 case 0:
4863 case 2:
4864 case 4:
4865 case 6:
4866 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4867 rn = "TagLo";
4868 break;
4869 default:
4870 goto cp0_unimplemented;
4871 }
4872 break;
4873 default:
4874 goto cp0_unimplemented;
4875 }
4876 trace_mips_translate_c0("mfhc0", rn, reg, sel);
4877 return;
4878
4879 cp0_unimplemented:
4880 qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4881 tcg_gen_movi_tl(arg, 0);
4882 }
4883
4884 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4885 {
4886 const char *rn = "invalid";
4887 uint64_t mask = ctx->PAMask >> 36;
4888
4889 CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
4890
4891 switch (reg) {
4892 case 2:
4893 switch (sel) {
4894 case 0:
4895 tcg_gen_andi_tl(arg, arg, mask);
4896 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4897 rn = "EntryLo0";
4898 break;
4899 default:
4900 goto cp0_unimplemented;
4901 }
4902 break;
4903 case 3:
4904 switch (sel) {
4905 case 0:
4906 tcg_gen_andi_tl(arg, arg, mask);
4907 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4908 rn = "EntryLo1";
4909 break;
4910 default:
4911 goto cp0_unimplemented;
4912 }
4913 break;
4914 case 17:
4915 switch (sel) {
4916 case 0:
4917 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4918 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4919 relevant for modern MIPS cores supporting MTHC0, therefore
4920 treating MTHC0 to LLAddr as NOP. */
4921 rn = "LLAddr";
4922 break;
4923 case 1:
4924 CP0_CHECK(ctx->mrp);
4925 gen_helper_mthc0_maar(cpu_env, arg);
4926 rn = "MAAR";
4927 break;
4928 default:
4929 goto cp0_unimplemented;
4930 }
4931 break;
4932 case 28:
4933 switch (sel) {
4934 case 0:
4935 case 2:
4936 case 4:
4937 case 6:
4938 tcg_gen_andi_tl(arg, arg, mask);
4939 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4940 rn = "TagLo";
4941 break;
4942 default:
4943 goto cp0_unimplemented;
4944 }
4945 break;
4946 default:
4947 goto cp0_unimplemented;
4948 }
4949 trace_mips_translate_c0("mthc0", rn, reg, sel);
4950
4951 cp0_unimplemented:
4952 qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4953 }
4954
4955 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4956 {
4957 if (ctx->insn_flags & ISA_MIPS32R6) {
4958 tcg_gen_movi_tl(arg, 0);
4959 } else {
4960 tcg_gen_movi_tl(arg, ~0);
4961 }
4962 }
4963
4964 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4965 {
4966 const char *rn = "invalid";
4967
4968 if (sel != 0)
4969 check_insn(ctx, ISA_MIPS32);
4970
4971 switch (reg) {
4972 case 0:
4973 switch (sel) {
4974 case 0:
4975 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4976 rn = "Index";
4977 break;
4978 case 1:
4979 CP0_CHECK(ctx->insn_flags & ASE_MT);
4980 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4981 rn = "MVPControl";
4982 break;
4983 case 2:
4984 CP0_CHECK(ctx->insn_flags & ASE_MT);
4985 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4986 rn = "MVPConf0";
4987 break;
4988 case 3:
4989 CP0_CHECK(ctx->insn_flags & ASE_MT);
4990 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4991 rn = "MVPConf1";
4992 break;
4993 case 4:
4994 CP0_CHECK(ctx->vp);
4995 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4996 rn = "VPControl";
4997 break;
4998 default:
4999 goto cp0_unimplemented;
5000 }
5001 break;
5002 case 1:
5003 switch (sel) {
5004 case 0:
5005 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5006 gen_helper_mfc0_random(arg, cpu_env);
5007 rn = "Random";
5008 break;
5009 case 1:
5010 CP0_CHECK(ctx->insn_flags & ASE_MT);
5011 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5012 rn = "VPEControl";
5013 break;
5014 case 2:
5015 CP0_CHECK(ctx->insn_flags & ASE_MT);
5016 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5017 rn = "VPEConf0";
5018 break;
5019 case 3:
5020 CP0_CHECK(ctx->insn_flags & ASE_MT);
5021 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5022 rn = "VPEConf1";
5023 break;
5024 case 4:
5025 CP0_CHECK(ctx->insn_flags & ASE_MT);
5026 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5027 rn = "YQMask";
5028 break;
5029 case 5:
5030 CP0_CHECK(ctx->insn_flags & ASE_MT);
5031 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5032 rn = "VPESchedule";
5033 break;
5034 case 6:
5035 CP0_CHECK(ctx->insn_flags & ASE_MT);
5036 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5037 rn = "VPEScheFBack";
5038 break;
5039 case 7:
5040 CP0_CHECK(ctx->insn_flags & ASE_MT);
5041 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5042 rn = "VPEOpt";
5043 break;
5044 default:
5045 goto cp0_unimplemented;
5046 }
5047 break;
5048 case 2:
5049 switch (sel) {
5050 case 0:
5051 {
5052 TCGv_i64 tmp = tcg_temp_new_i64();
5053 tcg_gen_ld_i64(tmp, cpu_env,
5054 offsetof(CPUMIPSState, CP0_EntryLo0));
5055 #if defined(TARGET_MIPS64)
5056 if (ctx->rxi) {
5057 /* Move RI/XI fields to bits 31:30 */
5058 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5059 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5060 }
5061 #endif
5062 gen_move_low32(arg, tmp);
5063 tcg_temp_free_i64(tmp);
5064 }
5065 rn = "EntryLo0";
5066 break;
5067 case 1:
5068 CP0_CHECK(ctx->insn_flags & ASE_MT);
5069 gen_helper_mfc0_tcstatus(arg, cpu_env);
5070 rn = "TCStatus";
5071 break;
5072 case 2:
5073 CP0_CHECK(ctx->insn_flags & ASE_MT);
5074 gen_helper_mfc0_tcbind(arg, cpu_env);
5075 rn = "TCBind";
5076 break;
5077 case 3:
5078 CP0_CHECK(ctx->insn_flags & ASE_MT);
5079 gen_helper_mfc0_tcrestart(arg, cpu_env);
5080 rn = "TCRestart";
5081 break;
5082 case 4:
5083 CP0_CHECK(ctx->insn_flags & ASE_MT);
5084 gen_helper_mfc0_tchalt(arg, cpu_env);
5085 rn = "TCHalt";
5086 break;
5087 case 5:
5088 CP0_CHECK(ctx->insn_flags & ASE_MT);
5089 gen_helper_mfc0_tccontext(arg, cpu_env);
5090 rn = "TCContext";
5091 break;
5092 case 6:
5093 CP0_CHECK(ctx->insn_flags & ASE_MT);
5094 gen_helper_mfc0_tcschedule(arg, cpu_env);
5095 rn = "TCSchedule";
5096 break;
5097 case 7:
5098 CP0_CHECK(ctx->insn_flags & ASE_MT);
5099 gen_helper_mfc0_tcschefback(arg, cpu_env);
5100 rn = "TCScheFBack";
5101 break;
5102 default:
5103 goto cp0_unimplemented;
5104 }
5105 break;
5106 case 3:
5107 switch (sel) {
5108 case 0:
5109 {
5110 TCGv_i64 tmp = tcg_temp_new_i64();
5111 tcg_gen_ld_i64(tmp, cpu_env,
5112 offsetof(CPUMIPSState, CP0_EntryLo1));
5113 #if defined(TARGET_MIPS64)
5114 if (ctx->rxi) {
5115 /* Move RI/XI fields to bits 31:30 */
5116 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5117 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5118 }
5119 #endif
5120 gen_move_low32(arg, tmp);
5121 tcg_temp_free_i64(tmp);
5122 }
5123 rn = "EntryLo1";
5124 break;
5125 case 1:
5126 CP0_CHECK(ctx->vp);
5127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5128 rn = "GlobalNumber";
5129 break;
5130 default:
5131 goto cp0_unimplemented;
5132 }
5133 break;
5134 case 4:
5135 switch (sel) {
5136 case 0:
5137 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5138 tcg_gen_ext32s_tl(arg, arg);
5139 rn = "Context";
5140 break;
5141 case 1:
5142 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5143 rn = "ContextConfig";
5144 goto cp0_unimplemented;
5145 case 2:
5146 CP0_CHECK(ctx->ulri);
5147 tcg_gen_ld32s_tl(arg, cpu_env,
5148 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5149 rn = "UserLocal";
5150 break;
5151 default:
5152 goto cp0_unimplemented;
5153 }
5154 break;
5155 case 5:
5156 switch (sel) {
5157 case 0:
5158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5159 rn = "PageMask";
5160 break;
5161 case 1:
5162 check_insn(ctx, ISA_MIPS32R2);
5163 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5164 rn = "PageGrain";
5165 break;
5166 default:
5167 goto cp0_unimplemented;
5168 }
5169 break;
5170 case 6:
5171 switch (sel) {
5172 case 0:
5173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5174 rn = "Wired";
5175 break;
5176 case 1:
5177 check_insn(ctx, ISA_MIPS32R2);
5178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5179 rn = "SRSConf0";
5180 break;
5181 case 2:
5182 check_insn(ctx, ISA_MIPS32R2);
5183 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5184 rn = "SRSConf1";
5185 break;
5186 case 3:
5187 check_insn(ctx, ISA_MIPS32R2);
5188 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5189 rn = "SRSConf2";
5190 break;
5191 case 4:
5192 check_insn(ctx, ISA_MIPS32R2);
5193 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5194 rn = "SRSConf3";
5195 break;
5196 case 5:
5197 check_insn(ctx, ISA_MIPS32R2);
5198 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5199 rn = "SRSConf4";
5200 break;
5201 default:
5202 goto cp0_unimplemented;
5203 }
5204 break;
5205 case 7:
5206 switch (sel) {
5207 case 0:
5208 check_insn(ctx, ISA_MIPS32R2);
5209 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5210 rn = "HWREna";
5211 break;
5212 default:
5213 goto cp0_unimplemented;
5214 }
5215 break;
5216 case 8:
5217 switch (sel) {
5218 case 0:
5219 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5220 tcg_gen_ext32s_tl(arg, arg);
5221 rn = "BadVAddr";
5222 break;
5223 case 1:
5224 CP0_CHECK(ctx->bi);
5225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5226 rn = "BadInstr";
5227 break;
5228 case 2:
5229 CP0_CHECK(ctx->bp);
5230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5231 rn = "BadInstrP";
5232 break;
5233 default:
5234 goto cp0_unimplemented;
5235 }
5236 break;
5237 case 9:
5238 switch (sel) {
5239 case 0:
5240 /* Mark as an IO operation because we read the time. */
5241 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5242 gen_io_start();
5243 }
5244 gen_helper_mfc0_count(arg, cpu_env);
5245 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5246 gen_io_end();
5247 }
5248 /* Break the TB to be able to take timer interrupts immediately
5249 after reading count. */
5250 ctx->bstate = BS_STOP;
5251 rn = "Count";
5252 break;
5253 /* 6,7 are implementation dependent */
5254 default:
5255 goto cp0_unimplemented;
5256 }
5257 break;
5258 case 10:
5259 switch (sel) {
5260 case 0:
5261 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5262 tcg_gen_ext32s_tl(arg, arg);
5263 rn = "EntryHi";
5264 break;
5265 default:
5266 goto cp0_unimplemented;
5267 }
5268 break;
5269 case 11:
5270 switch (sel) {
5271 case 0:
5272 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5273 rn = "Compare";
5274 break;
5275 /* 6,7 are implementation dependent */
5276 default:
5277 goto cp0_unimplemented;
5278 }
5279 break;
5280 case 12:
5281 switch (sel) {
5282 case 0:
5283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5284 rn = "Status";
5285 break;
5286 case 1:
5287 check_insn(ctx, ISA_MIPS32R2);
5288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5289 rn = "IntCtl";
5290 break;
5291 case 2:
5292 check_insn(ctx, ISA_MIPS32R2);
5293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5294 rn = "SRSCtl";
5295 break;
5296 case 3:
5297 check_insn(ctx, ISA_MIPS32R2);
5298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5299 rn = "SRSMap";
5300 break;
5301 default:
5302 goto cp0_unimplemented;
5303 }
5304 break;
5305 case 13:
5306 switch (sel) {
5307 case 0:
5308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5309 rn = "Cause";
5310 break;
5311 default:
5312 goto cp0_unimplemented;
5313 }
5314 break;
5315 case 14:
5316 switch (sel) {
5317 case 0:
5318 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5319 tcg_gen_ext32s_tl(arg, arg);
5320 rn = "EPC";
5321 break;
5322 default:
5323 goto cp0_unimplemented;
5324 }
5325 break;
5326 case 15:
5327 switch (sel) {
5328 case 0:
5329 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5330 rn = "PRid";
5331 break;
5332 case 1:
5333 check_insn(ctx, ISA_MIPS32R2);
5334 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5335 rn = "EBase";
5336 break;
5337 case 3:
5338 check_insn(ctx, ISA_MIPS32R2);
5339 CP0_CHECK(ctx->cmgcr);
5340 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5341 tcg_gen_ext32s_tl(arg, arg);
5342 rn = "CMGCRBase";
5343 break;
5344 default:
5345 goto cp0_unimplemented;
5346 }
5347 break;
5348 case 16:
5349 switch (sel) {
5350 case 0:
5351 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5352 rn = "Config";
5353 break;
5354 case 1:
5355 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5356 rn = "Config1";
5357 break;
5358 case 2:
5359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5360 rn = "Config2";
5361 break;
5362 case 3:
5363 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5364 rn = "Config3";
5365 break;
5366 case 4:
5367 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5368 rn = "Config4";
5369 break;
5370 case 5:
5371 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5372 rn = "Config5";
5373 break;
5374 /* 6,7 are implementation dependent */
5375 case 6:
5376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5377 rn = "Config6";
5378 break;
5379 case 7:
5380 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5381 rn = "Config7";
5382 break;
5383 default:
5384 goto cp0_unimplemented;
5385 }
5386 break;
5387 case 17:
5388 switch (sel) {
5389 case 0:
5390 gen_helper_mfc0_lladdr(arg, cpu_env);
5391 rn = "LLAddr";
5392 break;
5393 case 1:
5394 CP0_CHECK(ctx->mrp);
5395 gen_helper_mfc0_maar(arg, cpu_env);
5396 rn = "MAAR";
5397 break;
5398 case 2:
5399 CP0_CHECK(ctx->mrp);
5400 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
5401 rn = "MAARI";
5402 break;
5403 default:
5404 goto cp0_unimplemented;
5405 }
5406 break;
5407 case 18:
5408 switch (sel) {
5409 case 0 ... 7:
5410 gen_helper_1e0i(mfc0_watchlo, arg, sel);
5411 rn = "WatchLo";
5412 break;
5413 default:
5414 goto cp0_unimplemented;
5415 }
5416 break;
5417 case 19:
5418 switch (sel) {
5419 case 0 ...7:
5420 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5421 rn = "WatchHi";
5422 break;
5423 default:
5424 goto cp0_unimplemented;
5425 }
5426 break;
5427 case 20:
5428 switch (sel) {
5429 case 0:
5430 #if defined(TARGET_MIPS64)
5431 check_insn(ctx, ISA_MIPS3);
5432 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5433 tcg_gen_ext32s_tl(arg, arg);
5434 rn = "XContext";
5435 break;
5436 #endif
5437 default:
5438 goto cp0_unimplemented;
5439 }
5440 break;
5441 case 21:
5442 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5443 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5444 switch (sel) {
5445 case 0:
5446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5447 rn = "Framemask";
5448 break;
5449 default:
5450 goto cp0_unimplemented;
5451 }
5452 break;
5453 case 22:
5454 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5455 rn = "'Diagnostic"; /* implementation dependent */
5456 break;
5457 case 23:
5458 switch (sel) {
5459 case 0:
5460 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5461 rn = "Debug";
5462 break;
5463 case 1:
5464 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5465 rn = "TraceControl";
5466 goto cp0_unimplemented;
5467 case 2:
5468 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5469 rn = "TraceControl2";
5470 goto cp0_unimplemented;
5471 case 3:
5472 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5473 rn = "UserTraceData";
5474 goto cp0_unimplemented;
5475 case 4:
5476 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5477 rn = "TraceBPC";
5478 goto cp0_unimplemented;
5479 default:
5480 goto cp0_unimplemented;
5481 }
5482 break;
5483 case 24:
5484 switch (sel) {
5485 case 0:
5486 /* EJTAG support */
5487 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5488 tcg_gen_ext32s_tl(arg, arg);
5489 rn = "DEPC";
5490 break;
5491 default:
5492 goto cp0_unimplemented;
5493 }
5494 break;
5495 case 25:
5496 switch (sel) {
5497 case 0:
5498 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5499 rn = "Performance0";
5500 break;
5501 case 1:
5502 // gen_helper_mfc0_performance1(arg);
5503 rn = "Performance1";
5504 goto cp0_unimplemented;
5505 case 2:
5506 // gen_helper_mfc0_performance2(arg);
5507 rn = "Performance2";
5508 goto cp0_unimplemented;
5509 case 3:
5510 // gen_helper_mfc0_performance3(arg);
5511 rn = "Performance3";
5512 goto cp0_unimplemented;
5513 case 4:
5514 // gen_helper_mfc0_performance4(arg);
5515 rn = "Performance4";
5516 goto cp0_unimplemented;
5517 case 5:
5518 // gen_helper_mfc0_performance5(arg);
5519 rn = "Performance5";
5520 goto cp0_unimplemented;
5521 case 6:
5522 // gen_helper_mfc0_performance6(arg);
5523 rn = "Performance6";
5524 goto cp0_unimplemented;
5525 case 7:
5526 // gen_helper_mfc0_performance7(arg);
5527 rn = "Performance7";
5528 goto cp0_unimplemented;
5529 default:
5530 goto cp0_unimplemented;
5531 }
5532 break;
5533 case 26:
5534 switch (sel) {
5535 case 0:
5536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
5537 rn = "ErrCtl";
5538 break;
5539 default:
5540 goto cp0_unimplemented;
5541 }
5542 break;
5543 case 27:
5544 switch (sel) {
5545 case 0 ... 3:
5546 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5547 rn = "CacheErr";
5548 break;
5549 default:
5550 goto cp0_unimplemented;
5551 }
5552 break;
5553 case 28:
5554 switch (sel) {
5555 case 0:
5556 case 2:
5557 case 4:
5558 case 6:
5559 {
5560 TCGv_i64 tmp = tcg_temp_new_i64();
5561 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5562 gen_move_low32(arg, tmp);
5563 tcg_temp_free_i64(tmp);
5564 }
5565 rn = "TagLo";
5566 break;
5567 case 1:
5568 case 3:
5569 case 5:
5570 case 7:
5571 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5572 rn = "DataLo";
5573 break;
5574 default:
5575 goto cp0_unimplemented;
5576 }
5577 break;
5578 case 29:
5579 switch (sel) {
5580 case 0:
5581 case 2:
5582 case 4:
5583 case 6:
5584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5585 rn = "TagHi";
5586 break;
5587 case 1:
5588 case 3:
5589 case 5:
5590 case 7:
5591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5592 rn = "DataHi";
5593 break;
5594 default:
5595 goto cp0_unimplemented;
5596 }
5597 break;
5598 case 30:
5599 switch (sel) {
5600 case 0:
5601 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5602 tcg_gen_ext32s_tl(arg, arg);
5603 rn = "ErrorEPC";
5604 break;
5605 default:
5606 goto cp0_unimplemented;
5607 }
5608 break;
5609 case 31:
5610 switch (sel) {
5611 case 0:
5612 /* EJTAG support */
5613 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5614 rn = "DESAVE";
5615 break;
5616 case 2 ... 7:
5617 CP0_CHECK(ctx->kscrexist & (1 << sel));
5618 tcg_gen_ld_tl(arg, cpu_env,
5619 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5620 tcg_gen_ext32s_tl(arg, arg);
5621 rn = "KScratch";
5622 break;
5623 default:
5624 goto cp0_unimplemented;
5625 }
5626 break;
5627 default:
5628 goto cp0_unimplemented;
5629 }
5630 trace_mips_translate_c0("mfc0", rn, reg, sel);
5631 return;
5632
5633 cp0_unimplemented:
5634 qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5635 gen_mfc0_unimplemented(ctx, arg);
5636 }
5637
5638 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5639 {
5640 const char *rn = "invalid";
5641
5642 if (sel != 0)
5643 check_insn(ctx, ISA_MIPS32);
5644
5645 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5646 gen_io_start();
5647 }
5648
5649 switch (reg) {
5650 case 0:
5651 switch (sel) {
5652 case 0:
5653 gen_helper_mtc0_index(cpu_env, arg);
5654 rn = "Index";
5655 break;
5656 case 1:
5657 CP0_CHECK(ctx->insn_flags & ASE_MT);
5658 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5659 rn = "MVPControl";
5660 break;
5661 case 2:
5662 CP0_CHECK(ctx->insn_flags & ASE_MT);
5663 /* ignored */
5664 rn = "MVPConf0";
5665 break;
5666 case 3:
5667 CP0_CHECK(ctx->insn_flags & ASE_MT);
5668 /* ignored */
5669 rn = "MVPConf1";
5670 break;
5671 case 4:
5672 CP0_CHECK(ctx->vp);
5673 /* ignored */
5674 rn = "VPControl";
5675 break;
5676 default:
5677 goto cp0_unimplemented;
5678 }
5679 break;
5680 case 1:
5681 switch (sel) {
5682 case 0:
5683 /* ignored */
5684 rn = "Random";
5685 break;
5686 case 1:
5687 CP0_CHECK(ctx->insn_flags & ASE_MT);
5688 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5689 rn = "VPEControl";
5690 break;
5691 case 2:
5692 CP0_CHECK(ctx->insn_flags & ASE_MT);
5693 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5694 rn = "VPEConf0";
5695 break;
5696 case 3:
5697 CP0_CHECK(ctx->insn_flags & ASE_MT);
5698 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5699 rn = "VPEConf1";
5700 break;
5701 case 4:
5702 CP0_CHECK(ctx->insn_flags & ASE_MT);
5703 gen_helper_mtc0_yqmask(cpu_env, arg);
5704 rn = "YQMask";
5705 break;
5706 case 5:
5707 CP0_CHECK(ctx->insn_flags & ASE_MT);
5708 tcg_gen_st_tl(arg, cpu_env,
5709 offsetof(CPUMIPSState, CP0_VPESchedule));
5710 rn = "VPESchedule";
5711 break;
5712 case 6:
5713 CP0_CHECK(ctx->insn_flags & ASE_MT);
5714 tcg_gen_st_tl(arg, cpu_env,
5715 offsetof(CPUMIPSState, CP0_VPEScheFBack));
5716 rn = "VPEScheFBack";
5717 break;
5718 case 7:
5719 CP0_CHECK(ctx->insn_flags & ASE_MT);
5720 gen_helper_mtc0_vpeopt(cpu_env, arg);
5721 rn = "VPEOpt";
5722 break;
5723 default:
5724 goto cp0_unimplemented;
5725 }
5726 break;
5727 case 2:
5728 switch (sel) {
5729 case 0:
5730 gen_helper_mtc0_entrylo0(cpu_env, arg);
5731 rn = "EntryLo0";
5732 break;
5733 case 1:
5734 CP0_CHECK(ctx->insn_flags & ASE_MT);
5735 gen_helper_mtc0_tcstatus(cpu_env, arg);
5736 rn = "TCStatus";
5737 break;
5738 case 2:
5739 CP0_CHECK(ctx->insn_flags & ASE_MT);
5740 gen_helper_mtc0_tcbind(cpu_env, arg);
5741 rn = "TCBind";
5742 break;
5743 case 3:
5744 CP0_CHECK(ctx->insn_flags & ASE_MT);
5745 gen_helper_mtc0_tcrestart(cpu_env, arg);
5746 rn = "TCRestart";
5747 break;
5748 case 4:
5749 CP0_CHECK(ctx->insn_flags & ASE_MT);
5750 gen_helper_mtc0_tchalt(cpu_env, arg);
5751 rn = "TCHalt";
5752 break;
5753 case 5:
5754 CP0_CHECK(ctx->insn_flags & ASE_MT);
5755 gen_helper_mtc0_tccontext(cpu_env, arg);
5756 rn = "TCContext";
5757 break;
5758 case 6:
5759 CP0_CHECK(ctx->insn_flags & ASE_MT);
5760 gen_helper_mtc0_tcschedule(cpu_env, arg);
5761 rn = "TCSchedule";
5762 break;
5763 case 7:
5764 CP0_CHECK(ctx->insn_flags & ASE_MT);
5765 gen_helper_mtc0_tcschefback(cpu_env, arg);
5766 rn = "TCScheFBack";
5767 break;
5768 default:
5769 goto cp0_unimplemented;
5770 }
5771 break;
5772 case 3:
5773 switch (sel) {
5774 case 0:
5775 gen_helper_mtc0_entrylo1(cpu_env, arg);
5776 rn = "EntryLo1";
5777 break;
5778 case 1:
5779 CP0_CHECK(ctx->vp);
5780 /* ignored */
5781 rn = "GlobalNumber";
5782 break;
5783 default:
5784 goto cp0_unimplemented;
5785 }
5786 break;
5787 case 4:
5788 switch (sel) {
5789 case 0:
5790 gen_helper_mtc0_context(cpu_env, arg);
5791 rn = "Context";
5792 break;
5793 case 1:
5794 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5795 rn = "ContextConfig";
5796 goto cp0_unimplemented;
5797 case 2:
5798 CP0_CHECK(ctx->ulri);
5799 tcg_gen_st_tl(arg, cpu_env,
5800 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5801 rn = "UserLocal";
5802 break;
5803 default:
5804 goto cp0_unimplemented;
5805 }
5806 break;
5807 case 5:
5808 switch (sel) {
5809 case 0:
5810 gen_helper_mtc0_pagemask(cpu_env, arg);
5811 rn = "PageMask";
5812 break;
5813 case 1:
5814 check_insn(ctx, ISA_MIPS32R2);
5815 gen_helper_mtc0_pagegrain(cpu_env, arg);
5816 rn = "PageGrain";
5817 ctx->bstate = BS_STOP;
5818 break;
5819 default:
5820 goto cp0_unimplemented;
5821 }
5822 break;
5823 case 6:
5824 switch (sel) {
5825 case 0:
5826 gen_helper_mtc0_wired(cpu_env, arg);
5827 rn = "Wired";
5828 break;
5829 case 1:
5830 check_insn(ctx, ISA_MIPS32R2);
5831 gen_helper_mtc0_srsconf0(cpu_env, arg);
5832 rn = "SRSConf0";
5833 break;
5834 case 2:
5835 check_insn(ctx, ISA_MIPS32R2);
5836 gen_helper_mtc0_srsconf1(cpu_env, arg);
5837 rn = "SRSConf1";
5838 break;
5839 case 3:
5840 check_insn(ctx, ISA_MIPS32R2);
5841 gen_helper_mtc0_srsconf2(cpu_env, arg);
5842 rn = "SRSConf2";
5843 break;
5844 case 4:
5845 check_insn(ctx, ISA_MIPS32R2);
5846 gen_helper_mtc0_srsconf3(cpu_env, arg);
5847 rn = "SRSConf3";
5848 break;
5849 case 5:
5850 check_insn(ctx, ISA_MIPS32R2);
5851 gen_helper_mtc0_srsconf4(cpu_env, arg);
5852 rn = "SRSConf4";
5853 break;
5854 default:
5855 goto cp0_unimplemented;
5856 }
5857 break;
5858 case 7:
5859 switch (sel) {
5860 case 0:
5861 check_insn(ctx, ISA_MIPS32R2);
5862 gen_helper_mtc0_hwrena(cpu_env, arg);
5863 ctx->bstate = BS_STOP;
5864 rn = "HWREna";
5865 break;
5866 default:
5867 goto cp0_unimplemented;
5868 }
5869 break;
5870 case 8:
5871 switch (sel) {
5872 case 0:
5873 /* ignored */
5874 rn = "BadVAddr";
5875 break;
5876 case 1:
5877 /* ignored */
5878 rn = "BadInstr";
5879 break;
5880 case 2:
5881 /* ignored */
5882 rn = "BadInstrP";
5883 break;
5884 default:
5885 goto cp0_unimplemented;
5886 }
5887 break;
5888 case 9:
5889 switch (sel) {
5890 case 0:
5891 gen_helper_mtc0_count(cpu_env, arg);
5892 rn = "Count";
5893 break;
5894 /* 6,7 are implementation dependent */
5895 default:
5896 goto cp0_unimplemented;
5897 }
5898 break;
5899 case 10:
5900 switch (sel) {
5901 case 0:
5902 gen_helper_mtc0_entryhi(cpu_env, arg);
5903 rn = "EntryHi";
5904 break;
5905 default:
5906 goto cp0_unimplemented;
5907 }
5908 break;
5909 case 11:
5910 switch (sel) {
5911 case 0:
5912 gen_helper_mtc0_compare(cpu_env, arg);
5913 rn = "Compare";
5914 break;
5915 /* 6,7 are implementation dependent */
5916 default:
5917 goto cp0_unimplemented;
5918 }
5919 break;
5920 case 12:
5921 switch (sel) {
5922 case 0:
5923 save_cpu_state(ctx, 1);
5924 gen_helper_mtc0_status(cpu_env, arg);
5925 /* BS_STOP isn't good enough here, hflags may have changed. */
5926 gen_save_pc(ctx->pc + 4);
5927 ctx->bstate = BS_EXCP;
5928 rn = "Status";
5929 break;
5930 case 1:
5931 check_insn(ctx, ISA_MIPS32R2);
5932 gen_helper_mtc0_intctl(cpu_env, arg);
5933 /* Stop translation as we may have switched the execution mode */
5934 ctx->bstate = BS_STOP;
5935 rn = "IntCtl";
5936 break;
5937 case 2:
5938 check_insn(ctx, ISA_MIPS32R2);
5939 gen_helper_mtc0_srsctl(cpu_env, arg);
5940 /* Stop translation as we may have switched the execution mode */
5941 ctx->bstate = BS_STOP;
5942 rn = "SRSCtl";
5943 break;
5944 case 3:
5945 check_insn(ctx, ISA_MIPS32R2);
5946 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5947 /* Stop translation as we may have switched the execution mode */
5948 ctx->bstate = BS_STOP;
5949 rn = "SRSMap";
5950 break;
5951 default:
5952 goto cp0_unimplemented;
5953 }
5954 break;
5955 case 13:
5956 switch (sel) {
5957 case 0:
5958 save_cpu_state(ctx, 1);
5959 gen_helper_mtc0_cause(cpu_env, arg);
5960 rn = "Cause";
5961 break;
5962 default:
5963 goto cp0_unimplemented;
5964 }
5965 break;
5966 case 14:
5967 switch (sel) {
5968 case 0:
5969 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5970 rn = "EPC";
5971 break;
5972 default:
5973 goto cp0_unimplemented;
5974 }
5975 break;
5976 case 15:
5977 switch (sel) {
5978 case 0:
5979 /* ignored */
5980 rn = "PRid";
5981 break;
5982 case 1:
5983 check_insn(ctx, ISA_MIPS32R2);
5984 gen_helper_mtc0_ebase(cpu_env, arg);
5985 rn = "EBase";
5986 break;
5987 default:
5988 goto cp0_unimplemented;
5989 }
5990 break;
5991 case 16:
5992 switch (sel) {
5993 case 0:
5994 gen_helper_mtc0_config0(cpu_env, arg);
5995 rn = "Config";
5996 /* Stop translation as we may have switched the execution mode */
5997 ctx->bstate = BS_STOP;
5998 break;
5999 case 1:
6000 /* ignored, read only */
6001 rn = "Config1";
6002 break;
6003 case 2:
6004 gen_helper_mtc0_config2(cpu_env, arg);
6005 rn = "Config2";
6006 /* Stop translation as we may have switched the execution mode */
6007 ctx->bstate = BS_STOP;
6008 break;
6009 case 3:
6010 gen_helper_mtc0_config3(cpu_env, arg);
6011 rn = "Config3";
6012 /* Stop translation as we may have switched the execution mode */
6013 ctx->bstate = BS_STOP;
6014 break;
6015 case 4:
6016 gen_helper_mtc0_config4(cpu_env, arg);
6017 rn = "Config4";
6018 ctx->bstate = BS_STOP;
6019 break;
6020 case 5:
6021 gen_helper_mtc0_config5(cpu_env, arg);
6022 rn = "Config5";
6023 /* Stop translation as we may have switched the execution mode */
6024 ctx->bstate = BS_STOP;
6025 break;
6026 /* 6,7 are implementation dependent */
6027 case 6:
6028 /* ignored */
6029 rn = "Config6";
6030 break;
6031 case 7:
6032 /* ignored */
6033 rn = "Config7";
6034 break;
6035 default:
6036 rn = "Invalid config selector";
6037 goto cp0_unimplemented;
6038 }
6039 break;
6040 case 17:
6041 switch (sel) {
6042 case 0:
6043 gen_helper_mtc0_lladdr(cpu_env, arg);
6044 rn = "LLAddr";
6045 break;
6046 case 1:
6047 CP0_CHECK(ctx->mrp);
6048 gen_helper_mtc0_maar(cpu_env, arg);
6049 rn = "MAAR";
6050 break;
6051 case 2:
6052 CP0_CHECK(ctx->mrp);
6053 gen_helper_mtc0_maari(cpu_env, arg);
6054 rn = "MAARI";
6055 break;
6056 default:
6057 goto cp0_unimplemented;
6058 }
6059 break;
6060 case 18:
6061 switch (sel) {
6062 case 0 ... 7:
6063 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6064 rn = "WatchLo";
6065 break;
6066 default:
6067 goto cp0_unimplemented;
6068 }
6069 break;
6070 case 19:
6071 switch (sel) {
6072 case 0 ... 7:
6073 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6074 rn = "WatchHi";
6075 break;
6076 default:
6077 goto cp0_unimplemented;
6078 }
6079 break;
6080 case 20:
6081 switch (sel) {
6082 case 0:
6083 #if defined(TARGET_MIPS64)
6084 check_insn(ctx, ISA_MIPS3);
6085 gen_helper_mtc0_xcontext(cpu_env, arg);
6086 rn = "XContext";
6087 break;
6088 #endif
6089 default:
6090 goto cp0_unimplemented;
6091 }
6092 break;
6093 case 21:
6094 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6095 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6096 switch (sel) {
6097 case 0:
6098 gen_helper_mtc0_framemask(cpu_env, arg);
6099 rn = "Framemask";
6100 break;
6101 default:
6102 goto cp0_unimplemented;
6103 }
6104 break;
6105 case 22:
6106 /* ignored */
6107 rn = "Diagnostic"; /* implementation dependent */
6108 break;
6109 case 23:
6110 switch (sel) {
6111 case 0:
6112 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6113 /* BS_STOP isn't good enough here, hflags may have changed. */
6114 gen_save_pc(ctx->pc + 4);
6115 ctx->bstate = BS_EXCP;
6116 rn = "Debug";
6117 break;
6118 case 1:
6119 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6120 rn = "TraceControl";
6121 /* Stop translation as we may have switched the execution mode */
6122 ctx->bstate = BS_STOP;
6123 goto cp0_unimplemented;
6124 case 2:
6125 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6126 rn = "TraceControl2";
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx->bstate = BS_STOP;
6129 goto cp0_unimplemented;
6130 case 3:
6131 /* Stop translation as we may have switched the execution mode */
6132 ctx->bstate = BS_STOP;
6133 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6134 rn = "UserTraceData";
6135 /* Stop translation as we may have switched the execution mode */
6136 ctx->bstate = BS_STOP;
6137 goto cp0_unimplemented;
6138 case 4:
6139 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6140 /* Stop translation as we may have switched the execution mode */
6141 ctx->bstate = BS_STOP;
6142 rn = "TraceBPC";
6143 goto cp0_unimplemented;
6144 default:
6145 goto cp0_unimplemented;
6146 }
6147 break;
6148 case 24:
6149 switch (sel) {
6150 case 0:
6151 /* EJTAG support */
6152 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6153 rn = "DEPC";
6154 break;
6155 default:
6156 goto cp0_unimplemented;
6157 }
6158 break;
6159 case 25:
6160 switch (sel) {
6161 case 0:
6162 gen_helper_mtc0_performance0(cpu_env, arg);
6163 rn = "Performance0";
6164 break;
6165 case 1:
6166 // gen_helper_mtc0_performance1(arg);
6167 rn = "Performance1";
6168 goto cp0_unimplemented;
6169 case 2:
6170 // gen_helper_mtc0_performance2(arg);
6171 rn = "Performance2";
6172 goto cp0_unimplemented;
6173 case 3:
6174 // gen_helper_mtc0_performance3(arg);
6175 rn = "Performance3";
6176 goto cp0_unimplemented;
6177 case 4:
6178 // gen_helper_mtc0_performance4(arg);
6179 rn = "Performance4";
6180 goto cp0_unimplemented;
6181 case 5:
6182 // gen_helper_mtc0_performance5(arg);
6183 rn = "Performance5";
6184 goto cp0_unimplemented;
6185 case 6:
6186 // gen_helper_mtc0_performance6(arg);
6187 rn = "Performance6";
6188 goto cp0_unimplemented;
6189 case 7:
6190 // gen_helper_mtc0_performance7(arg);
6191 rn = "Performance7";
6192 goto cp0_unimplemented;
6193 default:
6194 goto cp0_unimplemented;
6195 }
6196 break;
6197 case 26:
6198 switch (sel) {
6199 case 0:
6200 gen_helper_mtc0_errctl(cpu_env, arg);
6201 ctx->bstate = BS_STOP;
6202 rn = "ErrCtl";
6203 break;
6204 default:
6205 goto cp0_unimplemented;
6206 }
6207 break;
6208 case 27:
6209 switch (sel) {
6210 case 0 ... 3:
6211 /* ignored */
6212 rn = "CacheErr";
6213 break;
6214 default:
6215 goto cp0_unimplemented;
6216 }
6217 break;
6218 case 28:
6219 switch (sel) {
6220 case 0:
6221 case 2:
6222 case 4:
6223 case 6:
6224 gen_helper_mtc0_taglo(cpu_env, arg);
6225 rn = "TagLo";
6226 break;
6227 case 1:
6228 case 3:
6229 case 5:
6230 case 7:
6231 gen_helper_mtc0_datalo(cpu_env, arg);
6232 rn = "DataLo";
6233 break;
6234 default:
6235 goto cp0_unimplemented;
6236 }
6237 break;
6238 case 29:
6239 switch (sel) {
6240 case 0:
6241 case 2:
6242 case 4:
6243 case 6:
6244 gen_helper_mtc0_taghi(cpu_env, arg);
6245 rn = "TagHi";
6246 break;
6247 case 1:
6248 case 3:
6249 case 5:
6250 case 7:
6251 gen_helper_mtc0_datahi(cpu_env, arg);
6252 rn = "DataHi";
6253 break;
6254 default:
6255 rn = "invalid sel";
6256 goto cp0_unimplemented;
6257 }
6258 break;
6259 case 30:
6260 switch (sel) {
6261 case 0:
6262 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6263 rn = "ErrorEPC";
6264 break;
6265 default:
6266 goto cp0_unimplemented;
6267 }
6268 break;
6269 case 31:
6270 switch (sel) {
6271 case 0:
6272 /* EJTAG support */
6273 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6274 rn = "DESAVE";
6275 break;
6276 case 2 ... 7:
6277 CP0_CHECK(ctx->kscrexist & (1 << sel));
6278 tcg_gen_st_tl(arg, cpu_env,
6279 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6280 rn = "KScratch";
6281 break;
6282 default:
6283 goto cp0_unimplemented;
6284 }
6285 /* Stop translation as we may have switched the execution mode */
6286 ctx->bstate = BS_STOP;
6287 break;
6288 default:
6289 goto cp0_unimplemented;
6290 }
6291 trace_mips_translate_c0("mtc0", rn, reg, sel);
6292
6293 /* For simplicity assume that all writes can cause interrupts. */
6294 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6295 gen_io_end();
6296 ctx->bstate = BS_STOP;
6297 }
6298 return;
6299
6300 cp0_unimplemented:
6301 qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6302 }
6303
6304 #if defined(TARGET_MIPS64)
6305 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6306 {
6307 const char *rn = "invalid";
6308
6309 if (sel != 0)
6310 check_insn(ctx, ISA_MIPS64);
6311
6312 switch (reg) {
6313 case 0:
6314 switch (sel) {
6315 case 0:
6316 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6317 rn = "Index";
6318 break;
6319 case 1:
6320 CP0_CHECK(ctx->insn_flags & ASE_MT);
6321 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6322 rn = "MVPControl";
6323 break;
6324 case 2:
6325 CP0_CHECK(ctx->insn_flags & ASE_MT);
6326 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6327 rn = "MVPConf0";
6328 break;
6329 case 3:
6330 CP0_CHECK(ctx->insn_flags & ASE_MT);
6331 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6332 rn = "MVPConf1";
6333 break;
6334 case 4:
6335 CP0_CHECK(ctx->vp);
6336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6337 rn = "VPControl";
6338 break;
6339 default:
6340 goto cp0_unimplemented;
6341 }
6342 break;
6343 case 1:
6344 switch (sel) {
6345 case 0:
6346 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6347 gen_helper_mfc0_random(arg, cpu_env);
6348 rn = "Random";
6349 break;
6350 case 1:
6351 CP0_CHECK(ctx->insn_flags & ASE_MT);
6352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6353 rn = "VPEControl";
6354 break;
6355 case 2:
6356 CP0_CHECK(ctx->insn_flags & ASE_MT);
6357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6358 rn = "VPEConf0";
6359 break;
6360 case 3:
6361 CP0_CHECK(ctx->insn_flags & ASE_MT);
6362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6363 rn = "VPEConf1";
6364 break;
6365 case 4:
6366 CP0_CHECK(ctx->insn_flags & ASE_MT);
6367 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6368 rn = "YQMask";
6369 break;
6370 case 5:
6371 CP0_CHECK(ctx->insn_flags & ASE_MT);
6372 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6373 rn = "VPESchedule";
6374 break;
6375 case 6:
6376 CP0_CHECK(ctx->insn_flags & ASE_MT);
6377 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6378 rn = "VPEScheFBack";
6379 break;
6380 case 7:
6381 CP0_CHECK(ctx->insn_flags & ASE_MT);
6382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6383 rn = "VPEOpt";
6384 break;
6385 default:
6386 goto cp0_unimplemented;
6387 }
6388 break;
6389 case 2:
6390 switch (sel) {
6391 case 0:
6392 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6393 rn = "EntryLo0";
6394 break;
6395 case 1:
6396 CP0_CHECK(ctx->insn_flags & ASE_MT);
6397 gen_helper_mfc0_tcstatus(arg, cpu_env);
6398 rn = "TCStatus";
6399 break;
6400 case 2:
6401 CP0_CHECK(ctx->insn_flags & ASE_MT);
6402 gen_helper_mfc0_tcbind(arg, cpu_env);
6403 rn = "TCBind";
6404 break;
6405 case 3:
6406 CP0_CHECK(ctx->insn_flags & ASE_MT);
6407 gen_helper_dmfc0_tcrestart(arg, cpu_env);
6408 rn = "TCRestart";
6409 break;
6410 case 4:
6411 CP0_CHECK(ctx->insn_flags & ASE_MT);
6412 gen_helper_dmfc0_tchalt(arg, cpu_env);
6413 rn = "TCHalt";
6414 break;
6415 case 5:
6416 CP0_CHECK(ctx->insn_flags & ASE_MT);
6417 gen_helper_dmfc0_tccontext(arg, cpu_env);
6418 rn = "TCContext";
6419 break;
6420 case 6:
6421 CP0_CHECK(ctx->insn_flags & ASE_MT);
6422 gen_helper_dmfc0_tcschedule(arg, cpu_env);
6423 rn = "TCSchedule";
6424 break;
6425 case 7:
6426 CP0_CHECK(ctx->insn_flags & ASE_MT);
6427 gen_helper_dmfc0_tcschefback(arg, cpu_env);
6428 rn = "TCScheFBack";
6429 break;
6430 default:
6431 goto cp0_unimplemented;
6432 }
6433 break;
6434 case 3:
6435 switch (sel) {
6436 case 0:
6437 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6438 rn = "EntryLo1";
6439 break;
6440 case 1:
6441 CP0_CHECK(ctx->vp);
6442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6443 rn = "GlobalNumber";
6444 break;
6445 default:
6446 goto cp0_unimplemented;
6447 }
6448 break;
6449 case 4:
6450 switch (sel) {
6451 case 0:
6452 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6453 rn = "Context";
6454 break;
6455 case 1:
6456 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6457 rn = "ContextConfig";
6458 goto cp0_unimplemented;
6459 case 2:
6460 CP0_CHECK(ctx->ulri);
6461 tcg_gen_ld_tl(arg, cpu_env,
6462 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6463 rn = "UserLocal";
6464 break;
6465 default:
6466 goto cp0_unimplemented;
6467 }
6468 break;
6469 case 5:
6470 switch (sel) {
6471 case 0:
6472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6473 rn = "PageMask";
6474 break;
6475 case 1:
6476 check_insn(ctx, ISA_MIPS32R2);
6477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6478 rn = "PageGrain";
6479 break;
6480 default:
6481 goto cp0_unimplemented;
6482 }
6483 break;
6484 case 6:
6485 switch (sel) {
6486 case 0:
6487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6488 rn = "Wired";
6489 break;
6490 case 1:
6491 check_insn(ctx, ISA_MIPS32R2);
6492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6493 rn = "SRSConf0";
6494 break;
6495 case 2:
6496 check_insn(ctx, ISA_MIPS32R2);
6497 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6498 rn = "SRSConf1";
6499 break;
6500 case 3:
6501 check_insn(ctx, ISA_MIPS32R2);
6502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6503 rn = "SRSConf2";
6504 break;
6505 case 4:
6506 check_insn(ctx, ISA_MIPS32R2);
6507 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6508 rn = "SRSConf3";
6509 break;
6510 case 5:
6511 check_insn(ctx, ISA_MIPS32R2);
6512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6513 rn = "SRSConf4";
6514 break;
6515 default:
6516 goto cp0_unimplemented;
6517 }
6518 break;
6519 case 7:
6520 switch (sel) {
6521 case 0:
6522 check_insn(ctx, ISA_MIPS32R2);
6523 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6524 rn = "HWREna";
6525 break;
6526 default:
6527 goto cp0_unimplemented;
6528 }
6529 break;
6530 case 8:
6531 switch (sel) {
6532 case 0:
6533 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6534 rn = "BadVAddr";
6535 break;
6536 case 1:
6537 CP0_CHECK(ctx->bi);
6538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6539 rn = "BadInstr";
6540 break;
6541 case 2:
6542 CP0_CHECK(ctx->bp);
6543 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6544 rn = "BadInstrP";
6545 break;
6546 default:
6547 goto cp0_unimplemented;
6548 }
6549 break;
6550 case 9:
6551 switch (sel) {
6552 case 0:
6553 /* Mark as an IO operation because we read the time. */
6554 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6555 gen_io_start();
6556 }
6557 gen_helper_mfc0_count(arg, cpu_env);
6558 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6559 gen_io_end();
6560 }
6561 /* Break the TB to be able to take timer interrupts immediately
6562 after reading count. */
6563 ctx->bstate = BS_STOP;
6564 rn = "Count";
6565 break;
6566 /* 6,7 are implementation dependent */
6567 default:
6568 goto cp0_unimplemented;
6569 }
6570 break;
6571 case 10:
6572 switch (sel) {
6573 case 0:
6574 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6575 rn = "EntryHi";
6576 break;
6577 default:
6578 goto cp0_unimplemented;
6579 }
6580 break;
6581 case 11:
6582 switch (sel) {
6583 case 0:
6584 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6585 rn = "Compare";
6586 break;
6587 /* 6,7 are implementation dependent */
6588 default:
6589 goto cp0_unimplemented;
6590 }
6591 break;
6592 case 12:
6593 switch (sel) {
6594 case 0:
6595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6596 rn = "Status";
6597 break;
6598 case 1:
6599 check_insn(ctx, ISA_MIPS32R2);
6600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6601 rn = "IntCtl";
6602 break;
6603 case 2:
6604 check_insn(ctx, ISA_MIPS32R2);
6605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6606 rn = "SRSCtl";
6607 break;
6608 case 3:
6609 check_insn(ctx, ISA_MIPS32R2);
6610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6611 rn = "SRSMap";
6612 break;
6613 default:
6614 goto cp0_unimplemented;
6615 }
6616 break;
6617 case 13:
6618 switch (sel) {
6619 case 0:
6620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6621 rn = "Cause";
6622 break;
6623 default:
6624 goto cp0_unimplemented;
6625 }
6626 break;
6627 case 14:
6628 switch (sel) {
6629 case 0:
6630 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6631 rn = "EPC";
6632 break;
6633 default:
6634 goto cp0_unimplemented;
6635 }
6636 break;
6637 case 15:
6638 switch (sel) {
6639 case 0:
6640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6641 rn = "PRid";
6642 break;
6643 case 1:
6644 check_insn(ctx, ISA_MIPS32R2);
6645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6646 rn = "EBase";
6647 break;
6648 case 3:
6649 check_insn(ctx, ISA_MIPS32R2);
6650 CP0_CHECK(ctx->cmgcr);
6651 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6652 rn = "CMGCRBase";
6653 break;
6654 default:
6655 goto cp0_unimplemented;
6656 }
6657 break;
6658 case 16:
6659 switch (sel) {
6660 case 0:
6661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6662 rn = "Config";
6663 break;
6664 case 1:
6665 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6666 rn = "Config1";
6667 break;
6668 case 2:
6669 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6670 rn = "Config2";
6671 break;
6672 case 3:
6673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6674 rn = "Config3";
6675 break;
6676 case 4:
6677 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6678 rn = "Config4";
6679 break;
6680 case 5:
6681 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6682 rn = "Config5";
6683 break;
6684 /* 6,7 are implementation dependent */
6685 case 6:
6686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6687 rn = "Config6";
6688 break;
6689 case 7:
6690 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6691 rn = "Config7";
6692 break;
6693 default:
6694 goto cp0_unimplemented;
6695 }
6696 break;
6697 case 17:
6698 switch (sel) {
6699 case 0:
6700 gen_helper_dmfc0_lladdr(arg, cpu_env);
6701 rn = "LLAddr";
6702 break;
6703 case 1:
6704 CP0_CHECK(ctx->mrp);
6705 gen_helper_dmfc0_maar(arg, cpu_env);
6706 rn = "MAAR";
6707 break;
6708 case 2:
6709 CP0_CHECK(ctx->mrp);
6710 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6711 rn = "MAARI";
6712 break;
6713 default:
6714 goto cp0_unimplemented;
6715 }
6716 break;
6717 case 18:
6718 switch (sel) {
6719 case 0 ... 7:
6720 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6721 rn = "WatchLo";
6722 break;
6723 default:
6724 goto cp0_unimplemented;
6725 }
6726 break;
6727 case 19:
6728 switch (sel) {
6729 case 0 ... 7:
6730 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6731 rn = "WatchHi";
6732 break;
6733 default:
6734 goto cp0_unimplemented;
6735 }
6736 break;
6737 case 20:
6738 switch (sel) {
6739 case 0:
6740 check_insn(ctx, ISA_MIPS3);
6741 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6742 rn = "XContext";
6743 break;
6744 default:
6745 goto cp0_unimplemented;
6746 }
6747 break;
6748 case 21:
6749 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6750 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6751 switch (sel) {
6752 case 0:
6753 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6754 rn = "Framemask";
6755 break;
6756 default:
6757 goto cp0_unimplemented;
6758 }
6759 break;
6760 case 22:
6761 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6762 rn = "'Diagnostic"; /* implementation dependent */
6763 break;
6764 case 23:
6765 switch (sel) {
6766 case 0:
6767 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6768 rn = "Debug";
6769 break;
6770 case 1:
6771 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6772 rn = "TraceControl";
6773 goto cp0_unimplemented;
6774 case 2:
6775 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6776 rn = "TraceControl2";
6777 goto cp0_unimplemented;
6778 case 3:
6779 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6780 rn = "UserTraceData";
6781 goto cp0_unimplemented;
6782 case 4:
6783 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6784 rn = "TraceBPC";
6785 goto cp0_unimplemented;
6786 default:
6787 goto cp0_unimplemented;
6788 }
6789 break;
6790 case 24:
6791 switch (sel) {
6792 case 0:
6793 /* EJTAG support */
6794 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6795 rn = "DEPC";
6796 break;
6797 default:
6798 goto cp0_unimplemented;
6799 }
6800 break;
6801 case 25:
6802 switch (sel) {
6803 case 0:
6804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6805 rn = "Performance0";
6806 break;
6807 case 1:
6808 // gen_helper_dmfc0_performance1(arg);
6809 rn = "Performance1";
6810 goto cp0_unimplemented;
6811 case 2:
6812 // gen_helper_dmfc0_performance2(arg);
6813 rn = "Performance2";
6814 goto cp0_unimplemented;
6815 case 3:
6816 // gen_helper_dmfc0_performance3(arg);
6817 rn = "Performance3";
6818 goto cp0_unimplemented;
6819 case 4:
6820 // gen_helper_dmfc0_performance4(arg);
6821 rn = "Performance4";
6822 goto cp0_unimplemented;
6823 case 5:
6824 // gen_helper_dmfc0_performance5(arg);
6825 rn = "Performance5";
6826 goto cp0_unimplemented;
6827 case 6:
6828 // gen_helper_dmfc0_performance6(arg);
6829 rn = "Performance6";
6830 goto cp0_unimplemented;
6831 case 7:
6832 // gen_helper_dmfc0_performance7(arg);
6833 rn = "Performance7";
6834 goto cp0_unimplemented;
6835 default:
6836 goto cp0_unimplemented;
6837 }
6838 break;
6839 case 26:
6840 switch (sel) {
6841 case 0:
6842 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6843 rn = "ErrCtl";
6844 break;
6845 default:
6846 goto cp0_unimplemented;
6847 }
6848 break;
6849 case 27:
6850 switch (sel) {
6851 /* ignored */
6852 case 0 ... 3:
6853 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6854 rn = "CacheErr";
6855 break;
6856 default:
6857 goto cp0_unimplemented;
6858 }
6859 break;
6860 case 28:
6861 switch (sel) {
6862 case 0:
6863 case 2:
6864 case 4:
6865 case 6:
6866 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6867 rn = "TagLo";
6868 break;
6869 case 1:
6870 case 3:
6871 case 5:
6872 case 7:
6873 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6874 rn = "DataLo";
6875 break;
6876 default:
6877 goto cp0_unimplemented;
6878 }
6879 break;
6880 case 29:
6881 switch (sel) {
6882 case 0:
6883 case 2:
6884 case 4:
6885 case 6:
6886 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6887 rn = "TagHi";
6888 break;
6889 case 1:
6890 case 3:
6891 case 5:
6892 case 7:
6893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6894 rn = "DataHi";
6895 break;
6896 default:
6897 goto cp0_unimplemented;
6898 }
6899 break;
6900 case 30:
6901 switch (sel) {
6902 case 0:
6903 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6904 rn = "ErrorEPC";
6905 break;
6906 default:
6907 goto cp0_unimplemented;
6908 }
6909 break;
6910 case 31:
6911 switch (sel) {
6912 case 0:
6913 /* EJTAG support */
6914 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6915 rn = "DESAVE";
6916 break;
6917 case 2 ... 7:
6918 CP0_CHECK(ctx->kscrexist & (1 << sel));
6919 tcg_gen_ld_tl(arg, cpu_env,
6920 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6921 rn = "KScratch";
6922 break;
6923 default:
6924 goto cp0_unimplemented;
6925 }
6926 break;
6927 default:
6928 goto cp0_unimplemented;
6929 }
6930 trace_mips_translate_c0("dmfc0", rn, reg, sel);
6931 return;
6932
6933 cp0_unimplemented:
6934 qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6935 gen_mfc0_unimplemented(ctx, arg);
6936 }
6937
6938 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6939 {
6940 const char *rn = "invalid";
6941
6942 if (sel != 0)
6943 check_insn(ctx, ISA_MIPS64);
6944
6945 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6946 gen_io_start();
6947 }
6948
6949 switch (reg) {
6950 case 0:
6951 switch (sel) {
6952 case 0:
6953 gen_helper_mtc0_index(cpu_env, arg);
6954 rn = "Index";
6955 break;
6956 case 1:
6957 CP0_CHECK(ctx->insn_flags & ASE_MT);
6958 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6959 rn = "MVPControl";
6960 break;
6961 case 2:
6962 CP0_CHECK(ctx->insn_flags & ASE_MT);
6963 /* ignored */
6964 rn = "MVPConf0";
6965 break;
6966 case 3:
6967 CP0_CHECK(ctx->insn_flags & ASE_MT);
6968 /* ignored */
6969 rn = "MVPConf1";
6970 break;
6971 case 4:
6972 CP0_CHECK(ctx->vp);
6973 /* ignored */
6974 rn = "VPControl";
6975 break;
6976 default:
6977 goto cp0_unimplemented;
6978 }
6979 break;
6980 case 1:
6981 switch (sel) {
6982 case 0:
6983 /* ignored */
6984 rn = "Random";
6985 break;
6986 case 1:
6987 CP0_CHECK(ctx->insn_flags & ASE_MT);
6988 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6989 rn = "VPEControl";
6990 break;
6991 case 2:
6992 CP0_CHECK(ctx->insn_flags & ASE_MT);
6993 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6994 rn = "VPEConf0";
6995 break;
6996 case 3:
6997 CP0_CHECK(ctx->insn_flags & ASE_MT);
6998 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6999 rn = "VPEConf1";
7000 break;
7001 case 4:
7002 CP0_CHECK(ctx->insn_flags & ASE_MT);
7003 gen_helper_mtc0_yqmask(cpu_env, arg);
7004 rn = "YQMask";
7005 break;
7006 case 5:
7007 CP0_CHECK(ctx->insn_flags & ASE_MT);
7008 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7009 rn = "VPESchedule";
7010 break;
7011 case 6:
7012 CP0_CHECK(ctx->insn_flags & ASE_MT);
7013 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7014 rn = "VPEScheFBack";
7015 break;
7016 case 7:
7017 CP0_CHECK(ctx->insn_flags & ASE_MT);
7018 gen_helper_mtc0_vpeopt(cpu_env, arg);
7019 rn = "VPEOpt";
7020 break;
7021 default:
7022 goto cp0_unimplemented;
7023 }
7024 break;
7025 case 2:
7026 switch (sel) {
7027 case 0:
7028 gen_helper_dmtc0_entrylo0(cpu_env, arg);
7029 rn = "EntryLo0";
7030 break;
7031 case 1:
7032 CP0_CHECK(ctx->insn_flags & ASE_MT);
7033 gen_helper_mtc0_tcstatus(cpu_env, arg);
7034 rn = "TCStatus";
7035 break;
7036 case 2:
7037 CP0_CHECK(ctx->insn_flags & ASE_MT);
7038 gen_helper_mtc0_tcbind(cpu_env, arg);
7039 rn = "TCBind";
7040 break;
7041 case 3:
7042 CP0_CHECK(ctx->insn_flags & ASE_MT);
7043 gen_helper_mtc0_tcrestart(cpu_env, arg);
7044 rn = "TCRestart";
7045 break;
7046 case 4:
7047 CP0_CHECK(ctx->insn_flags & ASE_MT);
7048 gen_helper_mtc0_tchalt(cpu_env, arg);
7049 rn = "TCHalt";
7050 break;
7051 case 5:
7052 CP0_CHECK(ctx->insn_flags & ASE_MT);
7053 gen_helper_mtc0_tccontext(cpu_env, arg);
7054 rn = "TCContext";
7055 break;
7056 case 6:
7057 CP0_CHECK(ctx->insn_flags & ASE_MT);
7058 gen_helper_mtc0_tcschedule(cpu_env, arg);
7059 rn = "TCSchedule";
7060 break;
7061 case 7:
7062 CP0_CHECK(ctx->insn_flags & ASE_MT);
7063 gen_helper_mtc0_tcschefback(cpu_env, arg);
7064 rn = "TCScheFBack";
7065 break;
7066 default:
7067 goto cp0_unimplemented;
7068 }
7069 break;
7070 case 3:
7071 switch (sel) {
7072 case 0:
7073 gen_helper_dmtc0_entrylo1(cpu_env, arg);
7074 rn = "EntryLo1";
7075 break;
7076 case 1:
7077 CP0_CHECK(ctx->vp);
7078 /* ignored */
7079 rn = "GlobalNumber";
7080 break;
7081 default:
7082 goto cp0_unimplemented;
7083 }
7084 break;
7085 case 4:
7086 switch (sel) {
7087 case 0:
7088 gen_helper_mtc0_context(cpu_env, arg);
7089 rn = "Context";
7090 break;
7091 case 1:
7092 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7093 rn = "ContextConfig";
7094 goto cp0_unimplemented;
7095 case 2:
7096 CP0_CHECK(ctx->ulri);
7097 tcg_gen_st_tl(arg, cpu_env,
7098 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7099 rn = "UserLocal";
7100 break;
7101 default:
7102 goto cp0_unimplemented;
7103 }
7104 break;
7105 case 5:
7106 switch (sel) {
7107 case 0:
7108 gen_helper_mtc0_pagemask(cpu_env, arg);
7109 rn = "PageMask";
7110 break;
7111 case 1:
7112 check_insn(ctx, ISA_MIPS32R2);
7113 gen_helper_mtc0_pagegrain(cpu_env, arg);
7114 rn = "PageGrain";
7115 break;
7116 default:
7117 goto cp0_unimplemented;
7118 }
7119 break;
7120 case 6:
7121 switch (sel) {
7122 case 0:
7123 gen_helper_mtc0_wired(cpu_env, arg);
7124 rn = "Wired";
7125 break;
7126 case 1:
7127 check_insn(ctx, ISA_MIPS32R2);
7128 gen_helper_mtc0_srsconf0(cpu_env, arg);
7129 rn = "SRSConf0";
7130 break;
7131 case 2:
7132 check_insn(ctx, ISA_MIPS32R2);
7133 gen_helper_mtc0_srsconf1(cpu_env, arg);
7134 rn = "SRSConf1";
7135 break;
7136 case 3:
7137 check_insn(ctx, ISA_MIPS32R2);
7138 gen_helper_mtc0_srsconf2(cpu_env, arg);
7139 rn = "SRSConf2";
7140 break;
7141 case 4:
7142 check_insn(ctx, ISA_MIPS32R2);
7143 gen_helper_mtc0_srsconf3(cpu_env, arg);
7144 rn = "SRSConf3";
7145 break;
7146 case 5:
7147 check_insn(ctx, ISA_MIPS32R2);
7148 gen_helper_mtc0_srsconf4(cpu_env, arg);
7149 rn = "SRSConf4";
7150 break;
7151 default:
7152 goto cp0_unimplemented;
7153 }
7154 break;
7155 case 7:
7156 switch (sel) {
7157 case 0:
7158 check_insn(ctx, ISA_MIPS32R2);
7159 gen_helper_mtc0_hwrena(cpu_env, arg);
7160 ctx->bstate = BS_STOP;
7161 rn = "HWREna";
7162 break;
7163 default:
7164 goto cp0_unimplemented;
7165 }
7166 break;
7167 case 8:
7168 switch (sel) {
7169 case 0:
7170 /* ignored */
7171 rn = "BadVAddr";
7172 break;
7173 case 1:
7174 /* ignored */
7175 rn = "BadInstr";
7176 break;
7177 case 2:
7178 /* ignored */
7179 rn = "BadInstrP";
7180 break;
7181 default:
7182 goto cp0_unimplemented;
7183 }
7184 break;
7185 case 9:
7186 switch (sel) {
7187 case 0:
7188 gen_helper_mtc0_count(cpu_env, arg);
7189 rn = "Count";
7190 break;
7191 /* 6,7 are implementation dependent */
7192 default:
7193 goto cp0_unimplemented;
7194 }
7195 /* Stop translation as we may have switched the execution mode */
7196 ctx->bstate = BS_STOP;
7197 break;
7198 case 10:
7199 switch (sel) {
7200 case 0:
7201 gen_helper_mtc0_entryhi(cpu_env, arg);
7202 rn = "EntryHi";
7203 break;
7204 default:
7205 goto cp0_unimplemented;
7206 }
7207 break;
7208 case 11:
7209 switch (sel) {
7210 case 0:
7211 gen_helper_mtc0_compare(cpu_env, arg);
7212 rn = "Compare";
7213 break;
7214 /* 6,7 are implementation dependent */
7215 default:
7216 goto cp0_unimplemented;
7217 }
7218 /* Stop translation as we may have switched the execution mode */
7219 ctx->bstate = BS_STOP;
7220 break;
7221 case 12:
7222 switch (sel) {
7223 case 0:
7224 save_cpu_state(ctx, 1);
7225 gen_helper_mtc0_status(cpu_env, arg);
7226 /* BS_STOP isn't good enough here, hflags may have changed. */
7227 gen_save_pc(ctx->pc + 4);
7228 ctx->bstate = BS_EXCP;
7229 rn = "Status";
7230 break;
7231 case 1:
7232 check_insn(ctx, ISA_MIPS32R2);
7233 gen_helper_mtc0_intctl(cpu_env, arg);
7234 /* Stop translation as we may have switched the execution mode */
7235 ctx->bstate = BS_STOP;
7236 rn = "IntCtl";
7237 break;
7238 case 2:
7239 check_insn(ctx, ISA_MIPS32R2);
7240 gen_helper_mtc0_srsctl(cpu_env, arg);
7241 /* Stop translation as we may have switched the execution mode */
7242 ctx->bstate = BS_STOP;
7243 rn = "SRSCtl";
7244 break;
7245 case 3:
7246 check_insn(ctx, ISA_MIPS32R2);
7247 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7248 /* Stop translation as we may have switched the execution mode */
7249 ctx->bstate = BS_STOP;
7250 rn = "SRSMap";
7251 break;
7252 default:
7253 goto cp0_unimplemented;
7254 }
7255 break;
7256 case 13:
7257 switch (sel) {
7258 case 0:
7259 save_cpu_state(ctx, 1);
7260 /* Mark as an IO operation because we may trigger a software
7261 interrupt. */
7262 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7263 gen_io_start();
7264 }
7265 gen_helper_mtc0_cause(cpu_env, arg);
7266 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7267 gen_io_end();
7268 }
7269 /* Stop translation as we may have triggered an intetrupt */
7270 ctx->bstate = BS_STOP;
7271 rn = "Cause";
7272 break;
7273 default:
7274 goto cp0_unimplemented;
7275 }
7276 break;
7277 case 14:
7278 switch (sel) {
7279 case 0:
7280 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7281 rn = "EPC";
7282 break;
7283 default:
7284 goto cp0_unimplemented;
7285 }
7286 break;
7287 case 15:
7288 switch (sel) {
7289 case 0:
7290 /* ignored */
7291 rn = "PRid";
7292 break;
7293 case 1:
7294 check_insn(ctx, ISA_MIPS32R2);
7295 gen_helper_mtc0_ebase(cpu_env, arg);
7296 rn = "EBase";
7297 break;
7298 default:
7299 goto cp0_unimplemented;
7300 }
7301 break;
7302 case 16:
7303 switch (sel) {
7304 case 0:
7305 gen_helper_mtc0_config0(cpu_env, arg);
7306 rn = "Config";
7307 /* Stop translation as we may have switched the execution mode */
7308 ctx->bstate = BS_STOP;
7309 break;
7310 case 1:
7311 /* ignored, read only */
7312 rn = "Config1";
7313 break;
7314 case 2:
7315 gen_helper_mtc0_config2(cpu_env, arg);
7316 rn = "Config2";
7317 /* Stop translation as we may have switched the execution mode */
7318 ctx->bstate = BS_STOP;
7319 break;
7320 case 3:
7321 gen_helper_mtc0_config3(cpu_env, arg);
7322 rn = "Config3";
7323 /* Stop translation as we may have switched the execution mode */
7324 ctx->bstate = BS_STOP;
7325 break;
7326 case 4:
7327 /* currently ignored */
7328 rn = "Config4";
7329 break;
7330 case 5:
7331 gen_helper_mtc0_config5(cpu_env, arg);
7332 rn = "Config5";
7333 /* Stop translation as we may have switched the execution mode */
7334 ctx->bstate = BS_STOP;
7335 break;
7336 /* 6,7 are implementation dependent */
7337 default:
7338 rn = "Invalid config selector";
7339 goto cp0_unimplemented;
7340 }
7341 break;
7342 case 17:
7343 switch (sel) {
7344 case 0:
7345 gen_helper_mtc0_lladdr(cpu_env, arg);
7346 rn = "LLAddr";
7347 break;
7348 case 1:
7349 CP0_CHECK(ctx->mrp);
7350 gen_helper_mtc0_maar(cpu_env, arg);
7351 rn = "MAAR";
7352 break;
7353 case 2:
7354 CP0_CHECK(ctx->mrp);
7355 gen_helper_mtc0_maari(cpu_env, arg);
7356 rn = "MAARI";
7357 break;
7358 default:
7359 goto cp0_unimplemented;
7360 }
7361 break;
7362 case 18:
7363 switch (sel) {
7364 case 0 ... 7:
7365 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7366 rn = "WatchLo";
7367 break;
7368 default:
7369 goto cp0_unimplemented;
7370 }
7371 break;
7372 case 19:
7373 switch (sel) {
7374 case 0 ... 7:
7375 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7376 rn = "WatchHi";
7377 break;
7378 default:
7379 goto cp0_unimplemented;
7380 }
7381 break;
7382 case 20:
7383 switch (sel) {
7384 case 0:
7385 check_insn(ctx, ISA_MIPS3);
7386 gen_helper_mtc0_xcontext(cpu_env, arg);
7387 rn = "XContext";
7388 break;
7389 default:
7390 goto cp0_unimplemented;
7391 }
7392 break;
7393 case 21:
7394 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7395 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7396 switch (sel) {
7397 case 0:
7398 gen_helper_mtc0_framemask(cpu_env, arg);
7399 rn = "Framemask";
7400 break;
7401 default:
7402 goto cp0_unimplemented;
7403 }
7404 break;
7405 case 22:
7406 /* ignored */
7407 rn = "Diagnostic"; /* implementation dependent */
7408 break;
7409 case 23:
7410 switch (sel) {
7411 case 0:
7412 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7413 /* BS_STOP isn't good enough here, hflags may have changed. */
7414 gen_save_pc(ctx->pc + 4);
7415 ctx->bstate = BS_EXCP;
7416 rn = "Debug";
7417 break;
7418 case 1:
7419 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7420 /* Stop translation as we may have switched the execution mode */
7421 ctx->bstate = BS_STOP;
7422 rn = "TraceControl";
7423 goto cp0_unimplemented;
7424 case 2:
7425 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7426 /* Stop translation as we may have switched the execution mode */
7427 ctx->bstate = BS_STOP;
7428 rn = "TraceControl2";
7429 goto cp0_unimplemented;
7430 case 3:
7431 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7432 /* Stop translation as we may have switched the execution mode */
7433 ctx->bstate = BS_STOP;
7434 rn = "UserTraceData";
7435 goto cp0_unimplemented;
7436 case 4:
7437 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7438 /* Stop translation as we may have switched the execution mode */
7439 ctx->bstate = BS_STOP;
7440 rn = "TraceBPC";
7441 goto cp0_unimplemented;
7442 default:
7443 goto cp0_unimplemented;
7444 }
7445 break;
7446 case 24:
7447 switch (sel) {
7448 case 0:
7449 /* EJTAG support */
7450 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7451 rn = "DEPC";
7452 break;
7453 default:
7454 goto cp0_unimplemented;
7455 }
7456 break;
7457 case 25:
7458 switch (sel) {
7459 case 0:
7460 gen_helper_mtc0_performance0(cpu_env, arg);
7461 rn = "Performance0";
7462 break;
7463 case 1:
7464 // gen_helper_mtc0_performance1(cpu_env, arg);
7465 rn = "Performance1";
7466 goto cp0_unimplemented;
7467 case 2:
7468 // gen_helper_mtc0_performance2(cpu_env, arg);
7469 rn = "Performance2";
7470 goto cp0_unimplemented;
7471 case 3:
7472 // gen_helper_mtc0_performance3(cpu_env, arg);
7473 rn = "Performance3";
7474 goto cp0_unimplemented;
7475 case 4:
7476 // gen_helper_mtc0_performance4(cpu_env, arg);
7477 rn = "Performance4";
7478 goto cp0_unimplemented;
7479 case 5:
7480 // gen_helper_mtc0_performance5(cpu_env, arg);
7481 rn = "Performance5";
7482 goto cp0_unimplemented;
7483 case 6:
7484 // gen_helper_mtc0_performance6(cpu_env, arg);
7485 rn = "Performance6";
7486 goto cp0_unimplemented;
7487 case 7:
7488 // gen_helper_mtc0_performance7(cpu_env, arg);
7489 rn = "Performance7";
7490 goto cp0_unimplemented;
7491 default:
7492 goto cp0_unimplemented;
7493 }
7494 break;
7495 case 26:
7496 switch (sel) {
7497 case 0:
7498 gen_helper_mtc0_errctl(cpu_env, arg);
7499 ctx->bstate = BS_STOP;
7500 rn = "ErrCtl";
7501 break;
7502 default:
7503 goto cp0_unimplemented;
7504 }
7505 break;
7506 case 27:
7507 switch (sel) {
7508 case 0 ... 3:
7509 /* ignored */
7510 rn = "CacheErr";
7511 break;
7512 default:
7513 goto cp0_unimplemented;
7514 }
7515 break;
7516 case 28:
7517 switch (sel) {
7518 case 0:
7519 case 2:
7520 case 4:
7521 case 6:
7522 gen_helper_mtc0_taglo(cpu_env, arg);
7523 rn = "TagLo";
7524 break;
7525 case 1:
7526 case 3:
7527 case 5:
7528 case 7:
7529 gen_helper_mtc0_datalo(cpu_env, arg);
7530 rn = "DataLo";
7531 break;
7532 default:
7533 goto cp0_unimplemented;
7534 }
7535 break;
7536 case 29:
7537 switch (sel) {
7538 case 0:
7539 case 2:
7540 case 4:
7541 case 6:
7542 gen_helper_mtc0_taghi(cpu_env, arg);
7543 rn = "TagHi";
7544 break;
7545 case 1:
7546 case 3:
7547 case 5:
7548 case 7:
7549 gen_helper_mtc0_datahi(cpu_env, arg);
7550 rn = "DataHi";
7551 break;
7552 default:
7553 rn = "invalid sel";
7554 goto cp0_unimplemented;
7555 }
7556 break;
7557 case 30:
7558 switch (sel) {
7559 case 0:
7560 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7561 rn = "ErrorEPC";
7562 break;
7563 default:
7564 goto cp0_unimplemented;
7565 }
7566 break;
7567 case 31:
7568 switch (sel) {
7569 case 0:
7570 /* EJTAG support */
7571 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7572 rn = "DESAVE";
7573 break;
7574 case 2 ... 7:
7575 CP0_CHECK(ctx->kscrexist & (1 << sel));
7576 tcg_gen_st_tl(arg, cpu_env,
7577 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7578 rn = "KScratch";
7579 break;
7580 default:
7581 goto cp0_unimplemented;
7582 }
7583 /* Stop translation as we may have switched the execution mode */
7584 ctx->bstate = BS_STOP;
7585 break;
7586 default:
7587 goto cp0_unimplemented;
7588 }
7589 trace_mips_translate_c0("dmtc0", rn, reg, sel);
7590
7591 /* For simplicity assume that all writes can cause interrupts. */
7592 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7593 gen_io_end();
7594 ctx->bstate = BS_STOP;
7595 }
7596 return;
7597
7598 cp0_unimplemented:
7599 qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7600 }
7601 #endif /* TARGET_MIPS64 */
7602
7603 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7604 int u, int sel, int h)
7605 {
7606 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7607 TCGv t0 = tcg_temp_local_new();
7608
7609 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7610 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7611 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7612 tcg_gen_movi_tl(t0, -1);
7613 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7614 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7615 tcg_gen_movi_tl(t0, -1);
7616 else if (u == 0) {
7617 switch (rt) {
7618 case 1:
7619 switch (sel) {
7620 case 1:
7621 gen_helper_mftc0_vpecontrol(t0, cpu_env);
7622 break;
7623 case 2:
7624 gen_helper_mftc0_vpeconf0(t0, cpu_env);
7625 break;
7626 default:
7627 goto die;
7628 break;
7629 }
7630 break;
7631 case 2:
7632 switch (sel) {
7633 case 1:
7634 gen_helper_mftc0_tcstatus(t0, cpu_env);
7635 break;
7636 case 2:
7637 gen_helper_mftc0_tcbind(t0, cpu_env);
7638 break;
7639 case 3:
7640 gen_helper_mftc0_tcrestart(t0, cpu_env);
7641 break;
7642 case 4:
7643 gen_helper_mftc0_tchalt(t0, cpu_env);
7644 break;
7645 case 5:
7646 gen_helper_mftc0_tccontext(t0, cpu_env);
7647 break;
7648 case 6:
7649 gen_helper_mftc0_tcschedule(t0, cpu_env);
7650 break;
7651 case 7:
7652 gen_helper_mftc0_tcschefback(t0, cpu_env);
7653 break;
7654 default:
7655 gen_mfc0(ctx, t0, rt, sel);
7656 break;
7657 }
7658 break;
7659 case 10:
7660 switch (sel) {
7661 case 0:
7662 gen_helper_mftc0_entryhi(t0, cpu_env);
7663 break;
7664 default:
7665 gen_mfc0(ctx, t0, rt, sel);
7666 break;
7667 }
7668 case 12:
7669 switch (sel) {
7670 case 0:
7671 gen_helper_mftc0_status(t0, cpu_env);
7672 break;
7673 default:
7674 gen_mfc0(ctx, t0, rt, sel);
7675 break;
7676 }
7677 case 13:
7678 switch (sel) {
7679 case 0:
7680 gen_helper_mftc0_cause(t0, cpu_env);
7681 break;
7682 default:
7683 goto die;
7684 break;
7685 }
7686 break;
7687 case 14:
7688 switch (sel) {
7689 case 0:
7690 gen_helper_mftc0_epc(t0, cpu_env);
7691 break;
7692 default:
7693 goto die;
7694 break;
7695 }
7696 break;
7697 case 15:
7698 switch (sel) {
7699 case 1:
7700 gen_helper_mftc0_ebase(t0, cpu_env);
7701 break;
7702 default:
7703 goto die;
7704 break;
7705 }
7706 break;
7707 case 16:
7708 switch (sel) {
7709 case 0 ... 7:
7710 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7711 break;
7712 default:
7713 goto die;
7714 break;
7715 }
7716 break;
7717 case 23:
7718 switch (sel) {
7719 case 0:
7720 gen_helper_mftc0_debug(t0, cpu_env);
7721 break;
7722 default:
7723 gen_mfc0(ctx, t0, rt, sel);
7724 break;
7725 }
7726 break;
7727 default:
7728 gen_mfc0(ctx, t0, rt, sel);
7729 }
7730 } else switch (sel) {
7731 /* GPR registers. */
7732 case 0:
7733 gen_helper_1e0i(mftgpr, t0, rt);
7734 break;
7735 /* Auxiliary CPU registers */
7736 case 1:
7737 switch (rt) {
7738 case 0:
7739 gen_helper_1e0i(mftlo, t0, 0);
7740 break;
7741 case 1:
7742 gen_helper_1e0i(mfthi, t0, 0);
7743 break;
7744 case 2:
7745 gen_helper_1e0i(mftacx, t0, 0);
7746 break;
7747 case 4:
7748 gen_helper_1e0i(mftlo, t0, 1);
7749 break;
7750 case 5:
7751 gen_helper_1e0i(mfthi, t0, 1);
7752 break;
7753 case 6:
7754 gen_helper_1e0i(mftacx, t0, 1);
7755 break;
7756 case 8:
7757 gen_helper_1e0i(mftlo, t0, 2);
7758 break;
7759 case 9:
7760 gen_helper_1e0i(mfthi, t0, 2);
7761 break;
7762 case 10:
7763 gen_helper_1e0i(mftacx, t0, 2);
7764 break;
7765 case 12:
7766 gen_helper_1e0i(mftlo, t0, 3);
7767 break;
7768 case 13:
7769 gen_helper_1e0i(mfthi, t0, 3);
7770 break;
7771 case 14:
7772 gen_helper_1e0i(mftacx, t0, 3);
7773 break;
7774 case 16:
7775 gen_helper_mftdsp(t0, cpu_env);
7776 break;
7777 default:
7778 goto die;
7779 }
7780 break;
7781 /* Floating point (COP1). */
7782 case 2:
7783 /* XXX: For now we support only a single FPU context. */
7784 if (h == 0) {
7785 TCGv_i32 fp0 = tcg_temp_new_i32();
7786
7787 gen_load_fpr32(ctx, fp0, rt);
7788 tcg_gen_ext_i32_tl(t0, fp0);
7789 tcg_temp_free_i32(fp0);
7790 } else {
7791 TCGv_i32 fp0 = tcg_temp_new_i32();
7792
7793 gen_load_fpr32h(ctx, fp0, rt);
7794 tcg_gen_ext_i32_tl(t0, fp0);
7795 tcg_temp_free_i32(fp0);
7796 }
7797 break;
7798 case 3:
7799 /* XXX: For now we support only a single FPU context. */
7800 gen_helper_1e0i(cfc1, t0, rt);
7801 break;
7802 /* COP2: Not implemented. */
7803 case 4:
7804 case 5:
7805 /* fall through */
7806 default:
7807 goto die;
7808 }
7809 trace_mips_translate_tr("mftr", rt, u, sel, h);
7810 gen_store_gpr(t0, rd);
7811 tcg_temp_free(t0);
7812 return;
7813
7814 die:
7815 tcg_temp_free(t0);
7816 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7817 generate_exception_end(ctx, EXCP_RI);
7818 }
7819
7820 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7821 int u, int sel, int h)
7822 {
7823 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7824 TCGv t0 = tcg_temp_local_new();
7825
7826 gen_load_gpr(t0, rt);
7827 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7828 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7829 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7830 /* NOP */ ;
7831 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7832 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7833 /* NOP */ ;
7834 else if (u == 0) {
7835 switch (rd) {
7836 case 1:
7837 switch (sel) {
7838 case 1:
7839 gen_helper_mttc0_vpecontrol(cpu_env, t0);
7840 break;
7841 case 2:
7842 gen_helper_mttc0_vpeconf0(cpu_env, t0);
7843 break;
7844 default:
7845 goto die;
7846 break;
7847 }
7848 break;
7849 case 2:
7850 switch (sel) {
7851 case 1:
7852 gen_helper_mttc0_tcstatus(cpu_env, t0);
7853 break;
7854 case 2:
7855 gen_helper_mttc0_tcbind(cpu_env, t0);
7856 break;
7857 case 3:
7858 gen_helper_mttc0_tcrestart(cpu_env, t0);
7859 break;
7860 case 4:
7861 gen_helper_mttc0_tchalt(cpu_env, t0);
7862 break;
7863 case 5:
7864 gen_helper_mttc0_tccontext(cpu_env, t0);
7865 break;
7866 case 6:
7867 gen_helper_mttc0_tcschedule(cpu_env, t0);
7868 break;
7869 case 7:
7870 gen_helper_mttc0_tcschefback(cpu_env, t0);
7871 break;
7872 default:
7873 gen_mtc0(ctx, t0, rd, sel);
7874 break;
7875 }
7876 break;
7877 case 10:
7878 switch (sel) {
7879 case 0:
7880 gen_helper_mttc0_entryhi(cpu_env, t0);
7881 break;
7882 default:
7883 gen_mtc0(ctx, t0, rd, sel);
7884 break;
7885 }
7886 case 12:
7887 switch (sel) {
7888 case 0:
7889 gen_helper_mttc0_status(cpu_env, t0);
7890 break;
7891 default:
7892 gen_mtc0(ctx, t0, rd, sel);
7893 break;
7894 }
7895 case 13:
7896 switch (sel) {
7897 case 0:
7898 gen_helper_mttc0_cause(cpu_env, t0);
7899 break;
7900 default:
7901 goto die;
7902 break;
7903 }
7904 break;
7905 case 15:
7906 switch (sel) {
7907 case 1:
7908 gen_helper_mttc0_ebase(cpu_env, t0);
7909 break;
7910 default:
7911 goto die;
7912 break;
7913 }
7914 break;
7915 case 23:
7916 switch (sel) {
7917 case 0:
7918 gen_helper_mttc0_debug(cpu_env, t0);
7919 break;
7920 default:
7921 gen_mtc0(ctx, t0, rd, sel);
7922 break;
7923 }
7924 break;
7925 default:
7926 gen_mtc0(ctx, t0, rd, sel);
7927 }
7928 } else switch (sel) {
7929 /* GPR registers. */
7930 case 0:
7931 gen_helper_0e1i(mttgpr, t0, rd);
7932 break;
7933 /* Auxiliary CPU registers */
7934 case 1:
7935 switch (rd) {
7936 case 0:
7937 gen_helper_0e1i(mttlo, t0, 0);
7938 break;
7939 case 1:
7940 gen_helper_0e1i(mtthi, t0, 0);
7941 break;
7942 case 2:
7943 gen_helper_0e1i(mttacx, t0, 0);
7944 break;
7945 case 4:
7946 gen_helper_0e1i(mttlo, t0, 1);
7947 break;
7948 case 5:
7949 gen_helper_0e1i(mtthi, t0, 1);
7950 break;
7951 case 6:
7952 gen_helper_0e1i(mttacx, t0, 1);
7953 break;
7954 case 8:
7955 gen_helper_0e1i(mttlo, t0, 2);
7956 break;
7957 case 9:
7958 gen_helper_0e1i(mtthi, t0, 2);
7959 break;
7960 case 10:
7961 gen_helper_0e1i(mttacx, t0, 2);
7962 break;
7963 case 12:
7964 gen_helper_0e1i(mttlo, t0, 3);
7965 break;
7966 case 13:
7967 gen_helper_0e1i(mtthi, t0, 3);
7968 break;
7969 case 14:
7970 gen_helper_0e1i(mttacx, t0, 3);
7971 break;
7972 case 16:
7973 gen_helper_mttdsp(cpu_env, t0);
7974 break;
7975 default:
7976 goto die;
7977 }
7978 break;
7979 /* Floating point (COP1). */
7980 case 2:
7981 /* XXX: For now we support only a single FPU context. */
7982 if (h == 0) {
7983 TCGv_i32 fp0 = tcg_temp_new_i32();
7984
7985 tcg_gen_trunc_tl_i32(fp0, t0);
7986 gen_store_fpr32(ctx, fp0, rd);
7987 tcg_temp_free_i32(fp0);
7988 } else {
7989 TCGv_i32 fp0 = tcg_temp_new_i32();
7990
7991 tcg_gen_trunc_tl_i32(fp0, t0);
7992 gen_store_fpr32h(ctx, fp0, rd);
7993 tcg_temp_free_i32(fp0);
7994 }
7995 break;
7996 case 3:
7997 /* XXX: For now we support only a single FPU context. */
7998 {
7999 TCGv_i32 fs_tmp = tcg_const_i32(rd);
8000
8001 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8002 tcg_temp_free_i32(fs_tmp);
8003 }
8004 /* Stop translation as we may have changed hflags */
8005 ctx->bstate = BS_STOP;
8006 break;
8007 /* COP2: Not implemented. */
8008 case 4:
8009 case 5:
8010 /* fall through */
8011 default:
8012 goto die;
8013 }
8014 trace_mips_translate_tr("mttr", rd, u, sel, h);
8015 tcg_temp_free(t0);
8016 return;
8017
8018 die:
8019 tcg_temp_free(t0);
8020 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
8021 generate_exception_end(ctx, EXCP_RI);
8022 }
8023
8024 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
8025 {
8026 const char *opn = "ldst";
8027
8028 check_cp0_enabled(ctx);
8029 switch (opc) {
8030 case OPC_MFC0:
8031 if (rt == 0) {
8032 /* Treat as NOP. */
8033 return;
8034 }
8035 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8036 opn = "mfc0";
8037 break;
8038 case OPC_MTC0:
8039 {
8040 TCGv t0 = tcg_temp_new();
8041
8042 gen_load_gpr(t0, rt);
8043 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
8044 tcg_temp_free(t0);
8045 }
8046 opn = "mtc0";
8047 break;
8048 #if defined(TARGET_MIPS64)
8049 case OPC_DMFC0:
8050 check_insn(ctx, ISA_MIPS3);
8051 if (rt == 0) {
8052 /* Treat as NOP. */
8053 return;
8054 }
8055 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8056 opn = "dmfc0";
8057 break;
8058 case OPC_DMTC0:
8059 check_insn(ctx, ISA_MIPS3);
8060 {
8061 TCGv t0 = tcg_temp_new();
8062
8063 gen_load_gpr(t0, rt);
8064 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
8065 tcg_temp_free(t0);
8066 }
8067 opn = "dmtc0";
8068 break;
8069 #endif
8070 case OPC_MFHC0:
8071 check_mvh(ctx);
8072 if (rt == 0) {
8073 /* Treat as NOP. */
8074 return;
8075 }
8076 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
8077 opn = "mfhc0";
8078 break;
8079 case OPC_MTHC0:
8080 check_mvh(ctx);
8081 {
8082 TCGv t0 = tcg_temp_new();
8083 gen_load_gpr(t0, rt);
8084 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
8085 tcg_temp_free(t0);
8086 }
8087 opn = "mthc0";
8088 break;
8089 case OPC_MFTR:
8090 check_insn(ctx, ASE_MT);
8091 if (rd == 0) {
8092 /* Treat as NOP. */
8093 return;
8094 }
8095 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8096 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8097 opn = "mftr";
8098 break;
8099 case OPC_MTTR:
8100 check_insn(ctx, ASE_MT);
8101 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8102 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8103 opn = "mttr";
8104 break;
8105 case OPC_TLBWI:
8106 opn = "tlbwi";
8107 if (!env->tlb->helper_tlbwi)
8108 goto die;
8109 gen_helper_tlbwi(cpu_env);
8110 break;
8111 case OPC_TLBINV:
8112 opn = "tlbinv";
8113 if (ctx->ie >= 2) {
8114 if (!env->tlb->helper_tlbinv) {
8115 goto die;
8116 }
8117 gen_helper_tlbinv(cpu_env);
8118 } /* treat as nop if TLBINV not supported */
8119 break;
8120 case OPC_TLBINVF:
8121 opn = "tlbinvf";
8122 if (ctx->ie >= 2) {
8123 if (!env->tlb->helper_tlbinvf) {
8124 goto die;
8125 }
8126 gen_helper_tlbinvf(cpu_env);
8127 } /* treat as nop if TLBINV not supported */
8128 break;
8129 case OPC_TLBWR:
8130 opn = "tlbwr";
8131 if (!env->tlb->helper_tlbwr)
8132 goto die;
8133 gen_helper_tlbwr(cpu_env);
8134 break;
8135 case OPC_TLBP:
8136 opn = "tlbp";
8137 if (!env->tlb->helper_tlbp)
8138 goto die;
8139 gen_helper_tlbp(cpu_env);
8140 break;
8141 case OPC_TLBR:
8142 opn = "tlbr";
8143 if (!env->tlb->helper_tlbr)
8144 goto die;
8145 gen_helper_tlbr(cpu_env);
8146 break;
8147 case OPC_ERET: /* OPC_ERETNC */
8148 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8149 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8150 goto die;
8151 } else {
8152 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8153 if (ctx->opcode & (1 << bit_shift)) {
8154 /* OPC_ERETNC */
8155 opn = "eretnc";
8156 check_insn(ctx, ISA_MIPS32R5);
8157 gen_helper_eretnc(cpu_env);
8158 } else {
8159 /* OPC_ERET */
8160 opn = "eret";
8161 check_insn(ctx, ISA_MIPS2);
8162 gen_helper_eret(cpu_env);
8163 }
8164 ctx->bstate = BS_EXCP;
8165 }
8166 break;
8167 case OPC_DERET:
8168 opn = "deret";
8169 check_insn(ctx, ISA_MIPS32);
8170 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8171 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8172 goto die;
8173 }
8174 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8175 MIPS_INVAL(opn);
8176 generate_exception_end(ctx, EXCP_RI);
8177 } else {
8178 gen_helper_deret(cpu_env);
8179 ctx->bstate = BS_EXCP;
8180 }
8181 break;
8182 case OPC_WAIT:
8183 opn = "wait";
8184 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8185 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8186 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8187 goto die;
8188 }
8189 /* If we get an exception, we want to restart at next instruction */
8190 ctx->pc += 4;
8191 save_cpu_state(ctx, 1);
8192 ctx->pc -= 4;
8193 gen_helper_wait(cpu_env);
8194 ctx->bstate = BS_EXCP;
8195 break;
8196 default:
8197 die:
8198 MIPS_INVAL(opn);
8199 generate_exception_end(ctx, EXCP_RI);
8200 return;
8201 }
8202 (void)opn; /* avoid a compiler warning */
8203 }
8204 #endif /* !CONFIG_USER_ONLY */
8205
8206 /* CP1 Branches (before delay slot) */
8207 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8208 int32_t cc, int32_t offset)
8209 {
8210 target_ulong btarget;
8211 TCGv_i32 t0 = tcg_temp_new_i32();
8212
8213 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8214 generate_exception_end(ctx, EXCP_RI);
8215 goto out;
8216 }
8217
8218 if (cc != 0)
8219 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8220
8221 btarget = ctx->pc + 4 + offset;
8222
8223 switch (op) {
8224 case OPC_BC1F:
8225 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8226 tcg_gen_not_i32(t0, t0);
8227 tcg_gen_andi_i32(t0, t0, 1);
8228 tcg_gen_extu_i32_tl(bcond, t0);
8229 goto not_likely;
8230 case OPC_BC1FL:
8231 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8232 tcg_gen_not_i32(t0, t0);
8233 tcg_gen_andi_i32(t0, t0, 1);
8234 tcg_gen_extu_i32_tl(bcond, t0);
8235 goto likely;
8236 case OPC_BC1T:
8237 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8238 tcg_gen_andi_i32(t0, t0, 1);
8239 tcg_gen_extu_i32_tl(bcond, t0);
8240 goto not_likely;
8241 case OPC_BC1TL:
8242 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8243 tcg_gen_andi_i32(t0, t0, 1);
8244 tcg_gen_extu_i32_tl(bcond, t0);
8245 likely:
8246 ctx->hflags |= MIPS_HFLAG_BL;
8247 break;
8248 case OPC_BC1FANY2:
8249 {
8250 TCGv_i32 t1 = tcg_temp_new_i32();
8251 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8252 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8253 tcg_gen_nand_i32(t0, t0, t1);
8254 tcg_temp_free_i32(t1);
8255 tcg_gen_andi_i32(t0, t0, 1);
8256 tcg_gen_extu_i32_tl(bcond, t0);
8257 }
8258 goto not_likely;
8259 case OPC_BC1TANY2:
8260 {
8261 TCGv_i32 t1 = tcg_temp_new_i32();
8262 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8263 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8264 tcg_gen_or_i32(t0, t0, t1);
8265 tcg_temp_free_i32(t1);
8266 tcg_gen_andi_i32(t0, t0, 1);
8267 tcg_gen_extu_i32_tl(bcond, t0);
8268 }
8269 goto not_likely;
8270 case OPC_BC1FANY4:
8271 {
8272 TCGv_i32 t1 = tcg_temp_new_i32();
8273 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8274 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8275 tcg_gen_and_i32(t0, t0, t1);
8276 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8277 tcg_gen_and_i32(t0, t0, t1);
8278 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8279 tcg_gen_nand_i32(t0, t0, t1);
8280 tcg_temp_free_i32(t1);
8281 tcg_gen_andi_i32(t0, t0, 1);
8282 tcg_gen_extu_i32_tl(bcond, t0);
8283 }
8284 goto not_likely;
8285 case OPC_BC1TANY4:
8286 {
8287 TCGv_i32 t1 = tcg_temp_new_i32();
8288 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8289 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8290 tcg_gen_or_i32(t0, t0, t1);
8291 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8292 tcg_gen_or_i32(t0, t0, t1);
8293 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8294 tcg_gen_or_i32(t0, t0, t1);
8295 tcg_temp_free_i32(t1);
8296 tcg_gen_andi_i32(t0, t0, 1);
8297 tcg_gen_extu_i32_tl(bcond, t0);
8298 }
8299 not_likely:
8300 ctx->hflags |= MIPS_HFLAG_BC;
8301 break;
8302 default:
8303 MIPS_INVAL("cp1 cond branch");
8304 generate_exception_end(ctx, EXCP_RI);
8305 goto out;
8306 }
8307 ctx->btarget = btarget;
8308 ctx->hflags |= MIPS_HFLAG_BDS32;
8309 out:
8310 tcg_temp_free_i32(t0);
8311 }
8312
8313 /* R6 CP1 Branches */
8314 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8315 int32_t ft, int32_t offset,
8316 int delayslot_size)
8317 {
8318 target_ulong btarget;
8319 TCGv_i64 t0 = tcg_temp_new_i64();
8320
8321 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8322 #ifdef MIPS_DEBUG_DISAS
8323 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8324 "\n", ctx->pc);
8325 #endif
8326 generate_exception_end(ctx, EXCP_RI);
8327 goto out;
8328 }
8329
8330 gen_load_fpr64(ctx, t0, ft);
8331 tcg_gen_andi_i64(t0, t0, 1);
8332
8333 btarget = addr_add(ctx, ctx->pc + 4, offset);
8334
8335 switch (op) {
8336 case OPC_BC1EQZ:
8337 tcg_gen_xori_i64(t0, t0, 1);
8338 ctx->hflags |= MIPS_HFLAG_BC;
8339 break;
8340 case OPC_BC1NEZ:
8341 /* t0 already set */
8342 ctx->hflags |= MIPS_HFLAG_BC;
8343 break;
8344 default:
8345 MIPS_INVAL("cp1 cond branch");
8346 generate_exception_end(ctx, EXCP_RI);
8347 goto out;
8348 }
8349
8350 tcg_gen_trunc_i64_tl(bcond, t0);
8351
8352 ctx->btarget = btarget;
8353
8354 switch (delayslot_size) {
8355 case 2:
8356 ctx->hflags |= MIPS_HFLAG_BDS16;
8357 break;
8358 case 4:
8359 ctx->hflags |= MIPS_HFLAG_BDS32;
8360 break;
8361 }
8362
8363 out:
8364 tcg_temp_free_i64(t0);
8365 }
8366
8367 /* Coprocessor 1 (FPU) */
8368
8369 #define FOP(func, fmt) (((fmt) << 21) | (func))
8370
8371 enum fopcode {
8372 OPC_ADD_S = FOP(0, FMT_S),
8373 OPC_SUB_S = FOP(1, FMT_S),
8374 OPC_MUL_S = FOP(2, FMT_S),
8375 OPC_DIV_S = FOP(3, FMT_S),
8376 OPC_SQRT_S = FOP(4, FMT_S),
8377 OPC_ABS_S = FOP(5, FMT_S),
8378 OPC_MOV_S = FOP(6, FMT_S),
8379 OPC_NEG_S = FOP(7, FMT_S),
8380 OPC_ROUND_L_S = FOP(8, FMT_S),
8381 OPC_TRUNC_L_S = FOP(9, FMT_S),
8382 OPC_CEIL_L_S = FOP(10, FMT_S),
8383 OPC_FLOOR_L_S = FOP(11, FMT_S),
8384 OPC_ROUND_W_S = FOP(12, FMT_S),
8385 OPC_TRUNC_W_S = FOP(13, FMT_S),
8386 OPC_CEIL_W_S = FOP(14, FMT_S),
8387 OPC_FLOOR_W_S = FOP(15, FMT_S),
8388 OPC_SEL_S = FOP(16, FMT_S),
8389 OPC_MOVCF_S = FOP(17, FMT_S),
8390 OPC_MOVZ_S = FOP(18, FMT_S),
8391 OPC_MOVN_S = FOP(19, FMT_S),
8392 OPC_SELEQZ_S = FOP(20, FMT_S),
8393 OPC_RECIP_S = FOP(21, FMT_S),
8394 OPC_RSQRT_S = FOP(22, FMT_S),
8395 OPC_SELNEZ_S = FOP(23, FMT_S),
8396 OPC_MADDF_S = FOP(24, FMT_S),
8397 OPC_MSUBF_S = FOP(25, FMT_S),
8398 OPC_RINT_S = FOP(26, FMT_S),
8399 OPC_CLASS_S = FOP(27, FMT_S),
8400 OPC_MIN_S = FOP(28, FMT_S),
8401 OPC_RECIP2_S = FOP(28, FMT_S),
8402 OPC_MINA_S = FOP(29, FMT_S),
8403 OPC_RECIP1_S = FOP(29, FMT_S),
8404 OPC_MAX_S = FOP(30, FMT_S),
8405 OPC_RSQRT1_S = FOP(30, FMT_S),
8406 OPC_MAXA_S = FOP(31, FMT_S),
8407 OPC_RSQRT2_S = FOP(31, FMT_S),
8408 OPC_CVT_D_S = FOP(33, FMT_S),
8409 OPC_CVT_W_S = FOP(36, FMT_S),
8410 OPC_CVT_L_S = FOP(37, FMT_S),
8411 OPC_CVT_PS_S = FOP(38, FMT_S),
8412 OPC_CMP_F_S = FOP (48, FMT_S),
8413 OPC_CMP_UN_S = FOP (49, FMT_S),
8414 OPC_CMP_EQ_S = FOP (50, FMT_S),
8415 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8416 OPC_CMP_OLT_S = FOP (52, FMT_S),
8417 OPC_CMP_ULT_S = FOP (53, FMT_S),
8418 OPC_CMP_OLE_S = FOP (54, FMT_S),
8419 OPC_CMP_ULE_S = FOP (55, FMT_S),
8420 OPC_CMP_SF_S = FOP (56, FMT_S),
8421 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8422 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8423 OPC_CMP_NGL_S = FOP (59, FMT_S),
8424 OPC_CMP_LT_S = FOP (60, FMT_S),
8425 OPC_CMP_NGE_S = FOP (61, FMT_S),
8426 OPC_CMP_LE_S = FOP (62, FMT_S),
8427 OPC_CMP_NGT_S = FOP (63, FMT_S),
8428
8429 OPC_ADD_D = FOP(0, FMT_D),
8430 OPC_SUB_D = FOP(1, FMT_D),
8431 OPC_MUL_D = FOP(2, FMT_D),
8432 OPC_DIV_D = FOP(3, FMT_D),
8433 OPC_SQRT_D = FOP(4, FMT_D),
8434 OPC_ABS_D = FOP(5, FMT_D),
8435 OPC_MOV_D = FOP(6, FMT_D),
8436 OPC_NEG_D = FOP(7, FMT_D),
8437 OPC_ROUND_L_D = FOP(8, FMT_D),
8438 OPC_TRUNC_L_D = FOP(9, FMT_D),
8439 OPC_CEIL_L_D = FOP(10, FMT_D),
8440 OPC_FLOOR_L_D = FOP(11, FMT_D),
8441 OPC_ROUND_W_D = FOP(12, FMT_D),
8442 OPC_TRUNC_W_D = FOP(13, FMT_D),
8443 OPC_CEIL_W_D = FOP(14, FMT_D),
8444 OPC_FLOOR_W_D = FOP(15, FMT_D),
8445 OPC_SEL_D = FOP(16, FMT_D),
8446 OPC_MOVCF_D = FOP(17, FMT_D),
8447 OPC_MOVZ_D = FOP(18, FMT_D),
8448 OPC_MOVN_D = FOP(19, FMT_D),
8449 OPC_SELEQZ_D = FOP(20, FMT_D),
8450 OPC_RECIP_D = FOP(21, FMT_D),
8451 OPC_RSQRT_D = FOP(22, FMT_D),
8452 OPC_SELNEZ_D = FOP(23, FMT_D),
8453 OPC_MADDF_D = FOP(24, FMT_D),
8454 OPC_MSUBF_D = FOP(25, FMT_D),
8455 OPC_RINT_D = FOP(26, FMT_D),
8456 OPC_CLASS_D = FOP(27, FMT_D),
8457 OPC_MIN_D = FOP(28, FMT_D),
8458 OPC_RECIP2_D = FOP(28, FMT_D),
8459 OPC_MINA_D = FOP(29, FMT_D),
8460 OPC_RECIP1_D = FOP(29, FMT_D),
8461 OPC_MAX_D = FOP(30, FMT_D),
8462 OPC_RSQRT1_D = FOP(30, FMT_D),
8463 OPC_MAXA_D = FOP(31, FMT_D),
8464 OPC_RSQRT2_D = FOP(31, FMT_D),
8465 OPC_CVT_S_D = FOP(32, FMT_D),
8466 OPC_CVT_W_D = FOP(36, FMT_D),
8467 OPC_CVT_L_D = FOP(37, FMT_D),
8468 OPC_CMP_F_D = FOP (48, FMT_D),
8469 OPC_CMP_UN_D = FOP (49, FMT_D),
8470 OPC_CMP_EQ_D = FOP (50, FMT_D),
8471 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8472 OPC_CMP_OLT_D = FOP (52, FMT_D),
8473 OPC_CMP_ULT_D = FOP (53, FMT_D),
8474 OPC_CMP_OLE_D = FOP (54, FMT_D),
8475 OPC_CMP_ULE_D = FOP (55, FMT_D),
8476 OPC_CMP_SF_D = FOP (56, FMT_D),
8477 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8478 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8479 OPC_CMP_NGL_D = FOP (59, FMT_D),
8480 OPC_CMP_LT_D = FOP (60, FMT_D),
8481 OPC_CMP_NGE_D = FOP (61, FMT_D),
8482 OPC_CMP_LE_D = FOP (62, FMT_D),
8483 OPC_CMP_NGT_D = FOP (63, FMT_D),
8484
8485 OPC_CVT_S_W = FOP(32, FMT_W),
8486 OPC_CVT_D_W = FOP(33, FMT_W),
8487 OPC_CVT_S_L = FOP(32, FMT_L),
8488 OPC_CVT_D_L = FOP(33, FMT_L),
8489 OPC_CVT_PS_PW = FOP(38, FMT_W),
8490
8491 OPC_ADD_PS = FOP(0, FMT_PS),
8492 OPC_SUB_PS = FOP(1, FMT_PS),
8493 OPC_MUL_PS = FOP(2, FMT_PS),
8494 OPC_DIV_PS = FOP(3, FMT_PS),
8495 OPC_ABS_PS = FOP(5, FMT_PS),
8496 OPC_MOV_PS = FOP(6, FMT_PS),
8497 OPC_NEG_PS = FOP(7, FMT_PS),
8498 OPC_MOVCF_PS = FOP(17, FMT_PS),
8499 OPC_MOVZ_PS = FOP(18, FMT_PS),
8500 OPC_MOVN_PS = FOP(19, FMT_PS),
8501 OPC_ADDR_PS = FOP(24, FMT_PS),
8502 OPC_MULR_PS = FOP(26, FMT_PS),
8503 OPC_RECIP2_PS = FOP(28, FMT_PS),
8504 OPC_RECIP1_PS = FOP(29, FMT_PS),
8505 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8506 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8507
8508 OPC_CVT_S_PU = FOP(32, FMT_PS),
8509 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8510 OPC_CVT_S_PL = FOP(40, FMT_PS),
8511 OPC_PLL_PS = FOP(44, FMT_PS),
8512 OPC_PLU_PS = FOP(45, FMT_PS),
8513 OPC_PUL_PS = FOP(46, FMT_PS),
8514 OPC_PUU_PS = FOP(47, FMT_PS),
8515 OPC_CMP_F_PS = FOP (48, FMT_PS),
8516 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8517 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8518 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8519 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8520 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8521 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8522 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8523 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8524 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8525 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8526 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8527 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8528 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8529 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8530 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8531 };
8532
8533 enum r6_f_cmp_op {
8534 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8535 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8536 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8537 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8538 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8539 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8540 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8541 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8542 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8543 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8544 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8545 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8546 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8547 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8548 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8549 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8550 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8551 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8552 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8553 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8554 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8555 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8556
8557 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8558 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8559 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8560 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8561 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8562 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8563 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8564 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8565 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8566 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8567 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8568 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8569 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8570 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8571 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8572 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8573 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8574 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8575 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8576 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8577 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8578 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8579 };
8580 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8581 {
8582 TCGv t0 = tcg_temp_new();
8583
8584 switch (opc) {
8585 case OPC_MFC1:
8586 {
8587 TCGv_i32 fp0 = tcg_temp_new_i32();
8588
8589 gen_load_fpr32(ctx, fp0, fs);
8590 tcg_gen_ext_i32_tl(t0, fp0);
8591 tcg_temp_free_i32(fp0);
8592 }
8593 gen_store_gpr(t0, rt);
8594 break;
8595 case OPC_MTC1:
8596 gen_load_gpr(t0, rt);
8597 {
8598 TCGv_i32 fp0 = tcg_temp_new_i32();
8599
8600 tcg_gen_trunc_tl_i32(fp0, t0);
8601 gen_store_fpr32(ctx, fp0, fs);
8602 tcg_temp_free_i32(fp0);
8603 }
8604 break;
8605 case OPC_CFC1:
8606 gen_helper_1e0i(cfc1, t0, fs);
8607 gen_store_gpr(t0, rt);
8608 break;
8609 case OPC_CTC1:
8610 gen_load_gpr(t0, rt);
8611 save_cpu_state(ctx, 0);
8612 {
8613 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8614
8615 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8616 tcg_temp_free_i32(fs_tmp);
8617 }
8618 /* Stop translation as we may have changed hflags */
8619 ctx->bstate = BS_STOP;
8620 break;
8621 #if defined(TARGET_MIPS64)
8622 case OPC_DMFC1:
8623 gen_load_fpr64(ctx, t0, fs);
8624 gen_store_gpr(t0, rt);
8625 break;
8626 case OPC_DMTC1:
8627 gen_load_gpr(t0, rt);
8628 gen_store_fpr64(ctx, t0, fs);
8629 break;
8630 #endif
8631 case OPC_MFHC1:
8632 {
8633 TCGv_i32 fp0 = tcg_temp_new_i32();
8634
8635 gen_load_fpr32h(ctx, fp0, fs);
8636 tcg_gen_ext_i32_tl(t0, fp0);
8637 tcg_temp_free_i32(fp0);
8638 }
8639 gen_store_gpr(t0, rt);
8640 break;
8641 case OPC_MTHC1:
8642 gen_load_gpr(t0, rt);
8643 {
8644 TCGv_i32 fp0 = tcg_temp_new_i32();
8645
8646 tcg_gen_trunc_tl_i32(fp0, t0);
8647 gen_store_fpr32h(ctx, fp0, fs);
8648 tcg_temp_free_i32(fp0);
8649 }
8650 break;
8651 default:
8652 MIPS_INVAL("cp1 move");
8653 generate_exception_end(ctx, EXCP_RI);
8654 goto out;
8655 }
8656
8657 out:
8658 tcg_temp_free(t0);
8659 }
8660
8661 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8662 {
8663 TCGLabel *l1;
8664 TCGCond cond;
8665 TCGv_i32 t0;
8666
8667 if (rd == 0) {
8668 /* Treat as NOP. */
8669 return;
8670 }
8671
8672 if (tf)
8673 cond = TCG_COND_EQ;
8674 else
8675 cond = TCG_COND_NE;
8676
8677 l1 = gen_new_label();
8678 t0 = tcg_temp_new_i32();
8679 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8680 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8681 tcg_temp_free_i32(t0);
8682 if (rs == 0) {
8683 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8684 } else {
8685 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8686 }
8687 gen_set_label(l1);
8688 }
8689
8690 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8691 int tf)
8692 {
8693 int cond;
8694 TCGv_i32 t0 = tcg_temp_new_i32();
8695 TCGLabel *l1 = gen_new_label();
8696
8697 if (tf)
8698 cond = TCG_COND_EQ;
8699 else
8700 cond = TCG_COND_NE;
8701
8702 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8703 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8704 gen_load_fpr32(ctx, t0, fs);
8705 gen_store_fpr32(ctx, t0, fd);
8706 gen_set_label(l1);
8707 tcg_temp_free_i32(t0);
8708 }
8709
8710 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8711 {
8712 int cond;
8713 TCGv_i32 t0 = tcg_temp_new_i32();
8714 TCGv_i64 fp0;
8715 TCGLabel *l1 = gen_new_label();
8716
8717 if (tf)
8718 cond = TCG_COND_EQ;
8719 else
8720 cond = TCG_COND_NE;
8721
8722 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8723 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8724 tcg_temp_free_i32(t0);
8725 fp0 = tcg_temp_new_i64();
8726 gen_load_fpr64(ctx, fp0, fs);
8727 gen_store_fpr64(ctx, fp0, fd);
8728 tcg_temp_free_i64(fp0);
8729 gen_set_label(l1);
8730 }
8731
8732 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8733 int cc, int tf)
8734 {
8735 int cond;
8736 TCGv_i32 t0 = tcg_temp_new_i32();
8737 TCGLabel *l1 = gen_new_label();
8738 TCGLabel *l2 = gen_new_label();
8739
8740 if (tf)
8741 cond = TCG_COND_EQ;
8742 else
8743 cond = TCG_COND_NE;
8744
8745 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8746 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8747 gen_load_fpr32(ctx, t0, fs);
8748 gen_store_fpr32(ctx, t0, fd);
8749 gen_set_label(l1);
8750
8751 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8752 tcg_gen_brcondi_i32(cond, t0, 0, l2);
8753 gen_load_fpr32h(ctx, t0, fs);
8754 gen_store_fpr32h(ctx, t0, fd);
8755 tcg_temp_free_i32(t0);
8756 gen_set_label(l2);
8757 }
8758
8759 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8760 int fs)
8761 {
8762 TCGv_i32 t1 = tcg_const_i32(0);
8763 TCGv_i32 fp0 = tcg_temp_new_i32();
8764 TCGv_i32 fp1 = tcg_temp_new_i32();
8765 TCGv_i32 fp2 = tcg_temp_new_i32();
8766 gen_load_fpr32(ctx, fp0, fd);
8767 gen_load_fpr32(ctx, fp1, ft);
8768 gen_load_fpr32(ctx, fp2, fs);
8769
8770 switch (op1) {
8771 case OPC_SEL_S:
8772 tcg_gen_andi_i32(fp0, fp0, 1);
8773 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8774 break;
8775 case OPC_SELEQZ_S:
8776 tcg_gen_andi_i32(fp1, fp1, 1);
8777 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8778 break;
8779 case OPC_SELNEZ_S:
8780 tcg_gen_andi_i32(fp1, fp1, 1);
8781 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8782 break;
8783 default:
8784 MIPS_INVAL("gen_sel_s");
8785 generate_exception_end(ctx, EXCP_RI);
8786 break;
8787 }
8788
8789 gen_store_fpr32(ctx, fp0, fd);
8790 tcg_temp_free_i32(fp2);
8791 tcg_temp_free_i32(fp1);
8792 tcg_temp_free_i32(fp0);
8793 tcg_temp_free_i32(t1);
8794 }
8795
8796 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8797 int fs)
8798 {
8799 TCGv_i64 t1 = tcg_const_i64(0);
8800 TCGv_i64 fp0 = tcg_temp_new_i64();
8801 TCGv_i64 fp1 = tcg_temp_new_i64();
8802 TCGv_i64 fp2 = tcg_temp_new_i64();
8803 gen_load_fpr64(ctx, fp0, fd);
8804 gen_load_fpr64(ctx, fp1, ft);
8805 gen_load_fpr64(ctx, fp2, fs);
8806
8807 switch (op1) {
8808 case OPC_SEL_D:
8809 tcg_gen_andi_i64(fp0, fp0, 1);
8810 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8811 break;
8812 case OPC_SELEQZ_D:
8813 tcg_gen_andi_i64(fp1, fp1, 1);
8814 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8815 break;
8816 case OPC_SELNEZ_D:
8817 tcg_gen_andi_i64(fp1, fp1, 1);
8818 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8819 break;
8820 default:
8821 MIPS_INVAL("gen_sel_d");
8822 generate_exception_end(ctx, EXCP_RI);
8823 break;
8824 }
8825
8826 gen_store_fpr64(ctx, fp0, fd);
8827 tcg_temp_free_i64(fp2);
8828 tcg_temp_free_i64(fp1);
8829 tcg_temp_free_i64(fp0);
8830 tcg_temp_free_i64(t1);
8831 }
8832
8833 static void gen_farith (DisasContext *ctx, enum fopcode op1,
8834 int ft, int fs, int fd, int cc)
8835 {
8836 uint32_t func = ctx->opcode & 0x3f;
8837 switch (op1) {
8838 case OPC_ADD_S:
8839 {
8840 TCGv_i32 fp0 = tcg_temp_new_i32();
8841 TCGv_i32 fp1 = tcg_temp_new_i32();
8842
8843 gen_load_fpr32(ctx, fp0, fs);
8844 gen_load_fpr32(ctx, fp1, ft);
8845 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8846 tcg_temp_free_i32(fp1);
8847 gen_store_fpr32(ctx, fp0, fd);
8848 tcg_temp_free_i32(fp0);
8849 }
8850 break;
8851 case OPC_SUB_S:
8852 {
8853 TCGv_i32 fp0 = tcg_temp_new_i32();
8854 TCGv_i32 fp1 = tcg_temp_new_i32();
8855
8856 gen_load_fpr32(ctx, fp0, fs);
8857 gen_load_fpr32(ctx, fp1, ft);
8858 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8859 tcg_temp_free_i32(fp1);
8860 gen_store_fpr32(ctx, fp0, fd);
8861 tcg_temp_free_i32(fp0);
8862 }
8863 break;
8864 case OPC_MUL_S:
8865 {
8866 TCGv_i32 fp0 = tcg_temp_new_i32();
8867 TCGv_i32 fp1 = tcg_temp_new_i32();
8868
8869 gen_load_fpr32(ctx, fp0, fs);
8870 gen_load_fpr32(ctx, fp1, ft);
8871 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8872 tcg_temp_free_i32(fp1);
8873 gen_store_fpr32(ctx, fp0, fd);
8874 tcg_temp_free_i32(fp0);
8875 }
8876 break;
8877 case OPC_DIV_S:
8878 {
8879 TCGv_i32 fp0 = tcg_temp_new_i32();
8880 TCGv_i32 fp1 = tcg_temp_new_i32();
8881
8882 gen_load_fpr32(ctx, fp0, fs);
8883 gen_load_fpr32(ctx, fp1, ft);
8884 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8885 tcg_temp_free_i32(fp1);
8886 gen_store_fpr32(ctx, fp0, fd);
8887 tcg_temp_free_i32(fp0);
8888 }
8889 break;
8890 case OPC_SQRT_S:
8891 {
8892 TCGv_i32 fp0 = tcg_temp_new_i32();
8893
8894 gen_load_fpr32(ctx, fp0, fs);
8895 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8896 gen_store_fpr32(ctx, fp0, fd);
8897 tcg_temp_free_i32(fp0);
8898 }
8899 break;
8900 case OPC_ABS_S:
8901 {
8902 TCGv_i32 fp0 = tcg_temp_new_i32();
8903
8904 gen_load_fpr32(ctx, fp0, fs);
8905 if (ctx->abs2008) {
8906 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
8907 } else {
8908 gen_helper_float_abs_s(fp0, fp0);
8909 }
8910 gen_store_fpr32(ctx, fp0, fd);
8911 tcg_temp_free_i32(fp0);
8912 }
8913 break;
8914 case OPC_MOV_S:
8915 {
8916 TCGv_i32 fp0 = tcg_temp_new_i32();
8917
8918 gen_load_fpr32(ctx, fp0, fs);
8919 gen_store_fpr32(ctx, fp0, fd);
8920 tcg_temp_free_i32(fp0);
8921 }
8922 break;
8923 case OPC_NEG_S:
8924 {
8925 TCGv_i32 fp0 = tcg_temp_new_i32();
8926
8927 gen_load_fpr32(ctx, fp0, fs);
8928 if (ctx->abs2008) {
8929 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
8930 } else {
8931 gen_helper_float_chs_s(fp0, fp0);
8932 }
8933 gen_store_fpr32(ctx, fp0, fd);
8934 tcg_temp_free_i32(fp0);
8935 }
8936 break;
8937 case OPC_ROUND_L_S:
8938 check_cp1_64bitmode(ctx);
8939 {
8940 TCGv_i32 fp32 = tcg_temp_new_i32();
8941 TCGv_i64 fp64 = tcg_temp_new_i64();
8942
8943 gen_load_fpr32(ctx, fp32, fs);
8944 if (ctx->nan2008) {
8945 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
8946 } else {
8947 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
8948 }
8949 tcg_temp_free_i32(fp32);
8950 gen_store_fpr64(ctx, fp64, fd);
8951 tcg_temp_free_i64(fp64);
8952 }
8953 break;
8954 case OPC_TRUNC_L_S:
8955 check_cp1_64bitmode(ctx);
8956 {
8957 TCGv_i32 fp32 = tcg_temp_new_i32();
8958 TCGv_i64 fp64 = tcg_temp_new_i64();
8959
8960 gen_load_fpr32(ctx, fp32, fs);
8961 if (ctx->nan2008) {
8962 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
8963 } else {
8964 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
8965 }
8966 tcg_temp_free_i32(fp32);
8967 gen_store_fpr64(ctx, fp64, fd);
8968 tcg_temp_free_i64(fp64);
8969 }
8970 break;
8971 case OPC_CEIL_L_S:
8972 check_cp1_64bitmode(ctx);
8973 {
8974 TCGv_i32 fp32 = tcg_temp_new_i32();
8975 TCGv_i64 fp64 = tcg_temp_new_i64();
8976
8977 gen_load_fpr32(ctx, fp32, fs);
8978 if (ctx->nan2008) {
8979 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
8980 } else {
8981 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
8982 }
8983 tcg_temp_free_i32(fp32);
8984 gen_store_fpr64(ctx, fp64, fd);
8985 tcg_temp_free_i64(fp64);
8986 }
8987 break;
8988 case OPC_FLOOR_L_S:
8989 check_cp1_64bitmode(ctx);
8990 {
8991 TCGv_i32 fp32 = tcg_temp_new_i32();
8992 TCGv_i64 fp64 = tcg_temp_new_i64();
8993
8994 gen_load_fpr32(ctx, fp32, fs);
8995 if (ctx->nan2008) {
8996 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
8997 } else {
8998 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
8999 }
9000 tcg_temp_free_i32(fp32);
9001 gen_store_fpr64(ctx, fp64, fd);
9002 tcg_temp_free_i64(fp64);
9003 }
9004 break;
9005 case OPC_ROUND_W_S:
9006 {
9007 TCGv_i32 fp0 = tcg_temp_new_i32();
9008
9009 gen_load_fpr32(ctx, fp0, fs);
9010 if (ctx->nan2008) {
9011 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
9012 } else {
9013 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
9014 }
9015 gen_store_fpr32(ctx, fp0, fd);
9016 tcg_temp_free_i32(fp0);
9017 }
9018 break;
9019 case OPC_TRUNC_W_S:
9020 {
9021 TCGv_i32 fp0 = tcg_temp_new_i32();
9022
9023 gen_load_fpr32(ctx, fp0, fs);
9024 if (ctx->nan2008) {
9025 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
9026 } else {
9027 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
9028 }
9029 gen_store_fpr32(ctx, fp0, fd);
9030 tcg_temp_free_i32(fp0);
9031 }
9032 break;
9033 case OPC_CEIL_W_S:
9034 {
9035 TCGv_i32 fp0 = tcg_temp_new_i32();
9036
9037 gen_load_fpr32(ctx, fp0, fs);
9038 if (ctx->nan2008) {
9039 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
9040 } else {
9041 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
9042 }
9043 gen_store_fpr32(ctx, fp0, fd);
9044 tcg_temp_free_i32(fp0);
9045 }
9046 break;
9047 case OPC_FLOOR_W_S:
9048 {
9049 TCGv_i32 fp0 = tcg_temp_new_i32();
9050
9051 gen_load_fpr32(ctx, fp0, fs);
9052 if (ctx->nan2008) {
9053 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
9054 } else {
9055 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
9056 }
9057 gen_store_fpr32(ctx, fp0, fd);
9058 tcg_temp_free_i32(fp0);
9059 }
9060 break;
9061 case OPC_SEL_S:
9062 check_insn(ctx, ISA_MIPS32R6);
9063 gen_sel_s(ctx, op1, fd, ft, fs);
9064 break;
9065 case OPC_SELEQZ_S:
9066 check_insn(ctx, ISA_MIPS32R6);
9067 gen_sel_s(ctx, op1, fd, ft, fs);
9068 break;
9069 case OPC_SELNEZ_S:
9070 check_insn(ctx, ISA_MIPS32R6);
9071 gen_sel_s(ctx, op1, fd, ft, fs);
9072 break;
9073 case OPC_MOVCF_S:
9074 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9075 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9076 break;
9077 case OPC_MOVZ_S:
9078 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9079 {
9080 TCGLabel *l1 = gen_new_label();
9081 TCGv_i32 fp0;
9082
9083 if (ft != 0) {
9084 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9085 }
9086 fp0 = tcg_temp_new_i32();
9087 gen_load_fpr32(ctx, fp0, fs);
9088 gen_store_fpr32(ctx, fp0, fd);
9089 tcg_temp_free_i32(fp0);
9090 gen_set_label(l1);
9091 }
9092 break;
9093 case OPC_MOVN_S:
9094 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9095 {
9096 TCGLabel *l1 = gen_new_label();
9097 TCGv_i32 fp0;
9098
9099 if (ft != 0) {
9100 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9101 fp0 = tcg_temp_new_i32();
9102 gen_load_fpr32(ctx, fp0, fs);
9103 gen_store_fpr32(ctx, fp0, fd);
9104 tcg_temp_free_i32(fp0);
9105 gen_set_label(l1);
9106 }
9107 }
9108 break;
9109 case OPC_RECIP_S:
9110 {
9111 TCGv_i32 fp0 = tcg_temp_new_i32();
9112
9113 gen_load_fpr32(ctx, fp0, fs);
9114 gen_helper_float_recip_s(fp0, cpu_env, fp0);
9115 gen_store_fpr32(ctx, fp0, fd);
9116 tcg_temp_free_i32(fp0);
9117 }
9118 break;
9119 case OPC_RSQRT_S:
9120 {
9121 TCGv_i32 fp0 = tcg_temp_new_i32();
9122
9123 gen_load_fpr32(ctx, fp0, fs);
9124 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
9125 gen_store_fpr32(ctx, fp0, fd);
9126 tcg_temp_free_i32(fp0);
9127 }
9128 break;
9129 case OPC_MADDF_S:
9130 check_insn(ctx, ISA_MIPS32R6);
9131 {
9132 TCGv_i32 fp0 = tcg_temp_new_i32();
9133 TCGv_i32 fp1 = tcg_temp_new_i32();
9134 TCGv_i32 fp2 = tcg_temp_new_i32();
9135 gen_load_fpr32(ctx, fp0, fs);
9136 gen_load_fpr32(ctx, fp1, ft);
9137 gen_load_fpr32(ctx, fp2, fd);
9138 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
9139 gen_store_fpr32(ctx, fp2, fd);
9140 tcg_temp_free_i32(fp2);
9141 tcg_temp_free_i32(fp1);
9142 tcg_temp_free_i32(fp0);
9143 }
9144 break;
9145 case OPC_MSUBF_S:
9146 check_insn(ctx, ISA_MIPS32R6);
9147 {
9148 TCGv_i32 fp0 = tcg_temp_new_i32();
9149 TCGv_i32 fp1 = tcg_temp_new_i32();
9150 TCGv_i32 fp2 = tcg_temp_new_i32();
9151 gen_load_fpr32(ctx, fp0, fs);
9152 gen_load_fpr32(ctx, fp1, ft);
9153 gen_load_fpr32(ctx, fp2, fd);
9154 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9155 gen_store_fpr32(ctx, fp2, fd);
9156 tcg_temp_free_i32(fp2);
9157 tcg_temp_free_i32(fp1);
9158 tcg_temp_free_i32(fp0);
9159 }
9160 break;
9161 case OPC_RINT_S:
9162 check_insn(ctx, ISA_MIPS32R6);
9163 {
9164 TCGv_i32 fp0 = tcg_temp_new_i32();
9165 gen_load_fpr32(ctx, fp0, fs);
9166 gen_helper_float_rint_s(fp0, cpu_env, fp0);
9167 gen_store_fpr32(ctx, fp0, fd);
9168 tcg_temp_free_i32(fp0);
9169 }
9170 break;
9171 case OPC_CLASS_S:
9172 check_insn(ctx, ISA_MIPS32R6);
9173 {
9174 TCGv_i32 fp0 = tcg_temp_new_i32();
9175 gen_load_fpr32(ctx, fp0, fs);
9176 gen_helper_float_class_s(fp0, cpu_env, fp0);
9177 gen_store_fpr32(ctx, fp0, fd);
9178 tcg_temp_free_i32(fp0);
9179 }
9180 break;
9181 case OPC_MIN_S: /* OPC_RECIP2_S */
9182 if (ctx->insn_flags & ISA_MIPS32R6) {
9183 /* OPC_MIN_S */
9184 TCGv_i32 fp0 = tcg_temp_new_i32();
9185 TCGv_i32 fp1 = tcg_temp_new_i32();
9186 TCGv_i32 fp2 = tcg_temp_new_i32();
9187 gen_load_fpr32(ctx, fp0, fs);
9188 gen_load_fpr32(ctx, fp1, ft);
9189 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9190 gen_store_fpr32(ctx, fp2, fd);
9191 tcg_temp_free_i32(fp2);
9192 tcg_temp_free_i32(fp1);
9193 tcg_temp_free_i32(fp0);
9194 } else {
9195 /* OPC_RECIP2_S */
9196 check_cp1_64bitmode(ctx);
9197 {
9198 TCGv_i32 fp0 = tcg_temp_new_i32();
9199 TCGv_i32 fp1 = tcg_temp_new_i32();
9200
9201 gen_load_fpr32(ctx, fp0, fs);
9202 gen_load_fpr32(ctx, fp1, ft);
9203 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9204 tcg_temp_free_i32(fp1);
9205 gen_store_fpr32(ctx, fp0, fd);
9206 tcg_temp_free_i32(fp0);
9207 }
9208 }
9209 break;
9210 case OPC_MINA_S: /* OPC_RECIP1_S */
9211 if (ctx->insn_flags & ISA_MIPS32R6) {
9212 /* OPC_MINA_S */
9213 TCGv_i32 fp0 = tcg_temp_new_i32();
9214 TCGv_i32 fp1 = tcg_temp_new_i32();
9215 TCGv_i32 fp2 = tcg_temp_new_i32();
9216 gen_load_fpr32(ctx, fp0, fs);
9217 gen_load_fpr32(ctx, fp1, ft);
9218 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9219 gen_store_fpr32(ctx, fp2, fd);
9220 tcg_temp_free_i32(fp2);
9221 tcg_temp_free_i32(fp1);
9222 tcg_temp_free_i32(fp0);
9223 } else {
9224 /* OPC_RECIP1_S */
9225 check_cp1_64bitmode(ctx);
9226 {
9227 TCGv_i32 fp0 = tcg_temp_new_i32();
9228
9229 gen_load_fpr32(ctx, fp0, fs);
9230 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9231 gen_store_fpr32(ctx, fp0, fd);
9232 tcg_temp_free_i32(fp0);
9233 }
9234 }
9235 break;
9236 case OPC_MAX_S: /* OPC_RSQRT1_S */
9237 if (ctx->insn_flags & ISA_MIPS32R6) {
9238 /* OPC_MAX_S */
9239 TCGv_i32 fp0 = tcg_temp_new_i32();
9240 TCGv_i32 fp1 = tcg_temp_new_i32();
9241 gen_load_fpr32(ctx, fp0, fs);
9242 gen_load_fpr32(ctx, fp1, ft);
9243 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9244 gen_store_fpr32(ctx, fp1, fd);
9245 tcg_temp_free_i32(fp1);
9246 tcg_temp_free_i32(fp0);
9247 } else {
9248 /* OPC_RSQRT1_S */
9249 check_cp1_64bitmode(ctx);
9250 {
9251 TCGv_i32 fp0 = tcg_temp_new_i32();
9252
9253 gen_load_fpr32(ctx, fp0, fs);
9254 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9255 gen_store_fpr32(ctx, fp0, fd);
9256 tcg_temp_free_i32(fp0);
9257 }
9258 }
9259 break;
9260 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9261 if (ctx->insn_flags & ISA_MIPS32R6) {
9262 /* OPC_MAXA_S */
9263 TCGv_i32 fp0 = tcg_temp_new_i32();
9264 TCGv_i32 fp1 = tcg_temp_new_i32();
9265 gen_load_fpr32(ctx, fp0, fs);
9266 gen_load_fpr32(ctx, fp1, ft);
9267 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9268 gen_store_fpr32(ctx, fp1, fd);
9269 tcg_temp_free_i32(fp1);
9270 tcg_temp_free_i32(fp0);
9271 } else {
9272 /* OPC_RSQRT2_S */
9273 check_cp1_64bitmode(ctx);
9274 {
9275 TCGv_i32 fp0 = tcg_temp_new_i32();
9276 TCGv_i32 fp1 = tcg_temp_new_i32();
9277
9278 gen_load_fpr32(ctx, fp0, fs);
9279 gen_load_fpr32(ctx, fp1, ft);
9280 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9281 tcg_temp_free_i32(fp1);
9282 gen_store_fpr32(ctx, fp0, fd);
9283 tcg_temp_free_i32(fp0);
9284 }
9285 }
9286 break;
9287 case OPC_CVT_D_S:
9288 check_cp1_registers(ctx, fd);
9289 {
9290 TCGv_i32 fp32 = tcg_temp_new_i32();
9291 TCGv_i64 fp64 = tcg_temp_new_i64();
9292
9293 gen_load_fpr32(ctx, fp32, fs);
9294 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9295 tcg_temp_free_i32(fp32);
9296 gen_store_fpr64(ctx, fp64, fd);
9297 tcg_temp_free_i64(fp64);
9298 }
9299 break;
9300 case OPC_CVT_W_S:
9301 {
9302 TCGv_i32 fp0 = tcg_temp_new_i32();
9303
9304 gen_load_fpr32(ctx, fp0, fs);
9305 if (ctx->nan2008) {
9306 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
9307 } else {
9308 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
9309 }
9310 gen_store_fpr32(ctx, fp0, fd);
9311 tcg_temp_free_i32(fp0);
9312 }
9313 break;
9314 case OPC_CVT_L_S:
9315 check_cp1_64bitmode(ctx);
9316 {
9317 TCGv_i32 fp32 = tcg_temp_new_i32();
9318 TCGv_i64 fp64 = tcg_temp_new_i64();
9319
9320 gen_load_fpr32(ctx, fp32, fs);
9321 if (ctx->nan2008) {
9322 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
9323 } else {
9324 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
9325 }
9326 tcg_temp_free_i32(fp32);
9327 gen_store_fpr64(ctx, fp64, fd);
9328 tcg_temp_free_i64(fp64);
9329 }
9330 break;
9331 case OPC_CVT_PS_S:
9332 check_ps(ctx);
9333 {
9334 TCGv_i64 fp64 = tcg_temp_new_i64();
9335 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9336 TCGv_i32 fp32_1 = tcg_temp_new_i32();
9337
9338 gen_load_fpr32(ctx, fp32_0, fs);
9339 gen_load_fpr32(ctx, fp32_1, ft);
9340 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9341 tcg_temp_free_i32(fp32_1);
9342 tcg_temp_free_i32(fp32_0);
9343 gen_store_fpr64(ctx, fp64, fd);
9344 tcg_temp_free_i64(fp64);
9345 }
9346 break;
9347 case OPC_CMP_F_S:
9348 case OPC_CMP_UN_S:
9349 case OPC_CMP_EQ_S:
9350 case OPC_CMP_UEQ_S:
9351 case OPC_CMP_OLT_S:
9352 case OPC_CMP_ULT_S:
9353 case OPC_CMP_OLE_S:
9354 case OPC_CMP_ULE_S:
9355 case OPC_CMP_SF_S:
9356 case OPC_CMP_NGLE_S:
9357 case OPC_CMP_SEQ_S:
9358 case OPC_CMP_NGL_S:
9359 case OPC_CMP_LT_S:
9360 case OPC_CMP_NGE_S:
9361 case OPC_CMP_LE_S:
9362 case OPC_CMP_NGT_S:
9363 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9364 if (ctx->opcode & (1 << 6)) {
9365 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9366 } else {
9367 gen_cmp_s(ctx, func-48, ft, fs, cc);
9368 }
9369 break;
9370 case OPC_ADD_D:
9371 check_cp1_registers(ctx, fs | ft | fd);
9372 {
9373 TCGv_i64 fp0 = tcg_temp_new_i64();
9374 TCGv_i64 fp1 = tcg_temp_new_i64();
9375
9376 gen_load_fpr64(ctx, fp0, fs);
9377 gen_load_fpr64(ctx, fp1, ft);
9378 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9379 tcg_temp_free_i64(fp1);
9380 gen_store_fpr64(ctx, fp0, fd);
9381 tcg_temp_free_i64(fp0);
9382 }
9383 break;
9384 case OPC_SUB_D:
9385 check_cp1_registers(ctx, fs | ft | fd);
9386 {
9387 TCGv_i64 fp0 = tcg_temp_new_i64();
9388 TCGv_i64 fp1 = tcg_temp_new_i64();
9389
9390 gen_load_fpr64(ctx, fp0, fs);
9391 gen_load_fpr64(ctx, fp1, ft);
9392 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9393 tcg_temp_free_i64(fp1);
9394 gen_store_fpr64(ctx, fp0, fd);
9395 tcg_temp_free_i64(fp0);
9396 }
9397 break;
9398 case OPC_MUL_D:
9399 check_cp1_registers(ctx, fs | ft | fd);
9400 {
9401 TCGv_i64 fp0 = tcg_temp_new_i64();
9402 TCGv_i64 fp1 = tcg_temp_new_i64();
9403
9404 gen_load_fpr64(ctx, fp0, fs);
9405 gen_load_fpr64(ctx, fp1, ft);
9406 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9407 tcg_temp_free_i64(fp1);
9408 gen_store_fpr64(ctx, fp0, fd);
9409 tcg_temp_free_i64(fp0);
9410 }
9411 break;
9412 case OPC_DIV_D:
9413 check_cp1_registers(ctx, fs | ft | fd);
9414 {
9415 TCGv_i64 fp0 = tcg_temp_new_i64();
9416 TCGv_i64 fp1 = tcg_temp_new_i64();
9417
9418 gen_load_fpr64(ctx, fp0, fs);
9419 gen_load_fpr64(ctx, fp1, ft);
9420 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9421 tcg_temp_free_i64(fp1);
9422 gen_store_fpr64(ctx, fp0, fd);
9423 tcg_temp_free_i64(fp0);
9424 }
9425 break;
9426 case OPC_SQRT_D:
9427 check_cp1_registers(ctx, fs | fd);
9428 {
9429 TCGv_i64 fp0 = tcg_temp_new_i64();
9430
9431 gen_load_fpr64(ctx, fp0, fs);
9432 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9433 gen_store_fpr64(ctx, fp0, fd);
9434 tcg_temp_free_i64(fp0);
9435 }
9436 break;
9437 case OPC_ABS_D:
9438 check_cp1_registers(ctx, fs | fd);
9439 {
9440 TCGv_i64 fp0 = tcg_temp_new_i64();
9441
9442 gen_load_fpr64(ctx, fp0, fs);
9443 if (ctx->abs2008) {
9444 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
9445 } else {
9446 gen_helper_float_abs_d(fp0, fp0);
9447 }
9448 gen_store_fpr64(ctx, fp0, fd);
9449 tcg_temp_free_i64(fp0);
9450 }
9451 break;
9452 case OPC_MOV_D:
9453 check_cp1_registers(ctx, fs | fd);
9454 {
9455 TCGv_i64 fp0 = tcg_temp_new_i64();
9456
9457 gen_load_fpr64(ctx, fp0, fs);
9458 gen_store_fpr64(ctx, fp0, fd);
9459 tcg_temp_free_i64(fp0);
9460 }
9461 break;
9462 case OPC_NEG_D:
9463 check_cp1_registers(ctx, fs | fd);
9464 {
9465 TCGv_i64 fp0 = tcg_temp_new_i64();
9466
9467 gen_load_fpr64(ctx, fp0, fs);
9468 if (ctx->abs2008) {
9469 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
9470 } else {
9471 gen_helper_float_chs_d(fp0, fp0);
9472 }
9473 gen_store_fpr64(ctx, fp0, fd);
9474 tcg_temp_free_i64(fp0);
9475 }
9476 break;
9477 case OPC_ROUND_L_D:
9478 check_cp1_64bitmode(ctx);
9479 {
9480 TCGv_i64 fp0 = tcg_temp_new_i64();
9481
9482 gen_load_fpr64(ctx, fp0, fs);
9483 if (ctx->nan2008) {
9484 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
9485 } else {
9486 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
9487 }
9488 gen_store_fpr64(ctx, fp0, fd);
9489 tcg_temp_free_i64(fp0);
9490 }
9491 break;
9492 case OPC_TRUNC_L_D:
9493 check_cp1_64bitmode(ctx);
9494 {
9495 TCGv_i64 fp0 = tcg_temp_new_i64();
9496
9497 gen_load_fpr64(ctx, fp0, fs);
9498 if (ctx->nan2008) {
9499 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
9500 } else {
9501 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
9502 }
9503 gen_store_fpr64(ctx, fp0, fd);
9504 tcg_temp_free_i64(fp0);
9505 }
9506 break;
9507 case OPC_CEIL_L_D:
9508 check_cp1_64bitmode(ctx);
9509 {
9510 TCGv_i64 fp0 = tcg_temp_new_i64();
9511
9512 gen_load_fpr64(ctx, fp0, fs);
9513 if (ctx->nan2008) {
9514 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
9515 } else {
9516 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
9517 }
9518 gen_store_fpr64(ctx, fp0, fd);
9519 tcg_temp_free_i64(fp0);
9520 }
9521 break;
9522 case OPC_FLOOR_L_D:
9523 check_cp1_64bitmode(ctx);
9524 {
9525 TCGv_i64 fp0 = tcg_temp_new_i64();
9526
9527 gen_load_fpr64(ctx, fp0, fs);
9528 if (ctx->nan2008) {
9529 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
9530 } else {
9531 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
9532 }
9533 gen_store_fpr64(ctx, fp0, fd);
9534 tcg_temp_free_i64(fp0);
9535 }
9536 break;
9537 case OPC_ROUND_W_D:
9538 check_cp1_registers(ctx, fs);
9539 {
9540 TCGv_i32 fp32 = tcg_temp_new_i32();
9541 TCGv_i64 fp64 = tcg_temp_new_i64();
9542
9543 gen_load_fpr64(ctx, fp64, fs);
9544 if (ctx->nan2008) {
9545 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
9546 } else {
9547 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
9548 }
9549 tcg_temp_free_i64(fp64);
9550 gen_store_fpr32(ctx, fp32, fd);
9551 tcg_temp_free_i32(fp32);
9552 }
9553 break;
9554 case OPC_TRUNC_W_D:
9555 check_cp1_registers(ctx, fs);
9556 {
9557 TCGv_i32 fp32 = tcg_temp_new_i32();
9558 TCGv_i64 fp64 = tcg_temp_new_i64();
9559
9560 gen_load_fpr64(ctx, fp64, fs);
9561 if (ctx->nan2008) {
9562 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
9563 } else {
9564 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
9565 }
9566 tcg_temp_free_i64(fp64);
9567 gen_store_fpr32(ctx, fp32, fd);
9568 tcg_temp_free_i32(fp32);
9569 }
9570 break;
9571 case OPC_CEIL_W_D:
9572 check_cp1_registers(ctx, fs);
9573 {
9574 TCGv_i32 fp32 = tcg_temp_new_i32();
9575 TCGv_i64 fp64 = tcg_temp_new_i64();
9576
9577 gen_load_fpr64(ctx, fp64, fs);
9578 if (ctx->nan2008) {
9579 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
9580 } else {
9581 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
9582 }
9583 tcg_temp_free_i64(fp64);
9584 gen_store_fpr32(ctx, fp32, fd);
9585 tcg_temp_free_i32(fp32);
9586 }
9587 break;
9588 case OPC_FLOOR_W_D:
9589 check_cp1_registers(ctx, fs);
9590 {
9591 TCGv_i32 fp32 = tcg_temp_new_i32();
9592 TCGv_i64 fp64 = tcg_temp_new_i64();
9593
9594 gen_load_fpr64(ctx, fp64, fs);
9595 if (ctx->nan2008) {
9596 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
9597 } else {
9598 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
9599 }
9600 tcg_temp_free_i64(fp64);
9601 gen_store_fpr32(ctx, fp32, fd);
9602 tcg_temp_free_i32(fp32);
9603 }
9604 break;
9605 case OPC_SEL_D:
9606 check_insn(ctx, ISA_MIPS32R6);
9607 gen_sel_d(ctx, op1, fd, ft, fs);
9608 break;
9609 case OPC_SELEQZ_D:
9610 check_insn(ctx, ISA_MIPS32R6);
9611 gen_sel_d(ctx, op1, fd, ft, fs);
9612 break;
9613 case OPC_SELNEZ_D:
9614 check_insn(ctx, ISA_MIPS32R6);
9615 gen_sel_d(ctx, op1, fd, ft, fs);
9616 break;
9617 case OPC_MOVCF_D:
9618 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9619 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9620 break;
9621 case OPC_MOVZ_D:
9622 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9623 {
9624 TCGLabel *l1 = gen_new_label();
9625 TCGv_i64 fp0;
9626
9627 if (ft != 0) {
9628 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9629 }
9630 fp0 = tcg_temp_new_i64();
9631 gen_load_fpr64(ctx, fp0, fs);
9632 gen_store_fpr64(ctx, fp0, fd);
9633 tcg_temp_free_i64(fp0);
9634 gen_set_label(l1);
9635 }
9636 break;
9637 case OPC_MOVN_D:
9638 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9639 {
9640 TCGLabel *l1 = gen_new_label();
9641 TCGv_i64 fp0;
9642
9643 if (ft != 0) {
9644 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9645 fp0 = tcg_temp_new_i64();
9646 gen_load_fpr64(ctx, fp0, fs);
9647 gen_store_fpr64(ctx, fp0, fd);
9648 tcg_temp_free_i64(fp0);
9649 gen_set_label(l1);
9650 }
9651 }
9652 break;
9653 case OPC_RECIP_D:
9654 check_cp1_registers(ctx, fs | fd);
9655 {
9656 TCGv_i64 fp0 = tcg_temp_new_i64();
9657
9658 gen_load_fpr64(ctx, fp0, fs);
9659 gen_helper_float_recip_d(fp0, cpu_env, fp0);
9660 gen_store_fpr64(ctx, fp0, fd);
9661 tcg_temp_free_i64(fp0);
9662 }
9663 break;
9664 case OPC_RSQRT_D:
9665 check_cp1_registers(ctx, fs | fd);
9666 {
9667 TCGv_i64 fp0 = tcg_temp_new_i64();
9668
9669 gen_load_fpr64(ctx, fp0, fs);
9670 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9671 gen_store_fpr64(ctx, fp0, fd);
9672 tcg_temp_free_i64(fp0);
9673 }
9674 break;
9675 case OPC_MADDF_D:
9676 check_insn(ctx, ISA_MIPS32R6);
9677 {
9678 TCGv_i64 fp0 = tcg_temp_new_i64();
9679 TCGv_i64 fp1 = tcg_temp_new_i64();
9680 TCGv_i64 fp2 = tcg_temp_new_i64();
9681 gen_load_fpr64(ctx, fp0, fs);
9682 gen_load_fpr64(ctx, fp1, ft);
9683 gen_load_fpr64(ctx, fp2, fd);
9684 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9685 gen_store_fpr64(ctx, fp2, fd);
9686 tcg_temp_free_i64(fp2);
9687 tcg_temp_free_i64(fp1);
9688 tcg_temp_free_i64(fp0);
9689 }
9690 break;
9691 case OPC_MSUBF_D:
9692 check_insn(ctx, ISA_MIPS32R6);
9693 {
9694 TCGv_i64 fp0 = tcg_temp_new_i64();
9695 TCGv_i64 fp1 = tcg_temp_new_i64();
9696 TCGv_i64 fp2 = tcg_temp_new_i64();
9697 gen_load_fpr64(ctx, fp0, fs);
9698 gen_load_fpr64(ctx, fp1, ft);
9699 gen_load_fpr64(ctx, fp2, fd);
9700 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9701 gen_store_fpr64(ctx, fp2, fd);
9702 tcg_temp_free_i64(fp2);
9703 tcg_temp_free_i64(fp1);
9704 tcg_temp_free_i64(fp0);
9705 }
9706 break;
9707 case OPC_RINT_D:
9708 check_insn(ctx, ISA_MIPS32R6);
9709 {
9710 TCGv_i64 fp0 = tcg_temp_new_i64();
9711 gen_load_fpr64(ctx, fp0, fs);
9712 gen_helper_float_rint_d(fp0, cpu_env, fp0);
9713 gen_store_fpr64(ctx, fp0, fd);
9714 tcg_temp_free_i64(fp0);
9715 }
9716 break;
9717 case OPC_CLASS_D:
9718 check_insn(ctx, ISA_MIPS32R6);
9719 {
9720 TCGv_i64 fp0 = tcg_temp_new_i64();
9721 gen_load_fpr64(ctx, fp0, fs);
9722 gen_helper_float_class_d(fp0, cpu_env, fp0);
9723 gen_store_fpr64(ctx, fp0, fd);
9724 tcg_temp_free_i64(fp0);
9725 }
9726 break;
9727 case OPC_MIN_D: /* OPC_RECIP2_D */
9728 if (ctx->insn_flags & ISA_MIPS32R6) {
9729 /* OPC_MIN_D */
9730 TCGv_i64 fp0 = tcg_temp_new_i64();
9731 TCGv_i64 fp1 = tcg_temp_new_i64();
9732 gen_load_fpr64(ctx, fp0, fs);
9733 gen_load_fpr64(ctx, fp1, ft);
9734 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9735 gen_store_fpr64(ctx, fp1, fd);
9736 tcg_temp_free_i64(fp1);
9737 tcg_temp_free_i64(fp0);
9738 } else {
9739 /* OPC_RECIP2_D */
9740 check_cp1_64bitmode(ctx);
9741 {
9742 TCGv_i64 fp0 = tcg_temp_new_i64();
9743 TCGv_i64 fp1 = tcg_temp_new_i64();
9744
9745 gen_load_fpr64(ctx, fp0, fs);
9746 gen_load_fpr64(ctx, fp1, ft);
9747 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9748 tcg_temp_free_i64(fp1);
9749 gen_store_fpr64(ctx, fp0, fd);
9750 tcg_temp_free_i64(fp0);
9751 }
9752 }
9753 break;
9754 case OPC_MINA_D: /* OPC_RECIP1_D */
9755 if (ctx->insn_flags & ISA_MIPS32R6) {
9756 /* OPC_MINA_D */
9757 TCGv_i64 fp0 = tcg_temp_new_i64();
9758 TCGv_i64 fp1 = tcg_temp_new_i64();
9759 gen_load_fpr64(ctx, fp0, fs);
9760 gen_load_fpr64(ctx, fp1, ft);
9761 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9762 gen_store_fpr64(ctx, fp1, fd);
9763 tcg_temp_free_i64(fp1);
9764 tcg_temp_free_i64(fp0);
9765 } else {
9766 /* OPC_RECIP1_D */
9767 check_cp1_64bitmode(ctx);
9768 {
9769 TCGv_i64 fp0 = tcg_temp_new_i64();
9770
9771 gen_load_fpr64(ctx, fp0, fs);
9772 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9773 gen_store_fpr64(ctx, fp0, fd);
9774 tcg_temp_free_i64(fp0);
9775 }
9776 }
9777 break;
9778 case OPC_MAX_D: /* OPC_RSQRT1_D */
9779 if (ctx->insn_flags & ISA_MIPS32R6) {
9780 /* OPC_MAX_D */
9781 TCGv_i64 fp0 = tcg_temp_new_i64();
9782 TCGv_i64 fp1 = tcg_temp_new_i64();
9783 gen_load_fpr64(ctx, fp0, fs);
9784 gen_load_fpr64(ctx, fp1, ft);
9785 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9786 gen_store_fpr64(ctx, fp1, fd);
9787 tcg_temp_free_i64(fp1);
9788 tcg_temp_free_i64(fp0);
9789 } else {
9790 /* OPC_RSQRT1_D */
9791 check_cp1_64bitmode(ctx);
9792 {
9793 TCGv_i64 fp0 = tcg_temp_new_i64();
9794
9795 gen_load_fpr64(ctx, fp0, fs);
9796 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9797 gen_store_fpr64(ctx, fp0, fd);
9798 tcg_temp_free_i64(fp0);
9799 }
9800 }
9801 break;
9802 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9803 if (ctx->insn_flags & ISA_MIPS32R6) {
9804 /* OPC_MAXA_D */
9805 TCGv_i64 fp0 = tcg_temp_new_i64();
9806 TCGv_i64 fp1 = tcg_temp_new_i64();
9807 gen_load_fpr64(ctx, fp0, fs);
9808 gen_load_fpr64(ctx, fp1, ft);
9809 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9810 gen_store_fpr64(ctx, fp1, fd);
9811 tcg_temp_free_i64(fp1);
9812 tcg_temp_free_i64(fp0);
9813 } else {
9814 /* OPC_RSQRT2_D */
9815 check_cp1_64bitmode(ctx);
9816 {
9817 TCGv_i64 fp0 = tcg_temp_new_i64();
9818 TCGv_i64 fp1 = tcg_temp_new_i64();
9819
9820 gen_load_fpr64(ctx, fp0, fs);
9821 gen_load_fpr64(ctx, fp1, ft);
9822 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9823 tcg_temp_free_i64(fp1);
9824 gen_store_fpr64(ctx, fp0, fd);
9825 tcg_temp_free_i64(fp0);
9826 }
9827 }
9828 break;
9829 case OPC_CMP_F_D:
9830 case OPC_CMP_UN_D:
9831 case OPC_CMP_EQ_D:
9832 case OPC_CMP_UEQ_D:
9833 case OPC_CMP_OLT_D:
9834 case OPC_CMP_ULT_D:
9835 case OPC_CMP_OLE_D:
9836 case OPC_CMP_ULE_D:
9837 case OPC_CMP_SF_D:
9838 case OPC_CMP_NGLE_D:
9839 case OPC_CMP_SEQ_D:
9840 case OPC_CMP_NGL_D:
9841 case OPC_CMP_LT_D:
9842 case OPC_CMP_NGE_D:
9843 case OPC_CMP_LE_D:
9844 case OPC_CMP_NGT_D:
9845 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9846 if (ctx->opcode & (1 << 6)) {
9847 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9848 } else {
9849 gen_cmp_d(ctx, func-48, ft, fs, cc);
9850 }
9851 break;
9852 case OPC_CVT_S_D:
9853 check_cp1_registers(ctx, fs);
9854 {
9855 TCGv_i32 fp32 = tcg_temp_new_i32();
9856 TCGv_i64 fp64 = tcg_temp_new_i64();
9857
9858 gen_load_fpr64(ctx, fp64, fs);
9859 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9860 tcg_temp_free_i64(fp64);
9861 gen_store_fpr32(ctx, fp32, fd);
9862 tcg_temp_free_i32(fp32);
9863 }
9864 break;
9865 case OPC_CVT_W_D:
9866 check_cp1_registers(ctx, fs);
9867 {
9868 TCGv_i32 fp32 = tcg_temp_new_i32();
9869 TCGv_i64 fp64 = tcg_temp_new_i64();
9870
9871 gen_load_fpr64(ctx, fp64, fs);
9872 if (ctx->nan2008) {
9873 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
9874 } else {
9875 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
9876 }
9877 tcg_temp_free_i64(fp64);
9878 gen_store_fpr32(ctx, fp32, fd);
9879 tcg_temp_free_i32(fp32);
9880 }
9881 break;
9882 case OPC_CVT_L_D:
9883 check_cp1_64bitmode(ctx);
9884 {
9885 TCGv_i64 fp0 = tcg_temp_new_i64();
9886
9887 gen_load_fpr64(ctx, fp0, fs);
9888 if (ctx->nan2008) {
9889 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
9890 } else {
9891 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
9892 }
9893 gen_store_fpr64(ctx, fp0, fd);
9894 tcg_temp_free_i64(fp0);
9895 }
9896 break;
9897 case OPC_CVT_S_W:
9898 {
9899 TCGv_i32 fp0 = tcg_temp_new_i32();
9900
9901 gen_load_fpr32(ctx, fp0, fs);
9902 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9903 gen_store_fpr32(ctx, fp0, fd);
9904 tcg_temp_free_i32(fp0);
9905 }
9906 break;
9907 case OPC_CVT_D_W:
9908 check_cp1_registers(ctx, fd);
9909 {
9910 TCGv_i32 fp32 = tcg_temp_new_i32();
9911 TCGv_i64 fp64 = tcg_temp_new_i64();
9912
9913 gen_load_fpr32(ctx, fp32, fs);
9914 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9915 tcg_temp_free_i32(fp32);
9916 gen_store_fpr64(ctx, fp64, fd);
9917 tcg_temp_free_i64(fp64);
9918 }
9919 break;
9920 case OPC_CVT_S_L:
9921 check_cp1_64bitmode(ctx);
9922 {
9923 TCGv_i32 fp32 = tcg_temp_new_i32();
9924 TCGv_i64 fp64 = tcg_temp_new_i64();
9925
9926 gen_load_fpr64(ctx, fp64, fs);
9927 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9928 tcg_temp_free_i64(fp64);
9929 gen_store_fpr32(ctx, fp32, fd);
9930 tcg_temp_free_i32(fp32);
9931 }
9932 break;
9933 case OPC_CVT_D_L:
9934 check_cp1_64bitmode(ctx);
9935 {
9936 TCGv_i64 fp0 = tcg_temp_new_i64();
9937
9938 gen_load_fpr64(ctx, fp0, fs);
9939 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9940 gen_store_fpr64(ctx, fp0, fd);
9941 tcg_temp_free_i64(fp0);
9942 }
9943 break;
9944 case OPC_CVT_PS_PW:
9945 check_ps(ctx);
9946 {
9947 TCGv_i64 fp0 = tcg_temp_new_i64();
9948
9949 gen_load_fpr64(ctx, fp0, fs);
9950 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9951 gen_store_fpr64(ctx, fp0, fd);
9952 tcg_temp_free_i64(fp0);
9953 }
9954 break;
9955 case OPC_ADD_PS:
9956 check_ps(ctx);
9957 {
9958 TCGv_i64 fp0 = tcg_temp_new_i64();
9959 TCGv_i64 fp1 = tcg_temp_new_i64();
9960
9961 gen_load_fpr64(ctx, fp0, fs);
9962 gen_load_fpr64(ctx, fp1, ft);
9963 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
9964 tcg_temp_free_i64(fp1);
9965 gen_store_fpr64(ctx, fp0, fd);
9966 tcg_temp_free_i64(fp0);
9967 }
9968 break;
9969 case OPC_SUB_PS:
9970 check_ps(ctx);
9971 {
9972 TCGv_i64 fp0 = tcg_temp_new_i64();
9973 TCGv_i64 fp1 = tcg_temp_new_i64();
9974
9975 gen_load_fpr64(ctx, fp0, fs);
9976 gen_load_fpr64(ctx, fp1, ft);
9977 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9978 tcg_temp_free_i64(fp1);
9979 gen_store_fpr64(ctx, fp0, fd);
9980 tcg_temp_free_i64(fp0);
9981 }
9982 break;
9983 case OPC_MUL_PS:
9984 check_ps(ctx);
9985 {
9986 TCGv_i64 fp0 = tcg_temp_new_i64();
9987 TCGv_i64 fp1 = tcg_temp_new_i64();
9988
9989 gen_load_fpr64(ctx, fp0, fs);
9990 gen_load_fpr64(ctx, fp1, ft);
9991 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9992 tcg_temp_free_i64(fp1);
9993 gen_store_fpr64(ctx, fp0, fd);
9994 tcg_temp_free_i64(fp0);
9995 }
9996 break;
9997 case OPC_ABS_PS:
9998 check_ps(ctx);
9999 {
10000 TCGv_i64 fp0 = tcg_temp_new_i64();
10001
10002 gen_load_fpr64(ctx, fp0, fs);
10003 gen_helper_float_abs_ps(fp0, fp0);
10004 gen_store_fpr64(ctx, fp0, fd);
10005 tcg_temp_free_i64(fp0);
10006 }
10007 break;
10008 case OPC_MOV_PS:
10009 check_ps(ctx);
10010 {
10011 TCGv_i64 fp0 = tcg_temp_new_i64();
10012
10013 gen_load_fpr64(ctx, fp0, fs);
10014 gen_store_fpr64(ctx, fp0, fd);
10015 tcg_temp_free_i64(fp0);
10016 }
10017 break;
10018 case OPC_NEG_PS:
10019 check_ps(ctx);
10020 {
10021 TCGv_i64 fp0 = tcg_temp_new_i64();
10022
10023 gen_load_fpr64(ctx, fp0, fs);
10024 gen_helper_float_chs_ps(fp0, fp0);
10025 gen_store_fpr64(ctx, fp0, fd);
10026 tcg_temp_free_i64(fp0);
10027 }
10028 break;
10029 case OPC_MOVCF_PS:
10030 check_ps(ctx);
10031 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10032 break;
10033 case OPC_MOVZ_PS:
10034 check_ps(ctx);
10035 {
10036 TCGLabel *l1 = gen_new_label();
10037 TCGv_i64 fp0;
10038
10039 if (ft != 0)
10040 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10041 fp0 = tcg_temp_new_i64();
10042 gen_load_fpr64(ctx, fp0, fs);
10043 gen_store_fpr64(ctx, fp0, fd);
10044 tcg_temp_free_i64(fp0);
10045 gen_set_label(l1);
10046 }
10047 break;
10048 case OPC_MOVN_PS:
10049 check_ps(ctx);
10050 {
10051 TCGLabel *l1 = gen_new_label();
10052 TCGv_i64 fp0;
10053
10054 if (ft != 0) {
10055 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10056 fp0 = tcg_temp_new_i64();
10057 gen_load_fpr64(ctx, fp0, fs);
10058 gen_store_fpr64(ctx, fp0, fd);
10059 tcg_temp_free_i64(fp0);
10060 gen_set_label(l1);
10061 }
10062 }
10063 break;
10064 case OPC_ADDR_PS:
10065 check_ps(ctx);
10066 {
10067 TCGv_i64 fp0 = tcg_temp_new_i64();
10068 TCGv_i64 fp1 = tcg_temp_new_i64();
10069
10070 gen_load_fpr64(ctx, fp0, ft);
10071 gen_load_fpr64(ctx, fp1, fs);
10072 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
10073 tcg_temp_free_i64(fp1);
10074 gen_store_fpr64(ctx, fp0, fd);
10075 tcg_temp_free_i64(fp0);
10076 }
10077 break;
10078 case OPC_MULR_PS:
10079 check_ps(ctx);
10080 {
10081 TCGv_i64 fp0 = tcg_temp_new_i64();
10082 TCGv_i64 fp1 = tcg_temp_new_i64();
10083
10084 gen_load_fpr64(ctx, fp0, ft);
10085 gen_load_fpr64(ctx, fp1, fs);
10086 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
10087 tcg_temp_free_i64(fp1);
10088 gen_store_fpr64(ctx, fp0, fd);
10089 tcg_temp_free_i64(fp0);
10090 }
10091 break;
10092 case OPC_RECIP2_PS:
10093 check_ps(ctx);
10094 {
10095 TCGv_i64 fp0 = tcg_temp_new_i64();
10096 TCGv_i64 fp1 = tcg_temp_new_i64();
10097
10098 gen_load_fpr64(ctx, fp0, fs);
10099 gen_load_fpr64(ctx, fp1, ft);
10100 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
10101 tcg_temp_free_i64(fp1);
10102 gen_store_fpr64(ctx, fp0, fd);
10103 tcg_temp_free_i64(fp0);
10104 }
10105 break;
10106 case OPC_RECIP1_PS:
10107 check_ps(ctx);
10108 {
10109 TCGv_i64 fp0 = tcg_temp_new_i64();
10110
10111 gen_load_fpr64(ctx, fp0, fs);
10112 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
10113 gen_store_fpr64(ctx, fp0, fd);
10114 tcg_temp_free_i64(fp0);
10115 }
10116 break;
10117 case OPC_RSQRT1_PS:
10118 check_ps(ctx);
10119 {
10120 TCGv_i64 fp0 = tcg_temp_new_i64();
10121
10122 gen_load_fpr64(ctx, fp0, fs);
10123 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
10124 gen_store_fpr64(ctx, fp0, fd);
10125 tcg_temp_free_i64(fp0);
10126 }
10127 break;
10128 case OPC_RSQRT2_PS:
10129 check_ps(ctx);
10130 {
10131 TCGv_i64 fp0 = tcg_temp_new_i64();
10132 TCGv_i64 fp1 = tcg_temp_new_i64();
10133
10134 gen_load_fpr64(ctx, fp0, fs);
10135 gen_load_fpr64(ctx, fp1, ft);
10136 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
10137 tcg_temp_free_i64(fp1);
10138 gen_store_fpr64(ctx, fp0, fd);
10139 tcg_temp_free_i64(fp0);
10140 }
10141 break;
10142 case OPC_CVT_S_PU:
10143 check_cp1_64bitmode(ctx);
10144 {
10145 TCGv_i32 fp0 = tcg_temp_new_i32();
10146
10147 gen_load_fpr32h(ctx, fp0, fs);
10148 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
10149 gen_store_fpr32(ctx, fp0, fd);
10150 tcg_temp_free_i32(fp0);
10151 }
10152 break;
10153 case OPC_CVT_PW_PS:
10154 check_ps(ctx);
10155 {
10156 TCGv_i64 fp0 = tcg_temp_new_i64();
10157
10158 gen_load_fpr64(ctx, fp0, fs);
10159 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
10160 gen_store_fpr64(ctx, fp0, fd);
10161 tcg_temp_free_i64(fp0);
10162 }
10163 break;
10164 case OPC_CVT_S_PL:
10165 check_cp1_64bitmode(ctx);
10166 {
10167 TCGv_i32 fp0 = tcg_temp_new_i32();
10168
10169 gen_load_fpr32(ctx, fp0, fs);
10170 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
10171 gen_store_fpr32(ctx, fp0, fd);
10172 tcg_temp_free_i32(fp0);
10173 }
10174 break;
10175 case OPC_PLL_PS:
10176 check_ps(ctx);
10177 {
10178 TCGv_i32 fp0 = tcg_temp_new_i32();
10179 TCGv_i32 fp1 = tcg_temp_new_i32();
10180
10181 gen_load_fpr32(ctx, fp0, fs);
10182 gen_load_fpr32(ctx, fp1, ft);
10183 gen_store_fpr32h(ctx, fp0, fd);
10184 gen_store_fpr32(ctx, fp1, fd);
10185 tcg_temp_free_i32(fp0);
10186 tcg_temp_free_i32(fp1);
10187 }
10188 break;
10189 case OPC_PLU_PS:
10190 check_ps(ctx);
10191 {
10192 TCGv_i32 fp0 = tcg_temp_new_i32();
10193 TCGv_i32 fp1 = tcg_temp_new_i32();
10194
10195 gen_load_fpr32(ctx, fp0, fs);
10196 gen_load_fpr32h(ctx, fp1, ft);
10197 gen_store_fpr32(ctx, fp1, fd);
10198 gen_store_fpr32h(ctx, fp0, fd);
10199 tcg_temp_free_i32(fp0);
10200 tcg_temp_free_i32(fp1);
10201 }
10202 break;
10203 case OPC_PUL_PS:
10204 check_ps(ctx);
10205 {
10206 TCGv_i32 fp0 = tcg_temp_new_i32();
10207 TCGv_i32 fp1 = tcg_temp_new_i32();
10208
10209 gen_load_fpr32h(ctx, fp0, fs);
10210 gen_load_fpr32(ctx, fp1, ft);
10211 gen_store_fpr32(ctx, fp1, fd);
10212 gen_store_fpr32h(ctx, fp0, fd);
10213 tcg_temp_free_i32(fp0);
10214 tcg_temp_free_i32(fp1);
10215 }
10216 break;
10217 case OPC_PUU_PS:
10218 check_ps(ctx);
10219 {
10220 TCGv_i32 fp0 = tcg_temp_new_i32();
10221 TCGv_i32 fp1 = tcg_temp_new_i32();
10222
10223 gen_load_fpr32h(ctx, fp0, fs);
10224 gen_load_fpr32h(ctx, fp1, ft);
10225 gen_store_fpr32(ctx, fp1, fd);
10226 gen_store_fpr32h(ctx, fp0, fd);
10227 tcg_temp_free_i32(fp0);
10228 tcg_temp_free_i32(fp1);
10229 }
10230 break;
10231 case OPC_CMP_F_PS:
10232 case OPC_CMP_UN_PS:
10233 case OPC_CMP_EQ_PS:
10234 case OPC_CMP_UEQ_PS:
10235 case OPC_CMP_OLT_PS:
10236 case OPC_CMP_ULT_PS:
10237 case OPC_CMP_OLE_PS:
10238 case OPC_CMP_ULE_PS:
10239 case OPC_CMP_SF_PS:
10240 case OPC_CMP_NGLE_PS:
10241 case OPC_CMP_SEQ_PS:
10242 case OPC_CMP_NGL_PS:
10243 case OPC_CMP_LT_PS:
10244 case OPC_CMP_NGE_PS:
10245 case OPC_CMP_LE_PS:
10246 case OPC_CMP_NGT_PS:
10247 if (ctx->opcode & (1 << 6)) {
10248 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10249 } else {
10250 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10251 }
10252 break;
10253 default:
10254 MIPS_INVAL("farith");
10255 generate_exception_end(ctx, EXCP_RI);
10256 return;
10257 }
10258 }
10259
10260 /* Coprocessor 3 (FPU) */
10261 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10262 int fd, int fs, int base, int index)
10263 {
10264 TCGv t0 = tcg_temp_new();
10265
10266 if (base == 0) {
10267 gen_load_gpr(t0, index);
10268 } else if (index == 0) {
10269 gen_load_gpr(t0, base);
10270 } else {
10271 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10272 }
10273 /* Don't do NOP if destination is zero: we must perform the actual
10274 memory access. */
10275 switch (opc) {
10276 case OPC_LWXC1:
10277 check_cop1x(ctx);
10278 {
10279 TCGv_i32 fp0 = tcg_temp_new_i32();
10280
10281 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10282 tcg_gen_trunc_tl_i32(fp0, t0);
10283 gen_store_fpr32(ctx, fp0, fd);
10284 tcg_temp_free_i32(fp0);
10285 }
10286 break;
10287 case OPC_LDXC1:
10288 check_cop1x(ctx);
10289 check_cp1_registers(ctx, fd);
10290 {
10291 TCGv_i64 fp0 = tcg_temp_new_i64();
10292 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10293 gen_store_fpr64(ctx, fp0, fd);
10294 tcg_temp_free_i64(fp0);
10295 }
10296 break;
10297 case OPC_LUXC1:
10298 check_cp1_64bitmode(ctx);
10299 tcg_gen_andi_tl(t0, t0, ~0x7);
10300 {
10301 TCGv_i64 fp0 = tcg_temp_new_i64();
10302
10303 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10304 gen_store_fpr64(ctx, fp0, fd);
10305 tcg_temp_free_i64(fp0);
10306 }
10307 break;
10308 case OPC_SWXC1:
10309 check_cop1x(ctx);
10310 {
10311 TCGv_i32 fp0 = tcg_temp_new_i32();
10312 gen_load_fpr32(ctx, fp0, fs);
10313 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10314 tcg_temp_free_i32(fp0);
10315 }
10316 break;
10317 case OPC_SDXC1:
10318 check_cop1x(ctx);
10319 check_cp1_registers(ctx, fs);
10320 {
10321 TCGv_i64 fp0 = tcg_temp_new_i64();
10322 gen_load_fpr64(ctx, fp0, fs);
10323 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10324 tcg_temp_free_i64(fp0);
10325 }
10326 break;
10327 case OPC_SUXC1:
10328 check_cp1_64bitmode(ctx);
10329 tcg_gen_andi_tl(t0, t0, ~0x7);
10330 {
10331 TCGv_i64 fp0 = tcg_temp_new_i64();
10332 gen_load_fpr64(ctx, fp0, fs);
10333 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10334 tcg_temp_free_i64(fp0);
10335 }
10336 break;
10337 }
10338 tcg_temp_free(t0);
10339 }
10340
10341 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10342 int fd, int fr, int fs, int ft)
10343 {
10344 switch (opc) {
10345 case OPC_ALNV_PS:
10346 check_ps(ctx);
10347 {
10348 TCGv t0 = tcg_temp_local_new();
10349 TCGv_i32 fp = tcg_temp_new_i32();
10350 TCGv_i32 fph = tcg_temp_new_i32();
10351 TCGLabel *l1 = gen_new_label();
10352 TCGLabel *l2 = gen_new_label();
10353
10354 gen_load_gpr(t0, fr);
10355 tcg_gen_andi_tl(t0, t0, 0x7);
10356
10357 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10358 gen_load_fpr32(ctx, fp, fs);
10359 gen_load_fpr32h(ctx, fph, fs);
10360 gen_store_fpr32(ctx, fp, fd);
10361 gen_store_fpr32h(ctx, fph, fd);
10362 tcg_gen_br(l2);
10363 gen_set_label(l1);
10364 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10365 tcg_temp_free(t0);
10366 #ifdef TARGET_WORDS_BIGENDIAN
10367 gen_load_fpr32(ctx, fp, fs);
10368 gen_load_fpr32h(ctx, fph, ft);
10369 gen_store_fpr32h(ctx, fp, fd);
10370 gen_store_fpr32(ctx, fph, fd);
10371 #else
10372 gen_load_fpr32h(ctx, fph, fs);
10373 gen_load_fpr32(ctx, fp, ft);
10374 gen_store_fpr32(ctx, fph, fd);
10375 gen_store_fpr32h(ctx, fp, fd);
10376 #endif
10377 gen_set_label(l2);
10378 tcg_temp_free_i32(fp);
10379 tcg_temp_free_i32(fph);
10380 }
10381 break;
10382 case OPC_MADD_S:
10383 check_cop1x(ctx);
10384 {
10385 TCGv_i32 fp0 = tcg_temp_new_i32();
10386 TCGv_i32 fp1 = tcg_temp_new_i32();
10387 TCGv_i32 fp2 = tcg_temp_new_i32();
10388
10389 gen_load_fpr32(ctx, fp0, fs);
10390 gen_load_fpr32(ctx, fp1, ft);
10391 gen_load_fpr32(ctx, fp2, fr);
10392 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10393 tcg_temp_free_i32(fp0);
10394 tcg_temp_free_i32(fp1);
10395 gen_store_fpr32(ctx, fp2, fd);
10396 tcg_temp_free_i32(fp2);
10397 }
10398 break;
10399 case OPC_MADD_D:
10400 check_cop1x(ctx);
10401 check_cp1_registers(ctx, fd | fs | ft | fr);
10402 {
10403 TCGv_i64 fp0 = tcg_temp_new_i64();
10404 TCGv_i64 fp1 = tcg_temp_new_i64();
10405 TCGv_i64 fp2 = tcg_temp_new_i64();
10406
10407 gen_load_fpr64(ctx, fp0, fs);
10408 gen_load_fpr64(ctx, fp1, ft);
10409 gen_load_fpr64(ctx, fp2, fr);
10410 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10411 tcg_temp_free_i64(fp0);
10412 tcg_temp_free_i64(fp1);
10413 gen_store_fpr64(ctx, fp2, fd);
10414 tcg_temp_free_i64(fp2);
10415 }
10416 break;
10417 case OPC_MADD_PS:
10418 check_ps(ctx);
10419 {
10420 TCGv_i64 fp0 = tcg_temp_new_i64();
10421 TCGv_i64 fp1 = tcg_temp_new_i64();
10422 TCGv_i64 fp2 = tcg_temp_new_i64();
10423
10424 gen_load_fpr64(ctx, fp0, fs);
10425 gen_load_fpr64(ctx, fp1, ft);
10426 gen_load_fpr64(ctx, fp2, fr);
10427 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10428 tcg_temp_free_i64(fp0);
10429 tcg_temp_free_i64(fp1);
10430 gen_store_fpr64(ctx, fp2, fd);
10431 tcg_temp_free_i64(fp2);
10432 }
10433 break;
10434 case OPC_MSUB_S:
10435 check_cop1x(ctx);
10436 {
10437 TCGv_i32 fp0 = tcg_temp_new_i32();
10438 TCGv_i32 fp1 = tcg_temp_new_i32();
10439 TCGv_i32 fp2 = tcg_temp_new_i32();
10440
10441 gen_load_fpr32(ctx, fp0, fs);
10442 gen_load_fpr32(ctx, fp1, ft);
10443 gen_load_fpr32(ctx, fp2, fr);
10444 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10445 tcg_temp_free_i32(fp0);
10446 tcg_temp_free_i32(fp1);
10447 gen_store_fpr32(ctx, fp2, fd);
10448 tcg_temp_free_i32(fp2);
10449 }
10450 break;
10451 case OPC_MSUB_D:
10452 check_cop1x(ctx);
10453 check_cp1_registers(ctx, fd | fs | ft | fr);
10454 {
10455 TCGv_i64 fp0 = tcg_temp_new_i64();
10456 TCGv_i64 fp1 = tcg_temp_new_i64();
10457 TCGv_i64 fp2 = tcg_temp_new_i64();
10458
10459 gen_load_fpr64(ctx, fp0, fs);
10460 gen_load_fpr64(ctx, fp1, ft);
10461 gen_load_fpr64(ctx, fp2, fr);
10462 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10463 tcg_temp_free_i64(fp0);
10464 tcg_temp_free_i64(fp1);
10465 gen_store_fpr64(ctx, fp2, fd);
10466 tcg_temp_free_i64(fp2);
10467 }
10468 break;
10469 case OPC_MSUB_PS:
10470 check_ps(ctx);
10471 {
10472 TCGv_i64 fp0 = tcg_temp_new_i64();
10473 TCGv_i64 fp1 = tcg_temp_new_i64();
10474 TCGv_i64 fp2 = tcg_temp_new_i64();
10475
10476 gen_load_fpr64(ctx, fp0, fs);
10477 gen_load_fpr64(ctx, fp1, ft);
10478 gen_load_fpr64(ctx, fp2, fr);
10479 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10480 tcg_temp_free_i64(fp0);
10481 tcg_temp_free_i64(fp1);
10482 gen_store_fpr64(ctx, fp2, fd);
10483 tcg_temp_free_i64(fp2);
10484 }
10485 break;
10486 case OPC_NMADD_S:
10487 check_cop1x(ctx);
10488 {
10489 TCGv_i32 fp0 = tcg_temp_new_i32();
10490 TCGv_i32 fp1 = tcg_temp_new_i32();
10491 TCGv_i32 fp2 = tcg_temp_new_i32();
10492
10493 gen_load_fpr32(ctx, fp0, fs);
10494 gen_load_fpr32(ctx, fp1, ft);
10495 gen_load_fpr32(ctx, fp2, fr);
10496 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10497 tcg_temp_free_i32(fp0);
10498 tcg_temp_free_i32(fp1);
10499 gen_store_fpr32(ctx, fp2, fd);
10500 tcg_temp_free_i32(fp2);
10501 }
10502 break;
10503 case OPC_NMADD_D:
10504 check_cop1x(ctx);
10505 check_cp1_registers(ctx, fd | fs | ft | fr);
10506 {
10507 TCGv_i64 fp0 = tcg_temp_new_i64();
10508 TCGv_i64 fp1 = tcg_temp_new_i64();
10509 TCGv_i64 fp2 = tcg_temp_new_i64();
10510
10511 gen_load_fpr64(ctx, fp0, fs);
10512 gen_load_fpr64(ctx, fp1, ft);
10513 gen_load_fpr64(ctx, fp2, fr);
10514 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10515 tcg_temp_free_i64(fp0);
10516 tcg_temp_free_i64(fp1);
10517 gen_store_fpr64(ctx, fp2, fd);
10518 tcg_temp_free_i64(fp2);
10519 }
10520 break;
10521 case OPC_NMADD_PS:
10522 check_ps(ctx);
10523 {
10524 TCGv_i64 fp0 = tcg_temp_new_i64();
10525 TCGv_i64 fp1 = tcg_temp_new_i64();
10526 TCGv_i64 fp2 = tcg_temp_new_i64();
10527
10528 gen_load_fpr64(ctx, fp0, fs);
10529 gen_load_fpr64(ctx, fp1, ft);
10530 gen_load_fpr64(ctx, fp2, fr);
10531 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10532 tcg_temp_free_i64(fp0);
10533 tcg_temp_free_i64(fp1);
10534 gen_store_fpr64(ctx, fp2, fd);
10535 tcg_temp_free_i64(fp2);
10536 }
10537 break;
10538 case OPC_NMSUB_S:
10539 check_cop1x(ctx);
10540 {
10541 TCGv_i32 fp0 = tcg_temp_new_i32();
10542 TCGv_i32 fp1 = tcg_temp_new_i32();
10543 TCGv_i32 fp2 = tcg_temp_new_i32();
10544
10545 gen_load_fpr32(ctx, fp0, fs);
10546 gen_load_fpr32(ctx, fp1, ft);
10547 gen_load_fpr32(ctx, fp2, fr);
10548 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10549 tcg_temp_free_i32(fp0);
10550 tcg_temp_free_i32(fp1);
10551 gen_store_fpr32(ctx, fp2, fd);
10552 tcg_temp_free_i32(fp2);
10553 }
10554 break;
10555 case OPC_NMSUB_D:
10556 check_cop1x(ctx);
10557 check_cp1_registers(ctx, fd | fs | ft | fr);
10558 {
10559 TCGv_i64 fp0 = tcg_temp_new_i64();
10560 TCGv_i64 fp1 = tcg_temp_new_i64();
10561 TCGv_i64 fp2 = tcg_temp_new_i64();
10562
10563 gen_load_fpr64(ctx, fp0, fs);
10564 gen_load_fpr64(ctx, fp1, ft);
10565 gen_load_fpr64(ctx, fp2, fr);
10566 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10567 tcg_temp_free_i64(fp0);
10568 tcg_temp_free_i64(fp1);
10569 gen_store_fpr64(ctx, fp2, fd);
10570 tcg_temp_free_i64(fp2);
10571 }
10572 break;
10573 case OPC_NMSUB_PS:
10574 check_ps(ctx);
10575 {
10576 TCGv_i64 fp0 = tcg_temp_new_i64();
10577 TCGv_i64 fp1 = tcg_temp_new_i64();
10578 TCGv_i64 fp2 = tcg_temp_new_i64();
10579
10580 gen_load_fpr64(ctx, fp0, fs);
10581 gen_load_fpr64(ctx, fp1, ft);
10582 gen_load_fpr64(ctx, fp2, fr);
10583 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10584 tcg_temp_free_i64(fp0);
10585 tcg_temp_free_i64(fp1);
10586 gen_store_fpr64(ctx, fp2, fd);
10587 tcg_temp_free_i64(fp2);
10588 }
10589 break;
10590 default:
10591 MIPS_INVAL("flt3_arith");
10592 generate_exception_end(ctx, EXCP_RI);
10593 return;
10594 }
10595 }
10596
10597 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10598 {
10599 TCGv t0;
10600
10601 #if !defined(CONFIG_USER_ONLY)
10602 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10603 Therefore only check the ISA in system mode. */
10604 check_insn(ctx, ISA_MIPS32R2);
10605 #endif
10606 t0 = tcg_temp_new();
10607
10608 switch (rd) {
10609 case 0:
10610 gen_helper_rdhwr_cpunum(t0, cpu_env);
10611 gen_store_gpr(t0, rt);
10612 break;
10613 case 1:
10614 gen_helper_rdhwr_synci_step(t0, cpu_env);
10615 gen_store_gpr(t0, rt);
10616 break;
10617 case 2:
10618 gen_helper_rdhwr_cc(t0, cpu_env);
10619 gen_store_gpr(t0, rt);
10620 break;
10621 case 3:
10622 gen_helper_rdhwr_ccres(t0, cpu_env);
10623 gen_store_gpr(t0, rt);
10624 break;
10625 case 4:
10626 check_insn(ctx, ISA_MIPS32R6);
10627 if (sel != 0) {
10628 /* Performance counter registers are not implemented other than
10629 * control register 0.
10630 */
10631 generate_exception(ctx, EXCP_RI);
10632 }
10633 gen_helper_rdhwr_performance(t0, cpu_env);
10634 gen_store_gpr(t0, rt);
10635 break;
10636 case 5:
10637 check_insn(ctx, ISA_MIPS32R6);
10638 gen_helper_rdhwr_xnp(t0, cpu_env);
10639 gen_store_gpr(t0, rt);
10640 break;
10641 case 29:
10642 #if defined(CONFIG_USER_ONLY)
10643 tcg_gen_ld_tl(t0, cpu_env,
10644 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10645 gen_store_gpr(t0, rt);
10646 break;
10647 #else
10648 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10649 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10650 tcg_gen_ld_tl(t0, cpu_env,
10651 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10652 gen_store_gpr(t0, rt);
10653 } else {
10654 generate_exception_end(ctx, EXCP_RI);
10655 }
10656 break;
10657 #endif
10658 default: /* Invalid */
10659 MIPS_INVAL("rdhwr");
10660 generate_exception_end(ctx, EXCP_RI);
10661 break;
10662 }
10663 tcg_temp_free(t0);
10664 }
10665
10666 static inline void clear_branch_hflags(DisasContext *ctx)
10667 {
10668 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10669 if (ctx->bstate == BS_NONE) {
10670 save_cpu_state(ctx, 0);
10671 } else {
10672 /* it is not safe to save ctx->hflags as hflags may be changed
10673 in execution time by the instruction in delay / forbidden slot. */
10674 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10675 }
10676 }
10677
10678 static void gen_branch(DisasContext *ctx, int insn_bytes)
10679 {
10680 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10681 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10682 /* Branches completion */
10683 clear_branch_hflags(ctx);
10684 ctx->bstate = BS_BRANCH;
10685 /* FIXME: Need to clear can_do_io. */
10686 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10687 case MIPS_HFLAG_FBNSLOT:
10688 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10689 break;
10690 case MIPS_HFLAG_B:
10691 /* unconditional branch */
10692 if (proc_hflags & MIPS_HFLAG_BX) {
10693 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10694 }
10695 gen_goto_tb(ctx, 0, ctx->btarget);
10696 break;
10697 case MIPS_HFLAG_BL:
10698 /* blikely taken case */
10699 gen_goto_tb(ctx, 0, ctx->btarget);
10700 break;
10701 case MIPS_HFLAG_BC:
10702 /* Conditional branch */
10703 {
10704 TCGLabel *l1 = gen_new_label();
10705
10706 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10707 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10708 gen_set_label(l1);
10709 gen_goto_tb(ctx, 0, ctx->btarget);
10710 }
10711 break;
10712 case MIPS_HFLAG_BR:
10713 /* unconditional branch to register */
10714 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10715 TCGv t0 = tcg_temp_new();
10716 TCGv_i32 t1 = tcg_temp_new_i32();
10717
10718 tcg_gen_andi_tl(t0, btarget, 0x1);
10719 tcg_gen_trunc_tl_i32(t1, t0);
10720 tcg_temp_free(t0);
10721 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10722 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10723 tcg_gen_or_i32(hflags, hflags, t1);
10724 tcg_temp_free_i32(t1);
10725
10726 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10727 } else {
10728 tcg_gen_mov_tl(cpu_PC, btarget);
10729 }
10730 if (ctx->singlestep_enabled) {
10731 save_cpu_state(ctx, 0);
10732 gen_helper_raise_exception_debug(cpu_env);
10733 }
10734 tcg_gen_lookup_and_goto_ptr(cpu_PC);
10735 break;
10736 default:
10737 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10738 abort();
10739 }
10740 }
10741 }
10742
10743 /* Compact Branches */
10744 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10745 int rs, int rt, int32_t offset)
10746 {
10747 int bcond_compute = 0;
10748 TCGv t0 = tcg_temp_new();
10749 TCGv t1 = tcg_temp_new();
10750 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10751
10752 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10753 #ifdef MIPS_DEBUG_DISAS
10754 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10755 "\n", ctx->pc);
10756 #endif
10757 generate_exception_end(ctx, EXCP_RI);
10758 goto out;
10759 }
10760
10761 /* Load needed operands and calculate btarget */
10762 switch (opc) {
10763 /* compact branch */
10764 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10765 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10766 gen_load_gpr(t0, rs);
10767 gen_load_gpr(t1, rt);
10768 bcond_compute = 1;
10769 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10770 if (rs <= rt && rs == 0) {
10771 /* OPC_BEQZALC, OPC_BNEZALC */
10772 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10773 }
10774 break;
10775 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10776 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10777 gen_load_gpr(t0, rs);
10778 gen_load_gpr(t1, rt);
10779 bcond_compute = 1;
10780 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10781 break;
10782 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10783 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10784 if (rs == 0 || rs == rt) {
10785 /* OPC_BLEZALC, OPC_BGEZALC */
10786 /* OPC_BGTZALC, OPC_BLTZALC */
10787 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10788 }
10789 gen_load_gpr(t0, rs);
10790 gen_load_gpr(t1, rt);
10791 bcond_compute = 1;
10792 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10793 break;
10794 case OPC_BC:
10795 case OPC_BALC:
10796 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10797 break;
10798 case OPC_BEQZC:
10799 case OPC_BNEZC:
10800 if (rs != 0) {
10801 /* OPC_BEQZC, OPC_BNEZC */
10802 gen_load_gpr(t0, rs);
10803 bcond_compute = 1;
10804 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10805 } else {
10806 /* OPC_JIC, OPC_JIALC */
10807 TCGv tbase = tcg_temp_new();
10808 TCGv toffset = tcg_temp_new();
10809
10810 gen_load_gpr(tbase, rt);
10811 tcg_gen_movi_tl(toffset, offset);
10812 gen_op_addr_add(ctx, btarget, tbase, toffset);
10813 tcg_temp_free(tbase);
10814 tcg_temp_free(toffset);
10815 }
10816 break;
10817 default:
10818 MIPS_INVAL("Compact branch/jump");
10819 generate_exception_end(ctx, EXCP_RI);
10820 goto out;
10821 }
10822
10823 if (bcond_compute == 0) {
10824 /* Uncoditional compact branch */
10825 switch (opc) {
10826 case OPC_JIALC:
10827 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10828 /* Fallthrough */
10829 case OPC_JIC:
10830 ctx->hflags |= MIPS_HFLAG_BR;
10831 break;
10832 case OPC_BALC:
10833 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10834 /* Fallthrough */
10835 case OPC_BC:
10836 ctx->hflags |= MIPS_HFLAG_B;
10837 break;
10838 default:
10839 MIPS_INVAL("Compact branch/jump");
10840 generate_exception_end(ctx, EXCP_RI);
10841 goto out;
10842 }
10843
10844 /* Generating branch here as compact branches don't have delay slot */
10845 gen_branch(ctx, 4);
10846 } else {
10847 /* Conditional compact branch */
10848 TCGLabel *fs = gen_new_label();
10849 save_cpu_state(ctx, 0);
10850
10851 switch (opc) {
10852 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10853 if (rs == 0 && rt != 0) {
10854 /* OPC_BLEZALC */
10855 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10856 } else if (rs != 0 && rt != 0 && rs == rt) {
10857 /* OPC_BGEZALC */
10858 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10859 } else {
10860 /* OPC_BGEUC */
10861 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10862 }
10863 break;
10864 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10865 if (rs == 0 && rt != 0) {
10866 /* OPC_BGTZALC */
10867 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10868 } else if (rs != 0 && rt != 0 && rs == rt) {
10869 /* OPC_BLTZALC */
10870 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10871 } else {
10872 /* OPC_BLTUC */
10873 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10874 }
10875 break;
10876 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10877 if (rs == 0 && rt != 0) {
10878 /* OPC_BLEZC */
10879 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10880 } else if (rs != 0 && rt != 0 && rs == rt) {
10881 /* OPC_BGEZC */
10882 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10883 } else {
10884 /* OPC_BGEC */
10885 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10886 }
10887 break;
10888 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10889 if (rs == 0 && rt != 0) {
10890 /* OPC_BGTZC */
10891 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10892 } else if (rs != 0 && rt != 0 && rs == rt) {
10893 /* OPC_BLTZC */
10894 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10895 } else {
10896 /* OPC_BLTC */
10897 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10898 }
10899 break;
10900 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10901 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10902 if (rs >= rt) {
10903 /* OPC_BOVC, OPC_BNVC */
10904 TCGv t2 = tcg_temp_new();
10905 TCGv t3 = tcg_temp_new();
10906 TCGv t4 = tcg_temp_new();
10907 TCGv input_overflow = tcg_temp_new();
10908
10909 gen_load_gpr(t0, rs);
10910 gen_load_gpr(t1, rt);
10911 tcg_gen_ext32s_tl(t2, t0);
10912 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10913 tcg_gen_ext32s_tl(t3, t1);
10914 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10915 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10916
10917 tcg_gen_add_tl(t4, t2, t3);
10918 tcg_gen_ext32s_tl(t4, t4);
10919 tcg_gen_xor_tl(t2, t2, t3);
10920 tcg_gen_xor_tl(t3, t4, t3);
10921 tcg_gen_andc_tl(t2, t3, t2);
10922 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10923 tcg_gen_or_tl(t4, t4, input_overflow);
10924 if (opc == OPC_BOVC) {
10925 /* OPC_BOVC */
10926 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10927 } else {
10928 /* OPC_BNVC */
10929 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10930 }
10931 tcg_temp_free(input_overflow);
10932 tcg_temp_free(t4);
10933 tcg_temp_free(t3);
10934 tcg_temp_free(t2);
10935 } else if (rs < rt && rs == 0) {
10936 /* OPC_BEQZALC, OPC_BNEZALC */
10937 if (opc == OPC_BEQZALC) {
10938 /* OPC_BEQZALC */
10939 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10940 } else {
10941 /* OPC_BNEZALC */
10942 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10943 }
10944 } else {
10945 /* OPC_BEQC, OPC_BNEC */
10946 if (opc == OPC_BEQC) {
10947 /* OPC_BEQC */
10948 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10949 } else {
10950 /* OPC_BNEC */
10951 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10952 }
10953 }
10954 break;
10955 case OPC_BEQZC:
10956 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10957 break;
10958 case OPC_BNEZC:
10959 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10960 break;
10961 default:
10962 MIPS_INVAL("Compact conditional branch/jump");
10963 generate_exception_end(ctx, EXCP_RI);
10964 goto out;
10965 }
10966
10967 /* Generating branch here as compact branches don't have delay slot */
10968 gen_goto_tb(ctx, 1, ctx->btarget);
10969 gen_set_label(fs);
10970
10971 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
10972 }
10973
10974 out:
10975 tcg_temp_free(t0);
10976 tcg_temp_free(t1);
10977 }
10978
10979 /* ISA extensions (ASEs) */
10980 /* MIPS16 extension to MIPS32 */
10981
10982 /* MIPS16 major opcodes */
10983 enum {
10984 M16_OPC_ADDIUSP = 0x00,
10985 M16_OPC_ADDIUPC = 0x01,
10986 M16_OPC_B = 0x02,
10987 M16_OPC_JAL = 0x03,
10988 M16_OPC_BEQZ = 0x04,
10989 M16_OPC_BNEQZ = 0x05,
10990 M16_OPC_SHIFT = 0x06,
10991 M16_OPC_LD = 0x07,
10992 M16_OPC_RRIA = 0x08,
10993 M16_OPC_ADDIU8 = 0x09,
10994 M16_OPC_SLTI = 0x0a,
10995 M16_OPC_SLTIU = 0x0b,
10996 M16_OPC_I8 = 0x0c,
10997 M16_OPC_LI = 0x0d,
10998 M16_OPC_CMPI = 0x0e,
10999 M16_OPC_SD = 0x0f,
11000 M16_OPC_LB = 0x10,
11001 M16_OPC_LH = 0x11,
11002 M16_OPC_LWSP = 0x12,
11003 M16_OPC_LW = 0x13,
11004 M16_OPC_LBU = 0x14,
11005 M16_OPC_LHU = 0x15,
11006 M16_OPC_LWPC = 0x16,
11007 M16_OPC_LWU = 0x17,
11008 M16_OPC_SB = 0x18,
11009 M16_OPC_SH = 0x19,
11010 M16_OPC_SWSP = 0x1a,
11011 M16_OPC_SW = 0x1b,
11012 M16_OPC_RRR = 0x1c,
11013 M16_OPC_RR = 0x1d,
11014 M16_OPC_EXTEND = 0x1e,
11015 M16_OPC_I64 = 0x1f
11016 };
11017
11018 /* I8 funct field */
11019 enum {
11020 I8_BTEQZ = 0x0,
11021 I8_BTNEZ = 0x1,
11022 I8_SWRASP = 0x2,
11023 I8_ADJSP = 0x3,
11024 I8_SVRS = 0x4,
11025 I8_MOV32R = 0x5,
11026 I8_MOVR32 = 0x7
11027 };
11028
11029 /* RRR f field */
11030 enum {
11031 RRR_DADDU = 0x0,
11032 RRR_ADDU = 0x1,
11033 RRR_DSUBU = 0x2,
11034 RRR_SUBU = 0x3
11035 };
11036
11037 /* RR funct field */
11038 enum {
11039 RR_JR = 0x00,
11040 RR_SDBBP = 0x01,
11041 RR_SLT = 0x02,
11042 RR_SLTU = 0x03,
11043 RR_SLLV = 0x04,
11044 RR_BREAK = 0x05,
11045 RR_SRLV = 0x06,
11046 RR_SRAV = 0x07,
11047 RR_DSRL = 0x08,
11048 RR_CMP = 0x0a,
11049 RR_NEG = 0x0b,
11050 RR_AND = 0x0c,
11051 RR_OR = 0x0d,
11052 RR_XOR = 0x0e,
11053 RR_NOT = 0x0f,
11054 RR_MFHI = 0x10,
11055 RR_CNVT = 0x11,
11056 RR_MFLO = 0x12,
11057 RR_DSRA = 0x13,
11058 RR_DSLLV = 0x14,
11059 RR_DSRLV = 0x16,
11060 RR_DSRAV = 0x17,
11061 RR_MULT = 0x18,
11062 RR_MULTU = 0x19,
11063 RR_DIV = 0x1a,
11064 RR_DIVU = 0x1b,
11065 RR_DMULT = 0x1c,
11066 RR_DMULTU = 0x1d,
11067 RR_DDIV = 0x1e,
11068 RR_DDIVU = 0x1f
11069 };
11070
11071 /* I64 funct field */
11072 enum {
11073 I64_LDSP = 0x0,
11074 I64_SDSP = 0x1,
11075 I64_SDRASP = 0x2,
11076 I64_DADJSP = 0x3,
11077 I64_LDPC = 0x4,
11078 I64_DADDIU5 = 0x5,
11079 I64_DADDIUPC = 0x6,
11080 I64_DADDIUSP = 0x7
11081 };
11082
11083 /* RR ry field for CNVT */
11084 enum {
11085 RR_RY_CNVT_ZEB = 0x0,
11086 RR_RY_CNVT_ZEH = 0x1,
11087 RR_RY_CNVT_ZEW = 0x2,
11088 RR_RY_CNVT_SEB = 0x4,
11089 RR_RY_CNVT_SEH = 0x5,
11090 RR_RY_CNVT_SEW = 0x6,
11091 };
11092
11093 static int xlat (int r)
11094 {
11095 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11096
11097 return map[r];
11098 }
11099
11100 static void gen_mips16_save (DisasContext *ctx,
11101 int xsregs, int aregs,
11102 int do_ra, int do_s0, int do_s1,
11103 int framesize)
11104 {
11105 TCGv t0 = tcg_temp_new();
11106 TCGv t1 = tcg_temp_new();
11107 TCGv t2 = tcg_temp_new();
11108 int args, astatic;
11109
11110 switch (aregs) {
11111 case 0:
11112 case 1:
11113 case 2:
11114 case 3:
11115 case 11:
11116 args = 0;
11117 break;
11118 case 4:
11119 case 5:
11120 case 6:
11121 case 7:
11122 args = 1;
11123 break;
11124 case 8:
11125 case 9:
11126 case 10:
11127 args = 2;
11128 break;
11129 case 12:
11130 case 13:
11131 args = 3;
11132 break;
11133 case 14:
11134 args = 4;
11135 break;
11136 default:
11137 generate_exception_end(ctx, EXCP_RI);
11138 return;
11139 }
11140
11141 switch (args) {
11142 case 4:
11143 gen_base_offset_addr(ctx, t0, 29, 12);
11144 gen_load_gpr(t1, 7);
11145 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11146 /* Fall through */
11147 case 3:
11148 gen_base_offset_addr(ctx, t0, 29, 8);
11149 gen_load_gpr(t1, 6);
11150 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11151 /* Fall through */
11152 case 2:
11153 gen_base_offset_addr(ctx, t0, 29, 4);
11154 gen_load_gpr(t1, 5);
11155 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11156 /* Fall through */
11157 case 1:
11158 gen_base_offset_addr(ctx, t0, 29, 0);
11159 gen_load_gpr(t1, 4);
11160 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11161 }
11162
11163 gen_load_gpr(t0, 29);
11164
11165 #define DECR_AND_STORE(reg) do { \
11166 tcg_gen_movi_tl(t2, -4); \
11167 gen_op_addr_add(ctx, t0, t0, t2); \
11168 gen_load_gpr(t1, reg); \
11169 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11170 } while (0)
11171
11172 if (do_ra) {
11173 DECR_AND_STORE(31);
11174 }
11175
11176 switch (xsregs) {
11177 case 7:
11178 DECR_AND_STORE(30);
11179 /* Fall through */
11180 case 6:
11181 DECR_AND_STORE(23);
11182 /* Fall through */
11183 case 5:
11184 DECR_AND_STORE(22);
11185 /* Fall through */
11186 case 4:
11187 DECR_AND_STORE(21);
11188 /* Fall through */
11189 case 3:
11190 DECR_AND_STORE(20);
11191 /* Fall through */
11192 case 2:
11193 DECR_AND_STORE(19);
11194 /* Fall through */
11195 case 1:
11196 DECR_AND_STORE(18);
11197 }
11198
11199 if (do_s1) {
11200 DECR_AND_STORE(17);
11201 }
11202 if (do_s0) {
11203 DECR_AND_STORE(16);
11204 }
11205
11206 switch (aregs) {
11207 case 0:
11208 case 4:
11209 case 8:
11210 case 12:
11211 case 14:
11212 astatic = 0;
11213 break;
11214 case 1:
11215 case 5:
11216 case 9:
11217 case 13:
11218 astatic = 1;
11219 break;
11220 case 2:
11221 case 6:
11222 case 10:
11223 astatic = 2;
11224 break;
11225 case 3:
11226 case 7:
11227 astatic = 3;
11228 break;
11229 case 11:
11230 astatic = 4;
11231 break;
11232 default:
11233 generate_exception_end(ctx, EXCP_RI);
11234 return;
11235 }
11236
11237 if (astatic > 0) {
11238 DECR_AND_STORE(7);
11239 if (astatic > 1) {
11240 DECR_AND_STORE(6);
11241 if (astatic > 2) {
11242 DECR_AND_STORE(5);
11243 if (astatic > 3) {
11244 DECR_AND_STORE(4);
11245 }
11246 }
11247 }
11248 }
11249 #undef DECR_AND_STORE
11250
11251 tcg_gen_movi_tl(t2, -framesize);
11252 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11253 tcg_temp_free(t0);
11254 tcg_temp_free(t1);
11255 tcg_temp_free(t2);
11256 }
11257
11258 static void gen_mips16_restore (DisasContext *ctx,
11259 int xsregs, int aregs,
11260 int do_ra, int do_s0, int do_s1,
11261 int framesize)
11262 {
11263 int astatic;
11264 TCGv t0 = tcg_temp_new();
11265 TCGv t1 = tcg_temp_new();
11266 TCGv t2 = tcg_temp_new();
11267
11268 tcg_gen_movi_tl(t2, framesize);
11269 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
11270
11271 #define DECR_AND_LOAD(reg) do { \
11272 tcg_gen_movi_tl(t2, -4); \
11273 gen_op_addr_add(ctx, t0, t0, t2); \
11274 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11275 gen_store_gpr(t1, reg); \
11276 } while (0)
11277
11278 if (do_ra) {
11279 DECR_AND_LOAD(31);
11280 }
11281
11282 switch (xsregs) {
11283 case 7:
11284 DECR_AND_LOAD(30);
11285 /* Fall through */
11286 case 6:
11287 DECR_AND_LOAD(23);
11288 /* Fall through */
11289 case 5:
11290 DECR_AND_LOAD(22);
11291 /* Fall through */
11292 case 4:
11293 DECR_AND_LOAD(21);
11294 /* Fall through */
11295 case 3:
11296 DECR_AND_LOAD(20);
11297 /* Fall through */
11298 case 2:
11299 DECR_AND_LOAD(19);
11300 /* Fall through */
11301 case 1:
11302 DECR_AND_LOAD(18);
11303 }
11304
11305 if (do_s1) {
11306 DECR_AND_LOAD(17);
11307 }
11308 if (do_s0) {
11309 DECR_AND_LOAD(16);
11310 }
11311
11312 switch (aregs) {
11313 case 0:
11314 case 4:
11315 case 8:
11316 case 12:
11317 case 14:
11318 astatic = 0;
11319 break;
11320 case 1:
11321 case 5:
11322 case 9:
11323 case 13:
11324 astatic = 1;
11325 break;
11326 case 2:
11327 case 6:
11328 case 10:
11329 astatic = 2;
11330 break;
11331 case 3:
11332 case 7:
11333 astatic = 3;
11334 break;
11335 case 11:
11336 astatic = 4;
11337 break;
11338 default:
11339 generate_exception_end(ctx, EXCP_RI);
11340 return;
11341 }
11342
11343 if (astatic > 0) {
11344 DECR_AND_LOAD(7);
11345 if (astatic > 1) {
11346 DECR_AND_LOAD(6);
11347 if (astatic > 2) {
11348 DECR_AND_LOAD(5);
11349 if (astatic > 3) {
11350 DECR_AND_LOAD(4);
11351 }
11352 }
11353 }
11354 }
11355 #undef DECR_AND_LOAD
11356
11357 tcg_gen_movi_tl(t2, framesize);
11358 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11359 tcg_temp_free(t0);
11360 tcg_temp_free(t1);
11361 tcg_temp_free(t2);
11362 }
11363
11364 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11365 int is_64_bit, int extended)
11366 {
11367 TCGv t0;
11368
11369 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11370 generate_exception_end(ctx, EXCP_RI);
11371 return;
11372 }
11373
11374 t0 = tcg_temp_new();
11375
11376 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11377 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11378 if (!is_64_bit) {
11379 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11380 }
11381
11382 tcg_temp_free(t0);
11383 }
11384
11385 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
11386 int16_t offset)
11387 {
11388 TCGv_i32 t0 = tcg_const_i32(op);
11389 TCGv t1 = tcg_temp_new();
11390 gen_base_offset_addr(ctx, t1, base, offset);
11391 gen_helper_cache(cpu_env, t1, t0);
11392 }
11393
11394 #if defined(TARGET_MIPS64)
11395 static void decode_i64_mips16 (DisasContext *ctx,
11396 int ry, int funct, int16_t offset,
11397 int extended)
11398 {
11399 switch (funct) {
11400 case I64_LDSP:
11401 check_insn(ctx, ISA_MIPS3);
11402 check_mips_64(ctx);
11403 offset = extended ? offset : offset << 3;
11404 gen_ld(ctx, OPC_LD, ry, 29, offset);
11405 break;
11406 case I64_SDSP:
11407 check_insn(ctx, ISA_MIPS3);
11408 check_mips_64(ctx);
11409 offset = extended ? offset : offset << 3;
11410 gen_st(ctx, OPC_SD, ry, 29, offset);
11411 break;
11412 case I64_SDRASP:
11413 check_insn(ctx, ISA_MIPS3);
11414 check_mips_64(ctx);
11415 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11416 gen_st(ctx, OPC_SD, 31, 29, offset);
11417 break;
11418 case I64_DADJSP:
11419 check_insn(ctx, ISA_MIPS3);
11420 check_mips_64(ctx);
11421 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11422 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11423 break;
11424 case I64_LDPC:
11425 check_insn(ctx, ISA_MIPS3);
11426 check_mips_64(ctx);
11427 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11428 generate_exception_end(ctx, EXCP_RI);
11429 } else {
11430 offset = extended ? offset : offset << 3;
11431 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11432 }
11433 break;
11434 case I64_DADDIU5:
11435 check_insn(ctx, ISA_MIPS3);
11436 check_mips_64(ctx);
11437 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11438 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11439 break;
11440 case I64_DADDIUPC:
11441 check_insn(ctx, ISA_MIPS3);
11442 check_mips_64(ctx);
11443 offset = extended ? offset : offset << 2;
11444 gen_addiupc(ctx, ry, offset, 1, extended);
11445 break;
11446 case I64_DADDIUSP:
11447 check_insn(ctx, ISA_MIPS3);
11448 check_mips_64(ctx);
11449 offset = extended ? offset : offset << 2;
11450 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11451 break;
11452 }
11453 }
11454 #endif
11455
11456 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11457 {
11458 int extend = cpu_lduw_code(env, ctx->pc + 2);
11459 int op, rx, ry, funct, sa;
11460 int16_t imm, offset;
11461
11462 ctx->opcode = (ctx->opcode << 16) | extend;
11463 op = (ctx->opcode >> 11) & 0x1f;
11464 sa = (ctx->opcode >> 22) & 0x1f;
11465 funct = (ctx->opcode >> 8) & 0x7;
11466 rx = xlat((ctx->opcode >> 8) & 0x7);
11467 ry = xlat((ctx->opcode >> 5) & 0x7);
11468 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11469 | ((ctx->opcode >> 21) & 0x3f) << 5
11470 | (ctx->opcode & 0x1f));
11471
11472 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11473 counterparts. */
11474 switch (op) {
11475 case M16_OPC_ADDIUSP:
11476 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11477 break;
11478 case M16_OPC_ADDIUPC:
11479 gen_addiupc(ctx, rx, imm, 0, 1);
11480 break;
11481 case M16_OPC_B:
11482 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11483 /* No delay slot, so just process as a normal instruction */
11484 break;
11485 case M16_OPC_BEQZ:
11486 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11487 /* No delay slot, so just process as a normal instruction */
11488 break;
11489 case M16_OPC_BNEQZ:
11490 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11491 /* No delay slot, so just process as a normal instruction */
11492 break;
11493 case M16_OPC_SHIFT:
11494 switch (ctx->opcode & 0x3) {
11495 case 0x0:
11496 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11497 break;
11498 case 0x1:
11499 #if defined(TARGET_MIPS64)
11500 check_mips_64(ctx);
11501 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11502 #else
11503 generate_exception_end(ctx, EXCP_RI);
11504 #endif
11505 break;
11506 case 0x2:
11507 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11508 break;
11509 case 0x3:
11510 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11511 break;
11512 }
11513 break;
11514 #if defined(TARGET_MIPS64)
11515 case M16_OPC_LD:
11516 check_insn(ctx, ISA_MIPS3);
11517 check_mips_64(ctx);
11518 gen_ld(ctx, OPC_LD, ry, rx, offset);
11519 break;
11520 #endif
11521 case M16_OPC_RRIA:
11522 imm = ctx->opcode & 0xf;
11523 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11524 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11525 imm = (int16_t) (imm << 1) >> 1;
11526 if ((ctx->opcode >> 4) & 0x1) {
11527 #if defined(TARGET_MIPS64)
11528 check_mips_64(ctx);
11529 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11530 #else
11531 generate_exception_end(ctx, EXCP_RI);
11532 #endif
11533 } else {
11534 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11535 }
11536 break;
11537 case M16_OPC_ADDIU8:
11538 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11539 break;
11540 case M16_OPC_SLTI:
11541 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11542 break;
11543 case M16_OPC_SLTIU:
11544 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11545 break;
11546 case M16_OPC_I8:
11547 switch (funct) {
11548 case I8_BTEQZ:
11549 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11550 break;
11551 case I8_BTNEZ:
11552 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11553 break;
11554 case I8_SWRASP:
11555 gen_st(ctx, OPC_SW, 31, 29, imm);
11556 break;
11557 case I8_ADJSP:
11558 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11559 break;
11560 case I8_SVRS:
11561 check_insn(ctx, ISA_MIPS32);
11562 {
11563 int xsregs = (ctx->opcode >> 24) & 0x7;
11564 int aregs = (ctx->opcode >> 16) & 0xf;
11565 int do_ra = (ctx->opcode >> 6) & 0x1;
11566 int do_s0 = (ctx->opcode >> 5) & 0x1;
11567 int do_s1 = (ctx->opcode >> 4) & 0x1;
11568 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11569 | (ctx->opcode & 0xf)) << 3;
11570
11571 if (ctx->opcode & (1 << 7)) {
11572 gen_mips16_save(ctx, xsregs, aregs,
11573 do_ra, do_s0, do_s1,
11574 framesize);
11575 } else {
11576 gen_mips16_restore(ctx, xsregs, aregs,
11577 do_ra, do_s0, do_s1,
11578 framesize);
11579 }
11580 }
11581 break;
11582 default:
11583 generate_exception_end(ctx, EXCP_RI);
11584 break;
11585 }
11586 break;
11587 case M16_OPC_LI:
11588 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11589 break;
11590 case M16_OPC_CMPI:
11591 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11592 break;
11593 #if defined(TARGET_MIPS64)
11594 case M16_OPC_SD:
11595 check_insn(ctx, ISA_MIPS3);
11596 check_mips_64(ctx);
11597 gen_st(ctx, OPC_SD, ry, rx, offset);
11598 break;
11599 #endif
11600 case M16_OPC_LB:
11601 gen_ld(ctx, OPC_LB, ry, rx, offset);
11602 break;
11603 case M16_OPC_LH:
11604 gen_ld(ctx, OPC_LH, ry, rx, offset);
11605 break;
11606 case M16_OPC_LWSP:
11607 gen_ld(ctx, OPC_LW, rx, 29, offset);
11608 break;
11609 case M16_OPC_LW:
11610 gen_ld(ctx, OPC_LW, ry, rx, offset);
11611 break;
11612 case M16_OPC_LBU:
11613 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11614 break;
11615 case M16_OPC_LHU:
11616 gen_ld(ctx, OPC_LHU, ry, rx, offset);
11617 break;
11618 case M16_OPC_LWPC:
11619 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11620 break;
11621 #if defined(TARGET_MIPS64)
11622 case M16_OPC_LWU:
11623 check_insn(ctx, ISA_MIPS3);
11624 check_mips_64(ctx);
11625 gen_ld(ctx, OPC_LWU, ry, rx, offset);
11626 break;
11627 #endif
11628 case M16_OPC_SB:
11629 gen_st(ctx, OPC_SB, ry, rx, offset);
11630 break;
11631 case M16_OPC_SH:
11632 gen_st(ctx, OPC_SH, ry, rx, offset);
11633 break;
11634 case M16_OPC_SWSP:
11635 gen_st(ctx, OPC_SW, rx, 29, offset);
11636 break;
11637 case M16_OPC_SW:
11638 gen_st(ctx, OPC_SW, ry, rx, offset);
11639 break;
11640 #if defined(TARGET_MIPS64)
11641 case M16_OPC_I64:
11642 decode_i64_mips16(ctx, ry, funct, offset, 1);
11643 break;
11644 #endif
11645 default:
11646 generate_exception_end(ctx, EXCP_RI);
11647 break;
11648 }
11649
11650 return 4;
11651 }
11652
11653 static inline bool is_uhi(int sdbbp_code)
11654 {
11655 #ifdef CONFIG_USER_ONLY
11656 return false;
11657 #else
11658 return semihosting_enabled() && sdbbp_code == 1;
11659 #endif
11660 }
11661
11662 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11663 {
11664 int rx, ry;
11665 int sa;
11666 int op, cnvt_op, op1, offset;
11667 int funct;
11668 int n_bytes;
11669
11670 op = (ctx->opcode >> 11) & 0x1f;
11671 sa = (ctx->opcode >> 2) & 0x7;
11672 sa = sa == 0 ? 8 : sa;
11673 rx = xlat((ctx->opcode >> 8) & 0x7);
11674 cnvt_op = (ctx->opcode >> 5) & 0x7;
11675 ry = xlat((ctx->opcode >> 5) & 0x7);
11676 op1 = offset = ctx->opcode & 0x1f;
11677
11678 n_bytes = 2;
11679
11680 switch (op) {
11681 case M16_OPC_ADDIUSP:
11682 {
11683 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11684
11685 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11686 }
11687 break;
11688 case M16_OPC_ADDIUPC:
11689 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11690 break;
11691 case M16_OPC_B:
11692 offset = (ctx->opcode & 0x7ff) << 1;
11693 offset = (int16_t)(offset << 4) >> 4;
11694 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11695 /* No delay slot, so just process as a normal instruction */
11696 break;
11697 case M16_OPC_JAL:
11698 offset = cpu_lduw_code(env, ctx->pc + 2);
11699 offset = (((ctx->opcode & 0x1f) << 21)
11700 | ((ctx->opcode >> 5) & 0x1f) << 16
11701 | offset) << 2;
11702 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11703 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11704 n_bytes = 4;
11705 break;
11706 case M16_OPC_BEQZ:
11707 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11708 ((int8_t)ctx->opcode) << 1, 0);
11709 /* No delay slot, so just process as a normal instruction */
11710 break;
11711 case M16_OPC_BNEQZ:
11712 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11713 ((int8_t)ctx->opcode) << 1, 0);
11714 /* No delay slot, so just process as a normal instruction */
11715 break;
11716 case M16_OPC_SHIFT:
11717 switch (ctx->opcode & 0x3) {
11718 case 0x0:
11719 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11720 break;
11721 case 0x1:
11722 #if defined(TARGET_MIPS64)
11723 check_insn(ctx, ISA_MIPS3);
11724 check_mips_64(ctx);
11725 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11726 #else
11727 generate_exception_end(ctx, EXCP_RI);
11728 #endif
11729 break;
11730 case 0x2:
11731 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11732 break;
11733 case 0x3:
11734 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11735 break;
11736 }
11737 break;
11738 #if defined(TARGET_MIPS64)
11739 case M16_OPC_LD:
11740 check_insn(ctx, ISA_MIPS3);
11741 check_mips_64(ctx);
11742 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11743 break;
11744 #endif
11745 case M16_OPC_RRIA:
11746 {
11747 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11748
11749 if ((ctx->opcode >> 4) & 1) {
11750 #if defined(TARGET_MIPS64)
11751 check_insn(ctx, ISA_MIPS3);
11752 check_mips_64(ctx);
11753 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11754 #else
11755 generate_exception_end(ctx, EXCP_RI);
11756 #endif
11757 } else {
11758 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11759 }
11760 }
11761 break;
11762 case M16_OPC_ADDIU8:
11763 {
11764 int16_t imm = (int8_t) ctx->opcode;
11765
11766 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11767 }
11768 break;
11769 case M16_OPC_SLTI:
11770 {
11771 int16_t imm = (uint8_t) ctx->opcode;
11772 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11773 }
11774 break;
11775 case M16_OPC_SLTIU:
11776 {
11777 int16_t imm = (uint8_t) ctx->opcode;
11778 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11779 }
11780 break;
11781 case M16_OPC_I8:
11782 {
11783 int reg32;
11784
11785 funct = (ctx->opcode >> 8) & 0x7;
11786 switch (funct) {
11787 case I8_BTEQZ:
11788 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11789 ((int8_t)ctx->opcode) << 1, 0);
11790 break;
11791 case I8_BTNEZ:
11792 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11793 ((int8_t)ctx->opcode) << 1, 0);
11794 break;
11795 case I8_SWRASP:
11796 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11797 break;
11798 case I8_ADJSP:
11799 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11800 ((int8_t)ctx->opcode) << 3);
11801 break;
11802 case I8_SVRS:
11803 check_insn(ctx, ISA_MIPS32);
11804 {
11805 int do_ra = ctx->opcode & (1 << 6);
11806 int do_s0 = ctx->opcode & (1 << 5);
11807 int do_s1 = ctx->opcode & (1 << 4);
11808 int framesize = ctx->opcode & 0xf;
11809
11810 if (framesize == 0) {
11811 framesize = 128;
11812 } else {
11813 framesize = framesize << 3;
11814 }
11815
11816 if (ctx->opcode & (1 << 7)) {
11817 gen_mips16_save(ctx, 0, 0,
11818 do_ra, do_s0, do_s1, framesize);
11819 } else {
11820 gen_mips16_restore(ctx, 0, 0,
11821 do_ra, do_s0, do_s1, framesize);
11822 }
11823 }
11824 break;
11825 case I8_MOV32R:
11826 {
11827 int rz = xlat(ctx->opcode & 0x7);
11828
11829 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11830 ((ctx->opcode >> 5) & 0x7);
11831 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11832 }
11833 break;
11834 case I8_MOVR32:
11835 reg32 = ctx->opcode & 0x1f;
11836 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11837 break;
11838 default:
11839 generate_exception_end(ctx, EXCP_RI);
11840 break;
11841 }
11842 }
11843 break;
11844 case M16_OPC_LI:
11845 {
11846 int16_t imm = (uint8_t) ctx->opcode;
11847
11848 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11849 }
11850 break;
11851 case M16_OPC_CMPI:
11852 {
11853 int16_t imm = (uint8_t) ctx->opcode;
11854 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11855 }
11856 break;
11857 #if defined(TARGET_MIPS64)
11858 case M16_OPC_SD:
11859 check_insn(ctx, ISA_MIPS3);
11860 check_mips_64(ctx);
11861 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11862 break;
11863 #endif
11864 case M16_OPC_LB:
11865 gen_ld(ctx, OPC_LB, ry, rx, offset);
11866 break;
11867 case M16_OPC_LH:
11868 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11869 break;
11870 case M16_OPC_LWSP:
11871 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11872 break;
11873 case M16_OPC_LW:
11874 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11875 break;
11876 case M16_OPC_LBU:
11877 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11878 break;
11879 case M16_OPC_LHU:
11880 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11881 break;
11882 case M16_OPC_LWPC:
11883 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11884 break;
11885 #if defined (TARGET_MIPS64)
11886 case M16_OPC_LWU:
11887 check_insn(ctx, ISA_MIPS3);
11888 check_mips_64(ctx);
11889 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11890 break;
11891 #endif
11892 case M16_OPC_SB:
11893 gen_st(ctx, OPC_SB, ry, rx, offset);
11894 break;
11895 case M16_OPC_SH:
11896 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11897 break;
11898 case M16_OPC_SWSP:
11899 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11900 break;
11901 case M16_OPC_SW:
11902 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11903 break;
11904 case M16_OPC_RRR:
11905 {
11906 int rz = xlat((ctx->opcode >> 2) & 0x7);
11907 int mips32_op;
11908
11909 switch (ctx->opcode & 0x3) {
11910 case RRR_ADDU:
11911 mips32_op = OPC_ADDU;
11912 break;
11913 case RRR_SUBU:
11914 mips32_op = OPC_SUBU;
11915 break;
11916 #if defined(TARGET_MIPS64)
11917 case RRR_DADDU:
11918 mips32_op = OPC_DADDU;
11919 check_insn(ctx, ISA_MIPS3);
11920 check_mips_64(ctx);
11921 break;
11922 case RRR_DSUBU:
11923 mips32_op = OPC_DSUBU;
11924 check_insn(ctx, ISA_MIPS3);
11925 check_mips_64(ctx);
11926 break;
11927 #endif
11928 default:
11929 generate_exception_end(ctx, EXCP_RI);
11930 goto done;
11931 }
11932
11933 gen_arith(ctx, mips32_op, rz, rx, ry);
11934 done:
11935 ;
11936 }
11937 break;
11938 case M16_OPC_RR:
11939 switch (op1) {
11940 case RR_JR:
11941 {
11942 int nd = (ctx->opcode >> 7) & 0x1;
11943 int link = (ctx->opcode >> 6) & 0x1;
11944 int ra = (ctx->opcode >> 5) & 0x1;
11945
11946 if (nd) {
11947 check_insn(ctx, ISA_MIPS32);
11948 }
11949
11950 if (link) {
11951 op = OPC_JALR;
11952 } else {
11953 op = OPC_JR;
11954 }
11955
11956 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11957 (nd ? 0 : 2));
11958 }
11959 break;
11960 case RR_SDBBP:
11961 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11962 gen_helper_do_semihosting(cpu_env);
11963 } else {
11964 /* XXX: not clear which exception should be raised
11965 * when in debug mode...
11966 */
11967 check_insn(ctx, ISA_MIPS32);
11968 generate_exception_end(ctx, EXCP_DBp);
11969 }
11970 break;
11971 case RR_SLT:
11972 gen_slt(ctx, OPC_SLT, 24, rx, ry);
11973 break;
11974 case RR_SLTU:
11975 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11976 break;
11977 case RR_BREAK:
11978 generate_exception_end(ctx, EXCP_BREAK);
11979 break;
11980 case RR_SLLV:
11981 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11982 break;
11983 case RR_SRLV:
11984 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11985 break;
11986 case RR_SRAV:
11987 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11988 break;
11989 #if defined (TARGET_MIPS64)
11990 case RR_DSRL:
11991 check_insn(ctx, ISA_MIPS3);
11992 check_mips_64(ctx);
11993 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11994 break;
11995 #endif
11996 case RR_CMP:
11997 gen_logic(ctx, OPC_XOR, 24, rx, ry);
11998 break;
11999 case RR_NEG:
12000 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
12001 break;
12002 case RR_AND:
12003 gen_logic(ctx, OPC_AND, rx, rx, ry);
12004 break;
12005 case RR_OR:
12006 gen_logic(ctx, OPC_OR, rx, rx, ry);
12007 break;
12008 case RR_XOR:
12009 gen_logic(ctx, OPC_XOR, rx, rx, ry);
12010 break;
12011 case RR_NOT:
12012 gen_logic(ctx, OPC_NOR, rx, ry, 0);
12013 break;
12014 case RR_MFHI:
12015 gen_HILO(ctx, OPC_MFHI, 0, rx);
12016 break;
12017 case RR_CNVT:
12018 check_insn(ctx, ISA_MIPS32);
12019 switch (cnvt_op) {
12020 case RR_RY_CNVT_ZEB:
12021 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12022 break;
12023 case RR_RY_CNVT_ZEH:
12024 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12025 break;
12026 case RR_RY_CNVT_SEB:
12027 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12028 break;
12029 case RR_RY_CNVT_SEH:
12030 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12031 break;
12032 #if defined (TARGET_MIPS64)
12033 case RR_RY_CNVT_ZEW:
12034 check_insn(ctx, ISA_MIPS64);
12035 check_mips_64(ctx);
12036 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
12037 break;
12038 case RR_RY_CNVT_SEW:
12039 check_insn(ctx, ISA_MIPS64);
12040 check_mips_64(ctx);
12041 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12042 break;
12043 #endif
12044 default:
12045 generate_exception_end(ctx, EXCP_RI);
12046 break;
12047 }
12048 break;
12049 case RR_MFLO:
12050 gen_HILO(ctx, OPC_MFLO, 0, rx);
12051 break;
12052 #if defined (TARGET_MIPS64)
12053 case RR_DSRA:
12054 check_insn(ctx, ISA_MIPS3);
12055 check_mips_64(ctx);
12056 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
12057 break;
12058 case RR_DSLLV:
12059 check_insn(ctx, ISA_MIPS3);
12060 check_mips_64(ctx);
12061 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
12062 break;
12063 case RR_DSRLV:
12064 check_insn(ctx, ISA_MIPS3);
12065 check_mips_64(ctx);
12066 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
12067 break;
12068 case RR_DSRAV:
12069 check_insn(ctx, ISA_MIPS3);
12070 check_mips_64(ctx);
12071 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
12072 break;
12073 #endif
12074 case RR_MULT:
12075 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
12076 break;
12077 case RR_MULTU:
12078 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
12079 break;
12080 case RR_DIV:
12081 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
12082 break;
12083 case RR_DIVU:
12084 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
12085 break;
12086 #if defined (TARGET_MIPS64)
12087 case RR_DMULT:
12088 check_insn(ctx, ISA_MIPS3);
12089 check_mips_64(ctx);
12090 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
12091 break;
12092 case RR_DMULTU:
12093 check_insn(ctx, ISA_MIPS3);
12094 check_mips_64(ctx);
12095 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
12096 break;
12097 case RR_DDIV:
12098 check_insn(ctx, ISA_MIPS3);
12099 check_mips_64(ctx);
12100 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
12101 break;
12102 case RR_DDIVU:
12103 check_insn(ctx, ISA_MIPS3);
12104 check_mips_64(ctx);
12105 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
12106 break;
12107 #endif
12108 default:
12109 generate_exception_end(ctx, EXCP_RI);
12110 break;
12111 }
12112 break;
12113 case M16_OPC_EXTEND:
12114 decode_extended_mips16_opc(env, ctx);
12115 n_bytes = 4;
12116 break;
12117 #if defined(TARGET_MIPS64)
12118 case M16_OPC_I64:
12119 funct = (ctx->opcode >> 8) & 0x7;
12120 decode_i64_mips16(ctx, ry, funct, offset, 0);
12121 break;
12122 #endif
12123 default:
12124 generate_exception_end(ctx, EXCP_RI);
12125 break;
12126 }
12127
12128 return n_bytes;
12129 }
12130
12131 /* microMIPS extension to MIPS32/MIPS64 */
12132
12133 /*
12134 * microMIPS32/microMIPS64 major opcodes
12135 *
12136 * 1. MIPS Architecture for Programmers Volume II-B:
12137 * The microMIPS32 Instruction Set (Revision 3.05)
12138 *
12139 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12140 *
12141 * 2. MIPS Architecture For Programmers Volume II-A:
12142 * The MIPS64 Instruction Set (Revision 3.51)
12143 */
12144
12145 enum {
12146 POOL32A = 0x00,
12147 POOL16A = 0x01,
12148 LBU16 = 0x02,
12149 MOVE16 = 0x03,
12150 ADDI32 = 0x04,
12151 R6_LUI = 0x04,
12152 AUI = 0x04,
12153 LBU32 = 0x05,
12154 SB32 = 0x06,
12155 LB32 = 0x07,
12156
12157 POOL32B = 0x08,
12158 POOL16B = 0x09,
12159 LHU16 = 0x0a,
12160 ANDI16 = 0x0b,
12161 ADDIU32 = 0x0c,
12162 LHU32 = 0x0d,
12163 SH32 = 0x0e,
12164 LH32 = 0x0f,
12165
12166 POOL32I = 0x10,
12167 POOL16C = 0x11,
12168 LWSP16 = 0x12,
12169 POOL16D = 0x13,
12170 ORI32 = 0x14,
12171 POOL32F = 0x15,
12172 POOL32S = 0x16, /* MIPS64 */
12173 DADDIU32 = 0x17, /* MIPS64 */
12174
12175 POOL32C = 0x18,
12176 LWGP16 = 0x19,
12177 LW16 = 0x1a,
12178 POOL16E = 0x1b,
12179 XORI32 = 0x1c,
12180 JALS32 = 0x1d,
12181 BOVC = 0x1d,
12182 BEQC = 0x1d,
12183 BEQZALC = 0x1d,
12184 ADDIUPC = 0x1e,
12185 PCREL = 0x1e,
12186 BNVC = 0x1f,
12187 BNEC = 0x1f,
12188 BNEZALC = 0x1f,
12189
12190 R6_BEQZC = 0x20,
12191 JIC = 0x20,
12192 POOL16F = 0x21,
12193 SB16 = 0x22,
12194 BEQZ16 = 0x23,
12195 BEQZC16 = 0x23,
12196 SLTI32 = 0x24,
12197 BEQ32 = 0x25,
12198 BC = 0x25,
12199 SWC132 = 0x26,
12200 LWC132 = 0x27,
12201
12202 /* 0x29 is reserved */
12203 RES_29 = 0x29,
12204 R6_BNEZC = 0x28,
12205 JIALC = 0x28,
12206 SH16 = 0x2a,
12207 BNEZ16 = 0x2b,
12208 BNEZC16 = 0x2b,
12209 SLTIU32 = 0x2c,
12210 BNE32 = 0x2d,
12211 BALC = 0x2d,
12212 SDC132 = 0x2e,
12213 LDC132 = 0x2f,
12214
12215 /* 0x31 is reserved */
12216 RES_31 = 0x31,
12217 BLEZALC = 0x30,
12218 BGEZALC = 0x30,
12219 BGEUC = 0x30,
12220 SWSP16 = 0x32,
12221 B16 = 0x33,
12222 BC16 = 0x33,
12223 ANDI32 = 0x34,
12224 J32 = 0x35,
12225 BGTZC = 0x35,
12226 BLTZC = 0x35,
12227 BLTC = 0x35,
12228 SD32 = 0x36, /* MIPS64 */
12229 LD32 = 0x37, /* MIPS64 */
12230
12231 /* 0x39 is reserved */
12232 RES_39 = 0x39,
12233 BGTZALC = 0x38,
12234 BLTZALC = 0x38,
12235 BLTUC = 0x38,
12236 SW16 = 0x3a,
12237 LI16 = 0x3b,
12238 JALX32 = 0x3c,
12239 JAL32 = 0x3d,
12240 BLEZC = 0x3d,
12241 BGEZC = 0x3d,
12242 BGEC = 0x3d,
12243 SW32 = 0x3e,
12244 LW32 = 0x3f
12245 };
12246
12247 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12248 enum {
12249 ADDIUPC_00 = 0x00,
12250 ADDIUPC_07 = 0x07,
12251 AUIPC = 0x1e,
12252 ALUIPC = 0x1f,
12253 LWPC_08 = 0x08,
12254 LWPC_0F = 0x0F,
12255 };
12256
12257 /* POOL32A encoding of minor opcode field */
12258
12259 enum {
12260 /* These opcodes are distinguished only by bits 9..6; those bits are
12261 * what are recorded below. */
12262 SLL32 = 0x0,
12263 SRL32 = 0x1,
12264 SRA = 0x2,
12265 ROTR = 0x3,
12266 SELEQZ = 0x5,
12267 SELNEZ = 0x6,
12268 R6_RDHWR = 0x7,
12269
12270 SLLV = 0x0,
12271 SRLV = 0x1,
12272 SRAV = 0x2,
12273 ROTRV = 0x3,
12274 ADD = 0x4,
12275 ADDU32 = 0x5,
12276 SUB = 0x6,
12277 SUBU32 = 0x7,
12278 MUL = 0x8,
12279 AND = 0x9,
12280 OR32 = 0xa,
12281 NOR = 0xb,
12282 XOR32 = 0xc,
12283 SLT = 0xd,
12284 SLTU = 0xe,
12285
12286 MOVN = 0x0,
12287 R6_MUL = 0x0,
12288 MOVZ = 0x1,
12289 MUH = 0x1,
12290 MULU = 0x2,
12291 MUHU = 0x3,
12292 LWXS = 0x4,
12293 R6_DIV = 0x4,
12294 MOD = 0x5,
12295 R6_DIVU = 0x6,
12296 MODU = 0x7,
12297
12298 /* The following can be distinguished by their lower 6 bits. */
12299 BREAK32 = 0x07,
12300 INS = 0x0c,
12301 LSA = 0x0f,
12302 ALIGN = 0x1f,
12303 EXT = 0x2c,
12304 POOL32AXF = 0x3c,
12305 SIGRIE = 0x3f
12306 };
12307
12308 /* POOL32AXF encoding of minor opcode field extension */
12309
12310 /*
12311 * 1. MIPS Architecture for Programmers Volume II-B:
12312 * The microMIPS32 Instruction Set (Revision 3.05)
12313 *
12314 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12315 *
12316 * 2. MIPS Architecture for Programmers VolumeIV-e:
12317 * The MIPS DSP Application-Specific Extension
12318 * to the microMIPS32 Architecture (Revision 2.34)
12319 *
12320 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12321 */
12322
12323 enum {
12324 /* bits 11..6 */
12325 TEQ = 0x00,
12326 TGE = 0x08,
12327 TGEU = 0x10,
12328 TLT = 0x20,
12329 TLTU = 0x28,
12330 TNE = 0x30,
12331
12332 MFC0 = 0x03,
12333 MTC0 = 0x0b,
12334
12335 /* begin of microMIPS32 DSP */
12336
12337 /* bits 13..12 for 0x01 */
12338 MFHI_ACC = 0x0,
12339 MFLO_ACC = 0x1,
12340 MTHI_ACC = 0x2,
12341 MTLO_ACC = 0x3,
12342
12343 /* bits 13..12 for 0x2a */
12344 MADD_ACC = 0x0,
12345 MADDU_ACC = 0x1,
12346 MSUB_ACC = 0x2,
12347 MSUBU_ACC = 0x3,
12348
12349 /* bits 13..12 for 0x32 */
12350 MULT_ACC = 0x0,
12351 MULTU_ACC = 0x1,
12352
12353 /* end of microMIPS32 DSP */
12354
12355 /* bits 15..12 for 0x2c */
12356 BITSWAP = 0x0,
12357 SEB = 0x2,
12358 SEH = 0x3,
12359 CLO = 0x4,
12360 CLZ = 0x5,
12361 RDHWR = 0x6,
12362 WSBH = 0x7,
12363 MULT = 0x8,
12364 MULTU = 0x9,
12365 DIV = 0xa,
12366 DIVU = 0xb,
12367 MADD = 0xc,
12368 MADDU = 0xd,
12369 MSUB = 0xe,
12370 MSUBU = 0xf,
12371
12372 /* bits 15..12 for 0x34 */
12373 MFC2 = 0x4,
12374 MTC2 = 0x5,
12375 MFHC2 = 0x8,
12376 MTHC2 = 0x9,
12377 CFC2 = 0xc,
12378 CTC2 = 0xd,
12379
12380 /* bits 15..12 for 0x3c */
12381 JALR = 0x0,
12382 JR = 0x0, /* alias */
12383 JALRC = 0x0,
12384 JRC = 0x0,
12385 JALR_HB = 0x1,
12386 JALRC_HB = 0x1,
12387 JALRS = 0x4,
12388 JALRS_HB = 0x5,
12389
12390 /* bits 15..12 for 0x05 */
12391 RDPGPR = 0xe,
12392 WRPGPR = 0xf,
12393
12394 /* bits 15..12 for 0x0d */
12395 TLBP = 0x0,
12396 TLBR = 0x1,
12397 TLBWI = 0x2,
12398 TLBWR = 0x3,
12399 TLBINV = 0x4,
12400 TLBINVF = 0x5,
12401 WAIT = 0x9,
12402 IRET = 0xd,
12403 DERET = 0xe,
12404 ERET = 0xf,
12405
12406 /* bits 15..12 for 0x15 */
12407 DMT = 0x0,
12408 DVPE = 0x1,
12409 EMT = 0x2,
12410 EVPE = 0x3,
12411
12412 /* bits 15..12 for 0x1d */
12413 DI = 0x4,
12414 EI = 0x5,
12415
12416 /* bits 15..12 for 0x2d */
12417 SYNC = 0x6,
12418 SYSCALL = 0x8,
12419 SDBBP = 0xd,
12420
12421 /* bits 15..12 for 0x35 */
12422 MFHI32 = 0x0,
12423 MFLO32 = 0x1,
12424 MTHI32 = 0x2,
12425 MTLO32 = 0x3,
12426 };
12427
12428 /* POOL32B encoding of minor opcode field (bits 15..12) */
12429
12430 enum {
12431 LWC2 = 0x0,
12432 LWP = 0x1,
12433 LDP = 0x4,
12434 LWM32 = 0x5,
12435 CACHE = 0x6,
12436 LDM = 0x7,
12437 SWC2 = 0x8,
12438 SWP = 0x9,
12439 SDP = 0xc,
12440 SWM32 = 0xd,
12441 SDM = 0xf
12442 };
12443
12444 /* POOL32C encoding of minor opcode field (bits 15..12) */
12445
12446 enum {
12447 LWL = 0x0,
12448 SWL = 0x8,
12449 LWR = 0x1,
12450 SWR = 0x9,
12451 PREF = 0x2,
12452 /* 0xa is reserved */
12453 LL = 0x3,
12454 SC = 0xb,
12455 LDL = 0x4,
12456 SDL = 0xc,
12457 LDR = 0x5,
12458 SDR = 0xd,
12459 /* 0x6 is reserved */
12460 LWU = 0xe,
12461 LLD = 0x7,
12462 SCD = 0xf
12463 };
12464
12465 /* POOL32F encoding of minor opcode field (bits 5..0) */
12466
12467 enum {
12468 /* These are the bit 7..6 values */
12469 ADD_FMT = 0x0,
12470
12471 SUB_FMT = 0x1,
12472
12473 MUL_FMT = 0x2,
12474
12475 DIV_FMT = 0x3,
12476
12477 /* These are the bit 8..6 values */
12478 MOVN_FMT = 0x0,
12479 RSQRT2_FMT = 0x0,
12480 MOVF_FMT = 0x0,
12481 RINT_FMT = 0x0,
12482 SELNEZ_FMT = 0x0,
12483
12484 MOVZ_FMT = 0x1,
12485 LWXC1 = 0x1,
12486 MOVT_FMT = 0x1,
12487 CLASS_FMT = 0x1,
12488 SELEQZ_FMT = 0x1,
12489
12490 PLL_PS = 0x2,
12491 SWXC1 = 0x2,
12492 SEL_FMT = 0x2,
12493
12494 PLU_PS = 0x3,
12495 LDXC1 = 0x3,
12496
12497 MOVN_FMT_04 = 0x4,
12498 PUL_PS = 0x4,
12499 SDXC1 = 0x4,
12500 RECIP2_FMT = 0x4,
12501
12502 MOVZ_FMT_05 = 0x05,
12503 PUU_PS = 0x5,
12504 LUXC1 = 0x5,
12505
12506 CVT_PS_S = 0x6,
12507 SUXC1 = 0x6,
12508 ADDR_PS = 0x6,
12509 PREFX = 0x6,
12510 MADDF_FMT = 0x6,
12511
12512 MULR_PS = 0x7,
12513 MSUBF_FMT = 0x7,
12514
12515 MADD_S = 0x01,
12516 MADD_D = 0x09,
12517 MADD_PS = 0x11,
12518 ALNV_PS = 0x19,
12519 MSUB_S = 0x21,
12520 MSUB_D = 0x29,
12521 MSUB_PS = 0x31,
12522
12523 NMADD_S = 0x02,
12524 NMADD_D = 0x0a,
12525 NMADD_PS = 0x12,
12526 NMSUB_S = 0x22,
12527 NMSUB_D = 0x2a,
12528 NMSUB_PS = 0x32,
12529
12530 MIN_FMT = 0x3,
12531 MAX_FMT = 0xb,
12532 MINA_FMT = 0x23,
12533 MAXA_FMT = 0x2b,
12534 POOL32FXF = 0x3b,
12535
12536 CABS_COND_FMT = 0x1c, /* MIPS3D */
12537 C_COND_FMT = 0x3c,
12538
12539 CMP_CONDN_S = 0x5,
12540 CMP_CONDN_D = 0x15
12541 };
12542
12543 /* POOL32Fxf encoding of minor opcode extension field */
12544
12545 enum {
12546 CVT_L = 0x04,
12547 RSQRT_FMT = 0x08,
12548 FLOOR_L = 0x0c,
12549 CVT_PW_PS = 0x1c,
12550 CVT_W = 0x24,
12551 SQRT_FMT = 0x28,
12552 FLOOR_W = 0x2c,
12553 CVT_PS_PW = 0x3c,
12554 CFC1 = 0x40,
12555 RECIP_FMT = 0x48,
12556 CEIL_L = 0x4c,
12557 CTC1 = 0x60,
12558 CEIL_W = 0x6c,
12559 MFC1 = 0x80,
12560 CVT_S_PL = 0x84,
12561 TRUNC_L = 0x8c,
12562 MTC1 = 0xa0,
12563 CVT_S_PU = 0xa4,
12564 TRUNC_W = 0xac,
12565 MFHC1 = 0xc0,
12566 ROUND_L = 0xcc,
12567 MTHC1 = 0xe0,
12568 ROUND_W = 0xec,
12569
12570 MOV_FMT = 0x01,
12571 MOVF = 0x05,
12572 ABS_FMT = 0x0d,
12573 RSQRT1_FMT = 0x1d,
12574 MOVT = 0x25,
12575 NEG_FMT = 0x2d,
12576 CVT_D = 0x4d,
12577 RECIP1_FMT = 0x5d,
12578 CVT_S = 0x6d
12579 };
12580
12581 /* POOL32I encoding of minor opcode field (bits 25..21) */
12582
12583 enum {
12584 BLTZ = 0x00,
12585 BLTZAL = 0x01,
12586 BGEZ = 0x02,
12587 BGEZAL = 0x03,
12588 BLEZ = 0x04,
12589 BNEZC = 0x05,
12590 BGTZ = 0x06,
12591 BEQZC = 0x07,
12592 TLTI = 0x08,
12593 BC1EQZC = 0x08,
12594 TGEI = 0x09,
12595 BC1NEZC = 0x09,
12596 TLTIU = 0x0a,
12597 BC2EQZC = 0x0a,
12598 TGEIU = 0x0b,
12599 BC2NEZC = 0x0a,
12600 TNEI = 0x0c,
12601 R6_SYNCI = 0x0c,
12602 LUI = 0x0d,
12603 TEQI = 0x0e,
12604 SYNCI = 0x10,
12605 BLTZALS = 0x11,
12606 BGEZALS = 0x13,
12607 BC2F = 0x14,
12608 BC2T = 0x15,
12609 BPOSGE64 = 0x1a,
12610 BPOSGE32 = 0x1b,
12611 /* These overlap and are distinguished by bit16 of the instruction */
12612 BC1F = 0x1c,
12613 BC1T = 0x1d,
12614 BC1ANY2F = 0x1c,
12615 BC1ANY2T = 0x1d,
12616 BC1ANY4F = 0x1e,
12617 BC1ANY4T = 0x1f
12618 };
12619
12620 /* POOL16A encoding of minor opcode field */
12621
12622 enum {
12623 ADDU16 = 0x0,
12624 SUBU16 = 0x1
12625 };
12626
12627 /* POOL16B encoding of minor opcode field */
12628
12629 enum {
12630 SLL16 = 0x0,
12631 SRL16 = 0x1
12632 };
12633
12634 /* POOL16C encoding of minor opcode field */
12635
12636 enum {
12637 NOT16 = 0x00,
12638 XOR16 = 0x04,
12639 AND16 = 0x08,
12640 OR16 = 0x0c,
12641 LWM16 = 0x10,
12642 SWM16 = 0x14,
12643 JR16 = 0x18,
12644 JRC16 = 0x1a,
12645 JALR16 = 0x1c,
12646 JALR16S = 0x1e,
12647 MFHI16 = 0x20,
12648 MFLO16 = 0x24,
12649 BREAK16 = 0x28,
12650 SDBBP16 = 0x2c,
12651 JRADDIUSP = 0x30
12652 };
12653
12654 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12655
12656 enum {
12657 R6_NOT16 = 0x00,
12658 R6_AND16 = 0x01,
12659 R6_LWM16 = 0x02,
12660 R6_JRC16 = 0x03,
12661 MOVEP = 0x04,
12662 MOVEP_07 = 0x07,
12663 R6_XOR16 = 0x08,
12664 R6_OR16 = 0x09,
12665 R6_SWM16 = 0x0a,
12666 JALRC16 = 0x0b,
12667 MOVEP_0C = 0x0c,
12668 MOVEP_0F = 0x0f,
12669 JRCADDIUSP = 0x13,
12670 R6_BREAK16 = 0x1b,
12671 R6_SDBBP16 = 0x3b
12672 };
12673
12674 /* POOL16D encoding of minor opcode field */
12675
12676 enum {
12677 ADDIUS5 = 0x0,
12678 ADDIUSP = 0x1
12679 };
12680
12681 /* POOL16E encoding of minor opcode field */
12682
12683 enum {
12684 ADDIUR2 = 0x0,
12685 ADDIUR1SP = 0x1
12686 };
12687
12688 static int mmreg (int r)
12689 {
12690 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12691
12692 return map[r];
12693 }
12694
12695 /* Used for 16-bit store instructions. */
12696 static int mmreg2 (int r)
12697 {
12698 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12699
12700 return map[r];
12701 }
12702
12703 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12704 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12705 #define uMIPS_RS2(op) uMIPS_RS(op)
12706 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12707 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12708 #define uMIPS_RS5(op) (op & 0x1f)
12709
12710 /* Signed immediate */
12711 #define SIMM(op, start, width) \
12712 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12713 << (32-width)) \
12714 >> (32-width))
12715 /* Zero-extended immediate */
12716 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12717
12718 static void gen_addiur1sp(DisasContext *ctx)
12719 {
12720 int rd = mmreg(uMIPS_RD(ctx->opcode));
12721
12722 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12723 }
12724
12725 static void gen_addiur2(DisasContext *ctx)
12726 {
12727 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12728 int rd = mmreg(uMIPS_RD(ctx->opcode));
12729 int rs = mmreg(uMIPS_RS(ctx->opcode));
12730
12731 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12732 }
12733
12734 static void gen_addiusp(DisasContext *ctx)
12735 {
12736 int encoded = ZIMM(ctx->opcode, 1, 9);
12737 int decoded;
12738
12739 if (encoded <= 1) {
12740 decoded = 256 + encoded;
12741 } else if (encoded <= 255) {
12742 decoded = encoded;
12743 } else if (encoded <= 509) {
12744 decoded = encoded - 512;
12745 } else {
12746 decoded = encoded - 768;
12747 }
12748
12749 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12750 }
12751
12752 static void gen_addius5(DisasContext *ctx)
12753 {
12754 int imm = SIMM(ctx->opcode, 1, 4);
12755 int rd = (ctx->opcode >> 5) & 0x1f;
12756
12757 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12758 }
12759
12760 static void gen_andi16(DisasContext *ctx)
12761 {
12762 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12763 31, 32, 63, 64, 255, 32768, 65535 };
12764 int rd = mmreg(uMIPS_RD(ctx->opcode));
12765 int rs = mmreg(uMIPS_RS(ctx->opcode));
12766 int encoded = ZIMM(ctx->opcode, 0, 4);
12767
12768 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12769 }
12770
12771 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12772 int base, int16_t offset)
12773 {
12774 TCGv t0, t1;
12775 TCGv_i32 t2;
12776
12777 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12778 generate_exception_end(ctx, EXCP_RI);
12779 return;
12780 }
12781
12782 t0 = tcg_temp_new();
12783
12784 gen_base_offset_addr(ctx, t0, base, offset);
12785
12786 t1 = tcg_const_tl(reglist);
12787 t2 = tcg_const_i32(ctx->mem_idx);
12788
12789 save_cpu_state(ctx, 1);
12790 switch (opc) {
12791 case LWM32:
12792 gen_helper_lwm(cpu_env, t0, t1, t2);
12793 break;
12794 case SWM32:
12795 gen_helper_swm(cpu_env, t0, t1, t2);
12796 break;
12797 #ifdef TARGET_MIPS64
12798 case LDM:
12799 gen_helper_ldm(cpu_env, t0, t1, t2);
12800 break;
12801 case SDM:
12802 gen_helper_sdm(cpu_env, t0, t1, t2);
12803 break;
12804 #endif
12805 }
12806 tcg_temp_free(t0);
12807 tcg_temp_free(t1);
12808 tcg_temp_free_i32(t2);
12809 }
12810
12811
12812 static void gen_pool16c_insn(DisasContext *ctx)
12813 {
12814 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12815 int rs = mmreg(ctx->opcode & 0x7);
12816
12817 switch (((ctx->opcode) >> 4) & 0x3f) {
12818 case NOT16 + 0:
12819 case NOT16 + 1:
12820 case NOT16 + 2:
12821 case NOT16 + 3:
12822 gen_logic(ctx, OPC_NOR, rd, rs, 0);
12823 break;
12824 case XOR16 + 0:
12825 case XOR16 + 1:
12826 case XOR16 + 2:
12827 case XOR16 + 3:
12828 gen_logic(ctx, OPC_XOR, rd, rd, rs);
12829 break;
12830 case AND16 + 0:
12831 case AND16 + 1:
12832 case AND16 + 2:
12833 case AND16 + 3:
12834 gen_logic(ctx, OPC_AND, rd, rd, rs);
12835 break;
12836 case OR16 + 0:
12837 case OR16 + 1:
12838 case OR16 + 2:
12839 case OR16 + 3:
12840 gen_logic(ctx, OPC_OR, rd, rd, rs);
12841 break;
12842 case LWM16 + 0:
12843 case LWM16 + 1:
12844 case LWM16 + 2:
12845 case LWM16 + 3:
12846 {
12847 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12848 int offset = ZIMM(ctx->opcode, 0, 4);
12849
12850 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12851 29, offset << 2);
12852 }
12853 break;
12854 case SWM16 + 0:
12855 case SWM16 + 1:
12856 case SWM16 + 2:
12857 case SWM16 + 3:
12858 {
12859 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12860 int offset = ZIMM(ctx->opcode, 0, 4);
12861
12862 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12863 29, offset << 2);
12864 }
12865 break;
12866 case JR16 + 0:
12867 case JR16 + 1:
12868 {
12869 int reg = ctx->opcode & 0x1f;
12870
12871 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12872 }
12873 break;
12874 case JRC16 + 0:
12875 case JRC16 + 1:
12876 {
12877 int reg = ctx->opcode & 0x1f;
12878 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12879 /* Let normal delay slot handling in our caller take us
12880 to the branch target. */
12881 }
12882 break;
12883 case JALR16 + 0:
12884 case JALR16 + 1:
12885 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12886 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12887 break;
12888 case JALR16S + 0:
12889 case JALR16S + 1:
12890 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12891 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12892 break;
12893 case MFHI16 + 0:
12894 case MFHI16 + 1:
12895 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12896 break;
12897 case MFLO16 + 0:
12898 case MFLO16 + 1:
12899 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12900 break;
12901 case BREAK16:
12902 generate_exception_end(ctx, EXCP_BREAK);
12903 break;
12904 case SDBBP16:
12905 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12906 gen_helper_do_semihosting(cpu_env);
12907 } else {
12908 /* XXX: not clear which exception should be raised
12909 * when in debug mode...
12910 */
12911 check_insn(ctx, ISA_MIPS32);
12912 generate_exception_end(ctx, EXCP_DBp);
12913 }
12914 break;
12915 case JRADDIUSP + 0:
12916 case JRADDIUSP + 1:
12917 {
12918 int imm = ZIMM(ctx->opcode, 0, 5);
12919 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12920 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12921 /* Let normal delay slot handling in our caller take us
12922 to the branch target. */
12923 }
12924 break;
12925 default:
12926 generate_exception_end(ctx, EXCP_RI);
12927 break;
12928 }
12929 }
12930
12931 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12932 int enc_rs)
12933 {
12934 int rd, rs, re, rt;
12935 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12936 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12937 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12938 rd = rd_enc[enc_dest];
12939 re = re_enc[enc_dest];
12940 rs = rs_rt_enc[enc_rs];
12941 rt = rs_rt_enc[enc_rt];
12942 if (rs) {
12943 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12944 } else {
12945 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12946 }
12947 if (rt) {
12948 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12949 } else {
12950 tcg_gen_movi_tl(cpu_gpr[re], 0);
12951 }
12952 }
12953
12954 static void gen_pool16c_r6_insn(DisasContext *ctx)
12955 {
12956 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12957 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12958
12959 switch (ctx->opcode & 0xf) {
12960 case R6_NOT16:
12961 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12962 break;
12963 case R6_AND16:
12964 gen_logic(ctx, OPC_AND, rt, rt, rs);
12965 break;
12966 case R6_LWM16:
12967 {
12968 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12969 int offset = extract32(ctx->opcode, 4, 4);
12970 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12971 }
12972 break;
12973 case R6_JRC16: /* JRCADDIUSP */
12974 if ((ctx->opcode >> 4) & 1) {
12975 /* JRCADDIUSP */
12976 int imm = extract32(ctx->opcode, 5, 5);
12977 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12978 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12979 } else {
12980 /* JRC16 */
12981 int rs = extract32(ctx->opcode, 5, 5);
12982 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12983 }
12984 break;
12985 case MOVEP ... MOVEP_07:
12986 case MOVEP_0C ... MOVEP_0F:
12987 {
12988 int enc_dest = uMIPS_RD(ctx->opcode);
12989 int enc_rt = uMIPS_RS2(ctx->opcode);
12990 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12991 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12992 }
12993 break;
12994 case R6_XOR16:
12995 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12996 break;
12997 case R6_OR16:
12998 gen_logic(ctx, OPC_OR, rt, rt, rs);
12999 break;
13000 case R6_SWM16:
13001 {
13002 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
13003 int offset = extract32(ctx->opcode, 4, 4);
13004 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
13005 }
13006 break;
13007 case JALRC16: /* BREAK16, SDBBP16 */
13008 switch (ctx->opcode & 0x3f) {
13009 case JALRC16:
13010 case JALRC16 + 0x20:
13011 /* JALRC16 */
13012 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
13013 31, 0, 0);
13014 break;
13015 case R6_BREAK16:
13016 /* BREAK16 */
13017 generate_exception(ctx, EXCP_BREAK);
13018 break;
13019 case R6_SDBBP16:
13020 /* SDBBP16 */
13021 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
13022 gen_helper_do_semihosting(cpu_env);
13023 } else {
13024 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13025 generate_exception(ctx, EXCP_RI);
13026 } else {
13027 generate_exception(ctx, EXCP_DBp);
13028 }
13029 }
13030 break;
13031 }
13032 break;
13033 default:
13034 generate_exception(ctx, EXCP_RI);
13035 break;
13036 }
13037 }
13038
13039 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
13040 {
13041 TCGv t0 = tcg_temp_new();
13042 TCGv t1 = tcg_temp_new();
13043
13044 gen_load_gpr(t0, base);
13045
13046 if (index != 0) {
13047 gen_load_gpr(t1, index);
13048 tcg_gen_shli_tl(t1, t1, 2);
13049 gen_op_addr_add(ctx, t0, t1, t0);
13050 }
13051
13052 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13053 gen_store_gpr(t1, rd);
13054
13055 tcg_temp_free(t0);
13056 tcg_temp_free(t1);
13057 }
13058
13059 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
13060 int base, int16_t offset)
13061 {
13062 TCGv t0, t1;
13063
13064 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
13065 generate_exception_end(ctx, EXCP_RI);
13066 return;
13067 }
13068
13069 t0 = tcg_temp_new();
13070 t1 = tcg_temp_new();
13071
13072 gen_base_offset_addr(ctx, t0, base, offset);
13073
13074 switch (opc) {
13075 case LWP:
13076 if (rd == base) {
13077 generate_exception_end(ctx, EXCP_RI);
13078 return;
13079 }
13080 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13081 gen_store_gpr(t1, rd);
13082 tcg_gen_movi_tl(t1, 4);
13083 gen_op_addr_add(ctx, t0, t0, t1);
13084 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
13085 gen_store_gpr(t1, rd+1);
13086 break;
13087 case SWP:
13088 gen_load_gpr(t1, rd);
13089 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13090 tcg_gen_movi_tl(t1, 4);
13091 gen_op_addr_add(ctx, t0, t0, t1);
13092 gen_load_gpr(t1, rd+1);
13093 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13094 break;
13095 #ifdef TARGET_MIPS64
13096 case LDP:
13097 if (rd == base) {
13098 generate_exception_end(ctx, EXCP_RI);
13099 return;
13100 }
13101 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13102 gen_store_gpr(t1, rd);
13103 tcg_gen_movi_tl(t1, 8);
13104 gen_op_addr_add(ctx, t0, t0, t1);
13105 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13106 gen_store_gpr(t1, rd+1);
13107 break;
13108 case SDP:
13109 gen_load_gpr(t1, rd);
13110 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13111 tcg_gen_movi_tl(t1, 8);
13112 gen_op_addr_add(ctx, t0, t0, t1);
13113 gen_load_gpr(t1, rd+1);
13114 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
13115 break;
13116 #endif
13117 }
13118 tcg_temp_free(t0);
13119 tcg_temp_free(t1);
13120 }
13121
13122 static void gen_sync(int stype)
13123 {
13124 TCGBar tcg_mo = TCG_BAR_SC;
13125
13126 switch (stype) {
13127 case 0x4: /* SYNC_WMB */
13128 tcg_mo |= TCG_MO_ST_ST;
13129 break;
13130 case 0x10: /* SYNC_MB */
13131 tcg_mo |= TCG_MO_ALL;
13132 break;
13133 case 0x11: /* SYNC_ACQUIRE */
13134 tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
13135 break;
13136 case 0x12: /* SYNC_RELEASE */
13137 tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
13138 break;
13139 case 0x13: /* SYNC_RMB */
13140 tcg_mo |= TCG_MO_LD_LD;
13141 break;
13142 default:
13143 tcg_mo |= TCG_MO_ALL;
13144 break;
13145 }
13146
13147 tcg_gen_mb(tcg_mo);
13148 }
13149
13150 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
13151 {
13152 int extension = (ctx->opcode >> 6) & 0x3f;
13153 int minor = (ctx->opcode >> 12) & 0xf;
13154 uint32_t mips32_op;
13155
13156 switch (extension) {
13157 case TEQ:
13158 mips32_op = OPC_TEQ;
13159 goto do_trap;
13160 case TGE:
13161 mips32_op = OPC_TGE;
13162 goto do_trap;
13163 case TGEU:
13164 mips32_op = OPC_TGEU;
13165 goto do_trap;
13166 case TLT:
13167 mips32_op = OPC_TLT;
13168 goto do_trap;
13169 case TLTU:
13170 mips32_op = OPC_TLTU;
13171 goto do_trap;
13172 case TNE:
13173 mips32_op = OPC_TNE;
13174 do_trap:
13175 gen_trap(ctx, mips32_op, rs, rt, -1);
13176 break;
13177 #ifndef CONFIG_USER_ONLY
13178 case MFC0:
13179 case MFC0 + 32:
13180 check_cp0_enabled(ctx);
13181 if (rt == 0) {
13182 /* Treat as NOP. */
13183 break;
13184 }
13185 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
13186 break;
13187 case MTC0:
13188 case MTC0 + 32:
13189 check_cp0_enabled(ctx);
13190 {
13191 TCGv t0 = tcg_temp_new();
13192
13193 gen_load_gpr(t0, rt);
13194 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
13195 tcg_temp_free(t0);
13196 }
13197 break;
13198 #endif
13199 case 0x2a:
13200 switch (minor & 3) {
13201 case MADD_ACC:
13202 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
13203 break;
13204 case MADDU_ACC:
13205 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
13206 break;
13207 case MSUB_ACC:
13208 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
13209 break;
13210 case MSUBU_ACC:
13211 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
13212 break;
13213 default:
13214 goto pool32axf_invalid;
13215 }
13216 break;
13217 case 0x32:
13218 switch (minor & 3) {
13219 case MULT_ACC:
13220 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
13221 break;
13222 case MULTU_ACC:
13223 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
13224 break;
13225 default:
13226 goto pool32axf_invalid;
13227 }
13228 break;
13229 case 0x2c:
13230 switch (minor) {
13231 case BITSWAP:
13232 check_insn(ctx, ISA_MIPS32R6);
13233 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13234 break;
13235 case SEB:
13236 gen_bshfl(ctx, OPC_SEB, rs, rt);
13237 break;
13238 case SEH:
13239 gen_bshfl(ctx, OPC_SEH, rs, rt);
13240 break;
13241 case CLO:
13242 mips32_op = OPC_CLO;
13243 goto do_cl;
13244 case CLZ:
13245 mips32_op = OPC_CLZ;
13246 do_cl:
13247 check_insn(ctx, ISA_MIPS32);
13248 gen_cl(ctx, mips32_op, rt, rs);
13249 break;
13250 case RDHWR:
13251 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13252 gen_rdhwr(ctx, rt, rs, 0);
13253 break;
13254 case WSBH:
13255 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13256 break;
13257 case MULT:
13258 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13259 mips32_op = OPC_MULT;
13260 goto do_mul;
13261 case MULTU:
13262 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13263 mips32_op = OPC_MULTU;
13264 goto do_mul;
13265 case DIV:
13266 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13267 mips32_op = OPC_DIV;
13268 goto do_div;
13269 case DIVU:
13270 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13271 mips32_op = OPC_DIVU;
13272 goto do_div;
13273 do_div:
13274 check_insn(ctx, ISA_MIPS32);
13275 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13276 break;
13277 case MADD:
13278 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13279 mips32_op = OPC_MADD;
13280 goto do_mul;
13281 case MADDU:
13282 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13283 mips32_op = OPC_MADDU;
13284 goto do_mul;
13285 case MSUB:
13286 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13287 mips32_op = OPC_MSUB;
13288 goto do_mul;
13289 case MSUBU:
13290 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13291 mips32_op = OPC_MSUBU;
13292 do_mul:
13293 check_insn(ctx, ISA_MIPS32);
13294 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13295 break;
13296 default:
13297 goto pool32axf_invalid;
13298 }
13299 break;
13300 case 0x34:
13301 switch (minor) {
13302 case MFC2:
13303 case MTC2:
13304 case MFHC2:
13305 case MTHC2:
13306 case CFC2:
13307 case CTC2:
13308 generate_exception_err(ctx, EXCP_CpU, 2);
13309 break;
13310 default:
13311 goto pool32axf_invalid;
13312 }
13313 break;
13314 case 0x3c:
13315 switch (minor) {
13316 case JALR: /* JALRC */
13317 case JALR_HB: /* JALRC_HB */
13318 if (ctx->insn_flags & ISA_MIPS32R6) {
13319 /* JALRC, JALRC_HB */
13320 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13321 } else {
13322 /* JALR, JALR_HB */
13323 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13324 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13325 }
13326 break;
13327 case JALRS:
13328 case JALRS_HB:
13329 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13330 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13331 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13332 break;
13333 default:
13334 goto pool32axf_invalid;
13335 }
13336 break;
13337 case 0x05:
13338 switch (minor) {
13339 case RDPGPR:
13340 check_cp0_enabled(ctx);
13341 check_insn(ctx, ISA_MIPS32R2);
13342 gen_load_srsgpr(rs, rt);
13343 break;
13344 case WRPGPR:
13345 check_cp0_enabled(ctx);
13346 check_insn(ctx, ISA_MIPS32R2);
13347 gen_store_srsgpr(rs, rt);
13348 break;
13349 default:
13350 goto pool32axf_invalid;
13351 }
13352 break;
13353 #ifndef CONFIG_USER_ONLY
13354 case 0x0d:
13355 switch (minor) {
13356 case TLBP:
13357 mips32_op = OPC_TLBP;
13358 goto do_cp0;
13359 case TLBR:
13360 mips32_op = OPC_TLBR;
13361 goto do_cp0;
13362 case TLBWI:
13363 mips32_op = OPC_TLBWI;
13364 goto do_cp0;
13365 case TLBWR:
13366 mips32_op = OPC_TLBWR;
13367 goto do_cp0;
13368 case TLBINV:
13369 mips32_op = OPC_TLBINV;
13370 goto do_cp0;
13371 case TLBINVF:
13372 mips32_op = OPC_TLBINVF;
13373 goto do_cp0;
13374 case WAIT:
13375 mips32_op = OPC_WAIT;
13376 goto do_cp0;
13377 case DERET:
13378 mips32_op = OPC_DERET;
13379 goto do_cp0;
13380 case ERET:
13381 mips32_op = OPC_ERET;
13382 do_cp0:
13383 gen_cp0(env, ctx, mips32_op, rt, rs);
13384 break;
13385 default:
13386 goto pool32axf_invalid;
13387 }
13388 break;
13389 case 0x1d:
13390 switch (minor) {
13391 case DI:
13392 check_cp0_enabled(ctx);
13393 {
13394 TCGv t0 = tcg_temp_new();
13395
13396 save_cpu_state(ctx, 1);
13397 gen_helper_di(t0, cpu_env);
13398 gen_store_gpr(t0, rs);
13399 /* Stop translation as we may have switched the execution mode */
13400 ctx->bstate = BS_STOP;
13401 tcg_temp_free(t0);
13402 }
13403 break;
13404 case EI:
13405 check_cp0_enabled(ctx);
13406 {
13407 TCGv t0 = tcg_temp_new();
13408
13409 save_cpu_state(ctx, 1);
13410 gen_helper_ei(t0, cpu_env);
13411 gen_store_gpr(t0, rs);
13412 /* Stop translation as we may have switched the execution mode */
13413 ctx->bstate = BS_STOP;
13414 tcg_temp_free(t0);
13415 }
13416 break;
13417 default:
13418 goto pool32axf_invalid;
13419 }
13420 break;
13421 #endif
13422 case 0x2d:
13423 switch (minor) {
13424 case SYNC:
13425 gen_sync(extract32(ctx->opcode, 16, 5));
13426 break;
13427 case SYSCALL:
13428 generate_exception_end(ctx, EXCP_SYSCALL);
13429 break;
13430 case SDBBP:
13431 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13432 gen_helper_do_semihosting(cpu_env);
13433 } else {
13434 check_insn(ctx, ISA_MIPS32);
13435 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13436 generate_exception_end(ctx, EXCP_RI);
13437 } else {
13438 generate_exception_end(ctx, EXCP_DBp);
13439 }
13440 }
13441 break;
13442 default:
13443 goto pool32axf_invalid;
13444 }
13445 break;
13446 case 0x01:
13447 switch (minor & 3) {
13448 case MFHI_ACC:
13449 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13450 break;
13451 case MFLO_ACC:
13452 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13453 break;
13454 case MTHI_ACC:
13455 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13456 break;
13457 case MTLO_ACC:
13458 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13459 break;
13460 default:
13461 goto pool32axf_invalid;
13462 }
13463 break;
13464 case 0x35:
13465 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13466 switch (minor) {
13467 case MFHI32:
13468 gen_HILO(ctx, OPC_MFHI, 0, rs);
13469 break;
13470 case MFLO32:
13471 gen_HILO(ctx, OPC_MFLO, 0, rs);
13472 break;
13473 case MTHI32:
13474 gen_HILO(ctx, OPC_MTHI, 0, rs);
13475 break;
13476 case MTLO32:
13477 gen_HILO(ctx, OPC_MTLO, 0, rs);
13478 break;
13479 default:
13480 goto pool32axf_invalid;
13481 }
13482 break;
13483 default:
13484 pool32axf_invalid:
13485 MIPS_INVAL("pool32axf");
13486 generate_exception_end(ctx, EXCP_RI);
13487 break;
13488 }
13489 }
13490
13491 /* Values for microMIPS fmt field. Variable-width, depending on which
13492 formats the instruction supports. */
13493
13494 enum {
13495 FMT_SD_S = 0,
13496 FMT_SD_D = 1,
13497
13498 FMT_SDPS_S = 0,
13499 FMT_SDPS_D = 1,
13500 FMT_SDPS_PS = 2,
13501
13502 FMT_SWL_S = 0,
13503 FMT_SWL_W = 1,
13504 FMT_SWL_L = 2,
13505
13506 FMT_DWL_D = 0,
13507 FMT_DWL_W = 1,
13508 FMT_DWL_L = 2
13509 };
13510
13511 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13512 {
13513 int extension = (ctx->opcode >> 6) & 0x3ff;
13514 uint32_t mips32_op;
13515
13516 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13517 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13518 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13519
13520 switch (extension) {
13521 case FLOAT_1BIT_FMT(CFC1, 0):
13522 mips32_op = OPC_CFC1;
13523 goto do_cp1;
13524 case FLOAT_1BIT_FMT(CTC1, 0):
13525 mips32_op = OPC_CTC1;
13526 goto do_cp1;
13527 case FLOAT_1BIT_FMT(MFC1, 0):
13528 mips32_op = OPC_MFC1;
13529 goto do_cp1;
13530 case FLOAT_1BIT_FMT(MTC1, 0):
13531 mips32_op = OPC_MTC1;
13532 goto do_cp1;
13533 case FLOAT_1BIT_FMT(MFHC1, 0):
13534 mips32_op = OPC_MFHC1;
13535 goto do_cp1;
13536 case FLOAT_1BIT_FMT(MTHC1, 0):
13537 mips32_op = OPC_MTHC1;
13538 do_cp1:
13539 gen_cp1(ctx, mips32_op, rt, rs);
13540 break;
13541
13542 /* Reciprocal square root */
13543 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13544 mips32_op = OPC_RSQRT_S;
13545 goto do_unaryfp;
13546 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13547 mips32_op = OPC_RSQRT_D;
13548 goto do_unaryfp;
13549
13550 /* Square root */
13551 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13552 mips32_op = OPC_SQRT_S;
13553 goto do_unaryfp;
13554 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13555 mips32_op = OPC_SQRT_D;
13556 goto do_unaryfp;
13557
13558 /* Reciprocal */
13559 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13560 mips32_op = OPC_RECIP_S;
13561 goto do_unaryfp;
13562 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13563 mips32_op = OPC_RECIP_D;
13564 goto do_unaryfp;
13565
13566 /* Floor */
13567 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13568 mips32_op = OPC_FLOOR_L_S;
13569 goto do_unaryfp;
13570 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13571 mips32_op = OPC_FLOOR_L_D;
13572 goto do_unaryfp;
13573 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13574 mips32_op = OPC_FLOOR_W_S;
13575 goto do_unaryfp;
13576 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13577 mips32_op = OPC_FLOOR_W_D;
13578 goto do_unaryfp;
13579
13580 /* Ceiling */
13581 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13582 mips32_op = OPC_CEIL_L_S;
13583 goto do_unaryfp;
13584 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13585 mips32_op = OPC_CEIL_L_D;
13586 goto do_unaryfp;
13587 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13588 mips32_op = OPC_CEIL_W_S;
13589 goto do_unaryfp;
13590 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13591 mips32_op = OPC_CEIL_W_D;
13592 goto do_unaryfp;
13593
13594 /* Truncation */
13595 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13596 mips32_op = OPC_TRUNC_L_S;
13597 goto do_unaryfp;
13598 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13599 mips32_op = OPC_TRUNC_L_D;
13600 goto do_unaryfp;
13601 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13602 mips32_op = OPC_TRUNC_W_S;
13603 goto do_unaryfp;
13604 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13605 mips32_op = OPC_TRUNC_W_D;
13606 goto do_unaryfp;
13607
13608 /* Round */
13609 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13610 mips32_op = OPC_ROUND_L_S;
13611 goto do_unaryfp;
13612 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13613 mips32_op = OPC_ROUND_L_D;
13614 goto do_unaryfp;
13615 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13616 mips32_op = OPC_ROUND_W_S;
13617 goto do_unaryfp;
13618 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13619 mips32_op = OPC_ROUND_W_D;
13620 goto do_unaryfp;
13621
13622 /* Integer to floating-point conversion */
13623 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13624 mips32_op = OPC_CVT_L_S;
13625 goto do_unaryfp;
13626 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13627 mips32_op = OPC_CVT_L_D;
13628 goto do_unaryfp;
13629 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13630 mips32_op = OPC_CVT_W_S;
13631 goto do_unaryfp;
13632 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13633 mips32_op = OPC_CVT_W_D;
13634 goto do_unaryfp;
13635
13636 /* Paired-foo conversions */
13637 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13638 mips32_op = OPC_CVT_S_PL;
13639 goto do_unaryfp;
13640 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13641 mips32_op = OPC_CVT_S_PU;
13642 goto do_unaryfp;
13643 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13644 mips32_op = OPC_CVT_PW_PS;
13645 goto do_unaryfp;
13646 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13647 mips32_op = OPC_CVT_PS_PW;
13648 goto do_unaryfp;
13649
13650 /* Floating-point moves */
13651 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13652 mips32_op = OPC_MOV_S;
13653 goto do_unaryfp;
13654 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13655 mips32_op = OPC_MOV_D;
13656 goto do_unaryfp;
13657 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13658 mips32_op = OPC_MOV_PS;
13659 goto do_unaryfp;
13660
13661 /* Absolute value */
13662 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13663 mips32_op = OPC_ABS_S;
13664 goto do_unaryfp;
13665 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13666 mips32_op = OPC_ABS_D;
13667 goto do_unaryfp;
13668 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13669 mips32_op = OPC_ABS_PS;
13670 goto do_unaryfp;
13671
13672 /* Negation */
13673 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13674 mips32_op = OPC_NEG_S;
13675 goto do_unaryfp;
13676 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13677 mips32_op = OPC_NEG_D;
13678 goto do_unaryfp;
13679 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13680 mips32_op = OPC_NEG_PS;
13681 goto do_unaryfp;
13682
13683 /* Reciprocal square root step */
13684 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13685 mips32_op = OPC_RSQRT1_S;
13686 goto do_unaryfp;
13687 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13688 mips32_op = OPC_RSQRT1_D;
13689 goto do_unaryfp;
13690 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13691 mips32_op = OPC_RSQRT1_PS;
13692 goto do_unaryfp;
13693
13694 /* Reciprocal step */
13695 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13696 mips32_op = OPC_RECIP1_S;
13697 goto do_unaryfp;
13698 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13699 mips32_op = OPC_RECIP1_S;
13700 goto do_unaryfp;
13701 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13702 mips32_op = OPC_RECIP1_PS;
13703 goto do_unaryfp;
13704
13705 /* Conversions from double */
13706 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13707 mips32_op = OPC_CVT_D_S;
13708 goto do_unaryfp;
13709 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13710 mips32_op = OPC_CVT_D_W;
13711 goto do_unaryfp;
13712 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13713 mips32_op = OPC_CVT_D_L;
13714 goto do_unaryfp;
13715
13716 /* Conversions from single */
13717 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13718 mips32_op = OPC_CVT_S_D;
13719 goto do_unaryfp;
13720 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13721 mips32_op = OPC_CVT_S_W;
13722 goto do_unaryfp;
13723 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13724 mips32_op = OPC_CVT_S_L;
13725 do_unaryfp:
13726 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13727 break;
13728
13729 /* Conditional moves on floating-point codes */
13730 case COND_FLOAT_MOV(MOVT, 0):
13731 case COND_FLOAT_MOV(MOVT, 1):
13732 case COND_FLOAT_MOV(MOVT, 2):
13733 case COND_FLOAT_MOV(MOVT, 3):
13734 case COND_FLOAT_MOV(MOVT, 4):
13735 case COND_FLOAT_MOV(MOVT, 5):
13736 case COND_FLOAT_MOV(MOVT, 6):
13737 case COND_FLOAT_MOV(MOVT, 7):
13738 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13739 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13740 break;
13741 case COND_FLOAT_MOV(MOVF, 0):
13742 case COND_FLOAT_MOV(MOVF, 1):
13743 case COND_FLOAT_MOV(MOVF, 2):
13744 case COND_FLOAT_MOV(MOVF, 3):
13745 case COND_FLOAT_MOV(MOVF, 4):
13746 case COND_FLOAT_MOV(MOVF, 5):
13747 case COND_FLOAT_MOV(MOVF, 6):
13748 case COND_FLOAT_MOV(MOVF, 7):
13749 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13750 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13751 break;
13752 default:
13753 MIPS_INVAL("pool32fxf");
13754 generate_exception_end(ctx, EXCP_RI);
13755 break;
13756 }
13757 }
13758
13759 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13760 {
13761 int32_t offset;
13762 uint16_t insn;
13763 int rt, rs, rd, rr;
13764 int16_t imm;
13765 uint32_t op, minor, mips32_op;
13766 uint32_t cond, fmt, cc;
13767
13768 insn = cpu_lduw_code(env, ctx->pc + 2);
13769 ctx->opcode = (ctx->opcode << 16) | insn;
13770
13771 rt = (ctx->opcode >> 21) & 0x1f;
13772 rs = (ctx->opcode >> 16) & 0x1f;
13773 rd = (ctx->opcode >> 11) & 0x1f;
13774 rr = (ctx->opcode >> 6) & 0x1f;
13775 imm = (int16_t) ctx->opcode;
13776
13777 op = (ctx->opcode >> 26) & 0x3f;
13778 switch (op) {
13779 case POOL32A:
13780 minor = ctx->opcode & 0x3f;
13781 switch (minor) {
13782 case 0x00:
13783 minor = (ctx->opcode >> 6) & 0xf;
13784 switch (minor) {
13785 case SLL32:
13786 mips32_op = OPC_SLL;
13787 goto do_shifti;
13788 case SRA:
13789 mips32_op = OPC_SRA;
13790 goto do_shifti;
13791 case SRL32:
13792 mips32_op = OPC_SRL;
13793 goto do_shifti;
13794 case ROTR:
13795 mips32_op = OPC_ROTR;
13796 do_shifti:
13797 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13798 break;
13799 case SELEQZ:
13800 check_insn(ctx, ISA_MIPS32R6);
13801 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13802 break;
13803 case SELNEZ:
13804 check_insn(ctx, ISA_MIPS32R6);
13805 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13806 break;
13807 case R6_RDHWR:
13808 check_insn(ctx, ISA_MIPS32R6);
13809 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13810 break;
13811 default:
13812 goto pool32a_invalid;
13813 }
13814 break;
13815 case 0x10:
13816 minor = (ctx->opcode >> 6) & 0xf;
13817 switch (minor) {
13818 /* Arithmetic */
13819 case ADD:
13820 mips32_op = OPC_ADD;
13821 goto do_arith;
13822 case ADDU32:
13823 mips32_op = OPC_ADDU;
13824 goto do_arith;
13825 case SUB:
13826 mips32_op = OPC_SUB;
13827 goto do_arith;
13828 case SUBU32:
13829 mips32_op = OPC_SUBU;
13830 goto do_arith;
13831 case MUL:
13832 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13833 mips32_op = OPC_MUL;
13834 do_arith:
13835 gen_arith(ctx, mips32_op, rd, rs, rt);
13836 break;
13837 /* Shifts */
13838 case SLLV:
13839 mips32_op = OPC_SLLV;
13840 goto do_shift;
13841 case SRLV:
13842 mips32_op = OPC_SRLV;
13843 goto do_shift;
13844 case SRAV:
13845 mips32_op = OPC_SRAV;
13846 goto do_shift;
13847 case ROTRV:
13848 mips32_op = OPC_ROTRV;
13849 do_shift:
13850 gen_shift(ctx, mips32_op, rd, rs, rt);
13851 break;
13852 /* Logical operations */
13853 case AND:
13854 mips32_op = OPC_AND;
13855 goto do_logic;
13856 case OR32:
13857 mips32_op = OPC_OR;
13858 goto do_logic;
13859 case NOR:
13860 mips32_op = OPC_NOR;
13861 goto do_logic;
13862 case XOR32:
13863 mips32_op = OPC_XOR;
13864 do_logic:
13865 gen_logic(ctx, mips32_op, rd, rs, rt);
13866 break;
13867 /* Set less than */
13868 case SLT:
13869 mips32_op = OPC_SLT;
13870 goto do_slt;
13871 case SLTU:
13872 mips32_op = OPC_SLTU;
13873 do_slt:
13874 gen_slt(ctx, mips32_op, rd, rs, rt);
13875 break;
13876 default:
13877 goto pool32a_invalid;
13878 }
13879 break;
13880 case 0x18:
13881 minor = (ctx->opcode >> 6) & 0xf;
13882 switch (minor) {
13883 /* Conditional moves */
13884 case MOVN: /* MUL */
13885 if (ctx->insn_flags & ISA_MIPS32R6) {
13886 /* MUL */
13887 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13888 } else {
13889 /* MOVN */
13890 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13891 }
13892 break;
13893 case MOVZ: /* MUH */
13894 if (ctx->insn_flags & ISA_MIPS32R6) {
13895 /* MUH */
13896 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13897 } else {
13898 /* MOVZ */
13899 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13900 }
13901 break;
13902 case MULU:
13903 check_insn(ctx, ISA_MIPS32R6);
13904 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13905 break;
13906 case MUHU:
13907 check_insn(ctx, ISA_MIPS32R6);
13908 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13909 break;
13910 case LWXS: /* DIV */
13911 if (ctx->insn_flags & ISA_MIPS32R6) {
13912 /* DIV */
13913 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13914 } else {
13915 /* LWXS */
13916 gen_ldxs(ctx, rs, rt, rd);
13917 }
13918 break;
13919 case MOD:
13920 check_insn(ctx, ISA_MIPS32R6);
13921 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13922 break;
13923 case R6_DIVU:
13924 check_insn(ctx, ISA_MIPS32R6);
13925 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
13926 break;
13927 case MODU:
13928 check_insn(ctx, ISA_MIPS32R6);
13929 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
13930 break;
13931 default:
13932 goto pool32a_invalid;
13933 }
13934 break;
13935 case INS:
13936 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13937 return;
13938 case LSA:
13939 check_insn(ctx, ISA_MIPS32R6);
13940 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13941 extract32(ctx->opcode, 9, 2));
13942 break;
13943 case ALIGN:
13944 check_insn(ctx, ISA_MIPS32R6);
13945 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13946 extract32(ctx->opcode, 9, 2));
13947 break;
13948 case EXT:
13949 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13950 return;
13951 case POOL32AXF:
13952 gen_pool32axf(env, ctx, rt, rs);
13953 break;
13954 case BREAK32:
13955 generate_exception_end(ctx, EXCP_BREAK);
13956 break;
13957 case SIGRIE:
13958 check_insn(ctx, ISA_MIPS32R6);
13959 generate_exception_end(ctx, EXCP_RI);
13960 break;
13961 default:
13962 pool32a_invalid:
13963 MIPS_INVAL("pool32a");
13964 generate_exception_end(ctx, EXCP_RI);
13965 break;
13966 }
13967 break;
13968 case POOL32B:
13969 minor = (ctx->opcode >> 12) & 0xf;
13970 switch (minor) {
13971 case CACHE:
13972 check_cp0_enabled(ctx);
13973 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
13974 gen_cache_operation(ctx, rt, rs, imm);
13975 }
13976 break;
13977 case LWC2:
13978 case SWC2:
13979 /* COP2: Not implemented. */
13980 generate_exception_err(ctx, EXCP_CpU, 2);
13981 break;
13982 #ifdef TARGET_MIPS64
13983 case LDP:
13984 case SDP:
13985 check_insn(ctx, ISA_MIPS3);
13986 check_mips_64(ctx);
13987 /* Fallthrough */
13988 #endif
13989 case LWP:
13990 case SWP:
13991 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13992 break;
13993 #ifdef TARGET_MIPS64
13994 case LDM:
13995 case SDM:
13996 check_insn(ctx, ISA_MIPS3);
13997 check_mips_64(ctx);
13998 /* Fallthrough */
13999 #endif
14000 case LWM32:
14001 case SWM32:
14002 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
14003 break;
14004 default:
14005 MIPS_INVAL("pool32b");
14006 generate_exception_end(ctx, EXCP_RI);
14007 break;
14008 }
14009 break;
14010 case POOL32F:
14011 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
14012 minor = ctx->opcode & 0x3f;
14013 check_cp1_enabled(ctx);
14014 switch (minor) {
14015 case ALNV_PS:
14016 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14017 mips32_op = OPC_ALNV_PS;
14018 goto do_madd;
14019 case MADD_S:
14020 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14021 mips32_op = OPC_MADD_S;
14022 goto do_madd;
14023 case MADD_D:
14024 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14025 mips32_op = OPC_MADD_D;
14026 goto do_madd;
14027 case MADD_PS:
14028 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14029 mips32_op = OPC_MADD_PS;
14030 goto do_madd;
14031 case MSUB_S:
14032 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14033 mips32_op = OPC_MSUB_S;
14034 goto do_madd;
14035 case MSUB_D:
14036 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14037 mips32_op = OPC_MSUB_D;
14038 goto do_madd;
14039 case MSUB_PS:
14040 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14041 mips32_op = OPC_MSUB_PS;
14042 goto do_madd;
14043 case NMADD_S:
14044 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14045 mips32_op = OPC_NMADD_S;
14046 goto do_madd;
14047 case NMADD_D:
14048 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14049 mips32_op = OPC_NMADD_D;
14050 goto do_madd;
14051 case NMADD_PS:
14052 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14053 mips32_op = OPC_NMADD_PS;
14054 goto do_madd;
14055 case NMSUB_S:
14056 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14057 mips32_op = OPC_NMSUB_S;
14058 goto do_madd;
14059 case NMSUB_D:
14060 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14061 mips32_op = OPC_NMSUB_D;
14062 goto do_madd;
14063 case NMSUB_PS:
14064 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14065 mips32_op = OPC_NMSUB_PS;
14066 do_madd:
14067 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
14068 break;
14069 case CABS_COND_FMT:
14070 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14071 cond = (ctx->opcode >> 6) & 0xf;
14072 cc = (ctx->opcode >> 13) & 0x7;
14073 fmt = (ctx->opcode >> 10) & 0x3;
14074 switch (fmt) {
14075 case 0x0:
14076 gen_cmpabs_s(ctx, cond, rt, rs, cc);
14077 break;
14078 case 0x1:
14079 gen_cmpabs_d(ctx, cond, rt, rs, cc);
14080 break;
14081 case 0x2:
14082 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
14083 break;
14084 default:
14085 goto pool32f_invalid;
14086 }
14087 break;
14088 case C_COND_FMT:
14089 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14090 cond = (ctx->opcode >> 6) & 0xf;
14091 cc = (ctx->opcode >> 13) & 0x7;
14092 fmt = (ctx->opcode >> 10) & 0x3;
14093 switch (fmt) {
14094 case 0x0:
14095 gen_cmp_s(ctx, cond, rt, rs, cc);
14096 break;
14097 case 0x1:
14098 gen_cmp_d(ctx, cond, rt, rs, cc);
14099 break;
14100 case 0x2:
14101 gen_cmp_ps(ctx, cond, rt, rs, cc);
14102 break;
14103 default:
14104 goto pool32f_invalid;
14105 }
14106 break;
14107 case CMP_CONDN_S:
14108 check_insn(ctx, ISA_MIPS32R6);
14109 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14110 break;
14111 case CMP_CONDN_D:
14112 check_insn(ctx, ISA_MIPS32R6);
14113 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
14114 break;
14115 case POOL32FXF:
14116 gen_pool32fxf(ctx, rt, rs);
14117 break;
14118 case 0x00:
14119 /* PLL foo */
14120 switch ((ctx->opcode >> 6) & 0x7) {
14121 case PLL_PS:
14122 mips32_op = OPC_PLL_PS;
14123 goto do_ps;
14124 case PLU_PS:
14125 mips32_op = OPC_PLU_PS;
14126 goto do_ps;
14127 case PUL_PS:
14128 mips32_op = OPC_PUL_PS;
14129 goto do_ps;
14130 case PUU_PS:
14131 mips32_op = OPC_PUU_PS;
14132 goto do_ps;
14133 case CVT_PS_S:
14134 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14135 mips32_op = OPC_CVT_PS_S;
14136 do_ps:
14137 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14138 break;
14139 default:
14140 goto pool32f_invalid;
14141 }
14142 break;
14143 case MIN_FMT:
14144 check_insn(ctx, ISA_MIPS32R6);
14145 switch ((ctx->opcode >> 9) & 0x3) {
14146 case FMT_SDPS_S:
14147 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
14148 break;
14149 case FMT_SDPS_D:
14150 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
14151 break;
14152 default:
14153 goto pool32f_invalid;
14154 }
14155 break;
14156 case 0x08:
14157 /* [LS][WDU]XC1 */
14158 switch ((ctx->opcode >> 6) & 0x7) {
14159 case LWXC1:
14160 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14161 mips32_op = OPC_LWXC1;
14162 goto do_ldst_cp1;
14163 case SWXC1:
14164 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14165 mips32_op = OPC_SWXC1;
14166 goto do_ldst_cp1;
14167 case LDXC1:
14168 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14169 mips32_op = OPC_LDXC1;
14170 goto do_ldst_cp1;
14171 case SDXC1:
14172 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14173 mips32_op = OPC_SDXC1;
14174 goto do_ldst_cp1;
14175 case LUXC1:
14176 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14177 mips32_op = OPC_LUXC1;
14178 goto do_ldst_cp1;
14179 case SUXC1:
14180 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14181 mips32_op = OPC_SUXC1;
14182 do_ldst_cp1:
14183 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
14184 break;
14185 default:
14186 goto pool32f_invalid;
14187 }
14188 break;
14189 case MAX_FMT:
14190 check_insn(ctx, ISA_MIPS32R6);
14191 switch ((ctx->opcode >> 9) & 0x3) {
14192 case FMT_SDPS_S:
14193 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
14194 break;
14195 case FMT_SDPS_D:
14196 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
14197 break;
14198 default:
14199 goto pool32f_invalid;
14200 }
14201 break;
14202 case 0x18:
14203 /* 3D insns */
14204 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14205 fmt = (ctx->opcode >> 9) & 0x3;
14206 switch ((ctx->opcode >> 6) & 0x7) {
14207 case RSQRT2_FMT:
14208 switch (fmt) {
14209 case FMT_SDPS_S:
14210 mips32_op = OPC_RSQRT2_S;
14211 goto do_3d;
14212 case FMT_SDPS_D:
14213 mips32_op = OPC_RSQRT2_D;
14214 goto do_3d;
14215 case FMT_SDPS_PS:
14216 mips32_op = OPC_RSQRT2_PS;
14217 goto do_3d;
14218 default:
14219 goto pool32f_invalid;
14220 }
14221 break;
14222 case RECIP2_FMT:
14223 switch (fmt) {
14224 case FMT_SDPS_S:
14225 mips32_op = OPC_RECIP2_S;
14226 goto do_3d;
14227 case FMT_SDPS_D:
14228 mips32_op = OPC_RECIP2_D;
14229 goto do_3d;
14230 case FMT_SDPS_PS:
14231 mips32_op = OPC_RECIP2_PS;
14232 goto do_3d;
14233 default:
14234 goto pool32f_invalid;
14235 }
14236 break;
14237 case ADDR_PS:
14238 mips32_op = OPC_ADDR_PS;
14239 goto do_3d;
14240 case MULR_PS:
14241 mips32_op = OPC_MULR_PS;
14242 do_3d:
14243 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14244 break;
14245 default:
14246 goto pool32f_invalid;
14247 }
14248 break;
14249 case 0x20:
14250 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14251 cc = (ctx->opcode >> 13) & 0x7;
14252 fmt = (ctx->opcode >> 9) & 0x3;
14253 switch ((ctx->opcode >> 6) & 0x7) {
14254 case MOVF_FMT: /* RINT_FMT */
14255 if (ctx->insn_flags & ISA_MIPS32R6) {
14256 /* RINT_FMT */
14257 switch (fmt) {
14258 case FMT_SDPS_S:
14259 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14260 break;
14261 case FMT_SDPS_D:
14262 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14263 break;
14264 default:
14265 goto pool32f_invalid;
14266 }
14267 } else {
14268 /* MOVF_FMT */
14269 switch (fmt) {
14270 case FMT_SDPS_S:
14271 gen_movcf_s(ctx, rs, rt, cc, 0);
14272 break;
14273 case FMT_SDPS_D:
14274 gen_movcf_d(ctx, rs, rt, cc, 0);
14275 break;
14276 case FMT_SDPS_PS:
14277 check_ps(ctx);
14278 gen_movcf_ps(ctx, rs, rt, cc, 0);
14279 break;
14280 default:
14281 goto pool32f_invalid;
14282 }
14283 }
14284 break;
14285 case MOVT_FMT: /* CLASS_FMT */
14286 if (ctx->insn_flags & ISA_MIPS32R6) {
14287 /* CLASS_FMT */
14288 switch (fmt) {
14289 case FMT_SDPS_S:
14290 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14291 break;
14292 case FMT_SDPS_D:
14293 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14294 break;
14295 default:
14296 goto pool32f_invalid;
14297 }
14298 } else {
14299 /* MOVT_FMT */
14300 switch (fmt) {
14301 case FMT_SDPS_S:
14302 gen_movcf_s(ctx, rs, rt, cc, 1);
14303 break;
14304 case FMT_SDPS_D:
14305 gen_movcf_d(ctx, rs, rt, cc, 1);
14306 break;
14307 case FMT_SDPS_PS:
14308 check_ps(ctx);
14309 gen_movcf_ps(ctx, rs, rt, cc, 1);
14310 break;
14311 default:
14312 goto pool32f_invalid;
14313 }
14314 }
14315 break;
14316 case PREFX:
14317 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14318 break;
14319 default:
14320 goto pool32f_invalid;
14321 }
14322 break;
14323 #define FINSN_3ARG_SDPS(prfx) \
14324 switch ((ctx->opcode >> 8) & 0x3) { \
14325 case FMT_SDPS_S: \
14326 mips32_op = OPC_##prfx##_S; \
14327 goto do_fpop; \
14328 case FMT_SDPS_D: \
14329 mips32_op = OPC_##prfx##_D; \
14330 goto do_fpop; \
14331 case FMT_SDPS_PS: \
14332 check_ps(ctx); \
14333 mips32_op = OPC_##prfx##_PS; \
14334 goto do_fpop; \
14335 default: \
14336 goto pool32f_invalid; \
14337 }
14338 case MINA_FMT:
14339 check_insn(ctx, ISA_MIPS32R6);
14340 switch ((ctx->opcode >> 9) & 0x3) {
14341 case FMT_SDPS_S:
14342 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14343 break;
14344 case FMT_SDPS_D:
14345 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14346 break;
14347 default:
14348 goto pool32f_invalid;
14349 }
14350 break;
14351 case MAXA_FMT:
14352 check_insn(ctx, ISA_MIPS32R6);
14353 switch ((ctx->opcode >> 9) & 0x3) {
14354 case FMT_SDPS_S:
14355 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14356 break;
14357 case FMT_SDPS_D:
14358 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14359 break;
14360 default:
14361 goto pool32f_invalid;
14362 }
14363 break;
14364 case 0x30:
14365 /* regular FP ops */
14366 switch ((ctx->opcode >> 6) & 0x3) {
14367 case ADD_FMT:
14368 FINSN_3ARG_SDPS(ADD);
14369 break;
14370 case SUB_FMT:
14371 FINSN_3ARG_SDPS(SUB);
14372 break;
14373 case MUL_FMT:
14374 FINSN_3ARG_SDPS(MUL);
14375 break;
14376 case DIV_FMT:
14377 fmt = (ctx->opcode >> 8) & 0x3;
14378 if (fmt == 1) {
14379 mips32_op = OPC_DIV_D;
14380 } else if (fmt == 0) {
14381 mips32_op = OPC_DIV_S;
14382 } else {
14383 goto pool32f_invalid;
14384 }
14385 goto do_fpop;
14386 default:
14387 goto pool32f_invalid;
14388 }
14389 break;
14390 case 0x38:
14391 /* cmovs */
14392 switch ((ctx->opcode >> 6) & 0x7) {
14393 case MOVN_FMT: /* SELNEZ_FMT */
14394 if (ctx->insn_flags & ISA_MIPS32R6) {
14395 /* SELNEZ_FMT */
14396 switch ((ctx->opcode >> 9) & 0x3) {
14397 case FMT_SDPS_S:
14398 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14399 break;
14400 case FMT_SDPS_D:
14401 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14402 break;
14403 default:
14404 goto pool32f_invalid;
14405 }
14406 } else {
14407 /* MOVN_FMT */
14408 FINSN_3ARG_SDPS(MOVN);
14409 }
14410 break;
14411 case MOVN_FMT_04:
14412 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14413 FINSN_3ARG_SDPS(MOVN);
14414 break;
14415 case MOVZ_FMT: /* SELEQZ_FMT */
14416 if (ctx->insn_flags & ISA_MIPS32R6) {
14417 /* SELEQZ_FMT */
14418 switch ((ctx->opcode >> 9) & 0x3) {
14419 case FMT_SDPS_S:
14420 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14421 break;
14422 case FMT_SDPS_D:
14423 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14424 break;
14425 default:
14426 goto pool32f_invalid;
14427 }
14428 } else {
14429 /* MOVZ_FMT */
14430 FINSN_3ARG_SDPS(MOVZ);
14431 }
14432 break;
14433 case MOVZ_FMT_05:
14434 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14435 FINSN_3ARG_SDPS(MOVZ);
14436 break;
14437 case SEL_FMT:
14438 check_insn(ctx, ISA_MIPS32R6);
14439 switch ((ctx->opcode >> 9) & 0x3) {
14440 case FMT_SDPS_S:
14441 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14442 break;
14443 case FMT_SDPS_D:
14444 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14445 break;
14446 default:
14447 goto pool32f_invalid;
14448 }
14449 break;
14450 case MADDF_FMT:
14451 check_insn(ctx, ISA_MIPS32R6);
14452 switch ((ctx->opcode >> 9) & 0x3) {
14453 case FMT_SDPS_S:
14454 mips32_op = OPC_MADDF_S;
14455 goto do_fpop;
14456 case FMT_SDPS_D:
14457 mips32_op = OPC_MADDF_D;
14458 goto do_fpop;
14459 default:
14460 goto pool32f_invalid;
14461 }
14462 break;
14463 case MSUBF_FMT:
14464 check_insn(ctx, ISA_MIPS32R6);
14465 switch ((ctx->opcode >> 9) & 0x3) {
14466 case FMT_SDPS_S:
14467 mips32_op = OPC_MSUBF_S;
14468 goto do_fpop;
14469 case FMT_SDPS_D:
14470 mips32_op = OPC_MSUBF_D;
14471 goto do_fpop;
14472 default:
14473 goto pool32f_invalid;
14474 }
14475 break;
14476 default:
14477 goto pool32f_invalid;
14478 }
14479 break;
14480 do_fpop:
14481 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14482 break;
14483 default:
14484 pool32f_invalid:
14485 MIPS_INVAL("pool32f");
14486 generate_exception_end(ctx, EXCP_RI);
14487 break;
14488 }
14489 } else {
14490 generate_exception_err(ctx, EXCP_CpU, 1);
14491 }
14492 break;
14493 case POOL32I:
14494 minor = (ctx->opcode >> 21) & 0x1f;
14495 switch (minor) {
14496 case BLTZ:
14497 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14498 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14499 break;
14500 case BLTZAL:
14501 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14502 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14503 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14504 break;
14505 case BLTZALS:
14506 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14507 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14508 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14509 break;
14510 case BGEZ:
14511 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14512 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14513 break;
14514 case BGEZAL:
14515 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14516 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14517 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14518 break;
14519 case BGEZALS:
14520 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14521 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14522 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14523 break;
14524 case BLEZ:
14525 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14526 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14527 break;
14528 case BGTZ:
14529 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14530 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14531 break;
14532
14533 /* Traps */
14534 case TLTI: /* BC1EQZC */
14535 if (ctx->insn_flags & ISA_MIPS32R6) {
14536 /* BC1EQZC */
14537 check_cp1_enabled(ctx);
14538 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14539 } else {
14540 /* TLTI */
14541 mips32_op = OPC_TLTI;
14542 goto do_trapi;
14543 }
14544 break;
14545 case TGEI: /* BC1NEZC */
14546 if (ctx->insn_flags & ISA_MIPS32R6) {
14547 /* BC1NEZC */
14548 check_cp1_enabled(ctx);
14549 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14550 } else {
14551 /* TGEI */
14552 mips32_op = OPC_TGEI;
14553 goto do_trapi;
14554 }
14555 break;
14556 case TLTIU:
14557 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14558 mips32_op = OPC_TLTIU;
14559 goto do_trapi;
14560 case TGEIU:
14561 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14562 mips32_op = OPC_TGEIU;
14563 goto do_trapi;
14564 case TNEI: /* SYNCI */
14565 if (ctx->insn_flags & ISA_MIPS32R6) {
14566 /* SYNCI */
14567 /* Break the TB to be able to sync copied instructions
14568 immediately */
14569 ctx->bstate = BS_STOP;
14570 } else {
14571 /* TNEI */
14572 mips32_op = OPC_TNEI;
14573 goto do_trapi;
14574 }
14575 break;
14576 case TEQI:
14577 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14578 mips32_op = OPC_TEQI;
14579 do_trapi:
14580 gen_trap(ctx, mips32_op, rs, -1, imm);
14581 break;
14582
14583 case BNEZC:
14584 case BEQZC:
14585 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14586 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14587 4, rs, 0, imm << 1, 0);
14588 /* Compact branches don't have a delay slot, so just let
14589 the normal delay slot handling take us to the branch
14590 target. */
14591 break;
14592 case LUI:
14593 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14594 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14595 break;
14596 case SYNCI:
14597 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14598 /* Break the TB to be able to sync copied instructions
14599 immediately */
14600 ctx->bstate = BS_STOP;
14601 break;
14602 case BC2F:
14603 case BC2T:
14604 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14605 /* COP2: Not implemented. */
14606 generate_exception_err(ctx, EXCP_CpU, 2);
14607 break;
14608 case BC1F:
14609 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14610 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14611 goto do_cp1branch;
14612 case BC1T:
14613 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14614 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14615 goto do_cp1branch;
14616 case BC1ANY4F:
14617 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14618 mips32_op = OPC_BC1FANY4;
14619 goto do_cp1mips3d;
14620 case BC1ANY4T:
14621 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14622 mips32_op = OPC_BC1TANY4;
14623 do_cp1mips3d:
14624 check_cop1x(ctx);
14625 check_insn(ctx, ASE_MIPS3D);
14626 /* Fall through */
14627 do_cp1branch:
14628 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14629 check_cp1_enabled(ctx);
14630 gen_compute_branch1(ctx, mips32_op,
14631 (ctx->opcode >> 18) & 0x7, imm << 1);
14632 } else {
14633 generate_exception_err(ctx, EXCP_CpU, 1);
14634 }
14635 break;
14636 case BPOSGE64:
14637 case BPOSGE32:
14638 /* MIPS DSP: not implemented */
14639 /* Fall through */
14640 default:
14641 MIPS_INVAL("pool32i");
14642 generate_exception_end(ctx, EXCP_RI);
14643 break;
14644 }
14645 break;
14646 case POOL32C:
14647 minor = (ctx->opcode >> 12) & 0xf;
14648 offset = sextract32(ctx->opcode, 0,
14649 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14650 switch (minor) {
14651 case LWL:
14652 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14653 mips32_op = OPC_LWL;
14654 goto do_ld_lr;
14655 case SWL:
14656 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14657 mips32_op = OPC_SWL;
14658 goto do_st_lr;
14659 case LWR:
14660 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14661 mips32_op = OPC_LWR;
14662 goto do_ld_lr;
14663 case SWR:
14664 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14665 mips32_op = OPC_SWR;
14666 goto do_st_lr;
14667 #if defined(TARGET_MIPS64)
14668 case LDL:
14669 check_insn(ctx, ISA_MIPS3);
14670 check_mips_64(ctx);
14671 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14672 mips32_op = OPC_LDL;
14673 goto do_ld_lr;
14674 case SDL:
14675 check_insn(ctx, ISA_MIPS3);
14676 check_mips_64(ctx);
14677 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14678 mips32_op = OPC_SDL;
14679 goto do_st_lr;
14680 case LDR:
14681 check_insn(ctx, ISA_MIPS3);
14682 check_mips_64(ctx);
14683 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14684 mips32_op = OPC_LDR;
14685 goto do_ld_lr;
14686 case SDR:
14687 check_insn(ctx, ISA_MIPS3);
14688 check_mips_64(ctx);
14689 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14690 mips32_op = OPC_SDR;
14691 goto do_st_lr;
14692 case LWU:
14693 check_insn(ctx, ISA_MIPS3);
14694 check_mips_64(ctx);
14695 mips32_op = OPC_LWU;
14696 goto do_ld_lr;
14697 case LLD:
14698 check_insn(ctx, ISA_MIPS3);
14699 check_mips_64(ctx);
14700 mips32_op = OPC_LLD;
14701 goto do_ld_lr;
14702 #endif
14703 case LL:
14704 mips32_op = OPC_LL;
14705 goto do_ld_lr;
14706 do_ld_lr:
14707 gen_ld(ctx, mips32_op, rt, rs, offset);
14708 break;
14709 do_st_lr:
14710 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
14711 break;
14712 case SC:
14713 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14714 break;
14715 #if defined(TARGET_MIPS64)
14716 case SCD:
14717 check_insn(ctx, ISA_MIPS3);
14718 check_mips_64(ctx);
14719 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14720 break;
14721 #endif
14722 case PREF:
14723 /* Treat as no-op */
14724 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14725 /* hint codes 24-31 are reserved and signal RI */
14726 generate_exception(ctx, EXCP_RI);
14727 }
14728 break;
14729 default:
14730 MIPS_INVAL("pool32c");
14731 generate_exception_end(ctx, EXCP_RI);
14732 break;
14733 }
14734 break;
14735 case ADDI32: /* AUI, LUI */
14736 if (ctx->insn_flags & ISA_MIPS32R6) {
14737 /* AUI, LUI */
14738 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14739 } else {
14740 /* ADDI32 */
14741 mips32_op = OPC_ADDI;
14742 goto do_addi;
14743 }
14744 break;
14745 case ADDIU32:
14746 mips32_op = OPC_ADDIU;
14747 do_addi:
14748 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
14749 break;
14750
14751 /* Logical operations */
14752 case ORI32:
14753 mips32_op = OPC_ORI;
14754 goto do_logici;
14755 case XORI32:
14756 mips32_op = OPC_XORI;
14757 goto do_logici;
14758 case ANDI32:
14759 mips32_op = OPC_ANDI;
14760 do_logici:
14761 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
14762 break;
14763
14764 /* Set less than immediate */
14765 case SLTI32:
14766 mips32_op = OPC_SLTI;
14767 goto do_slti;
14768 case SLTIU32:
14769 mips32_op = OPC_SLTIU;
14770 do_slti:
14771 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
14772 break;
14773 case JALX32:
14774 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14775 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14776 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14777 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14778 break;
14779 case JALS32: /* BOVC, BEQC, BEQZALC */
14780 if (ctx->insn_flags & ISA_MIPS32R6) {
14781 if (rs >= rt) {
14782 /* BOVC */
14783 mips32_op = OPC_BOVC;
14784 } else if (rs < rt && rs == 0) {
14785 /* BEQZALC */
14786 mips32_op = OPC_BEQZALC;
14787 } else {
14788 /* BEQC */
14789 mips32_op = OPC_BEQC;
14790 }
14791 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14792 } else {
14793 /* JALS32 */
14794 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14795 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14796 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14797 }
14798 break;
14799 case BEQ32: /* BC */
14800 if (ctx->insn_flags & ISA_MIPS32R6) {
14801 /* BC */
14802 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14803 sextract32(ctx->opcode << 1, 0, 27));
14804 } else {
14805 /* BEQ32 */
14806 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14807 }
14808 break;
14809 case BNE32: /* BALC */
14810 if (ctx->insn_flags & ISA_MIPS32R6) {
14811 /* BALC */
14812 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14813 sextract32(ctx->opcode << 1, 0, 27));
14814 } else {
14815 /* BNE32 */
14816 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14817 }
14818 break;
14819 case J32: /* BGTZC, BLTZC, BLTC */
14820 if (ctx->insn_flags & ISA_MIPS32R6) {
14821 if (rs == 0 && rt != 0) {
14822 /* BGTZC */
14823 mips32_op = OPC_BGTZC;
14824 } else if (rs != 0 && rt != 0 && rs == rt) {
14825 /* BLTZC */
14826 mips32_op = OPC_BLTZC;
14827 } else {
14828 /* BLTC */
14829 mips32_op = OPC_BLTC;
14830 }
14831 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14832 } else {
14833 /* J32 */
14834 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14835 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14836 }
14837 break;
14838 case JAL32: /* BLEZC, BGEZC, BGEC */
14839 if (ctx->insn_flags & ISA_MIPS32R6) {
14840 if (rs == 0 && rt != 0) {
14841 /* BLEZC */
14842 mips32_op = OPC_BLEZC;
14843 } else if (rs != 0 && rt != 0 && rs == rt) {
14844 /* BGEZC */
14845 mips32_op = OPC_BGEZC;
14846 } else {
14847 /* BGEC */
14848 mips32_op = OPC_BGEC;
14849 }
14850 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14851 } else {
14852 /* JAL32 */
14853 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14854 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14855 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14856 }
14857 break;
14858 /* Floating point (COP1) */
14859 case LWC132:
14860 mips32_op = OPC_LWC1;
14861 goto do_cop1;
14862 case LDC132:
14863 mips32_op = OPC_LDC1;
14864 goto do_cop1;
14865 case SWC132:
14866 mips32_op = OPC_SWC1;
14867 goto do_cop1;
14868 case SDC132:
14869 mips32_op = OPC_SDC1;
14870 do_cop1:
14871 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
14872 break;
14873 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14874 if (ctx->insn_flags & ISA_MIPS32R6) {
14875 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14876 switch ((ctx->opcode >> 16) & 0x1f) {
14877 case ADDIUPC_00 ... ADDIUPC_07:
14878 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14879 break;
14880 case AUIPC:
14881 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14882 break;
14883 case ALUIPC:
14884 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14885 break;
14886 case LWPC_08 ... LWPC_0F:
14887 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14888 break;
14889 default:
14890 generate_exception(ctx, EXCP_RI);
14891 break;
14892 }
14893 } else {
14894 /* ADDIUPC */
14895 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14896 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14897
14898 gen_addiupc(ctx, reg, offset, 0, 0);
14899 }
14900 break;
14901 case BNVC: /* BNEC, BNEZALC */
14902 check_insn(ctx, ISA_MIPS32R6);
14903 if (rs >= rt) {
14904 /* BNVC */
14905 mips32_op = OPC_BNVC;
14906 } else if (rs < rt && rs == 0) {
14907 /* BNEZALC */
14908 mips32_op = OPC_BNEZALC;
14909 } else {
14910 /* BNEC */
14911 mips32_op = OPC_BNEC;
14912 }
14913 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14914 break;
14915 case R6_BNEZC: /* JIALC */
14916 check_insn(ctx, ISA_MIPS32R6);
14917 if (rt != 0) {
14918 /* BNEZC */
14919 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14920 sextract32(ctx->opcode << 1, 0, 22));
14921 } else {
14922 /* JIALC */
14923 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14924 }
14925 break;
14926 case R6_BEQZC: /* JIC */
14927 check_insn(ctx, ISA_MIPS32R6);
14928 if (rt != 0) {
14929 /* BEQZC */
14930 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14931 sextract32(ctx->opcode << 1, 0, 22));
14932 } else {
14933 /* JIC */
14934 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14935 }
14936 break;
14937 case BLEZALC: /* BGEZALC, BGEUC */
14938 check_insn(ctx, ISA_MIPS32R6);
14939 if (rs == 0 && rt != 0) {
14940 /* BLEZALC */
14941 mips32_op = OPC_BLEZALC;
14942 } else if (rs != 0 && rt != 0 && rs == rt) {
14943 /* BGEZALC */
14944 mips32_op = OPC_BGEZALC;
14945 } else {
14946 /* BGEUC */
14947 mips32_op = OPC_BGEUC;
14948 }
14949 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14950 break;
14951 case BGTZALC: /* BLTZALC, BLTUC */
14952 check_insn(ctx, ISA_MIPS32R6);
14953 if (rs == 0 && rt != 0) {
14954 /* BGTZALC */
14955 mips32_op = OPC_BGTZALC;
14956 } else if (rs != 0 && rt != 0 && rs == rt) {
14957 /* BLTZALC */
14958 mips32_op = OPC_BLTZALC;
14959 } else {
14960 /* BLTUC */
14961 mips32_op = OPC_BLTUC;
14962 }
14963 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14964 break;
14965 /* Loads and stores */
14966 case LB32:
14967 mips32_op = OPC_LB;
14968 goto do_ld;
14969 case LBU32:
14970 mips32_op = OPC_LBU;
14971 goto do_ld;
14972 case LH32:
14973 mips32_op = OPC_LH;
14974 goto do_ld;
14975 case LHU32:
14976 mips32_op = OPC_LHU;
14977 goto do_ld;
14978 case LW32:
14979 mips32_op = OPC_LW;
14980 goto do_ld;
14981 #ifdef TARGET_MIPS64
14982 case LD32:
14983 check_insn(ctx, ISA_MIPS3);
14984 check_mips_64(ctx);
14985 mips32_op = OPC_LD;
14986 goto do_ld;
14987 case SD32:
14988 check_insn(ctx, ISA_MIPS3);
14989 check_mips_64(ctx);
14990 mips32_op = OPC_SD;
14991 goto do_st;
14992 #endif
14993 case SB32:
14994 mips32_op = OPC_SB;
14995 goto do_st;
14996 case SH32:
14997 mips32_op = OPC_SH;
14998 goto do_st;
14999 case SW32:
15000 mips32_op = OPC_SW;
15001 goto do_st;
15002 do_ld:
15003 gen_ld(ctx, mips32_op, rt, rs, imm);
15004 break;
15005 do_st:
15006 gen_st(ctx, mips32_op, rt, rs, imm);
15007 break;
15008 default:
15009 generate_exception_end(ctx, EXCP_RI);
15010 break;
15011 }
15012 }
15013
15014 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
15015 {
15016 uint32_t op;
15017
15018 /* make sure instructions are on a halfword boundary */
15019 if (ctx->pc & 0x1) {
15020 env->CP0_BadVAddr = ctx->pc;
15021 generate_exception_end(ctx, EXCP_AdEL);
15022 return 2;
15023 }
15024
15025 op = (ctx->opcode >> 10) & 0x3f;
15026 /* Enforce properly-sized instructions in a delay slot */
15027 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
15028 switch (op & 0x7) { /* MSB-3..MSB-5 */
15029 case 0:
15030 /* POOL32A, POOL32B, POOL32I, POOL32C */
15031 case 4:
15032 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15033 case 5:
15034 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15035 case 6:
15036 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15037 case 7:
15038 /* LB32, LH32, LWC132, LDC132, LW32 */
15039 if (ctx->hflags & MIPS_HFLAG_BDS16) {
15040 generate_exception_end(ctx, EXCP_RI);
15041 return 2;
15042 }
15043 break;
15044 case 1:
15045 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15046 case 2:
15047 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15048 case 3:
15049 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15050 if (ctx->hflags & MIPS_HFLAG_BDS32) {
15051 generate_exception_end(ctx, EXCP_RI);
15052 return 2;
15053 }
15054 break;
15055 }
15056 }
15057
15058 switch (op) {
15059 case POOL16A:
15060 {
15061 int rd = mmreg(uMIPS_RD(ctx->opcode));
15062 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
15063 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
15064 uint32_t opc = 0;
15065
15066 switch (ctx->opcode & 0x1) {
15067 case ADDU16:
15068 opc = OPC_ADDU;
15069 break;
15070 case SUBU16:
15071 opc = OPC_SUBU;
15072 break;
15073 }
15074 if (ctx->insn_flags & ISA_MIPS32R6) {
15075 /* In the Release 6 the register number location in
15076 * the instruction encoding has changed.
15077 */
15078 gen_arith(ctx, opc, rs1, rd, rs2);
15079 } else {
15080 gen_arith(ctx, opc, rd, rs1, rs2);
15081 }
15082 }
15083 break;
15084 case POOL16B:
15085 {
15086 int rd = mmreg(uMIPS_RD(ctx->opcode));
15087 int rs = mmreg(uMIPS_RS(ctx->opcode));
15088 int amount = (ctx->opcode >> 1) & 0x7;
15089 uint32_t opc = 0;
15090 amount = amount == 0 ? 8 : amount;
15091
15092 switch (ctx->opcode & 0x1) {
15093 case SLL16:
15094 opc = OPC_SLL;
15095 break;
15096 case SRL16:
15097 opc = OPC_SRL;
15098 break;
15099 }
15100
15101 gen_shift_imm(ctx, opc, rd, rs, amount);
15102 }
15103 break;
15104 case POOL16C:
15105 if (ctx->insn_flags & ISA_MIPS32R6) {
15106 gen_pool16c_r6_insn(ctx);
15107 } else {
15108 gen_pool16c_insn(ctx);
15109 }
15110 break;
15111 case LWGP16:
15112 {
15113 int rd = mmreg(uMIPS_RD(ctx->opcode));
15114 int rb = 28; /* GP */
15115 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
15116
15117 gen_ld(ctx, OPC_LW, rd, rb, offset);
15118 }
15119 break;
15120 case POOL16F:
15121 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15122 if (ctx->opcode & 1) {
15123 generate_exception_end(ctx, EXCP_RI);
15124 } else {
15125 /* MOVEP */
15126 int enc_dest = uMIPS_RD(ctx->opcode);
15127 int enc_rt = uMIPS_RS2(ctx->opcode);
15128 int enc_rs = uMIPS_RS1(ctx->opcode);
15129 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15130 }
15131 break;
15132 case LBU16:
15133 {
15134 int rd = mmreg(uMIPS_RD(ctx->opcode));
15135 int rb = mmreg(uMIPS_RS(ctx->opcode));
15136 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15137 offset = (offset == 0xf ? -1 : offset);
15138
15139 gen_ld(ctx, OPC_LBU, rd, rb, offset);
15140 }
15141 break;
15142 case LHU16:
15143 {
15144 int rd = mmreg(uMIPS_RD(ctx->opcode));
15145 int rb = mmreg(uMIPS_RS(ctx->opcode));
15146 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15147
15148 gen_ld(ctx, OPC_LHU, rd, rb, offset);
15149 }
15150 break;
15151 case LWSP16:
15152 {
15153 int rd = (ctx->opcode >> 5) & 0x1f;
15154 int rb = 29; /* SP */
15155 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15156
15157 gen_ld(ctx, OPC_LW, rd, rb, offset);
15158 }
15159 break;
15160 case LW16:
15161 {
15162 int rd = mmreg(uMIPS_RD(ctx->opcode));
15163 int rb = mmreg(uMIPS_RS(ctx->opcode));
15164 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15165
15166 gen_ld(ctx, OPC_LW, rd, rb, offset);
15167 }
15168 break;
15169 case SB16:
15170 {
15171 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15172 int rb = mmreg(uMIPS_RS(ctx->opcode));
15173 int16_t offset = ZIMM(ctx->opcode, 0, 4);
15174
15175 gen_st(ctx, OPC_SB, rd, rb, offset);
15176 }
15177 break;
15178 case SH16:
15179 {
15180 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15181 int rb = mmreg(uMIPS_RS(ctx->opcode));
15182 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
15183
15184 gen_st(ctx, OPC_SH, rd, rb, offset);
15185 }
15186 break;
15187 case SWSP16:
15188 {
15189 int rd = (ctx->opcode >> 5) & 0x1f;
15190 int rb = 29; /* SP */
15191 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
15192
15193 gen_st(ctx, OPC_SW, rd, rb, offset);
15194 }
15195 break;
15196 case SW16:
15197 {
15198 int rd = mmreg2(uMIPS_RD(ctx->opcode));
15199 int rb = mmreg(uMIPS_RS(ctx->opcode));
15200 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
15201
15202 gen_st(ctx, OPC_SW, rd, rb, offset);
15203 }
15204 break;
15205 case MOVE16:
15206 {
15207 int rd = uMIPS_RD5(ctx->opcode);
15208 int rs = uMIPS_RS5(ctx->opcode);
15209
15210 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
15211 }
15212 break;
15213 case ANDI16:
15214 gen_andi16(ctx);
15215 break;
15216 case POOL16D:
15217 switch (ctx->opcode & 0x1) {
15218 case ADDIUS5:
15219 gen_addius5(ctx);
15220 break;
15221 case ADDIUSP:
15222 gen_addiusp(ctx);
15223 break;
15224 }
15225 break;
15226 case POOL16E:
15227 switch (ctx->opcode & 0x1) {
15228 case ADDIUR2:
15229 gen_addiur2(ctx);
15230 break;
15231 case ADDIUR1SP:
15232 gen_addiur1sp(ctx);
15233 break;
15234 }
15235 break;
15236 case B16: /* BC16 */
15237 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
15238 sextract32(ctx->opcode, 0, 10) << 1,
15239 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15240 break;
15241 case BNEZ16: /* BNEZC16 */
15242 case BEQZ16: /* BEQZC16 */
15243 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15244 mmreg(uMIPS_RD(ctx->opcode)),
15245 0, sextract32(ctx->opcode, 0, 7) << 1,
15246 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15247
15248 break;
15249 case LI16:
15250 {
15251 int reg = mmreg(uMIPS_RD(ctx->opcode));
15252 int imm = ZIMM(ctx->opcode, 0, 7);
15253
15254 imm = (imm == 0x7f ? -1 : imm);
15255 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15256 }
15257 break;
15258 case RES_29:
15259 case RES_31:
15260 case RES_39:
15261 generate_exception_end(ctx, EXCP_RI);
15262 break;
15263 default:
15264 decode_micromips32_opc(env, ctx);
15265 return 4;
15266 }
15267
15268 return 2;
15269 }
15270
15271 /* SmartMIPS extension to MIPS32 */
15272
15273 #if defined(TARGET_MIPS64)
15274
15275 /* MDMX extension to MIPS64 */
15276
15277 #endif
15278
15279 /* MIPSDSP functions. */
15280 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
15281 int rd, int base, int offset)
15282 {
15283 TCGv t0;
15284
15285 check_dsp(ctx);
15286 t0 = tcg_temp_new();
15287
15288 if (base == 0) {
15289 gen_load_gpr(t0, offset);
15290 } else if (offset == 0) {
15291 gen_load_gpr(t0, base);
15292 } else {
15293 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15294 }
15295
15296 switch (opc) {
15297 case OPC_LBUX:
15298 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
15299 gen_store_gpr(t0, rd);
15300 break;
15301 case OPC_LHX:
15302 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
15303 gen_store_gpr(t0, rd);
15304 break;
15305 case OPC_LWX:
15306 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
15307 gen_store_gpr(t0, rd);
15308 break;
15309 #if defined(TARGET_MIPS64)
15310 case OPC_LDX:
15311 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
15312 gen_store_gpr(t0, rd);
15313 break;
15314 #endif
15315 }
15316 tcg_temp_free(t0);
15317 }
15318
15319 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15320 int ret, int v1, int v2)
15321 {
15322 TCGv v1_t;
15323 TCGv v2_t;
15324
15325 if (ret == 0) {
15326 /* Treat as NOP. */
15327 return;
15328 }
15329
15330 v1_t = tcg_temp_new();
15331 v2_t = tcg_temp_new();
15332
15333 gen_load_gpr(v1_t, v1);
15334 gen_load_gpr(v2_t, v2);
15335
15336 switch (op1) {
15337 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15338 case OPC_MULT_G_2E:
15339 check_dspr2(ctx);
15340 switch (op2) {
15341 case OPC_ADDUH_QB:
15342 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15343 break;
15344 case OPC_ADDUH_R_QB:
15345 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15346 break;
15347 case OPC_ADDQH_PH:
15348 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15349 break;
15350 case OPC_ADDQH_R_PH:
15351 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15352 break;
15353 case OPC_ADDQH_W:
15354 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15355 break;
15356 case OPC_ADDQH_R_W:
15357 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15358 break;
15359 case OPC_SUBUH_QB:
15360 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15361 break;
15362 case OPC_SUBUH_R_QB:
15363 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15364 break;
15365 case OPC_SUBQH_PH:
15366 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15367 break;
15368 case OPC_SUBQH_R_PH:
15369 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15370 break;
15371 case OPC_SUBQH_W:
15372 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15373 break;
15374 case OPC_SUBQH_R_W:
15375 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15376 break;
15377 }
15378 break;
15379 case OPC_ABSQ_S_PH_DSP:
15380 switch (op2) {
15381 case OPC_ABSQ_S_QB:
15382 check_dspr2(ctx);
15383 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15384 break;
15385 case OPC_ABSQ_S_PH:
15386 check_dsp(ctx);
15387 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15388 break;
15389 case OPC_ABSQ_S_W:
15390 check_dsp(ctx);
15391 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15392 break;
15393 case OPC_PRECEQ_W_PHL:
15394 check_dsp(ctx);
15395 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15396 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15397 break;
15398 case OPC_PRECEQ_W_PHR:
15399 check_dsp(ctx);
15400 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15401 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15402 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15403 break;
15404 case OPC_PRECEQU_PH_QBL:
15405 check_dsp(ctx);
15406 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15407 break;
15408 case OPC_PRECEQU_PH_QBR:
15409 check_dsp(ctx);
15410 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15411 break;
15412 case OPC_PRECEQU_PH_QBLA:
15413 check_dsp(ctx);
15414 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15415 break;
15416 case OPC_PRECEQU_PH_QBRA:
15417 check_dsp(ctx);
15418 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15419 break;
15420 case OPC_PRECEU_PH_QBL:
15421 check_dsp(ctx);
15422 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15423 break;
15424 case OPC_PRECEU_PH_QBR:
15425 check_dsp(ctx);
15426 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15427 break;
15428 case OPC_PRECEU_PH_QBLA:
15429 check_dsp(ctx);
15430 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15431 break;
15432 case OPC_PRECEU_PH_QBRA:
15433 check_dsp(ctx);
15434 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15435 break;
15436 }
15437 break;
15438 case OPC_ADDU_QB_DSP:
15439 switch (op2) {
15440 case OPC_ADDQ_PH:
15441 check_dsp(ctx);
15442 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15443 break;
15444 case OPC_ADDQ_S_PH:
15445 check_dsp(ctx);
15446 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15447 break;
15448 case OPC_ADDQ_S_W:
15449 check_dsp(ctx);
15450 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15451 break;
15452 case OPC_ADDU_QB:
15453 check_dsp(ctx);
15454 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15455 break;
15456 case OPC_ADDU_S_QB:
15457 check_dsp(ctx);
15458 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15459 break;
15460 case OPC_ADDU_PH:
15461 check_dspr2(ctx);
15462 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15463 break;
15464 case OPC_ADDU_S_PH:
15465 check_dspr2(ctx);
15466 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15467 break;
15468 case OPC_SUBQ_PH:
15469 check_dsp(ctx);
15470 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15471 break;
15472 case OPC_SUBQ_S_PH:
15473 check_dsp(ctx);
15474 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15475 break;
15476 case OPC_SUBQ_S_W:
15477 check_dsp(ctx);
15478 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15479 break;
15480 case OPC_SUBU_QB:
15481 check_dsp(ctx);
15482 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15483 break;
15484 case OPC_SUBU_S_QB:
15485 check_dsp(ctx);
15486 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15487 break;
15488 case OPC_SUBU_PH:
15489 check_dspr2(ctx);
15490 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15491 break;
15492 case OPC_SUBU_S_PH:
15493 check_dspr2(ctx);
15494 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15495 break;
15496 case OPC_ADDSC:
15497 check_dsp(ctx);
15498 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15499 break;
15500 case OPC_ADDWC:
15501 check_dsp(ctx);
15502 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15503 break;
15504 case OPC_MODSUB:
15505 check_dsp(ctx);
15506 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15507 break;
15508 case OPC_RADDU_W_QB:
15509 check_dsp(ctx);
15510 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15511 break;
15512 }
15513 break;
15514 case OPC_CMPU_EQ_QB_DSP:
15515 switch (op2) {
15516 case OPC_PRECR_QB_PH:
15517 check_dspr2(ctx);
15518 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15519 break;
15520 case OPC_PRECRQ_QB_PH:
15521 check_dsp(ctx);
15522 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15523 break;
15524 case OPC_PRECR_SRA_PH_W:
15525 check_dspr2(ctx);
15526 {
15527 TCGv_i32 sa_t = tcg_const_i32(v2);
15528 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15529 cpu_gpr[ret]);
15530 tcg_temp_free_i32(sa_t);
15531 break;
15532 }
15533 case OPC_PRECR_SRA_R_PH_W:
15534 check_dspr2(ctx);
15535 {
15536 TCGv_i32 sa_t = tcg_const_i32(v2);
15537 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15538 cpu_gpr[ret]);
15539 tcg_temp_free_i32(sa_t);
15540 break;
15541 }
15542 case OPC_PRECRQ_PH_W:
15543 check_dsp(ctx);
15544 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15545 break;
15546 case OPC_PRECRQ_RS_PH_W:
15547 check_dsp(ctx);
15548 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15549 break;
15550 case OPC_PRECRQU_S_QB_PH:
15551 check_dsp(ctx);
15552 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15553 break;
15554 }
15555 break;
15556 #ifdef TARGET_MIPS64
15557 case OPC_ABSQ_S_QH_DSP:
15558 switch (op2) {
15559 case OPC_PRECEQ_L_PWL:
15560 check_dsp(ctx);
15561 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15562 break;
15563 case OPC_PRECEQ_L_PWR:
15564 check_dsp(ctx);
15565 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15566 break;
15567 case OPC_PRECEQ_PW_QHL:
15568 check_dsp(ctx);
15569 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15570 break;
15571 case OPC_PRECEQ_PW_QHR:
15572 check_dsp(ctx);
15573 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15574 break;
15575 case OPC_PRECEQ_PW_QHLA:
15576 check_dsp(ctx);
15577 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15578 break;
15579 case OPC_PRECEQ_PW_QHRA:
15580 check_dsp(ctx);
15581 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15582 break;
15583 case OPC_PRECEQU_QH_OBL:
15584 check_dsp(ctx);
15585 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15586 break;
15587 case OPC_PRECEQU_QH_OBR:
15588 check_dsp(ctx);
15589 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15590 break;
15591 case OPC_PRECEQU_QH_OBLA:
15592 check_dsp(ctx);
15593 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15594 break;
15595 case OPC_PRECEQU_QH_OBRA:
15596 check_dsp(ctx);
15597 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15598 break;
15599 case OPC_PRECEU_QH_OBL:
15600 check_dsp(ctx);
15601 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15602 break;
15603 case OPC_PRECEU_QH_OBR:
15604 check_dsp(ctx);
15605 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15606 break;
15607 case OPC_PRECEU_QH_OBLA:
15608 check_dsp(ctx);
15609 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15610 break;
15611 case OPC_PRECEU_QH_OBRA:
15612 check_dsp(ctx);
15613 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15614 break;
15615 case OPC_ABSQ_S_OB:
15616 check_dspr2(ctx);
15617 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15618 break;
15619 case OPC_ABSQ_S_PW:
15620 check_dsp(ctx);
15621 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15622 break;
15623 case OPC_ABSQ_S_QH:
15624 check_dsp(ctx);
15625 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15626 break;
15627 }
15628 break;
15629 case OPC_ADDU_OB_DSP:
15630 switch (op2) {
15631 case OPC_RADDU_L_OB:
15632 check_dsp(ctx);
15633 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15634 break;
15635 case OPC_SUBQ_PW:
15636 check_dsp(ctx);
15637 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15638 break;
15639 case OPC_SUBQ_S_PW:
15640 check_dsp(ctx);
15641 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15642 break;
15643 case OPC_SUBQ_QH:
15644 check_dsp(ctx);
15645 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15646 break;
15647 case OPC_SUBQ_S_QH:
15648 check_dsp(ctx);
15649 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15650 break;
15651 case OPC_SUBU_OB:
15652 check_dsp(ctx);
15653 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15654 break;
15655 case OPC_SUBU_S_OB:
15656 check_dsp(ctx);
15657 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15658 break;
15659 case OPC_SUBU_QH:
15660 check_dspr2(ctx);
15661 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15662 break;
15663 case OPC_SUBU_S_QH:
15664 check_dspr2(ctx);
15665 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15666 break;
15667 case OPC_SUBUH_OB:
15668 check_dspr2(ctx);
15669 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15670 break;
15671 case OPC_SUBUH_R_OB:
15672 check_dspr2(ctx);
15673 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15674 break;
15675 case OPC_ADDQ_PW:
15676 check_dsp(ctx);
15677 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15678 break;
15679 case OPC_ADDQ_S_PW:
15680 check_dsp(ctx);
15681 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15682 break;
15683 case OPC_ADDQ_QH:
15684 check_dsp(ctx);
15685 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15686 break;
15687 case OPC_ADDQ_S_QH:
15688 check_dsp(ctx);
15689 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15690 break;
15691 case OPC_ADDU_OB:
15692 check_dsp(ctx);
15693 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15694 break;
15695 case OPC_ADDU_S_OB:
15696 check_dsp(ctx);
15697 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15698 break;
15699 case OPC_ADDU_QH:
15700 check_dspr2(ctx);
15701 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15702 break;
15703 case OPC_ADDU_S_QH:
15704 check_dspr2(ctx);
15705 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15706 break;
15707 case OPC_ADDUH_OB:
15708 check_dspr2(ctx);
15709 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15710 break;
15711 case OPC_ADDUH_R_OB:
15712 check_dspr2(ctx);
15713 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15714 break;
15715 }
15716 break;
15717 case OPC_CMPU_EQ_OB_DSP:
15718 switch (op2) {
15719 case OPC_PRECR_OB_QH:
15720 check_dspr2(ctx);
15721 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15722 break;
15723 case OPC_PRECR_SRA_QH_PW:
15724 check_dspr2(ctx);
15725 {
15726 TCGv_i32 ret_t = tcg_const_i32(ret);
15727 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15728 tcg_temp_free_i32(ret_t);
15729 break;
15730 }
15731 case OPC_PRECR_SRA_R_QH_PW:
15732 check_dspr2(ctx);
15733 {
15734 TCGv_i32 sa_v = tcg_const_i32(ret);
15735 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15736 tcg_temp_free_i32(sa_v);
15737 break;
15738 }
15739 case OPC_PRECRQ_OB_QH:
15740 check_dsp(ctx);
15741 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15742 break;
15743 case OPC_PRECRQ_PW_L:
15744 check_dsp(ctx);
15745 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15746 break;
15747 case OPC_PRECRQ_QH_PW:
15748 check_dsp(ctx);
15749 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15750 break;
15751 case OPC_PRECRQ_RS_QH_PW:
15752 check_dsp(ctx);
15753 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15754 break;
15755 case OPC_PRECRQU_S_OB_QH:
15756 check_dsp(ctx);
15757 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15758 break;
15759 }
15760 break;
15761 #endif
15762 }
15763
15764 tcg_temp_free(v1_t);
15765 tcg_temp_free(v2_t);
15766 }
15767
15768 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15769 int ret, int v1, int v2)
15770 {
15771 uint32_t op2;
15772 TCGv t0;
15773 TCGv v1_t;
15774 TCGv v2_t;
15775
15776 if (ret == 0) {
15777 /* Treat as NOP. */
15778 return;
15779 }
15780
15781 t0 = tcg_temp_new();
15782 v1_t = tcg_temp_new();
15783 v2_t = tcg_temp_new();
15784
15785 tcg_gen_movi_tl(t0, v1);
15786 gen_load_gpr(v1_t, v1);
15787 gen_load_gpr(v2_t, v2);
15788
15789 switch (opc) {
15790 case OPC_SHLL_QB_DSP:
15791 {
15792 op2 = MASK_SHLL_QB(ctx->opcode);
15793 switch (op2) {
15794 case OPC_SHLL_QB:
15795 check_dsp(ctx);
15796 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15797 break;
15798 case OPC_SHLLV_QB:
15799 check_dsp(ctx);
15800 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15801 break;
15802 case OPC_SHLL_PH:
15803 check_dsp(ctx);
15804 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15805 break;
15806 case OPC_SHLLV_PH:
15807 check_dsp(ctx);
15808 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15809 break;
15810 case OPC_SHLL_S_PH:
15811 check_dsp(ctx);
15812 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15813 break;
15814 case OPC_SHLLV_S_PH:
15815 check_dsp(ctx);
15816 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15817 break;
15818 case OPC_SHLL_S_W:
15819 check_dsp(ctx);
15820 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15821 break;
15822 case OPC_SHLLV_S_W:
15823 check_dsp(ctx);
15824 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15825 break;
15826 case OPC_SHRL_QB:
15827 check_dsp(ctx);
15828 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15829 break;
15830 case OPC_SHRLV_QB:
15831 check_dsp(ctx);
15832 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15833 break;
15834 case OPC_SHRL_PH:
15835 check_dspr2(ctx);
15836 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15837 break;
15838 case OPC_SHRLV_PH:
15839 check_dspr2(ctx);
15840 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15841 break;
15842 case OPC_SHRA_QB:
15843 check_dspr2(ctx);
15844 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15845 break;
15846 case OPC_SHRA_R_QB:
15847 check_dspr2(ctx);
15848 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15849 break;
15850 case OPC_SHRAV_QB:
15851 check_dspr2(ctx);
15852 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15853 break;
15854 case OPC_SHRAV_R_QB:
15855 check_dspr2(ctx);
15856 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15857 break;
15858 case OPC_SHRA_PH:
15859 check_dsp(ctx);
15860 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15861 break;
15862 case OPC_SHRA_R_PH:
15863 check_dsp(ctx);
15864 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15865 break;
15866 case OPC_SHRAV_PH:
15867 check_dsp(ctx);
15868 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15869 break;
15870 case OPC_SHRAV_R_PH:
15871 check_dsp(ctx);
15872 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15873 break;
15874 case OPC_SHRA_R_W:
15875 check_dsp(ctx);
15876 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15877 break;
15878 case OPC_SHRAV_R_W:
15879 check_dsp(ctx);
15880 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15881 break;
15882 default: /* Invalid */
15883 MIPS_INVAL("MASK SHLL.QB");
15884 generate_exception_end(ctx, EXCP_RI);
15885 break;
15886 }
15887 break;
15888 }
15889 #ifdef TARGET_MIPS64
15890 case OPC_SHLL_OB_DSP:
15891 op2 = MASK_SHLL_OB(ctx->opcode);
15892 switch (op2) {
15893 case OPC_SHLL_PW:
15894 check_dsp(ctx);
15895 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15896 break;
15897 case OPC_SHLLV_PW:
15898 check_dsp(ctx);
15899 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15900 break;
15901 case OPC_SHLL_S_PW:
15902 check_dsp(ctx);
15903 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15904 break;
15905 case OPC_SHLLV_S_PW:
15906 check_dsp(ctx);
15907 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15908 break;
15909 case OPC_SHLL_OB:
15910 check_dsp(ctx);
15911 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15912 break;
15913 case OPC_SHLLV_OB:
15914 check_dsp(ctx);
15915 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15916 break;
15917 case OPC_SHLL_QH:
15918 check_dsp(ctx);
15919 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15920 break;
15921 case OPC_SHLLV_QH:
15922 check_dsp(ctx);
15923 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15924 break;
15925 case OPC_SHLL_S_QH:
15926 check_dsp(ctx);
15927 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15928 break;
15929 case OPC_SHLLV_S_QH:
15930 check_dsp(ctx);
15931 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15932 break;
15933 case OPC_SHRA_OB:
15934 check_dspr2(ctx);
15935 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15936 break;
15937 case OPC_SHRAV_OB:
15938 check_dspr2(ctx);
15939 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15940 break;
15941 case OPC_SHRA_R_OB:
15942 check_dspr2(ctx);
15943 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15944 break;
15945 case OPC_SHRAV_R_OB:
15946 check_dspr2(ctx);
15947 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15948 break;
15949 case OPC_SHRA_PW:
15950 check_dsp(ctx);
15951 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15952 break;
15953 case OPC_SHRAV_PW:
15954 check_dsp(ctx);
15955 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15956 break;
15957 case OPC_SHRA_R_PW:
15958 check_dsp(ctx);
15959 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15960 break;
15961 case OPC_SHRAV_R_PW:
15962 check_dsp(ctx);
15963 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15964 break;
15965 case OPC_SHRA_QH:
15966 check_dsp(ctx);
15967 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15968 break;
15969 case OPC_SHRAV_QH:
15970 check_dsp(ctx);
15971 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15972 break;
15973 case OPC_SHRA_R_QH:
15974 check_dsp(ctx);
15975 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15976 break;
15977 case OPC_SHRAV_R_QH:
15978 check_dsp(ctx);
15979 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15980 break;
15981 case OPC_SHRL_OB:
15982 check_dsp(ctx);
15983 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15984 break;
15985 case OPC_SHRLV_OB:
15986 check_dsp(ctx);
15987 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15988 break;
15989 case OPC_SHRL_QH:
15990 check_dspr2(ctx);
15991 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15992 break;
15993 case OPC_SHRLV_QH:
15994 check_dspr2(ctx);
15995 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15996 break;
15997 default: /* Invalid */
15998 MIPS_INVAL("MASK SHLL.OB");
15999 generate_exception_end(ctx, EXCP_RI);
16000 break;
16001 }
16002 break;
16003 #endif
16004 }
16005
16006 tcg_temp_free(t0);
16007 tcg_temp_free(v1_t);
16008 tcg_temp_free(v2_t);
16009 }
16010
16011 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
16012 int ret, int v1, int v2, int check_ret)
16013 {
16014 TCGv_i32 t0;
16015 TCGv v1_t;
16016 TCGv v2_t;
16017
16018 if ((ret == 0) && (check_ret == 1)) {
16019 /* Treat as NOP. */
16020 return;
16021 }
16022
16023 t0 = tcg_temp_new_i32();
16024 v1_t = tcg_temp_new();
16025 v2_t = tcg_temp_new();
16026
16027 tcg_gen_movi_i32(t0, ret);
16028 gen_load_gpr(v1_t, v1);
16029 gen_load_gpr(v2_t, v2);
16030
16031 switch (op1) {
16032 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16033 * the same mask and op1. */
16034 case OPC_MULT_G_2E:
16035 check_dspr2(ctx);
16036 switch (op2) {
16037 case OPC_MUL_PH:
16038 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16039 break;
16040 case OPC_MUL_S_PH:
16041 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16042 break;
16043 case OPC_MULQ_S_W:
16044 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16045 break;
16046 case OPC_MULQ_RS_W:
16047 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16048 break;
16049 }
16050 break;
16051 case OPC_DPA_W_PH_DSP:
16052 switch (op2) {
16053 case OPC_DPAU_H_QBL:
16054 check_dsp(ctx);
16055 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
16056 break;
16057 case OPC_DPAU_H_QBR:
16058 check_dsp(ctx);
16059 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
16060 break;
16061 case OPC_DPSU_H_QBL:
16062 check_dsp(ctx);
16063 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
16064 break;
16065 case OPC_DPSU_H_QBR:
16066 check_dsp(ctx);
16067 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
16068 break;
16069 case OPC_DPA_W_PH:
16070 check_dspr2(ctx);
16071 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
16072 break;
16073 case OPC_DPAX_W_PH:
16074 check_dspr2(ctx);
16075 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
16076 break;
16077 case OPC_DPAQ_S_W_PH:
16078 check_dsp(ctx);
16079 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16080 break;
16081 case OPC_DPAQX_S_W_PH:
16082 check_dspr2(ctx);
16083 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16084 break;
16085 case OPC_DPAQX_SA_W_PH:
16086 check_dspr2(ctx);
16087 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16088 break;
16089 case OPC_DPS_W_PH:
16090 check_dspr2(ctx);
16091 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
16092 break;
16093 case OPC_DPSX_W_PH:
16094 check_dspr2(ctx);
16095 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
16096 break;
16097 case OPC_DPSQ_S_W_PH:
16098 check_dsp(ctx);
16099 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16100 break;
16101 case OPC_DPSQX_S_W_PH:
16102 check_dspr2(ctx);
16103 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
16104 break;
16105 case OPC_DPSQX_SA_W_PH:
16106 check_dspr2(ctx);
16107 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
16108 break;
16109 case OPC_MULSAQ_S_W_PH:
16110 check_dsp(ctx);
16111 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
16112 break;
16113 case OPC_DPAQ_SA_L_W:
16114 check_dsp(ctx);
16115 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16116 break;
16117 case OPC_DPSQ_SA_L_W:
16118 check_dsp(ctx);
16119 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
16120 break;
16121 case OPC_MAQ_S_W_PHL:
16122 check_dsp(ctx);
16123 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
16124 break;
16125 case OPC_MAQ_S_W_PHR:
16126 check_dsp(ctx);
16127 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
16128 break;
16129 case OPC_MAQ_SA_W_PHL:
16130 check_dsp(ctx);
16131 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
16132 break;
16133 case OPC_MAQ_SA_W_PHR:
16134 check_dsp(ctx);
16135 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
16136 break;
16137 case OPC_MULSA_W_PH:
16138 check_dspr2(ctx);
16139 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
16140 break;
16141 }
16142 break;
16143 #ifdef TARGET_MIPS64
16144 case OPC_DPAQ_W_QH_DSP:
16145 {
16146 int ac = ret & 0x03;
16147 tcg_gen_movi_i32(t0, ac);
16148
16149 switch (op2) {
16150 case OPC_DMADD:
16151 check_dsp(ctx);
16152 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
16153 break;
16154 case OPC_DMADDU:
16155 check_dsp(ctx);
16156 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
16157 break;
16158 case OPC_DMSUB:
16159 check_dsp(ctx);
16160 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
16161 break;
16162 case OPC_DMSUBU:
16163 check_dsp(ctx);
16164 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
16165 break;
16166 case OPC_DPA_W_QH:
16167 check_dspr2(ctx);
16168 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
16169 break;
16170 case OPC_DPAQ_S_W_QH:
16171 check_dsp(ctx);
16172 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16173 break;
16174 case OPC_DPAQ_SA_L_PW:
16175 check_dsp(ctx);
16176 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16177 break;
16178 case OPC_DPAU_H_OBL:
16179 check_dsp(ctx);
16180 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
16181 break;
16182 case OPC_DPAU_H_OBR:
16183 check_dsp(ctx);
16184 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
16185 break;
16186 case OPC_DPS_W_QH:
16187 check_dspr2(ctx);
16188 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
16189 break;
16190 case OPC_DPSQ_S_W_QH:
16191 check_dsp(ctx);
16192 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16193 break;
16194 case OPC_DPSQ_SA_L_PW:
16195 check_dsp(ctx);
16196 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
16197 break;
16198 case OPC_DPSU_H_OBL:
16199 check_dsp(ctx);
16200 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
16201 break;
16202 case OPC_DPSU_H_OBR:
16203 check_dsp(ctx);
16204 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
16205 break;
16206 case OPC_MAQ_S_L_PWL:
16207 check_dsp(ctx);
16208 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
16209 break;
16210 case OPC_MAQ_S_L_PWR:
16211 check_dsp(ctx);
16212 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
16213 break;
16214 case OPC_MAQ_S_W_QHLL:
16215 check_dsp(ctx);
16216 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
16217 break;
16218 case OPC_MAQ_SA_W_QHLL:
16219 check_dsp(ctx);
16220 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
16221 break;
16222 case OPC_MAQ_S_W_QHLR:
16223 check_dsp(ctx);
16224 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
16225 break;
16226 case OPC_MAQ_SA_W_QHLR:
16227 check_dsp(ctx);
16228 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
16229 break;
16230 case OPC_MAQ_S_W_QHRL:
16231 check_dsp(ctx);
16232 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16233 break;
16234 case OPC_MAQ_SA_W_QHRL:
16235 check_dsp(ctx);
16236 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16237 break;
16238 case OPC_MAQ_S_W_QHRR:
16239 check_dsp(ctx);
16240 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16241 break;
16242 case OPC_MAQ_SA_W_QHRR:
16243 check_dsp(ctx);
16244 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16245 break;
16246 case OPC_MULSAQ_S_L_PW:
16247 check_dsp(ctx);
16248 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16249 break;
16250 case OPC_MULSAQ_S_W_QH:
16251 check_dsp(ctx);
16252 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16253 break;
16254 }
16255 }
16256 break;
16257 #endif
16258 case OPC_ADDU_QB_DSP:
16259 switch (op2) {
16260 case OPC_MULEU_S_PH_QBL:
16261 check_dsp(ctx);
16262 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16263 break;
16264 case OPC_MULEU_S_PH_QBR:
16265 check_dsp(ctx);
16266 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16267 break;
16268 case OPC_MULQ_RS_PH:
16269 check_dsp(ctx);
16270 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16271 break;
16272 case OPC_MULEQ_S_W_PHL:
16273 check_dsp(ctx);
16274 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16275 break;
16276 case OPC_MULEQ_S_W_PHR:
16277 check_dsp(ctx);
16278 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16279 break;
16280 case OPC_MULQ_S_PH:
16281 check_dspr2(ctx);
16282 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16283 break;
16284 }
16285 break;
16286 #ifdef TARGET_MIPS64
16287 case OPC_ADDU_OB_DSP:
16288 switch (op2) {
16289 case OPC_MULEQ_S_PW_QHL:
16290 check_dsp(ctx);
16291 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16292 break;
16293 case OPC_MULEQ_S_PW_QHR:
16294 check_dsp(ctx);
16295 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16296 break;
16297 case OPC_MULEU_S_QH_OBL:
16298 check_dsp(ctx);
16299 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16300 break;
16301 case OPC_MULEU_S_QH_OBR:
16302 check_dsp(ctx);
16303 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16304 break;
16305 case OPC_MULQ_RS_QH:
16306 check_dsp(ctx);
16307 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16308 break;
16309 }
16310 break;
16311 #endif
16312 }
16313
16314 tcg_temp_free_i32(t0);
16315 tcg_temp_free(v1_t);
16316 tcg_temp_free(v2_t);
16317 }
16318
16319 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16320 int ret, int val)
16321 {
16322 int16_t imm;
16323 TCGv t0;
16324 TCGv val_t;
16325
16326 if (ret == 0) {
16327 /* Treat as NOP. */
16328 return;
16329 }
16330
16331 t0 = tcg_temp_new();
16332 val_t = tcg_temp_new();
16333 gen_load_gpr(val_t, val);
16334
16335 switch (op1) {
16336 case OPC_ABSQ_S_PH_DSP:
16337 switch (op2) {
16338 case OPC_BITREV:
16339 check_dsp(ctx);
16340 gen_helper_bitrev(cpu_gpr[ret], val_t);
16341 break;
16342 case OPC_REPL_QB:
16343 check_dsp(ctx);
16344 {
16345 target_long result;
16346 imm = (ctx->opcode >> 16) & 0xFF;
16347 result = (uint32_t)imm << 24 |
16348 (uint32_t)imm << 16 |
16349 (uint32_t)imm << 8 |
16350 (uint32_t)imm;
16351 result = (int32_t)result;
16352 tcg_gen_movi_tl(cpu_gpr[ret], result);
16353 }
16354 break;
16355 case OPC_REPLV_QB:
16356 check_dsp(ctx);
16357 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16358 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16359 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16360 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16361 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16362 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16363 break;
16364 case OPC_REPL_PH:
16365 check_dsp(ctx);
16366 {
16367 imm = (ctx->opcode >> 16) & 0x03FF;
16368 imm = (int16_t)(imm << 6) >> 6;
16369 tcg_gen_movi_tl(cpu_gpr[ret], \
16370 (target_long)((int32_t)imm << 16 | \
16371 (uint16_t)imm));
16372 }
16373 break;
16374 case OPC_REPLV_PH:
16375 check_dsp(ctx);
16376 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16377 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16378 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16379 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16380 break;
16381 }
16382 break;
16383 #ifdef TARGET_MIPS64
16384 case OPC_ABSQ_S_QH_DSP:
16385 switch (op2) {
16386 case OPC_REPL_OB:
16387 check_dsp(ctx);
16388 {
16389 target_long temp;
16390
16391 imm = (ctx->opcode >> 16) & 0xFF;
16392 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16393 temp = (temp << 16) | temp;
16394 temp = (temp << 32) | temp;
16395 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16396 break;
16397 }
16398 case OPC_REPL_PW:
16399 check_dsp(ctx);
16400 {
16401 target_long temp;
16402
16403 imm = (ctx->opcode >> 16) & 0x03FF;
16404 imm = (int16_t)(imm << 6) >> 6;
16405 temp = ((target_long)imm << 32) \
16406 | ((target_long)imm & 0xFFFFFFFF);
16407 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16408 break;
16409 }
16410 case OPC_REPL_QH:
16411 check_dsp(ctx);
16412 {
16413 target_long temp;
16414
16415 imm = (ctx->opcode >> 16) & 0x03FF;
16416 imm = (int16_t)(imm << 6) >> 6;
16417
16418 temp = ((uint64_t)(uint16_t)imm << 48) |
16419 ((uint64_t)(uint16_t)imm << 32) |
16420 ((uint64_t)(uint16_t)imm << 16) |
16421 (uint64_t)(uint16_t)imm;
16422 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16423 break;
16424 }
16425 case OPC_REPLV_OB:
16426 check_dsp(ctx);
16427 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16428 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16429 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16430 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16431 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16432 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16433 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16434 break;
16435 case OPC_REPLV_PW:
16436 check_dsp(ctx);
16437 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16438 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16439 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16440 break;
16441 case OPC_REPLV_QH:
16442 check_dsp(ctx);
16443 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16444 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16445 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16446 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16447 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16448 break;
16449 }
16450 break;
16451 #endif
16452 }
16453 tcg_temp_free(t0);
16454 tcg_temp_free(val_t);
16455 }
16456
16457 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16458 uint32_t op1, uint32_t op2,
16459 int ret, int v1, int v2, int check_ret)
16460 {
16461 TCGv t1;
16462 TCGv v1_t;
16463 TCGv v2_t;
16464
16465 if ((ret == 0) && (check_ret == 1)) {
16466 /* Treat as NOP. */
16467 return;
16468 }
16469
16470 t1 = tcg_temp_new();
16471 v1_t = tcg_temp_new();
16472 v2_t = tcg_temp_new();
16473
16474 gen_load_gpr(v1_t, v1);
16475 gen_load_gpr(v2_t, v2);
16476
16477 switch (op1) {
16478 case OPC_CMPU_EQ_QB_DSP:
16479 switch (op2) {
16480 case OPC_CMPU_EQ_QB:
16481 check_dsp(ctx);
16482 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16483 break;
16484 case OPC_CMPU_LT_QB:
16485 check_dsp(ctx);
16486 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16487 break;
16488 case OPC_CMPU_LE_QB:
16489 check_dsp(ctx);
16490 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16491 break;
16492 case OPC_CMPGU_EQ_QB:
16493 check_dsp(ctx);
16494 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16495 break;
16496 case OPC_CMPGU_LT_QB:
16497 check_dsp(ctx);
16498 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16499 break;
16500 case OPC_CMPGU_LE_QB:
16501 check_dsp(ctx);
16502 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16503 break;
16504 case OPC_CMPGDU_EQ_QB:
16505 check_dspr2(ctx);
16506 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16507 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16508 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16509 tcg_gen_shli_tl(t1, t1, 24);
16510 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16511 break;
16512 case OPC_CMPGDU_LT_QB:
16513 check_dspr2(ctx);
16514 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16515 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16516 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16517 tcg_gen_shli_tl(t1, t1, 24);
16518 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16519 break;
16520 case OPC_CMPGDU_LE_QB:
16521 check_dspr2(ctx);
16522 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16523 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16524 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16525 tcg_gen_shli_tl(t1, t1, 24);
16526 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16527 break;
16528 case OPC_CMP_EQ_PH:
16529 check_dsp(ctx);
16530 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16531 break;
16532 case OPC_CMP_LT_PH:
16533 check_dsp(ctx);
16534 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16535 break;
16536 case OPC_CMP_LE_PH:
16537 check_dsp(ctx);
16538 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16539 break;
16540 case OPC_PICK_QB:
16541 check_dsp(ctx);
16542 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16543 break;
16544 case OPC_PICK_PH:
16545 check_dsp(ctx);
16546 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16547 break;
16548 case OPC_PACKRL_PH:
16549 check_dsp(ctx);
16550 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16551 break;
16552 }
16553 break;
16554 #ifdef TARGET_MIPS64
16555 case OPC_CMPU_EQ_OB_DSP:
16556 switch (op2) {
16557 case OPC_CMP_EQ_PW:
16558 check_dsp(ctx);
16559 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16560 break;
16561 case OPC_CMP_LT_PW:
16562 check_dsp(ctx);
16563 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16564 break;
16565 case OPC_CMP_LE_PW:
16566 check_dsp(ctx);
16567 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16568 break;
16569 case OPC_CMP_EQ_QH:
16570 check_dsp(ctx);
16571 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16572 break;
16573 case OPC_CMP_LT_QH:
16574 check_dsp(ctx);
16575 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16576 break;
16577 case OPC_CMP_LE_QH:
16578 check_dsp(ctx);
16579 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16580 break;
16581 case OPC_CMPGDU_EQ_OB:
16582 check_dspr2(ctx);
16583 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16584 break;
16585 case OPC_CMPGDU_LT_OB:
16586 check_dspr2(ctx);
16587 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16588 break;
16589 case OPC_CMPGDU_LE_OB:
16590 check_dspr2(ctx);
16591 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16592 break;
16593 case OPC_CMPGU_EQ_OB:
16594 check_dsp(ctx);
16595 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16596 break;
16597 case OPC_CMPGU_LT_OB:
16598 check_dsp(ctx);
16599 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16600 break;
16601 case OPC_CMPGU_LE_OB:
16602 check_dsp(ctx);
16603 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16604 break;
16605 case OPC_CMPU_EQ_OB:
16606 check_dsp(ctx);
16607 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16608 break;
16609 case OPC_CMPU_LT_OB:
16610 check_dsp(ctx);
16611 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16612 break;
16613 case OPC_CMPU_LE_OB:
16614 check_dsp(ctx);
16615 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16616 break;
16617 case OPC_PACKRL_PW:
16618 check_dsp(ctx);
16619 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16620 break;
16621 case OPC_PICK_OB:
16622 check_dsp(ctx);
16623 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16624 break;
16625 case OPC_PICK_PW:
16626 check_dsp(ctx);
16627 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16628 break;
16629 case OPC_PICK_QH:
16630 check_dsp(ctx);
16631 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16632 break;
16633 }
16634 break;
16635 #endif
16636 }
16637
16638 tcg_temp_free(t1);
16639 tcg_temp_free(v1_t);
16640 tcg_temp_free(v2_t);
16641 }
16642
16643 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16644 uint32_t op1, int rt, int rs, int sa)
16645 {
16646 TCGv t0;
16647
16648 check_dspr2(ctx);
16649
16650 if (rt == 0) {
16651 /* Treat as NOP. */
16652 return;
16653 }
16654
16655 t0 = tcg_temp_new();
16656 gen_load_gpr(t0, rs);
16657
16658 switch (op1) {
16659 case OPC_APPEND_DSP:
16660 switch (MASK_APPEND(ctx->opcode)) {
16661 case OPC_APPEND:
16662 if (sa != 0) {
16663 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16664 }
16665 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16666 break;
16667 case OPC_PREPEND:
16668 if (sa != 0) {
16669 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16670 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16671 tcg_gen_shli_tl(t0, t0, 32 - sa);
16672 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16673 }
16674 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16675 break;
16676 case OPC_BALIGN:
16677 sa &= 3;
16678 if (sa != 0 && sa != 2) {
16679 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16680 tcg_gen_ext32u_tl(t0, t0);
16681 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16682 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16683 }
16684 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16685 break;
16686 default: /* Invalid */
16687 MIPS_INVAL("MASK APPEND");
16688 generate_exception_end(ctx, EXCP_RI);
16689 break;
16690 }
16691 break;
16692 #ifdef TARGET_MIPS64
16693 case OPC_DAPPEND_DSP:
16694 switch (MASK_DAPPEND(ctx->opcode)) {
16695 case OPC_DAPPEND:
16696 if (sa != 0) {
16697 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16698 }
16699 break;
16700 case OPC_PREPENDD:
16701 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16702 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16703 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16704 break;
16705 case OPC_PREPENDW:
16706 if (sa != 0) {
16707 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16708 tcg_gen_shli_tl(t0, t0, 64 - sa);
16709 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16710 }
16711 break;
16712 case OPC_DBALIGN:
16713 sa &= 7;
16714 if (sa != 0 && sa != 2 && sa != 4) {
16715 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16716 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16717 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16718 }
16719 break;
16720 default: /* Invalid */
16721 MIPS_INVAL("MASK DAPPEND");
16722 generate_exception_end(ctx, EXCP_RI);
16723 break;
16724 }
16725 break;
16726 #endif
16727 }
16728 tcg_temp_free(t0);
16729 }
16730
16731 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16732 int ret, int v1, int v2, int check_ret)
16733
16734 {
16735 TCGv t0;
16736 TCGv t1;
16737 TCGv v1_t;
16738 TCGv v2_t;
16739 int16_t imm;
16740
16741 if ((ret == 0) && (check_ret == 1)) {
16742 /* Treat as NOP. */
16743 return;
16744 }
16745
16746 t0 = tcg_temp_new();
16747 t1 = tcg_temp_new();
16748 v1_t = tcg_temp_new();
16749 v2_t = tcg_temp_new();
16750
16751 gen_load_gpr(v1_t, v1);
16752 gen_load_gpr(v2_t, v2);
16753
16754 switch (op1) {
16755 case OPC_EXTR_W_DSP:
16756 check_dsp(ctx);
16757 switch (op2) {
16758 case OPC_EXTR_W:
16759 tcg_gen_movi_tl(t0, v2);
16760 tcg_gen_movi_tl(t1, v1);
16761 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16762 break;
16763 case OPC_EXTR_R_W:
16764 tcg_gen_movi_tl(t0, v2);
16765 tcg_gen_movi_tl(t1, v1);
16766 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16767 break;
16768 case OPC_EXTR_RS_W:
16769 tcg_gen_movi_tl(t0, v2);
16770 tcg_gen_movi_tl(t1, v1);
16771 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16772 break;
16773 case OPC_EXTR_S_H:
16774 tcg_gen_movi_tl(t0, v2);
16775 tcg_gen_movi_tl(t1, v1);
16776 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16777 break;
16778 case OPC_EXTRV_S_H:
16779 tcg_gen_movi_tl(t0, v2);
16780 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16781 break;
16782 case OPC_EXTRV_W:
16783 tcg_gen_movi_tl(t0, v2);
16784 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16785 break;
16786 case OPC_EXTRV_R_W:
16787 tcg_gen_movi_tl(t0, v2);
16788 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16789 break;
16790 case OPC_EXTRV_RS_W:
16791 tcg_gen_movi_tl(t0, v2);
16792 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16793 break;
16794 case OPC_EXTP:
16795 tcg_gen_movi_tl(t0, v2);
16796 tcg_gen_movi_tl(t1, v1);
16797 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16798 break;
16799 case OPC_EXTPV:
16800 tcg_gen_movi_tl(t0, v2);
16801 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16802 break;
16803 case OPC_EXTPDP:
16804 tcg_gen_movi_tl(t0, v2);
16805 tcg_gen_movi_tl(t1, v1);
16806 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16807 break;
16808 case OPC_EXTPDPV:
16809 tcg_gen_movi_tl(t0, v2);
16810 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16811 break;
16812 case OPC_SHILO:
16813 imm = (ctx->opcode >> 20) & 0x3F;
16814 tcg_gen_movi_tl(t0, ret);
16815 tcg_gen_movi_tl(t1, imm);
16816 gen_helper_shilo(t0, t1, cpu_env);
16817 break;
16818 case OPC_SHILOV:
16819 tcg_gen_movi_tl(t0, ret);
16820 gen_helper_shilo(t0, v1_t, cpu_env);
16821 break;
16822 case OPC_MTHLIP:
16823 tcg_gen_movi_tl(t0, ret);
16824 gen_helper_mthlip(t0, v1_t, cpu_env);
16825 break;
16826 case OPC_WRDSP:
16827 imm = (ctx->opcode >> 11) & 0x3FF;
16828 tcg_gen_movi_tl(t0, imm);
16829 gen_helper_wrdsp(v1_t, t0, cpu_env);
16830 break;
16831 case OPC_RDDSP:
16832 imm = (ctx->opcode >> 16) & 0x03FF;
16833 tcg_gen_movi_tl(t0, imm);
16834 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16835 break;
16836 }
16837 break;
16838 #ifdef TARGET_MIPS64
16839 case OPC_DEXTR_W_DSP:
16840 check_dsp(ctx);
16841 switch (op2) {
16842 case OPC_DMTHLIP:
16843 tcg_gen_movi_tl(t0, ret);
16844 gen_helper_dmthlip(v1_t, t0, cpu_env);
16845 break;
16846 case OPC_DSHILO:
16847 {
16848 int shift = (ctx->opcode >> 19) & 0x7F;
16849 int ac = (ctx->opcode >> 11) & 0x03;
16850 tcg_gen_movi_tl(t0, shift);
16851 tcg_gen_movi_tl(t1, ac);
16852 gen_helper_dshilo(t0, t1, cpu_env);
16853 break;
16854 }
16855 case OPC_DSHILOV:
16856 {
16857 int ac = (ctx->opcode >> 11) & 0x03;
16858 tcg_gen_movi_tl(t0, ac);
16859 gen_helper_dshilo(v1_t, t0, cpu_env);
16860 break;
16861 }
16862 case OPC_DEXTP:
16863 tcg_gen_movi_tl(t0, v2);
16864 tcg_gen_movi_tl(t1, v1);
16865
16866 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16867 break;
16868 case OPC_DEXTPV:
16869 tcg_gen_movi_tl(t0, v2);
16870 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16871 break;
16872 case OPC_DEXTPDP:
16873 tcg_gen_movi_tl(t0, v2);
16874 tcg_gen_movi_tl(t1, v1);
16875 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16876 break;
16877 case OPC_DEXTPDPV:
16878 tcg_gen_movi_tl(t0, v2);
16879 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16880 break;
16881 case OPC_DEXTR_L:
16882 tcg_gen_movi_tl(t0, v2);
16883 tcg_gen_movi_tl(t1, v1);
16884 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16885 break;
16886 case OPC_DEXTR_R_L:
16887 tcg_gen_movi_tl(t0, v2);
16888 tcg_gen_movi_tl(t1, v1);
16889 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16890 break;
16891 case OPC_DEXTR_RS_L:
16892 tcg_gen_movi_tl(t0, v2);
16893 tcg_gen_movi_tl(t1, v1);
16894 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16895 break;
16896 case OPC_DEXTR_W:
16897 tcg_gen_movi_tl(t0, v2);
16898 tcg_gen_movi_tl(t1, v1);
16899 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16900 break;
16901 case OPC_DEXTR_R_W:
16902 tcg_gen_movi_tl(t0, v2);
16903 tcg_gen_movi_tl(t1, v1);
16904 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16905 break;
16906 case OPC_DEXTR_RS_W:
16907 tcg_gen_movi_tl(t0, v2);
16908 tcg_gen_movi_tl(t1, v1);
16909 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16910 break;
16911 case OPC_DEXTR_S_H:
16912 tcg_gen_movi_tl(t0, v2);
16913 tcg_gen_movi_tl(t1, v1);
16914 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16915 break;
16916 case OPC_DEXTRV_S_H:
16917 tcg_gen_movi_tl(t0, v2);
16918 tcg_gen_movi_tl(t1, v1);
16919 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16920 break;
16921 case OPC_DEXTRV_L:
16922 tcg_gen_movi_tl(t0, v2);
16923 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16924 break;
16925 case OPC_DEXTRV_R_L:
16926 tcg_gen_movi_tl(t0, v2);
16927 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16928 break;
16929 case OPC_DEXTRV_RS_L:
16930 tcg_gen_movi_tl(t0, v2);
16931 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16932 break;
16933 case OPC_DEXTRV_W:
16934 tcg_gen_movi_tl(t0, v2);
16935 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16936 break;
16937 case OPC_DEXTRV_R_W:
16938 tcg_gen_movi_tl(t0, v2);
16939 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16940 break;
16941 case OPC_DEXTRV_RS_W:
16942 tcg_gen_movi_tl(t0, v2);
16943 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16944 break;
16945 }
16946 break;
16947 #endif
16948 }
16949
16950 tcg_temp_free(t0);
16951 tcg_temp_free(t1);
16952 tcg_temp_free(v1_t);
16953 tcg_temp_free(v2_t);
16954 }
16955
16956 /* End MIPSDSP functions. */
16957
16958 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16959 {
16960 int rs, rt, rd, sa;
16961 uint32_t op1, op2;
16962
16963 rs = (ctx->opcode >> 21) & 0x1f;
16964 rt = (ctx->opcode >> 16) & 0x1f;
16965 rd = (ctx->opcode >> 11) & 0x1f;
16966 sa = (ctx->opcode >> 6) & 0x1f;
16967
16968 op1 = MASK_SPECIAL(ctx->opcode);
16969 switch (op1) {
16970 case OPC_LSA:
16971 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16972 break;
16973 case OPC_MULT ... OPC_DIVU:
16974 op2 = MASK_R6_MULDIV(ctx->opcode);
16975 switch (op2) {
16976 case R6_OPC_MUL:
16977 case R6_OPC_MUH:
16978 case R6_OPC_MULU:
16979 case R6_OPC_MUHU:
16980 case R6_OPC_DIV:
16981 case R6_OPC_MOD:
16982 case R6_OPC_DIVU:
16983 case R6_OPC_MODU:
16984 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16985 break;
16986 default:
16987 MIPS_INVAL("special_r6 muldiv");
16988 generate_exception_end(ctx, EXCP_RI);
16989 break;
16990 }
16991 break;
16992 case OPC_SELEQZ:
16993 case OPC_SELNEZ:
16994 gen_cond_move(ctx, op1, rd, rs, rt);
16995 break;
16996 case R6_OPC_CLO:
16997 case R6_OPC_CLZ:
16998 if (rt == 0 && sa == 1) {
16999 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17000 We need additionally to check other fields */
17001 gen_cl(ctx, op1, rd, rs);
17002 } else {
17003 generate_exception_end(ctx, EXCP_RI);
17004 }
17005 break;
17006 case R6_OPC_SDBBP:
17007 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17008 gen_helper_do_semihosting(cpu_env);
17009 } else {
17010 if (ctx->hflags & MIPS_HFLAG_SBRI) {
17011 generate_exception_end(ctx, EXCP_RI);
17012 } else {
17013 generate_exception_end(ctx, EXCP_DBp);
17014 }
17015 }
17016 break;
17017 #if defined(TARGET_MIPS64)
17018 case OPC_DLSA:
17019 check_mips_64(ctx);
17020 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
17021 break;
17022 case R6_OPC_DCLO:
17023 case R6_OPC_DCLZ:
17024 if (rt == 0 && sa == 1) {
17025 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17026 We need additionally to check other fields */
17027 check_mips_64(ctx);
17028 gen_cl(ctx, op1, rd, rs);
17029 } else {
17030 generate_exception_end(ctx, EXCP_RI);
17031 }
17032 break;
17033 case OPC_DMULT ... OPC_DDIVU:
17034 op2 = MASK_R6_MULDIV(ctx->opcode);
17035 switch (op2) {
17036 case R6_OPC_DMUL:
17037 case R6_OPC_DMUH:
17038 case R6_OPC_DMULU:
17039 case R6_OPC_DMUHU:
17040 case R6_OPC_DDIV:
17041 case R6_OPC_DMOD:
17042 case R6_OPC_DDIVU:
17043 case R6_OPC_DMODU:
17044 check_mips_64(ctx);
17045 gen_r6_muldiv(ctx, op2, rd, rs, rt);
17046 break;
17047 default:
17048 MIPS_INVAL("special_r6 muldiv");
17049 generate_exception_end(ctx, EXCP_RI);
17050 break;
17051 }
17052 break;
17053 #endif
17054 default: /* Invalid */
17055 MIPS_INVAL("special_r6");
17056 generate_exception_end(ctx, EXCP_RI);
17057 break;
17058 }
17059 }
17060
17061 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
17062 {
17063 int rs, rt, rd, sa;
17064 uint32_t op1;
17065
17066 rs = (ctx->opcode >> 21) & 0x1f;
17067 rt = (ctx->opcode >> 16) & 0x1f;
17068 rd = (ctx->opcode >> 11) & 0x1f;
17069 sa = (ctx->opcode >> 6) & 0x1f;
17070
17071 op1 = MASK_SPECIAL(ctx->opcode);
17072 switch (op1) {
17073 case OPC_MOVN: /* Conditional move */
17074 case OPC_MOVZ:
17075 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
17076 INSN_LOONGSON2E | INSN_LOONGSON2F);
17077 gen_cond_move(ctx, op1, rd, rs, rt);
17078 break;
17079 case OPC_MFHI: /* Move from HI/LO */
17080 case OPC_MFLO:
17081 gen_HILO(ctx, op1, rs & 3, rd);
17082 break;
17083 case OPC_MTHI:
17084 case OPC_MTLO: /* Move to HI/LO */
17085 gen_HILO(ctx, op1, rd & 3, rs);
17086 break;
17087 case OPC_MOVCI:
17088 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17089 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17090 check_cp1_enabled(ctx);
17091 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
17092 (ctx->opcode >> 16) & 1);
17093 } else {
17094 generate_exception_err(ctx, EXCP_CpU, 1);
17095 }
17096 break;
17097 case OPC_MULT:
17098 case OPC_MULTU:
17099 if (sa) {
17100 check_insn(ctx, INSN_VR54XX);
17101 op1 = MASK_MUL_VR54XX(ctx->opcode);
17102 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
17103 } else {
17104 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17105 }
17106 break;
17107 case OPC_DIV:
17108 case OPC_DIVU:
17109 gen_muldiv(ctx, op1, 0, rs, rt);
17110 break;
17111 #if defined(TARGET_MIPS64)
17112 case OPC_DMULT ... OPC_DDIVU:
17113 check_insn(ctx, ISA_MIPS3);
17114 check_mips_64(ctx);
17115 gen_muldiv(ctx, op1, 0, rs, rt);
17116 break;
17117 #endif
17118 case OPC_JR:
17119 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17120 break;
17121 case OPC_SPIM:
17122 #ifdef MIPS_STRICT_STANDARD
17123 MIPS_INVAL("SPIM");
17124 generate_exception_end(ctx, EXCP_RI);
17125 #else
17126 /* Implemented as RI exception for now. */
17127 MIPS_INVAL("spim (unofficial)");
17128 generate_exception_end(ctx, EXCP_RI);
17129 #endif
17130 break;
17131 default: /* Invalid */
17132 MIPS_INVAL("special_legacy");
17133 generate_exception_end(ctx, EXCP_RI);
17134 break;
17135 }
17136 }
17137
17138 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
17139 {
17140 int rs, rt, rd, sa;
17141 uint32_t op1;
17142
17143 rs = (ctx->opcode >> 21) & 0x1f;
17144 rt = (ctx->opcode >> 16) & 0x1f;
17145 rd = (ctx->opcode >> 11) & 0x1f;
17146 sa = (ctx->opcode >> 6) & 0x1f;
17147
17148 op1 = MASK_SPECIAL(ctx->opcode);
17149 switch (op1) {
17150 case OPC_SLL: /* Shift with immediate */
17151 if (sa == 5 && rd == 0 &&
17152 rs == 0 && rt == 0) { /* PAUSE */
17153 if ((ctx->insn_flags & ISA_MIPS32R6) &&
17154 (ctx->hflags & MIPS_HFLAG_BMASK)) {
17155 generate_exception_end(ctx, EXCP_RI);
17156 break;
17157 }
17158 }
17159 /* Fallthrough */
17160 case OPC_SRA:
17161 gen_shift_imm(ctx, op1, rd, rt, sa);
17162 break;
17163 case OPC_SRL:
17164 switch ((ctx->opcode >> 21) & 0x1f) {
17165 case 1:
17166 /* rotr is decoded as srl on non-R2 CPUs */
17167 if (ctx->insn_flags & ISA_MIPS32R2) {
17168 op1 = OPC_ROTR;
17169 }
17170 /* Fallthrough */
17171 case 0:
17172 gen_shift_imm(ctx, op1, rd, rt, sa);
17173 break;
17174 default:
17175 generate_exception_end(ctx, EXCP_RI);
17176 break;
17177 }
17178 break;
17179 case OPC_ADD ... OPC_SUBU:
17180 gen_arith(ctx, op1, rd, rs, rt);
17181 break;
17182 case OPC_SLLV: /* Shifts */
17183 case OPC_SRAV:
17184 gen_shift(ctx, op1, rd, rs, rt);
17185 break;
17186 case OPC_SRLV:
17187 switch ((ctx->opcode >> 6) & 0x1f) {
17188 case 1:
17189 /* rotrv is decoded as srlv on non-R2 CPUs */
17190 if (ctx->insn_flags & ISA_MIPS32R2) {
17191 op1 = OPC_ROTRV;
17192 }
17193 /* Fallthrough */
17194 case 0:
17195 gen_shift(ctx, op1, rd, rs, rt);
17196 break;
17197 default:
17198 generate_exception_end(ctx, EXCP_RI);
17199 break;
17200 }
17201 break;
17202 case OPC_SLT: /* Set on less than */
17203 case OPC_SLTU:
17204 gen_slt(ctx, op1, rd, rs, rt);
17205 break;
17206 case OPC_AND: /* Logic*/
17207 case OPC_OR:
17208 case OPC_NOR:
17209 case OPC_XOR:
17210 gen_logic(ctx, op1, rd, rs, rt);
17211 break;
17212 case OPC_JALR:
17213 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
17214 break;
17215 case OPC_TGE ... OPC_TEQ: /* Traps */
17216 case OPC_TNE:
17217 check_insn(ctx, ISA_MIPS2);
17218 gen_trap(ctx, op1, rs, rt, -1);
17219 break;
17220 case OPC_LSA: /* OPC_PMON */
17221 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17222 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17223 decode_opc_special_r6(env, ctx);
17224 } else {
17225 /* Pmon entry point, also R4010 selsl */
17226 #ifdef MIPS_STRICT_STANDARD
17227 MIPS_INVAL("PMON / selsl");
17228 generate_exception_end(ctx, EXCP_RI);
17229 #else
17230 gen_helper_0e0i(pmon, sa);
17231 #endif
17232 }
17233 break;
17234 case OPC_SYSCALL:
17235 generate_exception_end(ctx, EXCP_SYSCALL);
17236 break;
17237 case OPC_BREAK:
17238 generate_exception_end(ctx, EXCP_BREAK);
17239 break;
17240 case OPC_SYNC:
17241 check_insn(ctx, ISA_MIPS2);
17242 gen_sync(extract32(ctx->opcode, 6, 5));
17243 break;
17244
17245 #if defined(TARGET_MIPS64)
17246 /* MIPS64 specific opcodes */
17247 case OPC_DSLL:
17248 case OPC_DSRA:
17249 case OPC_DSLL32:
17250 case OPC_DSRA32:
17251 check_insn(ctx, ISA_MIPS3);
17252 check_mips_64(ctx);
17253 gen_shift_imm(ctx, op1, rd, rt, sa);
17254 break;
17255 case OPC_DSRL:
17256 switch ((ctx->opcode >> 21) & 0x1f) {
17257 case 1:
17258 /* drotr is decoded as dsrl on non-R2 CPUs */
17259 if (ctx->insn_flags & ISA_MIPS32R2) {
17260 op1 = OPC_DROTR;
17261 }
17262 /* Fallthrough */
17263 case 0:
17264 check_insn(ctx, ISA_MIPS3);
17265 check_mips_64(ctx);
17266 gen_shift_imm(ctx, op1, rd, rt, sa);
17267 break;
17268 default:
17269 generate_exception_end(ctx, EXCP_RI);
17270 break;
17271 }
17272 break;
17273 case OPC_DSRL32:
17274 switch ((ctx->opcode >> 21) & 0x1f) {
17275 case 1:
17276 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17277 if (ctx->insn_flags & ISA_MIPS32R2) {
17278 op1 = OPC_DROTR32;
17279 }
17280 /* Fallthrough */
17281 case 0:
17282 check_insn(ctx, ISA_MIPS3);
17283 check_mips_64(ctx);
17284 gen_shift_imm(ctx, op1, rd, rt, sa);
17285 break;
17286 default:
17287 generate_exception_end(ctx, EXCP_RI);
17288 break;
17289 }
17290 break;
17291 case OPC_DADD ... OPC_DSUBU:
17292 check_insn(ctx, ISA_MIPS3);
17293 check_mips_64(ctx);
17294 gen_arith(ctx, op1, rd, rs, rt);
17295 break;
17296 case OPC_DSLLV:
17297 case OPC_DSRAV:
17298 check_insn(ctx, ISA_MIPS3);
17299 check_mips_64(ctx);
17300 gen_shift(ctx, op1, rd, rs, rt);
17301 break;
17302 case OPC_DSRLV:
17303 switch ((ctx->opcode >> 6) & 0x1f) {
17304 case 1:
17305 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17306 if (ctx->insn_flags & ISA_MIPS32R2) {
17307 op1 = OPC_DROTRV;
17308 }
17309 /* Fallthrough */
17310 case 0:
17311 check_insn(ctx, ISA_MIPS3);
17312 check_mips_64(ctx);
17313 gen_shift(ctx, op1, rd, rs, rt);
17314 break;
17315 default:
17316 generate_exception_end(ctx, EXCP_RI);
17317 break;
17318 }
17319 break;
17320 case OPC_DLSA:
17321 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17322 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17323 decode_opc_special_r6(env, ctx);
17324 }
17325 break;
17326 #endif
17327 default:
17328 if (ctx->insn_flags & ISA_MIPS32R6) {
17329 decode_opc_special_r6(env, ctx);
17330 } else {
17331 decode_opc_special_legacy(env, ctx);
17332 }
17333 }
17334 }
17335
17336 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17337 {
17338 int rs, rt, rd;
17339 uint32_t op1;
17340
17341 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17342
17343 rs = (ctx->opcode >> 21) & 0x1f;
17344 rt = (ctx->opcode >> 16) & 0x1f;
17345 rd = (ctx->opcode >> 11) & 0x1f;
17346
17347 op1 = MASK_SPECIAL2(ctx->opcode);
17348 switch (op1) {
17349 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17350 case OPC_MSUB ... OPC_MSUBU:
17351 check_insn(ctx, ISA_MIPS32);
17352 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17353 break;
17354 case OPC_MUL:
17355 gen_arith(ctx, op1, rd, rs, rt);
17356 break;
17357 case OPC_DIV_G_2F:
17358 case OPC_DIVU_G_2F:
17359 case OPC_MULT_G_2F:
17360 case OPC_MULTU_G_2F:
17361 case OPC_MOD_G_2F:
17362 case OPC_MODU_G_2F:
17363 check_insn(ctx, INSN_LOONGSON2F);
17364 gen_loongson_integer(ctx, op1, rd, rs, rt);
17365 break;
17366 case OPC_CLO:
17367 case OPC_CLZ:
17368 check_insn(ctx, ISA_MIPS32);
17369 gen_cl(ctx, op1, rd, rs);
17370 break;
17371 case OPC_SDBBP:
17372 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17373 gen_helper_do_semihosting(cpu_env);
17374 } else {
17375 /* XXX: not clear which exception should be raised
17376 * when in debug mode...
17377 */
17378 check_insn(ctx, ISA_MIPS32);
17379 generate_exception_end(ctx, EXCP_DBp);
17380 }
17381 break;
17382 #if defined(TARGET_MIPS64)
17383 case OPC_DCLO:
17384 case OPC_DCLZ:
17385 check_insn(ctx, ISA_MIPS64);
17386 check_mips_64(ctx);
17387 gen_cl(ctx, op1, rd, rs);
17388 break;
17389 case OPC_DMULT_G_2F:
17390 case OPC_DMULTU_G_2F:
17391 case OPC_DDIV_G_2F:
17392 case OPC_DDIVU_G_2F:
17393 case OPC_DMOD_G_2F:
17394 case OPC_DMODU_G_2F:
17395 check_insn(ctx, INSN_LOONGSON2F);
17396 gen_loongson_integer(ctx, op1, rd, rs, rt);
17397 break;
17398 #endif
17399 default: /* Invalid */
17400 MIPS_INVAL("special2_legacy");
17401 generate_exception_end(ctx, EXCP_RI);
17402 break;
17403 }
17404 }
17405
17406 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17407 {
17408 int rs, rt, rd, sa;
17409 uint32_t op1, op2;
17410 int16_t imm;
17411
17412 rs = (ctx->opcode >> 21) & 0x1f;
17413 rt = (ctx->opcode >> 16) & 0x1f;
17414 rd = (ctx->opcode >> 11) & 0x1f;
17415 sa = (ctx->opcode >> 6) & 0x1f;
17416 imm = (int16_t)ctx->opcode >> 7;
17417
17418 op1 = MASK_SPECIAL3(ctx->opcode);
17419 switch (op1) {
17420 case R6_OPC_PREF:
17421 if (rt >= 24) {
17422 /* hint codes 24-31 are reserved and signal RI */
17423 generate_exception_end(ctx, EXCP_RI);
17424 }
17425 /* Treat as NOP. */
17426 break;
17427 case R6_OPC_CACHE:
17428 check_cp0_enabled(ctx);
17429 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
17430 gen_cache_operation(ctx, rt, rs, imm);
17431 }
17432 break;
17433 case R6_OPC_SC:
17434 gen_st_cond(ctx, op1, rt, rs, imm);
17435 break;
17436 case R6_OPC_LL:
17437 gen_ld(ctx, op1, rt, rs, imm);
17438 break;
17439 case OPC_BSHFL:
17440 {
17441 if (rd == 0) {
17442 /* Treat as NOP. */
17443 break;
17444 }
17445 op2 = MASK_BSHFL(ctx->opcode);
17446 switch (op2) {
17447 case OPC_ALIGN ... OPC_ALIGN_END:
17448 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17449 break;
17450 case OPC_BITSWAP:
17451 gen_bitswap(ctx, op2, rd, rt);
17452 break;
17453 }
17454 }
17455 break;
17456 #if defined(TARGET_MIPS64)
17457 case R6_OPC_SCD:
17458 gen_st_cond(ctx, op1, rt, rs, imm);
17459 break;
17460 case R6_OPC_LLD:
17461 gen_ld(ctx, op1, rt, rs, imm);
17462 break;
17463 case OPC_DBSHFL:
17464 check_mips_64(ctx);
17465 {
17466 if (rd == 0) {
17467 /* Treat as NOP. */
17468 break;
17469 }
17470 op2 = MASK_DBSHFL(ctx->opcode);
17471 switch (op2) {
17472 case OPC_DALIGN ... OPC_DALIGN_END:
17473 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17474 break;
17475 case OPC_DBITSWAP:
17476 gen_bitswap(ctx, op2, rd, rt);
17477 break;
17478 }
17479
17480 }
17481 break;
17482 #endif
17483 default: /* Invalid */
17484 MIPS_INVAL("special3_r6");
17485 generate_exception_end(ctx, EXCP_RI);
17486 break;
17487 }
17488 }
17489
17490 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17491 {
17492 int rs, rt, rd;
17493 uint32_t op1, op2;
17494
17495 rs = (ctx->opcode >> 21) & 0x1f;
17496 rt = (ctx->opcode >> 16) & 0x1f;
17497 rd = (ctx->opcode >> 11) & 0x1f;
17498
17499 op1 = MASK_SPECIAL3(ctx->opcode);
17500 switch (op1) {
17501 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17502 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17503 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17504 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17505 * the same mask and op1. */
17506 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17507 op2 = MASK_ADDUH_QB(ctx->opcode);
17508 switch (op2) {
17509 case OPC_ADDUH_QB:
17510 case OPC_ADDUH_R_QB:
17511 case OPC_ADDQH_PH:
17512 case OPC_ADDQH_R_PH:
17513 case OPC_ADDQH_W:
17514 case OPC_ADDQH_R_W:
17515 case OPC_SUBUH_QB:
17516 case OPC_SUBUH_R_QB:
17517 case OPC_SUBQH_PH:
17518 case OPC_SUBQH_R_PH:
17519 case OPC_SUBQH_W:
17520 case OPC_SUBQH_R_W:
17521 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17522 break;
17523 case OPC_MUL_PH:
17524 case OPC_MUL_S_PH:
17525 case OPC_MULQ_S_W:
17526 case OPC_MULQ_RS_W:
17527 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17528 break;
17529 default:
17530 MIPS_INVAL("MASK ADDUH.QB");
17531 generate_exception_end(ctx, EXCP_RI);
17532 break;
17533 }
17534 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17535 gen_loongson_integer(ctx, op1, rd, rs, rt);
17536 } else {
17537 generate_exception_end(ctx, EXCP_RI);
17538 }
17539 break;
17540 case OPC_LX_DSP:
17541 op2 = MASK_LX(ctx->opcode);
17542 switch (op2) {
17543 #if defined(TARGET_MIPS64)
17544 case OPC_LDX:
17545 #endif
17546 case OPC_LBUX:
17547 case OPC_LHX:
17548 case OPC_LWX:
17549 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17550 break;
17551 default: /* Invalid */
17552 MIPS_INVAL("MASK LX");
17553 generate_exception_end(ctx, EXCP_RI);
17554 break;
17555 }
17556 break;
17557 case OPC_ABSQ_S_PH_DSP:
17558 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17559 switch (op2) {
17560 case OPC_ABSQ_S_QB:
17561 case OPC_ABSQ_S_PH:
17562 case OPC_ABSQ_S_W:
17563 case OPC_PRECEQ_W_PHL:
17564 case OPC_PRECEQ_W_PHR:
17565 case OPC_PRECEQU_PH_QBL:
17566 case OPC_PRECEQU_PH_QBR:
17567 case OPC_PRECEQU_PH_QBLA:
17568 case OPC_PRECEQU_PH_QBRA:
17569 case OPC_PRECEU_PH_QBL:
17570 case OPC_PRECEU_PH_QBR:
17571 case OPC_PRECEU_PH_QBLA:
17572 case OPC_PRECEU_PH_QBRA:
17573 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17574 break;
17575 case OPC_BITREV:
17576 case OPC_REPL_QB:
17577 case OPC_REPLV_QB:
17578 case OPC_REPL_PH:
17579 case OPC_REPLV_PH:
17580 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17581 break;
17582 default:
17583 MIPS_INVAL("MASK ABSQ_S.PH");
17584 generate_exception_end(ctx, EXCP_RI);
17585 break;
17586 }
17587 break;
17588 case OPC_ADDU_QB_DSP:
17589 op2 = MASK_ADDU_QB(ctx->opcode);
17590 switch (op2) {
17591 case OPC_ADDQ_PH:
17592 case OPC_ADDQ_S_PH:
17593 case OPC_ADDQ_S_W:
17594 case OPC_ADDU_QB:
17595 case OPC_ADDU_S_QB:
17596 case OPC_ADDU_PH:
17597 case OPC_ADDU_S_PH:
17598 case OPC_SUBQ_PH:
17599 case OPC_SUBQ_S_PH:
17600 case OPC_SUBQ_S_W:
17601 case OPC_SUBU_QB:
17602 case OPC_SUBU_S_QB:
17603 case OPC_SUBU_PH:
17604 case OPC_SUBU_S_PH:
17605 case OPC_ADDSC:
17606 case OPC_ADDWC:
17607 case OPC_MODSUB:
17608 case OPC_RADDU_W_QB:
17609 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17610 break;
17611 case OPC_MULEU_S_PH_QBL:
17612 case OPC_MULEU_S_PH_QBR:
17613 case OPC_MULQ_RS_PH:
17614 case OPC_MULEQ_S_W_PHL:
17615 case OPC_MULEQ_S_W_PHR:
17616 case OPC_MULQ_S_PH:
17617 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17618 break;
17619 default: /* Invalid */
17620 MIPS_INVAL("MASK ADDU.QB");
17621 generate_exception_end(ctx, EXCP_RI);
17622 break;
17623
17624 }
17625 break;
17626 case OPC_CMPU_EQ_QB_DSP:
17627 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17628 switch (op2) {
17629 case OPC_PRECR_SRA_PH_W:
17630 case OPC_PRECR_SRA_R_PH_W:
17631 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17632 break;
17633 case OPC_PRECR_QB_PH:
17634 case OPC_PRECRQ_QB_PH:
17635 case OPC_PRECRQ_PH_W:
17636 case OPC_PRECRQ_RS_PH_W:
17637 case OPC_PRECRQU_S_QB_PH:
17638 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17639 break;
17640 case OPC_CMPU_EQ_QB:
17641 case OPC_CMPU_LT_QB:
17642 case OPC_CMPU_LE_QB:
17643 case OPC_CMP_EQ_PH:
17644 case OPC_CMP_LT_PH:
17645 case OPC_CMP_LE_PH:
17646 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17647 break;
17648 case OPC_CMPGU_EQ_QB:
17649 case OPC_CMPGU_LT_QB:
17650 case OPC_CMPGU_LE_QB:
17651 case OPC_CMPGDU_EQ_QB:
17652 case OPC_CMPGDU_LT_QB:
17653 case OPC_CMPGDU_LE_QB:
17654 case OPC_PICK_QB:
17655 case OPC_PICK_PH:
17656 case OPC_PACKRL_PH:
17657 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17658 break;
17659 default: /* Invalid */
17660 MIPS_INVAL("MASK CMPU.EQ.QB");
17661 generate_exception_end(ctx, EXCP_RI);
17662 break;
17663 }
17664 break;
17665 case OPC_SHLL_QB_DSP:
17666 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17667 break;
17668 case OPC_DPA_W_PH_DSP:
17669 op2 = MASK_DPA_W_PH(ctx->opcode);
17670 switch (op2) {
17671 case OPC_DPAU_H_QBL:
17672 case OPC_DPAU_H_QBR:
17673 case OPC_DPSU_H_QBL:
17674 case OPC_DPSU_H_QBR:
17675 case OPC_DPA_W_PH:
17676 case OPC_DPAX_W_PH:
17677 case OPC_DPAQ_S_W_PH:
17678 case OPC_DPAQX_S_W_PH:
17679 case OPC_DPAQX_SA_W_PH:
17680 case OPC_DPS_W_PH:
17681 case OPC_DPSX_W_PH:
17682 case OPC_DPSQ_S_W_PH:
17683 case OPC_DPSQX_S_W_PH:
17684 case OPC_DPSQX_SA_W_PH:
17685 case OPC_MULSAQ_S_W_PH:
17686 case OPC_DPAQ_SA_L_W:
17687 case OPC_DPSQ_SA_L_W:
17688 case OPC_MAQ_S_W_PHL:
17689 case OPC_MAQ_S_W_PHR:
17690 case OPC_MAQ_SA_W_PHL:
17691 case OPC_MAQ_SA_W_PHR:
17692 case OPC_MULSA_W_PH:
17693 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17694 break;
17695 default: /* Invalid */
17696 MIPS_INVAL("MASK DPAW.PH");
17697 generate_exception_end(ctx, EXCP_RI);
17698 break;
17699 }
17700 break;
17701 case OPC_INSV_DSP:
17702 op2 = MASK_INSV(ctx->opcode);
17703 switch (op2) {
17704 case OPC_INSV:
17705 check_dsp(ctx);
17706 {
17707 TCGv t0, t1;
17708
17709 if (rt == 0) {
17710 break;
17711 }
17712
17713 t0 = tcg_temp_new();
17714 t1 = tcg_temp_new();
17715
17716 gen_load_gpr(t0, rt);
17717 gen_load_gpr(t1, rs);
17718
17719 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17720
17721 tcg_temp_free(t0);
17722 tcg_temp_free(t1);
17723 break;
17724 }
17725 default: /* Invalid */
17726 MIPS_INVAL("MASK INSV");
17727 generate_exception_end(ctx, EXCP_RI);
17728 break;
17729 }
17730 break;
17731 case OPC_APPEND_DSP:
17732 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17733 break;
17734 case OPC_EXTR_W_DSP:
17735 op2 = MASK_EXTR_W(ctx->opcode);
17736 switch (op2) {
17737 case OPC_EXTR_W:
17738 case OPC_EXTR_R_W:
17739 case OPC_EXTR_RS_W:
17740 case OPC_EXTR_S_H:
17741 case OPC_EXTRV_S_H:
17742 case OPC_EXTRV_W:
17743 case OPC_EXTRV_R_W:
17744 case OPC_EXTRV_RS_W:
17745 case OPC_EXTP:
17746 case OPC_EXTPV:
17747 case OPC_EXTPDP:
17748 case OPC_EXTPDPV:
17749 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17750 break;
17751 case OPC_RDDSP:
17752 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17753 break;
17754 case OPC_SHILO:
17755 case OPC_SHILOV:
17756 case OPC_MTHLIP:
17757 case OPC_WRDSP:
17758 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17759 break;
17760 default: /* Invalid */
17761 MIPS_INVAL("MASK EXTR.W");
17762 generate_exception_end(ctx, EXCP_RI);
17763 break;
17764 }
17765 break;
17766 #if defined(TARGET_MIPS64)
17767 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17768 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17769 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17770 check_insn(ctx, INSN_LOONGSON2E);
17771 gen_loongson_integer(ctx, op1, rd, rs, rt);
17772 break;
17773 case OPC_ABSQ_S_QH_DSP:
17774 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17775 switch (op2) {
17776 case OPC_PRECEQ_L_PWL:
17777 case OPC_PRECEQ_L_PWR:
17778 case OPC_PRECEQ_PW_QHL:
17779 case OPC_PRECEQ_PW_QHR:
17780 case OPC_PRECEQ_PW_QHLA:
17781 case OPC_PRECEQ_PW_QHRA:
17782 case OPC_PRECEQU_QH_OBL:
17783 case OPC_PRECEQU_QH_OBR:
17784 case OPC_PRECEQU_QH_OBLA:
17785 case OPC_PRECEQU_QH_OBRA:
17786 case OPC_PRECEU_QH_OBL:
17787 case OPC_PRECEU_QH_OBR:
17788 case OPC_PRECEU_QH_OBLA:
17789 case OPC_PRECEU_QH_OBRA:
17790 case OPC_ABSQ_S_OB:
17791 case OPC_ABSQ_S_PW:
17792 case OPC_ABSQ_S_QH:
17793 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17794 break;
17795 case OPC_REPL_OB:
17796 case OPC_REPL_PW:
17797 case OPC_REPL_QH:
17798 case OPC_REPLV_OB:
17799 case OPC_REPLV_PW:
17800 case OPC_REPLV_QH:
17801 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17802 break;
17803 default: /* Invalid */
17804 MIPS_INVAL("MASK ABSQ_S.QH");
17805 generate_exception_end(ctx, EXCP_RI);
17806 break;
17807 }
17808 break;
17809 case OPC_ADDU_OB_DSP:
17810 op2 = MASK_ADDU_OB(ctx->opcode);
17811 switch (op2) {
17812 case OPC_RADDU_L_OB:
17813 case OPC_SUBQ_PW:
17814 case OPC_SUBQ_S_PW:
17815 case OPC_SUBQ_QH:
17816 case OPC_SUBQ_S_QH:
17817 case OPC_SUBU_OB:
17818 case OPC_SUBU_S_OB:
17819 case OPC_SUBU_QH:
17820 case OPC_SUBU_S_QH:
17821 case OPC_SUBUH_OB:
17822 case OPC_SUBUH_R_OB:
17823 case OPC_ADDQ_PW:
17824 case OPC_ADDQ_S_PW:
17825 case OPC_ADDQ_QH:
17826 case OPC_ADDQ_S_QH:
17827 case OPC_ADDU_OB:
17828 case OPC_ADDU_S_OB:
17829 case OPC_ADDU_QH:
17830 case OPC_ADDU_S_QH:
17831 case OPC_ADDUH_OB:
17832 case OPC_ADDUH_R_OB:
17833 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17834 break;
17835 case OPC_MULEQ_S_PW_QHL:
17836 case OPC_MULEQ_S_PW_QHR:
17837 case OPC_MULEU_S_QH_OBL:
17838 case OPC_MULEU_S_QH_OBR:
17839 case OPC_MULQ_RS_QH:
17840 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17841 break;
17842 default: /* Invalid */
17843 MIPS_INVAL("MASK ADDU.OB");
17844 generate_exception_end(ctx, EXCP_RI);
17845 break;
17846 }
17847 break;
17848 case OPC_CMPU_EQ_OB_DSP:
17849 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17850 switch (op2) {
17851 case OPC_PRECR_SRA_QH_PW:
17852 case OPC_PRECR_SRA_R_QH_PW:
17853 /* Return value is rt. */
17854 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17855 break;
17856 case OPC_PRECR_OB_QH:
17857 case OPC_PRECRQ_OB_QH:
17858 case OPC_PRECRQ_PW_L:
17859 case OPC_PRECRQ_QH_PW:
17860 case OPC_PRECRQ_RS_QH_PW:
17861 case OPC_PRECRQU_S_OB_QH:
17862 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17863 break;
17864 case OPC_CMPU_EQ_OB:
17865 case OPC_CMPU_LT_OB:
17866 case OPC_CMPU_LE_OB:
17867 case OPC_CMP_EQ_QH:
17868 case OPC_CMP_LT_QH:
17869 case OPC_CMP_LE_QH:
17870 case OPC_CMP_EQ_PW:
17871 case OPC_CMP_LT_PW:
17872 case OPC_CMP_LE_PW:
17873 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17874 break;
17875 case OPC_CMPGDU_EQ_OB:
17876 case OPC_CMPGDU_LT_OB:
17877 case OPC_CMPGDU_LE_OB:
17878 case OPC_CMPGU_EQ_OB:
17879 case OPC_CMPGU_LT_OB:
17880 case OPC_CMPGU_LE_OB:
17881 case OPC_PACKRL_PW:
17882 case OPC_PICK_OB:
17883 case OPC_PICK_PW:
17884 case OPC_PICK_QH:
17885 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17886 break;
17887 default: /* Invalid */
17888 MIPS_INVAL("MASK CMPU_EQ.OB");
17889 generate_exception_end(ctx, EXCP_RI);
17890 break;
17891 }
17892 break;
17893 case OPC_DAPPEND_DSP:
17894 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17895 break;
17896 case OPC_DEXTR_W_DSP:
17897 op2 = MASK_DEXTR_W(ctx->opcode);
17898 switch (op2) {
17899 case OPC_DEXTP:
17900 case OPC_DEXTPDP:
17901 case OPC_DEXTPDPV:
17902 case OPC_DEXTPV:
17903 case OPC_DEXTR_L:
17904 case OPC_DEXTR_R_L:
17905 case OPC_DEXTR_RS_L:
17906 case OPC_DEXTR_W:
17907 case OPC_DEXTR_R_W:
17908 case OPC_DEXTR_RS_W:
17909 case OPC_DEXTR_S_H:
17910 case OPC_DEXTRV_L:
17911 case OPC_DEXTRV_R_L:
17912 case OPC_DEXTRV_RS_L:
17913 case OPC_DEXTRV_S_H:
17914 case OPC_DEXTRV_W:
17915 case OPC_DEXTRV_R_W:
17916 case OPC_DEXTRV_RS_W:
17917 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17918 break;
17919 case OPC_DMTHLIP:
17920 case OPC_DSHILO:
17921 case OPC_DSHILOV:
17922 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17923 break;
17924 default: /* Invalid */
17925 MIPS_INVAL("MASK EXTR.W");
17926 generate_exception_end(ctx, EXCP_RI);
17927 break;
17928 }
17929 break;
17930 case OPC_DPAQ_W_QH_DSP:
17931 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17932 switch (op2) {
17933 case OPC_DPAU_H_OBL:
17934 case OPC_DPAU_H_OBR:
17935 case OPC_DPSU_H_OBL:
17936 case OPC_DPSU_H_OBR:
17937 case OPC_DPA_W_QH:
17938 case OPC_DPAQ_S_W_QH:
17939 case OPC_DPS_W_QH:
17940 case OPC_DPSQ_S_W_QH:
17941 case OPC_MULSAQ_S_W_QH:
17942 case OPC_DPAQ_SA_L_PW:
17943 case OPC_DPSQ_SA_L_PW:
17944 case OPC_MULSAQ_S_L_PW:
17945 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17946 break;
17947 case OPC_MAQ_S_W_QHLL:
17948 case OPC_MAQ_S_W_QHLR:
17949 case OPC_MAQ_S_W_QHRL:
17950 case OPC_MAQ_S_W_QHRR:
17951 case OPC_MAQ_SA_W_QHLL:
17952 case OPC_MAQ_SA_W_QHLR:
17953 case OPC_MAQ_SA_W_QHRL:
17954 case OPC_MAQ_SA_W_QHRR:
17955 case OPC_MAQ_S_L_PWL:
17956 case OPC_MAQ_S_L_PWR:
17957 case OPC_DMADD:
17958 case OPC_DMADDU:
17959 case OPC_DMSUB:
17960 case OPC_DMSUBU:
17961 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17962 break;
17963 default: /* Invalid */
17964 MIPS_INVAL("MASK DPAQ.W.QH");
17965 generate_exception_end(ctx, EXCP_RI);
17966 break;
17967 }
17968 break;
17969 case OPC_DINSV_DSP:
17970 op2 = MASK_INSV(ctx->opcode);
17971 switch (op2) {
17972 case OPC_DINSV:
17973 {
17974 TCGv t0, t1;
17975
17976 if (rt == 0) {
17977 break;
17978 }
17979 check_dsp(ctx);
17980
17981 t0 = tcg_temp_new();
17982 t1 = tcg_temp_new();
17983
17984 gen_load_gpr(t0, rt);
17985 gen_load_gpr(t1, rs);
17986
17987 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
17988
17989 tcg_temp_free(t0);
17990 tcg_temp_free(t1);
17991 break;
17992 }
17993 default: /* Invalid */
17994 MIPS_INVAL("MASK DINSV");
17995 generate_exception_end(ctx, EXCP_RI);
17996 break;
17997 }
17998 break;
17999 case OPC_SHLL_OB_DSP:
18000 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
18001 break;
18002 #endif
18003 default: /* Invalid */
18004 MIPS_INVAL("special3_legacy");
18005 generate_exception_end(ctx, EXCP_RI);
18006 break;
18007 }
18008 }
18009
18010 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
18011 {
18012 int rs, rt, rd, sa;
18013 uint32_t op1, op2;
18014
18015 rs = (ctx->opcode >> 21) & 0x1f;
18016 rt = (ctx->opcode >> 16) & 0x1f;
18017 rd = (ctx->opcode >> 11) & 0x1f;
18018 sa = (ctx->opcode >> 6) & 0x1f;
18019
18020 op1 = MASK_SPECIAL3(ctx->opcode);
18021 switch (op1) {
18022 case OPC_EXT:
18023 case OPC_INS:
18024 check_insn(ctx, ISA_MIPS32R2);
18025 gen_bitops(ctx, op1, rt, rs, sa, rd);
18026 break;
18027 case OPC_BSHFL:
18028 op2 = MASK_BSHFL(ctx->opcode);
18029 switch (op2) {
18030 case OPC_ALIGN ... OPC_ALIGN_END:
18031 case OPC_BITSWAP:
18032 check_insn(ctx, ISA_MIPS32R6);
18033 decode_opc_special3_r6(env, ctx);
18034 break;
18035 default:
18036 check_insn(ctx, ISA_MIPS32R2);
18037 gen_bshfl(ctx, op2, rt, rd);
18038 break;
18039 }
18040 break;
18041 #if defined(TARGET_MIPS64)
18042 case OPC_DEXTM ... OPC_DEXT:
18043 case OPC_DINSM ... OPC_DINS:
18044 check_insn(ctx, ISA_MIPS64R2);
18045 check_mips_64(ctx);
18046 gen_bitops(ctx, op1, rt, rs, sa, rd);
18047 break;
18048 case OPC_DBSHFL:
18049 op2 = MASK_DBSHFL(ctx->opcode);
18050 switch (op2) {
18051 case OPC_DALIGN ... OPC_DALIGN_END:
18052 case OPC_DBITSWAP:
18053 check_insn(ctx, ISA_MIPS32R6);
18054 decode_opc_special3_r6(env, ctx);
18055 break;
18056 default:
18057 check_insn(ctx, ISA_MIPS64R2);
18058 check_mips_64(ctx);
18059 op2 = MASK_DBSHFL(ctx->opcode);
18060 gen_bshfl(ctx, op2, rt, rd);
18061 break;
18062 }
18063 break;
18064 #endif
18065 case OPC_RDHWR:
18066 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
18067 break;
18068 case OPC_FORK:
18069 check_insn(ctx, ASE_MT);
18070 {
18071 TCGv t0 = tcg_temp_new();
18072 TCGv t1 = tcg_temp_new();
18073
18074 gen_load_gpr(t0, rt);
18075 gen_load_gpr(t1, rs);
18076 gen_helper_fork(t0, t1);
18077 tcg_temp_free(t0);
18078 tcg_temp_free(t1);
18079 }
18080 break;
18081 case OPC_YIELD:
18082 check_insn(ctx, ASE_MT);
18083 {
18084 TCGv t0 = tcg_temp_new();
18085
18086 gen_load_gpr(t0, rs);
18087 gen_helper_yield(t0, cpu_env, t0);
18088 gen_store_gpr(t0, rd);
18089 tcg_temp_free(t0);
18090 }
18091 break;
18092 default:
18093 if (ctx->insn_flags & ISA_MIPS32R6) {
18094 decode_opc_special3_r6(env, ctx);
18095 } else {
18096 decode_opc_special3_legacy(env, ctx);
18097 }
18098 }
18099 }
18100
18101 /* MIPS SIMD Architecture (MSA) */
18102 static inline int check_msa_access(DisasContext *ctx)
18103 {
18104 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
18105 !(ctx->hflags & MIPS_HFLAG_F64))) {
18106 generate_exception_end(ctx, EXCP_RI);
18107 return 0;
18108 }
18109
18110 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
18111 if (ctx->insn_flags & ASE_MSA) {
18112 generate_exception_end(ctx, EXCP_MSADIS);
18113 return 0;
18114 } else {
18115 generate_exception_end(ctx, EXCP_RI);
18116 return 0;
18117 }
18118 }
18119 return 1;
18120 }
18121
18122 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
18123 {
18124 /* generates tcg ops to check if any element is 0 */
18125 /* Note this function only works with MSA_WRLEN = 128 */
18126 uint64_t eval_zero_or_big = 0;
18127 uint64_t eval_big = 0;
18128 TCGv_i64 t0 = tcg_temp_new_i64();
18129 TCGv_i64 t1 = tcg_temp_new_i64();
18130 switch (df) {
18131 case DF_BYTE:
18132 eval_zero_or_big = 0x0101010101010101ULL;
18133 eval_big = 0x8080808080808080ULL;
18134 break;
18135 case DF_HALF:
18136 eval_zero_or_big = 0x0001000100010001ULL;
18137 eval_big = 0x8000800080008000ULL;
18138 break;
18139 case DF_WORD:
18140 eval_zero_or_big = 0x0000000100000001ULL;
18141 eval_big = 0x8000000080000000ULL;
18142 break;
18143 case DF_DOUBLE:
18144 eval_zero_or_big = 0x0000000000000001ULL;
18145 eval_big = 0x8000000000000000ULL;
18146 break;
18147 }
18148 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
18149 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
18150 tcg_gen_andi_i64(t0, t0, eval_big);
18151 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
18152 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
18153 tcg_gen_andi_i64(t1, t1, eval_big);
18154 tcg_gen_or_i64(t0, t0, t1);
18155 /* if all bits are zero then all elements are not zero */
18156 /* if some bit is non-zero then some element is zero */
18157 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
18158 tcg_gen_trunc_i64_tl(tresult, t0);
18159 tcg_temp_free_i64(t0);
18160 tcg_temp_free_i64(t1);
18161 }
18162
18163 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
18164 {
18165 uint8_t df = (ctx->opcode >> 21) & 0x3;
18166 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18167 int64_t s16 = (int16_t)ctx->opcode;
18168
18169 check_msa_access(ctx);
18170
18171 if (ctx->hflags & MIPS_HFLAG_BMASK) {
18172 generate_exception_end(ctx, EXCP_RI);
18173 return;
18174 }
18175 switch (op1) {
18176 case OPC_BZ_V:
18177 case OPC_BNZ_V:
18178 {
18179 TCGv_i64 t0 = tcg_temp_new_i64();
18180 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
18181 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
18182 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
18183 tcg_gen_trunc_i64_tl(bcond, t0);
18184 tcg_temp_free_i64(t0);
18185 }
18186 break;
18187 case OPC_BZ_B:
18188 case OPC_BZ_H:
18189 case OPC_BZ_W:
18190 case OPC_BZ_D:
18191 gen_check_zero_element(bcond, df, wt);
18192 break;
18193 case OPC_BNZ_B:
18194 case OPC_BNZ_H:
18195 case OPC_BNZ_W:
18196 case OPC_BNZ_D:
18197 gen_check_zero_element(bcond, df, wt);
18198 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
18199 break;
18200 }
18201
18202 ctx->btarget = ctx->pc + (s16 << 2) + 4;
18203
18204 ctx->hflags |= MIPS_HFLAG_BC;
18205 ctx->hflags |= MIPS_HFLAG_BDS32;
18206 }
18207
18208 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
18209 {
18210 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18211 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
18212 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18213 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18214
18215 TCGv_i32 twd = tcg_const_i32(wd);
18216 TCGv_i32 tws = tcg_const_i32(ws);
18217 TCGv_i32 ti8 = tcg_const_i32(i8);
18218
18219 switch (MASK_MSA_I8(ctx->opcode)) {
18220 case OPC_ANDI_B:
18221 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
18222 break;
18223 case OPC_ORI_B:
18224 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
18225 break;
18226 case OPC_NORI_B:
18227 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
18228 break;
18229 case OPC_XORI_B:
18230 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
18231 break;
18232 case OPC_BMNZI_B:
18233 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18234 break;
18235 case OPC_BMZI_B:
18236 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18237 break;
18238 case OPC_BSELI_B:
18239 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18240 break;
18241 case OPC_SHF_B:
18242 case OPC_SHF_H:
18243 case OPC_SHF_W:
18244 {
18245 uint8_t df = (ctx->opcode >> 24) & 0x3;
18246 if (df == DF_DOUBLE) {
18247 generate_exception_end(ctx, EXCP_RI);
18248 } else {
18249 TCGv_i32 tdf = tcg_const_i32(df);
18250 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18251 tcg_temp_free_i32(tdf);
18252 }
18253 }
18254 break;
18255 default:
18256 MIPS_INVAL("MSA instruction");
18257 generate_exception_end(ctx, EXCP_RI);
18258 break;
18259 }
18260
18261 tcg_temp_free_i32(twd);
18262 tcg_temp_free_i32(tws);
18263 tcg_temp_free_i32(ti8);
18264 }
18265
18266 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18267 {
18268 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18269 uint8_t df = (ctx->opcode >> 21) & 0x3;
18270 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18271 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18272 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18273 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18274
18275 TCGv_i32 tdf = tcg_const_i32(df);
18276 TCGv_i32 twd = tcg_const_i32(wd);
18277 TCGv_i32 tws = tcg_const_i32(ws);
18278 TCGv_i32 timm = tcg_temp_new_i32();
18279 tcg_gen_movi_i32(timm, u5);
18280
18281 switch (MASK_MSA_I5(ctx->opcode)) {
18282 case OPC_ADDVI_df:
18283 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18284 break;
18285 case OPC_SUBVI_df:
18286 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18287 break;
18288 case OPC_MAXI_S_df:
18289 tcg_gen_movi_i32(timm, s5);
18290 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18291 break;
18292 case OPC_MAXI_U_df:
18293 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18294 break;
18295 case OPC_MINI_S_df:
18296 tcg_gen_movi_i32(timm, s5);
18297 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18298 break;
18299 case OPC_MINI_U_df:
18300 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18301 break;
18302 case OPC_CEQI_df:
18303 tcg_gen_movi_i32(timm, s5);
18304 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18305 break;
18306 case OPC_CLTI_S_df:
18307 tcg_gen_movi_i32(timm, s5);
18308 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18309 break;
18310 case OPC_CLTI_U_df:
18311 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18312 break;
18313 case OPC_CLEI_S_df:
18314 tcg_gen_movi_i32(timm, s5);
18315 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18316 break;
18317 case OPC_CLEI_U_df:
18318 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18319 break;
18320 case OPC_LDI_df:
18321 {
18322 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18323 tcg_gen_movi_i32(timm, s10);
18324 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18325 }
18326 break;
18327 default:
18328 MIPS_INVAL("MSA instruction");
18329 generate_exception_end(ctx, EXCP_RI);
18330 break;
18331 }
18332
18333 tcg_temp_free_i32(tdf);
18334 tcg_temp_free_i32(twd);
18335 tcg_temp_free_i32(tws);
18336 tcg_temp_free_i32(timm);
18337 }
18338
18339 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18340 {
18341 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18342 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18343 uint32_t df = 0, m = 0;
18344 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18345 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18346
18347 TCGv_i32 tdf;
18348 TCGv_i32 tm;
18349 TCGv_i32 twd;
18350 TCGv_i32 tws;
18351
18352 if ((dfm & 0x40) == 0x00) {
18353 m = dfm & 0x3f;
18354 df = DF_DOUBLE;
18355 } else if ((dfm & 0x60) == 0x40) {
18356 m = dfm & 0x1f;
18357 df = DF_WORD;
18358 } else if ((dfm & 0x70) == 0x60) {
18359 m = dfm & 0x0f;
18360 df = DF_HALF;
18361 } else if ((dfm & 0x78) == 0x70) {
18362 m = dfm & 0x7;
18363 df = DF_BYTE;
18364 } else {
18365 generate_exception_end(ctx, EXCP_RI);
18366 return;
18367 }
18368
18369 tdf = tcg_const_i32(df);
18370 tm = tcg_const_i32(m);
18371 twd = tcg_const_i32(wd);
18372 tws = tcg_const_i32(ws);
18373
18374 switch (MASK_MSA_BIT(ctx->opcode)) {
18375 case OPC_SLLI_df:
18376 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18377 break;
18378 case OPC_SRAI_df:
18379 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18380 break;
18381 case OPC_SRLI_df:
18382 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18383 break;
18384 case OPC_BCLRI_df:
18385 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18386 break;
18387 case OPC_BSETI_df:
18388 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18389 break;
18390 case OPC_BNEGI_df:
18391 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18392 break;
18393 case OPC_BINSLI_df:
18394 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18395 break;
18396 case OPC_BINSRI_df:
18397 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18398 break;
18399 case OPC_SAT_S_df:
18400 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18401 break;
18402 case OPC_SAT_U_df:
18403 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18404 break;
18405 case OPC_SRARI_df:
18406 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18407 break;
18408 case OPC_SRLRI_df:
18409 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18410 break;
18411 default:
18412 MIPS_INVAL("MSA instruction");
18413 generate_exception_end(ctx, EXCP_RI);
18414 break;
18415 }
18416
18417 tcg_temp_free_i32(tdf);
18418 tcg_temp_free_i32(tm);
18419 tcg_temp_free_i32(twd);
18420 tcg_temp_free_i32(tws);
18421 }
18422
18423 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18424 {
18425 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18426 uint8_t df = (ctx->opcode >> 21) & 0x3;
18427 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18428 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18429 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18430
18431 TCGv_i32 tdf = tcg_const_i32(df);
18432 TCGv_i32 twd = tcg_const_i32(wd);
18433 TCGv_i32 tws = tcg_const_i32(ws);
18434 TCGv_i32 twt = tcg_const_i32(wt);
18435
18436 switch (MASK_MSA_3R(ctx->opcode)) {
18437 case OPC_SLL_df:
18438 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18439 break;
18440 case OPC_ADDV_df:
18441 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18442 break;
18443 case OPC_CEQ_df:
18444 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18445 break;
18446 case OPC_ADD_A_df:
18447 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18448 break;
18449 case OPC_SUBS_S_df:
18450 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18451 break;
18452 case OPC_MULV_df:
18453 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18454 break;
18455 case OPC_SLD_df:
18456 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18457 break;
18458 case OPC_VSHF_df:
18459 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18460 break;
18461 case OPC_SRA_df:
18462 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18463 break;
18464 case OPC_SUBV_df:
18465 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18466 break;
18467 case OPC_ADDS_A_df:
18468 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18469 break;
18470 case OPC_SUBS_U_df:
18471 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18472 break;
18473 case OPC_MADDV_df:
18474 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18475 break;
18476 case OPC_SPLAT_df:
18477 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18478 break;
18479 case OPC_SRAR_df:
18480 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18481 break;
18482 case OPC_SRL_df:
18483 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18484 break;
18485 case OPC_MAX_S_df:
18486 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18487 break;
18488 case OPC_CLT_S_df:
18489 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18490 break;
18491 case OPC_ADDS_S_df:
18492 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18493 break;
18494 case OPC_SUBSUS_U_df:
18495 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18496 break;
18497 case OPC_MSUBV_df:
18498 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18499 break;
18500 case OPC_PCKEV_df:
18501 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18502 break;
18503 case OPC_SRLR_df:
18504 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18505 break;
18506 case OPC_BCLR_df:
18507 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18508 break;
18509 case OPC_MAX_U_df:
18510 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18511 break;
18512 case OPC_CLT_U_df:
18513 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18514 break;
18515 case OPC_ADDS_U_df:
18516 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18517 break;
18518 case OPC_SUBSUU_S_df:
18519 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18520 break;
18521 case OPC_PCKOD_df:
18522 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18523 break;
18524 case OPC_BSET_df:
18525 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18526 break;
18527 case OPC_MIN_S_df:
18528 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18529 break;
18530 case OPC_CLE_S_df:
18531 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18532 break;
18533 case OPC_AVE_S_df:
18534 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18535 break;
18536 case OPC_ASUB_S_df:
18537 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18538 break;
18539 case OPC_DIV_S_df:
18540 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18541 break;
18542 case OPC_ILVL_df:
18543 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18544 break;
18545 case OPC_BNEG_df:
18546 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18547 break;
18548 case OPC_MIN_U_df:
18549 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18550 break;
18551 case OPC_CLE_U_df:
18552 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18553 break;
18554 case OPC_AVE_U_df:
18555 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18556 break;
18557 case OPC_ASUB_U_df:
18558 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18559 break;
18560 case OPC_DIV_U_df:
18561 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18562 break;
18563 case OPC_ILVR_df:
18564 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18565 break;
18566 case OPC_BINSL_df:
18567 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18568 break;
18569 case OPC_MAX_A_df:
18570 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18571 break;
18572 case OPC_AVER_S_df:
18573 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18574 break;
18575 case OPC_MOD_S_df:
18576 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18577 break;
18578 case OPC_ILVEV_df:
18579 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18580 break;
18581 case OPC_BINSR_df:
18582 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18583 break;
18584 case OPC_MIN_A_df:
18585 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18586 break;
18587 case OPC_AVER_U_df:
18588 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18589 break;
18590 case OPC_MOD_U_df:
18591 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18592 break;
18593 case OPC_ILVOD_df:
18594 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18595 break;
18596
18597 case OPC_DOTP_S_df:
18598 case OPC_DOTP_U_df:
18599 case OPC_DPADD_S_df:
18600 case OPC_DPADD_U_df:
18601 case OPC_DPSUB_S_df:
18602 case OPC_HADD_S_df:
18603 case OPC_DPSUB_U_df:
18604 case OPC_HADD_U_df:
18605 case OPC_HSUB_S_df:
18606 case OPC_HSUB_U_df:
18607 if (df == DF_BYTE) {
18608 generate_exception_end(ctx, EXCP_RI);
18609 break;
18610 }
18611 switch (MASK_MSA_3R(ctx->opcode)) {
18612 case OPC_DOTP_S_df:
18613 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18614 break;
18615 case OPC_DOTP_U_df:
18616 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18617 break;
18618 case OPC_DPADD_S_df:
18619 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18620 break;
18621 case OPC_DPADD_U_df:
18622 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18623 break;
18624 case OPC_DPSUB_S_df:
18625 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18626 break;
18627 case OPC_HADD_S_df:
18628 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18629 break;
18630 case OPC_DPSUB_U_df:
18631 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18632 break;
18633 case OPC_HADD_U_df:
18634 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18635 break;
18636 case OPC_HSUB_S_df:
18637 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18638 break;
18639 case OPC_HSUB_U_df:
18640 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18641 break;
18642 }
18643 break;
18644 default:
18645 MIPS_INVAL("MSA instruction");
18646 generate_exception_end(ctx, EXCP_RI);
18647 break;
18648 }
18649 tcg_temp_free_i32(twd);
18650 tcg_temp_free_i32(tws);
18651 tcg_temp_free_i32(twt);
18652 tcg_temp_free_i32(tdf);
18653 }
18654
18655 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18656 {
18657 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18658 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18659 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18660 TCGv telm = tcg_temp_new();
18661 TCGv_i32 tsr = tcg_const_i32(source);
18662 TCGv_i32 tdt = tcg_const_i32(dest);
18663
18664 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18665 case OPC_CTCMSA:
18666 gen_load_gpr(telm, source);
18667 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18668 break;
18669 case OPC_CFCMSA:
18670 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18671 gen_store_gpr(telm, dest);
18672 break;
18673 case OPC_MOVE_V:
18674 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18675 break;
18676 default:
18677 MIPS_INVAL("MSA instruction");
18678 generate_exception_end(ctx, EXCP_RI);
18679 break;
18680 }
18681
18682 tcg_temp_free(telm);
18683 tcg_temp_free_i32(tdt);
18684 tcg_temp_free_i32(tsr);
18685 }
18686
18687 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18688 uint32_t n)
18689 {
18690 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18691 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18692 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18693
18694 TCGv_i32 tws = tcg_const_i32(ws);
18695 TCGv_i32 twd = tcg_const_i32(wd);
18696 TCGv_i32 tn = tcg_const_i32(n);
18697 TCGv_i32 tdf = tcg_const_i32(df);
18698
18699 switch (MASK_MSA_ELM(ctx->opcode)) {
18700 case OPC_SLDI_df:
18701 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18702 break;
18703 case OPC_SPLATI_df:
18704 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18705 break;
18706 case OPC_INSVE_df:
18707 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18708 break;
18709 case OPC_COPY_S_df:
18710 case OPC_COPY_U_df:
18711 case OPC_INSERT_df:
18712 #if !defined(TARGET_MIPS64)
18713 /* Double format valid only for MIPS64 */
18714 if (df == DF_DOUBLE) {
18715 generate_exception_end(ctx, EXCP_RI);
18716 break;
18717 }
18718 #endif
18719 switch (MASK_MSA_ELM(ctx->opcode)) {
18720 case OPC_COPY_S_df:
18721 if (likely(wd != 0)) {
18722 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18723 }
18724 break;
18725 case OPC_COPY_U_df:
18726 if (likely(wd != 0)) {
18727 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18728 }
18729 break;
18730 case OPC_INSERT_df:
18731 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18732 break;
18733 }
18734 break;
18735 default:
18736 MIPS_INVAL("MSA instruction");
18737 generate_exception_end(ctx, EXCP_RI);
18738 }
18739 tcg_temp_free_i32(twd);
18740 tcg_temp_free_i32(tws);
18741 tcg_temp_free_i32(tn);
18742 tcg_temp_free_i32(tdf);
18743 }
18744
18745 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18746 {
18747 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18748 uint32_t df = 0, n = 0;
18749
18750 if ((dfn & 0x30) == 0x00) {
18751 n = dfn & 0x0f;
18752 df = DF_BYTE;
18753 } else if ((dfn & 0x38) == 0x20) {
18754 n = dfn & 0x07;
18755 df = DF_HALF;
18756 } else if ((dfn & 0x3c) == 0x30) {
18757 n = dfn & 0x03;
18758 df = DF_WORD;
18759 } else if ((dfn & 0x3e) == 0x38) {
18760 n = dfn & 0x01;
18761 df = DF_DOUBLE;
18762 } else if (dfn == 0x3E) {
18763 /* CTCMSA, CFCMSA, MOVE.V */
18764 gen_msa_elm_3e(env, ctx);
18765 return;
18766 } else {
18767 generate_exception_end(ctx, EXCP_RI);
18768 return;
18769 }
18770
18771 gen_msa_elm_df(env, ctx, df, n);
18772 }
18773
18774 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18775 {
18776 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18777 uint8_t df = (ctx->opcode >> 21) & 0x1;
18778 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18779 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18780 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18781
18782 TCGv_i32 twd = tcg_const_i32(wd);
18783 TCGv_i32 tws = tcg_const_i32(ws);
18784 TCGv_i32 twt = tcg_const_i32(wt);
18785 TCGv_i32 tdf = tcg_temp_new_i32();
18786
18787 /* adjust df value for floating-point instruction */
18788 tcg_gen_movi_i32(tdf, df + 2);
18789
18790 switch (MASK_MSA_3RF(ctx->opcode)) {
18791 case OPC_FCAF_df:
18792 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18793 break;
18794 case OPC_FADD_df:
18795 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18796 break;
18797 case OPC_FCUN_df:
18798 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18799 break;
18800 case OPC_FSUB_df:
18801 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18802 break;
18803 case OPC_FCOR_df:
18804 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18805 break;
18806 case OPC_FCEQ_df:
18807 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18808 break;
18809 case OPC_FMUL_df:
18810 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18811 break;
18812 case OPC_FCUNE_df:
18813 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18814 break;
18815 case OPC_FCUEQ_df:
18816 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18817 break;
18818 case OPC_FDIV_df:
18819 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18820 break;
18821 case OPC_FCNE_df:
18822 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18823 break;
18824 case OPC_FCLT_df:
18825 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18826 break;
18827 case OPC_FMADD_df:
18828 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18829 break;
18830 case OPC_MUL_Q_df:
18831 tcg_gen_movi_i32(tdf, df + 1);
18832 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18833 break;
18834 case OPC_FCULT_df:
18835 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18836 break;
18837 case OPC_FMSUB_df:
18838 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18839 break;
18840 case OPC_MADD_Q_df:
18841 tcg_gen_movi_i32(tdf, df + 1);
18842 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18843 break;
18844 case OPC_FCLE_df:
18845 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18846 break;
18847 case OPC_MSUB_Q_df:
18848 tcg_gen_movi_i32(tdf, df + 1);
18849 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18850 break;
18851 case OPC_FCULE_df:
18852 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18853 break;
18854 case OPC_FEXP2_df:
18855 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18856 break;
18857 case OPC_FSAF_df:
18858 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18859 break;
18860 case OPC_FEXDO_df:
18861 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18862 break;
18863 case OPC_FSUN_df:
18864 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18865 break;
18866 case OPC_FSOR_df:
18867 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18868 break;
18869 case OPC_FSEQ_df:
18870 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18871 break;
18872 case OPC_FTQ_df:
18873 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18874 break;
18875 case OPC_FSUNE_df:
18876 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18877 break;
18878 case OPC_FSUEQ_df:
18879 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18880 break;
18881 case OPC_FSNE_df:
18882 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18883 break;
18884 case OPC_FSLT_df:
18885 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18886 break;
18887 case OPC_FMIN_df:
18888 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18889 break;
18890 case OPC_MULR_Q_df:
18891 tcg_gen_movi_i32(tdf, df + 1);
18892 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18893 break;
18894 case OPC_FSULT_df:
18895 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18896 break;
18897 case OPC_FMIN_A_df:
18898 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18899 break;
18900 case OPC_MADDR_Q_df:
18901 tcg_gen_movi_i32(tdf, df + 1);
18902 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18903 break;
18904 case OPC_FSLE_df:
18905 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18906 break;
18907 case OPC_FMAX_df:
18908 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18909 break;
18910 case OPC_MSUBR_Q_df:
18911 tcg_gen_movi_i32(tdf, df + 1);
18912 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18913 break;
18914 case OPC_FSULE_df:
18915 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18916 break;
18917 case OPC_FMAX_A_df:
18918 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18919 break;
18920 default:
18921 MIPS_INVAL("MSA instruction");
18922 generate_exception_end(ctx, EXCP_RI);
18923 break;
18924 }
18925
18926 tcg_temp_free_i32(twd);
18927 tcg_temp_free_i32(tws);
18928 tcg_temp_free_i32(twt);
18929 tcg_temp_free_i32(tdf);
18930 }
18931
18932 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18933 {
18934 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18935 (op & (0x7 << 18)))
18936 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18937 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18938 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18939 uint8_t df = (ctx->opcode >> 16) & 0x3;
18940 TCGv_i32 twd = tcg_const_i32(wd);
18941 TCGv_i32 tws = tcg_const_i32(ws);
18942 TCGv_i32 twt = tcg_const_i32(wt);
18943 TCGv_i32 tdf = tcg_const_i32(df);
18944
18945 switch (MASK_MSA_2R(ctx->opcode)) {
18946 case OPC_FILL_df:
18947 #if !defined(TARGET_MIPS64)
18948 /* Double format valid only for MIPS64 */
18949 if (df == DF_DOUBLE) {
18950 generate_exception_end(ctx, EXCP_RI);
18951 break;
18952 }
18953 #endif
18954 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18955 break;
18956 case OPC_PCNT_df:
18957 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18958 break;
18959 case OPC_NLOC_df:
18960 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18961 break;
18962 case OPC_NLZC_df:
18963 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18964 break;
18965 default:
18966 MIPS_INVAL("MSA instruction");
18967 generate_exception_end(ctx, EXCP_RI);
18968 break;
18969 }
18970
18971 tcg_temp_free_i32(twd);
18972 tcg_temp_free_i32(tws);
18973 tcg_temp_free_i32(twt);
18974 tcg_temp_free_i32(tdf);
18975 }
18976
18977 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18978 {
18979 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18980 (op & (0xf << 17)))
18981 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18982 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18983 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18984 uint8_t df = (ctx->opcode >> 16) & 0x1;
18985 TCGv_i32 twd = tcg_const_i32(wd);
18986 TCGv_i32 tws = tcg_const_i32(ws);
18987 TCGv_i32 twt = tcg_const_i32(wt);
18988 /* adjust df value for floating-point instruction */
18989 TCGv_i32 tdf = tcg_const_i32(df + 2);
18990
18991 switch (MASK_MSA_2RF(ctx->opcode)) {
18992 case OPC_FCLASS_df:
18993 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18994 break;
18995 case OPC_FTRUNC_S_df:
18996 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18997 break;
18998 case OPC_FTRUNC_U_df:
18999 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
19000 break;
19001 case OPC_FSQRT_df:
19002 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
19003 break;
19004 case OPC_FRSQRT_df:
19005 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
19006 break;
19007 case OPC_FRCP_df:
19008 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
19009 break;
19010 case OPC_FRINT_df:
19011 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
19012 break;
19013 case OPC_FLOG2_df:
19014 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
19015 break;
19016 case OPC_FEXUPL_df:
19017 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
19018 break;
19019 case OPC_FEXUPR_df:
19020 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
19021 break;
19022 case OPC_FFQL_df:
19023 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
19024 break;
19025 case OPC_FFQR_df:
19026 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
19027 break;
19028 case OPC_FTINT_S_df:
19029 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
19030 break;
19031 case OPC_FTINT_U_df:
19032 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
19033 break;
19034 case OPC_FFINT_S_df:
19035 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
19036 break;
19037 case OPC_FFINT_U_df:
19038 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
19039 break;
19040 }
19041
19042 tcg_temp_free_i32(twd);
19043 tcg_temp_free_i32(tws);
19044 tcg_temp_free_i32(twt);
19045 tcg_temp_free_i32(tdf);
19046 }
19047
19048 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
19049 {
19050 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19051 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
19052 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
19053 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19054 TCGv_i32 twd = tcg_const_i32(wd);
19055 TCGv_i32 tws = tcg_const_i32(ws);
19056 TCGv_i32 twt = tcg_const_i32(wt);
19057
19058 switch (MASK_MSA_VEC(ctx->opcode)) {
19059 case OPC_AND_V:
19060 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
19061 break;
19062 case OPC_OR_V:
19063 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
19064 break;
19065 case OPC_NOR_V:
19066 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
19067 break;
19068 case OPC_XOR_V:
19069 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
19070 break;
19071 case OPC_BMNZ_V:
19072 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
19073 break;
19074 case OPC_BMZ_V:
19075 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
19076 break;
19077 case OPC_BSEL_V:
19078 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
19079 break;
19080 default:
19081 MIPS_INVAL("MSA instruction");
19082 generate_exception_end(ctx, EXCP_RI);
19083 break;
19084 }
19085
19086 tcg_temp_free_i32(twd);
19087 tcg_temp_free_i32(tws);
19088 tcg_temp_free_i32(twt);
19089 }
19090
19091 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
19092 {
19093 switch (MASK_MSA_VEC(ctx->opcode)) {
19094 case OPC_AND_V:
19095 case OPC_OR_V:
19096 case OPC_NOR_V:
19097 case OPC_XOR_V:
19098 case OPC_BMNZ_V:
19099 case OPC_BMZ_V:
19100 case OPC_BSEL_V:
19101 gen_msa_vec_v(env, ctx);
19102 break;
19103 case OPC_MSA_2R:
19104 gen_msa_2r(env, ctx);
19105 break;
19106 case OPC_MSA_2RF:
19107 gen_msa_2rf(env, ctx);
19108 break;
19109 default:
19110 MIPS_INVAL("MSA instruction");
19111 generate_exception_end(ctx, EXCP_RI);
19112 break;
19113 }
19114 }
19115
19116 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
19117 {
19118 uint32_t opcode = ctx->opcode;
19119 check_insn(ctx, ASE_MSA);
19120 check_msa_access(ctx);
19121
19122 switch (MASK_MSA_MINOR(opcode)) {
19123 case OPC_MSA_I8_00:
19124 case OPC_MSA_I8_01:
19125 case OPC_MSA_I8_02:
19126 gen_msa_i8(env, ctx);
19127 break;
19128 case OPC_MSA_I5_06:
19129 case OPC_MSA_I5_07:
19130 gen_msa_i5(env, ctx);
19131 break;
19132 case OPC_MSA_BIT_09:
19133 case OPC_MSA_BIT_0A:
19134 gen_msa_bit(env, ctx);
19135 break;
19136 case OPC_MSA_3R_0D:
19137 case OPC_MSA_3R_0E:
19138 case OPC_MSA_3R_0F:
19139 case OPC_MSA_3R_10:
19140 case OPC_MSA_3R_11:
19141 case OPC_MSA_3R_12:
19142 case OPC_MSA_3R_13:
19143 case OPC_MSA_3R_14:
19144 case OPC_MSA_3R_15:
19145 gen_msa_3r(env, ctx);
19146 break;
19147 case OPC_MSA_ELM:
19148 gen_msa_elm(env, ctx);
19149 break;
19150 case OPC_MSA_3RF_1A:
19151 case OPC_MSA_3RF_1B:
19152 case OPC_MSA_3RF_1C:
19153 gen_msa_3rf(env, ctx);
19154 break;
19155 case OPC_MSA_VEC:
19156 gen_msa_vec(env, ctx);
19157 break;
19158 case OPC_LD_B:
19159 case OPC_LD_H:
19160 case OPC_LD_W:
19161 case OPC_LD_D:
19162 case OPC_ST_B:
19163 case OPC_ST_H:
19164 case OPC_ST_W:
19165 case OPC_ST_D:
19166 {
19167 int32_t s10 = sextract32(ctx->opcode, 16, 10);
19168 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
19169 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
19170 uint8_t df = (ctx->opcode >> 0) & 0x3;
19171
19172 TCGv_i32 twd = tcg_const_i32(wd);
19173 TCGv taddr = tcg_temp_new();
19174 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
19175
19176 switch (MASK_MSA_MINOR(opcode)) {
19177 case OPC_LD_B:
19178 gen_helper_msa_ld_b(cpu_env, twd, taddr);
19179 break;
19180 case OPC_LD_H:
19181 gen_helper_msa_ld_h(cpu_env, twd, taddr);
19182 break;
19183 case OPC_LD_W:
19184 gen_helper_msa_ld_w(cpu_env, twd, taddr);
19185 break;
19186 case OPC_LD_D:
19187 gen_helper_msa_ld_d(cpu_env, twd, taddr);
19188 break;
19189 case OPC_ST_B:
19190 gen_helper_msa_st_b(cpu_env, twd, taddr);
19191 break;
19192 case OPC_ST_H:
19193 gen_helper_msa_st_h(cpu_env, twd, taddr);
19194 break;
19195 case OPC_ST_W:
19196 gen_helper_msa_st_w(cpu_env, twd, taddr);
19197 break;
19198 case OPC_ST_D:
19199 gen_helper_msa_st_d(cpu_env, twd, taddr);
19200 break;
19201 }
19202
19203 tcg_temp_free_i32(twd);
19204 tcg_temp_free(taddr);
19205 }
19206 break;
19207 default:
19208 MIPS_INVAL("MSA instruction");
19209 generate_exception_end(ctx, EXCP_RI);
19210 break;
19211 }
19212
19213 }
19214
19215 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
19216 {
19217 int32_t offset;
19218 int rs, rt, rd, sa;
19219 uint32_t op, op1;
19220 int16_t imm;
19221
19222 /* make sure instructions are on a word boundary */
19223 if (ctx->pc & 0x3) {
19224 env->CP0_BadVAddr = ctx->pc;
19225 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
19226 return;
19227 }
19228
19229 /* Handle blikely not taken case */
19230 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
19231 TCGLabel *l1 = gen_new_label();
19232
19233 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
19234 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
19235 gen_goto_tb(ctx, 1, ctx->pc + 4);
19236 gen_set_label(l1);
19237 }
19238
19239 op = MASK_OP_MAJOR(ctx->opcode);
19240 rs = (ctx->opcode >> 21) & 0x1f;
19241 rt = (ctx->opcode >> 16) & 0x1f;
19242 rd = (ctx->opcode >> 11) & 0x1f;
19243 sa = (ctx->opcode >> 6) & 0x1f;
19244 imm = (int16_t)ctx->opcode;
19245 switch (op) {
19246 case OPC_SPECIAL:
19247 decode_opc_special(env, ctx);
19248 break;
19249 case OPC_SPECIAL2:
19250 decode_opc_special2_legacy(env, ctx);
19251 break;
19252 case OPC_SPECIAL3:
19253 decode_opc_special3(env, ctx);
19254 break;
19255 case OPC_REGIMM:
19256 op1 = MASK_REGIMM(ctx->opcode);
19257 switch (op1) {
19258 case OPC_BLTZL: /* REGIMM branches */
19259 case OPC_BGEZL:
19260 case OPC_BLTZALL:
19261 case OPC_BGEZALL:
19262 check_insn(ctx, ISA_MIPS2);
19263 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19264 /* Fallthrough */
19265 case OPC_BLTZ:
19266 case OPC_BGEZ:
19267 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19268 break;
19269 case OPC_BLTZAL:
19270 case OPC_BGEZAL:
19271 if (ctx->insn_flags & ISA_MIPS32R6) {
19272 if (rs == 0) {
19273 /* OPC_NAL, OPC_BAL */
19274 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
19275 } else {
19276 generate_exception_end(ctx, EXCP_RI);
19277 }
19278 } else {
19279 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19280 }
19281 break;
19282 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19283 case OPC_TNEI:
19284 check_insn(ctx, ISA_MIPS2);
19285 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19286 gen_trap(ctx, op1, rs, -1, imm);
19287 break;
19288 case OPC_SIGRIE:
19289 check_insn(ctx, ISA_MIPS32R6);
19290 generate_exception_end(ctx, EXCP_RI);
19291 break;
19292 case OPC_SYNCI:
19293 check_insn(ctx, ISA_MIPS32R2);
19294 /* Break the TB to be able to sync copied instructions
19295 immediately */
19296 ctx->bstate = BS_STOP;
19297 break;
19298 case OPC_BPOSGE32: /* MIPS DSP branch */
19299 #if defined(TARGET_MIPS64)
19300 case OPC_BPOSGE64:
19301 #endif
19302 check_dsp(ctx);
19303 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
19304 break;
19305 #if defined(TARGET_MIPS64)
19306 case OPC_DAHI:
19307 check_insn(ctx, ISA_MIPS32R6);
19308 check_mips_64(ctx);
19309 if (rs != 0) {
19310 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19311 }
19312 break;
19313 case OPC_DATI:
19314 check_insn(ctx, ISA_MIPS32R6);
19315 check_mips_64(ctx);
19316 if (rs != 0) {
19317 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19318 }
19319 break;
19320 #endif
19321 default: /* Invalid */
19322 MIPS_INVAL("regimm");
19323 generate_exception_end(ctx, EXCP_RI);
19324 break;
19325 }
19326 break;
19327 case OPC_CP0:
19328 check_cp0_enabled(ctx);
19329 op1 = MASK_CP0(ctx->opcode);
19330 switch (op1) {
19331 case OPC_MFC0:
19332 case OPC_MTC0:
19333 case OPC_MFTR:
19334 case OPC_MTTR:
19335 case OPC_MFHC0:
19336 case OPC_MTHC0:
19337 #if defined(TARGET_MIPS64)
19338 case OPC_DMFC0:
19339 case OPC_DMTC0:
19340 #endif
19341 #ifndef CONFIG_USER_ONLY
19342 gen_cp0(env, ctx, op1, rt, rd);
19343 #endif /* !CONFIG_USER_ONLY */
19344 break;
19345 case OPC_C0_FIRST ... OPC_C0_LAST:
19346 #ifndef CONFIG_USER_ONLY
19347 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19348 #endif /* !CONFIG_USER_ONLY */
19349 break;
19350 case OPC_MFMC0:
19351 #ifndef CONFIG_USER_ONLY
19352 {
19353 uint32_t op2;
19354 TCGv t0 = tcg_temp_new();
19355
19356 op2 = MASK_MFMC0(ctx->opcode);
19357 switch (op2) {
19358 case OPC_DMT:
19359 check_insn(ctx, ASE_MT);
19360 gen_helper_dmt(t0);
19361 gen_store_gpr(t0, rt);
19362 break;
19363 case OPC_EMT:
19364 check_insn(ctx, ASE_MT);
19365 gen_helper_emt(t0);
19366 gen_store_gpr(t0, rt);
19367 break;
19368 case OPC_DVPE:
19369 check_insn(ctx, ASE_MT);
19370 gen_helper_dvpe(t0, cpu_env);
19371 gen_store_gpr(t0, rt);
19372 break;
19373 case OPC_EVPE:
19374 check_insn(ctx, ASE_MT);
19375 gen_helper_evpe(t0, cpu_env);
19376 gen_store_gpr(t0, rt);
19377 break;
19378 case OPC_DVP:
19379 check_insn(ctx, ISA_MIPS32R6);
19380 if (ctx->vp) {
19381 gen_helper_dvp(t0, cpu_env);
19382 gen_store_gpr(t0, rt);
19383 }
19384 break;
19385 case OPC_EVP:
19386 check_insn(ctx, ISA_MIPS32R6);
19387 if (ctx->vp) {
19388 gen_helper_evp(t0, cpu_env);
19389 gen_store_gpr(t0, rt);
19390 }
19391 break;
19392 case OPC_DI:
19393 check_insn(ctx, ISA_MIPS32R2);
19394 save_cpu_state(ctx, 1);
19395 gen_helper_di(t0, cpu_env);
19396 gen_store_gpr(t0, rt);
19397 /* Stop translation as we may have switched
19398 the execution mode. */
19399 ctx->bstate = BS_STOP;
19400 break;
19401 case OPC_EI:
19402 check_insn(ctx, ISA_MIPS32R2);
19403 save_cpu_state(ctx, 1);
19404 gen_helper_ei(t0, cpu_env);
19405 gen_store_gpr(t0, rt);
19406 /* Stop translation as we may have switched
19407 the execution mode. */
19408 ctx->bstate = BS_STOP;
19409 break;
19410 default: /* Invalid */
19411 MIPS_INVAL("mfmc0");
19412 generate_exception_end(ctx, EXCP_RI);
19413 break;
19414 }
19415 tcg_temp_free(t0);
19416 }
19417 #endif /* !CONFIG_USER_ONLY */
19418 break;
19419 case OPC_RDPGPR:
19420 check_insn(ctx, ISA_MIPS32R2);
19421 gen_load_srsgpr(rt, rd);
19422 break;
19423 case OPC_WRPGPR:
19424 check_insn(ctx, ISA_MIPS32R2);
19425 gen_store_srsgpr(rt, rd);
19426 break;
19427 default:
19428 MIPS_INVAL("cp0");
19429 generate_exception_end(ctx, EXCP_RI);
19430 break;
19431 }
19432 break;
19433 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19434 if (ctx->insn_flags & ISA_MIPS32R6) {
19435 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19436 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19437 } else {
19438 /* OPC_ADDI */
19439 /* Arithmetic with immediate opcode */
19440 gen_arith_imm(ctx, op, rt, rs, imm);
19441 }
19442 break;
19443 case OPC_ADDIU:
19444 gen_arith_imm(ctx, op, rt, rs, imm);
19445 break;
19446 case OPC_SLTI: /* Set on less than with immediate opcode */
19447 case OPC_SLTIU:
19448 gen_slt_imm(ctx, op, rt, rs, imm);
19449 break;
19450 case OPC_ANDI: /* Arithmetic with immediate opcode */
19451 case OPC_LUI: /* OPC_AUI */
19452 case OPC_ORI:
19453 case OPC_XORI:
19454 gen_logic_imm(ctx, op, rt, rs, imm);
19455 break;
19456 case OPC_J ... OPC_JAL: /* Jump */
19457 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19458 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19459 break;
19460 /* Branch */
19461 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19462 if (ctx->insn_flags & ISA_MIPS32R6) {
19463 if (rt == 0) {
19464 generate_exception_end(ctx, EXCP_RI);
19465 break;
19466 }
19467 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19468 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19469 } else {
19470 /* OPC_BLEZL */
19471 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19472 }
19473 break;
19474 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19475 if (ctx->insn_flags & ISA_MIPS32R6) {
19476 if (rt == 0) {
19477 generate_exception_end(ctx, EXCP_RI);
19478 break;
19479 }
19480 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19481 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19482 } else {
19483 /* OPC_BGTZL */
19484 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19485 }
19486 break;
19487 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19488 if (rt == 0) {
19489 /* OPC_BLEZ */
19490 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19491 } else {
19492 check_insn(ctx, ISA_MIPS32R6);
19493 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19494 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19495 }
19496 break;
19497 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19498 if (rt == 0) {
19499 /* OPC_BGTZ */
19500 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19501 } else {
19502 check_insn(ctx, ISA_MIPS32R6);
19503 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19504 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19505 }
19506 break;
19507 case OPC_BEQL:
19508 case OPC_BNEL:
19509 check_insn(ctx, ISA_MIPS2);
19510 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19511 /* Fallthrough */
19512 case OPC_BEQ:
19513 case OPC_BNE:
19514 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19515 break;
19516 case OPC_LL: /* Load and stores */
19517 check_insn(ctx, ISA_MIPS2);
19518 /* Fallthrough */
19519 case OPC_LWL:
19520 case OPC_LWR:
19521 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19522 /* Fallthrough */
19523 case OPC_LB ... OPC_LH:
19524 case OPC_LW ... OPC_LHU:
19525 gen_ld(ctx, op, rt, rs, imm);
19526 break;
19527 case OPC_SWL:
19528 case OPC_SWR:
19529 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19530 /* fall through */
19531 case OPC_SB ... OPC_SH:
19532 case OPC_SW:
19533 gen_st(ctx, op, rt, rs, imm);
19534 break;
19535 case OPC_SC:
19536 check_insn(ctx, ISA_MIPS2);
19537 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19538 gen_st_cond(ctx, op, rt, rs, imm);
19539 break;
19540 case OPC_CACHE:
19541 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19542 check_cp0_enabled(ctx);
19543 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19544 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
19545 gen_cache_operation(ctx, rt, rs, imm);
19546 }
19547 /* Treat as NOP. */
19548 break;
19549 case OPC_PREF:
19550 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19551 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19552 /* Treat as NOP. */
19553 break;
19554
19555 /* Floating point (COP1). */
19556 case OPC_LWC1:
19557 case OPC_LDC1:
19558 case OPC_SWC1:
19559 case OPC_SDC1:
19560 gen_cop1_ldst(ctx, op, rt, rs, imm);
19561 break;
19562
19563 case OPC_CP1:
19564 op1 = MASK_CP1(ctx->opcode);
19565
19566 switch (op1) {
19567 case OPC_MFHC1:
19568 case OPC_MTHC1:
19569 check_cp1_enabled(ctx);
19570 check_insn(ctx, ISA_MIPS32R2);
19571 case OPC_MFC1:
19572 case OPC_CFC1:
19573 case OPC_MTC1:
19574 case OPC_CTC1:
19575 check_cp1_enabled(ctx);
19576 gen_cp1(ctx, op1, rt, rd);
19577 break;
19578 #if defined(TARGET_MIPS64)
19579 case OPC_DMFC1:
19580 case OPC_DMTC1:
19581 check_cp1_enabled(ctx);
19582 check_insn(ctx, ISA_MIPS3);
19583 check_mips_64(ctx);
19584 gen_cp1(ctx, op1, rt, rd);
19585 break;
19586 #endif
19587 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19588 check_cp1_enabled(ctx);
19589 if (ctx->insn_flags & ISA_MIPS32R6) {
19590 /* OPC_BC1EQZ */
19591 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19592 rt, imm << 2, 4);
19593 } else {
19594 /* OPC_BC1ANY2 */
19595 check_cop1x(ctx);
19596 check_insn(ctx, ASE_MIPS3D);
19597 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19598 (rt >> 2) & 0x7, imm << 2);
19599 }
19600 break;
19601 case OPC_BC1NEZ:
19602 check_cp1_enabled(ctx);
19603 check_insn(ctx, ISA_MIPS32R6);
19604 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19605 rt, imm << 2, 4);
19606 break;
19607 case OPC_BC1ANY4:
19608 check_cp1_enabled(ctx);
19609 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19610 check_cop1x(ctx);
19611 check_insn(ctx, ASE_MIPS3D);
19612 /* fall through */
19613 case OPC_BC1:
19614 check_cp1_enabled(ctx);
19615 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19616 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19617 (rt >> 2) & 0x7, imm << 2);
19618 break;
19619 case OPC_PS_FMT:
19620 check_ps(ctx);
19621 /* fall through */
19622 case OPC_S_FMT:
19623 case OPC_D_FMT:
19624 check_cp1_enabled(ctx);
19625 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19626 (imm >> 8) & 0x7);
19627 break;
19628 case OPC_W_FMT:
19629 case OPC_L_FMT:
19630 {
19631 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19632 check_cp1_enabled(ctx);
19633 if (ctx->insn_flags & ISA_MIPS32R6) {
19634 switch (r6_op) {
19635 case R6_OPC_CMP_AF_S:
19636 case R6_OPC_CMP_UN_S:
19637 case R6_OPC_CMP_EQ_S:
19638 case R6_OPC_CMP_UEQ_S:
19639 case R6_OPC_CMP_LT_S:
19640 case R6_OPC_CMP_ULT_S:
19641 case R6_OPC_CMP_LE_S:
19642 case R6_OPC_CMP_ULE_S:
19643 case R6_OPC_CMP_SAF_S:
19644 case R6_OPC_CMP_SUN_S:
19645 case R6_OPC_CMP_SEQ_S:
19646 case R6_OPC_CMP_SEUQ_S:
19647 case R6_OPC_CMP_SLT_S:
19648 case R6_OPC_CMP_SULT_S:
19649 case R6_OPC_CMP_SLE_S:
19650 case R6_OPC_CMP_SULE_S:
19651 case R6_OPC_CMP_OR_S:
19652 case R6_OPC_CMP_UNE_S:
19653 case R6_OPC_CMP_NE_S:
19654 case R6_OPC_CMP_SOR_S:
19655 case R6_OPC_CMP_SUNE_S:
19656 case R6_OPC_CMP_SNE_S:
19657 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19658 break;
19659 case R6_OPC_CMP_AF_D:
19660 case R6_OPC_CMP_UN_D:
19661 case R6_OPC_CMP_EQ_D:
19662 case R6_OPC_CMP_UEQ_D:
19663 case R6_OPC_CMP_LT_D:
19664 case R6_OPC_CMP_ULT_D:
19665 case R6_OPC_CMP_LE_D:
19666 case R6_OPC_CMP_ULE_D:
19667 case R6_OPC_CMP_SAF_D:
19668 case R6_OPC_CMP_SUN_D:
19669 case R6_OPC_CMP_SEQ_D:
19670 case R6_OPC_CMP_SEUQ_D:
19671 case R6_OPC_CMP_SLT_D:
19672 case R6_OPC_CMP_SULT_D:
19673 case R6_OPC_CMP_SLE_D:
19674 case R6_OPC_CMP_SULE_D:
19675 case R6_OPC_CMP_OR_D:
19676 case R6_OPC_CMP_UNE_D:
19677 case R6_OPC_CMP_NE_D:
19678 case R6_OPC_CMP_SOR_D:
19679 case R6_OPC_CMP_SUNE_D:
19680 case R6_OPC_CMP_SNE_D:
19681 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19682 break;
19683 default:
19684 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19685 rt, rd, sa, (imm >> 8) & 0x7);
19686
19687 break;
19688 }
19689 } else {
19690 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19691 (imm >> 8) & 0x7);
19692 }
19693 break;
19694 }
19695 case OPC_BZ_V:
19696 case OPC_BNZ_V:
19697 case OPC_BZ_B:
19698 case OPC_BZ_H:
19699 case OPC_BZ_W:
19700 case OPC_BZ_D:
19701 case OPC_BNZ_B:
19702 case OPC_BNZ_H:
19703 case OPC_BNZ_W:
19704 case OPC_BNZ_D:
19705 check_insn(ctx, ASE_MSA);
19706 gen_msa_branch(env, ctx, op1);
19707 break;
19708 default:
19709 MIPS_INVAL("cp1");
19710 generate_exception_end(ctx, EXCP_RI);
19711 break;
19712 }
19713 break;
19714
19715 /* Compact branches [R6] and COP2 [non-R6] */
19716 case OPC_BC: /* OPC_LWC2 */
19717 case OPC_BALC: /* OPC_SWC2 */
19718 if (ctx->insn_flags & ISA_MIPS32R6) {
19719 /* OPC_BC, OPC_BALC */
19720 gen_compute_compact_branch(ctx, op, 0, 0,
19721 sextract32(ctx->opcode << 2, 0, 28));
19722 } else {
19723 /* OPC_LWC2, OPC_SWC2 */
19724 /* COP2: Not implemented. */
19725 generate_exception_err(ctx, EXCP_CpU, 2);
19726 }
19727 break;
19728 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19729 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19730 if (ctx->insn_flags & ISA_MIPS32R6) {
19731 if (rs != 0) {
19732 /* OPC_BEQZC, OPC_BNEZC */
19733 gen_compute_compact_branch(ctx, op, rs, 0,
19734 sextract32(ctx->opcode << 2, 0, 23));
19735 } else {
19736 /* OPC_JIC, OPC_JIALC */
19737 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19738 }
19739 } else {
19740 /* OPC_LWC2, OPC_SWC2 */
19741 /* COP2: Not implemented. */
19742 generate_exception_err(ctx, EXCP_CpU, 2);
19743 }
19744 break;
19745 case OPC_CP2:
19746 check_insn(ctx, INSN_LOONGSON2F);
19747 /* Note that these instructions use different fields. */
19748 gen_loongson_multimedia(ctx, sa, rd, rt);
19749 break;
19750
19751 case OPC_CP3:
19752 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19753 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19754 check_cp1_enabled(ctx);
19755 op1 = MASK_CP3(ctx->opcode);
19756 switch (op1) {
19757 case OPC_LUXC1:
19758 case OPC_SUXC1:
19759 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19760 /* Fallthrough */
19761 case OPC_LWXC1:
19762 case OPC_LDXC1:
19763 case OPC_SWXC1:
19764 case OPC_SDXC1:
19765 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19766 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19767 break;
19768 case OPC_PREFX:
19769 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19770 /* Treat as NOP. */
19771 break;
19772 case OPC_ALNV_PS:
19773 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19774 /* Fallthrough */
19775 case OPC_MADD_S:
19776 case OPC_MADD_D:
19777 case OPC_MADD_PS:
19778 case OPC_MSUB_S:
19779 case OPC_MSUB_D:
19780 case OPC_MSUB_PS:
19781 case OPC_NMADD_S:
19782 case OPC_NMADD_D:
19783 case OPC_NMADD_PS:
19784 case OPC_NMSUB_S:
19785 case OPC_NMSUB_D:
19786 case OPC_NMSUB_PS:
19787 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19788 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19789 break;
19790 default:
19791 MIPS_INVAL("cp3");
19792 generate_exception_end(ctx, EXCP_RI);
19793 break;
19794 }
19795 } else {
19796 generate_exception_err(ctx, EXCP_CpU, 1);
19797 }
19798 break;
19799
19800 #if defined(TARGET_MIPS64)
19801 /* MIPS64 opcodes */
19802 case OPC_LDL ... OPC_LDR:
19803 case OPC_LLD:
19804 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19805 /* fall through */
19806 case OPC_LWU:
19807 case OPC_LD:
19808 check_insn(ctx, ISA_MIPS3);
19809 check_mips_64(ctx);
19810 gen_ld(ctx, op, rt, rs, imm);
19811 break;
19812 case OPC_SDL ... OPC_SDR:
19813 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19814 /* fall through */
19815 case OPC_SD:
19816 check_insn(ctx, ISA_MIPS3);
19817 check_mips_64(ctx);
19818 gen_st(ctx, op, rt, rs, imm);
19819 break;
19820 case OPC_SCD:
19821 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19822 check_insn(ctx, ISA_MIPS3);
19823 check_mips_64(ctx);
19824 gen_st_cond(ctx, op, rt, rs, imm);
19825 break;
19826 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19827 if (ctx->insn_flags & ISA_MIPS32R6) {
19828 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19829 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19830 } else {
19831 /* OPC_DADDI */
19832 check_insn(ctx, ISA_MIPS3);
19833 check_mips_64(ctx);
19834 gen_arith_imm(ctx, op, rt, rs, imm);
19835 }
19836 break;
19837 case OPC_DADDIU:
19838 check_insn(ctx, ISA_MIPS3);
19839 check_mips_64(ctx);
19840 gen_arith_imm(ctx, op, rt, rs, imm);
19841 break;
19842 #else
19843 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19844 if (ctx->insn_flags & ISA_MIPS32R6) {
19845 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19846 } else {
19847 MIPS_INVAL("major opcode");
19848 generate_exception_end(ctx, EXCP_RI);
19849 }
19850 break;
19851 #endif
19852 case OPC_DAUI: /* OPC_JALX */
19853 if (ctx->insn_flags & ISA_MIPS32R6) {
19854 #if defined(TARGET_MIPS64)
19855 /* OPC_DAUI */
19856 check_mips_64(ctx);
19857 if (rs == 0) {
19858 generate_exception(ctx, EXCP_RI);
19859 } else if (rt != 0) {
19860 TCGv t0 = tcg_temp_new();
19861 gen_load_gpr(t0, rs);
19862 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19863 tcg_temp_free(t0);
19864 }
19865 #else
19866 generate_exception_end(ctx, EXCP_RI);
19867 MIPS_INVAL("major opcode");
19868 #endif
19869 } else {
19870 /* OPC_JALX */
19871 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19872 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19873 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19874 }
19875 break;
19876 case OPC_MSA: /* OPC_MDMX */
19877 /* MDMX: Not implemented. */
19878 gen_msa(env, ctx);
19879 break;
19880 case OPC_PCREL:
19881 check_insn(ctx, ISA_MIPS32R6);
19882 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
19883 break;
19884 default: /* Invalid */
19885 MIPS_INVAL("major opcode");
19886 generate_exception_end(ctx, EXCP_RI);
19887 break;
19888 }
19889 }
19890
19891 void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
19892 {
19893 MIPSCPU *cpu = mips_env_get_cpu(env);
19894 CPUState *cs = CPU(cpu);
19895 DisasContext ctx;
19896 target_ulong pc_start;
19897 target_ulong next_page_start;
19898 int num_insns;
19899 int max_insns;
19900 int insn_bytes;
19901 int is_slot;
19902
19903 pc_start = tb->pc;
19904 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19905 ctx.pc = pc_start;
19906 ctx.saved_pc = -1;
19907 ctx.singlestep_enabled = cs->singlestep_enabled;
19908 ctx.insn_flags = env->insn_flags;
19909 ctx.CP0_Config1 = env->CP0_Config1;
19910 ctx.tb = tb;
19911 ctx.bstate = BS_NONE;
19912 ctx.btarget = 0;
19913 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19914 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19915 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19916 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19917 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19918 ctx.PAMask = env->PAMask;
19919 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19920 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
19921 ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
19922 /* Restore delay slot state from the tb context. */
19923 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19924 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
19925 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19926 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
19927 ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
19928 ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
19929 ctx.nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
19930 ctx.abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
19931 restore_cpu_state(env, &ctx);
19932 #ifdef CONFIG_USER_ONLY
19933 ctx.mem_idx = MIPS_HFLAG_UM;
19934 #else
19935 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19936 #endif
19937 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19938 MO_UNALN : MO_ALIGN;
19939 num_insns = 0;
19940 max_insns = tb->cflags & CF_COUNT_MASK;
19941 if (max_insns == 0) {
19942 max_insns = CF_COUNT_MASK;
19943 }
19944 if (max_insns > TCG_MAX_INSNS) {
19945 max_insns = TCG_MAX_INSNS;
19946 }
19947
19948 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19949 gen_tb_start(tb);
19950 while (ctx.bstate == BS_NONE) {
19951 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
19952 num_insns++;
19953
19954 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19955 save_cpu_state(&ctx, 1);
19956 ctx.bstate = BS_BRANCH;
19957 gen_helper_raise_exception_debug(cpu_env);
19958 /* The address covered by the breakpoint must be included in
19959 [tb->pc, tb->pc + tb->size) in order to for it to be
19960 properly cleared -- thus we increment the PC here so that
19961 the logic setting tb->size below does the right thing. */
19962 ctx.pc += 4;
19963 goto done_generating;
19964 }
19965
19966 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
19967 gen_io_start();
19968 }
19969
19970 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19971 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19972 ctx.opcode = cpu_ldl_code(env, ctx.pc);
19973 insn_bytes = 4;
19974 decode_opc(env, &ctx);
19975 } else if (ctx.insn_flags & ASE_MICROMIPS) {
19976 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19977 insn_bytes = decode_micromips_opc(env, &ctx);
19978 } else if (ctx.insn_flags & ASE_MIPS16) {
19979 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19980 insn_bytes = decode_mips16_opc(env, &ctx);
19981 } else {
19982 generate_exception_end(&ctx, EXCP_RI);
19983 break;
19984 }
19985
19986 if (ctx.hflags & MIPS_HFLAG_BMASK) {
19987 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19988 MIPS_HFLAG_FBNSLOT))) {
19989 /* force to generate branch as there is neither delay nor
19990 forbidden slot */
19991 is_slot = 1;
19992 }
19993 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19994 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19995 /* Force to generate branch as microMIPS R6 doesn't restrict
19996 branches in the forbidden slot. */
19997 is_slot = 1;
19998 }
19999 }
20000 if (is_slot) {
20001 gen_branch(&ctx, insn_bytes);
20002 }
20003 ctx.pc += insn_bytes;
20004
20005 /* Execute a branch and its delay slot as a single instruction.
20006 This is what GDB expects and is consistent with what the
20007 hardware does (e.g. if a delay slot instruction faults, the
20008 reported PC is the PC of the branch). */
20009 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
20010 break;
20011 }
20012
20013 if (ctx.pc >= next_page_start) {
20014 break;
20015 }
20016
20017 if (tcg_op_buf_full()) {
20018 break;
20019 }
20020
20021 if (num_insns >= max_insns)
20022 break;
20023
20024 if (singlestep)
20025 break;
20026 }
20027 if (tb->cflags & CF_LAST_IO) {
20028 gen_io_end();
20029 }
20030 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
20031 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
20032 gen_helper_raise_exception_debug(cpu_env);
20033 } else {
20034 switch (ctx.bstate) {
20035 case BS_STOP:
20036 gen_goto_tb(&ctx, 0, ctx.pc);
20037 break;
20038 case BS_NONE:
20039 save_cpu_state(&ctx, 0);
20040 gen_goto_tb(&ctx, 0, ctx.pc);
20041 break;
20042 case BS_EXCP:
20043 tcg_gen_exit_tb(0);
20044 break;
20045 case BS_BRANCH:
20046 default:
20047 break;
20048 }
20049 }
20050 done_generating:
20051 gen_tb_end(tb, num_insns);
20052
20053 tb->size = ctx.pc - pc_start;
20054 tb->icount = num_insns;
20055
20056 #ifdef DEBUG_DISAS
20057 LOG_DISAS("\n");
20058 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
20059 && qemu_log_in_addr_range(pc_start)) {
20060 qemu_log_lock();
20061 qemu_log("IN: %s\n", lookup_symbol(pc_start));
20062 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
20063 qemu_log("\n");
20064 qemu_log_unlock();
20065 }
20066 #endif
20067 }
20068
20069 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
20070 int flags)
20071 {
20072 int i;
20073 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
20074
20075 #define printfpr(fp) \
20076 do { \
20077 if (is_fpu64) \
20078 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20079 " fd:%13g fs:%13g psu: %13g\n", \
20080 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20081 (double)(fp)->fd, \
20082 (double)(fp)->fs[FP_ENDIAN_IDX], \
20083 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20084 else { \
20085 fpr_t tmp; \
20086 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20087 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20088 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20089 " fd:%13g fs:%13g psu:%13g\n", \
20090 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20091 (double)tmp.fd, \
20092 (double)tmp.fs[FP_ENDIAN_IDX], \
20093 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20094 } \
20095 } while(0)
20096
20097
20098 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20099 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
20100 get_float_exception_flags(&env->active_fpu.fp_status));
20101 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
20102 fpu_fprintf(f, "%3s: ", fregnames[i]);
20103 printfpr(&env->active_fpu.fpr[i]);
20104 }
20105
20106 #undef printfpr
20107 }
20108
20109 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
20110 int flags)
20111 {
20112 MIPSCPU *cpu = MIPS_CPU(cs);
20113 CPUMIPSState *env = &cpu->env;
20114 int i;
20115
20116 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
20117 " LO=0x" TARGET_FMT_lx " ds %04x "
20118 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
20119 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
20120 env->hflags, env->btarget, env->bcond);
20121 for (i = 0; i < 32; i++) {
20122 if ((i & 3) == 0)
20123 cpu_fprintf(f, "GPR%02d:", i);
20124 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
20125 if ((i & 3) == 3)
20126 cpu_fprintf(f, "\n");
20127 }
20128
20129 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
20130 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
20131 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20132 PRIx64 "\n",
20133 env->CP0_Config0, env->CP0_Config1, env->lladdr);
20134 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
20135 env->CP0_Config2, env->CP0_Config3);
20136 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
20137 env->CP0_Config4, env->CP0_Config5);
20138 if (env->hflags & MIPS_HFLAG_FPU)
20139 fpu_dump_state(env, f, cpu_fprintf, flags);
20140 }
20141
20142 void mips_tcg_init(void)
20143 {
20144 int i;
20145 static int inited;
20146
20147 /* Initialize various static tables. */
20148 if (inited)
20149 return;
20150
20151 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
20152 tcg_ctx.tcg_env = cpu_env;
20153
20154 TCGV_UNUSED(cpu_gpr[0]);
20155 for (i = 1; i < 32; i++)
20156 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
20157 offsetof(CPUMIPSState, active_tc.gpr[i]),
20158 regnames[i]);
20159
20160 for (i = 0; i < 32; i++) {
20161 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
20162 msa_wr_d[i * 2] =
20163 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
20164 /* The scalar floating-point unit (FPU) registers are mapped on
20165 * the MSA vector registers. */
20166 fpu_f64[i] = msa_wr_d[i * 2];
20167 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
20168 msa_wr_d[i * 2 + 1] =
20169 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
20170 }
20171
20172 cpu_PC = tcg_global_mem_new(cpu_env,
20173 offsetof(CPUMIPSState, active_tc.PC), "PC");
20174 for (i = 0; i < MIPS_DSP_ACC; i++) {
20175 cpu_HI[i] = tcg_global_mem_new(cpu_env,
20176 offsetof(CPUMIPSState, active_tc.HI[i]),
20177 regnames_HI[i]);
20178 cpu_LO[i] = tcg_global_mem_new(cpu_env,
20179 offsetof(CPUMIPSState, active_tc.LO[i]),
20180 regnames_LO[i]);
20181 }
20182 cpu_dspctrl = tcg_global_mem_new(cpu_env,
20183 offsetof(CPUMIPSState, active_tc.DSPControl),
20184 "DSPControl");
20185 bcond = tcg_global_mem_new(cpu_env,
20186 offsetof(CPUMIPSState, bcond), "bcond");
20187 btarget = tcg_global_mem_new(cpu_env,
20188 offsetof(CPUMIPSState, btarget), "btarget");
20189 hflags = tcg_global_mem_new_i32(cpu_env,
20190 offsetof(CPUMIPSState, hflags), "hflags");
20191
20192 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
20193 offsetof(CPUMIPSState, active_fpu.fcr0),
20194 "fcr0");
20195 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
20196 offsetof(CPUMIPSState, active_fpu.fcr31),
20197 "fcr31");
20198
20199 inited = 1;
20200 }
20201
20202 #include "translate_init.c"
20203
20204 MIPSCPU *cpu_mips_init(const char *cpu_model)
20205 {
20206 MIPSCPU *cpu;
20207 CPUMIPSState *env;
20208 const mips_def_t *def;
20209
20210 def = cpu_mips_find_by_name(cpu_model);
20211 if (!def)
20212 return NULL;
20213 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
20214 env = &cpu->env;
20215 env->cpu_model = def;
20216 env->exception_base = (int32_t)0xBFC00000;
20217
20218 #ifndef CONFIG_USER_ONLY
20219 mmu_init(env, def);
20220 #endif
20221 fpu_init(env, def);
20222 mvp_init(env, def);
20223
20224 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
20225
20226 return cpu;
20227 }
20228
20229 bool cpu_supports_cps_smp(const char *cpu_model)
20230 {
20231 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20232 if (!def) {
20233 return false;
20234 }
20235
20236 return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
20237 }
20238
20239 bool cpu_supports_isa(const char *cpu_model, unsigned int isa)
20240 {
20241 const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
20242 if (!def) {
20243 return false;
20244 }
20245
20246 return (def->insn_flags & isa) != 0;
20247 }
20248
20249 void cpu_set_exception_base(int vp_index, target_ulong address)
20250 {
20251 MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
20252 vp->env.exception_base = address;
20253 }
20254
20255 void cpu_state_reset(CPUMIPSState *env)
20256 {
20257 MIPSCPU *cpu = mips_env_get_cpu(env);
20258 CPUState *cs = CPU(cpu);
20259
20260 /* Reset registers to their default values */
20261 env->CP0_PRid = env->cpu_model->CP0_PRid;
20262 env->CP0_Config0 = env->cpu_model->CP0_Config0;
20263 #ifdef TARGET_WORDS_BIGENDIAN
20264 env->CP0_Config0 |= (1 << CP0C0_BE);
20265 #endif
20266 env->CP0_Config1 = env->cpu_model->CP0_Config1;
20267 env->CP0_Config2 = env->cpu_model->CP0_Config2;
20268 env->CP0_Config3 = env->cpu_model->CP0_Config3;
20269 env->CP0_Config4 = env->cpu_model->CP0_Config4;
20270 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
20271 env->CP0_Config5 = env->cpu_model->CP0_Config5;
20272 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
20273 env->CP0_Config6 = env->cpu_model->CP0_Config6;
20274 env->CP0_Config7 = env->cpu_model->CP0_Config7;
20275 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20276 << env->cpu_model->CP0_LLAddr_shift;
20277 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
20278 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20279 env->CCRes = env->cpu_model->CCRes;
20280 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20281 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20282 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20283 env->current_tc = 0;
20284 env->SEGBITS = env->cpu_model->SEGBITS;
20285 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20286 #if defined(TARGET_MIPS64)
20287 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20288 env->SEGMask |= 3ULL << 62;
20289 }
20290 #endif
20291 env->PABITS = env->cpu_model->PABITS;
20292 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20293 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20294 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20295 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20296 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20297 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20298 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20299 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20300 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20301 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
20302 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20303 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
20304 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
20305 env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
20306 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
20307 env->msair = env->cpu_model->MSAIR;
20308 env->insn_flags = env->cpu_model->insn_flags;
20309
20310 #if defined(CONFIG_USER_ONLY)
20311 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
20312 # ifdef TARGET_MIPS64
20313 /* Enable 64-bit register mode. */
20314 env->CP0_Status |= (1 << CP0St_PX);
20315 # endif
20316 # ifdef TARGET_ABI_MIPSN64
20317 /* Enable 64-bit address mode. */
20318 env->CP0_Status |= (1 << CP0St_UX);
20319 # endif
20320 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20321 hardware registers. */
20322 env->CP0_HWREna |= 0x0000000F;
20323 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
20324 env->CP0_Status |= (1 << CP0St_CU1);
20325 }
20326 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20327 env->CP0_Status |= (1 << CP0St_MX);
20328 }
20329 # if defined(TARGET_MIPS64)
20330 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20331 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20332 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
20333 env->CP0_Status |= (1 << CP0St_FR);
20334 }
20335 # endif
20336 #else
20337 if (env->hflags & MIPS_HFLAG_BMASK) {
20338 /* If the exception was raised from a delay slot,
20339 come back to the jump. */
20340 env->CP0_ErrorEPC = (env->active_tc.PC
20341 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
20342 } else {
20343 env->CP0_ErrorEPC = env->active_tc.PC;
20344 }
20345 env->active_tc.PC = env->exception_base;
20346 env->CP0_Random = env->tlb->nb_tlb - 1;
20347 env->tlb->tlb_in_use = env->tlb->nb_tlb;
20348 env->CP0_Wired = 0;
20349 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
20350 env->CP0_EBase = (cs->cpu_index & 0x3FF);
20351 if (kvm_enabled()) {
20352 env->CP0_EBase |= 0x40000000;
20353 } else {
20354 env->CP0_EBase |= 0x80000000;
20355 }
20356 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20357 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20358 }
20359 env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
20360 0x3ff : 0xff;
20361 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20362 /* vectored interrupts not implemented, timer on int 7,
20363 no performance counters. */
20364 env->CP0_IntCtl = 0xe0000000;
20365 {
20366 int i;
20367
20368 for (i = 0; i < 7; i++) {
20369 env->CP0_WatchLo[i] = 0;
20370 env->CP0_WatchHi[i] = 0x80000000;
20371 }
20372 env->CP0_WatchLo[7] = 0;
20373 env->CP0_WatchHi[7] = 0;
20374 }
20375 /* Count register increments in debug mode, EJTAG version 1 */
20376 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
20377
20378 cpu_mips_store_count(env, 1);
20379
20380 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20381 int i;
20382
20383 /* Only TC0 on VPE 0 starts as active. */
20384 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20385 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20386 env->tcs[i].CP0_TCHalt = 1;
20387 }
20388 env->active_tc.CP0_TCHalt = 1;
20389 cs->halted = 1;
20390
20391 if (cs->cpu_index == 0) {
20392 /* VPE0 starts up enabled. */
20393 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20394 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20395
20396 /* TC0 starts up unhalted. */
20397 cs->halted = 0;
20398 env->active_tc.CP0_TCHalt = 0;
20399 env->tcs[0].CP0_TCHalt = 0;
20400 /* With thread 0 active. */
20401 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20402 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20403 }
20404 }
20405 #endif
20406 if ((env->insn_flags & ISA_MIPS32R6) &&
20407 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20408 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20409 env->CP0_Status |= (1 << CP0St_FR);
20410 }
20411
20412 /* MSA */
20413 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20414 msa_reset(env);
20415 }
20416
20417 compute_hflags(env);
20418 restore_fp_status(env);
20419 restore_pamask(env);
20420 cs->exception_index = EXCP_NONE;
20421
20422 if (semihosting_get_argc()) {
20423 /* UHI interface can be used to obtain argc and argv */
20424 env->active_tc.gpr[4] = -1;
20425 }
20426 }
20427
20428 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20429 target_ulong *data)
20430 {
20431 env->active_tc.PC = data[0];
20432 env->hflags &= ~MIPS_HFLAG_BMASK;
20433 env->hflags |= data[1];
20434 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20435 case MIPS_HFLAG_BR:
20436 break;
20437 case MIPS_HFLAG_BC:
20438 case MIPS_HFLAG_BL:
20439 case MIPS_HFLAG_B:
20440 env->btarget = data[2];
20441 break;
20442 }
20443 }