]> git.proxmox.com Git - mirror_qemu.git/blob - target-mips/translate.c
target-mips: add PC, XNP reg numbers to RDHWR
[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 "cpu.h"
25 #include "disas/disas.h"
26 #include "tcg-op.h"
27 #include "exec/cpu_ldst.h"
28
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 #include "sysemu/kvm.h"
32 #include "exec/semihost.h"
33
34 #include "trace-tcg.h"
35
36 #define MIPS_DEBUG_DISAS 0
37
38 /* MIPS major opcodes */
39 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
40
41 enum {
42 /* indirect opcode tables */
43 OPC_SPECIAL = (0x00 << 26),
44 OPC_REGIMM = (0x01 << 26),
45 OPC_CP0 = (0x10 << 26),
46 OPC_CP1 = (0x11 << 26),
47 OPC_CP2 = (0x12 << 26),
48 OPC_CP3 = (0x13 << 26),
49 OPC_SPECIAL2 = (0x1C << 26),
50 OPC_SPECIAL3 = (0x1F << 26),
51 /* arithmetic with immediate */
52 OPC_ADDI = (0x08 << 26),
53 OPC_ADDIU = (0x09 << 26),
54 OPC_SLTI = (0x0A << 26),
55 OPC_SLTIU = (0x0B << 26),
56 /* logic with immediate */
57 OPC_ANDI = (0x0C << 26),
58 OPC_ORI = (0x0D << 26),
59 OPC_XORI = (0x0E << 26),
60 OPC_LUI = (0x0F << 26),
61 /* arithmetic with immediate */
62 OPC_DADDI = (0x18 << 26),
63 OPC_DADDIU = (0x19 << 26),
64 /* Jump and branches */
65 OPC_J = (0x02 << 26),
66 OPC_JAL = (0x03 << 26),
67 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
68 OPC_BEQL = (0x14 << 26),
69 OPC_BNE = (0x05 << 26),
70 OPC_BNEL = (0x15 << 26),
71 OPC_BLEZ = (0x06 << 26),
72 OPC_BLEZL = (0x16 << 26),
73 OPC_BGTZ = (0x07 << 26),
74 OPC_BGTZL = (0x17 << 26),
75 OPC_JALX = (0x1D << 26),
76 OPC_DAUI = (0x1D << 26),
77 /* Load and stores */
78 OPC_LDL = (0x1A << 26),
79 OPC_LDR = (0x1B << 26),
80 OPC_LB = (0x20 << 26),
81 OPC_LH = (0x21 << 26),
82 OPC_LWL = (0x22 << 26),
83 OPC_LW = (0x23 << 26),
84 OPC_LWPC = OPC_LW | 0x5,
85 OPC_LBU = (0x24 << 26),
86 OPC_LHU = (0x25 << 26),
87 OPC_LWR = (0x26 << 26),
88 OPC_LWU = (0x27 << 26),
89 OPC_SB = (0x28 << 26),
90 OPC_SH = (0x29 << 26),
91 OPC_SWL = (0x2A << 26),
92 OPC_SW = (0x2B << 26),
93 OPC_SDL = (0x2C << 26),
94 OPC_SDR = (0x2D << 26),
95 OPC_SWR = (0x2E << 26),
96 OPC_LL = (0x30 << 26),
97 OPC_LLD = (0x34 << 26),
98 OPC_LD = (0x37 << 26),
99 OPC_LDPC = OPC_LD | 0x5,
100 OPC_SC = (0x38 << 26),
101 OPC_SCD = (0x3C << 26),
102 OPC_SD = (0x3F << 26),
103 /* Floating point load/store */
104 OPC_LWC1 = (0x31 << 26),
105 OPC_LWC2 = (0x32 << 26),
106 OPC_LDC1 = (0x35 << 26),
107 OPC_LDC2 = (0x36 << 26),
108 OPC_SWC1 = (0x39 << 26),
109 OPC_SWC2 = (0x3A << 26),
110 OPC_SDC1 = (0x3D << 26),
111 OPC_SDC2 = (0x3E << 26),
112 /* Compact Branches */
113 OPC_BLEZALC = (0x06 << 26),
114 OPC_BGEZALC = (0x06 << 26),
115 OPC_BGEUC = (0x06 << 26),
116 OPC_BGTZALC = (0x07 << 26),
117 OPC_BLTZALC = (0x07 << 26),
118 OPC_BLTUC = (0x07 << 26),
119 OPC_BOVC = (0x08 << 26),
120 OPC_BEQZALC = (0x08 << 26),
121 OPC_BEQC = (0x08 << 26),
122 OPC_BLEZC = (0x16 << 26),
123 OPC_BGEZC = (0x16 << 26),
124 OPC_BGEC = (0x16 << 26),
125 OPC_BGTZC = (0x17 << 26),
126 OPC_BLTZC = (0x17 << 26),
127 OPC_BLTC = (0x17 << 26),
128 OPC_BNVC = (0x18 << 26),
129 OPC_BNEZALC = (0x18 << 26),
130 OPC_BNEC = (0x18 << 26),
131 OPC_BC = (0x32 << 26),
132 OPC_BEQZC = (0x36 << 26),
133 OPC_JIC = (0x36 << 26),
134 OPC_BALC = (0x3A << 26),
135 OPC_BNEZC = (0x3E << 26),
136 OPC_JIALC = (0x3E << 26),
137 /* MDMX ASE specific */
138 OPC_MDMX = (0x1E << 26),
139 /* MSA ASE, same as MDMX */
140 OPC_MSA = OPC_MDMX,
141 /* Cache and prefetch */
142 OPC_CACHE = (0x2F << 26),
143 OPC_PREF = (0x33 << 26),
144 /* PC-relative address computation / loads */
145 OPC_PCREL = (0x3B << 26),
146 };
147
148 /* PC-relative address computation / loads */
149 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
150 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
151 enum {
152 /* Instructions determined by bits 19 and 20 */
153 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
154 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
155 OPC_LWUPC = OPC_PCREL | (2 << 19),
156
157 /* Instructions determined by bits 16 ... 20 */
158 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
159 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
160
161 /* Other */
162 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
163 };
164
165 /* MIPS special opcodes */
166 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
167
168 enum {
169 /* Shifts */
170 OPC_SLL = 0x00 | OPC_SPECIAL,
171 /* NOP is SLL r0, r0, 0 */
172 /* SSNOP is SLL r0, r0, 1 */
173 /* EHB is SLL r0, r0, 3 */
174 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
175 OPC_ROTR = OPC_SRL | (1 << 21),
176 OPC_SRA = 0x03 | OPC_SPECIAL,
177 OPC_SLLV = 0x04 | OPC_SPECIAL,
178 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
179 OPC_ROTRV = OPC_SRLV | (1 << 6),
180 OPC_SRAV = 0x07 | OPC_SPECIAL,
181 OPC_DSLLV = 0x14 | OPC_SPECIAL,
182 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
183 OPC_DROTRV = OPC_DSRLV | (1 << 6),
184 OPC_DSRAV = 0x17 | OPC_SPECIAL,
185 OPC_DSLL = 0x38 | OPC_SPECIAL,
186 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
187 OPC_DROTR = OPC_DSRL | (1 << 21),
188 OPC_DSRA = 0x3B | OPC_SPECIAL,
189 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
190 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
191 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
192 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
193 /* Multiplication / division */
194 OPC_MULT = 0x18 | OPC_SPECIAL,
195 OPC_MULTU = 0x19 | OPC_SPECIAL,
196 OPC_DIV = 0x1A | OPC_SPECIAL,
197 OPC_DIVU = 0x1B | OPC_SPECIAL,
198 OPC_DMULT = 0x1C | OPC_SPECIAL,
199 OPC_DMULTU = 0x1D | OPC_SPECIAL,
200 OPC_DDIV = 0x1E | OPC_SPECIAL,
201 OPC_DDIVU = 0x1F | OPC_SPECIAL,
202
203 /* 2 registers arithmetic / logic */
204 OPC_ADD = 0x20 | OPC_SPECIAL,
205 OPC_ADDU = 0x21 | OPC_SPECIAL,
206 OPC_SUB = 0x22 | OPC_SPECIAL,
207 OPC_SUBU = 0x23 | OPC_SPECIAL,
208 OPC_AND = 0x24 | OPC_SPECIAL,
209 OPC_OR = 0x25 | OPC_SPECIAL,
210 OPC_XOR = 0x26 | OPC_SPECIAL,
211 OPC_NOR = 0x27 | OPC_SPECIAL,
212 OPC_SLT = 0x2A | OPC_SPECIAL,
213 OPC_SLTU = 0x2B | OPC_SPECIAL,
214 OPC_DADD = 0x2C | OPC_SPECIAL,
215 OPC_DADDU = 0x2D | OPC_SPECIAL,
216 OPC_DSUB = 0x2E | OPC_SPECIAL,
217 OPC_DSUBU = 0x2F | OPC_SPECIAL,
218 /* Jumps */
219 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
220 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
221 /* Traps */
222 OPC_TGE = 0x30 | OPC_SPECIAL,
223 OPC_TGEU = 0x31 | OPC_SPECIAL,
224 OPC_TLT = 0x32 | OPC_SPECIAL,
225 OPC_TLTU = 0x33 | OPC_SPECIAL,
226 OPC_TEQ = 0x34 | OPC_SPECIAL,
227 OPC_TNE = 0x36 | OPC_SPECIAL,
228 /* HI / LO registers load & stores */
229 OPC_MFHI = 0x10 | OPC_SPECIAL,
230 OPC_MTHI = 0x11 | OPC_SPECIAL,
231 OPC_MFLO = 0x12 | OPC_SPECIAL,
232 OPC_MTLO = 0x13 | OPC_SPECIAL,
233 /* Conditional moves */
234 OPC_MOVZ = 0x0A | OPC_SPECIAL,
235 OPC_MOVN = 0x0B | OPC_SPECIAL,
236
237 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
238 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
239
240 OPC_MOVCI = 0x01 | OPC_SPECIAL,
241
242 /* Special */
243 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
244 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
245 OPC_BREAK = 0x0D | OPC_SPECIAL,
246 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
247 OPC_SYNC = 0x0F | OPC_SPECIAL,
248
249 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
250 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
251 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
252 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
253 };
254
255 /* R6 Multiply and Divide instructions have the same Opcode
256 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
257 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
258
259 enum {
260 R6_OPC_MUL = OPC_MULT | (2 << 6),
261 R6_OPC_MUH = OPC_MULT | (3 << 6),
262 R6_OPC_MULU = OPC_MULTU | (2 << 6),
263 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
264 R6_OPC_DIV = OPC_DIV | (2 << 6),
265 R6_OPC_MOD = OPC_DIV | (3 << 6),
266 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
267 R6_OPC_MODU = OPC_DIVU | (3 << 6),
268
269 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
270 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
271 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
272 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
273 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
274 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
275 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
276 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
277
278 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
279 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
280 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
281 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
282 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
283
284 OPC_LSA = 0x05 | OPC_SPECIAL,
285 OPC_DLSA = 0x15 | OPC_SPECIAL,
286 };
287
288 /* Multiplication variants of the vr54xx. */
289 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
290
291 enum {
292 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
293 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
294 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
295 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
296 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
297 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
298 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
299 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
300 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
301 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
302 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
303 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
304 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
305 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
306 };
307
308 /* REGIMM (rt field) opcodes */
309 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
310
311 enum {
312 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
313 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
314 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
315 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
316 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
317 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
318 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
319 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
320 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
321 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
322 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
323 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
324 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
325 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
326 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
327
328 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
329 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
330 };
331
332 /* Special2 opcodes */
333 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
334
335 enum {
336 /* Multiply & xxx operations */
337 OPC_MADD = 0x00 | OPC_SPECIAL2,
338 OPC_MADDU = 0x01 | OPC_SPECIAL2,
339 OPC_MUL = 0x02 | OPC_SPECIAL2,
340 OPC_MSUB = 0x04 | OPC_SPECIAL2,
341 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
342 /* Loongson 2F */
343 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
344 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
345 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
346 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
347 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
348 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
349 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
350 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
351 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
352 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
353 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
354 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
355 /* Misc */
356 OPC_CLZ = 0x20 | OPC_SPECIAL2,
357 OPC_CLO = 0x21 | OPC_SPECIAL2,
358 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
359 OPC_DCLO = 0x25 | OPC_SPECIAL2,
360 /* Special */
361 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
362 };
363
364 /* Special3 opcodes */
365 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
366
367 enum {
368 OPC_EXT = 0x00 | OPC_SPECIAL3,
369 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
370 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
371 OPC_DEXT = 0x03 | OPC_SPECIAL3,
372 OPC_INS = 0x04 | OPC_SPECIAL3,
373 OPC_DINSM = 0x05 | OPC_SPECIAL3,
374 OPC_DINSU = 0x06 | OPC_SPECIAL3,
375 OPC_DINS = 0x07 | OPC_SPECIAL3,
376 OPC_FORK = 0x08 | OPC_SPECIAL3,
377 OPC_YIELD = 0x09 | OPC_SPECIAL3,
378 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
379 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
380 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
381
382 /* Loongson 2E */
383 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
384 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
385 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
386 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
387 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
388 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
389 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
390 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
391 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
392 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
393 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
394 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
395
396 /* MIPS DSP Load */
397 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
398 /* MIPS DSP Arithmetic */
399 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
400 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
401 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
402 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
403 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
404 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
405 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
406 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
407 /* MIPS DSP GPR-Based Shift Sub-class */
408 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
409 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
410 /* MIPS DSP Multiply Sub-class insns */
411 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
412 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
413 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
414 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
415 /* DSP Bit/Manipulation Sub-class */
416 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
417 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
418 /* MIPS DSP Append Sub-class */
419 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
420 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
421 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
422 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
423 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
424
425 /* R6 */
426 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
427 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
428 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
429 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
430 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
431 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
432 };
433
434 /* BSHFL opcodes */
435 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
436
437 enum {
438 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
439 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
440 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
441 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
442 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
443 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
444 };
445
446 /* DBSHFL opcodes */
447 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
448
449 enum {
450 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
451 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
452 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
453 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
454 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
455 };
456
457 /* MIPS DSP REGIMM opcodes */
458 enum {
459 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
460 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
461 };
462
463 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
464 /* MIPS DSP Load */
465 enum {
466 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
467 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
468 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
469 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
470 };
471
472 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
473 enum {
474 /* MIPS DSP Arithmetic Sub-class */
475 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
476 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
477 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
478 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
479 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
480 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
482 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
483 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
484 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
485 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
486 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
489 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
490 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
491 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
492 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
493 /* MIPS DSP Multiply Sub-class insns */
494 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
495 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
496 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
497 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
498 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
499 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
500 };
501
502 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
503 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
504 enum {
505 /* MIPS DSP Arithmetic Sub-class */
506 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
507 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
508 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
509 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
510 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
511 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
515 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
516 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
518 /* MIPS DSP Multiply Sub-class insns */
519 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
520 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
521 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
522 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
523 };
524
525 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
526 enum {
527 /* MIPS DSP Arithmetic Sub-class */
528 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
529 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
530 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
531 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
532 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
533 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
541 /* DSP Bit/Manipulation Sub-class */
542 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
546 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
547 };
548
549 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
550 enum {
551 /* MIPS DSP Arithmetic Sub-class */
552 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
553 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
554 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
555 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
556 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
557 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
559 /* DSP Compare-Pick Sub-class */
560 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
564 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
565 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
575 };
576
577 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
578 enum {
579 /* MIPS DSP GPR-Based Shift Sub-class */
580 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
581 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
582 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
583 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
584 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
585 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
602 };
603
604 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 enum {
606 /* MIPS DSP Multiply Sub-class insns */
607 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
608 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
609 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
610 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
611 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
612 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
621 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
624 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
628 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
629 };
630
631 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
632 enum {
633 /* DSP Bit/Manipulation Sub-class */
634 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
635 };
636
637 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
638 enum {
639 /* MIPS DSP Append Sub-class */
640 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
641 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
642 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
643 };
644
645 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
646 enum {
647 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
648 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
649 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
650 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
651 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
652 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
653 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
660 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
661 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
662 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
663 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
664 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
665 };
666
667 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
668 enum {
669 /* MIPS DSP Arithmetic Sub-class */
670 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
671 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
672 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
673 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
674 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
675 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
687 /* DSP Bit/Manipulation Sub-class */
688 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
692 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
693 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
694 };
695
696 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
697 enum {
698 /* MIPS DSP Multiply Sub-class insns */
699 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
700 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
701 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
702 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
703 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
704 /* MIPS DSP Arithmetic Sub-class */
705 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
706 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
707 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
708 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
709 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
710 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
716 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
717 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
718 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
719 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
720 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
726 };
727
728 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
729 enum {
730 /* DSP Compare-Pick Sub-class */
731 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
732 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
733 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
734 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
735 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
736 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
750 /* MIPS DSP Arithmetic Sub-class */
751 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
755 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
756 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
759 };
760
761 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
762 enum {
763 /* DSP Append Sub-class */
764 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
765 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
766 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
767 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
768 };
769
770 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
771 enum {
772 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
773 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
774 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
775 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
776 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
777 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
778 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
779 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
794 };
795
796 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
797 enum {
798 /* DSP Bit/Manipulation Sub-class */
799 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
800 };
801
802 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
803 enum {
804 /* MIPS DSP Multiply Sub-class insns */
805 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
806 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
807 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
808 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
809 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
810 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
831 };
832
833 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
834 enum {
835 /* MIPS DSP GPR-Based Shift Sub-class */
836 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
837 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
838 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
839 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
840 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
841 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
862 };
863
864 /* Coprocessor 0 (rs field) */
865 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
866
867 enum {
868 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
869 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
870 OPC_MFHC0 = (0x02 << 21) | OPC_CP0,
871 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
872 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
873 OPC_MTHC0 = (0x06 << 21) | OPC_CP0,
874 OPC_MFTR = (0x08 << 21) | OPC_CP0,
875 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
876 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
877 OPC_MTTR = (0x0C << 21) | OPC_CP0,
878 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
879 OPC_C0 = (0x10 << 21) | OPC_CP0,
880 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
881 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
882 };
883
884 /* MFMC0 opcodes */
885 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
886
887 enum {
888 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
889 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
890 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
891 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
892 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
893 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
894 };
895
896 /* Coprocessor 0 (with rs == C0) */
897 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
898
899 enum {
900 OPC_TLBR = 0x01 | OPC_C0,
901 OPC_TLBWI = 0x02 | OPC_C0,
902 OPC_TLBINV = 0x03 | OPC_C0,
903 OPC_TLBINVF = 0x04 | OPC_C0,
904 OPC_TLBWR = 0x06 | OPC_C0,
905 OPC_TLBP = 0x08 | OPC_C0,
906 OPC_RFE = 0x10 | OPC_C0,
907 OPC_ERET = 0x18 | OPC_C0,
908 OPC_DERET = 0x1F | OPC_C0,
909 OPC_WAIT = 0x20 | OPC_C0,
910 };
911
912 /* Coprocessor 1 (rs field) */
913 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
914
915 /* Values for the fmt field in FP instructions */
916 enum {
917 /* 0 - 15 are reserved */
918 FMT_S = 16, /* single fp */
919 FMT_D = 17, /* double fp */
920 FMT_E = 18, /* extended fp */
921 FMT_Q = 19, /* quad fp */
922 FMT_W = 20, /* 32-bit fixed */
923 FMT_L = 21, /* 64-bit fixed */
924 FMT_PS = 22, /* paired single fp */
925 /* 23 - 31 are reserved */
926 };
927
928 enum {
929 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
930 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
931 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
932 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
933 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
934 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
935 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
936 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
937 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
938 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
939 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
940 OPC_BZ_V = (0x0B << 21) | OPC_CP1,
941 OPC_BNZ_V = (0x0F << 21) | OPC_CP1,
942 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
943 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
944 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
945 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
946 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
947 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
948 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
949 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
950 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
951 OPC_BZ_B = (0x18 << 21) | OPC_CP1,
952 OPC_BZ_H = (0x19 << 21) | OPC_CP1,
953 OPC_BZ_W = (0x1A << 21) | OPC_CP1,
954 OPC_BZ_D = (0x1B << 21) | OPC_CP1,
955 OPC_BNZ_B = (0x1C << 21) | OPC_CP1,
956 OPC_BNZ_H = (0x1D << 21) | OPC_CP1,
957 OPC_BNZ_W = (0x1E << 21) | OPC_CP1,
958 OPC_BNZ_D = (0x1F << 21) | OPC_CP1,
959 };
960
961 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
962 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
963
964 enum {
965 OPC_BC1F = (0x00 << 16) | OPC_BC1,
966 OPC_BC1T = (0x01 << 16) | OPC_BC1,
967 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
968 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
969 };
970
971 enum {
972 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
973 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
974 };
975
976 enum {
977 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
978 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
979 };
980
981 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
982
983 enum {
984 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
985 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
986 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
987 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
988 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
989 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
990 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
991 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
992 OPC_BC2 = (0x08 << 21) | OPC_CP2,
993 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
994 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
995 };
996
997 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
998
999 enum {
1000 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
1001 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1002 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
1003 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
1004 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
1005 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1006 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
1007 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
1008
1009 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1010 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1011 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1012 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1013 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1014 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1015 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1016 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1017
1018 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1019 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1020 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1021 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1022 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1023 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1024 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1025 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1026
1027 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1028 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1029 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1030 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1031 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1032 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1033 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1034 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1035
1036 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1037 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1038 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1039 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1040 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1041 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1042
1043 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1044 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1045 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1046 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1047 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1048 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1049
1050 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1051 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1052 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1053 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1054 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1055 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1056
1057 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1058 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1059 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1060 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1061 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1062 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1063
1064 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1065 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1066 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1067 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1068 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1069 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1070
1071 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1072 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1073 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1074 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1075 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1076 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1077
1078 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1079 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1080 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1081 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1082 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1083 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1084
1085 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1086 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1087 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1088 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1089 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1090 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1091 };
1092
1093
1094 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1095
1096 enum {
1097 OPC_LWXC1 = 0x00 | OPC_CP3,
1098 OPC_LDXC1 = 0x01 | OPC_CP3,
1099 OPC_LUXC1 = 0x05 | OPC_CP3,
1100 OPC_SWXC1 = 0x08 | OPC_CP3,
1101 OPC_SDXC1 = 0x09 | OPC_CP3,
1102 OPC_SUXC1 = 0x0D | OPC_CP3,
1103 OPC_PREFX = 0x0F | OPC_CP3,
1104 OPC_ALNV_PS = 0x1E | OPC_CP3,
1105 OPC_MADD_S = 0x20 | OPC_CP3,
1106 OPC_MADD_D = 0x21 | OPC_CP3,
1107 OPC_MADD_PS = 0x26 | OPC_CP3,
1108 OPC_MSUB_S = 0x28 | OPC_CP3,
1109 OPC_MSUB_D = 0x29 | OPC_CP3,
1110 OPC_MSUB_PS = 0x2E | OPC_CP3,
1111 OPC_NMADD_S = 0x30 | OPC_CP3,
1112 OPC_NMADD_D = 0x31 | OPC_CP3,
1113 OPC_NMADD_PS= 0x36 | OPC_CP3,
1114 OPC_NMSUB_S = 0x38 | OPC_CP3,
1115 OPC_NMSUB_D = 0x39 | OPC_CP3,
1116 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1117 };
1118
1119 /* MSA Opcodes */
1120 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1121 enum {
1122 OPC_MSA_I8_00 = 0x00 | OPC_MSA,
1123 OPC_MSA_I8_01 = 0x01 | OPC_MSA,
1124 OPC_MSA_I8_02 = 0x02 | OPC_MSA,
1125 OPC_MSA_I5_06 = 0x06 | OPC_MSA,
1126 OPC_MSA_I5_07 = 0x07 | OPC_MSA,
1127 OPC_MSA_BIT_09 = 0x09 | OPC_MSA,
1128 OPC_MSA_BIT_0A = 0x0A | OPC_MSA,
1129 OPC_MSA_3R_0D = 0x0D | OPC_MSA,
1130 OPC_MSA_3R_0E = 0x0E | OPC_MSA,
1131 OPC_MSA_3R_0F = 0x0F | OPC_MSA,
1132 OPC_MSA_3R_10 = 0x10 | OPC_MSA,
1133 OPC_MSA_3R_11 = 0x11 | OPC_MSA,
1134 OPC_MSA_3R_12 = 0x12 | OPC_MSA,
1135 OPC_MSA_3R_13 = 0x13 | OPC_MSA,
1136 OPC_MSA_3R_14 = 0x14 | OPC_MSA,
1137 OPC_MSA_3R_15 = 0x15 | OPC_MSA,
1138 OPC_MSA_ELM = 0x19 | OPC_MSA,
1139 OPC_MSA_3RF_1A = 0x1A | OPC_MSA,
1140 OPC_MSA_3RF_1B = 0x1B | OPC_MSA,
1141 OPC_MSA_3RF_1C = 0x1C | OPC_MSA,
1142 OPC_MSA_VEC = 0x1E | OPC_MSA,
1143
1144 /* MI10 instruction */
1145 OPC_LD_B = (0x20) | OPC_MSA,
1146 OPC_LD_H = (0x21) | OPC_MSA,
1147 OPC_LD_W = (0x22) | OPC_MSA,
1148 OPC_LD_D = (0x23) | OPC_MSA,
1149 OPC_ST_B = (0x24) | OPC_MSA,
1150 OPC_ST_H = (0x25) | OPC_MSA,
1151 OPC_ST_W = (0x26) | OPC_MSA,
1152 OPC_ST_D = (0x27) | OPC_MSA,
1153 };
1154
1155 enum {
1156 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1157 OPC_ADDVI_df = (0x0 << 23) | OPC_MSA_I5_06,
1158 OPC_CEQI_df = (0x0 << 23) | OPC_MSA_I5_07,
1159 OPC_SUBVI_df = (0x1 << 23) | OPC_MSA_I5_06,
1160 OPC_MAXI_S_df = (0x2 << 23) | OPC_MSA_I5_06,
1161 OPC_CLTI_S_df = (0x2 << 23) | OPC_MSA_I5_07,
1162 OPC_MAXI_U_df = (0x3 << 23) | OPC_MSA_I5_06,
1163 OPC_CLTI_U_df = (0x3 << 23) | OPC_MSA_I5_07,
1164 OPC_MINI_S_df = (0x4 << 23) | OPC_MSA_I5_06,
1165 OPC_CLEI_S_df = (0x4 << 23) | OPC_MSA_I5_07,
1166 OPC_MINI_U_df = (0x5 << 23) | OPC_MSA_I5_06,
1167 OPC_CLEI_U_df = (0x5 << 23) | OPC_MSA_I5_07,
1168 OPC_LDI_df = (0x6 << 23) | OPC_MSA_I5_07,
1169
1170 /* I8 instruction */
1171 OPC_ANDI_B = (0x0 << 24) | OPC_MSA_I8_00,
1172 OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1173 OPC_SHF_B = (0x0 << 24) | OPC_MSA_I8_02,
1174 OPC_ORI_B = (0x1 << 24) | OPC_MSA_I8_00,
1175 OPC_BMZI_B = (0x1 << 24) | OPC_MSA_I8_01,
1176 OPC_SHF_H = (0x1 << 24) | OPC_MSA_I8_02,
1177 OPC_NORI_B = (0x2 << 24) | OPC_MSA_I8_00,
1178 OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1179 OPC_SHF_W = (0x2 << 24) | OPC_MSA_I8_02,
1180 OPC_XORI_B = (0x3 << 24) | OPC_MSA_I8_00,
1181
1182 /* VEC/2R/2RF instruction */
1183 OPC_AND_V = (0x00 << 21) | OPC_MSA_VEC,
1184 OPC_OR_V = (0x01 << 21) | OPC_MSA_VEC,
1185 OPC_NOR_V = (0x02 << 21) | OPC_MSA_VEC,
1186 OPC_XOR_V = (0x03 << 21) | OPC_MSA_VEC,
1187 OPC_BMNZ_V = (0x04 << 21) | OPC_MSA_VEC,
1188 OPC_BMZ_V = (0x05 << 21) | OPC_MSA_VEC,
1189 OPC_BSEL_V = (0x06 << 21) | OPC_MSA_VEC,
1190
1191 OPC_MSA_2R = (0x18 << 21) | OPC_MSA_VEC,
1192 OPC_MSA_2RF = (0x19 << 21) | OPC_MSA_VEC,
1193
1194 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1195 OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1196 OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1197 OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1198 OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1199
1200 /* 2RF instruction df(bit 16) = _w, _d */
1201 OPC_FCLASS_df = (0x00 << 17) | OPC_MSA_2RF,
1202 OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1203 OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1204 OPC_FSQRT_df = (0x03 << 17) | OPC_MSA_2RF,
1205 OPC_FRSQRT_df = (0x04 << 17) | OPC_MSA_2RF,
1206 OPC_FRCP_df = (0x05 << 17) | OPC_MSA_2RF,
1207 OPC_FRINT_df = (0x06 << 17) | OPC_MSA_2RF,
1208 OPC_FLOG2_df = (0x07 << 17) | OPC_MSA_2RF,
1209 OPC_FEXUPL_df = (0x08 << 17) | OPC_MSA_2RF,
1210 OPC_FEXUPR_df = (0x09 << 17) | OPC_MSA_2RF,
1211 OPC_FFQL_df = (0x0A << 17) | OPC_MSA_2RF,
1212 OPC_FFQR_df = (0x0B << 17) | OPC_MSA_2RF,
1213 OPC_FTINT_S_df = (0x0C << 17) | OPC_MSA_2RF,
1214 OPC_FTINT_U_df = (0x0D << 17) | OPC_MSA_2RF,
1215 OPC_FFINT_S_df = (0x0E << 17) | OPC_MSA_2RF,
1216 OPC_FFINT_U_df = (0x0F << 17) | OPC_MSA_2RF,
1217
1218 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1219 OPC_SLL_df = (0x0 << 23) | OPC_MSA_3R_0D,
1220 OPC_ADDV_df = (0x0 << 23) | OPC_MSA_3R_0E,
1221 OPC_CEQ_df = (0x0 << 23) | OPC_MSA_3R_0F,
1222 OPC_ADD_A_df = (0x0 << 23) | OPC_MSA_3R_10,
1223 OPC_SUBS_S_df = (0x0 << 23) | OPC_MSA_3R_11,
1224 OPC_MULV_df = (0x0 << 23) | OPC_MSA_3R_12,
1225 OPC_DOTP_S_df = (0x0 << 23) | OPC_MSA_3R_13,
1226 OPC_SLD_df = (0x0 << 23) | OPC_MSA_3R_14,
1227 OPC_VSHF_df = (0x0 << 23) | OPC_MSA_3R_15,
1228 OPC_SRA_df = (0x1 << 23) | OPC_MSA_3R_0D,
1229 OPC_SUBV_df = (0x1 << 23) | OPC_MSA_3R_0E,
1230 OPC_ADDS_A_df = (0x1 << 23) | OPC_MSA_3R_10,
1231 OPC_SUBS_U_df = (0x1 << 23) | OPC_MSA_3R_11,
1232 OPC_MADDV_df = (0x1 << 23) | OPC_MSA_3R_12,
1233 OPC_DOTP_U_df = (0x1 << 23) | OPC_MSA_3R_13,
1234 OPC_SPLAT_df = (0x1 << 23) | OPC_MSA_3R_14,
1235 OPC_SRAR_df = (0x1 << 23) | OPC_MSA_3R_15,
1236 OPC_SRL_df = (0x2 << 23) | OPC_MSA_3R_0D,
1237 OPC_MAX_S_df = (0x2 << 23) | OPC_MSA_3R_0E,
1238 OPC_CLT_S_df = (0x2 << 23) | OPC_MSA_3R_0F,
1239 OPC_ADDS_S_df = (0x2 << 23) | OPC_MSA_3R_10,
1240 OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1241 OPC_MSUBV_df = (0x2 << 23) | OPC_MSA_3R_12,
1242 OPC_DPADD_S_df = (0x2 << 23) | OPC_MSA_3R_13,
1243 OPC_PCKEV_df = (0x2 << 23) | OPC_MSA_3R_14,
1244 OPC_SRLR_df = (0x2 << 23) | OPC_MSA_3R_15,
1245 OPC_BCLR_df = (0x3 << 23) | OPC_MSA_3R_0D,
1246 OPC_MAX_U_df = (0x3 << 23) | OPC_MSA_3R_0E,
1247 OPC_CLT_U_df = (0x3 << 23) | OPC_MSA_3R_0F,
1248 OPC_ADDS_U_df = (0x3 << 23) | OPC_MSA_3R_10,
1249 OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1250 OPC_DPADD_U_df = (0x3 << 23) | OPC_MSA_3R_13,
1251 OPC_PCKOD_df = (0x3 << 23) | OPC_MSA_3R_14,
1252 OPC_BSET_df = (0x4 << 23) | OPC_MSA_3R_0D,
1253 OPC_MIN_S_df = (0x4 << 23) | OPC_MSA_3R_0E,
1254 OPC_CLE_S_df = (0x4 << 23) | OPC_MSA_3R_0F,
1255 OPC_AVE_S_df = (0x4 << 23) | OPC_MSA_3R_10,
1256 OPC_ASUB_S_df = (0x4 << 23) | OPC_MSA_3R_11,
1257 OPC_DIV_S_df = (0x4 << 23) | OPC_MSA_3R_12,
1258 OPC_DPSUB_S_df = (0x4 << 23) | OPC_MSA_3R_13,
1259 OPC_ILVL_df = (0x4 << 23) | OPC_MSA_3R_14,
1260 OPC_HADD_S_df = (0x4 << 23) | OPC_MSA_3R_15,
1261 OPC_BNEG_df = (0x5 << 23) | OPC_MSA_3R_0D,
1262 OPC_MIN_U_df = (0x5 << 23) | OPC_MSA_3R_0E,
1263 OPC_CLE_U_df = (0x5 << 23) | OPC_MSA_3R_0F,
1264 OPC_AVE_U_df = (0x5 << 23) | OPC_MSA_3R_10,
1265 OPC_ASUB_U_df = (0x5 << 23) | OPC_MSA_3R_11,
1266 OPC_DIV_U_df = (0x5 << 23) | OPC_MSA_3R_12,
1267 OPC_DPSUB_U_df = (0x5 << 23) | OPC_MSA_3R_13,
1268 OPC_ILVR_df = (0x5 << 23) | OPC_MSA_3R_14,
1269 OPC_HADD_U_df = (0x5 << 23) | OPC_MSA_3R_15,
1270 OPC_BINSL_df = (0x6 << 23) | OPC_MSA_3R_0D,
1271 OPC_MAX_A_df = (0x6 << 23) | OPC_MSA_3R_0E,
1272 OPC_AVER_S_df = (0x6 << 23) | OPC_MSA_3R_10,
1273 OPC_MOD_S_df = (0x6 << 23) | OPC_MSA_3R_12,
1274 OPC_ILVEV_df = (0x6 << 23) | OPC_MSA_3R_14,
1275 OPC_HSUB_S_df = (0x6 << 23) | OPC_MSA_3R_15,
1276 OPC_BINSR_df = (0x7 << 23) | OPC_MSA_3R_0D,
1277 OPC_MIN_A_df = (0x7 << 23) | OPC_MSA_3R_0E,
1278 OPC_AVER_U_df = (0x7 << 23) | OPC_MSA_3R_10,
1279 OPC_MOD_U_df = (0x7 << 23) | OPC_MSA_3R_12,
1280 OPC_ILVOD_df = (0x7 << 23) | OPC_MSA_3R_14,
1281 OPC_HSUB_U_df = (0x7 << 23) | OPC_MSA_3R_15,
1282
1283 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1284 OPC_SLDI_df = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1285 OPC_CTCMSA = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1286 OPC_SPLATI_df = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1287 OPC_CFCMSA = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1288 OPC_COPY_S_df = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1289 OPC_MOVE_V = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1290 OPC_COPY_U_df = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1291 OPC_INSERT_df = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1292 OPC_INSVE_df = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1293
1294 /* 3RF instruction _df(bit 21) = _w, _d */
1295 OPC_FCAF_df = (0x0 << 22) | OPC_MSA_3RF_1A,
1296 OPC_FADD_df = (0x0 << 22) | OPC_MSA_3RF_1B,
1297 OPC_FCUN_df = (0x1 << 22) | OPC_MSA_3RF_1A,
1298 OPC_FSUB_df = (0x1 << 22) | OPC_MSA_3RF_1B,
1299 OPC_FCOR_df = (0x1 << 22) | OPC_MSA_3RF_1C,
1300 OPC_FCEQ_df = (0x2 << 22) | OPC_MSA_3RF_1A,
1301 OPC_FMUL_df = (0x2 << 22) | OPC_MSA_3RF_1B,
1302 OPC_FCUNE_df = (0x2 << 22) | OPC_MSA_3RF_1C,
1303 OPC_FCUEQ_df = (0x3 << 22) | OPC_MSA_3RF_1A,
1304 OPC_FDIV_df = (0x3 << 22) | OPC_MSA_3RF_1B,
1305 OPC_FCNE_df = (0x3 << 22) | OPC_MSA_3RF_1C,
1306 OPC_FCLT_df = (0x4 << 22) | OPC_MSA_3RF_1A,
1307 OPC_FMADD_df = (0x4 << 22) | OPC_MSA_3RF_1B,
1308 OPC_MUL_Q_df = (0x4 << 22) | OPC_MSA_3RF_1C,
1309 OPC_FCULT_df = (0x5 << 22) | OPC_MSA_3RF_1A,
1310 OPC_FMSUB_df = (0x5 << 22) | OPC_MSA_3RF_1B,
1311 OPC_MADD_Q_df = (0x5 << 22) | OPC_MSA_3RF_1C,
1312 OPC_FCLE_df = (0x6 << 22) | OPC_MSA_3RF_1A,
1313 OPC_MSUB_Q_df = (0x6 << 22) | OPC_MSA_3RF_1C,
1314 OPC_FCULE_df = (0x7 << 22) | OPC_MSA_3RF_1A,
1315 OPC_FEXP2_df = (0x7 << 22) | OPC_MSA_3RF_1B,
1316 OPC_FSAF_df = (0x8 << 22) | OPC_MSA_3RF_1A,
1317 OPC_FEXDO_df = (0x8 << 22) | OPC_MSA_3RF_1B,
1318 OPC_FSUN_df = (0x9 << 22) | OPC_MSA_3RF_1A,
1319 OPC_FSOR_df = (0x9 << 22) | OPC_MSA_3RF_1C,
1320 OPC_FSEQ_df = (0xA << 22) | OPC_MSA_3RF_1A,
1321 OPC_FTQ_df = (0xA << 22) | OPC_MSA_3RF_1B,
1322 OPC_FSUNE_df = (0xA << 22) | OPC_MSA_3RF_1C,
1323 OPC_FSUEQ_df = (0xB << 22) | OPC_MSA_3RF_1A,
1324 OPC_FSNE_df = (0xB << 22) | OPC_MSA_3RF_1C,
1325 OPC_FSLT_df = (0xC << 22) | OPC_MSA_3RF_1A,
1326 OPC_FMIN_df = (0xC << 22) | OPC_MSA_3RF_1B,
1327 OPC_MULR_Q_df = (0xC << 22) | OPC_MSA_3RF_1C,
1328 OPC_FSULT_df = (0xD << 22) | OPC_MSA_3RF_1A,
1329 OPC_FMIN_A_df = (0xD << 22) | OPC_MSA_3RF_1B,
1330 OPC_MADDR_Q_df = (0xD << 22) | OPC_MSA_3RF_1C,
1331 OPC_FSLE_df = (0xE << 22) | OPC_MSA_3RF_1A,
1332 OPC_FMAX_df = (0xE << 22) | OPC_MSA_3RF_1B,
1333 OPC_MSUBR_Q_df = (0xE << 22) | OPC_MSA_3RF_1C,
1334 OPC_FSULE_df = (0xF << 22) | OPC_MSA_3RF_1A,
1335 OPC_FMAX_A_df = (0xF << 22) | OPC_MSA_3RF_1B,
1336
1337 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1338 OPC_SLLI_df = (0x0 << 23) | OPC_MSA_BIT_09,
1339 OPC_SAT_S_df = (0x0 << 23) | OPC_MSA_BIT_0A,
1340 OPC_SRAI_df = (0x1 << 23) | OPC_MSA_BIT_09,
1341 OPC_SAT_U_df = (0x1 << 23) | OPC_MSA_BIT_0A,
1342 OPC_SRLI_df = (0x2 << 23) | OPC_MSA_BIT_09,
1343 OPC_SRARI_df = (0x2 << 23) | OPC_MSA_BIT_0A,
1344 OPC_BCLRI_df = (0x3 << 23) | OPC_MSA_BIT_09,
1345 OPC_SRLRI_df = (0x3 << 23) | OPC_MSA_BIT_0A,
1346 OPC_BSETI_df = (0x4 << 23) | OPC_MSA_BIT_09,
1347 OPC_BNEGI_df = (0x5 << 23) | OPC_MSA_BIT_09,
1348 OPC_BINSLI_df = (0x6 << 23) | OPC_MSA_BIT_09,
1349 OPC_BINSRI_df = (0x7 << 23) | OPC_MSA_BIT_09,
1350 };
1351
1352 /* global register indices */
1353 static TCGv_ptr cpu_env;
1354 static TCGv cpu_gpr[32], cpu_PC;
1355 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1356 static TCGv cpu_dspctrl, btarget, bcond;
1357 static TCGv_i32 hflags;
1358 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1359 static TCGv_i64 fpu_f64[32];
1360 static TCGv_i64 msa_wr_d[64];
1361
1362 #include "exec/gen-icount.h"
1363
1364 #define gen_helper_0e0i(name, arg) do { \
1365 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1366 gen_helper_##name(cpu_env, helper_tmp); \
1367 tcg_temp_free_i32(helper_tmp); \
1368 } while(0)
1369
1370 #define gen_helper_0e1i(name, arg1, arg2) do { \
1371 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1372 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1373 tcg_temp_free_i32(helper_tmp); \
1374 } while(0)
1375
1376 #define gen_helper_1e0i(name, ret, arg1) do { \
1377 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1378 gen_helper_##name(ret, cpu_env, helper_tmp); \
1379 tcg_temp_free_i32(helper_tmp); \
1380 } while(0)
1381
1382 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1383 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1384 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1385 tcg_temp_free_i32(helper_tmp); \
1386 } while(0)
1387
1388 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1389 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1390 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1391 tcg_temp_free_i32(helper_tmp); \
1392 } while(0)
1393
1394 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1395 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1396 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1397 tcg_temp_free_i32(helper_tmp); \
1398 } while(0)
1399
1400 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1401 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1402 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1403 tcg_temp_free_i32(helper_tmp); \
1404 } while(0)
1405
1406 typedef struct DisasContext {
1407 struct TranslationBlock *tb;
1408 target_ulong pc, saved_pc;
1409 uint32_t opcode;
1410 int singlestep_enabled;
1411 int insn_flags;
1412 int32_t CP0_Config1;
1413 /* Routine used to access memory */
1414 int mem_idx;
1415 TCGMemOp default_tcg_memop_mask;
1416 uint32_t hflags, saved_hflags;
1417 int bstate;
1418 target_ulong btarget;
1419 bool ulri;
1420 int kscrexist;
1421 bool rxi;
1422 int ie;
1423 bool bi;
1424 bool bp;
1425 uint64_t PAMask;
1426 bool mvh;
1427 int CP0_LLAddr_shift;
1428 bool ps;
1429 } DisasContext;
1430
1431 enum {
1432 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1433 * exception condition */
1434 BS_STOP = 1, /* We want to stop translation for any reason */
1435 BS_BRANCH = 2, /* We reached a branch condition */
1436 BS_EXCP = 3, /* We reached an exception condition */
1437 };
1438
1439 static const char * const regnames[] = {
1440 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1441 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1442 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1443 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1444 };
1445
1446 static const char * const regnames_HI[] = {
1447 "HI0", "HI1", "HI2", "HI3",
1448 };
1449
1450 static const char * const regnames_LO[] = {
1451 "LO0", "LO1", "LO2", "LO3",
1452 };
1453
1454 static const char * const fregnames[] = {
1455 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1456 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1457 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1458 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1459 };
1460
1461 static const char * const msaregnames[] = {
1462 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1463 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1464 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1465 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1466 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1467 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1468 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1469 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1470 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1471 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1472 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1473 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1474 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1475 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1476 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1477 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1478 };
1479
1480 #define LOG_DISAS(...) \
1481 do { \
1482 if (MIPS_DEBUG_DISAS) { \
1483 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1484 } \
1485 } while (0)
1486
1487 #define MIPS_INVAL(op) \
1488 do { \
1489 if (MIPS_DEBUG_DISAS) { \
1490 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1491 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1492 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1493 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
1494 } \
1495 } while (0)
1496
1497 /* General purpose registers moves. */
1498 static inline void gen_load_gpr (TCGv t, int reg)
1499 {
1500 if (reg == 0)
1501 tcg_gen_movi_tl(t, 0);
1502 else
1503 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1504 }
1505
1506 static inline void gen_store_gpr (TCGv t, int reg)
1507 {
1508 if (reg != 0)
1509 tcg_gen_mov_tl(cpu_gpr[reg], t);
1510 }
1511
1512 /* Moves to/from shadow registers. */
1513 static inline void gen_load_srsgpr (int from, int to)
1514 {
1515 TCGv t0 = tcg_temp_new();
1516
1517 if (from == 0)
1518 tcg_gen_movi_tl(t0, 0);
1519 else {
1520 TCGv_i32 t2 = tcg_temp_new_i32();
1521 TCGv_ptr addr = tcg_temp_new_ptr();
1522
1523 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1524 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1525 tcg_gen_andi_i32(t2, t2, 0xf);
1526 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1527 tcg_gen_ext_i32_ptr(addr, t2);
1528 tcg_gen_add_ptr(addr, cpu_env, addr);
1529
1530 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1531 tcg_temp_free_ptr(addr);
1532 tcg_temp_free_i32(t2);
1533 }
1534 gen_store_gpr(t0, to);
1535 tcg_temp_free(t0);
1536 }
1537
1538 static inline void gen_store_srsgpr (int from, int to)
1539 {
1540 if (to != 0) {
1541 TCGv t0 = tcg_temp_new();
1542 TCGv_i32 t2 = tcg_temp_new_i32();
1543 TCGv_ptr addr = tcg_temp_new_ptr();
1544
1545 gen_load_gpr(t0, from);
1546 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1547 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1548 tcg_gen_andi_i32(t2, t2, 0xf);
1549 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1550 tcg_gen_ext_i32_ptr(addr, t2);
1551 tcg_gen_add_ptr(addr, cpu_env, addr);
1552
1553 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1554 tcg_temp_free_ptr(addr);
1555 tcg_temp_free_i32(t2);
1556 tcg_temp_free(t0);
1557 }
1558 }
1559
1560 /* Tests */
1561 static inline void gen_save_pc(target_ulong pc)
1562 {
1563 tcg_gen_movi_tl(cpu_PC, pc);
1564 }
1565
1566 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1567 {
1568 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1569 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1570 gen_save_pc(ctx->pc);
1571 ctx->saved_pc = ctx->pc;
1572 }
1573 if (ctx->hflags != ctx->saved_hflags) {
1574 tcg_gen_movi_i32(hflags, ctx->hflags);
1575 ctx->saved_hflags = ctx->hflags;
1576 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1577 case MIPS_HFLAG_BR:
1578 break;
1579 case MIPS_HFLAG_BC:
1580 case MIPS_HFLAG_BL:
1581 case MIPS_HFLAG_B:
1582 tcg_gen_movi_tl(btarget, ctx->btarget);
1583 break;
1584 }
1585 }
1586 }
1587
1588 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1589 {
1590 ctx->saved_hflags = ctx->hflags;
1591 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1592 case MIPS_HFLAG_BR:
1593 break;
1594 case MIPS_HFLAG_BC:
1595 case MIPS_HFLAG_BL:
1596 case MIPS_HFLAG_B:
1597 ctx->btarget = env->btarget;
1598 break;
1599 }
1600 }
1601
1602 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
1603 {
1604 TCGv_i32 texcp = tcg_const_i32(excp);
1605 TCGv_i32 terr = tcg_const_i32(err);
1606 save_cpu_state(ctx, 1);
1607 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1608 tcg_temp_free_i32(terr);
1609 tcg_temp_free_i32(texcp);
1610 ctx->bstate = BS_EXCP;
1611 }
1612
1613 static inline void generate_exception(DisasContext *ctx, int excp)
1614 {
1615 gen_helper_0e0i(raise_exception, excp);
1616 }
1617
1618 static inline void generate_exception_end(DisasContext *ctx, int excp)
1619 {
1620 generate_exception_err(ctx, excp, 0);
1621 }
1622
1623 /* Floating point register moves. */
1624 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1625 {
1626 if (ctx->hflags & MIPS_HFLAG_FRE) {
1627 generate_exception(ctx, EXCP_RI);
1628 }
1629 tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1630 }
1631
1632 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1633 {
1634 TCGv_i64 t64;
1635 if (ctx->hflags & MIPS_HFLAG_FRE) {
1636 generate_exception(ctx, EXCP_RI);
1637 }
1638 t64 = tcg_temp_new_i64();
1639 tcg_gen_extu_i32_i64(t64, t);
1640 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1641 tcg_temp_free_i64(t64);
1642 }
1643
1644 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1645 {
1646 if (ctx->hflags & MIPS_HFLAG_F64) {
1647 tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1648 } else {
1649 gen_load_fpr32(ctx, t, reg | 1);
1650 }
1651 }
1652
1653 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1654 {
1655 if (ctx->hflags & MIPS_HFLAG_F64) {
1656 TCGv_i64 t64 = tcg_temp_new_i64();
1657 tcg_gen_extu_i32_i64(t64, t);
1658 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1659 tcg_temp_free_i64(t64);
1660 } else {
1661 gen_store_fpr32(ctx, t, reg | 1);
1662 }
1663 }
1664
1665 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1666 {
1667 if (ctx->hflags & MIPS_HFLAG_F64) {
1668 tcg_gen_mov_i64(t, fpu_f64[reg]);
1669 } else {
1670 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1671 }
1672 }
1673
1674 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1675 {
1676 if (ctx->hflags & MIPS_HFLAG_F64) {
1677 tcg_gen_mov_i64(fpu_f64[reg], t);
1678 } else {
1679 TCGv_i64 t0;
1680 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1681 t0 = tcg_temp_new_i64();
1682 tcg_gen_shri_i64(t0, t, 32);
1683 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1684 tcg_temp_free_i64(t0);
1685 }
1686 }
1687
1688 static inline int get_fp_bit (int cc)
1689 {
1690 if (cc)
1691 return 24 + cc;
1692 else
1693 return 23;
1694 }
1695
1696 /* Addresses computation */
1697 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1698 {
1699 tcg_gen_add_tl(ret, arg0, arg1);
1700
1701 #if defined(TARGET_MIPS64)
1702 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1703 tcg_gen_ext32s_i64(ret, ret);
1704 }
1705 #endif
1706 }
1707
1708 /* Addresses computation (translation time) */
1709 static target_long addr_add(DisasContext *ctx, target_long base,
1710 target_long offset)
1711 {
1712 target_long sum = base + offset;
1713
1714 #if defined(TARGET_MIPS64)
1715 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1716 sum = (int32_t)sum;
1717 }
1718 #endif
1719 return sum;
1720 }
1721
1722 /* Sign-extract the low 32-bits to a target_long. */
1723 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
1724 {
1725 #if defined(TARGET_MIPS64)
1726 tcg_gen_ext32s_i64(ret, arg);
1727 #else
1728 tcg_gen_extrl_i64_i32(ret, arg);
1729 #endif
1730 }
1731
1732 /* Sign-extract the high 32-bits to a target_long. */
1733 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
1734 {
1735 #if defined(TARGET_MIPS64)
1736 tcg_gen_sari_i64(ret, arg, 32);
1737 #else
1738 tcg_gen_extrh_i64_i32(ret, arg);
1739 #endif
1740 }
1741
1742 static inline void check_cp0_enabled(DisasContext *ctx)
1743 {
1744 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1745 generate_exception_err(ctx, EXCP_CpU, 0);
1746 }
1747
1748 static inline void check_cp1_enabled(DisasContext *ctx)
1749 {
1750 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1751 generate_exception_err(ctx, EXCP_CpU, 1);
1752 }
1753
1754 /* Verify that the processor is running with COP1X instructions enabled.
1755 This is associated with the nabla symbol in the MIPS32 and MIPS64
1756 opcode tables. */
1757
1758 static inline void check_cop1x(DisasContext *ctx)
1759 {
1760 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1761 generate_exception_end(ctx, EXCP_RI);
1762 }
1763
1764 /* Verify that the processor is running with 64-bit floating-point
1765 operations enabled. */
1766
1767 static inline void check_cp1_64bitmode(DisasContext *ctx)
1768 {
1769 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1770 generate_exception_end(ctx, EXCP_RI);
1771 }
1772
1773 /*
1774 * Verify if floating point register is valid; an operation is not defined
1775 * if bit 0 of any register specification is set and the FR bit in the
1776 * Status register equals zero, since the register numbers specify an
1777 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1778 * in the Status register equals one, both even and odd register numbers
1779 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1780 *
1781 * Multiple 64 bit wide registers can be checked by calling
1782 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1783 */
1784 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1785 {
1786 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1787 generate_exception_end(ctx, EXCP_RI);
1788 }
1789
1790 /* Verify that the processor is running with DSP instructions enabled.
1791 This is enabled by CP0 Status register MX(24) bit.
1792 */
1793
1794 static inline void check_dsp(DisasContext *ctx)
1795 {
1796 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1797 if (ctx->insn_flags & ASE_DSP) {
1798 generate_exception_end(ctx, EXCP_DSPDIS);
1799 } else {
1800 generate_exception_end(ctx, EXCP_RI);
1801 }
1802 }
1803 }
1804
1805 static inline void check_dspr2(DisasContext *ctx)
1806 {
1807 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1808 if (ctx->insn_flags & ASE_DSP) {
1809 generate_exception_end(ctx, EXCP_DSPDIS);
1810 } else {
1811 generate_exception_end(ctx, EXCP_RI);
1812 }
1813 }
1814 }
1815
1816 /* This code generates a "reserved instruction" exception if the
1817 CPU does not support the instruction set corresponding to flags. */
1818 static inline void check_insn(DisasContext *ctx, int flags)
1819 {
1820 if (unlikely(!(ctx->insn_flags & flags))) {
1821 generate_exception_end(ctx, EXCP_RI);
1822 }
1823 }
1824
1825 /* This code generates a "reserved instruction" exception if the
1826 CPU has corresponding flag set which indicates that the instruction
1827 has been removed. */
1828 static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1829 {
1830 if (unlikely(ctx->insn_flags & flags)) {
1831 generate_exception_end(ctx, EXCP_RI);
1832 }
1833 }
1834
1835 /* This code generates a "reserved instruction" exception if the
1836 CPU does not support 64-bit paired-single (PS) floating point data type */
1837 static inline void check_ps(DisasContext *ctx)
1838 {
1839 if (unlikely(!ctx->ps)) {
1840 generate_exception(ctx, EXCP_RI);
1841 }
1842 check_cp1_64bitmode(ctx);
1843 }
1844
1845 #ifdef TARGET_MIPS64
1846 /* This code generates a "reserved instruction" exception if 64-bit
1847 instructions are not enabled. */
1848 static inline void check_mips_64(DisasContext *ctx)
1849 {
1850 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1851 generate_exception_end(ctx, EXCP_RI);
1852 }
1853 #endif
1854
1855 #ifndef CONFIG_USER_ONLY
1856 static inline void check_mvh(DisasContext *ctx)
1857 {
1858 if (unlikely(!ctx->mvh)) {
1859 generate_exception(ctx, EXCP_RI);
1860 }
1861 }
1862 #endif
1863
1864 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1865 calling interface for 32 and 64-bit FPRs. No sense in changing
1866 all callers for gen_load_fpr32 when we need the CTX parameter for
1867 this one use. */
1868 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1869 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1870 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1871 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1872 int ft, int fs, int cc) \
1873 { \
1874 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1875 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1876 switch (ifmt) { \
1877 case FMT_PS: \
1878 check_ps(ctx); \
1879 break; \
1880 case FMT_D: \
1881 if (abs) { \
1882 check_cop1x(ctx); \
1883 } \
1884 check_cp1_registers(ctx, fs | ft); \
1885 break; \
1886 case FMT_S: \
1887 if (abs) { \
1888 check_cop1x(ctx); \
1889 } \
1890 break; \
1891 } \
1892 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1893 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1894 switch (n) { \
1895 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1896 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1897 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1898 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1899 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1900 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1901 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1902 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1903 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1904 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1905 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1906 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1907 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1908 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1909 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1910 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1911 default: abort(); \
1912 } \
1913 tcg_temp_free_i##bits (fp0); \
1914 tcg_temp_free_i##bits (fp1); \
1915 }
1916
1917 FOP_CONDS(, 0, d, FMT_D, 64)
1918 FOP_CONDS(abs, 1, d, FMT_D, 64)
1919 FOP_CONDS(, 0, s, FMT_S, 32)
1920 FOP_CONDS(abs, 1, s, FMT_S, 32)
1921 FOP_CONDS(, 0, ps, FMT_PS, 64)
1922 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1923 #undef FOP_CONDS
1924
1925 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1926 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1927 int ft, int fs, int fd) \
1928 { \
1929 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1930 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1931 if (ifmt == FMT_D) { \
1932 check_cp1_registers(ctx, fs | ft | fd); \
1933 } \
1934 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1935 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1936 switch (n) { \
1937 case 0: \
1938 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1939 break; \
1940 case 1: \
1941 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1942 break; \
1943 case 2: \
1944 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1945 break; \
1946 case 3: \
1947 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1948 break; \
1949 case 4: \
1950 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1951 break; \
1952 case 5: \
1953 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1954 break; \
1955 case 6: \
1956 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1957 break; \
1958 case 7: \
1959 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1960 break; \
1961 case 8: \
1962 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1963 break; \
1964 case 9: \
1965 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1966 break; \
1967 case 10: \
1968 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1969 break; \
1970 case 11: \
1971 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1972 break; \
1973 case 12: \
1974 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1975 break; \
1976 case 13: \
1977 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1978 break; \
1979 case 14: \
1980 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1981 break; \
1982 case 15: \
1983 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1984 break; \
1985 case 17: \
1986 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1987 break; \
1988 case 18: \
1989 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1990 break; \
1991 case 19: \
1992 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1993 break; \
1994 case 25: \
1995 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1996 break; \
1997 case 26: \
1998 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1999 break; \
2000 case 27: \
2001 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2002 break; \
2003 default: \
2004 abort(); \
2005 } \
2006 STORE; \
2007 tcg_temp_free_i ## bits (fp0); \
2008 tcg_temp_free_i ## bits (fp1); \
2009 }
2010
2011 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2012 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2013 #undef FOP_CONDNS
2014 #undef gen_ldcmp_fpr32
2015 #undef gen_ldcmp_fpr64
2016
2017 /* load/store instructions. */
2018 #ifdef CONFIG_USER_ONLY
2019 #define OP_LD_ATOMIC(insn,fname) \
2020 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2021 { \
2022 TCGv t0 = tcg_temp_new(); \
2023 tcg_gen_mov_tl(t0, arg1); \
2024 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2025 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2026 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2027 tcg_temp_free(t0); \
2028 }
2029 #else
2030 #define OP_LD_ATOMIC(insn,fname) \
2031 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2032 { \
2033 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
2034 }
2035 #endif
2036 OP_LD_ATOMIC(ll,ld32s);
2037 #if defined(TARGET_MIPS64)
2038 OP_LD_ATOMIC(lld,ld64);
2039 #endif
2040 #undef OP_LD_ATOMIC
2041
2042 #ifdef CONFIG_USER_ONLY
2043 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2044 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2045 { \
2046 TCGv t0 = tcg_temp_new(); \
2047 TCGLabel *l1 = gen_new_label(); \
2048 TCGLabel *l2 = gen_new_label(); \
2049 \
2050 tcg_gen_andi_tl(t0, arg2, almask); \
2051 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2052 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2053 generate_exception(ctx, EXCP_AdES); \
2054 gen_set_label(l1); \
2055 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2056 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2057 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2058 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2059 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2060 generate_exception_end(ctx, EXCP_SC); \
2061 gen_set_label(l2); \
2062 tcg_gen_movi_tl(t0, 0); \
2063 gen_store_gpr(t0, rt); \
2064 tcg_temp_free(t0); \
2065 }
2066 #else
2067 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2068 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2069 { \
2070 TCGv t0 = tcg_temp_new(); \
2071 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2072 gen_store_gpr(t0, rt); \
2073 tcg_temp_free(t0); \
2074 }
2075 #endif
2076 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2077 #if defined(TARGET_MIPS64)
2078 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2079 #endif
2080 #undef OP_ST_ATOMIC
2081
2082 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2083 int base, int16_t offset)
2084 {
2085 if (base == 0) {
2086 tcg_gen_movi_tl(addr, offset);
2087 } else if (offset == 0) {
2088 gen_load_gpr(addr, base);
2089 } else {
2090 tcg_gen_movi_tl(addr, offset);
2091 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2092 }
2093 }
2094
2095 static target_ulong pc_relative_pc (DisasContext *ctx)
2096 {
2097 target_ulong pc = ctx->pc;
2098
2099 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2100 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2101
2102 pc -= branch_bytes;
2103 }
2104
2105 pc &= ~(target_ulong)3;
2106 return pc;
2107 }
2108
2109 /* Load */
2110 static void gen_ld(DisasContext *ctx, uint32_t opc,
2111 int rt, int base, int16_t offset)
2112 {
2113 TCGv t0, t1, t2;
2114
2115 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2116 /* Loongson CPU uses a load to zero register for prefetch.
2117 We emulate it as a NOP. On other CPU we must perform the
2118 actual memory access. */
2119 return;
2120 }
2121
2122 t0 = tcg_temp_new();
2123 gen_base_offset_addr(ctx, t0, base, offset);
2124
2125 switch (opc) {
2126 #if defined(TARGET_MIPS64)
2127 case OPC_LWU:
2128 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
2129 ctx->default_tcg_memop_mask);
2130 gen_store_gpr(t0, rt);
2131 break;
2132 case OPC_LD:
2133 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
2134 ctx->default_tcg_memop_mask);
2135 gen_store_gpr(t0, rt);
2136 break;
2137 case OPC_LLD:
2138 case R6_OPC_LLD:
2139 op_ld_lld(t0, t0, ctx);
2140 gen_store_gpr(t0, rt);
2141 break;
2142 case OPC_LDL:
2143 t1 = tcg_temp_new();
2144 /* Do a byte access to possibly trigger a page
2145 fault with the unaligned address. */
2146 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2147 tcg_gen_andi_tl(t1, t0, 7);
2148 #ifndef TARGET_WORDS_BIGENDIAN
2149 tcg_gen_xori_tl(t1, t1, 7);
2150 #endif
2151 tcg_gen_shli_tl(t1, t1, 3);
2152 tcg_gen_andi_tl(t0, t0, ~7);
2153 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2154 tcg_gen_shl_tl(t0, t0, t1);
2155 t2 = tcg_const_tl(-1);
2156 tcg_gen_shl_tl(t2, t2, t1);
2157 gen_load_gpr(t1, rt);
2158 tcg_gen_andc_tl(t1, t1, t2);
2159 tcg_temp_free(t2);
2160 tcg_gen_or_tl(t0, t0, t1);
2161 tcg_temp_free(t1);
2162 gen_store_gpr(t0, rt);
2163 break;
2164 case OPC_LDR:
2165 t1 = tcg_temp_new();
2166 /* Do a byte access to possibly trigger a page
2167 fault with the unaligned address. */
2168 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2169 tcg_gen_andi_tl(t1, t0, 7);
2170 #ifdef TARGET_WORDS_BIGENDIAN
2171 tcg_gen_xori_tl(t1, t1, 7);
2172 #endif
2173 tcg_gen_shli_tl(t1, t1, 3);
2174 tcg_gen_andi_tl(t0, t0, ~7);
2175 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2176 tcg_gen_shr_tl(t0, t0, t1);
2177 tcg_gen_xori_tl(t1, t1, 63);
2178 t2 = tcg_const_tl(0xfffffffffffffffeull);
2179 tcg_gen_shl_tl(t2, t2, t1);
2180 gen_load_gpr(t1, rt);
2181 tcg_gen_and_tl(t1, t1, t2);
2182 tcg_temp_free(t2);
2183 tcg_gen_or_tl(t0, t0, t1);
2184 tcg_temp_free(t1);
2185 gen_store_gpr(t0, rt);
2186 break;
2187 case OPC_LDPC:
2188 t1 = tcg_const_tl(pc_relative_pc(ctx));
2189 gen_op_addr_add(ctx, t0, t0, t1);
2190 tcg_temp_free(t1);
2191 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
2192 gen_store_gpr(t0, rt);
2193 break;
2194 #endif
2195 case OPC_LWPC:
2196 t1 = tcg_const_tl(pc_relative_pc(ctx));
2197 gen_op_addr_add(ctx, t0, t0, t1);
2198 tcg_temp_free(t1);
2199 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
2200 gen_store_gpr(t0, rt);
2201 break;
2202 case OPC_LW:
2203 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
2204 ctx->default_tcg_memop_mask);
2205 gen_store_gpr(t0, rt);
2206 break;
2207 case OPC_LH:
2208 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
2209 ctx->default_tcg_memop_mask);
2210 gen_store_gpr(t0, rt);
2211 break;
2212 case OPC_LHU:
2213 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
2214 ctx->default_tcg_memop_mask);
2215 gen_store_gpr(t0, rt);
2216 break;
2217 case OPC_LB:
2218 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
2219 gen_store_gpr(t0, rt);
2220 break;
2221 case OPC_LBU:
2222 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
2223 gen_store_gpr(t0, rt);
2224 break;
2225 case OPC_LWL:
2226 t1 = tcg_temp_new();
2227 /* Do a byte access to possibly trigger a page
2228 fault with the unaligned address. */
2229 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2230 tcg_gen_andi_tl(t1, t0, 3);
2231 #ifndef TARGET_WORDS_BIGENDIAN
2232 tcg_gen_xori_tl(t1, t1, 3);
2233 #endif
2234 tcg_gen_shli_tl(t1, t1, 3);
2235 tcg_gen_andi_tl(t0, t0, ~3);
2236 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2237 tcg_gen_shl_tl(t0, t0, t1);
2238 t2 = tcg_const_tl(-1);
2239 tcg_gen_shl_tl(t2, t2, t1);
2240 gen_load_gpr(t1, rt);
2241 tcg_gen_andc_tl(t1, t1, t2);
2242 tcg_temp_free(t2);
2243 tcg_gen_or_tl(t0, t0, t1);
2244 tcg_temp_free(t1);
2245 tcg_gen_ext32s_tl(t0, t0);
2246 gen_store_gpr(t0, rt);
2247 break;
2248 case OPC_LWR:
2249 t1 = tcg_temp_new();
2250 /* Do a byte access to possibly trigger a page
2251 fault with the unaligned address. */
2252 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
2253 tcg_gen_andi_tl(t1, t0, 3);
2254 #ifdef TARGET_WORDS_BIGENDIAN
2255 tcg_gen_xori_tl(t1, t1, 3);
2256 #endif
2257 tcg_gen_shli_tl(t1, t1, 3);
2258 tcg_gen_andi_tl(t0, t0, ~3);
2259 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
2260 tcg_gen_shr_tl(t0, t0, t1);
2261 tcg_gen_xori_tl(t1, t1, 31);
2262 t2 = tcg_const_tl(0xfffffffeull);
2263 tcg_gen_shl_tl(t2, t2, t1);
2264 gen_load_gpr(t1, rt);
2265 tcg_gen_and_tl(t1, t1, t2);
2266 tcg_temp_free(t2);
2267 tcg_gen_or_tl(t0, t0, t1);
2268 tcg_temp_free(t1);
2269 tcg_gen_ext32s_tl(t0, t0);
2270 gen_store_gpr(t0, rt);
2271 break;
2272 case OPC_LL:
2273 case R6_OPC_LL:
2274 op_ld_ll(t0, t0, ctx);
2275 gen_store_gpr(t0, rt);
2276 break;
2277 }
2278 tcg_temp_free(t0);
2279 }
2280
2281 /* Store */
2282 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
2283 int base, int16_t offset)
2284 {
2285 TCGv t0 = tcg_temp_new();
2286 TCGv t1 = tcg_temp_new();
2287
2288 gen_base_offset_addr(ctx, t0, base, offset);
2289 gen_load_gpr(t1, rt);
2290 switch (opc) {
2291 #if defined(TARGET_MIPS64)
2292 case OPC_SD:
2293 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
2294 ctx->default_tcg_memop_mask);
2295 break;
2296 case OPC_SDL:
2297 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2298 break;
2299 case OPC_SDR:
2300 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2301 break;
2302 #endif
2303 case OPC_SW:
2304 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
2305 ctx->default_tcg_memop_mask);
2306 break;
2307 case OPC_SH:
2308 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
2309 ctx->default_tcg_memop_mask);
2310 break;
2311 case OPC_SB:
2312 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2313 break;
2314 case OPC_SWL:
2315 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2316 break;
2317 case OPC_SWR:
2318 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2319 break;
2320 }
2321 tcg_temp_free(t0);
2322 tcg_temp_free(t1);
2323 }
2324
2325
2326 /* Store conditional */
2327 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2328 int base, int16_t offset)
2329 {
2330 TCGv t0, t1;
2331
2332 #ifdef CONFIG_USER_ONLY
2333 t0 = tcg_temp_local_new();
2334 t1 = tcg_temp_local_new();
2335 #else
2336 t0 = tcg_temp_new();
2337 t1 = tcg_temp_new();
2338 #endif
2339 gen_base_offset_addr(ctx, t0, base, offset);
2340 gen_load_gpr(t1, rt);
2341 switch (opc) {
2342 #if defined(TARGET_MIPS64)
2343 case OPC_SCD:
2344 case R6_OPC_SCD:
2345 op_st_scd(t1, t0, rt, ctx);
2346 break;
2347 #endif
2348 case OPC_SC:
2349 case R6_OPC_SC:
2350 op_st_sc(t1, t0, rt, ctx);
2351 break;
2352 }
2353 tcg_temp_free(t1);
2354 tcg_temp_free(t0);
2355 }
2356
2357 /* Load and store */
2358 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2359 int base, int16_t offset)
2360 {
2361 TCGv t0 = tcg_temp_new();
2362
2363 gen_base_offset_addr(ctx, t0, base, offset);
2364 /* Don't do NOP if destination is zero: we must perform the actual
2365 memory access. */
2366 switch (opc) {
2367 case OPC_LWC1:
2368 {
2369 TCGv_i32 fp0 = tcg_temp_new_i32();
2370 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2371 ctx->default_tcg_memop_mask);
2372 gen_store_fpr32(ctx, fp0, ft);
2373 tcg_temp_free_i32(fp0);
2374 }
2375 break;
2376 case OPC_SWC1:
2377 {
2378 TCGv_i32 fp0 = tcg_temp_new_i32();
2379 gen_load_fpr32(ctx, fp0, ft);
2380 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2381 ctx->default_tcg_memop_mask);
2382 tcg_temp_free_i32(fp0);
2383 }
2384 break;
2385 case OPC_LDC1:
2386 {
2387 TCGv_i64 fp0 = tcg_temp_new_i64();
2388 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2389 ctx->default_tcg_memop_mask);
2390 gen_store_fpr64(ctx, fp0, ft);
2391 tcg_temp_free_i64(fp0);
2392 }
2393 break;
2394 case OPC_SDC1:
2395 {
2396 TCGv_i64 fp0 = tcg_temp_new_i64();
2397 gen_load_fpr64(ctx, fp0, ft);
2398 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2399 ctx->default_tcg_memop_mask);
2400 tcg_temp_free_i64(fp0);
2401 }
2402 break;
2403 default:
2404 MIPS_INVAL("flt_ldst");
2405 generate_exception_end(ctx, EXCP_RI);
2406 goto out;
2407 }
2408 out:
2409 tcg_temp_free(t0);
2410 }
2411
2412 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2413 int rs, int16_t imm)
2414 {
2415 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2416 check_cp1_enabled(ctx);
2417 switch (op) {
2418 case OPC_LDC1:
2419 case OPC_SDC1:
2420 check_insn(ctx, ISA_MIPS2);
2421 /* Fallthrough */
2422 default:
2423 gen_flt_ldst(ctx, op, rt, rs, imm);
2424 }
2425 } else {
2426 generate_exception_err(ctx, EXCP_CpU, 1);
2427 }
2428 }
2429
2430 /* Arithmetic with immediate operand */
2431 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2432 int rt, int rs, int16_t imm)
2433 {
2434 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2435
2436 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2437 /* If no destination, treat it as a NOP.
2438 For addi, we must generate the overflow exception when needed. */
2439 return;
2440 }
2441 switch (opc) {
2442 case OPC_ADDI:
2443 {
2444 TCGv t0 = tcg_temp_local_new();
2445 TCGv t1 = tcg_temp_new();
2446 TCGv t2 = tcg_temp_new();
2447 TCGLabel *l1 = gen_new_label();
2448
2449 gen_load_gpr(t1, rs);
2450 tcg_gen_addi_tl(t0, t1, uimm);
2451 tcg_gen_ext32s_tl(t0, t0);
2452
2453 tcg_gen_xori_tl(t1, t1, ~uimm);
2454 tcg_gen_xori_tl(t2, t0, uimm);
2455 tcg_gen_and_tl(t1, t1, t2);
2456 tcg_temp_free(t2);
2457 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2458 tcg_temp_free(t1);
2459 /* operands of same sign, result different sign */
2460 generate_exception(ctx, EXCP_OVERFLOW);
2461 gen_set_label(l1);
2462 tcg_gen_ext32s_tl(t0, t0);
2463 gen_store_gpr(t0, rt);
2464 tcg_temp_free(t0);
2465 }
2466 break;
2467 case OPC_ADDIU:
2468 if (rs != 0) {
2469 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2470 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2471 } else {
2472 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2473 }
2474 break;
2475 #if defined(TARGET_MIPS64)
2476 case OPC_DADDI:
2477 {
2478 TCGv t0 = tcg_temp_local_new();
2479 TCGv t1 = tcg_temp_new();
2480 TCGv t2 = tcg_temp_new();
2481 TCGLabel *l1 = gen_new_label();
2482
2483 gen_load_gpr(t1, rs);
2484 tcg_gen_addi_tl(t0, t1, uimm);
2485
2486 tcg_gen_xori_tl(t1, t1, ~uimm);
2487 tcg_gen_xori_tl(t2, t0, uimm);
2488 tcg_gen_and_tl(t1, t1, t2);
2489 tcg_temp_free(t2);
2490 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2491 tcg_temp_free(t1);
2492 /* operands of same sign, result different sign */
2493 generate_exception(ctx, EXCP_OVERFLOW);
2494 gen_set_label(l1);
2495 gen_store_gpr(t0, rt);
2496 tcg_temp_free(t0);
2497 }
2498 break;
2499 case OPC_DADDIU:
2500 if (rs != 0) {
2501 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2502 } else {
2503 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2504 }
2505 break;
2506 #endif
2507 }
2508 }
2509
2510 /* Logic with immediate operand */
2511 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2512 int rt, int rs, int16_t imm)
2513 {
2514 target_ulong uimm;
2515
2516 if (rt == 0) {
2517 /* If no destination, treat it as a NOP. */
2518 return;
2519 }
2520 uimm = (uint16_t)imm;
2521 switch (opc) {
2522 case OPC_ANDI:
2523 if (likely(rs != 0))
2524 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2525 else
2526 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2527 break;
2528 case OPC_ORI:
2529 if (rs != 0)
2530 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2531 else
2532 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2533 break;
2534 case OPC_XORI:
2535 if (likely(rs != 0))
2536 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2537 else
2538 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2539 break;
2540 case OPC_LUI:
2541 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2542 /* OPC_AUI */
2543 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2544 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2545 } else {
2546 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2547 }
2548 break;
2549
2550 default:
2551 break;
2552 }
2553 }
2554
2555 /* Set on less than with immediate operand */
2556 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2557 int rt, int rs, int16_t imm)
2558 {
2559 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2560 TCGv t0;
2561
2562 if (rt == 0) {
2563 /* If no destination, treat it as a NOP. */
2564 return;
2565 }
2566 t0 = tcg_temp_new();
2567 gen_load_gpr(t0, rs);
2568 switch (opc) {
2569 case OPC_SLTI:
2570 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2571 break;
2572 case OPC_SLTIU:
2573 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2574 break;
2575 }
2576 tcg_temp_free(t0);
2577 }
2578
2579 /* Shifts with immediate operand */
2580 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2581 int rt, int rs, int16_t imm)
2582 {
2583 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2584 TCGv t0;
2585
2586 if (rt == 0) {
2587 /* If no destination, treat it as a NOP. */
2588 return;
2589 }
2590
2591 t0 = tcg_temp_new();
2592 gen_load_gpr(t0, rs);
2593 switch (opc) {
2594 case OPC_SLL:
2595 tcg_gen_shli_tl(t0, t0, uimm);
2596 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2597 break;
2598 case OPC_SRA:
2599 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2600 break;
2601 case OPC_SRL:
2602 if (uimm != 0) {
2603 tcg_gen_ext32u_tl(t0, t0);
2604 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2605 } else {
2606 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2607 }
2608 break;
2609 case OPC_ROTR:
2610 if (uimm != 0) {
2611 TCGv_i32 t1 = tcg_temp_new_i32();
2612
2613 tcg_gen_trunc_tl_i32(t1, t0);
2614 tcg_gen_rotri_i32(t1, t1, uimm);
2615 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2616 tcg_temp_free_i32(t1);
2617 } else {
2618 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2619 }
2620 break;
2621 #if defined(TARGET_MIPS64)
2622 case OPC_DSLL:
2623 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2624 break;
2625 case OPC_DSRA:
2626 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2627 break;
2628 case OPC_DSRL:
2629 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2630 break;
2631 case OPC_DROTR:
2632 if (uimm != 0) {
2633 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2634 } else {
2635 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2636 }
2637 break;
2638 case OPC_DSLL32:
2639 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2640 break;
2641 case OPC_DSRA32:
2642 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2643 break;
2644 case OPC_DSRL32:
2645 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2646 break;
2647 case OPC_DROTR32:
2648 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2649 break;
2650 #endif
2651 }
2652 tcg_temp_free(t0);
2653 }
2654
2655 /* Arithmetic */
2656 static void gen_arith(DisasContext *ctx, uint32_t opc,
2657 int rd, int rs, int rt)
2658 {
2659 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2660 && opc != OPC_DADD && opc != OPC_DSUB) {
2661 /* If no destination, treat it as a NOP.
2662 For add & sub, we must generate the overflow exception when needed. */
2663 return;
2664 }
2665
2666 switch (opc) {
2667 case OPC_ADD:
2668 {
2669 TCGv t0 = tcg_temp_local_new();
2670 TCGv t1 = tcg_temp_new();
2671 TCGv t2 = tcg_temp_new();
2672 TCGLabel *l1 = gen_new_label();
2673
2674 gen_load_gpr(t1, rs);
2675 gen_load_gpr(t2, rt);
2676 tcg_gen_add_tl(t0, t1, t2);
2677 tcg_gen_ext32s_tl(t0, t0);
2678 tcg_gen_xor_tl(t1, t1, t2);
2679 tcg_gen_xor_tl(t2, t0, t2);
2680 tcg_gen_andc_tl(t1, t2, t1);
2681 tcg_temp_free(t2);
2682 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2683 tcg_temp_free(t1);
2684 /* operands of same sign, result different sign */
2685 generate_exception(ctx, EXCP_OVERFLOW);
2686 gen_set_label(l1);
2687 gen_store_gpr(t0, rd);
2688 tcg_temp_free(t0);
2689 }
2690 break;
2691 case OPC_ADDU:
2692 if (rs != 0 && rt != 0) {
2693 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2694 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2695 } else if (rs == 0 && rt != 0) {
2696 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2697 } else if (rs != 0 && rt == 0) {
2698 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2699 } else {
2700 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2701 }
2702 break;
2703 case OPC_SUB:
2704 {
2705 TCGv t0 = tcg_temp_local_new();
2706 TCGv t1 = tcg_temp_new();
2707 TCGv t2 = tcg_temp_new();
2708 TCGLabel *l1 = gen_new_label();
2709
2710 gen_load_gpr(t1, rs);
2711 gen_load_gpr(t2, rt);
2712 tcg_gen_sub_tl(t0, t1, t2);
2713 tcg_gen_ext32s_tl(t0, t0);
2714 tcg_gen_xor_tl(t2, t1, t2);
2715 tcg_gen_xor_tl(t1, t0, t1);
2716 tcg_gen_and_tl(t1, t1, t2);
2717 tcg_temp_free(t2);
2718 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2719 tcg_temp_free(t1);
2720 /* operands of different sign, first operand and result different sign */
2721 generate_exception(ctx, EXCP_OVERFLOW);
2722 gen_set_label(l1);
2723 gen_store_gpr(t0, rd);
2724 tcg_temp_free(t0);
2725 }
2726 break;
2727 case OPC_SUBU:
2728 if (rs != 0 && rt != 0) {
2729 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2730 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2731 } else if (rs == 0 && rt != 0) {
2732 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2733 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2734 } else if (rs != 0 && rt == 0) {
2735 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2736 } else {
2737 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2738 }
2739 break;
2740 #if defined(TARGET_MIPS64)
2741 case OPC_DADD:
2742 {
2743 TCGv t0 = tcg_temp_local_new();
2744 TCGv t1 = tcg_temp_new();
2745 TCGv t2 = tcg_temp_new();
2746 TCGLabel *l1 = gen_new_label();
2747
2748 gen_load_gpr(t1, rs);
2749 gen_load_gpr(t2, rt);
2750 tcg_gen_add_tl(t0, t1, t2);
2751 tcg_gen_xor_tl(t1, t1, t2);
2752 tcg_gen_xor_tl(t2, t0, t2);
2753 tcg_gen_andc_tl(t1, t2, t1);
2754 tcg_temp_free(t2);
2755 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2756 tcg_temp_free(t1);
2757 /* operands of same sign, result different sign */
2758 generate_exception(ctx, EXCP_OVERFLOW);
2759 gen_set_label(l1);
2760 gen_store_gpr(t0, rd);
2761 tcg_temp_free(t0);
2762 }
2763 break;
2764 case OPC_DADDU:
2765 if (rs != 0 && rt != 0) {
2766 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2767 } else if (rs == 0 && rt != 0) {
2768 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2769 } else if (rs != 0 && rt == 0) {
2770 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2771 } else {
2772 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2773 }
2774 break;
2775 case OPC_DSUB:
2776 {
2777 TCGv t0 = tcg_temp_local_new();
2778 TCGv t1 = tcg_temp_new();
2779 TCGv t2 = tcg_temp_new();
2780 TCGLabel *l1 = gen_new_label();
2781
2782 gen_load_gpr(t1, rs);
2783 gen_load_gpr(t2, rt);
2784 tcg_gen_sub_tl(t0, t1, t2);
2785 tcg_gen_xor_tl(t2, t1, t2);
2786 tcg_gen_xor_tl(t1, t0, t1);
2787 tcg_gen_and_tl(t1, t1, t2);
2788 tcg_temp_free(t2);
2789 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2790 tcg_temp_free(t1);
2791 /* operands of different sign, first operand and result different sign */
2792 generate_exception(ctx, EXCP_OVERFLOW);
2793 gen_set_label(l1);
2794 gen_store_gpr(t0, rd);
2795 tcg_temp_free(t0);
2796 }
2797 break;
2798 case OPC_DSUBU:
2799 if (rs != 0 && rt != 0) {
2800 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2801 } else if (rs == 0 && rt != 0) {
2802 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2803 } else if (rs != 0 && rt == 0) {
2804 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2805 } else {
2806 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2807 }
2808 break;
2809 #endif
2810 case OPC_MUL:
2811 if (likely(rs != 0 && rt != 0)) {
2812 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2813 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2814 } else {
2815 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2816 }
2817 break;
2818 }
2819 }
2820
2821 /* Conditional move */
2822 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2823 int rd, int rs, int rt)
2824 {
2825 TCGv t0, t1, t2;
2826
2827 if (rd == 0) {
2828 /* If no destination, treat it as a NOP. */
2829 return;
2830 }
2831
2832 t0 = tcg_temp_new();
2833 gen_load_gpr(t0, rt);
2834 t1 = tcg_const_tl(0);
2835 t2 = tcg_temp_new();
2836 gen_load_gpr(t2, rs);
2837 switch (opc) {
2838 case OPC_MOVN:
2839 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2840 break;
2841 case OPC_MOVZ:
2842 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2843 break;
2844 case OPC_SELNEZ:
2845 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2846 break;
2847 case OPC_SELEQZ:
2848 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2849 break;
2850 }
2851 tcg_temp_free(t2);
2852 tcg_temp_free(t1);
2853 tcg_temp_free(t0);
2854 }
2855
2856 /* Logic */
2857 static void gen_logic(DisasContext *ctx, uint32_t opc,
2858 int rd, int rs, int rt)
2859 {
2860 if (rd == 0) {
2861 /* If no destination, treat it as a NOP. */
2862 return;
2863 }
2864
2865 switch (opc) {
2866 case OPC_AND:
2867 if (likely(rs != 0 && rt != 0)) {
2868 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2869 } else {
2870 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2871 }
2872 break;
2873 case OPC_NOR:
2874 if (rs != 0 && rt != 0) {
2875 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2876 } else if (rs == 0 && rt != 0) {
2877 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2878 } else if (rs != 0 && rt == 0) {
2879 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2880 } else {
2881 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2882 }
2883 break;
2884 case OPC_OR:
2885 if (likely(rs != 0 && rt != 0)) {
2886 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2887 } else if (rs == 0 && rt != 0) {
2888 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2889 } else if (rs != 0 && rt == 0) {
2890 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2891 } else {
2892 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2893 }
2894 break;
2895 case OPC_XOR:
2896 if (likely(rs != 0 && rt != 0)) {
2897 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2898 } else if (rs == 0 && rt != 0) {
2899 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2900 } else if (rs != 0 && rt == 0) {
2901 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2902 } else {
2903 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2904 }
2905 break;
2906 }
2907 }
2908
2909 /* Set on lower than */
2910 static void gen_slt(DisasContext *ctx, uint32_t opc,
2911 int rd, int rs, int rt)
2912 {
2913 TCGv t0, t1;
2914
2915 if (rd == 0) {
2916 /* If no destination, treat it as a NOP. */
2917 return;
2918 }
2919
2920 t0 = tcg_temp_new();
2921 t1 = tcg_temp_new();
2922 gen_load_gpr(t0, rs);
2923 gen_load_gpr(t1, rt);
2924 switch (opc) {
2925 case OPC_SLT:
2926 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2927 break;
2928 case OPC_SLTU:
2929 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2930 break;
2931 }
2932 tcg_temp_free(t0);
2933 tcg_temp_free(t1);
2934 }
2935
2936 /* Shifts */
2937 static void gen_shift(DisasContext *ctx, uint32_t opc,
2938 int rd, int rs, int rt)
2939 {
2940 TCGv t0, t1;
2941
2942 if (rd == 0) {
2943 /* If no destination, treat it as a NOP.
2944 For add & sub, we must generate the overflow exception when needed. */
2945 return;
2946 }
2947
2948 t0 = tcg_temp_new();
2949 t1 = tcg_temp_new();
2950 gen_load_gpr(t0, rs);
2951 gen_load_gpr(t1, rt);
2952 switch (opc) {
2953 case OPC_SLLV:
2954 tcg_gen_andi_tl(t0, t0, 0x1f);
2955 tcg_gen_shl_tl(t0, t1, t0);
2956 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2957 break;
2958 case OPC_SRAV:
2959 tcg_gen_andi_tl(t0, t0, 0x1f);
2960 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2961 break;
2962 case OPC_SRLV:
2963 tcg_gen_ext32u_tl(t1, t1);
2964 tcg_gen_andi_tl(t0, t0, 0x1f);
2965 tcg_gen_shr_tl(t0, t1, t0);
2966 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2967 break;
2968 case OPC_ROTRV:
2969 {
2970 TCGv_i32 t2 = tcg_temp_new_i32();
2971 TCGv_i32 t3 = tcg_temp_new_i32();
2972
2973 tcg_gen_trunc_tl_i32(t2, t0);
2974 tcg_gen_trunc_tl_i32(t3, t1);
2975 tcg_gen_andi_i32(t2, t2, 0x1f);
2976 tcg_gen_rotr_i32(t2, t3, t2);
2977 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2978 tcg_temp_free_i32(t2);
2979 tcg_temp_free_i32(t3);
2980 }
2981 break;
2982 #if defined(TARGET_MIPS64)
2983 case OPC_DSLLV:
2984 tcg_gen_andi_tl(t0, t0, 0x3f);
2985 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2986 break;
2987 case OPC_DSRAV:
2988 tcg_gen_andi_tl(t0, t0, 0x3f);
2989 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2990 break;
2991 case OPC_DSRLV:
2992 tcg_gen_andi_tl(t0, t0, 0x3f);
2993 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2994 break;
2995 case OPC_DROTRV:
2996 tcg_gen_andi_tl(t0, t0, 0x3f);
2997 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2998 break;
2999 #endif
3000 }
3001 tcg_temp_free(t0);
3002 tcg_temp_free(t1);
3003 }
3004
3005 /* Arithmetic on HI/LO registers */
3006 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3007 {
3008 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3009 /* Treat as NOP. */
3010 return;
3011 }
3012
3013 if (acc != 0) {
3014 check_dsp(ctx);
3015 }
3016
3017 switch (opc) {
3018 case OPC_MFHI:
3019 #if defined(TARGET_MIPS64)
3020 if (acc != 0) {
3021 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3022 } else
3023 #endif
3024 {
3025 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3026 }
3027 break;
3028 case OPC_MFLO:
3029 #if defined(TARGET_MIPS64)
3030 if (acc != 0) {
3031 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3032 } else
3033 #endif
3034 {
3035 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3036 }
3037 break;
3038 case OPC_MTHI:
3039 if (reg != 0) {
3040 #if defined(TARGET_MIPS64)
3041 if (acc != 0) {
3042 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3043 } else
3044 #endif
3045 {
3046 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3047 }
3048 } else {
3049 tcg_gen_movi_tl(cpu_HI[acc], 0);
3050 }
3051 break;
3052 case OPC_MTLO:
3053 if (reg != 0) {
3054 #if defined(TARGET_MIPS64)
3055 if (acc != 0) {
3056 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3057 } else
3058 #endif
3059 {
3060 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3061 }
3062 } else {
3063 tcg_gen_movi_tl(cpu_LO[acc], 0);
3064 }
3065 break;
3066 }
3067 }
3068
3069 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3070 TCGMemOp memop)
3071 {
3072 TCGv t0 = tcg_const_tl(addr);
3073 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3074 gen_store_gpr(t0, reg);
3075 tcg_temp_free(t0);
3076 }
3077
3078 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3079 int rs)
3080 {
3081 target_long offset;
3082 target_long addr;
3083
3084 switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3085 case OPC_ADDIUPC:
3086 if (rs != 0) {
3087 offset = sextract32(ctx->opcode << 2, 0, 21);
3088 addr = addr_add(ctx, pc, offset);
3089 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3090 }
3091 break;
3092 case R6_OPC_LWPC:
3093 offset = sextract32(ctx->opcode << 2, 0, 21);
3094 addr = addr_add(ctx, pc, offset);
3095 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3096 break;
3097 #if defined(TARGET_MIPS64)
3098 case OPC_LWUPC:
3099 check_mips_64(ctx);
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_TEUL);
3103 break;
3104 #endif
3105 default:
3106 switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3107 case OPC_AUIPC:
3108 if (rs != 0) {
3109 offset = sextract32(ctx->opcode, 0, 16) << 16;
3110 addr = addr_add(ctx, pc, offset);
3111 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3112 }
3113 break;
3114 case OPC_ALUIPC:
3115 if (rs != 0) {
3116 offset = sextract32(ctx->opcode, 0, 16) << 16;
3117 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3118 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3119 }
3120 break;
3121 #if defined(TARGET_MIPS64)
3122 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3123 case R6_OPC_LDPC + (1 << 16):
3124 case R6_OPC_LDPC + (2 << 16):
3125 case R6_OPC_LDPC + (3 << 16):
3126 check_mips_64(ctx);
3127 offset = sextract32(ctx->opcode << 3, 0, 21);
3128 addr = addr_add(ctx, (pc & ~0x7), offset);
3129 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3130 break;
3131 #endif
3132 default:
3133 MIPS_INVAL("OPC_PCREL");
3134 generate_exception_end(ctx, EXCP_RI);
3135 break;
3136 }
3137 break;
3138 }
3139 }
3140
3141 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3142 {
3143 TCGv t0, t1;
3144
3145 if (rd == 0) {
3146 /* Treat as NOP. */
3147 return;
3148 }
3149
3150 t0 = tcg_temp_new();
3151 t1 = tcg_temp_new();
3152
3153 gen_load_gpr(t0, rs);
3154 gen_load_gpr(t1, rt);
3155
3156 switch (opc) {
3157 case R6_OPC_DIV:
3158 {
3159 TCGv t2 = tcg_temp_new();
3160 TCGv t3 = tcg_temp_new();
3161 tcg_gen_ext32s_tl(t0, t0);
3162 tcg_gen_ext32s_tl(t1, t1);
3163 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3164 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3165 tcg_gen_and_tl(t2, t2, t3);
3166 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3167 tcg_gen_or_tl(t2, t2, t3);
3168 tcg_gen_movi_tl(t3, 0);
3169 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3170 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3171 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3172 tcg_temp_free(t3);
3173 tcg_temp_free(t2);
3174 }
3175 break;
3176 case R6_OPC_MOD:
3177 {
3178 TCGv t2 = tcg_temp_new();
3179 TCGv t3 = tcg_temp_new();
3180 tcg_gen_ext32s_tl(t0, t0);
3181 tcg_gen_ext32s_tl(t1, t1);
3182 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3183 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3184 tcg_gen_and_tl(t2, t2, t3);
3185 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3186 tcg_gen_or_tl(t2, t2, t3);
3187 tcg_gen_movi_tl(t3, 0);
3188 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3189 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3190 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3191 tcg_temp_free(t3);
3192 tcg_temp_free(t2);
3193 }
3194 break;
3195 case R6_OPC_DIVU:
3196 {
3197 TCGv t2 = tcg_const_tl(0);
3198 TCGv t3 = tcg_const_tl(1);
3199 tcg_gen_ext32u_tl(t0, t0);
3200 tcg_gen_ext32u_tl(t1, t1);
3201 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3202 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3203 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3204 tcg_temp_free(t3);
3205 tcg_temp_free(t2);
3206 }
3207 break;
3208 case R6_OPC_MODU:
3209 {
3210 TCGv t2 = tcg_const_tl(0);
3211 TCGv t3 = tcg_const_tl(1);
3212 tcg_gen_ext32u_tl(t0, t0);
3213 tcg_gen_ext32u_tl(t1, t1);
3214 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3215 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3216 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3217 tcg_temp_free(t3);
3218 tcg_temp_free(t2);
3219 }
3220 break;
3221 case R6_OPC_MUL:
3222 {
3223 TCGv_i32 t2 = tcg_temp_new_i32();
3224 TCGv_i32 t3 = tcg_temp_new_i32();
3225 tcg_gen_trunc_tl_i32(t2, t0);
3226 tcg_gen_trunc_tl_i32(t3, t1);
3227 tcg_gen_mul_i32(t2, t2, t3);
3228 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3229 tcg_temp_free_i32(t2);
3230 tcg_temp_free_i32(t3);
3231 }
3232 break;
3233 case R6_OPC_MUH:
3234 {
3235 TCGv_i32 t2 = tcg_temp_new_i32();
3236 TCGv_i32 t3 = tcg_temp_new_i32();
3237 tcg_gen_trunc_tl_i32(t2, t0);
3238 tcg_gen_trunc_tl_i32(t3, t1);
3239 tcg_gen_muls2_i32(t2, t3, t2, t3);
3240 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3241 tcg_temp_free_i32(t2);
3242 tcg_temp_free_i32(t3);
3243 }
3244 break;
3245 case R6_OPC_MULU:
3246 {
3247 TCGv_i32 t2 = tcg_temp_new_i32();
3248 TCGv_i32 t3 = tcg_temp_new_i32();
3249 tcg_gen_trunc_tl_i32(t2, t0);
3250 tcg_gen_trunc_tl_i32(t3, t1);
3251 tcg_gen_mul_i32(t2, t2, t3);
3252 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3253 tcg_temp_free_i32(t2);
3254 tcg_temp_free_i32(t3);
3255 }
3256 break;
3257 case R6_OPC_MUHU:
3258 {
3259 TCGv_i32 t2 = tcg_temp_new_i32();
3260 TCGv_i32 t3 = tcg_temp_new_i32();
3261 tcg_gen_trunc_tl_i32(t2, t0);
3262 tcg_gen_trunc_tl_i32(t3, t1);
3263 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3264 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3265 tcg_temp_free_i32(t2);
3266 tcg_temp_free_i32(t3);
3267 }
3268 break;
3269 #if defined(TARGET_MIPS64)
3270 case R6_OPC_DDIV:
3271 {
3272 TCGv t2 = tcg_temp_new();
3273 TCGv t3 = tcg_temp_new();
3274 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3275 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3276 tcg_gen_and_tl(t2, t2, t3);
3277 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3278 tcg_gen_or_tl(t2, t2, t3);
3279 tcg_gen_movi_tl(t3, 0);
3280 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3281 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3282 tcg_temp_free(t3);
3283 tcg_temp_free(t2);
3284 }
3285 break;
3286 case R6_OPC_DMOD:
3287 {
3288 TCGv t2 = tcg_temp_new();
3289 TCGv t3 = tcg_temp_new();
3290 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3291 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3292 tcg_gen_and_tl(t2, t2, t3);
3293 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3294 tcg_gen_or_tl(t2, t2, t3);
3295 tcg_gen_movi_tl(t3, 0);
3296 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3297 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3298 tcg_temp_free(t3);
3299 tcg_temp_free(t2);
3300 }
3301 break;
3302 case R6_OPC_DDIVU:
3303 {
3304 TCGv t2 = tcg_const_tl(0);
3305 TCGv t3 = tcg_const_tl(1);
3306 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3307 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3308 tcg_temp_free(t3);
3309 tcg_temp_free(t2);
3310 }
3311 break;
3312 case R6_OPC_DMODU:
3313 {
3314 TCGv t2 = tcg_const_tl(0);
3315 TCGv t3 = tcg_const_tl(1);
3316 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3317 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3318 tcg_temp_free(t3);
3319 tcg_temp_free(t2);
3320 }
3321 break;
3322 case R6_OPC_DMUL:
3323 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3324 break;
3325 case R6_OPC_DMUH:
3326 {
3327 TCGv t2 = tcg_temp_new();
3328 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3329 tcg_temp_free(t2);
3330 }
3331 break;
3332 case R6_OPC_DMULU:
3333 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3334 break;
3335 case R6_OPC_DMUHU:
3336 {
3337 TCGv t2 = tcg_temp_new();
3338 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3339 tcg_temp_free(t2);
3340 }
3341 break;
3342 #endif
3343 default:
3344 MIPS_INVAL("r6 mul/div");
3345 generate_exception_end(ctx, EXCP_RI);
3346 goto out;
3347 }
3348 out:
3349 tcg_temp_free(t0);
3350 tcg_temp_free(t1);
3351 }
3352
3353 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3354 int acc, int rs, int rt)
3355 {
3356 TCGv t0, t1;
3357
3358 t0 = tcg_temp_new();
3359 t1 = tcg_temp_new();
3360
3361 gen_load_gpr(t0, rs);
3362 gen_load_gpr(t1, rt);
3363
3364 if (acc != 0) {
3365 check_dsp(ctx);
3366 }
3367
3368 switch (opc) {
3369 case OPC_DIV:
3370 {
3371 TCGv t2 = tcg_temp_new();
3372 TCGv t3 = tcg_temp_new();
3373 tcg_gen_ext32s_tl(t0, t0);
3374 tcg_gen_ext32s_tl(t1, t1);
3375 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3376 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3377 tcg_gen_and_tl(t2, t2, t3);
3378 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3379 tcg_gen_or_tl(t2, t2, t3);
3380 tcg_gen_movi_tl(t3, 0);
3381 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3382 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3383 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3384 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3385 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3386 tcg_temp_free(t3);
3387 tcg_temp_free(t2);
3388 }
3389 break;
3390 case OPC_DIVU:
3391 {
3392 TCGv t2 = tcg_const_tl(0);
3393 TCGv t3 = tcg_const_tl(1);
3394 tcg_gen_ext32u_tl(t0, t0);
3395 tcg_gen_ext32u_tl(t1, t1);
3396 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3397 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3398 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3399 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3400 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3401 tcg_temp_free(t3);
3402 tcg_temp_free(t2);
3403 }
3404 break;
3405 case OPC_MULT:
3406 {
3407 TCGv_i32 t2 = tcg_temp_new_i32();
3408 TCGv_i32 t3 = tcg_temp_new_i32();
3409 tcg_gen_trunc_tl_i32(t2, t0);
3410 tcg_gen_trunc_tl_i32(t3, t1);
3411 tcg_gen_muls2_i32(t2, t3, t2, t3);
3412 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3413 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3414 tcg_temp_free_i32(t2);
3415 tcg_temp_free_i32(t3);
3416 }
3417 break;
3418 case OPC_MULTU:
3419 {
3420 TCGv_i32 t2 = tcg_temp_new_i32();
3421 TCGv_i32 t3 = tcg_temp_new_i32();
3422 tcg_gen_trunc_tl_i32(t2, t0);
3423 tcg_gen_trunc_tl_i32(t3, t1);
3424 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3425 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3426 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3427 tcg_temp_free_i32(t2);
3428 tcg_temp_free_i32(t3);
3429 }
3430 break;
3431 #if defined(TARGET_MIPS64)
3432 case OPC_DDIV:
3433 {
3434 TCGv t2 = tcg_temp_new();
3435 TCGv t3 = tcg_temp_new();
3436 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3437 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3438 tcg_gen_and_tl(t2, t2, t3);
3439 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3440 tcg_gen_or_tl(t2, t2, t3);
3441 tcg_gen_movi_tl(t3, 0);
3442 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3443 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3444 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3445 tcg_temp_free(t3);
3446 tcg_temp_free(t2);
3447 }
3448 break;
3449 case OPC_DDIVU:
3450 {
3451 TCGv t2 = tcg_const_tl(0);
3452 TCGv t3 = tcg_const_tl(1);
3453 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3454 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3455 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3456 tcg_temp_free(t3);
3457 tcg_temp_free(t2);
3458 }
3459 break;
3460 case OPC_DMULT:
3461 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3462 break;
3463 case OPC_DMULTU:
3464 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3465 break;
3466 #endif
3467 case OPC_MADD:
3468 {
3469 TCGv_i64 t2 = tcg_temp_new_i64();
3470 TCGv_i64 t3 = tcg_temp_new_i64();
3471
3472 tcg_gen_ext_tl_i64(t2, t0);
3473 tcg_gen_ext_tl_i64(t3, t1);
3474 tcg_gen_mul_i64(t2, t2, t3);
3475 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3476 tcg_gen_add_i64(t2, t2, t3);
3477 tcg_temp_free_i64(t3);
3478 gen_move_low32(cpu_LO[acc], t2);
3479 gen_move_high32(cpu_HI[acc], t2);
3480 tcg_temp_free_i64(t2);
3481 }
3482 break;
3483 case OPC_MADDU:
3484 {
3485 TCGv_i64 t2 = tcg_temp_new_i64();
3486 TCGv_i64 t3 = tcg_temp_new_i64();
3487
3488 tcg_gen_ext32u_tl(t0, t0);
3489 tcg_gen_ext32u_tl(t1, t1);
3490 tcg_gen_extu_tl_i64(t2, t0);
3491 tcg_gen_extu_tl_i64(t3, t1);
3492 tcg_gen_mul_i64(t2, t2, t3);
3493 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3494 tcg_gen_add_i64(t2, t2, t3);
3495 tcg_temp_free_i64(t3);
3496 gen_move_low32(cpu_LO[acc], t2);
3497 gen_move_high32(cpu_HI[acc], t2);
3498 tcg_temp_free_i64(t2);
3499 }
3500 break;
3501 case OPC_MSUB:
3502 {
3503 TCGv_i64 t2 = tcg_temp_new_i64();
3504 TCGv_i64 t3 = tcg_temp_new_i64();
3505
3506 tcg_gen_ext_tl_i64(t2, t0);
3507 tcg_gen_ext_tl_i64(t3, t1);
3508 tcg_gen_mul_i64(t2, t2, t3);
3509 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3510 tcg_gen_sub_i64(t2, t3, t2);
3511 tcg_temp_free_i64(t3);
3512 gen_move_low32(cpu_LO[acc], t2);
3513 gen_move_high32(cpu_HI[acc], t2);
3514 tcg_temp_free_i64(t2);
3515 }
3516 break;
3517 case OPC_MSUBU:
3518 {
3519 TCGv_i64 t2 = tcg_temp_new_i64();
3520 TCGv_i64 t3 = tcg_temp_new_i64();
3521
3522 tcg_gen_ext32u_tl(t0, t0);
3523 tcg_gen_ext32u_tl(t1, t1);
3524 tcg_gen_extu_tl_i64(t2, t0);
3525 tcg_gen_extu_tl_i64(t3, t1);
3526 tcg_gen_mul_i64(t2, t2, t3);
3527 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3528 tcg_gen_sub_i64(t2, t3, t2);
3529 tcg_temp_free_i64(t3);
3530 gen_move_low32(cpu_LO[acc], t2);
3531 gen_move_high32(cpu_HI[acc], t2);
3532 tcg_temp_free_i64(t2);
3533 }
3534 break;
3535 default:
3536 MIPS_INVAL("mul/div");
3537 generate_exception_end(ctx, EXCP_RI);
3538 goto out;
3539 }
3540 out:
3541 tcg_temp_free(t0);
3542 tcg_temp_free(t1);
3543 }
3544
3545 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3546 int rd, int rs, int rt)
3547 {
3548 TCGv t0 = tcg_temp_new();
3549 TCGv t1 = tcg_temp_new();
3550
3551 gen_load_gpr(t0, rs);
3552 gen_load_gpr(t1, rt);
3553
3554 switch (opc) {
3555 case OPC_VR54XX_MULS:
3556 gen_helper_muls(t0, cpu_env, t0, t1);
3557 break;
3558 case OPC_VR54XX_MULSU:
3559 gen_helper_mulsu(t0, cpu_env, t0, t1);
3560 break;
3561 case OPC_VR54XX_MACC:
3562 gen_helper_macc(t0, cpu_env, t0, t1);
3563 break;
3564 case OPC_VR54XX_MACCU:
3565 gen_helper_maccu(t0, cpu_env, t0, t1);
3566 break;
3567 case OPC_VR54XX_MSAC:
3568 gen_helper_msac(t0, cpu_env, t0, t1);
3569 break;
3570 case OPC_VR54XX_MSACU:
3571 gen_helper_msacu(t0, cpu_env, t0, t1);
3572 break;
3573 case OPC_VR54XX_MULHI:
3574 gen_helper_mulhi(t0, cpu_env, t0, t1);
3575 break;
3576 case OPC_VR54XX_MULHIU:
3577 gen_helper_mulhiu(t0, cpu_env, t0, t1);
3578 break;
3579 case OPC_VR54XX_MULSHI:
3580 gen_helper_mulshi(t0, cpu_env, t0, t1);
3581 break;
3582 case OPC_VR54XX_MULSHIU:
3583 gen_helper_mulshiu(t0, cpu_env, t0, t1);
3584 break;
3585 case OPC_VR54XX_MACCHI:
3586 gen_helper_macchi(t0, cpu_env, t0, t1);
3587 break;
3588 case OPC_VR54XX_MACCHIU:
3589 gen_helper_macchiu(t0, cpu_env, t0, t1);
3590 break;
3591 case OPC_VR54XX_MSACHI:
3592 gen_helper_msachi(t0, cpu_env, t0, t1);
3593 break;
3594 case OPC_VR54XX_MSACHIU:
3595 gen_helper_msachiu(t0, cpu_env, t0, t1);
3596 break;
3597 default:
3598 MIPS_INVAL("mul vr54xx");
3599 generate_exception_end(ctx, EXCP_RI);
3600 goto out;
3601 }
3602 gen_store_gpr(t0, rd);
3603
3604 out:
3605 tcg_temp_free(t0);
3606 tcg_temp_free(t1);
3607 }
3608
3609 static void gen_cl (DisasContext *ctx, uint32_t opc,
3610 int rd, int rs)
3611 {
3612 TCGv t0;
3613
3614 if (rd == 0) {
3615 /* Treat as NOP. */
3616 return;
3617 }
3618 t0 = tcg_temp_new();
3619 gen_load_gpr(t0, rs);
3620 switch (opc) {
3621 case OPC_CLO:
3622 case R6_OPC_CLO:
3623 gen_helper_clo(cpu_gpr[rd], t0);
3624 break;
3625 case OPC_CLZ:
3626 case R6_OPC_CLZ:
3627 gen_helper_clz(cpu_gpr[rd], t0);
3628 break;
3629 #if defined(TARGET_MIPS64)
3630 case OPC_DCLO:
3631 case R6_OPC_DCLO:
3632 gen_helper_dclo(cpu_gpr[rd], t0);
3633 break;
3634 case OPC_DCLZ:
3635 case R6_OPC_DCLZ:
3636 gen_helper_dclz(cpu_gpr[rd], t0);
3637 break;
3638 #endif
3639 }
3640 tcg_temp_free(t0);
3641 }
3642
3643 /* Godson integer instructions */
3644 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3645 int rd, int rs, int rt)
3646 {
3647 TCGv t0, t1;
3648
3649 if (rd == 0) {
3650 /* Treat as NOP. */
3651 return;
3652 }
3653
3654 switch (opc) {
3655 case OPC_MULT_G_2E:
3656 case OPC_MULT_G_2F:
3657 case OPC_MULTU_G_2E:
3658 case OPC_MULTU_G_2F:
3659 #if defined(TARGET_MIPS64)
3660 case OPC_DMULT_G_2E:
3661 case OPC_DMULT_G_2F:
3662 case OPC_DMULTU_G_2E:
3663 case OPC_DMULTU_G_2F:
3664 #endif
3665 t0 = tcg_temp_new();
3666 t1 = tcg_temp_new();
3667 break;
3668 default:
3669 t0 = tcg_temp_local_new();
3670 t1 = tcg_temp_local_new();
3671 break;
3672 }
3673
3674 gen_load_gpr(t0, rs);
3675 gen_load_gpr(t1, rt);
3676
3677 switch (opc) {
3678 case OPC_MULT_G_2E:
3679 case OPC_MULT_G_2F:
3680 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3681 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3682 break;
3683 case OPC_MULTU_G_2E:
3684 case OPC_MULTU_G_2F:
3685 tcg_gen_ext32u_tl(t0, t0);
3686 tcg_gen_ext32u_tl(t1, t1);
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_DIV_G_2E:
3691 case OPC_DIV_G_2F:
3692 {
3693 TCGLabel *l1 = gen_new_label();
3694 TCGLabel *l2 = gen_new_label();
3695 TCGLabel *l3 = gen_new_label();
3696 tcg_gen_ext32s_tl(t0, t0);
3697 tcg_gen_ext32s_tl(t1, t1);
3698 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3699 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3700 tcg_gen_br(l3);
3701 gen_set_label(l1);
3702 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3703 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3704 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3705 tcg_gen_br(l3);
3706 gen_set_label(l2);
3707 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3708 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3709 gen_set_label(l3);
3710 }
3711 break;
3712 case OPC_DIVU_G_2E:
3713 case OPC_DIVU_G_2F:
3714 {
3715 TCGLabel *l1 = gen_new_label();
3716 TCGLabel *l2 = gen_new_label();
3717 tcg_gen_ext32u_tl(t0, t0);
3718 tcg_gen_ext32u_tl(t1, t1);
3719 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3720 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3721 tcg_gen_br(l2);
3722 gen_set_label(l1);
3723 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3724 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3725 gen_set_label(l2);
3726 }
3727 break;
3728 case OPC_MOD_G_2E:
3729 case OPC_MOD_G_2F:
3730 {
3731 TCGLabel *l1 = gen_new_label();
3732 TCGLabel *l2 = gen_new_label();
3733 TCGLabel *l3 = gen_new_label();
3734 tcg_gen_ext32u_tl(t0, t0);
3735 tcg_gen_ext32u_tl(t1, t1);
3736 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3737 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3738 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3739 gen_set_label(l1);
3740 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3741 tcg_gen_br(l3);
3742 gen_set_label(l2);
3743 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3744 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3745 gen_set_label(l3);
3746 }
3747 break;
3748 case OPC_MODU_G_2E:
3749 case OPC_MODU_G_2F:
3750 {
3751 TCGLabel *l1 = gen_new_label();
3752 TCGLabel *l2 = gen_new_label();
3753 tcg_gen_ext32u_tl(t0, t0);
3754 tcg_gen_ext32u_tl(t1, t1);
3755 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3756 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3757 tcg_gen_br(l2);
3758 gen_set_label(l1);
3759 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3760 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3761 gen_set_label(l2);
3762 }
3763 break;
3764 #if defined(TARGET_MIPS64)
3765 case OPC_DMULT_G_2E:
3766 case OPC_DMULT_G_2F:
3767 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3768 break;
3769 case OPC_DMULTU_G_2E:
3770 case OPC_DMULTU_G_2F:
3771 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3772 break;
3773 case OPC_DDIV_G_2E:
3774 case OPC_DDIV_G_2F:
3775 {
3776 TCGLabel *l1 = gen_new_label();
3777 TCGLabel *l2 = gen_new_label();
3778 TCGLabel *l3 = gen_new_label();
3779 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3780 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3781 tcg_gen_br(l3);
3782 gen_set_label(l1);
3783 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3784 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3785 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3786 tcg_gen_br(l3);
3787 gen_set_label(l2);
3788 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3789 gen_set_label(l3);
3790 }
3791 break;
3792 case OPC_DDIVU_G_2E:
3793 case OPC_DDIVU_G_2F:
3794 {
3795 TCGLabel *l1 = gen_new_label();
3796 TCGLabel *l2 = gen_new_label();
3797 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3798 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3799 tcg_gen_br(l2);
3800 gen_set_label(l1);
3801 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3802 gen_set_label(l2);
3803 }
3804 break;
3805 case OPC_DMOD_G_2E:
3806 case OPC_DMOD_G_2F:
3807 {
3808 TCGLabel *l1 = gen_new_label();
3809 TCGLabel *l2 = gen_new_label();
3810 TCGLabel *l3 = gen_new_label();
3811 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3812 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3813 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3814 gen_set_label(l1);
3815 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3816 tcg_gen_br(l3);
3817 gen_set_label(l2);
3818 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3819 gen_set_label(l3);
3820 }
3821 break;
3822 case OPC_DMODU_G_2E:
3823 case OPC_DMODU_G_2F:
3824 {
3825 TCGLabel *l1 = gen_new_label();
3826 TCGLabel *l2 = gen_new_label();
3827 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3828 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3829 tcg_gen_br(l2);
3830 gen_set_label(l1);
3831 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3832 gen_set_label(l2);
3833 }
3834 break;
3835 #endif
3836 }
3837
3838 tcg_temp_free(t0);
3839 tcg_temp_free(t1);
3840 }
3841
3842 /* Loongson multimedia instructions */
3843 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3844 {
3845 uint32_t opc, shift_max;
3846 TCGv_i64 t0, t1;
3847
3848 opc = MASK_LMI(ctx->opcode);
3849 switch (opc) {
3850 case OPC_ADD_CP2:
3851 case OPC_SUB_CP2:
3852 case OPC_DADD_CP2:
3853 case OPC_DSUB_CP2:
3854 t0 = tcg_temp_local_new_i64();
3855 t1 = tcg_temp_local_new_i64();
3856 break;
3857 default:
3858 t0 = tcg_temp_new_i64();
3859 t1 = tcg_temp_new_i64();
3860 break;
3861 }
3862
3863 gen_load_fpr64(ctx, t0, rs);
3864 gen_load_fpr64(ctx, t1, rt);
3865
3866 #define LMI_HELPER(UP, LO) \
3867 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3868 #define LMI_HELPER_1(UP, LO) \
3869 case OPC_##UP: gen_helper_##LO(t0, t0); break
3870 #define LMI_DIRECT(UP, LO, OP) \
3871 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3872
3873 switch (opc) {
3874 LMI_HELPER(PADDSH, paddsh);
3875 LMI_HELPER(PADDUSH, paddush);
3876 LMI_HELPER(PADDH, paddh);
3877 LMI_HELPER(PADDW, paddw);
3878 LMI_HELPER(PADDSB, paddsb);
3879 LMI_HELPER(PADDUSB, paddusb);
3880 LMI_HELPER(PADDB, paddb);
3881
3882 LMI_HELPER(PSUBSH, psubsh);
3883 LMI_HELPER(PSUBUSH, psubush);
3884 LMI_HELPER(PSUBH, psubh);
3885 LMI_HELPER(PSUBW, psubw);
3886 LMI_HELPER(PSUBSB, psubsb);
3887 LMI_HELPER(PSUBUSB, psubusb);
3888 LMI_HELPER(PSUBB, psubb);
3889
3890 LMI_HELPER(PSHUFH, pshufh);
3891 LMI_HELPER(PACKSSWH, packsswh);
3892 LMI_HELPER(PACKSSHB, packsshb);
3893 LMI_HELPER(PACKUSHB, packushb);
3894
3895 LMI_HELPER(PUNPCKLHW, punpcklhw);
3896 LMI_HELPER(PUNPCKHHW, punpckhhw);
3897 LMI_HELPER(PUNPCKLBH, punpcklbh);
3898 LMI_HELPER(PUNPCKHBH, punpckhbh);
3899 LMI_HELPER(PUNPCKLWD, punpcklwd);
3900 LMI_HELPER(PUNPCKHWD, punpckhwd);
3901
3902 LMI_HELPER(PAVGH, pavgh);
3903 LMI_HELPER(PAVGB, pavgb);
3904 LMI_HELPER(PMAXSH, pmaxsh);
3905 LMI_HELPER(PMINSH, pminsh);
3906 LMI_HELPER(PMAXUB, pmaxub);
3907 LMI_HELPER(PMINUB, pminub);
3908
3909 LMI_HELPER(PCMPEQW, pcmpeqw);
3910 LMI_HELPER(PCMPGTW, pcmpgtw);
3911 LMI_HELPER(PCMPEQH, pcmpeqh);
3912 LMI_HELPER(PCMPGTH, pcmpgth);
3913 LMI_HELPER(PCMPEQB, pcmpeqb);
3914 LMI_HELPER(PCMPGTB, pcmpgtb);
3915
3916 LMI_HELPER(PSLLW, psllw);
3917 LMI_HELPER(PSLLH, psllh);
3918 LMI_HELPER(PSRLW, psrlw);
3919 LMI_HELPER(PSRLH, psrlh);
3920 LMI_HELPER(PSRAW, psraw);
3921 LMI_HELPER(PSRAH, psrah);
3922
3923 LMI_HELPER(PMULLH, pmullh);
3924 LMI_HELPER(PMULHH, pmulhh);
3925 LMI_HELPER(PMULHUH, pmulhuh);
3926 LMI_HELPER(PMADDHW, pmaddhw);
3927
3928 LMI_HELPER(PASUBUB, pasubub);
3929 LMI_HELPER_1(BIADD, biadd);
3930 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3931
3932 LMI_DIRECT(PADDD, paddd, add);
3933 LMI_DIRECT(PSUBD, psubd, sub);
3934 LMI_DIRECT(XOR_CP2, xor, xor);
3935 LMI_DIRECT(NOR_CP2, nor, nor);
3936 LMI_DIRECT(AND_CP2, and, and);
3937 LMI_DIRECT(PANDN, pandn, andc);
3938 LMI_DIRECT(OR, or, or);
3939
3940 case OPC_PINSRH_0:
3941 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3942 break;
3943 case OPC_PINSRH_1:
3944 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3945 break;
3946 case OPC_PINSRH_2:
3947 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3948 break;
3949 case OPC_PINSRH_3:
3950 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3951 break;
3952
3953 case OPC_PEXTRH:
3954 tcg_gen_andi_i64(t1, t1, 3);
3955 tcg_gen_shli_i64(t1, t1, 4);
3956 tcg_gen_shr_i64(t0, t0, t1);
3957 tcg_gen_ext16u_i64(t0, t0);
3958 break;
3959
3960 case OPC_ADDU_CP2:
3961 tcg_gen_add_i64(t0, t0, t1);
3962 tcg_gen_ext32s_i64(t0, t0);
3963 break;
3964 case OPC_SUBU_CP2:
3965 tcg_gen_sub_i64(t0, t0, t1);
3966 tcg_gen_ext32s_i64(t0, t0);
3967 break;
3968
3969 case OPC_SLL_CP2:
3970 shift_max = 32;
3971 goto do_shift;
3972 case OPC_SRL_CP2:
3973 shift_max = 32;
3974 goto do_shift;
3975 case OPC_SRA_CP2:
3976 shift_max = 32;
3977 goto do_shift;
3978 case OPC_DSLL_CP2:
3979 shift_max = 64;
3980 goto do_shift;
3981 case OPC_DSRL_CP2:
3982 shift_max = 64;
3983 goto do_shift;
3984 case OPC_DSRA_CP2:
3985 shift_max = 64;
3986 goto do_shift;
3987 do_shift:
3988 /* Make sure shift count isn't TCG undefined behaviour. */
3989 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3990
3991 switch (opc) {
3992 case OPC_SLL_CP2:
3993 case OPC_DSLL_CP2:
3994 tcg_gen_shl_i64(t0, t0, t1);
3995 break;
3996 case OPC_SRA_CP2:
3997 case OPC_DSRA_CP2:
3998 /* Since SRA is UndefinedResult without sign-extended inputs,
3999 we can treat SRA and DSRA the same. */
4000 tcg_gen_sar_i64(t0, t0, t1);
4001 break;
4002 case OPC_SRL_CP2:
4003 /* We want to shift in zeros for SRL; zero-extend first. */
4004 tcg_gen_ext32u_i64(t0, t0);
4005 /* FALLTHRU */
4006 case OPC_DSRL_CP2:
4007 tcg_gen_shr_i64(t0, t0, t1);
4008 break;
4009 }
4010
4011 if (shift_max == 32) {
4012 tcg_gen_ext32s_i64(t0, t0);
4013 }
4014
4015 /* Shifts larger than MAX produce zero. */
4016 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4017 tcg_gen_neg_i64(t1, t1);
4018 tcg_gen_and_i64(t0, t0, t1);
4019 break;
4020
4021 case OPC_ADD_CP2:
4022 case OPC_DADD_CP2:
4023 {
4024 TCGv_i64 t2 = tcg_temp_new_i64();
4025 TCGLabel *lab = gen_new_label();
4026
4027 tcg_gen_mov_i64(t2, t0);
4028 tcg_gen_add_i64(t0, t1, t2);
4029 if (opc == OPC_ADD_CP2) {
4030 tcg_gen_ext32s_i64(t0, t0);
4031 }
4032 tcg_gen_xor_i64(t1, t1, t2);
4033 tcg_gen_xor_i64(t2, t2, t0);
4034 tcg_gen_andc_i64(t1, t2, t1);
4035 tcg_temp_free_i64(t2);
4036 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4037 generate_exception(ctx, EXCP_OVERFLOW);
4038 gen_set_label(lab);
4039 break;
4040 }
4041
4042 case OPC_SUB_CP2:
4043 case OPC_DSUB_CP2:
4044 {
4045 TCGv_i64 t2 = tcg_temp_new_i64();
4046 TCGLabel *lab = gen_new_label();
4047
4048 tcg_gen_mov_i64(t2, t0);
4049 tcg_gen_sub_i64(t0, t1, t2);
4050 if (opc == OPC_SUB_CP2) {
4051 tcg_gen_ext32s_i64(t0, t0);
4052 }
4053 tcg_gen_xor_i64(t1, t1, t2);
4054 tcg_gen_xor_i64(t2, t2, t0);
4055 tcg_gen_and_i64(t1, t1, t2);
4056 tcg_temp_free_i64(t2);
4057 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4058 generate_exception(ctx, EXCP_OVERFLOW);
4059 gen_set_label(lab);
4060 break;
4061 }
4062
4063 case OPC_PMULUW:
4064 tcg_gen_ext32u_i64(t0, t0);
4065 tcg_gen_ext32u_i64(t1, t1);
4066 tcg_gen_mul_i64(t0, t0, t1);
4067 break;
4068
4069 case OPC_SEQU_CP2:
4070 case OPC_SEQ_CP2:
4071 case OPC_SLTU_CP2:
4072 case OPC_SLT_CP2:
4073 case OPC_SLEU_CP2:
4074 case OPC_SLE_CP2:
4075 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4076 FD field is the CC field? */
4077 default:
4078 MIPS_INVAL("loongson_cp2");
4079 generate_exception_end(ctx, EXCP_RI);
4080 return;
4081 }
4082
4083 #undef LMI_HELPER
4084 #undef LMI_DIRECT
4085
4086 gen_store_fpr64(ctx, t0, rd);
4087
4088 tcg_temp_free_i64(t0);
4089 tcg_temp_free_i64(t1);
4090 }
4091
4092 /* Traps */
4093 static void gen_trap (DisasContext *ctx, uint32_t opc,
4094 int rs, int rt, int16_t imm)
4095 {
4096 int cond;
4097 TCGv t0 = tcg_temp_new();
4098 TCGv t1 = tcg_temp_new();
4099
4100 cond = 0;
4101 /* Load needed operands */
4102 switch (opc) {
4103 case OPC_TEQ:
4104 case OPC_TGE:
4105 case OPC_TGEU:
4106 case OPC_TLT:
4107 case OPC_TLTU:
4108 case OPC_TNE:
4109 /* Compare two registers */
4110 if (rs != rt) {
4111 gen_load_gpr(t0, rs);
4112 gen_load_gpr(t1, rt);
4113 cond = 1;
4114 }
4115 break;
4116 case OPC_TEQI:
4117 case OPC_TGEI:
4118 case OPC_TGEIU:
4119 case OPC_TLTI:
4120 case OPC_TLTIU:
4121 case OPC_TNEI:
4122 /* Compare register to immediate */
4123 if (rs != 0 || imm != 0) {
4124 gen_load_gpr(t0, rs);
4125 tcg_gen_movi_tl(t1, (int32_t)imm);
4126 cond = 1;
4127 }
4128 break;
4129 }
4130 if (cond == 0) {
4131 switch (opc) {
4132 case OPC_TEQ: /* rs == rs */
4133 case OPC_TEQI: /* r0 == 0 */
4134 case OPC_TGE: /* rs >= rs */
4135 case OPC_TGEI: /* r0 >= 0 */
4136 case OPC_TGEU: /* rs >= rs unsigned */
4137 case OPC_TGEIU: /* r0 >= 0 unsigned */
4138 /* Always trap */
4139 generate_exception_end(ctx, EXCP_TRAP);
4140 break;
4141 case OPC_TLT: /* rs < rs */
4142 case OPC_TLTI: /* r0 < 0 */
4143 case OPC_TLTU: /* rs < rs unsigned */
4144 case OPC_TLTIU: /* r0 < 0 unsigned */
4145 case OPC_TNE: /* rs != rs */
4146 case OPC_TNEI: /* r0 != 0 */
4147 /* Never trap: treat as NOP. */
4148 break;
4149 }
4150 } else {
4151 TCGLabel *l1 = gen_new_label();
4152
4153 switch (opc) {
4154 case OPC_TEQ:
4155 case OPC_TEQI:
4156 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4157 break;
4158 case OPC_TGE:
4159 case OPC_TGEI:
4160 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4161 break;
4162 case OPC_TGEU:
4163 case OPC_TGEIU:
4164 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4165 break;
4166 case OPC_TLT:
4167 case OPC_TLTI:
4168 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4169 break;
4170 case OPC_TLTU:
4171 case OPC_TLTIU:
4172 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4173 break;
4174 case OPC_TNE:
4175 case OPC_TNEI:
4176 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4177 break;
4178 }
4179 generate_exception(ctx, EXCP_TRAP);
4180 gen_set_label(l1);
4181 }
4182 tcg_temp_free(t0);
4183 tcg_temp_free(t1);
4184 }
4185
4186 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4187 {
4188 TranslationBlock *tb;
4189 tb = ctx->tb;
4190 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4191 likely(!ctx->singlestep_enabled)) {
4192 tcg_gen_goto_tb(n);
4193 gen_save_pc(dest);
4194 tcg_gen_exit_tb((uintptr_t)tb + n);
4195 } else {
4196 gen_save_pc(dest);
4197 if (ctx->singlestep_enabled) {
4198 save_cpu_state(ctx, 0);
4199 gen_helper_raise_exception_debug(cpu_env);
4200 }
4201 tcg_gen_exit_tb(0);
4202 }
4203 }
4204
4205 /* Branches (before delay slot) */
4206 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4207 int insn_bytes,
4208 int rs, int rt, int32_t offset,
4209 int delayslot_size)
4210 {
4211 target_ulong btgt = -1;
4212 int blink = 0;
4213 int bcond_compute = 0;
4214 TCGv t0 = tcg_temp_new();
4215 TCGv t1 = tcg_temp_new();
4216
4217 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4218 #ifdef MIPS_DEBUG_DISAS
4219 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4220 TARGET_FMT_lx "\n", ctx->pc);
4221 #endif
4222 generate_exception_end(ctx, EXCP_RI);
4223 goto out;
4224 }
4225
4226 /* Load needed operands */
4227 switch (opc) {
4228 case OPC_BEQ:
4229 case OPC_BEQL:
4230 case OPC_BNE:
4231 case OPC_BNEL:
4232 /* Compare two registers */
4233 if (rs != rt) {
4234 gen_load_gpr(t0, rs);
4235 gen_load_gpr(t1, rt);
4236 bcond_compute = 1;
4237 }
4238 btgt = ctx->pc + insn_bytes + offset;
4239 break;
4240 case OPC_BGEZ:
4241 case OPC_BGEZAL:
4242 case OPC_BGEZALL:
4243 case OPC_BGEZL:
4244 case OPC_BGTZ:
4245 case OPC_BGTZL:
4246 case OPC_BLEZ:
4247 case OPC_BLEZL:
4248 case OPC_BLTZ:
4249 case OPC_BLTZAL:
4250 case OPC_BLTZALL:
4251 case OPC_BLTZL:
4252 /* Compare to zero */
4253 if (rs != 0) {
4254 gen_load_gpr(t0, rs);
4255 bcond_compute = 1;
4256 }
4257 btgt = ctx->pc + insn_bytes + offset;
4258 break;
4259 case OPC_BPOSGE32:
4260 #if defined(TARGET_MIPS64)
4261 case OPC_BPOSGE64:
4262 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4263 #else
4264 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4265 #endif
4266 bcond_compute = 1;
4267 btgt = ctx->pc + insn_bytes + offset;
4268 break;
4269 case OPC_J:
4270 case OPC_JAL:
4271 case OPC_JALX:
4272 /* Jump to immediate */
4273 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4274 break;
4275 case OPC_JR:
4276 case OPC_JALR:
4277 /* Jump to register */
4278 if (offset != 0 && offset != 16) {
4279 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4280 others are reserved. */
4281 MIPS_INVAL("jump hint");
4282 generate_exception_end(ctx, EXCP_RI);
4283 goto out;
4284 }
4285 gen_load_gpr(btarget, rs);
4286 break;
4287 default:
4288 MIPS_INVAL("branch/jump");
4289 generate_exception_end(ctx, EXCP_RI);
4290 goto out;
4291 }
4292 if (bcond_compute == 0) {
4293 /* No condition to be computed */
4294 switch (opc) {
4295 case OPC_BEQ: /* rx == rx */
4296 case OPC_BEQL: /* rx == rx likely */
4297 case OPC_BGEZ: /* 0 >= 0 */
4298 case OPC_BGEZL: /* 0 >= 0 likely */
4299 case OPC_BLEZ: /* 0 <= 0 */
4300 case OPC_BLEZL: /* 0 <= 0 likely */
4301 /* Always take */
4302 ctx->hflags |= MIPS_HFLAG_B;
4303 break;
4304 case OPC_BGEZAL: /* 0 >= 0 */
4305 case OPC_BGEZALL: /* 0 >= 0 likely */
4306 /* Always take and link */
4307 blink = 31;
4308 ctx->hflags |= MIPS_HFLAG_B;
4309 break;
4310 case OPC_BNE: /* rx != rx */
4311 case OPC_BGTZ: /* 0 > 0 */
4312 case OPC_BLTZ: /* 0 < 0 */
4313 /* Treat as NOP. */
4314 goto out;
4315 case OPC_BLTZAL: /* 0 < 0 */
4316 /* Handle as an unconditional branch to get correct delay
4317 slot checking. */
4318 blink = 31;
4319 btgt = ctx->pc + insn_bytes + delayslot_size;
4320 ctx->hflags |= MIPS_HFLAG_B;
4321 break;
4322 case OPC_BLTZALL: /* 0 < 0 likely */
4323 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4324 /* Skip the instruction in the delay slot */
4325 ctx->pc += 4;
4326 goto out;
4327 case OPC_BNEL: /* rx != rx likely */
4328 case OPC_BGTZL: /* 0 > 0 likely */
4329 case OPC_BLTZL: /* 0 < 0 likely */
4330 /* Skip the instruction in the delay slot */
4331 ctx->pc += 4;
4332 goto out;
4333 case OPC_J:
4334 ctx->hflags |= MIPS_HFLAG_B;
4335 break;
4336 case OPC_JALX:
4337 ctx->hflags |= MIPS_HFLAG_BX;
4338 /* Fallthrough */
4339 case OPC_JAL:
4340 blink = 31;
4341 ctx->hflags |= MIPS_HFLAG_B;
4342 break;
4343 case OPC_JR:
4344 ctx->hflags |= MIPS_HFLAG_BR;
4345 break;
4346 case OPC_JALR:
4347 blink = rt;
4348 ctx->hflags |= MIPS_HFLAG_BR;
4349 break;
4350 default:
4351 MIPS_INVAL("branch/jump");
4352 generate_exception_end(ctx, EXCP_RI);
4353 goto out;
4354 }
4355 } else {
4356 switch (opc) {
4357 case OPC_BEQ:
4358 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4359 goto not_likely;
4360 case OPC_BEQL:
4361 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4362 goto likely;
4363 case OPC_BNE:
4364 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4365 goto not_likely;
4366 case OPC_BNEL:
4367 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4368 goto likely;
4369 case OPC_BGEZ:
4370 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4371 goto not_likely;
4372 case OPC_BGEZL:
4373 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4374 goto likely;
4375 case OPC_BGEZAL:
4376 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4377 blink = 31;
4378 goto not_likely;
4379 case OPC_BGEZALL:
4380 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4381 blink = 31;
4382 goto likely;
4383 case OPC_BGTZ:
4384 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4385 goto not_likely;
4386 case OPC_BGTZL:
4387 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4388 goto likely;
4389 case OPC_BLEZ:
4390 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4391 goto not_likely;
4392 case OPC_BLEZL:
4393 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4394 goto likely;
4395 case OPC_BLTZ:
4396 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4397 goto not_likely;
4398 case OPC_BLTZL:
4399 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4400 goto likely;
4401 case OPC_BPOSGE32:
4402 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4403 goto not_likely;
4404 #if defined(TARGET_MIPS64)
4405 case OPC_BPOSGE64:
4406 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4407 goto not_likely;
4408 #endif
4409 case OPC_BLTZAL:
4410 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4411 blink = 31;
4412 not_likely:
4413 ctx->hflags |= MIPS_HFLAG_BC;
4414 break;
4415 case OPC_BLTZALL:
4416 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4417 blink = 31;
4418 likely:
4419 ctx->hflags |= MIPS_HFLAG_BL;
4420 break;
4421 default:
4422 MIPS_INVAL("conditional branch/jump");
4423 generate_exception_end(ctx, EXCP_RI);
4424 goto out;
4425 }
4426 }
4427
4428 ctx->btarget = btgt;
4429
4430 switch (delayslot_size) {
4431 case 2:
4432 ctx->hflags |= MIPS_HFLAG_BDS16;
4433 break;
4434 case 4:
4435 ctx->hflags |= MIPS_HFLAG_BDS32;
4436 break;
4437 }
4438
4439 if (blink > 0) {
4440 int post_delay = insn_bytes + delayslot_size;
4441 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4442
4443 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4444 }
4445
4446 out:
4447 if (insn_bytes == 2)
4448 ctx->hflags |= MIPS_HFLAG_B16;
4449 tcg_temp_free(t0);
4450 tcg_temp_free(t1);
4451 }
4452
4453 /* special3 bitfield operations */
4454 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4455 int rs, int lsb, int msb)
4456 {
4457 TCGv t0 = tcg_temp_new();
4458 TCGv t1 = tcg_temp_new();
4459
4460 gen_load_gpr(t1, rs);
4461 switch (opc) {
4462 case OPC_EXT:
4463 if (lsb + msb > 31) {
4464 goto fail;
4465 }
4466 tcg_gen_shri_tl(t0, t1, lsb);
4467 if (msb != 31) {
4468 tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1);
4469 } else {
4470 tcg_gen_ext32s_tl(t0, t0);
4471 }
4472 break;
4473 #if defined(TARGET_MIPS64)
4474 case OPC_DEXTU:
4475 lsb += 32;
4476 goto do_dext;
4477 case OPC_DEXTM:
4478 msb += 32;
4479 goto do_dext;
4480 case OPC_DEXT:
4481 do_dext:
4482 if (lsb + msb > 63) {
4483 goto fail;
4484 }
4485 tcg_gen_shri_tl(t0, t1, lsb);
4486 if (msb != 63) {
4487 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4488 }
4489 break;
4490 #endif
4491 case OPC_INS:
4492 if (lsb > msb) {
4493 goto fail;
4494 }
4495 gen_load_gpr(t0, rt);
4496 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4497 tcg_gen_ext32s_tl(t0, t0);
4498 break;
4499 #if defined(TARGET_MIPS64)
4500 case OPC_DINSU:
4501 lsb += 32;
4502 /* FALLTHRU */
4503 case OPC_DINSM:
4504 msb += 32;
4505 /* FALLTHRU */
4506 case OPC_DINS:
4507 if (lsb > msb) {
4508 goto fail;
4509 }
4510 gen_load_gpr(t0, rt);
4511 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4512 break;
4513 #endif
4514 default:
4515 fail:
4516 MIPS_INVAL("bitops");
4517 generate_exception_end(ctx, EXCP_RI);
4518 tcg_temp_free(t0);
4519 tcg_temp_free(t1);
4520 return;
4521 }
4522 gen_store_gpr(t0, rt);
4523 tcg_temp_free(t0);
4524 tcg_temp_free(t1);
4525 }
4526
4527 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4528 {
4529 TCGv t0;
4530
4531 if (rd == 0) {
4532 /* If no destination, treat it as a NOP. */
4533 return;
4534 }
4535
4536 t0 = tcg_temp_new();
4537 gen_load_gpr(t0, rt);
4538 switch (op2) {
4539 case OPC_WSBH:
4540 {
4541 TCGv t1 = tcg_temp_new();
4542
4543 tcg_gen_shri_tl(t1, t0, 8);
4544 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4545 tcg_gen_shli_tl(t0, t0, 8);
4546 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4547 tcg_gen_or_tl(t0, t0, t1);
4548 tcg_temp_free(t1);
4549 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4550 }
4551 break;
4552 case OPC_SEB:
4553 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4554 break;
4555 case OPC_SEH:
4556 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4557 break;
4558 #if defined(TARGET_MIPS64)
4559 case OPC_DSBH:
4560 {
4561 TCGv t1 = tcg_temp_new();
4562
4563 tcg_gen_shri_tl(t1, t0, 8);
4564 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4565 tcg_gen_shli_tl(t0, t0, 8);
4566 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4567 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4568 tcg_temp_free(t1);
4569 }
4570 break;
4571 case OPC_DSHD:
4572 {
4573 TCGv t1 = tcg_temp_new();
4574
4575 tcg_gen_shri_tl(t1, t0, 16);
4576 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4577 tcg_gen_shli_tl(t0, t0, 16);
4578 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4579 tcg_gen_or_tl(t0, t0, t1);
4580 tcg_gen_shri_tl(t1, t0, 32);
4581 tcg_gen_shli_tl(t0, t0, 32);
4582 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4583 tcg_temp_free(t1);
4584 }
4585 break;
4586 #endif
4587 default:
4588 MIPS_INVAL("bsfhl");
4589 generate_exception_end(ctx, EXCP_RI);
4590 tcg_temp_free(t0);
4591 return;
4592 }
4593 tcg_temp_free(t0);
4594 }
4595
4596 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
4597 int imm2)
4598 {
4599 TCGv t0;
4600 TCGv t1;
4601 if (rd == 0) {
4602 /* Treat as NOP. */
4603 return;
4604 }
4605 t0 = tcg_temp_new();
4606 t1 = tcg_temp_new();
4607 gen_load_gpr(t0, rs);
4608 gen_load_gpr(t1, rt);
4609 tcg_gen_shli_tl(t0, t0, imm2 + 1);
4610 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
4611 if (opc == OPC_LSA) {
4612 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4613 }
4614
4615 tcg_temp_free(t1);
4616 tcg_temp_free(t0);
4617
4618 return;
4619 }
4620
4621 static void gen_align(DisasContext *ctx, int opc, int rd, int rs, int rt,
4622 int bp)
4623 {
4624 TCGv t0;
4625 if (rd == 0) {
4626 /* Treat as NOP. */
4627 return;
4628 }
4629 t0 = tcg_temp_new();
4630 gen_load_gpr(t0, rt);
4631 if (bp == 0) {
4632 tcg_gen_mov_tl(cpu_gpr[rd], t0);
4633 } else {
4634 TCGv t1 = tcg_temp_new();
4635 gen_load_gpr(t1, rs);
4636 switch (opc) {
4637 case OPC_ALIGN:
4638 {
4639 TCGv_i64 t2 = tcg_temp_new_i64();
4640 tcg_gen_concat_tl_i64(t2, t1, t0);
4641 tcg_gen_shri_i64(t2, t2, 8 * (4 - bp));
4642 gen_move_low32(cpu_gpr[rd], t2);
4643 tcg_temp_free_i64(t2);
4644 }
4645 break;
4646 #if defined(TARGET_MIPS64)
4647 case OPC_DALIGN:
4648 tcg_gen_shli_tl(t0, t0, 8 * bp);
4649 tcg_gen_shri_tl(t1, t1, 8 * (8 - bp));
4650 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
4651 break;
4652 #endif
4653 }
4654 tcg_temp_free(t1);
4655 }
4656
4657 tcg_temp_free(t0);
4658 }
4659
4660 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
4661 {
4662 TCGv t0;
4663 if (rd == 0) {
4664 /* Treat as NOP. */
4665 return;
4666 }
4667 t0 = tcg_temp_new();
4668 gen_load_gpr(t0, rt);
4669 switch (opc) {
4670 case OPC_BITSWAP:
4671 gen_helper_bitswap(cpu_gpr[rd], t0);
4672 break;
4673 #if defined(TARGET_MIPS64)
4674 case OPC_DBITSWAP:
4675 gen_helper_dbitswap(cpu_gpr[rd], t0);
4676 break;
4677 #endif
4678 }
4679 tcg_temp_free(t0);
4680 }
4681
4682 #ifndef CONFIG_USER_ONLY
4683 /* CP0 (MMU and control) */
4684 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
4685 {
4686 TCGv_i64 t0 = tcg_temp_new_i64();
4687 TCGv_i64 t1 = tcg_temp_new_i64();
4688
4689 tcg_gen_ext_tl_i64(t0, arg);
4690 tcg_gen_ld_i64(t1, cpu_env, off);
4691 #if defined(TARGET_MIPS64)
4692 tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
4693 #else
4694 tcg_gen_concat32_i64(t1, t1, t0);
4695 #endif
4696 tcg_gen_st_i64(t1, cpu_env, off);
4697 tcg_temp_free_i64(t1);
4698 tcg_temp_free_i64(t0);
4699 }
4700
4701 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
4702 {
4703 TCGv_i64 t0 = tcg_temp_new_i64();
4704 TCGv_i64 t1 = tcg_temp_new_i64();
4705
4706 tcg_gen_ext_tl_i64(t0, arg);
4707 tcg_gen_ld_i64(t1, cpu_env, off);
4708 tcg_gen_concat32_i64(t1, t1, t0);
4709 tcg_gen_st_i64(t1, cpu_env, off);
4710 tcg_temp_free_i64(t1);
4711 tcg_temp_free_i64(t0);
4712 }
4713
4714 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
4715 {
4716 TCGv_i64 t0 = tcg_temp_new_i64();
4717
4718 tcg_gen_ld_i64(t0, cpu_env, off);
4719 #if defined(TARGET_MIPS64)
4720 tcg_gen_shri_i64(t0, t0, 30);
4721 #else
4722 tcg_gen_shri_i64(t0, t0, 32);
4723 #endif
4724 gen_move_low32(arg, t0);
4725 tcg_temp_free_i64(t0);
4726 }
4727
4728 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
4729 {
4730 TCGv_i64 t0 = tcg_temp_new_i64();
4731
4732 tcg_gen_ld_i64(t0, cpu_env, off);
4733 tcg_gen_shri_i64(t0, t0, 32 + shift);
4734 gen_move_low32(arg, t0);
4735 tcg_temp_free_i64(t0);
4736 }
4737
4738 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4739 {
4740 TCGv_i32 t0 = tcg_temp_new_i32();
4741
4742 tcg_gen_ld_i32(t0, cpu_env, off);
4743 tcg_gen_ext_i32_tl(arg, t0);
4744 tcg_temp_free_i32(t0);
4745 }
4746
4747 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4748 {
4749 tcg_gen_ld_tl(arg, cpu_env, off);
4750 tcg_gen_ext32s_tl(arg, arg);
4751 }
4752
4753 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4754 {
4755 TCGv_i32 t0 = tcg_temp_new_i32();
4756
4757 tcg_gen_trunc_tl_i32(t0, arg);
4758 tcg_gen_st_i32(t0, cpu_env, off);
4759 tcg_temp_free_i32(t0);
4760 }
4761
4762 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4763 {
4764 const char *rn = "invalid";
4765
4766 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4767 goto mfhc0_read_zero;
4768 }
4769
4770 switch (reg) {
4771 case 2:
4772 switch (sel) {
4773 case 0:
4774 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4775 rn = "EntryLo0";
4776 break;
4777 default:
4778 goto mfhc0_read_zero;
4779 }
4780 break;
4781 case 3:
4782 switch (sel) {
4783 case 0:
4784 gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4785 rn = "EntryLo1";
4786 break;
4787 default:
4788 goto mfhc0_read_zero;
4789 }
4790 break;
4791 case 17:
4792 switch (sel) {
4793 case 0:
4794 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
4795 ctx->CP0_LLAddr_shift);
4796 rn = "LLAddr";
4797 break;
4798 default:
4799 goto mfhc0_read_zero;
4800 }
4801 break;
4802 case 28:
4803 switch (sel) {
4804 case 0:
4805 case 2:
4806 case 4:
4807 case 6:
4808 gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
4809 rn = "TagLo";
4810 break;
4811 default:
4812 goto mfhc0_read_zero;
4813 }
4814 break;
4815 default:
4816 goto mfhc0_read_zero;
4817 }
4818
4819 (void)rn; /* avoid a compiler warning */
4820 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4821 return;
4822
4823 mfhc0_read_zero:
4824 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
4825 tcg_gen_movi_tl(arg, 0);
4826 }
4827
4828 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4829 {
4830 const char *rn = "invalid";
4831 uint64_t mask = ctx->PAMask >> 36;
4832
4833 if (!(ctx->hflags & MIPS_HFLAG_ELPA)) {
4834 goto mthc0_nop;
4835 }
4836
4837 switch (reg) {
4838 case 2:
4839 switch (sel) {
4840 case 0:
4841 tcg_gen_andi_tl(arg, arg, mask);
4842 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
4843 rn = "EntryLo0";
4844 break;
4845 default:
4846 goto mthc0_nop;
4847 }
4848 break;
4849 case 3:
4850 switch (sel) {
4851 case 0:
4852 tcg_gen_andi_tl(arg, arg, mask);
4853 gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
4854 rn = "EntryLo1";
4855 break;
4856 default:
4857 goto mthc0_nop;
4858 }
4859 break;
4860 case 17:
4861 switch (sel) {
4862 case 0:
4863 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4864 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4865 relevant for modern MIPS cores supporting MTHC0, therefore
4866 treating MTHC0 to LLAddr as NOP. */
4867 rn = "LLAddr";
4868 break;
4869 default:
4870 goto mthc0_nop;
4871 }
4872 break;
4873 case 28:
4874 switch (sel) {
4875 case 0:
4876 case 2:
4877 case 4:
4878 case 6:
4879 tcg_gen_andi_tl(arg, arg, mask);
4880 gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
4881 rn = "TagLo";
4882 break;
4883 default:
4884 goto mthc0_nop;
4885 }
4886 break;
4887 default:
4888 goto mthc0_nop;
4889 }
4890
4891 (void)rn; /* avoid a compiler warning */
4892 mthc0_nop:
4893 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
4894 }
4895
4896 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
4897 {
4898 if (ctx->insn_flags & ISA_MIPS32R6) {
4899 tcg_gen_movi_tl(arg, 0);
4900 } else {
4901 tcg_gen_movi_tl(arg, ~0);
4902 }
4903 }
4904
4905 #define CP0_CHECK(c) \
4906 do { \
4907 if (!(c)) { \
4908 goto cp0_unimplemented; \
4909 } \
4910 } while (0)
4911
4912 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4913 {
4914 const char *rn = "invalid";
4915
4916 if (sel != 0)
4917 check_insn(ctx, ISA_MIPS32);
4918
4919 switch (reg) {
4920 case 0:
4921 switch (sel) {
4922 case 0:
4923 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4924 rn = "Index";
4925 break;
4926 case 1:
4927 CP0_CHECK(ctx->insn_flags & ASE_MT);
4928 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4929 rn = "MVPControl";
4930 break;
4931 case 2:
4932 CP0_CHECK(ctx->insn_flags & ASE_MT);
4933 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4934 rn = "MVPConf0";
4935 break;
4936 case 3:
4937 CP0_CHECK(ctx->insn_flags & ASE_MT);
4938 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4939 rn = "MVPConf1";
4940 break;
4941 default:
4942 goto cp0_unimplemented;
4943 }
4944 break;
4945 case 1:
4946 switch (sel) {
4947 case 0:
4948 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
4949 gen_helper_mfc0_random(arg, cpu_env);
4950 rn = "Random";
4951 break;
4952 case 1:
4953 CP0_CHECK(ctx->insn_flags & ASE_MT);
4954 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4955 rn = "VPEControl";
4956 break;
4957 case 2:
4958 CP0_CHECK(ctx->insn_flags & ASE_MT);
4959 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4960 rn = "VPEConf0";
4961 break;
4962 case 3:
4963 CP0_CHECK(ctx->insn_flags & ASE_MT);
4964 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4965 rn = "VPEConf1";
4966 break;
4967 case 4:
4968 CP0_CHECK(ctx->insn_flags & ASE_MT);
4969 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4970 rn = "YQMask";
4971 break;
4972 case 5:
4973 CP0_CHECK(ctx->insn_flags & ASE_MT);
4974 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4975 rn = "VPESchedule";
4976 break;
4977 case 6:
4978 CP0_CHECK(ctx->insn_flags & ASE_MT);
4979 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4980 rn = "VPEScheFBack";
4981 break;
4982 case 7:
4983 CP0_CHECK(ctx->insn_flags & ASE_MT);
4984 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4985 rn = "VPEOpt";
4986 break;
4987 default:
4988 goto cp0_unimplemented;
4989 }
4990 break;
4991 case 2:
4992 switch (sel) {
4993 case 0:
4994 {
4995 TCGv_i64 tmp = tcg_temp_new_i64();
4996 tcg_gen_ld_i64(tmp, cpu_env,
4997 offsetof(CPUMIPSState, CP0_EntryLo0));
4998 #if defined(TARGET_MIPS64)
4999 if (ctx->rxi) {
5000 /* Move RI/XI fields to bits 31:30 */
5001 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5002 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5003 }
5004 #endif
5005 gen_move_low32(arg, tmp);
5006 tcg_temp_free_i64(tmp);
5007 }
5008 rn = "EntryLo0";
5009 break;
5010 case 1:
5011 CP0_CHECK(ctx->insn_flags & ASE_MT);
5012 gen_helper_mfc0_tcstatus(arg, cpu_env);
5013 rn = "TCStatus";
5014 break;
5015 case 2:
5016 CP0_CHECK(ctx->insn_flags & ASE_MT);
5017 gen_helper_mfc0_tcbind(arg, cpu_env);
5018 rn = "TCBind";
5019 break;
5020 case 3:
5021 CP0_CHECK(ctx->insn_flags & ASE_MT);
5022 gen_helper_mfc0_tcrestart(arg, cpu_env);
5023 rn = "TCRestart";
5024 break;
5025 case 4:
5026 CP0_CHECK(ctx->insn_flags & ASE_MT);
5027 gen_helper_mfc0_tchalt(arg, cpu_env);
5028 rn = "TCHalt";
5029 break;
5030 case 5:
5031 CP0_CHECK(ctx->insn_flags & ASE_MT);
5032 gen_helper_mfc0_tccontext(arg, cpu_env);
5033 rn = "TCContext";
5034 break;
5035 case 6:
5036 CP0_CHECK(ctx->insn_flags & ASE_MT);
5037 gen_helper_mfc0_tcschedule(arg, cpu_env);
5038 rn = "TCSchedule";
5039 break;
5040 case 7:
5041 CP0_CHECK(ctx->insn_flags & ASE_MT);
5042 gen_helper_mfc0_tcschefback(arg, cpu_env);
5043 rn = "TCScheFBack";
5044 break;
5045 default:
5046 goto cp0_unimplemented;
5047 }
5048 break;
5049 case 3:
5050 switch (sel) {
5051 case 0:
5052 {
5053 TCGv_i64 tmp = tcg_temp_new_i64();
5054 tcg_gen_ld_i64(tmp, cpu_env,
5055 offsetof(CPUMIPSState, CP0_EntryLo1));
5056 #if defined(TARGET_MIPS64)
5057 if (ctx->rxi) {
5058 /* Move RI/XI fields to bits 31:30 */
5059 tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5060 tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5061 }
5062 #endif
5063 gen_move_low32(arg, tmp);
5064 tcg_temp_free_i64(tmp);
5065 }
5066 rn = "EntryLo1";
5067 break;
5068 default:
5069 goto cp0_unimplemented;
5070 }
5071 break;
5072 case 4:
5073 switch (sel) {
5074 case 0:
5075 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5076 tcg_gen_ext32s_tl(arg, arg);
5077 rn = "Context";
5078 break;
5079 case 1:
5080 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5081 rn = "ContextConfig";
5082 goto cp0_unimplemented;
5083 // break;
5084 case 2:
5085 CP0_CHECK(ctx->ulri);
5086 tcg_gen_ld32s_tl(arg, cpu_env,
5087 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5088 rn = "UserLocal";
5089 break;
5090 default:
5091 goto cp0_unimplemented;
5092 }
5093 break;
5094 case 5:
5095 switch (sel) {
5096 case 0:
5097 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5098 rn = "PageMask";
5099 break;
5100 case 1:
5101 check_insn(ctx, ISA_MIPS32R2);
5102 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5103 rn = "PageGrain";
5104 break;
5105 default:
5106 goto cp0_unimplemented;
5107 }
5108 break;
5109 case 6:
5110 switch (sel) {
5111 case 0:
5112 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5113 rn = "Wired";
5114 break;
5115 case 1:
5116 check_insn(ctx, ISA_MIPS32R2);
5117 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5118 rn = "SRSConf0";
5119 break;
5120 case 2:
5121 check_insn(ctx, ISA_MIPS32R2);
5122 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5123 rn = "SRSConf1";
5124 break;
5125 case 3:
5126 check_insn(ctx, ISA_MIPS32R2);
5127 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5128 rn = "SRSConf2";
5129 break;
5130 case 4:
5131 check_insn(ctx, ISA_MIPS32R2);
5132 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5133 rn = "SRSConf3";
5134 break;
5135 case 5:
5136 check_insn(ctx, ISA_MIPS32R2);
5137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5138 rn = "SRSConf4";
5139 break;
5140 default:
5141 goto cp0_unimplemented;
5142 }
5143 break;
5144 case 7:
5145 switch (sel) {
5146 case 0:
5147 check_insn(ctx, ISA_MIPS32R2);
5148 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5149 rn = "HWREna";
5150 break;
5151 default:
5152 goto cp0_unimplemented;
5153 }
5154 break;
5155 case 8:
5156 switch (sel) {
5157 case 0:
5158 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5159 tcg_gen_ext32s_tl(arg, arg);
5160 rn = "BadVAddr";
5161 break;
5162 case 1:
5163 CP0_CHECK(ctx->bi);
5164 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5165 rn = "BadInstr";
5166 break;
5167 case 2:
5168 CP0_CHECK(ctx->bp);
5169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5170 rn = "BadInstrP";
5171 break;
5172 default:
5173 goto cp0_unimplemented;
5174 }
5175 break;
5176 case 9:
5177 switch (sel) {
5178 case 0:
5179 /* Mark as an IO operation because we read the time. */
5180 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5181 gen_io_start();
5182 }
5183 gen_helper_mfc0_count(arg, cpu_env);
5184 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5185 gen_io_end();
5186 }
5187 /* Break the TB to be able to take timer interrupts immediately
5188 after reading count. */
5189 ctx->bstate = BS_STOP;
5190 rn = "Count";
5191 break;
5192 /* 6,7 are implementation dependent */
5193 default:
5194 goto cp0_unimplemented;
5195 }
5196 break;
5197 case 10:
5198 switch (sel) {
5199 case 0:
5200 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5201 tcg_gen_ext32s_tl(arg, arg);
5202 rn = "EntryHi";
5203 break;
5204 default:
5205 goto cp0_unimplemented;
5206 }
5207 break;
5208 case 11:
5209 switch (sel) {
5210 case 0:
5211 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5212 rn = "Compare";
5213 break;
5214 /* 6,7 are implementation dependent */
5215 default:
5216 goto cp0_unimplemented;
5217 }
5218 break;
5219 case 12:
5220 switch (sel) {
5221 case 0:
5222 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5223 rn = "Status";
5224 break;
5225 case 1:
5226 check_insn(ctx, ISA_MIPS32R2);
5227 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5228 rn = "IntCtl";
5229 break;
5230 case 2:
5231 check_insn(ctx, ISA_MIPS32R2);
5232 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5233 rn = "SRSCtl";
5234 break;
5235 case 3:
5236 check_insn(ctx, ISA_MIPS32R2);
5237 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5238 rn = "SRSMap";
5239 break;
5240 default:
5241 goto cp0_unimplemented;
5242 }
5243 break;
5244 case 13:
5245 switch (sel) {
5246 case 0:
5247 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5248 rn = "Cause";
5249 break;
5250 default:
5251 goto cp0_unimplemented;
5252 }
5253 break;
5254 case 14:
5255 switch (sel) {
5256 case 0:
5257 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5258 tcg_gen_ext32s_tl(arg, arg);
5259 rn = "EPC";
5260 break;
5261 default:
5262 goto cp0_unimplemented;
5263 }
5264 break;
5265 case 15:
5266 switch (sel) {
5267 case 0:
5268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5269 rn = "PRid";
5270 break;
5271 case 1:
5272 check_insn(ctx, ISA_MIPS32R2);
5273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5274 rn = "EBase";
5275 break;
5276 default:
5277 goto cp0_unimplemented;
5278 }
5279 break;
5280 case 16:
5281 switch (sel) {
5282 case 0:
5283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5284 rn = "Config";
5285 break;
5286 case 1:
5287 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5288 rn = "Config1";
5289 break;
5290 case 2:
5291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5292 rn = "Config2";
5293 break;
5294 case 3:
5295 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5296 rn = "Config3";
5297 break;
5298 case 4:
5299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
5300 rn = "Config4";
5301 break;
5302 case 5:
5303 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
5304 rn = "Config5";
5305 break;
5306 /* 6,7 are implementation dependent */
5307 case 6:
5308 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5309 rn = "Config6";
5310 break;
5311 case 7:
5312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5313 rn = "Config7";
5314 break;
5315 default:
5316 goto cp0_unimplemented;
5317 }
5318 break;
5319 case 17:
5320 switch (sel) {
5321 case 0:
5322 gen_helper_mfc0_lladdr(arg, cpu_env);
5323 rn = "LLAddr";
5324 break;
5325 default:
5326 goto cp0_unimplemented;
5327 }
5328 break;
5329 case 18:
5330 switch (sel) {
5331 case 0 ... 7:
5332 gen_helper_1e0i(mfc0_watchlo, arg, sel);
5333 rn = "WatchLo";
5334 break;
5335 default:
5336 goto cp0_unimplemented;
5337 }
5338 break;
5339 case 19:
5340 switch (sel) {
5341 case 0 ...7:
5342 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5343 rn = "WatchHi";
5344 break;
5345 default:
5346 goto cp0_unimplemented;
5347 }
5348 break;
5349 case 20:
5350 switch (sel) {
5351 case 0:
5352 #if defined(TARGET_MIPS64)
5353 check_insn(ctx, ISA_MIPS3);
5354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5355 tcg_gen_ext32s_tl(arg, arg);
5356 rn = "XContext";
5357 break;
5358 #endif
5359 default:
5360 goto cp0_unimplemented;
5361 }
5362 break;
5363 case 21:
5364 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5365 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5366 switch (sel) {
5367 case 0:
5368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5369 rn = "Framemask";
5370 break;
5371 default:
5372 goto cp0_unimplemented;
5373 }
5374 break;
5375 case 22:
5376 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5377 rn = "'Diagnostic"; /* implementation dependent */
5378 break;
5379 case 23:
5380 switch (sel) {
5381 case 0:
5382 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5383 rn = "Debug";
5384 break;
5385 case 1:
5386 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5387 rn = "TraceControl";
5388 // break;
5389 case 2:
5390 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5391 rn = "TraceControl2";
5392 // break;
5393 case 3:
5394 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5395 rn = "UserTraceData";
5396 // break;
5397 case 4:
5398 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5399 rn = "TraceBPC";
5400 // break;
5401 default:
5402 goto cp0_unimplemented;
5403 }
5404 break;
5405 case 24:
5406 switch (sel) {
5407 case 0:
5408 /* EJTAG support */
5409 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5410 tcg_gen_ext32s_tl(arg, arg);
5411 rn = "DEPC";
5412 break;
5413 default:
5414 goto cp0_unimplemented;
5415 }
5416 break;
5417 case 25:
5418 switch (sel) {
5419 case 0:
5420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5421 rn = "Performance0";
5422 break;
5423 case 1:
5424 // gen_helper_mfc0_performance1(arg);
5425 rn = "Performance1";
5426 // break;
5427 case 2:
5428 // gen_helper_mfc0_performance2(arg);
5429 rn = "Performance2";
5430 // break;
5431 case 3:
5432 // gen_helper_mfc0_performance3(arg);
5433 rn = "Performance3";
5434 // break;
5435 case 4:
5436 // gen_helper_mfc0_performance4(arg);
5437 rn = "Performance4";
5438 // break;
5439 case 5:
5440 // gen_helper_mfc0_performance5(arg);
5441 rn = "Performance5";
5442 // break;
5443 case 6:
5444 // gen_helper_mfc0_performance6(arg);
5445 rn = "Performance6";
5446 // break;
5447 case 7:
5448 // gen_helper_mfc0_performance7(arg);
5449 rn = "Performance7";
5450 // break;
5451 default:
5452 goto cp0_unimplemented;
5453 }
5454 break;
5455 case 26:
5456 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5457 rn = "ECC";
5458 break;
5459 case 27:
5460 switch (sel) {
5461 case 0 ... 3:
5462 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5463 rn = "CacheErr";
5464 break;
5465 default:
5466 goto cp0_unimplemented;
5467 }
5468 break;
5469 case 28:
5470 switch (sel) {
5471 case 0:
5472 case 2:
5473 case 4:
5474 case 6:
5475 {
5476 TCGv_i64 tmp = tcg_temp_new_i64();
5477 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
5478 gen_move_low32(arg, tmp);
5479 tcg_temp_free_i64(tmp);
5480 }
5481 rn = "TagLo";
5482 break;
5483 case 1:
5484 case 3:
5485 case 5:
5486 case 7:
5487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5488 rn = "DataLo";
5489 break;
5490 default:
5491 goto cp0_unimplemented;
5492 }
5493 break;
5494 case 29:
5495 switch (sel) {
5496 case 0:
5497 case 2:
5498 case 4:
5499 case 6:
5500 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5501 rn = "TagHi";
5502 break;
5503 case 1:
5504 case 3:
5505 case 5:
5506 case 7:
5507 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5508 rn = "DataHi";
5509 break;
5510 default:
5511 goto cp0_unimplemented;
5512 }
5513 break;
5514 case 30:
5515 switch (sel) {
5516 case 0:
5517 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5518 tcg_gen_ext32s_tl(arg, arg);
5519 rn = "ErrorEPC";
5520 break;
5521 default:
5522 goto cp0_unimplemented;
5523 }
5524 break;
5525 case 31:
5526 switch (sel) {
5527 case 0:
5528 /* EJTAG support */
5529 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5530 rn = "DESAVE";
5531 break;
5532 case 2 ... 7:
5533 CP0_CHECK(ctx->kscrexist & (1 << sel));
5534 tcg_gen_ld_tl(arg, cpu_env,
5535 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
5536 tcg_gen_ext32s_tl(arg, arg);
5537 rn = "KScratch";
5538 break;
5539 default:
5540 goto cp0_unimplemented;
5541 }
5542 break;
5543 default:
5544 goto cp0_unimplemented;
5545 }
5546 (void)rn; /* avoid a compiler warning */
5547 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5548 return;
5549
5550 cp0_unimplemented:
5551 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5552 gen_mfc0_unimplemented(ctx, arg);
5553 }
5554
5555 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5556 {
5557 const char *rn = "invalid";
5558
5559 if (sel != 0)
5560 check_insn(ctx, ISA_MIPS32);
5561
5562 if (ctx->tb->cflags & CF_USE_ICOUNT) {
5563 gen_io_start();
5564 }
5565
5566 switch (reg) {
5567 case 0:
5568 switch (sel) {
5569 case 0:
5570 gen_helper_mtc0_index(cpu_env, arg);
5571 rn = "Index";
5572 break;
5573 case 1:
5574 CP0_CHECK(ctx->insn_flags & ASE_MT);
5575 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5576 rn = "MVPControl";
5577 break;
5578 case 2:
5579 CP0_CHECK(ctx->insn_flags & ASE_MT);
5580 /* ignored */
5581 rn = "MVPConf0";
5582 break;
5583 case 3:
5584 CP0_CHECK(ctx->insn_flags & ASE_MT);
5585 /* ignored */
5586 rn = "MVPConf1";
5587 break;
5588 default:
5589 goto cp0_unimplemented;
5590 }
5591 break;
5592 case 1:
5593 switch (sel) {
5594 case 0:
5595 /* ignored */
5596 rn = "Random";
5597 break;
5598 case 1:
5599 CP0_CHECK(ctx->insn_flags & ASE_MT);
5600 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5601 rn = "VPEControl";
5602 break;
5603 case 2:
5604 CP0_CHECK(ctx->insn_flags & ASE_MT);
5605 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5606 rn = "VPEConf0";
5607 break;
5608 case 3:
5609 CP0_CHECK(ctx->insn_flags & ASE_MT);
5610 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5611 rn = "VPEConf1";
5612 break;
5613 case 4:
5614 CP0_CHECK(ctx->insn_flags & ASE_MT);
5615 gen_helper_mtc0_yqmask(cpu_env, arg);
5616 rn = "YQMask";
5617 break;
5618 case 5:
5619 CP0_CHECK(ctx->insn_flags & ASE_MT);
5620 tcg_gen_st_tl(arg, cpu_env,
5621 offsetof(CPUMIPSState, CP0_VPESchedule));
5622 rn = "VPESchedule";
5623 break;
5624 case 6:
5625 CP0_CHECK(ctx->insn_flags & ASE_MT);
5626 tcg_gen_st_tl(arg, cpu_env,
5627 offsetof(CPUMIPSState, CP0_VPEScheFBack));
5628 rn = "VPEScheFBack";
5629 break;
5630 case 7:
5631 CP0_CHECK(ctx->insn_flags & ASE_MT);
5632 gen_helper_mtc0_vpeopt(cpu_env, arg);
5633 rn = "VPEOpt";
5634 break;
5635 default:
5636 goto cp0_unimplemented;
5637 }
5638 break;
5639 case 2:
5640 switch (sel) {
5641 case 0:
5642 gen_helper_mtc0_entrylo0(cpu_env, arg);
5643 rn = "EntryLo0";
5644 break;
5645 case 1:
5646 CP0_CHECK(ctx->insn_flags & ASE_MT);
5647 gen_helper_mtc0_tcstatus(cpu_env, arg);
5648 rn = "TCStatus";
5649 break;
5650 case 2:
5651 CP0_CHECK(ctx->insn_flags & ASE_MT);
5652 gen_helper_mtc0_tcbind(cpu_env, arg);
5653 rn = "TCBind";
5654 break;
5655 case 3:
5656 CP0_CHECK(ctx->insn_flags & ASE_MT);
5657 gen_helper_mtc0_tcrestart(cpu_env, arg);
5658 rn = "TCRestart";
5659 break;
5660 case 4:
5661 CP0_CHECK(ctx->insn_flags & ASE_MT);
5662 gen_helper_mtc0_tchalt(cpu_env, arg);
5663 rn = "TCHalt";
5664 break;
5665 case 5:
5666 CP0_CHECK(ctx->insn_flags & ASE_MT);
5667 gen_helper_mtc0_tccontext(cpu_env, arg);
5668 rn = "TCContext";
5669 break;
5670 case 6:
5671 CP0_CHECK(ctx->insn_flags & ASE_MT);
5672 gen_helper_mtc0_tcschedule(cpu_env, arg);
5673 rn = "TCSchedule";
5674 break;
5675 case 7:
5676 CP0_CHECK(ctx->insn_flags & ASE_MT);
5677 gen_helper_mtc0_tcschefback(cpu_env, arg);
5678 rn = "TCScheFBack";
5679 break;
5680 default:
5681 goto cp0_unimplemented;
5682 }
5683 break;
5684 case 3:
5685 switch (sel) {
5686 case 0:
5687 gen_helper_mtc0_entrylo1(cpu_env, arg);
5688 rn = "EntryLo1";
5689 break;
5690 default:
5691 goto cp0_unimplemented;
5692 }
5693 break;
5694 case 4:
5695 switch (sel) {
5696 case 0:
5697 gen_helper_mtc0_context(cpu_env, arg);
5698 rn = "Context";
5699 break;
5700 case 1:
5701 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5702 rn = "ContextConfig";
5703 goto cp0_unimplemented;
5704 // break;
5705 case 2:
5706 CP0_CHECK(ctx->ulri);
5707 tcg_gen_st_tl(arg, cpu_env,
5708 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5709 rn = "UserLocal";
5710 break;
5711 default:
5712 goto cp0_unimplemented;
5713 }
5714 break;
5715 case 5:
5716 switch (sel) {
5717 case 0:
5718 gen_helper_mtc0_pagemask(cpu_env, arg);
5719 rn = "PageMask";
5720 break;
5721 case 1:
5722 check_insn(ctx, ISA_MIPS32R2);
5723 gen_helper_mtc0_pagegrain(cpu_env, arg);
5724 rn = "PageGrain";
5725 ctx->bstate = BS_STOP;
5726 break;
5727 default:
5728 goto cp0_unimplemented;
5729 }
5730 break;
5731 case 6:
5732 switch (sel) {
5733 case 0:
5734 gen_helper_mtc0_wired(cpu_env, arg);
5735 rn = "Wired";
5736 break;
5737 case 1:
5738 check_insn(ctx, ISA_MIPS32R2);
5739 gen_helper_mtc0_srsconf0(cpu_env, arg);
5740 rn = "SRSConf0";
5741 break;
5742 case 2:
5743 check_insn(ctx, ISA_MIPS32R2);
5744 gen_helper_mtc0_srsconf1(cpu_env, arg);
5745 rn = "SRSConf1";
5746 break;
5747 case 3:
5748 check_insn(ctx, ISA_MIPS32R2);
5749 gen_helper_mtc0_srsconf2(cpu_env, arg);
5750 rn = "SRSConf2";
5751 break;
5752 case 4:
5753 check_insn(ctx, ISA_MIPS32R2);
5754 gen_helper_mtc0_srsconf3(cpu_env, arg);
5755 rn = "SRSConf3";
5756 break;
5757 case 5:
5758 check_insn(ctx, ISA_MIPS32R2);
5759 gen_helper_mtc0_srsconf4(cpu_env, arg);
5760 rn = "SRSConf4";
5761 break;
5762 default:
5763 goto cp0_unimplemented;
5764 }
5765 break;
5766 case 7:
5767 switch (sel) {
5768 case 0:
5769 check_insn(ctx, ISA_MIPS32R2);
5770 gen_helper_mtc0_hwrena(cpu_env, arg);
5771 ctx->bstate = BS_STOP;
5772 rn = "HWREna";
5773 break;
5774 default:
5775 goto cp0_unimplemented;
5776 }
5777 break;
5778 case 8:
5779 switch (sel) {
5780 case 0:
5781 /* ignored */
5782 rn = "BadVAddr";
5783 break;
5784 case 1:
5785 /* ignored */
5786 rn = "BadInstr";
5787 break;
5788 case 2:
5789 /* ignored */
5790 rn = "BadInstrP";
5791 break;
5792 default:
5793 goto cp0_unimplemented;
5794 }
5795 break;
5796 case 9:
5797 switch (sel) {
5798 case 0:
5799 gen_helper_mtc0_count(cpu_env, arg);
5800 rn = "Count";
5801 break;
5802 /* 6,7 are implementation dependent */
5803 default:
5804 goto cp0_unimplemented;
5805 }
5806 break;
5807 case 10:
5808 switch (sel) {
5809 case 0:
5810 gen_helper_mtc0_entryhi(cpu_env, arg);
5811 rn = "EntryHi";
5812 break;
5813 default:
5814 goto cp0_unimplemented;
5815 }
5816 break;
5817 case 11:
5818 switch (sel) {
5819 case 0:
5820 gen_helper_mtc0_compare(cpu_env, arg);
5821 rn = "Compare";
5822 break;
5823 /* 6,7 are implementation dependent */
5824 default:
5825 goto cp0_unimplemented;
5826 }
5827 break;
5828 case 12:
5829 switch (sel) {
5830 case 0:
5831 save_cpu_state(ctx, 1);
5832 gen_helper_mtc0_status(cpu_env, arg);
5833 /* BS_STOP isn't good enough here, hflags may have changed. */
5834 gen_save_pc(ctx->pc + 4);
5835 ctx->bstate = BS_EXCP;
5836 rn = "Status";
5837 break;
5838 case 1:
5839 check_insn(ctx, ISA_MIPS32R2);
5840 gen_helper_mtc0_intctl(cpu_env, arg);
5841 /* Stop translation as we may have switched the execution mode */
5842 ctx->bstate = BS_STOP;
5843 rn = "IntCtl";
5844 break;
5845 case 2:
5846 check_insn(ctx, ISA_MIPS32R2);
5847 gen_helper_mtc0_srsctl(cpu_env, arg);
5848 /* Stop translation as we may have switched the execution mode */
5849 ctx->bstate = BS_STOP;
5850 rn = "SRSCtl";
5851 break;
5852 case 3:
5853 check_insn(ctx, ISA_MIPS32R2);
5854 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5855 /* Stop translation as we may have switched the execution mode */
5856 ctx->bstate = BS_STOP;
5857 rn = "SRSMap";
5858 break;
5859 default:
5860 goto cp0_unimplemented;
5861 }
5862 break;
5863 case 13:
5864 switch (sel) {
5865 case 0:
5866 save_cpu_state(ctx, 1);
5867 gen_helper_mtc0_cause(cpu_env, arg);
5868 rn = "Cause";
5869 break;
5870 default:
5871 goto cp0_unimplemented;
5872 }
5873 break;
5874 case 14:
5875 switch (sel) {
5876 case 0:
5877 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5878 rn = "EPC";
5879 break;
5880 default:
5881 goto cp0_unimplemented;
5882 }
5883 break;
5884 case 15:
5885 switch (sel) {
5886 case 0:
5887 /* ignored */
5888 rn = "PRid";
5889 break;
5890 case 1:
5891 check_insn(ctx, ISA_MIPS32R2);
5892 gen_helper_mtc0_ebase(cpu_env, arg);
5893 rn = "EBase";
5894 break;
5895 default:
5896 goto cp0_unimplemented;
5897 }
5898 break;
5899 case 16:
5900 switch (sel) {
5901 case 0:
5902 gen_helper_mtc0_config0(cpu_env, arg);
5903 rn = "Config";
5904 /* Stop translation as we may have switched the execution mode */
5905 ctx->bstate = BS_STOP;
5906 break;
5907 case 1:
5908 /* ignored, read only */
5909 rn = "Config1";
5910 break;
5911 case 2:
5912 gen_helper_mtc0_config2(cpu_env, arg);
5913 rn = "Config2";
5914 /* Stop translation as we may have switched the execution mode */
5915 ctx->bstate = BS_STOP;
5916 break;
5917 case 3:
5918 gen_helper_mtc0_config3(cpu_env, arg);
5919 rn = "Config3";
5920 /* Stop translation as we may have switched the execution mode */
5921 ctx->bstate = BS_STOP;
5922 break;
5923 case 4:
5924 gen_helper_mtc0_config4(cpu_env, arg);
5925 rn = "Config4";
5926 ctx->bstate = BS_STOP;
5927 break;
5928 case 5:
5929 gen_helper_mtc0_config5(cpu_env, arg);
5930 rn = "Config5";
5931 /* Stop translation as we may have switched the execution mode */
5932 ctx->bstate = BS_STOP;
5933 break;
5934 /* 6,7 are implementation dependent */
5935 case 6:
5936 /* ignored */
5937 rn = "Config6";
5938 break;
5939 case 7:
5940 /* ignored */
5941 rn = "Config7";
5942 break;
5943 default:
5944 rn = "Invalid config selector";
5945 goto cp0_unimplemented;
5946 }
5947 break;
5948 case 17:
5949 switch (sel) {
5950 case 0:
5951 gen_helper_mtc0_lladdr(cpu_env, arg);
5952 rn = "LLAddr";
5953 break;
5954 default:
5955 goto cp0_unimplemented;
5956 }
5957 break;
5958 case 18:
5959 switch (sel) {
5960 case 0 ... 7:
5961 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5962 rn = "WatchLo";
5963 break;
5964 default:
5965 goto cp0_unimplemented;
5966 }
5967 break;
5968 case 19:
5969 switch (sel) {
5970 case 0 ... 7:
5971 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5972 rn = "WatchHi";
5973 break;
5974 default:
5975 goto cp0_unimplemented;
5976 }
5977 break;
5978 case 20:
5979 switch (sel) {
5980 case 0:
5981 #if defined(TARGET_MIPS64)
5982 check_insn(ctx, ISA_MIPS3);
5983 gen_helper_mtc0_xcontext(cpu_env, arg);
5984 rn = "XContext";
5985 break;
5986 #endif
5987 default:
5988 goto cp0_unimplemented;
5989 }
5990 break;
5991 case 21:
5992 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5993 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5994 switch (sel) {
5995 case 0:
5996 gen_helper_mtc0_framemask(cpu_env, arg);
5997 rn = "Framemask";
5998 break;
5999 default:
6000 goto cp0_unimplemented;
6001 }
6002 break;
6003 case 22:
6004 /* ignored */
6005 rn = "Diagnostic"; /* implementation dependent */
6006 break;
6007 case 23:
6008 switch (sel) {
6009 case 0:
6010 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6011 /* BS_STOP isn't good enough here, hflags may have changed. */
6012 gen_save_pc(ctx->pc + 4);
6013 ctx->bstate = BS_EXCP;
6014 rn = "Debug";
6015 break;
6016 case 1:
6017 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6018 rn = "TraceControl";
6019 /* Stop translation as we may have switched the execution mode */
6020 ctx->bstate = BS_STOP;
6021 // break;
6022 case 2:
6023 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6024 rn = "TraceControl2";
6025 /* Stop translation as we may have switched the execution mode */
6026 ctx->bstate = BS_STOP;
6027 // break;
6028 case 3:
6029 /* Stop translation as we may have switched the execution mode */
6030 ctx->bstate = BS_STOP;
6031 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6032 rn = "UserTraceData";
6033 /* Stop translation as we may have switched the execution mode */
6034 ctx->bstate = BS_STOP;
6035 // break;
6036 case 4:
6037 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6038 /* Stop translation as we may have switched the execution mode */
6039 ctx->bstate = BS_STOP;
6040 rn = "TraceBPC";
6041 // break;
6042 default:
6043 goto cp0_unimplemented;
6044 }
6045 break;
6046 case 24:
6047 switch (sel) {
6048 case 0:
6049 /* EJTAG support */
6050 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6051 rn = "DEPC";
6052 break;
6053 default:
6054 goto cp0_unimplemented;
6055 }
6056 break;
6057 case 25:
6058 switch (sel) {
6059 case 0:
6060 gen_helper_mtc0_performance0(cpu_env, arg);
6061 rn = "Performance0";
6062 break;
6063 case 1:
6064 // gen_helper_mtc0_performance1(arg);
6065 rn = "Performance1";
6066 // break;
6067 case 2:
6068 // gen_helper_mtc0_performance2(arg);
6069 rn = "Performance2";
6070 // break;
6071 case 3:
6072 // gen_helper_mtc0_performance3(arg);
6073 rn = "Performance3";
6074 // break;
6075 case 4:
6076 // gen_helper_mtc0_performance4(arg);
6077 rn = "Performance4";
6078 // break;
6079 case 5:
6080 // gen_helper_mtc0_performance5(arg);
6081 rn = "Performance5";
6082 // break;
6083 case 6:
6084 // gen_helper_mtc0_performance6(arg);
6085 rn = "Performance6";
6086 // break;
6087 case 7:
6088 // gen_helper_mtc0_performance7(arg);
6089 rn = "Performance7";
6090 // break;
6091 default:
6092 goto cp0_unimplemented;
6093 }
6094 break;
6095 case 26:
6096 /* ignored */
6097 rn = "ECC";
6098 break;
6099 case 27:
6100 switch (sel) {
6101 case 0 ... 3:
6102 /* ignored */
6103 rn = "CacheErr";
6104 break;
6105 default:
6106 goto cp0_unimplemented;
6107 }
6108 break;
6109 case 28:
6110 switch (sel) {
6111 case 0:
6112 case 2:
6113 case 4:
6114 case 6:
6115 gen_helper_mtc0_taglo(cpu_env, arg);
6116 rn = "TagLo";
6117 break;
6118 case 1:
6119 case 3:
6120 case 5:
6121 case 7:
6122 gen_helper_mtc0_datalo(cpu_env, arg);
6123 rn = "DataLo";
6124 break;
6125 default:
6126 goto cp0_unimplemented;
6127 }
6128 break;
6129 case 29:
6130 switch (sel) {
6131 case 0:
6132 case 2:
6133 case 4:
6134 case 6:
6135 gen_helper_mtc0_taghi(cpu_env, arg);
6136 rn = "TagHi";
6137 break;
6138 case 1:
6139 case 3:
6140 case 5:
6141 case 7:
6142 gen_helper_mtc0_datahi(cpu_env, arg);
6143 rn = "DataHi";
6144 break;
6145 default:
6146 rn = "invalid sel";
6147 goto cp0_unimplemented;
6148 }
6149 break;
6150 case 30:
6151 switch (sel) {
6152 case 0:
6153 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6154 rn = "ErrorEPC";
6155 break;
6156 default:
6157 goto cp0_unimplemented;
6158 }
6159 break;
6160 case 31:
6161 switch (sel) {
6162 case 0:
6163 /* EJTAG support */
6164 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6165 rn = "DESAVE";
6166 break;
6167 case 2 ... 7:
6168 CP0_CHECK(ctx->kscrexist & (1 << sel));
6169 tcg_gen_st_tl(arg, cpu_env,
6170 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6171 rn = "KScratch";
6172 break;
6173 default:
6174 goto cp0_unimplemented;
6175 }
6176 /* Stop translation as we may have switched the execution mode */
6177 ctx->bstate = BS_STOP;
6178 break;
6179 default:
6180 goto cp0_unimplemented;
6181 }
6182 (void)rn; /* avoid a compiler warning */
6183 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6184 /* For simplicity assume that all writes can cause interrupts. */
6185 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6186 gen_io_end();
6187 ctx->bstate = BS_STOP;
6188 }
6189 return;
6190
6191 cp0_unimplemented:
6192 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6193 }
6194
6195 #if defined(TARGET_MIPS64)
6196 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6197 {
6198 const char *rn = "invalid";
6199
6200 if (sel != 0)
6201 check_insn(ctx, ISA_MIPS64);
6202
6203 switch (reg) {
6204 case 0:
6205 switch (sel) {
6206 case 0:
6207 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6208 rn = "Index";
6209 break;
6210 case 1:
6211 CP0_CHECK(ctx->insn_flags & ASE_MT);
6212 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6213 rn = "MVPControl";
6214 break;
6215 case 2:
6216 CP0_CHECK(ctx->insn_flags & ASE_MT);
6217 gen_helper_mfc0_mvpconf0(arg, cpu_env);
6218 rn = "MVPConf0";
6219 break;
6220 case 3:
6221 CP0_CHECK(ctx->insn_flags & ASE_MT);
6222 gen_helper_mfc0_mvpconf1(arg, cpu_env);
6223 rn = "MVPConf1";
6224 break;
6225 default:
6226 goto cp0_unimplemented;
6227 }
6228 break;
6229 case 1:
6230 switch (sel) {
6231 case 0:
6232 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6233 gen_helper_mfc0_random(arg, cpu_env);
6234 rn = "Random";
6235 break;
6236 case 1:
6237 CP0_CHECK(ctx->insn_flags & ASE_MT);
6238 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6239 rn = "VPEControl";
6240 break;
6241 case 2:
6242 CP0_CHECK(ctx->insn_flags & ASE_MT);
6243 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6244 rn = "VPEConf0";
6245 break;
6246 case 3:
6247 CP0_CHECK(ctx->insn_flags & ASE_MT);
6248 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6249 rn = "VPEConf1";
6250 break;
6251 case 4:
6252 CP0_CHECK(ctx->insn_flags & ASE_MT);
6253 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
6254 rn = "YQMask";
6255 break;
6256 case 5:
6257 CP0_CHECK(ctx->insn_flags & ASE_MT);
6258 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6259 rn = "VPESchedule";
6260 break;
6261 case 6:
6262 CP0_CHECK(ctx->insn_flags & ASE_MT);
6263 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6264 rn = "VPEScheFBack";
6265 break;
6266 case 7:
6267 CP0_CHECK(ctx->insn_flags & ASE_MT);
6268 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6269 rn = "VPEOpt";
6270 break;
6271 default:
6272 goto cp0_unimplemented;
6273 }
6274 break;
6275 case 2:
6276 switch (sel) {
6277 case 0:
6278 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
6279 rn = "EntryLo0";
6280 break;
6281 case 1:
6282 CP0_CHECK(ctx->insn_flags & ASE_MT);
6283 gen_helper_mfc0_tcstatus(arg, cpu_env);
6284 rn = "TCStatus";
6285 break;
6286 case 2:
6287 CP0_CHECK(ctx->insn_flags & ASE_MT);
6288 gen_helper_mfc0_tcbind(arg, cpu_env);
6289 rn = "TCBind";
6290 break;
6291 case 3:
6292 CP0_CHECK(ctx->insn_flags & ASE_MT);
6293 gen_helper_dmfc0_tcrestart(arg, cpu_env);
6294 rn = "TCRestart";
6295 break;
6296 case 4:
6297 CP0_CHECK(ctx->insn_flags & ASE_MT);
6298 gen_helper_dmfc0_tchalt(arg, cpu_env);
6299 rn = "TCHalt";
6300 break;
6301 case 5:
6302 CP0_CHECK(ctx->insn_flags & ASE_MT);
6303 gen_helper_dmfc0_tccontext(arg, cpu_env);
6304 rn = "TCContext";
6305 break;
6306 case 6:
6307 CP0_CHECK(ctx->insn_flags & ASE_MT);
6308 gen_helper_dmfc0_tcschedule(arg, cpu_env);
6309 rn = "TCSchedule";
6310 break;
6311 case 7:
6312 CP0_CHECK(ctx->insn_flags & ASE_MT);
6313 gen_helper_dmfc0_tcschefback(arg, cpu_env);
6314 rn = "TCScheFBack";
6315 break;
6316 default:
6317 goto cp0_unimplemented;
6318 }
6319 break;
6320 case 3:
6321 switch (sel) {
6322 case 0:
6323 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
6324 rn = "EntryLo1";
6325 break;
6326 default:
6327 goto cp0_unimplemented;
6328 }
6329 break;
6330 case 4:
6331 switch (sel) {
6332 case 0:
6333 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6334 rn = "Context";
6335 break;
6336 case 1:
6337 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6338 rn = "ContextConfig";
6339 goto cp0_unimplemented;
6340 // break;
6341 case 2:
6342 CP0_CHECK(ctx->ulri);
6343 tcg_gen_ld_tl(arg, cpu_env,
6344 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6345 rn = "UserLocal";
6346 break;
6347 default:
6348 goto cp0_unimplemented;
6349 }
6350 break;
6351 case 5:
6352 switch (sel) {
6353 case 0:
6354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6355 rn = "PageMask";
6356 break;
6357 case 1:
6358 check_insn(ctx, ISA_MIPS32R2);
6359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6360 rn = "PageGrain";
6361 break;
6362 default:
6363 goto cp0_unimplemented;
6364 }
6365 break;
6366 case 6:
6367 switch (sel) {
6368 case 0:
6369 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6370 rn = "Wired";
6371 break;
6372 case 1:
6373 check_insn(ctx, ISA_MIPS32R2);
6374 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6375 rn = "SRSConf0";
6376 break;
6377 case 2:
6378 check_insn(ctx, ISA_MIPS32R2);
6379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6380 rn = "SRSConf1";
6381 break;
6382 case 3:
6383 check_insn(ctx, ISA_MIPS32R2);
6384 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6385 rn = "SRSConf2";
6386 break;
6387 case 4:
6388 check_insn(ctx, ISA_MIPS32R2);
6389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6390 rn = "SRSConf3";
6391 break;
6392 case 5:
6393 check_insn(ctx, ISA_MIPS32R2);
6394 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6395 rn = "SRSConf4";
6396 break;
6397 default:
6398 goto cp0_unimplemented;
6399 }
6400 break;
6401 case 7:
6402 switch (sel) {
6403 case 0:
6404 check_insn(ctx, ISA_MIPS32R2);
6405 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6406 rn = "HWREna";
6407 break;
6408 default:
6409 goto cp0_unimplemented;
6410 }
6411 break;
6412 case 8:
6413 switch (sel) {
6414 case 0:
6415 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6416 rn = "BadVAddr";
6417 break;
6418 case 1:
6419 CP0_CHECK(ctx->bi);
6420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6421 rn = "BadInstr";
6422 break;
6423 case 2:
6424 CP0_CHECK(ctx->bp);
6425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6426 rn = "BadInstrP";
6427 break;
6428 default:
6429 goto cp0_unimplemented;
6430 }
6431 break;
6432 case 9:
6433 switch (sel) {
6434 case 0:
6435 /* Mark as an IO operation because we read the time. */
6436 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6437 gen_io_start();
6438 }
6439 gen_helper_mfc0_count(arg, cpu_env);
6440 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6441 gen_io_end();
6442 }
6443 /* Break the TB to be able to take timer interrupts immediately
6444 after reading count. */
6445 ctx->bstate = BS_STOP;
6446 rn = "Count";
6447 break;
6448 /* 6,7 are implementation dependent */
6449 default:
6450 goto cp0_unimplemented;
6451 }
6452 break;
6453 case 10:
6454 switch (sel) {
6455 case 0:
6456 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6457 rn = "EntryHi";
6458 break;
6459 default:
6460 goto cp0_unimplemented;
6461 }
6462 break;
6463 case 11:
6464 switch (sel) {
6465 case 0:
6466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6467 rn = "Compare";
6468 break;
6469 /* 6,7 are implementation dependent */
6470 default:
6471 goto cp0_unimplemented;
6472 }
6473 break;
6474 case 12:
6475 switch (sel) {
6476 case 0:
6477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6478 rn = "Status";
6479 break;
6480 case 1:
6481 check_insn(ctx, ISA_MIPS32R2);
6482 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6483 rn = "IntCtl";
6484 break;
6485 case 2:
6486 check_insn(ctx, ISA_MIPS32R2);
6487 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6488 rn = "SRSCtl";
6489 break;
6490 case 3:
6491 check_insn(ctx, ISA_MIPS32R2);
6492 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6493 rn = "SRSMap";
6494 break;
6495 default:
6496 goto cp0_unimplemented;
6497 }
6498 break;
6499 case 13:
6500 switch (sel) {
6501 case 0:
6502 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6503 rn = "Cause";
6504 break;
6505 default:
6506 goto cp0_unimplemented;
6507 }
6508 break;
6509 case 14:
6510 switch (sel) {
6511 case 0:
6512 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6513 rn = "EPC";
6514 break;
6515 default:
6516 goto cp0_unimplemented;
6517 }
6518 break;
6519 case 15:
6520 switch (sel) {
6521 case 0:
6522 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6523 rn = "PRid";
6524 break;
6525 case 1:
6526 check_insn(ctx, ISA_MIPS32R2);
6527 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6528 rn = "EBase";
6529 break;
6530 default:
6531 goto cp0_unimplemented;
6532 }
6533 break;
6534 case 16:
6535 switch (sel) {
6536 case 0:
6537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6538 rn = "Config";
6539 break;
6540 case 1:
6541 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6542 rn = "Config1";
6543 break;
6544 case 2:
6545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6546 rn = "Config2";
6547 break;
6548 case 3:
6549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6550 rn = "Config3";
6551 break;
6552 case 4:
6553 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6554 rn = "Config4";
6555 break;
6556 case 5:
6557 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6558 rn = "Config5";
6559 break;
6560 /* 6,7 are implementation dependent */
6561 case 6:
6562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6563 rn = "Config6";
6564 break;
6565 case 7:
6566 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6567 rn = "Config7";
6568 break;
6569 default:
6570 goto cp0_unimplemented;
6571 }
6572 break;
6573 case 17:
6574 switch (sel) {
6575 case 0:
6576 gen_helper_dmfc0_lladdr(arg, cpu_env);
6577 rn = "LLAddr";
6578 break;
6579 default:
6580 goto cp0_unimplemented;
6581 }
6582 break;
6583 case 18:
6584 switch (sel) {
6585 case 0 ... 7:
6586 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6587 rn = "WatchLo";
6588 break;
6589 default:
6590 goto cp0_unimplemented;
6591 }
6592 break;
6593 case 19:
6594 switch (sel) {
6595 case 0 ... 7:
6596 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6597 rn = "WatchHi";
6598 break;
6599 default:
6600 goto cp0_unimplemented;
6601 }
6602 break;
6603 case 20:
6604 switch (sel) {
6605 case 0:
6606 check_insn(ctx, ISA_MIPS3);
6607 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6608 rn = "XContext";
6609 break;
6610 default:
6611 goto cp0_unimplemented;
6612 }
6613 break;
6614 case 21:
6615 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6616 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6617 switch (sel) {
6618 case 0:
6619 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6620 rn = "Framemask";
6621 break;
6622 default:
6623 goto cp0_unimplemented;
6624 }
6625 break;
6626 case 22:
6627 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6628 rn = "'Diagnostic"; /* implementation dependent */
6629 break;
6630 case 23:
6631 switch (sel) {
6632 case 0:
6633 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6634 rn = "Debug";
6635 break;
6636 case 1:
6637 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6638 rn = "TraceControl";
6639 // break;
6640 case 2:
6641 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6642 rn = "TraceControl2";
6643 // break;
6644 case 3:
6645 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6646 rn = "UserTraceData";
6647 // break;
6648 case 4:
6649 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6650 rn = "TraceBPC";
6651 // break;
6652 default:
6653 goto cp0_unimplemented;
6654 }
6655 break;
6656 case 24:
6657 switch (sel) {
6658 case 0:
6659 /* EJTAG support */
6660 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6661 rn = "DEPC";
6662 break;
6663 default:
6664 goto cp0_unimplemented;
6665 }
6666 break;
6667 case 25:
6668 switch (sel) {
6669 case 0:
6670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6671 rn = "Performance0";
6672 break;
6673 case 1:
6674 // gen_helper_dmfc0_performance1(arg);
6675 rn = "Performance1";
6676 // break;
6677 case 2:
6678 // gen_helper_dmfc0_performance2(arg);
6679 rn = "Performance2";
6680 // break;
6681 case 3:
6682 // gen_helper_dmfc0_performance3(arg);
6683 rn = "Performance3";
6684 // break;
6685 case 4:
6686 // gen_helper_dmfc0_performance4(arg);
6687 rn = "Performance4";
6688 // break;
6689 case 5:
6690 // gen_helper_dmfc0_performance5(arg);
6691 rn = "Performance5";
6692 // break;
6693 case 6:
6694 // gen_helper_dmfc0_performance6(arg);
6695 rn = "Performance6";
6696 // break;
6697 case 7:
6698 // gen_helper_dmfc0_performance7(arg);
6699 rn = "Performance7";
6700 // break;
6701 default:
6702 goto cp0_unimplemented;
6703 }
6704 break;
6705 case 26:
6706 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6707 rn = "ECC";
6708 break;
6709 case 27:
6710 switch (sel) {
6711 /* ignored */
6712 case 0 ... 3:
6713 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6714 rn = "CacheErr";
6715 break;
6716 default:
6717 goto cp0_unimplemented;
6718 }
6719 break;
6720 case 28:
6721 switch (sel) {
6722 case 0:
6723 case 2:
6724 case 4:
6725 case 6:
6726 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6727 rn = "TagLo";
6728 break;
6729 case 1:
6730 case 3:
6731 case 5:
6732 case 7:
6733 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6734 rn = "DataLo";
6735 break;
6736 default:
6737 goto cp0_unimplemented;
6738 }
6739 break;
6740 case 29:
6741 switch (sel) {
6742 case 0:
6743 case 2:
6744 case 4:
6745 case 6:
6746 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6747 rn = "TagHi";
6748 break;
6749 case 1:
6750 case 3:
6751 case 5:
6752 case 7:
6753 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6754 rn = "DataHi";
6755 break;
6756 default:
6757 goto cp0_unimplemented;
6758 }
6759 break;
6760 case 30:
6761 switch (sel) {
6762 case 0:
6763 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6764 rn = "ErrorEPC";
6765 break;
6766 default:
6767 goto cp0_unimplemented;
6768 }
6769 break;
6770 case 31:
6771 switch (sel) {
6772 case 0:
6773 /* EJTAG support */
6774 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6775 rn = "DESAVE";
6776 break;
6777 case 2 ... 7:
6778 CP0_CHECK(ctx->kscrexist & (1 << sel));
6779 tcg_gen_ld_tl(arg, cpu_env,
6780 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6781 rn = "KScratch";
6782 break;
6783 default:
6784 goto cp0_unimplemented;
6785 }
6786 break;
6787 default:
6788 goto cp0_unimplemented;
6789 }
6790 (void)rn; /* avoid a compiler warning */
6791 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6792 return;
6793
6794 cp0_unimplemented:
6795 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6796 gen_mfc0_unimplemented(ctx, arg);
6797 }
6798
6799 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6800 {
6801 const char *rn = "invalid";
6802
6803 if (sel != 0)
6804 check_insn(ctx, ISA_MIPS64);
6805
6806 if (ctx->tb->cflags & CF_USE_ICOUNT) {
6807 gen_io_start();
6808 }
6809
6810 switch (reg) {
6811 case 0:
6812 switch (sel) {
6813 case 0:
6814 gen_helper_mtc0_index(cpu_env, arg);
6815 rn = "Index";
6816 break;
6817 case 1:
6818 CP0_CHECK(ctx->insn_flags & ASE_MT);
6819 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6820 rn = "MVPControl";
6821 break;
6822 case 2:
6823 CP0_CHECK(ctx->insn_flags & ASE_MT);
6824 /* ignored */
6825 rn = "MVPConf0";
6826 break;
6827 case 3:
6828 CP0_CHECK(ctx->insn_flags & ASE_MT);
6829 /* ignored */
6830 rn = "MVPConf1";
6831 break;
6832 default:
6833 goto cp0_unimplemented;
6834 }
6835 break;
6836 case 1:
6837 switch (sel) {
6838 case 0:
6839 /* ignored */
6840 rn = "Random";
6841 break;
6842 case 1:
6843 CP0_CHECK(ctx->insn_flags & ASE_MT);
6844 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6845 rn = "VPEControl";
6846 break;
6847 case 2:
6848 CP0_CHECK(ctx->insn_flags & ASE_MT);
6849 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6850 rn = "VPEConf0";
6851 break;
6852 case 3:
6853 CP0_CHECK(ctx->insn_flags & ASE_MT);
6854 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6855 rn = "VPEConf1";
6856 break;
6857 case 4:
6858 CP0_CHECK(ctx->insn_flags & ASE_MT);
6859 gen_helper_mtc0_yqmask(cpu_env, arg);
6860 rn = "YQMask";
6861 break;
6862 case 5:
6863 CP0_CHECK(ctx->insn_flags & ASE_MT);
6864 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6865 rn = "VPESchedule";
6866 break;
6867 case 6:
6868 CP0_CHECK(ctx->insn_flags & ASE_MT);
6869 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6870 rn = "VPEScheFBack";
6871 break;
6872 case 7:
6873 CP0_CHECK(ctx->insn_flags & ASE_MT);
6874 gen_helper_mtc0_vpeopt(cpu_env, arg);
6875 rn = "VPEOpt";
6876 break;
6877 default:
6878 goto cp0_unimplemented;
6879 }
6880 break;
6881 case 2:
6882 switch (sel) {
6883 case 0:
6884 gen_helper_dmtc0_entrylo0(cpu_env, arg);
6885 rn = "EntryLo0";
6886 break;
6887 case 1:
6888 CP0_CHECK(ctx->insn_flags & ASE_MT);
6889 gen_helper_mtc0_tcstatus(cpu_env, arg);
6890 rn = "TCStatus";
6891 break;
6892 case 2:
6893 CP0_CHECK(ctx->insn_flags & ASE_MT);
6894 gen_helper_mtc0_tcbind(cpu_env, arg);
6895 rn = "TCBind";
6896 break;
6897 case 3:
6898 CP0_CHECK(ctx->insn_flags & ASE_MT);
6899 gen_helper_mtc0_tcrestart(cpu_env, arg);
6900 rn = "TCRestart";
6901 break;
6902 case 4:
6903 CP0_CHECK(ctx->insn_flags & ASE_MT);
6904 gen_helper_mtc0_tchalt(cpu_env, arg);
6905 rn = "TCHalt";
6906 break;
6907 case 5:
6908 CP0_CHECK(ctx->insn_flags & ASE_MT);
6909 gen_helper_mtc0_tccontext(cpu_env, arg);
6910 rn = "TCContext";
6911 break;
6912 case 6:
6913 CP0_CHECK(ctx->insn_flags & ASE_MT);
6914 gen_helper_mtc0_tcschedule(cpu_env, arg);
6915 rn = "TCSchedule";
6916 break;
6917 case 7:
6918 CP0_CHECK(ctx->insn_flags & ASE_MT);
6919 gen_helper_mtc0_tcschefback(cpu_env, arg);
6920 rn = "TCScheFBack";
6921 break;
6922 default:
6923 goto cp0_unimplemented;
6924 }
6925 break;
6926 case 3:
6927 switch (sel) {
6928 case 0:
6929 gen_helper_dmtc0_entrylo1(cpu_env, arg);
6930 rn = "EntryLo1";
6931 break;
6932 default:
6933 goto cp0_unimplemented;
6934 }
6935 break;
6936 case 4:
6937 switch (sel) {
6938 case 0:
6939 gen_helper_mtc0_context(cpu_env, arg);
6940 rn = "Context";
6941 break;
6942 case 1:
6943 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6944 rn = "ContextConfig";
6945 goto cp0_unimplemented;
6946 // break;
6947 case 2:
6948 CP0_CHECK(ctx->ulri);
6949 tcg_gen_st_tl(arg, cpu_env,
6950 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6951 rn = "UserLocal";
6952 break;
6953 default:
6954 goto cp0_unimplemented;
6955 }
6956 break;
6957 case 5:
6958 switch (sel) {
6959 case 0:
6960 gen_helper_mtc0_pagemask(cpu_env, arg);
6961 rn = "PageMask";
6962 break;
6963 case 1:
6964 check_insn(ctx, ISA_MIPS32R2);
6965 gen_helper_mtc0_pagegrain(cpu_env, arg);
6966 rn = "PageGrain";
6967 break;
6968 default:
6969 goto cp0_unimplemented;
6970 }
6971 break;
6972 case 6:
6973 switch (sel) {
6974 case 0:
6975 gen_helper_mtc0_wired(cpu_env, arg);
6976 rn = "Wired";
6977 break;
6978 case 1:
6979 check_insn(ctx, ISA_MIPS32R2);
6980 gen_helper_mtc0_srsconf0(cpu_env, arg);
6981 rn = "SRSConf0";
6982 break;
6983 case 2:
6984 check_insn(ctx, ISA_MIPS32R2);
6985 gen_helper_mtc0_srsconf1(cpu_env, arg);
6986 rn = "SRSConf1";
6987 break;
6988 case 3:
6989 check_insn(ctx, ISA_MIPS32R2);
6990 gen_helper_mtc0_srsconf2(cpu_env, arg);
6991 rn = "SRSConf2";
6992 break;
6993 case 4:
6994 check_insn(ctx, ISA_MIPS32R2);
6995 gen_helper_mtc0_srsconf3(cpu_env, arg);
6996 rn = "SRSConf3";
6997 break;
6998 case 5:
6999 check_insn(ctx, ISA_MIPS32R2);
7000 gen_helper_mtc0_srsconf4(cpu_env, arg);
7001 rn = "SRSConf4";
7002 break;
7003 default:
7004 goto cp0_unimplemented;
7005 }
7006 break;
7007 case 7:
7008 switch (sel) {
7009 case 0:
7010 check_insn(ctx, ISA_MIPS32R2);
7011 gen_helper_mtc0_hwrena(cpu_env, arg);
7012 ctx->bstate = BS_STOP;
7013 rn = "HWREna";
7014 break;
7015 default:
7016 goto cp0_unimplemented;
7017 }
7018 break;
7019 case 8:
7020 switch (sel) {
7021 case 0:
7022 /* ignored */
7023 rn = "BadVAddr";
7024 break;
7025 case 1:
7026 /* ignored */
7027 rn = "BadInstr";
7028 break;
7029 case 2:
7030 /* ignored */
7031 rn = "BadInstrP";
7032 break;
7033 default:
7034 goto cp0_unimplemented;
7035 }
7036 break;
7037 case 9:
7038 switch (sel) {
7039 case 0:
7040 gen_helper_mtc0_count(cpu_env, arg);
7041 rn = "Count";
7042 break;
7043 /* 6,7 are implementation dependent */
7044 default:
7045 goto cp0_unimplemented;
7046 }
7047 /* Stop translation as we may have switched the execution mode */
7048 ctx->bstate = BS_STOP;
7049 break;
7050 case 10:
7051 switch (sel) {
7052 case 0:
7053 gen_helper_mtc0_entryhi(cpu_env, arg);
7054 rn = "EntryHi";
7055 break;
7056 default:
7057 goto cp0_unimplemented;
7058 }
7059 break;
7060 case 11:
7061 switch (sel) {
7062 case 0:
7063 gen_helper_mtc0_compare(cpu_env, arg);
7064 rn = "Compare";
7065 break;
7066 /* 6,7 are implementation dependent */
7067 default:
7068 goto cp0_unimplemented;
7069 }
7070 /* Stop translation as we may have switched the execution mode */
7071 ctx->bstate = BS_STOP;
7072 break;
7073 case 12:
7074 switch (sel) {
7075 case 0:
7076 save_cpu_state(ctx, 1);
7077 gen_helper_mtc0_status(cpu_env, arg);
7078 /* BS_STOP isn't good enough here, hflags may have changed. */
7079 gen_save_pc(ctx->pc + 4);
7080 ctx->bstate = BS_EXCP;
7081 rn = "Status";
7082 break;
7083 case 1:
7084 check_insn(ctx, ISA_MIPS32R2);
7085 gen_helper_mtc0_intctl(cpu_env, arg);
7086 /* Stop translation as we may have switched the execution mode */
7087 ctx->bstate = BS_STOP;
7088 rn = "IntCtl";
7089 break;
7090 case 2:
7091 check_insn(ctx, ISA_MIPS32R2);
7092 gen_helper_mtc0_srsctl(cpu_env, arg);
7093 /* Stop translation as we may have switched the execution mode */
7094 ctx->bstate = BS_STOP;
7095 rn = "SRSCtl";
7096 break;
7097 case 3:
7098 check_insn(ctx, ISA_MIPS32R2);
7099 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7100 /* Stop translation as we may have switched the execution mode */
7101 ctx->bstate = BS_STOP;
7102 rn = "SRSMap";
7103 break;
7104 default:
7105 goto cp0_unimplemented;
7106 }
7107 break;
7108 case 13:
7109 switch (sel) {
7110 case 0:
7111 save_cpu_state(ctx, 1);
7112 /* Mark as an IO operation because we may trigger a software
7113 interrupt. */
7114 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7115 gen_io_start();
7116 }
7117 gen_helper_mtc0_cause(cpu_env, arg);
7118 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7119 gen_io_end();
7120 }
7121 /* Stop translation as we may have triggered an intetrupt */
7122 ctx->bstate = BS_STOP;
7123 rn = "Cause";
7124 break;
7125 default:
7126 goto cp0_unimplemented;
7127 }
7128 break;
7129 case 14:
7130 switch (sel) {
7131 case 0:
7132 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7133 rn = "EPC";
7134 break;
7135 default:
7136 goto cp0_unimplemented;
7137 }
7138 break;
7139 case 15:
7140 switch (sel) {
7141 case 0:
7142 /* ignored */
7143 rn = "PRid";
7144 break;
7145 case 1:
7146 check_insn(ctx, ISA_MIPS32R2);
7147 gen_helper_mtc0_ebase(cpu_env, arg);
7148 rn = "EBase";
7149 break;
7150 default:
7151 goto cp0_unimplemented;
7152 }
7153 break;
7154 case 16:
7155 switch (sel) {
7156 case 0:
7157 gen_helper_mtc0_config0(cpu_env, arg);
7158 rn = "Config";
7159 /* Stop translation as we may have switched the execution mode */
7160 ctx->bstate = BS_STOP;
7161 break;
7162 case 1:
7163 /* ignored, read only */
7164 rn = "Config1";
7165 break;
7166 case 2:
7167 gen_helper_mtc0_config2(cpu_env, arg);
7168 rn = "Config2";
7169 /* Stop translation as we may have switched the execution mode */
7170 ctx->bstate = BS_STOP;
7171 break;
7172 case 3:
7173 gen_helper_mtc0_config3(cpu_env, arg);
7174 rn = "Config3";
7175 /* Stop translation as we may have switched the execution mode */
7176 ctx->bstate = BS_STOP;
7177 break;
7178 case 4:
7179 /* currently ignored */
7180 rn = "Config4";
7181 break;
7182 case 5:
7183 gen_helper_mtc0_config5(cpu_env, arg);
7184 rn = "Config5";
7185 /* Stop translation as we may have switched the execution mode */
7186 ctx->bstate = BS_STOP;
7187 break;
7188 /* 6,7 are implementation dependent */
7189 default:
7190 rn = "Invalid config selector";
7191 goto cp0_unimplemented;
7192 }
7193 break;
7194 case 17:
7195 switch (sel) {
7196 case 0:
7197 gen_helper_mtc0_lladdr(cpu_env, arg);
7198 rn = "LLAddr";
7199 break;
7200 default:
7201 goto cp0_unimplemented;
7202 }
7203 break;
7204 case 18:
7205 switch (sel) {
7206 case 0 ... 7:
7207 gen_helper_0e1i(mtc0_watchlo, arg, sel);
7208 rn = "WatchLo";
7209 break;
7210 default:
7211 goto cp0_unimplemented;
7212 }
7213 break;
7214 case 19:
7215 switch (sel) {
7216 case 0 ... 7:
7217 gen_helper_0e1i(mtc0_watchhi, arg, sel);
7218 rn = "WatchHi";
7219 break;
7220 default:
7221 goto cp0_unimplemented;
7222 }
7223 break;
7224 case 20:
7225 switch (sel) {
7226 case 0:
7227 check_insn(ctx, ISA_MIPS3);
7228 gen_helper_mtc0_xcontext(cpu_env, arg);
7229 rn = "XContext";
7230 break;
7231 default:
7232 goto cp0_unimplemented;
7233 }
7234 break;
7235 case 21:
7236 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7237 CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7238 switch (sel) {
7239 case 0:
7240 gen_helper_mtc0_framemask(cpu_env, arg);
7241 rn = "Framemask";
7242 break;
7243 default:
7244 goto cp0_unimplemented;
7245 }
7246 break;
7247 case 22:
7248 /* ignored */
7249 rn = "Diagnostic"; /* implementation dependent */
7250 break;
7251 case 23:
7252 switch (sel) {
7253 case 0:
7254 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7255 /* BS_STOP isn't good enough here, hflags may have changed. */
7256 gen_save_pc(ctx->pc + 4);
7257 ctx->bstate = BS_EXCP;
7258 rn = "Debug";
7259 break;
7260 case 1:
7261 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7262 /* Stop translation as we may have switched the execution mode */
7263 ctx->bstate = BS_STOP;
7264 rn = "TraceControl";
7265 // break;
7266 case 2:
7267 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7268 /* Stop translation as we may have switched the execution mode */
7269 ctx->bstate = BS_STOP;
7270 rn = "TraceControl2";
7271 // break;
7272 case 3:
7273 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7274 /* Stop translation as we may have switched the execution mode */
7275 ctx->bstate = BS_STOP;
7276 rn = "UserTraceData";
7277 // break;
7278 case 4:
7279 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7280 /* Stop translation as we may have switched the execution mode */
7281 ctx->bstate = BS_STOP;
7282 rn = "TraceBPC";
7283 // break;
7284 default:
7285 goto cp0_unimplemented;
7286 }
7287 break;
7288 case 24:
7289 switch (sel) {
7290 case 0:
7291 /* EJTAG support */
7292 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7293 rn = "DEPC";
7294 break;
7295 default:
7296 goto cp0_unimplemented;
7297 }
7298 break;
7299 case 25:
7300 switch (sel) {
7301 case 0:
7302 gen_helper_mtc0_performance0(cpu_env, arg);
7303 rn = "Performance0";
7304 break;
7305 case 1:
7306 // gen_helper_mtc0_performance1(cpu_env, arg);
7307 rn = "Performance1";
7308 // break;
7309 case 2:
7310 // gen_helper_mtc0_performance2(cpu_env, arg);
7311 rn = "Performance2";
7312 // break;
7313 case 3:
7314 // gen_helper_mtc0_performance3(cpu_env, arg);
7315 rn = "Performance3";
7316 // break;
7317 case 4:
7318 // gen_helper_mtc0_performance4(cpu_env, arg);
7319 rn = "Performance4";
7320 // break;
7321 case 5:
7322 // gen_helper_mtc0_performance5(cpu_env, arg);
7323 rn = "Performance5";
7324 // break;
7325 case 6:
7326 // gen_helper_mtc0_performance6(cpu_env, arg);
7327 rn = "Performance6";
7328 // break;
7329 case 7:
7330 // gen_helper_mtc0_performance7(cpu_env, arg);
7331 rn = "Performance7";
7332 // break;
7333 default:
7334 goto cp0_unimplemented;
7335 }
7336 break;
7337 case 26:
7338 /* ignored */
7339 rn = "ECC";
7340 break;
7341 case 27:
7342 switch (sel) {
7343 case 0 ... 3:
7344 /* ignored */
7345 rn = "CacheErr";
7346 break;
7347 default:
7348 goto cp0_unimplemented;
7349 }
7350 break;
7351 case 28:
7352 switch (sel) {
7353 case 0:
7354 case 2:
7355 case 4:
7356 case 6:
7357 gen_helper_mtc0_taglo(cpu_env, arg);
7358 rn = "TagLo";
7359 break;
7360 case 1:
7361 case 3:
7362 case 5:
7363 case 7:
7364 gen_helper_mtc0_datalo(cpu_env, arg);
7365 rn = "DataLo";
7366 break;
7367 default:
7368 goto cp0_unimplemented;
7369 }
7370 break;
7371 case 29:
7372 switch (sel) {
7373 case 0:
7374 case 2:
7375 case 4:
7376 case 6:
7377 gen_helper_mtc0_taghi(cpu_env, arg);
7378 rn = "TagHi";
7379 break;
7380 case 1:
7381 case 3:
7382 case 5:
7383 case 7:
7384 gen_helper_mtc0_datahi(cpu_env, arg);
7385 rn = "DataHi";
7386 break;
7387 default:
7388 rn = "invalid sel";
7389 goto cp0_unimplemented;
7390 }
7391 break;
7392 case 30:
7393 switch (sel) {
7394 case 0:
7395 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7396 rn = "ErrorEPC";
7397 break;
7398 default:
7399 goto cp0_unimplemented;
7400 }
7401 break;
7402 case 31:
7403 switch (sel) {
7404 case 0:
7405 /* EJTAG support */
7406 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7407 rn = "DESAVE";
7408 break;
7409 case 2 ... 7:
7410 CP0_CHECK(ctx->kscrexist & (1 << sel));
7411 tcg_gen_st_tl(arg, cpu_env,
7412 offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7413 rn = "KScratch";
7414 break;
7415 default:
7416 goto cp0_unimplemented;
7417 }
7418 /* Stop translation as we may have switched the execution mode */
7419 ctx->bstate = BS_STOP;
7420 break;
7421 default:
7422 goto cp0_unimplemented;
7423 }
7424 (void)rn; /* avoid a compiler warning */
7425 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7426 /* For simplicity assume that all writes can cause interrupts. */
7427 if (ctx->tb->cflags & CF_USE_ICOUNT) {
7428 gen_io_end();
7429 ctx->bstate = BS_STOP;
7430 }
7431 return;
7432
7433 cp0_unimplemented:
7434 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7435 }
7436 #endif /* TARGET_MIPS64 */
7437
7438 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7439 int u, int sel, int h)
7440 {
7441 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7442 TCGv t0 = tcg_temp_local_new();
7443
7444 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7445 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7446 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7447 tcg_gen_movi_tl(t0, -1);
7448 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7449 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7450 tcg_gen_movi_tl(t0, -1);
7451 else if (u == 0) {
7452 switch (rt) {
7453 case 1:
7454 switch (sel) {
7455 case 1:
7456 gen_helper_mftc0_vpecontrol(t0, cpu_env);
7457 break;
7458 case 2:
7459 gen_helper_mftc0_vpeconf0(t0, cpu_env);
7460 break;
7461 default:
7462 goto die;
7463 break;
7464 }
7465 break;
7466 case 2:
7467 switch (sel) {
7468 case 1:
7469 gen_helper_mftc0_tcstatus(t0, cpu_env);
7470 break;
7471 case 2:
7472 gen_helper_mftc0_tcbind(t0, cpu_env);
7473 break;
7474 case 3:
7475 gen_helper_mftc0_tcrestart(t0, cpu_env);
7476 break;
7477 case 4:
7478 gen_helper_mftc0_tchalt(t0, cpu_env);
7479 break;
7480 case 5:
7481 gen_helper_mftc0_tccontext(t0, cpu_env);
7482 break;
7483 case 6:
7484 gen_helper_mftc0_tcschedule(t0, cpu_env);
7485 break;
7486 case 7:
7487 gen_helper_mftc0_tcschefback(t0, cpu_env);
7488 break;
7489 default:
7490 gen_mfc0(ctx, t0, rt, sel);
7491 break;
7492 }
7493 break;
7494 case 10:
7495 switch (sel) {
7496 case 0:
7497 gen_helper_mftc0_entryhi(t0, cpu_env);
7498 break;
7499 default:
7500 gen_mfc0(ctx, t0, rt, sel);
7501 break;
7502 }
7503 case 12:
7504 switch (sel) {
7505 case 0:
7506 gen_helper_mftc0_status(t0, cpu_env);
7507 break;
7508 default:
7509 gen_mfc0(ctx, t0, rt, sel);
7510 break;
7511 }
7512 case 13:
7513 switch (sel) {
7514 case 0:
7515 gen_helper_mftc0_cause(t0, cpu_env);
7516 break;
7517 default:
7518 goto die;
7519 break;
7520 }
7521 break;
7522 case 14:
7523 switch (sel) {
7524 case 0:
7525 gen_helper_mftc0_epc(t0, cpu_env);
7526 break;
7527 default:
7528 goto die;
7529 break;
7530 }
7531 break;
7532 case 15:
7533 switch (sel) {
7534 case 1:
7535 gen_helper_mftc0_ebase(t0, cpu_env);
7536 break;
7537 default:
7538 goto die;
7539 break;
7540 }
7541 break;
7542 case 16:
7543 switch (sel) {
7544 case 0 ... 7:
7545 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7546 break;
7547 default:
7548 goto die;
7549 break;
7550 }
7551 break;
7552 case 23:
7553 switch (sel) {
7554 case 0:
7555 gen_helper_mftc0_debug(t0, cpu_env);
7556 break;
7557 default:
7558 gen_mfc0(ctx, t0, rt, sel);
7559 break;
7560 }
7561 break;
7562 default:
7563 gen_mfc0(ctx, t0, rt, sel);
7564 }
7565 } else switch (sel) {
7566 /* GPR registers. */
7567 case 0:
7568 gen_helper_1e0i(mftgpr, t0, rt);
7569 break;
7570 /* Auxiliary CPU registers */
7571 case 1:
7572 switch (rt) {
7573 case 0:
7574 gen_helper_1e0i(mftlo, t0, 0);
7575 break;
7576 case 1:
7577 gen_helper_1e0i(mfthi, t0, 0);
7578 break;
7579 case 2:
7580 gen_helper_1e0i(mftacx, t0, 0);
7581 break;
7582 case 4:
7583 gen_helper_1e0i(mftlo, t0, 1);
7584 break;
7585 case 5:
7586 gen_helper_1e0i(mfthi, t0, 1);
7587 break;
7588 case 6:
7589 gen_helper_1e0i(mftacx, t0, 1);
7590 break;
7591 case 8:
7592 gen_helper_1e0i(mftlo, t0, 2);
7593 break;
7594 case 9:
7595 gen_helper_1e0i(mfthi, t0, 2);
7596 break;
7597 case 10:
7598 gen_helper_1e0i(mftacx, t0, 2);
7599 break;
7600 case 12:
7601 gen_helper_1e0i(mftlo, t0, 3);
7602 break;
7603 case 13:
7604 gen_helper_1e0i(mfthi, t0, 3);
7605 break;
7606 case 14:
7607 gen_helper_1e0i(mftacx, t0, 3);
7608 break;
7609 case 16:
7610 gen_helper_mftdsp(t0, cpu_env);
7611 break;
7612 default:
7613 goto die;
7614 }
7615 break;
7616 /* Floating point (COP1). */
7617 case 2:
7618 /* XXX: For now we support only a single FPU context. */
7619 if (h == 0) {
7620 TCGv_i32 fp0 = tcg_temp_new_i32();
7621
7622 gen_load_fpr32(ctx, fp0, rt);
7623 tcg_gen_ext_i32_tl(t0, fp0);
7624 tcg_temp_free_i32(fp0);
7625 } else {
7626 TCGv_i32 fp0 = tcg_temp_new_i32();
7627
7628 gen_load_fpr32h(ctx, fp0, rt);
7629 tcg_gen_ext_i32_tl(t0, fp0);
7630 tcg_temp_free_i32(fp0);
7631 }
7632 break;
7633 case 3:
7634 /* XXX: For now we support only a single FPU context. */
7635 gen_helper_1e0i(cfc1, t0, rt);
7636 break;
7637 /* COP2: Not implemented. */
7638 case 4:
7639 case 5:
7640 /* fall through */
7641 default:
7642 goto die;
7643 }
7644 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7645 gen_store_gpr(t0, rd);
7646 tcg_temp_free(t0);
7647 return;
7648
7649 die:
7650 tcg_temp_free(t0);
7651 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7652 generate_exception_end(ctx, EXCP_RI);
7653 }
7654
7655 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7656 int u, int sel, int h)
7657 {
7658 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7659 TCGv t0 = tcg_temp_local_new();
7660
7661 gen_load_gpr(t0, rt);
7662 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7663 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7664 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7665 /* NOP */ ;
7666 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7667 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7668 /* NOP */ ;
7669 else if (u == 0) {
7670 switch (rd) {
7671 case 1:
7672 switch (sel) {
7673 case 1:
7674 gen_helper_mttc0_vpecontrol(cpu_env, t0);
7675 break;
7676 case 2:
7677 gen_helper_mttc0_vpeconf0(cpu_env, t0);
7678 break;
7679 default:
7680 goto die;
7681 break;
7682 }
7683 break;
7684 case 2:
7685 switch (sel) {
7686 case 1:
7687 gen_helper_mttc0_tcstatus(cpu_env, t0);
7688 break;
7689 case 2:
7690 gen_helper_mttc0_tcbind(cpu_env, t0);
7691 break;
7692 case 3:
7693 gen_helper_mttc0_tcrestart(cpu_env, t0);
7694 break;
7695 case 4:
7696 gen_helper_mttc0_tchalt(cpu_env, t0);
7697 break;
7698 case 5:
7699 gen_helper_mttc0_tccontext(cpu_env, t0);
7700 break;
7701 case 6:
7702 gen_helper_mttc0_tcschedule(cpu_env, t0);
7703 break;
7704 case 7:
7705 gen_helper_mttc0_tcschefback(cpu_env, t0);
7706 break;
7707 default:
7708 gen_mtc0(ctx, t0, rd, sel);
7709 break;
7710 }
7711 break;
7712 case 10:
7713 switch (sel) {
7714 case 0:
7715 gen_helper_mttc0_entryhi(cpu_env, t0);
7716 break;
7717 default:
7718 gen_mtc0(ctx, t0, rd, sel);
7719 break;
7720 }
7721 case 12:
7722 switch (sel) {
7723 case 0:
7724 gen_helper_mttc0_status(cpu_env, t0);
7725 break;
7726 default:
7727 gen_mtc0(ctx, t0, rd, sel);
7728 break;
7729 }
7730 case 13:
7731 switch (sel) {
7732 case 0:
7733 gen_helper_mttc0_cause(cpu_env, t0);
7734 break;
7735 default:
7736 goto die;
7737 break;
7738 }
7739 break;
7740 case 15:
7741 switch (sel) {
7742 case 1:
7743 gen_helper_mttc0_ebase(cpu_env, t0);
7744 break;
7745 default:
7746 goto die;
7747 break;
7748 }
7749 break;
7750 case 23:
7751 switch (sel) {
7752 case 0:
7753 gen_helper_mttc0_debug(cpu_env, t0);
7754 break;
7755 default:
7756 gen_mtc0(ctx, t0, rd, sel);
7757 break;
7758 }
7759 break;
7760 default:
7761 gen_mtc0(ctx, t0, rd, sel);
7762 }
7763 } else switch (sel) {
7764 /* GPR registers. */
7765 case 0:
7766 gen_helper_0e1i(mttgpr, t0, rd);
7767 break;
7768 /* Auxiliary CPU registers */
7769 case 1:
7770 switch (rd) {
7771 case 0:
7772 gen_helper_0e1i(mttlo, t0, 0);
7773 break;
7774 case 1:
7775 gen_helper_0e1i(mtthi, t0, 0);
7776 break;
7777 case 2:
7778 gen_helper_0e1i(mttacx, t0, 0);
7779 break;
7780 case 4:
7781 gen_helper_0e1i(mttlo, t0, 1);
7782 break;
7783 case 5:
7784 gen_helper_0e1i(mtthi, t0, 1);
7785 break;
7786 case 6:
7787 gen_helper_0e1i(mttacx, t0, 1);
7788 break;
7789 case 8:
7790 gen_helper_0e1i(mttlo, t0, 2);
7791 break;
7792 case 9:
7793 gen_helper_0e1i(mtthi, t0, 2);
7794 break;
7795 case 10:
7796 gen_helper_0e1i(mttacx, t0, 2);
7797 break;
7798 case 12:
7799 gen_helper_0e1i(mttlo, t0, 3);
7800 break;
7801 case 13:
7802 gen_helper_0e1i(mtthi, t0, 3);
7803 break;
7804 case 14:
7805 gen_helper_0e1i(mttacx, t0, 3);
7806 break;
7807 case 16:
7808 gen_helper_mttdsp(cpu_env, t0);
7809 break;
7810 default:
7811 goto die;
7812 }
7813 break;
7814 /* Floating point (COP1). */
7815 case 2:
7816 /* XXX: For now we support only a single FPU context. */
7817 if (h == 0) {
7818 TCGv_i32 fp0 = tcg_temp_new_i32();
7819
7820 tcg_gen_trunc_tl_i32(fp0, t0);
7821 gen_store_fpr32(ctx, fp0, rd);
7822 tcg_temp_free_i32(fp0);
7823 } else {
7824 TCGv_i32 fp0 = tcg_temp_new_i32();
7825
7826 tcg_gen_trunc_tl_i32(fp0, t0);
7827 gen_store_fpr32h(ctx, fp0, rd);
7828 tcg_temp_free_i32(fp0);
7829 }
7830 break;
7831 case 3:
7832 /* XXX: For now we support only a single FPU context. */
7833 {
7834 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7835
7836 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7837 tcg_temp_free_i32(fs_tmp);
7838 }
7839 /* Stop translation as we may have changed hflags */
7840 ctx->bstate = BS_STOP;
7841 break;
7842 /* COP2: Not implemented. */
7843 case 4:
7844 case 5:
7845 /* fall through */
7846 default:
7847 goto die;
7848 }
7849 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7850 tcg_temp_free(t0);
7851 return;
7852
7853 die:
7854 tcg_temp_free(t0);
7855 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7856 generate_exception_end(ctx, EXCP_RI);
7857 }
7858
7859 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
7860 {
7861 const char *opn = "ldst";
7862
7863 check_cp0_enabled(ctx);
7864 switch (opc) {
7865 case OPC_MFC0:
7866 if (rt == 0) {
7867 /* Treat as NOP. */
7868 return;
7869 }
7870 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7871 opn = "mfc0";
7872 break;
7873 case OPC_MTC0:
7874 {
7875 TCGv t0 = tcg_temp_new();
7876
7877 gen_load_gpr(t0, rt);
7878 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
7879 tcg_temp_free(t0);
7880 }
7881 opn = "mtc0";
7882 break;
7883 #if defined(TARGET_MIPS64)
7884 case OPC_DMFC0:
7885 check_insn(ctx, ISA_MIPS3);
7886 if (rt == 0) {
7887 /* Treat as NOP. */
7888 return;
7889 }
7890 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7891 opn = "dmfc0";
7892 break;
7893 case OPC_DMTC0:
7894 check_insn(ctx, ISA_MIPS3);
7895 {
7896 TCGv t0 = tcg_temp_new();
7897
7898 gen_load_gpr(t0, rt);
7899 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
7900 tcg_temp_free(t0);
7901 }
7902 opn = "dmtc0";
7903 break;
7904 #endif
7905 case OPC_MFHC0:
7906 check_mvh(ctx);
7907 if (rt == 0) {
7908 /* Treat as NOP. */
7909 return;
7910 }
7911 gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7912 opn = "mfhc0";
7913 break;
7914 case OPC_MTHC0:
7915 check_mvh(ctx);
7916 {
7917 TCGv t0 = tcg_temp_new();
7918 gen_load_gpr(t0, rt);
7919 gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
7920 tcg_temp_free(t0);
7921 }
7922 opn = "mthc0";
7923 break;
7924 case OPC_MFTR:
7925 check_insn(ctx, ASE_MT);
7926 if (rd == 0) {
7927 /* Treat as NOP. */
7928 return;
7929 }
7930 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
7931 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7932 opn = "mftr";
7933 break;
7934 case OPC_MTTR:
7935 check_insn(ctx, ASE_MT);
7936 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
7937 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7938 opn = "mttr";
7939 break;
7940 case OPC_TLBWI:
7941 opn = "tlbwi";
7942 if (!env->tlb->helper_tlbwi)
7943 goto die;
7944 gen_helper_tlbwi(cpu_env);
7945 break;
7946 case OPC_TLBINV:
7947 opn = "tlbinv";
7948 if (ctx->ie >= 2) {
7949 if (!env->tlb->helper_tlbinv) {
7950 goto die;
7951 }
7952 gen_helper_tlbinv(cpu_env);
7953 } /* treat as nop if TLBINV not supported */
7954 break;
7955 case OPC_TLBINVF:
7956 opn = "tlbinvf";
7957 if (ctx->ie >= 2) {
7958 if (!env->tlb->helper_tlbinvf) {
7959 goto die;
7960 }
7961 gen_helper_tlbinvf(cpu_env);
7962 } /* treat as nop if TLBINV not supported */
7963 break;
7964 case OPC_TLBWR:
7965 opn = "tlbwr";
7966 if (!env->tlb->helper_tlbwr)
7967 goto die;
7968 gen_helper_tlbwr(cpu_env);
7969 break;
7970 case OPC_TLBP:
7971 opn = "tlbp";
7972 if (!env->tlb->helper_tlbp)
7973 goto die;
7974 gen_helper_tlbp(cpu_env);
7975 break;
7976 case OPC_TLBR:
7977 opn = "tlbr";
7978 if (!env->tlb->helper_tlbr)
7979 goto die;
7980 gen_helper_tlbr(cpu_env);
7981 break;
7982 case OPC_ERET: /* OPC_ERETNC */
7983 if ((ctx->insn_flags & ISA_MIPS32R6) &&
7984 (ctx->hflags & MIPS_HFLAG_BMASK)) {
7985 goto die;
7986 } else {
7987 int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
7988 if (ctx->opcode & (1 << bit_shift)) {
7989 /* OPC_ERETNC */
7990 opn = "eretnc";
7991 check_insn(ctx, ISA_MIPS32R5);
7992 gen_helper_eretnc(cpu_env);
7993 } else {
7994 /* OPC_ERET */
7995 opn = "eret";
7996 check_insn(ctx, ISA_MIPS2);
7997 gen_helper_eret(cpu_env);
7998 }
7999 ctx->bstate = BS_EXCP;
8000 }
8001 break;
8002 case OPC_DERET:
8003 opn = "deret";
8004 check_insn(ctx, ISA_MIPS32);
8005 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8006 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8007 goto die;
8008 }
8009 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
8010 MIPS_INVAL(opn);
8011 generate_exception_end(ctx, EXCP_RI);
8012 } else {
8013 gen_helper_deret(cpu_env);
8014 ctx->bstate = BS_EXCP;
8015 }
8016 break;
8017 case OPC_WAIT:
8018 opn = "wait";
8019 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
8020 if ((ctx->insn_flags & ISA_MIPS32R6) &&
8021 (ctx->hflags & MIPS_HFLAG_BMASK)) {
8022 goto die;
8023 }
8024 /* If we get an exception, we want to restart at next instruction */
8025 ctx->pc += 4;
8026 save_cpu_state(ctx, 1);
8027 ctx->pc -= 4;
8028 gen_helper_wait(cpu_env);
8029 ctx->bstate = BS_EXCP;
8030 break;
8031 default:
8032 die:
8033 MIPS_INVAL(opn);
8034 generate_exception_end(ctx, EXCP_RI);
8035 return;
8036 }
8037 (void)opn; /* avoid a compiler warning */
8038 }
8039 #endif /* !CONFIG_USER_ONLY */
8040
8041 /* CP1 Branches (before delay slot) */
8042 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
8043 int32_t cc, int32_t offset)
8044 {
8045 target_ulong btarget;
8046 TCGv_i32 t0 = tcg_temp_new_i32();
8047
8048 if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
8049 generate_exception_end(ctx, EXCP_RI);
8050 goto out;
8051 }
8052
8053 if (cc != 0)
8054 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
8055
8056 btarget = ctx->pc + 4 + offset;
8057
8058 switch (op) {
8059 case OPC_BC1F:
8060 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8061 tcg_gen_not_i32(t0, t0);
8062 tcg_gen_andi_i32(t0, t0, 1);
8063 tcg_gen_extu_i32_tl(bcond, t0);
8064 goto not_likely;
8065 case OPC_BC1FL:
8066 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8067 tcg_gen_not_i32(t0, t0);
8068 tcg_gen_andi_i32(t0, t0, 1);
8069 tcg_gen_extu_i32_tl(bcond, t0);
8070 goto likely;
8071 case OPC_BC1T:
8072 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8073 tcg_gen_andi_i32(t0, t0, 1);
8074 tcg_gen_extu_i32_tl(bcond, t0);
8075 goto not_likely;
8076 case OPC_BC1TL:
8077 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8078 tcg_gen_andi_i32(t0, t0, 1);
8079 tcg_gen_extu_i32_tl(bcond, t0);
8080 likely:
8081 ctx->hflags |= MIPS_HFLAG_BL;
8082 break;
8083 case OPC_BC1FANY2:
8084 {
8085 TCGv_i32 t1 = tcg_temp_new_i32();
8086 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8087 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8088 tcg_gen_nand_i32(t0, t0, t1);
8089 tcg_temp_free_i32(t1);
8090 tcg_gen_andi_i32(t0, t0, 1);
8091 tcg_gen_extu_i32_tl(bcond, t0);
8092 }
8093 goto not_likely;
8094 case OPC_BC1TANY2:
8095 {
8096 TCGv_i32 t1 = tcg_temp_new_i32();
8097 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8098 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8099 tcg_gen_or_i32(t0, t0, t1);
8100 tcg_temp_free_i32(t1);
8101 tcg_gen_andi_i32(t0, t0, 1);
8102 tcg_gen_extu_i32_tl(bcond, t0);
8103 }
8104 goto not_likely;
8105 case OPC_BC1FANY4:
8106 {
8107 TCGv_i32 t1 = tcg_temp_new_i32();
8108 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8109 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8110 tcg_gen_and_i32(t0, t0, t1);
8111 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8112 tcg_gen_and_i32(t0, t0, t1);
8113 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8114 tcg_gen_nand_i32(t0, t0, t1);
8115 tcg_temp_free_i32(t1);
8116 tcg_gen_andi_i32(t0, t0, 1);
8117 tcg_gen_extu_i32_tl(bcond, t0);
8118 }
8119 goto not_likely;
8120 case OPC_BC1TANY4:
8121 {
8122 TCGv_i32 t1 = tcg_temp_new_i32();
8123 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
8124 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
8125 tcg_gen_or_i32(t0, t0, t1);
8126 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
8127 tcg_gen_or_i32(t0, t0, t1);
8128 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
8129 tcg_gen_or_i32(t0, t0, t1);
8130 tcg_temp_free_i32(t1);
8131 tcg_gen_andi_i32(t0, t0, 1);
8132 tcg_gen_extu_i32_tl(bcond, t0);
8133 }
8134 not_likely:
8135 ctx->hflags |= MIPS_HFLAG_BC;
8136 break;
8137 default:
8138 MIPS_INVAL("cp1 cond branch");
8139 generate_exception_end(ctx, EXCP_RI);
8140 goto out;
8141 }
8142 ctx->btarget = btarget;
8143 ctx->hflags |= MIPS_HFLAG_BDS32;
8144 out:
8145 tcg_temp_free_i32(t0);
8146 }
8147
8148 /* R6 CP1 Branches */
8149 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
8150 int32_t ft, int32_t offset,
8151 int delayslot_size)
8152 {
8153 target_ulong btarget;
8154 TCGv_i64 t0 = tcg_temp_new_i64();
8155
8156 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8157 #ifdef MIPS_DEBUG_DISAS
8158 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8159 "\n", ctx->pc);
8160 #endif
8161 generate_exception_end(ctx, EXCP_RI);
8162 goto out;
8163 }
8164
8165 gen_load_fpr64(ctx, t0, ft);
8166 tcg_gen_andi_i64(t0, t0, 1);
8167
8168 btarget = addr_add(ctx, ctx->pc + 4, offset);
8169
8170 switch (op) {
8171 case OPC_BC1EQZ:
8172 tcg_gen_xori_i64(t0, t0, 1);
8173 ctx->hflags |= MIPS_HFLAG_BC;
8174 break;
8175 case OPC_BC1NEZ:
8176 /* t0 already set */
8177 ctx->hflags |= MIPS_HFLAG_BC;
8178 break;
8179 default:
8180 MIPS_INVAL("cp1 cond branch");
8181 generate_exception_end(ctx, EXCP_RI);
8182 goto out;
8183 }
8184
8185 tcg_gen_trunc_i64_tl(bcond, t0);
8186
8187 ctx->btarget = btarget;
8188
8189 switch (delayslot_size) {
8190 case 2:
8191 ctx->hflags |= MIPS_HFLAG_BDS16;
8192 break;
8193 case 4:
8194 ctx->hflags |= MIPS_HFLAG_BDS32;
8195 break;
8196 }
8197
8198 out:
8199 tcg_temp_free_i64(t0);
8200 }
8201
8202 /* Coprocessor 1 (FPU) */
8203
8204 #define FOP(func, fmt) (((fmt) << 21) | (func))
8205
8206 enum fopcode {
8207 OPC_ADD_S = FOP(0, FMT_S),
8208 OPC_SUB_S = FOP(1, FMT_S),
8209 OPC_MUL_S = FOP(2, FMT_S),
8210 OPC_DIV_S = FOP(3, FMT_S),
8211 OPC_SQRT_S = FOP(4, FMT_S),
8212 OPC_ABS_S = FOP(5, FMT_S),
8213 OPC_MOV_S = FOP(6, FMT_S),
8214 OPC_NEG_S = FOP(7, FMT_S),
8215 OPC_ROUND_L_S = FOP(8, FMT_S),
8216 OPC_TRUNC_L_S = FOP(9, FMT_S),
8217 OPC_CEIL_L_S = FOP(10, FMT_S),
8218 OPC_FLOOR_L_S = FOP(11, FMT_S),
8219 OPC_ROUND_W_S = FOP(12, FMT_S),
8220 OPC_TRUNC_W_S = FOP(13, FMT_S),
8221 OPC_CEIL_W_S = FOP(14, FMT_S),
8222 OPC_FLOOR_W_S = FOP(15, FMT_S),
8223 OPC_SEL_S = FOP(16, FMT_S),
8224 OPC_MOVCF_S = FOP(17, FMT_S),
8225 OPC_MOVZ_S = FOP(18, FMT_S),
8226 OPC_MOVN_S = FOP(19, FMT_S),
8227 OPC_SELEQZ_S = FOP(20, FMT_S),
8228 OPC_RECIP_S = FOP(21, FMT_S),
8229 OPC_RSQRT_S = FOP(22, FMT_S),
8230 OPC_SELNEZ_S = FOP(23, FMT_S),
8231 OPC_MADDF_S = FOP(24, FMT_S),
8232 OPC_MSUBF_S = FOP(25, FMT_S),
8233 OPC_RINT_S = FOP(26, FMT_S),
8234 OPC_CLASS_S = FOP(27, FMT_S),
8235 OPC_MIN_S = FOP(28, FMT_S),
8236 OPC_RECIP2_S = FOP(28, FMT_S),
8237 OPC_MINA_S = FOP(29, FMT_S),
8238 OPC_RECIP1_S = FOP(29, FMT_S),
8239 OPC_MAX_S = FOP(30, FMT_S),
8240 OPC_RSQRT1_S = FOP(30, FMT_S),
8241 OPC_MAXA_S = FOP(31, FMT_S),
8242 OPC_RSQRT2_S = FOP(31, FMT_S),
8243 OPC_CVT_D_S = FOP(33, FMT_S),
8244 OPC_CVT_W_S = FOP(36, FMT_S),
8245 OPC_CVT_L_S = FOP(37, FMT_S),
8246 OPC_CVT_PS_S = FOP(38, FMT_S),
8247 OPC_CMP_F_S = FOP (48, FMT_S),
8248 OPC_CMP_UN_S = FOP (49, FMT_S),
8249 OPC_CMP_EQ_S = FOP (50, FMT_S),
8250 OPC_CMP_UEQ_S = FOP (51, FMT_S),
8251 OPC_CMP_OLT_S = FOP (52, FMT_S),
8252 OPC_CMP_ULT_S = FOP (53, FMT_S),
8253 OPC_CMP_OLE_S = FOP (54, FMT_S),
8254 OPC_CMP_ULE_S = FOP (55, FMT_S),
8255 OPC_CMP_SF_S = FOP (56, FMT_S),
8256 OPC_CMP_NGLE_S = FOP (57, FMT_S),
8257 OPC_CMP_SEQ_S = FOP (58, FMT_S),
8258 OPC_CMP_NGL_S = FOP (59, FMT_S),
8259 OPC_CMP_LT_S = FOP (60, FMT_S),
8260 OPC_CMP_NGE_S = FOP (61, FMT_S),
8261 OPC_CMP_LE_S = FOP (62, FMT_S),
8262 OPC_CMP_NGT_S = FOP (63, FMT_S),
8263
8264 OPC_ADD_D = FOP(0, FMT_D),
8265 OPC_SUB_D = FOP(1, FMT_D),
8266 OPC_MUL_D = FOP(2, FMT_D),
8267 OPC_DIV_D = FOP(3, FMT_D),
8268 OPC_SQRT_D = FOP(4, FMT_D),
8269 OPC_ABS_D = FOP(5, FMT_D),
8270 OPC_MOV_D = FOP(6, FMT_D),
8271 OPC_NEG_D = FOP(7, FMT_D),
8272 OPC_ROUND_L_D = FOP(8, FMT_D),
8273 OPC_TRUNC_L_D = FOP(9, FMT_D),
8274 OPC_CEIL_L_D = FOP(10, FMT_D),
8275 OPC_FLOOR_L_D = FOP(11, FMT_D),
8276 OPC_ROUND_W_D = FOP(12, FMT_D),
8277 OPC_TRUNC_W_D = FOP(13, FMT_D),
8278 OPC_CEIL_W_D = FOP(14, FMT_D),
8279 OPC_FLOOR_W_D = FOP(15, FMT_D),
8280 OPC_SEL_D = FOP(16, FMT_D),
8281 OPC_MOVCF_D = FOP(17, FMT_D),
8282 OPC_MOVZ_D = FOP(18, FMT_D),
8283 OPC_MOVN_D = FOP(19, FMT_D),
8284 OPC_SELEQZ_D = FOP(20, FMT_D),
8285 OPC_RECIP_D = FOP(21, FMT_D),
8286 OPC_RSQRT_D = FOP(22, FMT_D),
8287 OPC_SELNEZ_D = FOP(23, FMT_D),
8288 OPC_MADDF_D = FOP(24, FMT_D),
8289 OPC_MSUBF_D = FOP(25, FMT_D),
8290 OPC_RINT_D = FOP(26, FMT_D),
8291 OPC_CLASS_D = FOP(27, FMT_D),
8292 OPC_MIN_D = FOP(28, FMT_D),
8293 OPC_RECIP2_D = FOP(28, FMT_D),
8294 OPC_MINA_D = FOP(29, FMT_D),
8295 OPC_RECIP1_D = FOP(29, FMT_D),
8296 OPC_MAX_D = FOP(30, FMT_D),
8297 OPC_RSQRT1_D = FOP(30, FMT_D),
8298 OPC_MAXA_D = FOP(31, FMT_D),
8299 OPC_RSQRT2_D = FOP(31, FMT_D),
8300 OPC_CVT_S_D = FOP(32, FMT_D),
8301 OPC_CVT_W_D = FOP(36, FMT_D),
8302 OPC_CVT_L_D = FOP(37, FMT_D),
8303 OPC_CMP_F_D = FOP (48, FMT_D),
8304 OPC_CMP_UN_D = FOP (49, FMT_D),
8305 OPC_CMP_EQ_D = FOP (50, FMT_D),
8306 OPC_CMP_UEQ_D = FOP (51, FMT_D),
8307 OPC_CMP_OLT_D = FOP (52, FMT_D),
8308 OPC_CMP_ULT_D = FOP (53, FMT_D),
8309 OPC_CMP_OLE_D = FOP (54, FMT_D),
8310 OPC_CMP_ULE_D = FOP (55, FMT_D),
8311 OPC_CMP_SF_D = FOP (56, FMT_D),
8312 OPC_CMP_NGLE_D = FOP (57, FMT_D),
8313 OPC_CMP_SEQ_D = FOP (58, FMT_D),
8314 OPC_CMP_NGL_D = FOP (59, FMT_D),
8315 OPC_CMP_LT_D = FOP (60, FMT_D),
8316 OPC_CMP_NGE_D = FOP (61, FMT_D),
8317 OPC_CMP_LE_D = FOP (62, FMT_D),
8318 OPC_CMP_NGT_D = FOP (63, FMT_D),
8319
8320 OPC_CVT_S_W = FOP(32, FMT_W),
8321 OPC_CVT_D_W = FOP(33, FMT_W),
8322 OPC_CVT_S_L = FOP(32, FMT_L),
8323 OPC_CVT_D_L = FOP(33, FMT_L),
8324 OPC_CVT_PS_PW = FOP(38, FMT_W),
8325
8326 OPC_ADD_PS = FOP(0, FMT_PS),
8327 OPC_SUB_PS = FOP(1, FMT_PS),
8328 OPC_MUL_PS = FOP(2, FMT_PS),
8329 OPC_DIV_PS = FOP(3, FMT_PS),
8330 OPC_ABS_PS = FOP(5, FMT_PS),
8331 OPC_MOV_PS = FOP(6, FMT_PS),
8332 OPC_NEG_PS = FOP(7, FMT_PS),
8333 OPC_MOVCF_PS = FOP(17, FMT_PS),
8334 OPC_MOVZ_PS = FOP(18, FMT_PS),
8335 OPC_MOVN_PS = FOP(19, FMT_PS),
8336 OPC_ADDR_PS = FOP(24, FMT_PS),
8337 OPC_MULR_PS = FOP(26, FMT_PS),
8338 OPC_RECIP2_PS = FOP(28, FMT_PS),
8339 OPC_RECIP1_PS = FOP(29, FMT_PS),
8340 OPC_RSQRT1_PS = FOP(30, FMT_PS),
8341 OPC_RSQRT2_PS = FOP(31, FMT_PS),
8342
8343 OPC_CVT_S_PU = FOP(32, FMT_PS),
8344 OPC_CVT_PW_PS = FOP(36, FMT_PS),
8345 OPC_CVT_S_PL = FOP(40, FMT_PS),
8346 OPC_PLL_PS = FOP(44, FMT_PS),
8347 OPC_PLU_PS = FOP(45, FMT_PS),
8348 OPC_PUL_PS = FOP(46, FMT_PS),
8349 OPC_PUU_PS = FOP(47, FMT_PS),
8350 OPC_CMP_F_PS = FOP (48, FMT_PS),
8351 OPC_CMP_UN_PS = FOP (49, FMT_PS),
8352 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
8353 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
8354 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
8355 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
8356 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
8357 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
8358 OPC_CMP_SF_PS = FOP (56, FMT_PS),
8359 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
8360 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
8361 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
8362 OPC_CMP_LT_PS = FOP (60, FMT_PS),
8363 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
8364 OPC_CMP_LE_PS = FOP (62, FMT_PS),
8365 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
8366 };
8367
8368 enum r6_f_cmp_op {
8369 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
8370 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
8371 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
8372 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
8373 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
8374 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
8375 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
8376 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
8377 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
8378 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
8379 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
8380 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
8381 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
8382 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
8383 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
8384 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
8385 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
8386 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
8387 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
8388 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
8389 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
8390 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
8391
8392 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
8393 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
8394 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
8395 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
8396 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
8397 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
8398 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
8399 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
8400 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
8401 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
8402 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
8403 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
8404 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
8405 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
8406 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
8407 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
8408 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
8409 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
8410 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
8411 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
8412 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
8413 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
8414 };
8415 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
8416 {
8417 TCGv t0 = tcg_temp_new();
8418
8419 switch (opc) {
8420 case OPC_MFC1:
8421 {
8422 TCGv_i32 fp0 = tcg_temp_new_i32();
8423
8424 gen_load_fpr32(ctx, fp0, fs);
8425 tcg_gen_ext_i32_tl(t0, fp0);
8426 tcg_temp_free_i32(fp0);
8427 }
8428 gen_store_gpr(t0, rt);
8429 break;
8430 case OPC_MTC1:
8431 gen_load_gpr(t0, rt);
8432 {
8433 TCGv_i32 fp0 = tcg_temp_new_i32();
8434
8435 tcg_gen_trunc_tl_i32(fp0, t0);
8436 gen_store_fpr32(ctx, fp0, fs);
8437 tcg_temp_free_i32(fp0);
8438 }
8439 break;
8440 case OPC_CFC1:
8441 gen_helper_1e0i(cfc1, t0, fs);
8442 gen_store_gpr(t0, rt);
8443 break;
8444 case OPC_CTC1:
8445 gen_load_gpr(t0, rt);
8446 save_cpu_state(ctx, 0);
8447 {
8448 TCGv_i32 fs_tmp = tcg_const_i32(fs);
8449
8450 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
8451 tcg_temp_free_i32(fs_tmp);
8452 }
8453 /* Stop translation as we may have changed hflags */
8454 ctx->bstate = BS_STOP;
8455 break;
8456 #if defined(TARGET_MIPS64)
8457 case OPC_DMFC1:
8458 gen_load_fpr64(ctx, t0, fs);
8459 gen_store_gpr(t0, rt);
8460 break;
8461 case OPC_DMTC1:
8462 gen_load_gpr(t0, rt);
8463 gen_store_fpr64(ctx, t0, fs);
8464 break;
8465 #endif
8466 case OPC_MFHC1:
8467 {
8468 TCGv_i32 fp0 = tcg_temp_new_i32();
8469
8470 gen_load_fpr32h(ctx, fp0, fs);
8471 tcg_gen_ext_i32_tl(t0, fp0);
8472 tcg_temp_free_i32(fp0);
8473 }
8474 gen_store_gpr(t0, rt);
8475 break;
8476 case OPC_MTHC1:
8477 gen_load_gpr(t0, rt);
8478 {
8479 TCGv_i32 fp0 = tcg_temp_new_i32();
8480
8481 tcg_gen_trunc_tl_i32(fp0, t0);
8482 gen_store_fpr32h(ctx, fp0, fs);
8483 tcg_temp_free_i32(fp0);
8484 }
8485 break;
8486 default:
8487 MIPS_INVAL("cp1 move");
8488 generate_exception_end(ctx, EXCP_RI);
8489 goto out;
8490 }
8491
8492 out:
8493 tcg_temp_free(t0);
8494 }
8495
8496 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8497 {
8498 TCGLabel *l1;
8499 TCGCond cond;
8500 TCGv_i32 t0;
8501
8502 if (rd == 0) {
8503 /* Treat as NOP. */
8504 return;
8505 }
8506
8507 if (tf)
8508 cond = TCG_COND_EQ;
8509 else
8510 cond = TCG_COND_NE;
8511
8512 l1 = gen_new_label();
8513 t0 = tcg_temp_new_i32();
8514 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8515 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8516 tcg_temp_free_i32(t0);
8517 if (rs == 0) {
8518 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8519 } else {
8520 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8521 }
8522 gen_set_label(l1);
8523 }
8524
8525 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
8526 int tf)
8527 {
8528 int cond;
8529 TCGv_i32 t0 = tcg_temp_new_i32();
8530 TCGLabel *l1 = gen_new_label();
8531
8532 if (tf)
8533 cond = TCG_COND_EQ;
8534 else
8535 cond = TCG_COND_NE;
8536
8537 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8538 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8539 gen_load_fpr32(ctx, t0, fs);
8540 gen_store_fpr32(ctx, t0, fd);
8541 gen_set_label(l1);
8542 tcg_temp_free_i32(t0);
8543 }
8544
8545 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8546 {
8547 int cond;
8548 TCGv_i32 t0 = tcg_temp_new_i32();
8549 TCGv_i64 fp0;
8550 TCGLabel *l1 = gen_new_label();
8551
8552 if (tf)
8553 cond = TCG_COND_EQ;
8554 else
8555 cond = TCG_COND_NE;
8556
8557 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8558 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8559 tcg_temp_free_i32(t0);
8560 fp0 = tcg_temp_new_i64();
8561 gen_load_fpr64(ctx, fp0, fs);
8562 gen_store_fpr64(ctx, fp0, fd);
8563 tcg_temp_free_i64(fp0);
8564 gen_set_label(l1);
8565 }
8566
8567 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8568 int cc, int tf)
8569 {
8570 int cond;
8571 TCGv_i32 t0 = tcg_temp_new_i32();
8572 TCGLabel *l1 = gen_new_label();
8573 TCGLabel *l2 = gen_new_label();
8574
8575 if (tf)
8576 cond = TCG_COND_EQ;
8577 else
8578 cond = TCG_COND_NE;
8579
8580 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8581 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8582 gen_load_fpr32(ctx, t0, fs);
8583 gen_store_fpr32(ctx, t0, fd);
8584 gen_set_label(l1);
8585
8586 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8587 tcg_gen_brcondi_i32(cond, t0, 0, l2);
8588 gen_load_fpr32h(ctx, t0, fs);
8589 gen_store_fpr32h(ctx, t0, fd);
8590 tcg_temp_free_i32(t0);
8591 gen_set_label(l2);
8592 }
8593
8594 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8595 int fs)
8596 {
8597 TCGv_i32 t1 = tcg_const_i32(0);
8598 TCGv_i32 fp0 = tcg_temp_new_i32();
8599 TCGv_i32 fp1 = tcg_temp_new_i32();
8600 TCGv_i32 fp2 = tcg_temp_new_i32();
8601 gen_load_fpr32(ctx, fp0, fd);
8602 gen_load_fpr32(ctx, fp1, ft);
8603 gen_load_fpr32(ctx, fp2, fs);
8604
8605 switch (op1) {
8606 case OPC_SEL_S:
8607 tcg_gen_andi_i32(fp0, fp0, 1);
8608 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8609 break;
8610 case OPC_SELEQZ_S:
8611 tcg_gen_andi_i32(fp1, fp1, 1);
8612 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8613 break;
8614 case OPC_SELNEZ_S:
8615 tcg_gen_andi_i32(fp1, fp1, 1);
8616 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8617 break;
8618 default:
8619 MIPS_INVAL("gen_sel_s");
8620 generate_exception_end(ctx, EXCP_RI);
8621 break;
8622 }
8623
8624 gen_store_fpr32(ctx, fp0, fd);
8625 tcg_temp_free_i32(fp2);
8626 tcg_temp_free_i32(fp1);
8627 tcg_temp_free_i32(fp0);
8628 tcg_temp_free_i32(t1);
8629 }
8630
8631 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8632 int fs)
8633 {
8634 TCGv_i64 t1 = tcg_const_i64(0);
8635 TCGv_i64 fp0 = tcg_temp_new_i64();
8636 TCGv_i64 fp1 = tcg_temp_new_i64();
8637 TCGv_i64 fp2 = tcg_temp_new_i64();
8638 gen_load_fpr64(ctx, fp0, fd);
8639 gen_load_fpr64(ctx, fp1, ft);
8640 gen_load_fpr64(ctx, fp2, fs);
8641
8642 switch (op1) {
8643 case OPC_SEL_D:
8644 tcg_gen_andi_i64(fp0, fp0, 1);
8645 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8646 break;
8647 case OPC_SELEQZ_D:
8648 tcg_gen_andi_i64(fp1, fp1, 1);
8649 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8650 break;
8651 case OPC_SELNEZ_D:
8652 tcg_gen_andi_i64(fp1, fp1, 1);
8653 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8654 break;
8655 default:
8656 MIPS_INVAL("gen_sel_d");
8657 generate_exception_end(ctx, EXCP_RI);
8658 break;
8659 }
8660
8661 gen_store_fpr64(ctx, fp0, fd);
8662 tcg_temp_free_i64(fp2);
8663 tcg_temp_free_i64(fp1);
8664 tcg_temp_free_i64(fp0);
8665 tcg_temp_free_i64(t1);
8666 }
8667
8668 static void gen_farith (DisasContext *ctx, enum fopcode op1,
8669 int ft, int fs, int fd, int cc)
8670 {
8671 uint32_t func = ctx->opcode & 0x3f;
8672 switch (op1) {
8673 case OPC_ADD_S:
8674 {
8675 TCGv_i32 fp0 = tcg_temp_new_i32();
8676 TCGv_i32 fp1 = tcg_temp_new_i32();
8677
8678 gen_load_fpr32(ctx, fp0, fs);
8679 gen_load_fpr32(ctx, fp1, ft);
8680 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8681 tcg_temp_free_i32(fp1);
8682 gen_store_fpr32(ctx, fp0, fd);
8683 tcg_temp_free_i32(fp0);
8684 }
8685 break;
8686 case OPC_SUB_S:
8687 {
8688 TCGv_i32 fp0 = tcg_temp_new_i32();
8689 TCGv_i32 fp1 = tcg_temp_new_i32();
8690
8691 gen_load_fpr32(ctx, fp0, fs);
8692 gen_load_fpr32(ctx, fp1, ft);
8693 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8694 tcg_temp_free_i32(fp1);
8695 gen_store_fpr32(ctx, fp0, fd);
8696 tcg_temp_free_i32(fp0);
8697 }
8698 break;
8699 case OPC_MUL_S:
8700 {
8701 TCGv_i32 fp0 = tcg_temp_new_i32();
8702 TCGv_i32 fp1 = tcg_temp_new_i32();
8703
8704 gen_load_fpr32(ctx, fp0, fs);
8705 gen_load_fpr32(ctx, fp1, ft);
8706 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8707 tcg_temp_free_i32(fp1);
8708 gen_store_fpr32(ctx, fp0, fd);
8709 tcg_temp_free_i32(fp0);
8710 }
8711 break;
8712 case OPC_DIV_S:
8713 {
8714 TCGv_i32 fp0 = tcg_temp_new_i32();
8715 TCGv_i32 fp1 = tcg_temp_new_i32();
8716
8717 gen_load_fpr32(ctx, fp0, fs);
8718 gen_load_fpr32(ctx, fp1, ft);
8719 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8720 tcg_temp_free_i32(fp1);
8721 gen_store_fpr32(ctx, fp0, fd);
8722 tcg_temp_free_i32(fp0);
8723 }
8724 break;
8725 case OPC_SQRT_S:
8726 {
8727 TCGv_i32 fp0 = tcg_temp_new_i32();
8728
8729 gen_load_fpr32(ctx, fp0, fs);
8730 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8731 gen_store_fpr32(ctx, fp0, fd);
8732 tcg_temp_free_i32(fp0);
8733 }
8734 break;
8735 case OPC_ABS_S:
8736 {
8737 TCGv_i32 fp0 = tcg_temp_new_i32();
8738
8739 gen_load_fpr32(ctx, fp0, fs);
8740 gen_helper_float_abs_s(fp0, fp0);
8741 gen_store_fpr32(ctx, fp0, fd);
8742 tcg_temp_free_i32(fp0);
8743 }
8744 break;
8745 case OPC_MOV_S:
8746 {
8747 TCGv_i32 fp0 = tcg_temp_new_i32();
8748
8749 gen_load_fpr32(ctx, fp0, fs);
8750 gen_store_fpr32(ctx, fp0, fd);
8751 tcg_temp_free_i32(fp0);
8752 }
8753 break;
8754 case OPC_NEG_S:
8755 {
8756 TCGv_i32 fp0 = tcg_temp_new_i32();
8757
8758 gen_load_fpr32(ctx, fp0, fs);
8759 gen_helper_float_chs_s(fp0, fp0);
8760 gen_store_fpr32(ctx, fp0, fd);
8761 tcg_temp_free_i32(fp0);
8762 }
8763 break;
8764 case OPC_ROUND_L_S:
8765 check_cp1_64bitmode(ctx);
8766 {
8767 TCGv_i32 fp32 = tcg_temp_new_i32();
8768 TCGv_i64 fp64 = tcg_temp_new_i64();
8769
8770 gen_load_fpr32(ctx, fp32, fs);
8771 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
8772 tcg_temp_free_i32(fp32);
8773 gen_store_fpr64(ctx, fp64, fd);
8774 tcg_temp_free_i64(fp64);
8775 }
8776 break;
8777 case OPC_TRUNC_L_S:
8778 check_cp1_64bitmode(ctx);
8779 {
8780 TCGv_i32 fp32 = tcg_temp_new_i32();
8781 TCGv_i64 fp64 = tcg_temp_new_i64();
8782
8783 gen_load_fpr32(ctx, fp32, fs);
8784 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
8785 tcg_temp_free_i32(fp32);
8786 gen_store_fpr64(ctx, fp64, fd);
8787 tcg_temp_free_i64(fp64);
8788 }
8789 break;
8790 case OPC_CEIL_L_S:
8791 check_cp1_64bitmode(ctx);
8792 {
8793 TCGv_i32 fp32 = tcg_temp_new_i32();
8794 TCGv_i64 fp64 = tcg_temp_new_i64();
8795
8796 gen_load_fpr32(ctx, fp32, fs);
8797 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
8798 tcg_temp_free_i32(fp32);
8799 gen_store_fpr64(ctx, fp64, fd);
8800 tcg_temp_free_i64(fp64);
8801 }
8802 break;
8803 case OPC_FLOOR_L_S:
8804 check_cp1_64bitmode(ctx);
8805 {
8806 TCGv_i32 fp32 = tcg_temp_new_i32();
8807 TCGv_i64 fp64 = tcg_temp_new_i64();
8808
8809 gen_load_fpr32(ctx, fp32, fs);
8810 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
8811 tcg_temp_free_i32(fp32);
8812 gen_store_fpr64(ctx, fp64, fd);
8813 tcg_temp_free_i64(fp64);
8814 }
8815 break;
8816 case OPC_ROUND_W_S:
8817 {
8818 TCGv_i32 fp0 = tcg_temp_new_i32();
8819
8820 gen_load_fpr32(ctx, fp0, fs);
8821 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
8822 gen_store_fpr32(ctx, fp0, fd);
8823 tcg_temp_free_i32(fp0);
8824 }
8825 break;
8826 case OPC_TRUNC_W_S:
8827 {
8828 TCGv_i32 fp0 = tcg_temp_new_i32();
8829
8830 gen_load_fpr32(ctx, fp0, fs);
8831 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
8832 gen_store_fpr32(ctx, fp0, fd);
8833 tcg_temp_free_i32(fp0);
8834 }
8835 break;
8836 case OPC_CEIL_W_S:
8837 {
8838 TCGv_i32 fp0 = tcg_temp_new_i32();
8839
8840 gen_load_fpr32(ctx, fp0, fs);
8841 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
8842 gen_store_fpr32(ctx, fp0, fd);
8843 tcg_temp_free_i32(fp0);
8844 }
8845 break;
8846 case OPC_FLOOR_W_S:
8847 {
8848 TCGv_i32 fp0 = tcg_temp_new_i32();
8849
8850 gen_load_fpr32(ctx, fp0, fs);
8851 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
8852 gen_store_fpr32(ctx, fp0, fd);
8853 tcg_temp_free_i32(fp0);
8854 }
8855 break;
8856 case OPC_SEL_S:
8857 check_insn(ctx, ISA_MIPS32R6);
8858 gen_sel_s(ctx, op1, fd, ft, fs);
8859 break;
8860 case OPC_SELEQZ_S:
8861 check_insn(ctx, ISA_MIPS32R6);
8862 gen_sel_s(ctx, op1, fd, ft, fs);
8863 break;
8864 case OPC_SELNEZ_S:
8865 check_insn(ctx, ISA_MIPS32R6);
8866 gen_sel_s(ctx, op1, fd, ft, fs);
8867 break;
8868 case OPC_MOVCF_S:
8869 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8870 gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8871 break;
8872 case OPC_MOVZ_S:
8873 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8874 {
8875 TCGLabel *l1 = gen_new_label();
8876 TCGv_i32 fp0;
8877
8878 if (ft != 0) {
8879 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8880 }
8881 fp0 = tcg_temp_new_i32();
8882 gen_load_fpr32(ctx, fp0, fs);
8883 gen_store_fpr32(ctx, fp0, fd);
8884 tcg_temp_free_i32(fp0);
8885 gen_set_label(l1);
8886 }
8887 break;
8888 case OPC_MOVN_S:
8889 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8890 {
8891 TCGLabel *l1 = gen_new_label();
8892 TCGv_i32 fp0;
8893
8894 if (ft != 0) {
8895 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8896 fp0 = tcg_temp_new_i32();
8897 gen_load_fpr32(ctx, fp0, fs);
8898 gen_store_fpr32(ctx, fp0, fd);
8899 tcg_temp_free_i32(fp0);
8900 gen_set_label(l1);
8901 }
8902 }
8903 break;
8904 case OPC_RECIP_S:
8905 {
8906 TCGv_i32 fp0 = tcg_temp_new_i32();
8907
8908 gen_load_fpr32(ctx, fp0, fs);
8909 gen_helper_float_recip_s(fp0, cpu_env, fp0);
8910 gen_store_fpr32(ctx, fp0, fd);
8911 tcg_temp_free_i32(fp0);
8912 }
8913 break;
8914 case OPC_RSQRT_S:
8915 {
8916 TCGv_i32 fp0 = tcg_temp_new_i32();
8917
8918 gen_load_fpr32(ctx, fp0, fs);
8919 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
8920 gen_store_fpr32(ctx, fp0, fd);
8921 tcg_temp_free_i32(fp0);
8922 }
8923 break;
8924 case OPC_MADDF_S:
8925 check_insn(ctx, ISA_MIPS32R6);
8926 {
8927 TCGv_i32 fp0 = tcg_temp_new_i32();
8928 TCGv_i32 fp1 = tcg_temp_new_i32();
8929 TCGv_i32 fp2 = tcg_temp_new_i32();
8930 gen_load_fpr32(ctx, fp0, fs);
8931 gen_load_fpr32(ctx, fp1, ft);
8932 gen_load_fpr32(ctx, fp2, fd);
8933 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
8934 gen_store_fpr32(ctx, fp2, fd);
8935 tcg_temp_free_i32(fp2);
8936 tcg_temp_free_i32(fp1);
8937 tcg_temp_free_i32(fp0);
8938 }
8939 break;
8940 case OPC_MSUBF_S:
8941 check_insn(ctx, ISA_MIPS32R6);
8942 {
8943 TCGv_i32 fp0 = tcg_temp_new_i32();
8944 TCGv_i32 fp1 = tcg_temp_new_i32();
8945 TCGv_i32 fp2 = tcg_temp_new_i32();
8946 gen_load_fpr32(ctx, fp0, fs);
8947 gen_load_fpr32(ctx, fp1, ft);
8948 gen_load_fpr32(ctx, fp2, fd);
8949 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
8950 gen_store_fpr32(ctx, fp2, fd);
8951 tcg_temp_free_i32(fp2);
8952 tcg_temp_free_i32(fp1);
8953 tcg_temp_free_i32(fp0);
8954 }
8955 break;
8956 case OPC_RINT_S:
8957 check_insn(ctx, ISA_MIPS32R6);
8958 {
8959 TCGv_i32 fp0 = tcg_temp_new_i32();
8960 gen_load_fpr32(ctx, fp0, fs);
8961 gen_helper_float_rint_s(fp0, cpu_env, fp0);
8962 gen_store_fpr32(ctx, fp0, fd);
8963 tcg_temp_free_i32(fp0);
8964 }
8965 break;
8966 case OPC_CLASS_S:
8967 check_insn(ctx, ISA_MIPS32R6);
8968 {
8969 TCGv_i32 fp0 = tcg_temp_new_i32();
8970 gen_load_fpr32(ctx, fp0, fs);
8971 gen_helper_float_class_s(fp0, fp0);
8972 gen_store_fpr32(ctx, fp0, fd);
8973 tcg_temp_free_i32(fp0);
8974 }
8975 break;
8976 case OPC_MIN_S: /* OPC_RECIP2_S */
8977 if (ctx->insn_flags & ISA_MIPS32R6) {
8978 /* OPC_MIN_S */
8979 TCGv_i32 fp0 = tcg_temp_new_i32();
8980 TCGv_i32 fp1 = tcg_temp_new_i32();
8981 TCGv_i32 fp2 = tcg_temp_new_i32();
8982 gen_load_fpr32(ctx, fp0, fs);
8983 gen_load_fpr32(ctx, fp1, ft);
8984 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
8985 gen_store_fpr32(ctx, fp2, fd);
8986 tcg_temp_free_i32(fp2);
8987 tcg_temp_free_i32(fp1);
8988 tcg_temp_free_i32(fp0);
8989 } else {
8990 /* OPC_RECIP2_S */
8991 check_cp1_64bitmode(ctx);
8992 {
8993 TCGv_i32 fp0 = tcg_temp_new_i32();
8994 TCGv_i32 fp1 = tcg_temp_new_i32();
8995
8996 gen_load_fpr32(ctx, fp0, fs);
8997 gen_load_fpr32(ctx, fp1, ft);
8998 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
8999 tcg_temp_free_i32(fp1);
9000 gen_store_fpr32(ctx, fp0, fd);
9001 tcg_temp_free_i32(fp0);
9002 }
9003 }
9004 break;
9005 case OPC_MINA_S: /* OPC_RECIP1_S */
9006 if (ctx->insn_flags & ISA_MIPS32R6) {
9007 /* OPC_MINA_S */
9008 TCGv_i32 fp0 = tcg_temp_new_i32();
9009 TCGv_i32 fp1 = tcg_temp_new_i32();
9010 TCGv_i32 fp2 = tcg_temp_new_i32();
9011 gen_load_fpr32(ctx, fp0, fs);
9012 gen_load_fpr32(ctx, fp1, ft);
9013 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
9014 gen_store_fpr32(ctx, fp2, fd);
9015 tcg_temp_free_i32(fp2);
9016 tcg_temp_free_i32(fp1);
9017 tcg_temp_free_i32(fp0);
9018 } else {
9019 /* OPC_RECIP1_S */
9020 check_cp1_64bitmode(ctx);
9021 {
9022 TCGv_i32 fp0 = tcg_temp_new_i32();
9023
9024 gen_load_fpr32(ctx, fp0, fs);
9025 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
9026 gen_store_fpr32(ctx, fp0, fd);
9027 tcg_temp_free_i32(fp0);
9028 }
9029 }
9030 break;
9031 case OPC_MAX_S: /* OPC_RSQRT1_S */
9032 if (ctx->insn_flags & ISA_MIPS32R6) {
9033 /* OPC_MAX_S */
9034 TCGv_i32 fp0 = tcg_temp_new_i32();
9035 TCGv_i32 fp1 = tcg_temp_new_i32();
9036 gen_load_fpr32(ctx, fp0, fs);
9037 gen_load_fpr32(ctx, fp1, ft);
9038 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
9039 gen_store_fpr32(ctx, fp1, fd);
9040 tcg_temp_free_i32(fp1);
9041 tcg_temp_free_i32(fp0);
9042 } else {
9043 /* OPC_RSQRT1_S */
9044 check_cp1_64bitmode(ctx);
9045 {
9046 TCGv_i32 fp0 = tcg_temp_new_i32();
9047
9048 gen_load_fpr32(ctx, fp0, fs);
9049 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
9050 gen_store_fpr32(ctx, fp0, fd);
9051 tcg_temp_free_i32(fp0);
9052 }
9053 }
9054 break;
9055 case OPC_MAXA_S: /* OPC_RSQRT2_S */
9056 if (ctx->insn_flags & ISA_MIPS32R6) {
9057 /* OPC_MAXA_S */
9058 TCGv_i32 fp0 = tcg_temp_new_i32();
9059 TCGv_i32 fp1 = tcg_temp_new_i32();
9060 gen_load_fpr32(ctx, fp0, fs);
9061 gen_load_fpr32(ctx, fp1, ft);
9062 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
9063 gen_store_fpr32(ctx, fp1, fd);
9064 tcg_temp_free_i32(fp1);
9065 tcg_temp_free_i32(fp0);
9066 } else {
9067 /* OPC_RSQRT2_S */
9068 check_cp1_64bitmode(ctx);
9069 {
9070 TCGv_i32 fp0 = tcg_temp_new_i32();
9071 TCGv_i32 fp1 = tcg_temp_new_i32();
9072
9073 gen_load_fpr32(ctx, fp0, fs);
9074 gen_load_fpr32(ctx, fp1, ft);
9075 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
9076 tcg_temp_free_i32(fp1);
9077 gen_store_fpr32(ctx, fp0, fd);
9078 tcg_temp_free_i32(fp0);
9079 }
9080 }
9081 break;
9082 case OPC_CVT_D_S:
9083 check_cp1_registers(ctx, fd);
9084 {
9085 TCGv_i32 fp32 = tcg_temp_new_i32();
9086 TCGv_i64 fp64 = tcg_temp_new_i64();
9087
9088 gen_load_fpr32(ctx, fp32, fs);
9089 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
9090 tcg_temp_free_i32(fp32);
9091 gen_store_fpr64(ctx, fp64, fd);
9092 tcg_temp_free_i64(fp64);
9093 }
9094 break;
9095 case OPC_CVT_W_S:
9096 {
9097 TCGv_i32 fp0 = tcg_temp_new_i32();
9098
9099 gen_load_fpr32(ctx, fp0, fs);
9100 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
9101 gen_store_fpr32(ctx, fp0, fd);
9102 tcg_temp_free_i32(fp0);
9103 }
9104 break;
9105 case OPC_CVT_L_S:
9106 check_cp1_64bitmode(ctx);
9107 {
9108 TCGv_i32 fp32 = tcg_temp_new_i32();
9109 TCGv_i64 fp64 = tcg_temp_new_i64();
9110
9111 gen_load_fpr32(ctx, fp32, fs);
9112 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
9113 tcg_temp_free_i32(fp32);
9114 gen_store_fpr64(ctx, fp64, fd);
9115 tcg_temp_free_i64(fp64);
9116 }
9117 break;
9118 case OPC_CVT_PS_S:
9119 check_ps(ctx);
9120 {
9121 TCGv_i64 fp64 = tcg_temp_new_i64();
9122 TCGv_i32 fp32_0 = tcg_temp_new_i32();
9123 TCGv_i32 fp32_1 = tcg_temp_new_i32();
9124
9125 gen_load_fpr32(ctx, fp32_0, fs);
9126 gen_load_fpr32(ctx, fp32_1, ft);
9127 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
9128 tcg_temp_free_i32(fp32_1);
9129 tcg_temp_free_i32(fp32_0);
9130 gen_store_fpr64(ctx, fp64, fd);
9131 tcg_temp_free_i64(fp64);
9132 }
9133 break;
9134 case OPC_CMP_F_S:
9135 case OPC_CMP_UN_S:
9136 case OPC_CMP_EQ_S:
9137 case OPC_CMP_UEQ_S:
9138 case OPC_CMP_OLT_S:
9139 case OPC_CMP_ULT_S:
9140 case OPC_CMP_OLE_S:
9141 case OPC_CMP_ULE_S:
9142 case OPC_CMP_SF_S:
9143 case OPC_CMP_NGLE_S:
9144 case OPC_CMP_SEQ_S:
9145 case OPC_CMP_NGL_S:
9146 case OPC_CMP_LT_S:
9147 case OPC_CMP_NGE_S:
9148 case OPC_CMP_LE_S:
9149 case OPC_CMP_NGT_S:
9150 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9151 if (ctx->opcode & (1 << 6)) {
9152 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
9153 } else {
9154 gen_cmp_s(ctx, func-48, ft, fs, cc);
9155 }
9156 break;
9157 case OPC_ADD_D:
9158 check_cp1_registers(ctx, fs | ft | fd);
9159 {
9160 TCGv_i64 fp0 = tcg_temp_new_i64();
9161 TCGv_i64 fp1 = tcg_temp_new_i64();
9162
9163 gen_load_fpr64(ctx, fp0, fs);
9164 gen_load_fpr64(ctx, fp1, ft);
9165 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
9166 tcg_temp_free_i64(fp1);
9167 gen_store_fpr64(ctx, fp0, fd);
9168 tcg_temp_free_i64(fp0);
9169 }
9170 break;
9171 case OPC_SUB_D:
9172 check_cp1_registers(ctx, fs | ft | fd);
9173 {
9174 TCGv_i64 fp0 = tcg_temp_new_i64();
9175 TCGv_i64 fp1 = tcg_temp_new_i64();
9176
9177 gen_load_fpr64(ctx, fp0, fs);
9178 gen_load_fpr64(ctx, fp1, ft);
9179 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
9180 tcg_temp_free_i64(fp1);
9181 gen_store_fpr64(ctx, fp0, fd);
9182 tcg_temp_free_i64(fp0);
9183 }
9184 break;
9185 case OPC_MUL_D:
9186 check_cp1_registers(ctx, fs | ft | fd);
9187 {
9188 TCGv_i64 fp0 = tcg_temp_new_i64();
9189 TCGv_i64 fp1 = tcg_temp_new_i64();
9190
9191 gen_load_fpr64(ctx, fp0, fs);
9192 gen_load_fpr64(ctx, fp1, ft);
9193 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
9194 tcg_temp_free_i64(fp1);
9195 gen_store_fpr64(ctx, fp0, fd);
9196 tcg_temp_free_i64(fp0);
9197 }
9198 break;
9199 case OPC_DIV_D:
9200 check_cp1_registers(ctx, fs | ft | fd);
9201 {
9202 TCGv_i64 fp0 = tcg_temp_new_i64();
9203 TCGv_i64 fp1 = tcg_temp_new_i64();
9204
9205 gen_load_fpr64(ctx, fp0, fs);
9206 gen_load_fpr64(ctx, fp1, ft);
9207 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
9208 tcg_temp_free_i64(fp1);
9209 gen_store_fpr64(ctx, fp0, fd);
9210 tcg_temp_free_i64(fp0);
9211 }
9212 break;
9213 case OPC_SQRT_D:
9214 check_cp1_registers(ctx, fs | fd);
9215 {
9216 TCGv_i64 fp0 = tcg_temp_new_i64();
9217
9218 gen_load_fpr64(ctx, fp0, fs);
9219 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
9220 gen_store_fpr64(ctx, fp0, fd);
9221 tcg_temp_free_i64(fp0);
9222 }
9223 break;
9224 case OPC_ABS_D:
9225 check_cp1_registers(ctx, fs | fd);
9226 {
9227 TCGv_i64 fp0 = tcg_temp_new_i64();
9228
9229 gen_load_fpr64(ctx, fp0, fs);
9230 gen_helper_float_abs_d(fp0, fp0);
9231 gen_store_fpr64(ctx, fp0, fd);
9232 tcg_temp_free_i64(fp0);
9233 }
9234 break;
9235 case OPC_MOV_D:
9236 check_cp1_registers(ctx, fs | fd);
9237 {
9238 TCGv_i64 fp0 = tcg_temp_new_i64();
9239
9240 gen_load_fpr64(ctx, fp0, fs);
9241 gen_store_fpr64(ctx, fp0, fd);
9242 tcg_temp_free_i64(fp0);
9243 }
9244 break;
9245 case OPC_NEG_D:
9246 check_cp1_registers(ctx, fs | fd);
9247 {
9248 TCGv_i64 fp0 = tcg_temp_new_i64();
9249
9250 gen_load_fpr64(ctx, fp0, fs);
9251 gen_helper_float_chs_d(fp0, fp0);
9252 gen_store_fpr64(ctx, fp0, fd);
9253 tcg_temp_free_i64(fp0);
9254 }
9255 break;
9256 case OPC_ROUND_L_D:
9257 check_cp1_64bitmode(ctx);
9258 {
9259 TCGv_i64 fp0 = tcg_temp_new_i64();
9260
9261 gen_load_fpr64(ctx, fp0, fs);
9262 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
9263 gen_store_fpr64(ctx, fp0, fd);
9264 tcg_temp_free_i64(fp0);
9265 }
9266 break;
9267 case OPC_TRUNC_L_D:
9268 check_cp1_64bitmode(ctx);
9269 {
9270 TCGv_i64 fp0 = tcg_temp_new_i64();
9271
9272 gen_load_fpr64(ctx, fp0, fs);
9273 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
9274 gen_store_fpr64(ctx, fp0, fd);
9275 tcg_temp_free_i64(fp0);
9276 }
9277 break;
9278 case OPC_CEIL_L_D:
9279 check_cp1_64bitmode(ctx);
9280 {
9281 TCGv_i64 fp0 = tcg_temp_new_i64();
9282
9283 gen_load_fpr64(ctx, fp0, fs);
9284 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
9285 gen_store_fpr64(ctx, fp0, fd);
9286 tcg_temp_free_i64(fp0);
9287 }
9288 break;
9289 case OPC_FLOOR_L_D:
9290 check_cp1_64bitmode(ctx);
9291 {
9292 TCGv_i64 fp0 = tcg_temp_new_i64();
9293
9294 gen_load_fpr64(ctx, fp0, fs);
9295 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
9296 gen_store_fpr64(ctx, fp0, fd);
9297 tcg_temp_free_i64(fp0);
9298 }
9299 break;
9300 case OPC_ROUND_W_D:
9301 check_cp1_registers(ctx, fs);
9302 {
9303 TCGv_i32 fp32 = tcg_temp_new_i32();
9304 TCGv_i64 fp64 = tcg_temp_new_i64();
9305
9306 gen_load_fpr64(ctx, fp64, fs);
9307 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
9308 tcg_temp_free_i64(fp64);
9309 gen_store_fpr32(ctx, fp32, fd);
9310 tcg_temp_free_i32(fp32);
9311 }
9312 break;
9313 case OPC_TRUNC_W_D:
9314 check_cp1_registers(ctx, fs);
9315 {
9316 TCGv_i32 fp32 = tcg_temp_new_i32();
9317 TCGv_i64 fp64 = tcg_temp_new_i64();
9318
9319 gen_load_fpr64(ctx, fp64, fs);
9320 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
9321 tcg_temp_free_i64(fp64);
9322 gen_store_fpr32(ctx, fp32, fd);
9323 tcg_temp_free_i32(fp32);
9324 }
9325 break;
9326 case OPC_CEIL_W_D:
9327 check_cp1_registers(ctx, fs);
9328 {
9329 TCGv_i32 fp32 = tcg_temp_new_i32();
9330 TCGv_i64 fp64 = tcg_temp_new_i64();
9331
9332 gen_load_fpr64(ctx, fp64, fs);
9333 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
9334 tcg_temp_free_i64(fp64);
9335 gen_store_fpr32(ctx, fp32, fd);
9336 tcg_temp_free_i32(fp32);
9337 }
9338 break;
9339 case OPC_FLOOR_W_D:
9340 check_cp1_registers(ctx, fs);
9341 {
9342 TCGv_i32 fp32 = tcg_temp_new_i32();
9343 TCGv_i64 fp64 = tcg_temp_new_i64();
9344
9345 gen_load_fpr64(ctx, fp64, fs);
9346 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
9347 tcg_temp_free_i64(fp64);
9348 gen_store_fpr32(ctx, fp32, fd);
9349 tcg_temp_free_i32(fp32);
9350 }
9351 break;
9352 case OPC_SEL_D:
9353 check_insn(ctx, ISA_MIPS32R6);
9354 gen_sel_d(ctx, op1, fd, ft, fs);
9355 break;
9356 case OPC_SELEQZ_D:
9357 check_insn(ctx, ISA_MIPS32R6);
9358 gen_sel_d(ctx, op1, fd, ft, fs);
9359 break;
9360 case OPC_SELNEZ_D:
9361 check_insn(ctx, ISA_MIPS32R6);
9362 gen_sel_d(ctx, op1, fd, ft, fs);
9363 break;
9364 case OPC_MOVCF_D:
9365 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9366 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9367 break;
9368 case OPC_MOVZ_D:
9369 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9370 {
9371 TCGLabel *l1 = gen_new_label();
9372 TCGv_i64 fp0;
9373
9374 if (ft != 0) {
9375 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9376 }
9377 fp0 = tcg_temp_new_i64();
9378 gen_load_fpr64(ctx, fp0, fs);
9379 gen_store_fpr64(ctx, fp0, fd);
9380 tcg_temp_free_i64(fp0);
9381 gen_set_label(l1);
9382 }
9383 break;
9384 case OPC_MOVN_D:
9385 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9386 {
9387 TCGLabel *l1 = gen_new_label();
9388 TCGv_i64 fp0;
9389
9390 if (ft != 0) {
9391 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9392 fp0 = tcg_temp_new_i64();
9393 gen_load_fpr64(ctx, fp0, fs);
9394 gen_store_fpr64(ctx, fp0, fd);
9395 tcg_temp_free_i64(fp0);
9396 gen_set_label(l1);
9397 }
9398 }
9399 break;
9400 case OPC_RECIP_D:
9401 check_cp1_registers(ctx, fs | fd);
9402 {
9403 TCGv_i64 fp0 = tcg_temp_new_i64();
9404
9405 gen_load_fpr64(ctx, fp0, fs);
9406 gen_helper_float_recip_d(fp0, cpu_env, fp0);
9407 gen_store_fpr64(ctx, fp0, fd);
9408 tcg_temp_free_i64(fp0);
9409 }
9410 break;
9411 case OPC_RSQRT_D:
9412 check_cp1_registers(ctx, fs | fd);
9413 {
9414 TCGv_i64 fp0 = tcg_temp_new_i64();
9415
9416 gen_load_fpr64(ctx, fp0, fs);
9417 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9418 gen_store_fpr64(ctx, fp0, fd);
9419 tcg_temp_free_i64(fp0);
9420 }
9421 break;
9422 case OPC_MADDF_D:
9423 check_insn(ctx, ISA_MIPS32R6);
9424 {
9425 TCGv_i64 fp0 = tcg_temp_new_i64();
9426 TCGv_i64 fp1 = tcg_temp_new_i64();
9427 TCGv_i64 fp2 = tcg_temp_new_i64();
9428 gen_load_fpr64(ctx, fp0, fs);
9429 gen_load_fpr64(ctx, fp1, ft);
9430 gen_load_fpr64(ctx, fp2, fd);
9431 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9432 gen_store_fpr64(ctx, fp2, fd);
9433 tcg_temp_free_i64(fp2);
9434 tcg_temp_free_i64(fp1);
9435 tcg_temp_free_i64(fp0);
9436 }
9437 break;
9438 case OPC_MSUBF_D:
9439 check_insn(ctx, ISA_MIPS32R6);
9440 {
9441 TCGv_i64 fp0 = tcg_temp_new_i64();
9442 TCGv_i64 fp1 = tcg_temp_new_i64();
9443 TCGv_i64 fp2 = tcg_temp_new_i64();
9444 gen_load_fpr64(ctx, fp0, fs);
9445 gen_load_fpr64(ctx, fp1, ft);
9446 gen_load_fpr64(ctx, fp2, fd);
9447 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9448 gen_store_fpr64(ctx, fp2, fd);
9449 tcg_temp_free_i64(fp2);
9450 tcg_temp_free_i64(fp1);
9451 tcg_temp_free_i64(fp0);
9452 }
9453 break;
9454 case OPC_RINT_D:
9455 check_insn(ctx, ISA_MIPS32R6);
9456 {
9457 TCGv_i64 fp0 = tcg_temp_new_i64();
9458 gen_load_fpr64(ctx, fp0, fs);
9459 gen_helper_float_rint_d(fp0, cpu_env, fp0);
9460 gen_store_fpr64(ctx, fp0, fd);
9461 tcg_temp_free_i64(fp0);
9462 }
9463 break;
9464 case OPC_CLASS_D:
9465 check_insn(ctx, ISA_MIPS32R6);
9466 {
9467 TCGv_i64 fp0 = tcg_temp_new_i64();
9468 gen_load_fpr64(ctx, fp0, fs);
9469 gen_helper_float_class_d(fp0, fp0);
9470 gen_store_fpr64(ctx, fp0, fd);
9471 tcg_temp_free_i64(fp0);
9472 }
9473 break;
9474 case OPC_MIN_D: /* OPC_RECIP2_D */
9475 if (ctx->insn_flags & ISA_MIPS32R6) {
9476 /* OPC_MIN_D */
9477 TCGv_i64 fp0 = tcg_temp_new_i64();
9478 TCGv_i64 fp1 = tcg_temp_new_i64();
9479 gen_load_fpr64(ctx, fp0, fs);
9480 gen_load_fpr64(ctx, fp1, ft);
9481 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9482 gen_store_fpr64(ctx, fp1, fd);
9483 tcg_temp_free_i64(fp1);
9484 tcg_temp_free_i64(fp0);
9485 } else {
9486 /* OPC_RECIP2_D */
9487 check_cp1_64bitmode(ctx);
9488 {
9489 TCGv_i64 fp0 = tcg_temp_new_i64();
9490 TCGv_i64 fp1 = tcg_temp_new_i64();
9491
9492 gen_load_fpr64(ctx, fp0, fs);
9493 gen_load_fpr64(ctx, fp1, ft);
9494 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9495 tcg_temp_free_i64(fp1);
9496 gen_store_fpr64(ctx, fp0, fd);
9497 tcg_temp_free_i64(fp0);
9498 }
9499 }
9500 break;
9501 case OPC_MINA_D: /* OPC_RECIP1_D */
9502 if (ctx->insn_flags & ISA_MIPS32R6) {
9503 /* OPC_MINA_D */
9504 TCGv_i64 fp0 = tcg_temp_new_i64();
9505 TCGv_i64 fp1 = tcg_temp_new_i64();
9506 gen_load_fpr64(ctx, fp0, fs);
9507 gen_load_fpr64(ctx, fp1, ft);
9508 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9509 gen_store_fpr64(ctx, fp1, fd);
9510 tcg_temp_free_i64(fp1);
9511 tcg_temp_free_i64(fp0);
9512 } else {
9513 /* OPC_RECIP1_D */
9514 check_cp1_64bitmode(ctx);
9515 {
9516 TCGv_i64 fp0 = tcg_temp_new_i64();
9517
9518 gen_load_fpr64(ctx, fp0, fs);
9519 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9520 gen_store_fpr64(ctx, fp0, fd);
9521 tcg_temp_free_i64(fp0);
9522 }
9523 }
9524 break;
9525 case OPC_MAX_D: /* OPC_RSQRT1_D */
9526 if (ctx->insn_flags & ISA_MIPS32R6) {
9527 /* OPC_MAX_D */
9528 TCGv_i64 fp0 = tcg_temp_new_i64();
9529 TCGv_i64 fp1 = tcg_temp_new_i64();
9530 gen_load_fpr64(ctx, fp0, fs);
9531 gen_load_fpr64(ctx, fp1, ft);
9532 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9533 gen_store_fpr64(ctx, fp1, fd);
9534 tcg_temp_free_i64(fp1);
9535 tcg_temp_free_i64(fp0);
9536 } else {
9537 /* OPC_RSQRT1_D */
9538 check_cp1_64bitmode(ctx);
9539 {
9540 TCGv_i64 fp0 = tcg_temp_new_i64();
9541
9542 gen_load_fpr64(ctx, fp0, fs);
9543 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9544 gen_store_fpr64(ctx, fp0, fd);
9545 tcg_temp_free_i64(fp0);
9546 }
9547 }
9548 break;
9549 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9550 if (ctx->insn_flags & ISA_MIPS32R6) {
9551 /* OPC_MAXA_D */
9552 TCGv_i64 fp0 = tcg_temp_new_i64();
9553 TCGv_i64 fp1 = tcg_temp_new_i64();
9554 gen_load_fpr64(ctx, fp0, fs);
9555 gen_load_fpr64(ctx, fp1, ft);
9556 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9557 gen_store_fpr64(ctx, fp1, fd);
9558 tcg_temp_free_i64(fp1);
9559 tcg_temp_free_i64(fp0);
9560 } else {
9561 /* OPC_RSQRT2_D */
9562 check_cp1_64bitmode(ctx);
9563 {
9564 TCGv_i64 fp0 = tcg_temp_new_i64();
9565 TCGv_i64 fp1 = tcg_temp_new_i64();
9566
9567 gen_load_fpr64(ctx, fp0, fs);
9568 gen_load_fpr64(ctx, fp1, ft);
9569 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9570 tcg_temp_free_i64(fp1);
9571 gen_store_fpr64(ctx, fp0, fd);
9572 tcg_temp_free_i64(fp0);
9573 }
9574 }
9575 break;
9576 case OPC_CMP_F_D:
9577 case OPC_CMP_UN_D:
9578 case OPC_CMP_EQ_D:
9579 case OPC_CMP_UEQ_D:
9580 case OPC_CMP_OLT_D:
9581 case OPC_CMP_ULT_D:
9582 case OPC_CMP_OLE_D:
9583 case OPC_CMP_ULE_D:
9584 case OPC_CMP_SF_D:
9585 case OPC_CMP_NGLE_D:
9586 case OPC_CMP_SEQ_D:
9587 case OPC_CMP_NGL_D:
9588 case OPC_CMP_LT_D:
9589 case OPC_CMP_NGE_D:
9590 case OPC_CMP_LE_D:
9591 case OPC_CMP_NGT_D:
9592 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9593 if (ctx->opcode & (1 << 6)) {
9594 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9595 } else {
9596 gen_cmp_d(ctx, func-48, ft, fs, cc);
9597 }
9598 break;
9599 case OPC_CVT_S_D:
9600 check_cp1_registers(ctx, fs);
9601 {
9602 TCGv_i32 fp32 = tcg_temp_new_i32();
9603 TCGv_i64 fp64 = tcg_temp_new_i64();
9604
9605 gen_load_fpr64(ctx, fp64, fs);
9606 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9607 tcg_temp_free_i64(fp64);
9608 gen_store_fpr32(ctx, fp32, fd);
9609 tcg_temp_free_i32(fp32);
9610 }
9611 break;
9612 case OPC_CVT_W_D:
9613 check_cp1_registers(ctx, fs);
9614 {
9615 TCGv_i32 fp32 = tcg_temp_new_i32();
9616 TCGv_i64 fp64 = tcg_temp_new_i64();
9617
9618 gen_load_fpr64(ctx, fp64, fs);
9619 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
9620 tcg_temp_free_i64(fp64);
9621 gen_store_fpr32(ctx, fp32, fd);
9622 tcg_temp_free_i32(fp32);
9623 }
9624 break;
9625 case OPC_CVT_L_D:
9626 check_cp1_64bitmode(ctx);
9627 {
9628 TCGv_i64 fp0 = tcg_temp_new_i64();
9629
9630 gen_load_fpr64(ctx, fp0, fs);
9631 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
9632 gen_store_fpr64(ctx, fp0, fd);
9633 tcg_temp_free_i64(fp0);
9634 }
9635 break;
9636 case OPC_CVT_S_W:
9637 {
9638 TCGv_i32 fp0 = tcg_temp_new_i32();
9639
9640 gen_load_fpr32(ctx, fp0, fs);
9641 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9642 gen_store_fpr32(ctx, fp0, fd);
9643 tcg_temp_free_i32(fp0);
9644 }
9645 break;
9646 case OPC_CVT_D_W:
9647 check_cp1_registers(ctx, fd);
9648 {
9649 TCGv_i32 fp32 = tcg_temp_new_i32();
9650 TCGv_i64 fp64 = tcg_temp_new_i64();
9651
9652 gen_load_fpr32(ctx, fp32, fs);
9653 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9654 tcg_temp_free_i32(fp32);
9655 gen_store_fpr64(ctx, fp64, fd);
9656 tcg_temp_free_i64(fp64);
9657 }
9658 break;
9659 case OPC_CVT_S_L:
9660 check_cp1_64bitmode(ctx);
9661 {
9662 TCGv_i32 fp32 = tcg_temp_new_i32();
9663 TCGv_i64 fp64 = tcg_temp_new_i64();
9664
9665 gen_load_fpr64(ctx, fp64, fs);
9666 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9667 tcg_temp_free_i64(fp64);
9668 gen_store_fpr32(ctx, fp32, fd);
9669 tcg_temp_free_i32(fp32);
9670 }
9671 break;
9672 case OPC_CVT_D_L:
9673 check_cp1_64bitmode(ctx);
9674 {
9675 TCGv_i64 fp0 = tcg_temp_new_i64();
9676
9677 gen_load_fpr64(ctx, fp0, fs);
9678 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9679 gen_store_fpr64(ctx, fp0, fd);
9680 tcg_temp_free_i64(fp0);
9681 }
9682 break;
9683 case OPC_CVT_PS_PW:
9684 check_ps(ctx);
9685 {
9686 TCGv_i64 fp0 = tcg_temp_new_i64();
9687
9688 gen_load_fpr64(ctx, fp0, fs);
9689 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9690 gen_store_fpr64(ctx, fp0, fd);
9691 tcg_temp_free_i64(fp0);
9692 }
9693 break;
9694 case OPC_ADD_PS:
9695 check_ps(ctx);
9696 {
9697 TCGv_i64 fp0 = tcg_temp_new_i64();
9698 TCGv_i64 fp1 = tcg_temp_new_i64();
9699
9700 gen_load_fpr64(ctx, fp0, fs);
9701 gen_load_fpr64(ctx, fp1, ft);
9702 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
9703 tcg_temp_free_i64(fp1);
9704 gen_store_fpr64(ctx, fp0, fd);
9705 tcg_temp_free_i64(fp0);
9706 }
9707 break;
9708 case OPC_SUB_PS:
9709 check_ps(ctx);
9710 {
9711 TCGv_i64 fp0 = tcg_temp_new_i64();
9712 TCGv_i64 fp1 = tcg_temp_new_i64();
9713
9714 gen_load_fpr64(ctx, fp0, fs);
9715 gen_load_fpr64(ctx, fp1, ft);
9716 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9717 tcg_temp_free_i64(fp1);
9718 gen_store_fpr64(ctx, fp0, fd);
9719 tcg_temp_free_i64(fp0);
9720 }
9721 break;
9722 case OPC_MUL_PS:
9723 check_ps(ctx);
9724 {
9725 TCGv_i64 fp0 = tcg_temp_new_i64();
9726 TCGv_i64 fp1 = tcg_temp_new_i64();
9727
9728 gen_load_fpr64(ctx, fp0, fs);
9729 gen_load_fpr64(ctx, fp1, ft);
9730 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9731 tcg_temp_free_i64(fp1);
9732 gen_store_fpr64(ctx, fp0, fd);
9733 tcg_temp_free_i64(fp0);
9734 }
9735 break;
9736 case OPC_ABS_PS:
9737 check_ps(ctx);
9738 {
9739 TCGv_i64 fp0 = tcg_temp_new_i64();
9740
9741 gen_load_fpr64(ctx, fp0, fs);
9742 gen_helper_float_abs_ps(fp0, fp0);
9743 gen_store_fpr64(ctx, fp0, fd);
9744 tcg_temp_free_i64(fp0);
9745 }
9746 break;
9747 case OPC_MOV_PS:
9748 check_ps(ctx);
9749 {
9750 TCGv_i64 fp0 = tcg_temp_new_i64();
9751
9752 gen_load_fpr64(ctx, fp0, fs);
9753 gen_store_fpr64(ctx, fp0, fd);
9754 tcg_temp_free_i64(fp0);
9755 }
9756 break;
9757 case OPC_NEG_PS:
9758 check_ps(ctx);
9759 {
9760 TCGv_i64 fp0 = tcg_temp_new_i64();
9761
9762 gen_load_fpr64(ctx, fp0, fs);
9763 gen_helper_float_chs_ps(fp0, fp0);
9764 gen_store_fpr64(ctx, fp0, fd);
9765 tcg_temp_free_i64(fp0);
9766 }
9767 break;
9768 case OPC_MOVCF_PS:
9769 check_ps(ctx);
9770 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9771 break;
9772 case OPC_MOVZ_PS:
9773 check_ps(ctx);
9774 {
9775 TCGLabel *l1 = gen_new_label();
9776 TCGv_i64 fp0;
9777
9778 if (ft != 0)
9779 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9780 fp0 = tcg_temp_new_i64();
9781 gen_load_fpr64(ctx, fp0, fs);
9782 gen_store_fpr64(ctx, fp0, fd);
9783 tcg_temp_free_i64(fp0);
9784 gen_set_label(l1);
9785 }
9786 break;
9787 case OPC_MOVN_PS:
9788 check_ps(ctx);
9789 {
9790 TCGLabel *l1 = gen_new_label();
9791 TCGv_i64 fp0;
9792
9793 if (ft != 0) {
9794 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9795 fp0 = tcg_temp_new_i64();
9796 gen_load_fpr64(ctx, fp0, fs);
9797 gen_store_fpr64(ctx, fp0, fd);
9798 tcg_temp_free_i64(fp0);
9799 gen_set_label(l1);
9800 }
9801 }
9802 break;
9803 case OPC_ADDR_PS:
9804 check_ps(ctx);
9805 {
9806 TCGv_i64 fp0 = tcg_temp_new_i64();
9807 TCGv_i64 fp1 = tcg_temp_new_i64();
9808
9809 gen_load_fpr64(ctx, fp0, ft);
9810 gen_load_fpr64(ctx, fp1, fs);
9811 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
9812 tcg_temp_free_i64(fp1);
9813 gen_store_fpr64(ctx, fp0, fd);
9814 tcg_temp_free_i64(fp0);
9815 }
9816 break;
9817 case OPC_MULR_PS:
9818 check_ps(ctx);
9819 {
9820 TCGv_i64 fp0 = tcg_temp_new_i64();
9821 TCGv_i64 fp1 = tcg_temp_new_i64();
9822
9823 gen_load_fpr64(ctx, fp0, ft);
9824 gen_load_fpr64(ctx, fp1, fs);
9825 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
9826 tcg_temp_free_i64(fp1);
9827 gen_store_fpr64(ctx, fp0, fd);
9828 tcg_temp_free_i64(fp0);
9829 }
9830 break;
9831 case OPC_RECIP2_PS:
9832 check_ps(ctx);
9833 {
9834 TCGv_i64 fp0 = tcg_temp_new_i64();
9835 TCGv_i64 fp1 = tcg_temp_new_i64();
9836
9837 gen_load_fpr64(ctx, fp0, fs);
9838 gen_load_fpr64(ctx, fp1, ft);
9839 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
9840 tcg_temp_free_i64(fp1);
9841 gen_store_fpr64(ctx, fp0, fd);
9842 tcg_temp_free_i64(fp0);
9843 }
9844 break;
9845 case OPC_RECIP1_PS:
9846 check_ps(ctx);
9847 {
9848 TCGv_i64 fp0 = tcg_temp_new_i64();
9849
9850 gen_load_fpr64(ctx, fp0, fs);
9851 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
9852 gen_store_fpr64(ctx, fp0, fd);
9853 tcg_temp_free_i64(fp0);
9854 }
9855 break;
9856 case OPC_RSQRT1_PS:
9857 check_ps(ctx);
9858 {
9859 TCGv_i64 fp0 = tcg_temp_new_i64();
9860
9861 gen_load_fpr64(ctx, fp0, fs);
9862 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
9863 gen_store_fpr64(ctx, fp0, fd);
9864 tcg_temp_free_i64(fp0);
9865 }
9866 break;
9867 case OPC_RSQRT2_PS:
9868 check_ps(ctx);
9869 {
9870 TCGv_i64 fp0 = tcg_temp_new_i64();
9871 TCGv_i64 fp1 = tcg_temp_new_i64();
9872
9873 gen_load_fpr64(ctx, fp0, fs);
9874 gen_load_fpr64(ctx, fp1, ft);
9875 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
9876 tcg_temp_free_i64(fp1);
9877 gen_store_fpr64(ctx, fp0, fd);
9878 tcg_temp_free_i64(fp0);
9879 }
9880 break;
9881 case OPC_CVT_S_PU:
9882 check_cp1_64bitmode(ctx);
9883 {
9884 TCGv_i32 fp0 = tcg_temp_new_i32();
9885
9886 gen_load_fpr32h(ctx, fp0, fs);
9887 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
9888 gen_store_fpr32(ctx, fp0, fd);
9889 tcg_temp_free_i32(fp0);
9890 }
9891 break;
9892 case OPC_CVT_PW_PS:
9893 check_ps(ctx);
9894 {
9895 TCGv_i64 fp0 = tcg_temp_new_i64();
9896
9897 gen_load_fpr64(ctx, fp0, fs);
9898 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
9899 gen_store_fpr64(ctx, fp0, fd);
9900 tcg_temp_free_i64(fp0);
9901 }
9902 break;
9903 case OPC_CVT_S_PL:
9904 check_cp1_64bitmode(ctx);
9905 {
9906 TCGv_i32 fp0 = tcg_temp_new_i32();
9907
9908 gen_load_fpr32(ctx, fp0, fs);
9909 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
9910 gen_store_fpr32(ctx, fp0, fd);
9911 tcg_temp_free_i32(fp0);
9912 }
9913 break;
9914 case OPC_PLL_PS:
9915 check_ps(ctx);
9916 {
9917 TCGv_i32 fp0 = tcg_temp_new_i32();
9918 TCGv_i32 fp1 = tcg_temp_new_i32();
9919
9920 gen_load_fpr32(ctx, fp0, fs);
9921 gen_load_fpr32(ctx, fp1, ft);
9922 gen_store_fpr32h(ctx, fp0, fd);
9923 gen_store_fpr32(ctx, fp1, fd);
9924 tcg_temp_free_i32(fp0);
9925 tcg_temp_free_i32(fp1);
9926 }
9927 break;
9928 case OPC_PLU_PS:
9929 check_ps(ctx);
9930 {
9931 TCGv_i32 fp0 = tcg_temp_new_i32();
9932 TCGv_i32 fp1 = tcg_temp_new_i32();
9933
9934 gen_load_fpr32(ctx, fp0, fs);
9935 gen_load_fpr32h(ctx, fp1, ft);
9936 gen_store_fpr32(ctx, fp1, fd);
9937 gen_store_fpr32h(ctx, fp0, fd);
9938 tcg_temp_free_i32(fp0);
9939 tcg_temp_free_i32(fp1);
9940 }
9941 break;
9942 case OPC_PUL_PS:
9943 check_ps(ctx);
9944 {
9945 TCGv_i32 fp0 = tcg_temp_new_i32();
9946 TCGv_i32 fp1 = tcg_temp_new_i32();
9947
9948 gen_load_fpr32h(ctx, fp0, fs);
9949 gen_load_fpr32(ctx, fp1, ft);
9950 gen_store_fpr32(ctx, fp1, fd);
9951 gen_store_fpr32h(ctx, fp0, fd);
9952 tcg_temp_free_i32(fp0);
9953 tcg_temp_free_i32(fp1);
9954 }
9955 break;
9956 case OPC_PUU_PS:
9957 check_ps(ctx);
9958 {
9959 TCGv_i32 fp0 = tcg_temp_new_i32();
9960 TCGv_i32 fp1 = tcg_temp_new_i32();
9961
9962 gen_load_fpr32h(ctx, fp0, fs);
9963 gen_load_fpr32h(ctx, fp1, ft);
9964 gen_store_fpr32(ctx, fp1, fd);
9965 gen_store_fpr32h(ctx, fp0, fd);
9966 tcg_temp_free_i32(fp0);
9967 tcg_temp_free_i32(fp1);
9968 }
9969 break;
9970 case OPC_CMP_F_PS:
9971 case OPC_CMP_UN_PS:
9972 case OPC_CMP_EQ_PS:
9973 case OPC_CMP_UEQ_PS:
9974 case OPC_CMP_OLT_PS:
9975 case OPC_CMP_ULT_PS:
9976 case OPC_CMP_OLE_PS:
9977 case OPC_CMP_ULE_PS:
9978 case OPC_CMP_SF_PS:
9979 case OPC_CMP_NGLE_PS:
9980 case OPC_CMP_SEQ_PS:
9981 case OPC_CMP_NGL_PS:
9982 case OPC_CMP_LT_PS:
9983 case OPC_CMP_NGE_PS:
9984 case OPC_CMP_LE_PS:
9985 case OPC_CMP_NGT_PS:
9986 if (ctx->opcode & (1 << 6)) {
9987 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
9988 } else {
9989 gen_cmp_ps(ctx, func-48, ft, fs, cc);
9990 }
9991 break;
9992 default:
9993 MIPS_INVAL("farith");
9994 generate_exception_end(ctx, EXCP_RI);
9995 return;
9996 }
9997 }
9998
9999 /* Coprocessor 3 (FPU) */
10000 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
10001 int fd, int fs, int base, int index)
10002 {
10003 TCGv t0 = tcg_temp_new();
10004
10005 if (base == 0) {
10006 gen_load_gpr(t0, index);
10007 } else if (index == 0) {
10008 gen_load_gpr(t0, base);
10009 } else {
10010 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
10011 }
10012 /* Don't do NOP if destination is zero: we must perform the actual
10013 memory access. */
10014 switch (opc) {
10015 case OPC_LWXC1:
10016 check_cop1x(ctx);
10017 {
10018 TCGv_i32 fp0 = tcg_temp_new_i32();
10019
10020 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
10021 tcg_gen_trunc_tl_i32(fp0, t0);
10022 gen_store_fpr32(ctx, fp0, fd);
10023 tcg_temp_free_i32(fp0);
10024 }
10025 break;
10026 case OPC_LDXC1:
10027 check_cop1x(ctx);
10028 check_cp1_registers(ctx, fd);
10029 {
10030 TCGv_i64 fp0 = tcg_temp_new_i64();
10031 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10032 gen_store_fpr64(ctx, fp0, fd);
10033 tcg_temp_free_i64(fp0);
10034 }
10035 break;
10036 case OPC_LUXC1:
10037 check_cp1_64bitmode(ctx);
10038 tcg_gen_andi_tl(t0, t0, ~0x7);
10039 {
10040 TCGv_i64 fp0 = tcg_temp_new_i64();
10041
10042 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10043 gen_store_fpr64(ctx, fp0, fd);
10044 tcg_temp_free_i64(fp0);
10045 }
10046 break;
10047 case OPC_SWXC1:
10048 check_cop1x(ctx);
10049 {
10050 TCGv_i32 fp0 = tcg_temp_new_i32();
10051 gen_load_fpr32(ctx, fp0, fs);
10052 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
10053 tcg_temp_free_i32(fp0);
10054 }
10055 break;
10056 case OPC_SDXC1:
10057 check_cop1x(ctx);
10058 check_cp1_registers(ctx, fs);
10059 {
10060 TCGv_i64 fp0 = tcg_temp_new_i64();
10061 gen_load_fpr64(ctx, fp0, fs);
10062 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10063 tcg_temp_free_i64(fp0);
10064 }
10065 break;
10066 case OPC_SUXC1:
10067 check_cp1_64bitmode(ctx);
10068 tcg_gen_andi_tl(t0, t0, ~0x7);
10069 {
10070 TCGv_i64 fp0 = tcg_temp_new_i64();
10071 gen_load_fpr64(ctx, fp0, fs);
10072 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
10073 tcg_temp_free_i64(fp0);
10074 }
10075 break;
10076 }
10077 tcg_temp_free(t0);
10078 }
10079
10080 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
10081 int fd, int fr, int fs, int ft)
10082 {
10083 switch (opc) {
10084 case OPC_ALNV_PS:
10085 check_ps(ctx);
10086 {
10087 TCGv t0 = tcg_temp_local_new();
10088 TCGv_i32 fp = tcg_temp_new_i32();
10089 TCGv_i32 fph = tcg_temp_new_i32();
10090 TCGLabel *l1 = gen_new_label();
10091 TCGLabel *l2 = gen_new_label();
10092
10093 gen_load_gpr(t0, fr);
10094 tcg_gen_andi_tl(t0, t0, 0x7);
10095
10096 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
10097 gen_load_fpr32(ctx, fp, fs);
10098 gen_load_fpr32h(ctx, fph, fs);
10099 gen_store_fpr32(ctx, fp, fd);
10100 gen_store_fpr32h(ctx, fph, fd);
10101 tcg_gen_br(l2);
10102 gen_set_label(l1);
10103 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
10104 tcg_temp_free(t0);
10105 #ifdef TARGET_WORDS_BIGENDIAN
10106 gen_load_fpr32(ctx, fp, fs);
10107 gen_load_fpr32h(ctx, fph, ft);
10108 gen_store_fpr32h(ctx, fp, fd);
10109 gen_store_fpr32(ctx, fph, fd);
10110 #else
10111 gen_load_fpr32h(ctx, fph, fs);
10112 gen_load_fpr32(ctx, fp, ft);
10113 gen_store_fpr32(ctx, fph, fd);
10114 gen_store_fpr32h(ctx, fp, fd);
10115 #endif
10116 gen_set_label(l2);
10117 tcg_temp_free_i32(fp);
10118 tcg_temp_free_i32(fph);
10119 }
10120 break;
10121 case OPC_MADD_S:
10122 check_cop1x(ctx);
10123 {
10124 TCGv_i32 fp0 = tcg_temp_new_i32();
10125 TCGv_i32 fp1 = tcg_temp_new_i32();
10126 TCGv_i32 fp2 = tcg_temp_new_i32();
10127
10128 gen_load_fpr32(ctx, fp0, fs);
10129 gen_load_fpr32(ctx, fp1, ft);
10130 gen_load_fpr32(ctx, fp2, fr);
10131 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
10132 tcg_temp_free_i32(fp0);
10133 tcg_temp_free_i32(fp1);
10134 gen_store_fpr32(ctx, fp2, fd);
10135 tcg_temp_free_i32(fp2);
10136 }
10137 break;
10138 case OPC_MADD_D:
10139 check_cop1x(ctx);
10140 check_cp1_registers(ctx, fd | fs | ft | fr);
10141 {
10142 TCGv_i64 fp0 = tcg_temp_new_i64();
10143 TCGv_i64 fp1 = tcg_temp_new_i64();
10144 TCGv_i64 fp2 = tcg_temp_new_i64();
10145
10146 gen_load_fpr64(ctx, fp0, fs);
10147 gen_load_fpr64(ctx, fp1, ft);
10148 gen_load_fpr64(ctx, fp2, fr);
10149 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
10150 tcg_temp_free_i64(fp0);
10151 tcg_temp_free_i64(fp1);
10152 gen_store_fpr64(ctx, fp2, fd);
10153 tcg_temp_free_i64(fp2);
10154 }
10155 break;
10156 case OPC_MADD_PS:
10157 check_ps(ctx);
10158 {
10159 TCGv_i64 fp0 = tcg_temp_new_i64();
10160 TCGv_i64 fp1 = tcg_temp_new_i64();
10161 TCGv_i64 fp2 = tcg_temp_new_i64();
10162
10163 gen_load_fpr64(ctx, fp0, fs);
10164 gen_load_fpr64(ctx, fp1, ft);
10165 gen_load_fpr64(ctx, fp2, fr);
10166 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
10167 tcg_temp_free_i64(fp0);
10168 tcg_temp_free_i64(fp1);
10169 gen_store_fpr64(ctx, fp2, fd);
10170 tcg_temp_free_i64(fp2);
10171 }
10172 break;
10173 case OPC_MSUB_S:
10174 check_cop1x(ctx);
10175 {
10176 TCGv_i32 fp0 = tcg_temp_new_i32();
10177 TCGv_i32 fp1 = tcg_temp_new_i32();
10178 TCGv_i32 fp2 = tcg_temp_new_i32();
10179
10180 gen_load_fpr32(ctx, fp0, fs);
10181 gen_load_fpr32(ctx, fp1, ft);
10182 gen_load_fpr32(ctx, fp2, fr);
10183 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
10184 tcg_temp_free_i32(fp0);
10185 tcg_temp_free_i32(fp1);
10186 gen_store_fpr32(ctx, fp2, fd);
10187 tcg_temp_free_i32(fp2);
10188 }
10189 break;
10190 case OPC_MSUB_D:
10191 check_cop1x(ctx);
10192 check_cp1_registers(ctx, fd | fs | ft | fr);
10193 {
10194 TCGv_i64 fp0 = tcg_temp_new_i64();
10195 TCGv_i64 fp1 = tcg_temp_new_i64();
10196 TCGv_i64 fp2 = tcg_temp_new_i64();
10197
10198 gen_load_fpr64(ctx, fp0, fs);
10199 gen_load_fpr64(ctx, fp1, ft);
10200 gen_load_fpr64(ctx, fp2, fr);
10201 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
10202 tcg_temp_free_i64(fp0);
10203 tcg_temp_free_i64(fp1);
10204 gen_store_fpr64(ctx, fp2, fd);
10205 tcg_temp_free_i64(fp2);
10206 }
10207 break;
10208 case OPC_MSUB_PS:
10209 check_ps(ctx);
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_msub_ps(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_NMADD_S:
10226 check_cop1x(ctx);
10227 {
10228 TCGv_i32 fp0 = tcg_temp_new_i32();
10229 TCGv_i32 fp1 = tcg_temp_new_i32();
10230 TCGv_i32 fp2 = tcg_temp_new_i32();
10231
10232 gen_load_fpr32(ctx, fp0, fs);
10233 gen_load_fpr32(ctx, fp1, ft);
10234 gen_load_fpr32(ctx, fp2, fr);
10235 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
10236 tcg_temp_free_i32(fp0);
10237 tcg_temp_free_i32(fp1);
10238 gen_store_fpr32(ctx, fp2, fd);
10239 tcg_temp_free_i32(fp2);
10240 }
10241 break;
10242 case OPC_NMADD_D:
10243 check_cop1x(ctx);
10244 check_cp1_registers(ctx, fd | fs | ft | fr);
10245 {
10246 TCGv_i64 fp0 = tcg_temp_new_i64();
10247 TCGv_i64 fp1 = tcg_temp_new_i64();
10248 TCGv_i64 fp2 = tcg_temp_new_i64();
10249
10250 gen_load_fpr64(ctx, fp0, fs);
10251 gen_load_fpr64(ctx, fp1, ft);
10252 gen_load_fpr64(ctx, fp2, fr);
10253 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
10254 tcg_temp_free_i64(fp0);
10255 tcg_temp_free_i64(fp1);
10256 gen_store_fpr64(ctx, fp2, fd);
10257 tcg_temp_free_i64(fp2);
10258 }
10259 break;
10260 case OPC_NMADD_PS:
10261 check_ps(ctx);
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_nmadd_ps(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_NMSUB_S:
10278 check_cop1x(ctx);
10279 {
10280 TCGv_i32 fp0 = tcg_temp_new_i32();
10281 TCGv_i32 fp1 = tcg_temp_new_i32();
10282 TCGv_i32 fp2 = tcg_temp_new_i32();
10283
10284 gen_load_fpr32(ctx, fp0, fs);
10285 gen_load_fpr32(ctx, fp1, ft);
10286 gen_load_fpr32(ctx, fp2, fr);
10287 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10288 tcg_temp_free_i32(fp0);
10289 tcg_temp_free_i32(fp1);
10290 gen_store_fpr32(ctx, fp2, fd);
10291 tcg_temp_free_i32(fp2);
10292 }
10293 break;
10294 case OPC_NMSUB_D:
10295 check_cop1x(ctx);
10296 check_cp1_registers(ctx, fd | fs | ft | fr);
10297 {
10298 TCGv_i64 fp0 = tcg_temp_new_i64();
10299 TCGv_i64 fp1 = tcg_temp_new_i64();
10300 TCGv_i64 fp2 = tcg_temp_new_i64();
10301
10302 gen_load_fpr64(ctx, fp0, fs);
10303 gen_load_fpr64(ctx, fp1, ft);
10304 gen_load_fpr64(ctx, fp2, fr);
10305 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10306 tcg_temp_free_i64(fp0);
10307 tcg_temp_free_i64(fp1);
10308 gen_store_fpr64(ctx, fp2, fd);
10309 tcg_temp_free_i64(fp2);
10310 }
10311 break;
10312 case OPC_NMSUB_PS:
10313 check_ps(ctx);
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_nmsub_ps(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 default:
10330 MIPS_INVAL("flt3_arith");
10331 generate_exception_end(ctx, EXCP_RI);
10332 return;
10333 }
10334 }
10335
10336 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
10337 {
10338 TCGv t0;
10339
10340 #if !defined(CONFIG_USER_ONLY)
10341 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10342 Therefore only check the ISA in system mode. */
10343 check_insn(ctx, ISA_MIPS32R2);
10344 #endif
10345 t0 = tcg_temp_new();
10346
10347 switch (rd) {
10348 case 0:
10349 gen_helper_rdhwr_cpunum(t0, cpu_env);
10350 gen_store_gpr(t0, rt);
10351 break;
10352 case 1:
10353 gen_helper_rdhwr_synci_step(t0, cpu_env);
10354 gen_store_gpr(t0, rt);
10355 break;
10356 case 2:
10357 gen_helper_rdhwr_cc(t0, cpu_env);
10358 gen_store_gpr(t0, rt);
10359 break;
10360 case 3:
10361 gen_helper_rdhwr_ccres(t0, cpu_env);
10362 gen_store_gpr(t0, rt);
10363 break;
10364 case 4:
10365 check_insn(ctx, ISA_MIPS32R6);
10366 if (sel != 0) {
10367 /* Performance counter registers are not implemented other than
10368 * control register 0.
10369 */
10370 generate_exception(ctx, EXCP_RI);
10371 }
10372 gen_helper_rdhwr_performance(t0, cpu_env);
10373 gen_store_gpr(t0, rt);
10374 break;
10375 case 5:
10376 check_insn(ctx, ISA_MIPS32R6);
10377 gen_helper_rdhwr_xnp(t0, cpu_env);
10378 gen_store_gpr(t0, rt);
10379 break;
10380 case 29:
10381 #if defined(CONFIG_USER_ONLY)
10382 tcg_gen_ld_tl(t0, cpu_env,
10383 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10384 gen_store_gpr(t0, rt);
10385 break;
10386 #else
10387 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10388 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10389 tcg_gen_ld_tl(t0, cpu_env,
10390 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10391 gen_store_gpr(t0, rt);
10392 } else {
10393 generate_exception_end(ctx, EXCP_RI);
10394 }
10395 break;
10396 #endif
10397 default: /* Invalid */
10398 MIPS_INVAL("rdhwr");
10399 generate_exception_end(ctx, EXCP_RI);
10400 break;
10401 }
10402 tcg_temp_free(t0);
10403 }
10404
10405 static inline void clear_branch_hflags(DisasContext *ctx)
10406 {
10407 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10408 if (ctx->bstate == BS_NONE) {
10409 save_cpu_state(ctx, 0);
10410 } else {
10411 /* it is not safe to save ctx->hflags as hflags may be changed
10412 in execution time by the instruction in delay / forbidden slot. */
10413 tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
10414 }
10415 }
10416
10417 static void gen_branch(DisasContext *ctx, int insn_bytes)
10418 {
10419 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10420 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10421 /* Branches completion */
10422 clear_branch_hflags(ctx);
10423 ctx->bstate = BS_BRANCH;
10424 /* FIXME: Need to clear can_do_io. */
10425 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10426 case MIPS_HFLAG_FBNSLOT:
10427 gen_goto_tb(ctx, 0, ctx->pc + insn_bytes);
10428 break;
10429 case MIPS_HFLAG_B:
10430 /* unconditional branch */
10431 if (proc_hflags & MIPS_HFLAG_BX) {
10432 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10433 }
10434 gen_goto_tb(ctx, 0, ctx->btarget);
10435 break;
10436 case MIPS_HFLAG_BL:
10437 /* blikely taken case */
10438 gen_goto_tb(ctx, 0, ctx->btarget);
10439 break;
10440 case MIPS_HFLAG_BC:
10441 /* Conditional branch */
10442 {
10443 TCGLabel *l1 = gen_new_label();
10444
10445 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10446 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10447 gen_set_label(l1);
10448 gen_goto_tb(ctx, 0, ctx->btarget);
10449 }
10450 break;
10451 case MIPS_HFLAG_BR:
10452 /* unconditional branch to register */
10453 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10454 TCGv t0 = tcg_temp_new();
10455 TCGv_i32 t1 = tcg_temp_new_i32();
10456
10457 tcg_gen_andi_tl(t0, btarget, 0x1);
10458 tcg_gen_trunc_tl_i32(t1, t0);
10459 tcg_temp_free(t0);
10460 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10461 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10462 tcg_gen_or_i32(hflags, hflags, t1);
10463 tcg_temp_free_i32(t1);
10464
10465 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10466 } else {
10467 tcg_gen_mov_tl(cpu_PC, btarget);
10468 }
10469 if (ctx->singlestep_enabled) {
10470 save_cpu_state(ctx, 0);
10471 gen_helper_raise_exception_debug(cpu_env);
10472 }
10473 tcg_gen_exit_tb(0);
10474 break;
10475 default:
10476 fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
10477 abort();
10478 }
10479 }
10480 }
10481
10482 /* Compact Branches */
10483 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
10484 int rs, int rt, int32_t offset)
10485 {
10486 int bcond_compute = 0;
10487 TCGv t0 = tcg_temp_new();
10488 TCGv t1 = tcg_temp_new();
10489 int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
10490
10491 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10492 #ifdef MIPS_DEBUG_DISAS
10493 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10494 "\n", ctx->pc);
10495 #endif
10496 generate_exception_end(ctx, EXCP_RI);
10497 goto out;
10498 }
10499
10500 /* Load needed operands and calculate btarget */
10501 switch (opc) {
10502 /* compact branch */
10503 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10504 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10505 gen_load_gpr(t0, rs);
10506 gen_load_gpr(t1, rt);
10507 bcond_compute = 1;
10508 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10509 if (rs <= rt && rs == 0) {
10510 /* OPC_BEQZALC, OPC_BNEZALC */
10511 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10512 }
10513 break;
10514 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10515 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10516 gen_load_gpr(t0, rs);
10517 gen_load_gpr(t1, rt);
10518 bcond_compute = 1;
10519 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10520 break;
10521 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10522 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10523 if (rs == 0 || rs == rt) {
10524 /* OPC_BLEZALC, OPC_BGEZALC */
10525 /* OPC_BGTZALC, OPC_BLTZALC */
10526 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10527 }
10528 gen_load_gpr(t0, rs);
10529 gen_load_gpr(t1, rt);
10530 bcond_compute = 1;
10531 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10532 break;
10533 case OPC_BC:
10534 case OPC_BALC:
10535 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10536 break;
10537 case OPC_BEQZC:
10538 case OPC_BNEZC:
10539 if (rs != 0) {
10540 /* OPC_BEQZC, OPC_BNEZC */
10541 gen_load_gpr(t0, rs);
10542 bcond_compute = 1;
10543 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
10544 } else {
10545 /* OPC_JIC, OPC_JIALC */
10546 TCGv tbase = tcg_temp_new();
10547 TCGv toffset = tcg_temp_new();
10548
10549 gen_load_gpr(tbase, rt);
10550 tcg_gen_movi_tl(toffset, offset);
10551 gen_op_addr_add(ctx, btarget, tbase, toffset);
10552 tcg_temp_free(tbase);
10553 tcg_temp_free(toffset);
10554 }
10555 break;
10556 default:
10557 MIPS_INVAL("Compact branch/jump");
10558 generate_exception_end(ctx, EXCP_RI);
10559 goto out;
10560 }
10561
10562 if (bcond_compute == 0) {
10563 /* Uncoditional compact branch */
10564 switch (opc) {
10565 case OPC_JIALC:
10566 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10567 /* Fallthrough */
10568 case OPC_JIC:
10569 ctx->hflags |= MIPS_HFLAG_BR;
10570 break;
10571 case OPC_BALC:
10572 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4 + m16_lowbit);
10573 /* Fallthrough */
10574 case OPC_BC:
10575 ctx->hflags |= MIPS_HFLAG_B;
10576 break;
10577 default:
10578 MIPS_INVAL("Compact branch/jump");
10579 generate_exception_end(ctx, EXCP_RI);
10580 goto out;
10581 }
10582
10583 /* Generating branch here as compact branches don't have delay slot */
10584 gen_branch(ctx, 4);
10585 } else {
10586 /* Conditional compact branch */
10587 TCGLabel *fs = gen_new_label();
10588 save_cpu_state(ctx, 0);
10589
10590 switch (opc) {
10591 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
10592 if (rs == 0 && rt != 0) {
10593 /* OPC_BLEZALC */
10594 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10595 } else if (rs != 0 && rt != 0 && rs == rt) {
10596 /* OPC_BGEZALC */
10597 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10598 } else {
10599 /* OPC_BGEUC */
10600 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
10601 }
10602 break;
10603 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
10604 if (rs == 0 && rt != 0) {
10605 /* OPC_BGTZALC */
10606 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10607 } else if (rs != 0 && rt != 0 && rs == rt) {
10608 /* OPC_BLTZALC */
10609 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10610 } else {
10611 /* OPC_BLTUC */
10612 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
10613 }
10614 break;
10615 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
10616 if (rs == 0 && rt != 0) {
10617 /* OPC_BLEZC */
10618 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
10619 } else if (rs != 0 && rt != 0 && rs == rt) {
10620 /* OPC_BGEZC */
10621 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
10622 } else {
10623 /* OPC_BGEC */
10624 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
10625 }
10626 break;
10627 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
10628 if (rs == 0 && rt != 0) {
10629 /* OPC_BGTZC */
10630 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
10631 } else if (rs != 0 && rt != 0 && rs == rt) {
10632 /* OPC_BLTZC */
10633 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
10634 } else {
10635 /* OPC_BLTC */
10636 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
10637 }
10638 break;
10639 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
10640 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
10641 if (rs >= rt) {
10642 /* OPC_BOVC, OPC_BNVC */
10643 TCGv t2 = tcg_temp_new();
10644 TCGv t3 = tcg_temp_new();
10645 TCGv t4 = tcg_temp_new();
10646 TCGv input_overflow = tcg_temp_new();
10647
10648 gen_load_gpr(t0, rs);
10649 gen_load_gpr(t1, rt);
10650 tcg_gen_ext32s_tl(t2, t0);
10651 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
10652 tcg_gen_ext32s_tl(t3, t1);
10653 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
10654 tcg_gen_or_tl(input_overflow, input_overflow, t4);
10655
10656 tcg_gen_add_tl(t4, t2, t3);
10657 tcg_gen_ext32s_tl(t4, t4);
10658 tcg_gen_xor_tl(t2, t2, t3);
10659 tcg_gen_xor_tl(t3, t4, t3);
10660 tcg_gen_andc_tl(t2, t3, t2);
10661 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
10662 tcg_gen_or_tl(t4, t4, input_overflow);
10663 if (opc == OPC_BOVC) {
10664 /* OPC_BOVC */
10665 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
10666 } else {
10667 /* OPC_BNVC */
10668 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
10669 }
10670 tcg_temp_free(input_overflow);
10671 tcg_temp_free(t4);
10672 tcg_temp_free(t3);
10673 tcg_temp_free(t2);
10674 } else if (rs < rt && rs == 0) {
10675 /* OPC_BEQZALC, OPC_BNEZALC */
10676 if (opc == OPC_BEQZALC) {
10677 /* OPC_BEQZALC */
10678 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
10679 } else {
10680 /* OPC_BNEZALC */
10681 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
10682 }
10683 } else {
10684 /* OPC_BEQC, OPC_BNEC */
10685 if (opc == OPC_BEQC) {
10686 /* OPC_BEQC */
10687 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
10688 } else {
10689 /* OPC_BNEC */
10690 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
10691 }
10692 }
10693 break;
10694 case OPC_BEQZC:
10695 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
10696 break;
10697 case OPC_BNEZC:
10698 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
10699 break;
10700 default:
10701 MIPS_INVAL("Compact conditional branch/jump");
10702 generate_exception_end(ctx, EXCP_RI);
10703 goto out;
10704 }
10705
10706 /* Generating branch here as compact branches don't have delay slot */
10707 gen_goto_tb(ctx, 1, ctx->btarget);
10708 gen_set_label(fs);
10709
10710 ctx->hflags |= MIPS_HFLAG_FBNSLOT;
10711 }
10712
10713 out:
10714 tcg_temp_free(t0);
10715 tcg_temp_free(t1);
10716 }
10717
10718 /* ISA extensions (ASEs) */
10719 /* MIPS16 extension to MIPS32 */
10720
10721 /* MIPS16 major opcodes */
10722 enum {
10723 M16_OPC_ADDIUSP = 0x00,
10724 M16_OPC_ADDIUPC = 0x01,
10725 M16_OPC_B = 0x02,
10726 M16_OPC_JAL = 0x03,
10727 M16_OPC_BEQZ = 0x04,
10728 M16_OPC_BNEQZ = 0x05,
10729 M16_OPC_SHIFT = 0x06,
10730 M16_OPC_LD = 0x07,
10731 M16_OPC_RRIA = 0x08,
10732 M16_OPC_ADDIU8 = 0x09,
10733 M16_OPC_SLTI = 0x0a,
10734 M16_OPC_SLTIU = 0x0b,
10735 M16_OPC_I8 = 0x0c,
10736 M16_OPC_LI = 0x0d,
10737 M16_OPC_CMPI = 0x0e,
10738 M16_OPC_SD = 0x0f,
10739 M16_OPC_LB = 0x10,
10740 M16_OPC_LH = 0x11,
10741 M16_OPC_LWSP = 0x12,
10742 M16_OPC_LW = 0x13,
10743 M16_OPC_LBU = 0x14,
10744 M16_OPC_LHU = 0x15,
10745 M16_OPC_LWPC = 0x16,
10746 M16_OPC_LWU = 0x17,
10747 M16_OPC_SB = 0x18,
10748 M16_OPC_SH = 0x19,
10749 M16_OPC_SWSP = 0x1a,
10750 M16_OPC_SW = 0x1b,
10751 M16_OPC_RRR = 0x1c,
10752 M16_OPC_RR = 0x1d,
10753 M16_OPC_EXTEND = 0x1e,
10754 M16_OPC_I64 = 0x1f
10755 };
10756
10757 /* I8 funct field */
10758 enum {
10759 I8_BTEQZ = 0x0,
10760 I8_BTNEZ = 0x1,
10761 I8_SWRASP = 0x2,
10762 I8_ADJSP = 0x3,
10763 I8_SVRS = 0x4,
10764 I8_MOV32R = 0x5,
10765 I8_MOVR32 = 0x7
10766 };
10767
10768 /* RRR f field */
10769 enum {
10770 RRR_DADDU = 0x0,
10771 RRR_ADDU = 0x1,
10772 RRR_DSUBU = 0x2,
10773 RRR_SUBU = 0x3
10774 };
10775
10776 /* RR funct field */
10777 enum {
10778 RR_JR = 0x00,
10779 RR_SDBBP = 0x01,
10780 RR_SLT = 0x02,
10781 RR_SLTU = 0x03,
10782 RR_SLLV = 0x04,
10783 RR_BREAK = 0x05,
10784 RR_SRLV = 0x06,
10785 RR_SRAV = 0x07,
10786 RR_DSRL = 0x08,
10787 RR_CMP = 0x0a,
10788 RR_NEG = 0x0b,
10789 RR_AND = 0x0c,
10790 RR_OR = 0x0d,
10791 RR_XOR = 0x0e,
10792 RR_NOT = 0x0f,
10793 RR_MFHI = 0x10,
10794 RR_CNVT = 0x11,
10795 RR_MFLO = 0x12,
10796 RR_DSRA = 0x13,
10797 RR_DSLLV = 0x14,
10798 RR_DSRLV = 0x16,
10799 RR_DSRAV = 0x17,
10800 RR_MULT = 0x18,
10801 RR_MULTU = 0x19,
10802 RR_DIV = 0x1a,
10803 RR_DIVU = 0x1b,
10804 RR_DMULT = 0x1c,
10805 RR_DMULTU = 0x1d,
10806 RR_DDIV = 0x1e,
10807 RR_DDIVU = 0x1f
10808 };
10809
10810 /* I64 funct field */
10811 enum {
10812 I64_LDSP = 0x0,
10813 I64_SDSP = 0x1,
10814 I64_SDRASP = 0x2,
10815 I64_DADJSP = 0x3,
10816 I64_LDPC = 0x4,
10817 I64_DADDIU5 = 0x5,
10818 I64_DADDIUPC = 0x6,
10819 I64_DADDIUSP = 0x7
10820 };
10821
10822 /* RR ry field for CNVT */
10823 enum {
10824 RR_RY_CNVT_ZEB = 0x0,
10825 RR_RY_CNVT_ZEH = 0x1,
10826 RR_RY_CNVT_ZEW = 0x2,
10827 RR_RY_CNVT_SEB = 0x4,
10828 RR_RY_CNVT_SEH = 0x5,
10829 RR_RY_CNVT_SEW = 0x6,
10830 };
10831
10832 static int xlat (int r)
10833 {
10834 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10835
10836 return map[r];
10837 }
10838
10839 static void gen_mips16_save (DisasContext *ctx,
10840 int xsregs, int aregs,
10841 int do_ra, int do_s0, int do_s1,
10842 int framesize)
10843 {
10844 TCGv t0 = tcg_temp_new();
10845 TCGv t1 = tcg_temp_new();
10846 TCGv t2 = tcg_temp_new();
10847 int args, astatic;
10848
10849 switch (aregs) {
10850 case 0:
10851 case 1:
10852 case 2:
10853 case 3:
10854 case 11:
10855 args = 0;
10856 break;
10857 case 4:
10858 case 5:
10859 case 6:
10860 case 7:
10861 args = 1;
10862 break;
10863 case 8:
10864 case 9:
10865 case 10:
10866 args = 2;
10867 break;
10868 case 12:
10869 case 13:
10870 args = 3;
10871 break;
10872 case 14:
10873 args = 4;
10874 break;
10875 default:
10876 generate_exception_end(ctx, EXCP_RI);
10877 return;
10878 }
10879
10880 switch (args) {
10881 case 4:
10882 gen_base_offset_addr(ctx, t0, 29, 12);
10883 gen_load_gpr(t1, 7);
10884 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10885 /* Fall through */
10886 case 3:
10887 gen_base_offset_addr(ctx, t0, 29, 8);
10888 gen_load_gpr(t1, 6);
10889 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10890 /* Fall through */
10891 case 2:
10892 gen_base_offset_addr(ctx, t0, 29, 4);
10893 gen_load_gpr(t1, 5);
10894 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10895 /* Fall through */
10896 case 1:
10897 gen_base_offset_addr(ctx, t0, 29, 0);
10898 gen_load_gpr(t1, 4);
10899 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10900 }
10901
10902 gen_load_gpr(t0, 29);
10903
10904 #define DECR_AND_STORE(reg) do { \
10905 tcg_gen_movi_tl(t2, -4); \
10906 gen_op_addr_add(ctx, t0, t0, t2); \
10907 gen_load_gpr(t1, reg); \
10908 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
10909 } while (0)
10910
10911 if (do_ra) {
10912 DECR_AND_STORE(31);
10913 }
10914
10915 switch (xsregs) {
10916 case 7:
10917 DECR_AND_STORE(30);
10918 /* Fall through */
10919 case 6:
10920 DECR_AND_STORE(23);
10921 /* Fall through */
10922 case 5:
10923 DECR_AND_STORE(22);
10924 /* Fall through */
10925 case 4:
10926 DECR_AND_STORE(21);
10927 /* Fall through */
10928 case 3:
10929 DECR_AND_STORE(20);
10930 /* Fall through */
10931 case 2:
10932 DECR_AND_STORE(19);
10933 /* Fall through */
10934 case 1:
10935 DECR_AND_STORE(18);
10936 }
10937
10938 if (do_s1) {
10939 DECR_AND_STORE(17);
10940 }
10941 if (do_s0) {
10942 DECR_AND_STORE(16);
10943 }
10944
10945 switch (aregs) {
10946 case 0:
10947 case 4:
10948 case 8:
10949 case 12:
10950 case 14:
10951 astatic = 0;
10952 break;
10953 case 1:
10954 case 5:
10955 case 9:
10956 case 13:
10957 astatic = 1;
10958 break;
10959 case 2:
10960 case 6:
10961 case 10:
10962 astatic = 2;
10963 break;
10964 case 3:
10965 case 7:
10966 astatic = 3;
10967 break;
10968 case 11:
10969 astatic = 4;
10970 break;
10971 default:
10972 generate_exception_end(ctx, EXCP_RI);
10973 return;
10974 }
10975
10976 if (astatic > 0) {
10977 DECR_AND_STORE(7);
10978 if (astatic > 1) {
10979 DECR_AND_STORE(6);
10980 if (astatic > 2) {
10981 DECR_AND_STORE(5);
10982 if (astatic > 3) {
10983 DECR_AND_STORE(4);
10984 }
10985 }
10986 }
10987 }
10988 #undef DECR_AND_STORE
10989
10990 tcg_gen_movi_tl(t2, -framesize);
10991 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
10992 tcg_temp_free(t0);
10993 tcg_temp_free(t1);
10994 tcg_temp_free(t2);
10995 }
10996
10997 static void gen_mips16_restore (DisasContext *ctx,
10998 int xsregs, int aregs,
10999 int do_ra, int do_s0, int do_s1,
11000 int framesize)
11001 {
11002 int astatic;
11003 TCGv t0 = tcg_temp_new();
11004 TCGv t1 = tcg_temp_new();
11005 TCGv t2 = tcg_temp_new();
11006
11007 tcg_gen_movi_tl(t2, framesize);
11008 gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
11009
11010 #define DECR_AND_LOAD(reg) do { \
11011 tcg_gen_movi_tl(t2, -4); \
11012 gen_op_addr_add(ctx, t0, t0, t2); \
11013 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11014 gen_store_gpr(t1, reg); \
11015 } while (0)
11016
11017 if (do_ra) {
11018 DECR_AND_LOAD(31);
11019 }
11020
11021 switch (xsregs) {
11022 case 7:
11023 DECR_AND_LOAD(30);
11024 /* Fall through */
11025 case 6:
11026 DECR_AND_LOAD(23);
11027 /* Fall through */
11028 case 5:
11029 DECR_AND_LOAD(22);
11030 /* Fall through */
11031 case 4:
11032 DECR_AND_LOAD(21);
11033 /* Fall through */
11034 case 3:
11035 DECR_AND_LOAD(20);
11036 /* Fall through */
11037 case 2:
11038 DECR_AND_LOAD(19);
11039 /* Fall through */
11040 case 1:
11041 DECR_AND_LOAD(18);
11042 }
11043
11044 if (do_s1) {
11045 DECR_AND_LOAD(17);
11046 }
11047 if (do_s0) {
11048 DECR_AND_LOAD(16);
11049 }
11050
11051 switch (aregs) {
11052 case 0:
11053 case 4:
11054 case 8:
11055 case 12:
11056 case 14:
11057 astatic = 0;
11058 break;
11059 case 1:
11060 case 5:
11061 case 9:
11062 case 13:
11063 astatic = 1;
11064 break;
11065 case 2:
11066 case 6:
11067 case 10:
11068 astatic = 2;
11069 break;
11070 case 3:
11071 case 7:
11072 astatic = 3;
11073 break;
11074 case 11:
11075 astatic = 4;
11076 break;
11077 default:
11078 generate_exception_end(ctx, EXCP_RI);
11079 return;
11080 }
11081
11082 if (astatic > 0) {
11083 DECR_AND_LOAD(7);
11084 if (astatic > 1) {
11085 DECR_AND_LOAD(6);
11086 if (astatic > 2) {
11087 DECR_AND_LOAD(5);
11088 if (astatic > 3) {
11089 DECR_AND_LOAD(4);
11090 }
11091 }
11092 }
11093 }
11094 #undef DECR_AND_LOAD
11095
11096 tcg_gen_movi_tl(t2, framesize);
11097 gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
11098 tcg_temp_free(t0);
11099 tcg_temp_free(t1);
11100 tcg_temp_free(t2);
11101 }
11102
11103 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
11104 int is_64_bit, int extended)
11105 {
11106 TCGv t0;
11107
11108 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11109 generate_exception_end(ctx, EXCP_RI);
11110 return;
11111 }
11112
11113 t0 = tcg_temp_new();
11114
11115 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
11116 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
11117 if (!is_64_bit) {
11118 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11119 }
11120
11121 tcg_temp_free(t0);
11122 }
11123
11124 #if defined(TARGET_MIPS64)
11125 static void decode_i64_mips16 (DisasContext *ctx,
11126 int ry, int funct, int16_t offset,
11127 int extended)
11128 {
11129 switch (funct) {
11130 case I64_LDSP:
11131 check_insn(ctx, ISA_MIPS3);
11132 check_mips_64(ctx);
11133 offset = extended ? offset : offset << 3;
11134 gen_ld(ctx, OPC_LD, ry, 29, offset);
11135 break;
11136 case I64_SDSP:
11137 check_insn(ctx, ISA_MIPS3);
11138 check_mips_64(ctx);
11139 offset = extended ? offset : offset << 3;
11140 gen_st(ctx, OPC_SD, ry, 29, offset);
11141 break;
11142 case I64_SDRASP:
11143 check_insn(ctx, ISA_MIPS3);
11144 check_mips_64(ctx);
11145 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
11146 gen_st(ctx, OPC_SD, 31, 29, offset);
11147 break;
11148 case I64_DADJSP:
11149 check_insn(ctx, ISA_MIPS3);
11150 check_mips_64(ctx);
11151 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
11152 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
11153 break;
11154 case I64_LDPC:
11155 check_insn(ctx, ISA_MIPS3);
11156 check_mips_64(ctx);
11157 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
11158 generate_exception_end(ctx, EXCP_RI);
11159 } else {
11160 offset = extended ? offset : offset << 3;
11161 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
11162 }
11163 break;
11164 case I64_DADDIU5:
11165 check_insn(ctx, ISA_MIPS3);
11166 check_mips_64(ctx);
11167 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
11168 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
11169 break;
11170 case I64_DADDIUPC:
11171 check_insn(ctx, ISA_MIPS3);
11172 check_mips_64(ctx);
11173 offset = extended ? offset : offset << 2;
11174 gen_addiupc(ctx, ry, offset, 1, extended);
11175 break;
11176 case I64_DADDIUSP:
11177 check_insn(ctx, ISA_MIPS3);
11178 check_mips_64(ctx);
11179 offset = extended ? offset : offset << 2;
11180 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
11181 break;
11182 }
11183 }
11184 #endif
11185
11186 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11187 {
11188 int extend = cpu_lduw_code(env, ctx->pc + 2);
11189 int op, rx, ry, funct, sa;
11190 int16_t imm, offset;
11191
11192 ctx->opcode = (ctx->opcode << 16) | extend;
11193 op = (ctx->opcode >> 11) & 0x1f;
11194 sa = (ctx->opcode >> 22) & 0x1f;
11195 funct = (ctx->opcode >> 8) & 0x7;
11196 rx = xlat((ctx->opcode >> 8) & 0x7);
11197 ry = xlat((ctx->opcode >> 5) & 0x7);
11198 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
11199 | ((ctx->opcode >> 21) & 0x3f) << 5
11200 | (ctx->opcode & 0x1f));
11201
11202 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11203 counterparts. */
11204 switch (op) {
11205 case M16_OPC_ADDIUSP:
11206 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11207 break;
11208 case M16_OPC_ADDIUPC:
11209 gen_addiupc(ctx, rx, imm, 0, 1);
11210 break;
11211 case M16_OPC_B:
11212 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
11213 /* No delay slot, so just process as a normal instruction */
11214 break;
11215 case M16_OPC_BEQZ:
11216 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
11217 /* No delay slot, so just process as a normal instruction */
11218 break;
11219 case M16_OPC_BNEQZ:
11220 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
11221 /* No delay slot, so just process as a normal instruction */
11222 break;
11223 case M16_OPC_SHIFT:
11224 switch (ctx->opcode & 0x3) {
11225 case 0x0:
11226 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11227 break;
11228 case 0x1:
11229 #if defined(TARGET_MIPS64)
11230 check_mips_64(ctx);
11231 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11232 #else
11233 generate_exception_end(ctx, EXCP_RI);
11234 #endif
11235 break;
11236 case 0x2:
11237 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11238 break;
11239 case 0x3:
11240 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11241 break;
11242 }
11243 break;
11244 #if defined(TARGET_MIPS64)
11245 case M16_OPC_LD:
11246 check_insn(ctx, ISA_MIPS3);
11247 check_mips_64(ctx);
11248 gen_ld(ctx, OPC_LD, ry, rx, offset);
11249 break;
11250 #endif
11251 case M16_OPC_RRIA:
11252 imm = ctx->opcode & 0xf;
11253 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
11254 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
11255 imm = (int16_t) (imm << 1) >> 1;
11256 if ((ctx->opcode >> 4) & 0x1) {
11257 #if defined(TARGET_MIPS64)
11258 check_mips_64(ctx);
11259 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11260 #else
11261 generate_exception_end(ctx, EXCP_RI);
11262 #endif
11263 } else {
11264 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11265 }
11266 break;
11267 case M16_OPC_ADDIU8:
11268 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11269 break;
11270 case M16_OPC_SLTI:
11271 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11272 break;
11273 case M16_OPC_SLTIU:
11274 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11275 break;
11276 case M16_OPC_I8:
11277 switch (funct) {
11278 case I8_BTEQZ:
11279 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
11280 break;
11281 case I8_BTNEZ:
11282 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
11283 break;
11284 case I8_SWRASP:
11285 gen_st(ctx, OPC_SW, 31, 29, imm);
11286 break;
11287 case I8_ADJSP:
11288 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
11289 break;
11290 case I8_SVRS:
11291 check_insn(ctx, ISA_MIPS32);
11292 {
11293 int xsregs = (ctx->opcode >> 24) & 0x7;
11294 int aregs = (ctx->opcode >> 16) & 0xf;
11295 int do_ra = (ctx->opcode >> 6) & 0x1;
11296 int do_s0 = (ctx->opcode >> 5) & 0x1;
11297 int do_s1 = (ctx->opcode >> 4) & 0x1;
11298 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
11299 | (ctx->opcode & 0xf)) << 3;
11300
11301 if (ctx->opcode & (1 << 7)) {
11302 gen_mips16_save(ctx, xsregs, aregs,
11303 do_ra, do_s0, do_s1,
11304 framesize);
11305 } else {
11306 gen_mips16_restore(ctx, xsregs, aregs,
11307 do_ra, do_s0, do_s1,
11308 framesize);
11309 }
11310 }
11311 break;
11312 default:
11313 generate_exception_end(ctx, EXCP_RI);
11314 break;
11315 }
11316 break;
11317 case M16_OPC_LI:
11318 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
11319 break;
11320 case M16_OPC_CMPI:
11321 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
11322 break;
11323 #if defined(TARGET_MIPS64)
11324 case M16_OPC_SD:
11325 check_insn(ctx, ISA_MIPS3);
11326 check_mips_64(ctx);
11327 gen_st(ctx, OPC_SD, ry, rx, offset);
11328 break;
11329 #endif
11330 case M16_OPC_LB:
11331 gen_ld(ctx, OPC_LB, ry, rx, offset);
11332 break;
11333 case M16_OPC_LH:
11334 gen_ld(ctx, OPC_LH, ry, rx, offset);
11335 break;
11336 case M16_OPC_LWSP:
11337 gen_ld(ctx, OPC_LW, rx, 29, offset);
11338 break;
11339 case M16_OPC_LW:
11340 gen_ld(ctx, OPC_LW, ry, rx, offset);
11341 break;
11342 case M16_OPC_LBU:
11343 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11344 break;
11345 case M16_OPC_LHU:
11346 gen_ld(ctx, OPC_LHU, ry, rx, offset);
11347 break;
11348 case M16_OPC_LWPC:
11349 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
11350 break;
11351 #if defined(TARGET_MIPS64)
11352 case M16_OPC_LWU:
11353 check_insn(ctx, ISA_MIPS3);
11354 check_mips_64(ctx);
11355 gen_ld(ctx, OPC_LWU, ry, rx, offset);
11356 break;
11357 #endif
11358 case M16_OPC_SB:
11359 gen_st(ctx, OPC_SB, ry, rx, offset);
11360 break;
11361 case M16_OPC_SH:
11362 gen_st(ctx, OPC_SH, ry, rx, offset);
11363 break;
11364 case M16_OPC_SWSP:
11365 gen_st(ctx, OPC_SW, rx, 29, offset);
11366 break;
11367 case M16_OPC_SW:
11368 gen_st(ctx, OPC_SW, ry, rx, offset);
11369 break;
11370 #if defined(TARGET_MIPS64)
11371 case M16_OPC_I64:
11372 decode_i64_mips16(ctx, ry, funct, offset, 1);
11373 break;
11374 #endif
11375 default:
11376 generate_exception_end(ctx, EXCP_RI);
11377 break;
11378 }
11379
11380 return 4;
11381 }
11382
11383 static inline bool is_uhi(int sdbbp_code)
11384 {
11385 #ifdef CONFIG_USER_ONLY
11386 return false;
11387 #else
11388 return semihosting_enabled() && sdbbp_code == 1;
11389 #endif
11390 }
11391
11392 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
11393 {
11394 int rx, ry;
11395 int sa;
11396 int op, cnvt_op, op1, offset;
11397 int funct;
11398 int n_bytes;
11399
11400 op = (ctx->opcode >> 11) & 0x1f;
11401 sa = (ctx->opcode >> 2) & 0x7;
11402 sa = sa == 0 ? 8 : sa;
11403 rx = xlat((ctx->opcode >> 8) & 0x7);
11404 cnvt_op = (ctx->opcode >> 5) & 0x7;
11405 ry = xlat((ctx->opcode >> 5) & 0x7);
11406 op1 = offset = ctx->opcode & 0x1f;
11407
11408 n_bytes = 2;
11409
11410 switch (op) {
11411 case M16_OPC_ADDIUSP:
11412 {
11413 int16_t imm = ((uint8_t) ctx->opcode) << 2;
11414
11415 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
11416 }
11417 break;
11418 case M16_OPC_ADDIUPC:
11419 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
11420 break;
11421 case M16_OPC_B:
11422 offset = (ctx->opcode & 0x7ff) << 1;
11423 offset = (int16_t)(offset << 4) >> 4;
11424 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
11425 /* No delay slot, so just process as a normal instruction */
11426 break;
11427 case M16_OPC_JAL:
11428 offset = cpu_lduw_code(env, ctx->pc + 2);
11429 offset = (((ctx->opcode & 0x1f) << 21)
11430 | ((ctx->opcode >> 5) & 0x1f) << 16
11431 | offset) << 2;
11432 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
11433 gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
11434 n_bytes = 4;
11435 break;
11436 case M16_OPC_BEQZ:
11437 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
11438 ((int8_t)ctx->opcode) << 1, 0);
11439 /* No delay slot, so just process as a normal instruction */
11440 break;
11441 case M16_OPC_BNEQZ:
11442 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
11443 ((int8_t)ctx->opcode) << 1, 0);
11444 /* No delay slot, so just process as a normal instruction */
11445 break;
11446 case M16_OPC_SHIFT:
11447 switch (ctx->opcode & 0x3) {
11448 case 0x0:
11449 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
11450 break;
11451 case 0x1:
11452 #if defined(TARGET_MIPS64)
11453 check_insn(ctx, ISA_MIPS3);
11454 check_mips_64(ctx);
11455 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
11456 #else
11457 generate_exception_end(ctx, EXCP_RI);
11458 #endif
11459 break;
11460 case 0x2:
11461 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
11462 break;
11463 case 0x3:
11464 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
11465 break;
11466 }
11467 break;
11468 #if defined(TARGET_MIPS64)
11469 case M16_OPC_LD:
11470 check_insn(ctx, ISA_MIPS3);
11471 check_mips_64(ctx);
11472 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
11473 break;
11474 #endif
11475 case M16_OPC_RRIA:
11476 {
11477 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
11478
11479 if ((ctx->opcode >> 4) & 1) {
11480 #if defined(TARGET_MIPS64)
11481 check_insn(ctx, ISA_MIPS3);
11482 check_mips_64(ctx);
11483 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
11484 #else
11485 generate_exception_end(ctx, EXCP_RI);
11486 #endif
11487 } else {
11488 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
11489 }
11490 }
11491 break;
11492 case M16_OPC_ADDIU8:
11493 {
11494 int16_t imm = (int8_t) ctx->opcode;
11495
11496 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
11497 }
11498 break;
11499 case M16_OPC_SLTI:
11500 {
11501 int16_t imm = (uint8_t) ctx->opcode;
11502 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
11503 }
11504 break;
11505 case M16_OPC_SLTIU:
11506 {
11507 int16_t imm = (uint8_t) ctx->opcode;
11508 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
11509 }
11510 break;
11511 case M16_OPC_I8:
11512 {
11513 int reg32;
11514
11515 funct = (ctx->opcode >> 8) & 0x7;
11516 switch (funct) {
11517 case I8_BTEQZ:
11518 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
11519 ((int8_t)ctx->opcode) << 1, 0);
11520 break;
11521 case I8_BTNEZ:
11522 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
11523 ((int8_t)ctx->opcode) << 1, 0);
11524 break;
11525 case I8_SWRASP:
11526 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
11527 break;
11528 case I8_ADJSP:
11529 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
11530 ((int8_t)ctx->opcode) << 3);
11531 break;
11532 case I8_SVRS:
11533 check_insn(ctx, ISA_MIPS32);
11534 {
11535 int do_ra = ctx->opcode & (1 << 6);
11536 int do_s0 = ctx->opcode & (1 << 5);
11537 int do_s1 = ctx->opcode & (1 << 4);
11538 int framesize = ctx->opcode & 0xf;
11539
11540 if (framesize == 0) {
11541 framesize = 128;
11542 } else {
11543 framesize = framesize << 3;
11544 }
11545
11546 if (ctx->opcode & (1 << 7)) {
11547 gen_mips16_save(ctx, 0, 0,
11548 do_ra, do_s0, do_s1, framesize);
11549 } else {
11550 gen_mips16_restore(ctx, 0, 0,
11551 do_ra, do_s0, do_s1, framesize);
11552 }
11553 }
11554 break;
11555 case I8_MOV32R:
11556 {
11557 int rz = xlat(ctx->opcode & 0x7);
11558
11559 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
11560 ((ctx->opcode >> 5) & 0x7);
11561 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
11562 }
11563 break;
11564 case I8_MOVR32:
11565 reg32 = ctx->opcode & 0x1f;
11566 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11567 break;
11568 default:
11569 generate_exception_end(ctx, EXCP_RI);
11570 break;
11571 }
11572 }
11573 break;
11574 case M16_OPC_LI:
11575 {
11576 int16_t imm = (uint8_t) ctx->opcode;
11577
11578 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11579 }
11580 break;
11581 case M16_OPC_CMPI:
11582 {
11583 int16_t imm = (uint8_t) ctx->opcode;
11584 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11585 }
11586 break;
11587 #if defined(TARGET_MIPS64)
11588 case M16_OPC_SD:
11589 check_insn(ctx, ISA_MIPS3);
11590 check_mips_64(ctx);
11591 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11592 break;
11593 #endif
11594 case M16_OPC_LB:
11595 gen_ld(ctx, OPC_LB, ry, rx, offset);
11596 break;
11597 case M16_OPC_LH:
11598 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11599 break;
11600 case M16_OPC_LWSP:
11601 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11602 break;
11603 case M16_OPC_LW:
11604 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11605 break;
11606 case M16_OPC_LBU:
11607 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11608 break;
11609 case M16_OPC_LHU:
11610 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11611 break;
11612 case M16_OPC_LWPC:
11613 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11614 break;
11615 #if defined (TARGET_MIPS64)
11616 case M16_OPC_LWU:
11617 check_insn(ctx, ISA_MIPS3);
11618 check_mips_64(ctx);
11619 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11620 break;
11621 #endif
11622 case M16_OPC_SB:
11623 gen_st(ctx, OPC_SB, ry, rx, offset);
11624 break;
11625 case M16_OPC_SH:
11626 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11627 break;
11628 case M16_OPC_SWSP:
11629 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11630 break;
11631 case M16_OPC_SW:
11632 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11633 break;
11634 case M16_OPC_RRR:
11635 {
11636 int rz = xlat((ctx->opcode >> 2) & 0x7);
11637 int mips32_op;
11638
11639 switch (ctx->opcode & 0x3) {
11640 case RRR_ADDU:
11641 mips32_op = OPC_ADDU;
11642 break;
11643 case RRR_SUBU:
11644 mips32_op = OPC_SUBU;
11645 break;
11646 #if defined(TARGET_MIPS64)
11647 case RRR_DADDU:
11648 mips32_op = OPC_DADDU;
11649 check_insn(ctx, ISA_MIPS3);
11650 check_mips_64(ctx);
11651 break;
11652 case RRR_DSUBU:
11653 mips32_op = OPC_DSUBU;
11654 check_insn(ctx, ISA_MIPS3);
11655 check_mips_64(ctx);
11656 break;
11657 #endif
11658 default:
11659 generate_exception_end(ctx, EXCP_RI);
11660 goto done;
11661 }
11662
11663 gen_arith(ctx, mips32_op, rz, rx, ry);
11664 done:
11665 ;
11666 }
11667 break;
11668 case M16_OPC_RR:
11669 switch (op1) {
11670 case RR_JR:
11671 {
11672 int nd = (ctx->opcode >> 7) & 0x1;
11673 int link = (ctx->opcode >> 6) & 0x1;
11674 int ra = (ctx->opcode >> 5) & 0x1;
11675
11676 if (nd) {
11677 check_insn(ctx, ISA_MIPS32);
11678 }
11679
11680 if (link) {
11681 op = OPC_JALR;
11682 } else {
11683 op = OPC_JR;
11684 }
11685
11686 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
11687 (nd ? 0 : 2));
11688 }
11689 break;
11690 case RR_SDBBP:
11691 if (is_uhi(extract32(ctx->opcode, 5, 6))) {
11692 gen_helper_do_semihosting(cpu_env);
11693 } else {
11694 /* XXX: not clear which exception should be raised
11695 * when in debug mode...
11696 */
11697 check_insn(ctx, ISA_MIPS32);
11698 generate_exception_end(ctx, EXCP_DBp);
11699 }
11700 break;
11701 case RR_SLT:
11702 gen_slt(ctx, OPC_SLT, 24, rx, ry);
11703 break;
11704 case RR_SLTU:
11705 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11706 break;
11707 case RR_BREAK:
11708 generate_exception_end(ctx, EXCP_BREAK);
11709 break;
11710 case RR_SLLV:
11711 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11712 break;
11713 case RR_SRLV:
11714 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11715 break;
11716 case RR_SRAV:
11717 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11718 break;
11719 #if defined (TARGET_MIPS64)
11720 case RR_DSRL:
11721 check_insn(ctx, ISA_MIPS3);
11722 check_mips_64(ctx);
11723 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11724 break;
11725 #endif
11726 case RR_CMP:
11727 gen_logic(ctx, OPC_XOR, 24, rx, ry);
11728 break;
11729 case RR_NEG:
11730 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11731 break;
11732 case RR_AND:
11733 gen_logic(ctx, OPC_AND, rx, rx, ry);
11734 break;
11735 case RR_OR:
11736 gen_logic(ctx, OPC_OR, rx, rx, ry);
11737 break;
11738 case RR_XOR:
11739 gen_logic(ctx, OPC_XOR, rx, rx, ry);
11740 break;
11741 case RR_NOT:
11742 gen_logic(ctx, OPC_NOR, rx, ry, 0);
11743 break;
11744 case RR_MFHI:
11745 gen_HILO(ctx, OPC_MFHI, 0, rx);
11746 break;
11747 case RR_CNVT:
11748 check_insn(ctx, ISA_MIPS32);
11749 switch (cnvt_op) {
11750 case RR_RY_CNVT_ZEB:
11751 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11752 break;
11753 case RR_RY_CNVT_ZEH:
11754 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11755 break;
11756 case RR_RY_CNVT_SEB:
11757 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11758 break;
11759 case RR_RY_CNVT_SEH:
11760 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11761 break;
11762 #if defined (TARGET_MIPS64)
11763 case RR_RY_CNVT_ZEW:
11764 check_insn(ctx, ISA_MIPS64);
11765 check_mips_64(ctx);
11766 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11767 break;
11768 case RR_RY_CNVT_SEW:
11769 check_insn(ctx, ISA_MIPS64);
11770 check_mips_64(ctx);
11771 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11772 break;
11773 #endif
11774 default:
11775 generate_exception_end(ctx, EXCP_RI);
11776 break;
11777 }
11778 break;
11779 case RR_MFLO:
11780 gen_HILO(ctx, OPC_MFLO, 0, rx);
11781 break;
11782 #if defined (TARGET_MIPS64)
11783 case RR_DSRA:
11784 check_insn(ctx, ISA_MIPS3);
11785 check_mips_64(ctx);
11786 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
11787 break;
11788 case RR_DSLLV:
11789 check_insn(ctx, ISA_MIPS3);
11790 check_mips_64(ctx);
11791 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
11792 break;
11793 case RR_DSRLV:
11794 check_insn(ctx, ISA_MIPS3);
11795 check_mips_64(ctx);
11796 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
11797 break;
11798 case RR_DSRAV:
11799 check_insn(ctx, ISA_MIPS3);
11800 check_mips_64(ctx);
11801 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
11802 break;
11803 #endif
11804 case RR_MULT:
11805 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
11806 break;
11807 case RR_MULTU:
11808 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
11809 break;
11810 case RR_DIV:
11811 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
11812 break;
11813 case RR_DIVU:
11814 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
11815 break;
11816 #if defined (TARGET_MIPS64)
11817 case RR_DMULT:
11818 check_insn(ctx, ISA_MIPS3);
11819 check_mips_64(ctx);
11820 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
11821 break;
11822 case RR_DMULTU:
11823 check_insn(ctx, ISA_MIPS3);
11824 check_mips_64(ctx);
11825 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
11826 break;
11827 case RR_DDIV:
11828 check_insn(ctx, ISA_MIPS3);
11829 check_mips_64(ctx);
11830 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
11831 break;
11832 case RR_DDIVU:
11833 check_insn(ctx, ISA_MIPS3);
11834 check_mips_64(ctx);
11835 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
11836 break;
11837 #endif
11838 default:
11839 generate_exception_end(ctx, EXCP_RI);
11840 break;
11841 }
11842 break;
11843 case M16_OPC_EXTEND:
11844 decode_extended_mips16_opc(env, ctx);
11845 n_bytes = 4;
11846 break;
11847 #if defined(TARGET_MIPS64)
11848 case M16_OPC_I64:
11849 funct = (ctx->opcode >> 8) & 0x7;
11850 decode_i64_mips16(ctx, ry, funct, offset, 0);
11851 break;
11852 #endif
11853 default:
11854 generate_exception_end(ctx, EXCP_RI);
11855 break;
11856 }
11857
11858 return n_bytes;
11859 }
11860
11861 /* microMIPS extension to MIPS32/MIPS64 */
11862
11863 /*
11864 * microMIPS32/microMIPS64 major opcodes
11865 *
11866 * 1. MIPS Architecture for Programmers Volume II-B:
11867 * The microMIPS32 Instruction Set (Revision 3.05)
11868 *
11869 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11870 *
11871 * 2. MIPS Architecture For Programmers Volume II-A:
11872 * The MIPS64 Instruction Set (Revision 3.51)
11873 */
11874
11875 enum {
11876 POOL32A = 0x00,
11877 POOL16A = 0x01,
11878 LBU16 = 0x02,
11879 MOVE16 = 0x03,
11880 ADDI32 = 0x04,
11881 R6_LUI = 0x04,
11882 AUI = 0x04,
11883 LBU32 = 0x05,
11884 SB32 = 0x06,
11885 LB32 = 0x07,
11886
11887 POOL32B = 0x08,
11888 POOL16B = 0x09,
11889 LHU16 = 0x0a,
11890 ANDI16 = 0x0b,
11891 ADDIU32 = 0x0c,
11892 LHU32 = 0x0d,
11893 SH32 = 0x0e,
11894 LH32 = 0x0f,
11895
11896 POOL32I = 0x10,
11897 POOL16C = 0x11,
11898 LWSP16 = 0x12,
11899 POOL16D = 0x13,
11900 ORI32 = 0x14,
11901 POOL32F = 0x15,
11902 POOL32S = 0x16, /* MIPS64 */
11903 DADDIU32 = 0x17, /* MIPS64 */
11904
11905 POOL32C = 0x18,
11906 LWGP16 = 0x19,
11907 LW16 = 0x1a,
11908 POOL16E = 0x1b,
11909 XORI32 = 0x1c,
11910 JALS32 = 0x1d,
11911 BOVC = 0x1d,
11912 BEQC = 0x1d,
11913 BEQZALC = 0x1d,
11914 ADDIUPC = 0x1e,
11915 PCREL = 0x1e,
11916 BNVC = 0x1f,
11917 BNEC = 0x1f,
11918 BNEZALC = 0x1f,
11919
11920 R6_BEQZC = 0x20,
11921 JIC = 0x20,
11922 POOL16F = 0x21,
11923 SB16 = 0x22,
11924 BEQZ16 = 0x23,
11925 BEQZC16 = 0x23,
11926 SLTI32 = 0x24,
11927 BEQ32 = 0x25,
11928 BC = 0x25,
11929 SWC132 = 0x26,
11930 LWC132 = 0x27,
11931
11932 /* 0x29 is reserved */
11933 RES_29 = 0x29,
11934 R6_BNEZC = 0x28,
11935 JIALC = 0x28,
11936 SH16 = 0x2a,
11937 BNEZ16 = 0x2b,
11938 BNEZC16 = 0x2b,
11939 SLTIU32 = 0x2c,
11940 BNE32 = 0x2d,
11941 BALC = 0x2d,
11942 SDC132 = 0x2e,
11943 LDC132 = 0x2f,
11944
11945 /* 0x31 is reserved */
11946 RES_31 = 0x31,
11947 BLEZALC = 0x30,
11948 BGEZALC = 0x30,
11949 BGEUC = 0x30,
11950 SWSP16 = 0x32,
11951 B16 = 0x33,
11952 BC16 = 0x33,
11953 ANDI32 = 0x34,
11954 J32 = 0x35,
11955 BGTZC = 0x35,
11956 BLTZC = 0x35,
11957 BLTC = 0x35,
11958 SD32 = 0x36, /* MIPS64 */
11959 LD32 = 0x37, /* MIPS64 */
11960
11961 /* 0x39 is reserved */
11962 RES_39 = 0x39,
11963 BGTZALC = 0x38,
11964 BLTZALC = 0x38,
11965 BLTUC = 0x38,
11966 SW16 = 0x3a,
11967 LI16 = 0x3b,
11968 JALX32 = 0x3c,
11969 JAL32 = 0x3d,
11970 BLEZC = 0x3d,
11971 BGEZC = 0x3d,
11972 BGEC = 0x3d,
11973 SW32 = 0x3e,
11974 LW32 = 0x3f
11975 };
11976
11977 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
11978 enum {
11979 ADDIUPC_00 = 0x00,
11980 ADDIUPC_07 = 0x07,
11981 AUIPC = 0x1e,
11982 ALUIPC = 0x1f,
11983 LWPC_08 = 0x08,
11984 LWPC_0F = 0x0F,
11985 };
11986
11987 /* POOL32A encoding of minor opcode field */
11988
11989 enum {
11990 /* These opcodes are distinguished only by bits 9..6; those bits are
11991 * what are recorded below. */
11992 SLL32 = 0x0,
11993 SRL32 = 0x1,
11994 SRA = 0x2,
11995 ROTR = 0x3,
11996 SELEQZ = 0x5,
11997 SELNEZ = 0x6,
11998 R6_RDHWR = 0x7,
11999
12000 SLLV = 0x0,
12001 SRLV = 0x1,
12002 SRAV = 0x2,
12003 ROTRV = 0x3,
12004 ADD = 0x4,
12005 ADDU32 = 0x5,
12006 SUB = 0x6,
12007 SUBU32 = 0x7,
12008 MUL = 0x8,
12009 AND = 0x9,
12010 OR32 = 0xa,
12011 NOR = 0xb,
12012 XOR32 = 0xc,
12013 SLT = 0xd,
12014 SLTU = 0xe,
12015
12016 MOVN = 0x0,
12017 R6_MUL = 0x0,
12018 MOVZ = 0x1,
12019 MUH = 0x1,
12020 MULU = 0x2,
12021 MUHU = 0x3,
12022 LWXS = 0x4,
12023 R6_DIV = 0x4,
12024 MOD = 0x5,
12025 R6_DIVU = 0x6,
12026 MODU = 0x7,
12027
12028 /* The following can be distinguished by their lower 6 bits. */
12029 BREAK32 = 0x07,
12030 INS = 0x0c,
12031 LSA = 0x0f,
12032 ALIGN = 0x1f,
12033 EXT = 0x2c,
12034 POOL32AXF = 0x3c
12035 };
12036
12037 /* POOL32AXF encoding of minor opcode field extension */
12038
12039 /*
12040 * 1. MIPS Architecture for Programmers Volume II-B:
12041 * The microMIPS32 Instruction Set (Revision 3.05)
12042 *
12043 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12044 *
12045 * 2. MIPS Architecture for Programmers VolumeIV-e:
12046 * The MIPS DSP Application-Specific Extension
12047 * to the microMIPS32 Architecture (Revision 2.34)
12048 *
12049 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12050 */
12051
12052 enum {
12053 /* bits 11..6 */
12054 TEQ = 0x00,
12055 TGE = 0x08,
12056 TGEU = 0x10,
12057 TLT = 0x20,
12058 TLTU = 0x28,
12059 TNE = 0x30,
12060
12061 MFC0 = 0x03,
12062 MTC0 = 0x0b,
12063
12064 /* begin of microMIPS32 DSP */
12065
12066 /* bits 13..12 for 0x01 */
12067 MFHI_ACC = 0x0,
12068 MFLO_ACC = 0x1,
12069 MTHI_ACC = 0x2,
12070 MTLO_ACC = 0x3,
12071
12072 /* bits 13..12 for 0x2a */
12073 MADD_ACC = 0x0,
12074 MADDU_ACC = 0x1,
12075 MSUB_ACC = 0x2,
12076 MSUBU_ACC = 0x3,
12077
12078 /* bits 13..12 for 0x32 */
12079 MULT_ACC = 0x0,
12080 MULTU_ACC = 0x1,
12081
12082 /* end of microMIPS32 DSP */
12083
12084 /* bits 15..12 for 0x2c */
12085 BITSWAP = 0x0,
12086 SEB = 0x2,
12087 SEH = 0x3,
12088 CLO = 0x4,
12089 CLZ = 0x5,
12090 RDHWR = 0x6,
12091 WSBH = 0x7,
12092 MULT = 0x8,
12093 MULTU = 0x9,
12094 DIV = 0xa,
12095 DIVU = 0xb,
12096 MADD = 0xc,
12097 MADDU = 0xd,
12098 MSUB = 0xe,
12099 MSUBU = 0xf,
12100
12101 /* bits 15..12 for 0x34 */
12102 MFC2 = 0x4,
12103 MTC2 = 0x5,
12104 MFHC2 = 0x8,
12105 MTHC2 = 0x9,
12106 CFC2 = 0xc,
12107 CTC2 = 0xd,
12108
12109 /* bits 15..12 for 0x3c */
12110 JALR = 0x0,
12111 JR = 0x0, /* alias */
12112 JALRC = 0x0,
12113 JRC = 0x0,
12114 JALR_HB = 0x1,
12115 JALRC_HB = 0x1,
12116 JALRS = 0x4,
12117 JALRS_HB = 0x5,
12118
12119 /* bits 15..12 for 0x05 */
12120 RDPGPR = 0xe,
12121 WRPGPR = 0xf,
12122
12123 /* bits 15..12 for 0x0d */
12124 TLBP = 0x0,
12125 TLBR = 0x1,
12126 TLBWI = 0x2,
12127 TLBWR = 0x3,
12128 TLBINV = 0x4,
12129 TLBINVF = 0x5,
12130 WAIT = 0x9,
12131 IRET = 0xd,
12132 DERET = 0xe,
12133 ERET = 0xf,
12134
12135 /* bits 15..12 for 0x15 */
12136 DMT = 0x0,
12137 DVPE = 0x1,
12138 EMT = 0x2,
12139 EVPE = 0x3,
12140
12141 /* bits 15..12 for 0x1d */
12142 DI = 0x4,
12143 EI = 0x5,
12144
12145 /* bits 15..12 for 0x2d */
12146 SYNC = 0x6,
12147 SYSCALL = 0x8,
12148 SDBBP = 0xd,
12149
12150 /* bits 15..12 for 0x35 */
12151 MFHI32 = 0x0,
12152 MFLO32 = 0x1,
12153 MTHI32 = 0x2,
12154 MTLO32 = 0x3,
12155 };
12156
12157 /* POOL32B encoding of minor opcode field (bits 15..12) */
12158
12159 enum {
12160 LWC2 = 0x0,
12161 LWP = 0x1,
12162 LDP = 0x4,
12163 LWM32 = 0x5,
12164 CACHE = 0x6,
12165 LDM = 0x7,
12166 SWC2 = 0x8,
12167 SWP = 0x9,
12168 SDP = 0xc,
12169 SWM32 = 0xd,
12170 SDM = 0xf
12171 };
12172
12173 /* POOL32C encoding of minor opcode field (bits 15..12) */
12174
12175 enum {
12176 LWL = 0x0,
12177 SWL = 0x8,
12178 LWR = 0x1,
12179 SWR = 0x9,
12180 PREF = 0x2,
12181 /* 0xa is reserved */
12182 LL = 0x3,
12183 SC = 0xb,
12184 LDL = 0x4,
12185 SDL = 0xc,
12186 LDR = 0x5,
12187 SDR = 0xd,
12188 /* 0x6 is reserved */
12189 LWU = 0xe,
12190 LLD = 0x7,
12191 SCD = 0xf
12192 };
12193
12194 /* POOL32F encoding of minor opcode field (bits 5..0) */
12195
12196 enum {
12197 /* These are the bit 7..6 values */
12198 ADD_FMT = 0x0,
12199
12200 SUB_FMT = 0x1,
12201
12202 MUL_FMT = 0x2,
12203
12204 DIV_FMT = 0x3,
12205
12206 /* These are the bit 8..6 values */
12207 MOVN_FMT = 0x0,
12208 RSQRT2_FMT = 0x0,
12209 MOVF_FMT = 0x0,
12210 RINT_FMT = 0x0,
12211 SELNEZ_FMT = 0x0,
12212
12213 MOVZ_FMT = 0x1,
12214 LWXC1 = 0x1,
12215 MOVT_FMT = 0x1,
12216 CLASS_FMT = 0x1,
12217 SELEQZ_FMT = 0x1,
12218
12219 PLL_PS = 0x2,
12220 SWXC1 = 0x2,
12221 SEL_FMT = 0x2,
12222
12223 PLU_PS = 0x3,
12224 LDXC1 = 0x3,
12225
12226 MOVN_FMT_04 = 0x4,
12227 PUL_PS = 0x4,
12228 SDXC1 = 0x4,
12229 RECIP2_FMT = 0x4,
12230
12231 MOVZ_FMT_05 = 0x05,
12232 PUU_PS = 0x5,
12233 LUXC1 = 0x5,
12234
12235 CVT_PS_S = 0x6,
12236 SUXC1 = 0x6,
12237 ADDR_PS = 0x6,
12238 PREFX = 0x6,
12239 MADDF_FMT = 0x6,
12240
12241 MULR_PS = 0x7,
12242 MSUBF_FMT = 0x7,
12243
12244 MADD_S = 0x01,
12245 MADD_D = 0x09,
12246 MADD_PS = 0x11,
12247 ALNV_PS = 0x19,
12248 MSUB_S = 0x21,
12249 MSUB_D = 0x29,
12250 MSUB_PS = 0x31,
12251
12252 NMADD_S = 0x02,
12253 NMADD_D = 0x0a,
12254 NMADD_PS = 0x12,
12255 NMSUB_S = 0x22,
12256 NMSUB_D = 0x2a,
12257 NMSUB_PS = 0x32,
12258
12259 MIN_FMT = 0x3,
12260 MAX_FMT = 0xb,
12261 MINA_FMT = 0x23,
12262 MAXA_FMT = 0x2b,
12263 POOL32FXF = 0x3b,
12264
12265 CABS_COND_FMT = 0x1c, /* MIPS3D */
12266 C_COND_FMT = 0x3c,
12267
12268 CMP_CONDN_S = 0x5,
12269 CMP_CONDN_D = 0x15
12270 };
12271
12272 /* POOL32Fxf encoding of minor opcode extension field */
12273
12274 enum {
12275 CVT_L = 0x04,
12276 RSQRT_FMT = 0x08,
12277 FLOOR_L = 0x0c,
12278 CVT_PW_PS = 0x1c,
12279 CVT_W = 0x24,
12280 SQRT_FMT = 0x28,
12281 FLOOR_W = 0x2c,
12282 CVT_PS_PW = 0x3c,
12283 CFC1 = 0x40,
12284 RECIP_FMT = 0x48,
12285 CEIL_L = 0x4c,
12286 CTC1 = 0x60,
12287 CEIL_W = 0x6c,
12288 MFC1 = 0x80,
12289 CVT_S_PL = 0x84,
12290 TRUNC_L = 0x8c,
12291 MTC1 = 0xa0,
12292 CVT_S_PU = 0xa4,
12293 TRUNC_W = 0xac,
12294 MFHC1 = 0xc0,
12295 ROUND_L = 0xcc,
12296 MTHC1 = 0xe0,
12297 ROUND_W = 0xec,
12298
12299 MOV_FMT = 0x01,
12300 MOVF = 0x05,
12301 ABS_FMT = 0x0d,
12302 RSQRT1_FMT = 0x1d,
12303 MOVT = 0x25,
12304 NEG_FMT = 0x2d,
12305 CVT_D = 0x4d,
12306 RECIP1_FMT = 0x5d,
12307 CVT_S = 0x6d
12308 };
12309
12310 /* POOL32I encoding of minor opcode field (bits 25..21) */
12311
12312 enum {
12313 BLTZ = 0x00,
12314 BLTZAL = 0x01,
12315 BGEZ = 0x02,
12316 BGEZAL = 0x03,
12317 BLEZ = 0x04,
12318 BNEZC = 0x05,
12319 BGTZ = 0x06,
12320 BEQZC = 0x07,
12321 TLTI = 0x08,
12322 BC1EQZC = 0x08,
12323 TGEI = 0x09,
12324 BC1NEZC = 0x09,
12325 TLTIU = 0x0a,
12326 BC2EQZC = 0x0a,
12327 TGEIU = 0x0b,
12328 BC2NEZC = 0x0a,
12329 TNEI = 0x0c,
12330 R6_SYNCI = 0x0c,
12331 LUI = 0x0d,
12332 TEQI = 0x0e,
12333 SYNCI = 0x10,
12334 BLTZALS = 0x11,
12335 BGEZALS = 0x13,
12336 BC2F = 0x14,
12337 BC2T = 0x15,
12338 BPOSGE64 = 0x1a,
12339 BPOSGE32 = 0x1b,
12340 /* These overlap and are distinguished by bit16 of the instruction */
12341 BC1F = 0x1c,
12342 BC1T = 0x1d,
12343 BC1ANY2F = 0x1c,
12344 BC1ANY2T = 0x1d,
12345 BC1ANY4F = 0x1e,
12346 BC1ANY4T = 0x1f
12347 };
12348
12349 /* POOL16A encoding of minor opcode field */
12350
12351 enum {
12352 ADDU16 = 0x0,
12353 SUBU16 = 0x1
12354 };
12355
12356 /* POOL16B encoding of minor opcode field */
12357
12358 enum {
12359 SLL16 = 0x0,
12360 SRL16 = 0x1
12361 };
12362
12363 /* POOL16C encoding of minor opcode field */
12364
12365 enum {
12366 NOT16 = 0x00,
12367 XOR16 = 0x04,
12368 AND16 = 0x08,
12369 OR16 = 0x0c,
12370 LWM16 = 0x10,
12371 SWM16 = 0x14,
12372 JR16 = 0x18,
12373 JRC16 = 0x1a,
12374 JALR16 = 0x1c,
12375 JALR16S = 0x1e,
12376 MFHI16 = 0x20,
12377 MFLO16 = 0x24,
12378 BREAK16 = 0x28,
12379 SDBBP16 = 0x2c,
12380 JRADDIUSP = 0x30
12381 };
12382
12383 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12384
12385 enum {
12386 R6_NOT16 = 0x00,
12387 R6_AND16 = 0x01,
12388 R6_LWM16 = 0x02,
12389 R6_JRC16 = 0x03,
12390 MOVEP = 0x04,
12391 MOVEP_07 = 0x07,
12392 R6_XOR16 = 0x08,
12393 R6_OR16 = 0x09,
12394 R6_SWM16 = 0x0a,
12395 JALRC16 = 0x0b,
12396 MOVEP_0C = 0x0c,
12397 MOVEP_0F = 0x0f,
12398 JRCADDIUSP = 0x13,
12399 R6_BREAK16 = 0x1b,
12400 R6_SDBBP16 = 0x3b
12401 };
12402
12403 /* POOL16D encoding of minor opcode field */
12404
12405 enum {
12406 ADDIUS5 = 0x0,
12407 ADDIUSP = 0x1
12408 };
12409
12410 /* POOL16E encoding of minor opcode field */
12411
12412 enum {
12413 ADDIUR2 = 0x0,
12414 ADDIUR1SP = 0x1
12415 };
12416
12417 static int mmreg (int r)
12418 {
12419 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12420
12421 return map[r];
12422 }
12423
12424 /* Used for 16-bit store instructions. */
12425 static int mmreg2 (int r)
12426 {
12427 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12428
12429 return map[r];
12430 }
12431
12432 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12433 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12434 #define uMIPS_RS2(op) uMIPS_RS(op)
12435 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12436 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12437 #define uMIPS_RS5(op) (op & 0x1f)
12438
12439 /* Signed immediate */
12440 #define SIMM(op, start, width) \
12441 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12442 << (32-width)) \
12443 >> (32-width))
12444 /* Zero-extended immediate */
12445 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12446
12447 static void gen_addiur1sp(DisasContext *ctx)
12448 {
12449 int rd = mmreg(uMIPS_RD(ctx->opcode));
12450
12451 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
12452 }
12453
12454 static void gen_addiur2(DisasContext *ctx)
12455 {
12456 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12457 int rd = mmreg(uMIPS_RD(ctx->opcode));
12458 int rs = mmreg(uMIPS_RS(ctx->opcode));
12459
12460 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
12461 }
12462
12463 static void gen_addiusp(DisasContext *ctx)
12464 {
12465 int encoded = ZIMM(ctx->opcode, 1, 9);
12466 int decoded;
12467
12468 if (encoded <= 1) {
12469 decoded = 256 + encoded;
12470 } else if (encoded <= 255) {
12471 decoded = encoded;
12472 } else if (encoded <= 509) {
12473 decoded = encoded - 512;
12474 } else {
12475 decoded = encoded - 768;
12476 }
12477
12478 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
12479 }
12480
12481 static void gen_addius5(DisasContext *ctx)
12482 {
12483 int imm = SIMM(ctx->opcode, 1, 4);
12484 int rd = (ctx->opcode >> 5) & 0x1f;
12485
12486 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
12487 }
12488
12489 static void gen_andi16(DisasContext *ctx)
12490 {
12491 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12492 31, 32, 63, 64, 255, 32768, 65535 };
12493 int rd = mmreg(uMIPS_RD(ctx->opcode));
12494 int rs = mmreg(uMIPS_RS(ctx->opcode));
12495 int encoded = ZIMM(ctx->opcode, 0, 4);
12496
12497 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
12498 }
12499
12500 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
12501 int base, int16_t offset)
12502 {
12503 TCGv t0, t1;
12504 TCGv_i32 t2;
12505
12506 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12507 generate_exception_end(ctx, EXCP_RI);
12508 return;
12509 }
12510
12511 t0 = tcg_temp_new();
12512
12513 gen_base_offset_addr(ctx, t0, base, offset);
12514
12515 t1 = tcg_const_tl(reglist);
12516 t2 = tcg_const_i32(ctx->mem_idx);
12517
12518 save_cpu_state(ctx, 1);
12519 switch (opc) {
12520 case LWM32:
12521 gen_helper_lwm(cpu_env, t0, t1, t2);
12522 break;
12523 case SWM32:
12524 gen_helper_swm(cpu_env, t0, t1, t2);
12525 break;
12526 #ifdef TARGET_MIPS64
12527 case LDM:
12528 gen_helper_ldm(cpu_env, t0, t1, t2);
12529 break;
12530 case SDM:
12531 gen_helper_sdm(cpu_env, t0, t1, t2);
12532 break;
12533 #endif
12534 }
12535 tcg_temp_free(t0);
12536 tcg_temp_free(t1);
12537 tcg_temp_free_i32(t2);
12538 }
12539
12540
12541 static void gen_pool16c_insn(DisasContext *ctx)
12542 {
12543 int rd = mmreg((ctx->opcode >> 3) & 0x7);
12544 int rs = mmreg(ctx->opcode & 0x7);
12545
12546 switch (((ctx->opcode) >> 4) & 0x3f) {
12547 case NOT16 + 0:
12548 case NOT16 + 1:
12549 case NOT16 + 2:
12550 case NOT16 + 3:
12551 gen_logic(ctx, OPC_NOR, rd, rs, 0);
12552 break;
12553 case XOR16 + 0:
12554 case XOR16 + 1:
12555 case XOR16 + 2:
12556 case XOR16 + 3:
12557 gen_logic(ctx, OPC_XOR, rd, rd, rs);
12558 break;
12559 case AND16 + 0:
12560 case AND16 + 1:
12561 case AND16 + 2:
12562 case AND16 + 3:
12563 gen_logic(ctx, OPC_AND, rd, rd, rs);
12564 break;
12565 case OR16 + 0:
12566 case OR16 + 1:
12567 case OR16 + 2:
12568 case OR16 + 3:
12569 gen_logic(ctx, OPC_OR, rd, rd, rs);
12570 break;
12571 case LWM16 + 0:
12572 case LWM16 + 1:
12573 case LWM16 + 2:
12574 case LWM16 + 3:
12575 {
12576 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12577 int offset = ZIMM(ctx->opcode, 0, 4);
12578
12579 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
12580 29, offset << 2);
12581 }
12582 break;
12583 case SWM16 + 0:
12584 case SWM16 + 1:
12585 case SWM16 + 2:
12586 case SWM16 + 3:
12587 {
12588 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
12589 int offset = ZIMM(ctx->opcode, 0, 4);
12590
12591 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
12592 29, offset << 2);
12593 }
12594 break;
12595 case JR16 + 0:
12596 case JR16 + 1:
12597 {
12598 int reg = ctx->opcode & 0x1f;
12599
12600 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
12601 }
12602 break;
12603 case JRC16 + 0:
12604 case JRC16 + 1:
12605 {
12606 int reg = ctx->opcode & 0x1f;
12607 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
12608 /* Let normal delay slot handling in our caller take us
12609 to the branch target. */
12610 }
12611 break;
12612 case JALR16 + 0:
12613 case JALR16 + 1:
12614 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
12615 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12616 break;
12617 case JALR16S + 0:
12618 case JALR16S + 1:
12619 gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
12620 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
12621 break;
12622 case MFHI16 + 0:
12623 case MFHI16 + 1:
12624 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
12625 break;
12626 case MFLO16 + 0:
12627 case MFLO16 + 1:
12628 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
12629 break;
12630 case BREAK16:
12631 generate_exception_end(ctx, EXCP_BREAK);
12632 break;
12633 case SDBBP16:
12634 if (is_uhi(extract32(ctx->opcode, 0, 4))) {
12635 gen_helper_do_semihosting(cpu_env);
12636 } else {
12637 /* XXX: not clear which exception should be raised
12638 * when in debug mode...
12639 */
12640 check_insn(ctx, ISA_MIPS32);
12641 generate_exception_end(ctx, EXCP_DBp);
12642 }
12643 break;
12644 case JRADDIUSP + 0:
12645 case JRADDIUSP + 1:
12646 {
12647 int imm = ZIMM(ctx->opcode, 0, 5);
12648 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12649 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12650 /* Let normal delay slot handling in our caller take us
12651 to the branch target. */
12652 }
12653 break;
12654 default:
12655 generate_exception_end(ctx, EXCP_RI);
12656 break;
12657 }
12658 }
12659
12660 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
12661 int enc_rs)
12662 {
12663 int rd, rs, re, rt;
12664 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12665 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12666 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12667 rd = rd_enc[enc_dest];
12668 re = re_enc[enc_dest];
12669 rs = rs_rt_enc[enc_rs];
12670 rt = rs_rt_enc[enc_rt];
12671 if (rs) {
12672 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
12673 } else {
12674 tcg_gen_movi_tl(cpu_gpr[rd], 0);
12675 }
12676 if (rt) {
12677 tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
12678 } else {
12679 tcg_gen_movi_tl(cpu_gpr[re], 0);
12680 }
12681 }
12682
12683 static void gen_pool16c_r6_insn(DisasContext *ctx)
12684 {
12685 int rt = mmreg((ctx->opcode >> 7) & 0x7);
12686 int rs = mmreg((ctx->opcode >> 4) & 0x7);
12687
12688 switch (ctx->opcode & 0xf) {
12689 case R6_NOT16:
12690 gen_logic(ctx, OPC_NOR, rt, rs, 0);
12691 break;
12692 case R6_AND16:
12693 gen_logic(ctx, OPC_AND, rt, rt, rs);
12694 break;
12695 case R6_LWM16:
12696 {
12697 int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12698 int offset = extract32(ctx->opcode, 4, 4);
12699 gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
12700 }
12701 break;
12702 case R6_JRC16: /* JRCADDIUSP */
12703 if ((ctx->opcode >> 4) & 1) {
12704 /* JRCADDIUSP */
12705 int imm = extract32(ctx->opcode, 5, 5);
12706 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
12707 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
12708 } else {
12709 /* JRC16 */
12710 int rs = extract32(ctx->opcode, 5, 5);
12711 gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
12712 }
12713 break;
12714 case MOVEP ... MOVEP_07:
12715 case MOVEP_0C ... MOVEP_0F:
12716 {
12717 int enc_dest = uMIPS_RD(ctx->opcode);
12718 int enc_rt = uMIPS_RS2(ctx->opcode);
12719 int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
12720 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
12721 }
12722 break;
12723 case R6_XOR16:
12724 gen_logic(ctx, OPC_XOR, rt, rt, rs);
12725 break;
12726 case R6_OR16:
12727 gen_logic(ctx, OPC_OR, rt, rt, rs);
12728 break;
12729 case R6_SWM16:
12730 {
12731 int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
12732 int offset = extract32(ctx->opcode, 4, 4);
12733 gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
12734 }
12735 break;
12736 case JALRC16: /* BREAK16, SDBBP16 */
12737 switch (ctx->opcode & 0x3f) {
12738 case JALRC16:
12739 case JALRC16 + 0x20:
12740 /* JALRC16 */
12741 gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
12742 31, 0, 0);
12743 break;
12744 case R6_BREAK16:
12745 /* BREAK16 */
12746 generate_exception(ctx, EXCP_BREAK);
12747 break;
12748 case R6_SDBBP16:
12749 /* SDBBP16 */
12750 if (is_uhi(extract32(ctx->opcode, 6, 4))) {
12751 gen_helper_do_semihosting(cpu_env);
12752 } else {
12753 if (ctx->hflags & MIPS_HFLAG_SBRI) {
12754 generate_exception(ctx, EXCP_RI);
12755 } else {
12756 generate_exception(ctx, EXCP_DBp);
12757 }
12758 }
12759 break;
12760 }
12761 break;
12762 default:
12763 generate_exception(ctx, EXCP_RI);
12764 break;
12765 }
12766 }
12767
12768 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
12769 {
12770 TCGv t0 = tcg_temp_new();
12771 TCGv t1 = tcg_temp_new();
12772
12773 gen_load_gpr(t0, base);
12774
12775 if (index != 0) {
12776 gen_load_gpr(t1, index);
12777 tcg_gen_shli_tl(t1, t1, 2);
12778 gen_op_addr_add(ctx, t0, t1, t0);
12779 }
12780
12781 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12782 gen_store_gpr(t1, rd);
12783
12784 tcg_temp_free(t0);
12785 tcg_temp_free(t1);
12786 }
12787
12788 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12789 int base, int16_t offset)
12790 {
12791 TCGv t0, t1;
12792
12793 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
12794 generate_exception_end(ctx, EXCP_RI);
12795 return;
12796 }
12797
12798 t0 = tcg_temp_new();
12799 t1 = tcg_temp_new();
12800
12801 gen_base_offset_addr(ctx, t0, base, offset);
12802
12803 switch (opc) {
12804 case LWP:
12805 if (rd == base) {
12806 generate_exception_end(ctx, EXCP_RI);
12807 return;
12808 }
12809 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12810 gen_store_gpr(t1, rd);
12811 tcg_gen_movi_tl(t1, 4);
12812 gen_op_addr_add(ctx, t0, t0, t1);
12813 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12814 gen_store_gpr(t1, rd+1);
12815 break;
12816 case SWP:
12817 gen_load_gpr(t1, rd);
12818 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12819 tcg_gen_movi_tl(t1, 4);
12820 gen_op_addr_add(ctx, t0, t0, t1);
12821 gen_load_gpr(t1, rd+1);
12822 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12823 break;
12824 #ifdef TARGET_MIPS64
12825 case LDP:
12826 if (rd == base) {
12827 generate_exception_end(ctx, EXCP_RI);
12828 return;
12829 }
12830 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12831 gen_store_gpr(t1, rd);
12832 tcg_gen_movi_tl(t1, 8);
12833 gen_op_addr_add(ctx, t0, t0, t1);
12834 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12835 gen_store_gpr(t1, rd+1);
12836 break;
12837 case SDP:
12838 gen_load_gpr(t1, rd);
12839 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12840 tcg_gen_movi_tl(t1, 8);
12841 gen_op_addr_add(ctx, t0, t0, t1);
12842 gen_load_gpr(t1, rd+1);
12843 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12844 break;
12845 #endif
12846 }
12847 tcg_temp_free(t0);
12848 tcg_temp_free(t1);
12849 }
12850
12851 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
12852 {
12853 int extension = (ctx->opcode >> 6) & 0x3f;
12854 int minor = (ctx->opcode >> 12) & 0xf;
12855 uint32_t mips32_op;
12856
12857 switch (extension) {
12858 case TEQ:
12859 mips32_op = OPC_TEQ;
12860 goto do_trap;
12861 case TGE:
12862 mips32_op = OPC_TGE;
12863 goto do_trap;
12864 case TGEU:
12865 mips32_op = OPC_TGEU;
12866 goto do_trap;
12867 case TLT:
12868 mips32_op = OPC_TLT;
12869 goto do_trap;
12870 case TLTU:
12871 mips32_op = OPC_TLTU;
12872 goto do_trap;
12873 case TNE:
12874 mips32_op = OPC_TNE;
12875 do_trap:
12876 gen_trap(ctx, mips32_op, rs, rt, -1);
12877 break;
12878 #ifndef CONFIG_USER_ONLY
12879 case MFC0:
12880 case MFC0 + 32:
12881 check_cp0_enabled(ctx);
12882 if (rt == 0) {
12883 /* Treat as NOP. */
12884 break;
12885 }
12886 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
12887 break;
12888 case MTC0:
12889 case MTC0 + 32:
12890 check_cp0_enabled(ctx);
12891 {
12892 TCGv t0 = tcg_temp_new();
12893
12894 gen_load_gpr(t0, rt);
12895 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
12896 tcg_temp_free(t0);
12897 }
12898 break;
12899 #endif
12900 case 0x2a:
12901 switch (minor & 3) {
12902 case MADD_ACC:
12903 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12904 break;
12905 case MADDU_ACC:
12906 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12907 break;
12908 case MSUB_ACC:
12909 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12910 break;
12911 case MSUBU_ACC:
12912 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12913 break;
12914 default:
12915 goto pool32axf_invalid;
12916 }
12917 break;
12918 case 0x32:
12919 switch (minor & 3) {
12920 case MULT_ACC:
12921 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12922 break;
12923 case MULTU_ACC:
12924 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12925 break;
12926 default:
12927 goto pool32axf_invalid;
12928 }
12929 break;
12930 case 0x2c:
12931 switch (minor) {
12932 case BITSWAP:
12933 check_insn(ctx, ISA_MIPS32R6);
12934 gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
12935 break;
12936 case SEB:
12937 gen_bshfl(ctx, OPC_SEB, rs, rt);
12938 break;
12939 case SEH:
12940 gen_bshfl(ctx, OPC_SEH, rs, rt);
12941 break;
12942 case CLO:
12943 mips32_op = OPC_CLO;
12944 goto do_cl;
12945 case CLZ:
12946 mips32_op = OPC_CLZ;
12947 do_cl:
12948 check_insn(ctx, ISA_MIPS32);
12949 gen_cl(ctx, mips32_op, rt, rs);
12950 break;
12951 case RDHWR:
12952 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12953 gen_rdhwr(ctx, rt, rs, 0);
12954 break;
12955 case WSBH:
12956 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12957 break;
12958 case MULT:
12959 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12960 mips32_op = OPC_MULT;
12961 goto do_mul;
12962 case MULTU:
12963 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12964 mips32_op = OPC_MULTU;
12965 goto do_mul;
12966 case DIV:
12967 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12968 mips32_op = OPC_DIV;
12969 goto do_div;
12970 case DIVU:
12971 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12972 mips32_op = OPC_DIVU;
12973 goto do_div;
12974 do_div:
12975 check_insn(ctx, ISA_MIPS32);
12976 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12977 break;
12978 case MADD:
12979 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12980 mips32_op = OPC_MADD;
12981 goto do_mul;
12982 case MADDU:
12983 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12984 mips32_op = OPC_MADDU;
12985 goto do_mul;
12986 case MSUB:
12987 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12988 mips32_op = OPC_MSUB;
12989 goto do_mul;
12990 case MSUBU:
12991 check_insn_opc_removed(ctx, ISA_MIPS32R6);
12992 mips32_op = OPC_MSUBU;
12993 do_mul:
12994 check_insn(ctx, ISA_MIPS32);
12995 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12996 break;
12997 default:
12998 goto pool32axf_invalid;
12999 }
13000 break;
13001 case 0x34:
13002 switch (minor) {
13003 case MFC2:
13004 case MTC2:
13005 case MFHC2:
13006 case MTHC2:
13007 case CFC2:
13008 case CTC2:
13009 generate_exception_err(ctx, EXCP_CpU, 2);
13010 break;
13011 default:
13012 goto pool32axf_invalid;
13013 }
13014 break;
13015 case 0x3c:
13016 switch (minor) {
13017 case JALR: /* JALRC */
13018 case JALR_HB: /* JALRC_HB */
13019 if (ctx->insn_flags & ISA_MIPS32R6) {
13020 /* JALRC, JALRC_HB */
13021 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
13022 } else {
13023 /* JALR, JALR_HB */
13024 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
13025 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13026 }
13027 break;
13028 case JALRS:
13029 case JALRS_HB:
13030 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13031 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
13032 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
13033 break;
13034 default:
13035 goto pool32axf_invalid;
13036 }
13037 break;
13038 case 0x05:
13039 switch (minor) {
13040 case RDPGPR:
13041 check_cp0_enabled(ctx);
13042 check_insn(ctx, ISA_MIPS32R2);
13043 gen_load_srsgpr(rs, rt);
13044 break;
13045 case WRPGPR:
13046 check_cp0_enabled(ctx);
13047 check_insn(ctx, ISA_MIPS32R2);
13048 gen_store_srsgpr(rs, rt);
13049 break;
13050 default:
13051 goto pool32axf_invalid;
13052 }
13053 break;
13054 #ifndef CONFIG_USER_ONLY
13055 case 0x0d:
13056 switch (minor) {
13057 case TLBP:
13058 mips32_op = OPC_TLBP;
13059 goto do_cp0;
13060 case TLBR:
13061 mips32_op = OPC_TLBR;
13062 goto do_cp0;
13063 case TLBWI:
13064 mips32_op = OPC_TLBWI;
13065 goto do_cp0;
13066 case TLBWR:
13067 mips32_op = OPC_TLBWR;
13068 goto do_cp0;
13069 case TLBINV:
13070 mips32_op = OPC_TLBINV;
13071 goto do_cp0;
13072 case TLBINVF:
13073 mips32_op = OPC_TLBINVF;
13074 goto do_cp0;
13075 case WAIT:
13076 mips32_op = OPC_WAIT;
13077 goto do_cp0;
13078 case DERET:
13079 mips32_op = OPC_DERET;
13080 goto do_cp0;
13081 case ERET:
13082 mips32_op = OPC_ERET;
13083 do_cp0:
13084 gen_cp0(env, ctx, mips32_op, rt, rs);
13085 break;
13086 default:
13087 goto pool32axf_invalid;
13088 }
13089 break;
13090 case 0x1d:
13091 switch (minor) {
13092 case DI:
13093 check_cp0_enabled(ctx);
13094 {
13095 TCGv t0 = tcg_temp_new();
13096
13097 save_cpu_state(ctx, 1);
13098 gen_helper_di(t0, cpu_env);
13099 gen_store_gpr(t0, rs);
13100 /* Stop translation as we may have switched the execution mode */
13101 ctx->bstate = BS_STOP;
13102 tcg_temp_free(t0);
13103 }
13104 break;
13105 case EI:
13106 check_cp0_enabled(ctx);
13107 {
13108 TCGv t0 = tcg_temp_new();
13109
13110 save_cpu_state(ctx, 1);
13111 gen_helper_ei(t0, cpu_env);
13112 gen_store_gpr(t0, rs);
13113 /* Stop translation as we may have switched the execution mode */
13114 ctx->bstate = BS_STOP;
13115 tcg_temp_free(t0);
13116 }
13117 break;
13118 default:
13119 goto pool32axf_invalid;
13120 }
13121 break;
13122 #endif
13123 case 0x2d:
13124 switch (minor) {
13125 case SYNC:
13126 /* NOP */
13127 break;
13128 case SYSCALL:
13129 generate_exception_end(ctx, EXCP_SYSCALL);
13130 break;
13131 case SDBBP:
13132 if (is_uhi(extract32(ctx->opcode, 16, 10))) {
13133 gen_helper_do_semihosting(cpu_env);
13134 } else {
13135 check_insn(ctx, ISA_MIPS32);
13136 if (ctx->hflags & MIPS_HFLAG_SBRI) {
13137 generate_exception_end(ctx, EXCP_RI);
13138 } else {
13139 generate_exception_end(ctx, EXCP_DBp);
13140 }
13141 }
13142 break;
13143 default:
13144 goto pool32axf_invalid;
13145 }
13146 break;
13147 case 0x01:
13148 switch (minor & 3) {
13149 case MFHI_ACC:
13150 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
13151 break;
13152 case MFLO_ACC:
13153 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
13154 break;
13155 case MTHI_ACC:
13156 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
13157 break;
13158 case MTLO_ACC:
13159 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
13160 break;
13161 default:
13162 goto pool32axf_invalid;
13163 }
13164 break;
13165 case 0x35:
13166 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13167 switch (minor) {
13168 case MFHI32:
13169 gen_HILO(ctx, OPC_MFHI, 0, rs);
13170 break;
13171 case MFLO32:
13172 gen_HILO(ctx, OPC_MFLO, 0, rs);
13173 break;
13174 case MTHI32:
13175 gen_HILO(ctx, OPC_MTHI, 0, rs);
13176 break;
13177 case MTLO32:
13178 gen_HILO(ctx, OPC_MTLO, 0, rs);
13179 break;
13180 default:
13181 goto pool32axf_invalid;
13182 }
13183 break;
13184 default:
13185 pool32axf_invalid:
13186 MIPS_INVAL("pool32axf");
13187 generate_exception_end(ctx, EXCP_RI);
13188 break;
13189 }
13190 }
13191
13192 /* Values for microMIPS fmt field. Variable-width, depending on which
13193 formats the instruction supports. */
13194
13195 enum {
13196 FMT_SD_S = 0,
13197 FMT_SD_D = 1,
13198
13199 FMT_SDPS_S = 0,
13200 FMT_SDPS_D = 1,
13201 FMT_SDPS_PS = 2,
13202
13203 FMT_SWL_S = 0,
13204 FMT_SWL_W = 1,
13205 FMT_SWL_L = 2,
13206
13207 FMT_DWL_D = 0,
13208 FMT_DWL_W = 1,
13209 FMT_DWL_L = 2
13210 };
13211
13212 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
13213 {
13214 int extension = (ctx->opcode >> 6) & 0x3ff;
13215 uint32_t mips32_op;
13216
13217 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13218 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13219 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13220
13221 switch (extension) {
13222 case FLOAT_1BIT_FMT(CFC1, 0):
13223 mips32_op = OPC_CFC1;
13224 goto do_cp1;
13225 case FLOAT_1BIT_FMT(CTC1, 0):
13226 mips32_op = OPC_CTC1;
13227 goto do_cp1;
13228 case FLOAT_1BIT_FMT(MFC1, 0):
13229 mips32_op = OPC_MFC1;
13230 goto do_cp1;
13231 case FLOAT_1BIT_FMT(MTC1, 0):
13232 mips32_op = OPC_MTC1;
13233 goto do_cp1;
13234 case FLOAT_1BIT_FMT(MFHC1, 0):
13235 mips32_op = OPC_MFHC1;
13236 goto do_cp1;
13237 case FLOAT_1BIT_FMT(MTHC1, 0):
13238 mips32_op = OPC_MTHC1;
13239 do_cp1:
13240 gen_cp1(ctx, mips32_op, rt, rs);
13241 break;
13242
13243 /* Reciprocal square root */
13244 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
13245 mips32_op = OPC_RSQRT_S;
13246 goto do_unaryfp;
13247 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
13248 mips32_op = OPC_RSQRT_D;
13249 goto do_unaryfp;
13250
13251 /* Square root */
13252 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
13253 mips32_op = OPC_SQRT_S;
13254 goto do_unaryfp;
13255 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
13256 mips32_op = OPC_SQRT_D;
13257 goto do_unaryfp;
13258
13259 /* Reciprocal */
13260 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
13261 mips32_op = OPC_RECIP_S;
13262 goto do_unaryfp;
13263 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
13264 mips32_op = OPC_RECIP_D;
13265 goto do_unaryfp;
13266
13267 /* Floor */
13268 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
13269 mips32_op = OPC_FLOOR_L_S;
13270 goto do_unaryfp;
13271 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
13272 mips32_op = OPC_FLOOR_L_D;
13273 goto do_unaryfp;
13274 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
13275 mips32_op = OPC_FLOOR_W_S;
13276 goto do_unaryfp;
13277 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
13278 mips32_op = OPC_FLOOR_W_D;
13279 goto do_unaryfp;
13280
13281 /* Ceiling */
13282 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
13283 mips32_op = OPC_CEIL_L_S;
13284 goto do_unaryfp;
13285 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
13286 mips32_op = OPC_CEIL_L_D;
13287 goto do_unaryfp;
13288 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
13289 mips32_op = OPC_CEIL_W_S;
13290 goto do_unaryfp;
13291 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
13292 mips32_op = OPC_CEIL_W_D;
13293 goto do_unaryfp;
13294
13295 /* Truncation */
13296 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
13297 mips32_op = OPC_TRUNC_L_S;
13298 goto do_unaryfp;
13299 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
13300 mips32_op = OPC_TRUNC_L_D;
13301 goto do_unaryfp;
13302 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
13303 mips32_op = OPC_TRUNC_W_S;
13304 goto do_unaryfp;
13305 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
13306 mips32_op = OPC_TRUNC_W_D;
13307 goto do_unaryfp;
13308
13309 /* Round */
13310 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
13311 mips32_op = OPC_ROUND_L_S;
13312 goto do_unaryfp;
13313 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
13314 mips32_op = OPC_ROUND_L_D;
13315 goto do_unaryfp;
13316 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
13317 mips32_op = OPC_ROUND_W_S;
13318 goto do_unaryfp;
13319 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
13320 mips32_op = OPC_ROUND_W_D;
13321 goto do_unaryfp;
13322
13323 /* Integer to floating-point conversion */
13324 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
13325 mips32_op = OPC_CVT_L_S;
13326 goto do_unaryfp;
13327 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
13328 mips32_op = OPC_CVT_L_D;
13329 goto do_unaryfp;
13330 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
13331 mips32_op = OPC_CVT_W_S;
13332 goto do_unaryfp;
13333 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
13334 mips32_op = OPC_CVT_W_D;
13335 goto do_unaryfp;
13336
13337 /* Paired-foo conversions */
13338 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
13339 mips32_op = OPC_CVT_S_PL;
13340 goto do_unaryfp;
13341 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
13342 mips32_op = OPC_CVT_S_PU;
13343 goto do_unaryfp;
13344 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
13345 mips32_op = OPC_CVT_PW_PS;
13346 goto do_unaryfp;
13347 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
13348 mips32_op = OPC_CVT_PS_PW;
13349 goto do_unaryfp;
13350
13351 /* Floating-point moves */
13352 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
13353 mips32_op = OPC_MOV_S;
13354 goto do_unaryfp;
13355 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
13356 mips32_op = OPC_MOV_D;
13357 goto do_unaryfp;
13358 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
13359 mips32_op = OPC_MOV_PS;
13360 goto do_unaryfp;
13361
13362 /* Absolute value */
13363 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
13364 mips32_op = OPC_ABS_S;
13365 goto do_unaryfp;
13366 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
13367 mips32_op = OPC_ABS_D;
13368 goto do_unaryfp;
13369 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
13370 mips32_op = OPC_ABS_PS;
13371 goto do_unaryfp;
13372
13373 /* Negation */
13374 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
13375 mips32_op = OPC_NEG_S;
13376 goto do_unaryfp;
13377 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
13378 mips32_op = OPC_NEG_D;
13379 goto do_unaryfp;
13380 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
13381 mips32_op = OPC_NEG_PS;
13382 goto do_unaryfp;
13383
13384 /* Reciprocal square root step */
13385 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
13386 mips32_op = OPC_RSQRT1_S;
13387 goto do_unaryfp;
13388 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
13389 mips32_op = OPC_RSQRT1_D;
13390 goto do_unaryfp;
13391 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
13392 mips32_op = OPC_RSQRT1_PS;
13393 goto do_unaryfp;
13394
13395 /* Reciprocal step */
13396 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
13397 mips32_op = OPC_RECIP1_S;
13398 goto do_unaryfp;
13399 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
13400 mips32_op = OPC_RECIP1_S;
13401 goto do_unaryfp;
13402 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
13403 mips32_op = OPC_RECIP1_PS;
13404 goto do_unaryfp;
13405
13406 /* Conversions from double */
13407 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
13408 mips32_op = OPC_CVT_D_S;
13409 goto do_unaryfp;
13410 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
13411 mips32_op = OPC_CVT_D_W;
13412 goto do_unaryfp;
13413 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
13414 mips32_op = OPC_CVT_D_L;
13415 goto do_unaryfp;
13416
13417 /* Conversions from single */
13418 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
13419 mips32_op = OPC_CVT_S_D;
13420 goto do_unaryfp;
13421 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
13422 mips32_op = OPC_CVT_S_W;
13423 goto do_unaryfp;
13424 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
13425 mips32_op = OPC_CVT_S_L;
13426 do_unaryfp:
13427 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
13428 break;
13429
13430 /* Conditional moves on floating-point codes */
13431 case COND_FLOAT_MOV(MOVT, 0):
13432 case COND_FLOAT_MOV(MOVT, 1):
13433 case COND_FLOAT_MOV(MOVT, 2):
13434 case COND_FLOAT_MOV(MOVT, 3):
13435 case COND_FLOAT_MOV(MOVT, 4):
13436 case COND_FLOAT_MOV(MOVT, 5):
13437 case COND_FLOAT_MOV(MOVT, 6):
13438 case COND_FLOAT_MOV(MOVT, 7):
13439 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13440 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
13441 break;
13442 case COND_FLOAT_MOV(MOVF, 0):
13443 case COND_FLOAT_MOV(MOVF, 1):
13444 case COND_FLOAT_MOV(MOVF, 2):
13445 case COND_FLOAT_MOV(MOVF, 3):
13446 case COND_FLOAT_MOV(MOVF, 4):
13447 case COND_FLOAT_MOV(MOVF, 5):
13448 case COND_FLOAT_MOV(MOVF, 6):
13449 case COND_FLOAT_MOV(MOVF, 7):
13450 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13451 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
13452 break;
13453 default:
13454 MIPS_INVAL("pool32fxf");
13455 generate_exception_end(ctx, EXCP_RI);
13456 break;
13457 }
13458 }
13459
13460 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
13461 {
13462 int32_t offset;
13463 uint16_t insn;
13464 int rt, rs, rd, rr;
13465 int16_t imm;
13466 uint32_t op, minor, mips32_op;
13467 uint32_t cond, fmt, cc;
13468
13469 insn = cpu_lduw_code(env, ctx->pc + 2);
13470 ctx->opcode = (ctx->opcode << 16) | insn;
13471
13472 rt = (ctx->opcode >> 21) & 0x1f;
13473 rs = (ctx->opcode >> 16) & 0x1f;
13474 rd = (ctx->opcode >> 11) & 0x1f;
13475 rr = (ctx->opcode >> 6) & 0x1f;
13476 imm = (int16_t) ctx->opcode;
13477
13478 op = (ctx->opcode >> 26) & 0x3f;
13479 switch (op) {
13480 case POOL32A:
13481 minor = ctx->opcode & 0x3f;
13482 switch (minor) {
13483 case 0x00:
13484 minor = (ctx->opcode >> 6) & 0xf;
13485 switch (minor) {
13486 case SLL32:
13487 mips32_op = OPC_SLL;
13488 goto do_shifti;
13489 case SRA:
13490 mips32_op = OPC_SRA;
13491 goto do_shifti;
13492 case SRL32:
13493 mips32_op = OPC_SRL;
13494 goto do_shifti;
13495 case ROTR:
13496 mips32_op = OPC_ROTR;
13497 do_shifti:
13498 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
13499 break;
13500 case SELEQZ:
13501 check_insn(ctx, ISA_MIPS32R6);
13502 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
13503 break;
13504 case SELNEZ:
13505 check_insn(ctx, ISA_MIPS32R6);
13506 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
13507 break;
13508 case R6_RDHWR:
13509 check_insn(ctx, ISA_MIPS32R6);
13510 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
13511 break;
13512 default:
13513 goto pool32a_invalid;
13514 }
13515 break;
13516 case 0x10:
13517 minor = (ctx->opcode >> 6) & 0xf;
13518 switch (minor) {
13519 /* Arithmetic */
13520 case ADD:
13521 mips32_op = OPC_ADD;
13522 goto do_arith;
13523 case ADDU32:
13524 mips32_op = OPC_ADDU;
13525 goto do_arith;
13526 case SUB:
13527 mips32_op = OPC_SUB;
13528 goto do_arith;
13529 case SUBU32:
13530 mips32_op = OPC_SUBU;
13531 goto do_arith;
13532 case MUL:
13533 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13534 mips32_op = OPC_MUL;
13535 do_arith:
13536 gen_arith(ctx, mips32_op, rd, rs, rt);
13537 break;
13538 /* Shifts */
13539 case SLLV:
13540 mips32_op = OPC_SLLV;
13541 goto do_shift;
13542 case SRLV:
13543 mips32_op = OPC_SRLV;
13544 goto do_shift;
13545 case SRAV:
13546 mips32_op = OPC_SRAV;
13547 goto do_shift;
13548 case ROTRV:
13549 mips32_op = OPC_ROTRV;
13550 do_shift:
13551 gen_shift(ctx, mips32_op, rd, rs, rt);
13552 break;
13553 /* Logical operations */
13554 case AND:
13555 mips32_op = OPC_AND;
13556 goto do_logic;
13557 case OR32:
13558 mips32_op = OPC_OR;
13559 goto do_logic;
13560 case NOR:
13561 mips32_op = OPC_NOR;
13562 goto do_logic;
13563 case XOR32:
13564 mips32_op = OPC_XOR;
13565 do_logic:
13566 gen_logic(ctx, mips32_op, rd, rs, rt);
13567 break;
13568 /* Set less than */
13569 case SLT:
13570 mips32_op = OPC_SLT;
13571 goto do_slt;
13572 case SLTU:
13573 mips32_op = OPC_SLTU;
13574 do_slt:
13575 gen_slt(ctx, mips32_op, rd, rs, rt);
13576 break;
13577 default:
13578 goto pool32a_invalid;
13579 }
13580 break;
13581 case 0x18:
13582 minor = (ctx->opcode >> 6) & 0xf;
13583 switch (minor) {
13584 /* Conditional moves */
13585 case MOVN: /* MUL */
13586 if (ctx->insn_flags & ISA_MIPS32R6) {
13587 /* MUL */
13588 gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
13589 } else {
13590 /* MOVN */
13591 gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
13592 }
13593 break;
13594 case MOVZ: /* MUH */
13595 if (ctx->insn_flags & ISA_MIPS32R6) {
13596 /* MUH */
13597 gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
13598 } else {
13599 /* MOVZ */
13600 gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
13601 }
13602 break;
13603 case MULU:
13604 check_insn(ctx, ISA_MIPS32R6);
13605 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
13606 break;
13607 case MUHU:
13608 check_insn(ctx, ISA_MIPS32R6);
13609 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
13610 break;
13611 case LWXS: /* DIV */
13612 if (ctx->insn_flags & ISA_MIPS32R6) {
13613 /* DIV */
13614 gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
13615 } else {
13616 /* LWXS */
13617 gen_ldxs(ctx, rs, rt, rd);
13618 }
13619 break;
13620 case MOD:
13621 check_insn(ctx, ISA_MIPS32R6);
13622 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
13623 break;
13624 case R6_DIVU:
13625 check_insn(ctx, ISA_MIPS32R6);
13626 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
13627 break;
13628 case MODU:
13629 check_insn(ctx, ISA_MIPS32R6);
13630 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
13631 break;
13632 default:
13633 goto pool32a_invalid;
13634 }
13635 break;
13636 case INS:
13637 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
13638 return;
13639 case LSA:
13640 check_insn(ctx, ISA_MIPS32R6);
13641 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
13642 extract32(ctx->opcode, 9, 2));
13643 break;
13644 case ALIGN:
13645 check_insn(ctx, ISA_MIPS32R6);
13646 gen_align(ctx, OPC_ALIGN, rd, rs, rt,
13647 extract32(ctx->opcode, 9, 2));
13648 break;
13649 case EXT:
13650 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
13651 return;
13652 case POOL32AXF:
13653 gen_pool32axf(env, ctx, rt, rs);
13654 break;
13655 case BREAK32:
13656 generate_exception_end(ctx, EXCP_BREAK);
13657 break;
13658 default:
13659 pool32a_invalid:
13660 MIPS_INVAL("pool32a");
13661 generate_exception_end(ctx, EXCP_RI);
13662 break;
13663 }
13664 break;
13665 case POOL32B:
13666 minor = (ctx->opcode >> 12) & 0xf;
13667 switch (minor) {
13668 case CACHE:
13669 check_cp0_enabled(ctx);
13670 /* Treat as no-op. */
13671 break;
13672 case LWC2:
13673 case SWC2:
13674 /* COP2: Not implemented. */
13675 generate_exception_err(ctx, EXCP_CpU, 2);
13676 break;
13677 #ifdef TARGET_MIPS64
13678 case LDP:
13679 case SDP:
13680 check_insn(ctx, ISA_MIPS3);
13681 check_mips_64(ctx);
13682 /* Fallthrough */
13683 #endif
13684 case LWP:
13685 case SWP:
13686 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13687 break;
13688 #ifdef TARGET_MIPS64
13689 case LDM:
13690 case SDM:
13691 check_insn(ctx, ISA_MIPS3);
13692 check_mips_64(ctx);
13693 /* Fallthrough */
13694 #endif
13695 case LWM32:
13696 case SWM32:
13697 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
13698 break;
13699 default:
13700 MIPS_INVAL("pool32b");
13701 generate_exception_end(ctx, EXCP_RI);
13702 break;
13703 }
13704 break;
13705 case POOL32F:
13706 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
13707 minor = ctx->opcode & 0x3f;
13708 check_cp1_enabled(ctx);
13709 switch (minor) {
13710 case ALNV_PS:
13711 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13712 mips32_op = OPC_ALNV_PS;
13713 goto do_madd;
13714 case MADD_S:
13715 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13716 mips32_op = OPC_MADD_S;
13717 goto do_madd;
13718 case MADD_D:
13719 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13720 mips32_op = OPC_MADD_D;
13721 goto do_madd;
13722 case MADD_PS:
13723 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13724 mips32_op = OPC_MADD_PS;
13725 goto do_madd;
13726 case MSUB_S:
13727 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13728 mips32_op = OPC_MSUB_S;
13729 goto do_madd;
13730 case MSUB_D:
13731 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13732 mips32_op = OPC_MSUB_D;
13733 goto do_madd;
13734 case MSUB_PS:
13735 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13736 mips32_op = OPC_MSUB_PS;
13737 goto do_madd;
13738 case NMADD_S:
13739 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13740 mips32_op = OPC_NMADD_S;
13741 goto do_madd;
13742 case NMADD_D:
13743 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13744 mips32_op = OPC_NMADD_D;
13745 goto do_madd;
13746 case NMADD_PS:
13747 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13748 mips32_op = OPC_NMADD_PS;
13749 goto do_madd;
13750 case NMSUB_S:
13751 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13752 mips32_op = OPC_NMSUB_S;
13753 goto do_madd;
13754 case NMSUB_D:
13755 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13756 mips32_op = OPC_NMSUB_D;
13757 goto do_madd;
13758 case NMSUB_PS:
13759 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13760 mips32_op = OPC_NMSUB_PS;
13761 do_madd:
13762 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
13763 break;
13764 case CABS_COND_FMT:
13765 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13766 cond = (ctx->opcode >> 6) & 0xf;
13767 cc = (ctx->opcode >> 13) & 0x7;
13768 fmt = (ctx->opcode >> 10) & 0x3;
13769 switch (fmt) {
13770 case 0x0:
13771 gen_cmpabs_s(ctx, cond, rt, rs, cc);
13772 break;
13773 case 0x1:
13774 gen_cmpabs_d(ctx, cond, rt, rs, cc);
13775 break;
13776 case 0x2:
13777 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
13778 break;
13779 default:
13780 goto pool32f_invalid;
13781 }
13782 break;
13783 case C_COND_FMT:
13784 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13785 cond = (ctx->opcode >> 6) & 0xf;
13786 cc = (ctx->opcode >> 13) & 0x7;
13787 fmt = (ctx->opcode >> 10) & 0x3;
13788 switch (fmt) {
13789 case 0x0:
13790 gen_cmp_s(ctx, cond, rt, rs, cc);
13791 break;
13792 case 0x1:
13793 gen_cmp_d(ctx, cond, rt, rs, cc);
13794 break;
13795 case 0x2:
13796 gen_cmp_ps(ctx, cond, rt, rs, cc);
13797 break;
13798 default:
13799 goto pool32f_invalid;
13800 }
13801 break;
13802 case CMP_CONDN_S:
13803 check_insn(ctx, ISA_MIPS32R6);
13804 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13805 break;
13806 case CMP_CONDN_D:
13807 check_insn(ctx, ISA_MIPS32R6);
13808 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
13809 break;
13810 case POOL32FXF:
13811 gen_pool32fxf(ctx, rt, rs);
13812 break;
13813 case 0x00:
13814 /* PLL foo */
13815 switch ((ctx->opcode >> 6) & 0x7) {
13816 case PLL_PS:
13817 mips32_op = OPC_PLL_PS;
13818 goto do_ps;
13819 case PLU_PS:
13820 mips32_op = OPC_PLU_PS;
13821 goto do_ps;
13822 case PUL_PS:
13823 mips32_op = OPC_PUL_PS;
13824 goto do_ps;
13825 case PUU_PS:
13826 mips32_op = OPC_PUU_PS;
13827 goto do_ps;
13828 case CVT_PS_S:
13829 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13830 mips32_op = OPC_CVT_PS_S;
13831 do_ps:
13832 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13833 break;
13834 default:
13835 goto pool32f_invalid;
13836 }
13837 break;
13838 case MIN_FMT:
13839 check_insn(ctx, ISA_MIPS32R6);
13840 switch ((ctx->opcode >> 9) & 0x3) {
13841 case FMT_SDPS_S:
13842 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
13843 break;
13844 case FMT_SDPS_D:
13845 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
13846 break;
13847 default:
13848 goto pool32f_invalid;
13849 }
13850 break;
13851 case 0x08:
13852 /* [LS][WDU]XC1 */
13853 switch ((ctx->opcode >> 6) & 0x7) {
13854 case LWXC1:
13855 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13856 mips32_op = OPC_LWXC1;
13857 goto do_ldst_cp1;
13858 case SWXC1:
13859 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13860 mips32_op = OPC_SWXC1;
13861 goto do_ldst_cp1;
13862 case LDXC1:
13863 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13864 mips32_op = OPC_LDXC1;
13865 goto do_ldst_cp1;
13866 case SDXC1:
13867 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13868 mips32_op = OPC_SDXC1;
13869 goto do_ldst_cp1;
13870 case LUXC1:
13871 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13872 mips32_op = OPC_LUXC1;
13873 goto do_ldst_cp1;
13874 case SUXC1:
13875 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13876 mips32_op = OPC_SUXC1;
13877 do_ldst_cp1:
13878 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
13879 break;
13880 default:
13881 goto pool32f_invalid;
13882 }
13883 break;
13884 case MAX_FMT:
13885 check_insn(ctx, ISA_MIPS32R6);
13886 switch ((ctx->opcode >> 9) & 0x3) {
13887 case FMT_SDPS_S:
13888 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
13889 break;
13890 case FMT_SDPS_D:
13891 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
13892 break;
13893 default:
13894 goto pool32f_invalid;
13895 }
13896 break;
13897 case 0x18:
13898 /* 3D insns */
13899 check_insn_opc_removed(ctx, ISA_MIPS32R6);
13900 fmt = (ctx->opcode >> 9) & 0x3;
13901 switch ((ctx->opcode >> 6) & 0x7) {
13902 case RSQRT2_FMT:
13903 switch (fmt) {
13904 case FMT_SDPS_S:
13905 mips32_op = OPC_RSQRT2_S;
13906 goto do_3d;
13907 case FMT_SDPS_D:
13908 mips32_op = OPC_RSQRT2_D;
13909 goto do_3d;
13910 case FMT_SDPS_PS:
13911 mips32_op = OPC_RSQRT2_PS;
13912 goto do_3d;
13913 default:
13914 goto pool32f_invalid;
13915 }
13916 break;
13917 case RECIP2_FMT:
13918 switch (fmt) {
13919 case FMT_SDPS_S:
13920 mips32_op = OPC_RECIP2_S;
13921 goto do_3d;
13922 case FMT_SDPS_D:
13923 mips32_op = OPC_RECIP2_D;
13924 goto do_3d;
13925 case FMT_SDPS_PS:
13926 mips32_op = OPC_RECIP2_PS;
13927 goto do_3d;
13928 default:
13929 goto pool32f_invalid;
13930 }
13931 break;
13932 case ADDR_PS:
13933 mips32_op = OPC_ADDR_PS;
13934 goto do_3d;
13935 case MULR_PS:
13936 mips32_op = OPC_MULR_PS;
13937 do_3d:
13938 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13939 break;
13940 default:
13941 goto pool32f_invalid;
13942 }
13943 break;
13944 case 0x20:
13945 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
13946 cc = (ctx->opcode >> 13) & 0x7;
13947 fmt = (ctx->opcode >> 9) & 0x3;
13948 switch ((ctx->opcode >> 6) & 0x7) {
13949 case MOVF_FMT: /* RINT_FMT */
13950 if (ctx->insn_flags & ISA_MIPS32R6) {
13951 /* RINT_FMT */
13952 switch (fmt) {
13953 case FMT_SDPS_S:
13954 gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
13955 break;
13956 case FMT_SDPS_D:
13957 gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
13958 break;
13959 default:
13960 goto pool32f_invalid;
13961 }
13962 } else {
13963 /* MOVF_FMT */
13964 switch (fmt) {
13965 case FMT_SDPS_S:
13966 gen_movcf_s(ctx, rs, rt, cc, 0);
13967 break;
13968 case FMT_SDPS_D:
13969 gen_movcf_d(ctx, rs, rt, cc, 0);
13970 break;
13971 case FMT_SDPS_PS:
13972 check_ps(ctx);
13973 gen_movcf_ps(ctx, rs, rt, cc, 0);
13974 break;
13975 default:
13976 goto pool32f_invalid;
13977 }
13978 }
13979 break;
13980 case MOVT_FMT: /* CLASS_FMT */
13981 if (ctx->insn_flags & ISA_MIPS32R6) {
13982 /* CLASS_FMT */
13983 switch (fmt) {
13984 case FMT_SDPS_S:
13985 gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
13986 break;
13987 case FMT_SDPS_D:
13988 gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
13989 break;
13990 default:
13991 goto pool32f_invalid;
13992 }
13993 } else {
13994 /* MOVT_FMT */
13995 switch (fmt) {
13996 case FMT_SDPS_S:
13997 gen_movcf_s(ctx, rs, rt, cc, 1);
13998 break;
13999 case FMT_SDPS_D:
14000 gen_movcf_d(ctx, rs, rt, cc, 1);
14001 break;
14002 case FMT_SDPS_PS:
14003 check_ps(ctx);
14004 gen_movcf_ps(ctx, rs, rt, cc, 1);
14005 break;
14006 default:
14007 goto pool32f_invalid;
14008 }
14009 }
14010 break;
14011 case PREFX:
14012 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14013 break;
14014 default:
14015 goto pool32f_invalid;
14016 }
14017 break;
14018 #define FINSN_3ARG_SDPS(prfx) \
14019 switch ((ctx->opcode >> 8) & 0x3) { \
14020 case FMT_SDPS_S: \
14021 mips32_op = OPC_##prfx##_S; \
14022 goto do_fpop; \
14023 case FMT_SDPS_D: \
14024 mips32_op = OPC_##prfx##_D; \
14025 goto do_fpop; \
14026 case FMT_SDPS_PS: \
14027 check_ps(ctx); \
14028 mips32_op = OPC_##prfx##_PS; \
14029 goto do_fpop; \
14030 default: \
14031 goto pool32f_invalid; \
14032 }
14033 case MINA_FMT:
14034 check_insn(ctx, ISA_MIPS32R6);
14035 switch ((ctx->opcode >> 9) & 0x3) {
14036 case FMT_SDPS_S:
14037 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
14038 break;
14039 case FMT_SDPS_D:
14040 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
14041 break;
14042 default:
14043 goto pool32f_invalid;
14044 }
14045 break;
14046 case MAXA_FMT:
14047 check_insn(ctx, ISA_MIPS32R6);
14048 switch ((ctx->opcode >> 9) & 0x3) {
14049 case FMT_SDPS_S:
14050 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
14051 break;
14052 case FMT_SDPS_D:
14053 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
14054 break;
14055 default:
14056 goto pool32f_invalid;
14057 }
14058 break;
14059 case 0x30:
14060 /* regular FP ops */
14061 switch ((ctx->opcode >> 6) & 0x3) {
14062 case ADD_FMT:
14063 FINSN_3ARG_SDPS(ADD);
14064 break;
14065 case SUB_FMT:
14066 FINSN_3ARG_SDPS(SUB);
14067 break;
14068 case MUL_FMT:
14069 FINSN_3ARG_SDPS(MUL);
14070 break;
14071 case DIV_FMT:
14072 fmt = (ctx->opcode >> 8) & 0x3;
14073 if (fmt == 1) {
14074 mips32_op = OPC_DIV_D;
14075 } else if (fmt == 0) {
14076 mips32_op = OPC_DIV_S;
14077 } else {
14078 goto pool32f_invalid;
14079 }
14080 goto do_fpop;
14081 default:
14082 goto pool32f_invalid;
14083 }
14084 break;
14085 case 0x38:
14086 /* cmovs */
14087 switch ((ctx->opcode >> 6) & 0x7) {
14088 case MOVN_FMT: /* SELNEZ_FMT */
14089 if (ctx->insn_flags & ISA_MIPS32R6) {
14090 /* SELNEZ_FMT */
14091 switch ((ctx->opcode >> 9) & 0x3) {
14092 case FMT_SDPS_S:
14093 gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
14094 break;
14095 case FMT_SDPS_D:
14096 gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
14097 break;
14098 default:
14099 goto pool32f_invalid;
14100 }
14101 } else {
14102 /* MOVN_FMT */
14103 FINSN_3ARG_SDPS(MOVN);
14104 }
14105 break;
14106 case MOVN_FMT_04:
14107 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14108 FINSN_3ARG_SDPS(MOVN);
14109 break;
14110 case MOVZ_FMT: /* SELEQZ_FMT */
14111 if (ctx->insn_flags & ISA_MIPS32R6) {
14112 /* SELEQZ_FMT */
14113 switch ((ctx->opcode >> 9) & 0x3) {
14114 case FMT_SDPS_S:
14115 gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
14116 break;
14117 case FMT_SDPS_D:
14118 gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
14119 break;
14120 default:
14121 goto pool32f_invalid;
14122 }
14123 } else {
14124 /* MOVZ_FMT */
14125 FINSN_3ARG_SDPS(MOVZ);
14126 }
14127 break;
14128 case MOVZ_FMT_05:
14129 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14130 FINSN_3ARG_SDPS(MOVZ);
14131 break;
14132 case SEL_FMT:
14133 check_insn(ctx, ISA_MIPS32R6);
14134 switch ((ctx->opcode >> 9) & 0x3) {
14135 case FMT_SDPS_S:
14136 gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
14137 break;
14138 case FMT_SDPS_D:
14139 gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
14140 break;
14141 default:
14142 goto pool32f_invalid;
14143 }
14144 break;
14145 case MADDF_FMT:
14146 check_insn(ctx, ISA_MIPS32R6);
14147 switch ((ctx->opcode >> 9) & 0x3) {
14148 case FMT_SDPS_S:
14149 mips32_op = OPC_MADDF_S;
14150 goto do_fpop;
14151 case FMT_SDPS_D:
14152 mips32_op = OPC_MADDF_D;
14153 goto do_fpop;
14154 default:
14155 goto pool32f_invalid;
14156 }
14157 break;
14158 case MSUBF_FMT:
14159 check_insn(ctx, ISA_MIPS32R6);
14160 switch ((ctx->opcode >> 9) & 0x3) {
14161 case FMT_SDPS_S:
14162 mips32_op = OPC_MSUBF_S;
14163 goto do_fpop;
14164 case FMT_SDPS_D:
14165 mips32_op = OPC_MSUBF_D;
14166 goto do_fpop;
14167 default:
14168 goto pool32f_invalid;
14169 }
14170 break;
14171 default:
14172 goto pool32f_invalid;
14173 }
14174 break;
14175 do_fpop:
14176 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
14177 break;
14178 default:
14179 pool32f_invalid:
14180 MIPS_INVAL("pool32f");
14181 generate_exception_end(ctx, EXCP_RI);
14182 break;
14183 }
14184 } else {
14185 generate_exception_err(ctx, EXCP_CpU, 1);
14186 }
14187 break;
14188 case POOL32I:
14189 minor = (ctx->opcode >> 21) & 0x1f;
14190 switch (minor) {
14191 case BLTZ:
14192 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14193 gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
14194 break;
14195 case BLTZAL:
14196 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14197 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
14198 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14199 break;
14200 case BLTZALS:
14201 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14202 gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
14203 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14204 break;
14205 case BGEZ:
14206 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14207 gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
14208 break;
14209 case BGEZAL:
14210 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14211 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
14212 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14213 break;
14214 case BGEZALS:
14215 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14216 gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
14217 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14218 break;
14219 case BLEZ:
14220 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14221 gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
14222 break;
14223 case BGTZ:
14224 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14225 gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
14226 break;
14227
14228 /* Traps */
14229 case TLTI: /* BC1EQZC */
14230 if (ctx->insn_flags & ISA_MIPS32R6) {
14231 /* BC1EQZC */
14232 check_cp1_enabled(ctx);
14233 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
14234 } else {
14235 /* TLTI */
14236 mips32_op = OPC_TLTI;
14237 goto do_trapi;
14238 }
14239 break;
14240 case TGEI: /* BC1NEZC */
14241 if (ctx->insn_flags & ISA_MIPS32R6) {
14242 /* BC1NEZC */
14243 check_cp1_enabled(ctx);
14244 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
14245 } else {
14246 /* TGEI */
14247 mips32_op = OPC_TGEI;
14248 goto do_trapi;
14249 }
14250 break;
14251 case TLTIU:
14252 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14253 mips32_op = OPC_TLTIU;
14254 goto do_trapi;
14255 case TGEIU:
14256 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14257 mips32_op = OPC_TGEIU;
14258 goto do_trapi;
14259 case TNEI: /* SYNCI */
14260 if (ctx->insn_flags & ISA_MIPS32R6) {
14261 /* SYNCI */
14262 /* Break the TB to be able to sync copied instructions
14263 immediately */
14264 ctx->bstate = BS_STOP;
14265 } else {
14266 /* TNEI */
14267 mips32_op = OPC_TNEI;
14268 goto do_trapi;
14269 }
14270 break;
14271 case TEQI:
14272 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14273 mips32_op = OPC_TEQI;
14274 do_trapi:
14275 gen_trap(ctx, mips32_op, rs, -1, imm);
14276 break;
14277
14278 case BNEZC:
14279 case BEQZC:
14280 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14281 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
14282 4, rs, 0, imm << 1, 0);
14283 /* Compact branches don't have a delay slot, so just let
14284 the normal delay slot handling take us to the branch
14285 target. */
14286 break;
14287 case LUI:
14288 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14289 gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
14290 break;
14291 case SYNCI:
14292 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14293 /* Break the TB to be able to sync copied instructions
14294 immediately */
14295 ctx->bstate = BS_STOP;
14296 break;
14297 case BC2F:
14298 case BC2T:
14299 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14300 /* COP2: Not implemented. */
14301 generate_exception_err(ctx, EXCP_CpU, 2);
14302 break;
14303 case BC1F:
14304 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14305 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
14306 goto do_cp1branch;
14307 case BC1T:
14308 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14309 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
14310 goto do_cp1branch;
14311 case BC1ANY4F:
14312 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14313 mips32_op = OPC_BC1FANY4;
14314 goto do_cp1mips3d;
14315 case BC1ANY4T:
14316 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14317 mips32_op = OPC_BC1TANY4;
14318 do_cp1mips3d:
14319 check_cop1x(ctx);
14320 check_insn(ctx, ASE_MIPS3D);
14321 /* Fall through */
14322 do_cp1branch:
14323 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14324 check_cp1_enabled(ctx);
14325 gen_compute_branch1(ctx, mips32_op,
14326 (ctx->opcode >> 18) & 0x7, imm << 1);
14327 } else {
14328 generate_exception_err(ctx, EXCP_CpU, 1);
14329 }
14330 break;
14331 case BPOSGE64:
14332 case BPOSGE32:
14333 /* MIPS DSP: not implemented */
14334 /* Fall through */
14335 default:
14336 MIPS_INVAL("pool32i");
14337 generate_exception_end(ctx, EXCP_RI);
14338 break;
14339 }
14340 break;
14341 case POOL32C:
14342 minor = (ctx->opcode >> 12) & 0xf;
14343 offset = sextract32(ctx->opcode, 0,
14344 (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
14345 switch (minor) {
14346 case LWL:
14347 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14348 mips32_op = OPC_LWL;
14349 goto do_ld_lr;
14350 case SWL:
14351 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14352 mips32_op = OPC_SWL;
14353 goto do_st_lr;
14354 case LWR:
14355 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14356 mips32_op = OPC_LWR;
14357 goto do_ld_lr;
14358 case SWR:
14359 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14360 mips32_op = OPC_SWR;
14361 goto do_st_lr;
14362 #if defined(TARGET_MIPS64)
14363 case LDL:
14364 check_insn(ctx, ISA_MIPS3);
14365 check_mips_64(ctx);
14366 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14367 mips32_op = OPC_LDL;
14368 goto do_ld_lr;
14369 case SDL:
14370 check_insn(ctx, ISA_MIPS3);
14371 check_mips_64(ctx);
14372 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14373 mips32_op = OPC_SDL;
14374 goto do_st_lr;
14375 case LDR:
14376 check_insn(ctx, ISA_MIPS3);
14377 check_mips_64(ctx);
14378 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14379 mips32_op = OPC_LDR;
14380 goto do_ld_lr;
14381 case SDR:
14382 check_insn(ctx, ISA_MIPS3);
14383 check_mips_64(ctx);
14384 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14385 mips32_op = OPC_SDR;
14386 goto do_st_lr;
14387 case LWU:
14388 check_insn(ctx, ISA_MIPS3);
14389 check_mips_64(ctx);
14390 mips32_op = OPC_LWU;
14391 goto do_ld_lr;
14392 case LLD:
14393 check_insn(ctx, ISA_MIPS3);
14394 check_mips_64(ctx);
14395 mips32_op = OPC_LLD;
14396 goto do_ld_lr;
14397 #endif
14398 case LL:
14399 mips32_op = OPC_LL;
14400 goto do_ld_lr;
14401 do_ld_lr:
14402 gen_ld(ctx, mips32_op, rt, rs, offset);
14403 break;
14404 do_st_lr:
14405 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
14406 break;
14407 case SC:
14408 gen_st_cond(ctx, OPC_SC, rt, rs, offset);
14409 break;
14410 #if defined(TARGET_MIPS64)
14411 case SCD:
14412 check_insn(ctx, ISA_MIPS3);
14413 check_mips_64(ctx);
14414 gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
14415 break;
14416 #endif
14417 case PREF:
14418 /* Treat as no-op */
14419 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
14420 /* hint codes 24-31 are reserved and signal RI */
14421 generate_exception(ctx, EXCP_RI);
14422 }
14423 break;
14424 default:
14425 MIPS_INVAL("pool32c");
14426 generate_exception_end(ctx, EXCP_RI);
14427 break;
14428 }
14429 break;
14430 case ADDI32: /* AUI, LUI */
14431 if (ctx->insn_flags & ISA_MIPS32R6) {
14432 /* AUI, LUI */
14433 gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
14434 } else {
14435 /* ADDI32 */
14436 mips32_op = OPC_ADDI;
14437 goto do_addi;
14438 }
14439 break;
14440 case ADDIU32:
14441 mips32_op = OPC_ADDIU;
14442 do_addi:
14443 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
14444 break;
14445
14446 /* Logical operations */
14447 case ORI32:
14448 mips32_op = OPC_ORI;
14449 goto do_logici;
14450 case XORI32:
14451 mips32_op = OPC_XORI;
14452 goto do_logici;
14453 case ANDI32:
14454 mips32_op = OPC_ANDI;
14455 do_logici:
14456 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
14457 break;
14458
14459 /* Set less than immediate */
14460 case SLTI32:
14461 mips32_op = OPC_SLTI;
14462 goto do_slti;
14463 case SLTIU32:
14464 mips32_op = OPC_SLTIU;
14465 do_slti:
14466 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
14467 break;
14468 case JALX32:
14469 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14470 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
14471 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
14472 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14473 break;
14474 case JALS32: /* BOVC, BEQC, BEQZALC */
14475 if (ctx->insn_flags & ISA_MIPS32R6) {
14476 if (rs >= rt) {
14477 /* BOVC */
14478 mips32_op = OPC_BOVC;
14479 } else if (rs < rt && rs == 0) {
14480 /* BEQZALC */
14481 mips32_op = OPC_BEQZALC;
14482 } else {
14483 /* BEQC */
14484 mips32_op = OPC_BEQC;
14485 }
14486 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14487 } else {
14488 /* JALS32 */
14489 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
14490 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
14491 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14492 }
14493 break;
14494 case BEQ32: /* BC */
14495 if (ctx->insn_flags & ISA_MIPS32R6) {
14496 /* BC */
14497 gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
14498 sextract32(ctx->opcode << 1, 0, 27));
14499 } else {
14500 /* BEQ32 */
14501 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
14502 }
14503 break;
14504 case BNE32: /* BALC */
14505 if (ctx->insn_flags & ISA_MIPS32R6) {
14506 /* BALC */
14507 gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
14508 sextract32(ctx->opcode << 1, 0, 27));
14509 } else {
14510 /* BNE32 */
14511 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
14512 }
14513 break;
14514 case J32: /* BGTZC, BLTZC, BLTC */
14515 if (ctx->insn_flags & ISA_MIPS32R6) {
14516 if (rs == 0 && rt != 0) {
14517 /* BGTZC */
14518 mips32_op = OPC_BGTZC;
14519 } else if (rs != 0 && rt != 0 && rs == rt) {
14520 /* BLTZC */
14521 mips32_op = OPC_BLTZC;
14522 } else {
14523 /* BLTC */
14524 mips32_op = OPC_BLTC;
14525 }
14526 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14527 } else {
14528 /* J32 */
14529 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
14530 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14531 }
14532 break;
14533 case JAL32: /* BLEZC, BGEZC, BGEC */
14534 if (ctx->insn_flags & ISA_MIPS32R6) {
14535 if (rs == 0 && rt != 0) {
14536 /* BLEZC */
14537 mips32_op = OPC_BLEZC;
14538 } else if (rs != 0 && rt != 0 && rs == rt) {
14539 /* BGEZC */
14540 mips32_op = OPC_BGEZC;
14541 } else {
14542 /* BGEC */
14543 mips32_op = OPC_BGEC;
14544 }
14545 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14546 } else {
14547 /* JAL32 */
14548 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
14549 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
14550 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14551 }
14552 break;
14553 /* Floating point (COP1) */
14554 case LWC132:
14555 mips32_op = OPC_LWC1;
14556 goto do_cop1;
14557 case LDC132:
14558 mips32_op = OPC_LDC1;
14559 goto do_cop1;
14560 case SWC132:
14561 mips32_op = OPC_SWC1;
14562 goto do_cop1;
14563 case SDC132:
14564 mips32_op = OPC_SDC1;
14565 do_cop1:
14566 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
14567 break;
14568 case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14569 if (ctx->insn_flags & ISA_MIPS32R6) {
14570 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14571 switch ((ctx->opcode >> 16) & 0x1f) {
14572 case ADDIUPC_00 ... ADDIUPC_07:
14573 gen_pcrel(ctx, OPC_ADDIUPC, ctx->pc & ~0x3, rt);
14574 break;
14575 case AUIPC:
14576 gen_pcrel(ctx, OPC_AUIPC, ctx->pc, rt);
14577 break;
14578 case ALUIPC:
14579 gen_pcrel(ctx, OPC_ALUIPC, ctx->pc, rt);
14580 break;
14581 case LWPC_08 ... LWPC_0F:
14582 gen_pcrel(ctx, R6_OPC_LWPC, ctx->pc & ~0x3, rt);
14583 break;
14584 default:
14585 generate_exception(ctx, EXCP_RI);
14586 break;
14587 }
14588 } else {
14589 /* ADDIUPC */
14590 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
14591 int offset = SIMM(ctx->opcode, 0, 23) << 2;
14592
14593 gen_addiupc(ctx, reg, offset, 0, 0);
14594 }
14595 break;
14596 case BNVC: /* BNEC, BNEZALC */
14597 check_insn(ctx, ISA_MIPS32R6);
14598 if (rs >= rt) {
14599 /* BNVC */
14600 mips32_op = OPC_BNVC;
14601 } else if (rs < rt && rs == 0) {
14602 /* BNEZALC */
14603 mips32_op = OPC_BNEZALC;
14604 } else {
14605 /* BNEC */
14606 mips32_op = OPC_BNEC;
14607 }
14608 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14609 break;
14610 case R6_BNEZC: /* JIALC */
14611 check_insn(ctx, ISA_MIPS32R6);
14612 if (rt != 0) {
14613 /* BNEZC */
14614 gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
14615 sextract32(ctx->opcode << 1, 0, 22));
14616 } else {
14617 /* JIALC */
14618 gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
14619 }
14620 break;
14621 case R6_BEQZC: /* JIC */
14622 check_insn(ctx, ISA_MIPS32R6);
14623 if (rt != 0) {
14624 /* BEQZC */
14625 gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
14626 sextract32(ctx->opcode << 1, 0, 22));
14627 } else {
14628 /* JIC */
14629 gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
14630 }
14631 break;
14632 case BLEZALC: /* BGEZALC, BGEUC */
14633 check_insn(ctx, ISA_MIPS32R6);
14634 if (rs == 0 && rt != 0) {
14635 /* BLEZALC */
14636 mips32_op = OPC_BLEZALC;
14637 } else if (rs != 0 && rt != 0 && rs == rt) {
14638 /* BGEZALC */
14639 mips32_op = OPC_BGEZALC;
14640 } else {
14641 /* BGEUC */
14642 mips32_op = OPC_BGEUC;
14643 }
14644 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14645 break;
14646 case BGTZALC: /* BLTZALC, BLTUC */
14647 check_insn(ctx, ISA_MIPS32R6);
14648 if (rs == 0 && rt != 0) {
14649 /* BGTZALC */
14650 mips32_op = OPC_BGTZALC;
14651 } else if (rs != 0 && rt != 0 && rs == rt) {
14652 /* BLTZALC */
14653 mips32_op = OPC_BLTZALC;
14654 } else {
14655 /* BLTUC */
14656 mips32_op = OPC_BLTUC;
14657 }
14658 gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
14659 break;
14660 /* Loads and stores */
14661 case LB32:
14662 mips32_op = OPC_LB;
14663 goto do_ld;
14664 case LBU32:
14665 mips32_op = OPC_LBU;
14666 goto do_ld;
14667 case LH32:
14668 mips32_op = OPC_LH;
14669 goto do_ld;
14670 case LHU32:
14671 mips32_op = OPC_LHU;
14672 goto do_ld;
14673 case LW32:
14674 mips32_op = OPC_LW;
14675 goto do_ld;
14676 #ifdef TARGET_MIPS64
14677 case LD32:
14678 check_insn(ctx, ISA_MIPS3);
14679 check_mips_64(ctx);
14680 mips32_op = OPC_LD;
14681 goto do_ld;
14682 case SD32:
14683 check_insn(ctx, ISA_MIPS3);
14684 check_mips_64(ctx);
14685 mips32_op = OPC_SD;
14686 goto do_st;
14687 #endif
14688 case SB32:
14689 mips32_op = OPC_SB;
14690 goto do_st;
14691 case SH32:
14692 mips32_op = OPC_SH;
14693 goto do_st;
14694 case SW32:
14695 mips32_op = OPC_SW;
14696 goto do_st;
14697 do_ld:
14698 gen_ld(ctx, mips32_op, rt, rs, imm);
14699 break;
14700 do_st:
14701 gen_st(ctx, mips32_op, rt, rs, imm);
14702 break;
14703 default:
14704 generate_exception_end(ctx, EXCP_RI);
14705 break;
14706 }
14707 }
14708
14709 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
14710 {
14711 uint32_t op;
14712
14713 /* make sure instructions are on a halfword boundary */
14714 if (ctx->pc & 0x1) {
14715 env->CP0_BadVAddr = ctx->pc;
14716 generate_exception_end(ctx, EXCP_AdEL);
14717 return 2;
14718 }
14719
14720 op = (ctx->opcode >> 10) & 0x3f;
14721 /* Enforce properly-sized instructions in a delay slot */
14722 if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
14723 switch (op & 0x7) { /* MSB-3..MSB-5 */
14724 case 0:
14725 /* POOL32A, POOL32B, POOL32I, POOL32C */
14726 case 4:
14727 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
14728 case 5:
14729 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
14730 case 6:
14731 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
14732 case 7:
14733 /* LB32, LH32, LWC132, LDC132, LW32 */
14734 if (ctx->hflags & MIPS_HFLAG_BDS16) {
14735 generate_exception_end(ctx, EXCP_RI);
14736 return 2;
14737 }
14738 break;
14739 case 1:
14740 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
14741 case 2:
14742 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
14743 case 3:
14744 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
14745 if (ctx->hflags & MIPS_HFLAG_BDS32) {
14746 generate_exception_end(ctx, EXCP_RI);
14747 return 2;
14748 }
14749 break;
14750 }
14751 }
14752
14753 switch (op) {
14754 case POOL16A:
14755 {
14756 int rd = mmreg(uMIPS_RD(ctx->opcode));
14757 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
14758 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
14759 uint32_t opc = 0;
14760
14761 switch (ctx->opcode & 0x1) {
14762 case ADDU16:
14763 opc = OPC_ADDU;
14764 break;
14765 case SUBU16:
14766 opc = OPC_SUBU;
14767 break;
14768 }
14769 if (ctx->insn_flags & ISA_MIPS32R6) {
14770 /* In the Release 6 the register number location in
14771 * the instruction encoding has changed.
14772 */
14773 gen_arith(ctx, opc, rs1, rd, rs2);
14774 } else {
14775 gen_arith(ctx, opc, rd, rs1, rs2);
14776 }
14777 }
14778 break;
14779 case POOL16B:
14780 {
14781 int rd = mmreg(uMIPS_RD(ctx->opcode));
14782 int rs = mmreg(uMIPS_RS(ctx->opcode));
14783 int amount = (ctx->opcode >> 1) & 0x7;
14784 uint32_t opc = 0;
14785 amount = amount == 0 ? 8 : amount;
14786
14787 switch (ctx->opcode & 0x1) {
14788 case SLL16:
14789 opc = OPC_SLL;
14790 break;
14791 case SRL16:
14792 opc = OPC_SRL;
14793 break;
14794 }
14795
14796 gen_shift_imm(ctx, opc, rd, rs, amount);
14797 }
14798 break;
14799 case POOL16C:
14800 if (ctx->insn_flags & ISA_MIPS32R6) {
14801 gen_pool16c_r6_insn(ctx);
14802 } else {
14803 gen_pool16c_insn(ctx);
14804 }
14805 break;
14806 case LWGP16:
14807 {
14808 int rd = mmreg(uMIPS_RD(ctx->opcode));
14809 int rb = 28; /* GP */
14810 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
14811
14812 gen_ld(ctx, OPC_LW, rd, rb, offset);
14813 }
14814 break;
14815 case POOL16F:
14816 check_insn_opc_removed(ctx, ISA_MIPS32R6);
14817 if (ctx->opcode & 1) {
14818 generate_exception_end(ctx, EXCP_RI);
14819 } else {
14820 /* MOVEP */
14821 int enc_dest = uMIPS_RD(ctx->opcode);
14822 int enc_rt = uMIPS_RS2(ctx->opcode);
14823 int enc_rs = uMIPS_RS1(ctx->opcode);
14824 gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14825 }
14826 break;
14827 case LBU16:
14828 {
14829 int rd = mmreg(uMIPS_RD(ctx->opcode));
14830 int rb = mmreg(uMIPS_RS(ctx->opcode));
14831 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14832 offset = (offset == 0xf ? -1 : offset);
14833
14834 gen_ld(ctx, OPC_LBU, rd, rb, offset);
14835 }
14836 break;
14837 case LHU16:
14838 {
14839 int rd = mmreg(uMIPS_RD(ctx->opcode));
14840 int rb = mmreg(uMIPS_RS(ctx->opcode));
14841 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14842
14843 gen_ld(ctx, OPC_LHU, rd, rb, offset);
14844 }
14845 break;
14846 case LWSP16:
14847 {
14848 int rd = (ctx->opcode >> 5) & 0x1f;
14849 int rb = 29; /* SP */
14850 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14851
14852 gen_ld(ctx, OPC_LW, rd, rb, offset);
14853 }
14854 break;
14855 case LW16:
14856 {
14857 int rd = mmreg(uMIPS_RD(ctx->opcode));
14858 int rb = mmreg(uMIPS_RS(ctx->opcode));
14859 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14860
14861 gen_ld(ctx, OPC_LW, rd, rb, offset);
14862 }
14863 break;
14864 case SB16:
14865 {
14866 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14867 int rb = mmreg(uMIPS_RS(ctx->opcode));
14868 int16_t offset = ZIMM(ctx->opcode, 0, 4);
14869
14870 gen_st(ctx, OPC_SB, rd, rb, offset);
14871 }
14872 break;
14873 case SH16:
14874 {
14875 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14876 int rb = mmreg(uMIPS_RS(ctx->opcode));
14877 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
14878
14879 gen_st(ctx, OPC_SH, rd, rb, offset);
14880 }
14881 break;
14882 case SWSP16:
14883 {
14884 int rd = (ctx->opcode >> 5) & 0x1f;
14885 int rb = 29; /* SP */
14886 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
14887
14888 gen_st(ctx, OPC_SW, rd, rb, offset);
14889 }
14890 break;
14891 case SW16:
14892 {
14893 int rd = mmreg2(uMIPS_RD(ctx->opcode));
14894 int rb = mmreg(uMIPS_RS(ctx->opcode));
14895 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
14896
14897 gen_st(ctx, OPC_SW, rd, rb, offset);
14898 }
14899 break;
14900 case MOVE16:
14901 {
14902 int rd = uMIPS_RD5(ctx->opcode);
14903 int rs = uMIPS_RS5(ctx->opcode);
14904
14905 gen_arith(ctx, OPC_ADDU, rd, rs, 0);
14906 }
14907 break;
14908 case ANDI16:
14909 gen_andi16(ctx);
14910 break;
14911 case POOL16D:
14912 switch (ctx->opcode & 0x1) {
14913 case ADDIUS5:
14914 gen_addius5(ctx);
14915 break;
14916 case ADDIUSP:
14917 gen_addiusp(ctx);
14918 break;
14919 }
14920 break;
14921 case POOL16E:
14922 switch (ctx->opcode & 0x1) {
14923 case ADDIUR2:
14924 gen_addiur2(ctx);
14925 break;
14926 case ADDIUR1SP:
14927 gen_addiur1sp(ctx);
14928 break;
14929 }
14930 break;
14931 case B16: /* BC16 */
14932 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
14933 sextract32(ctx->opcode, 0, 10) << 1,
14934 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
14935 break;
14936 case BNEZ16: /* BNEZC16 */
14937 case BEQZ16: /* BEQZC16 */
14938 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
14939 mmreg(uMIPS_RD(ctx->opcode)),
14940 0, sextract32(ctx->opcode, 0, 7) << 1,
14941 (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
14942
14943 break;
14944 case LI16:
14945 {
14946 int reg = mmreg(uMIPS_RD(ctx->opcode));
14947 int imm = ZIMM(ctx->opcode, 0, 7);
14948
14949 imm = (imm == 0x7f ? -1 : imm);
14950 tcg_gen_movi_tl(cpu_gpr[reg], imm);
14951 }
14952 break;
14953 case RES_29:
14954 case RES_31:
14955 case RES_39:
14956 generate_exception_end(ctx, EXCP_RI);
14957 break;
14958 default:
14959 decode_micromips32_opc(env, ctx);
14960 return 4;
14961 }
14962
14963 return 2;
14964 }
14965
14966 /* SmartMIPS extension to MIPS32 */
14967
14968 #if defined(TARGET_MIPS64)
14969
14970 /* MDMX extension to MIPS64 */
14971
14972 #endif
14973
14974 /* MIPSDSP functions. */
14975 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
14976 int rd, int base, int offset)
14977 {
14978 TCGv t0;
14979
14980 check_dsp(ctx);
14981 t0 = tcg_temp_new();
14982
14983 if (base == 0) {
14984 gen_load_gpr(t0, offset);
14985 } else if (offset == 0) {
14986 gen_load_gpr(t0, base);
14987 } else {
14988 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
14989 }
14990
14991 switch (opc) {
14992 case OPC_LBUX:
14993 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
14994 gen_store_gpr(t0, rd);
14995 break;
14996 case OPC_LHX:
14997 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
14998 gen_store_gpr(t0, rd);
14999 break;
15000 case OPC_LWX:
15001 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
15002 gen_store_gpr(t0, rd);
15003 break;
15004 #if defined(TARGET_MIPS64)
15005 case OPC_LDX:
15006 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
15007 gen_store_gpr(t0, rd);
15008 break;
15009 #endif
15010 }
15011 tcg_temp_free(t0);
15012 }
15013
15014 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
15015 int ret, int v1, int v2)
15016 {
15017 TCGv v1_t;
15018 TCGv v2_t;
15019
15020 if (ret == 0) {
15021 /* Treat as NOP. */
15022 return;
15023 }
15024
15025 v1_t = tcg_temp_new();
15026 v2_t = tcg_temp_new();
15027
15028 gen_load_gpr(v1_t, v1);
15029 gen_load_gpr(v2_t, v2);
15030
15031 switch (op1) {
15032 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15033 case OPC_MULT_G_2E:
15034 check_dspr2(ctx);
15035 switch (op2) {
15036 case OPC_ADDUH_QB:
15037 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
15038 break;
15039 case OPC_ADDUH_R_QB:
15040 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15041 break;
15042 case OPC_ADDQH_PH:
15043 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
15044 break;
15045 case OPC_ADDQH_R_PH:
15046 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15047 break;
15048 case OPC_ADDQH_W:
15049 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
15050 break;
15051 case OPC_ADDQH_R_W:
15052 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15053 break;
15054 case OPC_SUBUH_QB:
15055 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
15056 break;
15057 case OPC_SUBUH_R_QB:
15058 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
15059 break;
15060 case OPC_SUBQH_PH:
15061 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
15062 break;
15063 case OPC_SUBQH_R_PH:
15064 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
15065 break;
15066 case OPC_SUBQH_W:
15067 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
15068 break;
15069 case OPC_SUBQH_R_W:
15070 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
15071 break;
15072 }
15073 break;
15074 case OPC_ABSQ_S_PH_DSP:
15075 switch (op2) {
15076 case OPC_ABSQ_S_QB:
15077 check_dspr2(ctx);
15078 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
15079 break;
15080 case OPC_ABSQ_S_PH:
15081 check_dsp(ctx);
15082 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
15083 break;
15084 case OPC_ABSQ_S_W:
15085 check_dsp(ctx);
15086 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
15087 break;
15088 case OPC_PRECEQ_W_PHL:
15089 check_dsp(ctx);
15090 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
15091 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15092 break;
15093 case OPC_PRECEQ_W_PHR:
15094 check_dsp(ctx);
15095 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
15096 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
15097 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
15098 break;
15099 case OPC_PRECEQU_PH_QBL:
15100 check_dsp(ctx);
15101 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
15102 break;
15103 case OPC_PRECEQU_PH_QBR:
15104 check_dsp(ctx);
15105 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
15106 break;
15107 case OPC_PRECEQU_PH_QBLA:
15108 check_dsp(ctx);
15109 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
15110 break;
15111 case OPC_PRECEQU_PH_QBRA:
15112 check_dsp(ctx);
15113 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
15114 break;
15115 case OPC_PRECEU_PH_QBL:
15116 check_dsp(ctx);
15117 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
15118 break;
15119 case OPC_PRECEU_PH_QBR:
15120 check_dsp(ctx);
15121 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
15122 break;
15123 case OPC_PRECEU_PH_QBLA:
15124 check_dsp(ctx);
15125 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
15126 break;
15127 case OPC_PRECEU_PH_QBRA:
15128 check_dsp(ctx);
15129 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
15130 break;
15131 }
15132 break;
15133 case OPC_ADDU_QB_DSP:
15134 switch (op2) {
15135 case OPC_ADDQ_PH:
15136 check_dsp(ctx);
15137 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15138 break;
15139 case OPC_ADDQ_S_PH:
15140 check_dsp(ctx);
15141 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15142 break;
15143 case OPC_ADDQ_S_W:
15144 check_dsp(ctx);
15145 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15146 break;
15147 case OPC_ADDU_QB:
15148 check_dsp(ctx);
15149 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15150 break;
15151 case OPC_ADDU_S_QB:
15152 check_dsp(ctx);
15153 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15154 break;
15155 case OPC_ADDU_PH:
15156 check_dspr2(ctx);
15157 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15158 break;
15159 case OPC_ADDU_S_PH:
15160 check_dspr2(ctx);
15161 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15162 break;
15163 case OPC_SUBQ_PH:
15164 check_dsp(ctx);
15165 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15166 break;
15167 case OPC_SUBQ_S_PH:
15168 check_dsp(ctx);
15169 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15170 break;
15171 case OPC_SUBQ_S_W:
15172 check_dsp(ctx);
15173 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15174 break;
15175 case OPC_SUBU_QB:
15176 check_dsp(ctx);
15177 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15178 break;
15179 case OPC_SUBU_S_QB:
15180 check_dsp(ctx);
15181 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15182 break;
15183 case OPC_SUBU_PH:
15184 check_dspr2(ctx);
15185 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15186 break;
15187 case OPC_SUBU_S_PH:
15188 check_dspr2(ctx);
15189 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15190 break;
15191 case OPC_ADDSC:
15192 check_dsp(ctx);
15193 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15194 break;
15195 case OPC_ADDWC:
15196 check_dsp(ctx);
15197 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15198 break;
15199 case OPC_MODSUB:
15200 check_dsp(ctx);
15201 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
15202 break;
15203 case OPC_RADDU_W_QB:
15204 check_dsp(ctx);
15205 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
15206 break;
15207 }
15208 break;
15209 case OPC_CMPU_EQ_QB_DSP:
15210 switch (op2) {
15211 case OPC_PRECR_QB_PH:
15212 check_dspr2(ctx);
15213 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15214 break;
15215 case OPC_PRECRQ_QB_PH:
15216 check_dsp(ctx);
15217 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
15218 break;
15219 case OPC_PRECR_SRA_PH_W:
15220 check_dspr2(ctx);
15221 {
15222 TCGv_i32 sa_t = tcg_const_i32(v2);
15223 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
15224 cpu_gpr[ret]);
15225 tcg_temp_free_i32(sa_t);
15226 break;
15227 }
15228 case OPC_PRECR_SRA_R_PH_W:
15229 check_dspr2(ctx);
15230 {
15231 TCGv_i32 sa_t = tcg_const_i32(v2);
15232 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
15233 cpu_gpr[ret]);
15234 tcg_temp_free_i32(sa_t);
15235 break;
15236 }
15237 case OPC_PRECRQ_PH_W:
15238 check_dsp(ctx);
15239 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
15240 break;
15241 case OPC_PRECRQ_RS_PH_W:
15242 check_dsp(ctx);
15243 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15244 break;
15245 case OPC_PRECRQU_S_QB_PH:
15246 check_dsp(ctx);
15247 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15248 break;
15249 }
15250 break;
15251 #ifdef TARGET_MIPS64
15252 case OPC_ABSQ_S_QH_DSP:
15253 switch (op2) {
15254 case OPC_PRECEQ_L_PWL:
15255 check_dsp(ctx);
15256 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
15257 break;
15258 case OPC_PRECEQ_L_PWR:
15259 check_dsp(ctx);
15260 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
15261 break;
15262 case OPC_PRECEQ_PW_QHL:
15263 check_dsp(ctx);
15264 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
15265 break;
15266 case OPC_PRECEQ_PW_QHR:
15267 check_dsp(ctx);
15268 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
15269 break;
15270 case OPC_PRECEQ_PW_QHLA:
15271 check_dsp(ctx);
15272 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
15273 break;
15274 case OPC_PRECEQ_PW_QHRA:
15275 check_dsp(ctx);
15276 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
15277 break;
15278 case OPC_PRECEQU_QH_OBL:
15279 check_dsp(ctx);
15280 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
15281 break;
15282 case OPC_PRECEQU_QH_OBR:
15283 check_dsp(ctx);
15284 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
15285 break;
15286 case OPC_PRECEQU_QH_OBLA:
15287 check_dsp(ctx);
15288 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
15289 break;
15290 case OPC_PRECEQU_QH_OBRA:
15291 check_dsp(ctx);
15292 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
15293 break;
15294 case OPC_PRECEU_QH_OBL:
15295 check_dsp(ctx);
15296 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
15297 break;
15298 case OPC_PRECEU_QH_OBR:
15299 check_dsp(ctx);
15300 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
15301 break;
15302 case OPC_PRECEU_QH_OBLA:
15303 check_dsp(ctx);
15304 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
15305 break;
15306 case OPC_PRECEU_QH_OBRA:
15307 check_dsp(ctx);
15308 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
15309 break;
15310 case OPC_ABSQ_S_OB:
15311 check_dspr2(ctx);
15312 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
15313 break;
15314 case OPC_ABSQ_S_PW:
15315 check_dsp(ctx);
15316 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
15317 break;
15318 case OPC_ABSQ_S_QH:
15319 check_dsp(ctx);
15320 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
15321 break;
15322 }
15323 break;
15324 case OPC_ADDU_OB_DSP:
15325 switch (op2) {
15326 case OPC_RADDU_L_OB:
15327 check_dsp(ctx);
15328 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
15329 break;
15330 case OPC_SUBQ_PW:
15331 check_dsp(ctx);
15332 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15333 break;
15334 case OPC_SUBQ_S_PW:
15335 check_dsp(ctx);
15336 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15337 break;
15338 case OPC_SUBQ_QH:
15339 check_dsp(ctx);
15340 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15341 break;
15342 case OPC_SUBQ_S_QH:
15343 check_dsp(ctx);
15344 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15345 break;
15346 case OPC_SUBU_OB:
15347 check_dsp(ctx);
15348 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15349 break;
15350 case OPC_SUBU_S_OB:
15351 check_dsp(ctx);
15352 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15353 break;
15354 case OPC_SUBU_QH:
15355 check_dspr2(ctx);
15356 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15357 break;
15358 case OPC_SUBU_S_QH:
15359 check_dspr2(ctx);
15360 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15361 break;
15362 case OPC_SUBUH_OB:
15363 check_dspr2(ctx);
15364 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
15365 break;
15366 case OPC_SUBUH_R_OB:
15367 check_dspr2(ctx);
15368 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15369 break;
15370 case OPC_ADDQ_PW:
15371 check_dsp(ctx);
15372 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15373 break;
15374 case OPC_ADDQ_S_PW:
15375 check_dsp(ctx);
15376 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15377 break;
15378 case OPC_ADDQ_QH:
15379 check_dsp(ctx);
15380 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15381 break;
15382 case OPC_ADDQ_S_QH:
15383 check_dsp(ctx);
15384 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15385 break;
15386 case OPC_ADDU_OB:
15387 check_dsp(ctx);
15388 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15389 break;
15390 case OPC_ADDU_S_OB:
15391 check_dsp(ctx);
15392 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15393 break;
15394 case OPC_ADDU_QH:
15395 check_dspr2(ctx);
15396 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15397 break;
15398 case OPC_ADDU_S_QH:
15399 check_dspr2(ctx);
15400 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15401 break;
15402 case OPC_ADDUH_OB:
15403 check_dspr2(ctx);
15404 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
15405 break;
15406 case OPC_ADDUH_R_OB:
15407 check_dspr2(ctx);
15408 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
15409 break;
15410 }
15411 break;
15412 case OPC_CMPU_EQ_OB_DSP:
15413 switch (op2) {
15414 case OPC_PRECR_OB_QH:
15415 check_dspr2(ctx);
15416 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15417 break;
15418 case OPC_PRECR_SRA_QH_PW:
15419 check_dspr2(ctx);
15420 {
15421 TCGv_i32 ret_t = tcg_const_i32(ret);
15422 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
15423 tcg_temp_free_i32(ret_t);
15424 break;
15425 }
15426 case OPC_PRECR_SRA_R_QH_PW:
15427 check_dspr2(ctx);
15428 {
15429 TCGv_i32 sa_v = tcg_const_i32(ret);
15430 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
15431 tcg_temp_free_i32(sa_v);
15432 break;
15433 }
15434 case OPC_PRECRQ_OB_QH:
15435 check_dsp(ctx);
15436 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
15437 break;
15438 case OPC_PRECRQ_PW_L:
15439 check_dsp(ctx);
15440 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
15441 break;
15442 case OPC_PRECRQ_QH_PW:
15443 check_dsp(ctx);
15444 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
15445 break;
15446 case OPC_PRECRQ_RS_QH_PW:
15447 check_dsp(ctx);
15448 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15449 break;
15450 case OPC_PRECRQU_S_OB_QH:
15451 check_dsp(ctx);
15452 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15453 break;
15454 }
15455 break;
15456 #endif
15457 }
15458
15459 tcg_temp_free(v1_t);
15460 tcg_temp_free(v2_t);
15461 }
15462
15463 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
15464 int ret, int v1, int v2)
15465 {
15466 uint32_t op2;
15467 TCGv t0;
15468 TCGv v1_t;
15469 TCGv v2_t;
15470
15471 if (ret == 0) {
15472 /* Treat as NOP. */
15473 return;
15474 }
15475
15476 t0 = tcg_temp_new();
15477 v1_t = tcg_temp_new();
15478 v2_t = tcg_temp_new();
15479
15480 tcg_gen_movi_tl(t0, v1);
15481 gen_load_gpr(v1_t, v1);
15482 gen_load_gpr(v2_t, v2);
15483
15484 switch (opc) {
15485 case OPC_SHLL_QB_DSP:
15486 {
15487 op2 = MASK_SHLL_QB(ctx->opcode);
15488 switch (op2) {
15489 case OPC_SHLL_QB:
15490 check_dsp(ctx);
15491 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
15492 break;
15493 case OPC_SHLLV_QB:
15494 check_dsp(ctx);
15495 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15496 break;
15497 case OPC_SHLL_PH:
15498 check_dsp(ctx);
15499 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15500 break;
15501 case OPC_SHLLV_PH:
15502 check_dsp(ctx);
15503 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15504 break;
15505 case OPC_SHLL_S_PH:
15506 check_dsp(ctx);
15507 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
15508 break;
15509 case OPC_SHLLV_S_PH:
15510 check_dsp(ctx);
15511 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15512 break;
15513 case OPC_SHLL_S_W:
15514 check_dsp(ctx);
15515 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
15516 break;
15517 case OPC_SHLLV_S_W:
15518 check_dsp(ctx);
15519 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15520 break;
15521 case OPC_SHRL_QB:
15522 check_dsp(ctx);
15523 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
15524 break;
15525 case OPC_SHRLV_QB:
15526 check_dsp(ctx);
15527 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
15528 break;
15529 case OPC_SHRL_PH:
15530 check_dspr2(ctx);
15531 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
15532 break;
15533 case OPC_SHRLV_PH:
15534 check_dspr2(ctx);
15535 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
15536 break;
15537 case OPC_SHRA_QB:
15538 check_dspr2(ctx);
15539 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
15540 break;
15541 case OPC_SHRA_R_QB:
15542 check_dspr2(ctx);
15543 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
15544 break;
15545 case OPC_SHRAV_QB:
15546 check_dspr2(ctx);
15547 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
15548 break;
15549 case OPC_SHRAV_R_QB:
15550 check_dspr2(ctx);
15551 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
15552 break;
15553 case OPC_SHRA_PH:
15554 check_dsp(ctx);
15555 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
15556 break;
15557 case OPC_SHRA_R_PH:
15558 check_dsp(ctx);
15559 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
15560 break;
15561 case OPC_SHRAV_PH:
15562 check_dsp(ctx);
15563 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
15564 break;
15565 case OPC_SHRAV_R_PH:
15566 check_dsp(ctx);
15567 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
15568 break;
15569 case OPC_SHRA_R_W:
15570 check_dsp(ctx);
15571 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
15572 break;
15573 case OPC_SHRAV_R_W:
15574 check_dsp(ctx);
15575 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
15576 break;
15577 default: /* Invalid */
15578 MIPS_INVAL("MASK SHLL.QB");
15579 generate_exception_end(ctx, EXCP_RI);
15580 break;
15581 }
15582 break;
15583 }
15584 #ifdef TARGET_MIPS64
15585 case OPC_SHLL_OB_DSP:
15586 op2 = MASK_SHLL_OB(ctx->opcode);
15587 switch (op2) {
15588 case OPC_SHLL_PW:
15589 check_dsp(ctx);
15590 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15591 break;
15592 case OPC_SHLLV_PW:
15593 check_dsp(ctx);
15594 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15595 break;
15596 case OPC_SHLL_S_PW:
15597 check_dsp(ctx);
15598 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
15599 break;
15600 case OPC_SHLLV_S_PW:
15601 check_dsp(ctx);
15602 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15603 break;
15604 case OPC_SHLL_OB:
15605 check_dsp(ctx);
15606 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
15607 break;
15608 case OPC_SHLLV_OB:
15609 check_dsp(ctx);
15610 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15611 break;
15612 case OPC_SHLL_QH:
15613 check_dsp(ctx);
15614 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15615 break;
15616 case OPC_SHLLV_QH:
15617 check_dsp(ctx);
15618 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15619 break;
15620 case OPC_SHLL_S_QH:
15621 check_dsp(ctx);
15622 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
15623 break;
15624 case OPC_SHLLV_S_QH:
15625 check_dsp(ctx);
15626 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
15627 break;
15628 case OPC_SHRA_OB:
15629 check_dspr2(ctx);
15630 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
15631 break;
15632 case OPC_SHRAV_OB:
15633 check_dspr2(ctx);
15634 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
15635 break;
15636 case OPC_SHRA_R_OB:
15637 check_dspr2(ctx);
15638 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
15639 break;
15640 case OPC_SHRAV_R_OB:
15641 check_dspr2(ctx);
15642 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
15643 break;
15644 case OPC_SHRA_PW:
15645 check_dsp(ctx);
15646 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
15647 break;
15648 case OPC_SHRAV_PW:
15649 check_dsp(ctx);
15650 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
15651 break;
15652 case OPC_SHRA_R_PW:
15653 check_dsp(ctx);
15654 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
15655 break;
15656 case OPC_SHRAV_R_PW:
15657 check_dsp(ctx);
15658 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
15659 break;
15660 case OPC_SHRA_QH:
15661 check_dsp(ctx);
15662 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
15663 break;
15664 case OPC_SHRAV_QH:
15665 check_dsp(ctx);
15666 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
15667 break;
15668 case OPC_SHRA_R_QH:
15669 check_dsp(ctx);
15670 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
15671 break;
15672 case OPC_SHRAV_R_QH:
15673 check_dsp(ctx);
15674 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
15675 break;
15676 case OPC_SHRL_OB:
15677 check_dsp(ctx);
15678 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
15679 break;
15680 case OPC_SHRLV_OB:
15681 check_dsp(ctx);
15682 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
15683 break;
15684 case OPC_SHRL_QH:
15685 check_dspr2(ctx);
15686 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
15687 break;
15688 case OPC_SHRLV_QH:
15689 check_dspr2(ctx);
15690 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
15691 break;
15692 default: /* Invalid */
15693 MIPS_INVAL("MASK SHLL.OB");
15694 generate_exception_end(ctx, EXCP_RI);
15695 break;
15696 }
15697 break;
15698 #endif
15699 }
15700
15701 tcg_temp_free(t0);
15702 tcg_temp_free(v1_t);
15703 tcg_temp_free(v2_t);
15704 }
15705
15706 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
15707 int ret, int v1, int v2, int check_ret)
15708 {
15709 TCGv_i32 t0;
15710 TCGv v1_t;
15711 TCGv v2_t;
15712
15713 if ((ret == 0) && (check_ret == 1)) {
15714 /* Treat as NOP. */
15715 return;
15716 }
15717
15718 t0 = tcg_temp_new_i32();
15719 v1_t = tcg_temp_new();
15720 v2_t = tcg_temp_new();
15721
15722 tcg_gen_movi_i32(t0, ret);
15723 gen_load_gpr(v1_t, v1);
15724 gen_load_gpr(v2_t, v2);
15725
15726 switch (op1) {
15727 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
15728 * the same mask and op1. */
15729 case OPC_MULT_G_2E:
15730 check_dspr2(ctx);
15731 switch (op2) {
15732 case OPC_MUL_PH:
15733 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15734 break;
15735 case OPC_MUL_S_PH:
15736 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15737 break;
15738 case OPC_MULQ_S_W:
15739 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15740 break;
15741 case OPC_MULQ_RS_W:
15742 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15743 break;
15744 }
15745 break;
15746 case OPC_DPA_W_PH_DSP:
15747 switch (op2) {
15748 case OPC_DPAU_H_QBL:
15749 check_dsp(ctx);
15750 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
15751 break;
15752 case OPC_DPAU_H_QBR:
15753 check_dsp(ctx);
15754 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
15755 break;
15756 case OPC_DPSU_H_QBL:
15757 check_dsp(ctx);
15758 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
15759 break;
15760 case OPC_DPSU_H_QBR:
15761 check_dsp(ctx);
15762 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
15763 break;
15764 case OPC_DPA_W_PH:
15765 check_dspr2(ctx);
15766 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
15767 break;
15768 case OPC_DPAX_W_PH:
15769 check_dspr2(ctx);
15770 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
15771 break;
15772 case OPC_DPAQ_S_W_PH:
15773 check_dsp(ctx);
15774 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15775 break;
15776 case OPC_DPAQX_S_W_PH:
15777 check_dspr2(ctx);
15778 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15779 break;
15780 case OPC_DPAQX_SA_W_PH:
15781 check_dspr2(ctx);
15782 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15783 break;
15784 case OPC_DPS_W_PH:
15785 check_dspr2(ctx);
15786 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
15787 break;
15788 case OPC_DPSX_W_PH:
15789 check_dspr2(ctx);
15790 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
15791 break;
15792 case OPC_DPSQ_S_W_PH:
15793 check_dsp(ctx);
15794 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15795 break;
15796 case OPC_DPSQX_S_W_PH:
15797 check_dspr2(ctx);
15798 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
15799 break;
15800 case OPC_DPSQX_SA_W_PH:
15801 check_dspr2(ctx);
15802 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
15803 break;
15804 case OPC_MULSAQ_S_W_PH:
15805 check_dsp(ctx);
15806 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
15807 break;
15808 case OPC_DPAQ_SA_L_W:
15809 check_dsp(ctx);
15810 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15811 break;
15812 case OPC_DPSQ_SA_L_W:
15813 check_dsp(ctx);
15814 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
15815 break;
15816 case OPC_MAQ_S_W_PHL:
15817 check_dsp(ctx);
15818 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
15819 break;
15820 case OPC_MAQ_S_W_PHR:
15821 check_dsp(ctx);
15822 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
15823 break;
15824 case OPC_MAQ_SA_W_PHL:
15825 check_dsp(ctx);
15826 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
15827 break;
15828 case OPC_MAQ_SA_W_PHR:
15829 check_dsp(ctx);
15830 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
15831 break;
15832 case OPC_MULSA_W_PH:
15833 check_dspr2(ctx);
15834 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
15835 break;
15836 }
15837 break;
15838 #ifdef TARGET_MIPS64
15839 case OPC_DPAQ_W_QH_DSP:
15840 {
15841 int ac = ret & 0x03;
15842 tcg_gen_movi_i32(t0, ac);
15843
15844 switch (op2) {
15845 case OPC_DMADD:
15846 check_dsp(ctx);
15847 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
15848 break;
15849 case OPC_DMADDU:
15850 check_dsp(ctx);
15851 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
15852 break;
15853 case OPC_DMSUB:
15854 check_dsp(ctx);
15855 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
15856 break;
15857 case OPC_DMSUBU:
15858 check_dsp(ctx);
15859 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
15860 break;
15861 case OPC_DPA_W_QH:
15862 check_dspr2(ctx);
15863 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
15864 break;
15865 case OPC_DPAQ_S_W_QH:
15866 check_dsp(ctx);
15867 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15868 break;
15869 case OPC_DPAQ_SA_L_PW:
15870 check_dsp(ctx);
15871 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15872 break;
15873 case OPC_DPAU_H_OBL:
15874 check_dsp(ctx);
15875 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
15876 break;
15877 case OPC_DPAU_H_OBR:
15878 check_dsp(ctx);
15879 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
15880 break;
15881 case OPC_DPS_W_QH:
15882 check_dspr2(ctx);
15883 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
15884 break;
15885 case OPC_DPSQ_S_W_QH:
15886 check_dsp(ctx);
15887 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15888 break;
15889 case OPC_DPSQ_SA_L_PW:
15890 check_dsp(ctx);
15891 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
15892 break;
15893 case OPC_DPSU_H_OBL:
15894 check_dsp(ctx);
15895 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
15896 break;
15897 case OPC_DPSU_H_OBR:
15898 check_dsp(ctx);
15899 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
15900 break;
15901 case OPC_MAQ_S_L_PWL:
15902 check_dsp(ctx);
15903 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
15904 break;
15905 case OPC_MAQ_S_L_PWR:
15906 check_dsp(ctx);
15907 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
15908 break;
15909 case OPC_MAQ_S_W_QHLL:
15910 check_dsp(ctx);
15911 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
15912 break;
15913 case OPC_MAQ_SA_W_QHLL:
15914 check_dsp(ctx);
15915 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
15916 break;
15917 case OPC_MAQ_S_W_QHLR:
15918 check_dsp(ctx);
15919 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
15920 break;
15921 case OPC_MAQ_SA_W_QHLR:
15922 check_dsp(ctx);
15923 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
15924 break;
15925 case OPC_MAQ_S_W_QHRL:
15926 check_dsp(ctx);
15927 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
15928 break;
15929 case OPC_MAQ_SA_W_QHRL:
15930 check_dsp(ctx);
15931 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
15932 break;
15933 case OPC_MAQ_S_W_QHRR:
15934 check_dsp(ctx);
15935 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
15936 break;
15937 case OPC_MAQ_SA_W_QHRR:
15938 check_dsp(ctx);
15939 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
15940 break;
15941 case OPC_MULSAQ_S_L_PW:
15942 check_dsp(ctx);
15943 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
15944 break;
15945 case OPC_MULSAQ_S_W_QH:
15946 check_dsp(ctx);
15947 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
15948 break;
15949 }
15950 }
15951 break;
15952 #endif
15953 case OPC_ADDU_QB_DSP:
15954 switch (op2) {
15955 case OPC_MULEU_S_PH_QBL:
15956 check_dsp(ctx);
15957 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15958 break;
15959 case OPC_MULEU_S_PH_QBR:
15960 check_dsp(ctx);
15961 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15962 break;
15963 case OPC_MULQ_RS_PH:
15964 check_dsp(ctx);
15965 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15966 break;
15967 case OPC_MULEQ_S_W_PHL:
15968 check_dsp(ctx);
15969 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15970 break;
15971 case OPC_MULEQ_S_W_PHR:
15972 check_dsp(ctx);
15973 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15974 break;
15975 case OPC_MULQ_S_PH:
15976 check_dspr2(ctx);
15977 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15978 break;
15979 }
15980 break;
15981 #ifdef TARGET_MIPS64
15982 case OPC_ADDU_OB_DSP:
15983 switch (op2) {
15984 case OPC_MULEQ_S_PW_QHL:
15985 check_dsp(ctx);
15986 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15987 break;
15988 case OPC_MULEQ_S_PW_QHR:
15989 check_dsp(ctx);
15990 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15991 break;
15992 case OPC_MULEU_S_QH_OBL:
15993 check_dsp(ctx);
15994 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15995 break;
15996 case OPC_MULEU_S_QH_OBR:
15997 check_dsp(ctx);
15998 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15999 break;
16000 case OPC_MULQ_RS_QH:
16001 check_dsp(ctx);
16002 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16003 break;
16004 }
16005 break;
16006 #endif
16007 }
16008
16009 tcg_temp_free_i32(t0);
16010 tcg_temp_free(v1_t);
16011 tcg_temp_free(v2_t);
16012 }
16013
16014 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16015 int ret, int val)
16016 {
16017 int16_t imm;
16018 TCGv t0;
16019 TCGv val_t;
16020
16021 if (ret == 0) {
16022 /* Treat as NOP. */
16023 return;
16024 }
16025
16026 t0 = tcg_temp_new();
16027 val_t = tcg_temp_new();
16028 gen_load_gpr(val_t, val);
16029
16030 switch (op1) {
16031 case OPC_ABSQ_S_PH_DSP:
16032 switch (op2) {
16033 case OPC_BITREV:
16034 check_dsp(ctx);
16035 gen_helper_bitrev(cpu_gpr[ret], val_t);
16036 break;
16037 case OPC_REPL_QB:
16038 check_dsp(ctx);
16039 {
16040 target_long result;
16041 imm = (ctx->opcode >> 16) & 0xFF;
16042 result = (uint32_t)imm << 24 |
16043 (uint32_t)imm << 16 |
16044 (uint32_t)imm << 8 |
16045 (uint32_t)imm;
16046 result = (int32_t)result;
16047 tcg_gen_movi_tl(cpu_gpr[ret], result);
16048 }
16049 break;
16050 case OPC_REPLV_QB:
16051 check_dsp(ctx);
16052 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16053 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16054 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16055 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16056 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16057 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16058 break;
16059 case OPC_REPL_PH:
16060 check_dsp(ctx);
16061 {
16062 imm = (ctx->opcode >> 16) & 0x03FF;
16063 imm = (int16_t)(imm << 6) >> 6;
16064 tcg_gen_movi_tl(cpu_gpr[ret], \
16065 (target_long)((int32_t)imm << 16 | \
16066 (uint16_t)imm));
16067 }
16068 break;
16069 case OPC_REPLV_PH:
16070 check_dsp(ctx);
16071 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16072 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16073 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16074 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
16075 break;
16076 }
16077 break;
16078 #ifdef TARGET_MIPS64
16079 case OPC_ABSQ_S_QH_DSP:
16080 switch (op2) {
16081 case OPC_REPL_OB:
16082 check_dsp(ctx);
16083 {
16084 target_long temp;
16085
16086 imm = (ctx->opcode >> 16) & 0xFF;
16087 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
16088 temp = (temp << 16) | temp;
16089 temp = (temp << 32) | temp;
16090 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16091 break;
16092 }
16093 case OPC_REPL_PW:
16094 check_dsp(ctx);
16095 {
16096 target_long temp;
16097
16098 imm = (ctx->opcode >> 16) & 0x03FF;
16099 imm = (int16_t)(imm << 6) >> 6;
16100 temp = ((target_long)imm << 32) \
16101 | ((target_long)imm & 0xFFFFFFFF);
16102 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16103 break;
16104 }
16105 case OPC_REPL_QH:
16106 check_dsp(ctx);
16107 {
16108 target_long temp;
16109
16110 imm = (ctx->opcode >> 16) & 0x03FF;
16111 imm = (int16_t)(imm << 6) >> 6;
16112
16113 temp = ((uint64_t)(uint16_t)imm << 48) |
16114 ((uint64_t)(uint16_t)imm << 32) |
16115 ((uint64_t)(uint16_t)imm << 16) |
16116 (uint64_t)(uint16_t)imm;
16117 tcg_gen_movi_tl(cpu_gpr[ret], temp);
16118 break;
16119 }
16120 case OPC_REPLV_OB:
16121 check_dsp(ctx);
16122 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
16123 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
16124 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16125 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16126 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16127 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16128 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16129 break;
16130 case OPC_REPLV_PW:
16131 check_dsp(ctx);
16132 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
16133 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16134 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16135 break;
16136 case OPC_REPLV_QH:
16137 check_dsp(ctx);
16138 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
16139 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
16140 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16141 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
16142 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
16143 break;
16144 }
16145 break;
16146 #endif
16147 }
16148 tcg_temp_free(t0);
16149 tcg_temp_free(val_t);
16150 }
16151
16152 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
16153 uint32_t op1, uint32_t op2,
16154 int ret, int v1, int v2, int check_ret)
16155 {
16156 TCGv t1;
16157 TCGv v1_t;
16158 TCGv v2_t;
16159
16160 if ((ret == 0) && (check_ret == 1)) {
16161 /* Treat as NOP. */
16162 return;
16163 }
16164
16165 t1 = tcg_temp_new();
16166 v1_t = tcg_temp_new();
16167 v2_t = tcg_temp_new();
16168
16169 gen_load_gpr(v1_t, v1);
16170 gen_load_gpr(v2_t, v2);
16171
16172 switch (op1) {
16173 case OPC_CMPU_EQ_QB_DSP:
16174 switch (op2) {
16175 case OPC_CMPU_EQ_QB:
16176 check_dsp(ctx);
16177 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
16178 break;
16179 case OPC_CMPU_LT_QB:
16180 check_dsp(ctx);
16181 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
16182 break;
16183 case OPC_CMPU_LE_QB:
16184 check_dsp(ctx);
16185 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
16186 break;
16187 case OPC_CMPGU_EQ_QB:
16188 check_dsp(ctx);
16189 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
16190 break;
16191 case OPC_CMPGU_LT_QB:
16192 check_dsp(ctx);
16193 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
16194 break;
16195 case OPC_CMPGU_LE_QB:
16196 check_dsp(ctx);
16197 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
16198 break;
16199 case OPC_CMPGDU_EQ_QB:
16200 check_dspr2(ctx);
16201 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
16202 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16203 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16204 tcg_gen_shli_tl(t1, t1, 24);
16205 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16206 break;
16207 case OPC_CMPGDU_LT_QB:
16208 check_dspr2(ctx);
16209 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
16210 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16211 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16212 tcg_gen_shli_tl(t1, t1, 24);
16213 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16214 break;
16215 case OPC_CMPGDU_LE_QB:
16216 check_dspr2(ctx);
16217 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
16218 tcg_gen_mov_tl(cpu_gpr[ret], t1);
16219 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
16220 tcg_gen_shli_tl(t1, t1, 24);
16221 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
16222 break;
16223 case OPC_CMP_EQ_PH:
16224 check_dsp(ctx);
16225 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
16226 break;
16227 case OPC_CMP_LT_PH:
16228 check_dsp(ctx);
16229 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
16230 break;
16231 case OPC_CMP_LE_PH:
16232 check_dsp(ctx);
16233 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
16234 break;
16235 case OPC_PICK_QB:
16236 check_dsp(ctx);
16237 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16238 break;
16239 case OPC_PICK_PH:
16240 check_dsp(ctx);
16241 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16242 break;
16243 case OPC_PACKRL_PH:
16244 check_dsp(ctx);
16245 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
16246 break;
16247 }
16248 break;
16249 #ifdef TARGET_MIPS64
16250 case OPC_CMPU_EQ_OB_DSP:
16251 switch (op2) {
16252 case OPC_CMP_EQ_PW:
16253 check_dsp(ctx);
16254 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
16255 break;
16256 case OPC_CMP_LT_PW:
16257 check_dsp(ctx);
16258 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
16259 break;
16260 case OPC_CMP_LE_PW:
16261 check_dsp(ctx);
16262 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
16263 break;
16264 case OPC_CMP_EQ_QH:
16265 check_dsp(ctx);
16266 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
16267 break;
16268 case OPC_CMP_LT_QH:
16269 check_dsp(ctx);
16270 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
16271 break;
16272 case OPC_CMP_LE_QH:
16273 check_dsp(ctx);
16274 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
16275 break;
16276 case OPC_CMPGDU_EQ_OB:
16277 check_dspr2(ctx);
16278 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16279 break;
16280 case OPC_CMPGDU_LT_OB:
16281 check_dspr2(ctx);
16282 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16283 break;
16284 case OPC_CMPGDU_LE_OB:
16285 check_dspr2(ctx);
16286 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16287 break;
16288 case OPC_CMPGU_EQ_OB:
16289 check_dsp(ctx);
16290 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
16291 break;
16292 case OPC_CMPGU_LT_OB:
16293 check_dsp(ctx);
16294 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
16295 break;
16296 case OPC_CMPGU_LE_OB:
16297 check_dsp(ctx);
16298 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
16299 break;
16300 case OPC_CMPU_EQ_OB:
16301 check_dsp(ctx);
16302 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
16303 break;
16304 case OPC_CMPU_LT_OB:
16305 check_dsp(ctx);
16306 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
16307 break;
16308 case OPC_CMPU_LE_OB:
16309 check_dsp(ctx);
16310 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
16311 break;
16312 case OPC_PACKRL_PW:
16313 check_dsp(ctx);
16314 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
16315 break;
16316 case OPC_PICK_OB:
16317 check_dsp(ctx);
16318 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16319 break;
16320 case OPC_PICK_PW:
16321 check_dsp(ctx);
16322 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16323 break;
16324 case OPC_PICK_QH:
16325 check_dsp(ctx);
16326 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
16327 break;
16328 }
16329 break;
16330 #endif
16331 }
16332
16333 tcg_temp_free(t1);
16334 tcg_temp_free(v1_t);
16335 tcg_temp_free(v2_t);
16336 }
16337
16338 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
16339 uint32_t op1, int rt, int rs, int sa)
16340 {
16341 TCGv t0;
16342
16343 check_dspr2(ctx);
16344
16345 if (rt == 0) {
16346 /* Treat as NOP. */
16347 return;
16348 }
16349
16350 t0 = tcg_temp_new();
16351 gen_load_gpr(t0, rs);
16352
16353 switch (op1) {
16354 case OPC_APPEND_DSP:
16355 switch (MASK_APPEND(ctx->opcode)) {
16356 case OPC_APPEND:
16357 if (sa != 0) {
16358 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
16359 }
16360 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16361 break;
16362 case OPC_PREPEND:
16363 if (sa != 0) {
16364 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
16365 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16366 tcg_gen_shli_tl(t0, t0, 32 - sa);
16367 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16368 }
16369 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16370 break;
16371 case OPC_BALIGN:
16372 sa &= 3;
16373 if (sa != 0 && sa != 2) {
16374 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16375 tcg_gen_ext32u_tl(t0, t0);
16376 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
16377 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16378 }
16379 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
16380 break;
16381 default: /* Invalid */
16382 MIPS_INVAL("MASK APPEND");
16383 generate_exception_end(ctx, EXCP_RI);
16384 break;
16385 }
16386 break;
16387 #ifdef TARGET_MIPS64
16388 case OPC_DAPPEND_DSP:
16389 switch (MASK_DAPPEND(ctx->opcode)) {
16390 case OPC_DAPPEND:
16391 if (sa != 0) {
16392 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
16393 }
16394 break;
16395 case OPC_PREPENDD:
16396 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
16397 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
16398 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
16399 break;
16400 case OPC_PREPENDW:
16401 if (sa != 0) {
16402 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
16403 tcg_gen_shli_tl(t0, t0, 64 - sa);
16404 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16405 }
16406 break;
16407 case OPC_DBALIGN:
16408 sa &= 7;
16409 if (sa != 0 && sa != 2 && sa != 4) {
16410 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
16411 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
16412 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
16413 }
16414 break;
16415 default: /* Invalid */
16416 MIPS_INVAL("MASK DAPPEND");
16417 generate_exception_end(ctx, EXCP_RI);
16418 break;
16419 }
16420 break;
16421 #endif
16422 }
16423 tcg_temp_free(t0);
16424 }
16425
16426 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
16427 int ret, int v1, int v2, int check_ret)
16428
16429 {
16430 TCGv t0;
16431 TCGv t1;
16432 TCGv v1_t;
16433 TCGv v2_t;
16434 int16_t imm;
16435
16436 if ((ret == 0) && (check_ret == 1)) {
16437 /* Treat as NOP. */
16438 return;
16439 }
16440
16441 t0 = tcg_temp_new();
16442 t1 = tcg_temp_new();
16443 v1_t = tcg_temp_new();
16444 v2_t = tcg_temp_new();
16445
16446 gen_load_gpr(v1_t, v1);
16447 gen_load_gpr(v2_t, v2);
16448
16449 switch (op1) {
16450 case OPC_EXTR_W_DSP:
16451 check_dsp(ctx);
16452 switch (op2) {
16453 case OPC_EXTR_W:
16454 tcg_gen_movi_tl(t0, v2);
16455 tcg_gen_movi_tl(t1, v1);
16456 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
16457 break;
16458 case OPC_EXTR_R_W:
16459 tcg_gen_movi_tl(t0, v2);
16460 tcg_gen_movi_tl(t1, v1);
16461 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16462 break;
16463 case OPC_EXTR_RS_W:
16464 tcg_gen_movi_tl(t0, v2);
16465 tcg_gen_movi_tl(t1, v1);
16466 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16467 break;
16468 case OPC_EXTR_S_H:
16469 tcg_gen_movi_tl(t0, v2);
16470 tcg_gen_movi_tl(t1, v1);
16471 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16472 break;
16473 case OPC_EXTRV_S_H:
16474 tcg_gen_movi_tl(t0, v2);
16475 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
16476 break;
16477 case OPC_EXTRV_W:
16478 tcg_gen_movi_tl(t0, v2);
16479 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16480 break;
16481 case OPC_EXTRV_R_W:
16482 tcg_gen_movi_tl(t0, v2);
16483 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16484 break;
16485 case OPC_EXTRV_RS_W:
16486 tcg_gen_movi_tl(t0, v2);
16487 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16488 break;
16489 case OPC_EXTP:
16490 tcg_gen_movi_tl(t0, v2);
16491 tcg_gen_movi_tl(t1, v1);
16492 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
16493 break;
16494 case OPC_EXTPV:
16495 tcg_gen_movi_tl(t0, v2);
16496 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
16497 break;
16498 case OPC_EXTPDP:
16499 tcg_gen_movi_tl(t0, v2);
16500 tcg_gen_movi_tl(t1, v1);
16501 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
16502 break;
16503 case OPC_EXTPDPV:
16504 tcg_gen_movi_tl(t0, v2);
16505 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16506 break;
16507 case OPC_SHILO:
16508 imm = (ctx->opcode >> 20) & 0x3F;
16509 tcg_gen_movi_tl(t0, ret);
16510 tcg_gen_movi_tl(t1, imm);
16511 gen_helper_shilo(t0, t1, cpu_env);
16512 break;
16513 case OPC_SHILOV:
16514 tcg_gen_movi_tl(t0, ret);
16515 gen_helper_shilo(t0, v1_t, cpu_env);
16516 break;
16517 case OPC_MTHLIP:
16518 tcg_gen_movi_tl(t0, ret);
16519 gen_helper_mthlip(t0, v1_t, cpu_env);
16520 break;
16521 case OPC_WRDSP:
16522 imm = (ctx->opcode >> 11) & 0x3FF;
16523 tcg_gen_movi_tl(t0, imm);
16524 gen_helper_wrdsp(v1_t, t0, cpu_env);
16525 break;
16526 case OPC_RDDSP:
16527 imm = (ctx->opcode >> 16) & 0x03FF;
16528 tcg_gen_movi_tl(t0, imm);
16529 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
16530 break;
16531 }
16532 break;
16533 #ifdef TARGET_MIPS64
16534 case OPC_DEXTR_W_DSP:
16535 check_dsp(ctx);
16536 switch (op2) {
16537 case OPC_DMTHLIP:
16538 tcg_gen_movi_tl(t0, ret);
16539 gen_helper_dmthlip(v1_t, t0, cpu_env);
16540 break;
16541 case OPC_DSHILO:
16542 {
16543 int shift = (ctx->opcode >> 19) & 0x7F;
16544 int ac = (ctx->opcode >> 11) & 0x03;
16545 tcg_gen_movi_tl(t0, shift);
16546 tcg_gen_movi_tl(t1, ac);
16547 gen_helper_dshilo(t0, t1, cpu_env);
16548 break;
16549 }
16550 case OPC_DSHILOV:
16551 {
16552 int ac = (ctx->opcode >> 11) & 0x03;
16553 tcg_gen_movi_tl(t0, ac);
16554 gen_helper_dshilo(v1_t, t0, cpu_env);
16555 break;
16556 }
16557 case OPC_DEXTP:
16558 tcg_gen_movi_tl(t0, v2);
16559 tcg_gen_movi_tl(t1, v1);
16560
16561 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
16562 break;
16563 case OPC_DEXTPV:
16564 tcg_gen_movi_tl(t0, v2);
16565 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
16566 break;
16567 case OPC_DEXTPDP:
16568 tcg_gen_movi_tl(t0, v2);
16569 tcg_gen_movi_tl(t1, v1);
16570 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
16571 break;
16572 case OPC_DEXTPDPV:
16573 tcg_gen_movi_tl(t0, v2);
16574 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
16575 break;
16576 case OPC_DEXTR_L:
16577 tcg_gen_movi_tl(t0, v2);
16578 tcg_gen_movi_tl(t1, v1);
16579 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
16580 break;
16581 case OPC_DEXTR_R_L:
16582 tcg_gen_movi_tl(t0, v2);
16583 tcg_gen_movi_tl(t1, v1);
16584 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
16585 break;
16586 case OPC_DEXTR_RS_L:
16587 tcg_gen_movi_tl(t0, v2);
16588 tcg_gen_movi_tl(t1, v1);
16589 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
16590 break;
16591 case OPC_DEXTR_W:
16592 tcg_gen_movi_tl(t0, v2);
16593 tcg_gen_movi_tl(t1, v1);
16594 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
16595 break;
16596 case OPC_DEXTR_R_W:
16597 tcg_gen_movi_tl(t0, v2);
16598 tcg_gen_movi_tl(t1, v1);
16599 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
16600 break;
16601 case OPC_DEXTR_RS_W:
16602 tcg_gen_movi_tl(t0, v2);
16603 tcg_gen_movi_tl(t1, v1);
16604 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
16605 break;
16606 case OPC_DEXTR_S_H:
16607 tcg_gen_movi_tl(t0, v2);
16608 tcg_gen_movi_tl(t1, v1);
16609 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16610 break;
16611 case OPC_DEXTRV_S_H:
16612 tcg_gen_movi_tl(t0, v2);
16613 tcg_gen_movi_tl(t1, v1);
16614 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
16615 break;
16616 case OPC_DEXTRV_L:
16617 tcg_gen_movi_tl(t0, v2);
16618 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16619 break;
16620 case OPC_DEXTRV_R_L:
16621 tcg_gen_movi_tl(t0, v2);
16622 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16623 break;
16624 case OPC_DEXTRV_RS_L:
16625 tcg_gen_movi_tl(t0, v2);
16626 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
16627 break;
16628 case OPC_DEXTRV_W:
16629 tcg_gen_movi_tl(t0, v2);
16630 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16631 break;
16632 case OPC_DEXTRV_R_W:
16633 tcg_gen_movi_tl(t0, v2);
16634 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16635 break;
16636 case OPC_DEXTRV_RS_W:
16637 tcg_gen_movi_tl(t0, v2);
16638 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
16639 break;
16640 }
16641 break;
16642 #endif
16643 }
16644
16645 tcg_temp_free(t0);
16646 tcg_temp_free(t1);
16647 tcg_temp_free(v1_t);
16648 tcg_temp_free(v2_t);
16649 }
16650
16651 /* End MIPSDSP functions. */
16652
16653 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
16654 {
16655 int rs, rt, rd, sa;
16656 uint32_t op1, op2;
16657
16658 rs = (ctx->opcode >> 21) & 0x1f;
16659 rt = (ctx->opcode >> 16) & 0x1f;
16660 rd = (ctx->opcode >> 11) & 0x1f;
16661 sa = (ctx->opcode >> 6) & 0x1f;
16662
16663 op1 = MASK_SPECIAL(ctx->opcode);
16664 switch (op1) {
16665 case OPC_LSA:
16666 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16667 break;
16668 case OPC_MULT ... OPC_DIVU:
16669 op2 = MASK_R6_MULDIV(ctx->opcode);
16670 switch (op2) {
16671 case R6_OPC_MUL:
16672 case R6_OPC_MUH:
16673 case R6_OPC_MULU:
16674 case R6_OPC_MUHU:
16675 case R6_OPC_DIV:
16676 case R6_OPC_MOD:
16677 case R6_OPC_DIVU:
16678 case R6_OPC_MODU:
16679 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16680 break;
16681 default:
16682 MIPS_INVAL("special_r6 muldiv");
16683 generate_exception_end(ctx, EXCP_RI);
16684 break;
16685 }
16686 break;
16687 case OPC_SELEQZ:
16688 case OPC_SELNEZ:
16689 gen_cond_move(ctx, op1, rd, rs, rt);
16690 break;
16691 case R6_OPC_CLO:
16692 case R6_OPC_CLZ:
16693 if (rt == 0 && sa == 1) {
16694 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16695 We need additionally to check other fields */
16696 gen_cl(ctx, op1, rd, rs);
16697 } else {
16698 generate_exception_end(ctx, EXCP_RI);
16699 }
16700 break;
16701 case R6_OPC_SDBBP:
16702 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
16703 gen_helper_do_semihosting(cpu_env);
16704 } else {
16705 if (ctx->hflags & MIPS_HFLAG_SBRI) {
16706 generate_exception_end(ctx, EXCP_RI);
16707 } else {
16708 generate_exception_end(ctx, EXCP_DBp);
16709 }
16710 }
16711 break;
16712 #if defined(TARGET_MIPS64)
16713 case OPC_DLSA:
16714 check_mips_64(ctx);
16715 gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
16716 break;
16717 case R6_OPC_DCLO:
16718 case R6_OPC_DCLZ:
16719 if (rt == 0 && sa == 1) {
16720 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16721 We need additionally to check other fields */
16722 check_mips_64(ctx);
16723 gen_cl(ctx, op1, rd, rs);
16724 } else {
16725 generate_exception_end(ctx, EXCP_RI);
16726 }
16727 break;
16728 case OPC_DMULT ... OPC_DDIVU:
16729 op2 = MASK_R6_MULDIV(ctx->opcode);
16730 switch (op2) {
16731 case R6_OPC_DMUL:
16732 case R6_OPC_DMUH:
16733 case R6_OPC_DMULU:
16734 case R6_OPC_DMUHU:
16735 case R6_OPC_DDIV:
16736 case R6_OPC_DMOD:
16737 case R6_OPC_DDIVU:
16738 case R6_OPC_DMODU:
16739 check_mips_64(ctx);
16740 gen_r6_muldiv(ctx, op2, rd, rs, rt);
16741 break;
16742 default:
16743 MIPS_INVAL("special_r6 muldiv");
16744 generate_exception_end(ctx, EXCP_RI);
16745 break;
16746 }
16747 break;
16748 #endif
16749 default: /* Invalid */
16750 MIPS_INVAL("special_r6");
16751 generate_exception_end(ctx, EXCP_RI);
16752 break;
16753 }
16754 }
16755
16756 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
16757 {
16758 int rs, rt, rd, sa;
16759 uint32_t op1;
16760
16761 rs = (ctx->opcode >> 21) & 0x1f;
16762 rt = (ctx->opcode >> 16) & 0x1f;
16763 rd = (ctx->opcode >> 11) & 0x1f;
16764 sa = (ctx->opcode >> 6) & 0x1f;
16765
16766 op1 = MASK_SPECIAL(ctx->opcode);
16767 switch (op1) {
16768 case OPC_MOVN: /* Conditional move */
16769 case OPC_MOVZ:
16770 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
16771 INSN_LOONGSON2E | INSN_LOONGSON2F);
16772 gen_cond_move(ctx, op1, rd, rs, rt);
16773 break;
16774 case OPC_MFHI: /* Move from HI/LO */
16775 case OPC_MFLO:
16776 gen_HILO(ctx, op1, rs & 3, rd);
16777 break;
16778 case OPC_MTHI:
16779 case OPC_MTLO: /* Move to HI/LO */
16780 gen_HILO(ctx, op1, rd & 3, rs);
16781 break;
16782 case OPC_MOVCI:
16783 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
16784 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16785 check_cp1_enabled(ctx);
16786 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
16787 (ctx->opcode >> 16) & 1);
16788 } else {
16789 generate_exception_err(ctx, EXCP_CpU, 1);
16790 }
16791 break;
16792 case OPC_MULT:
16793 case OPC_MULTU:
16794 if (sa) {
16795 check_insn(ctx, INSN_VR54XX);
16796 op1 = MASK_MUL_VR54XX(ctx->opcode);
16797 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
16798 } else {
16799 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16800 }
16801 break;
16802 case OPC_DIV:
16803 case OPC_DIVU:
16804 gen_muldiv(ctx, op1, 0, rs, rt);
16805 break;
16806 #if defined(TARGET_MIPS64)
16807 case OPC_DMULT ... OPC_DDIVU:
16808 check_insn(ctx, ISA_MIPS3);
16809 check_mips_64(ctx);
16810 gen_muldiv(ctx, op1, 0, rs, rt);
16811 break;
16812 #endif
16813 case OPC_JR:
16814 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16815 break;
16816 case OPC_SPIM:
16817 #ifdef MIPS_STRICT_STANDARD
16818 MIPS_INVAL("SPIM");
16819 generate_exception_end(ctx, EXCP_RI);
16820 #else
16821 /* Implemented as RI exception for now. */
16822 MIPS_INVAL("spim (unofficial)");
16823 generate_exception_end(ctx, EXCP_RI);
16824 #endif
16825 break;
16826 default: /* Invalid */
16827 MIPS_INVAL("special_legacy");
16828 generate_exception_end(ctx, EXCP_RI);
16829 break;
16830 }
16831 }
16832
16833 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
16834 {
16835 int rs, rt, rd, sa;
16836 uint32_t op1;
16837
16838 rs = (ctx->opcode >> 21) & 0x1f;
16839 rt = (ctx->opcode >> 16) & 0x1f;
16840 rd = (ctx->opcode >> 11) & 0x1f;
16841 sa = (ctx->opcode >> 6) & 0x1f;
16842
16843 op1 = MASK_SPECIAL(ctx->opcode);
16844 switch (op1) {
16845 case OPC_SLL: /* Shift with immediate */
16846 if (sa == 5 && rd == 0 &&
16847 rs == 0 && rt == 0) { /* PAUSE */
16848 if ((ctx->insn_flags & ISA_MIPS32R6) &&
16849 (ctx->hflags & MIPS_HFLAG_BMASK)) {
16850 generate_exception_end(ctx, EXCP_RI);
16851 break;
16852 }
16853 }
16854 /* Fallthrough */
16855 case OPC_SRA:
16856 gen_shift_imm(ctx, op1, rd, rt, sa);
16857 break;
16858 case OPC_SRL:
16859 switch ((ctx->opcode >> 21) & 0x1f) {
16860 case 1:
16861 /* rotr is decoded as srl on non-R2 CPUs */
16862 if (ctx->insn_flags & ISA_MIPS32R2) {
16863 op1 = OPC_ROTR;
16864 }
16865 /* Fallthrough */
16866 case 0:
16867 gen_shift_imm(ctx, op1, rd, rt, sa);
16868 break;
16869 default:
16870 generate_exception_end(ctx, EXCP_RI);
16871 break;
16872 }
16873 break;
16874 case OPC_ADD ... OPC_SUBU:
16875 gen_arith(ctx, op1, rd, rs, rt);
16876 break;
16877 case OPC_SLLV: /* Shifts */
16878 case OPC_SRAV:
16879 gen_shift(ctx, op1, rd, rs, rt);
16880 break;
16881 case OPC_SRLV:
16882 switch ((ctx->opcode >> 6) & 0x1f) {
16883 case 1:
16884 /* rotrv is decoded as srlv on non-R2 CPUs */
16885 if (ctx->insn_flags & ISA_MIPS32R2) {
16886 op1 = OPC_ROTRV;
16887 }
16888 /* Fallthrough */
16889 case 0:
16890 gen_shift(ctx, op1, rd, rs, rt);
16891 break;
16892 default:
16893 generate_exception_end(ctx, EXCP_RI);
16894 break;
16895 }
16896 break;
16897 case OPC_SLT: /* Set on less than */
16898 case OPC_SLTU:
16899 gen_slt(ctx, op1, rd, rs, rt);
16900 break;
16901 case OPC_AND: /* Logic*/
16902 case OPC_OR:
16903 case OPC_NOR:
16904 case OPC_XOR:
16905 gen_logic(ctx, op1, rd, rs, rt);
16906 break;
16907 case OPC_JALR:
16908 gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
16909 break;
16910 case OPC_TGE ... OPC_TEQ: /* Traps */
16911 case OPC_TNE:
16912 check_insn(ctx, ISA_MIPS2);
16913 gen_trap(ctx, op1, rs, rt, -1);
16914 break;
16915 case OPC_LSA: /* OPC_PMON */
16916 if ((ctx->insn_flags & ISA_MIPS32R6) ||
16917 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
16918 decode_opc_special_r6(env, ctx);
16919 } else {
16920 /* Pmon entry point, also R4010 selsl */
16921 #ifdef MIPS_STRICT_STANDARD
16922 MIPS_INVAL("PMON / selsl");
16923 generate_exception_end(ctx, EXCP_RI);
16924 #else
16925 gen_helper_0e0i(pmon, sa);
16926 #endif
16927 }
16928 break;
16929 case OPC_SYSCALL:
16930 generate_exception_end(ctx, EXCP_SYSCALL);
16931 break;
16932 case OPC_BREAK:
16933 generate_exception_end(ctx, EXCP_BREAK);
16934 break;
16935 case OPC_SYNC:
16936 check_insn(ctx, ISA_MIPS2);
16937 /* Treat as NOP. */
16938 break;
16939
16940 #if defined(TARGET_MIPS64)
16941 /* MIPS64 specific opcodes */
16942 case OPC_DSLL:
16943 case OPC_DSRA:
16944 case OPC_DSLL32:
16945 case OPC_DSRA32:
16946 check_insn(ctx, ISA_MIPS3);
16947 check_mips_64(ctx);
16948 gen_shift_imm(ctx, op1, rd, rt, sa);
16949 break;
16950 case OPC_DSRL:
16951 switch ((ctx->opcode >> 21) & 0x1f) {
16952 case 1:
16953 /* drotr is decoded as dsrl on non-R2 CPUs */
16954 if (ctx->insn_flags & ISA_MIPS32R2) {
16955 op1 = OPC_DROTR;
16956 }
16957 /* Fallthrough */
16958 case 0:
16959 check_insn(ctx, ISA_MIPS3);
16960 check_mips_64(ctx);
16961 gen_shift_imm(ctx, op1, rd, rt, sa);
16962 break;
16963 default:
16964 generate_exception_end(ctx, EXCP_RI);
16965 break;
16966 }
16967 break;
16968 case OPC_DSRL32:
16969 switch ((ctx->opcode >> 21) & 0x1f) {
16970 case 1:
16971 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16972 if (ctx->insn_flags & ISA_MIPS32R2) {
16973 op1 = OPC_DROTR32;
16974 }
16975 /* Fallthrough */
16976 case 0:
16977 check_insn(ctx, ISA_MIPS3);
16978 check_mips_64(ctx);
16979 gen_shift_imm(ctx, op1, rd, rt, sa);
16980 break;
16981 default:
16982 generate_exception_end(ctx, EXCP_RI);
16983 break;
16984 }
16985 break;
16986 case OPC_DADD ... OPC_DSUBU:
16987 check_insn(ctx, ISA_MIPS3);
16988 check_mips_64(ctx);
16989 gen_arith(ctx, op1, rd, rs, rt);
16990 break;
16991 case OPC_DSLLV:
16992 case OPC_DSRAV:
16993 check_insn(ctx, ISA_MIPS3);
16994 check_mips_64(ctx);
16995 gen_shift(ctx, op1, rd, rs, rt);
16996 break;
16997 case OPC_DSRLV:
16998 switch ((ctx->opcode >> 6) & 0x1f) {
16999 case 1:
17000 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17001 if (ctx->insn_flags & ISA_MIPS32R2) {
17002 op1 = OPC_DROTRV;
17003 }
17004 /* Fallthrough */
17005 case 0:
17006 check_insn(ctx, ISA_MIPS3);
17007 check_mips_64(ctx);
17008 gen_shift(ctx, op1, rd, rs, rt);
17009 break;
17010 default:
17011 generate_exception_end(ctx, EXCP_RI);
17012 break;
17013 }
17014 break;
17015 case OPC_DLSA:
17016 if ((ctx->insn_flags & ISA_MIPS32R6) ||
17017 (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
17018 decode_opc_special_r6(env, ctx);
17019 }
17020 break;
17021 #endif
17022 default:
17023 if (ctx->insn_flags & ISA_MIPS32R6) {
17024 decode_opc_special_r6(env, ctx);
17025 } else {
17026 decode_opc_special_legacy(env, ctx);
17027 }
17028 }
17029 }
17030
17031 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
17032 {
17033 int rs, rt, rd;
17034 uint32_t op1;
17035
17036 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17037
17038 rs = (ctx->opcode >> 21) & 0x1f;
17039 rt = (ctx->opcode >> 16) & 0x1f;
17040 rd = (ctx->opcode >> 11) & 0x1f;
17041
17042 op1 = MASK_SPECIAL2(ctx->opcode);
17043 switch (op1) {
17044 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
17045 case OPC_MSUB ... OPC_MSUBU:
17046 check_insn(ctx, ISA_MIPS32);
17047 gen_muldiv(ctx, op1, rd & 3, rs, rt);
17048 break;
17049 case OPC_MUL:
17050 gen_arith(ctx, op1, rd, rs, rt);
17051 break;
17052 case OPC_DIV_G_2F:
17053 case OPC_DIVU_G_2F:
17054 case OPC_MULT_G_2F:
17055 case OPC_MULTU_G_2F:
17056 case OPC_MOD_G_2F:
17057 case OPC_MODU_G_2F:
17058 check_insn(ctx, INSN_LOONGSON2F);
17059 gen_loongson_integer(ctx, op1, rd, rs, rt);
17060 break;
17061 case OPC_CLO:
17062 case OPC_CLZ:
17063 check_insn(ctx, ISA_MIPS32);
17064 gen_cl(ctx, op1, rd, rs);
17065 break;
17066 case OPC_SDBBP:
17067 if (is_uhi(extract32(ctx->opcode, 6, 20))) {
17068 gen_helper_do_semihosting(cpu_env);
17069 } else {
17070 /* XXX: not clear which exception should be raised
17071 * when in debug mode...
17072 */
17073 check_insn(ctx, ISA_MIPS32);
17074 generate_exception_end(ctx, EXCP_DBp);
17075 }
17076 break;
17077 #if defined(TARGET_MIPS64)
17078 case OPC_DCLO:
17079 case OPC_DCLZ:
17080 check_insn(ctx, ISA_MIPS64);
17081 check_mips_64(ctx);
17082 gen_cl(ctx, op1, rd, rs);
17083 break;
17084 case OPC_DMULT_G_2F:
17085 case OPC_DMULTU_G_2F:
17086 case OPC_DDIV_G_2F:
17087 case OPC_DDIVU_G_2F:
17088 case OPC_DMOD_G_2F:
17089 case OPC_DMODU_G_2F:
17090 check_insn(ctx, INSN_LOONGSON2F);
17091 gen_loongson_integer(ctx, op1, rd, rs, rt);
17092 break;
17093 #endif
17094 default: /* Invalid */
17095 MIPS_INVAL("special2_legacy");
17096 generate_exception_end(ctx, EXCP_RI);
17097 break;
17098 }
17099 }
17100
17101 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
17102 {
17103 int rs, rt, rd, sa;
17104 uint32_t op1, op2;
17105 int16_t imm;
17106
17107 rs = (ctx->opcode >> 21) & 0x1f;
17108 rt = (ctx->opcode >> 16) & 0x1f;
17109 rd = (ctx->opcode >> 11) & 0x1f;
17110 sa = (ctx->opcode >> 6) & 0x1f;
17111 imm = (int16_t)ctx->opcode >> 7;
17112
17113 op1 = MASK_SPECIAL3(ctx->opcode);
17114 switch (op1) {
17115 case R6_OPC_PREF:
17116 if (rt >= 24) {
17117 /* hint codes 24-31 are reserved and signal RI */
17118 generate_exception_end(ctx, EXCP_RI);
17119 }
17120 /* Treat as NOP. */
17121 break;
17122 case R6_OPC_CACHE:
17123 /* Treat as NOP. */
17124 break;
17125 case R6_OPC_SC:
17126 gen_st_cond(ctx, op1, rt, rs, imm);
17127 break;
17128 case R6_OPC_LL:
17129 gen_ld(ctx, op1, rt, rs, imm);
17130 break;
17131 case OPC_BSHFL:
17132 {
17133 if (rd == 0) {
17134 /* Treat as NOP. */
17135 break;
17136 }
17137 op2 = MASK_BSHFL(ctx->opcode);
17138 switch (op2) {
17139 case OPC_ALIGN ... OPC_ALIGN_END:
17140 gen_align(ctx, OPC_ALIGN, rd, rs, rt, sa & 3);
17141 break;
17142 case OPC_BITSWAP:
17143 gen_bitswap(ctx, op2, rd, rt);
17144 break;
17145 }
17146 }
17147 break;
17148 #if defined(TARGET_MIPS64)
17149 case R6_OPC_SCD:
17150 gen_st_cond(ctx, op1, rt, rs, imm);
17151 break;
17152 case R6_OPC_LLD:
17153 gen_ld(ctx, op1, rt, rs, imm);
17154 break;
17155 case OPC_DBSHFL:
17156 check_mips_64(ctx);
17157 {
17158 if (rd == 0) {
17159 /* Treat as NOP. */
17160 break;
17161 }
17162 op2 = MASK_DBSHFL(ctx->opcode);
17163 switch (op2) {
17164 case OPC_DALIGN ... OPC_DALIGN_END:
17165 gen_align(ctx, OPC_DALIGN, rd, rs, rt, sa & 7);
17166 break;
17167 case OPC_DBITSWAP:
17168 gen_bitswap(ctx, op2, rd, rt);
17169 break;
17170 }
17171
17172 }
17173 break;
17174 #endif
17175 default: /* Invalid */
17176 MIPS_INVAL("special3_r6");
17177 generate_exception_end(ctx, EXCP_RI);
17178 break;
17179 }
17180 }
17181
17182 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
17183 {
17184 int rs, rt, rd;
17185 uint32_t op1, op2;
17186
17187 rs = (ctx->opcode >> 21) & 0x1f;
17188 rt = (ctx->opcode >> 16) & 0x1f;
17189 rd = (ctx->opcode >> 11) & 0x1f;
17190
17191 op1 = MASK_SPECIAL3(ctx->opcode);
17192 switch (op1) {
17193 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
17194 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
17195 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
17196 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17197 * the same mask and op1. */
17198 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
17199 op2 = MASK_ADDUH_QB(ctx->opcode);
17200 switch (op2) {
17201 case OPC_ADDUH_QB:
17202 case OPC_ADDUH_R_QB:
17203 case OPC_ADDQH_PH:
17204 case OPC_ADDQH_R_PH:
17205 case OPC_ADDQH_W:
17206 case OPC_ADDQH_R_W:
17207 case OPC_SUBUH_QB:
17208 case OPC_SUBUH_R_QB:
17209 case OPC_SUBQH_PH:
17210 case OPC_SUBQH_R_PH:
17211 case OPC_SUBQH_W:
17212 case OPC_SUBQH_R_W:
17213 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17214 break;
17215 case OPC_MUL_PH:
17216 case OPC_MUL_S_PH:
17217 case OPC_MULQ_S_W:
17218 case OPC_MULQ_RS_W:
17219 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17220 break;
17221 default:
17222 MIPS_INVAL("MASK ADDUH.QB");
17223 generate_exception_end(ctx, EXCP_RI);
17224 break;
17225 }
17226 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
17227 gen_loongson_integer(ctx, op1, rd, rs, rt);
17228 } else {
17229 generate_exception_end(ctx, EXCP_RI);
17230 }
17231 break;
17232 case OPC_LX_DSP:
17233 op2 = MASK_LX(ctx->opcode);
17234 switch (op2) {
17235 #if defined(TARGET_MIPS64)
17236 case OPC_LDX:
17237 #endif
17238 case OPC_LBUX:
17239 case OPC_LHX:
17240 case OPC_LWX:
17241 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
17242 break;
17243 default: /* Invalid */
17244 MIPS_INVAL("MASK LX");
17245 generate_exception_end(ctx, EXCP_RI);
17246 break;
17247 }
17248 break;
17249 case OPC_ABSQ_S_PH_DSP:
17250 op2 = MASK_ABSQ_S_PH(ctx->opcode);
17251 switch (op2) {
17252 case OPC_ABSQ_S_QB:
17253 case OPC_ABSQ_S_PH:
17254 case OPC_ABSQ_S_W:
17255 case OPC_PRECEQ_W_PHL:
17256 case OPC_PRECEQ_W_PHR:
17257 case OPC_PRECEQU_PH_QBL:
17258 case OPC_PRECEQU_PH_QBR:
17259 case OPC_PRECEQU_PH_QBLA:
17260 case OPC_PRECEQU_PH_QBRA:
17261 case OPC_PRECEU_PH_QBL:
17262 case OPC_PRECEU_PH_QBR:
17263 case OPC_PRECEU_PH_QBLA:
17264 case OPC_PRECEU_PH_QBRA:
17265 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17266 break;
17267 case OPC_BITREV:
17268 case OPC_REPL_QB:
17269 case OPC_REPLV_QB:
17270 case OPC_REPL_PH:
17271 case OPC_REPLV_PH:
17272 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17273 break;
17274 default:
17275 MIPS_INVAL("MASK ABSQ_S.PH");
17276 generate_exception_end(ctx, EXCP_RI);
17277 break;
17278 }
17279 break;
17280 case OPC_ADDU_QB_DSP:
17281 op2 = MASK_ADDU_QB(ctx->opcode);
17282 switch (op2) {
17283 case OPC_ADDQ_PH:
17284 case OPC_ADDQ_S_PH:
17285 case OPC_ADDQ_S_W:
17286 case OPC_ADDU_QB:
17287 case OPC_ADDU_S_QB:
17288 case OPC_ADDU_PH:
17289 case OPC_ADDU_S_PH:
17290 case OPC_SUBQ_PH:
17291 case OPC_SUBQ_S_PH:
17292 case OPC_SUBQ_S_W:
17293 case OPC_SUBU_QB:
17294 case OPC_SUBU_S_QB:
17295 case OPC_SUBU_PH:
17296 case OPC_SUBU_S_PH:
17297 case OPC_ADDSC:
17298 case OPC_ADDWC:
17299 case OPC_MODSUB:
17300 case OPC_RADDU_W_QB:
17301 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17302 break;
17303 case OPC_MULEU_S_PH_QBL:
17304 case OPC_MULEU_S_PH_QBR:
17305 case OPC_MULQ_RS_PH:
17306 case OPC_MULEQ_S_W_PHL:
17307 case OPC_MULEQ_S_W_PHR:
17308 case OPC_MULQ_S_PH:
17309 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17310 break;
17311 default: /* Invalid */
17312 MIPS_INVAL("MASK ADDU.QB");
17313 generate_exception_end(ctx, EXCP_RI);
17314 break;
17315
17316 }
17317 break;
17318 case OPC_CMPU_EQ_QB_DSP:
17319 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
17320 switch (op2) {
17321 case OPC_PRECR_SRA_PH_W:
17322 case OPC_PRECR_SRA_R_PH_W:
17323 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17324 break;
17325 case OPC_PRECR_QB_PH:
17326 case OPC_PRECRQ_QB_PH:
17327 case OPC_PRECRQ_PH_W:
17328 case OPC_PRECRQ_RS_PH_W:
17329 case OPC_PRECRQU_S_QB_PH:
17330 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17331 break;
17332 case OPC_CMPU_EQ_QB:
17333 case OPC_CMPU_LT_QB:
17334 case OPC_CMPU_LE_QB:
17335 case OPC_CMP_EQ_PH:
17336 case OPC_CMP_LT_PH:
17337 case OPC_CMP_LE_PH:
17338 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17339 break;
17340 case OPC_CMPGU_EQ_QB:
17341 case OPC_CMPGU_LT_QB:
17342 case OPC_CMPGU_LE_QB:
17343 case OPC_CMPGDU_EQ_QB:
17344 case OPC_CMPGDU_LT_QB:
17345 case OPC_CMPGDU_LE_QB:
17346 case OPC_PICK_QB:
17347 case OPC_PICK_PH:
17348 case OPC_PACKRL_PH:
17349 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17350 break;
17351 default: /* Invalid */
17352 MIPS_INVAL("MASK CMPU.EQ.QB");
17353 generate_exception_end(ctx, EXCP_RI);
17354 break;
17355 }
17356 break;
17357 case OPC_SHLL_QB_DSP:
17358 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17359 break;
17360 case OPC_DPA_W_PH_DSP:
17361 op2 = MASK_DPA_W_PH(ctx->opcode);
17362 switch (op2) {
17363 case OPC_DPAU_H_QBL:
17364 case OPC_DPAU_H_QBR:
17365 case OPC_DPSU_H_QBL:
17366 case OPC_DPSU_H_QBR:
17367 case OPC_DPA_W_PH:
17368 case OPC_DPAX_W_PH:
17369 case OPC_DPAQ_S_W_PH:
17370 case OPC_DPAQX_S_W_PH:
17371 case OPC_DPAQX_SA_W_PH:
17372 case OPC_DPS_W_PH:
17373 case OPC_DPSX_W_PH:
17374 case OPC_DPSQ_S_W_PH:
17375 case OPC_DPSQX_S_W_PH:
17376 case OPC_DPSQX_SA_W_PH:
17377 case OPC_MULSAQ_S_W_PH:
17378 case OPC_DPAQ_SA_L_W:
17379 case OPC_DPSQ_SA_L_W:
17380 case OPC_MAQ_S_W_PHL:
17381 case OPC_MAQ_S_W_PHR:
17382 case OPC_MAQ_SA_W_PHL:
17383 case OPC_MAQ_SA_W_PHR:
17384 case OPC_MULSA_W_PH:
17385 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17386 break;
17387 default: /* Invalid */
17388 MIPS_INVAL("MASK DPAW.PH");
17389 generate_exception_end(ctx, EXCP_RI);
17390 break;
17391 }
17392 break;
17393 case OPC_INSV_DSP:
17394 op2 = MASK_INSV(ctx->opcode);
17395 switch (op2) {
17396 case OPC_INSV:
17397 check_dsp(ctx);
17398 {
17399 TCGv t0, t1;
17400
17401 if (rt == 0) {
17402 break;
17403 }
17404
17405 t0 = tcg_temp_new();
17406 t1 = tcg_temp_new();
17407
17408 gen_load_gpr(t0, rt);
17409 gen_load_gpr(t1, rs);
17410
17411 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
17412
17413 tcg_temp_free(t0);
17414 tcg_temp_free(t1);
17415 break;
17416 }
17417 default: /* Invalid */
17418 MIPS_INVAL("MASK INSV");
17419 generate_exception_end(ctx, EXCP_RI);
17420 break;
17421 }
17422 break;
17423 case OPC_APPEND_DSP:
17424 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17425 break;
17426 case OPC_EXTR_W_DSP:
17427 op2 = MASK_EXTR_W(ctx->opcode);
17428 switch (op2) {
17429 case OPC_EXTR_W:
17430 case OPC_EXTR_R_W:
17431 case OPC_EXTR_RS_W:
17432 case OPC_EXTR_S_H:
17433 case OPC_EXTRV_S_H:
17434 case OPC_EXTRV_W:
17435 case OPC_EXTRV_R_W:
17436 case OPC_EXTRV_RS_W:
17437 case OPC_EXTP:
17438 case OPC_EXTPV:
17439 case OPC_EXTPDP:
17440 case OPC_EXTPDPV:
17441 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17442 break;
17443 case OPC_RDDSP:
17444 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
17445 break;
17446 case OPC_SHILO:
17447 case OPC_SHILOV:
17448 case OPC_MTHLIP:
17449 case OPC_WRDSP:
17450 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17451 break;
17452 default: /* Invalid */
17453 MIPS_INVAL("MASK EXTR.W");
17454 generate_exception_end(ctx, EXCP_RI);
17455 break;
17456 }
17457 break;
17458 #if defined(TARGET_MIPS64)
17459 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
17460 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
17461 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
17462 check_insn(ctx, INSN_LOONGSON2E);
17463 gen_loongson_integer(ctx, op1, rd, rs, rt);
17464 break;
17465 case OPC_ABSQ_S_QH_DSP:
17466 op2 = MASK_ABSQ_S_QH(ctx->opcode);
17467 switch (op2) {
17468 case OPC_PRECEQ_L_PWL:
17469 case OPC_PRECEQ_L_PWR:
17470 case OPC_PRECEQ_PW_QHL:
17471 case OPC_PRECEQ_PW_QHR:
17472 case OPC_PRECEQ_PW_QHLA:
17473 case OPC_PRECEQ_PW_QHRA:
17474 case OPC_PRECEQU_QH_OBL:
17475 case OPC_PRECEQU_QH_OBR:
17476 case OPC_PRECEQU_QH_OBLA:
17477 case OPC_PRECEQU_QH_OBRA:
17478 case OPC_PRECEU_QH_OBL:
17479 case OPC_PRECEU_QH_OBR:
17480 case OPC_PRECEU_QH_OBLA:
17481 case OPC_PRECEU_QH_OBRA:
17482 case OPC_ABSQ_S_OB:
17483 case OPC_ABSQ_S_PW:
17484 case OPC_ABSQ_S_QH:
17485 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17486 break;
17487 case OPC_REPL_OB:
17488 case OPC_REPL_PW:
17489 case OPC_REPL_QH:
17490 case OPC_REPLV_OB:
17491 case OPC_REPLV_PW:
17492 case OPC_REPLV_QH:
17493 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
17494 break;
17495 default: /* Invalid */
17496 MIPS_INVAL("MASK ABSQ_S.QH");
17497 generate_exception_end(ctx, EXCP_RI);
17498 break;
17499 }
17500 break;
17501 case OPC_ADDU_OB_DSP:
17502 op2 = MASK_ADDU_OB(ctx->opcode);
17503 switch (op2) {
17504 case OPC_RADDU_L_OB:
17505 case OPC_SUBQ_PW:
17506 case OPC_SUBQ_S_PW:
17507 case OPC_SUBQ_QH:
17508 case OPC_SUBQ_S_QH:
17509 case OPC_SUBU_OB:
17510 case OPC_SUBU_S_OB:
17511 case OPC_SUBU_QH:
17512 case OPC_SUBU_S_QH:
17513 case OPC_SUBUH_OB:
17514 case OPC_SUBUH_R_OB:
17515 case OPC_ADDQ_PW:
17516 case OPC_ADDQ_S_PW:
17517 case OPC_ADDQ_QH:
17518 case OPC_ADDQ_S_QH:
17519 case OPC_ADDU_OB:
17520 case OPC_ADDU_S_OB:
17521 case OPC_ADDU_QH:
17522 case OPC_ADDU_S_QH:
17523 case OPC_ADDUH_OB:
17524 case OPC_ADDUH_R_OB:
17525 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17526 break;
17527 case OPC_MULEQ_S_PW_QHL:
17528 case OPC_MULEQ_S_PW_QHR:
17529 case OPC_MULEU_S_QH_OBL:
17530 case OPC_MULEU_S_QH_OBR:
17531 case OPC_MULQ_RS_QH:
17532 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
17533 break;
17534 default: /* Invalid */
17535 MIPS_INVAL("MASK ADDU.OB");
17536 generate_exception_end(ctx, EXCP_RI);
17537 break;
17538 }
17539 break;
17540 case OPC_CMPU_EQ_OB_DSP:
17541 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
17542 switch (op2) {
17543 case OPC_PRECR_SRA_QH_PW:
17544 case OPC_PRECR_SRA_R_QH_PW:
17545 /* Return value is rt. */
17546 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
17547 break;
17548 case OPC_PRECR_OB_QH:
17549 case OPC_PRECRQ_OB_QH:
17550 case OPC_PRECRQ_PW_L:
17551 case OPC_PRECRQ_QH_PW:
17552 case OPC_PRECRQ_RS_QH_PW:
17553 case OPC_PRECRQU_S_OB_QH:
17554 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
17555 break;
17556 case OPC_CMPU_EQ_OB:
17557 case OPC_CMPU_LT_OB:
17558 case OPC_CMPU_LE_OB:
17559 case OPC_CMP_EQ_QH:
17560 case OPC_CMP_LT_QH:
17561 case OPC_CMP_LE_QH:
17562 case OPC_CMP_EQ_PW:
17563 case OPC_CMP_LT_PW:
17564 case OPC_CMP_LE_PW:
17565 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
17566 break;
17567 case OPC_CMPGDU_EQ_OB:
17568 case OPC_CMPGDU_LT_OB:
17569 case OPC_CMPGDU_LE_OB:
17570 case OPC_CMPGU_EQ_OB:
17571 case OPC_CMPGU_LT_OB:
17572 case OPC_CMPGU_LE_OB:
17573 case OPC_PACKRL_PW:
17574 case OPC_PICK_OB:
17575 case OPC_PICK_PW:
17576 case OPC_PICK_QH:
17577 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
17578 break;
17579 default: /* Invalid */
17580 MIPS_INVAL("MASK CMPU_EQ.OB");
17581 generate_exception_end(ctx, EXCP_RI);
17582 break;
17583 }
17584 break;
17585 case OPC_DAPPEND_DSP:
17586 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
17587 break;
17588 case OPC_DEXTR_W_DSP:
17589 op2 = MASK_DEXTR_W(ctx->opcode);
17590 switch (op2) {
17591 case OPC_DEXTP:
17592 case OPC_DEXTPDP:
17593 case OPC_DEXTPDPV:
17594 case OPC_DEXTPV:
17595 case OPC_DEXTR_L:
17596 case OPC_DEXTR_R_L:
17597 case OPC_DEXTR_RS_L:
17598 case OPC_DEXTR_W:
17599 case OPC_DEXTR_R_W:
17600 case OPC_DEXTR_RS_W:
17601 case OPC_DEXTR_S_H:
17602 case OPC_DEXTRV_L:
17603 case OPC_DEXTRV_R_L:
17604 case OPC_DEXTRV_RS_L:
17605 case OPC_DEXTRV_S_H:
17606 case OPC_DEXTRV_W:
17607 case OPC_DEXTRV_R_W:
17608 case OPC_DEXTRV_RS_W:
17609 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
17610 break;
17611 case OPC_DMTHLIP:
17612 case OPC_DSHILO:
17613 case OPC_DSHILOV:
17614 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
17615 break;
17616 default: /* Invalid */
17617 MIPS_INVAL("MASK EXTR.W");
17618 generate_exception_end(ctx, EXCP_RI);
17619 break;
17620 }
17621 break;
17622 case OPC_DPAQ_W_QH_DSP:
17623 op2 = MASK_DPAQ_W_QH(ctx->opcode);
17624 switch (op2) {
17625 case OPC_DPAU_H_OBL:
17626 case OPC_DPAU_H_OBR:
17627 case OPC_DPSU_H_OBL:
17628 case OPC_DPSU_H_OBR:
17629 case OPC_DPA_W_QH:
17630 case OPC_DPAQ_S_W_QH:
17631 case OPC_DPS_W_QH:
17632 case OPC_DPSQ_S_W_QH:
17633 case OPC_MULSAQ_S_W_QH:
17634 case OPC_DPAQ_SA_L_PW:
17635 case OPC_DPSQ_SA_L_PW:
17636 case OPC_MULSAQ_S_L_PW:
17637 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17638 break;
17639 case OPC_MAQ_S_W_QHLL:
17640 case OPC_MAQ_S_W_QHLR:
17641 case OPC_MAQ_S_W_QHRL:
17642 case OPC_MAQ_S_W_QHRR:
17643 case OPC_MAQ_SA_W_QHLL:
17644 case OPC_MAQ_SA_W_QHLR:
17645 case OPC_MAQ_SA_W_QHRL:
17646 case OPC_MAQ_SA_W_QHRR:
17647 case OPC_MAQ_S_L_PWL:
17648 case OPC_MAQ_S_L_PWR:
17649 case OPC_DMADD:
17650 case OPC_DMADDU:
17651 case OPC_DMSUB:
17652 case OPC_DMSUBU:
17653 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
17654 break;
17655 default: /* Invalid */
17656 MIPS_INVAL("MASK DPAQ.W.QH");
17657 generate_exception_end(ctx, EXCP_RI);
17658 break;
17659 }
17660 break;
17661 case OPC_DINSV_DSP:
17662 op2 = MASK_INSV(ctx->opcode);
17663 switch (op2) {
17664 case OPC_DINSV:
17665 {
17666 TCGv t0, t1;
17667
17668 if (rt == 0) {
17669 break;
17670 }
17671 check_dsp(ctx);
17672
17673 t0 = tcg_temp_new();
17674 t1 = tcg_temp_new();
17675
17676 gen_load_gpr(t0, rt);
17677 gen_load_gpr(t1, rs);
17678
17679 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
17680
17681 tcg_temp_free(t0);
17682 tcg_temp_free(t1);
17683 break;
17684 }
17685 default: /* Invalid */
17686 MIPS_INVAL("MASK DINSV");
17687 generate_exception_end(ctx, EXCP_RI);
17688 break;
17689 }
17690 break;
17691 case OPC_SHLL_OB_DSP:
17692 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
17693 break;
17694 #endif
17695 default: /* Invalid */
17696 MIPS_INVAL("special3_legacy");
17697 generate_exception_end(ctx, EXCP_RI);
17698 break;
17699 }
17700 }
17701
17702 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
17703 {
17704 int rs, rt, rd, sa;
17705 uint32_t op1, op2;
17706
17707 rs = (ctx->opcode >> 21) & 0x1f;
17708 rt = (ctx->opcode >> 16) & 0x1f;
17709 rd = (ctx->opcode >> 11) & 0x1f;
17710 sa = (ctx->opcode >> 6) & 0x1f;
17711
17712 op1 = MASK_SPECIAL3(ctx->opcode);
17713 switch (op1) {
17714 case OPC_EXT:
17715 case OPC_INS:
17716 check_insn(ctx, ISA_MIPS32R2);
17717 gen_bitops(ctx, op1, rt, rs, sa, rd);
17718 break;
17719 case OPC_BSHFL:
17720 op2 = MASK_BSHFL(ctx->opcode);
17721 switch (op2) {
17722 case OPC_ALIGN ... OPC_ALIGN_END:
17723 case OPC_BITSWAP:
17724 check_insn(ctx, ISA_MIPS32R6);
17725 decode_opc_special3_r6(env, ctx);
17726 break;
17727 default:
17728 check_insn(ctx, ISA_MIPS32R2);
17729 gen_bshfl(ctx, op2, rt, rd);
17730 break;
17731 }
17732 break;
17733 #if defined(TARGET_MIPS64)
17734 case OPC_DEXTM ... OPC_DEXT:
17735 case OPC_DINSM ... OPC_DINS:
17736 check_insn(ctx, ISA_MIPS64R2);
17737 check_mips_64(ctx);
17738 gen_bitops(ctx, op1, rt, rs, sa, rd);
17739 break;
17740 case OPC_DBSHFL:
17741 op2 = MASK_DBSHFL(ctx->opcode);
17742 switch (op2) {
17743 case OPC_DALIGN ... OPC_DALIGN_END:
17744 case OPC_DBITSWAP:
17745 check_insn(ctx, ISA_MIPS32R6);
17746 decode_opc_special3_r6(env, ctx);
17747 break;
17748 default:
17749 check_insn(ctx, ISA_MIPS64R2);
17750 check_mips_64(ctx);
17751 op2 = MASK_DBSHFL(ctx->opcode);
17752 gen_bshfl(ctx, op2, rt, rd);
17753 break;
17754 }
17755 break;
17756 #endif
17757 case OPC_RDHWR:
17758 gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
17759 break;
17760 case OPC_FORK:
17761 check_insn(ctx, ASE_MT);
17762 {
17763 TCGv t0 = tcg_temp_new();
17764 TCGv t1 = tcg_temp_new();
17765
17766 gen_load_gpr(t0, rt);
17767 gen_load_gpr(t1, rs);
17768 gen_helper_fork(t0, t1);
17769 tcg_temp_free(t0);
17770 tcg_temp_free(t1);
17771 }
17772 break;
17773 case OPC_YIELD:
17774 check_insn(ctx, ASE_MT);
17775 {
17776 TCGv t0 = tcg_temp_new();
17777
17778 gen_load_gpr(t0, rs);
17779 gen_helper_yield(t0, cpu_env, t0);
17780 gen_store_gpr(t0, rd);
17781 tcg_temp_free(t0);
17782 }
17783 break;
17784 default:
17785 if (ctx->insn_flags & ISA_MIPS32R6) {
17786 decode_opc_special3_r6(env, ctx);
17787 } else {
17788 decode_opc_special3_legacy(env, ctx);
17789 }
17790 }
17791 }
17792
17793 /* MIPS SIMD Architecture (MSA) */
17794 static inline int check_msa_access(DisasContext *ctx)
17795 {
17796 if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
17797 !(ctx->hflags & MIPS_HFLAG_F64))) {
17798 generate_exception_end(ctx, EXCP_RI);
17799 return 0;
17800 }
17801
17802 if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
17803 if (ctx->insn_flags & ASE_MSA) {
17804 generate_exception_end(ctx, EXCP_MSADIS);
17805 return 0;
17806 } else {
17807 generate_exception_end(ctx, EXCP_RI);
17808 return 0;
17809 }
17810 }
17811 return 1;
17812 }
17813
17814 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
17815 {
17816 /* generates tcg ops to check if any element is 0 */
17817 /* Note this function only works with MSA_WRLEN = 128 */
17818 uint64_t eval_zero_or_big = 0;
17819 uint64_t eval_big = 0;
17820 TCGv_i64 t0 = tcg_temp_new_i64();
17821 TCGv_i64 t1 = tcg_temp_new_i64();
17822 switch (df) {
17823 case DF_BYTE:
17824 eval_zero_or_big = 0x0101010101010101ULL;
17825 eval_big = 0x8080808080808080ULL;
17826 break;
17827 case DF_HALF:
17828 eval_zero_or_big = 0x0001000100010001ULL;
17829 eval_big = 0x8000800080008000ULL;
17830 break;
17831 case DF_WORD:
17832 eval_zero_or_big = 0x0000000100000001ULL;
17833 eval_big = 0x8000000080000000ULL;
17834 break;
17835 case DF_DOUBLE:
17836 eval_zero_or_big = 0x0000000000000001ULL;
17837 eval_big = 0x8000000000000000ULL;
17838 break;
17839 }
17840 tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
17841 tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
17842 tcg_gen_andi_i64(t0, t0, eval_big);
17843 tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
17844 tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
17845 tcg_gen_andi_i64(t1, t1, eval_big);
17846 tcg_gen_or_i64(t0, t0, t1);
17847 /* if all bits are zero then all elements are not zero */
17848 /* if some bit is non-zero then some element is zero */
17849 tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
17850 tcg_gen_trunc_i64_tl(tresult, t0);
17851 tcg_temp_free_i64(t0);
17852 tcg_temp_free_i64(t1);
17853 }
17854
17855 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
17856 {
17857 uint8_t df = (ctx->opcode >> 21) & 0x3;
17858 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
17859 int64_t s16 = (int16_t)ctx->opcode;
17860
17861 check_msa_access(ctx);
17862
17863 if (ctx->insn_flags & ISA_MIPS32R6 && ctx->hflags & MIPS_HFLAG_BMASK) {
17864 generate_exception_end(ctx, EXCP_RI);
17865 return;
17866 }
17867 switch (op1) {
17868 case OPC_BZ_V:
17869 case OPC_BNZ_V:
17870 {
17871 TCGv_i64 t0 = tcg_temp_new_i64();
17872 tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
17873 tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
17874 TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
17875 tcg_gen_trunc_i64_tl(bcond, t0);
17876 tcg_temp_free_i64(t0);
17877 }
17878 break;
17879 case OPC_BZ_B:
17880 case OPC_BZ_H:
17881 case OPC_BZ_W:
17882 case OPC_BZ_D:
17883 gen_check_zero_element(bcond, df, wt);
17884 break;
17885 case OPC_BNZ_B:
17886 case OPC_BNZ_H:
17887 case OPC_BNZ_W:
17888 case OPC_BNZ_D:
17889 gen_check_zero_element(bcond, df, wt);
17890 tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
17891 break;
17892 }
17893
17894 ctx->btarget = ctx->pc + (s16 << 2) + 4;
17895
17896 ctx->hflags |= MIPS_HFLAG_BC;
17897 ctx->hflags |= MIPS_HFLAG_BDS32;
17898 }
17899
17900 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
17901 {
17902 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17903 uint8_t i8 = (ctx->opcode >> 16) & 0xff;
17904 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17905 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17906
17907 TCGv_i32 twd = tcg_const_i32(wd);
17908 TCGv_i32 tws = tcg_const_i32(ws);
17909 TCGv_i32 ti8 = tcg_const_i32(i8);
17910
17911 switch (MASK_MSA_I8(ctx->opcode)) {
17912 case OPC_ANDI_B:
17913 gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
17914 break;
17915 case OPC_ORI_B:
17916 gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
17917 break;
17918 case OPC_NORI_B:
17919 gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
17920 break;
17921 case OPC_XORI_B:
17922 gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
17923 break;
17924 case OPC_BMNZI_B:
17925 gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
17926 break;
17927 case OPC_BMZI_B:
17928 gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
17929 break;
17930 case OPC_BSELI_B:
17931 gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
17932 break;
17933 case OPC_SHF_B:
17934 case OPC_SHF_H:
17935 case OPC_SHF_W:
17936 {
17937 uint8_t df = (ctx->opcode >> 24) & 0x3;
17938 if (df == DF_DOUBLE) {
17939 generate_exception_end(ctx, EXCP_RI);
17940 } else {
17941 TCGv_i32 tdf = tcg_const_i32(df);
17942 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
17943 tcg_temp_free_i32(tdf);
17944 }
17945 }
17946 break;
17947 default:
17948 MIPS_INVAL("MSA instruction");
17949 generate_exception_end(ctx, EXCP_RI);
17950 break;
17951 }
17952
17953 tcg_temp_free_i32(twd);
17954 tcg_temp_free_i32(tws);
17955 tcg_temp_free_i32(ti8);
17956 }
17957
17958 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
17959 {
17960 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17961 uint8_t df = (ctx->opcode >> 21) & 0x3;
17962 int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
17963 uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
17964 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
17965 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
17966
17967 TCGv_i32 tdf = tcg_const_i32(df);
17968 TCGv_i32 twd = tcg_const_i32(wd);
17969 TCGv_i32 tws = tcg_const_i32(ws);
17970 TCGv_i32 timm = tcg_temp_new_i32();
17971 tcg_gen_movi_i32(timm, u5);
17972
17973 switch (MASK_MSA_I5(ctx->opcode)) {
17974 case OPC_ADDVI_df:
17975 gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
17976 break;
17977 case OPC_SUBVI_df:
17978 gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
17979 break;
17980 case OPC_MAXI_S_df:
17981 tcg_gen_movi_i32(timm, s5);
17982 gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
17983 break;
17984 case OPC_MAXI_U_df:
17985 gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
17986 break;
17987 case OPC_MINI_S_df:
17988 tcg_gen_movi_i32(timm, s5);
17989 gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
17990 break;
17991 case OPC_MINI_U_df:
17992 gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
17993 break;
17994 case OPC_CEQI_df:
17995 tcg_gen_movi_i32(timm, s5);
17996 gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
17997 break;
17998 case OPC_CLTI_S_df:
17999 tcg_gen_movi_i32(timm, s5);
18000 gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
18001 break;
18002 case OPC_CLTI_U_df:
18003 gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
18004 break;
18005 case OPC_CLEI_S_df:
18006 tcg_gen_movi_i32(timm, s5);
18007 gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
18008 break;
18009 case OPC_CLEI_U_df:
18010 gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
18011 break;
18012 case OPC_LDI_df:
18013 {
18014 int32_t s10 = sextract32(ctx->opcode, 11, 10);
18015 tcg_gen_movi_i32(timm, s10);
18016 gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
18017 }
18018 break;
18019 default:
18020 MIPS_INVAL("MSA instruction");
18021 generate_exception_end(ctx, EXCP_RI);
18022 break;
18023 }
18024
18025 tcg_temp_free_i32(tdf);
18026 tcg_temp_free_i32(twd);
18027 tcg_temp_free_i32(tws);
18028 tcg_temp_free_i32(timm);
18029 }
18030
18031 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
18032 {
18033 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18034 uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
18035 uint32_t df = 0, m = 0;
18036 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18037 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18038
18039 TCGv_i32 tdf;
18040 TCGv_i32 tm;
18041 TCGv_i32 twd;
18042 TCGv_i32 tws;
18043
18044 if ((dfm & 0x40) == 0x00) {
18045 m = dfm & 0x3f;
18046 df = DF_DOUBLE;
18047 } else if ((dfm & 0x60) == 0x40) {
18048 m = dfm & 0x1f;
18049 df = DF_WORD;
18050 } else if ((dfm & 0x70) == 0x60) {
18051 m = dfm & 0x0f;
18052 df = DF_HALF;
18053 } else if ((dfm & 0x78) == 0x70) {
18054 m = dfm & 0x7;
18055 df = DF_BYTE;
18056 } else {
18057 generate_exception_end(ctx, EXCP_RI);
18058 return;
18059 }
18060
18061 tdf = tcg_const_i32(df);
18062 tm = tcg_const_i32(m);
18063 twd = tcg_const_i32(wd);
18064 tws = tcg_const_i32(ws);
18065
18066 switch (MASK_MSA_BIT(ctx->opcode)) {
18067 case OPC_SLLI_df:
18068 gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
18069 break;
18070 case OPC_SRAI_df:
18071 gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
18072 break;
18073 case OPC_SRLI_df:
18074 gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
18075 break;
18076 case OPC_BCLRI_df:
18077 gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
18078 break;
18079 case OPC_BSETI_df:
18080 gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
18081 break;
18082 case OPC_BNEGI_df:
18083 gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
18084 break;
18085 case OPC_BINSLI_df:
18086 gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
18087 break;
18088 case OPC_BINSRI_df:
18089 gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
18090 break;
18091 case OPC_SAT_S_df:
18092 gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
18093 break;
18094 case OPC_SAT_U_df:
18095 gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
18096 break;
18097 case OPC_SRARI_df:
18098 gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
18099 break;
18100 case OPC_SRLRI_df:
18101 gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
18102 break;
18103 default:
18104 MIPS_INVAL("MSA instruction");
18105 generate_exception_end(ctx, EXCP_RI);
18106 break;
18107 }
18108
18109 tcg_temp_free_i32(tdf);
18110 tcg_temp_free_i32(tm);
18111 tcg_temp_free_i32(twd);
18112 tcg_temp_free_i32(tws);
18113 }
18114
18115 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
18116 {
18117 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18118 uint8_t df = (ctx->opcode >> 21) & 0x3;
18119 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18120 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18121 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18122
18123 TCGv_i32 tdf = tcg_const_i32(df);
18124 TCGv_i32 twd = tcg_const_i32(wd);
18125 TCGv_i32 tws = tcg_const_i32(ws);
18126 TCGv_i32 twt = tcg_const_i32(wt);
18127
18128 switch (MASK_MSA_3R(ctx->opcode)) {
18129 case OPC_SLL_df:
18130 gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
18131 break;
18132 case OPC_ADDV_df:
18133 gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
18134 break;
18135 case OPC_CEQ_df:
18136 gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
18137 break;
18138 case OPC_ADD_A_df:
18139 gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
18140 break;
18141 case OPC_SUBS_S_df:
18142 gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
18143 break;
18144 case OPC_MULV_df:
18145 gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
18146 break;
18147 case OPC_SLD_df:
18148 gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
18149 break;
18150 case OPC_VSHF_df:
18151 gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
18152 break;
18153 case OPC_SRA_df:
18154 gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
18155 break;
18156 case OPC_SUBV_df:
18157 gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
18158 break;
18159 case OPC_ADDS_A_df:
18160 gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
18161 break;
18162 case OPC_SUBS_U_df:
18163 gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
18164 break;
18165 case OPC_MADDV_df:
18166 gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
18167 break;
18168 case OPC_SPLAT_df:
18169 gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
18170 break;
18171 case OPC_SRAR_df:
18172 gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
18173 break;
18174 case OPC_SRL_df:
18175 gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
18176 break;
18177 case OPC_MAX_S_df:
18178 gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
18179 break;
18180 case OPC_CLT_S_df:
18181 gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
18182 break;
18183 case OPC_ADDS_S_df:
18184 gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
18185 break;
18186 case OPC_SUBSUS_U_df:
18187 gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
18188 break;
18189 case OPC_MSUBV_df:
18190 gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
18191 break;
18192 case OPC_PCKEV_df:
18193 gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
18194 break;
18195 case OPC_SRLR_df:
18196 gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
18197 break;
18198 case OPC_BCLR_df:
18199 gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
18200 break;
18201 case OPC_MAX_U_df:
18202 gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
18203 break;
18204 case OPC_CLT_U_df:
18205 gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
18206 break;
18207 case OPC_ADDS_U_df:
18208 gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
18209 break;
18210 case OPC_SUBSUU_S_df:
18211 gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
18212 break;
18213 case OPC_PCKOD_df:
18214 gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
18215 break;
18216 case OPC_BSET_df:
18217 gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
18218 break;
18219 case OPC_MIN_S_df:
18220 gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
18221 break;
18222 case OPC_CLE_S_df:
18223 gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
18224 break;
18225 case OPC_AVE_S_df:
18226 gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
18227 break;
18228 case OPC_ASUB_S_df:
18229 gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
18230 break;
18231 case OPC_DIV_S_df:
18232 gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
18233 break;
18234 case OPC_ILVL_df:
18235 gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
18236 break;
18237 case OPC_BNEG_df:
18238 gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
18239 break;
18240 case OPC_MIN_U_df:
18241 gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
18242 break;
18243 case OPC_CLE_U_df:
18244 gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
18245 break;
18246 case OPC_AVE_U_df:
18247 gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
18248 break;
18249 case OPC_ASUB_U_df:
18250 gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
18251 break;
18252 case OPC_DIV_U_df:
18253 gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
18254 break;
18255 case OPC_ILVR_df:
18256 gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
18257 break;
18258 case OPC_BINSL_df:
18259 gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
18260 break;
18261 case OPC_MAX_A_df:
18262 gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
18263 break;
18264 case OPC_AVER_S_df:
18265 gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
18266 break;
18267 case OPC_MOD_S_df:
18268 gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
18269 break;
18270 case OPC_ILVEV_df:
18271 gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
18272 break;
18273 case OPC_BINSR_df:
18274 gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
18275 break;
18276 case OPC_MIN_A_df:
18277 gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
18278 break;
18279 case OPC_AVER_U_df:
18280 gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
18281 break;
18282 case OPC_MOD_U_df:
18283 gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
18284 break;
18285 case OPC_ILVOD_df:
18286 gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
18287 break;
18288
18289 case OPC_DOTP_S_df:
18290 case OPC_DOTP_U_df:
18291 case OPC_DPADD_S_df:
18292 case OPC_DPADD_U_df:
18293 case OPC_DPSUB_S_df:
18294 case OPC_HADD_S_df:
18295 case OPC_DPSUB_U_df:
18296 case OPC_HADD_U_df:
18297 case OPC_HSUB_S_df:
18298 case OPC_HSUB_U_df:
18299 if (df == DF_BYTE) {
18300 generate_exception_end(ctx, EXCP_RI);
18301 break;
18302 }
18303 switch (MASK_MSA_3R(ctx->opcode)) {
18304 case OPC_DOTP_S_df:
18305 gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
18306 break;
18307 case OPC_DOTP_U_df:
18308 gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
18309 break;
18310 case OPC_DPADD_S_df:
18311 gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
18312 break;
18313 case OPC_DPADD_U_df:
18314 gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
18315 break;
18316 case OPC_DPSUB_S_df:
18317 gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
18318 break;
18319 case OPC_HADD_S_df:
18320 gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
18321 break;
18322 case OPC_DPSUB_U_df:
18323 gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
18324 break;
18325 case OPC_HADD_U_df:
18326 gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
18327 break;
18328 case OPC_HSUB_S_df:
18329 gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
18330 break;
18331 case OPC_HSUB_U_df:
18332 gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
18333 break;
18334 }
18335 break;
18336 default:
18337 MIPS_INVAL("MSA instruction");
18338 generate_exception_end(ctx, EXCP_RI);
18339 break;
18340 }
18341 tcg_temp_free_i32(twd);
18342 tcg_temp_free_i32(tws);
18343 tcg_temp_free_i32(twt);
18344 tcg_temp_free_i32(tdf);
18345 }
18346
18347 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
18348 {
18349 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18350 uint8_t source = (ctx->opcode >> 11) & 0x1f;
18351 uint8_t dest = (ctx->opcode >> 6) & 0x1f;
18352 TCGv telm = tcg_temp_new();
18353 TCGv_i32 tsr = tcg_const_i32(source);
18354 TCGv_i32 tdt = tcg_const_i32(dest);
18355
18356 switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
18357 case OPC_CTCMSA:
18358 gen_load_gpr(telm, source);
18359 gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
18360 break;
18361 case OPC_CFCMSA:
18362 gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
18363 gen_store_gpr(telm, dest);
18364 break;
18365 case OPC_MOVE_V:
18366 gen_helper_msa_move_v(cpu_env, tdt, tsr);
18367 break;
18368 default:
18369 MIPS_INVAL("MSA instruction");
18370 generate_exception_end(ctx, EXCP_RI);
18371 break;
18372 }
18373
18374 tcg_temp_free(telm);
18375 tcg_temp_free_i32(tdt);
18376 tcg_temp_free_i32(tsr);
18377 }
18378
18379 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
18380 uint32_t n)
18381 {
18382 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18383 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18384 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18385
18386 TCGv_i32 tws = tcg_const_i32(ws);
18387 TCGv_i32 twd = tcg_const_i32(wd);
18388 TCGv_i32 tn = tcg_const_i32(n);
18389 TCGv_i32 tdf = tcg_const_i32(df);
18390
18391 switch (MASK_MSA_ELM(ctx->opcode)) {
18392 case OPC_SLDI_df:
18393 gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
18394 break;
18395 case OPC_SPLATI_df:
18396 gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
18397 break;
18398 case OPC_INSVE_df:
18399 gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
18400 break;
18401 case OPC_COPY_S_df:
18402 case OPC_COPY_U_df:
18403 case OPC_INSERT_df:
18404 #if !defined(TARGET_MIPS64)
18405 /* Double format valid only for MIPS64 */
18406 if (df == DF_DOUBLE) {
18407 generate_exception_end(ctx, EXCP_RI);
18408 break;
18409 }
18410 #endif
18411 switch (MASK_MSA_ELM(ctx->opcode)) {
18412 case OPC_COPY_S_df:
18413 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
18414 break;
18415 case OPC_COPY_U_df:
18416 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
18417 break;
18418 case OPC_INSERT_df:
18419 gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
18420 break;
18421 }
18422 break;
18423 default:
18424 MIPS_INVAL("MSA instruction");
18425 generate_exception_end(ctx, EXCP_RI);
18426 }
18427 tcg_temp_free_i32(twd);
18428 tcg_temp_free_i32(tws);
18429 tcg_temp_free_i32(tn);
18430 tcg_temp_free_i32(tdf);
18431 }
18432
18433 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
18434 {
18435 uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
18436 uint32_t df = 0, n = 0;
18437
18438 if ((dfn & 0x30) == 0x00) {
18439 n = dfn & 0x0f;
18440 df = DF_BYTE;
18441 } else if ((dfn & 0x38) == 0x20) {
18442 n = dfn & 0x07;
18443 df = DF_HALF;
18444 } else if ((dfn & 0x3c) == 0x30) {
18445 n = dfn & 0x03;
18446 df = DF_WORD;
18447 } else if ((dfn & 0x3e) == 0x38) {
18448 n = dfn & 0x01;
18449 df = DF_DOUBLE;
18450 } else if (dfn == 0x3E) {
18451 /* CTCMSA, CFCMSA, MOVE.V */
18452 gen_msa_elm_3e(env, ctx);
18453 return;
18454 } else {
18455 generate_exception_end(ctx, EXCP_RI);
18456 return;
18457 }
18458
18459 gen_msa_elm_df(env, ctx, df, n);
18460 }
18461
18462 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
18463 {
18464 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18465 uint8_t df = (ctx->opcode >> 21) & 0x1;
18466 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18467 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18468 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18469
18470 TCGv_i32 twd = tcg_const_i32(wd);
18471 TCGv_i32 tws = tcg_const_i32(ws);
18472 TCGv_i32 twt = tcg_const_i32(wt);
18473 TCGv_i32 tdf = tcg_temp_new_i32();
18474
18475 /* adjust df value for floating-point instruction */
18476 tcg_gen_movi_i32(tdf, df + 2);
18477
18478 switch (MASK_MSA_3RF(ctx->opcode)) {
18479 case OPC_FCAF_df:
18480 gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
18481 break;
18482 case OPC_FADD_df:
18483 gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
18484 break;
18485 case OPC_FCUN_df:
18486 gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
18487 break;
18488 case OPC_FSUB_df:
18489 gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
18490 break;
18491 case OPC_FCOR_df:
18492 gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
18493 break;
18494 case OPC_FCEQ_df:
18495 gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
18496 break;
18497 case OPC_FMUL_df:
18498 gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
18499 break;
18500 case OPC_FCUNE_df:
18501 gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
18502 break;
18503 case OPC_FCUEQ_df:
18504 gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
18505 break;
18506 case OPC_FDIV_df:
18507 gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
18508 break;
18509 case OPC_FCNE_df:
18510 gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
18511 break;
18512 case OPC_FCLT_df:
18513 gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
18514 break;
18515 case OPC_FMADD_df:
18516 gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
18517 break;
18518 case OPC_MUL_Q_df:
18519 tcg_gen_movi_i32(tdf, df + 1);
18520 gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
18521 break;
18522 case OPC_FCULT_df:
18523 gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
18524 break;
18525 case OPC_FMSUB_df:
18526 gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
18527 break;
18528 case OPC_MADD_Q_df:
18529 tcg_gen_movi_i32(tdf, df + 1);
18530 gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
18531 break;
18532 case OPC_FCLE_df:
18533 gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
18534 break;
18535 case OPC_MSUB_Q_df:
18536 tcg_gen_movi_i32(tdf, df + 1);
18537 gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
18538 break;
18539 case OPC_FCULE_df:
18540 gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
18541 break;
18542 case OPC_FEXP2_df:
18543 gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
18544 break;
18545 case OPC_FSAF_df:
18546 gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
18547 break;
18548 case OPC_FEXDO_df:
18549 gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
18550 break;
18551 case OPC_FSUN_df:
18552 gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
18553 break;
18554 case OPC_FSOR_df:
18555 gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
18556 break;
18557 case OPC_FSEQ_df:
18558 gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
18559 break;
18560 case OPC_FTQ_df:
18561 gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
18562 break;
18563 case OPC_FSUNE_df:
18564 gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
18565 break;
18566 case OPC_FSUEQ_df:
18567 gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
18568 break;
18569 case OPC_FSNE_df:
18570 gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
18571 break;
18572 case OPC_FSLT_df:
18573 gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
18574 break;
18575 case OPC_FMIN_df:
18576 gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
18577 break;
18578 case OPC_MULR_Q_df:
18579 tcg_gen_movi_i32(tdf, df + 1);
18580 gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
18581 break;
18582 case OPC_FSULT_df:
18583 gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
18584 break;
18585 case OPC_FMIN_A_df:
18586 gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
18587 break;
18588 case OPC_MADDR_Q_df:
18589 tcg_gen_movi_i32(tdf, df + 1);
18590 gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
18591 break;
18592 case OPC_FSLE_df:
18593 gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
18594 break;
18595 case OPC_FMAX_df:
18596 gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
18597 break;
18598 case OPC_MSUBR_Q_df:
18599 tcg_gen_movi_i32(tdf, df + 1);
18600 gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
18601 break;
18602 case OPC_FSULE_df:
18603 gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
18604 break;
18605 case OPC_FMAX_A_df:
18606 gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
18607 break;
18608 default:
18609 MIPS_INVAL("MSA instruction");
18610 generate_exception_end(ctx, EXCP_RI);
18611 break;
18612 }
18613
18614 tcg_temp_free_i32(twd);
18615 tcg_temp_free_i32(tws);
18616 tcg_temp_free_i32(twt);
18617 tcg_temp_free_i32(tdf);
18618 }
18619
18620 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
18621 {
18622 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18623 (op & (0x7 << 18)))
18624 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18625 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18626 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18627 uint8_t df = (ctx->opcode >> 16) & 0x3;
18628 TCGv_i32 twd = tcg_const_i32(wd);
18629 TCGv_i32 tws = tcg_const_i32(ws);
18630 TCGv_i32 twt = tcg_const_i32(wt);
18631 TCGv_i32 tdf = tcg_const_i32(df);
18632
18633 switch (MASK_MSA_2R(ctx->opcode)) {
18634 case OPC_FILL_df:
18635 #if !defined(TARGET_MIPS64)
18636 /* Double format valid only for MIPS64 */
18637 if (df == DF_DOUBLE) {
18638 generate_exception_end(ctx, EXCP_RI);
18639 break;
18640 }
18641 #endif
18642 gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
18643 break;
18644 case OPC_PCNT_df:
18645 gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
18646 break;
18647 case OPC_NLOC_df:
18648 gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
18649 break;
18650 case OPC_NLZC_df:
18651 gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
18652 break;
18653 default:
18654 MIPS_INVAL("MSA instruction");
18655 generate_exception_end(ctx, EXCP_RI);
18656 break;
18657 }
18658
18659 tcg_temp_free_i32(twd);
18660 tcg_temp_free_i32(tws);
18661 tcg_temp_free_i32(twt);
18662 tcg_temp_free_i32(tdf);
18663 }
18664
18665 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
18666 {
18667 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18668 (op & (0xf << 17)))
18669 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18670 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18671 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18672 uint8_t df = (ctx->opcode >> 16) & 0x1;
18673 TCGv_i32 twd = tcg_const_i32(wd);
18674 TCGv_i32 tws = tcg_const_i32(ws);
18675 TCGv_i32 twt = tcg_const_i32(wt);
18676 /* adjust df value for floating-point instruction */
18677 TCGv_i32 tdf = tcg_const_i32(df + 2);
18678
18679 switch (MASK_MSA_2RF(ctx->opcode)) {
18680 case OPC_FCLASS_df:
18681 gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
18682 break;
18683 case OPC_FTRUNC_S_df:
18684 gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
18685 break;
18686 case OPC_FTRUNC_U_df:
18687 gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
18688 break;
18689 case OPC_FSQRT_df:
18690 gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
18691 break;
18692 case OPC_FRSQRT_df:
18693 gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
18694 break;
18695 case OPC_FRCP_df:
18696 gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
18697 break;
18698 case OPC_FRINT_df:
18699 gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
18700 break;
18701 case OPC_FLOG2_df:
18702 gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
18703 break;
18704 case OPC_FEXUPL_df:
18705 gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
18706 break;
18707 case OPC_FEXUPR_df:
18708 gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
18709 break;
18710 case OPC_FFQL_df:
18711 gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
18712 break;
18713 case OPC_FFQR_df:
18714 gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
18715 break;
18716 case OPC_FTINT_S_df:
18717 gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
18718 break;
18719 case OPC_FTINT_U_df:
18720 gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
18721 break;
18722 case OPC_FFINT_S_df:
18723 gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
18724 break;
18725 case OPC_FFINT_U_df:
18726 gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
18727 break;
18728 }
18729
18730 tcg_temp_free_i32(twd);
18731 tcg_temp_free_i32(tws);
18732 tcg_temp_free_i32(twt);
18733 tcg_temp_free_i32(tdf);
18734 }
18735
18736 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
18737 {
18738 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18739 uint8_t wt = (ctx->opcode >> 16) & 0x1f;
18740 uint8_t ws = (ctx->opcode >> 11) & 0x1f;
18741 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18742 TCGv_i32 twd = tcg_const_i32(wd);
18743 TCGv_i32 tws = tcg_const_i32(ws);
18744 TCGv_i32 twt = tcg_const_i32(wt);
18745
18746 switch (MASK_MSA_VEC(ctx->opcode)) {
18747 case OPC_AND_V:
18748 gen_helper_msa_and_v(cpu_env, twd, tws, twt);
18749 break;
18750 case OPC_OR_V:
18751 gen_helper_msa_or_v(cpu_env, twd, tws, twt);
18752 break;
18753 case OPC_NOR_V:
18754 gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
18755 break;
18756 case OPC_XOR_V:
18757 gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
18758 break;
18759 case OPC_BMNZ_V:
18760 gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
18761 break;
18762 case OPC_BMZ_V:
18763 gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
18764 break;
18765 case OPC_BSEL_V:
18766 gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
18767 break;
18768 default:
18769 MIPS_INVAL("MSA instruction");
18770 generate_exception_end(ctx, EXCP_RI);
18771 break;
18772 }
18773
18774 tcg_temp_free_i32(twd);
18775 tcg_temp_free_i32(tws);
18776 tcg_temp_free_i32(twt);
18777 }
18778
18779 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
18780 {
18781 switch (MASK_MSA_VEC(ctx->opcode)) {
18782 case OPC_AND_V:
18783 case OPC_OR_V:
18784 case OPC_NOR_V:
18785 case OPC_XOR_V:
18786 case OPC_BMNZ_V:
18787 case OPC_BMZ_V:
18788 case OPC_BSEL_V:
18789 gen_msa_vec_v(env, ctx);
18790 break;
18791 case OPC_MSA_2R:
18792 gen_msa_2r(env, ctx);
18793 break;
18794 case OPC_MSA_2RF:
18795 gen_msa_2rf(env, ctx);
18796 break;
18797 default:
18798 MIPS_INVAL("MSA instruction");
18799 generate_exception_end(ctx, EXCP_RI);
18800 break;
18801 }
18802 }
18803
18804 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
18805 {
18806 uint32_t opcode = ctx->opcode;
18807 check_insn(ctx, ASE_MSA);
18808 check_msa_access(ctx);
18809
18810 switch (MASK_MSA_MINOR(opcode)) {
18811 case OPC_MSA_I8_00:
18812 case OPC_MSA_I8_01:
18813 case OPC_MSA_I8_02:
18814 gen_msa_i8(env, ctx);
18815 break;
18816 case OPC_MSA_I5_06:
18817 case OPC_MSA_I5_07:
18818 gen_msa_i5(env, ctx);
18819 break;
18820 case OPC_MSA_BIT_09:
18821 case OPC_MSA_BIT_0A:
18822 gen_msa_bit(env, ctx);
18823 break;
18824 case OPC_MSA_3R_0D:
18825 case OPC_MSA_3R_0E:
18826 case OPC_MSA_3R_0F:
18827 case OPC_MSA_3R_10:
18828 case OPC_MSA_3R_11:
18829 case OPC_MSA_3R_12:
18830 case OPC_MSA_3R_13:
18831 case OPC_MSA_3R_14:
18832 case OPC_MSA_3R_15:
18833 gen_msa_3r(env, ctx);
18834 break;
18835 case OPC_MSA_ELM:
18836 gen_msa_elm(env, ctx);
18837 break;
18838 case OPC_MSA_3RF_1A:
18839 case OPC_MSA_3RF_1B:
18840 case OPC_MSA_3RF_1C:
18841 gen_msa_3rf(env, ctx);
18842 break;
18843 case OPC_MSA_VEC:
18844 gen_msa_vec(env, ctx);
18845 break;
18846 case OPC_LD_B:
18847 case OPC_LD_H:
18848 case OPC_LD_W:
18849 case OPC_LD_D:
18850 case OPC_ST_B:
18851 case OPC_ST_H:
18852 case OPC_ST_W:
18853 case OPC_ST_D:
18854 {
18855 int32_t s10 = sextract32(ctx->opcode, 16, 10);
18856 uint8_t rs = (ctx->opcode >> 11) & 0x1f;
18857 uint8_t wd = (ctx->opcode >> 6) & 0x1f;
18858 uint8_t df = (ctx->opcode >> 0) & 0x3;
18859
18860 TCGv_i32 twd = tcg_const_i32(wd);
18861 TCGv taddr = tcg_temp_new();
18862 gen_base_offset_addr(ctx, taddr, rs, s10 << df);
18863
18864 switch (MASK_MSA_MINOR(opcode)) {
18865 case OPC_LD_B:
18866 gen_helper_msa_ld_b(cpu_env, twd, taddr);
18867 break;
18868 case OPC_LD_H:
18869 gen_helper_msa_ld_h(cpu_env, twd, taddr);
18870 break;
18871 case OPC_LD_W:
18872 gen_helper_msa_ld_w(cpu_env, twd, taddr);
18873 break;
18874 case OPC_LD_D:
18875 gen_helper_msa_ld_d(cpu_env, twd, taddr);
18876 break;
18877 case OPC_ST_B:
18878 gen_helper_msa_st_b(cpu_env, twd, taddr);
18879 break;
18880 case OPC_ST_H:
18881 gen_helper_msa_st_h(cpu_env, twd, taddr);
18882 break;
18883 case OPC_ST_W:
18884 gen_helper_msa_st_w(cpu_env, twd, taddr);
18885 break;
18886 case OPC_ST_D:
18887 gen_helper_msa_st_d(cpu_env, twd, taddr);
18888 break;
18889 }
18890
18891 tcg_temp_free_i32(twd);
18892 tcg_temp_free(taddr);
18893 }
18894 break;
18895 default:
18896 MIPS_INVAL("MSA instruction");
18897 generate_exception_end(ctx, EXCP_RI);
18898 break;
18899 }
18900
18901 }
18902
18903 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
18904 {
18905 int32_t offset;
18906 int rs, rt, rd, sa;
18907 uint32_t op, op1;
18908 int16_t imm;
18909
18910 /* make sure instructions are on a word boundary */
18911 if (ctx->pc & 0x3) {
18912 env->CP0_BadVAddr = ctx->pc;
18913 generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
18914 return;
18915 }
18916
18917 /* Handle blikely not taken case */
18918 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
18919 TCGLabel *l1 = gen_new_label();
18920
18921 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
18922 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
18923 gen_goto_tb(ctx, 1, ctx->pc + 4);
18924 gen_set_label(l1);
18925 }
18926
18927 op = MASK_OP_MAJOR(ctx->opcode);
18928 rs = (ctx->opcode >> 21) & 0x1f;
18929 rt = (ctx->opcode >> 16) & 0x1f;
18930 rd = (ctx->opcode >> 11) & 0x1f;
18931 sa = (ctx->opcode >> 6) & 0x1f;
18932 imm = (int16_t)ctx->opcode;
18933 switch (op) {
18934 case OPC_SPECIAL:
18935 decode_opc_special(env, ctx);
18936 break;
18937 case OPC_SPECIAL2:
18938 decode_opc_special2_legacy(env, ctx);
18939 break;
18940 case OPC_SPECIAL3:
18941 decode_opc_special3(env, ctx);
18942 break;
18943 case OPC_REGIMM:
18944 op1 = MASK_REGIMM(ctx->opcode);
18945 switch (op1) {
18946 case OPC_BLTZL: /* REGIMM branches */
18947 case OPC_BGEZL:
18948 case OPC_BLTZALL:
18949 case OPC_BGEZALL:
18950 check_insn(ctx, ISA_MIPS2);
18951 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18952 /* Fallthrough */
18953 case OPC_BLTZ:
18954 case OPC_BGEZ:
18955 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
18956 break;
18957 case OPC_BLTZAL:
18958 case OPC_BGEZAL:
18959 if (ctx->insn_flags & ISA_MIPS32R6) {
18960 if (rs == 0) {
18961 /* OPC_NAL, OPC_BAL */
18962 gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
18963 } else {
18964 generate_exception_end(ctx, EXCP_RI);
18965 }
18966 } else {
18967 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
18968 }
18969 break;
18970 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
18971 case OPC_TNEI:
18972 check_insn(ctx, ISA_MIPS2);
18973 check_insn_opc_removed(ctx, ISA_MIPS32R6);
18974 gen_trap(ctx, op1, rs, -1, imm);
18975 break;
18976 case OPC_SYNCI:
18977 check_insn(ctx, ISA_MIPS32R2);
18978 /* Break the TB to be able to sync copied instructions
18979 immediately */
18980 ctx->bstate = BS_STOP;
18981 break;
18982 case OPC_BPOSGE32: /* MIPS DSP branch */
18983 #if defined(TARGET_MIPS64)
18984 case OPC_BPOSGE64:
18985 #endif
18986 check_dsp(ctx);
18987 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
18988 break;
18989 #if defined(TARGET_MIPS64)
18990 case OPC_DAHI:
18991 check_insn(ctx, ISA_MIPS32R6);
18992 check_mips_64(ctx);
18993 if (rs != 0) {
18994 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
18995 }
18996 break;
18997 case OPC_DATI:
18998 check_insn(ctx, ISA_MIPS32R6);
18999 check_mips_64(ctx);
19000 if (rs != 0) {
19001 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
19002 }
19003 break;
19004 #endif
19005 default: /* Invalid */
19006 MIPS_INVAL("regimm");
19007 generate_exception_end(ctx, EXCP_RI);
19008 break;
19009 }
19010 break;
19011 case OPC_CP0:
19012 check_cp0_enabled(ctx);
19013 op1 = MASK_CP0(ctx->opcode);
19014 switch (op1) {
19015 case OPC_MFC0:
19016 case OPC_MTC0:
19017 case OPC_MFTR:
19018 case OPC_MTTR:
19019 case OPC_MFHC0:
19020 case OPC_MTHC0:
19021 #if defined(TARGET_MIPS64)
19022 case OPC_DMFC0:
19023 case OPC_DMTC0:
19024 #endif
19025 #ifndef CONFIG_USER_ONLY
19026 gen_cp0(env, ctx, op1, rt, rd);
19027 #endif /* !CONFIG_USER_ONLY */
19028 break;
19029 case OPC_C0_FIRST ... OPC_C0_LAST:
19030 #ifndef CONFIG_USER_ONLY
19031 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
19032 #endif /* !CONFIG_USER_ONLY */
19033 break;
19034 case OPC_MFMC0:
19035 #ifndef CONFIG_USER_ONLY
19036 {
19037 uint32_t op2;
19038 TCGv t0 = tcg_temp_new();
19039
19040 op2 = MASK_MFMC0(ctx->opcode);
19041 switch (op2) {
19042 case OPC_DMT:
19043 check_insn(ctx, ASE_MT);
19044 gen_helper_dmt(t0);
19045 gen_store_gpr(t0, rt);
19046 break;
19047 case OPC_EMT:
19048 check_insn(ctx, ASE_MT);
19049 gen_helper_emt(t0);
19050 gen_store_gpr(t0, rt);
19051 break;
19052 case OPC_DVPE:
19053 check_insn(ctx, ASE_MT);
19054 gen_helper_dvpe(t0, cpu_env);
19055 gen_store_gpr(t0, rt);
19056 break;
19057 case OPC_EVPE:
19058 check_insn(ctx, ASE_MT);
19059 gen_helper_evpe(t0, cpu_env);
19060 gen_store_gpr(t0, rt);
19061 break;
19062 case OPC_DI:
19063 check_insn(ctx, ISA_MIPS32R2);
19064 save_cpu_state(ctx, 1);
19065 gen_helper_di(t0, cpu_env);
19066 gen_store_gpr(t0, rt);
19067 /* Stop translation as we may have switched
19068 the execution mode. */
19069 ctx->bstate = BS_STOP;
19070 break;
19071 case OPC_EI:
19072 check_insn(ctx, ISA_MIPS32R2);
19073 save_cpu_state(ctx, 1);
19074 gen_helper_ei(t0, cpu_env);
19075 gen_store_gpr(t0, rt);
19076 /* Stop translation as we may have switched
19077 the execution mode. */
19078 ctx->bstate = BS_STOP;
19079 break;
19080 default: /* Invalid */
19081 MIPS_INVAL("mfmc0");
19082 generate_exception_end(ctx, EXCP_RI);
19083 break;
19084 }
19085 tcg_temp_free(t0);
19086 }
19087 #endif /* !CONFIG_USER_ONLY */
19088 break;
19089 case OPC_RDPGPR:
19090 check_insn(ctx, ISA_MIPS32R2);
19091 gen_load_srsgpr(rt, rd);
19092 break;
19093 case OPC_WRPGPR:
19094 check_insn(ctx, ISA_MIPS32R2);
19095 gen_store_srsgpr(rt, rd);
19096 break;
19097 default:
19098 MIPS_INVAL("cp0");
19099 generate_exception_end(ctx, EXCP_RI);
19100 break;
19101 }
19102 break;
19103 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19104 if (ctx->insn_flags & ISA_MIPS32R6) {
19105 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19106 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19107 } else {
19108 /* OPC_ADDI */
19109 /* Arithmetic with immediate opcode */
19110 gen_arith_imm(ctx, op, rt, rs, imm);
19111 }
19112 break;
19113 case OPC_ADDIU:
19114 gen_arith_imm(ctx, op, rt, rs, imm);
19115 break;
19116 case OPC_SLTI: /* Set on less than with immediate opcode */
19117 case OPC_SLTIU:
19118 gen_slt_imm(ctx, op, rt, rs, imm);
19119 break;
19120 case OPC_ANDI: /* Arithmetic with immediate opcode */
19121 case OPC_LUI: /* OPC_AUI */
19122 case OPC_ORI:
19123 case OPC_XORI:
19124 gen_logic_imm(ctx, op, rt, rs, imm);
19125 break;
19126 case OPC_J ... OPC_JAL: /* Jump */
19127 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19128 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19129 break;
19130 /* Branch */
19131 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19132 if (ctx->insn_flags & ISA_MIPS32R6) {
19133 if (rt == 0) {
19134 generate_exception_end(ctx, EXCP_RI);
19135 break;
19136 }
19137 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19138 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19139 } else {
19140 /* OPC_BLEZL */
19141 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19142 }
19143 break;
19144 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19145 if (ctx->insn_flags & ISA_MIPS32R6) {
19146 if (rt == 0) {
19147 generate_exception_end(ctx, EXCP_RI);
19148 break;
19149 }
19150 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19151 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19152 } else {
19153 /* OPC_BGTZL */
19154 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19155 }
19156 break;
19157 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19158 if (rt == 0) {
19159 /* OPC_BLEZ */
19160 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19161 } else {
19162 check_insn(ctx, ISA_MIPS32R6);
19163 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19164 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19165 }
19166 break;
19167 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19168 if (rt == 0) {
19169 /* OPC_BGTZ */
19170 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19171 } else {
19172 check_insn(ctx, ISA_MIPS32R6);
19173 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19174 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19175 }
19176 break;
19177 case OPC_BEQL:
19178 case OPC_BNEL:
19179 check_insn(ctx, ISA_MIPS2);
19180 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19181 /* Fallthrough */
19182 case OPC_BEQ:
19183 case OPC_BNE:
19184 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
19185 break;
19186 case OPC_LL: /* Load and stores */
19187 check_insn(ctx, ISA_MIPS2);
19188 /* Fallthrough */
19189 case OPC_LWL:
19190 case OPC_LWR:
19191 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19192 /* Fallthrough */
19193 case OPC_LB ... OPC_LH:
19194 case OPC_LW ... OPC_LHU:
19195 gen_ld(ctx, op, rt, rs, imm);
19196 break;
19197 case OPC_SWL:
19198 case OPC_SWR:
19199 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19200 /* fall through */
19201 case OPC_SB ... OPC_SH:
19202 case OPC_SW:
19203 gen_st(ctx, op, rt, rs, imm);
19204 break;
19205 case OPC_SC:
19206 check_insn(ctx, ISA_MIPS2);
19207 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19208 gen_st_cond(ctx, op, rt, rs, imm);
19209 break;
19210 case OPC_CACHE:
19211 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19212 check_cp0_enabled(ctx);
19213 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
19214 /* Treat as NOP. */
19215 break;
19216 case OPC_PREF:
19217 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19218 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
19219 /* Treat as NOP. */
19220 break;
19221
19222 /* Floating point (COP1). */
19223 case OPC_LWC1:
19224 case OPC_LDC1:
19225 case OPC_SWC1:
19226 case OPC_SDC1:
19227 gen_cop1_ldst(ctx, op, rt, rs, imm);
19228 break;
19229
19230 case OPC_CP1:
19231 op1 = MASK_CP1(ctx->opcode);
19232
19233 switch (op1) {
19234 case OPC_MFHC1:
19235 case OPC_MTHC1:
19236 check_cp1_enabled(ctx);
19237 check_insn(ctx, ISA_MIPS32R2);
19238 case OPC_MFC1:
19239 case OPC_CFC1:
19240 case OPC_MTC1:
19241 case OPC_CTC1:
19242 check_cp1_enabled(ctx);
19243 gen_cp1(ctx, op1, rt, rd);
19244 break;
19245 #if defined(TARGET_MIPS64)
19246 case OPC_DMFC1:
19247 case OPC_DMTC1:
19248 check_cp1_enabled(ctx);
19249 check_insn(ctx, ISA_MIPS3);
19250 check_mips_64(ctx);
19251 gen_cp1(ctx, op1, rt, rd);
19252 break;
19253 #endif
19254 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
19255 check_cp1_enabled(ctx);
19256 if (ctx->insn_flags & ISA_MIPS32R6) {
19257 /* OPC_BC1EQZ */
19258 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19259 rt, imm << 2, 4);
19260 } else {
19261 /* OPC_BC1ANY2 */
19262 check_cop1x(ctx);
19263 check_insn(ctx, ASE_MIPS3D);
19264 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19265 (rt >> 2) & 0x7, imm << 2);
19266 }
19267 break;
19268 case OPC_BC1NEZ:
19269 check_cp1_enabled(ctx);
19270 check_insn(ctx, ISA_MIPS32R6);
19271 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
19272 rt, imm << 2, 4);
19273 break;
19274 case OPC_BC1ANY4:
19275 check_cp1_enabled(ctx);
19276 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19277 check_cop1x(ctx);
19278 check_insn(ctx, ASE_MIPS3D);
19279 /* fall through */
19280 case OPC_BC1:
19281 check_cp1_enabled(ctx);
19282 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19283 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
19284 (rt >> 2) & 0x7, imm << 2);
19285 break;
19286 case OPC_PS_FMT:
19287 check_ps(ctx);
19288 /* fall through */
19289 case OPC_S_FMT:
19290 case OPC_D_FMT:
19291 check_cp1_enabled(ctx);
19292 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19293 (imm >> 8) & 0x7);
19294 break;
19295 case OPC_W_FMT:
19296 case OPC_L_FMT:
19297 {
19298 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
19299 check_cp1_enabled(ctx);
19300 if (ctx->insn_flags & ISA_MIPS32R6) {
19301 switch (r6_op) {
19302 case R6_OPC_CMP_AF_S:
19303 case R6_OPC_CMP_UN_S:
19304 case R6_OPC_CMP_EQ_S:
19305 case R6_OPC_CMP_UEQ_S:
19306 case R6_OPC_CMP_LT_S:
19307 case R6_OPC_CMP_ULT_S:
19308 case R6_OPC_CMP_LE_S:
19309 case R6_OPC_CMP_ULE_S:
19310 case R6_OPC_CMP_SAF_S:
19311 case R6_OPC_CMP_SUN_S:
19312 case R6_OPC_CMP_SEQ_S:
19313 case R6_OPC_CMP_SEUQ_S:
19314 case R6_OPC_CMP_SLT_S:
19315 case R6_OPC_CMP_SULT_S:
19316 case R6_OPC_CMP_SLE_S:
19317 case R6_OPC_CMP_SULE_S:
19318 case R6_OPC_CMP_OR_S:
19319 case R6_OPC_CMP_UNE_S:
19320 case R6_OPC_CMP_NE_S:
19321 case R6_OPC_CMP_SOR_S:
19322 case R6_OPC_CMP_SUNE_S:
19323 case R6_OPC_CMP_SNE_S:
19324 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19325 break;
19326 case R6_OPC_CMP_AF_D:
19327 case R6_OPC_CMP_UN_D:
19328 case R6_OPC_CMP_EQ_D:
19329 case R6_OPC_CMP_UEQ_D:
19330 case R6_OPC_CMP_LT_D:
19331 case R6_OPC_CMP_ULT_D:
19332 case R6_OPC_CMP_LE_D:
19333 case R6_OPC_CMP_ULE_D:
19334 case R6_OPC_CMP_SAF_D:
19335 case R6_OPC_CMP_SUN_D:
19336 case R6_OPC_CMP_SEQ_D:
19337 case R6_OPC_CMP_SEUQ_D:
19338 case R6_OPC_CMP_SLT_D:
19339 case R6_OPC_CMP_SULT_D:
19340 case R6_OPC_CMP_SLE_D:
19341 case R6_OPC_CMP_SULE_D:
19342 case R6_OPC_CMP_OR_D:
19343 case R6_OPC_CMP_UNE_D:
19344 case R6_OPC_CMP_NE_D:
19345 case R6_OPC_CMP_SOR_D:
19346 case R6_OPC_CMP_SUNE_D:
19347 case R6_OPC_CMP_SNE_D:
19348 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
19349 break;
19350 default:
19351 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
19352 rt, rd, sa, (imm >> 8) & 0x7);
19353
19354 break;
19355 }
19356 } else {
19357 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
19358 (imm >> 8) & 0x7);
19359 }
19360 break;
19361 }
19362 case OPC_BZ_V:
19363 case OPC_BNZ_V:
19364 case OPC_BZ_B:
19365 case OPC_BZ_H:
19366 case OPC_BZ_W:
19367 case OPC_BZ_D:
19368 case OPC_BNZ_B:
19369 case OPC_BNZ_H:
19370 case OPC_BNZ_W:
19371 case OPC_BNZ_D:
19372 check_insn(ctx, ASE_MSA);
19373 gen_msa_branch(env, ctx, op1);
19374 break;
19375 default:
19376 MIPS_INVAL("cp1");
19377 generate_exception_end(ctx, EXCP_RI);
19378 break;
19379 }
19380 break;
19381
19382 /* Compact branches [R6] and COP2 [non-R6] */
19383 case OPC_BC: /* OPC_LWC2 */
19384 case OPC_BALC: /* OPC_SWC2 */
19385 if (ctx->insn_flags & ISA_MIPS32R6) {
19386 /* OPC_BC, OPC_BALC */
19387 gen_compute_compact_branch(ctx, op, 0, 0,
19388 sextract32(ctx->opcode << 2, 0, 28));
19389 } else {
19390 /* OPC_LWC2, OPC_SWC2 */
19391 /* COP2: Not implemented. */
19392 generate_exception_err(ctx, EXCP_CpU, 2);
19393 }
19394 break;
19395 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
19396 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
19397 if (ctx->insn_flags & ISA_MIPS32R6) {
19398 if (rs != 0) {
19399 /* OPC_BEQZC, OPC_BNEZC */
19400 gen_compute_compact_branch(ctx, op, rs, 0,
19401 sextract32(ctx->opcode << 2, 0, 23));
19402 } else {
19403 /* OPC_JIC, OPC_JIALC */
19404 gen_compute_compact_branch(ctx, op, 0, rt, imm);
19405 }
19406 } else {
19407 /* OPC_LWC2, OPC_SWC2 */
19408 /* COP2: Not implemented. */
19409 generate_exception_err(ctx, EXCP_CpU, 2);
19410 }
19411 break;
19412 case OPC_CP2:
19413 check_insn(ctx, INSN_LOONGSON2F);
19414 /* Note that these instructions use different fields. */
19415 gen_loongson_multimedia(ctx, sa, rd, rt);
19416 break;
19417
19418 case OPC_CP3:
19419 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19420 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19421 check_cp1_enabled(ctx);
19422 op1 = MASK_CP3(ctx->opcode);
19423 switch (op1) {
19424 case OPC_LUXC1:
19425 case OPC_SUXC1:
19426 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19427 /* Fallthrough */
19428 case OPC_LWXC1:
19429 case OPC_LDXC1:
19430 case OPC_SWXC1:
19431 case OPC_SDXC1:
19432 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19433 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
19434 break;
19435 case OPC_PREFX:
19436 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19437 /* Treat as NOP. */
19438 break;
19439 case OPC_ALNV_PS:
19440 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
19441 /* Fallthrough */
19442 case OPC_MADD_S:
19443 case OPC_MADD_D:
19444 case OPC_MADD_PS:
19445 case OPC_MSUB_S:
19446 case OPC_MSUB_D:
19447 case OPC_MSUB_PS:
19448 case OPC_NMADD_S:
19449 case OPC_NMADD_D:
19450 case OPC_NMADD_PS:
19451 case OPC_NMSUB_S:
19452 case OPC_NMSUB_D:
19453 case OPC_NMSUB_PS:
19454 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
19455 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
19456 break;
19457 default:
19458 MIPS_INVAL("cp3");
19459 generate_exception_end(ctx, EXCP_RI);
19460 break;
19461 }
19462 } else {
19463 generate_exception_err(ctx, EXCP_CpU, 1);
19464 }
19465 break;
19466
19467 #if defined(TARGET_MIPS64)
19468 /* MIPS64 opcodes */
19469 case OPC_LDL ... OPC_LDR:
19470 case OPC_LLD:
19471 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19472 /* fall through */
19473 case OPC_LWU:
19474 case OPC_LD:
19475 check_insn(ctx, ISA_MIPS3);
19476 check_mips_64(ctx);
19477 gen_ld(ctx, op, rt, rs, imm);
19478 break;
19479 case OPC_SDL ... OPC_SDR:
19480 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19481 /* fall through */
19482 case OPC_SD:
19483 check_insn(ctx, ISA_MIPS3);
19484 check_mips_64(ctx);
19485 gen_st(ctx, op, rt, rs, imm);
19486 break;
19487 case OPC_SCD:
19488 check_insn_opc_removed(ctx, ISA_MIPS32R6);
19489 check_insn(ctx, ISA_MIPS3);
19490 check_mips_64(ctx);
19491 gen_st_cond(ctx, op, rt, rs, imm);
19492 break;
19493 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19494 if (ctx->insn_flags & ISA_MIPS32R6) {
19495 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19496 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19497 } else {
19498 /* OPC_DADDI */
19499 check_insn(ctx, ISA_MIPS3);
19500 check_mips_64(ctx);
19501 gen_arith_imm(ctx, op, rt, rs, imm);
19502 }
19503 break;
19504 case OPC_DADDIU:
19505 check_insn(ctx, ISA_MIPS3);
19506 check_mips_64(ctx);
19507 gen_arith_imm(ctx, op, rt, rs, imm);
19508 break;
19509 #else
19510 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
19511 if (ctx->insn_flags & ISA_MIPS32R6) {
19512 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
19513 } else {
19514 MIPS_INVAL("major opcode");
19515 generate_exception_end(ctx, EXCP_RI);
19516 }
19517 break;
19518 #endif
19519 case OPC_DAUI: /* OPC_JALX */
19520 if (ctx->insn_flags & ISA_MIPS32R6) {
19521 #if defined(TARGET_MIPS64)
19522 /* OPC_DAUI */
19523 check_mips_64(ctx);
19524 if (rs == 0) {
19525 generate_exception(ctx, EXCP_RI);
19526 } else if (rt != 0) {
19527 TCGv t0 = tcg_temp_new();
19528 gen_load_gpr(t0, rs);
19529 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
19530 tcg_temp_free(t0);
19531 }
19532 #else
19533 generate_exception_end(ctx, EXCP_RI);
19534 MIPS_INVAL("major opcode");
19535 #endif
19536 } else {
19537 /* OPC_JALX */
19538 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
19539 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
19540 gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
19541 }
19542 break;
19543 case OPC_MSA: /* OPC_MDMX */
19544 /* MDMX: Not implemented. */
19545 gen_msa(env, ctx);
19546 break;
19547 case OPC_PCREL:
19548 check_insn(ctx, ISA_MIPS32R6);
19549 gen_pcrel(ctx, ctx->opcode, ctx->pc, rs);
19550 break;
19551 default: /* Invalid */
19552 MIPS_INVAL("major opcode");
19553 generate_exception_end(ctx, EXCP_RI);
19554 break;
19555 }
19556 }
19557
19558 void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb)
19559 {
19560 MIPSCPU *cpu = mips_env_get_cpu(env);
19561 CPUState *cs = CPU(cpu);
19562 DisasContext ctx;
19563 target_ulong pc_start;
19564 target_ulong next_page_start;
19565 int num_insns;
19566 int max_insns;
19567 int insn_bytes;
19568 int is_slot;
19569
19570 pc_start = tb->pc;
19571 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
19572 ctx.pc = pc_start;
19573 ctx.saved_pc = -1;
19574 ctx.singlestep_enabled = cs->singlestep_enabled;
19575 ctx.insn_flags = env->insn_flags;
19576 ctx.CP0_Config1 = env->CP0_Config1;
19577 ctx.tb = tb;
19578 ctx.bstate = BS_NONE;
19579 ctx.btarget = 0;
19580 ctx.kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
19581 ctx.rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
19582 ctx.ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
19583 ctx.bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
19584 ctx.bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
19585 ctx.PAMask = env->PAMask;
19586 ctx.mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
19587 ctx.CP0_LLAddr_shift = env->CP0_LLAddr_shift;
19588 /* Restore delay slot state from the tb context. */
19589 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
19590 ctx.ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
19591 ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
19592 (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
19593 restore_cpu_state(env, &ctx);
19594 #ifdef CONFIG_USER_ONLY
19595 ctx.mem_idx = MIPS_HFLAG_UM;
19596 #else
19597 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
19598 #endif
19599 ctx.default_tcg_memop_mask = (ctx.insn_flags & ISA_MIPS32R6) ?
19600 MO_UNALN : MO_ALIGN;
19601 num_insns = 0;
19602 max_insns = tb->cflags & CF_COUNT_MASK;
19603 if (max_insns == 0) {
19604 max_insns = CF_COUNT_MASK;
19605 }
19606 if (max_insns > TCG_MAX_INSNS) {
19607 max_insns = TCG_MAX_INSNS;
19608 }
19609
19610 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
19611 gen_tb_start(tb);
19612 while (ctx.bstate == BS_NONE) {
19613 tcg_gen_insn_start(ctx.pc, ctx.hflags & MIPS_HFLAG_BMASK, ctx.btarget);
19614 num_insns++;
19615
19616 if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
19617 save_cpu_state(&ctx, 1);
19618 ctx.bstate = BS_BRANCH;
19619 gen_helper_raise_exception_debug(cpu_env);
19620 /* The address covered by the breakpoint must be included in
19621 [tb->pc, tb->pc + tb->size) in order to for it to be
19622 properly cleared -- thus we increment the PC here so that
19623 the logic setting tb->size below does the right thing. */
19624 ctx.pc += 4;
19625 goto done_generating;
19626 }
19627
19628 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
19629 gen_io_start();
19630 }
19631
19632 is_slot = ctx.hflags & MIPS_HFLAG_BMASK;
19633 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
19634 ctx.opcode = cpu_ldl_code(env, ctx.pc);
19635 insn_bytes = 4;
19636 decode_opc(env, &ctx);
19637 } else if (ctx.insn_flags & ASE_MICROMIPS) {
19638 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19639 insn_bytes = decode_micromips_opc(env, &ctx);
19640 } else if (ctx.insn_flags & ASE_MIPS16) {
19641 ctx.opcode = cpu_lduw_code(env, ctx.pc);
19642 insn_bytes = decode_mips16_opc(env, &ctx);
19643 } else {
19644 generate_exception_end(&ctx, EXCP_RI);
19645 break;
19646 }
19647
19648 if (ctx.hflags & MIPS_HFLAG_BMASK) {
19649 if (!(ctx.hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
19650 MIPS_HFLAG_FBNSLOT))) {
19651 /* force to generate branch as there is neither delay nor
19652 forbidden slot */
19653 is_slot = 1;
19654 }
19655 if ((ctx.hflags & MIPS_HFLAG_M16) &&
19656 (ctx.hflags & MIPS_HFLAG_FBNSLOT)) {
19657 /* Force to generate branch as microMIPS R6 doesn't restrict
19658 branches in the forbidden slot. */
19659 is_slot = 1;
19660 }
19661 }
19662 if (is_slot) {
19663 gen_branch(&ctx, insn_bytes);
19664 }
19665 ctx.pc += insn_bytes;
19666
19667 /* Execute a branch and its delay slot as a single instruction.
19668 This is what GDB expects and is consistent with what the
19669 hardware does (e.g. if a delay slot instruction faults, the
19670 reported PC is the PC of the branch). */
19671 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
19672 break;
19673 }
19674
19675 if (ctx.pc >= next_page_start) {
19676 break;
19677 }
19678
19679 if (tcg_op_buf_full()) {
19680 break;
19681 }
19682
19683 if (num_insns >= max_insns)
19684 break;
19685
19686 if (singlestep)
19687 break;
19688 }
19689 if (tb->cflags & CF_LAST_IO) {
19690 gen_io_end();
19691 }
19692 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
19693 save_cpu_state(&ctx, ctx.bstate != BS_EXCP);
19694 gen_helper_raise_exception_debug(cpu_env);
19695 } else {
19696 switch (ctx.bstate) {
19697 case BS_STOP:
19698 gen_goto_tb(&ctx, 0, ctx.pc);
19699 break;
19700 case BS_NONE:
19701 save_cpu_state(&ctx, 0);
19702 gen_goto_tb(&ctx, 0, ctx.pc);
19703 break;
19704 case BS_EXCP:
19705 tcg_gen_exit_tb(0);
19706 break;
19707 case BS_BRANCH:
19708 default:
19709 break;
19710 }
19711 }
19712 done_generating:
19713 gen_tb_end(tb, num_insns);
19714
19715 tb->size = ctx.pc - pc_start;
19716 tb->icount = num_insns;
19717
19718 #ifdef DEBUG_DISAS
19719 LOG_DISAS("\n");
19720 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
19721 qemu_log("IN: %s\n", lookup_symbol(pc_start));
19722 log_target_disas(cs, pc_start, ctx.pc - pc_start, 0);
19723 qemu_log("\n");
19724 }
19725 #endif
19726 }
19727
19728 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
19729 int flags)
19730 {
19731 int i;
19732 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
19733
19734 #define printfpr(fp) \
19735 do { \
19736 if (is_fpu64) \
19737 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19738 " fd:%13g fs:%13g psu: %13g\n", \
19739 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19740 (double)(fp)->fd, \
19741 (double)(fp)->fs[FP_ENDIAN_IDX], \
19742 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19743 else { \
19744 fpr_t tmp; \
19745 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19746 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19747 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19748 " fd:%13g fs:%13g psu:%13g\n", \
19749 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19750 (double)tmp.fd, \
19751 (double)tmp.fs[FP_ENDIAN_IDX], \
19752 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19753 } \
19754 } while(0)
19755
19756
19757 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19758 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
19759 get_float_exception_flags(&env->active_fpu.fp_status));
19760 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
19761 fpu_fprintf(f, "%3s: ", fregnames[i]);
19762 printfpr(&env->active_fpu.fpr[i]);
19763 }
19764
19765 #undef printfpr
19766 }
19767
19768 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
19769 int flags)
19770 {
19771 MIPSCPU *cpu = MIPS_CPU(cs);
19772 CPUMIPSState *env = &cpu->env;
19773 int i;
19774
19775 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
19776 " LO=0x" TARGET_FMT_lx " ds %04x "
19777 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
19778 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
19779 env->hflags, env->btarget, env->bcond);
19780 for (i = 0; i < 32; i++) {
19781 if ((i & 3) == 0)
19782 cpu_fprintf(f, "GPR%02d:", i);
19783 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
19784 if ((i & 3) == 3)
19785 cpu_fprintf(f, "\n");
19786 }
19787
19788 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
19789 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
19790 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
19791 PRIx64 "\n",
19792 env->CP0_Config0, env->CP0_Config1, env->lladdr);
19793 cpu_fprintf(f, " Config2 0x%08x Config3 0x%08x\n",
19794 env->CP0_Config2, env->CP0_Config3);
19795 cpu_fprintf(f, " Config4 0x%08x Config5 0x%08x\n",
19796 env->CP0_Config4, env->CP0_Config5);
19797 if (env->hflags & MIPS_HFLAG_FPU)
19798 fpu_dump_state(env, f, cpu_fprintf, flags);
19799 }
19800
19801 void mips_tcg_init(void)
19802 {
19803 int i;
19804 static int inited;
19805
19806 /* Initialize various static tables. */
19807 if (inited)
19808 return;
19809
19810 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
19811 TCGV_UNUSED(cpu_gpr[0]);
19812 for (i = 1; i < 32; i++)
19813 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
19814 offsetof(CPUMIPSState, active_tc.gpr[i]),
19815 regnames[i]);
19816
19817 for (i = 0; i < 32; i++) {
19818 int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
19819 msa_wr_d[i * 2] =
19820 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2]);
19821 /* The scalar floating-point unit (FPU) registers are mapped on
19822 * the MSA vector registers. */
19823 fpu_f64[i] = msa_wr_d[i * 2];
19824 off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
19825 msa_wr_d[i * 2 + 1] =
19826 tcg_global_mem_new_i64(TCG_AREG0, off, msaregnames[i * 2 + 1]);
19827 }
19828
19829 cpu_PC = tcg_global_mem_new(TCG_AREG0,
19830 offsetof(CPUMIPSState, active_tc.PC), "PC");
19831 for (i = 0; i < MIPS_DSP_ACC; i++) {
19832 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
19833 offsetof(CPUMIPSState, active_tc.HI[i]),
19834 regnames_HI[i]);
19835 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
19836 offsetof(CPUMIPSState, active_tc.LO[i]),
19837 regnames_LO[i]);
19838 }
19839 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
19840 offsetof(CPUMIPSState, active_tc.DSPControl),
19841 "DSPControl");
19842 bcond = tcg_global_mem_new(TCG_AREG0,
19843 offsetof(CPUMIPSState, bcond), "bcond");
19844 btarget = tcg_global_mem_new(TCG_AREG0,
19845 offsetof(CPUMIPSState, btarget), "btarget");
19846 hflags = tcg_global_mem_new_i32(TCG_AREG0,
19847 offsetof(CPUMIPSState, hflags), "hflags");
19848
19849 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
19850 offsetof(CPUMIPSState, active_fpu.fcr0),
19851 "fcr0");
19852 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
19853 offsetof(CPUMIPSState, active_fpu.fcr31),
19854 "fcr31");
19855
19856 inited = 1;
19857 }
19858
19859 #include "translate_init.c"
19860
19861 MIPSCPU *cpu_mips_init(const char *cpu_model)
19862 {
19863 MIPSCPU *cpu;
19864 CPUMIPSState *env;
19865 const mips_def_t *def;
19866
19867 def = cpu_mips_find_by_name(cpu_model);
19868 if (!def)
19869 return NULL;
19870 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
19871 env = &cpu->env;
19872 env->cpu_model = def;
19873
19874 #ifndef CONFIG_USER_ONLY
19875 mmu_init(env, def);
19876 #endif
19877 fpu_init(env, def);
19878 mvp_init(env, def);
19879
19880 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
19881
19882 return cpu;
19883 }
19884
19885 void cpu_state_reset(CPUMIPSState *env)
19886 {
19887 MIPSCPU *cpu = mips_env_get_cpu(env);
19888 CPUState *cs = CPU(cpu);
19889
19890 /* Reset registers to their default values */
19891 env->CP0_PRid = env->cpu_model->CP0_PRid;
19892 env->CP0_Config0 = env->cpu_model->CP0_Config0;
19893 #ifdef TARGET_WORDS_BIGENDIAN
19894 env->CP0_Config0 |= (1 << CP0C0_BE);
19895 #endif
19896 env->CP0_Config1 = env->cpu_model->CP0_Config1;
19897 env->CP0_Config2 = env->cpu_model->CP0_Config2;
19898 env->CP0_Config3 = env->cpu_model->CP0_Config3;
19899 env->CP0_Config4 = env->cpu_model->CP0_Config4;
19900 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
19901 env->CP0_Config5 = env->cpu_model->CP0_Config5;
19902 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
19903 env->CP0_Config6 = env->cpu_model->CP0_Config6;
19904 env->CP0_Config7 = env->cpu_model->CP0_Config7;
19905 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
19906 << env->cpu_model->CP0_LLAddr_shift;
19907 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
19908 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
19909 env->CCRes = env->cpu_model->CCRes;
19910 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
19911 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
19912 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
19913 env->current_tc = 0;
19914 env->SEGBITS = env->cpu_model->SEGBITS;
19915 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
19916 #if defined(TARGET_MIPS64)
19917 if (env->cpu_model->insn_flags & ISA_MIPS3) {
19918 env->SEGMask |= 3ULL << 62;
19919 }
19920 #endif
19921 env->PABITS = env->cpu_model->PABITS;
19922 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
19923 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
19924 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
19925 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
19926 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
19927 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
19928 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
19929 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
19930 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
19931 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
19932 env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
19933 env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
19934 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
19935 env->msair = env->cpu_model->MSAIR;
19936 env->insn_flags = env->cpu_model->insn_flags;
19937
19938 #if defined(CONFIG_USER_ONLY)
19939 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
19940 # ifdef TARGET_MIPS64
19941 /* Enable 64-bit register mode. */
19942 env->CP0_Status |= (1 << CP0St_PX);
19943 # endif
19944 # ifdef TARGET_ABI_MIPSN64
19945 /* Enable 64-bit address mode. */
19946 env->CP0_Status |= (1 << CP0St_UX);
19947 # endif
19948 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19949 hardware registers. */
19950 env->CP0_HWREna |= 0x0000000F;
19951 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
19952 env->CP0_Status |= (1 << CP0St_CU1);
19953 }
19954 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
19955 env->CP0_Status |= (1 << CP0St_MX);
19956 }
19957 # if defined(TARGET_MIPS64)
19958 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19959 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
19960 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
19961 env->CP0_Status |= (1 << CP0St_FR);
19962 }
19963 # endif
19964 #else
19965 if (env->hflags & MIPS_HFLAG_BMASK) {
19966 /* If the exception was raised from a delay slot,
19967 come back to the jump. */
19968 env->CP0_ErrorEPC = (env->active_tc.PC
19969 - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
19970 } else {
19971 env->CP0_ErrorEPC = env->active_tc.PC;
19972 }
19973 env->active_tc.PC = (int32_t)0xBFC00000;
19974 env->CP0_Random = env->tlb->nb_tlb - 1;
19975 env->tlb->tlb_in_use = env->tlb->nb_tlb;
19976 env->CP0_Wired = 0;
19977 env->CP0_EBase = (cs->cpu_index & 0x3FF);
19978 if (kvm_enabled()) {
19979 env->CP0_EBase |= 0x40000000;
19980 } else {
19981 env->CP0_EBase |= 0x80000000;
19982 }
19983 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
19984 /* vectored interrupts not implemented, timer on int 7,
19985 no performance counters. */
19986 env->CP0_IntCtl = 0xe0000000;
19987 {
19988 int i;
19989
19990 for (i = 0; i < 7; i++) {
19991 env->CP0_WatchLo[i] = 0;
19992 env->CP0_WatchHi[i] = 0x80000000;
19993 }
19994 env->CP0_WatchLo[7] = 0;
19995 env->CP0_WatchHi[7] = 0;
19996 }
19997 /* Count register increments in debug mode, EJTAG version 1 */
19998 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
19999
20000 cpu_mips_store_count(env, 1);
20001
20002 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
20003 int i;
20004
20005 /* Only TC0 on VPE 0 starts as active. */
20006 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
20007 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
20008 env->tcs[i].CP0_TCHalt = 1;
20009 }
20010 env->active_tc.CP0_TCHalt = 1;
20011 cs->halted = 1;
20012
20013 if (cs->cpu_index == 0) {
20014 /* VPE0 starts up enabled. */
20015 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
20016 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
20017
20018 /* TC0 starts up unhalted. */
20019 cs->halted = 0;
20020 env->active_tc.CP0_TCHalt = 0;
20021 env->tcs[0].CP0_TCHalt = 0;
20022 /* With thread 0 active. */
20023 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
20024 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
20025 }
20026 }
20027 #endif
20028 if ((env->insn_flags & ISA_MIPS32R6) &&
20029 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
20030 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20031 env->CP0_Status |= (1 << CP0St_FR);
20032 }
20033
20034 /* MSA */
20035 if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
20036 msa_reset(env);
20037 }
20038
20039 compute_hflags(env);
20040 restore_rounding_mode(env);
20041 restore_flush_mode(env);
20042 restore_pamask(env);
20043 cs->exception_index = EXCP_NONE;
20044
20045 if (semihosting_get_argc()) {
20046 /* UHI interface can be used to obtain argc and argv */
20047 env->active_tc.gpr[4] = -1;
20048 }
20049 }
20050
20051 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
20052 target_ulong *data)
20053 {
20054 env->active_tc.PC = data[0];
20055 env->hflags &= ~MIPS_HFLAG_BMASK;
20056 env->hflags |= data[1];
20057 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
20058 case MIPS_HFLAG_BR:
20059 break;
20060 case MIPS_HFLAG_BC:
20061 case MIPS_HFLAG_BL:
20062 case MIPS_HFLAG_B:
20063 env->btarget = data[2];
20064 break;
20065 }
20066 }