]> git.proxmox.com Git - mirror_qemu.git/blob - target-mips/translate.c
target-mips: add CMGCRBase register
[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 "tcg-op.h"
28 #include "exec/cpu_ldst.h"
29
30 #include "exec/helper-proto.h"
31 #include "exec/helper-gen.h"
32 #include "sysemu/kvm.h"
33 #include "exec/semihost.h"
34
35 #include "trace-tcg.h"
36 #include "exec/log.h"
37
38 #define MIPS_DEBUG_DISAS 0
39
40 /* MIPS major opcodes */
41 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
42
43 enum {
44 /* indirect opcode tables */
45 OPC_SPECIAL = (0x00 << 26),
46 OPC_REGIMM = (0x01 << 26),
47 OPC_CP0 = (0x10 << 26),
48 OPC_CP1 = (0x11 << 26),
49 OPC_CP2 = (0x12 << 26),
50 OPC_CP3 = (0x13 << 26),
51 OPC_SPECIAL2 = (0x1C << 26),
52 OPC_SPECIAL3 = (0x1F << 26),
53 /* arithmetic with immediate */
54 OPC_ADDI = (0x08 << 26),
55 OPC_ADDIU = (0x09 << 26),
56 OPC_SLTI = (0x0A << 26),
57 OPC_SLTIU = (0x0B << 26),
58 /* logic with immediate */
59 OPC_ANDI = (0x0C << 26),
60 OPC_ORI = (0x0D << 26),
61 OPC_XORI = (0x0E << 26),
62 OPC_LUI = (0x0F << 26),
63 /* arithmetic with immediate */
64 OPC_DADDI = (0x18 << 26),
65 OPC_DADDIU = (0x19 << 26),
66 /* Jump and branches */
67 OPC_J = (0x02 << 26),
68 OPC_JAL = (0x03 << 26),
69 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
70 OPC_BEQL = (0x14 << 26),
71 OPC_BNE = (0x05 << 26),
72 OPC_BNEL = (0x15 << 26),
73 OPC_BLEZ = (0x06 << 26),
74 OPC_BLEZL = (0x16 << 26),
75 OPC_BGTZ = (0x07 << 26),
76 OPC_BGTZL = (0x17 << 26),
77 OPC_JALX = (0x1D << 26),
78 OPC_DAUI = (0x1D << 26),
79 /* Load and stores */
80 OPC_LDL = (0x1A << 26),
81 OPC_LDR = (0x1B << 26),
82 OPC_LB = (0x20 << 26),
83 OPC_LH = (0x21 << 26),
84 OPC_LWL = (0x22 << 26),
85 OPC_LW = (0x23 << 26),
86 OPC_LWPC = OPC_LW | 0x5,
87 OPC_LBU = (0x24 << 26),
88 OPC_LHU = (0x25 << 26),
89 OPC_LWR = (0x26 << 26),
90 OPC_LWU = (0x27 << 26),
91 OPC_SB = (0x28 << 26),
92 OPC_SH = (0x29 << 26),
93 OPC_SWL = (0x2A << 26),
94 OPC_SW = (0x2B << 26),
95 OPC_SDL = (0x2C << 26),
96 OPC_SDR = (0x2D << 26),
97 OPC_SWR = (0x2E << 26),
98 OPC_LL = (0x30 << 26),
99 OPC_LLD = (0x34 << 26),
100 OPC_LD = (0x37 << 26),
101 OPC_LDPC = OPC_LD | 0x5,
102 OPC_SC = (0x38 << 26),
103 OPC_SCD = (0x3C << 26),
104 OPC_SD = (0x3F << 26),
105 /* Floating point load/store */
106 OPC_LWC1 = (0x31 << 26),
107 OPC_LWC2 = (0x32 << 26),
108 OPC_LDC1 = (0x35 << 26),
109 OPC_LDC2 = (0x36 << 26),
110 OPC_SWC1 = (0x39 << 26),
111 OPC_SWC2 = (0x3A << 26),
112 OPC_SDC1 = (0x3D << 26),
113 OPC_SDC2 = (0x3E << 26),
114 /* Compact Branches */
115 OPC_BLEZALC = (0x06 << 26),
116 OPC_BGEZALC = (0x06 << 26),
117 OPC_BGEUC = (0x06 << 26),
118 OPC_BGTZALC = (0x07 << 26),
119 OPC_BLTZALC = (0x07 << 26),
120 OPC_BLTUC = (0x07 << 26),
121 OPC_BOVC = (0x08 << 26),
122 OPC_BEQZALC = (0x08 << 26),
123 OPC_BEQC = (0x08 << 26),
124 OPC_BLEZC = (0x16 << 26),
125 OPC_BGEZC = (0x16 << 26),
126 OPC_BGEC = (0x16 << 26),
127 OPC_BGTZC = (0x17 << 26),
128 OPC_BLTZC = (0x17 << 26),
129 OPC_BLTC = (0x17 << 26),
130 OPC_BNVC = (0x18 << 26),
131 OPC_BNEZALC = (0x18 << 26),
132 OPC_BNEC = (0x18 << 26),
133 OPC_BC = (0x32 << 26),
134 OPC_BEQZC = (0x36 << 26),
135 OPC_JIC = (0x36 << 26),
136 OPC_BALC = (0x3A << 26),
137 OPC_BNEZC = (0x3E << 26),
138 OPC_JIALC = (0x3E << 26),
139 /* MDMX ASE specific */
140 OPC_MDMX = (0x1E << 26),
141 /* MSA ASE, same as MDMX */
142 OPC_MSA = OPC_MDMX,
143 /* Cache and prefetch */
144 OPC_CACHE = (0x2F << 26),
145 OPC_PREF = (0x33 << 26),
146 /* PC-relative address computation / loads */
147 OPC_PCREL = (0x3B << 26),
148 };
149
150 /* PC-relative address computation / loads */
151 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
152 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
153 enum {
154 /* Instructions determined by bits 19 and 20 */
155 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
156 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
157 OPC_LWUPC = OPC_PCREL | (2 << 19),
158
159 /* Instructions determined by bits 16 ... 20 */
160 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
161 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
162
163 /* Other */
164 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
165 };
166
167 /* MIPS special opcodes */
168 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
169
170 enum {
171 /* Shifts */
172 OPC_SLL = 0x00 | OPC_SPECIAL,
173 /* NOP is SLL r0, r0, 0 */
174 /* SSNOP is SLL r0, r0, 1 */
175 /* EHB is SLL r0, r0, 3 */
176 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
177 OPC_ROTR = OPC_SRL | (1 << 21),
178 OPC_SRA = 0x03 | OPC_SPECIAL,
179 OPC_SLLV = 0x04 | OPC_SPECIAL,
180 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
181 OPC_ROTRV = OPC_SRLV | (1 << 6),
182 OPC_SRAV = 0x07 | OPC_SPECIAL,
183 OPC_DSLLV = 0x14 | OPC_SPECIAL,
184 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
185 OPC_DROTRV = OPC_DSRLV | (1 << 6),
186 OPC_DSRAV = 0x17 | OPC_SPECIAL,
187 OPC_DSLL = 0x38 | OPC_SPECIAL,
188 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
189 OPC_DROTR = OPC_DSRL | (1 << 21),
190 OPC_DSRA = 0x3B | OPC_SPECIAL,
191 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
192 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
193 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
194 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
195 /* Multiplication / division */
196 OPC_MULT = 0x18 | OPC_SPECIAL,
197 OPC_MULTU = 0x19 | OPC_SPECIAL,
198 OPC_DIV = 0x1A | OPC_SPECIAL,
199 OPC_DIVU = 0x1B | OPC_SPECIAL,
200 OPC_DMULT = 0x1C | OPC_SPECIAL,
201 OPC_DMULTU = 0x1D | OPC_SPECIAL,
202 OPC_DDIV = 0x1E | OPC_SPECIAL,
203 OPC_DDIVU = 0x1F | OPC_SPECIAL,
204
205 /* 2 registers arithmetic / logic */
206 OPC_ADD = 0x20 | OPC_SPECIAL,
207 OPC_ADDU = 0x21 | OPC_SPECIAL,
208 OPC_SUB = 0x22 | OPC_SPECIAL,
209 OPC_SUBU = 0x23 | OPC_SPECIAL,
210 OPC_AND = 0x24 | OPC_SPECIAL,
211 OPC_OR = 0x25 | OPC_SPECIAL,
212 OPC_XOR = 0x26 | OPC_SPECIAL,
213 OPC_NOR = 0x27 | OPC_SPECIAL,
214 OPC_SLT = 0x2A | OPC_SPECIAL,
215 OPC_SLTU = 0x2B | OPC_SPECIAL,
216 OPC_DADD = 0x2C | OPC_SPECIAL,
217 OPC_DADDU = 0x2D | OPC_SPECIAL,
218 OPC_DSUB = 0x2E | OPC_SPECIAL,
219 OPC_DSUBU = 0x2F | OPC_SPECIAL,
220 /* Jumps */
221 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
222 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
223 /* Traps */
224 OPC_TGE = 0x30 | OPC_SPECIAL,
225 OPC_TGEU = 0x31 | OPC_SPECIAL,
226 OPC_TLT = 0x32 | OPC_SPECIAL,
227 OPC_TLTU = 0x33 | OPC_SPECIAL,
228 OPC_TEQ = 0x34 | OPC_SPECIAL,
229 OPC_TNE = 0x36 | OPC_SPECIAL,
230 /* HI / LO registers load & stores */
231 OPC_MFHI = 0x10 | OPC_SPECIAL,
232 OPC_MTHI = 0x11 | OPC_SPECIAL,
233 OPC_MFLO = 0x12 | OPC_SPECIAL,
234 OPC_MTLO = 0x13 | OPC_SPECIAL,
235 /* Conditional moves */
236 OPC_MOVZ = 0x0A | OPC_SPECIAL,
237 OPC_MOVN = 0x0B | OPC_SPECIAL,
238
239 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
240 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
241
242 OPC_MOVCI = 0x01 | OPC_SPECIAL,
243
244 /* Special */
245 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
246 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
247 OPC_BREAK = 0x0D | OPC_SPECIAL,
248 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
249 OPC_SYNC = 0x0F | OPC_SPECIAL,
250
251 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
252 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
253 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
254 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
255 };
256
257 /* R6 Multiply and Divide instructions have the same Opcode
258 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
259 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
260
261 enum {
262 R6_OPC_MUL = OPC_MULT | (2 << 6),
263 R6_OPC_MUH = OPC_MULT | (3 << 6),
264 R6_OPC_MULU = OPC_MULTU | (2 << 6),
265 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
266 R6_OPC_DIV = OPC_DIV | (2 << 6),
267 R6_OPC_MOD = OPC_DIV | (3 << 6),
268 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
269 R6_OPC_MODU = OPC_DIVU | (3 << 6),
270
271 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
272 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
273 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
274 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
275 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
276 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
277 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
278 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
279
280 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
281 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
282 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
283 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
284 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
285
286 OPC_LSA = 0x05 | OPC_SPECIAL,
287 OPC_DLSA = 0x15 | OPC_SPECIAL,
288 };
289
290 /* Multiplication variants of the vr54xx. */
291 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
292
293 enum {
294 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
295 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
296 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
297 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
298 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
299 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
300 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
301 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
302 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
303 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
304 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
305 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
306 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
307 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
308 };
309
310 /* REGIMM (rt field) opcodes */
311 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
312
313 enum {
314 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
315 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
316 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
317 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
318 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
319 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
320 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
321 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
322 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
323 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
324 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
325 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
326 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
327 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
328 OPC_SIGRIE = (0x17 << 16) | OPC_REGIMM,
329 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
330
331 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
332 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
333 };
334
335 /* Special2 opcodes */
336 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
337
338 enum {
339 /* Multiply & xxx operations */
340 OPC_MADD = 0x00 | OPC_SPECIAL2,
341 OPC_MADDU = 0x01 | OPC_SPECIAL2,
342 OPC_MUL = 0x02 | OPC_SPECIAL2,
343 OPC_MSUB = 0x04 | OPC_SPECIAL2,
344 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
345 /* Loongson 2F */
346 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
347 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
348 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
349 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
350 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
351 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
352 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
353 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
354 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
355 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
356 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
357 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
358 /* Misc */
359 OPC_CLZ = 0x20 | OPC_SPECIAL2,
360 OPC_CLO = 0x21 | OPC_SPECIAL2,
361 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
362 OPC_DCLO = 0x25 | OPC_SPECIAL2,
363 /* Special */
364 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
365 };
366
367 /* Special3 opcodes */
368 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
369
370 enum {
371 OPC_EXT = 0x00 | OPC_SPECIAL3,
372 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
373 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
374 OPC_DEXT = 0x03 | OPC_SPECIAL3,
375 OPC_INS = 0x04 | OPC_SPECIAL3,
376 OPC_DINSM = 0x05 | OPC_SPECIAL3,
377 OPC_DINSU = 0x06 | OPC_SPECIAL3,
378 OPC_DINS = 0x07 | OPC_SPECIAL3,
379 OPC_FORK = 0x08 | OPC_SPECIAL3,
380 OPC_YIELD = 0x09 | OPC_SPECIAL3,
381 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
382 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
383 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
384
385 /* Loongson 2E */
386 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
387 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
388 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
389 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
390 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
391 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
392 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
393 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
394 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
395 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
396 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
397 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
398
399 /* MIPS DSP Load */
400 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
401 /* MIPS DSP Arithmetic */
402 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
403 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
404 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
405 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
406 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
407 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
408 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
409 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
410 /* MIPS DSP GPR-Based Shift Sub-class */
411 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
412 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
413 /* MIPS DSP Multiply Sub-class insns */
414 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
415 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
416 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
417 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
418 /* DSP Bit/Manipulation Sub-class */
419 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
420 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
421 /* MIPS DSP Append Sub-class */
422 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
423 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
424 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
425 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
426 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
427
428 /* R6 */
429 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
430 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
431 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
432 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
433 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
434 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
435 };
436
437 /* BSHFL opcodes */
438 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
439
440 enum {
441 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
442 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
443 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
444 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
445 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
446 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
447 };
448
449 /* DBSHFL opcodes */
450 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
451
452 enum {
453 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
454 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
455 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
456 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
457 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
458 };
459
460 /* MIPS DSP REGIMM opcodes */
461 enum {
462 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
463 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
464 };
465
466 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
467 /* MIPS DSP Load */
468 enum {
469 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
470 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
471 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
472 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
473 };
474
475 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
476 enum {
477 /* MIPS DSP Arithmetic Sub-class */
478 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
483 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
484 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
490 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
491 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
492 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
493 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
494 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
495 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
496 /* MIPS DSP Multiply Sub-class insns */
497 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
501 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
502 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
503 };
504
505 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
506 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
507 enum {
508 /* MIPS DSP Arithmetic Sub-class */
509 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
513 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
519 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
520 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
521 /* MIPS DSP Multiply Sub-class insns */
522 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
523 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
524 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
525 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
526 };
527
528 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529 enum {
530 /* MIPS DSP Arithmetic Sub-class */
531 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
544 /* DSP Bit/Manipulation Sub-class */
545 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
547 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
548 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
549 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
550 };
551
552 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 enum {
554 /* MIPS DSP Arithmetic Sub-class */
555 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
562 /* DSP Compare-Pick Sub-class */
563 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
578 };
579
580 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
581 enum {
582 /* MIPS DSP GPR-Based Shift Sub-class */
583 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
603 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
605 };
606
607 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
608 enum {
609 /* MIPS DSP Multiply Sub-class insns */
610 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
624 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
626 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
630 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
632 };
633
634 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
635 enum {
636 /* DSP Bit/Manipulation Sub-class */
637 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
638 };
639
640 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
641 enum {
642 /* MIPS DSP Append Sub-class */
643 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
644 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
645 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
646 };
647
648 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
649 enum {
650 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
651 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
661 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
662 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
663 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
664 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
665 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
666 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
667 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
668 };
669
670 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671 enum {
672 /* MIPS DSP Arithmetic Sub-class */
673 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
690 /* DSP Bit/Manipulation Sub-class */
691 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
697 };
698
699 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
700 enum {
701 /* MIPS DSP Multiply Sub-class insns */
702 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
704 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
705 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
706 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
707 /* MIPS DSP Arithmetic Sub-class */
708 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
717 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
718 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
727 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
728 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
729 };
730
731 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
732 enum {
733 /* DSP Compare-Pick Sub-class */
734 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
753 /* MIPS DSP Arithmetic Sub-class */
754 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
762 };
763
764 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
765 enum {
766 /* DSP Append Sub-class */
767 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
768 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
769 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
770 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
771 };
772
773 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
774 enum {
775 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
776 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
777 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
795 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
796 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
797 };
798
799 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
800 enum {
801 /* DSP Bit/Manipulation Sub-class */
802 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
803 };
804
805 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
806 enum {
807 /* MIPS DSP Multiply Sub-class insns */
808 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
834 };
835
836 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
837 enum {
838 /* MIPS DSP GPR-Based Shift Sub-class */
839 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
865 };
866
867 /* Coprocessor 0 (rs field) */
868 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
869
870 enum {
871 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
872 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
873 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
874 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
875 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
876 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
877 OPC_MFTR = (0x08 << 21) | OPC_CP0,
878 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
879 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
880 OPC_MTTR = (0x0C << 21) | OPC_CP0,
881 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
882 OPC_C0 = (0x10 << 21) | OPC_CP0,
883 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
884 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
885 };
886
887 /* MFMC0 opcodes */
888 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
889
890 enum {
891 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
892 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
893 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
894 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
895 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
896 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
897 OPC_DVP = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
898 OPC_EVP = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
899 };
900
901 /* Coprocessor 0 (with rs == C0) */
902 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
903
904 enum {
905 OPC_TLBR = 0x01 | OPC_C0,
906 OPC_TLBWI = 0x02 | OPC_C0,
907 OPC_TLBINV = 0x03 | OPC_C0,
908 OPC_TLBINVF = 0x04 | OPC_C0,
909 OPC_TLBWR = 0x06 | OPC_C0,
910 OPC_TLBP = 0x08 | OPC_C0,
911 OPC_RFE = 0x10 | OPC_C0,
912 OPC_ERET = 0x18 | OPC_C0,
913 OPC_DERET = 0x1F | OPC_C0,
914 OPC_WAIT = 0x20 | OPC_C0,
915 };
916
917 /* Coprocessor 1 (rs field) */
918 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
919
920 /* Values for the fmt field in FP instructions */
921 enum {
922 /* 0 - 15 are reserved */
923 FMT_S = 16, /* single fp */
924 FMT_D = 17, /* double fp */
925 FMT_E = 18, /* extended fp */
926 FMT_Q = 19, /* quad fp */
927 FMT_W = 20, /* 32-bit fixed */
928 FMT_L = 21, /* 64-bit fixed */
929 FMT_PS = 22, /* paired single fp */
930 /* 23 - 31 are reserved */
931 };
932
933 enum {
934 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
935 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
936 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
937 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
938 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
939 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
940 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
941 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
942 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
943 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
944 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
945 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
946 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
947 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
948 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
949 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
950 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
951 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
952 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
953 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
954 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
955 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
956 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
957 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
958 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
959 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
960 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
961 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
962 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
963 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
964 };
965
966 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
967 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
968
969 enum {
970 OPC_BC1F = (0x00 << 16) | OPC_BC1,
971 OPC_BC1T = (0x01 << 16) | OPC_BC1,
972 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
973 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
974 };
975
976 enum {
977 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
978 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
979 };
980
981 enum {
982 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
983 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
984 };
985
986 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
987
988 enum {
989 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
990 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
991 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
992 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
993 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
994 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
995 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
996 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
997 OPC_BC2 = (0x08 << 21) | OPC_CP2,
998 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
999 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
1000 };
1001
1002 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1003
1004 enum {
1005 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1008 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1009 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1010 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1011 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1012 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1013
1014 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1017 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1018 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1019 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1020 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1021 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1022
1023 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1024 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1025 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1026 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1027 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1028 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1029 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1030 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1031
1032 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1033 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1034 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1035 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1036 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1037 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1038 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1039 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1040
1041 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1042 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1043 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1044 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1045 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1046 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1047
1048 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1049 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1050 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1051 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1052 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1053 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1054
1055 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1056 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1057 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1058 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1059 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1060 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1063 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1064 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1065 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1066 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1067 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1070 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1071 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1072 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1073 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1074 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1077 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1078 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1079 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1080 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1081 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1084 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1085 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1086 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1087 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1088 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1091 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1092 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1093 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1094 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1095 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1096 };
1097
1098
1099 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1100
1101 enum {
1102 OPC_LWXC1 = 0x00 | OPC_CP3,
1103 OPC_LDXC1 = 0x01 | OPC_CP3,
1104 OPC_LUXC1 = 0x05 | OPC_CP3,
1105 OPC_SWXC1 = 0x08 | OPC_CP3,
1106 OPC_SDXC1 = 0x09 | OPC_CP3,
1107 OPC_SUXC1 = 0x0D | OPC_CP3,
1108 OPC_PREFX = 0x0F | OPC_CP3,
1109 OPC_ALNV_PS = 0x1E | OPC_CP3,
1110 OPC_MADD_S = 0x20 | OPC_CP3,
1111 OPC_MADD_D = 0x21 | OPC_CP3,
1112 OPC_MADD_PS = 0x26 | OPC_CP3,
1113 OPC_MSUB_S = 0x28 | OPC_CP3,
1114 OPC_MSUB_D = 0x29 | OPC_CP3,
1115 OPC_MSUB_PS = 0x2E | OPC_CP3,
1116 OPC_NMADD_S = 0x30 | OPC_CP3,
1117 OPC_NMADD_D = 0x31 | OPC_CP3,
1118 OPC_NMADD_PS= 0x36 | OPC_CP3,
1119 OPC_NMSUB_S = 0x38 | OPC_CP3,
1120 OPC_NMSUB_D = 0x39 | OPC_CP3,
1121 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1122 };
1123
1124 /* MSA Opcodes */
1125 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1126 enum {
1127 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1128 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1129 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1130 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1131 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1132 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1133 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1134 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1135 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1136 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1137 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1138 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1139 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1140 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1141 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1142 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1143 OPC_MSA_ELM = 0x19 | OPC_MSA,
1144 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1145 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1146 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1147 OPC_MSA_VEC = 0x1E | OPC_MSA,
1148
1149 /* MI10 instruction */
1150 OPC_LD_B = (0x20) | OPC_MSA,
1151 OPC_LD_H = (0x21) | OPC_MSA,
1152 OPC_LD_W = (0x22) | OPC_MSA,
1153 OPC_LD_D = (0x23) | OPC_MSA,
1154 OPC_ST_B = (0x24) | OPC_MSA,
1155 OPC_ST_H = (0x25) | OPC_MSA,
1156 OPC_ST_W = (0x26) | OPC_MSA,
1157 OPC_ST_D = (0x27) | OPC_MSA,
1158 };
1159
1160 enum {
1161 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1162 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1163 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1164 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1165 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1166 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1167 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1168 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1169 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1170 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1171 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1172 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1173 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1174
1175 /* I8 instruction */
1176 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1177 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1178 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1179 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1180 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1181 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1182 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1183 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1184 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1185 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1186
1187 /* VEC/2R/2RF instruction */
1188 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1189 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1190 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1191 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1192 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1193 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1194 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1195
1196 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1197 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1198
1199 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1200 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1201 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1202 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1203 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1204
1205 /* 2RF instruction df(bit 16) = _w, _d */
1206 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1207 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1208 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1209 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1210 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1211 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1212 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1213 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1214 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1215 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1216 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1217 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1218 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1219 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1220 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1221 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1222
1223 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1224 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1225 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1226 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1227 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1228 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1229 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1230 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1231 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1232 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1233 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1234 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1235 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1236 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1237 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1238 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1239 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1240 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1241 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1242 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1243 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1244 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1245 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1246 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1247 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1248 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1249 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1250 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1251 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1252 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1253 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1254 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1255 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1256 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1257 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1258 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1259 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1260 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1261 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1262 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1263 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1264 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1265 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1266 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1267 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1268 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1269 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1270 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1271 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1272 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1273 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1274 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1275 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1276 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1277 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1278 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1279 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1280 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1281 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1282 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1283 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1284 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1285 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1286 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1287
1288 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1289 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1290 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1291 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1293 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1294 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1295 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1296 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1297 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1298
1299 /* 3RF instruction _df(bit 21) = _w, _d */
1300 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1301 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1302 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1303 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1304 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1305 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1306 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1307 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1308 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1309 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1310 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1311 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1312 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1313 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1314 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1315 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1316 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1317 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1318 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1319 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1320 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1321 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1322 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1323 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1324 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1325 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1326 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1327 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1328 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1329 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1330 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1331 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1332 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1333 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1334 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1335 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1336 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1337 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1338 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1339 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1340 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1341
1342 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1343 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1344 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1345 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1346 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1347 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1348 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1349 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1350 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1351 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1352 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1353 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1354 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1355 };
1356
1357 /* global register indices */
1358 static TCGv_env cpu_env;
1359 static TCGv cpu_gpr[32], cpu_PC;
1360 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1361 static TCGv cpu_dspctrl, btarget, bcond;
1362 static TCGv_i32 hflags;
1363 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1364 static TCGv_i64 fpu_f64[32];
1365 static TCGv_i64 msa_wr_d[64];
1366
1367 #include "exec/gen-icount.h"
1368
1369 #define gen_helper_0e0i(name, arg) do { \
1370 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1371 gen_helper_##name(cpu_env, helper_tmp); \
1372 tcg_temp_free_i32(helper_tmp); \
1373 } while(0)
1374
1375 #define gen_helper_0e1i(name, arg1, arg2) do { \
1376 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1377 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1378 tcg_temp_free_i32(helper_tmp); \
1379 } while(0)
1380
1381 #define gen_helper_1e0i(name, ret, arg1) do { \
1382 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1383 gen_helper_##name(ret, cpu_env, helper_tmp); \
1384 tcg_temp_free_i32(helper_tmp); \
1385 } while(0)
1386
1387 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1388 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1389 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1390 tcg_temp_free_i32(helper_tmp); \
1391 } while(0)
1392
1393 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1394 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1395 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1396 tcg_temp_free_i32(helper_tmp); \
1397 } while(0)
1398
1399 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1400 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1401 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1402 tcg_temp_free_i32(helper_tmp); \
1403 } while(0)
1404
1405 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1406 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1407 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1408 tcg_temp_free_i32(helper_tmp); \
1409 } while(0)
1410
1411 typedef struct DisasContext {
1412 struct TranslationBlock *tb;
1413 target_ulong pc, saved_pc;
1414 uint32_t opcode;
1415 int singlestep_enabled;
1416 int insn_flags;
1417 int32_t CP0_Config1;
1418 /* Routine used to access memory */
1419 int mem_idx;
1420 TCGMemOp default_tcg_memop_mask;
1421 uint32_t hflags, saved_hflags;
1422 int bstate;
1423 target_ulong btarget;
1424 bool ulri;
1425 int kscrexist;
1426 bool rxi;
1427 int ie;
1428 bool bi;
1429 bool bp;
1430 uint64_t PAMask;
1431 bool mvh;
1432 int CP0_LLAddr_shift;
1433 bool ps;
1434 bool vp;
1435 bool cmgcr;
1436 } DisasContext;
1437
1438 enum {
1439 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1440 * exception condition */
1441 BS_STOP = 1, /* We want to stop translation for any reason */
1442 BS_BRANCH = 2, /* We reached a branch condition */
1443 BS_EXCP = 3, /* We reached an exception condition */
1444 };
1445
1446 static const char * const regnames[] = {
1447 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1448 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1449 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1450 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1451 };
1452
1453 static const char * const regnames_HI[] = {
1454 "HI0", "HI1", "HI2", "HI3",
1455 };
1456
1457 static const char * const regnames_LO[] = {
1458 "LO0", "LO1", "LO2", "LO3",
1459 };
1460
1461 static const char * const fregnames[] = {
1462 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1463 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1464 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1465 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1466 };
1467
1468 static const char * const msaregnames[] = {
1469 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1470 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1471 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1472 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1473 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1474 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1475 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1476 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1477 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1478 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1479 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1480 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1481 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1482 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1483 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1484 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1485 };
1486
1487 #define LOG_DISAS(...) \
1488 do { \
1489 if (MIPS_DEBUG_DISAS) { \
1490 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1491 } \
1492 } while (0)
1493
1494 #define MIPS_INVAL(op) \
1495 do { \
1496 if (MIPS_DEBUG_DISAS) { \
1497 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1498 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1499 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1500 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
1501 } \
1502 } while (0)
1503
1504 /* General purpose registers moves. */
1505 static inline void gen_load_gpr (TCGv t, int reg)
1506 {
1507 if (reg == 0)
1508 tcg_gen_movi_tl(t, 0);
1509 else
1510 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1511 }
1512
1513 static inline void gen_store_gpr (TCGv t, int reg)
1514 {
1515 if (reg != 0)
1516 tcg_gen_mov_tl(cpu_gpr[reg], t);
1517 }
1518
1519 /* Moves to/from shadow registers. */
1520 static inline void gen_load_srsgpr (int from, int to)
1521 {
1522 TCGv t0 = tcg_temp_new();
1523
1524 if (from == 0)
1525 tcg_gen_movi_tl(t0, 0);
1526 else {
1527 TCGv_i32 t2 = tcg_temp_new_i32();
1528 TCGv_ptr addr = tcg_temp_new_ptr();
1529
1530 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1531 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1532 tcg_gen_andi_i32(t2, t2, 0xf);
1533 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1534 tcg_gen_ext_i32_ptr(addr, t2);
1535 tcg_gen_add_ptr(addr, cpu_env, addr);
1536
1537 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1538 tcg_temp_free_ptr(addr);
1539 tcg_temp_free_i32(t2);
1540 }
1541 gen_store_gpr(t0, to);
1542 tcg_temp_free(t0);
1543 }
1544
1545 static inline void gen_store_srsgpr (int from, int to)
1546 {
1547 if (to != 0) {
1548 TCGv t0 = tcg_temp_new();
1549 TCGv_i32 t2 = tcg_temp_new_i32();
1550 TCGv_ptr addr = tcg_temp_new_ptr();
1551
1552 gen_load_gpr(t0, from);
1553 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1554 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1555 tcg_gen_andi_i32(t2, t2, 0xf);
1556 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1557 tcg_gen_ext_i32_ptr(addr, t2);
1558 tcg_gen_add_ptr(addr, cpu_env, addr);
1559
1560 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1561 tcg_temp_free_ptr(addr);
1562 tcg_temp_free_i32(t2);
1563 tcg_temp_free(t0);
1564 }
1565 }
1566
1567 /* Tests */
1568 static inline void gen_save_pc(target_ulong pc)
1569 {
1570 tcg_gen_movi_tl(cpu_PC, pc);
1571 }
1572
1573 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1574 {
1575 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1576 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1577 gen_save_pc(ctx->pc);
1578 ctx->saved_pc = ctx->pc;
1579 }
1580 if (ctx->hflags != ctx->saved_hflags) {
1581 tcg_gen_movi_i32(hflags, ctx->hflags);
1582 ctx->saved_hflags = ctx->hflags;
1583 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1584 case MIPS_HFLAG_BR:
1585 break;
1586 case MIPS_HFLAG_BC:
1587 case MIPS_HFLAG_BL:
1588 case MIPS_HFLAG_B:
1589 tcg_gen_movi_tl(btarget, ctx->btarget);
1590 break;
1591 }
1592 }
1593 }
1594
1595 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1596 {
1597 ctx->saved_hflags = ctx->hflags;
1598 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1599 case MIPS_HFLAG_BR:
1600 break;
1601 case MIPS_HFLAG_BC:
1602 case MIPS_HFLAG_BL:
1603 case MIPS_HFLAG_B:
1604 ctx->btarget = env->btarget;
1605 break;
1606 }
1607 }
1608
1609 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1610 {
1611 TCGv_i32 texcp = tcg_const_i32(excp);
1612 TCGv_i32 terr = tcg_const_i32(err);
1613 save_cpu_state(ctx, 1);
1614 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1615 tcg_temp_free_i32(terr);
1616 tcg_temp_free_i32(texcp);
1617 ctx->bstate = BS_EXCP;
1618 }
1619
1620 static inline void generate_exception(DisasContext *ctx, int excp)
1621 {
1622 gen_helper_0e0i(raise_exception, excp);
1623 }
1624
1625 static inline void generate_exception_end(DisasContext *ctx, int excp)
1626 {
1627 generate_exception_err(ctx, excp, 0);
1628 }
1629
1630 /* Floating point register moves. */
1631 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1632 {
1633 if (ctx->hflags & MIPS_HFLAG_FRE) {
1634 generate_exception(ctx, EXCP_RI);
1635 }
1636 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1637 }
1638
1639 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1640 {
1641 TCGv_i64 t64;
1642 if (ctx->hflags & MIPS_HFLAG_FRE) {
1643 generate_exception(ctx, EXCP_RI);
1644 }
1645 t64 = tcg_temp_new_i64();
1646 tcg_gen_extu_i32_i64(t64, t);
1647 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1648 tcg_temp_free_i64(t64);
1649 }
1650
1651 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1652 {
1653 if (ctx->hflags & MIPS_HFLAG_F64) {
1654 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1655 } else {
1656 gen_load_fpr32(ctx, t, reg | 1);
1657 }
1658 }
1659
1660 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1661 {
1662 if (ctx->hflags & MIPS_HFLAG_F64) {
1663 TCGv_i64 t64 = tcg_temp_new_i64();
1664 tcg_gen_extu_i32_i64(t64, t);
1665 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1666 tcg_temp_free_i64(t64);
1667 } else {
1668 gen_store_fpr32(ctx, t, reg | 1);
1669 }
1670 }
1671
1672 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1673 {
1674 if (ctx->hflags & MIPS_HFLAG_F64) {
1675 tcg_gen_mov_i64(t, fpu_f64[reg]);
1676 } else {
1677 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1678 }
1679 }
1680
1681 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1682 {
1683 if (ctx->hflags & MIPS_HFLAG_F64) {
1684 tcg_gen_mov_i64(fpu_f64[reg], t);
1685 } else {
1686 TCGv_i64 t0;
1687 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1688 t0 = tcg_temp_new_i64();
1689 tcg_gen_shri_i64(t0, t, 32);
1690 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1691 tcg_temp_free_i64(t0);
1692 }
1693 }
1694
1695 static inline int get_fp_bit (int cc)
1696 {
1697 if (cc)
1698 return 24 + cc;
1699 else
1700 return 23;
1701 }
1702
1703 /* Addresses computation */
1704 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1705 {
1706 tcg_gen_add_tl(ret, arg0, arg1);
1707
1708 #if defined(TARGET_MIPS64)
1709 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1710 tcg_gen_ext32s_i64(ret, ret);
1711 }
1712 #endif
1713 }
1714
1715 /* Addresses computation (translation time) */
1716 static target_long addr_add(DisasContext *ctx, target_long base,
1717 target_long offset)
1718 {
1719 target_long sum = base + offset;
1720
1721 #if defined(TARGET_MIPS64)
1722 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1723 sum = (int32_t)sum;
1724 }
1725 #endif
1726 return sum;
1727 }
1728
1729 /* Sign-extract the low 32-bits to a target_long. */
1730 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1731 {
1732 #if defined(TARGET_MIPS64)
1733 tcg_gen_ext32s_i64(ret, arg);
1734 #else
1735 tcg_gen_extrl_i64_i32(ret, arg);
1736 #endif
1737 }
1738
1739 /* Sign-extract the high 32-bits to a target_long. */
1740 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1741 {
1742 #if defined(TARGET_MIPS64)
1743 tcg_gen_sari_i64(ret, arg, 32);
1744 #else
1745 tcg_gen_extrh_i64_i32(ret, arg);
1746 #endif
1747 }
1748
1749 static inline void check_cp0_enabled(DisasContext *ctx)
1750 {
1751 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1752 generate_exception_err(ctx, EXCP_CpU, 0);
1753 }
1754
1755 static inline void check_cp1_enabled(DisasContext *ctx)
1756 {
1757 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1758 generate_exception_err(ctx, EXCP_CpU, 1);
1759 }
1760
1761 /* Verify that the processor is running with COP1X instructions enabled.
1762 This is associated with the nabla symbol in the MIPS32 and MIPS64
1763 opcode tables. */
1764
1765 static inline void check_cop1x(DisasContext *ctx)
1766 {
1767 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1768 generate_exception_end(ctx, EXCP_RI);
1769 }
1770
1771 /* Verify that the processor is running with 64-bit floating-point
1772 operations enabled. */
1773
1774 static inline void check_cp1_64bitmode(DisasContext *ctx)
1775 {
1776 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1777 generate_exception_end(ctx, EXCP_RI);
1778 }
1779
1780 /*
1781 * Verify if floating point register is valid; an operation is not defined
1782 * if bit 0 of any register specification is set and the FR bit in the
1783 * Status register equals zero, since the register numbers specify an
1784 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1785 * in the Status register equals one, both even and odd register numbers
1786 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1787 *
1788 * Multiple 64 bit wide registers can be checked by calling
1789 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1790 */
1791 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1792 {
1793 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1794 generate_exception_end(ctx, EXCP_RI);
1795 }
1796
1797 /* Verify that the processor is running with DSP instructions enabled.
1798 This is enabled by CP0 Status register MX(24) bit.
1799 */
1800
1801 static inline void check_dsp(DisasContext *ctx)
1802 {
1803 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1804 if (ctx->insn_flags & ASE_DSP) {
1805 generate_exception_end(ctx, EXCP_DSPDIS);
1806 } else {
1807 generate_exception_end(ctx, EXCP_RI);
1808 }
1809 }
1810 }
1811
1812 static inline void check_dspr2(DisasContext *ctx)
1813 {
1814 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1815 if (ctx->insn_flags & ASE_DSP) {
1816 generate_exception_end(ctx, EXCP_DSPDIS);
1817 } else {
1818 generate_exception_end(ctx, EXCP_RI);
1819 }
1820 }
1821 }
1822
1823 /* This code generates a "reserved instruction" exception if the
1824 CPU does not support the instruction set corresponding to flags. */
1825 static inline void check_insn(DisasContext *ctx, int flags)
1826 {
1827 if (unlikely(!(ctx->insn_flags & flags))) {
1828 generate_exception_end(ctx, EXCP_RI);
1829 }
1830 }
1831
1832 /* This code generates a "reserved instruction" exception if the
1833 CPU has corresponding flag set which indicates that the instruction
1834 has been removed. */
1835 static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1836 {
1837 if (unlikely(ctx->insn_flags & flags)) {
1838 generate_exception_end(ctx, EXCP_RI);
1839 }
1840 }
1841
1842 /* This code generates a "reserved instruction" exception if the
1843 CPU does not support 64-bit paired-single (PS) floating point data type */
1844 static inline void check_ps(DisasContext *ctx)
1845 {
1846 if (unlikely(!ctx->ps)) {
1847 generate_exception(ctx, EXCP_RI);
1848 }
1849 check_cp1_64bitmode(ctx);
1850 }
1851
1852 #ifdef TARGET_MIPS64
1853 /* This code generates a "reserved instruction" exception if 64-bit
1854 instructions are not enabled. */
1855 static inline void check_mips_64(DisasContext *ctx)
1856 {
1857 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1858 generate_exception_end(ctx, EXCP_RI);
1859 }
1860 #endif
1861
1862 #ifndef CONFIG_USER_ONLY
1863 static inline void check_mvh(DisasContext *ctx)
1864 {
1865 if (unlikely(!ctx->mvh)) {
1866 generate_exception(ctx, EXCP_RI);
1867 }
1868 }
1869 #endif
1870
1871 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1872 calling interface for 32 and 64-bit FPRs. No sense in changing
1873 all callers for gen_load_fpr32 when we need the CTX parameter for
1874 this one use. */
1875 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1876 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1877 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1878 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1879 int ft, int fs, int cc) \
1880 { \
1881 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1882 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1883 switch (ifmt) { \
1884 case FMT_PS: \
1885 check_ps(ctx); \
1886 break; \
1887 case FMT_D: \
1888 if (abs) { \
1889 check_cop1x(ctx); \
1890 } \
1891 check_cp1_registers(ctx, fs | ft); \
1892 break; \
1893 case FMT_S: \
1894 if (abs) { \
1895 check_cop1x(ctx); \
1896 } \
1897 break; \
1898 } \
1899 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1900 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1901 switch (n) { \
1902 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1903 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1904 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1905 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1906 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1907 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1908 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1909 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1910 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1911 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1912 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1913 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1914 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1915 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1916 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1917 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1918 default: abort(); \
1919 } \
1920 tcg_temp_free_i##bits (fp0); \
1921 tcg_temp_free_i##bits (fp1); \
1922 }
1923
1924 FOP_CONDS(, 0, d, FMT_D, 64)
1925 FOP_CONDS(abs, 1, d, FMT_D, 64)
1926 FOP_CONDS(, 0, s, FMT_S, 32)
1927 FOP_CONDS(abs, 1, s, FMT_S, 32)
1928 FOP_CONDS(, 0, ps, FMT_PS, 64)
1929 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1930 #undef FOP_CONDS
1931
1932 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1933 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1934 int ft, int fs, int fd) \
1935 { \
1936 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1937 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1938 if (ifmt == FMT_D) { \
1939 check_cp1_registers(ctx, fs | ft | fd); \
1940 } \
1941 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1942 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1943 switch (n) { \
1944 case 0: \
1945 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1946 break; \
1947 case 1: \
1948 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1949 break; \
1950 case 2: \
1951 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1952 break; \
1953 case 3: \
1954 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1955 break; \
1956 case 4: \
1957 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1958 break; \
1959 case 5: \
1960 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1961 break; \
1962 case 6: \
1963 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1964 break; \
1965 case 7: \
1966 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1967 break; \
1968 case 8: \
1969 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1970 break; \
1971 case 9: \
1972 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1973 break; \
1974 case 10: \
1975 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1976 break; \
1977 case 11: \
1978 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1979 break; \
1980 case 12: \
1981 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1982 break; \
1983 case 13: \
1984 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1985 break; \
1986 case 14: \
1987 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1988 break; \
1989 case 15: \
1990 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1991 break; \
1992 case 17: \
1993 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1994 break; \
1995 case 18: \
1996 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1997 break; \
1998 case 19: \
1999 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2000 break; \
2001 case 25: \
2002 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2003 break; \
2004 case 26: \
2005 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2006 break; \
2007 case 27: \
2008 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2009 break; \
2010 default: \
2011 abort(); \
2012 } \
2013 STORE; \
2014 tcg_temp_free_i ## bits (fp0); \
2015 tcg_temp_free_i ## bits (fp1); \
2016 }
2017
2018 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2019 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2020 #undef FOP_CONDNS
2021 #undef gen_ldcmp_fpr32
2022 #undef gen_ldcmp_fpr64
2023
2024 /* load/store instructions. */
2025 #ifdef CONFIG_USER_ONLY
2026 #define OP_LD_ATOMIC(insn,fname) \
2027 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2028 { \
2029 TCGv t0 = tcg_temp_new(); \
2030 tcg_gen_mov_tl(t0, arg1); \
2031 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2032 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2033 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2034 tcg_temp_free(t0); \
2035 }
2036 #else
2037 #define OP_LD_ATOMIC(insn,fname) \
2038 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2039 { \
2040 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
2041 }
2042 #endif
2043 OP_LD_ATOMIC(ll,ld32s);
2044 #if defined(TARGET_MIPS64)
2045 OP_LD_ATOMIC(lld,ld64);
2046 #endif
2047 #undef OP_LD_ATOMIC
2048
2049 #ifdef CONFIG_USER_ONLY
2050 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2051 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2052 { \
2053 TCGv t0 = tcg_temp_new(); \
2054 TCGLabel *l1 = gen_new_label(); \
2055 TCGLabel *l2 = gen_new_label(); \
2056 \
2057 tcg_gen_andi_tl(t0, arg2, almask); \
2058 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2059 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2060 generate_exception(ctx, EXCP_AdES); \
2061 gen_set_label(l1); \
2062 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2063 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2064 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2065 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2066 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2067 generate_exception_end(ctx, EXCP_SC); \
2068 gen_set_label(l2); \
2069 tcg_gen_movi_tl(t0, 0); \
2070 gen_store_gpr(t0, rt); \
2071 tcg_temp_free(t0); \
2072 }
2073 #else
2074 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2075 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2076 { \
2077 TCGv t0 = tcg_temp_new(); \
2078 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2079 gen_store_gpr(t0, rt); \
2080 tcg_temp_free(t0); \
2081 }
2082 #endif
2083 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2084 #if defined(TARGET_MIPS64)
2085 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2086 #endif
2087 #undef OP_ST_ATOMIC
2088
2089 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2090 int base, int16_t offset)
2091 {
2092 if (base == 0) {
2093 tcg_gen_movi_tl(addr, offset);
2094 } else if (offset == 0) {
2095 gen_load_gpr(addr, base);
2096 } else {
2097 tcg_gen_movi_tl(addr, offset);
2098 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2099 }
2100 }
2101
2102 static target_ulong pc_relative_pc (DisasContext *ctx)
2103 {
2104 target_ulong pc = ctx->pc;
2105
2106 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2107 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2108
2109 pc -= branch_bytes;
2110 }
2111
2112 pc &= ~(target_ulong)3;
2113 return pc;
2114 }
2115
2116 /* Load */
2117 static void gen_ld(DisasContext *ctx, uint32_t opc,
2118 int rt, int base, int16_t offset)
2119 {
2120 TCGv t0, t1, t2;
2121
2122 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2123 /* Loongson CPU uses a load to zero register for prefetch.
2124 We emulate it as a NOP. On other CPU we must perform the
2125 actual memory access. */
2126 return;
2127 }
2128
2129 t0 = tcg_temp_new();
2130 gen_base_offset_addr(ctx, t0, base, offset);
2131
2132 switch (opc) {
2133 #if defined(TARGET_MIPS64)
2134 case OPC_LWU:
2135 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2136 ctx->default_tcg_memop_mask);
2137 gen_store_gpr(t0, rt);
2138 break;
2139 case OPC_LD:
2140 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2141 ctx->default_tcg_memop_mask);
2142 gen_store_gpr(t0, rt);
2143 break;
2144 case OPC_LLD:
2145 case R6_OPC_LLD:
2146 op_ld_lld(t0, t0, ctx);
2147 gen_store_gpr(t0, rt);
2148 break;
2149 case OPC_LDL:
2150 t1 = tcg_temp_new();
2151 /* Do a byte access to possibly trigger a page
2152 fault with the unaligned address. */
2153 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2154 tcg_gen_andi_tl(t1, t0, 7);
2155 #ifndef TARGET_WORDS_BIGENDIAN
2156 tcg_gen_xori_tl(t1, t1, 7);
2157 #endif
2158 tcg_gen_shli_tl(t1, t1, 3);
2159 tcg_gen_andi_tl(t0, t0, ~7);
2160 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2161 tcg_gen_shl_tl(t0, t0, t1);
2162 t2 = tcg_const_tl(-1);
2163 tcg_gen_shl_tl(t2, t2, t1);
2164 gen_load_gpr(t1, rt);
2165 tcg_gen_andc_tl(t1, t1, t2);
2166 tcg_temp_free(t2);
2167 tcg_gen_or_tl(t0, t0, t1);
2168 tcg_temp_free(t1);
2169 gen_store_gpr(t0, rt);
2170 break;
2171 case OPC_LDR:
2172 t1 = tcg_temp_new();
2173 /* Do a byte access to possibly trigger a page
2174 fault with the unaligned address. */
2175 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2176 tcg_gen_andi_tl(t1, t0, 7);
2177 #ifdef TARGET_WORDS_BIGENDIAN
2178 tcg_gen_xori_tl(t1, t1, 7);
2179 #endif
2180 tcg_gen_shli_tl(t1, t1, 3);
2181 tcg_gen_andi_tl(t0, t0, ~7);
2182 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2183 tcg_gen_shr_tl(t0, t0, t1);
2184 tcg_gen_xori_tl(t1, t1, 63);
2185 t2 = tcg_const_tl(0xfffffffffffffffeull);
2186 tcg_gen_shl_tl(t2, t2, t1);
2187 gen_load_gpr(t1, rt);
2188 tcg_gen_and_tl(t1, t1, t2);
2189 tcg_temp_free(t2);
2190 tcg_gen_or_tl(t0, t0, t1);
2191 tcg_temp_free(t1);
2192 gen_store_gpr(t0, rt);
2193 break;
2194 case OPC_LDPC:
2195 t1 = tcg_const_tl(pc_relative_pc(ctx));
2196 gen_op_addr_add(ctx, t0, t0, t1);
2197 tcg_temp_free(t1);
2198 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2199 gen_store_gpr(t0, rt);
2200 break;
2201 #endif
2202 case OPC_LWPC:
2203 t1 = tcg_const_tl(pc_relative_pc(ctx));
2204 gen_op_addr_add(ctx, t0, t0, t1);
2205 tcg_temp_free(t1);
2206 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2207 gen_store_gpr(t0, rt);
2208 break;
2209 case OPC_LW:
2210 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2211 ctx->default_tcg_memop_mask);
2212 gen_store_gpr(t0, rt);
2213 break;
2214 case OPC_LH:
2215 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2216 ctx->default_tcg_memop_mask);
2217 gen_store_gpr(t0, rt);
2218 break;
2219 case OPC_LHU:
2220 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2221 ctx->default_tcg_memop_mask);
2222 gen_store_gpr(t0, rt);
2223 break;
2224 case OPC_LB:
2225 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2226 gen_store_gpr(t0, rt);
2227 break;
2228 case OPC_LBU:
2229 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2230 gen_store_gpr(t0, rt);
2231 break;
2232 case OPC_LWL:
2233 t1 = tcg_temp_new();
2234 /* Do a byte access to possibly trigger a page
2235 fault with the unaligned address. */
2236 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2237 tcg_gen_andi_tl(t1, t0, 3);
2238 #ifndef TARGET_WORDS_BIGENDIAN
2239 tcg_gen_xori_tl(t1, t1, 3);
2240 #endif
2241 tcg_gen_shli_tl(t1, t1, 3);
2242 tcg_gen_andi_tl(t0, t0, ~3);
2243 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2244 tcg_gen_shl_tl(t0, t0, t1);
2245 t2 = tcg_const_tl(-1);
2246 tcg_gen_shl_tl(t2, t2, t1);
2247 gen_load_gpr(t1, rt);
2248 tcg_gen_andc_tl(t1, t1, t2);
2249 tcg_temp_free(t2);
2250 tcg_gen_or_tl(t0, t0, t1);
2251 tcg_temp_free(t1);
2252 tcg_gen_ext32s_tl(t0, t0);
2253 gen_store_gpr(t0, rt);
2254 break;
2255 case OPC_LWR:
2256 t1 = tcg_temp_new();
2257 /* Do a byte access to possibly trigger a page
2258 fault with the unaligned address. */
2259 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2260 tcg_gen_andi_tl(t1, t0, 3);
2261 #ifdef TARGET_WORDS_BIGENDIAN
2262 tcg_gen_xori_tl(t1, t1, 3);
2263 #endif
2264 tcg_gen_shli_tl(t1, t1, 3);
2265 tcg_gen_andi_tl(t0, t0, ~3);
2266 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2267 tcg_gen_shr_tl(t0, t0, t1);
2268 tcg_gen_xori_tl(t1, t1, 31);
2269 t2 = tcg_const_tl(0xfffffffeull);
2270 tcg_gen_shl_tl(t2, t2, t1);
2271 gen_load_gpr(t1, rt);
2272 tcg_gen_and_tl(t1, t1, t2);
2273 tcg_temp_free(t2);
2274 tcg_gen_or_tl(t0, t0, t1);
2275 tcg_temp_free(t1);
2276 tcg_gen_ext32s_tl(t0, t0);
2277 gen_store_gpr(t0, rt);
2278 break;
2279 case OPC_LL:
2280 case R6_OPC_LL:
2281 op_ld_ll(t0, t0, ctx);
2282 gen_store_gpr(t0, rt);
2283 break;
2284 }
2285 tcg_temp_free(t0);
2286 }
2287
2288 /* Store */
2289 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2290 int base, int16_t offset)
2291 {
2292 TCGv t0 = tcg_temp_new();
2293 TCGv t1 = tcg_temp_new();
2294
2295 gen_base_offset_addr(ctx, t0, base, offset);
2296 gen_load_gpr(t1, rt);
2297 switch (opc) {
2298 #if defined(TARGET_MIPS64)
2299 case OPC_SD:
2300 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2301 ctx->default_tcg_memop_mask);
2302 break;
2303 case OPC_SDL:
2304 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2305 break;
2306 case OPC_SDR:
2307 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2308 break;
2309 #endif
2310 case OPC_SW:
2311 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2312 ctx->default_tcg_memop_mask);
2313 break;
2314 case OPC_SH:
2315 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2316 ctx->default_tcg_memop_mask);
2317 break;
2318 case OPC_SB:
2319 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2320 break;
2321 case OPC_SWL:
2322 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2323 break;
2324 case OPC_SWR:
2325 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2326 break;
2327 }
2328 tcg_temp_free(t0);
2329 tcg_temp_free(t1);
2330 }
2331
2332
2333 /* Store conditional */
2334 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2335 int base, int16_t offset)
2336 {
2337 TCGv t0, t1;
2338
2339 #ifdef CONFIG_USER_ONLY
2340 t0 = tcg_temp_local_new();
2341 t1 = tcg_temp_local_new();
2342 #else
2343 t0 = tcg_temp_new();
2344 t1 = tcg_temp_new();
2345 #endif
2346 gen_base_offset_addr(ctx, t0, base, offset);
2347 gen_load_gpr(t1, rt);
2348 switch (opc) {
2349 #if defined(TARGET_MIPS64)
2350 case OPC_SCD:
2351 case R6_OPC_SCD:
2352 op_st_scd(t1, t0, rt, ctx);
2353 break;
2354 #endif
2355 case OPC_SC:
2356 case R6_OPC_SC:
2357 op_st_sc(t1, t0, rt, ctx);
2358 break;
2359 }
2360 tcg_temp_free(t1);
2361 tcg_temp_free(t0);
2362 }
2363
2364 /* Load and store */
2365 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2366 int base, int16_t offset)
2367 {
2368 TCGv t0 = tcg_temp_new();
2369
2370 gen_base_offset_addr(ctx, t0, base, offset);
2371 /* Don't do NOP if destination is zero: we must perform the actual
2372 memory access. */
2373 switch (opc) {
2374 case OPC_LWC1:
2375 {
2376 TCGv_i32 fp0 = tcg_temp_new_i32();
2377 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2378 ctx->default_tcg_memop_mask);
2379 gen_store_fpr32(ctx, fp0, ft);
2380 tcg_temp_free_i32(fp0);
2381 }
2382 break;
2383 case OPC_SWC1:
2384 {
2385 TCGv_i32 fp0 = tcg_temp_new_i32();
2386 gen_load_fpr32(ctx, fp0, ft);
2387 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2388 ctx->default_tcg_memop_mask);
2389 tcg_temp_free_i32(fp0);
2390 }
2391 break;
2392 case OPC_LDC1:
2393 {
2394 TCGv_i64 fp0 = tcg_temp_new_i64();
2395 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2396 ctx->default_tcg_memop_mask);
2397 gen_store_fpr64(ctx, fp0, ft);
2398 tcg_temp_free_i64(fp0);
2399 }
2400 break;
2401 case OPC_SDC1:
2402 {
2403 TCGv_i64 fp0 = tcg_temp_new_i64();
2404 gen_load_fpr64(ctx, fp0, ft);
2405 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2406 ctx->default_tcg_memop_mask);
2407 tcg_temp_free_i64(fp0);
2408 }
2409 break;
2410 default:
2411 MIPS_INVAL("flt_ldst");
2412 generate_exception_end(ctx, EXCP_RI);
2413 goto out;
2414 }
2415 out:
2416 tcg_temp_free(t0);
2417 }
2418
2419 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2420 int rs, int16_t imm)
2421 {
2422 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2423 check_cp1_enabled(ctx);
2424 switch (op) {
2425 case OPC_LDC1:
2426 case OPC_SDC1:
2427 check_insn(ctx, ISA_MIPS2);
2428 /* Fallthrough */
2429 default:
2430 gen_flt_ldst(ctx, op, rt, rs, imm);
2431 }
2432 } else {
2433 generate_exception_err(ctx, EXCP_CpU, 1);
2434 }
2435 }
2436
2437 /* Arithmetic with immediate operand */
2438 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2439 int rt, int rs, int16_t imm)
2440 {
2441 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2442
2443 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2444 /* If no destination, treat it as a NOP.
2445 For addi, we must generate the overflow exception when needed. */
2446 return;
2447 }
2448 switch (opc) {
2449 case OPC_ADDI:
2450 {
2451 TCGv t0 = tcg_temp_local_new();
2452 TCGv t1 = tcg_temp_new();
2453 TCGv t2 = tcg_temp_new();
2454 TCGLabel *l1 = gen_new_label();
2455
2456 gen_load_gpr(t1, rs);
2457 tcg_gen_addi_tl(t0, t1, uimm);
2458 tcg_gen_ext32s_tl(t0, t0);
2459
2460 tcg_gen_xori_tl(t1, t1, ~uimm);
2461 tcg_gen_xori_tl(t2, t0, uimm);
2462 tcg_gen_and_tl(t1, t1, t2);
2463 tcg_temp_free(t2);
2464 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2465 tcg_temp_free(t1);
2466 /* operands of same sign, result different sign */
2467 generate_exception(ctx, EXCP_OVERFLOW);
2468 gen_set_label(l1);
2469 tcg_gen_ext32s_tl(t0, t0);
2470 gen_store_gpr(t0, rt);
2471 tcg_temp_free(t0);
2472 }
2473 break;
2474 case OPC_ADDIU:
2475 if (rs != 0) {
2476 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2477 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2478 } else {
2479 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2480 }
2481 break;
2482 #if defined(TARGET_MIPS64)
2483 case OPC_DADDI:
2484 {
2485 TCGv t0 = tcg_temp_local_new();
2486 TCGv t1 = tcg_temp_new();
2487 TCGv t2 = tcg_temp_new();
2488 TCGLabel *l1 = gen_new_label();
2489
2490 gen_load_gpr(t1, rs);
2491 tcg_gen_addi_tl(t0, t1, uimm);
2492
2493 tcg_gen_xori_tl(t1, t1, ~uimm);
2494 tcg_gen_xori_tl(t2, t0, uimm);
2495 tcg_gen_and_tl(t1, t1, t2);
2496 tcg_temp_free(t2);
2497 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2498 tcg_temp_free(t1);
2499 /* operands of same sign, result different sign */
2500 generate_exception(ctx, EXCP_OVERFLOW);
2501 gen_set_label(l1);
2502 gen_store_gpr(t0, rt);
2503 tcg_temp_free(t0);
2504 }
2505 break;
2506 case OPC_DADDIU:
2507 if (rs != 0) {
2508 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2509 } else {
2510 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2511 }
2512 break;
2513 #endif
2514 }
2515 }
2516
2517 /* Logic with immediate operand */
2518 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2519 int rt, int rs, int16_t imm)
2520 {
2521 target_ulong uimm;
2522
2523 if (rt == 0) {
2524 /* If no destination, treat it as a NOP. */
2525 return;
2526 }
2527 uimm = (uint16_t)imm;
2528 switch (opc) {
2529 case OPC_ANDI:
2530 if (likely(rs != 0))
2531 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2532 else
2533 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2534 break;
2535 case OPC_ORI:
2536 if (rs != 0)
2537 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2538 else
2539 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2540 break;
2541 case OPC_XORI:
2542 if (likely(rs != 0))
2543 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2544 else
2545 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2546 break;
2547 case OPC_LUI:
2548 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2549 /* OPC_AUI */
2550 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2551 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2552 } else {
2553 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2554 }
2555 break;
2556
2557 default:
2558 break;
2559 }
2560 }
2561
2562 /* Set on less than with immediate operand */
2563 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2564 int rt, int rs, int16_t imm)
2565 {
2566 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2567 TCGv t0;
2568
2569 if (rt == 0) {
2570 /* If no destination, treat it as a NOP. */
2571 return;
2572 }
2573 t0 = tcg_temp_new();
2574 gen_load_gpr(t0, rs);
2575 switch (opc) {
2576 case OPC_SLTI:
2577 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2578 break;
2579 case OPC_SLTIU:
2580 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2581 break;
2582 }
2583 tcg_temp_free(t0);
2584 }
2585
2586 /* Shifts with immediate operand */
2587 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2588 int rt, int rs, int16_t imm)
2589 {
2590 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2591 TCGv t0;
2592
2593 if (rt == 0) {
2594 /* If no destination, treat it as a NOP. */
2595 return;
2596 }
2597
2598 t0 = tcg_temp_new();
2599 gen_load_gpr(t0, rs);
2600 switch (opc) {
2601 case OPC_SLL:
2602 tcg_gen_shli_tl(t0, t0, uimm);
2603 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2604 break;
2605 case OPC_SRA:
2606 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2607 break;
2608 case OPC_SRL:
2609 if (uimm != 0) {
2610 tcg_gen_ext32u_tl(t0, t0);
2611 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2612 } else {
2613 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2614 }
2615 break;
2616 case OPC_ROTR:
2617 if (uimm != 0) {
2618 TCGv_i32 t1 = tcg_temp_new_i32();
2619
2620 tcg_gen_trunc_tl_i32(t1, t0);
2621 tcg_gen_rotri_i32(t1, t1, uimm);
2622 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2623 tcg_temp_free_i32(t1);
2624 } else {
2625 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2626 }
2627 break;
2628 #if defined(TARGET_MIPS64)
2629 case OPC_DSLL:
2630 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2631 break;
2632 case OPC_DSRA:
2633 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2634 break;
2635 case OPC_DSRL:
2636 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2637 break;
2638 case OPC_DROTR:
2639 if (uimm != 0) {
2640 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2641 } else {
2642 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2643 }
2644 break;
2645 case OPC_DSLL32:
2646 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2647 break;
2648 case OPC_DSRA32:
2649 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2650 break;
2651 case OPC_DSRL32:
2652 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2653 break;
2654 case OPC_DROTR32:
2655 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2656 break;
2657 #endif
2658 }
2659 tcg_temp_free(t0);
2660 }
2661
2662 /* Arithmetic */
2663 static void gen_arith(DisasContext *ctx, uint32_t opc,
2664 int rd, int rs, int rt)
2665 {
2666 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2667 && opc != OPC_DADD && opc != OPC_DSUB) {
2668 /* If no destination, treat it as a NOP.
2669 For add & sub, we must generate the overflow exception when needed. */
2670 return;
2671 }
2672
2673 switch (opc) {
2674 case OPC_ADD:
2675 {
2676 TCGv t0 = tcg_temp_local_new();
2677 TCGv t1 = tcg_temp_new();
2678 TCGv t2 = tcg_temp_new();
2679 TCGLabel *l1 = gen_new_label();
2680
2681 gen_load_gpr(t1, rs);
2682 gen_load_gpr(t2, rt);
2683 tcg_gen_add_tl(t0, t1, t2);
2684 tcg_gen_ext32s_tl(t0, t0);
2685 tcg_gen_xor_tl(t1, t1, t2);
2686 tcg_gen_xor_tl(t2, t0, t2);
2687 tcg_gen_andc_tl(t1, t2, t1);
2688 tcg_temp_free(t2);
2689 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2690 tcg_temp_free(t1);
2691 /* operands of same sign, result different sign */
2692 generate_exception(ctx, EXCP_OVERFLOW);
2693 gen_set_label(l1);
2694 gen_store_gpr(t0, rd);
2695 tcg_temp_free(t0);
2696 }
2697 break;
2698 case OPC_ADDU:
2699 if (rs != 0 && rt != 0) {
2700 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2701 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2702 } else if (rs == 0 && rt != 0) {
2703 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2704 } else if (rs != 0 && rt == 0) {
2705 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2706 } else {
2707 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2708 }
2709 break;
2710 case OPC_SUB:
2711 {
2712 TCGv t0 = tcg_temp_local_new();
2713 TCGv t1 = tcg_temp_new();
2714 TCGv t2 = tcg_temp_new();
2715 TCGLabel *l1 = gen_new_label();
2716
2717 gen_load_gpr(t1, rs);
2718 gen_load_gpr(t2, rt);
2719 tcg_gen_sub_tl(t0, t1, t2);
2720 tcg_gen_ext32s_tl(t0, t0);
2721 tcg_gen_xor_tl(t2, t1, t2);
2722 tcg_gen_xor_tl(t1, t0, t1);
2723 tcg_gen_and_tl(t1, t1, t2);
2724 tcg_temp_free(t2);
2725 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2726 tcg_temp_free(t1);
2727 /* operands of different sign, first operand and result different sign */
2728 generate_exception(ctx, EXCP_OVERFLOW);
2729 gen_set_label(l1);
2730 gen_store_gpr(t0, rd);
2731 tcg_temp_free(t0);
2732 }
2733 break;
2734 case OPC_SUBU:
2735 if (rs != 0 && rt != 0) {
2736 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2737 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2738 } else if (rs == 0 && rt != 0) {
2739 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2740 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2741 } else if (rs != 0 && rt == 0) {
2742 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2743 } else {
2744 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2745 }
2746 break;
2747 #if defined(TARGET_MIPS64)
2748 case OPC_DADD:
2749 {
2750 TCGv t0 = tcg_temp_local_new();
2751 TCGv t1 = tcg_temp_new();
2752 TCGv t2 = tcg_temp_new();
2753 TCGLabel *l1 = gen_new_label();
2754
2755 gen_load_gpr(t1, rs);
2756 gen_load_gpr(t2, rt);
2757 tcg_gen_add_tl(t0, t1, t2);
2758 tcg_gen_xor_tl(t1, t1, t2);
2759 tcg_gen_xor_tl(t2, t0, t2);
2760 tcg_gen_andc_tl(t1, t2, t1);
2761 tcg_temp_free(t2);
2762 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2763 tcg_temp_free(t1);
2764 /* operands of same sign, result different sign */
2765 generate_exception(ctx, EXCP_OVERFLOW);
2766 gen_set_label(l1);
2767 gen_store_gpr(t0, rd);
2768 tcg_temp_free(t0);
2769 }
2770 break;
2771 case OPC_DADDU:
2772 if (rs != 0 && rt != 0) {
2773 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2774 } else if (rs == 0 && rt != 0) {
2775 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2776 } else if (rs != 0 && rt == 0) {
2777 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2778 } else {
2779 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2780 }
2781 break;
2782 case OPC_DSUB:
2783 {
2784 TCGv t0 = tcg_temp_local_new();
2785 TCGv t1 = tcg_temp_new();
2786 TCGv t2 = tcg_temp_new();
2787 TCGLabel *l1 = gen_new_label();
2788
2789 gen_load_gpr(t1, rs);
2790 gen_load_gpr(t2, rt);
2791 tcg_gen_sub_tl(t0, t1, t2);
2792 tcg_gen_xor_tl(t2, t1, t2);
2793 tcg_gen_xor_tl(t1, t0, t1);
2794 tcg_gen_and_tl(t1, t1, t2);
2795 tcg_temp_free(t2);
2796 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2797 tcg_temp_free(t1);
2798 /* operands of different sign, first operand and result different sign */
2799 generate_exception(ctx, EXCP_OVERFLOW);
2800 gen_set_label(l1);
2801 gen_store_gpr(t0, rd);
2802 tcg_temp_free(t0);
2803 }
2804 break;
2805 case OPC_DSUBU:
2806 if (rs != 0 && rt != 0) {
2807 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2808 } else if (rs == 0 && rt != 0) {
2809 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2810 } else if (rs != 0 && rt == 0) {
2811 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2812 } else {
2813 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2814 }
2815 break;
2816 #endif
2817 case OPC_MUL:
2818 if (likely(rs != 0 && rt != 0)) {
2819 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2820 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2821 } else {
2822 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2823 }
2824 break;
2825 }
2826 }
2827
2828 /* Conditional move */
2829 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2830 int rd, int rs, int rt)
2831 {
2832 TCGv t0, t1, t2;
2833
2834 if (rd == 0) {
2835 /* If no destination, treat it as a NOP. */
2836 return;
2837 }
2838
2839 t0 = tcg_temp_new();
2840 gen_load_gpr(t0, rt);
2841 t1 = tcg_const_tl(0);
2842 t2 = tcg_temp_new();
2843 gen_load_gpr(t2, rs);
2844 switch (opc) {
2845 case OPC_MOVN:
2846 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2847 break;
2848 case OPC_MOVZ:
2849 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2850 break;
2851 case OPC_SELNEZ:
2852 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2853 break;
2854 case OPC_SELEQZ:
2855 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2856 break;
2857 }
2858 tcg_temp_free(t2);
2859 tcg_temp_free(t1);
2860 tcg_temp_free(t0);
2861 }
2862
2863 /* Logic */
2864 static void gen_logic(DisasContext *ctx, uint32_t opc,
2865 int rd, int rs, int rt)
2866 {
2867 if (rd == 0) {
2868 /* If no destination, treat it as a NOP. */
2869 return;
2870 }
2871
2872 switch (opc) {
2873 case OPC_AND:
2874 if (likely(rs != 0 && rt != 0)) {
2875 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2876 } else {
2877 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2878 }
2879 break;
2880 case OPC_NOR:
2881 if (rs != 0 && rt != 0) {
2882 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2883 } else if (rs == 0 && rt != 0) {
2884 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2885 } else if (rs != 0 && rt == 0) {
2886 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2887 } else {
2888 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2889 }
2890 break;
2891 case OPC_OR:
2892 if (likely(rs != 0 && rt != 0)) {
2893 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2894 } else if (rs == 0 && rt != 0) {
2895 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2896 } else if (rs != 0 && rt == 0) {
2897 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2898 } else {
2899 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2900 }
2901 break;
2902 case OPC_XOR:
2903 if (likely(rs != 0 && rt != 0)) {
2904 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2905 } else if (rs == 0 && rt != 0) {
2906 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2907 } else if (rs != 0 && rt == 0) {
2908 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2909 } else {
2910 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2911 }
2912 break;
2913 }
2914 }
2915
2916 /* Set on lower than */
2917 static void gen_slt(DisasContext *ctx, uint32_t opc,
2918 int rd, int rs, int rt)
2919 {
2920 TCGv t0, t1;
2921
2922 if (rd == 0) {
2923 /* If no destination, treat it as a NOP. */
2924 return;
2925 }
2926
2927 t0 = tcg_temp_new();
2928 t1 = tcg_temp_new();
2929 gen_load_gpr(t0, rs);
2930 gen_load_gpr(t1, rt);
2931 switch (opc) {
2932 case OPC_SLT:
2933 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2934 break;
2935 case OPC_SLTU:
2936 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2937 break;
2938 }
2939 tcg_temp_free(t0);
2940 tcg_temp_free(t1);
2941 }
2942
2943 /* Shifts */
2944 static void gen_shift(DisasContext *ctx, uint32_t opc,
2945 int rd, int rs, int rt)
2946 {
2947 TCGv t0, t1;
2948
2949 if (rd == 0) {
2950 /* If no destination, treat it as a NOP.
2951 For add & sub, we must generate the overflow exception when needed. */
2952 return;
2953 }
2954
2955 t0 = tcg_temp_new();
2956 t1 = tcg_temp_new();
2957 gen_load_gpr(t0, rs);
2958 gen_load_gpr(t1, rt);
2959 switch (opc) {
2960 case OPC_SLLV:
2961 tcg_gen_andi_tl(t0, t0, 0x1f);
2962 tcg_gen_shl_tl(t0, t1, t0);
2963 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2964 break;
2965 case OPC_SRAV:
2966 tcg_gen_andi_tl(t0, t0, 0x1f);
2967 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2968 break;
2969 case OPC_SRLV:
2970 tcg_gen_ext32u_tl(t1, t1);
2971 tcg_gen_andi_tl(t0, t0, 0x1f);
2972 tcg_gen_shr_tl(t0, t1, t0);
2973 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2974 break;
2975 case OPC_ROTRV:
2976 {
2977 TCGv_i32 t2 = tcg_temp_new_i32();
2978 TCGv_i32 t3 = tcg_temp_new_i32();
2979
2980 tcg_gen_trunc_tl_i32(t2, t0);
2981 tcg_gen_trunc_tl_i32(t3, t1);
2982 tcg_gen_andi_i32(t2, t2, 0x1f);
2983 tcg_gen_rotr_i32(t2, t3, t2);
2984 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2985 tcg_temp_free_i32(t2);
2986 tcg_temp_free_i32(t3);
2987 }
2988 break;
2989 #if defined(TARGET_MIPS64)
2990 case OPC_DSLLV:
2991 tcg_gen_andi_tl(t0, t0, 0x3f);
2992 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2993 break;
2994 case OPC_DSRAV:
2995 tcg_gen_andi_tl(t0, t0, 0x3f);
2996 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2997 break;
2998 case OPC_DSRLV:
2999 tcg_gen_andi_tl(t0, t0, 0x3f);
3000 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3001 break;
3002 case OPC_DROTRV:
3003 tcg_gen_andi_tl(t0, t0, 0x3f);
3004 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3005 break;
3006 #endif
3007 }
3008 tcg_temp_free(t0);
3009 tcg_temp_free(t1);
3010 }
3011
3012 /* Arithmetic on HI/LO registers */
3013 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3014 {
3015 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3016 /* Treat as NOP. */
3017 return;
3018 }
3019
3020 if (acc != 0) {
3021 check_dsp(ctx);
3022 }
3023
3024 switch (opc) {
3025 case OPC_MFHI:
3026 #if defined(TARGET_MIPS64)
3027 if (acc != 0) {
3028 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3029 } else
3030 #endif
3031 {
3032 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3033 }
3034 break;
3035 case OPC_MFLO:
3036 #if defined(TARGET_MIPS64)
3037 if (acc != 0) {
3038 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3039 } else
3040 #endif
3041 {
3042 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3043 }
3044 break;
3045 case OPC_MTHI:
3046 if (reg != 0) {
3047 #if defined(TARGET_MIPS64)
3048 if (acc != 0) {
3049 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3050 } else
3051 #endif
3052 {
3053 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3054 }
3055 } else {
3056 tcg_gen_movi_tl(cpu_HI[acc], 0);
3057 }
3058 break;
3059 case OPC_MTLO:
3060 if (reg != 0) {
3061 #if defined(TARGET_MIPS64)
3062 if (acc != 0) {
3063 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3064 } else
3065 #endif
3066 {
3067 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3068 }
3069 } else {
3070 tcg_gen_movi_tl(cpu_LO[acc], 0);
3071 }
3072 break;
3073 }
3074 }
3075
3076 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3077 TCGMemOp memop)
3078 {
3079 TCGv t0 = tcg_const_tl(addr);
3080 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3081 gen_store_gpr(t0, reg);
3082 tcg_temp_free(t0);
3083 }
3084
3085 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3086 int rs)
3087 {
3088 target_long offset;
3089 target_long addr;
3090
3091 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3092 case OPC_ADDIUPC:
3093 if (rs != 0) {
3094 offset = sextract32(ctx->opcode << 2, 0, 21);
3095 addr = addr_add(ctx, pc, offset);
3096 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3097 }
3098 break;
3099 case R6_OPC_LWPC:
3100 offset = sextract32(ctx->opcode << 2, 0, 21);
3101 addr = addr_add(ctx, pc, offset);
3102 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3103 break;
3104 #if defined(TARGET_MIPS64)
3105 case OPC_LWUPC:
3106 check_mips_64(ctx);
3107 offset = sextract32(ctx->opcode << 2, 0, 21);
3108 addr = addr_add(ctx, pc, offset);
3109 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3110 break;
3111 #endif
3112 default:
3113 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3114 case OPC_AUIPC:
3115 if (rs != 0) {
3116 offset = sextract32(ctx->opcode, 0, 16) << 16;
3117 addr = addr_add(ctx, pc, offset);
3118 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3119 }
3120 break;
3121 case OPC_ALUIPC:
3122 if (rs != 0) {
3123 offset = sextract32(ctx->opcode, 0, 16) << 16;
3124 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3125 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3126 }
3127 break;
3128 #if defined(TARGET_MIPS64)
3129 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3130 case R6_OPC_LDPC + (1 << 16):
3131 case R6_OPC_LDPC + (2 << 16):
3132 case R6_OPC_LDPC + (3 << 16):
3133 check_mips_64(ctx);
3134 offset = sextract32(ctx->opcode << 3, 0, 21);
3135 addr = addr_add(ctx, (pc & ~0x7), offset);
3136 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3137 break;
3138 #endif
3139 default:
3140 MIPS_INVAL("OPC_PCREL");
3141 generate_exception_end(ctx, EXCP_RI);
3142 break;
3143 }
3144 break;
3145 }
3146 }
3147
3148 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3149 {
3150 TCGv t0, t1;
3151
3152 if (rd == 0) {
3153 /* Treat as NOP. */
3154 return;
3155 }
3156
3157 t0 = tcg_temp_new();
3158 t1 = tcg_temp_new();
3159
3160 gen_load_gpr(t0, rs);
3161 gen_load_gpr(t1, rt);
3162
3163 switch (opc) {
3164 case R6_OPC_DIV:
3165 {
3166 TCGv t2 = tcg_temp_new();
3167 TCGv t3 = tcg_temp_new();
3168 tcg_gen_ext32s_tl(t0, t0);
3169 tcg_gen_ext32s_tl(t1, t1);
3170 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3171 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3172 tcg_gen_and_tl(t2, t2, t3);
3173 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3174 tcg_gen_or_tl(t2, t2, t3);
3175 tcg_gen_movi_tl(t3, 0);
3176 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3177 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3178 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3179 tcg_temp_free(t3);
3180 tcg_temp_free(t2);
3181 }
3182 break;
3183 case R6_OPC_MOD:
3184 {
3185 TCGv t2 = tcg_temp_new();
3186 TCGv t3 = tcg_temp_new();
3187 tcg_gen_ext32s_tl(t0, t0);
3188 tcg_gen_ext32s_tl(t1, t1);
3189 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3190 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3191 tcg_gen_and_tl(t2, t2, t3);
3192 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3193 tcg_gen_or_tl(t2, t2, t3);
3194 tcg_gen_movi_tl(t3, 0);
3195 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3196 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3197 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3198 tcg_temp_free(t3);
3199 tcg_temp_free(t2);
3200 }
3201 break;
3202 case R6_OPC_DIVU:
3203 {
3204 TCGv t2 = tcg_const_tl(0);
3205 TCGv t3 = tcg_const_tl(1);
3206 tcg_gen_ext32u_tl(t0, t0);
3207 tcg_gen_ext32u_tl(t1, t1);
3208 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3209 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3210 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3211 tcg_temp_free(t3);
3212 tcg_temp_free(t2);
3213 }
3214 break;
3215 case R6_OPC_MODU:
3216 {
3217 TCGv t2 = tcg_const_tl(0);
3218 TCGv t3 = tcg_const_tl(1);
3219 tcg_gen_ext32u_tl(t0, t0);
3220 tcg_gen_ext32u_tl(t1, t1);
3221 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3222 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3223 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3224 tcg_temp_free(t3);
3225 tcg_temp_free(t2);
3226 }
3227 break;
3228 case R6_OPC_MUL:
3229 {
3230 TCGv_i32 t2 = tcg_temp_new_i32();
3231 TCGv_i32 t3 = tcg_temp_new_i32();
3232 tcg_gen_trunc_tl_i32(t2, t0);
3233 tcg_gen_trunc_tl_i32(t3, t1);
3234 tcg_gen_mul_i32(t2, t2, t3);
3235 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3236 tcg_temp_free_i32(t2);
3237 tcg_temp_free_i32(t3);
3238 }
3239 break;
3240 case R6_OPC_MUH:
3241 {
3242 TCGv_i32 t2 = tcg_temp_new_i32();
3243 TCGv_i32 t3 = tcg_temp_new_i32();
3244 tcg_gen_trunc_tl_i32(t2, t0);
3245 tcg_gen_trunc_tl_i32(t3, t1);
3246 tcg_gen_muls2_i32(t2, t3, t2, t3);
3247 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3248 tcg_temp_free_i32(t2);
3249 tcg_temp_free_i32(t3);
3250 }
3251 break;
3252 case R6_OPC_MULU:
3253 {
3254 TCGv_i32 t2 = tcg_temp_new_i32();
3255 TCGv_i32 t3 = tcg_temp_new_i32();
3256 tcg_gen_trunc_tl_i32(t2, t0);
3257 tcg_gen_trunc_tl_i32(t3, t1);
3258 tcg_gen_mul_i32(t2, t2, t3);
3259 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3260 tcg_temp_free_i32(t2);
3261 tcg_temp_free_i32(t3);
3262 }
3263 break;
3264 case R6_OPC_MUHU:
3265 {
3266 TCGv_i32 t2 = tcg_temp_new_i32();
3267 TCGv_i32 t3 = tcg_temp_new_i32();
3268 tcg_gen_trunc_tl_i32(t2, t0);
3269 tcg_gen_trunc_tl_i32(t3, t1);
3270 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3271 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3272 tcg_temp_free_i32(t2);
3273 tcg_temp_free_i32(t3);
3274 }
3275 break;
3276 #if defined(TARGET_MIPS64)
3277 case R6_OPC_DDIV:
3278 {
3279 TCGv t2 = tcg_temp_new();
3280 TCGv t3 = tcg_temp_new();
3281 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3282 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3283 tcg_gen_and_tl(t2, t2, t3);
3284 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3285 tcg_gen_or_tl(t2, t2, t3);
3286 tcg_gen_movi_tl(t3, 0);
3287 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3288 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3289 tcg_temp_free(t3);
3290 tcg_temp_free(t2);
3291 }
3292 break;
3293 case R6_OPC_DMOD:
3294 {
3295 TCGv t2 = tcg_temp_new();
3296 TCGv t3 = tcg_temp_new();
3297 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3298 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3299 tcg_gen_and_tl(t2, t2, t3);
3300 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3301 tcg_gen_or_tl(t2, t2, t3);
3302 tcg_gen_movi_tl(t3, 0);
3303 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3304 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3305 tcg_temp_free(t3);
3306 tcg_temp_free(t2);
3307 }
3308 break;
3309 case R6_OPC_DDIVU:
3310 {
3311 TCGv t2 = tcg_const_tl(0);
3312 TCGv t3 = tcg_const_tl(1);
3313 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3314 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3315 tcg_temp_free(t3);
3316 tcg_temp_free(t2);
3317 }
3318 break;
3319 case R6_OPC_DMODU:
3320 {
3321 TCGv t2 = tcg_const_tl(0);
3322 TCGv t3 = tcg_const_tl(1);
3323 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3324 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3325 tcg_temp_free(t3);
3326 tcg_temp_free(t2);
3327 }
3328 break;
3329 case R6_OPC_DMUL:
3330 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3331 break;
3332 case R6_OPC_DMUH:
3333 {
3334 TCGv t2 = tcg_temp_new();
3335 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3336 tcg_temp_free(t2);
3337 }
3338 break;
3339 case R6_OPC_DMULU:
3340 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3341 break;
3342 case R6_OPC_DMUHU:
3343 {
3344 TCGv t2 = tcg_temp_new();
3345 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3346 tcg_temp_free(t2);
3347 }
3348 break;
3349 #endif
3350 default:
3351 MIPS_INVAL("r6 mul/div");
3352 generate_exception_end(ctx, EXCP_RI);
3353 goto out;
3354 }
3355 out:
3356 tcg_temp_free(t0);
3357 tcg_temp_free(t1);
3358 }
3359
3360 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3361 int acc, int rs, int rt)
3362 {
3363 TCGv t0, t1;
3364
3365 t0 = tcg_temp_new();
3366 t1 = tcg_temp_new();
3367
3368 gen_load_gpr(t0, rs);
3369 gen_load_gpr(t1, rt);
3370
3371 if (acc != 0) {
3372 check_dsp(ctx);
3373 }
3374
3375 switch (opc) {
3376 case OPC_DIV:
3377 {
3378 TCGv t2 = tcg_temp_new();
3379 TCGv t3 = tcg_temp_new();
3380 tcg_gen_ext32s_tl(t0, t0);
3381 tcg_gen_ext32s_tl(t1, t1);
3382 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3383 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3384 tcg_gen_and_tl(t2, t2, t3);
3385 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3386 tcg_gen_or_tl(t2, t2, t3);
3387 tcg_gen_movi_tl(t3, 0);
3388 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3389 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3390 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3391 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3392 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3393 tcg_temp_free(t3);
3394 tcg_temp_free(t2);
3395 }
3396 break;
3397 case OPC_DIVU:
3398 {
3399 TCGv t2 = tcg_const_tl(0);
3400 TCGv t3 = tcg_const_tl(1);
3401 tcg_gen_ext32u_tl(t0, t0);
3402 tcg_gen_ext32u_tl(t1, t1);
3403 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3404 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3405 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3406 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3407 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3408 tcg_temp_free(t3);
3409 tcg_temp_free(t2);
3410 }
3411 break;
3412 case OPC_MULT:
3413 {
3414 TCGv_i32 t2 = tcg_temp_new_i32();
3415 TCGv_i32 t3 = tcg_temp_new_i32();
3416 tcg_gen_trunc_tl_i32(t2, t0);
3417 tcg_gen_trunc_tl_i32(t3, t1);
3418 tcg_gen_muls2_i32(t2, t3, t2, t3);
3419 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3420 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3421 tcg_temp_free_i32(t2);
3422 tcg_temp_free_i32(t3);
3423 }
3424 break;
3425 case OPC_MULTU:
3426 {
3427 TCGv_i32 t2 = tcg_temp_new_i32();
3428 TCGv_i32 t3 = tcg_temp_new_i32();
3429 tcg_gen_trunc_tl_i32(t2, t0);
3430 tcg_gen_trunc_tl_i32(t3, t1);
3431 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3432 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3433 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3434 tcg_temp_free_i32(t2);
3435 tcg_temp_free_i32(t3);
3436 }
3437 break;
3438 #if defined(TARGET_MIPS64)
3439 case OPC_DDIV:
3440 {
3441 TCGv t2 = tcg_temp_new();
3442 TCGv t3 = tcg_temp_new();
3443 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3444 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3445 tcg_gen_and_tl(t2, t2, t3);
3446 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3447 tcg_gen_or_tl(t2, t2, t3);
3448 tcg_gen_movi_tl(t3, 0);
3449 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3450 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3451 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3452 tcg_temp_free(t3);
3453 tcg_temp_free(t2);
3454 }
3455 break;
3456 case OPC_DDIVU:
3457 {
3458 TCGv t2 = tcg_const_tl(0);
3459 TCGv t3 = tcg_const_tl(1);
3460 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3461 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3462 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3463 tcg_temp_free(t3);
3464 tcg_temp_free(t2);
3465 }
3466 break;
3467 case OPC_DMULT:
3468 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3469 break;
3470 case OPC_DMULTU:
3471 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3472 break;
3473 #endif
3474 case OPC_MADD:
3475 {
3476 TCGv_i64 t2 = tcg_temp_new_i64();
3477 TCGv_i64 t3 = tcg_temp_new_i64();
3478
3479 tcg_gen_ext_tl_i64(t2, t0);
3480 tcg_gen_ext_tl_i64(t3, t1);
3481 tcg_gen_mul_i64(t2, t2, t3);
3482 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3483 tcg_gen_add_i64(t2, t2, t3);
3484 tcg_temp_free_i64(t3);
3485 gen_move_low32(cpu_LO[acc], t2);
3486 gen_move_high32(cpu_HI[acc], t2);
3487 tcg_temp_free_i64(t2);
3488 }
3489 break;
3490 case OPC_MADDU:
3491 {
3492 TCGv_i64 t2 = tcg_temp_new_i64();
3493 TCGv_i64 t3 = tcg_temp_new_i64();
3494
3495 tcg_gen_ext32u_tl(t0, t0);
3496 tcg_gen_ext32u_tl(t1, t1);
3497 tcg_gen_extu_tl_i64(t2, t0);
3498 tcg_gen_extu_tl_i64(t3, t1);
3499 tcg_gen_mul_i64(t2, t2, t3);
3500 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3501 tcg_gen_add_i64(t2, t2, t3);
3502 tcg_temp_free_i64(t3);
3503 gen_move_low32(cpu_LO[acc], t2);
3504 gen_move_high32(cpu_HI[acc], t2);
3505 tcg_temp_free_i64(t2);
3506 }
3507 break;
3508 case OPC_MSUB:
3509 {
3510 TCGv_i64 t2 = tcg_temp_new_i64();
3511 TCGv_i64 t3 = tcg_temp_new_i64();
3512
3513 tcg_gen_ext_tl_i64(t2, t0);
3514 tcg_gen_ext_tl_i64(t3, t1);
3515 tcg_gen_mul_i64(t2, t2, t3);
3516 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3517 tcg_gen_sub_i64(t2, t3, t2);
3518 tcg_temp_free_i64(t3);
3519 gen_move_low32(cpu_LO[acc], t2);
3520 gen_move_high32(cpu_HI[acc], t2);
3521 tcg_temp_free_i64(t2);
3522 }
3523 break;
3524 case OPC_MSUBU:
3525 {
3526 TCGv_i64 t2 = tcg_temp_new_i64();
3527 TCGv_i64 t3 = tcg_temp_new_i64();
3528
3529 tcg_gen_ext32u_tl(t0, t0);
3530 tcg_gen_ext32u_tl(t1, t1);
3531 tcg_gen_extu_tl_i64(t2, t0);
3532 tcg_gen_extu_tl_i64(t3, t1);
3533 tcg_gen_mul_i64(t2, t2, t3);
3534 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3535 tcg_gen_sub_i64(t2, t3, t2);
3536 tcg_temp_free_i64(t3);
3537 gen_move_low32(cpu_LO[acc], t2);
3538 gen_move_high32(cpu_HI[acc], t2);
3539 tcg_temp_free_i64(t2);
3540 }
3541 break;
3542 default:
3543 MIPS_INVAL("mul/div");
3544 generate_exception_end(ctx, EXCP_RI);
3545 goto out;
3546 }
3547 out:
3548 tcg_temp_free(t0);
3549 tcg_temp_free(t1);
3550 }
3551
3552 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3553 int rd, int rs, int rt)
3554 {
3555 TCGv t0 = tcg_temp_new();
3556 TCGv t1 = tcg_temp_new();
3557
3558 gen_load_gpr(t0, rs);
3559 gen_load_gpr(t1, rt);
3560
3561 switch (opc) {
3562 case OPC_VR54XX_MULS:
3563 gen_helper_muls(t0, cpu_env, t0, t1);
3564 break;
3565 case OPC_VR54XX_MULSU:
3566 gen_helper_mulsu(t0, cpu_env, t0, t1);
3567 break;
3568 case OPC_VR54XX_MACC:
3569 gen_helper_macc(t0, cpu_env, t0, t1);
3570 break;
3571 case OPC_VR54XX_MACCU:
3572 gen_helper_maccu(t0, cpu_env, t0, t1);
3573 break;
3574 case OPC_VR54XX_MSAC:
3575 gen_helper_msac(t0, cpu_env, t0, t1);
3576 break;
3577 case OPC_VR54XX_MSACU:
3578 gen_helper_msacu(t0, cpu_env, t0, t1);
3579 break;
3580 case OPC_VR54XX_MULHI:
3581 gen_helper_mulhi(t0, cpu_env, t0, t1);
3582 break;
3583 case OPC_VR54XX_MULHIU:
3584 gen_helper_mulhiu(t0, cpu_env, t0, t1);
3585 break;
3586 case OPC_VR54XX_MULSHI:
3587 gen_helper_mulshi(t0, cpu_env, t0, t1);
3588 break;
3589 case OPC_VR54XX_MULSHIU:
3590 gen_helper_mulshiu(t0, cpu_env, t0, t1);
3591 break;
3592 case OPC_VR54XX_MACCHI:
3593 gen_helper_macchi(t0, cpu_env, t0, t1);
3594 break;
3595 case OPC_VR54XX_MACCHIU:
3596 gen_helper_macchiu(t0, cpu_env, t0, t1);
3597 break;
3598 case OPC_VR54XX_MSACHI:
3599 gen_helper_msachi(t0, cpu_env, t0, t1);
3600 break;
3601 case OPC_VR54XX_MSACHIU:
3602 gen_helper_msachiu(t0, cpu_env, t0, t1);
3603 break;
3604 default:
3605 MIPS_INVAL("mul vr54xx");
3606 generate_exception_end(ctx, EXCP_RI);
3607 goto out;
3608 }
3609 gen_store_gpr(t0, rd);
3610
3611 out:
3612 tcg_temp_free(t0);
3613 tcg_temp_free(t1);
3614 }
3615
3616 static void gen_cl (DisasContext *ctx, uint32_t opc,
3617 int rd, int rs)
3618 {
3619 TCGv t0;
3620
3621 if (rd == 0) {
3622 /* Treat as NOP. */
3623 return;
3624 }
3625 t0 = tcg_temp_new();
3626 gen_load_gpr(t0, rs);
3627 switch (opc) {
3628 case OPC_CLO:
3629 case R6_OPC_CLO:
3630 gen_helper_clo(cpu_gpr[rd], t0);
3631 break;
3632 case OPC_CLZ:
3633 case R6_OPC_CLZ:
3634 gen_helper_clz(cpu_gpr[rd], t0);
3635 break;
3636 #if defined(TARGET_MIPS64)
3637 case OPC_DCLO:
3638 case R6_OPC_DCLO:
3639 gen_helper_dclo(cpu_gpr[rd], t0);
3640 break;
3641 case OPC_DCLZ:
3642 case R6_OPC_DCLZ:
3643 gen_helper_dclz(cpu_gpr[rd], t0);
3644 break;
3645 #endif
3646 }
3647 tcg_temp_free(t0);
3648 }
3649
3650 /* Godson integer instructions */
3651 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3652 int rd, int rs, int rt)
3653 {
3654 TCGv t0, t1;
3655
3656 if (rd == 0) {
3657 /* Treat as NOP. */
3658 return;
3659 }
3660
3661 switch (opc) {
3662 case OPC_MULT_G_2E:
3663 case OPC_MULT_G_2F:
3664 case OPC_MULTU_G_2E:
3665 case OPC_MULTU_G_2F:
3666 #if defined(TARGET_MIPS64)
3667 case OPC_DMULT_G_2E:
3668 case OPC_DMULT_G_2F:
3669 case OPC_DMULTU_G_2E:
3670 case OPC_DMULTU_G_2F:
3671 #endif
3672 t0 = tcg_temp_new();
3673 t1 = tcg_temp_new();
3674 break;
3675 default:
3676 t0 = tcg_temp_local_new();
3677 t1 = tcg_temp_local_new();
3678 break;
3679 }
3680
3681 gen_load_gpr(t0, rs);
3682 gen_load_gpr(t1, rt);
3683
3684 switch (opc) {
3685 case OPC_MULT_G_2E:
3686 case OPC_MULT_G_2F:
3687 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3688 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3689 break;
3690 case OPC_MULTU_G_2E:
3691 case OPC_MULTU_G_2F:
3692 tcg_gen_ext32u_tl(t0, t0);
3693 tcg_gen_ext32u_tl(t1, t1);
3694 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3695 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3696 break;
3697 case OPC_DIV_G_2E:
3698 case OPC_DIV_G_2F:
3699 {
3700 TCGLabel *l1 = gen_new_label();
3701 TCGLabel *l2 = gen_new_label();
3702 TCGLabel *l3 = gen_new_label();
3703 tcg_gen_ext32s_tl(t0, t0);
3704 tcg_gen_ext32s_tl(t1, t1);
3705 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3706 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3707 tcg_gen_br(l3);
3708 gen_set_label(l1);
3709 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3710 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3711 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3712 tcg_gen_br(l3);
3713 gen_set_label(l2);
3714 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3715 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3716 gen_set_label(l3);
3717 }
3718 break;
3719 case OPC_DIVU_G_2E:
3720 case OPC_DIVU_G_2F:
3721 {
3722 TCGLabel *l1 = gen_new_label();
3723 TCGLabel *l2 = gen_new_label();
3724 tcg_gen_ext32u_tl(t0, t0);
3725 tcg_gen_ext32u_tl(t1, t1);
3726 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3727 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3728 tcg_gen_br(l2);
3729 gen_set_label(l1);
3730 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3731 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3732 gen_set_label(l2);
3733 }
3734 break;
3735 case OPC_MOD_G_2E:
3736 case OPC_MOD_G_2F:
3737 {
3738 TCGLabel *l1 = gen_new_label();
3739 TCGLabel *l2 = gen_new_label();
3740 TCGLabel *l3 = gen_new_label();
3741 tcg_gen_ext32u_tl(t0, t0);
3742 tcg_gen_ext32u_tl(t1, t1);
3743 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3744 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3745 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3746 gen_set_label(l1);
3747 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3748 tcg_gen_br(l3);
3749 gen_set_label(l2);
3750 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3751 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3752 gen_set_label(l3);
3753 }
3754 break;
3755 case OPC_MODU_G_2E:
3756 case OPC_MODU_G_2F:
3757 {
3758 TCGLabel *l1 = gen_new_label();
3759 TCGLabel *l2 = gen_new_label();
3760 tcg_gen_ext32u_tl(t0, t0);
3761 tcg_gen_ext32u_tl(t1, t1);
3762 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3763 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3764 tcg_gen_br(l2);
3765 gen_set_label(l1);
3766 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3767 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3768 gen_set_label(l2);
3769 }
3770 break;
3771 #if defined(TARGET_MIPS64)
3772 case OPC_DMULT_G_2E:
3773 case OPC_DMULT_G_2F:
3774 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3775 break;
3776 case OPC_DMULTU_G_2E:
3777 case OPC_DMULTU_G_2F:
3778 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3779 break;
3780 case OPC_DDIV_G_2E:
3781 case OPC_DDIV_G_2F:
3782 {
3783 TCGLabel *l1 = gen_new_label();
3784 TCGLabel *l2 = gen_new_label();
3785 TCGLabel *l3 = gen_new_label();
3786 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3787 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3788 tcg_gen_br(l3);
3789 gen_set_label(l1);
3790 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3791 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3792 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3793 tcg_gen_br(l3);
3794 gen_set_label(l2);
3795 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3796 gen_set_label(l3);
3797 }
3798 break;
3799 case OPC_DDIVU_G_2E:
3800 case OPC_DDIVU_G_2F:
3801 {
3802 TCGLabel *l1 = gen_new_label();
3803 TCGLabel *l2 = gen_new_label();
3804 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3805 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3806 tcg_gen_br(l2);
3807 gen_set_label(l1);
3808 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3809 gen_set_label(l2);
3810 }
3811 break;
3812 case OPC_DMOD_G_2E:
3813 case OPC_DMOD_G_2F:
3814 {
3815 TCGLabel *l1 = gen_new_label();
3816 TCGLabel *l2 = gen_new_label();
3817 TCGLabel *l3 = gen_new_label();
3818 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3819 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3820 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3821 gen_set_label(l1);
3822 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3823 tcg_gen_br(l3);
3824 gen_set_label(l2);
3825 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3826 gen_set_label(l3);
3827 }
3828 break;
3829 case OPC_DMODU_G_2E:
3830 case OPC_DMODU_G_2F:
3831 {
3832 TCGLabel *l1 = gen_new_label();
3833 TCGLabel *l2 = gen_new_label();
3834 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3835 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3836 tcg_gen_br(l2);
3837 gen_set_label(l1);
3838 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3839 gen_set_label(l2);
3840 }
3841 break;
3842 #endif
3843 }
3844
3845 tcg_temp_free(t0);
3846 tcg_temp_free(t1);
3847 }
3848
3849 /* Loongson multimedia instructions */
3850 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3851 {
3852 uint32_t opc, shift_max;
3853 TCGv_i64 t0, t1;
3854
3855 opc = MASK_LMI(ctx->opcode);
3856 switch (opc) {
3857 case OPC_ADD_CP2:
3858 case OPC_SUB_CP2:
3859 case OPC_DADD_CP2:
3860 case OPC_DSUB_CP2:
3861 t0 = tcg_temp_local_new_i64();
3862 t1 = tcg_temp_local_new_i64();
3863 break;
3864 default:
3865 t0 = tcg_temp_new_i64();
3866 t1 = tcg_temp_new_i64();
3867 break;
3868 }
3869
3870 gen_load_fpr64(ctx, t0, rs);
3871 gen_load_fpr64(ctx, t1, rt);
3872
3873 #define LMI_HELPER(UP, LO) \
3874 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3875 #define LMI_HELPER_1(UP, LO) \
3876 case OPC_##UP: gen_helper_##LO(t0, t0); break
3877 #define LMI_DIRECT(UP, LO, OP) \
3878 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3879
3880 switch (opc) {
3881 LMI_HELPER(PADDSH, paddsh);
3882 LMI_HELPER(PADDUSH, paddush);
3883 LMI_HELPER(PADDH, paddh);
3884 LMI_HELPER(PADDW, paddw);
3885 LMI_HELPER(PADDSB, paddsb);
3886 LMI_HELPER(PADDUSB, paddusb);
3887 LMI_HELPER(PADDB, paddb);
3888
3889 LMI_HELPER(PSUBSH, psubsh);
3890 LMI_HELPER(PSUBUSH, psubush);
3891 LMI_HELPER(PSUBH, psubh);
3892 LMI_HELPER(PSUBW, psubw);
3893 LMI_HELPER(PSUBSB, psubsb);
3894 LMI_HELPER(PSUBUSB, psubusb);
3895 LMI_HELPER(PSUBB, psubb);
3896
3897 LMI_HELPER(PSHUFH, pshufh);
3898 LMI_HELPER(PACKSSWH, packsswh);
3899 LMI_HELPER(PACKSSHB, packsshb);
3900 LMI_HELPER(PACKUSHB, packushb);
3901
3902 LMI_HELPER(PUNPCKLHW, punpcklhw);
3903 LMI_HELPER(PUNPCKHHW, punpckhhw);
3904 LMI_HELPER(PUNPCKLBH, punpcklbh);
3905 LMI_HELPER(PUNPCKHBH, punpckhbh);
3906 LMI_HELPER(PUNPCKLWD, punpcklwd);
3907 LMI_HELPER(PUNPCKHWD, punpckhwd);
3908
3909 LMI_HELPER(PAVGH, pavgh);
3910 LMI_HELPER(PAVGB, pavgb);
3911 LMI_HELPER(PMAXSH, pmaxsh);
3912 LMI_HELPER(PMINSH, pminsh);
3913 LMI_HELPER(PMAXUB, pmaxub);
3914 LMI_HELPER(PMINUB, pminub);
3915
3916 LMI_HELPER(PCMPEQW, pcmpeqw);
3917 LMI_HELPER(PCMPGTW, pcmpgtw);
3918 LMI_HELPER(PCMPEQH, pcmpeqh);
3919 LMI_HELPER(PCMPGTH, pcmpgth);
3920 LMI_HELPER(PCMPEQB, pcmpeqb);
3921 LMI_HELPER(PCMPGTB, pcmpgtb);
3922
3923 LMI_HELPER(PSLLW, psllw);
3924 LMI_HELPER(PSLLH, psllh);
3925 LMI_HELPER(PSRLW, psrlw);
3926 LMI_HELPER(PSRLH, psrlh);
3927 LMI_HELPER(PSRAW, psraw);
3928 LMI_HELPER(PSRAH, psrah);
3929
3930 LMI_HELPER(PMULLH, pmullh);
3931 LMI_HELPER(PMULHH, pmulhh);
3932 LMI_HELPER(PMULHUH, pmulhuh);
3933 LMI_HELPER(PMADDHW, pmaddhw);
3934
3935 LMI_HELPER(PASUBUB, pasubub);
3936 LMI_HELPER_1(BIADD, biadd);
3937 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3938
3939 LMI_DIRECT(PADDD, paddd, add);
3940 LMI_DIRECT(PSUBD, psubd, sub);
3941 LMI_DIRECT(XOR_CP2, xor, xor);
3942 LMI_DIRECT(NOR_CP2, nor, nor);
3943 LMI_DIRECT(AND_CP2, and, and);
3944 LMI_DIRECT(PANDN, pandn, andc);
3945 LMI_DIRECT(OR, or, or);
3946
3947 case OPC_PINSRH_0:
3948 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3949 break;
3950 case OPC_PINSRH_1:
3951 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3952 break;
3953 case OPC_PINSRH_2:
3954 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3955 break;
3956 case OPC_PINSRH_3:
3957 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3958 break;
3959
3960 case OPC_PEXTRH:
3961 tcg_gen_andi_i64(t1, t1, 3);
3962 tcg_gen_shli_i64(t1, t1, 4);
3963 tcg_gen_shr_i64(t0, t0, t1);
3964 tcg_gen_ext16u_i64(t0, t0);
3965 break;
3966
3967 case OPC_ADDU_CP2:
3968 tcg_gen_add_i64(t0, t0, t1);
3969 tcg_gen_ext32s_i64(t0, t0);
3970 break;
3971 case OPC_SUBU_CP2:
3972 tcg_gen_sub_i64(t0, t0, t1);
3973 tcg_gen_ext32s_i64(t0, t0);
3974 break;
3975
3976 case OPC_SLL_CP2:
3977 shift_max = 32;
3978 goto do_shift;
3979 case OPC_SRL_CP2:
3980 shift_max = 32;
3981 goto do_shift;
3982 case OPC_SRA_CP2:
3983 shift_max = 32;
3984 goto do_shift;
3985 case OPC_DSLL_CP2:
3986 shift_max = 64;
3987 goto do_shift;
3988 case OPC_DSRL_CP2:
3989 shift_max = 64;
3990 goto do_shift;
3991 case OPC_DSRA_CP2:
3992 shift_max = 64;
3993 goto do_shift;
3994 do_shift:
3995 /* Make sure shift count isn't TCG undefined behaviour. */
3996 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3997
3998 switch (opc) {
3999 case OPC_SLL_CP2:
4000 case OPC_DSLL_CP2:
4001 tcg_gen_shl_i64(t0, t0, t1);
4002 break;
4003 case OPC_SRA_CP2:
4004 case OPC_DSRA_CP2:
4005 /* Since SRA is UndefinedResult without sign-extended inputs,
4006 we can treat SRA and DSRA the same. */
4007 tcg_gen_sar_i64(t0, t0, t1);
4008 break;
4009 case OPC_SRL_CP2:
4010 /* We want to shift in zeros for SRL; zero-extend first. */
4011 tcg_gen_ext32u_i64(t0, t0);
4012 /* FALLTHRU */
4013 case OPC_DSRL_CP2:
4014 tcg_gen_shr_i64(t0, t0, t1);
4015 break;
4016 }
4017
4018 if (shift_max == 32) {
4019 tcg_gen_ext32s_i64(t0, t0);
4020 }
4021
4022 /* Shifts larger than MAX produce zero. */
4023 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4024 tcg_gen_neg_i64(t1, t1);
4025 tcg_gen_and_i64(t0, t0, t1);
4026 break;
4027
4028 case OPC_ADD_CP2:
4029 case OPC_DADD_CP2:
4030 {
4031 TCGv_i64 t2 = tcg_temp_new_i64();
4032 TCGLabel *lab = gen_new_label();
4033
4034 tcg_gen_mov_i64(t2, t0);
4035 tcg_gen_add_i64(t0, t1, t2);
4036 if (opc == OPC_ADD_CP2) {
4037 tcg_gen_ext32s_i64(t0, t0);
4038 }
4039 tcg_gen_xor_i64(t1, t1, t2);
4040 tcg_gen_xor_i64(t2, t2, t0);
4041 tcg_gen_andc_i64(t1, t2, t1);
4042 tcg_temp_free_i64(t2);
4043 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4044 generate_exception(ctx, EXCP_OVERFLOW);
4045 gen_set_label(lab);
4046 break;
4047 }
4048
4049 case OPC_SUB_CP2:
4050 case OPC_DSUB_CP2:
4051 {
4052 TCGv_i64 t2 = tcg_temp_new_i64();
4053 TCGLabel *lab = gen_new_label();
4054
4055 tcg_gen_mov_i64(t2, t0);
4056 tcg_gen_sub_i64(t0, t1, t2);
4057 if (opc == OPC_SUB_CP2) {
4058 tcg_gen_ext32s_i64(t0, t0);
4059 }
4060 tcg_gen_xor_i64(t1, t1, t2);
4061 tcg_gen_xor_i64(t2, t2, t0);
4062 tcg_gen_and_i64(t1, t1, t2);
4063 tcg_temp_free_i64(t2);
4064 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4065 generate_exception(ctx, EXCP_OVERFLOW);
4066 gen_set_label(lab);
4067 break;
4068 }
4069
4070 case OPC_PMULUW:
4071 tcg_gen_ext32u_i64(t0, t0);
4072 tcg_gen_ext32u_i64(t1, t1);
4073 tcg_gen_mul_i64(t0, t0, t1);
4074 break;
4075
4076 case OPC_SEQU_CP2:
4077 case OPC_SEQ_CP2:
4078 case OPC_SLTU_CP2:
4079 case OPC_SLT_CP2:
4080 case OPC_SLEU_CP2:
4081 case OPC_SLE_CP2:
4082 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4083 FD field is the CC field? */
4084 default:
4085 MIPS_INVAL("loongson_cp2");
4086 generate_exception_end(ctx, EXCP_RI);
4087 return;
4088 }
4089
4090 #undef LMI_HELPER
4091 #undef LMI_DIRECT
4092
4093 gen_store_fpr64(ctx, t0, rd);
4094
4095 tcg_temp_free_i64(t0);
4096 tcg_temp_free_i64(t1);
4097 }
4098
4099 /* Traps */
4100 static void gen_trap (DisasContext *ctx, uint32_t opc,
4101 int rs, int rt, int16_t imm)
4102 {
4103 int cond;
4104 TCGv t0 = tcg_temp_new();
4105 TCGv t1 = tcg_temp_new();
4106
4107 cond = 0;
4108 /* Load needed operands */
4109 switch (opc) {
4110 case OPC_TEQ:
4111 case OPC_TGE:
4112 case OPC_TGEU:
4113 case OPC_TLT:
4114 case OPC_TLTU:
4115 case OPC_TNE:
4116 /* Compare two registers */
4117 if (rs != rt) {
4118 gen_load_gpr(t0, rs);
4119 gen_load_gpr(t1, rt);
4120 cond = 1;
4121 }
4122 break;
4123 case OPC_TEQI:
4124 case OPC_TGEI:
4125 case OPC_TGEIU:
4126 case OPC_TLTI:
4127 case OPC_TLTIU:
4128 case OPC_TNEI:
4129 /* Compare register to immediate */
4130 if (rs != 0 || imm != 0) {
4131 gen_load_gpr(t0, rs);
4132 tcg_gen_movi_tl(t1, (int32_t)imm);
4133 cond = 1;
4134 }
4135 break;
4136 }
4137 if (cond == 0) {
4138 switch (opc) {
4139 case OPC_TEQ: /* rs == rs */
4140 case OPC_TEQI: /* r0 == 0 */
4141 case OPC_TGE: /* rs >= rs */
4142 case OPC_TGEI: /* r0 >= 0 */
4143 case OPC_TGEU: /* rs >= rs unsigned */
4144 case OPC_TGEIU: /* r0 >= 0 unsigned */
4145 /* Always trap */
4146 generate_exception_end(ctx, EXCP_TRAP);
4147 break;
4148 case OPC_TLT: /* rs < rs */
4149 case OPC_TLTI: /* r0 < 0 */
4150 case OPC_TLTU: /* rs < rs unsigned */
4151 case OPC_TLTIU: /* r0 < 0 unsigned */
4152 case OPC_TNE: /* rs != rs */
4153 case OPC_TNEI: /* r0 != 0 */
4154 /* Never trap: treat as NOP. */
4155 break;
4156 }
4157 } else {
4158 TCGLabel *l1 = gen_new_label();
4159
4160 switch (opc) {
4161 case OPC_TEQ:
4162 case OPC_TEQI:
4163 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4164 break;
4165 case OPC_TGE:
4166 case OPC_TGEI:
4167 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4168 break;
4169 case OPC_TGEU:
4170 case OPC_TGEIU:
4171 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4172 break;
4173 case OPC_TLT:
4174 case OPC_TLTI:
4175 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4176 break;
4177 case OPC_TLTU:
4178 case OPC_TLTIU:
4179 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4180 break;
4181 case OPC_TNE:
4182 case OPC_TNEI:
4183 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4184 break;
4185 }
4186 generate_exception(ctx, EXCP_TRAP);
4187 gen_set_label(l1);
4188 }
4189 tcg_temp_free(t0);
4190 tcg_temp_free(t1);
4191 }
4192
4193 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4194 {
4195 TranslationBlock *tb;
4196 tb = ctx->tb;
4197 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4198 likely(!ctx->singlestep_enabled)) {
4199 tcg_gen_goto_tb(n);
4200 gen_save_pc(dest);
4201 tcg_gen_exit_tb((uintptr_t)tb + n);
4202 } else {
4203 gen_save_pc(dest);
4204 if (ctx->singlestep_enabled) {
4205 save_cpu_state(ctx, 0);
4206 gen_helper_raise_exception_debug(cpu_env);
4207 }
4208 tcg_gen_exit_tb(0);
4209 }
4210 }
4211
4212 /* Branches (before delay slot) */
4213 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4214 int insn_bytes,
4215 int rs, int rt, int32_t offset,
4216 int delayslot_size)
4217 {
4218 target_ulong btgt = -1;
4219 int blink = 0;
4220 int bcond_compute = 0;
4221 TCGv t0 = tcg_temp_new();
4222 TCGv t1 = tcg_temp_new();
4223
4224 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4225 #ifdef MIPS_DEBUG_DISAS
4226 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4227 TARGET_FMT_lx "\n", ctx->pc);
4228 #endif
4229 generate_exception_end(ctx, EXCP_RI);
4230 goto out;
4231 }
4232
4233 /* Load needed operands */
4234 switch (opc) {
4235 case OPC_BEQ:
4236 case OPC_BEQL:
4237 case OPC_BNE:
4238 case OPC_BNEL:
4239 /* Compare two registers */
4240 if (rs != rt) {
4241 gen_load_gpr(t0, rs);
4242 gen_load_gpr(t1, rt);
4243 bcond_compute = 1;
4244 }
4245 btgt = ctx->pc + insn_bytes + offset;
4246 break;
4247 case OPC_BGEZ:
4248 case OPC_BGEZAL:
4249 case OPC_BGEZALL:
4250 case OPC_BGEZL:
4251 case OPC_BGTZ:
4252 case OPC_BGTZL:
4253 case OPC_BLEZ:
4254 case OPC_BLEZL:
4255 case OPC_BLTZ:
4256 case OPC_BLTZAL:
4257 case OPC_BLTZALL:
4258 case OPC_BLTZL:
4259 /* Compare to zero */
4260 if (rs != 0) {
4261 gen_load_gpr(t0, rs);
4262 bcond_compute = 1;
4263 }
4264 btgt = ctx->pc + insn_bytes + offset;
4265 break;
4266 case OPC_BPOSGE32:
4267 #if defined(TARGET_MIPS64)
4268 case OPC_BPOSGE64:
4269 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4270 #else
4271 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4272 #endif
4273 bcond_compute = 1;
4274 btgt = ctx->pc + insn_bytes + offset;
4275 break;
4276 case OPC_J:
4277 case OPC_JAL:
4278 case OPC_JALX:
4279 /* Jump to immediate */
4280 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4281 break;
4282 case OPC_JR:
4283 case OPC_JALR:
4284 /* Jump to register */
4285 if (offset != 0 && offset != 16) {
4286 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4287 others are reserved. */
4288 MIPS_INVAL("jump hint");
4289 generate_exception_end(ctx, EXCP_RI);
4290 goto out;
4291 }
4292 gen_load_gpr(btarget, rs);
4293 break;
4294 default:
4295 MIPS_INVAL("branch/jump");
4296 generate_exception_end(ctx, EXCP_RI);
4297 goto out;
4298 }
4299 if (bcond_compute == 0) {
4300 /* No condition to be computed */
4301 switch (opc) {
4302 case OPC_BEQ: /* rx == rx */
4303 case OPC_BEQL: /* rx == rx likely */
4304 case OPC_BGEZ: /* 0 >= 0 */
4305 case OPC_BGEZL: /* 0 >= 0 likely */
4306 case OPC_BLEZ: /* 0 <= 0 */
4307 case OPC_BLEZL: /* 0 <= 0 likely */
4308 /* Always take */
4309 ctx->hflags |= MIPS_HFLAG_B;
4310 break;
4311 case OPC_BGEZAL: /* 0 >= 0 */
4312 case OPC_BGEZALL: /* 0 >= 0 likely */
4313 /* Always take and link */
4314 blink = 31;
4315 ctx->hflags |= MIPS_HFLAG_B;
4316 break;
4317 case OPC_BNE: /* rx != rx */
4318 case OPC_BGTZ: /* 0 > 0 */
4319 case OPC_BLTZ: /* 0 < 0 */
4320 /* Treat as NOP. */
4321 goto out;
4322 case OPC_BLTZAL: /* 0 < 0 */
4323 /* Handle as an unconditional branch to get correct delay
4324 slot checking. */
4325 blink = 31;
4326 btgt = ctx->pc + insn_bytes + delayslot_size;
4327 ctx->hflags |= MIPS_HFLAG_B;
4328 break;
4329 case OPC_BLTZALL: /* 0 < 0 likely */
4330 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4331 /* Skip the instruction in the delay slot */
4332 ctx->pc += 4;
4333 goto out;
4334 case OPC_BNEL: /* rx != rx likely */
4335 case OPC_BGTZL: /* 0 > 0 likely */
4336 case OPC_BLTZL: /* 0 < 0 likely */
4337 /* Skip the instruction in the delay slot */
4338 ctx->pc += 4;
4339 goto out;
4340 case OPC_J:
4341 ctx->hflags |= MIPS_HFLAG_B;
4342 break;
4343 case OPC_JALX:
4344 ctx->hflags |= MIPS_HFLAG_BX;
4345 /* Fallthrough */
4346 case OPC_JAL:
4347 blink = 31;
4348 ctx->hflags |= MIPS_HFLAG_B;
4349 break;
4350 case OPC_JR:
4351 ctx->hflags |= MIPS_HFLAG_BR;
4352 break;
4353 case OPC_JALR:
4354 blink = rt;
4355 ctx->hflags |= MIPS_HFLAG_BR;
4356 break;
4357 default:
4358 MIPS_INVAL("branch/jump");
4359 generate_exception_end(ctx, EXCP_RI);
4360 goto out;
4361 }
4362 } else {
4363 switch (opc) {
4364 case OPC_BEQ:
4365 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4366 goto not_likely;
4367 case OPC_BEQL:
4368 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4369 goto likely;
4370 case OPC_BNE:
4371 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4372 goto not_likely;
4373 case OPC_BNEL:
4374 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4375 goto likely;
4376 case OPC_BGEZ:
4377 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4378 goto not_likely;
4379 case OPC_BGEZL:
4380 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4381 goto likely;
4382 case OPC_BGEZAL:
4383 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4384 blink = 31;
4385 goto not_likely;
4386 case OPC_BGEZALL:
4387 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4388 blink = 31;
4389 goto likely;
4390 case OPC_BGTZ:
4391 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4392 goto not_likely;
4393 case OPC_BGTZL:
4394 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4395 goto likely;
4396 case OPC_BLEZ:
4397 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4398 goto not_likely;
4399 case OPC_BLEZL:
4400 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4401 goto likely;
4402 case OPC_BLTZ:
4403 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4404 goto not_likely;
4405 case OPC_BLTZL:
4406 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4407 goto likely;
4408 case OPC_BPOSGE32:
4409 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4410 goto not_likely;
4411 #if defined(TARGET_MIPS64)
4412 case OPC_BPOSGE64:
4413 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4414 goto not_likely;
4415 #endif
4416 case OPC_BLTZAL:
4417 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4418 blink = 31;
4419 not_likely:
4420 ctx->hflags |= MIPS_HFLAG_BC;
4421 break;
4422 case OPC_BLTZALL:
4423 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4424 blink = 31;
4425 likely:
4426 ctx->hflags |= MIPS_HFLAG_BL;
4427 break;
4428 default:
4429 MIPS_INVAL("conditional branch/jump");
4430 generate_exception_end(ctx, EXCP_RI);
4431 goto out;
4432 }
4433 }
4434
4435 ctx->btarget = btgt;
4436
4437 switch (delayslot_size) {
4438 case 2:
4439 ctx->hflags |= MIPS_HFLAG_BDS16;
4440 break;
4441 case 4:
4442 ctx->hflags |= MIPS_HFLAG_BDS32;
4443 break;
4444 }
4445
4446 if (blink > 0) {
4447 int post_delay = insn_bytes + delayslot_size;
4448 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4449
4450 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4451 }
4452
4453 out:
4454 if (insn_bytes == 2)
4455 ctx->hflags |= MIPS_HFLAG_B16;
4456 tcg_temp_free(t0);
4457 tcg_temp_free(t1);
4458 }
4459
4460 /* special3 bitfield operations */
4461 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4462 int rs, int lsb, int msb)
4463 {
4464 TCGv t0 = tcg_temp_new();
4465 TCGv t1 = tcg_temp_new();
4466
4467 gen_load_gpr(t1, rs);
4468 switch (opc) {
4469 case OPC_EXT:
4470 if (lsb + msb > 31) {
4471 goto fail;
4472 }
4473 tcg_gen_shri_tl(t0, t1, lsb);
4474 if (msb != 31) {
4475 tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
4476 } else {
4477 tcg_gen_ext32s_tl(t0, t0);
4478 }
4479 break;
4480 #if defined(TARGET_MIPS64)
4481 case OPC_DEXTU:
4482 lsb += 32;
4483 goto do_dext;
4484 case OPC_DEXTM:
4485 msb += 32;
4486 goto do_dext;
4487 case OPC_DEXT:
4488 do_dext:
4489 if (lsb + msb > 63) {
4490 goto fail;
4491 }
4492 tcg_gen_shri_tl(t0, t1, lsb);
4493 if (msb != 63) {
4494 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4495 }
4496 break;
4497 #endif
4498 case OPC_INS:
4499 if (lsb > msb) {
4500 goto fail;
4501 }
4502 gen_load_gpr(t0, rt);
4503 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4504 tcg_gen_ext32s_tl(t0, t0);
4505 break;
4506 #if defined(TARGET_MIPS64)
4507 case OPC_DINSU:
4508 lsb += 32;
4509 /* FALLTHRU */
4510 case OPC_DINSM:
4511 msb += 32;
4512 /* FALLTHRU */
4513 case OPC_DINS:
4514 if (lsb > msb) {
4515 goto fail;
4516 }
4517 gen_load_gpr(t0, rt);
4518 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4519 break;
4520 #endif
4521 default:
4522 fail:
4523 MIPS_INVAL("bitops");
4524 generate_exception_end(ctx, EXCP_RI);
4525 tcg_temp_free(t0);
4526 tcg_temp_free(t1);
4527 return;
4528 }
4529 gen_store_gpr(t0, rt);
4530 tcg_temp_free(t0);
4531 tcg_temp_free(t1);
4532 }
4533
4534 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4535 {
4536 TCGv t0;
4537
4538 if (rd == 0) {
4539 /* If no destination, treat it as a NOP. */
4540 return;
4541 }
4542
4543 t0 = tcg_temp_new();
4544 gen_load_gpr(t0, rt);
4545 switch (op2) {
4546 case OPC_WSBH:
4547 {
4548 TCGv t1 = tcg_temp_new();
4549
4550 tcg_gen_shri_tl(t1, t0, 8);
4551 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4552 tcg_gen_shli_tl(t0, t0, 8);
4553 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4554 tcg_gen_or_tl(t0, t0, t1);
4555 tcg_temp_free(t1);
4556 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4557 }
4558 break;
4559 case OPC_SEB:
4560 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4561 break;
4562 case OPC_SEH:
4563 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4564 break;
4565 #if defined(TARGET_MIPS64)
4566 case OPC_DSBH:
4567 {
4568 TCGv t1 = tcg_temp_new();
4569
4570 tcg_gen_shri_tl(t1, t0, 8);
4571 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4572 tcg_gen_shli_tl(t0, t0, 8);
4573 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4574 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4575 tcg_temp_free(t1);
4576 }
4577 break;
4578 case OPC_DSHD:
4579 {
4580 TCGv t1 = tcg_temp_new();
4581
4582 tcg_gen_shri_tl(t1, t0, 16);
4583 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4584 tcg_gen_shli_tl(t0, t0, 16);
4585 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4586 tcg_gen_or_tl(t0, t0, t1);
4587 tcg_gen_shri_tl(t1, t0, 32);
4588 tcg_gen_shli_tl(t0, t0, 32);
4589 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4590 tcg_temp_free(t1);
4591 }
4592 break;
4593 #endif
4594 default:
4595 MIPS_INVAL("bsfhl");
4596 generate_exception_end(ctx, EXCP_RI);
4597 tcg_temp_free(t0);
4598 return;
4599 }
4600 tcg_temp_free(t0);
4601 }
4602
4603 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4604 int imm2)
4605 {
4606 TCGv t0;
4607 TCGv t1;
4608 if (rd == 0) {
4609 /* Treat as NOP. */
4610 return;
4611 }
4612 t0 = tcg_temp_new();
4613 t1 = tcg_temp_new();
4614 gen_load_gpr(t0, rs);
4615 gen_load_gpr(t1, rt);
4616 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4617 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4618 if (opc == OPC_LSA) {
4619 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4620 }
4621
4622 tcg_temp_free(t1);
4623 tcg_temp_free(t0);
4624
4625 return;
4626 }
4627
4628 static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4629 int bp)
4630 {
4631 TCGv t0;
4632 if (rd == 0) {
4633 /* Treat as NOP. */
4634 return;
4635 }
4636 t0 = tcg_temp_new();
4637 gen_load_gpr(t0, rt);
4638 if (bp == 0) {
4639 switch (opc) {
4640 case OPC_ALIGN:
4641 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4642 break;
4643 #if defined(TARGET_MIPS64)
4644 case OPC_DALIGN:
4645 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4646 break;
4647 #endif
4648 }
4649 } else {
4650 TCGv t1 = tcg_temp_new();
4651 gen_load_gpr(t1, rs);
4652 switch (opc) {
4653 case OPC_ALIGN:
4654 {
4655 TCGv_i64 t2 = tcg_temp_new_i64();
4656 tcg_gen_concat_tl_i64(t2, t1, t0);
4657 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4658 gen_move_low32(cpu_gpr[rd], t2);
4659 tcg_temp_free_i64(t2);
4660 }
4661 break;
4662 #if defined(TARGET_MIPS64)
4663 case OPC_DALIGN:
4664 tcg_gen_shli_tl(t0, t0, 8 * bp);
4665 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4666 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4667 break;
4668 #endif
4669 }
4670 tcg_temp_free(t1);
4671 }
4672
4673 tcg_temp_free(t0);
4674 }
4675
4676 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4677 {
4678 TCGv t0;
4679 if (rd == 0) {
4680 /* Treat as NOP. */
4681 return;
4682 }
4683 t0 = tcg_temp_new();
4684 gen_load_gpr(t0, rt);
4685 switch (opc) {
4686 case OPC_BITSWAP:
4687 gen_helper_bitswap(cpu_gpr[rd], t0);
4688 break;
4689 #if defined(TARGET_MIPS64)
4690 case OPC_DBITSWAP:
4691 gen_helper_dbitswap(cpu_gpr[rd], t0);
4692 break;
4693 #endif
4694 }
4695 tcg_temp_free(t0);
4696 }
4697
4698 #ifndef CONFIG_USER_ONLY
4699 /* CP0 (MMU and control) */
4700 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4701 {
4702 TCGv_i64 t0 = tcg_temp_new_i64();
4703 TCGv_i64 t1 = tcg_temp_new_i64();
4704
4705 tcg_gen_ext_tl_i64(t0, arg);
4706 tcg_gen_ld_i64(t1, cpu_env, off);
4707 #if defined(TARGET_MIPS64)
4708 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4709 #else
4710 tcg_gen_concat32_i64(t1, t1, t0);
4711 #endif
4712 tcg_gen_st_i64(t1, cpu_env, off);
4713 tcg_temp_free_i64(t1);
4714 tcg_temp_free_i64(t0);
4715 }
4716
4717 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4718 {
4719 TCGv_i64 t0 = tcg_temp_new_i64();
4720 TCGv_i64 t1 = tcg_temp_new_i64();
4721
4722 tcg_gen_ext_tl_i64(t0, arg);
4723 tcg_gen_ld_i64(t1, cpu_env, off);
4724 tcg_gen_concat32_i64(t1, t1, t0);
4725 tcg_gen_st_i64(t1, cpu_env, off);
4726 tcg_temp_free_i64(t1);
4727 tcg_temp_free_i64(t0);
4728 }
4729
4730 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4731 {
4732 TCGv_i64 t0 = tcg_temp_new_i64();
4733
4734 tcg_gen_ld_i64(t0, cpu_env, off);
4735 #if defined(TARGET_MIPS64)
4736 tcg_gen_shri_i64(t0, t0, 30);
4737 #else
4738 tcg_gen_shri_i64(t0, t0, 32);
4739 #endif
4740 gen_move_low32(arg, t0);
4741 tcg_temp_free_i64(t0);
4742 }
4743
4744 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4745 {
4746 TCGv_i64 t0 = tcg_temp_new_i64();
4747
4748 tcg_gen_ld_i64(t0, cpu_env, off);
4749 tcg_gen_shri_i64(t0, t0, 32 + shift);
4750 gen_move_low32(arg, t0);
4751 tcg_temp_free_i64(t0);
4752 }
4753
4754 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4755 {
4756 TCGv_i32 t0 = tcg_temp_new_i32();
4757
4758 tcg_gen_ld_i32(t0, cpu_env, off);
4759 tcg_gen_ext_i32_tl(arg, t0);
4760 tcg_temp_free_i32(t0);
4761 }
4762
4763 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4764 {
4765 tcg_gen_ld_tl(arg, cpu_env, off);
4766 tcg_gen_ext32s_tl(arg, arg);
4767 }
4768
4769 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4770 {
4771 TCGv_i32 t0 = tcg_temp_new_i32();
4772
4773 tcg_gen_trunc_tl_i32(t0, arg);
4774 tcg_gen_st_i32(t0, cpu_env, off);
4775 tcg_temp_free_i32(t0);
4776 }
4777
4778 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4779 {
4780 const char *rn = "invalid";
4781
4782 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4783 goto mfhc0_read_zero;
4784 }
4785
4786 switch (reg) {
4787 case 2:
4788 switch (sel) {
4789 case 0:
4790 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4791 rn = "EntryLo0";
4792 break;
4793 default:
4794 goto mfhc0_read_zero;
4795 }
4796 break;
4797 case 3:
4798 switch (sel) {
4799 case 0:
4800 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4801 rn = "EntryLo1";
4802 break;
4803 default:
4804 goto mfhc0_read_zero;
4805 }
4806 break;
4807 case 17:
4808 switch (sel) {
4809 case 0:
4810 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4811 ctx->CP0_LLAddr_shift);
4812 rn = "LLAddr";
4813 break;
4814 default:
4815 goto mfhc0_read_zero;
4816 }
4817 break;
4818 case 28:
4819 switch (sel) {
4820 case 0:
4821 case 2:
4822 case 4:
4823 case 6:
4824 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4825 rn = "TagLo";
4826 break;
4827 default:
4828 goto mfhc0_read_zero;
4829 }
4830 break;
4831 default:
4832 goto mfhc0_read_zero;
4833 }
4834
4835 (void)rn; /* avoid a compiler warning */
4836 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4837 return;
4838
4839 mfhc0_read_zero:
4840 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4841 tcg_gen_movi_tl(arg, 0);
4842 }
4843
4844 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4845 {
4846 const char *rn = "invalid";
4847 uint64_t mask = ctx->PAMask >> 36;
4848
4849 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4850 goto mthc0_nop;
4851 }
4852
4853 switch (reg) {
4854 case 2:
4855 switch (sel) {
4856 case 0:
4857 tcg_gen_andi_tl(arg, arg, mask);
4858 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4859 rn = "EntryLo0";
4860 break;
4861 default:
4862 goto mthc0_nop;
4863 }
4864 break;
4865 case 3:
4866 switch (sel) {
4867 case 0:
4868 tcg_gen_andi_tl(arg, arg, mask);
4869 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4870 rn = "EntryLo1";
4871 break;
4872 default:
4873 goto mthc0_nop;
4874 }
4875 break;
4876 case 17:
4877 switch (sel) {
4878 case 0:
4879 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4880 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4881 relevant for modern MIPS cores supporting MTHC0, therefore
4882 treating MTHC0 to LLAddr as NOP. */
4883 rn = "LLAddr";
4884 break;
4885 default:
4886 goto mthc0_nop;
4887 }
4888 break;
4889 case 28:
4890 switch (sel) {
4891 case 0:
4892 case 2:
4893 case 4:
4894 case 6:
4895 tcg_gen_andi_tl(arg, arg, mask);
4896 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4897 rn = "TagLo";
4898 break;
4899 default:
4900 goto mthc0_nop;
4901 }
4902 break;
4903 default:
4904 goto mthc0_nop;
4905 }
4906
4907 (void)rn; /* avoid a compiler warning */
4908 mthc0_nop:
4909 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4910 }
4911
4912 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4913 {
4914 if (ctx->insn_flags & ISA_MIPS32R6) {
4915 tcg_gen_movi_tl(arg, 0);
4916 } else {
4917 tcg_gen_movi_tl(arg, ~0);
4918 }
4919 }
4920
4921 #define CP0_CHECK(c) \
4922 do { \
4923 if (!(c)) { \
4924 goto cp0_unimplemented; \
4925 } \
4926 } while (0)
4927
4928 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4929 {
4930 const char *rn = "invalid";
4931
4932 if (sel != 0)
4933 check_insn(ctx, ISA_MIPS32);
4934
4935 switch (reg) {
4936 case 0:
4937 switch (sel) {
4938 case 0:
4939 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4940 rn = "Index";
4941 break;
4942 case 1:
4943 CP0_CHECK(ctx->insn_flags & ASE_MT);
4944 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4945 rn = "MVPControl";
4946 break;
4947 case 2:
4948 CP0_CHECK(ctx->insn_flags & ASE_MT);
4949 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4950 rn = "MVPConf0";
4951 break;
4952 case 3:
4953 CP0_CHECK(ctx->insn_flags & ASE_MT);
4954 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4955 rn = "MVPConf1";
4956 break;
4957 case 4:
4958 CP0_CHECK(ctx->vp);
4959 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
4960 rn = "VPControl";
4961 break;
4962 default:
4963 goto cp0_unimplemented;
4964 }
4965 break;
4966 case 1:
4967 switch (sel) {
4968 case 0:
4969 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4970 gen_helper_mfc0_random(arg, cpu_env);
4971 rn = "Random";
4972 break;
4973 case 1:
4974 CP0_CHECK(ctx->insn_flags & ASE_MT);
4975 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4976 rn = "VPEControl";
4977 break;
4978 case 2:
4979 CP0_CHECK(ctx->insn_flags & ASE_MT);
4980 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4981 rn = "VPEConf0";
4982 break;
4983 case 3:
4984 CP0_CHECK(ctx->insn_flags & ASE_MT);
4985 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4986 rn = "VPEConf1";
4987 break;
4988 case 4:
4989 CP0_CHECK(ctx->insn_flags & ASE_MT);
4990 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4991 rn = "YQMask";
4992 break;
4993 case 5:
4994 CP0_CHECK(ctx->insn_flags & ASE_MT);
4995 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4996 rn = "VPESchedule";
4997 break;
4998 case 6:
4999 CP0_CHECK(ctx->insn_flags & ASE_MT);
5000 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5001 rn = "VPEScheFBack";
5002 break;
5003 case 7:
5004 CP0_CHECK(ctx->insn_flags & ASE_MT);
5005 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5006 rn = "VPEOpt";
5007 break;
5008 default:
5009 goto cp0_unimplemented;
5010 }
5011 break;
5012 case 2:
5013 switch (sel) {
5014 case 0:
5015 {
5016 TCGv_i64 tmp = tcg_temp_new_i64();
5017 tcg_gen_ld_i64(tmp, cpu_env,
5018 offsetof(CPUMIPSState, CP0_EntryLo0));
5019 #if defined(TARGET_MIPS64)
5020 if (ctx->rxi) {
5021 /* Move RI/XI fields to bits 31:30 */
5022 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5023 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5024 }
5025 #endif
5026 gen_move_low32(arg, tmp);
5027 tcg_temp_free_i64(tmp);
5028 }
5029 rn = "EntryLo0";
5030 break;
5031 case 1:
5032 CP0_CHECK(ctx->insn_flags & ASE_MT);
5033 gen_helper_mfc0_tcstatus(arg, cpu_env);
5034 rn = "TCStatus";
5035 break;
5036 case 2:
5037 CP0_CHECK(ctx->insn_flags & ASE_MT);
5038 gen_helper_mfc0_tcbind(arg, cpu_env);
5039 rn = "TCBind";
5040 break;
5041 case 3:
5042 CP0_CHECK(ctx->insn_flags & ASE_MT);
5043 gen_helper_mfc0_tcrestart(arg, cpu_env);
5044 rn = "TCRestart";
5045 break;
5046 case 4:
5047 CP0_CHECK(ctx->insn_flags & ASE_MT);
5048 gen_helper_mfc0_tchalt(arg, cpu_env);
5049 rn = "TCHalt";
5050 break;
5051 case 5:
5052 CP0_CHECK(ctx->insn_flags & ASE_MT);
5053 gen_helper_mfc0_tccontext(arg, cpu_env);
5054 rn = "TCContext";
5055 break;
5056 case 6:
5057 CP0_CHECK(ctx->insn_flags & ASE_MT);
5058 gen_helper_mfc0_tcschedule(arg, cpu_env);
5059 rn = "TCSchedule";
5060 break;
5061 case 7:
5062 CP0_CHECK(ctx->insn_flags & ASE_MT);
5063 gen_helper_mfc0_tcschefback(arg, cpu_env);
5064 rn = "TCScheFBack";
5065 break;
5066 default:
5067 goto cp0_unimplemented;
5068 }
5069 break;
5070 case 3:
5071 switch (sel) {
5072 case 0:
5073 {
5074 TCGv_i64 tmp = tcg_temp_new_i64();
5075 tcg_gen_ld_i64(tmp, cpu_env,
5076 offsetof(CPUMIPSState, CP0_EntryLo1));
5077 #if defined(TARGET_MIPS64)
5078 if (ctx->rxi) {
5079 /* Move RI/XI fields to bits 31:30 */
5080 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5081 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5082 }
5083 #endif
5084 gen_move_low32(arg, tmp);
5085 tcg_temp_free_i64(tmp);
5086 }
5087 rn = "EntryLo1";
5088 break;
5089 case 1:
5090 CP0_CHECK(ctx->vp);
5091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5092 rn = "GlobalNumber";
5093 break;
5094 default:
5095 goto cp0_unimplemented;
5096 }
5097 break;
5098 case 4:
5099 switch (sel) {
5100 case 0:
5101 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5102 tcg_gen_ext32s_tl(arg, arg);
5103 rn = "Context";
5104 break;
5105 case 1:
5106 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5107 rn = "ContextConfig";
5108 goto cp0_unimplemented;
5109 // break;
5110 case 2:
5111 CP0_CHECK(ctx->ulri);
5112 tcg_gen_ld32s_tl(arg, cpu_env,
5113 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5114 rn = "UserLocal";
5115 break;
5116 default:
5117 goto cp0_unimplemented;
5118 }
5119 break;
5120 case 5:
5121 switch (sel) {
5122 case 0:
5123 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5124 rn = "PageMask";
5125 break;
5126 case 1:
5127 check_insn(ctx, ISA_MIPS32R2);
5128 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5129 rn = "PageGrain";
5130 break;
5131 default:
5132 goto cp0_unimplemented;
5133 }
5134 break;
5135 case 6:
5136 switch (sel) {
5137 case 0:
5138 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5139 rn = "Wired";
5140 break;
5141 case 1:
5142 check_insn(ctx, ISA_MIPS32R2);
5143 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5144 rn = "SRSConf0";
5145 break;
5146 case 2:
5147 check_insn(ctx, ISA_MIPS32R2);
5148 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5149 rn = "SRSConf1";
5150 break;
5151 case 3:
5152 check_insn(ctx, ISA_MIPS32R2);
5153 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5154 rn = "SRSConf2";
5155 break;
5156 case 4:
5157 check_insn(ctx, ISA_MIPS32R2);
5158 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5159 rn = "SRSConf3";
5160 break;
5161 case 5:
5162 check_insn(ctx, ISA_MIPS32R2);
5163 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5164 rn = "SRSConf4";
5165 break;
5166 default:
5167 goto cp0_unimplemented;
5168 }
5169 break;
5170 case 7:
5171 switch (sel) {
5172 case 0:
5173 check_insn(ctx, ISA_MIPS32R2);
5174 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5175 rn = "HWREna";
5176 break;
5177 default:
5178 goto cp0_unimplemented;
5179 }
5180 break;
5181 case 8:
5182 switch (sel) {
5183 case 0:
5184 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5185 tcg_gen_ext32s_tl(arg, arg);
5186 rn = "BadVAddr";
5187 break;
5188 case 1:
5189 CP0_CHECK(ctx->bi);
5190 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5191 rn = "BadInstr";
5192 break;
5193 case 2:
5194 CP0_CHECK(ctx->bp);
5195 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5196 rn = "BadInstrP";
5197 break;
5198 default:
5199 goto cp0_unimplemented;
5200 }
5201 break;
5202 case 9:
5203 switch (sel) {
5204 case 0:
5205 /* Mark as an IO operation because we read the time. */
5206 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5207 gen_io_start();
5208 }
5209 gen_helper_mfc0_count(arg, cpu_env);
5210 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5211 gen_io_end();
5212 }
5213 /* Break the TB to be able to take timer interrupts immediately
5214 after reading count. */
5215 ctx->bstate = BS_STOP;
5216 rn = "Count";
5217 break;
5218 /* 6,7 are implementation dependent */
5219 default:
5220 goto cp0_unimplemented;
5221 }
5222 break;
5223 case 10:
5224 switch (sel) {
5225 case 0:
5226 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5227 tcg_gen_ext32s_tl(arg, arg);
5228 rn = "EntryHi";
5229 break;
5230 default:
5231 goto cp0_unimplemented;
5232 }
5233 break;
5234 case 11:
5235 switch (sel) {
5236 case 0:
5237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5238 rn = "Compare";
5239 break;
5240 /* 6,7 are implementation dependent */
5241 default:
5242 goto cp0_unimplemented;
5243 }
5244 break;
5245 case 12:
5246 switch (sel) {
5247 case 0:
5248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5249 rn = "Status";
5250 break;
5251 case 1:
5252 check_insn(ctx, ISA_MIPS32R2);
5253 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5254 rn = "IntCtl";
5255 break;
5256 case 2:
5257 check_insn(ctx, ISA_MIPS32R2);
5258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5259 rn = "SRSCtl";
5260 break;
5261 case 3:
5262 check_insn(ctx, ISA_MIPS32R2);
5263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5264 rn = "SRSMap";
5265 break;
5266 default:
5267 goto cp0_unimplemented;
5268 }
5269 break;
5270 case 13:
5271 switch (sel) {
5272 case 0:
5273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5274 rn = "Cause";
5275 break;
5276 default:
5277 goto cp0_unimplemented;
5278 }
5279 break;
5280 case 14:
5281 switch (sel) {
5282 case 0:
5283 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5284 tcg_gen_ext32s_tl(arg, arg);
5285 rn = "EPC";
5286 break;
5287 default:
5288 goto cp0_unimplemented;
5289 }
5290 break;
5291 case 15:
5292 switch (sel) {
5293 case 0:
5294 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5295 rn = "PRid";
5296 break;
5297 case 1:
5298 check_insn(ctx, ISA_MIPS32R2);
5299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5300 rn = "EBase";
5301 break;
5302 case 3:
5303 check_insn(ctx, ISA_MIPS32R2);
5304 CP0_CHECK(ctx->cmgcr);
5305 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
5306 tcg_gen_ext32s_tl(arg, arg);
5307 rn = "CMGCRBase";
5308 break;
5309 default:
5310 goto cp0_unimplemented;
5311 }
5312 break;
5313 case 16:
5314 switch (sel) {
5315 case 0:
5316 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5317 rn = "Config";
5318 break;
5319 case 1:
5320 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5321 rn = "Config1";
5322 break;
5323 case 2:
5324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5325 rn = "Config2";
5326 break;
5327 case 3:
5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5329 rn = "Config3";
5330 break;
5331 case 4:
5332 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5333 rn = "Config4";
5334 break;
5335 case 5:
5336 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5337 rn = "Config5";
5338 break;
5339 /* 6,7 are implementation dependent */
5340 case 6:
5341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5342 rn = "Config6";
5343 break;
5344 case 7:
5345 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5346 rn = "Config7";
5347 break;
5348 default:
5349 goto cp0_unimplemented;
5350 }
5351 break;
5352 case 17:
5353 switch (sel) {
5354 case 0:
5355 gen_helper_mfc0_lladdr(arg, cpu_env);
5356 rn = "LLAddr";
5357 break;
5358 default:
5359 goto cp0_unimplemented;
5360 }
5361 break;
5362 case 18:
5363 switch (sel) {
5364 case 0 ... 7:
5365 gen_helper_1e0i(mfc0_watchlo, arg, sel);
5366 rn = "WatchLo";
5367 break;
5368 default:
5369 goto cp0_unimplemented;
5370 }
5371 break;
5372 case 19:
5373 switch (sel) {
5374 case 0 ...7:
5375 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5376 rn = "WatchHi";
5377 break;
5378 default:
5379 goto cp0_unimplemented;
5380 }
5381 break;
5382 case 20:
5383 switch (sel) {
5384 case 0:
5385 #if defined(TARGET_MIPS64)
5386 check_insn(ctx, ISA_MIPS3);
5387 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5388 tcg_gen_ext32s_tl(arg, arg);
5389 rn = "XContext";
5390 break;
5391 #endif
5392 default:
5393 goto cp0_unimplemented;
5394 }
5395 break;
5396 case 21:
5397 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5398 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5399 switch (sel) {
5400 case 0:
5401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5402 rn = "Framemask";
5403 break;
5404 default:
5405 goto cp0_unimplemented;
5406 }
5407 break;
5408 case 22:
5409 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5410 rn = "'Diagnostic"; /* implementation dependent */
5411 break;
5412 case 23:
5413 switch (sel) {
5414 case 0:
5415 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5416 rn = "Debug";
5417 break;
5418 case 1:
5419 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5420 rn = "TraceControl";
5421 // break;
5422 case 2:
5423 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5424 rn = "TraceControl2";
5425 // break;
5426 case 3:
5427 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5428 rn = "UserTraceData";
5429 // break;
5430 case 4:
5431 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5432 rn = "TraceBPC";
5433 // break;
5434 default:
5435 goto cp0_unimplemented;
5436 }
5437 break;
5438 case 24:
5439 switch (sel) {
5440 case 0:
5441 /* EJTAG support */
5442 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5443 tcg_gen_ext32s_tl(arg, arg);
5444 rn = "DEPC";
5445 break;
5446 default:
5447 goto cp0_unimplemented;
5448 }
5449 break;
5450 case 25:
5451 switch (sel) {
5452 case 0:
5453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5454 rn = "Performance0";
5455 break;
5456 case 1:
5457 // gen_helper_mfc0_performance1(arg);
5458 rn = "Performance1";
5459 // break;
5460 case 2:
5461 // gen_helper_mfc0_performance2(arg);
5462 rn = "Performance2";
5463 // break;
5464 case 3:
5465 // gen_helper_mfc0_performance3(arg);
5466 rn = "Performance3";
5467 // break;
5468 case 4:
5469 // gen_helper_mfc0_performance4(arg);
5470 rn = "Performance4";
5471 // break;
5472 case 5:
5473 // gen_helper_mfc0_performance5(arg);
5474 rn = "Performance5";
5475 // break;
5476 case 6:
5477 // gen_helper_mfc0_performance6(arg);
5478 rn = "Performance6";
5479 // break;
5480 case 7:
5481 // gen_helper_mfc0_performance7(arg);
5482 rn = "Performance7";
5483 // break;
5484 default:
5485 goto cp0_unimplemented;
5486 }
5487 break;
5488 case 26:
5489 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5490 rn = "ECC";
5491 break;
5492 case 27:
5493 switch (sel) {
5494 case 0 ... 3:
5495 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5496 rn = "CacheErr";
5497 break;
5498 default:
5499 goto cp0_unimplemented;
5500 }
5501 break;
5502 case 28:
5503 switch (sel) {
5504 case 0:
5505 case 2:
5506 case 4:
5507 case 6:
5508 {
5509 TCGv_i64 tmp = tcg_temp_new_i64();
5510 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5511 gen_move_low32(arg, tmp);
5512 tcg_temp_free_i64(tmp);
5513 }
5514 rn = "TagLo";
5515 break;
5516 case 1:
5517 case 3:
5518 case 5:
5519 case 7:
5520 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5521 rn = "DataLo";
5522 break;
5523 default:
5524 goto cp0_unimplemented;
5525 }
5526 break;
5527 case 29:
5528 switch (sel) {
5529 case 0:
5530 case 2:
5531 case 4:
5532 case 6:
5533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5534 rn = "TagHi";
5535 break;
5536 case 1:
5537 case 3:
5538 case 5:
5539 case 7:
5540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5541 rn = "DataHi";
5542 break;
5543 default:
5544 goto cp0_unimplemented;
5545 }
5546 break;
5547 case 30:
5548 switch (sel) {
5549 case 0:
5550 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5551 tcg_gen_ext32s_tl(arg, arg);
5552 rn = "ErrorEPC";
5553 break;
5554 default:
5555 goto cp0_unimplemented;
5556 }
5557 break;
5558 case 31:
5559 switch (sel) {
5560 case 0:
5561 /* EJTAG support */
5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5563 rn = "DESAVE";
5564 break;
5565 case 2 ... 7:
5566 CP0_CHECK(ctx->kscrexist & (1 << sel));
5567 tcg_gen_ld_tl(arg, cpu_env,
5568 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5569 tcg_gen_ext32s_tl(arg, arg);
5570 rn = "KScratch";
5571 break;
5572 default:
5573 goto cp0_unimplemented;
5574 }
5575 break;
5576 default:
5577 goto cp0_unimplemented;
5578 }
5579 (void)rn; /* avoid a compiler warning */
5580 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5581 return;
5582
5583 cp0_unimplemented:
5584 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5585 gen_mfc0_unimplemented(ctx, arg);
5586 }
5587
5588 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5589 {
5590 const char *rn = "invalid";
5591
5592 if (sel != 0)
5593 check_insn(ctx, ISA_MIPS32);
5594
5595 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5596 gen_io_start();
5597 }
5598
5599 switch (reg) {
5600 case 0:
5601 switch (sel) {
5602 case 0:
5603 gen_helper_mtc0_index(cpu_env, arg);
5604 rn = "Index";
5605 break;
5606 case 1:
5607 CP0_CHECK(ctx->insn_flags & ASE_MT);
5608 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5609 rn = "MVPControl";
5610 break;
5611 case 2:
5612 CP0_CHECK(ctx->insn_flags & ASE_MT);
5613 /* ignored */
5614 rn = "MVPConf0";
5615 break;
5616 case 3:
5617 CP0_CHECK(ctx->insn_flags & ASE_MT);
5618 /* ignored */
5619 rn = "MVPConf1";
5620 break;
5621 case 4:
5622 CP0_CHECK(ctx->vp);
5623 /* ignored */
5624 rn = "VPControl";
5625 break;
5626 default:
5627 goto cp0_unimplemented;
5628 }
5629 break;
5630 case 1:
5631 switch (sel) {
5632 case 0:
5633 /* ignored */
5634 rn = "Random";
5635 break;
5636 case 1:
5637 CP0_CHECK(ctx->insn_flags & ASE_MT);
5638 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5639 rn = "VPEControl";
5640 break;
5641 case 2:
5642 CP0_CHECK(ctx->insn_flags & ASE_MT);
5643 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5644 rn = "VPEConf0";
5645 break;
5646 case 3:
5647 CP0_CHECK(ctx->insn_flags & ASE_MT);
5648 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5649 rn = "VPEConf1";
5650 break;
5651 case 4:
5652 CP0_CHECK(ctx->insn_flags & ASE_MT);
5653 gen_helper_mtc0_yqmask(cpu_env, arg);
5654 rn = "YQMask";
5655 break;
5656 case 5:
5657 CP0_CHECK(ctx->insn_flags & ASE_MT);
5658 tcg_gen_st_tl(arg, cpu_env,
5659 offsetof(CPUMIPSState, CP0_VPESchedule));
5660 rn = "VPESchedule";
5661 break;
5662 case 6:
5663 CP0_CHECK(ctx->insn_flags & ASE_MT);
5664 tcg_gen_st_tl(arg, cpu_env,
5665 offsetof(CPUMIPSState, CP0_VPEScheFBack));
5666 rn = "VPEScheFBack";
5667 break;
5668 case 7:
5669 CP0_CHECK(ctx->insn_flags & ASE_MT);
5670 gen_helper_mtc0_vpeopt(cpu_env, arg);
5671 rn = "VPEOpt";
5672 break;
5673 default:
5674 goto cp0_unimplemented;
5675 }
5676 break;
5677 case 2:
5678 switch (sel) {
5679 case 0:
5680 gen_helper_mtc0_entrylo0(cpu_env, arg);
5681 rn = "EntryLo0";
5682 break;
5683 case 1:
5684 CP0_CHECK(ctx->insn_flags & ASE_MT);
5685 gen_helper_mtc0_tcstatus(cpu_env, arg);
5686 rn = "TCStatus";
5687 break;
5688 case 2:
5689 CP0_CHECK(ctx->insn_flags & ASE_MT);
5690 gen_helper_mtc0_tcbind(cpu_env, arg);
5691 rn = "TCBind";
5692 break;
5693 case 3:
5694 CP0_CHECK(ctx->insn_flags & ASE_MT);
5695 gen_helper_mtc0_tcrestart(cpu_env, arg);
5696 rn = "TCRestart";
5697 break;
5698 case 4:
5699 CP0_CHECK(ctx->insn_flags & ASE_MT);
5700 gen_helper_mtc0_tchalt(cpu_env, arg);
5701 rn = "TCHalt";
5702 break;
5703 case 5:
5704 CP0_CHECK(ctx->insn_flags & ASE_MT);
5705 gen_helper_mtc0_tccontext(cpu_env, arg);
5706 rn = "TCContext";
5707 break;
5708 case 6:
5709 CP0_CHECK(ctx->insn_flags & ASE_MT);
5710 gen_helper_mtc0_tcschedule(cpu_env, arg);
5711 rn = "TCSchedule";
5712 break;
5713 case 7:
5714 CP0_CHECK(ctx->insn_flags & ASE_MT);
5715 gen_helper_mtc0_tcschefback(cpu_env, arg);
5716 rn = "TCScheFBack";
5717 break;
5718 default:
5719 goto cp0_unimplemented;
5720 }
5721 break;
5722 case 3:
5723 switch (sel) {
5724 case 0:
5725 gen_helper_mtc0_entrylo1(cpu_env, arg);
5726 rn = "EntryLo1";
5727 break;
5728 case 1:
5729 CP0_CHECK(ctx->vp);
5730 /* ignored */
5731 rn = "GlobalNumber";
5732 break;
5733 default:
5734 goto cp0_unimplemented;
5735 }
5736 break;
5737 case 4:
5738 switch (sel) {
5739 case 0:
5740 gen_helper_mtc0_context(cpu_env, arg);
5741 rn = "Context";
5742 break;
5743 case 1:
5744 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5745 rn = "ContextConfig";
5746 goto cp0_unimplemented;
5747 // break;
5748 case 2:
5749 CP0_CHECK(ctx->ulri);
5750 tcg_gen_st_tl(arg, cpu_env,
5751 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5752 rn = "UserLocal";
5753 break;
5754 default:
5755 goto cp0_unimplemented;
5756 }
5757 break;
5758 case 5:
5759 switch (sel) {
5760 case 0:
5761 gen_helper_mtc0_pagemask(cpu_env, arg);
5762 rn = "PageMask";
5763 break;
5764 case 1:
5765 check_insn(ctx, ISA_MIPS32R2);
5766 gen_helper_mtc0_pagegrain(cpu_env, arg);
5767 rn = "PageGrain";
5768 ctx->bstate = BS_STOP;
5769 break;
5770 default:
5771 goto cp0_unimplemented;
5772 }
5773 break;
5774 case 6:
5775 switch (sel) {
5776 case 0:
5777 gen_helper_mtc0_wired(cpu_env, arg);
5778 rn = "Wired";
5779 break;
5780 case 1:
5781 check_insn(ctx, ISA_MIPS32R2);
5782 gen_helper_mtc0_srsconf0(cpu_env, arg);
5783 rn = "SRSConf0";
5784 break;
5785 case 2:
5786 check_insn(ctx, ISA_MIPS32R2);
5787 gen_helper_mtc0_srsconf1(cpu_env, arg);
5788 rn = "SRSConf1";
5789 break;
5790 case 3:
5791 check_insn(ctx, ISA_MIPS32R2);
5792 gen_helper_mtc0_srsconf2(cpu_env, arg);
5793 rn = "SRSConf2";
5794 break;
5795 case 4:
5796 check_insn(ctx, ISA_MIPS32R2);
5797 gen_helper_mtc0_srsconf3(cpu_env, arg);
5798 rn = "SRSConf3";
5799 break;
5800 case 5:
5801 check_insn(ctx, ISA_MIPS32R2);
5802 gen_helper_mtc0_srsconf4(cpu_env, arg);
5803 rn = "SRSConf4";
5804 break;
5805 default:
5806 goto cp0_unimplemented;
5807 }
5808 break;
5809 case 7:
5810 switch (sel) {
5811 case 0:
5812 check_insn(ctx, ISA_MIPS32R2);
5813 gen_helper_mtc0_hwrena(cpu_env, arg);
5814 ctx->bstate = BS_STOP;
5815 rn = "HWREna";
5816 break;
5817 default:
5818 goto cp0_unimplemented;
5819 }
5820 break;
5821 case 8:
5822 switch (sel) {
5823 case 0:
5824 /* ignored */
5825 rn = "BadVAddr";
5826 break;
5827 case 1:
5828 /* ignored */
5829 rn = "BadInstr";
5830 break;
5831 case 2:
5832 /* ignored */
5833 rn = "BadInstrP";
5834 break;
5835 default:
5836 goto cp0_unimplemented;
5837 }
5838 break;
5839 case 9:
5840 switch (sel) {
5841 case 0:
5842 gen_helper_mtc0_count(cpu_env, arg);
5843 rn = "Count";
5844 break;
5845 /* 6,7 are implementation dependent */
5846 default:
5847 goto cp0_unimplemented;
5848 }
5849 break;
5850 case 10:
5851 switch (sel) {
5852 case 0:
5853 gen_helper_mtc0_entryhi(cpu_env, arg);
5854 rn = "EntryHi";
5855 break;
5856 default:
5857 goto cp0_unimplemented;
5858 }
5859 break;
5860 case 11:
5861 switch (sel) {
5862 case 0:
5863 gen_helper_mtc0_compare(cpu_env, arg);
5864 rn = "Compare";
5865 break;
5866 /* 6,7 are implementation dependent */
5867 default:
5868 goto cp0_unimplemented;
5869 }
5870 break;
5871 case 12:
5872 switch (sel) {
5873 case 0:
5874 save_cpu_state(ctx, 1);
5875 gen_helper_mtc0_status(cpu_env, arg);
5876 /* BS_STOP isn't good enough here, hflags may have changed. */
5877 gen_save_pc(ctx->pc + 4);
5878 ctx->bstate = BS_EXCP;
5879 rn = "Status";
5880 break;
5881 case 1:
5882 check_insn(ctx, ISA_MIPS32R2);
5883 gen_helper_mtc0_intctl(cpu_env, arg);
5884 /* Stop translation as we may have switched the execution mode */
5885 ctx->bstate = BS_STOP;
5886 rn = "IntCtl";
5887 break;
5888 case 2:
5889 check_insn(ctx, ISA_MIPS32R2);
5890 gen_helper_mtc0_srsctl(cpu_env, arg);
5891 /* Stop translation as we may have switched the execution mode */
5892 ctx->bstate = BS_STOP;
5893 rn = "SRSCtl";
5894 break;
5895 case 3:
5896 check_insn(ctx, ISA_MIPS32R2);
5897 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5898 /* Stop translation as we may have switched the execution mode */
5899 ctx->bstate = BS_STOP;
5900 rn = "SRSMap";
5901 break;
5902 default:
5903 goto cp0_unimplemented;
5904 }
5905 break;
5906 case 13:
5907 switch (sel) {
5908 case 0:
5909 save_cpu_state(ctx, 1);
5910 gen_helper_mtc0_cause(cpu_env, arg);
5911 rn = "Cause";
5912 break;
5913 default:
5914 goto cp0_unimplemented;
5915 }
5916 break;
5917 case 14:
5918 switch (sel) {
5919 case 0:
5920 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5921 rn = "EPC";
5922 break;
5923 default:
5924 goto cp0_unimplemented;
5925 }
5926 break;
5927 case 15:
5928 switch (sel) {
5929 case 0:
5930 /* ignored */
5931 rn = "PRid";
5932 break;
5933 case 1:
5934 check_insn(ctx, ISA_MIPS32R2);
5935 gen_helper_mtc0_ebase(cpu_env, arg);
5936 rn = "EBase";
5937 break;
5938 default:
5939 goto cp0_unimplemented;
5940 }
5941 break;
5942 case 16:
5943 switch (sel) {
5944 case 0:
5945 gen_helper_mtc0_config0(cpu_env, arg);
5946 rn = "Config";
5947 /* Stop translation as we may have switched the execution mode */
5948 ctx->bstate = BS_STOP;
5949 break;
5950 case 1:
5951 /* ignored, read only */
5952 rn = "Config1";
5953 break;
5954 case 2:
5955 gen_helper_mtc0_config2(cpu_env, arg);
5956 rn = "Config2";
5957 /* Stop translation as we may have switched the execution mode */
5958 ctx->bstate = BS_STOP;
5959 break;
5960 case 3:
5961 gen_helper_mtc0_config3(cpu_env, arg);
5962 rn = "Config3";
5963 /* Stop translation as we may have switched the execution mode */
5964 ctx->bstate = BS_STOP;
5965 break;
5966 case 4:
5967 gen_helper_mtc0_config4(cpu_env, arg);
5968 rn = "Config4";
5969 ctx->bstate = BS_STOP;
5970 break;
5971 case 5:
5972 gen_helper_mtc0_config5(cpu_env, arg);
5973 rn = "Config5";
5974 /* Stop translation as we may have switched the execution mode */
5975 ctx->bstate = BS_STOP;
5976 break;
5977 /* 6,7 are implementation dependent */
5978 case 6:
5979 /* ignored */
5980 rn = "Config6";
5981 break;
5982 case 7:
5983 /* ignored */
5984 rn = "Config7";
5985 break;
5986 default:
5987 rn = "Invalid config selector";
5988 goto cp0_unimplemented;
5989 }
5990 break;
5991 case 17:
5992 switch (sel) {
5993 case 0:
5994 gen_helper_mtc0_lladdr(cpu_env, arg);
5995 rn = "LLAddr";
5996 break;
5997 default:
5998 goto cp0_unimplemented;
5999 }
6000 break;
6001 case 18:
6002 switch (sel) {
6003 case 0 ... 7:
6004 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6005 rn = "WatchLo";
6006 break;
6007 default:
6008 goto cp0_unimplemented;
6009 }
6010 break;
6011 case 19:
6012 switch (sel) {
6013 case 0 ... 7:
6014 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6015 rn = "WatchHi";
6016 break;
6017 default:
6018 goto cp0_unimplemented;
6019 }
6020 break;
6021 case 20:
6022 switch (sel) {
6023 case 0:
6024 #if defined(TARGET_MIPS64)
6025 check_insn(ctx, ISA_MIPS3);
6026 gen_helper_mtc0_xcontext(cpu_env, arg);
6027 rn = "XContext";
6028 break;
6029 #endif
6030 default:
6031 goto cp0_unimplemented;
6032 }
6033 break;
6034 case 21:
6035 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6036 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6037 switch (sel) {
6038 case 0:
6039 gen_helper_mtc0_framemask(cpu_env, arg);
6040 rn = "Framemask";
6041 break;
6042 default:
6043 goto cp0_unimplemented;
6044 }
6045 break;
6046 case 22:
6047 /* ignored */
6048 rn = "Diagnostic"; /* implementation dependent */
6049 break;
6050 case 23:
6051 switch (sel) {
6052 case 0:
6053 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6054 /* BS_STOP isn't good enough here, hflags may have changed. */
6055 gen_save_pc(ctx->pc + 4);
6056 ctx->bstate = BS_EXCP;
6057 rn = "Debug";
6058 break;
6059 case 1:
6060 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6061 rn = "TraceControl";
6062 /* Stop translation as we may have switched the execution mode */
6063 ctx->bstate = BS_STOP;
6064 // break;
6065 case 2:
6066 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6067 rn = "TraceControl2";
6068 /* Stop translation as we may have switched the execution mode */
6069 ctx->bstate = BS_STOP;
6070 // break;
6071 case 3:
6072 /* Stop translation as we may have switched the execution mode */
6073 ctx->bstate = BS_STOP;
6074 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6075 rn = "UserTraceData";
6076 /* Stop translation as we may have switched the execution mode */
6077 ctx->bstate = BS_STOP;
6078 // break;
6079 case 4:
6080 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6081 /* Stop translation as we may have switched the execution mode */
6082 ctx->bstate = BS_STOP;
6083 rn = "TraceBPC";
6084 // break;
6085 default:
6086 goto cp0_unimplemented;
6087 }
6088 break;
6089 case 24:
6090 switch (sel) {
6091 case 0:
6092 /* EJTAG support */
6093 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6094 rn = "DEPC";
6095 break;
6096 default:
6097 goto cp0_unimplemented;
6098 }
6099 break;
6100 case 25:
6101 switch (sel) {
6102 case 0:
6103 gen_helper_mtc0_performance0(cpu_env, arg);
6104 rn = "Performance0";
6105 break;
6106 case 1:
6107 // gen_helper_mtc0_performance1(arg);
6108 rn = "Performance1";
6109 // break;
6110 case 2:
6111 // gen_helper_mtc0_performance2(arg);
6112 rn = "Performance2";
6113 // break;
6114 case 3:
6115 // gen_helper_mtc0_performance3(arg);
6116 rn = "Performance3";
6117 // break;
6118 case 4:
6119 // gen_helper_mtc0_performance4(arg);
6120 rn = "Performance4";
6121 // break;
6122 case 5:
6123 // gen_helper_mtc0_performance5(arg);
6124 rn = "Performance5";
6125 // break;
6126 case 6:
6127 // gen_helper_mtc0_performance6(arg);
6128 rn = "Performance6";
6129 // break;
6130 case 7:
6131 // gen_helper_mtc0_performance7(arg);
6132 rn = "Performance7";
6133 // break;
6134 default:
6135 goto cp0_unimplemented;
6136 }
6137 break;
6138 case 26:
6139 /* ignored */
6140 rn = "ECC";
6141 break;
6142 case 27:
6143 switch (sel) {
6144 case 0 ... 3:
6145 /* ignored */
6146 rn = "CacheErr";
6147 break;
6148 default:
6149 goto cp0_unimplemented;
6150 }
6151 break;
6152 case 28:
6153 switch (sel) {
6154 case 0:
6155 case 2:
6156 case 4:
6157 case 6:
6158 gen_helper_mtc0_taglo(cpu_env, arg);
6159 rn = "TagLo";
6160 break;
6161 case 1:
6162 case 3:
6163 case 5:
6164 case 7:
6165 gen_helper_mtc0_datalo(cpu_env, arg);
6166 rn = "DataLo";
6167 break;
6168 default:
6169 goto cp0_unimplemented;
6170 }
6171 break;
6172 case 29:
6173 switch (sel) {
6174 case 0:
6175 case 2:
6176 case 4:
6177 case 6:
6178 gen_helper_mtc0_taghi(cpu_env, arg);
6179 rn = "TagHi";
6180 break;
6181 case 1:
6182 case 3:
6183 case 5:
6184 case 7:
6185 gen_helper_mtc0_datahi(cpu_env, arg);
6186 rn = "DataHi";
6187 break;
6188 default:
6189 rn = "invalid sel";
6190 goto cp0_unimplemented;
6191 }
6192 break;
6193 case 30:
6194 switch (sel) {
6195 case 0:
6196 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6197 rn = "ErrorEPC";
6198 break;
6199 default:
6200 goto cp0_unimplemented;
6201 }
6202 break;
6203 case 31:
6204 switch (sel) {
6205 case 0:
6206 /* EJTAG support */
6207 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6208 rn = "DESAVE";
6209 break;
6210 case 2 ... 7:
6211 CP0_CHECK(ctx->kscrexist & (1 << sel));
6212 tcg_gen_st_tl(arg, cpu_env,
6213 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6214 rn = "KScratch";
6215 break;
6216 default:
6217 goto cp0_unimplemented;
6218 }
6219 /* Stop translation as we may have switched the execution mode */
6220 ctx->bstate = BS_STOP;
6221 break;
6222 default:
6223 goto cp0_unimplemented;
6224 }
6225 (void)rn; /* avoid a compiler warning */
6226 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6227 /* For simplicity assume that all writes can cause interrupts. */
6228 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6229 gen_io_end();
6230 ctx->bstate = BS_STOP;
6231 }
6232 return;
6233
6234 cp0_unimplemented:
6235 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6236 }
6237
6238 #if defined(TARGET_MIPS64)
6239 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6240 {
6241 const char *rn = "invalid";
6242
6243 if (sel != 0)
6244 check_insn(ctx, ISA_MIPS64);
6245
6246 switch (reg) {
6247 case 0:
6248 switch (sel) {
6249 case 0:
6250 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6251 rn = "Index";
6252 break;
6253 case 1:
6254 CP0_CHECK(ctx->insn_flags & ASE_MT);
6255 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6256 rn = "MVPControl";
6257 break;
6258 case 2:
6259 CP0_CHECK(ctx->insn_flags & ASE_MT);
6260 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6261 rn = "MVPConf0";
6262 break;
6263 case 3:
6264 CP0_CHECK(ctx->insn_flags & ASE_MT);
6265 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6266 rn = "MVPConf1";
6267 break;
6268 case 4:
6269 CP0_CHECK(ctx->vp);
6270 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6271 rn = "VPControl";
6272 break;
6273 default:
6274 goto cp0_unimplemented;
6275 }
6276 break;
6277 case 1:
6278 switch (sel) {
6279 case 0:
6280 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6281 gen_helper_mfc0_random(arg, cpu_env);
6282 rn = "Random";
6283 break;
6284 case 1:
6285 CP0_CHECK(ctx->insn_flags & ASE_MT);
6286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6287 rn = "VPEControl";
6288 break;
6289 case 2:
6290 CP0_CHECK(ctx->insn_flags & ASE_MT);
6291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6292 rn = "VPEConf0";
6293 break;
6294 case 3:
6295 CP0_CHECK(ctx->insn_flags & ASE_MT);
6296 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6297 rn = "VPEConf1";
6298 break;
6299 case 4:
6300 CP0_CHECK(ctx->insn_flags & ASE_MT);
6301 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6302 rn = "YQMask";
6303 break;
6304 case 5:
6305 CP0_CHECK(ctx->insn_flags & ASE_MT);
6306 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6307 rn = "VPESchedule";
6308 break;
6309 case 6:
6310 CP0_CHECK(ctx->insn_flags & ASE_MT);
6311 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6312 rn = "VPEScheFBack";
6313 break;
6314 case 7:
6315 CP0_CHECK(ctx->insn_flags & ASE_MT);
6316 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6317 rn = "VPEOpt";
6318 break;
6319 default:
6320 goto cp0_unimplemented;
6321 }
6322 break;
6323 case 2:
6324 switch (sel) {
6325 case 0:
6326 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6327 rn = "EntryLo0";
6328 break;
6329 case 1:
6330 CP0_CHECK(ctx->insn_flags & ASE_MT);
6331 gen_helper_mfc0_tcstatus(arg, cpu_env);
6332 rn = "TCStatus";
6333 break;
6334 case 2:
6335 CP0_CHECK(ctx->insn_flags & ASE_MT);
6336 gen_helper_mfc0_tcbind(arg, cpu_env);
6337 rn = "TCBind";
6338 break;
6339 case 3:
6340 CP0_CHECK(ctx->insn_flags & ASE_MT);
6341 gen_helper_dmfc0_tcrestart(arg, cpu_env);
6342 rn = "TCRestart";
6343 break;
6344 case 4:
6345 CP0_CHECK(ctx->insn_flags & ASE_MT);
6346 gen_helper_dmfc0_tchalt(arg, cpu_env);
6347 rn = "TCHalt";
6348 break;
6349 case 5:
6350 CP0_CHECK(ctx->insn_flags & ASE_MT);
6351 gen_helper_dmfc0_tccontext(arg, cpu_env);
6352 rn = "TCContext";
6353 break;
6354 case 6:
6355 CP0_CHECK(ctx->insn_flags & ASE_MT);
6356 gen_helper_dmfc0_tcschedule(arg, cpu_env);
6357 rn = "TCSchedule";
6358 break;
6359 case 7:
6360 CP0_CHECK(ctx->insn_flags & ASE_MT);
6361 gen_helper_dmfc0_tcschefback(arg, cpu_env);
6362 rn = "TCScheFBack";
6363 break;
6364 default:
6365 goto cp0_unimplemented;
6366 }
6367 break;
6368 case 3:
6369 switch (sel) {
6370 case 0:
6371 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6372 rn = "EntryLo1";
6373 break;
6374 case 1:
6375 CP0_CHECK(ctx->vp);
6376 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6377 rn = "GlobalNumber";
6378 break;
6379 default:
6380 goto cp0_unimplemented;
6381 }
6382 break;
6383 case 4:
6384 switch (sel) {
6385 case 0:
6386 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6387 rn = "Context";
6388 break;
6389 case 1:
6390 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6391 rn = "ContextConfig";
6392 goto cp0_unimplemented;
6393 // break;
6394 case 2:
6395 CP0_CHECK(ctx->ulri);
6396 tcg_gen_ld_tl(arg, cpu_env,
6397 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6398 rn = "UserLocal";
6399 break;
6400 default:
6401 goto cp0_unimplemented;
6402 }
6403 break;
6404 case 5:
6405 switch (sel) {
6406 case 0:
6407 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6408 rn = "PageMask";
6409 break;
6410 case 1:
6411 check_insn(ctx, ISA_MIPS32R2);
6412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6413 rn = "PageGrain";
6414 break;
6415 default:
6416 goto cp0_unimplemented;
6417 }
6418 break;
6419 case 6:
6420 switch (sel) {
6421 case 0:
6422 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6423 rn = "Wired";
6424 break;
6425 case 1:
6426 check_insn(ctx, ISA_MIPS32R2);
6427 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6428 rn = "SRSConf0";
6429 break;
6430 case 2:
6431 check_insn(ctx, ISA_MIPS32R2);
6432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6433 rn = "SRSConf1";
6434 break;
6435 case 3:
6436 check_insn(ctx, ISA_MIPS32R2);
6437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6438 rn = "SRSConf2";
6439 break;
6440 case 4:
6441 check_insn(ctx, ISA_MIPS32R2);
6442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6443 rn = "SRSConf3";
6444 break;
6445 case 5:
6446 check_insn(ctx, ISA_MIPS32R2);
6447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6448 rn = "SRSConf4";
6449 break;
6450 default:
6451 goto cp0_unimplemented;
6452 }
6453 break;
6454 case 7:
6455 switch (sel) {
6456 case 0:
6457 check_insn(ctx, ISA_MIPS32R2);
6458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6459 rn = "HWREna";
6460 break;
6461 default:
6462 goto cp0_unimplemented;
6463 }
6464 break;
6465 case 8:
6466 switch (sel) {
6467 case 0:
6468 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6469 rn = "BadVAddr";
6470 break;
6471 case 1:
6472 CP0_CHECK(ctx->bi);
6473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6474 rn = "BadInstr";
6475 break;
6476 case 2:
6477 CP0_CHECK(ctx->bp);
6478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6479 rn = "BadInstrP";
6480 break;
6481 default:
6482 goto cp0_unimplemented;
6483 }
6484 break;
6485 case 9:
6486 switch (sel) {
6487 case 0:
6488 /* Mark as an IO operation because we read the time. */
6489 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6490 gen_io_start();
6491 }
6492 gen_helper_mfc0_count(arg, cpu_env);
6493 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6494 gen_io_end();
6495 }
6496 /* Break the TB to be able to take timer interrupts immediately
6497 after reading count. */
6498 ctx->bstate = BS_STOP;
6499 rn = "Count";
6500 break;
6501 /* 6,7 are implementation dependent */
6502 default:
6503 goto cp0_unimplemented;
6504 }
6505 break;
6506 case 10:
6507 switch (sel) {
6508 case 0:
6509 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6510 rn = "EntryHi";
6511 break;
6512 default:
6513 goto cp0_unimplemented;
6514 }
6515 break;
6516 case 11:
6517 switch (sel) {
6518 case 0:
6519 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6520 rn = "Compare";
6521 break;
6522 /* 6,7 are implementation dependent */
6523 default:
6524 goto cp0_unimplemented;
6525 }
6526 break;
6527 case 12:
6528 switch (sel) {
6529 case 0:
6530 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6531 rn = "Status";
6532 break;
6533 case 1:
6534 check_insn(ctx, ISA_MIPS32R2);
6535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6536 rn = "IntCtl";
6537 break;
6538 case 2:
6539 check_insn(ctx, ISA_MIPS32R2);
6540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6541 rn = "SRSCtl";
6542 break;
6543 case 3:
6544 check_insn(ctx, ISA_MIPS32R2);
6545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6546 rn = "SRSMap";
6547 break;
6548 default:
6549 goto cp0_unimplemented;
6550 }
6551 break;
6552 case 13:
6553 switch (sel) {
6554 case 0:
6555 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6556 rn = "Cause";
6557 break;
6558 default:
6559 goto cp0_unimplemented;
6560 }
6561 break;
6562 case 14:
6563 switch (sel) {
6564 case 0:
6565 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6566 rn = "EPC";
6567 break;
6568 default:
6569 goto cp0_unimplemented;
6570 }
6571 break;
6572 case 15:
6573 switch (sel) {
6574 case 0:
6575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6576 rn = "PRid";
6577 break;
6578 case 1:
6579 check_insn(ctx, ISA_MIPS32R2);
6580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6581 rn = "EBase";
6582 break;
6583 case 3:
6584 check_insn(ctx, ISA_MIPS32R2);
6585 CP0_CHECK(ctx->cmgcr);
6586 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6587 rn = "CMGCRBase";
6588 break;
6589 default:
6590 goto cp0_unimplemented;
6591 }
6592 break;
6593 case 16:
6594 switch (sel) {
6595 case 0:
6596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6597 rn = "Config";
6598 break;
6599 case 1:
6600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6601 rn = "Config1";
6602 break;
6603 case 2:
6604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6605 rn = "Config2";
6606 break;
6607 case 3:
6608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6609 rn = "Config3";
6610 break;
6611 case 4:
6612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6613 rn = "Config4";
6614 break;
6615 case 5:
6616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6617 rn = "Config5";
6618 break;
6619 /* 6,7 are implementation dependent */
6620 case 6:
6621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6622 rn = "Config6";
6623 break;
6624 case 7:
6625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6626 rn = "Config7";
6627 break;
6628 default:
6629 goto cp0_unimplemented;
6630 }
6631 break;
6632 case 17:
6633 switch (sel) {
6634 case 0:
6635 gen_helper_dmfc0_lladdr(arg, cpu_env);
6636 rn = "LLAddr";
6637 break;
6638 default:
6639 goto cp0_unimplemented;
6640 }
6641 break;
6642 case 18:
6643 switch (sel) {
6644 case 0 ... 7:
6645 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6646 rn = "WatchLo";
6647 break;
6648 default:
6649 goto cp0_unimplemented;
6650 }
6651 break;
6652 case 19:
6653 switch (sel) {
6654 case 0 ... 7:
6655 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6656 rn = "WatchHi";
6657 break;
6658 default:
6659 goto cp0_unimplemented;
6660 }
6661 break;
6662 case 20:
6663 switch (sel) {
6664 case 0:
6665 check_insn(ctx, ISA_MIPS3);
6666 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6667 rn = "XContext";
6668 break;
6669 default:
6670 goto cp0_unimplemented;
6671 }
6672 break;
6673 case 21:
6674 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6675 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6676 switch (sel) {
6677 case 0:
6678 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6679 rn = "Framemask";
6680 break;
6681 default:
6682 goto cp0_unimplemented;
6683 }
6684 break;
6685 case 22:
6686 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6687 rn = "'Diagnostic"; /* implementation dependent */
6688 break;
6689 case 23:
6690 switch (sel) {
6691 case 0:
6692 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6693 rn = "Debug";
6694 break;
6695 case 1:
6696 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6697 rn = "TraceControl";
6698 // break;
6699 case 2:
6700 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6701 rn = "TraceControl2";
6702 // break;
6703 case 3:
6704 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6705 rn = "UserTraceData";
6706 // break;
6707 case 4:
6708 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6709 rn = "TraceBPC";
6710 // break;
6711 default:
6712 goto cp0_unimplemented;
6713 }
6714 break;
6715 case 24:
6716 switch (sel) {
6717 case 0:
6718 /* EJTAG support */
6719 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6720 rn = "DEPC";
6721 break;
6722 default:
6723 goto cp0_unimplemented;
6724 }
6725 break;
6726 case 25:
6727 switch (sel) {
6728 case 0:
6729 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6730 rn = "Performance0";
6731 break;
6732 case 1:
6733 // gen_helper_dmfc0_performance1(arg);
6734 rn = "Performance1";
6735 // break;
6736 case 2:
6737 // gen_helper_dmfc0_performance2(arg);
6738 rn = "Performance2";
6739 // break;
6740 case 3:
6741 // gen_helper_dmfc0_performance3(arg);
6742 rn = "Performance3";
6743 // break;
6744 case 4:
6745 // gen_helper_dmfc0_performance4(arg);
6746 rn = "Performance4";
6747 // break;
6748 case 5:
6749 // gen_helper_dmfc0_performance5(arg);
6750 rn = "Performance5";
6751 // break;
6752 case 6:
6753 // gen_helper_dmfc0_performance6(arg);
6754 rn = "Performance6";
6755 // break;
6756 case 7:
6757 // gen_helper_dmfc0_performance7(arg);
6758 rn = "Performance7";
6759 // break;
6760 default:
6761 goto cp0_unimplemented;
6762 }
6763 break;
6764 case 26:
6765 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6766 rn = "ECC";
6767 break;
6768 case 27:
6769 switch (sel) {
6770 /* ignored */
6771 case 0 ... 3:
6772 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6773 rn = "CacheErr";
6774 break;
6775 default:
6776 goto cp0_unimplemented;
6777 }
6778 break;
6779 case 28:
6780 switch (sel) {
6781 case 0:
6782 case 2:
6783 case 4:
6784 case 6:
6785 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6786 rn = "TagLo";
6787 break;
6788 case 1:
6789 case 3:
6790 case 5:
6791 case 7:
6792 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6793 rn = "DataLo";
6794 break;
6795 default:
6796 goto cp0_unimplemented;
6797 }
6798 break;
6799 case 29:
6800 switch (sel) {
6801 case 0:
6802 case 2:
6803 case 4:
6804 case 6:
6805 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6806 rn = "TagHi";
6807 break;
6808 case 1:
6809 case 3:
6810 case 5:
6811 case 7:
6812 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6813 rn = "DataHi";
6814 break;
6815 default:
6816 goto cp0_unimplemented;
6817 }
6818 break;
6819 case 30:
6820 switch (sel) {
6821 case 0:
6822 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6823 rn = "ErrorEPC";
6824 break;
6825 default:
6826 goto cp0_unimplemented;
6827 }
6828 break;
6829 case 31:
6830 switch (sel) {
6831 case 0:
6832 /* EJTAG support */
6833 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6834 rn = "DESAVE";
6835 break;
6836 case 2 ... 7:
6837 CP0_CHECK(ctx->kscrexist & (1 << sel));
6838 tcg_gen_ld_tl(arg, cpu_env,
6839 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6840 rn = "KScratch";
6841 break;
6842 default:
6843 goto cp0_unimplemented;
6844 }
6845 break;
6846 default:
6847 goto cp0_unimplemented;
6848 }
6849 (void)rn; /* avoid a compiler warning */
6850 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6851 return;
6852
6853 cp0_unimplemented:
6854 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6855 gen_mfc0_unimplemented(ctx, arg);
6856 }
6857
6858 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6859 {
6860 const char *rn = "invalid";
6861
6862 if (sel != 0)
6863 check_insn(ctx, ISA_MIPS64);
6864
6865 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6866 gen_io_start();
6867 }
6868
6869 switch (reg) {
6870 case 0:
6871 switch (sel) {
6872 case 0:
6873 gen_helper_mtc0_index(cpu_env, arg);
6874 rn = "Index";
6875 break;
6876 case 1:
6877 CP0_CHECK(ctx->insn_flags & ASE_MT);
6878 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6879 rn = "MVPControl";
6880 break;
6881 case 2:
6882 CP0_CHECK(ctx->insn_flags & ASE_MT);
6883 /* ignored */
6884 rn = "MVPConf0";
6885 break;
6886 case 3:
6887 CP0_CHECK(ctx->insn_flags & ASE_MT);
6888 /* ignored */
6889 rn = "MVPConf1";
6890 break;
6891 case 4:
6892 CP0_CHECK(ctx->vp);
6893 /* ignored */
6894 rn = "VPControl";
6895 break;
6896 default:
6897 goto cp0_unimplemented;
6898 }
6899 break;
6900 case 1:
6901 switch (sel) {
6902 case 0:
6903 /* ignored */
6904 rn = "Random";
6905 break;
6906 case 1:
6907 CP0_CHECK(ctx->insn_flags & ASE_MT);
6908 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6909 rn = "VPEControl";
6910 break;
6911 case 2:
6912 CP0_CHECK(ctx->insn_flags & ASE_MT);
6913 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6914 rn = "VPEConf0";
6915 break;
6916 case 3:
6917 CP0_CHECK(ctx->insn_flags & ASE_MT);
6918 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6919 rn = "VPEConf1";
6920 break;
6921 case 4:
6922 CP0_CHECK(ctx->insn_flags & ASE_MT);
6923 gen_helper_mtc0_yqmask(cpu_env, arg);
6924 rn = "YQMask";
6925 break;
6926 case 5:
6927 CP0_CHECK(ctx->insn_flags & ASE_MT);
6928 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6929 rn = "VPESchedule";
6930 break;
6931 case 6:
6932 CP0_CHECK(ctx->insn_flags & ASE_MT);
6933 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6934 rn = "VPEScheFBack";
6935 break;
6936 case 7:
6937 CP0_CHECK(ctx->insn_flags & ASE_MT);
6938 gen_helper_mtc0_vpeopt(cpu_env, arg);
6939 rn = "VPEOpt";
6940 break;
6941 default:
6942 goto cp0_unimplemented;
6943 }
6944 break;
6945 case 2:
6946 switch (sel) {
6947 case 0:
6948 gen_helper_dmtc0_entrylo0(cpu_env, arg);
6949 rn = "EntryLo0";
6950 break;
6951 case 1:
6952 CP0_CHECK(ctx->insn_flags & ASE_MT);
6953 gen_helper_mtc0_tcstatus(cpu_env, arg);
6954 rn = "TCStatus";
6955 break;
6956 case 2:
6957 CP0_CHECK(ctx->insn_flags & ASE_MT);
6958 gen_helper_mtc0_tcbind(cpu_env, arg);
6959 rn = "TCBind";
6960 break;
6961 case 3:
6962 CP0_CHECK(ctx->insn_flags & ASE_MT);
6963 gen_helper_mtc0_tcrestart(cpu_env, arg);
6964 rn = "TCRestart";
6965 break;
6966 case 4:
6967 CP0_CHECK(ctx->insn_flags & ASE_MT);
6968 gen_helper_mtc0_tchalt(cpu_env, arg);
6969 rn = "TCHalt";
6970 break;
6971 case 5:
6972 CP0_CHECK(ctx->insn_flags & ASE_MT);
6973 gen_helper_mtc0_tccontext(cpu_env, arg);
6974 rn = "TCContext";
6975 break;
6976 case 6:
6977 CP0_CHECK(ctx->insn_flags & ASE_MT);
6978 gen_helper_mtc0_tcschedule(cpu_env, arg);
6979 rn = "TCSchedule";
6980 break;
6981 case 7:
6982 CP0_CHECK(ctx->insn_flags & ASE_MT);
6983 gen_helper_mtc0_tcschefback(cpu_env, arg);
6984 rn = "TCScheFBack";
6985 break;
6986 default:
6987 goto cp0_unimplemented;
6988 }
6989 break;
6990 case 3:
6991 switch (sel) {
6992 case 0:
6993 gen_helper_dmtc0_entrylo1(cpu_env, arg);
6994 rn = "EntryLo1";
6995 break;
6996 case 1:
6997 CP0_CHECK(ctx->vp);
6998 /* ignored */
6999 rn = "GlobalNumber";
7000 break;
7001 default:
7002 goto cp0_unimplemented;
7003 }
7004 break;
7005 case 4:
7006 switch (sel) {
7007 case 0:
7008 gen_helper_mtc0_context(cpu_env, arg);
7009 rn = "Context";
7010 break;
7011 case 1:
7012 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7013 rn = "ContextConfig";
7014 goto cp0_unimplemented;
7015 // break;
7016 case 2:
7017 CP0_CHECK(ctx->ulri);
7018 tcg_gen_st_tl(arg, cpu_env,
7019 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7020 rn = "UserLocal";
7021 break;
7022 default:
7023 goto cp0_unimplemented;
7024 }
7025 break;
7026 case 5:
7027 switch (sel) {
7028 case 0:
7029 gen_helper_mtc0_pagemask(cpu_env, arg);
7030 rn = "PageMask";
7031 break;
7032 case 1:
7033 check_insn(ctx, ISA_MIPS32R2);
7034 gen_helper_mtc0_pagegrain(cpu_env, arg);
7035 rn = "PageGrain";
7036 break;
7037 default:
7038 goto cp0_unimplemented;
7039 }
7040 break;
7041 case 6:
7042 switch (sel) {
7043 case 0:
7044 gen_helper_mtc0_wired(cpu_env, arg);
7045 rn = "Wired";
7046 break;
7047 case 1:
7048 check_insn(ctx, ISA_MIPS32R2);
7049 gen_helper_mtc0_srsconf0(cpu_env, arg);
7050 rn = "SRSConf0";
7051 break;
7052 case 2:
7053 check_insn(ctx, ISA_MIPS32R2);
7054 gen_helper_mtc0_srsconf1(cpu_env, arg);
7055 rn = "SRSConf1";
7056 break;
7057 case 3:
7058 check_insn(ctx, ISA_MIPS32R2);
7059 gen_helper_mtc0_srsconf2(cpu_env, arg);
7060 rn = "SRSConf2";
7061 break;
7062 case 4:
7063 check_insn(ctx, ISA_MIPS32R2);
7064 gen_helper_mtc0_srsconf3(cpu_env, arg);
7065 rn = "SRSConf3";
7066 break;
7067 case 5:
7068 check_insn(ctx, ISA_MIPS32R2);
7069 gen_helper_mtc0_srsconf4(cpu_env, arg);
7070 rn = "SRSConf4";
7071 break;
7072 default:
7073 goto cp0_unimplemented;
7074 }
7075 break;
7076 case 7:
7077 switch (sel) {
7078 case 0:
7079 check_insn(ctx, ISA_MIPS32R2);
7080 gen_helper_mtc0_hwrena(cpu_env, arg);
7081 ctx->bstate = BS_STOP;
7082 rn = "HWREna";
7083 break;
7084 default:
7085 goto cp0_unimplemented;
7086 }
7087 break;
7088 case 8:
7089 switch (sel) {
7090 case 0:
7091 /* ignored */
7092 rn = "BadVAddr";
7093 break;
7094 case 1:
7095 /* ignored */
7096 rn = "BadInstr";
7097 break;
7098 case 2:
7099 /* ignored */
7100 rn = "BadInstrP";
7101 break;
7102 default:
7103 goto cp0_unimplemented;
7104 }
7105 break;
7106 case 9:
7107 switch (sel) {
7108 case 0:
7109 gen_helper_mtc0_count(cpu_env, arg);
7110 rn = "Count";
7111 break;
7112 /* 6,7 are implementation dependent */
7113 default:
7114 goto cp0_unimplemented;
7115 }
7116 /* Stop translation as we may have switched the execution mode */
7117 ctx->bstate = BS_STOP;
7118 break;
7119 case 10:
7120 switch (sel) {
7121 case 0:
7122 gen_helper_mtc0_entryhi(cpu_env, arg);
7123 rn = "EntryHi";
7124 break;
7125 default:
7126 goto cp0_unimplemented;
7127 }
7128 break;
7129 case 11:
7130 switch (sel) {
7131 case 0:
7132 gen_helper_mtc0_compare(cpu_env, arg);
7133 rn = "Compare";
7134 break;
7135 /* 6,7 are implementation dependent */
7136 default:
7137 goto cp0_unimplemented;
7138 }
7139 /* Stop translation as we may have switched the execution mode */
7140 ctx->bstate = BS_STOP;
7141 break;
7142 case 12:
7143 switch (sel) {
7144 case 0:
7145 save_cpu_state(ctx, 1);
7146 gen_helper_mtc0_status(cpu_env, arg);
7147 /* BS_STOP isn't good enough here, hflags may have changed. */
7148 gen_save_pc(ctx->pc + 4);
7149 ctx->bstate = BS_EXCP;
7150 rn = "Status";
7151 break;
7152 case 1:
7153 check_insn(ctx, ISA_MIPS32R2);
7154 gen_helper_mtc0_intctl(cpu_env, arg);
7155 /* Stop translation as we may have switched the execution mode */
7156 ctx->bstate = BS_STOP;
7157 rn = "IntCtl";
7158 break;
7159 case 2:
7160 check_insn(ctx, ISA_MIPS32R2);
7161 gen_helper_mtc0_srsctl(cpu_env, arg);
7162 /* Stop translation as we may have switched the execution mode */
7163 ctx->bstate = BS_STOP;
7164 rn = "SRSCtl";
7165 break;
7166 case 3:
7167 check_insn(ctx, ISA_MIPS32R2);
7168 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7169 /* Stop translation as we may have switched the execution mode */
7170 ctx->bstate = BS_STOP;
7171 rn = "SRSMap";
7172 break;
7173 default:
7174 goto cp0_unimplemented;
7175 }
7176 break;
7177 case 13:
7178 switch (sel) {
7179 case 0:
7180 save_cpu_state(ctx, 1);
7181 /* Mark as an IO operation because we may trigger a software
7182 interrupt. */
7183 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7184 gen_io_start();
7185 }
7186 gen_helper_mtc0_cause(cpu_env, arg);
7187 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7188 gen_io_end();
7189 }
7190 /* Stop translation as we may have triggered an intetrupt */
7191 ctx->bstate = BS_STOP;
7192 rn = "Cause";
7193 break;
7194 default:
7195 goto cp0_unimplemented;
7196 }
7197 break;
7198 case 14:
7199 switch (sel) {
7200 case 0:
7201 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7202 rn = "EPC";
7203 break;
7204 default:
7205 goto cp0_unimplemented;
7206 }
7207 break;
7208 case 15:
7209 switch (sel) {
7210 case 0:
7211 /* ignored */
7212 rn = "PRid";
7213 break;
7214 case 1:
7215 check_insn(ctx, ISA_MIPS32R2);
7216 gen_helper_mtc0_ebase(cpu_env, arg);
7217 rn = "EBase";
7218 break;
7219 default:
7220 goto cp0_unimplemented;
7221 }
7222 break;
7223 case 16:
7224 switch (sel) {
7225 case 0:
7226 gen_helper_mtc0_config0(cpu_env, arg);
7227 rn = "Config";
7228 /* Stop translation as we may have switched the execution mode */
7229 ctx->bstate = BS_STOP;
7230 break;
7231 case 1:
7232 /* ignored, read only */
7233 rn = "Config1";
7234 break;
7235 case 2:
7236 gen_helper_mtc0_config2(cpu_env, arg);
7237 rn = "Config2";
7238 /* Stop translation as we may have switched the execution mode */
7239 ctx->bstate = BS_STOP;
7240 break;
7241 case 3:
7242 gen_helper_mtc0_config3(cpu_env, arg);
7243 rn = "Config3";
7244 /* Stop translation as we may have switched the execution mode */
7245 ctx->bstate = BS_STOP;
7246 break;
7247 case 4:
7248 /* currently ignored */
7249 rn = "Config4";
7250 break;
7251 case 5:
7252 gen_helper_mtc0_config5(cpu_env, arg);
7253 rn = "Config5";
7254 /* Stop translation as we may have switched the execution mode */
7255 ctx->bstate = BS_STOP;
7256 break;
7257 /* 6,7 are implementation dependent */
7258 default:
7259 rn = "Invalid config selector";
7260 goto cp0_unimplemented;
7261 }
7262 break;
7263 case 17:
7264 switch (sel) {
7265 case 0:
7266 gen_helper_mtc0_lladdr(cpu_env, arg);
7267 rn = "LLAddr";
7268 break;
7269 default:
7270 goto cp0_unimplemented;
7271 }
7272 break;
7273 case 18:
7274 switch (sel) {
7275 case 0 ... 7:
7276 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7277 rn = "WatchLo";
7278 break;
7279 default:
7280 goto cp0_unimplemented;
7281 }
7282 break;
7283 case 19:
7284 switch (sel) {
7285 case 0 ... 7:
7286 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7287 rn = "WatchHi";
7288 break;
7289 default:
7290 goto cp0_unimplemented;
7291 }
7292 break;
7293 case 20:
7294 switch (sel) {
7295 case 0:
7296 check_insn(ctx, ISA_MIPS3);
7297 gen_helper_mtc0_xcontext(cpu_env, arg);
7298 rn = "XContext";
7299 break;
7300 default:
7301 goto cp0_unimplemented;
7302 }
7303 break;
7304 case 21:
7305 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7306 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7307 switch (sel) {
7308 case 0:
7309 gen_helper_mtc0_framemask(cpu_env, arg);
7310 rn = "Framemask";
7311 break;
7312 default:
7313 goto cp0_unimplemented;
7314 }
7315 break;
7316 case 22:
7317 /* ignored */
7318 rn = "Diagnostic"; /* implementation dependent */
7319 break;
7320 case 23:
7321 switch (sel) {
7322 case 0:
7323 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7324 /* BS_STOP isn't good enough here, hflags may have changed. */
7325 gen_save_pc(ctx->pc + 4);
7326 ctx->bstate = BS_EXCP;
7327 rn = "Debug";
7328 break;
7329 case 1:
7330 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7331 /* Stop translation as we may have switched the execution mode */
7332 ctx->bstate = BS_STOP;
7333 rn = "TraceControl";
7334 // break;
7335 case 2:
7336 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7337 /* Stop translation as we may have switched the execution mode */
7338 ctx->bstate = BS_STOP;
7339 rn = "TraceControl2";
7340 // break;
7341 case 3:
7342 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7343 /* Stop translation as we may have switched the execution mode */
7344 ctx->bstate = BS_STOP;
7345 rn = "UserTraceData";
7346 // break;
7347 case 4:
7348 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7349 /* Stop translation as we may have switched the execution mode */
7350 ctx->bstate = BS_STOP;
7351 rn = "TraceBPC";
7352 // break;
7353 default:
7354 goto cp0_unimplemented;
7355 }
7356 break;
7357 case 24:
7358 switch (sel) {
7359 case 0:
7360 /* EJTAG support */
7361 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7362 rn = "DEPC";
7363 break;
7364 default:
7365 goto cp0_unimplemented;
7366 }
7367 break;
7368 case 25:
7369 switch (sel) {
7370 case 0:
7371 gen_helper_mtc0_performance0(cpu_env, arg);
7372 rn = "Performance0";
7373 break;
7374 case 1:
7375 // gen_helper_mtc0_performance1(cpu_env, arg);
7376 rn = "Performance1";
7377 // break;
7378 case 2:
7379 // gen_helper_mtc0_performance2(cpu_env, arg);
7380 rn = "Performance2";
7381 // break;
7382 case 3:
7383 // gen_helper_mtc0_performance3(cpu_env, arg);
7384 rn = "Performance3";
7385 // break;
7386 case 4:
7387 // gen_helper_mtc0_performance4(cpu_env, arg);
7388 rn = "Performance4";
7389 // break;
7390 case 5:
7391 // gen_helper_mtc0_performance5(cpu_env, arg);
7392 rn = "Performance5";
7393 // break;
7394 case 6:
7395 // gen_helper_mtc0_performance6(cpu_env, arg);
7396 rn = "Performance6";
7397 // break;
7398 case 7:
7399 // gen_helper_mtc0_performance7(cpu_env, arg);
7400 rn = "Performance7";
7401 // break;
7402 default:
7403 goto cp0_unimplemented;
7404 }
7405 break;
7406 case 26:
7407 /* ignored */
7408 rn = "ECC";
7409 break;
7410 case 27:
7411 switch (sel) {
7412 case 0 ... 3:
7413 /* ignored */
7414 rn = "CacheErr";
7415 break;
7416 default:
7417 goto cp0_unimplemented;
7418 }
7419 break;
7420 case 28:
7421 switch (sel) {
7422 case 0:
7423 case 2:
7424 case 4:
7425 case 6:
7426 gen_helper_mtc0_taglo(cpu_env, arg);
7427 rn = "TagLo";
7428 break;
7429 case 1:
7430 case 3:
7431 case 5:
7432 case 7:
7433 gen_helper_mtc0_datalo(cpu_env, arg);
7434 rn = "DataLo";
7435 break;
7436 default:
7437 goto cp0_unimplemented;
7438 }
7439 break;
7440 case 29:
7441 switch (sel) {
7442 case 0:
7443 case 2:
7444 case 4:
7445 case 6:
7446 gen_helper_mtc0_taghi(cpu_env, arg);
7447 rn = "TagHi";
7448 break;
7449 case 1:
7450 case 3:
7451 case 5:
7452 case 7:
7453 gen_helper_mtc0_datahi(cpu_env, arg);
7454 rn = "DataHi";
7455 break;
7456 default:
7457 rn = "invalid sel";
7458 goto cp0_unimplemented;
7459 }
7460 break;
7461 case 30:
7462 switch (sel) {
7463 case 0:
7464 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7465 rn = "ErrorEPC";
7466 break;
7467 default:
7468 goto cp0_unimplemented;
7469 }
7470 break;
7471 case 31:
7472 switch (sel) {
7473 case 0:
7474 /* EJTAG support */
7475 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7476 rn = "DESAVE";
7477 break;
7478 case 2 ... 7:
7479 CP0_CHECK(ctx->kscrexist & (1 << sel));
7480 tcg_gen_st_tl(arg, cpu_env,
7481 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7482 rn = "KScratch";
7483 break;
7484 default:
7485 goto cp0_unimplemented;
7486 }
7487 /* Stop translation as we may have switched the execution mode */
7488 ctx->bstate = BS_STOP;
7489 break;
7490 default:
7491 goto cp0_unimplemented;
7492 }
7493 (void)rn; /* avoid a compiler warning */
7494 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7495 /* For simplicity assume that all writes can cause interrupts. */
7496 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7497 gen_io_end();
7498 ctx->bstate = BS_STOP;
7499 }
7500 return;
7501
7502 cp0_unimplemented:
7503 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7504 }
7505 #endif /* TARGET_MIPS64 */
7506
7507 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7508 int u, int sel, int h)
7509 {
7510 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7511 TCGv t0 = tcg_temp_local_new();
7512
7513 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7514 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7515 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7516 tcg_gen_movi_tl(t0, -1);
7517 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7518 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7519 tcg_gen_movi_tl(t0, -1);
7520 else if (u == 0) {
7521 switch (rt) {
7522 case 1:
7523 switch (sel) {
7524 case 1:
7525 gen_helper_mftc0_vpecontrol(t0, cpu_env);
7526 break;
7527 case 2:
7528 gen_helper_mftc0_vpeconf0(t0, cpu_env);
7529 break;
7530 default:
7531 goto die;
7532 break;
7533 }
7534 break;
7535 case 2:
7536 switch (sel) {
7537 case 1:
7538 gen_helper_mftc0_tcstatus(t0, cpu_env);
7539 break;
7540 case 2:
7541 gen_helper_mftc0_tcbind(t0, cpu_env);
7542 break;
7543 case 3:
7544 gen_helper_mftc0_tcrestart(t0, cpu_env);
7545 break;
7546 case 4:
7547 gen_helper_mftc0_tchalt(t0, cpu_env);
7548 break;
7549 case 5:
7550 gen_helper_mftc0_tccontext(t0, cpu_env);
7551 break;
7552 case 6:
7553 gen_helper_mftc0_tcschedule(t0, cpu_env);
7554 break;
7555 case 7:
7556 gen_helper_mftc0_tcschefback(t0, cpu_env);
7557 break;
7558 default:
7559 gen_mfc0(ctx, t0, rt, sel);
7560 break;
7561 }
7562 break;
7563 case 10:
7564 switch (sel) {
7565 case 0:
7566 gen_helper_mftc0_entryhi(t0, cpu_env);
7567 break;
7568 default:
7569 gen_mfc0(ctx, t0, rt, sel);
7570 break;
7571 }
7572 case 12:
7573 switch (sel) {
7574 case 0:
7575 gen_helper_mftc0_status(t0, cpu_env);
7576 break;
7577 default:
7578 gen_mfc0(ctx, t0, rt, sel);
7579 break;
7580 }
7581 case 13:
7582 switch (sel) {
7583 case 0:
7584 gen_helper_mftc0_cause(t0, cpu_env);
7585 break;
7586 default:
7587 goto die;
7588 break;
7589 }
7590 break;
7591 case 14:
7592 switch (sel) {
7593 case 0:
7594 gen_helper_mftc0_epc(t0, cpu_env);
7595 break;
7596 default:
7597 goto die;
7598 break;
7599 }
7600 break;
7601 case 15:
7602 switch (sel) {
7603 case 1:
7604 gen_helper_mftc0_ebase(t0, cpu_env);
7605 break;
7606 default:
7607 goto die;
7608 break;
7609 }
7610 break;
7611 case 16:
7612 switch (sel) {
7613 case 0 ... 7:
7614 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7615 break;
7616 default:
7617 goto die;
7618 break;
7619 }
7620 break;
7621 case 23:
7622 switch (sel) {
7623 case 0:
7624 gen_helper_mftc0_debug(t0, cpu_env);
7625 break;
7626 default:
7627 gen_mfc0(ctx, t0, rt, sel);
7628 break;
7629 }
7630 break;
7631 default:
7632 gen_mfc0(ctx, t0, rt, sel);
7633 }
7634 } else switch (sel) {
7635 /* GPR registers. */
7636 case 0:
7637 gen_helper_1e0i(mftgpr, t0, rt);
7638 break;
7639 /* Auxiliary CPU registers */
7640 case 1:
7641 switch (rt) {
7642 case 0:
7643 gen_helper_1e0i(mftlo, t0, 0);
7644 break;
7645 case 1:
7646 gen_helper_1e0i(mfthi, t0, 0);
7647 break;
7648 case 2:
7649 gen_helper_1e0i(mftacx, t0, 0);
7650 break;
7651 case 4:
7652 gen_helper_1e0i(mftlo, t0, 1);
7653 break;
7654 case 5:
7655 gen_helper_1e0i(mfthi, t0, 1);
7656 break;
7657 case 6:
7658 gen_helper_1e0i(mftacx, t0, 1);
7659 break;
7660 case 8:
7661 gen_helper_1e0i(mftlo, t0, 2);
7662 break;
7663 case 9:
7664 gen_helper_1e0i(mfthi, t0, 2);
7665 break;
7666 case 10:
7667 gen_helper_1e0i(mftacx, t0, 2);
7668 break;
7669 case 12:
7670 gen_helper_1e0i(mftlo, t0, 3);
7671 break;
7672 case 13:
7673 gen_helper_1e0i(mfthi, t0, 3);
7674 break;
7675 case 14:
7676 gen_helper_1e0i(mftacx, t0, 3);
7677 break;
7678 case 16:
7679 gen_helper_mftdsp(t0, cpu_env);
7680 break;
7681 default:
7682 goto die;
7683 }
7684 break;
7685 /* Floating point (COP1). */
7686 case 2:
7687 /* XXX: For now we support only a single FPU context. */
7688 if (h == 0) {
7689 TCGv_i32 fp0 = tcg_temp_new_i32();
7690
7691 gen_load_fpr32(ctx, fp0, rt);
7692 tcg_gen_ext_i32_tl(t0, fp0);
7693 tcg_temp_free_i32(fp0);
7694 } else {
7695 TCGv_i32 fp0 = tcg_temp_new_i32();
7696
7697 gen_load_fpr32h(ctx, fp0, rt);
7698 tcg_gen_ext_i32_tl(t0, fp0);
7699 tcg_temp_free_i32(fp0);
7700 }
7701 break;
7702 case 3:
7703 /* XXX: For now we support only a single FPU context. */
7704 gen_helper_1e0i(cfc1, t0, rt);
7705 break;
7706 /* COP2: Not implemented. */
7707 case 4:
7708 case 5:
7709 /* fall through */
7710 default:
7711 goto die;
7712 }
7713 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7714 gen_store_gpr(t0, rd);
7715 tcg_temp_free(t0);
7716 return;
7717
7718 die:
7719 tcg_temp_free(t0);
7720 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7721 generate_exception_end(ctx, EXCP_RI);
7722 }
7723
7724 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7725 int u, int sel, int h)
7726 {
7727 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7728 TCGv t0 = tcg_temp_local_new();
7729
7730 gen_load_gpr(t0, rt);
7731 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7732 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7733 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7734 /* NOP */ ;
7735 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7736 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7737 /* NOP */ ;
7738 else if (u == 0) {
7739 switch (rd) {
7740 case 1:
7741 switch (sel) {
7742 case 1:
7743 gen_helper_mttc0_vpecontrol(cpu_env, t0);
7744 break;
7745 case 2:
7746 gen_helper_mttc0_vpeconf0(cpu_env, t0);
7747 break;
7748 default:
7749 goto die;
7750 break;
7751 }
7752 break;
7753 case 2:
7754 switch (sel) {
7755 case 1:
7756 gen_helper_mttc0_tcstatus(cpu_env, t0);
7757 break;
7758 case 2:
7759 gen_helper_mttc0_tcbind(cpu_env, t0);
7760 break;
7761 case 3:
7762 gen_helper_mttc0_tcrestart(cpu_env, t0);
7763 break;
7764 case 4:
7765 gen_helper_mttc0_tchalt(cpu_env, t0);
7766 break;
7767 case 5:
7768 gen_helper_mttc0_tccontext(cpu_env, t0);
7769 break;
7770 case 6:
7771 gen_helper_mttc0_tcschedule(cpu_env, t0);
7772 break;
7773 case 7:
7774 gen_helper_mttc0_tcschefback(cpu_env, t0);
7775 break;
7776 default:
7777 gen_mtc0(ctx, t0, rd, sel);
7778 break;
7779 }
7780 break;
7781 case 10:
7782 switch (sel) {
7783 case 0:
7784 gen_helper_mttc0_entryhi(cpu_env, t0);
7785 break;
7786 default:
7787 gen_mtc0(ctx, t0, rd, sel);
7788 break;
7789 }
7790 case 12:
7791 switch (sel) {
7792 case 0:
7793 gen_helper_mttc0_status(cpu_env, t0);
7794 break;
7795 default:
7796 gen_mtc0(ctx, t0, rd, sel);
7797 break;
7798 }
7799 case 13:
7800 switch (sel) {
7801 case 0:
7802 gen_helper_mttc0_cause(cpu_env, t0);
7803 break;
7804 default:
7805 goto die;
7806 break;
7807 }
7808 break;
7809 case 15:
7810 switch (sel) {
7811 case 1:
7812 gen_helper_mttc0_ebase(cpu_env, t0);
7813 break;
7814 default:
7815 goto die;
7816 break;
7817 }
7818 break;
7819 case 23:
7820 switch (sel) {
7821 case 0:
7822 gen_helper_mttc0_debug(cpu_env, t0);
7823 break;
7824 default:
7825 gen_mtc0(ctx, t0, rd, sel);
7826 break;
7827 }
7828 break;
7829 default:
7830 gen_mtc0(ctx, t0, rd, sel);
7831 }
7832 } else switch (sel) {
7833 /* GPR registers. */
7834 case 0:
7835 gen_helper_0e1i(mttgpr, t0, rd);
7836 break;
7837 /* Auxiliary CPU registers */
7838 case 1:
7839 switch (rd) {
7840 case 0:
7841 gen_helper_0e1i(mttlo, t0, 0);
7842 break;
7843 case 1:
7844 gen_helper_0e1i(mtthi, t0, 0);
7845 break;
7846 case 2:
7847 gen_helper_0e1i(mttacx, t0, 0);
7848 break;
7849 case 4:
7850 gen_helper_0e1i(mttlo, t0, 1);
7851 break;
7852 case 5:
7853 gen_helper_0e1i(mtthi, t0, 1);
7854 break;
7855 case 6:
7856 gen_helper_0e1i(mttacx, t0, 1);
7857 break;
7858 case 8:
7859 gen_helper_0e1i(mttlo, t0, 2);
7860 break;
7861 case 9:
7862 gen_helper_0e1i(mtthi, t0, 2);
7863 break;
7864 case 10:
7865 gen_helper_0e1i(mttacx, t0, 2);
7866 break;
7867 case 12:
7868 gen_helper_0e1i(mttlo, t0, 3);
7869 break;
7870 case 13:
7871 gen_helper_0e1i(mtthi, t0, 3);
7872 break;
7873 case 14:
7874 gen_helper_0e1i(mttacx, t0, 3);
7875 break;
7876 case 16:
7877 gen_helper_mttdsp(cpu_env, t0);
7878 break;
7879 default:
7880 goto die;
7881 }
7882 break;
7883 /* Floating point (COP1). */
7884 case 2:
7885 /* XXX: For now we support only a single FPU context. */
7886 if (h == 0) {
7887 TCGv_i32 fp0 = tcg_temp_new_i32();
7888
7889 tcg_gen_trunc_tl_i32(fp0, t0);
7890 gen_store_fpr32(ctx, fp0, rd);
7891 tcg_temp_free_i32(fp0);
7892 } else {
7893 TCGv_i32 fp0 = tcg_temp_new_i32();
7894
7895 tcg_gen_trunc_tl_i32(fp0, t0);
7896 gen_store_fpr32h(ctx, fp0, rd);
7897 tcg_temp_free_i32(fp0);
7898 }
7899 break;
7900 case 3:
7901 /* XXX: For now we support only a single FPU context. */
7902 {
7903 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7904
7905 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7906 tcg_temp_free_i32(fs_tmp);
7907 }
7908 /* Stop translation as we may have changed hflags */
7909 ctx->bstate = BS_STOP;
7910 break;
7911 /* COP2: Not implemented. */
7912 case 4:
7913 case 5:
7914 /* fall through */
7915 default:
7916 goto die;
7917 }
7918 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7919 tcg_temp_free(t0);
7920 return;
7921
7922 die:
7923 tcg_temp_free(t0);
7924 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7925 generate_exception_end(ctx, EXCP_RI);
7926 }
7927
7928 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
7929 {
7930 const char *opn = "ldst";
7931
7932 check_cp0_enabled(ctx);
7933 switch (opc) {
7934 case OPC_MFC0:
7935 if (rt == 0) {
7936 /* Treat as NOP. */
7937 return;
7938 }
7939 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7940 opn = "mfc0";
7941 break;
7942 case OPC_MTC0:
7943 {
7944 TCGv t0 = tcg_temp_new();
7945
7946 gen_load_gpr(t0, rt);
7947 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
7948 tcg_temp_free(t0);
7949 }
7950 opn = "mtc0";
7951 break;
7952 #if defined(TARGET_MIPS64)
7953 case OPC_DMFC0:
7954 check_insn(ctx, ISA_MIPS3);
7955 if (rt == 0) {
7956 /* Treat as NOP. */
7957 return;
7958 }
7959 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7960 opn = "dmfc0";
7961 break;
7962 case OPC_DMTC0:
7963 check_insn(ctx, ISA_MIPS3);
7964 {
7965 TCGv t0 = tcg_temp_new();
7966
7967 gen_load_gpr(t0, rt);
7968 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
7969 tcg_temp_free(t0);
7970 }
7971 opn = "dmtc0";
7972 break;
7973 #endif
7974 case OPC_MFHC0:
7975 check_mvh(ctx);
7976 if (rt == 0) {
7977 /* Treat as NOP. */
7978 return;
7979 }
7980 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7981 opn = "mfhc0";
7982 break;
7983 case OPC_MTHC0:
7984 check_mvh(ctx);
7985 {
7986 TCGv t0 = tcg_temp_new();
7987 gen_load_gpr(t0, rt);
7988 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
7989 tcg_temp_free(t0);
7990 }
7991 opn = "mthc0";
7992 break;
7993 case OPC_MFTR:
7994 check_insn(ctx, ASE_MT);
7995 if (rd == 0) {
7996 /* Treat as NOP. */
7997 return;
7998 }
7999 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
8000 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8001 opn = "mftr";
8002 break;
8003 case OPC_MTTR:
8004 check_insn(ctx, ASE_MT);
8005 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
8006 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
8007 opn = "mttr";
8008 break;
8009 case OPC_TLBWI:
8010 opn = "tlbwi";
8011 if (!env->tlb->helper_tlbwi)
8012 goto die;
8013 gen_helper_tlbwi(cpu_env);
8014 break;
8015 case OPC_TLBINV:
8016 opn = "tlbinv";
8017 if (ctx->ie >= 2) {
8018 if (!env->tlb->helper_tlbinv) {
8019 goto die;
8020 }
8021 gen_helper_tlbinv(cpu_env);
8022 } /* treat as nop if TLBINV not supported */
8023 break;
8024 case OPC_TLBINVF:
8025 opn = "tlbinvf";
8026 if (ctx->ie >= 2) {
8027 if (!env->tlb->helper_tlbinvf) {
8028 goto die;
8029 }
8030 gen_helper_tlbinvf(cpu_env);
8031 } /* treat as nop if TLBINV not supported */
8032 break;
8033 case OPC_TLBWR:
8034 opn = "tlbwr";
8035 if (!env->tlb->helper_tlbwr)
8036 goto die;
8037 gen_helper_tlbwr(cpu_env);
8038 break;
8039 case OPC_TLBP:
8040 opn = "tlbp";
8041 if (!env->tlb->helper_tlbp)
8042 goto die;
8043 gen_helper_tlbp(cpu_env);
8044 break;
8045 case OPC_TLBR:
8046 opn = "tlbr";
8047 if (!env->tlb->helper_tlbr)
8048 goto die;
8049 gen_helper_tlbr(cpu_env);
8050 break;
8051 case OPC_ERET: /* OPC_ERETNC */
8052 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8053 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8054 goto die;
8055 } else {
8056 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
8057 if (ctx->opcode & (1 << bit_shift)) {
8058 /* OPC_ERETNC */
8059 opn = "eretnc";
8060 check_insn(ctx, ISA_MIPS32R5);
8061 gen_helper_eretnc(cpu_env);
8062 } else {
8063 /* OPC_ERET */
8064 opn = "eret";
8065 check_insn(ctx, ISA_MIPS2);
8066 gen_helper_eret(cpu_env);
8067 }
8068 ctx->bstate = BS_EXCP;
8069 }
8070 break;
8071 case OPC_DERET:
8072 opn = "deret";
8073 check_insn(ctx, ISA_MIPS32);
8074 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8075 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8076 goto die;
8077 }
8078 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8079 MIPS_INVAL(opn);
8080 generate_exception_end(ctx, EXCP_RI);
8081 } else {
8082 gen_helper_deret(cpu_env);
8083 ctx->bstate = BS_EXCP;
8084 }
8085 break;
8086 case OPC_WAIT:
8087 opn = "wait";
8088 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8089 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8090 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8091 goto die;
8092 }
8093 /* If we get an exception, we want to restart at next instruction */
8094 ctx->pc += 4;
8095 save_cpu_state(ctx, 1);
8096 ctx->pc -= 4;
8097 gen_helper_wait(cpu_env);
8098 ctx->bstate = BS_EXCP;
8099 break;
8100 default:
8101 die:
8102 MIPS_INVAL(opn);
8103 generate_exception_end(ctx, EXCP_RI);
8104 return;
8105 }
8106 (void)opn; /* avoid a compiler warning */
8107 }
8108 #endif /* !CONFIG_USER_ONLY */
8109
8110 /* CP1 Branches (before delay slot) */
8111 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8112 int32_t cc, int32_t offset)
8113 {
8114 target_ulong btarget;
8115 TCGv_i32 t0 = tcg_temp_new_i32();
8116
8117 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8118 generate_exception_end(ctx, EXCP_RI);
8119 goto out;
8120 }
8121
8122 if (cc != 0)
8123 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8124
8125 btarget = ctx->pc + 4 + offset;
8126
8127 switch (op) {
8128 case OPC_BC1F:
8129 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8130 tcg_gen_not_i32(t0, t0);
8131 tcg_gen_andi_i32(t0, t0, 1);
8132 tcg_gen_extu_i32_tl(bcond, t0);
8133 goto not_likely;
8134 case OPC_BC1FL:
8135 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8136 tcg_gen_not_i32(t0, t0);
8137 tcg_gen_andi_i32(t0, t0, 1);
8138 tcg_gen_extu_i32_tl(bcond, t0);
8139 goto likely;
8140 case OPC_BC1T:
8141 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8142 tcg_gen_andi_i32(t0, t0, 1);
8143 tcg_gen_extu_i32_tl(bcond, t0);
8144 goto not_likely;
8145 case OPC_BC1TL:
8146 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8147 tcg_gen_andi_i32(t0, t0, 1);
8148 tcg_gen_extu_i32_tl(bcond, t0);
8149 likely:
8150 ctx->hflags |= MIPS_HFLAG_BL;
8151 break;
8152 case OPC_BC1FANY2:
8153 {
8154 TCGv_i32 t1 = tcg_temp_new_i32();
8155 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8156 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8157 tcg_gen_nand_i32(t0, t0, t1);
8158 tcg_temp_free_i32(t1);
8159 tcg_gen_andi_i32(t0, t0, 1);
8160 tcg_gen_extu_i32_tl(bcond, t0);
8161 }
8162 goto not_likely;
8163 case OPC_BC1TANY2:
8164 {
8165 TCGv_i32 t1 = tcg_temp_new_i32();
8166 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8167 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8168 tcg_gen_or_i32(t0, t0, t1);
8169 tcg_temp_free_i32(t1);
8170 tcg_gen_andi_i32(t0, t0, 1);
8171 tcg_gen_extu_i32_tl(bcond, t0);
8172 }
8173 goto not_likely;
8174 case OPC_BC1FANY4:
8175 {
8176 TCGv_i32 t1 = tcg_temp_new_i32();
8177 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8178 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8179 tcg_gen_and_i32(t0, t0, t1);
8180 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8181 tcg_gen_and_i32(t0, t0, t1);
8182 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8183 tcg_gen_nand_i32(t0, t0, t1);
8184 tcg_temp_free_i32(t1);
8185 tcg_gen_andi_i32(t0, t0, 1);
8186 tcg_gen_extu_i32_tl(bcond, t0);
8187 }
8188 goto not_likely;
8189 case OPC_BC1TANY4:
8190 {
8191 TCGv_i32 t1 = tcg_temp_new_i32();
8192 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8193 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8194 tcg_gen_or_i32(t0, t0, t1);
8195 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8196 tcg_gen_or_i32(t0, t0, t1);
8197 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8198 tcg_gen_or_i32(t0, t0, t1);
8199 tcg_temp_free_i32(t1);
8200 tcg_gen_andi_i32(t0, t0, 1);
8201 tcg_gen_extu_i32_tl(bcond, t0);
8202 }
8203 not_likely:
8204 ctx->hflags |= MIPS_HFLAG_BC;
8205 break;
8206 default:
8207 MIPS_INVAL("cp1 cond branch");
8208 generate_exception_end(ctx, EXCP_RI);
8209 goto out;
8210 }
8211 ctx->btarget = btarget;
8212 ctx->hflags |= MIPS_HFLAG_BDS32;
8213 out:
8214 tcg_temp_free_i32(t0);
8215 }
8216
8217 /* R6 CP1 Branches */
8218 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8219 int32_t ft, int32_t offset,
8220 int delayslot_size)
8221 {
8222 target_ulong btarget;
8223 TCGv_i64 t0 = tcg_temp_new_i64();
8224
8225 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8226 #ifdef MIPS_DEBUG_DISAS
8227 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8228 "\n", ctx->pc);
8229 #endif
8230 generate_exception_end(ctx, EXCP_RI);
8231 goto out;
8232 }
8233
8234 gen_load_fpr64(ctx, t0, ft);
8235 tcg_gen_andi_i64(t0, t0, 1);
8236
8237 btarget = addr_add(ctx, ctx->pc + 4, offset);
8238
8239 switch (op) {
8240 case OPC_BC1EQZ:
8241 tcg_gen_xori_i64(t0, t0, 1);
8242 ctx->hflags |= MIPS_HFLAG_BC;
8243 break;
8244 case OPC_BC1NEZ:
8245 /* t0 already set */
8246 ctx->hflags |= MIPS_HFLAG_BC;
8247 break;
8248 default:
8249 MIPS_INVAL("cp1 cond branch");
8250 generate_exception_end(ctx, EXCP_RI);
8251 goto out;
8252 }
8253
8254 tcg_gen_trunc_i64_tl(bcond, t0);
8255
8256 ctx->btarget = btarget;
8257
8258 switch (delayslot_size) {
8259 case 2:
8260 ctx->hflags |= MIPS_HFLAG_BDS16;
8261 break;
8262 case 4:
8263 ctx->hflags |= MIPS_HFLAG_BDS32;
8264 break;
8265 }
8266
8267 out:
8268 tcg_temp_free_i64(t0);
8269 }
8270
8271 /* Coprocessor 1 (FPU) */
8272
8273 #define FOP(func, fmt) (((fmt) << 21) | (func))
8274
8275 enum fopcode {
8276 OPC_ADD_S = FOP(0, FMT_S),
8277 OPC_SUB_S = FOP(1, FMT_S),
8278 OPC_MUL_S = FOP(2, FMT_S),
8279 OPC_DIV_S = FOP(3, FMT_S),
8280 OPC_SQRT_S = FOP(4, FMT_S),
8281 OPC_ABS_S = FOP(5, FMT_S),
8282 OPC_MOV_S = FOP(6, FMT_S),
8283 OPC_NEG_S = FOP(7, FMT_S),
8284 OPC_ROUND_L_S = FOP(8, FMT_S),
8285 OPC_TRUNC_L_S = FOP(9, FMT_S),
8286 OPC_CEIL_L_S = FOP(10, FMT_S),
8287 OPC_FLOOR_L_S = FOP(11, FMT_S),
8288 OPC_ROUND_W_S = FOP(12, FMT_S),
8289 OPC_TRUNC_W_S = FOP(13, FMT_S),
8290 OPC_CEIL_W_S = FOP(14, FMT_S),
8291 OPC_FLOOR_W_S = FOP(15, FMT_S),
8292 OPC_SEL_S = FOP(16, FMT_S),
8293 OPC_MOVCF_S = FOP(17, FMT_S),
8294 OPC_MOVZ_S = FOP(18, FMT_S),
8295 OPC_MOVN_S = FOP(19, FMT_S),
8296 OPC_SELEQZ_S = FOP(20, FMT_S),
8297 OPC_RECIP_S = FOP(21, FMT_S),
8298 OPC_RSQRT_S = FOP(22, FMT_S),
8299 OPC_SELNEZ_S = FOP(23, FMT_S),
8300 OPC_MADDF_S = FOP(24, FMT_S),
8301 OPC_MSUBF_S = FOP(25, FMT_S),
8302 OPC_RINT_S = FOP(26, FMT_S),
8303 OPC_CLASS_S = FOP(27, FMT_S),
8304 OPC_MIN_S = FOP(28, FMT_S),
8305 OPC_RECIP2_S = FOP(28, FMT_S),
8306 OPC_MINA_S = FOP(29, FMT_S),
8307 OPC_RECIP1_S = FOP(29, FMT_S),
8308 OPC_MAX_S = FOP(30, FMT_S),
8309 OPC_RSQRT1_S = FOP(30, FMT_S),
8310 OPC_MAXA_S = FOP(31, FMT_S),
8311 OPC_RSQRT2_S = FOP(31, FMT_S),
8312 OPC_CVT_D_S = FOP(33, FMT_S),
8313 OPC_CVT_W_S = FOP(36, FMT_S),
8314 OPC_CVT_L_S = FOP(37, FMT_S),
8315 OPC_CVT_PS_S = FOP(38, FMT_S),
8316 OPC_CMP_F_S = FOP (48, FMT_S),
8317 OPC_CMP_UN_S = FOP (49, FMT_S),
8318 OPC_CMP_EQ_S = FOP (50, FMT_S),
8319 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8320 OPC_CMP_OLT_S = FOP (52, FMT_S),
8321 OPC_CMP_ULT_S = FOP (53, FMT_S),
8322 OPC_CMP_OLE_S = FOP (54, FMT_S),
8323 OPC_CMP_ULE_S = FOP (55, FMT_S),
8324 OPC_CMP_SF_S = FOP (56, FMT_S),
8325 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8326 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8327 OPC_CMP_NGL_S = FOP (59, FMT_S),
8328 OPC_CMP_LT_S = FOP (60, FMT_S),
8329 OPC_CMP_NGE_S = FOP (61, FMT_S),
8330 OPC_CMP_LE_S = FOP (62, FMT_S),
8331 OPC_CMP_NGT_S = FOP (63, FMT_S),
8332
8333 OPC_ADD_D = FOP(0, FMT_D),
8334 OPC_SUB_D = FOP(1, FMT_D),
8335 OPC_MUL_D = FOP(2, FMT_D),
8336 OPC_DIV_D = FOP(3, FMT_D),
8337 OPC_SQRT_D = FOP(4, FMT_D),
8338 OPC_ABS_D = FOP(5, FMT_D),
8339 OPC_MOV_D = FOP(6, FMT_D),
8340 OPC_NEG_D = FOP(7, FMT_D),
8341 OPC_ROUND_L_D = FOP(8, FMT_D),
8342 OPC_TRUNC_L_D = FOP(9, FMT_D),
8343 OPC_CEIL_L_D = FOP(10, FMT_D),
8344 OPC_FLOOR_L_D = FOP(11, FMT_D),
8345 OPC_ROUND_W_D = FOP(12, FMT_D),
8346 OPC_TRUNC_W_D = FOP(13, FMT_D),
8347 OPC_CEIL_W_D = FOP(14, FMT_D),
8348 OPC_FLOOR_W_D = FOP(15, FMT_D),
8349 OPC_SEL_D = FOP(16, FMT_D),
8350 OPC_MOVCF_D = FOP(17, FMT_D),
8351 OPC_MOVZ_D = FOP(18, FMT_D),
8352 OPC_MOVN_D = FOP(19, FMT_D),
8353 OPC_SELEQZ_D = FOP(20, FMT_D),
8354 OPC_RECIP_D = FOP(21, FMT_D),
8355 OPC_RSQRT_D = FOP(22, FMT_D),
8356 OPC_SELNEZ_D = FOP(23, FMT_D),
8357 OPC_MADDF_D = FOP(24, FMT_D),
8358 OPC_MSUBF_D = FOP(25, FMT_D),
8359 OPC_RINT_D = FOP(26, FMT_D),
8360 OPC_CLASS_D = FOP(27, FMT_D),
8361 OPC_MIN_D = FOP(28, FMT_D),
8362 OPC_RECIP2_D = FOP(28, FMT_D),
8363 OPC_MINA_D = FOP(29, FMT_D),
8364 OPC_RECIP1_D = FOP(29, FMT_D),
8365 OPC_MAX_D = FOP(30, FMT_D),
8366 OPC_RSQRT1_D = FOP(30, FMT_D),
8367 OPC_MAXA_D = FOP(31, FMT_D),
8368 OPC_RSQRT2_D = FOP(31, FMT_D),
8369 OPC_CVT_S_D = FOP(32, FMT_D),
8370 OPC_CVT_W_D = FOP(36, FMT_D),
8371 OPC_CVT_L_D = FOP(37, FMT_D),
8372 OPC_CMP_F_D = FOP (48, FMT_D),
8373 OPC_CMP_UN_D = FOP (49, FMT_D),
8374 OPC_CMP_EQ_D = FOP (50, FMT_D),
8375 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8376 OPC_CMP_OLT_D = FOP (52, FMT_D),
8377 OPC_CMP_ULT_D = FOP (53, FMT_D),
8378 OPC_CMP_OLE_D = FOP (54, FMT_D),
8379 OPC_CMP_ULE_D = FOP (55, FMT_D),
8380 OPC_CMP_SF_D = FOP (56, FMT_D),
8381 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8382 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8383 OPC_CMP_NGL_D = FOP (59, FMT_D),
8384 OPC_CMP_LT_D = FOP (60, FMT_D),
8385 OPC_CMP_NGE_D = FOP (61, FMT_D),
8386 OPC_CMP_LE_D = FOP (62, FMT_D),
8387 OPC_CMP_NGT_D = FOP (63, FMT_D),
8388
8389 OPC_CVT_S_W = FOP(32, FMT_W),
8390 OPC_CVT_D_W = FOP(33, FMT_W),
8391 OPC_CVT_S_L = FOP(32, FMT_L),
8392 OPC_CVT_D_L = FOP(33, FMT_L),
8393 OPC_CVT_PS_PW = FOP(38, FMT_W),
8394
8395 OPC_ADD_PS = FOP(0, FMT_PS),
8396 OPC_SUB_PS = FOP(1, FMT_PS),
8397 OPC_MUL_PS = FOP(2, FMT_PS),
8398 OPC_DIV_PS = FOP(3, FMT_PS),
8399 OPC_ABS_PS = FOP(5, FMT_PS),
8400 OPC_MOV_PS = FOP(6, FMT_PS),
8401 OPC_NEG_PS = FOP(7, FMT_PS),
8402 OPC_MOVCF_PS = FOP(17, FMT_PS),
8403 OPC_MOVZ_PS = FOP(18, FMT_PS),
8404 OPC_MOVN_PS = FOP(19, FMT_PS),
8405 OPC_ADDR_PS = FOP(24, FMT_PS),
8406 OPC_MULR_PS = FOP(26, FMT_PS),
8407 OPC_RECIP2_PS = FOP(28, FMT_PS),
8408 OPC_RECIP1_PS = FOP(29, FMT_PS),
8409 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8410 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8411
8412 OPC_CVT_S_PU = FOP(32, FMT_PS),
8413 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8414 OPC_CVT_S_PL = FOP(40, FMT_PS),
8415 OPC_PLL_PS = FOP(44, FMT_PS),
8416 OPC_PLU_PS = FOP(45, FMT_PS),
8417 OPC_PUL_PS = FOP(46, FMT_PS),
8418 OPC_PUU_PS = FOP(47, FMT_PS),
8419 OPC_CMP_F_PS = FOP (48, FMT_PS),
8420 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8421 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8422 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8423 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8424 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8425 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8426 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8427 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8428 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8429 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8430 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8431 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8432 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8433 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8434 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8435 };
8436
8437 enum r6_f_cmp_op {
8438 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8439 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8440 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8441 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8442 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8443 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8444 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8445 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8446 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8447 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8448 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8449 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8450 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8451 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8452 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8453 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8454 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8455 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8456 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8457 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8458 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8459 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8460
8461 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8462 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8463 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8464 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8465 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8466 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8467 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8468 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8469 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8470 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8471 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8472 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8473 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8474 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8475 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8476 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8477 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8478 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8479 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8480 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8481 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8482 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8483 };
8484 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8485 {
8486 TCGv t0 = tcg_temp_new();
8487
8488 switch (opc) {
8489 case OPC_MFC1:
8490 {
8491 TCGv_i32 fp0 = tcg_temp_new_i32();
8492
8493 gen_load_fpr32(ctx, fp0, fs);
8494 tcg_gen_ext_i32_tl(t0, fp0);
8495 tcg_temp_free_i32(fp0);
8496 }
8497 gen_store_gpr(t0, rt);
8498 break;
8499 case OPC_MTC1:
8500 gen_load_gpr(t0, rt);
8501 {
8502 TCGv_i32 fp0 = tcg_temp_new_i32();
8503
8504 tcg_gen_trunc_tl_i32(fp0, t0);
8505 gen_store_fpr32(ctx, fp0, fs);
8506 tcg_temp_free_i32(fp0);
8507 }
8508 break;
8509 case OPC_CFC1:
8510 gen_helper_1e0i(cfc1, t0, fs);
8511 gen_store_gpr(t0, rt);
8512 break;
8513 case OPC_CTC1:
8514 gen_load_gpr(t0, rt);
8515 save_cpu_state(ctx, 0);
8516 {
8517 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8518
8519 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8520 tcg_temp_free_i32(fs_tmp);
8521 }
8522 /* Stop translation as we may have changed hflags */
8523 ctx->bstate = BS_STOP;
8524 break;
8525 #if defined(TARGET_MIPS64)
8526 case OPC_DMFC1:
8527 gen_load_fpr64(ctx, t0, fs);
8528 gen_store_gpr(t0, rt);
8529 break;
8530 case OPC_DMTC1:
8531 gen_load_gpr(t0, rt);
8532 gen_store_fpr64(ctx, t0, fs);
8533 break;
8534 #endif
8535 case OPC_MFHC1:
8536 {
8537 TCGv_i32 fp0 = tcg_temp_new_i32();
8538
8539 gen_load_fpr32h(ctx, fp0, fs);
8540 tcg_gen_ext_i32_tl(t0, fp0);
8541 tcg_temp_free_i32(fp0);
8542 }
8543 gen_store_gpr(t0, rt);
8544 break;
8545 case OPC_MTHC1:
8546 gen_load_gpr(t0, rt);
8547 {
8548 TCGv_i32 fp0 = tcg_temp_new_i32();
8549
8550 tcg_gen_trunc_tl_i32(fp0, t0);
8551 gen_store_fpr32h(ctx, fp0, fs);
8552 tcg_temp_free_i32(fp0);
8553 }
8554 break;
8555 default:
8556 MIPS_INVAL("cp1 move");
8557 generate_exception_end(ctx, EXCP_RI);
8558 goto out;
8559 }
8560
8561 out:
8562 tcg_temp_free(t0);
8563 }
8564
8565 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8566 {
8567 TCGLabel *l1;
8568 TCGCond cond;
8569 TCGv_i32 t0;
8570
8571 if (rd == 0) {
8572 /* Treat as NOP. */
8573 return;
8574 }
8575
8576 if (tf)
8577 cond = TCG_COND_EQ;
8578 else
8579 cond = TCG_COND_NE;
8580
8581 l1 = gen_new_label();
8582 t0 = tcg_temp_new_i32();
8583 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8584 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8585 tcg_temp_free_i32(t0);
8586 if (rs == 0) {
8587 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8588 } else {
8589 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8590 }
8591 gen_set_label(l1);
8592 }
8593
8594 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8595 int tf)
8596 {
8597 int cond;
8598 TCGv_i32 t0 = tcg_temp_new_i32();
8599 TCGLabel *l1 = gen_new_label();
8600
8601 if (tf)
8602 cond = TCG_COND_EQ;
8603 else
8604 cond = TCG_COND_NE;
8605
8606 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8607 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8608 gen_load_fpr32(ctx, t0, fs);
8609 gen_store_fpr32(ctx, t0, fd);
8610 gen_set_label(l1);
8611 tcg_temp_free_i32(t0);
8612 }
8613
8614 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8615 {
8616 int cond;
8617 TCGv_i32 t0 = tcg_temp_new_i32();
8618 TCGv_i64 fp0;
8619 TCGLabel *l1 = gen_new_label();
8620
8621 if (tf)
8622 cond = TCG_COND_EQ;
8623 else
8624 cond = TCG_COND_NE;
8625
8626 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8627 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8628 tcg_temp_free_i32(t0);
8629 fp0 = tcg_temp_new_i64();
8630 gen_load_fpr64(ctx, fp0, fs);
8631 gen_store_fpr64(ctx, fp0, fd);
8632 tcg_temp_free_i64(fp0);
8633 gen_set_label(l1);
8634 }
8635
8636 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8637 int cc, int tf)
8638 {
8639 int cond;
8640 TCGv_i32 t0 = tcg_temp_new_i32();
8641 TCGLabel *l1 = gen_new_label();
8642 TCGLabel *l2 = gen_new_label();
8643
8644 if (tf)
8645 cond = TCG_COND_EQ;
8646 else
8647 cond = TCG_COND_NE;
8648
8649 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8650 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8651 gen_load_fpr32(ctx, t0, fs);
8652 gen_store_fpr32(ctx, t0, fd);
8653 gen_set_label(l1);
8654
8655 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8656 tcg_gen_brcondi_i32(cond, t0, 0, l2);
8657 gen_load_fpr32h(ctx, t0, fs);
8658 gen_store_fpr32h(ctx, t0, fd);
8659 tcg_temp_free_i32(t0);
8660 gen_set_label(l2);
8661 }
8662
8663 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8664 int fs)
8665 {
8666 TCGv_i32 t1 = tcg_const_i32(0);
8667 TCGv_i32 fp0 = tcg_temp_new_i32();
8668 TCGv_i32 fp1 = tcg_temp_new_i32();
8669 TCGv_i32 fp2 = tcg_temp_new_i32();
8670 gen_load_fpr32(ctx, fp0, fd);
8671 gen_load_fpr32(ctx, fp1, ft);
8672 gen_load_fpr32(ctx, fp2, fs);
8673
8674 switch (op1) {
8675 case OPC_SEL_S:
8676 tcg_gen_andi_i32(fp0, fp0, 1);
8677 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8678 break;
8679 case OPC_SELEQZ_S:
8680 tcg_gen_andi_i32(fp1, fp1, 1);
8681 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8682 break;
8683 case OPC_SELNEZ_S:
8684 tcg_gen_andi_i32(fp1, fp1, 1);
8685 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8686 break;
8687 default:
8688 MIPS_INVAL("gen_sel_s");
8689 generate_exception_end(ctx, EXCP_RI);
8690 break;
8691 }
8692
8693 gen_store_fpr32(ctx, fp0, fd);
8694 tcg_temp_free_i32(fp2);
8695 tcg_temp_free_i32(fp1);
8696 tcg_temp_free_i32(fp0);
8697 tcg_temp_free_i32(t1);
8698 }
8699
8700 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8701 int fs)
8702 {
8703 TCGv_i64 t1 = tcg_const_i64(0);
8704 TCGv_i64 fp0 = tcg_temp_new_i64();
8705 TCGv_i64 fp1 = tcg_temp_new_i64();
8706 TCGv_i64 fp2 = tcg_temp_new_i64();
8707 gen_load_fpr64(ctx, fp0, fd);
8708 gen_load_fpr64(ctx, fp1, ft);
8709 gen_load_fpr64(ctx, fp2, fs);
8710
8711 switch (op1) {
8712 case OPC_SEL_D:
8713 tcg_gen_andi_i64(fp0, fp0, 1);
8714 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8715 break;
8716 case OPC_SELEQZ_D:
8717 tcg_gen_andi_i64(fp1, fp1, 1);
8718 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8719 break;
8720 case OPC_SELNEZ_D:
8721 tcg_gen_andi_i64(fp1, fp1, 1);
8722 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8723 break;
8724 default:
8725 MIPS_INVAL("gen_sel_d");
8726 generate_exception_end(ctx, EXCP_RI);
8727 break;
8728 }
8729
8730 gen_store_fpr64(ctx, fp0, fd);
8731 tcg_temp_free_i64(fp2);
8732 tcg_temp_free_i64(fp1);
8733 tcg_temp_free_i64(fp0);
8734 tcg_temp_free_i64(t1);
8735 }
8736
8737 static void gen_farith (DisasContext *ctx, enum fopcode op1,
8738 int ft, int fs, int fd, int cc)
8739 {
8740 uint32_t func = ctx->opcode & 0x3f;
8741 switch (op1) {
8742 case OPC_ADD_S:
8743 {
8744 TCGv_i32 fp0 = tcg_temp_new_i32();
8745 TCGv_i32 fp1 = tcg_temp_new_i32();
8746
8747 gen_load_fpr32(ctx, fp0, fs);
8748 gen_load_fpr32(ctx, fp1, ft);
8749 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8750 tcg_temp_free_i32(fp1);
8751 gen_store_fpr32(ctx, fp0, fd);
8752 tcg_temp_free_i32(fp0);
8753 }
8754 break;
8755 case OPC_SUB_S:
8756 {
8757 TCGv_i32 fp0 = tcg_temp_new_i32();
8758 TCGv_i32 fp1 = tcg_temp_new_i32();
8759
8760 gen_load_fpr32(ctx, fp0, fs);
8761 gen_load_fpr32(ctx, fp1, ft);
8762 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8763 tcg_temp_free_i32(fp1);
8764 gen_store_fpr32(ctx, fp0, fd);
8765 tcg_temp_free_i32(fp0);
8766 }
8767 break;
8768 case OPC_MUL_S:
8769 {
8770 TCGv_i32 fp0 = tcg_temp_new_i32();
8771 TCGv_i32 fp1 = tcg_temp_new_i32();
8772
8773 gen_load_fpr32(ctx, fp0, fs);
8774 gen_load_fpr32(ctx, fp1, ft);
8775 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8776 tcg_temp_free_i32(fp1);
8777 gen_store_fpr32(ctx, fp0, fd);
8778 tcg_temp_free_i32(fp0);
8779 }
8780 break;
8781 case OPC_DIV_S:
8782 {
8783 TCGv_i32 fp0 = tcg_temp_new_i32();
8784 TCGv_i32 fp1 = tcg_temp_new_i32();
8785
8786 gen_load_fpr32(ctx, fp0, fs);
8787 gen_load_fpr32(ctx, fp1, ft);
8788 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8789 tcg_temp_free_i32(fp1);
8790 gen_store_fpr32(ctx, fp0, fd);
8791 tcg_temp_free_i32(fp0);
8792 }
8793 break;
8794 case OPC_SQRT_S:
8795 {
8796 TCGv_i32 fp0 = tcg_temp_new_i32();
8797
8798 gen_load_fpr32(ctx, fp0, fs);
8799 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8800 gen_store_fpr32(ctx, fp0, fd);
8801 tcg_temp_free_i32(fp0);
8802 }
8803 break;
8804 case OPC_ABS_S:
8805 {
8806 TCGv_i32 fp0 = tcg_temp_new_i32();
8807
8808 gen_load_fpr32(ctx, fp0, fs);
8809 gen_helper_float_abs_s(fp0, fp0);
8810 gen_store_fpr32(ctx, fp0, fd);
8811 tcg_temp_free_i32(fp0);
8812 }
8813 break;
8814 case OPC_MOV_S:
8815 {
8816 TCGv_i32 fp0 = tcg_temp_new_i32();
8817
8818 gen_load_fpr32(ctx, fp0, fs);
8819 gen_store_fpr32(ctx, fp0, fd);
8820 tcg_temp_free_i32(fp0);
8821 }
8822 break;
8823 case OPC_NEG_S:
8824 {
8825 TCGv_i32 fp0 = tcg_temp_new_i32();
8826
8827 gen_load_fpr32(ctx, fp0, fs);
8828 gen_helper_float_chs_s(fp0, fp0);
8829 gen_store_fpr32(ctx, fp0, fd);
8830 tcg_temp_free_i32(fp0);
8831 }
8832 break;
8833 case OPC_ROUND_L_S:
8834 check_cp1_64bitmode(ctx);
8835 {
8836 TCGv_i32 fp32 = tcg_temp_new_i32();
8837 TCGv_i64 fp64 = tcg_temp_new_i64();
8838
8839 gen_load_fpr32(ctx, fp32, fs);
8840 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
8841 tcg_temp_free_i32(fp32);
8842 gen_store_fpr64(ctx, fp64, fd);
8843 tcg_temp_free_i64(fp64);
8844 }
8845 break;
8846 case OPC_TRUNC_L_S:
8847 check_cp1_64bitmode(ctx);
8848 {
8849 TCGv_i32 fp32 = tcg_temp_new_i32();
8850 TCGv_i64 fp64 = tcg_temp_new_i64();
8851
8852 gen_load_fpr32(ctx, fp32, fs);
8853 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
8854 tcg_temp_free_i32(fp32);
8855 gen_store_fpr64(ctx, fp64, fd);
8856 tcg_temp_free_i64(fp64);
8857 }
8858 break;
8859 case OPC_CEIL_L_S:
8860 check_cp1_64bitmode(ctx);
8861 {
8862 TCGv_i32 fp32 = tcg_temp_new_i32();
8863 TCGv_i64 fp64 = tcg_temp_new_i64();
8864
8865 gen_load_fpr32(ctx, fp32, fs);
8866 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
8867 tcg_temp_free_i32(fp32);
8868 gen_store_fpr64(ctx, fp64, fd);
8869 tcg_temp_free_i64(fp64);
8870 }
8871 break;
8872 case OPC_FLOOR_L_S:
8873 check_cp1_64bitmode(ctx);
8874 {
8875 TCGv_i32 fp32 = tcg_temp_new_i32();
8876 TCGv_i64 fp64 = tcg_temp_new_i64();
8877
8878 gen_load_fpr32(ctx, fp32, fs);
8879 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
8880 tcg_temp_free_i32(fp32);
8881 gen_store_fpr64(ctx, fp64, fd);
8882 tcg_temp_free_i64(fp64);
8883 }
8884 break;
8885 case OPC_ROUND_W_S:
8886 {
8887 TCGv_i32 fp0 = tcg_temp_new_i32();
8888
8889 gen_load_fpr32(ctx, fp0, fs);
8890 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
8891 gen_store_fpr32(ctx, fp0, fd);
8892 tcg_temp_free_i32(fp0);
8893 }
8894 break;
8895 case OPC_TRUNC_W_S:
8896 {
8897 TCGv_i32 fp0 = tcg_temp_new_i32();
8898
8899 gen_load_fpr32(ctx, fp0, fs);
8900 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
8901 gen_store_fpr32(ctx, fp0, fd);
8902 tcg_temp_free_i32(fp0);
8903 }
8904 break;
8905 case OPC_CEIL_W_S:
8906 {
8907 TCGv_i32 fp0 = tcg_temp_new_i32();
8908
8909 gen_load_fpr32(ctx, fp0, fs);
8910 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
8911 gen_store_fpr32(ctx, fp0, fd);
8912 tcg_temp_free_i32(fp0);
8913 }
8914 break;
8915 case OPC_FLOOR_W_S:
8916 {
8917 TCGv_i32 fp0 = tcg_temp_new_i32();
8918
8919 gen_load_fpr32(ctx, fp0, fs);
8920 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
8921 gen_store_fpr32(ctx, fp0, fd);
8922 tcg_temp_free_i32(fp0);
8923 }
8924 break;
8925 case OPC_SEL_S:
8926 check_insn(ctx, ISA_MIPS32R6);
8927 gen_sel_s(ctx, op1, fd, ft, fs);
8928 break;
8929 case OPC_SELEQZ_S:
8930 check_insn(ctx, ISA_MIPS32R6);
8931 gen_sel_s(ctx, op1, fd, ft, fs);
8932 break;
8933 case OPC_SELNEZ_S:
8934 check_insn(ctx, ISA_MIPS32R6);
8935 gen_sel_s(ctx, op1, fd, ft, fs);
8936 break;
8937 case OPC_MOVCF_S:
8938 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8939 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8940 break;
8941 case OPC_MOVZ_S:
8942 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8943 {
8944 TCGLabel *l1 = gen_new_label();
8945 TCGv_i32 fp0;
8946
8947 if (ft != 0) {
8948 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8949 }
8950 fp0 = tcg_temp_new_i32();
8951 gen_load_fpr32(ctx, fp0, fs);
8952 gen_store_fpr32(ctx, fp0, fd);
8953 tcg_temp_free_i32(fp0);
8954 gen_set_label(l1);
8955 }
8956 break;
8957 case OPC_MOVN_S:
8958 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8959 {
8960 TCGLabel *l1 = gen_new_label();
8961 TCGv_i32 fp0;
8962
8963 if (ft != 0) {
8964 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8965 fp0 = tcg_temp_new_i32();
8966 gen_load_fpr32(ctx, fp0, fs);
8967 gen_store_fpr32(ctx, fp0, fd);
8968 tcg_temp_free_i32(fp0);
8969 gen_set_label(l1);
8970 }
8971 }
8972 break;
8973 case OPC_RECIP_S:
8974 {
8975 TCGv_i32 fp0 = tcg_temp_new_i32();
8976
8977 gen_load_fpr32(ctx, fp0, fs);
8978 gen_helper_float_recip_s(fp0, cpu_env, fp0);
8979 gen_store_fpr32(ctx, fp0, fd);
8980 tcg_temp_free_i32(fp0);
8981 }
8982 break;
8983 case OPC_RSQRT_S:
8984 {
8985 TCGv_i32 fp0 = tcg_temp_new_i32();
8986
8987 gen_load_fpr32(ctx, fp0, fs);
8988 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
8989 gen_store_fpr32(ctx, fp0, fd);
8990 tcg_temp_free_i32(fp0);
8991 }
8992 break;
8993 case OPC_MADDF_S:
8994 check_insn(ctx, ISA_MIPS32R6);
8995 {
8996 TCGv_i32 fp0 = tcg_temp_new_i32();
8997 TCGv_i32 fp1 = tcg_temp_new_i32();
8998 TCGv_i32 fp2 = tcg_temp_new_i32();
8999 gen_load_fpr32(ctx, fp0, fs);
9000 gen_load_fpr32(ctx, fp1, ft);
9001 gen_load_fpr32(ctx, fp2, fd);
9002 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
9003 gen_store_fpr32(ctx, fp2, fd);
9004 tcg_temp_free_i32(fp2);
9005 tcg_temp_free_i32(fp1);
9006 tcg_temp_free_i32(fp0);
9007 }
9008 break;
9009 case OPC_MSUBF_S:
9010 check_insn(ctx, ISA_MIPS32R6);
9011 {
9012 TCGv_i32 fp0 = tcg_temp_new_i32();
9013 TCGv_i32 fp1 = tcg_temp_new_i32();
9014 TCGv_i32 fp2 = tcg_temp_new_i32();
9015 gen_load_fpr32(ctx, fp0, fs);
9016 gen_load_fpr32(ctx, fp1, ft);
9017 gen_load_fpr32(ctx, fp2, fd);
9018 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
9019 gen_store_fpr32(ctx, fp2, fd);
9020 tcg_temp_free_i32(fp2);
9021 tcg_temp_free_i32(fp1);
9022 tcg_temp_free_i32(fp0);
9023 }
9024 break;
9025 case OPC_RINT_S:
9026 check_insn(ctx, ISA_MIPS32R6);
9027 {
9028 TCGv_i32 fp0 = tcg_temp_new_i32();
9029 gen_load_fpr32(ctx, fp0, fs);
9030 gen_helper_float_rint_s(fp0, cpu_env, fp0);
9031 gen_store_fpr32(ctx, fp0, fd);
9032 tcg_temp_free_i32(fp0);
9033 }
9034 break;
9035 case OPC_CLASS_S:
9036 check_insn(ctx, ISA_MIPS32R6);
9037 {
9038 TCGv_i32 fp0 = tcg_temp_new_i32();
9039 gen_load_fpr32(ctx, fp0, fs);
9040 gen_helper_float_class_s(fp0, fp0);
9041 gen_store_fpr32(ctx, fp0, fd);
9042 tcg_temp_free_i32(fp0);
9043 }
9044 break;
9045 case OPC_MIN_S: /* OPC_RECIP2_S */
9046 if (ctx->insn_flags & ISA_MIPS32R6) {
9047 /* OPC_MIN_S */
9048 TCGv_i32 fp0 = tcg_temp_new_i32();
9049 TCGv_i32 fp1 = tcg_temp_new_i32();
9050 TCGv_i32 fp2 = tcg_temp_new_i32();
9051 gen_load_fpr32(ctx, fp0, fs);
9052 gen_load_fpr32(ctx, fp1, ft);
9053 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
9054 gen_store_fpr32(ctx, fp2, fd);
9055 tcg_temp_free_i32(fp2);
9056 tcg_temp_free_i32(fp1);
9057 tcg_temp_free_i32(fp0);
9058 } else {
9059 /* OPC_RECIP2_S */
9060 check_cp1_64bitmode(ctx);
9061 {
9062 TCGv_i32 fp0 = tcg_temp_new_i32();
9063 TCGv_i32 fp1 = tcg_temp_new_i32();
9064
9065 gen_load_fpr32(ctx, fp0, fs);
9066 gen_load_fpr32(ctx, fp1, ft);
9067 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
9068 tcg_temp_free_i32(fp1);
9069 gen_store_fpr32(ctx, fp0, fd);
9070 tcg_temp_free_i32(fp0);
9071 }
9072 }
9073 break;
9074 case OPC_MINA_S: /* OPC_RECIP1_S */
9075 if (ctx->insn_flags & ISA_MIPS32R6) {
9076 /* OPC_MINA_S */
9077 TCGv_i32 fp0 = tcg_temp_new_i32();
9078 TCGv_i32 fp1 = tcg_temp_new_i32();
9079 TCGv_i32 fp2 = tcg_temp_new_i32();
9080 gen_load_fpr32(ctx, fp0, fs);
9081 gen_load_fpr32(ctx, fp1, ft);
9082 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9083 gen_store_fpr32(ctx, fp2, fd);
9084 tcg_temp_free_i32(fp2);
9085 tcg_temp_free_i32(fp1);
9086 tcg_temp_free_i32(fp0);
9087 } else {
9088 /* OPC_RECIP1_S */
9089 check_cp1_64bitmode(ctx);
9090 {
9091 TCGv_i32 fp0 = tcg_temp_new_i32();
9092
9093 gen_load_fpr32(ctx, fp0, fs);
9094 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9095 gen_store_fpr32(ctx, fp0, fd);
9096 tcg_temp_free_i32(fp0);
9097 }
9098 }
9099 break;
9100 case OPC_MAX_S: /* OPC_RSQRT1_S */
9101 if (ctx->insn_flags & ISA_MIPS32R6) {
9102 /* OPC_MAX_S */
9103 TCGv_i32 fp0 = tcg_temp_new_i32();
9104 TCGv_i32 fp1 = tcg_temp_new_i32();
9105 gen_load_fpr32(ctx, fp0, fs);
9106 gen_load_fpr32(ctx, fp1, ft);
9107 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9108 gen_store_fpr32(ctx, fp1, fd);
9109 tcg_temp_free_i32(fp1);
9110 tcg_temp_free_i32(fp0);
9111 } else {
9112 /* OPC_RSQRT1_S */
9113 check_cp1_64bitmode(ctx);
9114 {
9115 TCGv_i32 fp0 = tcg_temp_new_i32();
9116
9117 gen_load_fpr32(ctx, fp0, fs);
9118 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9119 gen_store_fpr32(ctx, fp0, fd);
9120 tcg_temp_free_i32(fp0);
9121 }
9122 }
9123 break;
9124 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9125 if (ctx->insn_flags & ISA_MIPS32R6) {
9126 /* OPC_MAXA_S */
9127 TCGv_i32 fp0 = tcg_temp_new_i32();
9128 TCGv_i32 fp1 = tcg_temp_new_i32();
9129 gen_load_fpr32(ctx, fp0, fs);
9130 gen_load_fpr32(ctx, fp1, ft);
9131 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9132 gen_store_fpr32(ctx, fp1, fd);
9133 tcg_temp_free_i32(fp1);
9134 tcg_temp_free_i32(fp0);
9135 } else {
9136 /* OPC_RSQRT2_S */
9137 check_cp1_64bitmode(ctx);
9138 {
9139 TCGv_i32 fp0 = tcg_temp_new_i32();
9140 TCGv_i32 fp1 = tcg_temp_new_i32();
9141
9142 gen_load_fpr32(ctx, fp0, fs);
9143 gen_load_fpr32(ctx, fp1, ft);
9144 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9145 tcg_temp_free_i32(fp1);
9146 gen_store_fpr32(ctx, fp0, fd);
9147 tcg_temp_free_i32(fp0);
9148 }
9149 }
9150 break;
9151 case OPC_CVT_D_S:
9152 check_cp1_registers(ctx, fd);
9153 {
9154 TCGv_i32 fp32 = tcg_temp_new_i32();
9155 TCGv_i64 fp64 = tcg_temp_new_i64();
9156
9157 gen_load_fpr32(ctx, fp32, fs);
9158 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9159 tcg_temp_free_i32(fp32);
9160 gen_store_fpr64(ctx, fp64, fd);
9161 tcg_temp_free_i64(fp64);
9162 }
9163 break;
9164 case OPC_CVT_W_S:
9165 {
9166 TCGv_i32 fp0 = tcg_temp_new_i32();
9167
9168 gen_load_fpr32(ctx, fp0, fs);
9169 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
9170 gen_store_fpr32(ctx, fp0, fd);
9171 tcg_temp_free_i32(fp0);
9172 }
9173 break;
9174 case OPC_CVT_L_S:
9175 check_cp1_64bitmode(ctx);
9176 {
9177 TCGv_i32 fp32 = tcg_temp_new_i32();
9178 TCGv_i64 fp64 = tcg_temp_new_i64();
9179
9180 gen_load_fpr32(ctx, fp32, fs);
9181 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
9182 tcg_temp_free_i32(fp32);
9183 gen_store_fpr64(ctx, fp64, fd);
9184 tcg_temp_free_i64(fp64);
9185 }
9186 break;
9187 case OPC_CVT_PS_S:
9188 check_ps(ctx);
9189 {
9190 TCGv_i64 fp64 = tcg_temp_new_i64();
9191 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9192 TCGv_i32 fp32_1 = tcg_temp_new_i32();
9193
9194 gen_load_fpr32(ctx, fp32_0, fs);
9195 gen_load_fpr32(ctx, fp32_1, ft);
9196 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9197 tcg_temp_free_i32(fp32_1);
9198 tcg_temp_free_i32(fp32_0);
9199 gen_store_fpr64(ctx, fp64, fd);
9200 tcg_temp_free_i64(fp64);
9201 }
9202 break;
9203 case OPC_CMP_F_S:
9204 case OPC_CMP_UN_S:
9205 case OPC_CMP_EQ_S:
9206 case OPC_CMP_UEQ_S:
9207 case OPC_CMP_OLT_S:
9208 case OPC_CMP_ULT_S:
9209 case OPC_CMP_OLE_S:
9210 case OPC_CMP_ULE_S:
9211 case OPC_CMP_SF_S:
9212 case OPC_CMP_NGLE_S:
9213 case OPC_CMP_SEQ_S:
9214 case OPC_CMP_NGL_S:
9215 case OPC_CMP_LT_S:
9216 case OPC_CMP_NGE_S:
9217 case OPC_CMP_LE_S:
9218 case OPC_CMP_NGT_S:
9219 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9220 if (ctx->opcode & (1 << 6)) {
9221 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9222 } else {
9223 gen_cmp_s(ctx, func-48, ft, fs, cc);
9224 }
9225 break;
9226 case OPC_ADD_D:
9227 check_cp1_registers(ctx, fs | ft | fd);
9228 {
9229 TCGv_i64 fp0 = tcg_temp_new_i64();
9230 TCGv_i64 fp1 = tcg_temp_new_i64();
9231
9232 gen_load_fpr64(ctx, fp0, fs);
9233 gen_load_fpr64(ctx, fp1, ft);
9234 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9235 tcg_temp_free_i64(fp1);
9236 gen_store_fpr64(ctx, fp0, fd);
9237 tcg_temp_free_i64(fp0);
9238 }
9239 break;
9240 case OPC_SUB_D:
9241 check_cp1_registers(ctx, fs | ft | fd);
9242 {
9243 TCGv_i64 fp0 = tcg_temp_new_i64();
9244 TCGv_i64 fp1 = tcg_temp_new_i64();
9245
9246 gen_load_fpr64(ctx, fp0, fs);
9247 gen_load_fpr64(ctx, fp1, ft);
9248 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9249 tcg_temp_free_i64(fp1);
9250 gen_store_fpr64(ctx, fp0, fd);
9251 tcg_temp_free_i64(fp0);
9252 }
9253 break;
9254 case OPC_MUL_D:
9255 check_cp1_registers(ctx, fs | ft | fd);
9256 {
9257 TCGv_i64 fp0 = tcg_temp_new_i64();
9258 TCGv_i64 fp1 = tcg_temp_new_i64();
9259
9260 gen_load_fpr64(ctx, fp0, fs);
9261 gen_load_fpr64(ctx, fp1, ft);
9262 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9263 tcg_temp_free_i64(fp1);
9264 gen_store_fpr64(ctx, fp0, fd);
9265 tcg_temp_free_i64(fp0);
9266 }
9267 break;
9268 case OPC_DIV_D:
9269 check_cp1_registers(ctx, fs | ft | fd);
9270 {
9271 TCGv_i64 fp0 = tcg_temp_new_i64();
9272 TCGv_i64 fp1 = tcg_temp_new_i64();
9273
9274 gen_load_fpr64(ctx, fp0, fs);
9275 gen_load_fpr64(ctx, fp1, ft);
9276 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9277 tcg_temp_free_i64(fp1);
9278 gen_store_fpr64(ctx, fp0, fd);
9279 tcg_temp_free_i64(fp0);
9280 }
9281 break;
9282 case OPC_SQRT_D:
9283 check_cp1_registers(ctx, fs | fd);
9284 {
9285 TCGv_i64 fp0 = tcg_temp_new_i64();
9286
9287 gen_load_fpr64(ctx, fp0, fs);
9288 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9289 gen_store_fpr64(ctx, fp0, fd);
9290 tcg_temp_free_i64(fp0);
9291 }
9292 break;
9293 case OPC_ABS_D:
9294 check_cp1_registers(ctx, fs | fd);
9295 {
9296 TCGv_i64 fp0 = tcg_temp_new_i64();
9297
9298 gen_load_fpr64(ctx, fp0, fs);
9299 gen_helper_float_abs_d(fp0, fp0);
9300 gen_store_fpr64(ctx, fp0, fd);
9301 tcg_temp_free_i64(fp0);
9302 }
9303 break;
9304 case OPC_MOV_D:
9305 check_cp1_registers(ctx, fs | fd);
9306 {
9307 TCGv_i64 fp0 = tcg_temp_new_i64();
9308
9309 gen_load_fpr64(ctx, fp0, fs);
9310 gen_store_fpr64(ctx, fp0, fd);
9311 tcg_temp_free_i64(fp0);
9312 }
9313 break;
9314 case OPC_NEG_D:
9315 check_cp1_registers(ctx, fs | fd);
9316 {
9317 TCGv_i64 fp0 = tcg_temp_new_i64();
9318
9319 gen_load_fpr64(ctx, fp0, fs);
9320 gen_helper_float_chs_d(fp0, fp0);
9321 gen_store_fpr64(ctx, fp0, fd);
9322 tcg_temp_free_i64(fp0);
9323 }
9324 break;
9325 case OPC_ROUND_L_D:
9326 check_cp1_64bitmode(ctx);
9327 {
9328 TCGv_i64 fp0 = tcg_temp_new_i64();
9329
9330 gen_load_fpr64(ctx, fp0, fs);
9331 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
9332 gen_store_fpr64(ctx, fp0, fd);
9333 tcg_temp_free_i64(fp0);
9334 }
9335 break;
9336 case OPC_TRUNC_L_D:
9337 check_cp1_64bitmode(ctx);
9338 {
9339 TCGv_i64 fp0 = tcg_temp_new_i64();
9340
9341 gen_load_fpr64(ctx, fp0, fs);
9342 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
9343 gen_store_fpr64(ctx, fp0, fd);
9344 tcg_temp_free_i64(fp0);
9345 }
9346 break;
9347 case OPC_CEIL_L_D:
9348 check_cp1_64bitmode(ctx);
9349 {
9350 TCGv_i64 fp0 = tcg_temp_new_i64();
9351
9352 gen_load_fpr64(ctx, fp0, fs);
9353 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
9354 gen_store_fpr64(ctx, fp0, fd);
9355 tcg_temp_free_i64(fp0);
9356 }
9357 break;
9358 case OPC_FLOOR_L_D:
9359 check_cp1_64bitmode(ctx);
9360 {
9361 TCGv_i64 fp0 = tcg_temp_new_i64();
9362
9363 gen_load_fpr64(ctx, fp0, fs);
9364 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
9365 gen_store_fpr64(ctx, fp0, fd);
9366 tcg_temp_free_i64(fp0);
9367 }
9368 break;
9369 case OPC_ROUND_W_D:
9370 check_cp1_registers(ctx, fs);
9371 {
9372 TCGv_i32 fp32 = tcg_temp_new_i32();
9373 TCGv_i64 fp64 = tcg_temp_new_i64();
9374
9375 gen_load_fpr64(ctx, fp64, fs);
9376 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
9377 tcg_temp_free_i64(fp64);
9378 gen_store_fpr32(ctx, fp32, fd);
9379 tcg_temp_free_i32(fp32);
9380 }
9381 break;
9382 case OPC_TRUNC_W_D:
9383 check_cp1_registers(ctx, fs);
9384 {
9385 TCGv_i32 fp32 = tcg_temp_new_i32();
9386 TCGv_i64 fp64 = tcg_temp_new_i64();
9387
9388 gen_load_fpr64(ctx, fp64, fs);
9389 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
9390 tcg_temp_free_i64(fp64);
9391 gen_store_fpr32(ctx, fp32, fd);
9392 tcg_temp_free_i32(fp32);
9393 }
9394 break;
9395 case OPC_CEIL_W_D:
9396 check_cp1_registers(ctx, fs);
9397 {
9398 TCGv_i32 fp32 = tcg_temp_new_i32();
9399 TCGv_i64 fp64 = tcg_temp_new_i64();
9400
9401 gen_load_fpr64(ctx, fp64, fs);
9402 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
9403 tcg_temp_free_i64(fp64);
9404 gen_store_fpr32(ctx, fp32, fd);
9405 tcg_temp_free_i32(fp32);
9406 }
9407 break;
9408 case OPC_FLOOR_W_D:
9409 check_cp1_registers(ctx, fs);
9410 {
9411 TCGv_i32 fp32 = tcg_temp_new_i32();
9412 TCGv_i64 fp64 = tcg_temp_new_i64();
9413
9414 gen_load_fpr64(ctx, fp64, fs);
9415 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
9416 tcg_temp_free_i64(fp64);
9417 gen_store_fpr32(ctx, fp32, fd);
9418 tcg_temp_free_i32(fp32);
9419 }
9420 break;
9421 case OPC_SEL_D:
9422 check_insn(ctx, ISA_MIPS32R6);
9423 gen_sel_d(ctx, op1, fd, ft, fs);
9424 break;
9425 case OPC_SELEQZ_D:
9426 check_insn(ctx, ISA_MIPS32R6);
9427 gen_sel_d(ctx, op1, fd, ft, fs);
9428 break;
9429 case OPC_SELNEZ_D:
9430 check_insn(ctx, ISA_MIPS32R6);
9431 gen_sel_d(ctx, op1, fd, ft, fs);
9432 break;
9433 case OPC_MOVCF_D:
9434 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9435 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9436 break;
9437 case OPC_MOVZ_D:
9438 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9439 {
9440 TCGLabel *l1 = gen_new_label();
9441 TCGv_i64 fp0;
9442
9443 if (ft != 0) {
9444 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9445 }
9446 fp0 = tcg_temp_new_i64();
9447 gen_load_fpr64(ctx, fp0, fs);
9448 gen_store_fpr64(ctx, fp0, fd);
9449 tcg_temp_free_i64(fp0);
9450 gen_set_label(l1);
9451 }
9452 break;
9453 case OPC_MOVN_D:
9454 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9455 {
9456 TCGLabel *l1 = gen_new_label();
9457 TCGv_i64 fp0;
9458
9459 if (ft != 0) {
9460 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9461 fp0 = tcg_temp_new_i64();
9462 gen_load_fpr64(ctx, fp0, fs);
9463 gen_store_fpr64(ctx, fp0, fd);
9464 tcg_temp_free_i64(fp0);
9465 gen_set_label(l1);
9466 }
9467 }
9468 break;
9469 case OPC_RECIP_D:
9470 check_cp1_registers(ctx, fs | fd);
9471 {
9472 TCGv_i64 fp0 = tcg_temp_new_i64();
9473
9474 gen_load_fpr64(ctx, fp0, fs);
9475 gen_helper_float_recip_d(fp0, cpu_env, fp0);
9476 gen_store_fpr64(ctx, fp0, fd);
9477 tcg_temp_free_i64(fp0);
9478 }
9479 break;
9480 case OPC_RSQRT_D:
9481 check_cp1_registers(ctx, fs | fd);
9482 {
9483 TCGv_i64 fp0 = tcg_temp_new_i64();
9484
9485 gen_load_fpr64(ctx, fp0, fs);
9486 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9487 gen_store_fpr64(ctx, fp0, fd);
9488 tcg_temp_free_i64(fp0);
9489 }
9490 break;
9491 case OPC_MADDF_D:
9492 check_insn(ctx, ISA_MIPS32R6);
9493 {
9494 TCGv_i64 fp0 = tcg_temp_new_i64();
9495 TCGv_i64 fp1 = tcg_temp_new_i64();
9496 TCGv_i64 fp2 = tcg_temp_new_i64();
9497 gen_load_fpr64(ctx, fp0, fs);
9498 gen_load_fpr64(ctx, fp1, ft);
9499 gen_load_fpr64(ctx, fp2, fd);
9500 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9501 gen_store_fpr64(ctx, fp2, fd);
9502 tcg_temp_free_i64(fp2);
9503 tcg_temp_free_i64(fp1);
9504 tcg_temp_free_i64(fp0);
9505 }
9506 break;
9507 case OPC_MSUBF_D:
9508 check_insn(ctx, ISA_MIPS32R6);
9509 {
9510 TCGv_i64 fp0 = tcg_temp_new_i64();
9511 TCGv_i64 fp1 = tcg_temp_new_i64();
9512 TCGv_i64 fp2 = tcg_temp_new_i64();
9513 gen_load_fpr64(ctx, fp0, fs);
9514 gen_load_fpr64(ctx, fp1, ft);
9515 gen_load_fpr64(ctx, fp2, fd);
9516 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9517 gen_store_fpr64(ctx, fp2, fd);
9518 tcg_temp_free_i64(fp2);
9519 tcg_temp_free_i64(fp1);
9520 tcg_temp_free_i64(fp0);
9521 }
9522 break;
9523 case OPC_RINT_D:
9524 check_insn(ctx, ISA_MIPS32R6);
9525 {
9526 TCGv_i64 fp0 = tcg_temp_new_i64();
9527 gen_load_fpr64(ctx, fp0, fs);
9528 gen_helper_float_rint_d(fp0, cpu_env, fp0);
9529 gen_store_fpr64(ctx, fp0, fd);
9530 tcg_temp_free_i64(fp0);
9531 }
9532 break;
9533 case OPC_CLASS_D:
9534 check_insn(ctx, ISA_MIPS32R6);
9535 {
9536 TCGv_i64 fp0 = tcg_temp_new_i64();
9537 gen_load_fpr64(ctx, fp0, fs);
9538 gen_helper_float_class_d(fp0, fp0);
9539 gen_store_fpr64(ctx, fp0, fd);
9540 tcg_temp_free_i64(fp0);
9541 }
9542 break;
9543 case OPC_MIN_D: /* OPC_RECIP2_D */
9544 if (ctx->insn_flags & ISA_MIPS32R6) {
9545 /* OPC_MIN_D */
9546 TCGv_i64 fp0 = tcg_temp_new_i64();
9547 TCGv_i64 fp1 = tcg_temp_new_i64();
9548 gen_load_fpr64(ctx, fp0, fs);
9549 gen_load_fpr64(ctx, fp1, ft);
9550 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9551 gen_store_fpr64(ctx, fp1, fd);
9552 tcg_temp_free_i64(fp1);
9553 tcg_temp_free_i64(fp0);
9554 } else {
9555 /* OPC_RECIP2_D */
9556 check_cp1_64bitmode(ctx);
9557 {
9558 TCGv_i64 fp0 = tcg_temp_new_i64();
9559 TCGv_i64 fp1 = tcg_temp_new_i64();
9560
9561 gen_load_fpr64(ctx, fp0, fs);
9562 gen_load_fpr64(ctx, fp1, ft);
9563 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9564 tcg_temp_free_i64(fp1);
9565 gen_store_fpr64(ctx, fp0, fd);
9566 tcg_temp_free_i64(fp0);
9567 }
9568 }
9569 break;
9570 case OPC_MINA_D: /* OPC_RECIP1_D */
9571 if (ctx->insn_flags & ISA_MIPS32R6) {
9572 /* OPC_MINA_D */
9573 TCGv_i64 fp0 = tcg_temp_new_i64();
9574 TCGv_i64 fp1 = tcg_temp_new_i64();
9575 gen_load_fpr64(ctx, fp0, fs);
9576 gen_load_fpr64(ctx, fp1, ft);
9577 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9578 gen_store_fpr64(ctx, fp1, fd);
9579 tcg_temp_free_i64(fp1);
9580 tcg_temp_free_i64(fp0);
9581 } else {
9582 /* OPC_RECIP1_D */
9583 check_cp1_64bitmode(ctx);
9584 {
9585 TCGv_i64 fp0 = tcg_temp_new_i64();
9586
9587 gen_load_fpr64(ctx, fp0, fs);
9588 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9589 gen_store_fpr64(ctx, fp0, fd);
9590 tcg_temp_free_i64(fp0);
9591 }
9592 }
9593 break;
9594 case OPC_MAX_D: /* OPC_RSQRT1_D */
9595 if (ctx->insn_flags & ISA_MIPS32R6) {
9596 /* OPC_MAX_D */
9597 TCGv_i64 fp0 = tcg_temp_new_i64();
9598 TCGv_i64 fp1 = tcg_temp_new_i64();
9599 gen_load_fpr64(ctx, fp0, fs);
9600 gen_load_fpr64(ctx, fp1, ft);
9601 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9602 gen_store_fpr64(ctx, fp1, fd);
9603 tcg_temp_free_i64(fp1);
9604 tcg_temp_free_i64(fp0);
9605 } else {
9606 /* OPC_RSQRT1_D */
9607 check_cp1_64bitmode(ctx);
9608 {
9609 TCGv_i64 fp0 = tcg_temp_new_i64();
9610
9611 gen_load_fpr64(ctx, fp0, fs);
9612 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9613 gen_store_fpr64(ctx, fp0, fd);
9614 tcg_temp_free_i64(fp0);
9615 }
9616 }
9617 break;
9618 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9619 if (ctx->insn_flags & ISA_MIPS32R6) {
9620 /* OPC_MAXA_D */
9621 TCGv_i64 fp0 = tcg_temp_new_i64();
9622 TCGv_i64 fp1 = tcg_temp_new_i64();
9623 gen_load_fpr64(ctx, fp0, fs);
9624 gen_load_fpr64(ctx, fp1, ft);
9625 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9626 gen_store_fpr64(ctx, fp1, fd);
9627 tcg_temp_free_i64(fp1);
9628 tcg_temp_free_i64(fp0);
9629 } else {
9630 /* OPC_RSQRT2_D */
9631 check_cp1_64bitmode(ctx);
9632 {
9633 TCGv_i64 fp0 = tcg_temp_new_i64();
9634 TCGv_i64 fp1 = tcg_temp_new_i64();
9635
9636 gen_load_fpr64(ctx, fp0, fs);
9637 gen_load_fpr64(ctx, fp1, ft);
9638 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9639 tcg_temp_free_i64(fp1);
9640 gen_store_fpr64(ctx, fp0, fd);
9641 tcg_temp_free_i64(fp0);
9642 }
9643 }
9644 break;
9645 case OPC_CMP_F_D:
9646 case OPC_CMP_UN_D:
9647 case OPC_CMP_EQ_D:
9648 case OPC_CMP_UEQ_D:
9649 case OPC_CMP_OLT_D:
9650 case OPC_CMP_ULT_D:
9651 case OPC_CMP_OLE_D:
9652 case OPC_CMP_ULE_D:
9653 case OPC_CMP_SF_D:
9654 case OPC_CMP_NGLE_D:
9655 case OPC_CMP_SEQ_D:
9656 case OPC_CMP_NGL_D:
9657 case OPC_CMP_LT_D:
9658 case OPC_CMP_NGE_D:
9659 case OPC_CMP_LE_D:
9660 case OPC_CMP_NGT_D:
9661 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9662 if (ctx->opcode & (1 << 6)) {
9663 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9664 } else {
9665 gen_cmp_d(ctx, func-48, ft, fs, cc);
9666 }
9667 break;
9668 case OPC_CVT_S_D:
9669 check_cp1_registers(ctx, fs);
9670 {
9671 TCGv_i32 fp32 = tcg_temp_new_i32();
9672 TCGv_i64 fp64 = tcg_temp_new_i64();
9673
9674 gen_load_fpr64(ctx, fp64, fs);
9675 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9676 tcg_temp_free_i64(fp64);
9677 gen_store_fpr32(ctx, fp32, fd);
9678 tcg_temp_free_i32(fp32);
9679 }
9680 break;
9681 case OPC_CVT_W_D:
9682 check_cp1_registers(ctx, fs);
9683 {
9684 TCGv_i32 fp32 = tcg_temp_new_i32();
9685 TCGv_i64 fp64 = tcg_temp_new_i64();
9686
9687 gen_load_fpr64(ctx, fp64, fs);
9688 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
9689 tcg_temp_free_i64(fp64);
9690 gen_store_fpr32(ctx, fp32, fd);
9691 tcg_temp_free_i32(fp32);
9692 }
9693 break;
9694 case OPC_CVT_L_D:
9695 check_cp1_64bitmode(ctx);
9696 {
9697 TCGv_i64 fp0 = tcg_temp_new_i64();
9698
9699 gen_load_fpr64(ctx, fp0, fs);
9700 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
9701 gen_store_fpr64(ctx, fp0, fd);
9702 tcg_temp_free_i64(fp0);
9703 }
9704 break;
9705 case OPC_CVT_S_W:
9706 {
9707 TCGv_i32 fp0 = tcg_temp_new_i32();
9708
9709 gen_load_fpr32(ctx, fp0, fs);
9710 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9711 gen_store_fpr32(ctx, fp0, fd);
9712 tcg_temp_free_i32(fp0);
9713 }
9714 break;
9715 case OPC_CVT_D_W:
9716 check_cp1_registers(ctx, fd);
9717 {
9718 TCGv_i32 fp32 = tcg_temp_new_i32();
9719 TCGv_i64 fp64 = tcg_temp_new_i64();
9720
9721 gen_load_fpr32(ctx, fp32, fs);
9722 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9723 tcg_temp_free_i32(fp32);
9724 gen_store_fpr64(ctx, fp64, fd);
9725 tcg_temp_free_i64(fp64);
9726 }
9727 break;
9728 case OPC_CVT_S_L:
9729 check_cp1_64bitmode(ctx);
9730 {
9731 TCGv_i32 fp32 = tcg_temp_new_i32();
9732 TCGv_i64 fp64 = tcg_temp_new_i64();
9733
9734 gen_load_fpr64(ctx, fp64, fs);
9735 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9736 tcg_temp_free_i64(fp64);
9737 gen_store_fpr32(ctx, fp32, fd);
9738 tcg_temp_free_i32(fp32);
9739 }
9740 break;
9741 case OPC_CVT_D_L:
9742 check_cp1_64bitmode(ctx);
9743 {
9744 TCGv_i64 fp0 = tcg_temp_new_i64();
9745
9746 gen_load_fpr64(ctx, fp0, fs);
9747 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9748 gen_store_fpr64(ctx, fp0, fd);
9749 tcg_temp_free_i64(fp0);
9750 }
9751 break;
9752 case OPC_CVT_PS_PW:
9753 check_ps(ctx);
9754 {
9755 TCGv_i64 fp0 = tcg_temp_new_i64();
9756
9757 gen_load_fpr64(ctx, fp0, fs);
9758 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9759 gen_store_fpr64(ctx, fp0, fd);
9760 tcg_temp_free_i64(fp0);
9761 }
9762 break;
9763 case OPC_ADD_PS:
9764 check_ps(ctx);
9765 {
9766 TCGv_i64 fp0 = tcg_temp_new_i64();
9767 TCGv_i64 fp1 = tcg_temp_new_i64();
9768
9769 gen_load_fpr64(ctx, fp0, fs);
9770 gen_load_fpr64(ctx, fp1, ft);
9771 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
9772 tcg_temp_free_i64(fp1);
9773 gen_store_fpr64(ctx, fp0, fd);
9774 tcg_temp_free_i64(fp0);
9775 }
9776 break;
9777 case OPC_SUB_PS:
9778 check_ps(ctx);
9779 {
9780 TCGv_i64 fp0 = tcg_temp_new_i64();
9781 TCGv_i64 fp1 = tcg_temp_new_i64();
9782
9783 gen_load_fpr64(ctx, fp0, fs);
9784 gen_load_fpr64(ctx, fp1, ft);
9785 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9786 tcg_temp_free_i64(fp1);
9787 gen_store_fpr64(ctx, fp0, fd);
9788 tcg_temp_free_i64(fp0);
9789 }
9790 break;
9791 case OPC_MUL_PS:
9792 check_ps(ctx);
9793 {
9794 TCGv_i64 fp0 = tcg_temp_new_i64();
9795 TCGv_i64 fp1 = tcg_temp_new_i64();
9796
9797 gen_load_fpr64(ctx, fp0, fs);
9798 gen_load_fpr64(ctx, fp1, ft);
9799 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9800 tcg_temp_free_i64(fp1);
9801 gen_store_fpr64(ctx, fp0, fd);
9802 tcg_temp_free_i64(fp0);
9803 }
9804 break;
9805 case OPC_ABS_PS:
9806 check_ps(ctx);
9807 {
9808 TCGv_i64 fp0 = tcg_temp_new_i64();
9809
9810 gen_load_fpr64(ctx, fp0, fs);
9811 gen_helper_float_abs_ps(fp0, fp0);
9812 gen_store_fpr64(ctx, fp0, fd);
9813 tcg_temp_free_i64(fp0);
9814 }
9815 break;
9816 case OPC_MOV_PS:
9817 check_ps(ctx);
9818 {
9819 TCGv_i64 fp0 = tcg_temp_new_i64();
9820
9821 gen_load_fpr64(ctx, fp0, fs);
9822 gen_store_fpr64(ctx, fp0, fd);
9823 tcg_temp_free_i64(fp0);
9824 }
9825 break;
9826 case OPC_NEG_PS:
9827 check_ps(ctx);
9828 {
9829 TCGv_i64 fp0 = tcg_temp_new_i64();
9830
9831 gen_load_fpr64(ctx, fp0, fs);
9832 gen_helper_float_chs_ps(fp0, fp0);
9833 gen_store_fpr64(ctx, fp0, fd);
9834 tcg_temp_free_i64(fp0);
9835 }
9836 break;
9837 case OPC_MOVCF_PS:
9838 check_ps(ctx);
9839 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9840 break;
9841 case OPC_MOVZ_PS:
9842 check_ps(ctx);
9843 {
9844 TCGLabel *l1 = gen_new_label();
9845 TCGv_i64 fp0;
9846
9847 if (ft != 0)
9848 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9849 fp0 = tcg_temp_new_i64();
9850 gen_load_fpr64(ctx, fp0, fs);
9851 gen_store_fpr64(ctx, fp0, fd);
9852 tcg_temp_free_i64(fp0);
9853 gen_set_label(l1);
9854 }
9855 break;
9856 case OPC_MOVN_PS:
9857 check_ps(ctx);
9858 {
9859 TCGLabel *l1 = gen_new_label();
9860 TCGv_i64 fp0;
9861
9862 if (ft != 0) {
9863 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9864 fp0 = tcg_temp_new_i64();
9865 gen_load_fpr64(ctx, fp0, fs);
9866 gen_store_fpr64(ctx, fp0, fd);
9867 tcg_temp_free_i64(fp0);
9868 gen_set_label(l1);
9869 }
9870 }
9871 break;
9872 case OPC_ADDR_PS:
9873 check_ps(ctx);
9874 {
9875 TCGv_i64 fp0 = tcg_temp_new_i64();
9876 TCGv_i64 fp1 = tcg_temp_new_i64();
9877
9878 gen_load_fpr64(ctx, fp0, ft);
9879 gen_load_fpr64(ctx, fp1, fs);
9880 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
9881 tcg_temp_free_i64(fp1);
9882 gen_store_fpr64(ctx, fp0, fd);
9883 tcg_temp_free_i64(fp0);
9884 }
9885 break;
9886 case OPC_MULR_PS:
9887 check_ps(ctx);
9888 {
9889 TCGv_i64 fp0 = tcg_temp_new_i64();
9890 TCGv_i64 fp1 = tcg_temp_new_i64();
9891
9892 gen_load_fpr64(ctx, fp0, ft);
9893 gen_load_fpr64(ctx, fp1, fs);
9894 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
9895 tcg_temp_free_i64(fp1);
9896 gen_store_fpr64(ctx, fp0, fd);
9897 tcg_temp_free_i64(fp0);
9898 }
9899 break;
9900 case OPC_RECIP2_PS:
9901 check_ps(ctx);
9902 {
9903 TCGv_i64 fp0 = tcg_temp_new_i64();
9904 TCGv_i64 fp1 = tcg_temp_new_i64();
9905
9906 gen_load_fpr64(ctx, fp0, fs);
9907 gen_load_fpr64(ctx, fp1, ft);
9908 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
9909 tcg_temp_free_i64(fp1);
9910 gen_store_fpr64(ctx, fp0, fd);
9911 tcg_temp_free_i64(fp0);
9912 }
9913 break;
9914 case OPC_RECIP1_PS:
9915 check_ps(ctx);
9916 {
9917 TCGv_i64 fp0 = tcg_temp_new_i64();
9918
9919 gen_load_fpr64(ctx, fp0, fs);
9920 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
9921 gen_store_fpr64(ctx, fp0, fd);
9922 tcg_temp_free_i64(fp0);
9923 }
9924 break;
9925 case OPC_RSQRT1_PS:
9926 check_ps(ctx);
9927 {
9928 TCGv_i64 fp0 = tcg_temp_new_i64();
9929
9930 gen_load_fpr64(ctx, fp0, fs);
9931 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
9932 gen_store_fpr64(ctx, fp0, fd);
9933 tcg_temp_free_i64(fp0);
9934 }
9935 break;
9936 case OPC_RSQRT2_PS:
9937 check_ps(ctx);
9938 {
9939 TCGv_i64 fp0 = tcg_temp_new_i64();
9940 TCGv_i64 fp1 = tcg_temp_new_i64();
9941
9942 gen_load_fpr64(ctx, fp0, fs);
9943 gen_load_fpr64(ctx, fp1, ft);
9944 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
9945 tcg_temp_free_i64(fp1);
9946 gen_store_fpr64(ctx, fp0, fd);
9947 tcg_temp_free_i64(fp0);
9948 }
9949 break;
9950 case OPC_CVT_S_PU:
9951 check_cp1_64bitmode(ctx);
9952 {
9953 TCGv_i32 fp0 = tcg_temp_new_i32();
9954
9955 gen_load_fpr32h(ctx, fp0, fs);
9956 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
9957 gen_store_fpr32(ctx, fp0, fd);
9958 tcg_temp_free_i32(fp0);
9959 }
9960 break;
9961 case OPC_CVT_PW_PS:
9962 check_ps(ctx);
9963 {
9964 TCGv_i64 fp0 = tcg_temp_new_i64();
9965
9966 gen_load_fpr64(ctx, fp0, fs);
9967 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
9968 gen_store_fpr64(ctx, fp0, fd);
9969 tcg_temp_free_i64(fp0);
9970 }
9971 break;
9972 case OPC_CVT_S_PL:
9973 check_cp1_64bitmode(ctx);
9974 {
9975 TCGv_i32 fp0 = tcg_temp_new_i32();
9976
9977 gen_load_fpr32(ctx, fp0, fs);
9978 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
9979 gen_store_fpr32(ctx, fp0, fd);
9980 tcg_temp_free_i32(fp0);
9981 }
9982 break;
9983 case OPC_PLL_PS:
9984 check_ps(ctx);
9985 {
9986 TCGv_i32 fp0 = tcg_temp_new_i32();
9987 TCGv_i32 fp1 = tcg_temp_new_i32();
9988
9989 gen_load_fpr32(ctx, fp0, fs);
9990 gen_load_fpr32(ctx, fp1, ft);
9991 gen_store_fpr32h(ctx, fp0, fd);
9992 gen_store_fpr32(ctx, fp1, fd);
9993 tcg_temp_free_i32(fp0);
9994 tcg_temp_free_i32(fp1);
9995 }
9996 break;
9997 case OPC_PLU_PS:
9998 check_ps(ctx);
9999 {
10000 TCGv_i32 fp0 = tcg_temp_new_i32();
10001 TCGv_i32 fp1 = tcg_temp_new_i32();
10002
10003 gen_load_fpr32(ctx, fp0, fs);
10004 gen_load_fpr32h(ctx, fp1, ft);
10005 gen_store_fpr32(ctx, fp1, fd);
10006 gen_store_fpr32h(ctx, fp0, fd);
10007 tcg_temp_free_i32(fp0);
10008 tcg_temp_free_i32(fp1);
10009 }
10010 break;
10011 case OPC_PUL_PS:
10012 check_ps(ctx);
10013 {
10014 TCGv_i32 fp0 = tcg_temp_new_i32();
10015 TCGv_i32 fp1 = tcg_temp_new_i32();
10016
10017 gen_load_fpr32h(ctx, fp0, fs);
10018 gen_load_fpr32(ctx, fp1, ft);
10019 gen_store_fpr32(ctx, fp1, fd);
10020 gen_store_fpr32h(ctx, fp0, fd);
10021 tcg_temp_free_i32(fp0);
10022 tcg_temp_free_i32(fp1);
10023 }
10024 break;
10025 case OPC_PUU_PS:
10026 check_ps(ctx);
10027 {
10028 TCGv_i32 fp0 = tcg_temp_new_i32();
10029 TCGv_i32 fp1 = tcg_temp_new_i32();
10030
10031 gen_load_fpr32h(ctx, fp0, fs);
10032 gen_load_fpr32h(ctx, fp1, ft);
10033 gen_store_fpr32(ctx, fp1, fd);
10034 gen_store_fpr32h(ctx, fp0, fd);
10035 tcg_temp_free_i32(fp0);
10036 tcg_temp_free_i32(fp1);
10037 }
10038 break;
10039 case OPC_CMP_F_PS:
10040 case OPC_CMP_UN_PS:
10041 case OPC_CMP_EQ_PS:
10042 case OPC_CMP_UEQ_PS:
10043 case OPC_CMP_OLT_PS:
10044 case OPC_CMP_ULT_PS:
10045 case OPC_CMP_OLE_PS:
10046 case OPC_CMP_ULE_PS:
10047 case OPC_CMP_SF_PS:
10048 case OPC_CMP_NGLE_PS:
10049 case OPC_CMP_SEQ_PS:
10050 case OPC_CMP_NGL_PS:
10051 case OPC_CMP_LT_PS:
10052 case OPC_CMP_NGE_PS:
10053 case OPC_CMP_LE_PS:
10054 case OPC_CMP_NGT_PS:
10055 if (ctx->opcode & (1 << 6)) {
10056 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
10057 } else {
10058 gen_cmp_ps(ctx, func-48, ft, fs, cc);
10059 }
10060 break;
10061 default:
10062 MIPS_INVAL("farith");
10063 generate_exception_end(ctx, EXCP_RI);
10064 return;
10065 }
10066 }
10067
10068 /* Coprocessor 3 (FPU) */
10069 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10070 int fd, int fs, int base, int index)
10071 {
10072 TCGv t0 = tcg_temp_new();
10073
10074 if (base == 0) {
10075 gen_load_gpr(t0, index);
10076 } else if (index == 0) {
10077 gen_load_gpr(t0, base);
10078 } else {
10079 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10080 }
10081 /* Don't do NOP if destination is zero: we must perform the actual
10082 memory access. */
10083 switch (opc) {
10084 case OPC_LWXC1:
10085 check_cop1x(ctx);
10086 {
10087 TCGv_i32 fp0 = tcg_temp_new_i32();
10088
10089 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10090 tcg_gen_trunc_tl_i32(fp0, t0);
10091 gen_store_fpr32(ctx, fp0, fd);
10092 tcg_temp_free_i32(fp0);
10093 }
10094 break;
10095 case OPC_LDXC1:
10096 check_cop1x(ctx);
10097 check_cp1_registers(ctx, fd);
10098 {
10099 TCGv_i64 fp0 = tcg_temp_new_i64();
10100 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10101 gen_store_fpr64(ctx, fp0, fd);
10102 tcg_temp_free_i64(fp0);
10103 }
10104 break;
10105 case OPC_LUXC1:
10106 check_cp1_64bitmode(ctx);
10107 tcg_gen_andi_tl(t0, t0, ~0x7);
10108 {
10109 TCGv_i64 fp0 = tcg_temp_new_i64();
10110
10111 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10112 gen_store_fpr64(ctx, fp0, fd);
10113 tcg_temp_free_i64(fp0);
10114 }
10115 break;
10116 case OPC_SWXC1:
10117 check_cop1x(ctx);
10118 {
10119 TCGv_i32 fp0 = tcg_temp_new_i32();
10120 gen_load_fpr32(ctx, fp0, fs);
10121 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10122 tcg_temp_free_i32(fp0);
10123 }
10124 break;
10125 case OPC_SDXC1:
10126 check_cop1x(ctx);
10127 check_cp1_registers(ctx, fs);
10128 {
10129 TCGv_i64 fp0 = tcg_temp_new_i64();
10130 gen_load_fpr64(ctx, fp0, fs);
10131 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10132 tcg_temp_free_i64(fp0);
10133 }
10134 break;
10135 case OPC_SUXC1:
10136 check_cp1_64bitmode(ctx);
10137 tcg_gen_andi_tl(t0, t0, ~0x7);
10138 {
10139 TCGv_i64 fp0 = tcg_temp_new_i64();
10140 gen_load_fpr64(ctx, fp0, fs);
10141 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10142 tcg_temp_free_i64(fp0);
10143 }
10144 break;
10145 }
10146 tcg_temp_free(t0);
10147 }
10148
10149 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10150 int fd, int fr, int fs, int ft)
10151 {
10152 switch (opc) {
10153 case OPC_ALNV_PS:
10154 check_ps(ctx);
10155 {
10156 TCGv t0 = tcg_temp_local_new();
10157 TCGv_i32 fp = tcg_temp_new_i32();
10158 TCGv_i32 fph = tcg_temp_new_i32();
10159 TCGLabel *l1 = gen_new_label();
10160 TCGLabel *l2 = gen_new_label();
10161
10162 gen_load_gpr(t0, fr);
10163 tcg_gen_andi_tl(t0, t0, 0x7);
10164
10165 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10166 gen_load_fpr32(ctx, fp, fs);
10167 gen_load_fpr32h(ctx, fph, fs);
10168 gen_store_fpr32(ctx, fp, fd);
10169 gen_store_fpr32h(ctx, fph, fd);
10170 tcg_gen_br(l2);
10171 gen_set_label(l1);
10172 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10173 tcg_temp_free(t0);
10174 #ifdef TARGET_WORDS_BIGENDIAN
10175 gen_load_fpr32(ctx, fp, fs);
10176 gen_load_fpr32h(ctx, fph, ft);
10177 gen_store_fpr32h(ctx, fp, fd);
10178 gen_store_fpr32(ctx, fph, fd);
10179 #else
10180 gen_load_fpr32h(ctx, fph, fs);
10181 gen_load_fpr32(ctx, fp, ft);
10182 gen_store_fpr32(ctx, fph, fd);
10183 gen_store_fpr32h(ctx, fp, fd);
10184 #endif
10185 gen_set_label(l2);
10186 tcg_temp_free_i32(fp);
10187 tcg_temp_free_i32(fph);
10188 }
10189 break;
10190 case OPC_MADD_S:
10191 check_cop1x(ctx);
10192 {
10193 TCGv_i32 fp0 = tcg_temp_new_i32();
10194 TCGv_i32 fp1 = tcg_temp_new_i32();
10195 TCGv_i32 fp2 = tcg_temp_new_i32();
10196
10197 gen_load_fpr32(ctx, fp0, fs);
10198 gen_load_fpr32(ctx, fp1, ft);
10199 gen_load_fpr32(ctx, fp2, fr);
10200 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10201 tcg_temp_free_i32(fp0);
10202 tcg_temp_free_i32(fp1);
10203 gen_store_fpr32(ctx, fp2, fd);
10204 tcg_temp_free_i32(fp2);
10205 }
10206 break;
10207 case OPC_MADD_D:
10208 check_cop1x(ctx);
10209 check_cp1_registers(ctx, fd | fs | ft | fr);
10210 {
10211 TCGv_i64 fp0 = tcg_temp_new_i64();
10212 TCGv_i64 fp1 = tcg_temp_new_i64();
10213 TCGv_i64 fp2 = tcg_temp_new_i64();
10214
10215 gen_load_fpr64(ctx, fp0, fs);
10216 gen_load_fpr64(ctx, fp1, ft);
10217 gen_load_fpr64(ctx, fp2, fr);
10218 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10219 tcg_temp_free_i64(fp0);
10220 tcg_temp_free_i64(fp1);
10221 gen_store_fpr64(ctx, fp2, fd);
10222 tcg_temp_free_i64(fp2);
10223 }
10224 break;
10225 case OPC_MADD_PS:
10226 check_ps(ctx);
10227 {
10228 TCGv_i64 fp0 = tcg_temp_new_i64();
10229 TCGv_i64 fp1 = tcg_temp_new_i64();
10230 TCGv_i64 fp2 = tcg_temp_new_i64();
10231
10232 gen_load_fpr64(ctx, fp0, fs);
10233 gen_load_fpr64(ctx, fp1, ft);
10234 gen_load_fpr64(ctx, fp2, fr);
10235 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10236 tcg_temp_free_i64(fp0);
10237 tcg_temp_free_i64(fp1);
10238 gen_store_fpr64(ctx, fp2, fd);
10239 tcg_temp_free_i64(fp2);
10240 }
10241 break;
10242 case OPC_MSUB_S:
10243 check_cop1x(ctx);
10244 {
10245 TCGv_i32 fp0 = tcg_temp_new_i32();
10246 TCGv_i32 fp1 = tcg_temp_new_i32();
10247 TCGv_i32 fp2 = tcg_temp_new_i32();
10248
10249 gen_load_fpr32(ctx, fp0, fs);
10250 gen_load_fpr32(ctx, fp1, ft);
10251 gen_load_fpr32(ctx, fp2, fr);
10252 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10253 tcg_temp_free_i32(fp0);
10254 tcg_temp_free_i32(fp1);
10255 gen_store_fpr32(ctx, fp2, fd);
10256 tcg_temp_free_i32(fp2);
10257 }
10258 break;
10259 case OPC_MSUB_D:
10260 check_cop1x(ctx);
10261 check_cp1_registers(ctx, fd | fs | ft | fr);
10262 {
10263 TCGv_i64 fp0 = tcg_temp_new_i64();
10264 TCGv_i64 fp1 = tcg_temp_new_i64();
10265 TCGv_i64 fp2 = tcg_temp_new_i64();
10266
10267 gen_load_fpr64(ctx, fp0, fs);
10268 gen_load_fpr64(ctx, fp1, ft);
10269 gen_load_fpr64(ctx, fp2, fr);
10270 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10271 tcg_temp_free_i64(fp0);
10272 tcg_temp_free_i64(fp1);
10273 gen_store_fpr64(ctx, fp2, fd);
10274 tcg_temp_free_i64(fp2);
10275 }
10276 break;
10277 case OPC_MSUB_PS:
10278 check_ps(ctx);
10279 {
10280 TCGv_i64 fp0 = tcg_temp_new_i64();
10281 TCGv_i64 fp1 = tcg_temp_new_i64();
10282 TCGv_i64 fp2 = tcg_temp_new_i64();
10283
10284 gen_load_fpr64(ctx, fp0, fs);
10285 gen_load_fpr64(ctx, fp1, ft);
10286 gen_load_fpr64(ctx, fp2, fr);
10287 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
10288 tcg_temp_free_i64(fp0);
10289 tcg_temp_free_i64(fp1);
10290 gen_store_fpr64(ctx, fp2, fd);
10291 tcg_temp_free_i64(fp2);
10292 }
10293 break;
10294 case OPC_NMADD_S:
10295 check_cop1x(ctx);
10296 {
10297 TCGv_i32 fp0 = tcg_temp_new_i32();
10298 TCGv_i32 fp1 = tcg_temp_new_i32();
10299 TCGv_i32 fp2 = tcg_temp_new_i32();
10300
10301 gen_load_fpr32(ctx, fp0, fs);
10302 gen_load_fpr32(ctx, fp1, ft);
10303 gen_load_fpr32(ctx, fp2, fr);
10304 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10305 tcg_temp_free_i32(fp0);
10306 tcg_temp_free_i32(fp1);
10307 gen_store_fpr32(ctx, fp2, fd);
10308 tcg_temp_free_i32(fp2);
10309 }
10310 break;
10311 case OPC_NMADD_D:
10312 check_cop1x(ctx);
10313 check_cp1_registers(ctx, fd | fs | ft | fr);
10314 {
10315 TCGv_i64 fp0 = tcg_temp_new_i64();
10316 TCGv_i64 fp1 = tcg_temp_new_i64();
10317 TCGv_i64 fp2 = tcg_temp_new_i64();
10318
10319 gen_load_fpr64(ctx, fp0, fs);
10320 gen_load_fpr64(ctx, fp1, ft);
10321 gen_load_fpr64(ctx, fp2, fr);
10322 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10323 tcg_temp_free_i64(fp0);
10324 tcg_temp_free_i64(fp1);
10325 gen_store_fpr64(ctx, fp2, fd);
10326 tcg_temp_free_i64(fp2);
10327 }
10328 break;
10329 case OPC_NMADD_PS:
10330 check_ps(ctx);
10331 {
10332 TCGv_i64 fp0 = tcg_temp_new_i64();
10333 TCGv_i64 fp1 = tcg_temp_new_i64();
10334 TCGv_i64 fp2 = tcg_temp_new_i64();
10335
10336 gen_load_fpr64(ctx, fp0, fs);
10337 gen_load_fpr64(ctx, fp1, ft);
10338 gen_load_fpr64(ctx, fp2, fr);
10339 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
10340 tcg_temp_free_i64(fp0);
10341 tcg_temp_free_i64(fp1);
10342 gen_store_fpr64(ctx, fp2, fd);
10343 tcg_temp_free_i64(fp2);
10344 }
10345 break;
10346 case OPC_NMSUB_S:
10347 check_cop1x(ctx);
10348 {
10349 TCGv_i32 fp0 = tcg_temp_new_i32();
10350 TCGv_i32 fp1 = tcg_temp_new_i32();
10351 TCGv_i32 fp2 = tcg_temp_new_i32();
10352
10353 gen_load_fpr32(ctx, fp0, fs);
10354 gen_load_fpr32(ctx, fp1, ft);
10355 gen_load_fpr32(ctx, fp2, fr);
10356 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10357 tcg_temp_free_i32(fp0);
10358 tcg_temp_free_i32(fp1);
10359 gen_store_fpr32(ctx, fp2, fd);
10360 tcg_temp_free_i32(fp2);
10361 }
10362 break;
10363 case OPC_NMSUB_D:
10364 check_cop1x(ctx);
10365 check_cp1_registers(ctx, fd | fs | ft | fr);
10366 {
10367 TCGv_i64 fp0 = tcg_temp_new_i64();
10368 TCGv_i64 fp1 = tcg_temp_new_i64();
10369 TCGv_i64 fp2 = tcg_temp_new_i64();
10370
10371 gen_load_fpr64(ctx, fp0, fs);
10372 gen_load_fpr64(ctx, fp1, ft);
10373 gen_load_fpr64(ctx, fp2, fr);
10374 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10375 tcg_temp_free_i64(fp0);
10376 tcg_temp_free_i64(fp1);
10377 gen_store_fpr64(ctx, fp2, fd);
10378 tcg_temp_free_i64(fp2);
10379 }
10380 break;
10381 case OPC_NMSUB_PS:
10382 check_ps(ctx);
10383 {
10384 TCGv_i64 fp0 = tcg_temp_new_i64();
10385 TCGv_i64 fp1 = tcg_temp_new_i64();
10386 TCGv_i64 fp2 = tcg_temp_new_i64();
10387
10388 gen_load_fpr64(ctx, fp0, fs);
10389 gen_load_fpr64(ctx, fp1, ft);
10390 gen_load_fpr64(ctx, fp2, fr);
10391 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10392 tcg_temp_free_i64(fp0);
10393 tcg_temp_free_i64(fp1);
10394 gen_store_fpr64(ctx, fp2, fd);
10395 tcg_temp_free_i64(fp2);
10396 }
10397 break;
10398 default:
10399 MIPS_INVAL("flt3_arith");
10400 generate_exception_end(ctx, EXCP_RI);
10401 return;
10402 }
10403 }
10404
10405 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10406 {
10407 TCGv t0;
10408
10409 #if !defined(CONFIG_USER_ONLY)
10410 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10411 Therefore only check the ISA in system mode. */
10412 check_insn(ctx, ISA_MIPS32R2);
10413 #endif
10414 t0 = tcg_temp_new();
10415
10416 switch (rd) {
10417 case 0:
10418 gen_helper_rdhwr_cpunum(t0, cpu_env);
10419 gen_store_gpr(t0, rt);
10420 break;
10421 case 1:
10422 gen_helper_rdhwr_synci_step(t0, cpu_env);
10423 gen_store_gpr(t0, rt);
10424 break;
10425 case 2:
10426 gen_helper_rdhwr_cc(t0, cpu_env);
10427 gen_store_gpr(t0, rt);
10428 break;
10429 case 3:
10430 gen_helper_rdhwr_ccres(t0, cpu_env);
10431 gen_store_gpr(t0, rt);
10432 break;
10433 case 4:
10434 check_insn(ctx, ISA_MIPS32R6);
10435 if (sel != 0) {
10436 /* Performance counter registers are not implemented other than
10437 * control register 0.
10438 */
10439 generate_exception(ctx, EXCP_RI);
10440 }
10441 gen_helper_rdhwr_performance(t0, cpu_env);
10442 gen_store_gpr(t0, rt);
10443 break;
10444 case 5:
10445 check_insn(ctx, ISA_MIPS32R6);
10446 gen_helper_rdhwr_xnp(t0, cpu_env);
10447 gen_store_gpr(t0, rt);
10448 break;
10449 case 29:
10450 #if defined(CONFIG_USER_ONLY)
10451 tcg_gen_ld_tl(t0, cpu_env,
10452 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10453 gen_store_gpr(t0, rt);
10454 break;
10455 #else
10456 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10457 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10458 tcg_gen_ld_tl(t0, cpu_env,
10459 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10460 gen_store_gpr(t0, rt);
10461 } else {
10462 generate_exception_end(ctx, EXCP_RI);
10463 }
10464 break;
10465 #endif
10466 default: /* Invalid */
10467 MIPS_INVAL("rdhwr");
10468 generate_exception_end(ctx, EXCP_RI);
10469 break;
10470 }
10471 tcg_temp_free(t0);
10472 }
10473
10474 static inline void clear_branch_hflags(DisasContext *ctx)
10475 {
10476 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10477 if (ctx->bstate == BS_NONE) {
10478 save_cpu_state(ctx, 0);
10479 } else {
10480 /* it is not safe to save ctx->hflags as hflags may be changed
10481 in execution time by the instruction in delay / forbidden slot. */
10482 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10483 }
10484 }
10485
10486 static void gen_branch(DisasContext *ctx, int insn_bytes)
10487 {
10488 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10489 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10490 /* Branches completion */
10491 clear_branch_hflags(ctx);
10492 ctx->bstate = BS_BRANCH;
10493 /* FIXME: Need to clear can_do_io. */
10494 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10495 case MIPS_HFLAG_FBNSLOT:
10496 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10497 break;
10498 case MIPS_HFLAG_B:
10499 /* unconditional branch */
10500 if (proc_hflags & MIPS_HFLAG_BX) {
10501 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10502 }
10503 gen_goto_tb(ctx, 0, ctx->btarget);
10504 break;
10505 case MIPS_HFLAG_BL:
10506 /* blikely taken case */
10507 gen_goto_tb(ctx, 0, ctx->btarget);
10508 break;
10509 case MIPS_HFLAG_BC:
10510 /* Conditional branch */
10511 {
10512 TCGLabel *l1 = gen_new_label();
10513
10514 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10515 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10516 gen_set_label(l1);
10517 gen_goto_tb(ctx, 0, ctx->btarget);
10518 }
10519 break;
10520 case MIPS_HFLAG_BR:
10521 /* unconditional branch to register */
10522 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10523 TCGv t0 = tcg_temp_new();
10524 TCGv_i32 t1 = tcg_temp_new_i32();
10525
10526 tcg_gen_andi_tl(t0, btarget, 0x1);
10527 tcg_gen_trunc_tl_i32(t1, t0);
10528 tcg_temp_free(t0);
10529 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10530 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10531 tcg_gen_or_i32(hflags, hflags, t1);
10532 tcg_temp_free_i32(t1);
10533
10534 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10535 } else {
10536 tcg_gen_mov_tl(cpu_PC, btarget);
10537 }
10538 if (ctx->singlestep_enabled) {
10539 save_cpu_state(ctx, 0);
10540 gen_helper_raise_exception_debug(cpu_env);
10541 }
10542 tcg_gen_exit_tb(0);
10543 break;
10544 default:
10545 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10546 abort();
10547 }
10548 }
10549 }
10550
10551 /* Compact Branches */
10552 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10553 int rs, int rt, int32_t offset)
10554 {
10555 int bcond_compute = 0;
10556 TCGv t0 = tcg_temp_new();
10557 TCGv t1 = tcg_temp_new();
10558 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10559
10560 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10561 #ifdef MIPS_DEBUG_DISAS
10562 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10563 "\n", ctx->pc);
10564 #endif
10565 generate_exception_end(ctx, EXCP_RI);
10566 goto out;
10567 }
10568
10569 /* Load needed operands and calculate btarget */
10570 switch (opc) {
10571 /* compact branch */
10572 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10573 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10574 gen_load_gpr(t0, rs);
10575 gen_load_gpr(t1, rt);
10576 bcond_compute = 1;
10577 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10578 if (rs <= rt && rs == 0) {
10579 /* OPC_BEQZALC, OPC_BNEZALC */
10580 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10581 }
10582 break;
10583 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10584 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10585 gen_load_gpr(t0, rs);
10586 gen_load_gpr(t1, rt);
10587 bcond_compute = 1;
10588 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10589 break;
10590 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10591 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10592 if (rs == 0 || rs == rt) {
10593 /* OPC_BLEZALC, OPC_BGEZALC */
10594 /* OPC_BGTZALC, OPC_BLTZALC */
10595 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10596 }
10597 gen_load_gpr(t0, rs);
10598 gen_load_gpr(t1, rt);
10599 bcond_compute = 1;
10600 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10601 break;
10602 case OPC_BC:
10603 case OPC_BALC:
10604 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10605 break;
10606 case OPC_BEQZC:
10607 case OPC_BNEZC:
10608 if (rs != 0) {
10609 /* OPC_BEQZC, OPC_BNEZC */
10610 gen_load_gpr(t0, rs);
10611 bcond_compute = 1;
10612 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10613 } else {
10614 /* OPC_JIC, OPC_JIALC */
10615 TCGv tbase = tcg_temp_new();
10616 TCGv toffset = tcg_temp_new();
10617
10618 gen_load_gpr(tbase, rt);
10619 tcg_gen_movi_tl(toffset, offset);
10620 gen_op_addr_add(ctx, btarget, tbase, toffset);
10621 tcg_temp_free(tbase);
10622 tcg_temp_free(toffset);
10623 }
10624 break;
10625 default:
10626 MIPS_INVAL("Compact branch/jump");
10627 generate_exception_end(ctx, EXCP_RI);
10628 goto out;
10629 }
10630
10631 if (bcond_compute == 0) {
10632 /* Uncoditional compact branch */
10633 switch (opc) {
10634 case OPC_JIALC:
10635 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10636 /* Fallthrough */
10637 case OPC_JIC:
10638 ctx->hflags |= MIPS_HFLAG_BR;
10639 break;
10640 case OPC_BALC:
10641 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10642 /* Fallthrough */
10643 case OPC_BC:
10644 ctx->hflags |= MIPS_HFLAG_B;
10645 break;
10646 default:
10647 MIPS_INVAL("Compact branch/jump");
10648 generate_exception_end(ctx, EXCP_RI);
10649 goto out;
10650 }
10651
10652 /* Generating branch here as compact branches don't have delay slot */
10653 gen_branch(ctx, 4);
10654 } else {
10655 /* Conditional compact branch */
10656 TCGLabel *fs = gen_new_label();
10657 save_cpu_state(ctx, 0);
10658
10659 switch (opc) {
10660 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10661 if (rs == 0 && rt != 0) {
10662 /* OPC_BLEZALC */
10663 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10664 } else if (rs != 0 && rt != 0 && rs == rt) {
10665 /* OPC_BGEZALC */
10666 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10667 } else {
10668 /* OPC_BGEUC */
10669 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10670 }
10671 break;
10672 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10673 if (rs == 0 && rt != 0) {
10674 /* OPC_BGTZALC */
10675 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10676 } else if (rs != 0 && rt != 0 && rs == rt) {
10677 /* OPC_BLTZALC */
10678 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10679 } else {
10680 /* OPC_BLTUC */
10681 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10682 }
10683 break;
10684 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10685 if (rs == 0 && rt != 0) {
10686 /* OPC_BLEZC */
10687 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10688 } else if (rs != 0 && rt != 0 && rs == rt) {
10689 /* OPC_BGEZC */
10690 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10691 } else {
10692 /* OPC_BGEC */
10693 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10694 }
10695 break;
10696 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10697 if (rs == 0 && rt != 0) {
10698 /* OPC_BGTZC */
10699 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10700 } else if (rs != 0 && rt != 0 && rs == rt) {
10701 /* OPC_BLTZC */
10702 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10703 } else {
10704 /* OPC_BLTC */
10705 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10706 }
10707 break;
10708 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10709 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10710 if (rs >= rt) {
10711 /* OPC_BOVC, OPC_BNVC */
10712 TCGv t2 = tcg_temp_new();
10713 TCGv t3 = tcg_temp_new();
10714 TCGv t4 = tcg_temp_new();
10715 TCGv input_overflow = tcg_temp_new();
10716
10717 gen_load_gpr(t0, rs);
10718 gen_load_gpr(t1, rt);
10719 tcg_gen_ext32s_tl(t2, t0);
10720 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10721 tcg_gen_ext32s_tl(t3, t1);
10722 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10723 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10724
10725 tcg_gen_add_tl(t4, t2, t3);
10726 tcg_gen_ext32s_tl(t4, t4);
10727 tcg_gen_xor_tl(t2, t2, t3);
10728 tcg_gen_xor_tl(t3, t4, t3);
10729 tcg_gen_andc_tl(t2, t3, t2);
10730 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10731 tcg_gen_or_tl(t4, t4, input_overflow);
10732 if (opc == OPC_BOVC) {
10733 /* OPC_BOVC */
10734 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10735 } else {
10736 /* OPC_BNVC */
10737 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10738 }
10739 tcg_temp_free(input_overflow);
10740 tcg_temp_free(t4);
10741 tcg_temp_free(t3);
10742 tcg_temp_free(t2);
10743 } else if (rs < rt && rs == 0) {
10744 /* OPC_BEQZALC, OPC_BNEZALC */
10745 if (opc == OPC_BEQZALC) {
10746 /* OPC_BEQZALC */
10747 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10748 } else {
10749 /* OPC_BNEZALC */
10750 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10751 }
10752 } else {
10753 /* OPC_BEQC, OPC_BNEC */
10754 if (opc == OPC_BEQC) {
10755 /* OPC_BEQC */
10756 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10757 } else {
10758 /* OPC_BNEC */
10759 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10760 }
10761 }
10762 break;
10763 case OPC_BEQZC:
10764 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10765 break;
10766 case OPC_BNEZC:
10767 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10768 break;
10769 default:
10770 MIPS_INVAL("Compact conditional branch/jump");
10771 generate_exception_end(ctx, EXCP_RI);
10772 goto out;
10773 }
10774
10775 /* Generating branch here as compact branches don't have delay slot */
10776 gen_goto_tb(ctx, 1, ctx->btarget);
10777 gen_set_label(fs);
10778
10779 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
10780 }
10781
10782 out:
10783 tcg_temp_free(t0);
10784 tcg_temp_free(t1);
10785 }
10786
10787 /* ISA extensions (ASEs) */
10788 /* MIPS16 extension to MIPS32 */
10789
10790 /* MIPS16 major opcodes */
10791 enum {
10792 M16_OPC_ADDIUSP = 0x00,
10793 M16_OPC_ADDIUPC = 0x01,
10794 M16_OPC_B = 0x02,
10795 M16_OPC_JAL = 0x03,
10796 M16_OPC_BEQZ = 0x04,
10797 M16_OPC_BNEQZ = 0x05,
10798 M16_OPC_SHIFT = 0x06,
10799 M16_OPC_LD = 0x07,
10800 M16_OPC_RRIA = 0x08,
10801 M16_OPC_ADDIU8 = 0x09,
10802 M16_OPC_SLTI = 0x0a,
10803 M16_OPC_SLTIU = 0x0b,
10804 M16_OPC_I8 = 0x0c,
10805 M16_OPC_LI = 0x0d,
10806 M16_OPC_CMPI = 0x0e,
10807 M16_OPC_SD = 0x0f,
10808 M16_OPC_LB = 0x10,
10809 M16_OPC_LH = 0x11,
10810 M16_OPC_LWSP = 0x12,
10811 M16_OPC_LW = 0x13,
10812 M16_OPC_LBU = 0x14,
10813 M16_OPC_LHU = 0x15,
10814 M16_OPC_LWPC = 0x16,
10815 M16_OPC_LWU = 0x17,
10816 M16_OPC_SB = 0x18,
10817 M16_OPC_SH = 0x19,
10818 M16_OPC_SWSP = 0x1a,
10819 M16_OPC_SW = 0x1b,
10820 M16_OPC_RRR = 0x1c,
10821 M16_OPC_RR = 0x1d,
10822 M16_OPC_EXTEND = 0x1e,
10823 M16_OPC_I64 = 0x1f
10824 };
10825
10826 /* I8 funct field */
10827 enum {
10828 I8_BTEQZ = 0x0,
10829 I8_BTNEZ = 0x1,
10830 I8_SWRASP = 0x2,
10831 I8_ADJSP = 0x3,
10832 I8_SVRS = 0x4,
10833 I8_MOV32R = 0x5,
10834 I8_MOVR32 = 0x7
10835 };
10836
10837 /* RRR f field */
10838 enum {
10839 RRR_DADDU = 0x0,
10840 RRR_ADDU = 0x1,
10841 RRR_DSUBU = 0x2,
10842 RRR_SUBU = 0x3
10843 };
10844
10845 /* RR funct field */
10846 enum {
10847 RR_JR = 0x00,
10848 RR_SDBBP = 0x01,
10849 RR_SLT = 0x02,
10850 RR_SLTU = 0x03,
10851 RR_SLLV = 0x04,
10852 RR_BREAK = 0x05,
10853 RR_SRLV = 0x06,
10854 RR_SRAV = 0x07,
10855 RR_DSRL = 0x08,
10856 RR_CMP = 0x0a,
10857 RR_NEG = 0x0b,
10858 RR_AND = 0x0c,
10859 RR_OR = 0x0d,
10860 RR_XOR = 0x0e,
10861 RR_NOT = 0x0f,
10862 RR_MFHI = 0x10,
10863 RR_CNVT = 0x11,
10864 RR_MFLO = 0x12,
10865 RR_DSRA = 0x13,
10866 RR_DSLLV = 0x14,
10867 RR_DSRLV = 0x16,
10868 RR_DSRAV = 0x17,
10869 RR_MULT = 0x18,
10870 RR_MULTU = 0x19,
10871 RR_DIV = 0x1a,
10872 RR_DIVU = 0x1b,
10873 RR_DMULT = 0x1c,
10874 RR_DMULTU = 0x1d,
10875 RR_DDIV = 0x1e,
10876 RR_DDIVU = 0x1f
10877 };
10878
10879 /* I64 funct field */
10880 enum {
10881 I64_LDSP = 0x0,
10882 I64_SDSP = 0x1,
10883 I64_SDRASP = 0x2,
10884 I64_DADJSP = 0x3,
10885 I64_LDPC = 0x4,
10886 I64_DADDIU5 = 0x5,
10887 I64_DADDIUPC = 0x6,
10888 I64_DADDIUSP = 0x7
10889 };
10890
10891 /* RR ry field for CNVT */
10892 enum {
10893 RR_RY_CNVT_ZEB = 0x0,
10894 RR_RY_CNVT_ZEH = 0x1,
10895 RR_RY_CNVT_ZEW = 0x2,
10896 RR_RY_CNVT_SEB = 0x4,
10897 RR_RY_CNVT_SEH = 0x5,
10898 RR_RY_CNVT_SEW = 0x6,
10899 };
10900
10901 static int xlat (int r)
10902 {
10903 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10904
10905 return map[r];
10906 }
10907
10908 static void gen_mips16_save (DisasContext *ctx,
10909 int xsregs, int aregs,
10910 int do_ra, int do_s0, int do_s1,
10911 int framesize)
10912 {
10913 TCGv t0 = tcg_temp_new();
10914 TCGv t1 = tcg_temp_new();
10915 TCGv t2 = tcg_temp_new();
10916 int args, astatic;
10917
10918 switch (aregs) {
10919 case 0:
10920 case 1:
10921 case 2:
10922 case 3:
10923 case 11:
10924 args = 0;
10925 break;
10926 case 4:
10927 case 5:
10928 case 6:
10929 case 7:
10930 args = 1;
10931 break;
10932 case 8:
10933 case 9:
10934 case 10:
10935 args = 2;
10936 break;
10937 case 12:
10938 case 13:
10939 args = 3;
10940 break;
10941 case 14:
10942 args = 4;
10943 break;
10944 default:
10945 generate_exception_end(ctx, EXCP_RI);
10946 return;
10947 }
10948
10949 switch (args) {
10950 case 4:
10951 gen_base_offset_addr(ctx, t0, 29, 12);
10952 gen_load_gpr(t1, 7);
10953 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10954 /* Fall through */
10955 case 3:
10956 gen_base_offset_addr(ctx, t0, 29, 8);
10957 gen_load_gpr(t1, 6);
10958 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10959 /* Fall through */
10960 case 2:
10961 gen_base_offset_addr(ctx, t0, 29, 4);
10962 gen_load_gpr(t1, 5);
10963 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10964 /* Fall through */
10965 case 1:
10966 gen_base_offset_addr(ctx, t0, 29, 0);
10967 gen_load_gpr(t1, 4);
10968 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10969 }
10970
10971 gen_load_gpr(t0, 29);
10972
10973 #define DECR_AND_STORE(reg) do { \
10974 tcg_gen_movi_tl(t2, -4); \
10975 gen_op_addr_add(ctx, t0, t0, t2); \
10976 gen_load_gpr(t1, reg); \
10977 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
10978 } while (0)
10979
10980 if (do_ra) {
10981 DECR_AND_STORE(31);
10982 }
10983
10984 switch (xsregs) {
10985 case 7:
10986 DECR_AND_STORE(30);
10987 /* Fall through */
10988 case 6:
10989 DECR_AND_STORE(23);
10990 /* Fall through */
10991 case 5:
10992 DECR_AND_STORE(22);
10993 /* Fall through */
10994 case 4:
10995 DECR_AND_STORE(21);
10996 /* Fall through */
10997 case 3:
10998 DECR_AND_STORE(20);
10999 /* Fall through */
11000 case 2:
11001 DECR_AND_STORE(19);
11002 /* Fall through */
11003 case 1:
11004 DECR_AND_STORE(18);
11005 }
11006
11007 if (do_s1) {
11008 DECR_AND_STORE(17);
11009 }
11010 if (do_s0) {
11011 DECR_AND_STORE(16);
11012 }
11013
11014 switch (aregs) {
11015 case 0:
11016 case 4:
11017 case 8:
11018 case 12:
11019 case 14:
11020 astatic = 0;
11021 break;
11022 case 1:
11023 case 5:
11024 case 9:
11025 case 13:
11026 astatic = 1;
11027 break;
11028 case 2:
11029 case 6:
11030 case 10:
11031 astatic = 2;
11032 break;
11033 case 3:
11034 case 7:
11035 astatic = 3;
11036 break;
11037 case 11:
11038 astatic = 4;
11039 break;
11040 default:
11041 generate_exception_end(ctx, EXCP_RI);
11042 return;
11043 }
11044
11045 if (astatic > 0) {
11046 DECR_AND_STORE(7);
11047 if (astatic > 1) {
11048 DECR_AND_STORE(6);
11049 if (astatic > 2) {
11050 DECR_AND_STORE(5);
11051 if (astatic > 3) {
11052 DECR_AND_STORE(4);
11053 }
11054 }
11055 }
11056 }
11057 #undef DECR_AND_STORE
11058
11059 tcg_gen_movi_tl(t2, -framesize);
11060 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11061 tcg_temp_free(t0);
11062 tcg_temp_free(t1);
11063 tcg_temp_free(t2);
11064 }
11065
11066 static void gen_mips16_restore (DisasContext *ctx,
11067 int xsregs, int aregs,
11068 int do_ra, int do_s0, int do_s1,
11069 int framesize)
11070 {
11071 int astatic;
11072 TCGv t0 = tcg_temp_new();
11073 TCGv t1 = tcg_temp_new();
11074 TCGv t2 = tcg_temp_new();
11075
11076 tcg_gen_movi_tl(t2, framesize);
11077 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
11078
11079 #define DECR_AND_LOAD(reg) do { \
11080 tcg_gen_movi_tl(t2, -4); \
11081 gen_op_addr_add(ctx, t0, t0, t2); \
11082 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11083 gen_store_gpr(t1, reg); \
11084 } while (0)
11085
11086 if (do_ra) {
11087 DECR_AND_LOAD(31);
11088 }
11089
11090 switch (xsregs) {
11091 case 7:
11092 DECR_AND_LOAD(30);
11093 /* Fall through */
11094 case 6:
11095 DECR_AND_LOAD(23);
11096 /* Fall through */
11097 case 5:
11098 DECR_AND_LOAD(22);
11099 /* Fall through */
11100 case 4:
11101 DECR_AND_LOAD(21);
11102 /* Fall through */
11103 case 3:
11104 DECR_AND_LOAD(20);
11105 /* Fall through */
11106 case 2:
11107 DECR_AND_LOAD(19);
11108 /* Fall through */
11109 case 1:
11110 DECR_AND_LOAD(18);
11111 }
11112
11113 if (do_s1) {
11114 DECR_AND_LOAD(17);
11115 }
11116 if (do_s0) {
11117 DECR_AND_LOAD(16);
11118 }
11119
11120 switch (aregs) {
11121 case 0:
11122 case 4:
11123 case 8:
11124 case 12:
11125 case 14:
11126 astatic = 0;
11127 break;
11128 case 1:
11129 case 5:
11130 case 9:
11131 case 13:
11132 astatic = 1;
11133 break;
11134 case 2:
11135 case 6:
11136 case 10:
11137 astatic = 2;
11138 break;
11139 case 3:
11140 case 7:
11141 astatic = 3;
11142 break;
11143 case 11:
11144 astatic = 4;
11145 break;
11146 default:
11147 generate_exception_end(ctx, EXCP_RI);
11148 return;
11149 }
11150
11151 if (astatic > 0) {
11152 DECR_AND_LOAD(7);
11153 if (astatic > 1) {
11154 DECR_AND_LOAD(6);
11155 if (astatic > 2) {
11156 DECR_AND_LOAD(5);
11157 if (astatic > 3) {
11158 DECR_AND_LOAD(4);
11159 }
11160 }
11161 }
11162 }
11163 #undef DECR_AND_LOAD
11164
11165 tcg_gen_movi_tl(t2, framesize);
11166 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11167 tcg_temp_free(t0);
11168 tcg_temp_free(t1);
11169 tcg_temp_free(t2);
11170 }
11171
11172 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11173 int is_64_bit, int extended)
11174 {
11175 TCGv t0;
11176
11177 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11178 generate_exception_end(ctx, EXCP_RI);
11179 return;
11180 }
11181
11182 t0 = tcg_temp_new();
11183
11184 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11185 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11186 if (!is_64_bit) {
11187 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11188 }
11189
11190 tcg_temp_free(t0);
11191 }
11192
11193 #if defined(TARGET_MIPS64)
11194 static void decode_i64_mips16 (DisasContext *ctx,
11195 int ry, int funct, int16_t offset,
11196 int extended)
11197 {
11198 switch (funct) {
11199 case I64_LDSP:
11200 check_insn(ctx, ISA_MIPS3);
11201 check_mips_64(ctx);
11202 offset = extended ? offset : offset << 3;
11203 gen_ld(ctx, OPC_LD, ry, 29, offset);
11204 break;
11205 case I64_SDSP:
11206 check_insn(ctx, ISA_MIPS3);
11207 check_mips_64(ctx);
11208 offset = extended ? offset : offset << 3;
11209 gen_st(ctx, OPC_SD, ry, 29, offset);
11210 break;
11211 case I64_SDRASP:
11212 check_insn(ctx, ISA_MIPS3);
11213 check_mips_64(ctx);
11214 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11215 gen_st(ctx, OPC_SD, 31, 29, offset);
11216 break;
11217 case I64_DADJSP:
11218 check_insn(ctx, ISA_MIPS3);
11219 check_mips_64(ctx);
11220 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11221 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11222 break;
11223 case I64_LDPC:
11224 check_insn(ctx, ISA_MIPS3);
11225 check_mips_64(ctx);
11226 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11227 generate_exception_end(ctx, EXCP_RI);
11228 } else {
11229 offset = extended ? offset : offset << 3;
11230 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11231 }
11232 break;
11233 case I64_DADDIU5:
11234 check_insn(ctx, ISA_MIPS3);
11235 check_mips_64(ctx);
11236 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11237 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11238 break;
11239 case I64_DADDIUPC:
11240 check_insn(ctx, ISA_MIPS3);
11241 check_mips_64(ctx);
11242 offset = extended ? offset : offset << 2;
11243 gen_addiupc(ctx, ry, offset, 1, extended);
11244 break;
11245 case I64_DADDIUSP:
11246 check_insn(ctx, ISA_MIPS3);
11247 check_mips_64(ctx);
11248 offset = extended ? offset : offset << 2;
11249 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11250 break;
11251 }
11252 }
11253 #endif
11254
11255 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11256 {
11257 int extend = cpu_lduw_code(env, ctx->pc + 2);
11258 int op, rx, ry, funct, sa;
11259 int16_t imm, offset;
11260
11261 ctx->opcode = (ctx->opcode << 16) | extend;
11262 op = (ctx->opcode >> 11) & 0x1f;
11263 sa = (ctx->opcode >> 22) & 0x1f;
11264 funct = (ctx->opcode >> 8) & 0x7;
11265 rx = xlat((ctx->opcode >> 8) & 0x7);
11266 ry = xlat((ctx->opcode >> 5) & 0x7);
11267 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11268 | ((ctx->opcode >> 21) & 0x3f) << 5
11269 | (ctx->opcode & 0x1f));
11270
11271 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11272 counterparts. */
11273 switch (op) {
11274 case M16_OPC_ADDIUSP:
11275 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11276 break;
11277 case M16_OPC_ADDIUPC:
11278 gen_addiupc(ctx, rx, imm, 0, 1);
11279 break;
11280 case M16_OPC_B:
11281 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11282 /* No delay slot, so just process as a normal instruction */
11283 break;
11284 case M16_OPC_BEQZ:
11285 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11286 /* No delay slot, so just process as a normal instruction */
11287 break;
11288 case M16_OPC_BNEQZ:
11289 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11290 /* No delay slot, so just process as a normal instruction */
11291 break;
11292 case M16_OPC_SHIFT:
11293 switch (ctx->opcode & 0x3) {
11294 case 0x0:
11295 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11296 break;
11297 case 0x1:
11298 #if defined(TARGET_MIPS64)
11299 check_mips_64(ctx);
11300 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11301 #else
11302 generate_exception_end(ctx, EXCP_RI);
11303 #endif
11304 break;
11305 case 0x2:
11306 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11307 break;
11308 case 0x3:
11309 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11310 break;
11311 }
11312 break;
11313 #if defined(TARGET_MIPS64)
11314 case M16_OPC_LD:
11315 check_insn(ctx, ISA_MIPS3);
11316 check_mips_64(ctx);
11317 gen_ld(ctx, OPC_LD, ry, rx, offset);
11318 break;
11319 #endif
11320 case M16_OPC_RRIA:
11321 imm = ctx->opcode & 0xf;
11322 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11323 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11324 imm = (int16_t) (imm << 1) >> 1;
11325 if ((ctx->opcode >> 4) & 0x1) {
11326 #if defined(TARGET_MIPS64)
11327 check_mips_64(ctx);
11328 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11329 #else
11330 generate_exception_end(ctx, EXCP_RI);
11331 #endif
11332 } else {
11333 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11334 }
11335 break;
11336 case M16_OPC_ADDIU8:
11337 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11338 break;
11339 case M16_OPC_SLTI:
11340 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11341 break;
11342 case M16_OPC_SLTIU:
11343 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11344 break;
11345 case M16_OPC_I8:
11346 switch (funct) {
11347 case I8_BTEQZ:
11348 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11349 break;
11350 case I8_BTNEZ:
11351 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11352 break;
11353 case I8_SWRASP:
11354 gen_st(ctx, OPC_SW, 31, 29, imm);
11355 break;
11356 case I8_ADJSP:
11357 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11358 break;
11359 case I8_SVRS:
11360 check_insn(ctx, ISA_MIPS32);
11361 {
11362 int xsregs = (ctx->opcode >> 24) & 0x7;
11363 int aregs = (ctx->opcode >> 16) & 0xf;
11364 int do_ra = (ctx->opcode >> 6) & 0x1;
11365 int do_s0 = (ctx->opcode >> 5) & 0x1;
11366 int do_s1 = (ctx->opcode >> 4) & 0x1;
11367 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11368 | (ctx->opcode & 0xf)) << 3;
11369
11370 if (ctx->opcode & (1 << 7)) {
11371 gen_mips16_save(ctx, xsregs, aregs,
11372 do_ra, do_s0, do_s1,
11373 framesize);
11374 } else {
11375 gen_mips16_restore(ctx, xsregs, aregs,
11376 do_ra, do_s0, do_s1,
11377 framesize);
11378 }
11379 }
11380 break;
11381 default:
11382 generate_exception_end(ctx, EXCP_RI);
11383 break;
11384 }
11385 break;
11386 case M16_OPC_LI:
11387 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11388 break;
11389 case M16_OPC_CMPI:
11390 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11391 break;
11392 #if defined(TARGET_MIPS64)
11393 case M16_OPC_SD:
11394 check_insn(ctx, ISA_MIPS3);
11395 check_mips_64(ctx);
11396 gen_st(ctx, OPC_SD, ry, rx, offset);
11397 break;
11398 #endif
11399 case M16_OPC_LB:
11400 gen_ld(ctx, OPC_LB, ry, rx, offset);
11401 break;
11402 case M16_OPC_LH:
11403 gen_ld(ctx, OPC_LH, ry, rx, offset);
11404 break;
11405 case M16_OPC_LWSP:
11406 gen_ld(ctx, OPC_LW, rx, 29, offset);
11407 break;
11408 case M16_OPC_LW:
11409 gen_ld(ctx, OPC_LW, ry, rx, offset);
11410 break;
11411 case M16_OPC_LBU:
11412 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11413 break;
11414 case M16_OPC_LHU:
11415 gen_ld(ctx, OPC_LHU, ry, rx, offset);
11416 break;
11417 case M16_OPC_LWPC:
11418 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11419 break;
11420 #if defined(TARGET_MIPS64)
11421 case M16_OPC_LWU:
11422 check_insn(ctx, ISA_MIPS3);
11423 check_mips_64(ctx);
11424 gen_ld(ctx, OPC_LWU, ry, rx, offset);
11425 break;
11426 #endif
11427 case M16_OPC_SB:
11428 gen_st(ctx, OPC_SB, ry, rx, offset);
11429 break;
11430 case M16_OPC_SH:
11431 gen_st(ctx, OPC_SH, ry, rx, offset);
11432 break;
11433 case M16_OPC_SWSP:
11434 gen_st(ctx, OPC_SW, rx, 29, offset);
11435 break;
11436 case M16_OPC_SW:
11437 gen_st(ctx, OPC_SW, ry, rx, offset);
11438 break;
11439 #if defined(TARGET_MIPS64)
11440 case M16_OPC_I64:
11441 decode_i64_mips16(ctx, ry, funct, offset, 1);
11442 break;
11443 #endif
11444 default:
11445 generate_exception_end(ctx, EXCP_RI);
11446 break;
11447 }
11448
11449 return 4;
11450 }
11451
11452 static inline bool is_uhi(int sdbbp_code)
11453 {
11454 #ifdef CONFIG_USER_ONLY
11455 return false;
11456 #else
11457 return semihosting_enabled() && sdbbp_code == 1;
11458 #endif
11459 }
11460
11461 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11462 {
11463 int rx, ry;
11464 int sa;
11465 int op, cnvt_op, op1, offset;
11466 int funct;
11467 int n_bytes;
11468
11469 op = (ctx->opcode >> 11) & 0x1f;
11470 sa = (ctx->opcode >> 2) & 0x7;
11471 sa = sa == 0 ? 8 : sa;
11472 rx = xlat((ctx->opcode >> 8) & 0x7);
11473 cnvt_op = (ctx->opcode >> 5) & 0x7;
11474 ry = xlat((ctx->opcode >> 5) & 0x7);
11475 op1 = offset = ctx->opcode & 0x1f;
11476
11477 n_bytes = 2;
11478
11479 switch (op) {
11480 case M16_OPC_ADDIUSP:
11481 {
11482 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11483
11484 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11485 }
11486 break;
11487 case M16_OPC_ADDIUPC:
11488 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11489 break;
11490 case M16_OPC_B:
11491 offset = (ctx->opcode & 0x7ff) << 1;
11492 offset = (int16_t)(offset << 4) >> 4;
11493 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11494 /* No delay slot, so just process as a normal instruction */
11495 break;
11496 case M16_OPC_JAL:
11497 offset = cpu_lduw_code(env, ctx->pc + 2);
11498 offset = (((ctx->opcode & 0x1f) << 21)
11499 | ((ctx->opcode >> 5) & 0x1f) << 16
11500 | offset) << 2;
11501 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11502 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11503 n_bytes = 4;
11504 break;
11505 case M16_OPC_BEQZ:
11506 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11507 ((int8_t)ctx->opcode) << 1, 0);
11508 /* No delay slot, so just process as a normal instruction */
11509 break;
11510 case M16_OPC_BNEQZ:
11511 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11512 ((int8_t)ctx->opcode) << 1, 0);
11513 /* No delay slot, so just process as a normal instruction */
11514 break;
11515 case M16_OPC_SHIFT:
11516 switch (ctx->opcode & 0x3) {
11517 case 0x0:
11518 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11519 break;
11520 case 0x1:
11521 #if defined(TARGET_MIPS64)
11522 check_insn(ctx, ISA_MIPS3);
11523 check_mips_64(ctx);
11524 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11525 #else
11526 generate_exception_end(ctx, EXCP_RI);
11527 #endif
11528 break;
11529 case 0x2:
11530 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11531 break;
11532 case 0x3:
11533 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11534 break;
11535 }
11536 break;
11537 #if defined(TARGET_MIPS64)
11538 case M16_OPC_LD:
11539 check_insn(ctx, ISA_MIPS3);
11540 check_mips_64(ctx);
11541 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11542 break;
11543 #endif
11544 case M16_OPC_RRIA:
11545 {
11546 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11547
11548 if ((ctx->opcode >> 4) & 1) {
11549 #if defined(TARGET_MIPS64)
11550 check_insn(ctx, ISA_MIPS3);
11551 check_mips_64(ctx);
11552 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11553 #else
11554 generate_exception_end(ctx, EXCP_RI);
11555 #endif
11556 } else {
11557 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11558 }
11559 }
11560 break;
11561 case M16_OPC_ADDIU8:
11562 {
11563 int16_t imm = (int8_t) ctx->opcode;
11564
11565 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11566 }
11567 break;
11568 case M16_OPC_SLTI:
11569 {
11570 int16_t imm = (uint8_t) ctx->opcode;
11571 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11572 }
11573 break;
11574 case M16_OPC_SLTIU:
11575 {
11576 int16_t imm = (uint8_t) ctx->opcode;
11577 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11578 }
11579 break;
11580 case M16_OPC_I8:
11581 {
11582 int reg32;
11583
11584 funct = (ctx->opcode >> 8) & 0x7;
11585 switch (funct) {
11586 case I8_BTEQZ:
11587 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11588 ((int8_t)ctx->opcode) << 1, 0);
11589 break;
11590 case I8_BTNEZ:
11591 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11592 ((int8_t)ctx->opcode) << 1, 0);
11593 break;
11594 case I8_SWRASP:
11595 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11596 break;
11597 case I8_ADJSP:
11598 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11599 ((int8_t)ctx->opcode) << 3);
11600 break;
11601 case I8_SVRS:
11602 check_insn(ctx, ISA_MIPS32);
11603 {
11604 int do_ra = ctx->opcode & (1 << 6);
11605 int do_s0 = ctx->opcode & (1 << 5);
11606 int do_s1 = ctx->opcode & (1 << 4);
11607 int framesize = ctx->opcode & 0xf;
11608
11609 if (framesize == 0) {
11610 framesize = 128;
11611 } else {
11612 framesize = framesize << 3;
11613 }
11614
11615 if (ctx->opcode & (1 << 7)) {
11616 gen_mips16_save(ctx, 0, 0,
11617 do_ra, do_s0, do_s1, framesize);
11618 } else {
11619 gen_mips16_restore(ctx, 0, 0,
11620 do_ra, do_s0, do_s1, framesize);
11621 }
11622 }
11623 break;
11624 case I8_MOV32R:
11625 {
11626 int rz = xlat(ctx->opcode & 0x7);
11627
11628 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11629 ((ctx->opcode >> 5) & 0x7);
11630 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11631 }
11632 break;
11633 case I8_MOVR32:
11634 reg32 = ctx->opcode & 0x1f;
11635 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11636 break;
11637 default:
11638 generate_exception_end(ctx, EXCP_RI);
11639 break;
11640 }
11641 }
11642 break;
11643 case M16_OPC_LI:
11644 {
11645 int16_t imm = (uint8_t) ctx->opcode;
11646
11647 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11648 }
11649 break;
11650 case M16_OPC_CMPI:
11651 {
11652 int16_t imm = (uint8_t) ctx->opcode;
11653 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11654 }
11655 break;
11656 #if defined(TARGET_MIPS64)
11657 case M16_OPC_SD:
11658 check_insn(ctx, ISA_MIPS3);
11659 check_mips_64(ctx);
11660 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11661 break;
11662 #endif
11663 case M16_OPC_LB:
11664 gen_ld(ctx, OPC_LB, ry, rx, offset);
11665 break;
11666 case M16_OPC_LH:
11667 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11668 break;
11669 case M16_OPC_LWSP:
11670 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11671 break;
11672 case M16_OPC_LW:
11673 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11674 break;
11675 case M16_OPC_LBU:
11676 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11677 break;
11678 case M16_OPC_LHU:
11679 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11680 break;
11681 case M16_OPC_LWPC:
11682 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11683 break;
11684 #if defined (TARGET_MIPS64)
11685 case M16_OPC_LWU:
11686 check_insn(ctx, ISA_MIPS3);
11687 check_mips_64(ctx);
11688 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11689 break;
11690 #endif
11691 case M16_OPC_SB:
11692 gen_st(ctx, OPC_SB, ry, rx, offset);
11693 break;
11694 case M16_OPC_SH:
11695 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11696 break;
11697 case M16_OPC_SWSP:
11698 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11699 break;
11700 case M16_OPC_SW:
11701 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11702 break;
11703 case M16_OPC_RRR:
11704 {
11705 int rz = xlat((ctx->opcode >> 2) & 0x7);
11706 int mips32_op;
11707
11708 switch (ctx->opcode & 0x3) {
11709 case RRR_ADDU:
11710 mips32_op = OPC_ADDU;
11711 break;
11712 case RRR_SUBU:
11713 mips32_op = OPC_SUBU;
11714 break;
11715 #if defined(TARGET_MIPS64)
11716 case RRR_DADDU:
11717 mips32_op = OPC_DADDU;
11718 check_insn(ctx, ISA_MIPS3);
11719 check_mips_64(ctx);
11720 break;
11721 case RRR_DSUBU:
11722 mips32_op = OPC_DSUBU;
11723 check_insn(ctx, ISA_MIPS3);
11724 check_mips_64(ctx);
11725 break;
11726 #endif
11727 default:
11728 generate_exception_end(ctx, EXCP_RI);
11729 goto done;
11730 }
11731
11732 gen_arith(ctx, mips32_op, rz, rx, ry);
11733 done:
11734 ;
11735 }
11736 break;
11737 case M16_OPC_RR:
11738 switch (op1) {
11739 case RR_JR:
11740 {
11741 int nd = (ctx->opcode >> 7) & 0x1;
11742 int link = (ctx->opcode >> 6) & 0x1;
11743 int ra = (ctx->opcode >> 5) & 0x1;
11744
11745 if (nd) {
11746 check_insn(ctx, ISA_MIPS32);
11747 }
11748
11749 if (link) {
11750 op = OPC_JALR;
11751 } else {
11752 op = OPC_JR;
11753 }
11754
11755 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11756 (nd ? 0 : 2));
11757 }
11758 break;
11759 case RR_SDBBP:
11760 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11761 gen_helper_do_semihosting(cpu_env);
11762 } else {
11763 /* XXX: not clear which exception should be raised
11764 * when in debug mode...
11765 */
11766 check_insn(ctx, ISA_MIPS32);
11767 generate_exception_end(ctx, EXCP_DBp);
11768 }
11769 break;
11770 case RR_SLT:
11771 gen_slt(ctx, OPC_SLT, 24, rx, ry);
11772 break;
11773 case RR_SLTU:
11774 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11775 break;
11776 case RR_BREAK:
11777 generate_exception_end(ctx, EXCP_BREAK);
11778 break;
11779 case RR_SLLV:
11780 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11781 break;
11782 case RR_SRLV:
11783 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11784 break;
11785 case RR_SRAV:
11786 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11787 break;
11788 #if defined (TARGET_MIPS64)
11789 case RR_DSRL:
11790 check_insn(ctx, ISA_MIPS3);
11791 check_mips_64(ctx);
11792 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11793 break;
11794 #endif
11795 case RR_CMP:
11796 gen_logic(ctx, OPC_XOR, 24, rx, ry);
11797 break;
11798 case RR_NEG:
11799 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11800 break;
11801 case RR_AND:
11802 gen_logic(ctx, OPC_AND, rx, rx, ry);
11803 break;
11804 case RR_OR:
11805 gen_logic(ctx, OPC_OR, rx, rx, ry);
11806 break;
11807 case RR_XOR:
11808 gen_logic(ctx, OPC_XOR, rx, rx, ry);
11809 break;
11810 case RR_NOT:
11811 gen_logic(ctx, OPC_NOR, rx, ry, 0);
11812 break;
11813 case RR_MFHI:
11814 gen_HILO(ctx, OPC_MFHI, 0, rx);
11815 break;
11816 case RR_CNVT:
11817 check_insn(ctx, ISA_MIPS32);
11818 switch (cnvt_op) {
11819 case RR_RY_CNVT_ZEB:
11820 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11821 break;
11822 case RR_RY_CNVT_ZEH:
11823 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11824 break;
11825 case RR_RY_CNVT_SEB:
11826 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11827 break;
11828 case RR_RY_CNVT_SEH:
11829 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11830 break;
11831 #if defined (TARGET_MIPS64)
11832 case RR_RY_CNVT_ZEW:
11833 check_insn(ctx, ISA_MIPS64);
11834 check_mips_64(ctx);
11835 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11836 break;
11837 case RR_RY_CNVT_SEW:
11838 check_insn(ctx, ISA_MIPS64);
11839 check_mips_64(ctx);
11840 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11841 break;
11842 #endif
11843 default:
11844 generate_exception_end(ctx, EXCP_RI);
11845 break;
11846 }
11847 break;
11848 case RR_MFLO:
11849 gen_HILO(ctx, OPC_MFLO, 0, rx);
11850 break;
11851 #if defined (TARGET_MIPS64)
11852 case RR_DSRA:
11853 check_insn(ctx, ISA_MIPS3);
11854 check_mips_64(ctx);
11855 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
11856 break;
11857 case RR_DSLLV:
11858 check_insn(ctx, ISA_MIPS3);
11859 check_mips_64(ctx);
11860 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
11861 break;
11862 case RR_DSRLV:
11863 check_insn(ctx, ISA_MIPS3);
11864 check_mips_64(ctx);
11865 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
11866 break;
11867 case RR_DSRAV:
11868 check_insn(ctx, ISA_MIPS3);
11869 check_mips_64(ctx);
11870 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
11871 break;
11872 #endif
11873 case RR_MULT:
11874 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
11875 break;
11876 case RR_MULTU:
11877 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
11878 break;
11879 case RR_DIV:
11880 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
11881 break;
11882 case RR_DIVU:
11883 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
11884 break;
11885 #if defined (TARGET_MIPS64)
11886 case RR_DMULT:
11887 check_insn(ctx, ISA_MIPS3);
11888 check_mips_64(ctx);
11889 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
11890 break;
11891 case RR_DMULTU:
11892 check_insn(ctx, ISA_MIPS3);
11893 check_mips_64(ctx);
11894 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
11895 break;
11896 case RR_DDIV:
11897 check_insn(ctx, ISA_MIPS3);
11898 check_mips_64(ctx);
11899 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
11900 break;
11901 case RR_DDIVU:
11902 check_insn(ctx, ISA_MIPS3);
11903 check_mips_64(ctx);
11904 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
11905 break;
11906 #endif
11907 default:
11908 generate_exception_end(ctx, EXCP_RI);
11909 break;
11910 }
11911 break;
11912 case M16_OPC_EXTEND:
11913 decode_extended_mips16_opc(env, ctx);
11914 n_bytes = 4;
11915 break;
11916 #if defined(TARGET_MIPS64)
11917 case M16_OPC_I64:
11918 funct = (ctx->opcode >> 8) & 0x7;
11919 decode_i64_mips16(ctx, ry, funct, offset, 0);
11920 break;
11921 #endif
11922 default:
11923 generate_exception_end(ctx, EXCP_RI);
11924 break;
11925 }
11926
11927 return n_bytes;
11928 }
11929
11930 /* microMIPS extension to MIPS32/MIPS64 */
11931
11932 /*
11933 * microMIPS32/microMIPS64 major opcodes
11934 *
11935 * 1. MIPS Architecture for Programmers Volume II-B:
11936 * The microMIPS32 Instruction Set (Revision 3.05)
11937 *
11938 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11939 *
11940 * 2. MIPS Architecture For Programmers Volume II-A:
11941 * The MIPS64 Instruction Set (Revision 3.51)
11942 */
11943
11944 enum {
11945 POOL32A = 0x00,
11946 POOL16A = 0x01,
11947 LBU16 = 0x02,
11948 MOVE16 = 0x03,
11949 ADDI32 = 0x04,
11950 R6_LUI = 0x04,
11951 AUI = 0x04,
11952 LBU32 = 0x05,
11953 SB32 = 0x06,
11954 LB32 = 0x07,
11955
11956 POOL32B = 0x08,
11957 POOL16B = 0x09,
11958 LHU16 = 0x0a,
11959 ANDI16 = 0x0b,
11960 ADDIU32 = 0x0c,
11961 LHU32 = 0x0d,
11962 SH32 = 0x0e,
11963 LH32 = 0x0f,
11964
11965 POOL32I = 0x10,
11966 POOL16C = 0x11,
11967 LWSP16 = 0x12,
11968 POOL16D = 0x13,
11969 ORI32 = 0x14,
11970 POOL32F = 0x15,
11971 POOL32S = 0x16, /* MIPS64 */
11972 DADDIU32 = 0x17, /* MIPS64 */
11973
11974 POOL32C = 0x18,
11975 LWGP16 = 0x19,
11976 LW16 = 0x1a,
11977 POOL16E = 0x1b,
11978 XORI32 = 0x1c,
11979 JALS32 = 0x1d,
11980 BOVC = 0x1d,
11981 BEQC = 0x1d,
11982 BEQZALC = 0x1d,
11983 ADDIUPC = 0x1e,
11984 PCREL = 0x1e,
11985 BNVC = 0x1f,
11986 BNEC = 0x1f,
11987 BNEZALC = 0x1f,
11988
11989 R6_BEQZC = 0x20,
11990 JIC = 0x20,
11991 POOL16F = 0x21,
11992 SB16 = 0x22,
11993 BEQZ16 = 0x23,
11994 BEQZC16 = 0x23,
11995 SLTI32 = 0x24,
11996 BEQ32 = 0x25,
11997 BC = 0x25,
11998 SWC132 = 0x26,
11999 LWC132 = 0x27,
12000
12001 /* 0x29 is reserved */
12002 RES_29 = 0x29,
12003 R6_BNEZC = 0x28,
12004 JIALC = 0x28,
12005 SH16 = 0x2a,
12006 BNEZ16 = 0x2b,
12007 BNEZC16 = 0x2b,
12008 SLTIU32 = 0x2c,
12009 BNE32 = 0x2d,
12010 BALC = 0x2d,
12011 SDC132 = 0x2e,
12012 LDC132 = 0x2f,
12013
12014 /* 0x31 is reserved */
12015 RES_31 = 0x31,
12016 BLEZALC = 0x30,
12017 BGEZALC = 0x30,
12018 BGEUC = 0x30,
12019 SWSP16 = 0x32,
12020 B16 = 0x33,
12021 BC16 = 0x33,
12022 ANDI32 = 0x34,
12023 J32 = 0x35,
12024 BGTZC = 0x35,
12025 BLTZC = 0x35,
12026 BLTC = 0x35,
12027 SD32 = 0x36, /* MIPS64 */
12028 LD32 = 0x37, /* MIPS64 */
12029
12030 /* 0x39 is reserved */
12031 RES_39 = 0x39,
12032 BGTZALC = 0x38,
12033 BLTZALC = 0x38,
12034 BLTUC = 0x38,
12035 SW16 = 0x3a,
12036 LI16 = 0x3b,
12037 JALX32 = 0x3c,
12038 JAL32 = 0x3d,
12039 BLEZC = 0x3d,
12040 BGEZC = 0x3d,
12041 BGEC = 0x3d,
12042 SW32 = 0x3e,
12043 LW32 = 0x3f
12044 };
12045
12046 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12047 enum {
12048 ADDIUPC_00 = 0x00,
12049 ADDIUPC_07 = 0x07,
12050 AUIPC = 0x1e,
12051 ALUIPC = 0x1f,
12052 LWPC_08 = 0x08,
12053 LWPC_0F = 0x0F,
12054 };
12055
12056 /* POOL32A encoding of minor opcode field */
12057
12058 enum {
12059 /* These opcodes are distinguished only by bits 9..6; those bits are
12060 * what are recorded below. */
12061 SLL32 = 0x0,
12062 SRL32 = 0x1,
12063 SRA = 0x2,
12064 ROTR = 0x3,
12065 SELEQZ = 0x5,
12066 SELNEZ = 0x6,
12067 R6_RDHWR = 0x7,
12068
12069 SLLV = 0x0,
12070 SRLV = 0x1,
12071 SRAV = 0x2,
12072 ROTRV = 0x3,
12073 ADD = 0x4,
12074 ADDU32 = 0x5,
12075 SUB = 0x6,
12076 SUBU32 = 0x7,
12077 MUL = 0x8,
12078 AND = 0x9,
12079 OR32 = 0xa,
12080 NOR = 0xb,
12081 XOR32 = 0xc,
12082 SLT = 0xd,
12083 SLTU = 0xe,
12084
12085 MOVN = 0x0,
12086 R6_MUL = 0x0,
12087 MOVZ = 0x1,
12088 MUH = 0x1,
12089 MULU = 0x2,
12090 MUHU = 0x3,
12091 LWXS = 0x4,
12092 R6_DIV = 0x4,
12093 MOD = 0x5,
12094 R6_DIVU = 0x6,
12095 MODU = 0x7,
12096
12097 /* The following can be distinguished by their lower 6 bits. */
12098 BREAK32 = 0x07,
12099 INS = 0x0c,
12100 LSA = 0x0f,
12101 ALIGN = 0x1f,
12102 EXT = 0x2c,
12103 POOL32AXF = 0x3c,
12104 SIGRIE = 0x3f
12105 };
12106
12107 /* POOL32AXF encoding of minor opcode field extension */
12108
12109 /*
12110 * 1. MIPS Architecture for Programmers Volume II-B:
12111 * The microMIPS32 Instruction Set (Revision 3.05)
12112 *
12113 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12114 *
12115 * 2. MIPS Architecture for Programmers VolumeIV-e:
12116 * The MIPS DSP Application-Specific Extension
12117 * to the microMIPS32 Architecture (Revision 2.34)
12118 *
12119 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12120 */
12121
12122 enum {
12123 /* bits 11..6 */
12124 TEQ = 0x00,
12125 TGE = 0x08,
12126 TGEU = 0x10,
12127 TLT = 0x20,
12128 TLTU = 0x28,
12129 TNE = 0x30,
12130
12131 MFC0 = 0x03,
12132 MTC0 = 0x0b,
12133
12134 /* begin of microMIPS32 DSP */
12135
12136 /* bits 13..12 for 0x01 */
12137 MFHI_ACC = 0x0,
12138 MFLO_ACC = 0x1,
12139 MTHI_ACC = 0x2,
12140 MTLO_ACC = 0x3,
12141
12142 /* bits 13..12 for 0x2a */
12143 MADD_ACC = 0x0,
12144 MADDU_ACC = 0x1,
12145 MSUB_ACC = 0x2,
12146 MSUBU_ACC = 0x3,
12147
12148 /* bits 13..12 for 0x32 */
12149 MULT_ACC = 0x0,
12150 MULTU_ACC = 0x1,
12151
12152 /* end of microMIPS32 DSP */
12153
12154 /* bits 15..12 for 0x2c */
12155 BITSWAP = 0x0,
12156 SEB = 0x2,
12157 SEH = 0x3,
12158 CLO = 0x4,
12159 CLZ = 0x5,
12160 RDHWR = 0x6,
12161 WSBH = 0x7,
12162 MULT = 0x8,
12163 MULTU = 0x9,
12164 DIV = 0xa,
12165 DIVU = 0xb,
12166 MADD = 0xc,
12167 MADDU = 0xd,
12168 MSUB = 0xe,
12169 MSUBU = 0xf,
12170
12171 /* bits 15..12 for 0x34 */
12172 MFC2 = 0x4,
12173 MTC2 = 0x5,
12174 MFHC2 = 0x8,
12175 MTHC2 = 0x9,
12176 CFC2 = 0xc,
12177 CTC2 = 0xd,
12178
12179 /* bits 15..12 for 0x3c */
12180 JALR = 0x0,
12181 JR = 0x0, /* alias */
12182 JALRC = 0x0,
12183 JRC = 0x0,
12184 JALR_HB = 0x1,
12185 JALRC_HB = 0x1,
12186 JALRS = 0x4,
12187 JALRS_HB = 0x5,
12188
12189 /* bits 15..12 for 0x05 */
12190 RDPGPR = 0xe,
12191 WRPGPR = 0xf,
12192
12193 /* bits 15..12 for 0x0d */
12194 TLBP = 0x0,
12195 TLBR = 0x1,
12196 TLBWI = 0x2,
12197 TLBWR = 0x3,
12198 TLBINV = 0x4,
12199 TLBINVF = 0x5,
12200 WAIT = 0x9,
12201 IRET = 0xd,
12202 DERET = 0xe,
12203 ERET = 0xf,
12204
12205 /* bits 15..12 for 0x15 */
12206 DMT = 0x0,
12207 DVPE = 0x1,
12208 EMT = 0x2,
12209 EVPE = 0x3,
12210
12211 /* bits 15..12 for 0x1d */
12212 DI = 0x4,
12213 EI = 0x5,
12214
12215 /* bits 15..12 for 0x2d */
12216 SYNC = 0x6,
12217 SYSCALL = 0x8,
12218 SDBBP = 0xd,
12219
12220 /* bits 15..12 for 0x35 */
12221 MFHI32 = 0x0,
12222 MFLO32 = 0x1,
12223 MTHI32 = 0x2,
12224 MTLO32 = 0x3,
12225 };
12226
12227 /* POOL32B encoding of minor opcode field (bits 15..12) */
12228
12229 enum {
12230 LWC2 = 0x0,
12231 LWP = 0x1,
12232 LDP = 0x4,
12233 LWM32 = 0x5,
12234 CACHE = 0x6,
12235 LDM = 0x7,
12236 SWC2 = 0x8,
12237 SWP = 0x9,
12238 SDP = 0xc,
12239 SWM32 = 0xd,
12240 SDM = 0xf
12241 };
12242
12243 /* POOL32C encoding of minor opcode field (bits 15..12) */
12244
12245 enum {
12246 LWL = 0x0,
12247 SWL = 0x8,
12248 LWR = 0x1,
12249 SWR = 0x9,
12250 PREF = 0x2,
12251 /* 0xa is reserved */
12252 LL = 0x3,
12253 SC = 0xb,
12254 LDL = 0x4,
12255 SDL = 0xc,
12256 LDR = 0x5,
12257 SDR = 0xd,
12258 /* 0x6 is reserved */
12259 LWU = 0xe,
12260 LLD = 0x7,
12261 SCD = 0xf
12262 };
12263
12264 /* POOL32F encoding of minor opcode field (bits 5..0) */
12265
12266 enum {
12267 /* These are the bit 7..6 values */
12268 ADD_FMT = 0x0,
12269
12270 SUB_FMT = 0x1,
12271
12272 MUL_FMT = 0x2,
12273
12274 DIV_FMT = 0x3,
12275
12276 /* These are the bit 8..6 values */
12277 MOVN_FMT = 0x0,
12278 RSQRT2_FMT = 0x0,
12279 MOVF_FMT = 0x0,
12280 RINT_FMT = 0x0,
12281 SELNEZ_FMT = 0x0,
12282
12283 MOVZ_FMT = 0x1,
12284 LWXC1 = 0x1,
12285 MOVT_FMT = 0x1,
12286 CLASS_FMT = 0x1,
12287 SELEQZ_FMT = 0x1,
12288
12289 PLL_PS = 0x2,
12290 SWXC1 = 0x2,
12291 SEL_FMT = 0x2,
12292
12293 PLU_PS = 0x3,
12294 LDXC1 = 0x3,
12295
12296 MOVN_FMT_04 = 0x4,
12297 PUL_PS = 0x4,
12298 SDXC1 = 0x4,
12299 RECIP2_FMT = 0x4,
12300
12301 MOVZ_FMT_05 = 0x05,
12302 PUU_PS = 0x5,
12303 LUXC1 = 0x5,
12304
12305 CVT_PS_S = 0x6,
12306 SUXC1 = 0x6,
12307 ADDR_PS = 0x6,
12308 PREFX = 0x6,
12309 MADDF_FMT = 0x6,
12310
12311 MULR_PS = 0x7,
12312 MSUBF_FMT = 0x7,
12313
12314 MADD_S = 0x01,
12315 MADD_D = 0x09,
12316 MADD_PS = 0x11,
12317 ALNV_PS = 0x19,
12318 MSUB_S = 0x21,
12319 MSUB_D = 0x29,
12320 MSUB_PS = 0x31,
12321
12322 NMADD_S = 0x02,
12323 NMADD_D = 0x0a,
12324 NMADD_PS = 0x12,
12325 NMSUB_S = 0x22,
12326 NMSUB_D = 0x2a,
12327 NMSUB_PS = 0x32,
12328
12329 MIN_FMT = 0x3,
12330 MAX_FMT = 0xb,
12331 MINA_FMT = 0x23,
12332 MAXA_FMT = 0x2b,
12333 POOL32FXF = 0x3b,
12334
12335 CABS_COND_FMT = 0x1c, /* MIPS3D */
12336 C_COND_FMT = 0x3c,
12337
12338 CMP_CONDN_S = 0x5,
12339 CMP_CONDN_D = 0x15
12340 };
12341
12342 /* POOL32Fxf encoding of minor opcode extension field */
12343
12344 enum {
12345 CVT_L = 0x04,
12346 RSQRT_FMT = 0x08,
12347 FLOOR_L = 0x0c,
12348 CVT_PW_PS = 0x1c,
12349 CVT_W = 0x24,
12350 SQRT_FMT = 0x28,
12351 FLOOR_W = 0x2c,
12352 CVT_PS_PW = 0x3c,
12353 CFC1 = 0x40,
12354 RECIP_FMT = 0x48,
12355 CEIL_L = 0x4c,
12356 CTC1 = 0x60,
12357 CEIL_W = 0x6c,
12358 MFC1 = 0x80,
12359 CVT_S_PL = 0x84,
12360 TRUNC_L = 0x8c,
12361 MTC1 = 0xa0,
12362 CVT_S_PU = 0xa4,
12363 TRUNC_W = 0xac,
12364 MFHC1 = 0xc0,
12365 ROUND_L = 0xcc,
12366 MTHC1 = 0xe0,
12367 ROUND_W = 0xec,
12368
12369 MOV_FMT = 0x01,
12370 MOVF = 0x05,
12371 ABS_FMT = 0x0d,
12372 RSQRT1_FMT = 0x1d,
12373 MOVT = 0x25,
12374 NEG_FMT = 0x2d,
12375 CVT_D = 0x4d,
12376 RECIP1_FMT = 0x5d,
12377 CVT_S = 0x6d
12378 };
12379
12380 /* POOL32I encoding of minor opcode field (bits 25..21) */
12381
12382 enum {
12383 BLTZ = 0x00,
12384 BLTZAL = 0x01,
12385 BGEZ = 0x02,
12386 BGEZAL = 0x03,
12387 BLEZ = 0x04,
12388 BNEZC = 0x05,
12389 BGTZ = 0x06,
12390 BEQZC = 0x07,
12391 TLTI = 0x08,
12392 BC1EQZC = 0x08,
12393 TGEI = 0x09,
12394 BC1NEZC = 0x09,
12395 TLTIU = 0x0a,
12396 BC2EQZC = 0x0a,
12397 TGEIU = 0x0b,
12398 BC2NEZC = 0x0a,
12399 TNEI = 0x0c,
12400 R6_SYNCI = 0x0c,
12401 LUI = 0x0d,
12402 TEQI = 0x0e,
12403 SYNCI = 0x10,
12404 BLTZALS = 0x11,
12405 BGEZALS = 0x13,
12406 BC2F = 0x14,
12407 BC2T = 0x15,
12408 BPOSGE64 = 0x1a,
12409 BPOSGE32 = 0x1b,
12410 /* These overlap and are distinguished by bit16 of the instruction */
12411 BC1F = 0x1c,
12412 BC1T = 0x1d,
12413 BC1ANY2F = 0x1c,
12414 BC1ANY2T = 0x1d,
12415 BC1ANY4F = 0x1e,
12416 BC1ANY4T = 0x1f
12417 };
12418
12419 /* POOL16A encoding of minor opcode field */
12420
12421 enum {
12422 ADDU16 = 0x0,
12423 SUBU16 = 0x1
12424 };
12425
12426 /* POOL16B encoding of minor opcode field */
12427
12428 enum {
12429 SLL16 = 0x0,
12430 SRL16 = 0x1
12431 };
12432
12433 /* POOL16C encoding of minor opcode field */
12434
12435 enum {
12436 NOT16 = 0x00,
12437 XOR16 = 0x04,
12438 AND16 = 0x08,
12439 OR16 = 0x0c,
12440 LWM16 = 0x10,
12441 SWM16 = 0x14,
12442 JR16 = 0x18,
12443 JRC16 = 0x1a,
12444 JALR16 = 0x1c,
12445 JALR16S = 0x1e,
12446 MFHI16 = 0x20,
12447 MFLO16 = 0x24,
12448 BREAK16 = 0x28,
12449 SDBBP16 = 0x2c,
12450 JRADDIUSP = 0x30
12451 };
12452
12453 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12454
12455 enum {
12456 R6_NOT16 = 0x00,
12457 R6_AND16 = 0x01,
12458 R6_LWM16 = 0x02,
12459 R6_JRC16 = 0x03,
12460 MOVEP = 0x04,
12461 MOVEP_07 = 0x07,
12462 R6_XOR16 = 0x08,
12463 R6_OR16 = 0x09,
12464 R6_SWM16 = 0x0a,
12465 JALRC16 = 0x0b,
12466 MOVEP_0C = 0x0c,
12467 MOVEP_0F = 0x0f,
12468 JRCADDIUSP = 0x13,
12469 R6_BREAK16 = 0x1b,
12470 R6_SDBBP16 = 0x3b
12471 };
12472
12473 /* POOL16D encoding of minor opcode field */
12474
12475 enum {
12476 ADDIUS5 = 0x0,
12477 ADDIUSP = 0x1
12478 };
12479
12480 /* POOL16E encoding of minor opcode field */
12481
12482 enum {
12483 ADDIUR2 = 0x0,
12484 ADDIUR1SP = 0x1
12485 };
12486
12487 static int mmreg (int r)
12488 {
12489 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12490
12491 return map[r];
12492 }
12493
12494 /* Used for 16-bit store instructions. */
12495 static int mmreg2 (int r)
12496 {
12497 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12498
12499 return map[r];
12500 }
12501
12502 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12503 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12504 #define uMIPS_RS2(op) uMIPS_RS(op)
12505 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12506 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12507 #define uMIPS_RS5(op) (op & 0x1f)
12508
12509 /* Signed immediate */
12510 #define SIMM(op, start, width) \
12511 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12512 << (32-width)) \
12513 >> (32-width))
12514 /* Zero-extended immediate */
12515 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12516
12517 static void gen_addiur1sp(DisasContext *ctx)
12518 {
12519 int rd = mmreg(uMIPS_RD(ctx->opcode));
12520
12521 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12522 }
12523
12524 static void gen_addiur2(DisasContext *ctx)
12525 {
12526 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12527 int rd = mmreg(uMIPS_RD(ctx->opcode));
12528 int rs = mmreg(uMIPS_RS(ctx->opcode));
12529
12530 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12531 }
12532
12533 static void gen_addiusp(DisasContext *ctx)
12534 {
12535 int encoded = ZIMM(ctx->opcode, 1, 9);
12536 int decoded;
12537
12538 if (encoded <= 1) {
12539 decoded = 256 + encoded;
12540 } else if (encoded <= 255) {
12541 decoded = encoded;
12542 } else if (encoded <= 509) {
12543 decoded = encoded - 512;
12544 } else {
12545 decoded = encoded - 768;
12546 }
12547
12548 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12549 }
12550
12551 static void gen_addius5(DisasContext *ctx)
12552 {
12553 int imm = SIMM(ctx->opcode, 1, 4);
12554 int rd = (ctx->opcode >> 5) & 0x1f;
12555
12556 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12557 }
12558
12559 static void gen_andi16(DisasContext *ctx)
12560 {
12561 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12562 31, 32, 63, 64, 255, 32768, 65535 };
12563 int rd = mmreg(uMIPS_RD(ctx->opcode));
12564 int rs = mmreg(uMIPS_RS(ctx->opcode));
12565 int encoded = ZIMM(ctx->opcode, 0, 4);
12566
12567 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12568 }
12569
12570 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12571 int base, int16_t offset)
12572 {
12573 TCGv t0, t1;
12574 TCGv_i32 t2;
12575
12576 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12577 generate_exception_end(ctx, EXCP_RI);
12578 return;
12579 }
12580
12581 t0 = tcg_temp_new();
12582
12583 gen_base_offset_addr(ctx, t0, base, offset);
12584
12585 t1 = tcg_const_tl(reglist);
12586 t2 = tcg_const_i32(ctx->mem_idx);
12587
12588 save_cpu_state(ctx, 1);
12589 switch (opc) {
12590 case LWM32:
12591 gen_helper_lwm(cpu_env, t0, t1, t2);
12592 break;
12593 case SWM32:
12594 gen_helper_swm(cpu_env, t0, t1, t2);
12595 break;
12596 #ifdef TARGET_MIPS64
12597 case LDM:
12598 gen_helper_ldm(cpu_env, t0, t1, t2);
12599 break;
12600 case SDM:
12601 gen_helper_sdm(cpu_env, t0, t1, t2);
12602 break;
12603 #endif
12604 }
12605 tcg_temp_free(t0);
12606 tcg_temp_free(t1);
12607 tcg_temp_free_i32(t2);
12608 }
12609
12610
12611 static void gen_pool16c_insn(DisasContext *ctx)
12612 {
12613 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12614 int rs = mmreg(ctx->opcode & 0x7);
12615
12616 switch (((ctx->opcode) >> 4) & 0x3f) {
12617 case NOT16 + 0:
12618 case NOT16 + 1:
12619 case NOT16 + 2:
12620 case NOT16 + 3:
12621 gen_logic(ctx, OPC_NOR, rd, rs, 0);
12622 break;
12623 case XOR16 + 0:
12624 case XOR16 + 1:
12625 case XOR16 + 2:
12626 case XOR16 + 3:
12627 gen_logic(ctx, OPC_XOR, rd, rd, rs);
12628 break;
12629 case AND16 + 0:
12630 case AND16 + 1:
12631 case AND16 + 2:
12632 case AND16 + 3:
12633 gen_logic(ctx, OPC_AND, rd, rd, rs);
12634 break;
12635 case OR16 + 0:
12636 case OR16 + 1:
12637 case OR16 + 2:
12638 case OR16 + 3:
12639 gen_logic(ctx, OPC_OR, rd, rd, rs);
12640 break;
12641 case LWM16 + 0:
12642 case LWM16 + 1:
12643 case LWM16 + 2:
12644 case LWM16 + 3:
12645 {
12646 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12647 int offset = ZIMM(ctx->opcode, 0, 4);
12648
12649 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12650 29, offset << 2);
12651 }
12652 break;
12653 case SWM16 + 0:
12654 case SWM16 + 1:
12655 case SWM16 + 2:
12656 case SWM16 + 3:
12657 {
12658 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12659 int offset = ZIMM(ctx->opcode, 0, 4);
12660
12661 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12662 29, offset << 2);
12663 }
12664 break;
12665 case JR16 + 0:
12666 case JR16 + 1:
12667 {
12668 int reg = ctx->opcode & 0x1f;
12669
12670 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12671 }
12672 break;
12673 case JRC16 + 0:
12674 case JRC16 + 1:
12675 {
12676 int reg = ctx->opcode & 0x1f;
12677 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12678 /* Let normal delay slot handling in our caller take us
12679 to the branch target. */
12680 }
12681 break;
12682 case JALR16 + 0:
12683 case JALR16 + 1:
12684 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12685 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12686 break;
12687 case JALR16S + 0:
12688 case JALR16S + 1:
12689 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12690 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12691 break;
12692 case MFHI16 + 0:
12693 case MFHI16 + 1:
12694 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12695 break;
12696 case MFLO16 + 0:
12697 case MFLO16 + 1:
12698 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12699 break;
12700 case BREAK16:
12701 generate_exception_end(ctx, EXCP_BREAK);
12702 break;
12703 case SDBBP16:
12704 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12705 gen_helper_do_semihosting(cpu_env);
12706 } else {
12707 /* XXX: not clear which exception should be raised
12708 * when in debug mode...
12709 */
12710 check_insn(ctx, ISA_MIPS32);
12711 generate_exception_end(ctx, EXCP_DBp);
12712 }
12713 break;
12714 case JRADDIUSP + 0:
12715 case JRADDIUSP + 1:
12716 {
12717 int imm = ZIMM(ctx->opcode, 0, 5);
12718 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12719 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12720 /* Let normal delay slot handling in our caller take us
12721 to the branch target. */
12722 }
12723 break;
12724 default:
12725 generate_exception_end(ctx, EXCP_RI);
12726 break;
12727 }
12728 }
12729
12730 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12731 int enc_rs)
12732 {
12733 int rd, rs, re, rt;
12734 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12735 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12736 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12737 rd = rd_enc[enc_dest];
12738 re = re_enc[enc_dest];
12739 rs = rs_rt_enc[enc_rs];
12740 rt = rs_rt_enc[enc_rt];
12741 if (rs) {
12742 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12743 } else {
12744 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12745 }
12746 if (rt) {
12747 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12748 } else {
12749 tcg_gen_movi_tl(cpu_gpr[re], 0);
12750 }
12751 }
12752
12753 static void gen_pool16c_r6_insn(DisasContext *ctx)
12754 {
12755 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12756 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12757
12758 switch (ctx->opcode & 0xf) {
12759 case R6_NOT16:
12760 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12761 break;
12762 case R6_AND16:
12763 gen_logic(ctx, OPC_AND, rt, rt, rs);
12764 break;
12765 case R6_LWM16:
12766 {
12767 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12768 int offset = extract32(ctx->opcode, 4, 4);
12769 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12770 }
12771 break;
12772 case R6_JRC16: /* JRCADDIUSP */
12773 if ((ctx->opcode >> 4) & 1) {
12774 /* JRCADDIUSP */
12775 int imm = extract32(ctx->opcode, 5, 5);
12776 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12777 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12778 } else {
12779 /* JRC16 */
12780 int rs = extract32(ctx->opcode, 5, 5);
12781 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12782 }
12783 break;
12784 case MOVEP ... MOVEP_07:
12785 case MOVEP_0C ... MOVEP_0F:
12786 {
12787 int enc_dest = uMIPS_RD(ctx->opcode);
12788 int enc_rt = uMIPS_RS2(ctx->opcode);
12789 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12790 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12791 }
12792 break;
12793 case R6_XOR16:
12794 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12795 break;
12796 case R6_OR16:
12797 gen_logic(ctx, OPC_OR, rt, rt, rs);
12798 break;
12799 case R6_SWM16:
12800 {
12801 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12802 int offset = extract32(ctx->opcode, 4, 4);
12803 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12804 }
12805 break;
12806 case JALRC16: /* BREAK16, SDBBP16 */
12807 switch (ctx->opcode & 0x3f) {
12808 case JALRC16:
12809 case JALRC16 + 0x20:
12810 /* JALRC16 */
12811 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
12812 31, 0, 0);
12813 break;
12814 case R6_BREAK16:
12815 /* BREAK16 */
12816 generate_exception(ctx, EXCP_BREAK);
12817 break;
12818 case R6_SDBBP16:
12819 /* SDBBP16 */
12820 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
12821 gen_helper_do_semihosting(cpu_env);
12822 } else {
12823 if (ctx->hflags & MIPS_HFLAG_SBRI) {
12824 generate_exception(ctx, EXCP_RI);
12825 } else {
12826 generate_exception(ctx, EXCP_DBp);
12827 }
12828 }
12829 break;
12830 }
12831 break;
12832 default:
12833 generate_exception(ctx, EXCP_RI);
12834 break;
12835 }
12836 }
12837
12838 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12839 {
12840 TCGv t0 = tcg_temp_new();
12841 TCGv t1 = tcg_temp_new();
12842
12843 gen_load_gpr(t0, base);
12844
12845 if (index != 0) {
12846 gen_load_gpr(t1, index);
12847 tcg_gen_shli_tl(t1, t1, 2);
12848 gen_op_addr_add(ctx, t0, t1, t0);
12849 }
12850
12851 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12852 gen_store_gpr(t1, rd);
12853
12854 tcg_temp_free(t0);
12855 tcg_temp_free(t1);
12856 }
12857
12858 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12859 int base, int16_t offset)
12860 {
12861 TCGv t0, t1;
12862
12863 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
12864 generate_exception_end(ctx, EXCP_RI);
12865 return;
12866 }
12867
12868 t0 = tcg_temp_new();
12869 t1 = tcg_temp_new();
12870
12871 gen_base_offset_addr(ctx, t0, base, offset);
12872
12873 switch (opc) {
12874 case LWP:
12875 if (rd == base) {
12876 generate_exception_end(ctx, EXCP_RI);
12877 return;
12878 }
12879 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12880 gen_store_gpr(t1, rd);
12881 tcg_gen_movi_tl(t1, 4);
12882 gen_op_addr_add(ctx, t0, t0, t1);
12883 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12884 gen_store_gpr(t1, rd+1);
12885 break;
12886 case SWP:
12887 gen_load_gpr(t1, rd);
12888 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12889 tcg_gen_movi_tl(t1, 4);
12890 gen_op_addr_add(ctx, t0, t0, t1);
12891 gen_load_gpr(t1, rd+1);
12892 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12893 break;
12894 #ifdef TARGET_MIPS64
12895 case LDP:
12896 if (rd == base) {
12897 generate_exception_end(ctx, EXCP_RI);
12898 return;
12899 }
12900 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12901 gen_store_gpr(t1, rd);
12902 tcg_gen_movi_tl(t1, 8);
12903 gen_op_addr_add(ctx, t0, t0, t1);
12904 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12905 gen_store_gpr(t1, rd+1);
12906 break;
12907 case SDP:
12908 gen_load_gpr(t1, rd);
12909 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12910 tcg_gen_movi_tl(t1, 8);
12911 gen_op_addr_add(ctx, t0, t0, t1);
12912 gen_load_gpr(t1, rd+1);
12913 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12914 break;
12915 #endif
12916 }
12917 tcg_temp_free(t0);
12918 tcg_temp_free(t1);
12919 }
12920
12921 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
12922 {
12923 int extension = (ctx->opcode >> 6) & 0x3f;
12924 int minor = (ctx->opcode >> 12) & 0xf;
12925 uint32_t mips32_op;
12926
12927 switch (extension) {
12928 case TEQ:
12929 mips32_op = OPC_TEQ;
12930 goto do_trap;
12931 case TGE:
12932 mips32_op = OPC_TGE;
12933 goto do_trap;
12934 case TGEU:
12935 mips32_op = OPC_TGEU;
12936 goto do_trap;
12937 case TLT:
12938 mips32_op = OPC_TLT;
12939 goto do_trap;
12940 case TLTU:
12941 mips32_op = OPC_TLTU;
12942 goto do_trap;
12943 case TNE:
12944 mips32_op = OPC_TNE;
12945 do_trap:
12946 gen_trap(ctx, mips32_op, rs, rt, -1);
12947 break;
12948 #ifndef CONFIG_USER_ONLY
12949 case MFC0:
12950 case MFC0 + 32:
12951 check_cp0_enabled(ctx);
12952 if (rt == 0) {
12953 /* Treat as NOP. */
12954 break;
12955 }
12956 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
12957 break;
12958 case MTC0:
12959 case MTC0 + 32:
12960 check_cp0_enabled(ctx);
12961 {
12962 TCGv t0 = tcg_temp_new();
12963
12964 gen_load_gpr(t0, rt);
12965 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
12966 tcg_temp_free(t0);
12967 }
12968 break;
12969 #endif
12970 case 0x2a:
12971 switch (minor & 3) {
12972 case MADD_ACC:
12973 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12974 break;
12975 case MADDU_ACC:
12976 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12977 break;
12978 case MSUB_ACC:
12979 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12980 break;
12981 case MSUBU_ACC:
12982 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12983 break;
12984 default:
12985 goto pool32axf_invalid;
12986 }
12987 break;
12988 case 0x32:
12989 switch (minor & 3) {
12990 case MULT_ACC:
12991 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12992 break;
12993 case MULTU_ACC:
12994 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12995 break;
12996 default:
12997 goto pool32axf_invalid;
12998 }
12999 break;
13000 case 0x2c:
13001 switch (minor) {
13002 case BITSWAP:
13003 check_insn(ctx, ISA_MIPS32R6);
13004 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
13005 break;
13006 case SEB:
13007 gen_bshfl(ctx, OPC_SEB, rs, rt);
13008 break;
13009 case SEH:
13010 gen_bshfl(ctx, OPC_SEH, rs, rt);
13011 break;
13012 case CLO:
13013 mips32_op = OPC_CLO;
13014 goto do_cl;
13015 case CLZ:
13016 mips32_op = OPC_CLZ;
13017 do_cl:
13018 check_insn(ctx, ISA_MIPS32);
13019 gen_cl(ctx, mips32_op, rt, rs);
13020 break;
13021 case RDHWR:
13022 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13023 gen_rdhwr(ctx, rt, rs, 0);
13024 break;
13025 case WSBH:
13026 gen_bshfl(ctx, OPC_WSBH, rs, rt);
13027 break;
13028 case MULT:
13029 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13030 mips32_op = OPC_MULT;
13031 goto do_mul;
13032 case MULTU:
13033 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13034 mips32_op = OPC_MULTU;
13035 goto do_mul;
13036 case DIV:
13037 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13038 mips32_op = OPC_DIV;
13039 goto do_div;
13040 case DIVU:
13041 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13042 mips32_op = OPC_DIVU;
13043 goto do_div;
13044 do_div:
13045 check_insn(ctx, ISA_MIPS32);
13046 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13047 break;
13048 case MADD:
13049 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13050 mips32_op = OPC_MADD;
13051 goto do_mul;
13052 case MADDU:
13053 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13054 mips32_op = OPC_MADDU;
13055 goto do_mul;
13056 case MSUB:
13057 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13058 mips32_op = OPC_MSUB;
13059 goto do_mul;
13060 case MSUBU:
13061 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13062 mips32_op = OPC_MSUBU;
13063 do_mul:
13064 check_insn(ctx, ISA_MIPS32);
13065 gen_muldiv(ctx, mips32_op, 0, rs, rt);
13066 break;
13067 default:
13068 goto pool32axf_invalid;
13069 }
13070 break;
13071 case 0x34:
13072 switch (minor) {
13073 case MFC2:
13074 case MTC2:
13075 case MFHC2:
13076 case MTHC2:
13077 case CFC2:
13078 case CTC2:
13079 generate_exception_err(ctx, EXCP_CpU, 2);
13080 break;
13081 default:
13082 goto pool32axf_invalid;
13083 }
13084 break;
13085 case 0x3c:
13086 switch (minor) {
13087 case JALR: /* JALRC */
13088 case JALR_HB: /* JALRC_HB */
13089 if (ctx->insn_flags & ISA_MIPS32R6) {
13090 /* JALRC, JALRC_HB */
13091 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13092 } else {
13093 /* JALR, JALR_HB */
13094 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13095 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13096 }
13097 break;
13098 case JALRS:
13099 case JALRS_HB:
13100 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13101 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13102 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13103 break;
13104 default:
13105 goto pool32axf_invalid;
13106 }
13107 break;
13108 case 0x05:
13109 switch (minor) {
13110 case RDPGPR:
13111 check_cp0_enabled(ctx);
13112 check_insn(ctx, ISA_MIPS32R2);
13113 gen_load_srsgpr(rs, rt);
13114 break;
13115 case WRPGPR:
13116 check_cp0_enabled(ctx);
13117 check_insn(ctx, ISA_MIPS32R2);
13118 gen_store_srsgpr(rs, rt);
13119 break;
13120 default:
13121 goto pool32axf_invalid;
13122 }
13123 break;
13124 #ifndef CONFIG_USER_ONLY
13125 case 0x0d:
13126 switch (minor) {
13127 case TLBP:
13128 mips32_op = OPC_TLBP;
13129 goto do_cp0;
13130 case TLBR:
13131 mips32_op = OPC_TLBR;
13132 goto do_cp0;
13133 case TLBWI:
13134 mips32_op = OPC_TLBWI;
13135 goto do_cp0;
13136 case TLBWR:
13137 mips32_op = OPC_TLBWR;
13138 goto do_cp0;
13139 case TLBINV:
13140 mips32_op = OPC_TLBINV;
13141 goto do_cp0;
13142 case TLBINVF:
13143 mips32_op = OPC_TLBINVF;
13144 goto do_cp0;
13145 case WAIT:
13146 mips32_op = OPC_WAIT;
13147 goto do_cp0;
13148 case DERET:
13149 mips32_op = OPC_DERET;
13150 goto do_cp0;
13151 case ERET:
13152 mips32_op = OPC_ERET;
13153 do_cp0:
13154 gen_cp0(env, ctx, mips32_op, rt, rs);
13155 break;
13156 default:
13157 goto pool32axf_invalid;
13158 }
13159 break;
13160 case 0x1d:
13161 switch (minor) {
13162 case DI:
13163 check_cp0_enabled(ctx);
13164 {
13165 TCGv t0 = tcg_temp_new();
13166
13167 save_cpu_state(ctx, 1);
13168 gen_helper_di(t0, cpu_env);
13169 gen_store_gpr(t0, rs);
13170 /* Stop translation as we may have switched the execution mode */
13171 ctx->bstate = BS_STOP;
13172 tcg_temp_free(t0);
13173 }
13174 break;
13175 case EI:
13176 check_cp0_enabled(ctx);
13177 {
13178 TCGv t0 = tcg_temp_new();
13179
13180 save_cpu_state(ctx, 1);
13181 gen_helper_ei(t0, cpu_env);
13182 gen_store_gpr(t0, rs);
13183 /* Stop translation as we may have switched the execution mode */
13184 ctx->bstate = BS_STOP;
13185 tcg_temp_free(t0);
13186 }
13187 break;
13188 default:
13189 goto pool32axf_invalid;
13190 }
13191 break;
13192 #endif
13193 case 0x2d:
13194 switch (minor) {
13195 case SYNC:
13196 /* NOP */
13197 break;
13198 case SYSCALL:
13199 generate_exception_end(ctx, EXCP_SYSCALL);
13200 break;
13201 case SDBBP:
13202 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13203 gen_helper_do_semihosting(cpu_env);
13204 } else {
13205 check_insn(ctx, ISA_MIPS32);
13206 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13207 generate_exception_end(ctx, EXCP_RI);
13208 } else {
13209 generate_exception_end(ctx, EXCP_DBp);
13210 }
13211 }
13212 break;
13213 default:
13214 goto pool32axf_invalid;
13215 }
13216 break;
13217 case 0x01:
13218 switch (minor & 3) {
13219 case MFHI_ACC:
13220 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13221 break;
13222 case MFLO_ACC:
13223 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13224 break;
13225 case MTHI_ACC:
13226 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13227 break;
13228 case MTLO_ACC:
13229 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13230 break;
13231 default:
13232 goto pool32axf_invalid;
13233 }
13234 break;
13235 case 0x35:
13236 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13237 switch (minor) {
13238 case MFHI32:
13239 gen_HILO(ctx, OPC_MFHI, 0, rs);
13240 break;
13241 case MFLO32:
13242 gen_HILO(ctx, OPC_MFLO, 0, rs);
13243 break;
13244 case MTHI32:
13245 gen_HILO(ctx, OPC_MTHI, 0, rs);
13246 break;
13247 case MTLO32:
13248 gen_HILO(ctx, OPC_MTLO, 0, rs);
13249 break;
13250 default:
13251 goto pool32axf_invalid;
13252 }
13253 break;
13254 default:
13255 pool32axf_invalid:
13256 MIPS_INVAL("pool32axf");
13257 generate_exception_end(ctx, EXCP_RI);
13258 break;
13259 }
13260 }
13261
13262 /* Values for microMIPS fmt field. Variable-width, depending on which
13263 formats the instruction supports. */
13264
13265 enum {
13266 FMT_SD_S = 0,
13267 FMT_SD_D = 1,
13268
13269 FMT_SDPS_S = 0,
13270 FMT_SDPS_D = 1,
13271 FMT_SDPS_PS = 2,
13272
13273 FMT_SWL_S = 0,
13274 FMT_SWL_W = 1,
13275 FMT_SWL_L = 2,
13276
13277 FMT_DWL_D = 0,
13278 FMT_DWL_W = 1,
13279 FMT_DWL_L = 2
13280 };
13281
13282 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13283 {
13284 int extension = (ctx->opcode >> 6) & 0x3ff;
13285 uint32_t mips32_op;
13286
13287 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13288 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13289 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13290
13291 switch (extension) {
13292 case FLOAT_1BIT_FMT(CFC1, 0):
13293 mips32_op = OPC_CFC1;
13294 goto do_cp1;
13295 case FLOAT_1BIT_FMT(CTC1, 0):
13296 mips32_op = OPC_CTC1;
13297 goto do_cp1;
13298 case FLOAT_1BIT_FMT(MFC1, 0):
13299 mips32_op = OPC_MFC1;
13300 goto do_cp1;
13301 case FLOAT_1BIT_FMT(MTC1, 0):
13302 mips32_op = OPC_MTC1;
13303 goto do_cp1;
13304 case FLOAT_1BIT_FMT(MFHC1, 0):
13305 mips32_op = OPC_MFHC1;
13306 goto do_cp1;
13307 case FLOAT_1BIT_FMT(MTHC1, 0):
13308 mips32_op = OPC_MTHC1;
13309 do_cp1:
13310 gen_cp1(ctx, mips32_op, rt, rs);
13311 break;
13312
13313 /* Reciprocal square root */
13314 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13315 mips32_op = OPC_RSQRT_S;
13316 goto do_unaryfp;
13317 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13318 mips32_op = OPC_RSQRT_D;
13319 goto do_unaryfp;
13320
13321 /* Square root */
13322 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13323 mips32_op = OPC_SQRT_S;
13324 goto do_unaryfp;
13325 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13326 mips32_op = OPC_SQRT_D;
13327 goto do_unaryfp;
13328
13329 /* Reciprocal */
13330 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13331 mips32_op = OPC_RECIP_S;
13332 goto do_unaryfp;
13333 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13334 mips32_op = OPC_RECIP_D;
13335 goto do_unaryfp;
13336
13337 /* Floor */
13338 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13339 mips32_op = OPC_FLOOR_L_S;
13340 goto do_unaryfp;
13341 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13342 mips32_op = OPC_FLOOR_L_D;
13343 goto do_unaryfp;
13344 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13345 mips32_op = OPC_FLOOR_W_S;
13346 goto do_unaryfp;
13347 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13348 mips32_op = OPC_FLOOR_W_D;
13349 goto do_unaryfp;
13350
13351 /* Ceiling */
13352 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13353 mips32_op = OPC_CEIL_L_S;
13354 goto do_unaryfp;
13355 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13356 mips32_op = OPC_CEIL_L_D;
13357 goto do_unaryfp;
13358 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13359 mips32_op = OPC_CEIL_W_S;
13360 goto do_unaryfp;
13361 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13362 mips32_op = OPC_CEIL_W_D;
13363 goto do_unaryfp;
13364
13365 /* Truncation */
13366 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13367 mips32_op = OPC_TRUNC_L_S;
13368 goto do_unaryfp;
13369 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13370 mips32_op = OPC_TRUNC_L_D;
13371 goto do_unaryfp;
13372 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13373 mips32_op = OPC_TRUNC_W_S;
13374 goto do_unaryfp;
13375 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13376 mips32_op = OPC_TRUNC_W_D;
13377 goto do_unaryfp;
13378
13379 /* Round */
13380 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13381 mips32_op = OPC_ROUND_L_S;
13382 goto do_unaryfp;
13383 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13384 mips32_op = OPC_ROUND_L_D;
13385 goto do_unaryfp;
13386 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13387 mips32_op = OPC_ROUND_W_S;
13388 goto do_unaryfp;
13389 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13390 mips32_op = OPC_ROUND_W_D;
13391 goto do_unaryfp;
13392
13393 /* Integer to floating-point conversion */
13394 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13395 mips32_op = OPC_CVT_L_S;
13396 goto do_unaryfp;
13397 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13398 mips32_op = OPC_CVT_L_D;
13399 goto do_unaryfp;
13400 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13401 mips32_op = OPC_CVT_W_S;
13402 goto do_unaryfp;
13403 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13404 mips32_op = OPC_CVT_W_D;
13405 goto do_unaryfp;
13406
13407 /* Paired-foo conversions */
13408 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13409 mips32_op = OPC_CVT_S_PL;
13410 goto do_unaryfp;
13411 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13412 mips32_op = OPC_CVT_S_PU;
13413 goto do_unaryfp;
13414 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13415 mips32_op = OPC_CVT_PW_PS;
13416 goto do_unaryfp;
13417 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13418 mips32_op = OPC_CVT_PS_PW;
13419 goto do_unaryfp;
13420
13421 /* Floating-point moves */
13422 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13423 mips32_op = OPC_MOV_S;
13424 goto do_unaryfp;
13425 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13426 mips32_op = OPC_MOV_D;
13427 goto do_unaryfp;
13428 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13429 mips32_op = OPC_MOV_PS;
13430 goto do_unaryfp;
13431
13432 /* Absolute value */
13433 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13434 mips32_op = OPC_ABS_S;
13435 goto do_unaryfp;
13436 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13437 mips32_op = OPC_ABS_D;
13438 goto do_unaryfp;
13439 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13440 mips32_op = OPC_ABS_PS;
13441 goto do_unaryfp;
13442
13443 /* Negation */
13444 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13445 mips32_op = OPC_NEG_S;
13446 goto do_unaryfp;
13447 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13448 mips32_op = OPC_NEG_D;
13449 goto do_unaryfp;
13450 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13451 mips32_op = OPC_NEG_PS;
13452 goto do_unaryfp;
13453
13454 /* Reciprocal square root step */
13455 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13456 mips32_op = OPC_RSQRT1_S;
13457 goto do_unaryfp;
13458 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13459 mips32_op = OPC_RSQRT1_D;
13460 goto do_unaryfp;
13461 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13462 mips32_op = OPC_RSQRT1_PS;
13463 goto do_unaryfp;
13464
13465 /* Reciprocal step */
13466 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13467 mips32_op = OPC_RECIP1_S;
13468 goto do_unaryfp;
13469 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13470 mips32_op = OPC_RECIP1_S;
13471 goto do_unaryfp;
13472 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13473 mips32_op = OPC_RECIP1_PS;
13474 goto do_unaryfp;
13475
13476 /* Conversions from double */
13477 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13478 mips32_op = OPC_CVT_D_S;
13479 goto do_unaryfp;
13480 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13481 mips32_op = OPC_CVT_D_W;
13482 goto do_unaryfp;
13483 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13484 mips32_op = OPC_CVT_D_L;
13485 goto do_unaryfp;
13486
13487 /* Conversions from single */
13488 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13489 mips32_op = OPC_CVT_S_D;
13490 goto do_unaryfp;
13491 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13492 mips32_op = OPC_CVT_S_W;
13493 goto do_unaryfp;
13494 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13495 mips32_op = OPC_CVT_S_L;
13496 do_unaryfp:
13497 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13498 break;
13499
13500 /* Conditional moves on floating-point codes */
13501 case COND_FLOAT_MOV(MOVT, 0):
13502 case COND_FLOAT_MOV(MOVT, 1):
13503 case COND_FLOAT_MOV(MOVT, 2):
13504 case COND_FLOAT_MOV(MOVT, 3):
13505 case COND_FLOAT_MOV(MOVT, 4):
13506 case COND_FLOAT_MOV(MOVT, 5):
13507 case COND_FLOAT_MOV(MOVT, 6):
13508 case COND_FLOAT_MOV(MOVT, 7):
13509 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13510 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13511 break;
13512 case COND_FLOAT_MOV(MOVF, 0):
13513 case COND_FLOAT_MOV(MOVF, 1):
13514 case COND_FLOAT_MOV(MOVF, 2):
13515 case COND_FLOAT_MOV(MOVF, 3):
13516 case COND_FLOAT_MOV(MOVF, 4):
13517 case COND_FLOAT_MOV(MOVF, 5):
13518 case COND_FLOAT_MOV(MOVF, 6):
13519 case COND_FLOAT_MOV(MOVF, 7):
13520 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13521 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13522 break;
13523 default:
13524 MIPS_INVAL("pool32fxf");
13525 generate_exception_end(ctx, EXCP_RI);
13526 break;
13527 }
13528 }
13529
13530 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13531 {
13532 int32_t offset;
13533 uint16_t insn;
13534 int rt, rs, rd, rr;
13535 int16_t imm;
13536 uint32_t op, minor, mips32_op;
13537 uint32_t cond, fmt, cc;
13538
13539 insn = cpu_lduw_code(env, ctx->pc + 2);
13540 ctx->opcode = (ctx->opcode << 16) | insn;
13541
13542 rt = (ctx->opcode >> 21) & 0x1f;
13543 rs = (ctx->opcode >> 16) & 0x1f;
13544 rd = (ctx->opcode >> 11) & 0x1f;
13545 rr = (ctx->opcode >> 6) & 0x1f;
13546 imm = (int16_t) ctx->opcode;
13547
13548 op = (ctx->opcode >> 26) & 0x3f;
13549 switch (op) {
13550 case POOL32A:
13551 minor = ctx->opcode & 0x3f;
13552 switch (minor) {
13553 case 0x00:
13554 minor = (ctx->opcode >> 6) & 0xf;
13555 switch (minor) {
13556 case SLL32:
13557 mips32_op = OPC_SLL;
13558 goto do_shifti;
13559 case SRA:
13560 mips32_op = OPC_SRA;
13561 goto do_shifti;
13562 case SRL32:
13563 mips32_op = OPC_SRL;
13564 goto do_shifti;
13565 case ROTR:
13566 mips32_op = OPC_ROTR;
13567 do_shifti:
13568 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13569 break;
13570 case SELEQZ:
13571 check_insn(ctx, ISA_MIPS32R6);
13572 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13573 break;
13574 case SELNEZ:
13575 check_insn(ctx, ISA_MIPS32R6);
13576 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13577 break;
13578 case R6_RDHWR:
13579 check_insn(ctx, ISA_MIPS32R6);
13580 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13581 break;
13582 default:
13583 goto pool32a_invalid;
13584 }
13585 break;
13586 case 0x10:
13587 minor = (ctx->opcode >> 6) & 0xf;
13588 switch (minor) {
13589 /* Arithmetic */
13590 case ADD:
13591 mips32_op = OPC_ADD;
13592 goto do_arith;
13593 case ADDU32:
13594 mips32_op = OPC_ADDU;
13595 goto do_arith;
13596 case SUB:
13597 mips32_op = OPC_SUB;
13598 goto do_arith;
13599 case SUBU32:
13600 mips32_op = OPC_SUBU;
13601 goto do_arith;
13602 case MUL:
13603 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13604 mips32_op = OPC_MUL;
13605 do_arith:
13606 gen_arith(ctx, mips32_op, rd, rs, rt);
13607 break;
13608 /* Shifts */
13609 case SLLV:
13610 mips32_op = OPC_SLLV;
13611 goto do_shift;
13612 case SRLV:
13613 mips32_op = OPC_SRLV;
13614 goto do_shift;
13615 case SRAV:
13616 mips32_op = OPC_SRAV;
13617 goto do_shift;
13618 case ROTRV:
13619 mips32_op = OPC_ROTRV;
13620 do_shift:
13621 gen_shift(ctx, mips32_op, rd, rs, rt);
13622 break;
13623 /* Logical operations */
13624 case AND:
13625 mips32_op = OPC_AND;
13626 goto do_logic;
13627 case OR32:
13628 mips32_op = OPC_OR;
13629 goto do_logic;
13630 case NOR:
13631 mips32_op = OPC_NOR;
13632 goto do_logic;
13633 case XOR32:
13634 mips32_op = OPC_XOR;
13635 do_logic:
13636 gen_logic(ctx, mips32_op, rd, rs, rt);
13637 break;
13638 /* Set less than */
13639 case SLT:
13640 mips32_op = OPC_SLT;
13641 goto do_slt;
13642 case SLTU:
13643 mips32_op = OPC_SLTU;
13644 do_slt:
13645 gen_slt(ctx, mips32_op, rd, rs, rt);
13646 break;
13647 default:
13648 goto pool32a_invalid;
13649 }
13650 break;
13651 case 0x18:
13652 minor = (ctx->opcode >> 6) & 0xf;
13653 switch (minor) {
13654 /* Conditional moves */
13655 case MOVN: /* MUL */
13656 if (ctx->insn_flags & ISA_MIPS32R6) {
13657 /* MUL */
13658 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13659 } else {
13660 /* MOVN */
13661 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13662 }
13663 break;
13664 case MOVZ: /* MUH */
13665 if (ctx->insn_flags & ISA_MIPS32R6) {
13666 /* MUH */
13667 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13668 } else {
13669 /* MOVZ */
13670 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13671 }
13672 break;
13673 case MULU:
13674 check_insn(ctx, ISA_MIPS32R6);
13675 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13676 break;
13677 case MUHU:
13678 check_insn(ctx, ISA_MIPS32R6);
13679 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13680 break;
13681 case LWXS: /* DIV */
13682 if (ctx->insn_flags & ISA_MIPS32R6) {
13683 /* DIV */
13684 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13685 } else {
13686 /* LWXS */
13687 gen_ldxs(ctx, rs, rt, rd);
13688 }
13689 break;
13690 case MOD:
13691 check_insn(ctx, ISA_MIPS32R6);
13692 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13693 break;
13694 case R6_DIVU:
13695 check_insn(ctx, ISA_MIPS32R6);
13696 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
13697 break;
13698 case MODU:
13699 check_insn(ctx, ISA_MIPS32R6);
13700 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
13701 break;
13702 default:
13703 goto pool32a_invalid;
13704 }
13705 break;
13706 case INS:
13707 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13708 return;
13709 case LSA:
13710 check_insn(ctx, ISA_MIPS32R6);
13711 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13712 extract32(ctx->opcode, 9, 2));
13713 break;
13714 case ALIGN:
13715 check_insn(ctx, ISA_MIPS32R6);
13716 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13717 extract32(ctx->opcode, 9, 2));
13718 break;
13719 case EXT:
13720 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13721 return;
13722 case POOL32AXF:
13723 gen_pool32axf(env, ctx, rt, rs);
13724 break;
13725 case BREAK32:
13726 generate_exception_end(ctx, EXCP_BREAK);
13727 break;
13728 case SIGRIE:
13729 check_insn(ctx, ISA_MIPS32R6);
13730 generate_exception_end(ctx, EXCP_RI);
13731 break;
13732 default:
13733 pool32a_invalid:
13734 MIPS_INVAL("pool32a");
13735 generate_exception_end(ctx, EXCP_RI);
13736 break;
13737 }
13738 break;
13739 case POOL32B:
13740 minor = (ctx->opcode >> 12) & 0xf;
13741 switch (minor) {
13742 case CACHE:
13743 check_cp0_enabled(ctx);
13744 /* Treat as no-op. */
13745 break;
13746 case LWC2:
13747 case SWC2:
13748 /* COP2: Not implemented. */
13749 generate_exception_err(ctx, EXCP_CpU, 2);
13750 break;
13751 #ifdef TARGET_MIPS64
13752 case LDP:
13753 case SDP:
13754 check_insn(ctx, ISA_MIPS3);
13755 check_mips_64(ctx);
13756 /* Fallthrough */
13757 #endif
13758 case LWP:
13759 case SWP:
13760 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13761 break;
13762 #ifdef TARGET_MIPS64
13763 case LDM:
13764 case SDM:
13765 check_insn(ctx, ISA_MIPS3);
13766 check_mips_64(ctx);
13767 /* Fallthrough */
13768 #endif
13769 case LWM32:
13770 case SWM32:
13771 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13772 break;
13773 default:
13774 MIPS_INVAL("pool32b");
13775 generate_exception_end(ctx, EXCP_RI);
13776 break;
13777 }
13778 break;
13779 case POOL32F:
13780 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
13781 minor = ctx->opcode & 0x3f;
13782 check_cp1_enabled(ctx);
13783 switch (minor) {
13784 case ALNV_PS:
13785 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13786 mips32_op = OPC_ALNV_PS;
13787 goto do_madd;
13788 case MADD_S:
13789 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13790 mips32_op = OPC_MADD_S;
13791 goto do_madd;
13792 case MADD_D:
13793 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13794 mips32_op = OPC_MADD_D;
13795 goto do_madd;
13796 case MADD_PS:
13797 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13798 mips32_op = OPC_MADD_PS;
13799 goto do_madd;
13800 case MSUB_S:
13801 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13802 mips32_op = OPC_MSUB_S;
13803 goto do_madd;
13804 case MSUB_D:
13805 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13806 mips32_op = OPC_MSUB_D;
13807 goto do_madd;
13808 case MSUB_PS:
13809 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13810 mips32_op = OPC_MSUB_PS;
13811 goto do_madd;
13812 case NMADD_S:
13813 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13814 mips32_op = OPC_NMADD_S;
13815 goto do_madd;
13816 case NMADD_D:
13817 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13818 mips32_op = OPC_NMADD_D;
13819 goto do_madd;
13820 case NMADD_PS:
13821 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13822 mips32_op = OPC_NMADD_PS;
13823 goto do_madd;
13824 case NMSUB_S:
13825 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13826 mips32_op = OPC_NMSUB_S;
13827 goto do_madd;
13828 case NMSUB_D:
13829 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13830 mips32_op = OPC_NMSUB_D;
13831 goto do_madd;
13832 case NMSUB_PS:
13833 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13834 mips32_op = OPC_NMSUB_PS;
13835 do_madd:
13836 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13837 break;
13838 case CABS_COND_FMT:
13839 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13840 cond = (ctx->opcode >> 6) & 0xf;
13841 cc = (ctx->opcode >> 13) & 0x7;
13842 fmt = (ctx->opcode >> 10) & 0x3;
13843 switch (fmt) {
13844 case 0x0:
13845 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13846 break;
13847 case 0x1:
13848 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13849 break;
13850 case 0x2:
13851 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13852 break;
13853 default:
13854 goto pool32f_invalid;
13855 }
13856 break;
13857 case C_COND_FMT:
13858 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13859 cond = (ctx->opcode >> 6) & 0xf;
13860 cc = (ctx->opcode >> 13) & 0x7;
13861 fmt = (ctx->opcode >> 10) & 0x3;
13862 switch (fmt) {
13863 case 0x0:
13864 gen_cmp_s(ctx, cond, rt, rs, cc);
13865 break;
13866 case 0x1:
13867 gen_cmp_d(ctx, cond, rt, rs, cc);
13868 break;
13869 case 0x2:
13870 gen_cmp_ps(ctx, cond, rt, rs, cc);
13871 break;
13872 default:
13873 goto pool32f_invalid;
13874 }
13875 break;
13876 case CMP_CONDN_S:
13877 check_insn(ctx, ISA_MIPS32R6);
13878 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13879 break;
13880 case CMP_CONDN_D:
13881 check_insn(ctx, ISA_MIPS32R6);
13882 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13883 break;
13884 case POOL32FXF:
13885 gen_pool32fxf(ctx, rt, rs);
13886 break;
13887 case 0x00:
13888 /* PLL foo */
13889 switch ((ctx->opcode >> 6) & 0x7) {
13890 case PLL_PS:
13891 mips32_op = OPC_PLL_PS;
13892 goto do_ps;
13893 case PLU_PS:
13894 mips32_op = OPC_PLU_PS;
13895 goto do_ps;
13896 case PUL_PS:
13897 mips32_op = OPC_PUL_PS;
13898 goto do_ps;
13899 case PUU_PS:
13900 mips32_op = OPC_PUU_PS;
13901 goto do_ps;
13902 case CVT_PS_S:
13903 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13904 mips32_op = OPC_CVT_PS_S;
13905 do_ps:
13906 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13907 break;
13908 default:
13909 goto pool32f_invalid;
13910 }
13911 break;
13912 case MIN_FMT:
13913 check_insn(ctx, ISA_MIPS32R6);
13914 switch ((ctx->opcode >> 9) & 0x3) {
13915 case FMT_SDPS_S:
13916 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
13917 break;
13918 case FMT_SDPS_D:
13919 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
13920 break;
13921 default:
13922 goto pool32f_invalid;
13923 }
13924 break;
13925 case 0x08:
13926 /* [LS][WDU]XC1 */
13927 switch ((ctx->opcode >> 6) & 0x7) {
13928 case LWXC1:
13929 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13930 mips32_op = OPC_LWXC1;
13931 goto do_ldst_cp1;
13932 case SWXC1:
13933 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13934 mips32_op = OPC_SWXC1;
13935 goto do_ldst_cp1;
13936 case LDXC1:
13937 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13938 mips32_op = OPC_LDXC1;
13939 goto do_ldst_cp1;
13940 case SDXC1:
13941 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13942 mips32_op = OPC_SDXC1;
13943 goto do_ldst_cp1;
13944 case LUXC1:
13945 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13946 mips32_op = OPC_LUXC1;
13947 goto do_ldst_cp1;
13948 case SUXC1:
13949 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13950 mips32_op = OPC_SUXC1;
13951 do_ldst_cp1:
13952 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13953 break;
13954 default:
13955 goto pool32f_invalid;
13956 }
13957 break;
13958 case MAX_FMT:
13959 check_insn(ctx, ISA_MIPS32R6);
13960 switch ((ctx->opcode >> 9) & 0x3) {
13961 case FMT_SDPS_S:
13962 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
13963 break;
13964 case FMT_SDPS_D:
13965 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
13966 break;
13967 default:
13968 goto pool32f_invalid;
13969 }
13970 break;
13971 case 0x18:
13972 /* 3D insns */
13973 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13974 fmt = (ctx->opcode >> 9) & 0x3;
13975 switch ((ctx->opcode >> 6) & 0x7) {
13976 case RSQRT2_FMT:
13977 switch (fmt) {
13978 case FMT_SDPS_S:
13979 mips32_op = OPC_RSQRT2_S;
13980 goto do_3d;
13981 case FMT_SDPS_D:
13982 mips32_op = OPC_RSQRT2_D;
13983 goto do_3d;
13984 case FMT_SDPS_PS:
13985 mips32_op = OPC_RSQRT2_PS;
13986 goto do_3d;
13987 default:
13988 goto pool32f_invalid;
13989 }
13990 break;
13991 case RECIP2_FMT:
13992 switch (fmt) {
13993 case FMT_SDPS_S:
13994 mips32_op = OPC_RECIP2_S;
13995 goto do_3d;
13996 case FMT_SDPS_D:
13997 mips32_op = OPC_RECIP2_D;
13998 goto do_3d;
13999 case FMT_SDPS_PS:
14000 mips32_op = OPC_RECIP2_PS;
14001 goto do_3d;
14002 default:
14003 goto pool32f_invalid;
14004 }
14005 break;
14006 case ADDR_PS:
14007 mips32_op = OPC_ADDR_PS;
14008 goto do_3d;
14009 case MULR_PS:
14010 mips32_op = OPC_MULR_PS;
14011 do_3d:
14012 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14013 break;
14014 default:
14015 goto pool32f_invalid;
14016 }
14017 break;
14018 case 0x20:
14019 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14020 cc = (ctx->opcode >> 13) & 0x7;
14021 fmt = (ctx->opcode >> 9) & 0x3;
14022 switch ((ctx->opcode >> 6) & 0x7) {
14023 case MOVF_FMT: /* RINT_FMT */
14024 if (ctx->insn_flags & ISA_MIPS32R6) {
14025 /* RINT_FMT */
14026 switch (fmt) {
14027 case FMT_SDPS_S:
14028 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
14029 break;
14030 case FMT_SDPS_D:
14031 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
14032 break;
14033 default:
14034 goto pool32f_invalid;
14035 }
14036 } else {
14037 /* MOVF_FMT */
14038 switch (fmt) {
14039 case FMT_SDPS_S:
14040 gen_movcf_s(ctx, rs, rt, cc, 0);
14041 break;
14042 case FMT_SDPS_D:
14043 gen_movcf_d(ctx, rs, rt, cc, 0);
14044 break;
14045 case FMT_SDPS_PS:
14046 check_ps(ctx);
14047 gen_movcf_ps(ctx, rs, rt, cc, 0);
14048 break;
14049 default:
14050 goto pool32f_invalid;
14051 }
14052 }
14053 break;
14054 case MOVT_FMT: /* CLASS_FMT */
14055 if (ctx->insn_flags & ISA_MIPS32R6) {
14056 /* CLASS_FMT */
14057 switch (fmt) {
14058 case FMT_SDPS_S:
14059 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
14060 break;
14061 case FMT_SDPS_D:
14062 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
14063 break;
14064 default:
14065 goto pool32f_invalid;
14066 }
14067 } else {
14068 /* MOVT_FMT */
14069 switch (fmt) {
14070 case FMT_SDPS_S:
14071 gen_movcf_s(ctx, rs, rt, cc, 1);
14072 break;
14073 case FMT_SDPS_D:
14074 gen_movcf_d(ctx, rs, rt, cc, 1);
14075 break;
14076 case FMT_SDPS_PS:
14077 check_ps(ctx);
14078 gen_movcf_ps(ctx, rs, rt, cc, 1);
14079 break;
14080 default:
14081 goto pool32f_invalid;
14082 }
14083 }
14084 break;
14085 case PREFX:
14086 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14087 break;
14088 default:
14089 goto pool32f_invalid;
14090 }
14091 break;
14092 #define FINSN_3ARG_SDPS(prfx) \
14093 switch ((ctx->opcode >> 8) & 0x3) { \
14094 case FMT_SDPS_S: \
14095 mips32_op = OPC_##prfx##_S; \
14096 goto do_fpop; \
14097 case FMT_SDPS_D: \
14098 mips32_op = OPC_##prfx##_D; \
14099 goto do_fpop; \
14100 case FMT_SDPS_PS: \
14101 check_ps(ctx); \
14102 mips32_op = OPC_##prfx##_PS; \
14103 goto do_fpop; \
14104 default: \
14105 goto pool32f_invalid; \
14106 }
14107 case MINA_FMT:
14108 check_insn(ctx, ISA_MIPS32R6);
14109 switch ((ctx->opcode >> 9) & 0x3) {
14110 case FMT_SDPS_S:
14111 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14112 break;
14113 case FMT_SDPS_D:
14114 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14115 break;
14116 default:
14117 goto pool32f_invalid;
14118 }
14119 break;
14120 case MAXA_FMT:
14121 check_insn(ctx, ISA_MIPS32R6);
14122 switch ((ctx->opcode >> 9) & 0x3) {
14123 case FMT_SDPS_S:
14124 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14125 break;
14126 case FMT_SDPS_D:
14127 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14128 break;
14129 default:
14130 goto pool32f_invalid;
14131 }
14132 break;
14133 case 0x30:
14134 /* regular FP ops */
14135 switch ((ctx->opcode >> 6) & 0x3) {
14136 case ADD_FMT:
14137 FINSN_3ARG_SDPS(ADD);
14138 break;
14139 case SUB_FMT:
14140 FINSN_3ARG_SDPS(SUB);
14141 break;
14142 case MUL_FMT:
14143 FINSN_3ARG_SDPS(MUL);
14144 break;
14145 case DIV_FMT:
14146 fmt = (ctx->opcode >> 8) & 0x3;
14147 if (fmt == 1) {
14148 mips32_op = OPC_DIV_D;
14149 } else if (fmt == 0) {
14150 mips32_op = OPC_DIV_S;
14151 } else {
14152 goto pool32f_invalid;
14153 }
14154 goto do_fpop;
14155 default:
14156 goto pool32f_invalid;
14157 }
14158 break;
14159 case 0x38:
14160 /* cmovs */
14161 switch ((ctx->opcode >> 6) & 0x7) {
14162 case MOVN_FMT: /* SELNEZ_FMT */
14163 if (ctx->insn_flags & ISA_MIPS32R6) {
14164 /* SELNEZ_FMT */
14165 switch ((ctx->opcode >> 9) & 0x3) {
14166 case FMT_SDPS_S:
14167 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14168 break;
14169 case FMT_SDPS_D:
14170 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14171 break;
14172 default:
14173 goto pool32f_invalid;
14174 }
14175 } else {
14176 /* MOVN_FMT */
14177 FINSN_3ARG_SDPS(MOVN);
14178 }
14179 break;
14180 case MOVN_FMT_04:
14181 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14182 FINSN_3ARG_SDPS(MOVN);
14183 break;
14184 case MOVZ_FMT: /* SELEQZ_FMT */
14185 if (ctx->insn_flags & ISA_MIPS32R6) {
14186 /* SELEQZ_FMT */
14187 switch ((ctx->opcode >> 9) & 0x3) {
14188 case FMT_SDPS_S:
14189 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14190 break;
14191 case FMT_SDPS_D:
14192 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14193 break;
14194 default:
14195 goto pool32f_invalid;
14196 }
14197 } else {
14198 /* MOVZ_FMT */
14199 FINSN_3ARG_SDPS(MOVZ);
14200 }
14201 break;
14202 case MOVZ_FMT_05:
14203 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14204 FINSN_3ARG_SDPS(MOVZ);
14205 break;
14206 case SEL_FMT:
14207 check_insn(ctx, ISA_MIPS32R6);
14208 switch ((ctx->opcode >> 9) & 0x3) {
14209 case FMT_SDPS_S:
14210 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14211 break;
14212 case FMT_SDPS_D:
14213 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14214 break;
14215 default:
14216 goto pool32f_invalid;
14217 }
14218 break;
14219 case MADDF_FMT:
14220 check_insn(ctx, ISA_MIPS32R6);
14221 switch ((ctx->opcode >> 9) & 0x3) {
14222 case FMT_SDPS_S:
14223 mips32_op = OPC_MADDF_S;
14224 goto do_fpop;
14225 case FMT_SDPS_D:
14226 mips32_op = OPC_MADDF_D;
14227 goto do_fpop;
14228 default:
14229 goto pool32f_invalid;
14230 }
14231 break;
14232 case MSUBF_FMT:
14233 check_insn(ctx, ISA_MIPS32R6);
14234 switch ((ctx->opcode >> 9) & 0x3) {
14235 case FMT_SDPS_S:
14236 mips32_op = OPC_MSUBF_S;
14237 goto do_fpop;
14238 case FMT_SDPS_D:
14239 mips32_op = OPC_MSUBF_D;
14240 goto do_fpop;
14241 default:
14242 goto pool32f_invalid;
14243 }
14244 break;
14245 default:
14246 goto pool32f_invalid;
14247 }
14248 break;
14249 do_fpop:
14250 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14251 break;
14252 default:
14253 pool32f_invalid:
14254 MIPS_INVAL("pool32f");
14255 generate_exception_end(ctx, EXCP_RI);
14256 break;
14257 }
14258 } else {
14259 generate_exception_err(ctx, EXCP_CpU, 1);
14260 }
14261 break;
14262 case POOL32I:
14263 minor = (ctx->opcode >> 21) & 0x1f;
14264 switch (minor) {
14265 case BLTZ:
14266 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14267 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14268 break;
14269 case BLTZAL:
14270 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14271 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14272 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14273 break;
14274 case BLTZALS:
14275 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14276 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14277 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14278 break;
14279 case BGEZ:
14280 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14281 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14282 break;
14283 case BGEZAL:
14284 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14285 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14286 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14287 break;
14288 case BGEZALS:
14289 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14290 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14291 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14292 break;
14293 case BLEZ:
14294 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14295 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14296 break;
14297 case BGTZ:
14298 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14299 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14300 break;
14301
14302 /* Traps */
14303 case TLTI: /* BC1EQZC */
14304 if (ctx->insn_flags & ISA_MIPS32R6) {
14305 /* BC1EQZC */
14306 check_cp1_enabled(ctx);
14307 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14308 } else {
14309 /* TLTI */
14310 mips32_op = OPC_TLTI;
14311 goto do_trapi;
14312 }
14313 break;
14314 case TGEI: /* BC1NEZC */
14315 if (ctx->insn_flags & ISA_MIPS32R6) {
14316 /* BC1NEZC */
14317 check_cp1_enabled(ctx);
14318 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14319 } else {
14320 /* TGEI */
14321 mips32_op = OPC_TGEI;
14322 goto do_trapi;
14323 }
14324 break;
14325 case TLTIU:
14326 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14327 mips32_op = OPC_TLTIU;
14328 goto do_trapi;
14329 case TGEIU:
14330 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14331 mips32_op = OPC_TGEIU;
14332 goto do_trapi;
14333 case TNEI: /* SYNCI */
14334 if (ctx->insn_flags & ISA_MIPS32R6) {
14335 /* SYNCI */
14336 /* Break the TB to be able to sync copied instructions
14337 immediately */
14338 ctx->bstate = BS_STOP;
14339 } else {
14340 /* TNEI */
14341 mips32_op = OPC_TNEI;
14342 goto do_trapi;
14343 }
14344 break;
14345 case TEQI:
14346 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14347 mips32_op = OPC_TEQI;
14348 do_trapi:
14349 gen_trap(ctx, mips32_op, rs, -1, imm);
14350 break;
14351
14352 case BNEZC:
14353 case BEQZC:
14354 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14355 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14356 4, rs, 0, imm << 1, 0);
14357 /* Compact branches don't have a delay slot, so just let
14358 the normal delay slot handling take us to the branch
14359 target. */
14360 break;
14361 case LUI:
14362 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14363 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14364 break;
14365 case SYNCI:
14366 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14367 /* Break the TB to be able to sync copied instructions
14368 immediately */
14369 ctx->bstate = BS_STOP;
14370 break;
14371 case BC2F:
14372 case BC2T:
14373 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14374 /* COP2: Not implemented. */
14375 generate_exception_err(ctx, EXCP_CpU, 2);
14376 break;
14377 case BC1F:
14378 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14379 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14380 goto do_cp1branch;
14381 case BC1T:
14382 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14383 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14384 goto do_cp1branch;
14385 case BC1ANY4F:
14386 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14387 mips32_op = OPC_BC1FANY4;
14388 goto do_cp1mips3d;
14389 case BC1ANY4T:
14390 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14391 mips32_op = OPC_BC1TANY4;
14392 do_cp1mips3d:
14393 check_cop1x(ctx);
14394 check_insn(ctx, ASE_MIPS3D);
14395 /* Fall through */
14396 do_cp1branch:
14397 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14398 check_cp1_enabled(ctx);
14399 gen_compute_branch1(ctx, mips32_op,
14400 (ctx->opcode >> 18) & 0x7, imm << 1);
14401 } else {
14402 generate_exception_err(ctx, EXCP_CpU, 1);
14403 }
14404 break;
14405 case BPOSGE64:
14406 case BPOSGE32:
14407 /* MIPS DSP: not implemented */
14408 /* Fall through */
14409 default:
14410 MIPS_INVAL("pool32i");
14411 generate_exception_end(ctx, EXCP_RI);
14412 break;
14413 }
14414 break;
14415 case POOL32C:
14416 minor = (ctx->opcode >> 12) & 0xf;
14417 offset = sextract32(ctx->opcode, 0,
14418 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14419 switch (minor) {
14420 case LWL:
14421 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14422 mips32_op = OPC_LWL;
14423 goto do_ld_lr;
14424 case SWL:
14425 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14426 mips32_op = OPC_SWL;
14427 goto do_st_lr;
14428 case LWR:
14429 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14430 mips32_op = OPC_LWR;
14431 goto do_ld_lr;
14432 case SWR:
14433 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14434 mips32_op = OPC_SWR;
14435 goto do_st_lr;
14436 #if defined(TARGET_MIPS64)
14437 case LDL:
14438 check_insn(ctx, ISA_MIPS3);
14439 check_mips_64(ctx);
14440 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14441 mips32_op = OPC_LDL;
14442 goto do_ld_lr;
14443 case SDL:
14444 check_insn(ctx, ISA_MIPS3);
14445 check_mips_64(ctx);
14446 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14447 mips32_op = OPC_SDL;
14448 goto do_st_lr;
14449 case LDR:
14450 check_insn(ctx, ISA_MIPS3);
14451 check_mips_64(ctx);
14452 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14453 mips32_op = OPC_LDR;
14454 goto do_ld_lr;
14455 case SDR:
14456 check_insn(ctx, ISA_MIPS3);
14457 check_mips_64(ctx);
14458 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14459 mips32_op = OPC_SDR;
14460 goto do_st_lr;
14461 case LWU:
14462 check_insn(ctx, ISA_MIPS3);
14463 check_mips_64(ctx);
14464 mips32_op = OPC_LWU;
14465 goto do_ld_lr;
14466 case LLD:
14467 check_insn(ctx, ISA_MIPS3);
14468 check_mips_64(ctx);
14469 mips32_op = OPC_LLD;
14470 goto do_ld_lr;
14471 #endif
14472 case LL:
14473 mips32_op = OPC_LL;
14474 goto do_ld_lr;
14475 do_ld_lr:
14476 gen_ld(ctx, mips32_op, rt, rs, offset);
14477 break;
14478 do_st_lr:
14479 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
14480 break;
14481 case SC:
14482 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14483 break;
14484 #if defined(TARGET_MIPS64)
14485 case SCD:
14486 check_insn(ctx, ISA_MIPS3);
14487 check_mips_64(ctx);
14488 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14489 break;
14490 #endif
14491 case PREF:
14492 /* Treat as no-op */
14493 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14494 /* hint codes 24-31 are reserved and signal RI */
14495 generate_exception(ctx, EXCP_RI);
14496 }
14497 break;
14498 default:
14499 MIPS_INVAL("pool32c");
14500 generate_exception_end(ctx, EXCP_RI);
14501 break;
14502 }
14503 break;
14504 case ADDI32: /* AUI, LUI */
14505 if (ctx->insn_flags & ISA_MIPS32R6) {
14506 /* AUI, LUI */
14507 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14508 } else {
14509 /* ADDI32 */
14510 mips32_op = OPC_ADDI;
14511 goto do_addi;
14512 }
14513 break;
14514 case ADDIU32:
14515 mips32_op = OPC_ADDIU;
14516 do_addi:
14517 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
14518 break;
14519
14520 /* Logical operations */
14521 case ORI32:
14522 mips32_op = OPC_ORI;
14523 goto do_logici;
14524 case XORI32:
14525 mips32_op = OPC_XORI;
14526 goto do_logici;
14527 case ANDI32:
14528 mips32_op = OPC_ANDI;
14529 do_logici:
14530 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
14531 break;
14532
14533 /* Set less than immediate */
14534 case SLTI32:
14535 mips32_op = OPC_SLTI;
14536 goto do_slti;
14537 case SLTIU32:
14538 mips32_op = OPC_SLTIU;
14539 do_slti:
14540 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
14541 break;
14542 case JALX32:
14543 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14544 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14545 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14546 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14547 break;
14548 case JALS32: /* BOVC, BEQC, BEQZALC */
14549 if (ctx->insn_flags & ISA_MIPS32R6) {
14550 if (rs >= rt) {
14551 /* BOVC */
14552 mips32_op = OPC_BOVC;
14553 } else if (rs < rt && rs == 0) {
14554 /* BEQZALC */
14555 mips32_op = OPC_BEQZALC;
14556 } else {
14557 /* BEQC */
14558 mips32_op = OPC_BEQC;
14559 }
14560 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14561 } else {
14562 /* JALS32 */
14563 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14564 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14565 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14566 }
14567 break;
14568 case BEQ32: /* BC */
14569 if (ctx->insn_flags & ISA_MIPS32R6) {
14570 /* BC */
14571 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14572 sextract32(ctx->opcode << 1, 0, 27));
14573 } else {
14574 /* BEQ32 */
14575 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14576 }
14577 break;
14578 case BNE32: /* BALC */
14579 if (ctx->insn_flags & ISA_MIPS32R6) {
14580 /* BALC */
14581 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14582 sextract32(ctx->opcode << 1, 0, 27));
14583 } else {
14584 /* BNE32 */
14585 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14586 }
14587 break;
14588 case J32: /* BGTZC, BLTZC, BLTC */
14589 if (ctx->insn_flags & ISA_MIPS32R6) {
14590 if (rs == 0 && rt != 0) {
14591 /* BGTZC */
14592 mips32_op = OPC_BGTZC;
14593 } else if (rs != 0 && rt != 0 && rs == rt) {
14594 /* BLTZC */
14595 mips32_op = OPC_BLTZC;
14596 } else {
14597 /* BLTC */
14598 mips32_op = OPC_BLTC;
14599 }
14600 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14601 } else {
14602 /* J32 */
14603 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14604 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14605 }
14606 break;
14607 case JAL32: /* BLEZC, BGEZC, BGEC */
14608 if (ctx->insn_flags & ISA_MIPS32R6) {
14609 if (rs == 0 && rt != 0) {
14610 /* BLEZC */
14611 mips32_op = OPC_BLEZC;
14612 } else if (rs != 0 && rt != 0 && rs == rt) {
14613 /* BGEZC */
14614 mips32_op = OPC_BGEZC;
14615 } else {
14616 /* BGEC */
14617 mips32_op = OPC_BGEC;
14618 }
14619 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14620 } else {
14621 /* JAL32 */
14622 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14623 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14624 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14625 }
14626 break;
14627 /* Floating point (COP1) */
14628 case LWC132:
14629 mips32_op = OPC_LWC1;
14630 goto do_cop1;
14631 case LDC132:
14632 mips32_op = OPC_LDC1;
14633 goto do_cop1;
14634 case SWC132:
14635 mips32_op = OPC_SWC1;
14636 goto do_cop1;
14637 case SDC132:
14638 mips32_op = OPC_SDC1;
14639 do_cop1:
14640 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
14641 break;
14642 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14643 if (ctx->insn_flags & ISA_MIPS32R6) {
14644 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14645 switch ((ctx->opcode >> 16) & 0x1f) {
14646 case ADDIUPC_00 ... ADDIUPC_07:
14647 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14648 break;
14649 case AUIPC:
14650 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14651 break;
14652 case ALUIPC:
14653 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14654 break;
14655 case LWPC_08 ... LWPC_0F:
14656 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14657 break;
14658 default:
14659 generate_exception(ctx, EXCP_RI);
14660 break;
14661 }
14662 } else {
14663 /* ADDIUPC */
14664 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14665 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14666
14667 gen_addiupc(ctx, reg, offset, 0, 0);
14668 }
14669 break;
14670 case BNVC: /* BNEC, BNEZALC */
14671 check_insn(ctx, ISA_MIPS32R6);
14672 if (rs >= rt) {
14673 /* BNVC */
14674 mips32_op = OPC_BNVC;
14675 } else if (rs < rt && rs == 0) {
14676 /* BNEZALC */
14677 mips32_op = OPC_BNEZALC;
14678 } else {
14679 /* BNEC */
14680 mips32_op = OPC_BNEC;
14681 }
14682 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14683 break;
14684 case R6_BNEZC: /* JIALC */
14685 check_insn(ctx, ISA_MIPS32R6);
14686 if (rt != 0) {
14687 /* BNEZC */
14688 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14689 sextract32(ctx->opcode << 1, 0, 22));
14690 } else {
14691 /* JIALC */
14692 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14693 }
14694 break;
14695 case R6_BEQZC: /* JIC */
14696 check_insn(ctx, ISA_MIPS32R6);
14697 if (rt != 0) {
14698 /* BEQZC */
14699 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14700 sextract32(ctx->opcode << 1, 0, 22));
14701 } else {
14702 /* JIC */
14703 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14704 }
14705 break;
14706 case BLEZALC: /* BGEZALC, BGEUC */
14707 check_insn(ctx, ISA_MIPS32R6);
14708 if (rs == 0 && rt != 0) {
14709 /* BLEZALC */
14710 mips32_op = OPC_BLEZALC;
14711 } else if (rs != 0 && rt != 0 && rs == rt) {
14712 /* BGEZALC */
14713 mips32_op = OPC_BGEZALC;
14714 } else {
14715 /* BGEUC */
14716 mips32_op = OPC_BGEUC;
14717 }
14718 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14719 break;
14720 case BGTZALC: /* BLTZALC, BLTUC */
14721 check_insn(ctx, ISA_MIPS32R6);
14722 if (rs == 0 && rt != 0) {
14723 /* BGTZALC */
14724 mips32_op = OPC_BGTZALC;
14725 } else if (rs != 0 && rt != 0 && rs == rt) {
14726 /* BLTZALC */
14727 mips32_op = OPC_BLTZALC;
14728 } else {
14729 /* BLTUC */
14730 mips32_op = OPC_BLTUC;
14731 }
14732 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14733 break;
14734 /* Loads and stores */
14735 case LB32:
14736 mips32_op = OPC_LB;
14737 goto do_ld;
14738 case LBU32:
14739 mips32_op = OPC_LBU;
14740 goto do_ld;
14741 case LH32:
14742 mips32_op = OPC_LH;
14743 goto do_ld;
14744 case LHU32:
14745 mips32_op = OPC_LHU;
14746 goto do_ld;
14747 case LW32:
14748 mips32_op = OPC_LW;
14749 goto do_ld;
14750 #ifdef TARGET_MIPS64
14751 case LD32:
14752 check_insn(ctx, ISA_MIPS3);
14753 check_mips_64(ctx);
14754 mips32_op = OPC_LD;
14755 goto do_ld;
14756 case SD32:
14757 check_insn(ctx, ISA_MIPS3);
14758 check_mips_64(ctx);
14759 mips32_op = OPC_SD;
14760 goto do_st;
14761 #endif
14762 case SB32:
14763 mips32_op = OPC_SB;
14764 goto do_st;
14765 case SH32:
14766 mips32_op = OPC_SH;
14767 goto do_st;
14768 case SW32:
14769 mips32_op = OPC_SW;
14770 goto do_st;
14771 do_ld:
14772 gen_ld(ctx, mips32_op, rt, rs, imm);
14773 break;
14774 do_st:
14775 gen_st(ctx, mips32_op, rt, rs, imm);
14776 break;
14777 default:
14778 generate_exception_end(ctx, EXCP_RI);
14779 break;
14780 }
14781 }
14782
14783 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
14784 {
14785 uint32_t op;
14786
14787 /* make sure instructions are on a halfword boundary */
14788 if (ctx->pc & 0x1) {
14789 env->CP0_BadVAddr = ctx->pc;
14790 generate_exception_end(ctx, EXCP_AdEL);
14791 return 2;
14792 }
14793
14794 op = (ctx->opcode >> 10) & 0x3f;
14795 /* Enforce properly-sized instructions in a delay slot */
14796 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14797 switch (op & 0x7) { /* MSB-3..MSB-5 */
14798 case 0:
14799 /* POOL32A, POOL32B, POOL32I, POOL32C */
14800 case 4:
14801 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14802 case 5:
14803 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14804 case 6:
14805 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14806 case 7:
14807 /* LB32, LH32, LWC132, LDC132, LW32 */
14808 if (ctx->hflags & MIPS_HFLAG_BDS16) {
14809 generate_exception_end(ctx, EXCP_RI);
14810 return 2;
14811 }
14812 break;
14813 case 1:
14814 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
14815 case 2:
14816 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
14817 case 3:
14818 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
14819 if (ctx->hflags & MIPS_HFLAG_BDS32) {
14820 generate_exception_end(ctx, EXCP_RI);
14821 return 2;
14822 }
14823 break;
14824 }
14825 }
14826
14827 switch (op) {
14828 case POOL16A:
14829 {
14830 int rd = mmreg(uMIPS_RD(ctx->opcode));
14831 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
14832 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14833 uint32_t opc = 0;
14834
14835 switch (ctx->opcode & 0x1) {
14836 case ADDU16:
14837 opc = OPC_ADDU;
14838 break;
14839 case SUBU16:
14840 opc = OPC_SUBU;
14841 break;
14842 }
14843 if (ctx->insn_flags & ISA_MIPS32R6) {
14844 /* In the Release 6 the register number location in
14845 * the instruction encoding has changed.
14846 */
14847 gen_arith(ctx, opc, rs1, rd, rs2);
14848 } else {
14849 gen_arith(ctx, opc, rd, rs1, rs2);
14850 }
14851 }
14852 break;
14853 case POOL16B:
14854 {
14855 int rd = mmreg(uMIPS_RD(ctx->opcode));
14856 int rs = mmreg(uMIPS_RS(ctx->opcode));
14857 int amount = (ctx->opcode >> 1) & 0x7;
14858 uint32_t opc = 0;
14859 amount = amount == 0 ? 8 : amount;
14860
14861 switch (ctx->opcode & 0x1) {
14862 case SLL16:
14863 opc = OPC_SLL;
14864 break;
14865 case SRL16:
14866 opc = OPC_SRL;
14867 break;
14868 }
14869
14870 gen_shift_imm(ctx, opc, rd, rs, amount);
14871 }
14872 break;
14873 case POOL16C:
14874 if (ctx->insn_flags & ISA_MIPS32R6) {
14875 gen_pool16c_r6_insn(ctx);
14876 } else {
14877 gen_pool16c_insn(ctx);
14878 }
14879 break;
14880 case LWGP16:
14881 {
14882 int rd = mmreg(uMIPS_RD(ctx->opcode));
14883 int rb = 28; /* GP */
14884 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14885
14886 gen_ld(ctx, OPC_LW, rd, rb, offset);
14887 }
14888 break;
14889 case POOL16F:
14890 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14891 if (ctx->opcode & 1) {
14892 generate_exception_end(ctx, EXCP_RI);
14893 } else {
14894 /* MOVEP */
14895 int enc_dest = uMIPS_RD(ctx->opcode);
14896 int enc_rt = uMIPS_RS2(ctx->opcode);
14897 int enc_rs = uMIPS_RS1(ctx->opcode);
14898 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14899 }
14900 break;
14901 case LBU16:
14902 {
14903 int rd = mmreg(uMIPS_RD(ctx->opcode));
14904 int rb = mmreg(uMIPS_RS(ctx->opcode));
14905 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14906 offset = (offset == 0xf ? -1 : offset);
14907
14908 gen_ld(ctx, OPC_LBU, rd, rb, offset);
14909 }
14910 break;
14911 case LHU16:
14912 {
14913 int rd = mmreg(uMIPS_RD(ctx->opcode));
14914 int rb = mmreg(uMIPS_RS(ctx->opcode));
14915 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14916
14917 gen_ld(ctx, OPC_LHU, rd, rb, offset);
14918 }
14919 break;
14920 case LWSP16:
14921 {
14922 int rd = (ctx->opcode >> 5) & 0x1f;
14923 int rb = 29; /* SP */
14924 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14925
14926 gen_ld(ctx, OPC_LW, rd, rb, offset);
14927 }
14928 break;
14929 case LW16:
14930 {
14931 int rd = mmreg(uMIPS_RD(ctx->opcode));
14932 int rb = mmreg(uMIPS_RS(ctx->opcode));
14933 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14934
14935 gen_ld(ctx, OPC_LW, rd, rb, offset);
14936 }
14937 break;
14938 case SB16:
14939 {
14940 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14941 int rb = mmreg(uMIPS_RS(ctx->opcode));
14942 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14943
14944 gen_st(ctx, OPC_SB, rd, rb, offset);
14945 }
14946 break;
14947 case SH16:
14948 {
14949 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14950 int rb = mmreg(uMIPS_RS(ctx->opcode));
14951 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14952
14953 gen_st(ctx, OPC_SH, rd, rb, offset);
14954 }
14955 break;
14956 case SWSP16:
14957 {
14958 int rd = (ctx->opcode >> 5) & 0x1f;
14959 int rb = 29; /* SP */
14960 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14961
14962 gen_st(ctx, OPC_SW, rd, rb, offset);
14963 }
14964 break;
14965 case SW16:
14966 {
14967 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14968 int rb = mmreg(uMIPS_RS(ctx->opcode));
14969 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14970
14971 gen_st(ctx, OPC_SW, rd, rb, offset);
14972 }
14973 break;
14974 case MOVE16:
14975 {
14976 int rd = uMIPS_RD5(ctx->opcode);
14977 int rs = uMIPS_RS5(ctx->opcode);
14978
14979 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
14980 }
14981 break;
14982 case ANDI16:
14983 gen_andi16(ctx);
14984 break;
14985 case POOL16D:
14986 switch (ctx->opcode & 0x1) {
14987 case ADDIUS5:
14988 gen_addius5(ctx);
14989 break;
14990 case ADDIUSP:
14991 gen_addiusp(ctx);
14992 break;
14993 }
14994 break;
14995 case POOL16E:
14996 switch (ctx->opcode & 0x1) {
14997 case ADDIUR2:
14998 gen_addiur2(ctx);
14999 break;
15000 case ADDIUR1SP:
15001 gen_addiur1sp(ctx);
15002 break;
15003 }
15004 break;
15005 case B16: /* BC16 */
15006 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
15007 sextract32(ctx->opcode, 0, 10) << 1,
15008 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15009 break;
15010 case BNEZ16: /* BNEZC16 */
15011 case BEQZ16: /* BEQZC16 */
15012 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
15013 mmreg(uMIPS_RD(ctx->opcode)),
15014 0, sextract32(ctx->opcode, 0, 7) << 1,
15015 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
15016
15017 break;
15018 case LI16:
15019 {
15020 int reg = mmreg(uMIPS_RD(ctx->opcode));
15021 int imm = ZIMM(ctx->opcode, 0, 7);
15022
15023 imm = (imm == 0x7f ? -1 : imm);
15024 tcg_gen_movi_tl(cpu_gpr[reg], imm);
15025 }
15026 break;
15027 case RES_29:
15028 case RES_31:
15029 case RES_39:
15030 generate_exception_end(ctx, EXCP_RI);
15031 break;
15032 default:
15033 decode_micromips32_opc(env, ctx);
15034 return 4;
15035 }
15036
15037 return 2;
15038 }
15039
15040 /* SmartMIPS extension to MIPS32 */
15041
15042 #if defined(TARGET_MIPS64)
15043
15044 /* MDMX extension to MIPS64 */
15045
15046 #endif
15047
15048 /* MIPSDSP functions. */
15049 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
15050 int rd, int base, int offset)
15051 {
15052 TCGv t0;
15053
15054 check_dsp(ctx);
15055 t0 = tcg_temp_new();
15056
15057 if (base == 0) {
15058 gen_load_gpr(t0, offset);
15059 } else if (offset == 0) {
15060 gen_load_gpr(t0, base);
15061 } else {
15062 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
15063 }
15064
15065 switch (opc) {
15066 case OPC_LBUX:
15067 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
15068 gen_store_gpr(t0, rd);
15069 break;
15070 case OPC_LHX:
15071 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
15072 gen_store_gpr(t0, rd);
15073 break;
15074 case OPC_LWX:
15075 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
15076 gen_store_gpr(t0, rd);
15077 break;
15078 #if defined(TARGET_MIPS64)
15079 case OPC_LDX:
15080 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
15081 gen_store_gpr(t0, rd);
15082 break;
15083 #endif
15084 }
15085 tcg_temp_free(t0);
15086 }
15087
15088 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15089 int ret, int v1, int v2)
15090 {
15091 TCGv v1_t;
15092 TCGv v2_t;
15093
15094 if (ret == 0) {
15095 /* Treat as NOP. */
15096 return;
15097 }
15098
15099 v1_t = tcg_temp_new();
15100 v2_t = tcg_temp_new();
15101
15102 gen_load_gpr(v1_t, v1);
15103 gen_load_gpr(v2_t, v2);
15104
15105 switch (op1) {
15106 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15107 case OPC_MULT_G_2E:
15108 check_dspr2(ctx);
15109 switch (op2) {
15110 case OPC_ADDUH_QB:
15111 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15112 break;
15113 case OPC_ADDUH_R_QB:
15114 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15115 break;
15116 case OPC_ADDQH_PH:
15117 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15118 break;
15119 case OPC_ADDQH_R_PH:
15120 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15121 break;
15122 case OPC_ADDQH_W:
15123 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15124 break;
15125 case OPC_ADDQH_R_W:
15126 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15127 break;
15128 case OPC_SUBUH_QB:
15129 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15130 break;
15131 case OPC_SUBUH_R_QB:
15132 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15133 break;
15134 case OPC_SUBQH_PH:
15135 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15136 break;
15137 case OPC_SUBQH_R_PH:
15138 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15139 break;
15140 case OPC_SUBQH_W:
15141 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15142 break;
15143 case OPC_SUBQH_R_W:
15144 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15145 break;
15146 }
15147 break;
15148 case OPC_ABSQ_S_PH_DSP:
15149 switch (op2) {
15150 case OPC_ABSQ_S_QB:
15151 check_dspr2(ctx);
15152 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15153 break;
15154 case OPC_ABSQ_S_PH:
15155 check_dsp(ctx);
15156 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15157 break;
15158 case OPC_ABSQ_S_W:
15159 check_dsp(ctx);
15160 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15161 break;
15162 case OPC_PRECEQ_W_PHL:
15163 check_dsp(ctx);
15164 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15165 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15166 break;
15167 case OPC_PRECEQ_W_PHR:
15168 check_dsp(ctx);
15169 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15170 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15171 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15172 break;
15173 case OPC_PRECEQU_PH_QBL:
15174 check_dsp(ctx);
15175 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15176 break;
15177 case OPC_PRECEQU_PH_QBR:
15178 check_dsp(ctx);
15179 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15180 break;
15181 case OPC_PRECEQU_PH_QBLA:
15182 check_dsp(ctx);
15183 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15184 break;
15185 case OPC_PRECEQU_PH_QBRA:
15186 check_dsp(ctx);
15187 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15188 break;
15189 case OPC_PRECEU_PH_QBL:
15190 check_dsp(ctx);
15191 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15192 break;
15193 case OPC_PRECEU_PH_QBR:
15194 check_dsp(ctx);
15195 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15196 break;
15197 case OPC_PRECEU_PH_QBLA:
15198 check_dsp(ctx);
15199 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15200 break;
15201 case OPC_PRECEU_PH_QBRA:
15202 check_dsp(ctx);
15203 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15204 break;
15205 }
15206 break;
15207 case OPC_ADDU_QB_DSP:
15208 switch (op2) {
15209 case OPC_ADDQ_PH:
15210 check_dsp(ctx);
15211 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15212 break;
15213 case OPC_ADDQ_S_PH:
15214 check_dsp(ctx);
15215 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15216 break;
15217 case OPC_ADDQ_S_W:
15218 check_dsp(ctx);
15219 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15220 break;
15221 case OPC_ADDU_QB:
15222 check_dsp(ctx);
15223 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15224 break;
15225 case OPC_ADDU_S_QB:
15226 check_dsp(ctx);
15227 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15228 break;
15229 case OPC_ADDU_PH:
15230 check_dspr2(ctx);
15231 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15232 break;
15233 case OPC_ADDU_S_PH:
15234 check_dspr2(ctx);
15235 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15236 break;
15237 case OPC_SUBQ_PH:
15238 check_dsp(ctx);
15239 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15240 break;
15241 case OPC_SUBQ_S_PH:
15242 check_dsp(ctx);
15243 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15244 break;
15245 case OPC_SUBQ_S_W:
15246 check_dsp(ctx);
15247 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15248 break;
15249 case OPC_SUBU_QB:
15250 check_dsp(ctx);
15251 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15252 break;
15253 case OPC_SUBU_S_QB:
15254 check_dsp(ctx);
15255 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15256 break;
15257 case OPC_SUBU_PH:
15258 check_dspr2(ctx);
15259 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15260 break;
15261 case OPC_SUBU_S_PH:
15262 check_dspr2(ctx);
15263 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15264 break;
15265 case OPC_ADDSC:
15266 check_dsp(ctx);
15267 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15268 break;
15269 case OPC_ADDWC:
15270 check_dsp(ctx);
15271 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15272 break;
15273 case OPC_MODSUB:
15274 check_dsp(ctx);
15275 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15276 break;
15277 case OPC_RADDU_W_QB:
15278 check_dsp(ctx);
15279 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15280 break;
15281 }
15282 break;
15283 case OPC_CMPU_EQ_QB_DSP:
15284 switch (op2) {
15285 case OPC_PRECR_QB_PH:
15286 check_dspr2(ctx);
15287 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15288 break;
15289 case OPC_PRECRQ_QB_PH:
15290 check_dsp(ctx);
15291 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15292 break;
15293 case OPC_PRECR_SRA_PH_W:
15294 check_dspr2(ctx);
15295 {
15296 TCGv_i32 sa_t = tcg_const_i32(v2);
15297 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15298 cpu_gpr[ret]);
15299 tcg_temp_free_i32(sa_t);
15300 break;
15301 }
15302 case OPC_PRECR_SRA_R_PH_W:
15303 check_dspr2(ctx);
15304 {
15305 TCGv_i32 sa_t = tcg_const_i32(v2);
15306 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15307 cpu_gpr[ret]);
15308 tcg_temp_free_i32(sa_t);
15309 break;
15310 }
15311 case OPC_PRECRQ_PH_W:
15312 check_dsp(ctx);
15313 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15314 break;
15315 case OPC_PRECRQ_RS_PH_W:
15316 check_dsp(ctx);
15317 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15318 break;
15319 case OPC_PRECRQU_S_QB_PH:
15320 check_dsp(ctx);
15321 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15322 break;
15323 }
15324 break;
15325 #ifdef TARGET_MIPS64
15326 case OPC_ABSQ_S_QH_DSP:
15327 switch (op2) {
15328 case OPC_PRECEQ_L_PWL:
15329 check_dsp(ctx);
15330 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15331 break;
15332 case OPC_PRECEQ_L_PWR:
15333 check_dsp(ctx);
15334 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15335 break;
15336 case OPC_PRECEQ_PW_QHL:
15337 check_dsp(ctx);
15338 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15339 break;
15340 case OPC_PRECEQ_PW_QHR:
15341 check_dsp(ctx);
15342 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15343 break;
15344 case OPC_PRECEQ_PW_QHLA:
15345 check_dsp(ctx);
15346 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15347 break;
15348 case OPC_PRECEQ_PW_QHRA:
15349 check_dsp(ctx);
15350 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15351 break;
15352 case OPC_PRECEQU_QH_OBL:
15353 check_dsp(ctx);
15354 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15355 break;
15356 case OPC_PRECEQU_QH_OBR:
15357 check_dsp(ctx);
15358 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15359 break;
15360 case OPC_PRECEQU_QH_OBLA:
15361 check_dsp(ctx);
15362 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15363 break;
15364 case OPC_PRECEQU_QH_OBRA:
15365 check_dsp(ctx);
15366 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15367 break;
15368 case OPC_PRECEU_QH_OBL:
15369 check_dsp(ctx);
15370 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15371 break;
15372 case OPC_PRECEU_QH_OBR:
15373 check_dsp(ctx);
15374 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15375 break;
15376 case OPC_PRECEU_QH_OBLA:
15377 check_dsp(ctx);
15378 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15379 break;
15380 case OPC_PRECEU_QH_OBRA:
15381 check_dsp(ctx);
15382 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15383 break;
15384 case OPC_ABSQ_S_OB:
15385 check_dspr2(ctx);
15386 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15387 break;
15388 case OPC_ABSQ_S_PW:
15389 check_dsp(ctx);
15390 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15391 break;
15392 case OPC_ABSQ_S_QH:
15393 check_dsp(ctx);
15394 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15395 break;
15396 }
15397 break;
15398 case OPC_ADDU_OB_DSP:
15399 switch (op2) {
15400 case OPC_RADDU_L_OB:
15401 check_dsp(ctx);
15402 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15403 break;
15404 case OPC_SUBQ_PW:
15405 check_dsp(ctx);
15406 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15407 break;
15408 case OPC_SUBQ_S_PW:
15409 check_dsp(ctx);
15410 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15411 break;
15412 case OPC_SUBQ_QH:
15413 check_dsp(ctx);
15414 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15415 break;
15416 case OPC_SUBQ_S_QH:
15417 check_dsp(ctx);
15418 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15419 break;
15420 case OPC_SUBU_OB:
15421 check_dsp(ctx);
15422 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15423 break;
15424 case OPC_SUBU_S_OB:
15425 check_dsp(ctx);
15426 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15427 break;
15428 case OPC_SUBU_QH:
15429 check_dspr2(ctx);
15430 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15431 break;
15432 case OPC_SUBU_S_QH:
15433 check_dspr2(ctx);
15434 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15435 break;
15436 case OPC_SUBUH_OB:
15437 check_dspr2(ctx);
15438 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15439 break;
15440 case OPC_SUBUH_R_OB:
15441 check_dspr2(ctx);
15442 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15443 break;
15444 case OPC_ADDQ_PW:
15445 check_dsp(ctx);
15446 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15447 break;
15448 case OPC_ADDQ_S_PW:
15449 check_dsp(ctx);
15450 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15451 break;
15452 case OPC_ADDQ_QH:
15453 check_dsp(ctx);
15454 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15455 break;
15456 case OPC_ADDQ_S_QH:
15457 check_dsp(ctx);
15458 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15459 break;
15460 case OPC_ADDU_OB:
15461 check_dsp(ctx);
15462 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15463 break;
15464 case OPC_ADDU_S_OB:
15465 check_dsp(ctx);
15466 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15467 break;
15468 case OPC_ADDU_QH:
15469 check_dspr2(ctx);
15470 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15471 break;
15472 case OPC_ADDU_S_QH:
15473 check_dspr2(ctx);
15474 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15475 break;
15476 case OPC_ADDUH_OB:
15477 check_dspr2(ctx);
15478 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15479 break;
15480 case OPC_ADDUH_R_OB:
15481 check_dspr2(ctx);
15482 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15483 break;
15484 }
15485 break;
15486 case OPC_CMPU_EQ_OB_DSP:
15487 switch (op2) {
15488 case OPC_PRECR_OB_QH:
15489 check_dspr2(ctx);
15490 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15491 break;
15492 case OPC_PRECR_SRA_QH_PW:
15493 check_dspr2(ctx);
15494 {
15495 TCGv_i32 ret_t = tcg_const_i32(ret);
15496 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15497 tcg_temp_free_i32(ret_t);
15498 break;
15499 }
15500 case OPC_PRECR_SRA_R_QH_PW:
15501 check_dspr2(ctx);
15502 {
15503 TCGv_i32 sa_v = tcg_const_i32(ret);
15504 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15505 tcg_temp_free_i32(sa_v);
15506 break;
15507 }
15508 case OPC_PRECRQ_OB_QH:
15509 check_dsp(ctx);
15510 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15511 break;
15512 case OPC_PRECRQ_PW_L:
15513 check_dsp(ctx);
15514 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15515 break;
15516 case OPC_PRECRQ_QH_PW:
15517 check_dsp(ctx);
15518 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15519 break;
15520 case OPC_PRECRQ_RS_QH_PW:
15521 check_dsp(ctx);
15522 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15523 break;
15524 case OPC_PRECRQU_S_OB_QH:
15525 check_dsp(ctx);
15526 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15527 break;
15528 }
15529 break;
15530 #endif
15531 }
15532
15533 tcg_temp_free(v1_t);
15534 tcg_temp_free(v2_t);
15535 }
15536
15537 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15538 int ret, int v1, int v2)
15539 {
15540 uint32_t op2;
15541 TCGv t0;
15542 TCGv v1_t;
15543 TCGv v2_t;
15544
15545 if (ret == 0) {
15546 /* Treat as NOP. */
15547 return;
15548 }
15549
15550 t0 = tcg_temp_new();
15551 v1_t = tcg_temp_new();
15552 v2_t = tcg_temp_new();
15553
15554 tcg_gen_movi_tl(t0, v1);
15555 gen_load_gpr(v1_t, v1);
15556 gen_load_gpr(v2_t, v2);
15557
15558 switch (opc) {
15559 case OPC_SHLL_QB_DSP:
15560 {
15561 op2 = MASK_SHLL_QB(ctx->opcode);
15562 switch (op2) {
15563 case OPC_SHLL_QB:
15564 check_dsp(ctx);
15565 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15566 break;
15567 case OPC_SHLLV_QB:
15568 check_dsp(ctx);
15569 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15570 break;
15571 case OPC_SHLL_PH:
15572 check_dsp(ctx);
15573 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15574 break;
15575 case OPC_SHLLV_PH:
15576 check_dsp(ctx);
15577 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15578 break;
15579 case OPC_SHLL_S_PH:
15580 check_dsp(ctx);
15581 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15582 break;
15583 case OPC_SHLLV_S_PH:
15584 check_dsp(ctx);
15585 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15586 break;
15587 case OPC_SHLL_S_W:
15588 check_dsp(ctx);
15589 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15590 break;
15591 case OPC_SHLLV_S_W:
15592 check_dsp(ctx);
15593 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15594 break;
15595 case OPC_SHRL_QB:
15596 check_dsp(ctx);
15597 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15598 break;
15599 case OPC_SHRLV_QB:
15600 check_dsp(ctx);
15601 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15602 break;
15603 case OPC_SHRL_PH:
15604 check_dspr2(ctx);
15605 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15606 break;
15607 case OPC_SHRLV_PH:
15608 check_dspr2(ctx);
15609 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15610 break;
15611 case OPC_SHRA_QB:
15612 check_dspr2(ctx);
15613 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15614 break;
15615 case OPC_SHRA_R_QB:
15616 check_dspr2(ctx);
15617 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15618 break;
15619 case OPC_SHRAV_QB:
15620 check_dspr2(ctx);
15621 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15622 break;
15623 case OPC_SHRAV_R_QB:
15624 check_dspr2(ctx);
15625 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15626 break;
15627 case OPC_SHRA_PH:
15628 check_dsp(ctx);
15629 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15630 break;
15631 case OPC_SHRA_R_PH:
15632 check_dsp(ctx);
15633 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15634 break;
15635 case OPC_SHRAV_PH:
15636 check_dsp(ctx);
15637 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15638 break;
15639 case OPC_SHRAV_R_PH:
15640 check_dsp(ctx);
15641 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15642 break;
15643 case OPC_SHRA_R_W:
15644 check_dsp(ctx);
15645 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15646 break;
15647 case OPC_SHRAV_R_W:
15648 check_dsp(ctx);
15649 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15650 break;
15651 default: /* Invalid */
15652 MIPS_INVAL("MASK SHLL.QB");
15653 generate_exception_end(ctx, EXCP_RI);
15654 break;
15655 }
15656 break;
15657 }
15658 #ifdef TARGET_MIPS64
15659 case OPC_SHLL_OB_DSP:
15660 op2 = MASK_SHLL_OB(ctx->opcode);
15661 switch (op2) {
15662 case OPC_SHLL_PW:
15663 check_dsp(ctx);
15664 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15665 break;
15666 case OPC_SHLLV_PW:
15667 check_dsp(ctx);
15668 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15669 break;
15670 case OPC_SHLL_S_PW:
15671 check_dsp(ctx);
15672 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15673 break;
15674 case OPC_SHLLV_S_PW:
15675 check_dsp(ctx);
15676 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15677 break;
15678 case OPC_SHLL_OB:
15679 check_dsp(ctx);
15680 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15681 break;
15682 case OPC_SHLLV_OB:
15683 check_dsp(ctx);
15684 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15685 break;
15686 case OPC_SHLL_QH:
15687 check_dsp(ctx);
15688 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15689 break;
15690 case OPC_SHLLV_QH:
15691 check_dsp(ctx);
15692 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15693 break;
15694 case OPC_SHLL_S_QH:
15695 check_dsp(ctx);
15696 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15697 break;
15698 case OPC_SHLLV_S_QH:
15699 check_dsp(ctx);
15700 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15701 break;
15702 case OPC_SHRA_OB:
15703 check_dspr2(ctx);
15704 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15705 break;
15706 case OPC_SHRAV_OB:
15707 check_dspr2(ctx);
15708 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15709 break;
15710 case OPC_SHRA_R_OB:
15711 check_dspr2(ctx);
15712 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15713 break;
15714 case OPC_SHRAV_R_OB:
15715 check_dspr2(ctx);
15716 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15717 break;
15718 case OPC_SHRA_PW:
15719 check_dsp(ctx);
15720 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15721 break;
15722 case OPC_SHRAV_PW:
15723 check_dsp(ctx);
15724 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15725 break;
15726 case OPC_SHRA_R_PW:
15727 check_dsp(ctx);
15728 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15729 break;
15730 case OPC_SHRAV_R_PW:
15731 check_dsp(ctx);
15732 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15733 break;
15734 case OPC_SHRA_QH:
15735 check_dsp(ctx);
15736 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15737 break;
15738 case OPC_SHRAV_QH:
15739 check_dsp(ctx);
15740 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15741 break;
15742 case OPC_SHRA_R_QH:
15743 check_dsp(ctx);
15744 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15745 break;
15746 case OPC_SHRAV_R_QH:
15747 check_dsp(ctx);
15748 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15749 break;
15750 case OPC_SHRL_OB:
15751 check_dsp(ctx);
15752 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15753 break;
15754 case OPC_SHRLV_OB:
15755 check_dsp(ctx);
15756 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15757 break;
15758 case OPC_SHRL_QH:
15759 check_dspr2(ctx);
15760 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15761 break;
15762 case OPC_SHRLV_QH:
15763 check_dspr2(ctx);
15764 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15765 break;
15766 default: /* Invalid */
15767 MIPS_INVAL("MASK SHLL.OB");
15768 generate_exception_end(ctx, EXCP_RI);
15769 break;
15770 }
15771 break;
15772 #endif
15773 }
15774
15775 tcg_temp_free(t0);
15776 tcg_temp_free(v1_t);
15777 tcg_temp_free(v2_t);
15778 }
15779
15780 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15781 int ret, int v1, int v2, int check_ret)
15782 {
15783 TCGv_i32 t0;
15784 TCGv v1_t;
15785 TCGv v2_t;
15786
15787 if ((ret == 0) && (check_ret == 1)) {
15788 /* Treat as NOP. */
15789 return;
15790 }
15791
15792 t0 = tcg_temp_new_i32();
15793 v1_t = tcg_temp_new();
15794 v2_t = tcg_temp_new();
15795
15796 tcg_gen_movi_i32(t0, ret);
15797 gen_load_gpr(v1_t, v1);
15798 gen_load_gpr(v2_t, v2);
15799
15800 switch (op1) {
15801 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15802 * the same mask and op1. */
15803 case OPC_MULT_G_2E:
15804 check_dspr2(ctx);
15805 switch (op2) {
15806 case OPC_MUL_PH:
15807 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15808 break;
15809 case OPC_MUL_S_PH:
15810 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15811 break;
15812 case OPC_MULQ_S_W:
15813 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15814 break;
15815 case OPC_MULQ_RS_W:
15816 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15817 break;
15818 }
15819 break;
15820 case OPC_DPA_W_PH_DSP:
15821 switch (op2) {
15822 case OPC_DPAU_H_QBL:
15823 check_dsp(ctx);
15824 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15825 break;
15826 case OPC_DPAU_H_QBR:
15827 check_dsp(ctx);
15828 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15829 break;
15830 case OPC_DPSU_H_QBL:
15831 check_dsp(ctx);
15832 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15833 break;
15834 case OPC_DPSU_H_QBR:
15835 check_dsp(ctx);
15836 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15837 break;
15838 case OPC_DPA_W_PH:
15839 check_dspr2(ctx);
15840 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15841 break;
15842 case OPC_DPAX_W_PH:
15843 check_dspr2(ctx);
15844 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15845 break;
15846 case OPC_DPAQ_S_W_PH:
15847 check_dsp(ctx);
15848 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15849 break;
15850 case OPC_DPAQX_S_W_PH:
15851 check_dspr2(ctx);
15852 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15853 break;
15854 case OPC_DPAQX_SA_W_PH:
15855 check_dspr2(ctx);
15856 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15857 break;
15858 case OPC_DPS_W_PH:
15859 check_dspr2(ctx);
15860 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15861 break;
15862 case OPC_DPSX_W_PH:
15863 check_dspr2(ctx);
15864 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15865 break;
15866 case OPC_DPSQ_S_W_PH:
15867 check_dsp(ctx);
15868 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15869 break;
15870 case OPC_DPSQX_S_W_PH:
15871 check_dspr2(ctx);
15872 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15873 break;
15874 case OPC_DPSQX_SA_W_PH:
15875 check_dspr2(ctx);
15876 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15877 break;
15878 case OPC_MULSAQ_S_W_PH:
15879 check_dsp(ctx);
15880 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15881 break;
15882 case OPC_DPAQ_SA_L_W:
15883 check_dsp(ctx);
15884 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15885 break;
15886 case OPC_DPSQ_SA_L_W:
15887 check_dsp(ctx);
15888 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15889 break;
15890 case OPC_MAQ_S_W_PHL:
15891 check_dsp(ctx);
15892 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15893 break;
15894 case OPC_MAQ_S_W_PHR:
15895 check_dsp(ctx);
15896 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15897 break;
15898 case OPC_MAQ_SA_W_PHL:
15899 check_dsp(ctx);
15900 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15901 break;
15902 case OPC_MAQ_SA_W_PHR:
15903 check_dsp(ctx);
15904 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15905 break;
15906 case OPC_MULSA_W_PH:
15907 check_dspr2(ctx);
15908 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15909 break;
15910 }
15911 break;
15912 #ifdef TARGET_MIPS64
15913 case OPC_DPAQ_W_QH_DSP:
15914 {
15915 int ac = ret & 0x03;
15916 tcg_gen_movi_i32(t0, ac);
15917
15918 switch (op2) {
15919 case OPC_DMADD:
15920 check_dsp(ctx);
15921 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15922 break;
15923 case OPC_DMADDU:
15924 check_dsp(ctx);
15925 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15926 break;
15927 case OPC_DMSUB:
15928 check_dsp(ctx);
15929 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15930 break;
15931 case OPC_DMSUBU:
15932 check_dsp(ctx);
15933 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15934 break;
15935 case OPC_DPA_W_QH:
15936 check_dspr2(ctx);
15937 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15938 break;
15939 case OPC_DPAQ_S_W_QH:
15940 check_dsp(ctx);
15941 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15942 break;
15943 case OPC_DPAQ_SA_L_PW:
15944 check_dsp(ctx);
15945 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15946 break;
15947 case OPC_DPAU_H_OBL:
15948 check_dsp(ctx);
15949 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15950 break;
15951 case OPC_DPAU_H_OBR:
15952 check_dsp(ctx);
15953 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15954 break;
15955 case OPC_DPS_W_QH:
15956 check_dspr2(ctx);
15957 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15958 break;
15959 case OPC_DPSQ_S_W_QH:
15960 check_dsp(ctx);
15961 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15962 break;
15963 case OPC_DPSQ_SA_L_PW:
15964 check_dsp(ctx);
15965 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15966 break;
15967 case OPC_DPSU_H_OBL:
15968 check_dsp(ctx);
15969 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15970 break;
15971 case OPC_DPSU_H_OBR:
15972 check_dsp(ctx);
15973 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15974 break;
15975 case OPC_MAQ_S_L_PWL:
15976 check_dsp(ctx);
15977 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15978 break;
15979 case OPC_MAQ_S_L_PWR:
15980 check_dsp(ctx);
15981 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15982 break;
15983 case OPC_MAQ_S_W_QHLL:
15984 check_dsp(ctx);
15985 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15986 break;
15987 case OPC_MAQ_SA_W_QHLL:
15988 check_dsp(ctx);
15989 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15990 break;
15991 case OPC_MAQ_S_W_QHLR:
15992 check_dsp(ctx);
15993 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15994 break;
15995 case OPC_MAQ_SA_W_QHLR:
15996 check_dsp(ctx);
15997 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15998 break;
15999 case OPC_MAQ_S_W_QHRL:
16000 check_dsp(ctx);
16001 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
16002 break;
16003 case OPC_MAQ_SA_W_QHRL:
16004 check_dsp(ctx);
16005 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
16006 break;
16007 case OPC_MAQ_S_W_QHRR:
16008 check_dsp(ctx);
16009 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
16010 break;
16011 case OPC_MAQ_SA_W_QHRR:
16012 check_dsp(ctx);
16013 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
16014 break;
16015 case OPC_MULSAQ_S_L_PW:
16016 check_dsp(ctx);
16017 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
16018 break;
16019 case OPC_MULSAQ_S_W_QH:
16020 check_dsp(ctx);
16021 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
16022 break;
16023 }
16024 }
16025 break;
16026 #endif
16027 case OPC_ADDU_QB_DSP:
16028 switch (op2) {
16029 case OPC_MULEU_S_PH_QBL:
16030 check_dsp(ctx);
16031 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16032 break;
16033 case OPC_MULEU_S_PH_QBR:
16034 check_dsp(ctx);
16035 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16036 break;
16037 case OPC_MULQ_RS_PH:
16038 check_dsp(ctx);
16039 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16040 break;
16041 case OPC_MULEQ_S_W_PHL:
16042 check_dsp(ctx);
16043 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16044 break;
16045 case OPC_MULEQ_S_W_PHR:
16046 check_dsp(ctx);
16047 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16048 break;
16049 case OPC_MULQ_S_PH:
16050 check_dspr2(ctx);
16051 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16052 break;
16053 }
16054 break;
16055 #ifdef TARGET_MIPS64
16056 case OPC_ADDU_OB_DSP:
16057 switch (op2) {
16058 case OPC_MULEQ_S_PW_QHL:
16059 check_dsp(ctx);
16060 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16061 break;
16062 case OPC_MULEQ_S_PW_QHR:
16063 check_dsp(ctx);
16064 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16065 break;
16066 case OPC_MULEU_S_QH_OBL:
16067 check_dsp(ctx);
16068 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16069 break;
16070 case OPC_MULEU_S_QH_OBR:
16071 check_dsp(ctx);
16072 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16073 break;
16074 case OPC_MULQ_RS_QH:
16075 check_dsp(ctx);
16076 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16077 break;
16078 }
16079 break;
16080 #endif
16081 }
16082
16083 tcg_temp_free_i32(t0);
16084 tcg_temp_free(v1_t);
16085 tcg_temp_free(v2_t);
16086 }
16087
16088 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16089 int ret, int val)
16090 {
16091 int16_t imm;
16092 TCGv t0;
16093 TCGv val_t;
16094
16095 if (ret == 0) {
16096 /* Treat as NOP. */
16097 return;
16098 }
16099
16100 t0 = tcg_temp_new();
16101 val_t = tcg_temp_new();
16102 gen_load_gpr(val_t, val);
16103
16104 switch (op1) {
16105 case OPC_ABSQ_S_PH_DSP:
16106 switch (op2) {
16107 case OPC_BITREV:
16108 check_dsp(ctx);
16109 gen_helper_bitrev(cpu_gpr[ret], val_t);
16110 break;
16111 case OPC_REPL_QB:
16112 check_dsp(ctx);
16113 {
16114 target_long result;
16115 imm = (ctx->opcode >> 16) & 0xFF;
16116 result = (uint32_t)imm << 24 |
16117 (uint32_t)imm << 16 |
16118 (uint32_t)imm << 8 |
16119 (uint32_t)imm;
16120 result = (int32_t)result;
16121 tcg_gen_movi_tl(cpu_gpr[ret], result);
16122 }
16123 break;
16124 case OPC_REPLV_QB:
16125 check_dsp(ctx);
16126 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16127 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16128 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16129 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16130 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16131 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16132 break;
16133 case OPC_REPL_PH:
16134 check_dsp(ctx);
16135 {
16136 imm = (ctx->opcode >> 16) & 0x03FF;
16137 imm = (int16_t)(imm << 6) >> 6;
16138 tcg_gen_movi_tl(cpu_gpr[ret], \
16139 (target_long)((int32_t)imm << 16 | \
16140 (uint16_t)imm));
16141 }
16142 break;
16143 case OPC_REPLV_PH:
16144 check_dsp(ctx);
16145 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16146 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16147 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16148 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16149 break;
16150 }
16151 break;
16152 #ifdef TARGET_MIPS64
16153 case OPC_ABSQ_S_QH_DSP:
16154 switch (op2) {
16155 case OPC_REPL_OB:
16156 check_dsp(ctx);
16157 {
16158 target_long temp;
16159
16160 imm = (ctx->opcode >> 16) & 0xFF;
16161 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16162 temp = (temp << 16) | temp;
16163 temp = (temp << 32) | temp;
16164 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16165 break;
16166 }
16167 case OPC_REPL_PW:
16168 check_dsp(ctx);
16169 {
16170 target_long temp;
16171
16172 imm = (ctx->opcode >> 16) & 0x03FF;
16173 imm = (int16_t)(imm << 6) >> 6;
16174 temp = ((target_long)imm << 32) \
16175 | ((target_long)imm & 0xFFFFFFFF);
16176 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16177 break;
16178 }
16179 case OPC_REPL_QH:
16180 check_dsp(ctx);
16181 {
16182 target_long temp;
16183
16184 imm = (ctx->opcode >> 16) & 0x03FF;
16185 imm = (int16_t)(imm << 6) >> 6;
16186
16187 temp = ((uint64_t)(uint16_t)imm << 48) |
16188 ((uint64_t)(uint16_t)imm << 32) |
16189 ((uint64_t)(uint16_t)imm << 16) |
16190 (uint64_t)(uint16_t)imm;
16191 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16192 break;
16193 }
16194 case OPC_REPLV_OB:
16195 check_dsp(ctx);
16196 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16197 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16198 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16199 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16200 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16201 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16202 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16203 break;
16204 case OPC_REPLV_PW:
16205 check_dsp(ctx);
16206 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16207 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16208 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16209 break;
16210 case OPC_REPLV_QH:
16211 check_dsp(ctx);
16212 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16213 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16214 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16215 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16216 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16217 break;
16218 }
16219 break;
16220 #endif
16221 }
16222 tcg_temp_free(t0);
16223 tcg_temp_free(val_t);
16224 }
16225
16226 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16227 uint32_t op1, uint32_t op2,
16228 int ret, int v1, int v2, int check_ret)
16229 {
16230 TCGv t1;
16231 TCGv v1_t;
16232 TCGv v2_t;
16233
16234 if ((ret == 0) && (check_ret == 1)) {
16235 /* Treat as NOP. */
16236 return;
16237 }
16238
16239 t1 = tcg_temp_new();
16240 v1_t = tcg_temp_new();
16241 v2_t = tcg_temp_new();
16242
16243 gen_load_gpr(v1_t, v1);
16244 gen_load_gpr(v2_t, v2);
16245
16246 switch (op1) {
16247 case OPC_CMPU_EQ_QB_DSP:
16248 switch (op2) {
16249 case OPC_CMPU_EQ_QB:
16250 check_dsp(ctx);
16251 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16252 break;
16253 case OPC_CMPU_LT_QB:
16254 check_dsp(ctx);
16255 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16256 break;
16257 case OPC_CMPU_LE_QB:
16258 check_dsp(ctx);
16259 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16260 break;
16261 case OPC_CMPGU_EQ_QB:
16262 check_dsp(ctx);
16263 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16264 break;
16265 case OPC_CMPGU_LT_QB:
16266 check_dsp(ctx);
16267 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16268 break;
16269 case OPC_CMPGU_LE_QB:
16270 check_dsp(ctx);
16271 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16272 break;
16273 case OPC_CMPGDU_EQ_QB:
16274 check_dspr2(ctx);
16275 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16276 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16277 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16278 tcg_gen_shli_tl(t1, t1, 24);
16279 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16280 break;
16281 case OPC_CMPGDU_LT_QB:
16282 check_dspr2(ctx);
16283 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16284 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16285 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16286 tcg_gen_shli_tl(t1, t1, 24);
16287 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16288 break;
16289 case OPC_CMPGDU_LE_QB:
16290 check_dspr2(ctx);
16291 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16292 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16293 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16294 tcg_gen_shli_tl(t1, t1, 24);
16295 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16296 break;
16297 case OPC_CMP_EQ_PH:
16298 check_dsp(ctx);
16299 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16300 break;
16301 case OPC_CMP_LT_PH:
16302 check_dsp(ctx);
16303 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16304 break;
16305 case OPC_CMP_LE_PH:
16306 check_dsp(ctx);
16307 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16308 break;
16309 case OPC_PICK_QB:
16310 check_dsp(ctx);
16311 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16312 break;
16313 case OPC_PICK_PH:
16314 check_dsp(ctx);
16315 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16316 break;
16317 case OPC_PACKRL_PH:
16318 check_dsp(ctx);
16319 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16320 break;
16321 }
16322 break;
16323 #ifdef TARGET_MIPS64
16324 case OPC_CMPU_EQ_OB_DSP:
16325 switch (op2) {
16326 case OPC_CMP_EQ_PW:
16327 check_dsp(ctx);
16328 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16329 break;
16330 case OPC_CMP_LT_PW:
16331 check_dsp(ctx);
16332 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16333 break;
16334 case OPC_CMP_LE_PW:
16335 check_dsp(ctx);
16336 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16337 break;
16338 case OPC_CMP_EQ_QH:
16339 check_dsp(ctx);
16340 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16341 break;
16342 case OPC_CMP_LT_QH:
16343 check_dsp(ctx);
16344 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16345 break;
16346 case OPC_CMP_LE_QH:
16347 check_dsp(ctx);
16348 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16349 break;
16350 case OPC_CMPGDU_EQ_OB:
16351 check_dspr2(ctx);
16352 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16353 break;
16354 case OPC_CMPGDU_LT_OB:
16355 check_dspr2(ctx);
16356 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16357 break;
16358 case OPC_CMPGDU_LE_OB:
16359 check_dspr2(ctx);
16360 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16361 break;
16362 case OPC_CMPGU_EQ_OB:
16363 check_dsp(ctx);
16364 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16365 break;
16366 case OPC_CMPGU_LT_OB:
16367 check_dsp(ctx);
16368 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16369 break;
16370 case OPC_CMPGU_LE_OB:
16371 check_dsp(ctx);
16372 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16373 break;
16374 case OPC_CMPU_EQ_OB:
16375 check_dsp(ctx);
16376 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16377 break;
16378 case OPC_CMPU_LT_OB:
16379 check_dsp(ctx);
16380 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16381 break;
16382 case OPC_CMPU_LE_OB:
16383 check_dsp(ctx);
16384 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16385 break;
16386 case OPC_PACKRL_PW:
16387 check_dsp(ctx);
16388 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16389 break;
16390 case OPC_PICK_OB:
16391 check_dsp(ctx);
16392 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16393 break;
16394 case OPC_PICK_PW:
16395 check_dsp(ctx);
16396 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16397 break;
16398 case OPC_PICK_QH:
16399 check_dsp(ctx);
16400 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16401 break;
16402 }
16403 break;
16404 #endif
16405 }
16406
16407 tcg_temp_free(t1);
16408 tcg_temp_free(v1_t);
16409 tcg_temp_free(v2_t);
16410 }
16411
16412 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16413 uint32_t op1, int rt, int rs, int sa)
16414 {
16415 TCGv t0;
16416
16417 check_dspr2(ctx);
16418
16419 if (rt == 0) {
16420 /* Treat as NOP. */
16421 return;
16422 }
16423
16424 t0 = tcg_temp_new();
16425 gen_load_gpr(t0, rs);
16426
16427 switch (op1) {
16428 case OPC_APPEND_DSP:
16429 switch (MASK_APPEND(ctx->opcode)) {
16430 case OPC_APPEND:
16431 if (sa != 0) {
16432 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16433 }
16434 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16435 break;
16436 case OPC_PREPEND:
16437 if (sa != 0) {
16438 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16439 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16440 tcg_gen_shli_tl(t0, t0, 32 - sa);
16441 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16442 }
16443 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16444 break;
16445 case OPC_BALIGN:
16446 sa &= 3;
16447 if (sa != 0 && sa != 2) {
16448 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16449 tcg_gen_ext32u_tl(t0, t0);
16450 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16451 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16452 }
16453 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16454 break;
16455 default: /* Invalid */
16456 MIPS_INVAL("MASK APPEND");
16457 generate_exception_end(ctx, EXCP_RI);
16458 break;
16459 }
16460 break;
16461 #ifdef TARGET_MIPS64
16462 case OPC_DAPPEND_DSP:
16463 switch (MASK_DAPPEND(ctx->opcode)) {
16464 case OPC_DAPPEND:
16465 if (sa != 0) {
16466 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16467 }
16468 break;
16469 case OPC_PREPENDD:
16470 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16471 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16472 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16473 break;
16474 case OPC_PREPENDW:
16475 if (sa != 0) {
16476 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16477 tcg_gen_shli_tl(t0, t0, 64 - sa);
16478 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16479 }
16480 break;
16481 case OPC_DBALIGN:
16482 sa &= 7;
16483 if (sa != 0 && sa != 2 && sa != 4) {
16484 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16485 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16486 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16487 }
16488 break;
16489 default: /* Invalid */
16490 MIPS_INVAL("MASK DAPPEND");
16491 generate_exception_end(ctx, EXCP_RI);
16492 break;
16493 }
16494 break;
16495 #endif
16496 }
16497 tcg_temp_free(t0);
16498 }
16499
16500 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16501 int ret, int v1, int v2, int check_ret)
16502
16503 {
16504 TCGv t0;
16505 TCGv t1;
16506 TCGv v1_t;
16507 TCGv v2_t;
16508 int16_t imm;
16509
16510 if ((ret == 0) && (check_ret == 1)) {
16511 /* Treat as NOP. */
16512 return;
16513 }
16514
16515 t0 = tcg_temp_new();
16516 t1 = tcg_temp_new();
16517 v1_t = tcg_temp_new();
16518 v2_t = tcg_temp_new();
16519
16520 gen_load_gpr(v1_t, v1);
16521 gen_load_gpr(v2_t, v2);
16522
16523 switch (op1) {
16524 case OPC_EXTR_W_DSP:
16525 check_dsp(ctx);
16526 switch (op2) {
16527 case OPC_EXTR_W:
16528 tcg_gen_movi_tl(t0, v2);
16529 tcg_gen_movi_tl(t1, v1);
16530 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16531 break;
16532 case OPC_EXTR_R_W:
16533 tcg_gen_movi_tl(t0, v2);
16534 tcg_gen_movi_tl(t1, v1);
16535 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16536 break;
16537 case OPC_EXTR_RS_W:
16538 tcg_gen_movi_tl(t0, v2);
16539 tcg_gen_movi_tl(t1, v1);
16540 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16541 break;
16542 case OPC_EXTR_S_H:
16543 tcg_gen_movi_tl(t0, v2);
16544 tcg_gen_movi_tl(t1, v1);
16545 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16546 break;
16547 case OPC_EXTRV_S_H:
16548 tcg_gen_movi_tl(t0, v2);
16549 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16550 break;
16551 case OPC_EXTRV_W:
16552 tcg_gen_movi_tl(t0, v2);
16553 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16554 break;
16555 case OPC_EXTRV_R_W:
16556 tcg_gen_movi_tl(t0, v2);
16557 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16558 break;
16559 case OPC_EXTRV_RS_W:
16560 tcg_gen_movi_tl(t0, v2);
16561 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16562 break;
16563 case OPC_EXTP:
16564 tcg_gen_movi_tl(t0, v2);
16565 tcg_gen_movi_tl(t1, v1);
16566 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16567 break;
16568 case OPC_EXTPV:
16569 tcg_gen_movi_tl(t0, v2);
16570 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16571 break;
16572 case OPC_EXTPDP:
16573 tcg_gen_movi_tl(t0, v2);
16574 tcg_gen_movi_tl(t1, v1);
16575 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16576 break;
16577 case OPC_EXTPDPV:
16578 tcg_gen_movi_tl(t0, v2);
16579 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16580 break;
16581 case OPC_SHILO:
16582 imm = (ctx->opcode >> 20) & 0x3F;
16583 tcg_gen_movi_tl(t0, ret);
16584 tcg_gen_movi_tl(t1, imm);
16585 gen_helper_shilo(t0, t1, cpu_env);
16586 break;
16587 case OPC_SHILOV:
16588 tcg_gen_movi_tl(t0, ret);
16589 gen_helper_shilo(t0, v1_t, cpu_env);
16590 break;
16591 case OPC_MTHLIP:
16592 tcg_gen_movi_tl(t0, ret);
16593 gen_helper_mthlip(t0, v1_t, cpu_env);
16594 break;
16595 case OPC_WRDSP:
16596 imm = (ctx->opcode >> 11) & 0x3FF;
16597 tcg_gen_movi_tl(t0, imm);
16598 gen_helper_wrdsp(v1_t, t0, cpu_env);
16599 break;
16600 case OPC_RDDSP:
16601 imm = (ctx->opcode >> 16) & 0x03FF;
16602 tcg_gen_movi_tl(t0, imm);
16603 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16604 break;
16605 }
16606 break;
16607 #ifdef TARGET_MIPS64
16608 case OPC_DEXTR_W_DSP:
16609 check_dsp(ctx);
16610 switch (op2) {
16611 case OPC_DMTHLIP:
16612 tcg_gen_movi_tl(t0, ret);
16613 gen_helper_dmthlip(v1_t, t0, cpu_env);
16614 break;
16615 case OPC_DSHILO:
16616 {
16617 int shift = (ctx->opcode >> 19) & 0x7F;
16618 int ac = (ctx->opcode >> 11) & 0x03;
16619 tcg_gen_movi_tl(t0, shift);
16620 tcg_gen_movi_tl(t1, ac);
16621 gen_helper_dshilo(t0, t1, cpu_env);
16622 break;
16623 }
16624 case OPC_DSHILOV:
16625 {
16626 int ac = (ctx->opcode >> 11) & 0x03;
16627 tcg_gen_movi_tl(t0, ac);
16628 gen_helper_dshilo(v1_t, t0, cpu_env);
16629 break;
16630 }
16631 case OPC_DEXTP:
16632 tcg_gen_movi_tl(t0, v2);
16633 tcg_gen_movi_tl(t1, v1);
16634
16635 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16636 break;
16637 case OPC_DEXTPV:
16638 tcg_gen_movi_tl(t0, v2);
16639 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16640 break;
16641 case OPC_DEXTPDP:
16642 tcg_gen_movi_tl(t0, v2);
16643 tcg_gen_movi_tl(t1, v1);
16644 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16645 break;
16646 case OPC_DEXTPDPV:
16647 tcg_gen_movi_tl(t0, v2);
16648 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16649 break;
16650 case OPC_DEXTR_L:
16651 tcg_gen_movi_tl(t0, v2);
16652 tcg_gen_movi_tl(t1, v1);
16653 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16654 break;
16655 case OPC_DEXTR_R_L:
16656 tcg_gen_movi_tl(t0, v2);
16657 tcg_gen_movi_tl(t1, v1);
16658 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16659 break;
16660 case OPC_DEXTR_RS_L:
16661 tcg_gen_movi_tl(t0, v2);
16662 tcg_gen_movi_tl(t1, v1);
16663 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16664 break;
16665 case OPC_DEXTR_W:
16666 tcg_gen_movi_tl(t0, v2);
16667 tcg_gen_movi_tl(t1, v1);
16668 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16669 break;
16670 case OPC_DEXTR_R_W:
16671 tcg_gen_movi_tl(t0, v2);
16672 tcg_gen_movi_tl(t1, v1);
16673 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16674 break;
16675 case OPC_DEXTR_RS_W:
16676 tcg_gen_movi_tl(t0, v2);
16677 tcg_gen_movi_tl(t1, v1);
16678 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16679 break;
16680 case OPC_DEXTR_S_H:
16681 tcg_gen_movi_tl(t0, v2);
16682 tcg_gen_movi_tl(t1, v1);
16683 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16684 break;
16685 case OPC_DEXTRV_S_H:
16686 tcg_gen_movi_tl(t0, v2);
16687 tcg_gen_movi_tl(t1, v1);
16688 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16689 break;
16690 case OPC_DEXTRV_L:
16691 tcg_gen_movi_tl(t0, v2);
16692 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16693 break;
16694 case OPC_DEXTRV_R_L:
16695 tcg_gen_movi_tl(t0, v2);
16696 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16697 break;
16698 case OPC_DEXTRV_RS_L:
16699 tcg_gen_movi_tl(t0, v2);
16700 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16701 break;
16702 case OPC_DEXTRV_W:
16703 tcg_gen_movi_tl(t0, v2);
16704 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16705 break;
16706 case OPC_DEXTRV_R_W:
16707 tcg_gen_movi_tl(t0, v2);
16708 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16709 break;
16710 case OPC_DEXTRV_RS_W:
16711 tcg_gen_movi_tl(t0, v2);
16712 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16713 break;
16714 }
16715 break;
16716 #endif
16717 }
16718
16719 tcg_temp_free(t0);
16720 tcg_temp_free(t1);
16721 tcg_temp_free(v1_t);
16722 tcg_temp_free(v2_t);
16723 }
16724
16725 /* End MIPSDSP functions. */
16726
16727 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16728 {
16729 int rs, rt, rd, sa;
16730 uint32_t op1, op2;
16731
16732 rs = (ctx->opcode >> 21) & 0x1f;
16733 rt = (ctx->opcode >> 16) & 0x1f;
16734 rd = (ctx->opcode >> 11) & 0x1f;
16735 sa = (ctx->opcode >> 6) & 0x1f;
16736
16737 op1 = MASK_SPECIAL(ctx->opcode);
16738 switch (op1) {
16739 case OPC_LSA:
16740 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16741 break;
16742 case OPC_MULT ... OPC_DIVU:
16743 op2 = MASK_R6_MULDIV(ctx->opcode);
16744 switch (op2) {
16745 case R6_OPC_MUL:
16746 case R6_OPC_MUH:
16747 case R6_OPC_MULU:
16748 case R6_OPC_MUHU:
16749 case R6_OPC_DIV:
16750 case R6_OPC_MOD:
16751 case R6_OPC_DIVU:
16752 case R6_OPC_MODU:
16753 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16754 break;
16755 default:
16756 MIPS_INVAL("special_r6 muldiv");
16757 generate_exception_end(ctx, EXCP_RI);
16758 break;
16759 }
16760 break;
16761 case OPC_SELEQZ:
16762 case OPC_SELNEZ:
16763 gen_cond_move(ctx, op1, rd, rs, rt);
16764 break;
16765 case R6_OPC_CLO:
16766 case R6_OPC_CLZ:
16767 if (rt == 0 && sa == 1) {
16768 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16769 We need additionally to check other fields */
16770 gen_cl(ctx, op1, rd, rs);
16771 } else {
16772 generate_exception_end(ctx, EXCP_RI);
16773 }
16774 break;
16775 case R6_OPC_SDBBP:
16776 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16777 gen_helper_do_semihosting(cpu_env);
16778 } else {
16779 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16780 generate_exception_end(ctx, EXCP_RI);
16781 } else {
16782 generate_exception_end(ctx, EXCP_DBp);
16783 }
16784 }
16785 break;
16786 #if defined(TARGET_MIPS64)
16787 case OPC_DLSA:
16788 check_mips_64(ctx);
16789 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16790 break;
16791 case R6_OPC_DCLO:
16792 case R6_OPC_DCLZ:
16793 if (rt == 0 && sa == 1) {
16794 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16795 We need additionally to check other fields */
16796 check_mips_64(ctx);
16797 gen_cl(ctx, op1, rd, rs);
16798 } else {
16799 generate_exception_end(ctx, EXCP_RI);
16800 }
16801 break;
16802 case OPC_DMULT ... OPC_DDIVU:
16803 op2 = MASK_R6_MULDIV(ctx->opcode);
16804 switch (op2) {
16805 case R6_OPC_DMUL:
16806 case R6_OPC_DMUH:
16807 case R6_OPC_DMULU:
16808 case R6_OPC_DMUHU:
16809 case R6_OPC_DDIV:
16810 case R6_OPC_DMOD:
16811 case R6_OPC_DDIVU:
16812 case R6_OPC_DMODU:
16813 check_mips_64(ctx);
16814 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16815 break;
16816 default:
16817 MIPS_INVAL("special_r6 muldiv");
16818 generate_exception_end(ctx, EXCP_RI);
16819 break;
16820 }
16821 break;
16822 #endif
16823 default: /* Invalid */
16824 MIPS_INVAL("special_r6");
16825 generate_exception_end(ctx, EXCP_RI);
16826 break;
16827 }
16828 }
16829
16830 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16831 {
16832 int rs, rt, rd, sa;
16833 uint32_t op1;
16834
16835 rs = (ctx->opcode >> 21) & 0x1f;
16836 rt = (ctx->opcode >> 16) & 0x1f;
16837 rd = (ctx->opcode >> 11) & 0x1f;
16838 sa = (ctx->opcode >> 6) & 0x1f;
16839
16840 op1 = MASK_SPECIAL(ctx->opcode);
16841 switch (op1) {
16842 case OPC_MOVN: /* Conditional move */
16843 case OPC_MOVZ:
16844 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16845 INSN_LOONGSON2E | INSN_LOONGSON2F);
16846 gen_cond_move(ctx, op1, rd, rs, rt);
16847 break;
16848 case OPC_MFHI: /* Move from HI/LO */
16849 case OPC_MFLO:
16850 gen_HILO(ctx, op1, rs & 3, rd);
16851 break;
16852 case OPC_MTHI:
16853 case OPC_MTLO: /* Move to HI/LO */
16854 gen_HILO(ctx, op1, rd & 3, rs);
16855 break;
16856 case OPC_MOVCI:
16857 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16858 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16859 check_cp1_enabled(ctx);
16860 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16861 (ctx->opcode >> 16) & 1);
16862 } else {
16863 generate_exception_err(ctx, EXCP_CpU, 1);
16864 }
16865 break;
16866 case OPC_MULT:
16867 case OPC_MULTU:
16868 if (sa) {
16869 check_insn(ctx, INSN_VR54XX);
16870 op1 = MASK_MUL_VR54XX(ctx->opcode);
16871 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16872 } else {
16873 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16874 }
16875 break;
16876 case OPC_DIV:
16877 case OPC_DIVU:
16878 gen_muldiv(ctx, op1, 0, rs, rt);
16879 break;
16880 #if defined(TARGET_MIPS64)
16881 case OPC_DMULT ... OPC_DDIVU:
16882 check_insn(ctx, ISA_MIPS3);
16883 check_mips_64(ctx);
16884 gen_muldiv(ctx, op1, 0, rs, rt);
16885 break;
16886 #endif
16887 case OPC_JR:
16888 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16889 break;
16890 case OPC_SPIM:
16891 #ifdef MIPS_STRICT_STANDARD
16892 MIPS_INVAL("SPIM");
16893 generate_exception_end(ctx, EXCP_RI);
16894 #else
16895 /* Implemented as RI exception for now. */
16896 MIPS_INVAL("spim (unofficial)");
16897 generate_exception_end(ctx, EXCP_RI);
16898 #endif
16899 break;
16900 default: /* Invalid */
16901 MIPS_INVAL("special_legacy");
16902 generate_exception_end(ctx, EXCP_RI);
16903 break;
16904 }
16905 }
16906
16907 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
16908 {
16909 int rs, rt, rd, sa;
16910 uint32_t op1;
16911
16912 rs = (ctx->opcode >> 21) & 0x1f;
16913 rt = (ctx->opcode >> 16) & 0x1f;
16914 rd = (ctx->opcode >> 11) & 0x1f;
16915 sa = (ctx->opcode >> 6) & 0x1f;
16916
16917 op1 = MASK_SPECIAL(ctx->opcode);
16918 switch (op1) {
16919 case OPC_SLL: /* Shift with immediate */
16920 if (sa == 5 && rd == 0 &&
16921 rs == 0 && rt == 0) { /* PAUSE */
16922 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16923 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16924 generate_exception_end(ctx, EXCP_RI);
16925 break;
16926 }
16927 }
16928 /* Fallthrough */
16929 case OPC_SRA:
16930 gen_shift_imm(ctx, op1, rd, rt, sa);
16931 break;
16932 case OPC_SRL:
16933 switch ((ctx->opcode >> 21) & 0x1f) {
16934 case 1:
16935 /* rotr is decoded as srl on non-R2 CPUs */
16936 if (ctx->insn_flags & ISA_MIPS32R2) {
16937 op1 = OPC_ROTR;
16938 }
16939 /* Fallthrough */
16940 case 0:
16941 gen_shift_imm(ctx, op1, rd, rt, sa);
16942 break;
16943 default:
16944 generate_exception_end(ctx, EXCP_RI);
16945 break;
16946 }
16947 break;
16948 case OPC_ADD ... OPC_SUBU:
16949 gen_arith(ctx, op1, rd, rs, rt);
16950 break;
16951 case OPC_SLLV: /* Shifts */
16952 case OPC_SRAV:
16953 gen_shift(ctx, op1, rd, rs, rt);
16954 break;
16955 case OPC_SRLV:
16956 switch ((ctx->opcode >> 6) & 0x1f) {
16957 case 1:
16958 /* rotrv is decoded as srlv on non-R2 CPUs */
16959 if (ctx->insn_flags & ISA_MIPS32R2) {
16960 op1 = OPC_ROTRV;
16961 }
16962 /* Fallthrough */
16963 case 0:
16964 gen_shift(ctx, op1, rd, rs, rt);
16965 break;
16966 default:
16967 generate_exception_end(ctx, EXCP_RI);
16968 break;
16969 }
16970 break;
16971 case OPC_SLT: /* Set on less than */
16972 case OPC_SLTU:
16973 gen_slt(ctx, op1, rd, rs, rt);
16974 break;
16975 case OPC_AND: /* Logic*/
16976 case OPC_OR:
16977 case OPC_NOR:
16978 case OPC_XOR:
16979 gen_logic(ctx, op1, rd, rs, rt);
16980 break;
16981 case OPC_JALR:
16982 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16983 break;
16984 case OPC_TGE ... OPC_TEQ: /* Traps */
16985 case OPC_TNE:
16986 check_insn(ctx, ISA_MIPS2);
16987 gen_trap(ctx, op1, rs, rt, -1);
16988 break;
16989 case OPC_LSA: /* OPC_PMON */
16990 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16991 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16992 decode_opc_special_r6(env, ctx);
16993 } else {
16994 /* Pmon entry point, also R4010 selsl */
16995 #ifdef MIPS_STRICT_STANDARD
16996 MIPS_INVAL("PMON / selsl");
16997 generate_exception_end(ctx, EXCP_RI);
16998 #else
16999 gen_helper_0e0i(pmon, sa);
17000 #endif
17001 }
17002 break;
17003 case OPC_SYSCALL:
17004 generate_exception_end(ctx, EXCP_SYSCALL);
17005 break;
17006 case OPC_BREAK:
17007 generate_exception_end(ctx, EXCP_BREAK);
17008 break;
17009 case OPC_SYNC:
17010 check_insn(ctx, ISA_MIPS2);
17011 /* Treat as NOP. */
17012 break;
17013
17014 #if defined(TARGET_MIPS64)
17015 /* MIPS64 specific opcodes */
17016 case OPC_DSLL:
17017 case OPC_DSRA:
17018 case OPC_DSLL32:
17019 case OPC_DSRA32:
17020 check_insn(ctx, ISA_MIPS3);
17021 check_mips_64(ctx);
17022 gen_shift_imm(ctx, op1, rd, rt, sa);
17023 break;
17024 case OPC_DSRL:
17025 switch ((ctx->opcode >> 21) & 0x1f) {
17026 case 1:
17027 /* drotr is decoded as dsrl on non-R2 CPUs */
17028 if (ctx->insn_flags & ISA_MIPS32R2) {
17029 op1 = OPC_DROTR;
17030 }
17031 /* Fallthrough */
17032 case 0:
17033 check_insn(ctx, ISA_MIPS3);
17034 check_mips_64(ctx);
17035 gen_shift_imm(ctx, op1, rd, rt, sa);
17036 break;
17037 default:
17038 generate_exception_end(ctx, EXCP_RI);
17039 break;
17040 }
17041 break;
17042 case OPC_DSRL32:
17043 switch ((ctx->opcode >> 21) & 0x1f) {
17044 case 1:
17045 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17046 if (ctx->insn_flags & ISA_MIPS32R2) {
17047 op1 = OPC_DROTR32;
17048 }
17049 /* Fallthrough */
17050 case 0:
17051 check_insn(ctx, ISA_MIPS3);
17052 check_mips_64(ctx);
17053 gen_shift_imm(ctx, op1, rd, rt, sa);
17054 break;
17055 default:
17056 generate_exception_end(ctx, EXCP_RI);
17057 break;
17058 }
17059 break;
17060 case OPC_DADD ... OPC_DSUBU:
17061 check_insn(ctx, ISA_MIPS3);
17062 check_mips_64(ctx);
17063 gen_arith(ctx, op1, rd, rs, rt);
17064 break;
17065 case OPC_DSLLV:
17066 case OPC_DSRAV:
17067 check_insn(ctx, ISA_MIPS3);
17068 check_mips_64(ctx);
17069 gen_shift(ctx, op1, rd, rs, rt);
17070 break;
17071 case OPC_DSRLV:
17072 switch ((ctx->opcode >> 6) & 0x1f) {
17073 case 1:
17074 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17075 if (ctx->insn_flags & ISA_MIPS32R2) {
17076 op1 = OPC_DROTRV;
17077 }
17078 /* Fallthrough */
17079 case 0:
17080 check_insn(ctx, ISA_MIPS3);
17081 check_mips_64(ctx);
17082 gen_shift(ctx, op1, rd, rs, rt);
17083 break;
17084 default:
17085 generate_exception_end(ctx, EXCP_RI);
17086 break;
17087 }
17088 break;
17089 case OPC_DLSA:
17090 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17091 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17092 decode_opc_special_r6(env, ctx);
17093 }
17094 break;
17095 #endif
17096 default:
17097 if (ctx->insn_flags & ISA_MIPS32R6) {
17098 decode_opc_special_r6(env, ctx);
17099 } else {
17100 decode_opc_special_legacy(env, ctx);
17101 }
17102 }
17103 }
17104
17105 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17106 {
17107 int rs, rt, rd;
17108 uint32_t op1;
17109
17110 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17111
17112 rs = (ctx->opcode >> 21) & 0x1f;
17113 rt = (ctx->opcode >> 16) & 0x1f;
17114 rd = (ctx->opcode >> 11) & 0x1f;
17115
17116 op1 = MASK_SPECIAL2(ctx->opcode);
17117 switch (op1) {
17118 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17119 case OPC_MSUB ... OPC_MSUBU:
17120 check_insn(ctx, ISA_MIPS32);
17121 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17122 break;
17123 case OPC_MUL:
17124 gen_arith(ctx, op1, rd, rs, rt);
17125 break;
17126 case OPC_DIV_G_2F:
17127 case OPC_DIVU_G_2F:
17128 case OPC_MULT_G_2F:
17129 case OPC_MULTU_G_2F:
17130 case OPC_MOD_G_2F:
17131 case OPC_MODU_G_2F:
17132 check_insn(ctx, INSN_LOONGSON2F);
17133 gen_loongson_integer(ctx, op1, rd, rs, rt);
17134 break;
17135 case OPC_CLO:
17136 case OPC_CLZ:
17137 check_insn(ctx, ISA_MIPS32);
17138 gen_cl(ctx, op1, rd, rs);
17139 break;
17140 case OPC_SDBBP:
17141 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17142 gen_helper_do_semihosting(cpu_env);
17143 } else {
17144 /* XXX: not clear which exception should be raised
17145 * when in debug mode...
17146 */
17147 check_insn(ctx, ISA_MIPS32);
17148 generate_exception_end(ctx, EXCP_DBp);
17149 }
17150 break;
17151 #if defined(TARGET_MIPS64)
17152 case OPC_DCLO:
17153 case OPC_DCLZ:
17154 check_insn(ctx, ISA_MIPS64);
17155 check_mips_64(ctx);
17156 gen_cl(ctx, op1, rd, rs);
17157 break;
17158 case OPC_DMULT_G_2F:
17159 case OPC_DMULTU_G_2F:
17160 case OPC_DDIV_G_2F:
17161 case OPC_DDIVU_G_2F:
17162 case OPC_DMOD_G_2F:
17163 case OPC_DMODU_G_2F:
17164 check_insn(ctx, INSN_LOONGSON2F);
17165 gen_loongson_integer(ctx, op1, rd, rs, rt);
17166 break;
17167 #endif
17168 default: /* Invalid */
17169 MIPS_INVAL("special2_legacy");
17170 generate_exception_end(ctx, EXCP_RI);
17171 break;
17172 }
17173 }
17174
17175 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17176 {
17177 int rs, rt, rd, sa;
17178 uint32_t op1, op2;
17179 int16_t imm;
17180
17181 rs = (ctx->opcode >> 21) & 0x1f;
17182 rt = (ctx->opcode >> 16) & 0x1f;
17183 rd = (ctx->opcode >> 11) & 0x1f;
17184 sa = (ctx->opcode >> 6) & 0x1f;
17185 imm = (int16_t)ctx->opcode >> 7;
17186
17187 op1 = MASK_SPECIAL3(ctx->opcode);
17188 switch (op1) {
17189 case R6_OPC_PREF:
17190 if (rt >= 24) {
17191 /* hint codes 24-31 are reserved and signal RI */
17192 generate_exception_end(ctx, EXCP_RI);
17193 }
17194 /* Treat as NOP. */
17195 break;
17196 case R6_OPC_CACHE:
17197 /* Treat as NOP. */
17198 break;
17199 case R6_OPC_SC:
17200 gen_st_cond(ctx, op1, rt, rs, imm);
17201 break;
17202 case R6_OPC_LL:
17203 gen_ld(ctx, op1, rt, rs, imm);
17204 break;
17205 case OPC_BSHFL:
17206 {
17207 if (rd == 0) {
17208 /* Treat as NOP. */
17209 break;
17210 }
17211 op2 = MASK_BSHFL(ctx->opcode);
17212 switch (op2) {
17213 case OPC_ALIGN ... OPC_ALIGN_END:
17214 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17215 break;
17216 case OPC_BITSWAP:
17217 gen_bitswap(ctx, op2, rd, rt);
17218 break;
17219 }
17220 }
17221 break;
17222 #if defined(TARGET_MIPS64)
17223 case R6_OPC_SCD:
17224 gen_st_cond(ctx, op1, rt, rs, imm);
17225 break;
17226 case R6_OPC_LLD:
17227 gen_ld(ctx, op1, rt, rs, imm);
17228 break;
17229 case OPC_DBSHFL:
17230 check_mips_64(ctx);
17231 {
17232 if (rd == 0) {
17233 /* Treat as NOP. */
17234 break;
17235 }
17236 op2 = MASK_DBSHFL(ctx->opcode);
17237 switch (op2) {
17238 case OPC_DALIGN ... OPC_DALIGN_END:
17239 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17240 break;
17241 case OPC_DBITSWAP:
17242 gen_bitswap(ctx, op2, rd, rt);
17243 break;
17244 }
17245
17246 }
17247 break;
17248 #endif
17249 default: /* Invalid */
17250 MIPS_INVAL("special3_r6");
17251 generate_exception_end(ctx, EXCP_RI);
17252 break;
17253 }
17254 }
17255
17256 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17257 {
17258 int rs, rt, rd;
17259 uint32_t op1, op2;
17260
17261 rs = (ctx->opcode >> 21) & 0x1f;
17262 rt = (ctx->opcode >> 16) & 0x1f;
17263 rd = (ctx->opcode >> 11) & 0x1f;
17264
17265 op1 = MASK_SPECIAL3(ctx->opcode);
17266 switch (op1) {
17267 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17268 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17269 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17270 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17271 * the same mask and op1. */
17272 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17273 op2 = MASK_ADDUH_QB(ctx->opcode);
17274 switch (op2) {
17275 case OPC_ADDUH_QB:
17276 case OPC_ADDUH_R_QB:
17277 case OPC_ADDQH_PH:
17278 case OPC_ADDQH_R_PH:
17279 case OPC_ADDQH_W:
17280 case OPC_ADDQH_R_W:
17281 case OPC_SUBUH_QB:
17282 case OPC_SUBUH_R_QB:
17283 case OPC_SUBQH_PH:
17284 case OPC_SUBQH_R_PH:
17285 case OPC_SUBQH_W:
17286 case OPC_SUBQH_R_W:
17287 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17288 break;
17289 case OPC_MUL_PH:
17290 case OPC_MUL_S_PH:
17291 case OPC_MULQ_S_W:
17292 case OPC_MULQ_RS_W:
17293 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17294 break;
17295 default:
17296 MIPS_INVAL("MASK ADDUH.QB");
17297 generate_exception_end(ctx, EXCP_RI);
17298 break;
17299 }
17300 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17301 gen_loongson_integer(ctx, op1, rd, rs, rt);
17302 } else {
17303 generate_exception_end(ctx, EXCP_RI);
17304 }
17305 break;
17306 case OPC_LX_DSP:
17307 op2 = MASK_LX(ctx->opcode);
17308 switch (op2) {
17309 #if defined(TARGET_MIPS64)
17310 case OPC_LDX:
17311 #endif
17312 case OPC_LBUX:
17313 case OPC_LHX:
17314 case OPC_LWX:
17315 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17316 break;
17317 default: /* Invalid */
17318 MIPS_INVAL("MASK LX");
17319 generate_exception_end(ctx, EXCP_RI);
17320 break;
17321 }
17322 break;
17323 case OPC_ABSQ_S_PH_DSP:
17324 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17325 switch (op2) {
17326 case OPC_ABSQ_S_QB:
17327 case OPC_ABSQ_S_PH:
17328 case OPC_ABSQ_S_W:
17329 case OPC_PRECEQ_W_PHL:
17330 case OPC_PRECEQ_W_PHR:
17331 case OPC_PRECEQU_PH_QBL:
17332 case OPC_PRECEQU_PH_QBR:
17333 case OPC_PRECEQU_PH_QBLA:
17334 case OPC_PRECEQU_PH_QBRA:
17335 case OPC_PRECEU_PH_QBL:
17336 case OPC_PRECEU_PH_QBR:
17337 case OPC_PRECEU_PH_QBLA:
17338 case OPC_PRECEU_PH_QBRA:
17339 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17340 break;
17341 case OPC_BITREV:
17342 case OPC_REPL_QB:
17343 case OPC_REPLV_QB:
17344 case OPC_REPL_PH:
17345 case OPC_REPLV_PH:
17346 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17347 break;
17348 default:
17349 MIPS_INVAL("MASK ABSQ_S.PH");
17350 generate_exception_end(ctx, EXCP_RI);
17351 break;
17352 }
17353 break;
17354 case OPC_ADDU_QB_DSP:
17355 op2 = MASK_ADDU_QB(ctx->opcode);
17356 switch (op2) {
17357 case OPC_ADDQ_PH:
17358 case OPC_ADDQ_S_PH:
17359 case OPC_ADDQ_S_W:
17360 case OPC_ADDU_QB:
17361 case OPC_ADDU_S_QB:
17362 case OPC_ADDU_PH:
17363 case OPC_ADDU_S_PH:
17364 case OPC_SUBQ_PH:
17365 case OPC_SUBQ_S_PH:
17366 case OPC_SUBQ_S_W:
17367 case OPC_SUBU_QB:
17368 case OPC_SUBU_S_QB:
17369 case OPC_SUBU_PH:
17370 case OPC_SUBU_S_PH:
17371 case OPC_ADDSC:
17372 case OPC_ADDWC:
17373 case OPC_MODSUB:
17374 case OPC_RADDU_W_QB:
17375 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17376 break;
17377 case OPC_MULEU_S_PH_QBL:
17378 case OPC_MULEU_S_PH_QBR:
17379 case OPC_MULQ_RS_PH:
17380 case OPC_MULEQ_S_W_PHL:
17381 case OPC_MULEQ_S_W_PHR:
17382 case OPC_MULQ_S_PH:
17383 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17384 break;
17385 default: /* Invalid */
17386 MIPS_INVAL("MASK ADDU.QB");
17387 generate_exception_end(ctx, EXCP_RI);
17388 break;
17389
17390 }
17391 break;
17392 case OPC_CMPU_EQ_QB_DSP:
17393 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17394 switch (op2) {
17395 case OPC_PRECR_SRA_PH_W:
17396 case OPC_PRECR_SRA_R_PH_W:
17397 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17398 break;
17399 case OPC_PRECR_QB_PH:
17400 case OPC_PRECRQ_QB_PH:
17401 case OPC_PRECRQ_PH_W:
17402 case OPC_PRECRQ_RS_PH_W:
17403 case OPC_PRECRQU_S_QB_PH:
17404 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17405 break;
17406 case OPC_CMPU_EQ_QB:
17407 case OPC_CMPU_LT_QB:
17408 case OPC_CMPU_LE_QB:
17409 case OPC_CMP_EQ_PH:
17410 case OPC_CMP_LT_PH:
17411 case OPC_CMP_LE_PH:
17412 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17413 break;
17414 case OPC_CMPGU_EQ_QB:
17415 case OPC_CMPGU_LT_QB:
17416 case OPC_CMPGU_LE_QB:
17417 case OPC_CMPGDU_EQ_QB:
17418 case OPC_CMPGDU_LT_QB:
17419 case OPC_CMPGDU_LE_QB:
17420 case OPC_PICK_QB:
17421 case OPC_PICK_PH:
17422 case OPC_PACKRL_PH:
17423 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17424 break;
17425 default: /* Invalid */
17426 MIPS_INVAL("MASK CMPU.EQ.QB");
17427 generate_exception_end(ctx, EXCP_RI);
17428 break;
17429 }
17430 break;
17431 case OPC_SHLL_QB_DSP:
17432 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17433 break;
17434 case OPC_DPA_W_PH_DSP:
17435 op2 = MASK_DPA_W_PH(ctx->opcode);
17436 switch (op2) {
17437 case OPC_DPAU_H_QBL:
17438 case OPC_DPAU_H_QBR:
17439 case OPC_DPSU_H_QBL:
17440 case OPC_DPSU_H_QBR:
17441 case OPC_DPA_W_PH:
17442 case OPC_DPAX_W_PH:
17443 case OPC_DPAQ_S_W_PH:
17444 case OPC_DPAQX_S_W_PH:
17445 case OPC_DPAQX_SA_W_PH:
17446 case OPC_DPS_W_PH:
17447 case OPC_DPSX_W_PH:
17448 case OPC_DPSQ_S_W_PH:
17449 case OPC_DPSQX_S_W_PH:
17450 case OPC_DPSQX_SA_W_PH:
17451 case OPC_MULSAQ_S_W_PH:
17452 case OPC_DPAQ_SA_L_W:
17453 case OPC_DPSQ_SA_L_W:
17454 case OPC_MAQ_S_W_PHL:
17455 case OPC_MAQ_S_W_PHR:
17456 case OPC_MAQ_SA_W_PHL:
17457 case OPC_MAQ_SA_W_PHR:
17458 case OPC_MULSA_W_PH:
17459 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17460 break;
17461 default: /* Invalid */
17462 MIPS_INVAL("MASK DPAW.PH");
17463 generate_exception_end(ctx, EXCP_RI);
17464 break;
17465 }
17466 break;
17467 case OPC_INSV_DSP:
17468 op2 = MASK_INSV(ctx->opcode);
17469 switch (op2) {
17470 case OPC_INSV:
17471 check_dsp(ctx);
17472 {
17473 TCGv t0, t1;
17474
17475 if (rt == 0) {
17476 break;
17477 }
17478
17479 t0 = tcg_temp_new();
17480 t1 = tcg_temp_new();
17481
17482 gen_load_gpr(t0, rt);
17483 gen_load_gpr(t1, rs);
17484
17485 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17486
17487 tcg_temp_free(t0);
17488 tcg_temp_free(t1);
17489 break;
17490 }
17491 default: /* Invalid */
17492 MIPS_INVAL("MASK INSV");
17493 generate_exception_end(ctx, EXCP_RI);
17494 break;
17495 }
17496 break;
17497 case OPC_APPEND_DSP:
17498 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17499 break;
17500 case OPC_EXTR_W_DSP:
17501 op2 = MASK_EXTR_W(ctx->opcode);
17502 switch (op2) {
17503 case OPC_EXTR_W:
17504 case OPC_EXTR_R_W:
17505 case OPC_EXTR_RS_W:
17506 case OPC_EXTR_S_H:
17507 case OPC_EXTRV_S_H:
17508 case OPC_EXTRV_W:
17509 case OPC_EXTRV_R_W:
17510 case OPC_EXTRV_RS_W:
17511 case OPC_EXTP:
17512 case OPC_EXTPV:
17513 case OPC_EXTPDP:
17514 case OPC_EXTPDPV:
17515 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17516 break;
17517 case OPC_RDDSP:
17518 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17519 break;
17520 case OPC_SHILO:
17521 case OPC_SHILOV:
17522 case OPC_MTHLIP:
17523 case OPC_WRDSP:
17524 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17525 break;
17526 default: /* Invalid */
17527 MIPS_INVAL("MASK EXTR.W");
17528 generate_exception_end(ctx, EXCP_RI);
17529 break;
17530 }
17531 break;
17532 #if defined(TARGET_MIPS64)
17533 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17534 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17535 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17536 check_insn(ctx, INSN_LOONGSON2E);
17537 gen_loongson_integer(ctx, op1, rd, rs, rt);
17538 break;
17539 case OPC_ABSQ_S_QH_DSP:
17540 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17541 switch (op2) {
17542 case OPC_PRECEQ_L_PWL:
17543 case OPC_PRECEQ_L_PWR:
17544 case OPC_PRECEQ_PW_QHL:
17545 case OPC_PRECEQ_PW_QHR:
17546 case OPC_PRECEQ_PW_QHLA:
17547 case OPC_PRECEQ_PW_QHRA:
17548 case OPC_PRECEQU_QH_OBL:
17549 case OPC_PRECEQU_QH_OBR:
17550 case OPC_PRECEQU_QH_OBLA:
17551 case OPC_PRECEQU_QH_OBRA:
17552 case OPC_PRECEU_QH_OBL:
17553 case OPC_PRECEU_QH_OBR:
17554 case OPC_PRECEU_QH_OBLA:
17555 case OPC_PRECEU_QH_OBRA:
17556 case OPC_ABSQ_S_OB:
17557 case OPC_ABSQ_S_PW:
17558 case OPC_ABSQ_S_QH:
17559 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17560 break;
17561 case OPC_REPL_OB:
17562 case OPC_REPL_PW:
17563 case OPC_REPL_QH:
17564 case OPC_REPLV_OB:
17565 case OPC_REPLV_PW:
17566 case OPC_REPLV_QH:
17567 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17568 break;
17569 default: /* Invalid */
17570 MIPS_INVAL("MASK ABSQ_S.QH");
17571 generate_exception_end(ctx, EXCP_RI);
17572 break;
17573 }
17574 break;
17575 case OPC_ADDU_OB_DSP:
17576 op2 = MASK_ADDU_OB(ctx->opcode);
17577 switch (op2) {
17578 case OPC_RADDU_L_OB:
17579 case OPC_SUBQ_PW:
17580 case OPC_SUBQ_S_PW:
17581 case OPC_SUBQ_QH:
17582 case OPC_SUBQ_S_QH:
17583 case OPC_SUBU_OB:
17584 case OPC_SUBU_S_OB:
17585 case OPC_SUBU_QH:
17586 case OPC_SUBU_S_QH:
17587 case OPC_SUBUH_OB:
17588 case OPC_SUBUH_R_OB:
17589 case OPC_ADDQ_PW:
17590 case OPC_ADDQ_S_PW:
17591 case OPC_ADDQ_QH:
17592 case OPC_ADDQ_S_QH:
17593 case OPC_ADDU_OB:
17594 case OPC_ADDU_S_OB:
17595 case OPC_ADDU_QH:
17596 case OPC_ADDU_S_QH:
17597 case OPC_ADDUH_OB:
17598 case OPC_ADDUH_R_OB:
17599 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17600 break;
17601 case OPC_MULEQ_S_PW_QHL:
17602 case OPC_MULEQ_S_PW_QHR:
17603 case OPC_MULEU_S_QH_OBL:
17604 case OPC_MULEU_S_QH_OBR:
17605 case OPC_MULQ_RS_QH:
17606 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17607 break;
17608 default: /* Invalid */
17609 MIPS_INVAL("MASK ADDU.OB");
17610 generate_exception_end(ctx, EXCP_RI);
17611 break;
17612 }
17613 break;
17614 case OPC_CMPU_EQ_OB_DSP:
17615 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17616 switch (op2) {
17617 case OPC_PRECR_SRA_QH_PW:
17618 case OPC_PRECR_SRA_R_QH_PW:
17619 /* Return value is rt. */
17620 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17621 break;
17622 case OPC_PRECR_OB_QH:
17623 case OPC_PRECRQ_OB_QH:
17624 case OPC_PRECRQ_PW_L:
17625 case OPC_PRECRQ_QH_PW:
17626 case OPC_PRECRQ_RS_QH_PW:
17627 case OPC_PRECRQU_S_OB_QH:
17628 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17629 break;
17630 case OPC_CMPU_EQ_OB:
17631 case OPC_CMPU_LT_OB:
17632 case OPC_CMPU_LE_OB:
17633 case OPC_CMP_EQ_QH:
17634 case OPC_CMP_LT_QH:
17635 case OPC_CMP_LE_QH:
17636 case OPC_CMP_EQ_PW:
17637 case OPC_CMP_LT_PW:
17638 case OPC_CMP_LE_PW:
17639 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17640 break;
17641 case OPC_CMPGDU_EQ_OB:
17642 case OPC_CMPGDU_LT_OB:
17643 case OPC_CMPGDU_LE_OB:
17644 case OPC_CMPGU_EQ_OB:
17645 case OPC_CMPGU_LT_OB:
17646 case OPC_CMPGU_LE_OB:
17647 case OPC_PACKRL_PW:
17648 case OPC_PICK_OB:
17649 case OPC_PICK_PW:
17650 case OPC_PICK_QH:
17651 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17652 break;
17653 default: /* Invalid */
17654 MIPS_INVAL("MASK CMPU_EQ.OB");
17655 generate_exception_end(ctx, EXCP_RI);
17656 break;
17657 }
17658 break;
17659 case OPC_DAPPEND_DSP:
17660 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17661 break;
17662 case OPC_DEXTR_W_DSP:
17663 op2 = MASK_DEXTR_W(ctx->opcode);
17664 switch (op2) {
17665 case OPC_DEXTP:
17666 case OPC_DEXTPDP:
17667 case OPC_DEXTPDPV:
17668 case OPC_DEXTPV:
17669 case OPC_DEXTR_L:
17670 case OPC_DEXTR_R_L:
17671 case OPC_DEXTR_RS_L:
17672 case OPC_DEXTR_W:
17673 case OPC_DEXTR_R_W:
17674 case OPC_DEXTR_RS_W:
17675 case OPC_DEXTR_S_H:
17676 case OPC_DEXTRV_L:
17677 case OPC_DEXTRV_R_L:
17678 case OPC_DEXTRV_RS_L:
17679 case OPC_DEXTRV_S_H:
17680 case OPC_DEXTRV_W:
17681 case OPC_DEXTRV_R_W:
17682 case OPC_DEXTRV_RS_W:
17683 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17684 break;
17685 case OPC_DMTHLIP:
17686 case OPC_DSHILO:
17687 case OPC_DSHILOV:
17688 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17689 break;
17690 default: /* Invalid */
17691 MIPS_INVAL("MASK EXTR.W");
17692 generate_exception_end(ctx, EXCP_RI);
17693 break;
17694 }
17695 break;
17696 case OPC_DPAQ_W_QH_DSP:
17697 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17698 switch (op2) {
17699 case OPC_DPAU_H_OBL:
17700 case OPC_DPAU_H_OBR:
17701 case OPC_DPSU_H_OBL:
17702 case OPC_DPSU_H_OBR:
17703 case OPC_DPA_W_QH:
17704 case OPC_DPAQ_S_W_QH:
17705 case OPC_DPS_W_QH:
17706 case OPC_DPSQ_S_W_QH:
17707 case OPC_MULSAQ_S_W_QH:
17708 case OPC_DPAQ_SA_L_PW:
17709 case OPC_DPSQ_SA_L_PW:
17710 case OPC_MULSAQ_S_L_PW:
17711 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17712 break;
17713 case OPC_MAQ_S_W_QHLL:
17714 case OPC_MAQ_S_W_QHLR:
17715 case OPC_MAQ_S_W_QHRL:
17716 case OPC_MAQ_S_W_QHRR:
17717 case OPC_MAQ_SA_W_QHLL:
17718 case OPC_MAQ_SA_W_QHLR:
17719 case OPC_MAQ_SA_W_QHRL:
17720 case OPC_MAQ_SA_W_QHRR:
17721 case OPC_MAQ_S_L_PWL:
17722 case OPC_MAQ_S_L_PWR:
17723 case OPC_DMADD:
17724 case OPC_DMADDU:
17725 case OPC_DMSUB:
17726 case OPC_DMSUBU:
17727 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17728 break;
17729 default: /* Invalid */
17730 MIPS_INVAL("MASK DPAQ.W.QH");
17731 generate_exception_end(ctx, EXCP_RI);
17732 break;
17733 }
17734 break;
17735 case OPC_DINSV_DSP:
17736 op2 = MASK_INSV(ctx->opcode);
17737 switch (op2) {
17738 case OPC_DINSV:
17739 {
17740 TCGv t0, t1;
17741
17742 if (rt == 0) {
17743 break;
17744 }
17745 check_dsp(ctx);
17746
17747 t0 = tcg_temp_new();
17748 t1 = tcg_temp_new();
17749
17750 gen_load_gpr(t0, rt);
17751 gen_load_gpr(t1, rs);
17752
17753 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
17754
17755 tcg_temp_free(t0);
17756 tcg_temp_free(t1);
17757 break;
17758 }
17759 default: /* Invalid */
17760 MIPS_INVAL("MASK DINSV");
17761 generate_exception_end(ctx, EXCP_RI);
17762 break;
17763 }
17764 break;
17765 case OPC_SHLL_OB_DSP:
17766 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17767 break;
17768 #endif
17769 default: /* Invalid */
17770 MIPS_INVAL("special3_legacy");
17771 generate_exception_end(ctx, EXCP_RI);
17772 break;
17773 }
17774 }
17775
17776 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17777 {
17778 int rs, rt, rd, sa;
17779 uint32_t op1, op2;
17780
17781 rs = (ctx->opcode >> 21) & 0x1f;
17782 rt = (ctx->opcode >> 16) & 0x1f;
17783 rd = (ctx->opcode >> 11) & 0x1f;
17784 sa = (ctx->opcode >> 6) & 0x1f;
17785
17786 op1 = MASK_SPECIAL3(ctx->opcode);
17787 switch (op1) {
17788 case OPC_EXT:
17789 case OPC_INS:
17790 check_insn(ctx, ISA_MIPS32R2);
17791 gen_bitops(ctx, op1, rt, rs, sa, rd);
17792 break;
17793 case OPC_BSHFL:
17794 op2 = MASK_BSHFL(ctx->opcode);
17795 switch (op2) {
17796 case OPC_ALIGN ... OPC_ALIGN_END:
17797 case OPC_BITSWAP:
17798 check_insn(ctx, ISA_MIPS32R6);
17799 decode_opc_special3_r6(env, ctx);
17800 break;
17801 default:
17802 check_insn(ctx, ISA_MIPS32R2);
17803 gen_bshfl(ctx, op2, rt, rd);
17804 break;
17805 }
17806 break;
17807 #if defined(TARGET_MIPS64)
17808 case OPC_DEXTM ... OPC_DEXT:
17809 case OPC_DINSM ... OPC_DINS:
17810 check_insn(ctx, ISA_MIPS64R2);
17811 check_mips_64(ctx);
17812 gen_bitops(ctx, op1, rt, rs, sa, rd);
17813 break;
17814 case OPC_DBSHFL:
17815 op2 = MASK_DBSHFL(ctx->opcode);
17816 switch (op2) {
17817 case OPC_DALIGN ... OPC_DALIGN_END:
17818 case OPC_DBITSWAP:
17819 check_insn(ctx, ISA_MIPS32R6);
17820 decode_opc_special3_r6(env, ctx);
17821 break;
17822 default:
17823 check_insn(ctx, ISA_MIPS64R2);
17824 check_mips_64(ctx);
17825 op2 = MASK_DBSHFL(ctx->opcode);
17826 gen_bshfl(ctx, op2, rt, rd);
17827 break;
17828 }
17829 break;
17830 #endif
17831 case OPC_RDHWR:
17832 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
17833 break;
17834 case OPC_FORK:
17835 check_insn(ctx, ASE_MT);
17836 {
17837 TCGv t0 = tcg_temp_new();
17838 TCGv t1 = tcg_temp_new();
17839
17840 gen_load_gpr(t0, rt);
17841 gen_load_gpr(t1, rs);
17842 gen_helper_fork(t0, t1);
17843 tcg_temp_free(t0);
17844 tcg_temp_free(t1);
17845 }
17846 break;
17847 case OPC_YIELD:
17848 check_insn(ctx, ASE_MT);
17849 {
17850 TCGv t0 = tcg_temp_new();
17851
17852 gen_load_gpr(t0, rs);
17853 gen_helper_yield(t0, cpu_env, t0);
17854 gen_store_gpr(t0, rd);
17855 tcg_temp_free(t0);
17856 }
17857 break;
17858 default:
17859 if (ctx->insn_flags & ISA_MIPS32R6) {
17860 decode_opc_special3_r6(env, ctx);
17861 } else {
17862 decode_opc_special3_legacy(env, ctx);
17863 }
17864 }
17865 }
17866
17867 /* MIPS SIMD Architecture (MSA) */
17868 static inline int check_msa_access(DisasContext *ctx)
17869 {
17870 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17871 !(ctx->hflags & MIPS_HFLAG_F64))) {
17872 generate_exception_end(ctx, EXCP_RI);
17873 return 0;
17874 }
17875
17876 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17877 if (ctx->insn_flags & ASE_MSA) {
17878 generate_exception_end(ctx, EXCP_MSADIS);
17879 return 0;
17880 } else {
17881 generate_exception_end(ctx, EXCP_RI);
17882 return 0;
17883 }
17884 }
17885 return 1;
17886 }
17887
17888 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17889 {
17890 /* generates tcg ops to check if any element is 0 */
17891 /* Note this function only works with MSA_WRLEN = 128 */
17892 uint64_t eval_zero_or_big = 0;
17893 uint64_t eval_big = 0;
17894 TCGv_i64 t0 = tcg_temp_new_i64();
17895 TCGv_i64 t1 = tcg_temp_new_i64();
17896 switch (df) {
17897 case DF_BYTE:
17898 eval_zero_or_big = 0x0101010101010101ULL;
17899 eval_big = 0x8080808080808080ULL;
17900 break;
17901 case DF_HALF:
17902 eval_zero_or_big = 0x0001000100010001ULL;
17903 eval_big = 0x8000800080008000ULL;
17904 break;
17905 case DF_WORD:
17906 eval_zero_or_big = 0x0000000100000001ULL;
17907 eval_big = 0x8000000080000000ULL;
17908 break;
17909 case DF_DOUBLE:
17910 eval_zero_or_big = 0x0000000000000001ULL;
17911 eval_big = 0x8000000000000000ULL;
17912 break;
17913 }
17914 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17915 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17916 tcg_gen_andi_i64(t0, t0, eval_big);
17917 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17918 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17919 tcg_gen_andi_i64(t1, t1, eval_big);
17920 tcg_gen_or_i64(t0, t0, t1);
17921 /* if all bits are zero then all elements are not zero */
17922 /* if some bit is non-zero then some element is zero */
17923 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17924 tcg_gen_trunc_i64_tl(tresult, t0);
17925 tcg_temp_free_i64(t0);
17926 tcg_temp_free_i64(t1);
17927 }
17928
17929 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17930 {
17931 uint8_t df = (ctx->opcode >> 21) & 0x3;
17932 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17933 int64_t s16 = (int16_t)ctx->opcode;
17934
17935 check_msa_access(ctx);
17936
17937 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
17938 generate_exception_end(ctx, EXCP_RI);
17939 return;
17940 }
17941 switch (op1) {
17942 case OPC_BZ_V:
17943 case OPC_BNZ_V:
17944 {
17945 TCGv_i64 t0 = tcg_temp_new_i64();
17946 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17947 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17948 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17949 tcg_gen_trunc_i64_tl(bcond, t0);
17950 tcg_temp_free_i64(t0);
17951 }
17952 break;
17953 case OPC_BZ_B:
17954 case OPC_BZ_H:
17955 case OPC_BZ_W:
17956 case OPC_BZ_D:
17957 gen_check_zero_element(bcond, df, wt);
17958 break;
17959 case OPC_BNZ_B:
17960 case OPC_BNZ_H:
17961 case OPC_BNZ_W:
17962 case OPC_BNZ_D:
17963 gen_check_zero_element(bcond, df, wt);
17964 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17965 break;
17966 }
17967
17968 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17969
17970 ctx->hflags |= MIPS_HFLAG_BC;
17971 ctx->hflags |= MIPS_HFLAG_BDS32;
17972 }
17973
17974 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17975 {
17976 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17977 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17978 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17979 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17980
17981 TCGv_i32 twd = tcg_const_i32(wd);
17982 TCGv_i32 tws = tcg_const_i32(ws);
17983 TCGv_i32 ti8 = tcg_const_i32(i8);
17984
17985 switch (MASK_MSA_I8(ctx->opcode)) {
17986 case OPC_ANDI_B:
17987 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17988 break;
17989 case OPC_ORI_B:
17990 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17991 break;
17992 case OPC_NORI_B:
17993 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17994 break;
17995 case OPC_XORI_B:
17996 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17997 break;
17998 case OPC_BMNZI_B:
17999 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
18000 break;
18001 case OPC_BMZI_B:
18002 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
18003 break;
18004 case OPC_BSELI_B:
18005 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
18006 break;
18007 case OPC_SHF_B:
18008 case OPC_SHF_H:
18009 case OPC_SHF_W:
18010 {
18011 uint8_t df = (ctx->opcode >> 24) & 0x3;
18012 if (df == DF_DOUBLE) {
18013 generate_exception_end(ctx, EXCP_RI);
18014 } else {
18015 TCGv_i32 tdf = tcg_const_i32(df);
18016 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
18017 tcg_temp_free_i32(tdf);
18018 }
18019 }
18020 break;
18021 default:
18022 MIPS_INVAL("MSA instruction");
18023 generate_exception_end(ctx, EXCP_RI);
18024 break;
18025 }
18026
18027 tcg_temp_free_i32(twd);
18028 tcg_temp_free_i32(tws);
18029 tcg_temp_free_i32(ti8);
18030 }
18031
18032 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
18033 {
18034 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18035 uint8_t df = (ctx->opcode >> 21) & 0x3;
18036 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
18037 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
18038 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18039 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18040
18041 TCGv_i32 tdf = tcg_const_i32(df);
18042 TCGv_i32 twd = tcg_const_i32(wd);
18043 TCGv_i32 tws = tcg_const_i32(ws);
18044 TCGv_i32 timm = tcg_temp_new_i32();
18045 tcg_gen_movi_i32(timm, u5);
18046
18047 switch (MASK_MSA_I5(ctx->opcode)) {
18048 case OPC_ADDVI_df:
18049 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
18050 break;
18051 case OPC_SUBVI_df:
18052 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
18053 break;
18054 case OPC_MAXI_S_df:
18055 tcg_gen_movi_i32(timm, s5);
18056 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
18057 break;
18058 case OPC_MAXI_U_df:
18059 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
18060 break;
18061 case OPC_MINI_S_df:
18062 tcg_gen_movi_i32(timm, s5);
18063 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
18064 break;
18065 case OPC_MINI_U_df:
18066 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
18067 break;
18068 case OPC_CEQI_df:
18069 tcg_gen_movi_i32(timm, s5);
18070 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
18071 break;
18072 case OPC_CLTI_S_df:
18073 tcg_gen_movi_i32(timm, s5);
18074 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18075 break;
18076 case OPC_CLTI_U_df:
18077 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18078 break;
18079 case OPC_CLEI_S_df:
18080 tcg_gen_movi_i32(timm, s5);
18081 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18082 break;
18083 case OPC_CLEI_U_df:
18084 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18085 break;
18086 case OPC_LDI_df:
18087 {
18088 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18089 tcg_gen_movi_i32(timm, s10);
18090 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18091 }
18092 break;
18093 default:
18094 MIPS_INVAL("MSA instruction");
18095 generate_exception_end(ctx, EXCP_RI);
18096 break;
18097 }
18098
18099 tcg_temp_free_i32(tdf);
18100 tcg_temp_free_i32(twd);
18101 tcg_temp_free_i32(tws);
18102 tcg_temp_free_i32(timm);
18103 }
18104
18105 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18106 {
18107 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18108 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18109 uint32_t df = 0, m = 0;
18110 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18111 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18112
18113 TCGv_i32 tdf;
18114 TCGv_i32 tm;
18115 TCGv_i32 twd;
18116 TCGv_i32 tws;
18117
18118 if ((dfm & 0x40) == 0x00) {
18119 m = dfm & 0x3f;
18120 df = DF_DOUBLE;
18121 } else if ((dfm & 0x60) == 0x40) {
18122 m = dfm & 0x1f;
18123 df = DF_WORD;
18124 } else if ((dfm & 0x70) == 0x60) {
18125 m = dfm & 0x0f;
18126 df = DF_HALF;
18127 } else if ((dfm & 0x78) == 0x70) {
18128 m = dfm & 0x7;
18129 df = DF_BYTE;
18130 } else {
18131 generate_exception_end(ctx, EXCP_RI);
18132 return;
18133 }
18134
18135 tdf = tcg_const_i32(df);
18136 tm = tcg_const_i32(m);
18137 twd = tcg_const_i32(wd);
18138 tws = tcg_const_i32(ws);
18139
18140 switch (MASK_MSA_BIT(ctx->opcode)) {
18141 case OPC_SLLI_df:
18142 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18143 break;
18144 case OPC_SRAI_df:
18145 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18146 break;
18147 case OPC_SRLI_df:
18148 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18149 break;
18150 case OPC_BCLRI_df:
18151 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18152 break;
18153 case OPC_BSETI_df:
18154 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18155 break;
18156 case OPC_BNEGI_df:
18157 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18158 break;
18159 case OPC_BINSLI_df:
18160 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18161 break;
18162 case OPC_BINSRI_df:
18163 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18164 break;
18165 case OPC_SAT_S_df:
18166 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18167 break;
18168 case OPC_SAT_U_df:
18169 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18170 break;
18171 case OPC_SRARI_df:
18172 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18173 break;
18174 case OPC_SRLRI_df:
18175 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18176 break;
18177 default:
18178 MIPS_INVAL("MSA instruction");
18179 generate_exception_end(ctx, EXCP_RI);
18180 break;
18181 }
18182
18183 tcg_temp_free_i32(tdf);
18184 tcg_temp_free_i32(tm);
18185 tcg_temp_free_i32(twd);
18186 tcg_temp_free_i32(tws);
18187 }
18188
18189 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18190 {
18191 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18192 uint8_t df = (ctx->opcode >> 21) & 0x3;
18193 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18194 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18195 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18196
18197 TCGv_i32 tdf = tcg_const_i32(df);
18198 TCGv_i32 twd = tcg_const_i32(wd);
18199 TCGv_i32 tws = tcg_const_i32(ws);
18200 TCGv_i32 twt = tcg_const_i32(wt);
18201
18202 switch (MASK_MSA_3R(ctx->opcode)) {
18203 case OPC_SLL_df:
18204 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18205 break;
18206 case OPC_ADDV_df:
18207 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18208 break;
18209 case OPC_CEQ_df:
18210 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18211 break;
18212 case OPC_ADD_A_df:
18213 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18214 break;
18215 case OPC_SUBS_S_df:
18216 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18217 break;
18218 case OPC_MULV_df:
18219 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18220 break;
18221 case OPC_SLD_df:
18222 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18223 break;
18224 case OPC_VSHF_df:
18225 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18226 break;
18227 case OPC_SRA_df:
18228 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18229 break;
18230 case OPC_SUBV_df:
18231 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18232 break;
18233 case OPC_ADDS_A_df:
18234 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18235 break;
18236 case OPC_SUBS_U_df:
18237 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18238 break;
18239 case OPC_MADDV_df:
18240 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18241 break;
18242 case OPC_SPLAT_df:
18243 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18244 break;
18245 case OPC_SRAR_df:
18246 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18247 break;
18248 case OPC_SRL_df:
18249 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18250 break;
18251 case OPC_MAX_S_df:
18252 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18253 break;
18254 case OPC_CLT_S_df:
18255 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18256 break;
18257 case OPC_ADDS_S_df:
18258 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18259 break;
18260 case OPC_SUBSUS_U_df:
18261 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18262 break;
18263 case OPC_MSUBV_df:
18264 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18265 break;
18266 case OPC_PCKEV_df:
18267 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18268 break;
18269 case OPC_SRLR_df:
18270 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18271 break;
18272 case OPC_BCLR_df:
18273 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18274 break;
18275 case OPC_MAX_U_df:
18276 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18277 break;
18278 case OPC_CLT_U_df:
18279 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18280 break;
18281 case OPC_ADDS_U_df:
18282 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18283 break;
18284 case OPC_SUBSUU_S_df:
18285 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18286 break;
18287 case OPC_PCKOD_df:
18288 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18289 break;
18290 case OPC_BSET_df:
18291 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18292 break;
18293 case OPC_MIN_S_df:
18294 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18295 break;
18296 case OPC_CLE_S_df:
18297 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18298 break;
18299 case OPC_AVE_S_df:
18300 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18301 break;
18302 case OPC_ASUB_S_df:
18303 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18304 break;
18305 case OPC_DIV_S_df:
18306 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18307 break;
18308 case OPC_ILVL_df:
18309 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18310 break;
18311 case OPC_BNEG_df:
18312 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18313 break;
18314 case OPC_MIN_U_df:
18315 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18316 break;
18317 case OPC_CLE_U_df:
18318 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18319 break;
18320 case OPC_AVE_U_df:
18321 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18322 break;
18323 case OPC_ASUB_U_df:
18324 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18325 break;
18326 case OPC_DIV_U_df:
18327 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18328 break;
18329 case OPC_ILVR_df:
18330 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18331 break;
18332 case OPC_BINSL_df:
18333 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18334 break;
18335 case OPC_MAX_A_df:
18336 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18337 break;
18338 case OPC_AVER_S_df:
18339 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18340 break;
18341 case OPC_MOD_S_df:
18342 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18343 break;
18344 case OPC_ILVEV_df:
18345 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18346 break;
18347 case OPC_BINSR_df:
18348 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18349 break;
18350 case OPC_MIN_A_df:
18351 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18352 break;
18353 case OPC_AVER_U_df:
18354 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18355 break;
18356 case OPC_MOD_U_df:
18357 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18358 break;
18359 case OPC_ILVOD_df:
18360 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18361 break;
18362
18363 case OPC_DOTP_S_df:
18364 case OPC_DOTP_U_df:
18365 case OPC_DPADD_S_df:
18366 case OPC_DPADD_U_df:
18367 case OPC_DPSUB_S_df:
18368 case OPC_HADD_S_df:
18369 case OPC_DPSUB_U_df:
18370 case OPC_HADD_U_df:
18371 case OPC_HSUB_S_df:
18372 case OPC_HSUB_U_df:
18373 if (df == DF_BYTE) {
18374 generate_exception_end(ctx, EXCP_RI);
18375 break;
18376 }
18377 switch (MASK_MSA_3R(ctx->opcode)) {
18378 case OPC_DOTP_S_df:
18379 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18380 break;
18381 case OPC_DOTP_U_df:
18382 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18383 break;
18384 case OPC_DPADD_S_df:
18385 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18386 break;
18387 case OPC_DPADD_U_df:
18388 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18389 break;
18390 case OPC_DPSUB_S_df:
18391 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18392 break;
18393 case OPC_HADD_S_df:
18394 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18395 break;
18396 case OPC_DPSUB_U_df:
18397 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18398 break;
18399 case OPC_HADD_U_df:
18400 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18401 break;
18402 case OPC_HSUB_S_df:
18403 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18404 break;
18405 case OPC_HSUB_U_df:
18406 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18407 break;
18408 }
18409 break;
18410 default:
18411 MIPS_INVAL("MSA instruction");
18412 generate_exception_end(ctx, EXCP_RI);
18413 break;
18414 }
18415 tcg_temp_free_i32(twd);
18416 tcg_temp_free_i32(tws);
18417 tcg_temp_free_i32(twt);
18418 tcg_temp_free_i32(tdf);
18419 }
18420
18421 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18422 {
18423 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18424 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18425 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18426 TCGv telm = tcg_temp_new();
18427 TCGv_i32 tsr = tcg_const_i32(source);
18428 TCGv_i32 tdt = tcg_const_i32(dest);
18429
18430 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18431 case OPC_CTCMSA:
18432 gen_load_gpr(telm, source);
18433 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18434 break;
18435 case OPC_CFCMSA:
18436 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18437 gen_store_gpr(telm, dest);
18438 break;
18439 case OPC_MOVE_V:
18440 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18441 break;
18442 default:
18443 MIPS_INVAL("MSA instruction");
18444 generate_exception_end(ctx, EXCP_RI);
18445 break;
18446 }
18447
18448 tcg_temp_free(telm);
18449 tcg_temp_free_i32(tdt);
18450 tcg_temp_free_i32(tsr);
18451 }
18452
18453 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18454 uint32_t n)
18455 {
18456 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18457 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18458 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18459
18460 TCGv_i32 tws = tcg_const_i32(ws);
18461 TCGv_i32 twd = tcg_const_i32(wd);
18462 TCGv_i32 tn = tcg_const_i32(n);
18463 TCGv_i32 tdf = tcg_const_i32(df);
18464
18465 switch (MASK_MSA_ELM(ctx->opcode)) {
18466 case OPC_SLDI_df:
18467 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18468 break;
18469 case OPC_SPLATI_df:
18470 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18471 break;
18472 case OPC_INSVE_df:
18473 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18474 break;
18475 case OPC_COPY_S_df:
18476 case OPC_COPY_U_df:
18477 case OPC_INSERT_df:
18478 #if !defined(TARGET_MIPS64)
18479 /* Double format valid only for MIPS64 */
18480 if (df == DF_DOUBLE) {
18481 generate_exception_end(ctx, EXCP_RI);
18482 break;
18483 }
18484 #endif
18485 switch (MASK_MSA_ELM(ctx->opcode)) {
18486 case OPC_COPY_S_df:
18487 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18488 break;
18489 case OPC_COPY_U_df:
18490 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18491 break;
18492 case OPC_INSERT_df:
18493 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18494 break;
18495 }
18496 break;
18497 default:
18498 MIPS_INVAL("MSA instruction");
18499 generate_exception_end(ctx, EXCP_RI);
18500 }
18501 tcg_temp_free_i32(twd);
18502 tcg_temp_free_i32(tws);
18503 tcg_temp_free_i32(tn);
18504 tcg_temp_free_i32(tdf);
18505 }
18506
18507 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18508 {
18509 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18510 uint32_t df = 0, n = 0;
18511
18512 if ((dfn & 0x30) == 0x00) {
18513 n = dfn & 0x0f;
18514 df = DF_BYTE;
18515 } else if ((dfn & 0x38) == 0x20) {
18516 n = dfn & 0x07;
18517 df = DF_HALF;
18518 } else if ((dfn & 0x3c) == 0x30) {
18519 n = dfn & 0x03;
18520 df = DF_WORD;
18521 } else if ((dfn & 0x3e) == 0x38) {
18522 n = dfn & 0x01;
18523 df = DF_DOUBLE;
18524 } else if (dfn == 0x3E) {
18525 /* CTCMSA, CFCMSA, MOVE.V */
18526 gen_msa_elm_3e(env, ctx);
18527 return;
18528 } else {
18529 generate_exception_end(ctx, EXCP_RI);
18530 return;
18531 }
18532
18533 gen_msa_elm_df(env, ctx, df, n);
18534 }
18535
18536 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18537 {
18538 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18539 uint8_t df = (ctx->opcode >> 21) & 0x1;
18540 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18541 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18542 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18543
18544 TCGv_i32 twd = tcg_const_i32(wd);
18545 TCGv_i32 tws = tcg_const_i32(ws);
18546 TCGv_i32 twt = tcg_const_i32(wt);
18547 TCGv_i32 tdf = tcg_temp_new_i32();
18548
18549 /* adjust df value for floating-point instruction */
18550 tcg_gen_movi_i32(tdf, df + 2);
18551
18552 switch (MASK_MSA_3RF(ctx->opcode)) {
18553 case OPC_FCAF_df:
18554 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18555 break;
18556 case OPC_FADD_df:
18557 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18558 break;
18559 case OPC_FCUN_df:
18560 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18561 break;
18562 case OPC_FSUB_df:
18563 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18564 break;
18565 case OPC_FCOR_df:
18566 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18567 break;
18568 case OPC_FCEQ_df:
18569 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18570 break;
18571 case OPC_FMUL_df:
18572 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18573 break;
18574 case OPC_FCUNE_df:
18575 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18576 break;
18577 case OPC_FCUEQ_df:
18578 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18579 break;
18580 case OPC_FDIV_df:
18581 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18582 break;
18583 case OPC_FCNE_df:
18584 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18585 break;
18586 case OPC_FCLT_df:
18587 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18588 break;
18589 case OPC_FMADD_df:
18590 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18591 break;
18592 case OPC_MUL_Q_df:
18593 tcg_gen_movi_i32(tdf, df + 1);
18594 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18595 break;
18596 case OPC_FCULT_df:
18597 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18598 break;
18599 case OPC_FMSUB_df:
18600 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18601 break;
18602 case OPC_MADD_Q_df:
18603 tcg_gen_movi_i32(tdf, df + 1);
18604 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18605 break;
18606 case OPC_FCLE_df:
18607 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18608 break;
18609 case OPC_MSUB_Q_df:
18610 tcg_gen_movi_i32(tdf, df + 1);
18611 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18612 break;
18613 case OPC_FCULE_df:
18614 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18615 break;
18616 case OPC_FEXP2_df:
18617 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18618 break;
18619 case OPC_FSAF_df:
18620 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18621 break;
18622 case OPC_FEXDO_df:
18623 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18624 break;
18625 case OPC_FSUN_df:
18626 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18627 break;
18628 case OPC_FSOR_df:
18629 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18630 break;
18631 case OPC_FSEQ_df:
18632 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18633 break;
18634 case OPC_FTQ_df:
18635 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18636 break;
18637 case OPC_FSUNE_df:
18638 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18639 break;
18640 case OPC_FSUEQ_df:
18641 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18642 break;
18643 case OPC_FSNE_df:
18644 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18645 break;
18646 case OPC_FSLT_df:
18647 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18648 break;
18649 case OPC_FMIN_df:
18650 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18651 break;
18652 case OPC_MULR_Q_df:
18653 tcg_gen_movi_i32(tdf, df + 1);
18654 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18655 break;
18656 case OPC_FSULT_df:
18657 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18658 break;
18659 case OPC_FMIN_A_df:
18660 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18661 break;
18662 case OPC_MADDR_Q_df:
18663 tcg_gen_movi_i32(tdf, df + 1);
18664 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18665 break;
18666 case OPC_FSLE_df:
18667 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18668 break;
18669 case OPC_FMAX_df:
18670 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18671 break;
18672 case OPC_MSUBR_Q_df:
18673 tcg_gen_movi_i32(tdf, df + 1);
18674 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18675 break;
18676 case OPC_FSULE_df:
18677 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18678 break;
18679 case OPC_FMAX_A_df:
18680 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18681 break;
18682 default:
18683 MIPS_INVAL("MSA instruction");
18684 generate_exception_end(ctx, EXCP_RI);
18685 break;
18686 }
18687
18688 tcg_temp_free_i32(twd);
18689 tcg_temp_free_i32(tws);
18690 tcg_temp_free_i32(twt);
18691 tcg_temp_free_i32(tdf);
18692 }
18693
18694 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18695 {
18696 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18697 (op & (0x7 << 18)))
18698 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18699 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18700 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18701 uint8_t df = (ctx->opcode >> 16) & 0x3;
18702 TCGv_i32 twd = tcg_const_i32(wd);
18703 TCGv_i32 tws = tcg_const_i32(ws);
18704 TCGv_i32 twt = tcg_const_i32(wt);
18705 TCGv_i32 tdf = tcg_const_i32(df);
18706
18707 switch (MASK_MSA_2R(ctx->opcode)) {
18708 case OPC_FILL_df:
18709 #if !defined(TARGET_MIPS64)
18710 /* Double format valid only for MIPS64 */
18711 if (df == DF_DOUBLE) {
18712 generate_exception_end(ctx, EXCP_RI);
18713 break;
18714 }
18715 #endif
18716 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18717 break;
18718 case OPC_PCNT_df:
18719 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18720 break;
18721 case OPC_NLOC_df:
18722 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18723 break;
18724 case OPC_NLZC_df:
18725 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18726 break;
18727 default:
18728 MIPS_INVAL("MSA instruction");
18729 generate_exception_end(ctx, EXCP_RI);
18730 break;
18731 }
18732
18733 tcg_temp_free_i32(twd);
18734 tcg_temp_free_i32(tws);
18735 tcg_temp_free_i32(twt);
18736 tcg_temp_free_i32(tdf);
18737 }
18738
18739 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18740 {
18741 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18742 (op & (0xf << 17)))
18743 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18744 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18745 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18746 uint8_t df = (ctx->opcode >> 16) & 0x1;
18747 TCGv_i32 twd = tcg_const_i32(wd);
18748 TCGv_i32 tws = tcg_const_i32(ws);
18749 TCGv_i32 twt = tcg_const_i32(wt);
18750 /* adjust df value for floating-point instruction */
18751 TCGv_i32 tdf = tcg_const_i32(df + 2);
18752
18753 switch (MASK_MSA_2RF(ctx->opcode)) {
18754 case OPC_FCLASS_df:
18755 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18756 break;
18757 case OPC_FTRUNC_S_df:
18758 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18759 break;
18760 case OPC_FTRUNC_U_df:
18761 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18762 break;
18763 case OPC_FSQRT_df:
18764 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18765 break;
18766 case OPC_FRSQRT_df:
18767 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18768 break;
18769 case OPC_FRCP_df:
18770 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18771 break;
18772 case OPC_FRINT_df:
18773 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18774 break;
18775 case OPC_FLOG2_df:
18776 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18777 break;
18778 case OPC_FEXUPL_df:
18779 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18780 break;
18781 case OPC_FEXUPR_df:
18782 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18783 break;
18784 case OPC_FFQL_df:
18785 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18786 break;
18787 case OPC_FFQR_df:
18788 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18789 break;
18790 case OPC_FTINT_S_df:
18791 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18792 break;
18793 case OPC_FTINT_U_df:
18794 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18795 break;
18796 case OPC_FFINT_S_df:
18797 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18798 break;
18799 case OPC_FFINT_U_df:
18800 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18801 break;
18802 }
18803
18804 tcg_temp_free_i32(twd);
18805 tcg_temp_free_i32(tws);
18806 tcg_temp_free_i32(twt);
18807 tcg_temp_free_i32(tdf);
18808 }
18809
18810 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18811 {
18812 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18813 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18814 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18815 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18816 TCGv_i32 twd = tcg_const_i32(wd);
18817 TCGv_i32 tws = tcg_const_i32(ws);
18818 TCGv_i32 twt = tcg_const_i32(wt);
18819
18820 switch (MASK_MSA_VEC(ctx->opcode)) {
18821 case OPC_AND_V:
18822 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18823 break;
18824 case OPC_OR_V:
18825 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18826 break;
18827 case OPC_NOR_V:
18828 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18829 break;
18830 case OPC_XOR_V:
18831 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18832 break;
18833 case OPC_BMNZ_V:
18834 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18835 break;
18836 case OPC_BMZ_V:
18837 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18838 break;
18839 case OPC_BSEL_V:
18840 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18841 break;
18842 default:
18843 MIPS_INVAL("MSA instruction");
18844 generate_exception_end(ctx, EXCP_RI);
18845 break;
18846 }
18847
18848 tcg_temp_free_i32(twd);
18849 tcg_temp_free_i32(tws);
18850 tcg_temp_free_i32(twt);
18851 }
18852
18853 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18854 {
18855 switch (MASK_MSA_VEC(ctx->opcode)) {
18856 case OPC_AND_V:
18857 case OPC_OR_V:
18858 case OPC_NOR_V:
18859 case OPC_XOR_V:
18860 case OPC_BMNZ_V:
18861 case OPC_BMZ_V:
18862 case OPC_BSEL_V:
18863 gen_msa_vec_v(env, ctx);
18864 break;
18865 case OPC_MSA_2R:
18866 gen_msa_2r(env, ctx);
18867 break;
18868 case OPC_MSA_2RF:
18869 gen_msa_2rf(env, ctx);
18870 break;
18871 default:
18872 MIPS_INVAL("MSA instruction");
18873 generate_exception_end(ctx, EXCP_RI);
18874 break;
18875 }
18876 }
18877
18878 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18879 {
18880 uint32_t opcode = ctx->opcode;
18881 check_insn(ctx, ASE_MSA);
18882 check_msa_access(ctx);
18883
18884 switch (MASK_MSA_MINOR(opcode)) {
18885 case OPC_MSA_I8_00:
18886 case OPC_MSA_I8_01:
18887 case OPC_MSA_I8_02:
18888 gen_msa_i8(env, ctx);
18889 break;
18890 case OPC_MSA_I5_06:
18891 case OPC_MSA_I5_07:
18892 gen_msa_i5(env, ctx);
18893 break;
18894 case OPC_MSA_BIT_09:
18895 case OPC_MSA_BIT_0A:
18896 gen_msa_bit(env, ctx);
18897 break;
18898 case OPC_MSA_3R_0D:
18899 case OPC_MSA_3R_0E:
18900 case OPC_MSA_3R_0F:
18901 case OPC_MSA_3R_10:
18902 case OPC_MSA_3R_11:
18903 case OPC_MSA_3R_12:
18904 case OPC_MSA_3R_13:
18905 case OPC_MSA_3R_14:
18906 case OPC_MSA_3R_15:
18907 gen_msa_3r(env, ctx);
18908 break;
18909 case OPC_MSA_ELM:
18910 gen_msa_elm(env, ctx);
18911 break;
18912 case OPC_MSA_3RF_1A:
18913 case OPC_MSA_3RF_1B:
18914 case OPC_MSA_3RF_1C:
18915 gen_msa_3rf(env, ctx);
18916 break;
18917 case OPC_MSA_VEC:
18918 gen_msa_vec(env, ctx);
18919 break;
18920 case OPC_LD_B:
18921 case OPC_LD_H:
18922 case OPC_LD_W:
18923 case OPC_LD_D:
18924 case OPC_ST_B:
18925 case OPC_ST_H:
18926 case OPC_ST_W:
18927 case OPC_ST_D:
18928 {
18929 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18930 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18931 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18932 uint8_t df = (ctx->opcode >> 0) & 0x3;
18933
18934 TCGv_i32 twd = tcg_const_i32(wd);
18935 TCGv taddr = tcg_temp_new();
18936 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
18937
18938 switch (MASK_MSA_MINOR(opcode)) {
18939 case OPC_LD_B:
18940 gen_helper_msa_ld_b(cpu_env, twd, taddr);
18941 break;
18942 case OPC_LD_H:
18943 gen_helper_msa_ld_h(cpu_env, twd, taddr);
18944 break;
18945 case OPC_LD_W:
18946 gen_helper_msa_ld_w(cpu_env, twd, taddr);
18947 break;
18948 case OPC_LD_D:
18949 gen_helper_msa_ld_d(cpu_env, twd, taddr);
18950 break;
18951 case OPC_ST_B:
18952 gen_helper_msa_st_b(cpu_env, twd, taddr);
18953 break;
18954 case OPC_ST_H:
18955 gen_helper_msa_st_h(cpu_env, twd, taddr);
18956 break;
18957 case OPC_ST_W:
18958 gen_helper_msa_st_w(cpu_env, twd, taddr);
18959 break;
18960 case OPC_ST_D:
18961 gen_helper_msa_st_d(cpu_env, twd, taddr);
18962 break;
18963 }
18964
18965 tcg_temp_free_i32(twd);
18966 tcg_temp_free(taddr);
18967 }
18968 break;
18969 default:
18970 MIPS_INVAL("MSA instruction");
18971 generate_exception_end(ctx, EXCP_RI);
18972 break;
18973 }
18974
18975 }
18976
18977 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
18978 {
18979 int32_t offset;
18980 int rs, rt, rd, sa;
18981 uint32_t op, op1;
18982 int16_t imm;
18983
18984 /* make sure instructions are on a word boundary */
18985 if (ctx->pc & 0x3) {
18986 env->CP0_BadVAddr = ctx->pc;
18987 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
18988 return;
18989 }
18990
18991 /* Handle blikely not taken case */
18992 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
18993 TCGLabel *l1 = gen_new_label();
18994
18995 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18996 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18997 gen_goto_tb(ctx, 1, ctx->pc + 4);
18998 gen_set_label(l1);
18999 }
19000
19001 op = MASK_OP_MAJOR(ctx->opcode);
19002 rs = (ctx->opcode >> 21) & 0x1f;
19003 rt = (ctx->opcode >> 16) & 0x1f;
19004 rd = (ctx->opcode >> 11) & 0x1f;
19005 sa = (ctx->opcode >> 6) & 0x1f;
19006 imm = (int16_t)ctx->opcode;
19007 switch (op) {
19008 case OPC_SPECIAL:
19009 decode_opc_special(env, ctx);
19010 break;
19011 case OPC_SPECIAL2:
19012 decode_opc_special2_legacy(env, ctx);
19013 break;
19014 case OPC_SPECIAL3:
19015 decode_opc_special3(env, ctx);
19016 break;
19017 case OPC_REGIMM:
19018 op1 = MASK_REGIMM(ctx->opcode);
19019 switch (op1) {
19020 case OPC_BLTZL: /* REGIMM branches */
19021 case OPC_BGEZL:
19022 case OPC_BLTZALL:
19023 case OPC_BGEZALL:
19024 check_insn(ctx, ISA_MIPS2);
19025 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19026 /* Fallthrough */
19027 case OPC_BLTZ:
19028 case OPC_BGEZ:
19029 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19030 break;
19031 case OPC_BLTZAL:
19032 case OPC_BGEZAL:
19033 if (ctx->insn_flags & ISA_MIPS32R6) {
19034 if (rs == 0) {
19035 /* OPC_NAL, OPC_BAL */
19036 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
19037 } else {
19038 generate_exception_end(ctx, EXCP_RI);
19039 }
19040 } else {
19041 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
19042 }
19043 break;
19044 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
19045 case OPC_TNEI:
19046 check_insn(ctx, ISA_MIPS2);
19047 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19048 gen_trap(ctx, op1, rs, -1, imm);
19049 break;
19050 case OPC_SIGRIE:
19051 check_insn(ctx, ISA_MIPS32R6);
19052 generate_exception_end(ctx, EXCP_RI);
19053 break;
19054 case OPC_SYNCI:
19055 check_insn(ctx, ISA_MIPS32R2);
19056 /* Break the TB to be able to sync copied instructions
19057 immediately */
19058 ctx->bstate = BS_STOP;
19059 break;
19060 case OPC_BPOSGE32: /* MIPS DSP branch */
19061 #if defined(TARGET_MIPS64)
19062 case OPC_BPOSGE64:
19063 #endif
19064 check_dsp(ctx);
19065 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
19066 break;
19067 #if defined(TARGET_MIPS64)
19068 case OPC_DAHI:
19069 check_insn(ctx, ISA_MIPS32R6);
19070 check_mips_64(ctx);
19071 if (rs != 0) {
19072 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
19073 }
19074 break;
19075 case OPC_DATI:
19076 check_insn(ctx, ISA_MIPS32R6);
19077 check_mips_64(ctx);
19078 if (rs != 0) {
19079 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19080 }
19081 break;
19082 #endif
19083 default: /* Invalid */
19084 MIPS_INVAL("regimm");
19085 generate_exception_end(ctx, EXCP_RI);
19086 break;
19087 }
19088 break;
19089 case OPC_CP0:
19090 check_cp0_enabled(ctx);
19091 op1 = MASK_CP0(ctx->opcode);
19092 switch (op1) {
19093 case OPC_MFC0:
19094 case OPC_MTC0:
19095 case OPC_MFTR:
19096 case OPC_MTTR:
19097 case OPC_MFHC0:
19098 case OPC_MTHC0:
19099 #if defined(TARGET_MIPS64)
19100 case OPC_DMFC0:
19101 case OPC_DMTC0:
19102 #endif
19103 #ifndef CONFIG_USER_ONLY
19104 gen_cp0(env, ctx, op1, rt, rd);
19105 #endif /* !CONFIG_USER_ONLY */
19106 break;
19107 case OPC_C0_FIRST ... OPC_C0_LAST:
19108 #ifndef CONFIG_USER_ONLY
19109 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19110 #endif /* !CONFIG_USER_ONLY */
19111 break;
19112 case OPC_MFMC0:
19113 #ifndef CONFIG_USER_ONLY
19114 {
19115 uint32_t op2;
19116 TCGv t0 = tcg_temp_new();
19117
19118 op2 = MASK_MFMC0(ctx->opcode);
19119 switch (op2) {
19120 case OPC_DMT:
19121 check_insn(ctx, ASE_MT);
19122 gen_helper_dmt(t0);
19123 gen_store_gpr(t0, rt);
19124 break;
19125 case OPC_EMT:
19126 check_insn(ctx, ASE_MT);
19127 gen_helper_emt(t0);
19128 gen_store_gpr(t0, rt);
19129 break;
19130 case OPC_DVPE:
19131 check_insn(ctx, ASE_MT);
19132 gen_helper_dvpe(t0, cpu_env);
19133 gen_store_gpr(t0, rt);
19134 break;
19135 case OPC_EVPE:
19136 check_insn(ctx, ASE_MT);
19137 gen_helper_evpe(t0, cpu_env);
19138 gen_store_gpr(t0, rt);
19139 break;
19140 case OPC_DVP:
19141 check_insn(ctx, ISA_MIPS32R6);
19142 if (ctx->vp) {
19143 gen_helper_dvp(t0, cpu_env);
19144 gen_store_gpr(t0, rt);
19145 }
19146 break;
19147 case OPC_EVP:
19148 check_insn(ctx, ISA_MIPS32R6);
19149 if (ctx->vp) {
19150 gen_helper_evp(t0, cpu_env);
19151 gen_store_gpr(t0, rt);
19152 }
19153 break;
19154 case OPC_DI:
19155 check_insn(ctx, ISA_MIPS32R2);
19156 save_cpu_state(ctx, 1);
19157 gen_helper_di(t0, cpu_env);
19158 gen_store_gpr(t0, rt);
19159 /* Stop translation as we may have switched
19160 the execution mode. */
19161 ctx->bstate = BS_STOP;
19162 break;
19163 case OPC_EI:
19164 check_insn(ctx, ISA_MIPS32R2);
19165 save_cpu_state(ctx, 1);
19166 gen_helper_ei(t0, cpu_env);
19167 gen_store_gpr(t0, rt);
19168 /* Stop translation as we may have switched
19169 the execution mode. */
19170 ctx->bstate = BS_STOP;
19171 break;
19172 default: /* Invalid */
19173 MIPS_INVAL("mfmc0");
19174 generate_exception_end(ctx, EXCP_RI);
19175 break;
19176 }
19177 tcg_temp_free(t0);
19178 }
19179 #endif /* !CONFIG_USER_ONLY */
19180 break;
19181 case OPC_RDPGPR:
19182 check_insn(ctx, ISA_MIPS32R2);
19183 gen_load_srsgpr(rt, rd);
19184 break;
19185 case OPC_WRPGPR:
19186 check_insn(ctx, ISA_MIPS32R2);
19187 gen_store_srsgpr(rt, rd);
19188 break;
19189 default:
19190 MIPS_INVAL("cp0");
19191 generate_exception_end(ctx, EXCP_RI);
19192 break;
19193 }
19194 break;
19195 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19196 if (ctx->insn_flags & ISA_MIPS32R6) {
19197 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19198 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19199 } else {
19200 /* OPC_ADDI */
19201 /* Arithmetic with immediate opcode */
19202 gen_arith_imm(ctx, op, rt, rs, imm);
19203 }
19204 break;
19205 case OPC_ADDIU:
19206 gen_arith_imm(ctx, op, rt, rs, imm);
19207 break;
19208 case OPC_SLTI: /* Set on less than with immediate opcode */
19209 case OPC_SLTIU:
19210 gen_slt_imm(ctx, op, rt, rs, imm);
19211 break;
19212 case OPC_ANDI: /* Arithmetic with immediate opcode */
19213 case OPC_LUI: /* OPC_AUI */
19214 case OPC_ORI:
19215 case OPC_XORI:
19216 gen_logic_imm(ctx, op, rt, rs, imm);
19217 break;
19218 case OPC_J ... OPC_JAL: /* Jump */
19219 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19220 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19221 break;
19222 /* Branch */
19223 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19224 if (ctx->insn_flags & ISA_MIPS32R6) {
19225 if (rt == 0) {
19226 generate_exception_end(ctx, EXCP_RI);
19227 break;
19228 }
19229 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19230 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19231 } else {
19232 /* OPC_BLEZL */
19233 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19234 }
19235 break;
19236 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19237 if (ctx->insn_flags & ISA_MIPS32R6) {
19238 if (rt == 0) {
19239 generate_exception_end(ctx, EXCP_RI);
19240 break;
19241 }
19242 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19243 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19244 } else {
19245 /* OPC_BGTZL */
19246 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19247 }
19248 break;
19249 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19250 if (rt == 0) {
19251 /* OPC_BLEZ */
19252 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19253 } else {
19254 check_insn(ctx, ISA_MIPS32R6);
19255 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19256 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19257 }
19258 break;
19259 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19260 if (rt == 0) {
19261 /* OPC_BGTZ */
19262 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19263 } else {
19264 check_insn(ctx, ISA_MIPS32R6);
19265 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19266 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19267 }
19268 break;
19269 case OPC_BEQL:
19270 case OPC_BNEL:
19271 check_insn(ctx, ISA_MIPS2);
19272 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19273 /* Fallthrough */
19274 case OPC_BEQ:
19275 case OPC_BNE:
19276 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19277 break;
19278 case OPC_LL: /* Load and stores */
19279 check_insn(ctx, ISA_MIPS2);
19280 /* Fallthrough */
19281 case OPC_LWL:
19282 case OPC_LWR:
19283 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19284 /* Fallthrough */
19285 case OPC_LB ... OPC_LH:
19286 case OPC_LW ... OPC_LHU:
19287 gen_ld(ctx, op, rt, rs, imm);
19288 break;
19289 case OPC_SWL:
19290 case OPC_SWR:
19291 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19292 /* fall through */
19293 case OPC_SB ... OPC_SH:
19294 case OPC_SW:
19295 gen_st(ctx, op, rt, rs, imm);
19296 break;
19297 case OPC_SC:
19298 check_insn(ctx, ISA_MIPS2);
19299 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19300 gen_st_cond(ctx, op, rt, rs, imm);
19301 break;
19302 case OPC_CACHE:
19303 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19304 check_cp0_enabled(ctx);
19305 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19306 /* Treat as NOP. */
19307 break;
19308 case OPC_PREF:
19309 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19310 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19311 /* Treat as NOP. */
19312 break;
19313
19314 /* Floating point (COP1). */
19315 case OPC_LWC1:
19316 case OPC_LDC1:
19317 case OPC_SWC1:
19318 case OPC_SDC1:
19319 gen_cop1_ldst(ctx, op, rt, rs, imm);
19320 break;
19321
19322 case OPC_CP1:
19323 op1 = MASK_CP1(ctx->opcode);
19324
19325 switch (op1) {
19326 case OPC_MFHC1:
19327 case OPC_MTHC1:
19328 check_cp1_enabled(ctx);
19329 check_insn(ctx, ISA_MIPS32R2);
19330 case OPC_MFC1:
19331 case OPC_CFC1:
19332 case OPC_MTC1:
19333 case OPC_CTC1:
19334 check_cp1_enabled(ctx);
19335 gen_cp1(ctx, op1, rt, rd);
19336 break;
19337 #if defined(TARGET_MIPS64)
19338 case OPC_DMFC1:
19339 case OPC_DMTC1:
19340 check_cp1_enabled(ctx);
19341 check_insn(ctx, ISA_MIPS3);
19342 check_mips_64(ctx);
19343 gen_cp1(ctx, op1, rt, rd);
19344 break;
19345 #endif
19346 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19347 check_cp1_enabled(ctx);
19348 if (ctx->insn_flags & ISA_MIPS32R6) {
19349 /* OPC_BC1EQZ */
19350 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19351 rt, imm << 2, 4);
19352 } else {
19353 /* OPC_BC1ANY2 */
19354 check_cop1x(ctx);
19355 check_insn(ctx, ASE_MIPS3D);
19356 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19357 (rt >> 2) & 0x7, imm << 2);
19358 }
19359 break;
19360 case OPC_BC1NEZ:
19361 check_cp1_enabled(ctx);
19362 check_insn(ctx, ISA_MIPS32R6);
19363 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19364 rt, imm << 2, 4);
19365 break;
19366 case OPC_BC1ANY4:
19367 check_cp1_enabled(ctx);
19368 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19369 check_cop1x(ctx);
19370 check_insn(ctx, ASE_MIPS3D);
19371 /* fall through */
19372 case OPC_BC1:
19373 check_cp1_enabled(ctx);
19374 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19375 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19376 (rt >> 2) & 0x7, imm << 2);
19377 break;
19378 case OPC_PS_FMT:
19379 check_ps(ctx);
19380 /* fall through */
19381 case OPC_S_FMT:
19382 case OPC_D_FMT:
19383 check_cp1_enabled(ctx);
19384 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19385 (imm >> 8) & 0x7);
19386 break;
19387 case OPC_W_FMT:
19388 case OPC_L_FMT:
19389 {
19390 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19391 check_cp1_enabled(ctx);
19392 if (ctx->insn_flags & ISA_MIPS32R6) {
19393 switch (r6_op) {
19394 case R6_OPC_CMP_AF_S:
19395 case R6_OPC_CMP_UN_S:
19396 case R6_OPC_CMP_EQ_S:
19397 case R6_OPC_CMP_UEQ_S:
19398 case R6_OPC_CMP_LT_S:
19399 case R6_OPC_CMP_ULT_S:
19400 case R6_OPC_CMP_LE_S:
19401 case R6_OPC_CMP_ULE_S:
19402 case R6_OPC_CMP_SAF_S:
19403 case R6_OPC_CMP_SUN_S:
19404 case R6_OPC_CMP_SEQ_S:
19405 case R6_OPC_CMP_SEUQ_S:
19406 case R6_OPC_CMP_SLT_S:
19407 case R6_OPC_CMP_SULT_S:
19408 case R6_OPC_CMP_SLE_S:
19409 case R6_OPC_CMP_SULE_S:
19410 case R6_OPC_CMP_OR_S:
19411 case R6_OPC_CMP_UNE_S:
19412 case R6_OPC_CMP_NE_S:
19413 case R6_OPC_CMP_SOR_S:
19414 case R6_OPC_CMP_SUNE_S:
19415 case R6_OPC_CMP_SNE_S:
19416 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19417 break;
19418 case R6_OPC_CMP_AF_D:
19419 case R6_OPC_CMP_UN_D:
19420 case R6_OPC_CMP_EQ_D:
19421 case R6_OPC_CMP_UEQ_D:
19422 case R6_OPC_CMP_LT_D:
19423 case R6_OPC_CMP_ULT_D:
19424 case R6_OPC_CMP_LE_D:
19425 case R6_OPC_CMP_ULE_D:
19426 case R6_OPC_CMP_SAF_D:
19427 case R6_OPC_CMP_SUN_D:
19428 case R6_OPC_CMP_SEQ_D:
19429 case R6_OPC_CMP_SEUQ_D:
19430 case R6_OPC_CMP_SLT_D:
19431 case R6_OPC_CMP_SULT_D:
19432 case R6_OPC_CMP_SLE_D:
19433 case R6_OPC_CMP_SULE_D:
19434 case R6_OPC_CMP_OR_D:
19435 case R6_OPC_CMP_UNE_D:
19436 case R6_OPC_CMP_NE_D:
19437 case R6_OPC_CMP_SOR_D:
19438 case R6_OPC_CMP_SUNE_D:
19439 case R6_OPC_CMP_SNE_D:
19440 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19441 break;
19442 default:
19443 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19444 rt, rd, sa, (imm >> 8) & 0x7);
19445
19446 break;
19447 }
19448 } else {
19449 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19450 (imm >> 8) & 0x7);
19451 }
19452 break;
19453 }
19454 case OPC_BZ_V:
19455 case OPC_BNZ_V:
19456 case OPC_BZ_B:
19457 case OPC_BZ_H:
19458 case OPC_BZ_W:
19459 case OPC_BZ_D:
19460 case OPC_BNZ_B:
19461 case OPC_BNZ_H:
19462 case OPC_BNZ_W:
19463 case OPC_BNZ_D:
19464 check_insn(ctx, ASE_MSA);
19465 gen_msa_branch(env, ctx, op1);
19466 break;
19467 default:
19468 MIPS_INVAL("cp1");
19469 generate_exception_end(ctx, EXCP_RI);
19470 break;
19471 }
19472 break;
19473
19474 /* Compact branches [R6] and COP2 [non-R6] */
19475 case OPC_BC: /* OPC_LWC2 */
19476 case OPC_BALC: /* OPC_SWC2 */
19477 if (ctx->insn_flags & ISA_MIPS32R6) {
19478 /* OPC_BC, OPC_BALC */
19479 gen_compute_compact_branch(ctx, op, 0, 0,
19480 sextract32(ctx->opcode << 2, 0, 28));
19481 } else {
19482 /* OPC_LWC2, OPC_SWC2 */
19483 /* COP2: Not implemented. */
19484 generate_exception_err(ctx, EXCP_CpU, 2);
19485 }
19486 break;
19487 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19488 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19489 if (ctx->insn_flags & ISA_MIPS32R6) {
19490 if (rs != 0) {
19491 /* OPC_BEQZC, OPC_BNEZC */
19492 gen_compute_compact_branch(ctx, op, rs, 0,
19493 sextract32(ctx->opcode << 2, 0, 23));
19494 } else {
19495 /* OPC_JIC, OPC_JIALC */
19496 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19497 }
19498 } else {
19499 /* OPC_LWC2, OPC_SWC2 */
19500 /* COP2: Not implemented. */
19501 generate_exception_err(ctx, EXCP_CpU, 2);
19502 }
19503 break;
19504 case OPC_CP2:
19505 check_insn(ctx, INSN_LOONGSON2F);
19506 /* Note that these instructions use different fields. */
19507 gen_loongson_multimedia(ctx, sa, rd, rt);
19508 break;
19509
19510 case OPC_CP3:
19511 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19512 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19513 check_cp1_enabled(ctx);
19514 op1 = MASK_CP3(ctx->opcode);
19515 switch (op1) {
19516 case OPC_LUXC1:
19517 case OPC_SUXC1:
19518 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19519 /* Fallthrough */
19520 case OPC_LWXC1:
19521 case OPC_LDXC1:
19522 case OPC_SWXC1:
19523 case OPC_SDXC1:
19524 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19525 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19526 break;
19527 case OPC_PREFX:
19528 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19529 /* Treat as NOP. */
19530 break;
19531 case OPC_ALNV_PS:
19532 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19533 /* Fallthrough */
19534 case OPC_MADD_S:
19535 case OPC_MADD_D:
19536 case OPC_MADD_PS:
19537 case OPC_MSUB_S:
19538 case OPC_MSUB_D:
19539 case OPC_MSUB_PS:
19540 case OPC_NMADD_S:
19541 case OPC_NMADD_D:
19542 case OPC_NMADD_PS:
19543 case OPC_NMSUB_S:
19544 case OPC_NMSUB_D:
19545 case OPC_NMSUB_PS:
19546 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19547 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19548 break;
19549 default:
19550 MIPS_INVAL("cp3");
19551 generate_exception_end(ctx, EXCP_RI);
19552 break;
19553 }
19554 } else {
19555 generate_exception_err(ctx, EXCP_CpU, 1);
19556 }
19557 break;
19558
19559 #if defined(TARGET_MIPS64)
19560 /* MIPS64 opcodes */
19561 case OPC_LDL ... OPC_LDR:
19562 case OPC_LLD:
19563 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19564 /* fall through */
19565 case OPC_LWU:
19566 case OPC_LD:
19567 check_insn(ctx, ISA_MIPS3);
19568 check_mips_64(ctx);
19569 gen_ld(ctx, op, rt, rs, imm);
19570 break;
19571 case OPC_SDL ... OPC_SDR:
19572 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19573 /* fall through */
19574 case OPC_SD:
19575 check_insn(ctx, ISA_MIPS3);
19576 check_mips_64(ctx);
19577 gen_st(ctx, op, rt, rs, imm);
19578 break;
19579 case OPC_SCD:
19580 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19581 check_insn(ctx, ISA_MIPS3);
19582 check_mips_64(ctx);
19583 gen_st_cond(ctx, op, rt, rs, imm);
19584 break;
19585 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19586 if (ctx->insn_flags & ISA_MIPS32R6) {
19587 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19588 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19589 } else {
19590 /* OPC_DADDI */
19591 check_insn(ctx, ISA_MIPS3);
19592 check_mips_64(ctx);
19593 gen_arith_imm(ctx, op, rt, rs, imm);
19594 }
19595 break;
19596 case OPC_DADDIU:
19597 check_insn(ctx, ISA_MIPS3);
19598 check_mips_64(ctx);
19599 gen_arith_imm(ctx, op, rt, rs, imm);
19600 break;
19601 #else
19602 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19603 if (ctx->insn_flags & ISA_MIPS32R6) {
19604 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19605 } else {
19606 MIPS_INVAL("major opcode");
19607 generate_exception_end(ctx, EXCP_RI);
19608 }
19609 break;
19610 #endif
19611 case OPC_DAUI: /* OPC_JALX */
19612 if (ctx->insn_flags & ISA_MIPS32R6) {
19613 #if defined(TARGET_MIPS64)
19614 /* OPC_DAUI */
19615 check_mips_64(ctx);
19616 if (rs == 0) {
19617 generate_exception(ctx, EXCP_RI);
19618 } else if (rt != 0) {
19619 TCGv t0 = tcg_temp_new();
19620 gen_load_gpr(t0, rs);
19621 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19622 tcg_temp_free(t0);
19623 }
19624 #else
19625 generate_exception_end(ctx, EXCP_RI);
19626 MIPS_INVAL("major opcode");
19627 #endif
19628 } else {
19629 /* OPC_JALX */
19630 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19631 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19632 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19633 }
19634 break;
19635 case OPC_MSA: /* OPC_MDMX */
19636 /* MDMX: Not implemented. */
19637 gen_msa(env, ctx);
19638 break;
19639 case OPC_PCREL:
19640 check_insn(ctx, ISA_MIPS32R6);
19641 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
19642 break;
19643 default: /* Invalid */
19644 MIPS_INVAL("major opcode");
19645 generate_exception_end(ctx, EXCP_RI);
19646 break;
19647 }
19648 }
19649
19650 void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
19651 {
19652 MIPSCPU *cpu = mips_env_get_cpu(env);
19653 CPUState *cs = CPU(cpu);
19654 DisasContext ctx;
19655 target_ulong pc_start;
19656 target_ulong next_page_start;
19657 int num_insns;
19658 int max_insns;
19659 int insn_bytes;
19660 int is_slot;
19661
19662 pc_start = tb->pc;
19663 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19664 ctx.pc = pc_start;
19665 ctx.saved_pc = -1;
19666 ctx.singlestep_enabled = cs->singlestep_enabled;
19667 ctx.insn_flags = env->insn_flags;
19668 ctx.CP0_Config1 = env->CP0_Config1;
19669 ctx.tb = tb;
19670 ctx.bstate = BS_NONE;
19671 ctx.btarget = 0;
19672 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19673 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19674 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19675 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19676 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19677 ctx.PAMask = env->PAMask;
19678 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19679 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
19680 ctx.cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
19681 /* Restore delay slot state from the tb context. */
19682 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19683 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
19684 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19685 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
19686 ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
19687 restore_cpu_state(env, &ctx);
19688 #ifdef CONFIG_USER_ONLY
19689 ctx.mem_idx = MIPS_HFLAG_UM;
19690 #else
19691 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19692 #endif
19693 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19694 MO_UNALN : MO_ALIGN;
19695 num_insns = 0;
19696 max_insns = tb->cflags & CF_COUNT_MASK;
19697 if (max_insns == 0) {
19698 max_insns = CF_COUNT_MASK;
19699 }
19700 if (max_insns > TCG_MAX_INSNS) {
19701 max_insns = TCG_MAX_INSNS;
19702 }
19703
19704 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19705 gen_tb_start(tb);
19706 while (ctx.bstate == BS_NONE) {
19707 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
19708 num_insns++;
19709
19710 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19711 save_cpu_state(&ctx, 1);
19712 ctx.bstate = BS_BRANCH;
19713 gen_helper_raise_exception_debug(cpu_env);
19714 /* The address covered by the breakpoint must be included in
19715 [tb->pc, tb->pc + tb->size) in order to for it to be
19716 properly cleared -- thus we increment the PC here so that
19717 the logic setting tb->size below does the right thing. */
19718 ctx.pc += 4;
19719 goto done_generating;
19720 }
19721
19722 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
19723 gen_io_start();
19724 }
19725
19726 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19727 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19728 ctx.opcode = cpu_ldl_code(env, ctx.pc);
19729 insn_bytes = 4;
19730 decode_opc(env, &ctx);
19731 } else if (ctx.insn_flags & ASE_MICROMIPS) {
19732 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19733 insn_bytes = decode_micromips_opc(env, &ctx);
19734 } else if (ctx.insn_flags & ASE_MIPS16) {
19735 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19736 insn_bytes = decode_mips16_opc(env, &ctx);
19737 } else {
19738 generate_exception_end(&ctx, EXCP_RI);
19739 break;
19740 }
19741
19742 if (ctx.hflags & MIPS_HFLAG_BMASK) {
19743 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19744 MIPS_HFLAG_FBNSLOT))) {
19745 /* force to generate branch as there is neither delay nor
19746 forbidden slot */
19747 is_slot = 1;
19748 }
19749 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19750 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19751 /* Force to generate branch as microMIPS R6 doesn't restrict
19752 branches in the forbidden slot. */
19753 is_slot = 1;
19754 }
19755 }
19756 if (is_slot) {
19757 gen_branch(&ctx, insn_bytes);
19758 }
19759 ctx.pc += insn_bytes;
19760
19761 /* Execute a branch and its delay slot as a single instruction.
19762 This is what GDB expects and is consistent with what the
19763 hardware does (e.g. if a delay slot instruction faults, the
19764 reported PC is the PC of the branch). */
19765 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
19766 break;
19767 }
19768
19769 if (ctx.pc >= next_page_start) {
19770 break;
19771 }
19772
19773 if (tcg_op_buf_full()) {
19774 break;
19775 }
19776
19777 if (num_insns >= max_insns)
19778 break;
19779
19780 if (singlestep)
19781 break;
19782 }
19783 if (tb->cflags & CF_LAST_IO) {
19784 gen_io_end();
19785 }
19786 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
19787 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
19788 gen_helper_raise_exception_debug(cpu_env);
19789 } else {
19790 switch (ctx.bstate) {
19791 case BS_STOP:
19792 gen_goto_tb(&ctx, 0, ctx.pc);
19793 break;
19794 case BS_NONE:
19795 save_cpu_state(&ctx, 0);
19796 gen_goto_tb(&ctx, 0, ctx.pc);
19797 break;
19798 case BS_EXCP:
19799 tcg_gen_exit_tb(0);
19800 break;
19801 case BS_BRANCH:
19802 default:
19803 break;
19804 }
19805 }
19806 done_generating:
19807 gen_tb_end(tb, num_insns);
19808
19809 tb->size = ctx.pc - pc_start;
19810 tb->icount = num_insns;
19811
19812 #ifdef DEBUG_DISAS
19813 LOG_DISAS("\n");
19814 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
19815 qemu_log("IN: %s\n", lookup_symbol(pc_start));
19816 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
19817 qemu_log("\n");
19818 }
19819 #endif
19820 }
19821
19822 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
19823 int flags)
19824 {
19825 int i;
19826 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
19827
19828 #define printfpr(fp) \
19829 do { \
19830 if (is_fpu64) \
19831 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19832 " fd:%13g fs:%13g psu: %13g\n", \
19833 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19834 (double)(fp)->fd, \
19835 (double)(fp)->fs[FP_ENDIAN_IDX], \
19836 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19837 else { \
19838 fpr_t tmp; \
19839 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19840 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19841 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19842 " fd:%13g fs:%13g psu:%13g\n", \
19843 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19844 (double)tmp.fd, \
19845 (double)tmp.fs[FP_ENDIAN_IDX], \
19846 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19847 } \
19848 } while(0)
19849
19850
19851 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19852 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
19853 get_float_exception_flags(&env->active_fpu.fp_status));
19854 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19855 fpu_fprintf(f, "%3s: ", fregnames[i]);
19856 printfpr(&env->active_fpu.fpr[i]);
19857 }
19858
19859 #undef printfpr
19860 }
19861
19862 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19863 int flags)
19864 {
19865 MIPSCPU *cpu = MIPS_CPU(cs);
19866 CPUMIPSState *env = &cpu->env;
19867 int i;
19868
19869 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19870 " LO=0x" TARGET_FMT_lx " ds %04x "
19871 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
19872 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19873 env->hflags, env->btarget, env->bcond);
19874 for (i = 0; i < 32; i++) {
19875 if ((i & 3) == 0)
19876 cpu_fprintf(f, "GPR%02d:", i);
19877 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
19878 if ((i & 3) == 3)
19879 cpu_fprintf(f, "\n");
19880 }
19881
19882 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
19883 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
19884 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
19885 PRIx64 "\n",
19886 env->CP0_Config0, env->CP0_Config1, env->lladdr);
19887 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19888 env->CP0_Config2, env->CP0_Config3);
19889 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19890 env->CP0_Config4, env->CP0_Config5);
19891 if (env->hflags & MIPS_HFLAG_FPU)
19892 fpu_dump_state(env, f, cpu_fprintf, flags);
19893 }
19894
19895 void mips_tcg_init(void)
19896 {
19897 int i;
19898 static int inited;
19899
19900 /* Initialize various static tables. */
19901 if (inited)
19902 return;
19903
19904 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
19905
19906 TCGV_UNUSED(cpu_gpr[0]);
19907 for (i = 1; i < 32; i++)
19908 cpu_gpr[i] = tcg_global_mem_new(cpu_env,
19909 offsetof(CPUMIPSState, active_tc.gpr[i]),
19910 regnames[i]);
19911
19912 for (i = 0; i < 32; i++) {
19913 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19914 msa_wr_d[i * 2] =
19915 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
19916 /* The scalar floating-point unit (FPU) registers are mapped on
19917 * the MSA vector registers. */
19918 fpu_f64[i] = msa_wr_d[i * 2];
19919 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19920 msa_wr_d[i * 2 + 1] =
19921 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
19922 }
19923
19924 cpu_PC = tcg_global_mem_new(cpu_env,
19925 offsetof(CPUMIPSState, active_tc.PC), "PC");
19926 for (i = 0; i < MIPS_DSP_ACC; i++) {
19927 cpu_HI[i] = tcg_global_mem_new(cpu_env,
19928 offsetof(CPUMIPSState, active_tc.HI[i]),
19929 regnames_HI[i]);
19930 cpu_LO[i] = tcg_global_mem_new(cpu_env,
19931 offsetof(CPUMIPSState, active_tc.LO[i]),
19932 regnames_LO[i]);
19933 }
19934 cpu_dspctrl = tcg_global_mem_new(cpu_env,
19935 offsetof(CPUMIPSState, active_tc.DSPControl),
19936 "DSPControl");
19937 bcond = tcg_global_mem_new(cpu_env,
19938 offsetof(CPUMIPSState, bcond), "bcond");
19939 btarget = tcg_global_mem_new(cpu_env,
19940 offsetof(CPUMIPSState, btarget), "btarget");
19941 hflags = tcg_global_mem_new_i32(cpu_env,
19942 offsetof(CPUMIPSState, hflags), "hflags");
19943
19944 fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
19945 offsetof(CPUMIPSState, active_fpu.fcr0),
19946 "fcr0");
19947 fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
19948 offsetof(CPUMIPSState, active_fpu.fcr31),
19949 "fcr31");
19950
19951 inited = 1;
19952 }
19953
19954 #include "translate_init.c"
19955
19956 MIPSCPU *cpu_mips_init(const char *cpu_model)
19957 {
19958 MIPSCPU *cpu;
19959 CPUMIPSState *env;
19960 const mips_def_t *def;
19961
19962 def = cpu_mips_find_by_name(cpu_model);
19963 if (!def)
19964 return NULL;
19965 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19966 env = &cpu->env;
19967 env->cpu_model = def;
19968
19969 #ifndef CONFIG_USER_ONLY
19970 mmu_init(env, def);
19971 #endif
19972 fpu_init(env, def);
19973 mvp_init(env, def);
19974
19975 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19976
19977 return cpu;
19978 }
19979
19980 void cpu_state_reset(CPUMIPSState *env)
19981 {
19982 MIPSCPU *cpu = mips_env_get_cpu(env);
19983 CPUState *cs = CPU(cpu);
19984
19985 /* Reset registers to their default values */
19986 env->CP0_PRid = env->cpu_model->CP0_PRid;
19987 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19988 #ifdef TARGET_WORDS_BIGENDIAN
19989 env->CP0_Config0 |= (1 << CP0C0_BE);
19990 #endif
19991 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19992 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19993 env->CP0_Config3 = env->cpu_model->CP0_Config3;
19994 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19995 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
19996 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19997 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
19998 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19999 env->CP0_Config7 = env->cpu_model->CP0_Config7;
20000 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
20001 << env->cpu_model->CP0_LLAddr_shift;
20002 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
20003 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
20004 env->CCRes = env->cpu_model->CCRes;
20005 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
20006 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
20007 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
20008 env->current_tc = 0;
20009 env->SEGBITS = env->cpu_model->SEGBITS;
20010 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
20011 #if defined(TARGET_MIPS64)
20012 if (env->cpu_model->insn_flags & ISA_MIPS3) {
20013 env->SEGMask |= 3ULL << 62;
20014 }
20015 #endif
20016 env->PABITS = env->cpu_model->PABITS;
20017 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
20018 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
20019 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
20020 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
20021 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
20022 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
20023 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
20024 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
20025 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
20026 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
20027 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
20028 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
20029 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
20030 env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
20031 env->msair = env->cpu_model->MSAIR;
20032 env->insn_flags = env->cpu_model->insn_flags;
20033
20034 #if defined(CONFIG_USER_ONLY)
20035 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
20036 # ifdef TARGET_MIPS64
20037 /* Enable 64-bit register mode. */
20038 env->CP0_Status |= (1 << CP0St_PX);
20039 # endif
20040 # ifdef TARGET_ABI_MIPSN64
20041 /* Enable 64-bit address mode. */
20042 env->CP0_Status |= (1 << CP0St_UX);
20043 # endif
20044 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20045 hardware registers. */
20046 env->CP0_HWREna |= 0x0000000F;
20047 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
20048 env->CP0_Status |= (1 << CP0St_CU1);
20049 }
20050 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
20051 env->CP0_Status |= (1 << CP0St_MX);
20052 }
20053 # if defined(TARGET_MIPS64)
20054 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20055 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
20056 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
20057 env->CP0_Status |= (1 << CP0St_FR);
20058 }
20059 # endif
20060 #else
20061 if (env->hflags & MIPS_HFLAG_BMASK) {
20062 /* If the exception was raised from a delay slot,
20063 come back to the jump. */
20064 env->CP0_ErrorEPC = (env->active_tc.PC
20065 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
20066 } else {
20067 env->CP0_ErrorEPC = env->active_tc.PC;
20068 }
20069 env->active_tc.PC = (int32_t)0xBFC00000;
20070 env->CP0_Random = env->tlb->nb_tlb - 1;
20071 env->tlb->tlb_in_use = env->tlb->nb_tlb;
20072 env->CP0_Wired = 0;
20073 env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
20074 env->CP0_EBase = (cs->cpu_index & 0x3FF);
20075 if (kvm_enabled()) {
20076 env->CP0_EBase |= 0x40000000;
20077 } else {
20078 env->CP0_EBase |= 0x80000000;
20079 }
20080 if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
20081 env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
20082 }
20083 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
20084 /* vectored interrupts not implemented, timer on int 7,
20085 no performance counters. */
20086 env->CP0_IntCtl = 0xe0000000;
20087 {
20088 int i;
20089
20090 for (i = 0; i < 7; i++) {
20091 env->CP0_WatchLo[i] = 0;
20092 env->CP0_WatchHi[i] = 0x80000000;
20093 }
20094 env->CP0_WatchLo[7] = 0;
20095 env->CP0_WatchHi[7] = 0;
20096 }
20097 /* Count register increments in debug mode, EJTAG version 1 */
20098 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
20099
20100 cpu_mips_store_count(env, 1);
20101
20102 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20103 int i;
20104
20105 /* Only TC0 on VPE 0 starts as active. */
20106 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20107 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20108 env->tcs[i].CP0_TCHalt = 1;
20109 }
20110 env->active_tc.CP0_TCHalt = 1;
20111 cs->halted = 1;
20112
20113 if (cs->cpu_index == 0) {
20114 /* VPE0 starts up enabled. */
20115 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20116 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20117
20118 /* TC0 starts up unhalted. */
20119 cs->halted = 0;
20120 env->active_tc.CP0_TCHalt = 0;
20121 env->tcs[0].CP0_TCHalt = 0;
20122 /* With thread 0 active. */
20123 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20124 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20125 }
20126 }
20127 #endif
20128 if ((env->insn_flags & ISA_MIPS32R6) &&
20129 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20130 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20131 env->CP0_Status |= (1 << CP0St_FR);
20132 }
20133
20134 /* MSA */
20135 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20136 msa_reset(env);
20137 }
20138
20139 compute_hflags(env);
20140 restore_rounding_mode(env);
20141 restore_flush_mode(env);
20142 restore_pamask(env);
20143 cs->exception_index = EXCP_NONE;
20144
20145 if (semihosting_get_argc()) {
20146 /* UHI interface can be used to obtain argc and argv */
20147 env->active_tc.gpr[4] = -1;
20148 }
20149 }
20150
20151 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20152 target_ulong *data)
20153 {
20154 env->active_tc.PC = data[0];
20155 env->hflags &= ~MIPS_HFLAG_BMASK;
20156 env->hflags |= data[1];
20157 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20158 case MIPS_HFLAG_BR:
20159 break;
20160 case MIPS_HFLAG_BC:
20161 case MIPS_HFLAG_BL:
20162 case MIPS_HFLAG_B:
20163 env->btarget = data[2];
20164 break;
20165 }
20166 }