]> git.proxmox.com Git - mirror_qemu.git/blob - target-mips/translate.c
target-mips: do not allow Status.FR=0 mode in 64-bit FPU
[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
33 #include "trace-tcg.h"
34
35
36 #define MIPS_DEBUG_DISAS 0
37 //#define MIPS_DEBUG_SIGN_EXTENSIONS
38
39 /* MIPS major opcodes */
40 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
41
42 enum {
43 /* indirect opcode tables */
44 OPC_SPECIAL = (0x00 << 26),
45 OPC_REGIMM = (0x01 << 26),
46 OPC_CP0 = (0x10 << 26),
47 OPC_CP1 = (0x11 << 26),
48 OPC_CP2 = (0x12 << 26),
49 OPC_CP3 = (0x13 << 26),
50 OPC_SPECIAL2 = (0x1C << 26),
51 OPC_SPECIAL3 = (0x1F << 26),
52 /* arithmetic with immediate */
53 OPC_ADDI = (0x08 << 26),
54 OPC_ADDIU = (0x09 << 26),
55 OPC_SLTI = (0x0A << 26),
56 OPC_SLTIU = (0x0B << 26),
57 /* logic with immediate */
58 OPC_ANDI = (0x0C << 26),
59 OPC_ORI = (0x0D << 26),
60 OPC_XORI = (0x0E << 26),
61 OPC_LUI = (0x0F << 26),
62 /* arithmetic with immediate */
63 OPC_DADDI = (0x18 << 26),
64 OPC_DADDIU = (0x19 << 26),
65 /* Jump and branches */
66 OPC_J = (0x02 << 26),
67 OPC_JAL = (0x03 << 26),
68 OPC_JALS = OPC_JAL | 0x5,
69 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
70 OPC_BEQL = (0x14 << 26),
71 OPC_BNE = (0x05 << 26),
72 OPC_BNEL = (0x15 << 26),
73 OPC_BLEZ = (0x06 << 26),
74 OPC_BLEZL = (0x16 << 26),
75 OPC_BGTZ = (0x07 << 26),
76 OPC_BGTZL = (0x17 << 26),
77 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
78 OPC_DAUI = (0x1D << 26),
79 OPC_JALXS = OPC_JALX | 0x5,
80 /* Load and stores */
81 OPC_LDL = (0x1A << 26),
82 OPC_LDR = (0x1B << 26),
83 OPC_LB = (0x20 << 26),
84 OPC_LH = (0x21 << 26),
85 OPC_LWL = (0x22 << 26),
86 OPC_LW = (0x23 << 26),
87 OPC_LWPC = OPC_LW | 0x5,
88 OPC_LBU = (0x24 << 26),
89 OPC_LHU = (0x25 << 26),
90 OPC_LWR = (0x26 << 26),
91 OPC_LWU = (0x27 << 26),
92 OPC_SB = (0x28 << 26),
93 OPC_SH = (0x29 << 26),
94 OPC_SWL = (0x2A << 26),
95 OPC_SW = (0x2B << 26),
96 OPC_SDL = (0x2C << 26),
97 OPC_SDR = (0x2D << 26),
98 OPC_SWR = (0x2E << 26),
99 OPC_LL = (0x30 << 26),
100 OPC_LLD = (0x34 << 26),
101 OPC_LD = (0x37 << 26),
102 OPC_LDPC = OPC_LD | 0x5,
103 OPC_SC = (0x38 << 26),
104 OPC_SCD = (0x3C << 26),
105 OPC_SD = (0x3F << 26),
106 /* Floating point load/store */
107 OPC_LWC1 = (0x31 << 26),
108 OPC_LWC2 = (0x32 << 26),
109 OPC_LDC1 = (0x35 << 26),
110 OPC_LDC2 = (0x36 << 26),
111 OPC_SWC1 = (0x39 << 26),
112 OPC_SWC2 = (0x3A << 26),
113 OPC_SDC1 = (0x3D << 26),
114 OPC_SDC2 = (0x3E << 26),
115 /* Compact Branches */
116 OPC_BLEZALC = (0x06 << 26),
117 OPC_BGEZALC = (0x06 << 26),
118 OPC_BGEUC = (0x06 << 26),
119 OPC_BGTZALC = (0x07 << 26),
120 OPC_BLTZALC = (0x07 << 26),
121 OPC_BLTUC = (0x07 << 26),
122 OPC_BOVC = (0x08 << 26),
123 OPC_BEQZALC = (0x08 << 26),
124 OPC_BEQC = (0x08 << 26),
125 OPC_BLEZC = (0x16 << 26),
126 OPC_BGEZC = (0x16 << 26),
127 OPC_BGEC = (0x16 << 26),
128 OPC_BGTZC = (0x17 << 26),
129 OPC_BLTZC = (0x17 << 26),
130 OPC_BLTC = (0x17 << 26),
131 OPC_BNVC = (0x18 << 26),
132 OPC_BNEZALC = (0x18 << 26),
133 OPC_BNEC = (0x18 << 26),
134 OPC_BC = (0x32 << 26),
135 OPC_BEQZC = (0x36 << 26),
136 OPC_JIC = (0x36 << 26),
137 OPC_BALC = (0x3A << 26),
138 OPC_BNEZC = (0x3E << 26),
139 OPC_JIALC = (0x3E << 26),
140 /* MDMX ASE specific */
141 OPC_MDMX = (0x1E << 26),
142 /* Cache and prefetch */
143 OPC_CACHE = (0x2F << 26),
144 OPC_PREF = (0x33 << 26),
145 /* PC-relative address computation / loads */
146 OPC_PCREL = (0x3B << 26),
147 };
148
149 /* PC-relative address computation / loads */
150 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
151 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
152 enum {
153 /* Instructions determined by bits 19 and 20 */
154 OPC_ADDIUPC = OPC_PCREL | (0 << 19),
155 R6_OPC_LWPC = OPC_PCREL | (1 << 19),
156 OPC_LWUPC = OPC_PCREL | (2 << 19),
157
158 /* Instructions determined by bits 16 ... 20 */
159 OPC_AUIPC = OPC_PCREL | (0x1e << 16),
160 OPC_ALUIPC = OPC_PCREL | (0x1f << 16),
161
162 /* Other */
163 R6_OPC_LDPC = OPC_PCREL | (6 << 18),
164 };
165
166 /* MIPS special opcodes */
167 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
168
169 enum {
170 /* Shifts */
171 OPC_SLL = 0x00 | OPC_SPECIAL,
172 /* NOP is SLL r0, r0, 0 */
173 /* SSNOP is SLL r0, r0, 1 */
174 /* EHB is SLL r0, r0, 3 */
175 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
176 OPC_ROTR = OPC_SRL | (1 << 21),
177 OPC_SRA = 0x03 | OPC_SPECIAL,
178 OPC_SLLV = 0x04 | OPC_SPECIAL,
179 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
180 OPC_ROTRV = OPC_SRLV | (1 << 6),
181 OPC_SRAV = 0x07 | OPC_SPECIAL,
182 OPC_DSLLV = 0x14 | OPC_SPECIAL,
183 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
184 OPC_DROTRV = OPC_DSRLV | (1 << 6),
185 OPC_DSRAV = 0x17 | OPC_SPECIAL,
186 OPC_DSLL = 0x38 | OPC_SPECIAL,
187 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
188 OPC_DROTR = OPC_DSRL | (1 << 21),
189 OPC_DSRA = 0x3B | OPC_SPECIAL,
190 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
191 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
192 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
193 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
194 /* Multiplication / division */
195 OPC_MULT = 0x18 | OPC_SPECIAL,
196 OPC_MULTU = 0x19 | OPC_SPECIAL,
197 OPC_DIV = 0x1A | OPC_SPECIAL,
198 OPC_DIVU = 0x1B | OPC_SPECIAL,
199 OPC_DMULT = 0x1C | OPC_SPECIAL,
200 OPC_DMULTU = 0x1D | OPC_SPECIAL,
201 OPC_DDIV = 0x1E | OPC_SPECIAL,
202 OPC_DDIVU = 0x1F | OPC_SPECIAL,
203
204 /* 2 registers arithmetic / logic */
205 OPC_ADD = 0x20 | OPC_SPECIAL,
206 OPC_ADDU = 0x21 | OPC_SPECIAL,
207 OPC_SUB = 0x22 | OPC_SPECIAL,
208 OPC_SUBU = 0x23 | OPC_SPECIAL,
209 OPC_AND = 0x24 | OPC_SPECIAL,
210 OPC_OR = 0x25 | OPC_SPECIAL,
211 OPC_XOR = 0x26 | OPC_SPECIAL,
212 OPC_NOR = 0x27 | OPC_SPECIAL,
213 OPC_SLT = 0x2A | OPC_SPECIAL,
214 OPC_SLTU = 0x2B | OPC_SPECIAL,
215 OPC_DADD = 0x2C | OPC_SPECIAL,
216 OPC_DADDU = 0x2D | OPC_SPECIAL,
217 OPC_DSUB = 0x2E | OPC_SPECIAL,
218 OPC_DSUBU = 0x2F | OPC_SPECIAL,
219 /* Jumps */
220 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
221 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
222 OPC_JALRC = OPC_JALR | (0x5 << 6),
223 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
224 /* Traps */
225 OPC_TGE = 0x30 | OPC_SPECIAL,
226 OPC_TGEU = 0x31 | OPC_SPECIAL,
227 OPC_TLT = 0x32 | OPC_SPECIAL,
228 OPC_TLTU = 0x33 | OPC_SPECIAL,
229 OPC_TEQ = 0x34 | OPC_SPECIAL,
230 OPC_TNE = 0x36 | OPC_SPECIAL,
231 /* HI / LO registers load & stores */
232 OPC_MFHI = 0x10 | OPC_SPECIAL,
233 OPC_MTHI = 0x11 | OPC_SPECIAL,
234 OPC_MFLO = 0x12 | OPC_SPECIAL,
235 OPC_MTLO = 0x13 | OPC_SPECIAL,
236 /* Conditional moves */
237 OPC_MOVZ = 0x0A | OPC_SPECIAL,
238 OPC_MOVN = 0x0B | OPC_SPECIAL,
239
240 OPC_SELEQZ = 0x35 | OPC_SPECIAL,
241 OPC_SELNEZ = 0x37 | OPC_SPECIAL,
242
243 OPC_MOVCI = 0x01 | OPC_SPECIAL,
244
245 /* Special */
246 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
247 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
248 OPC_BREAK = 0x0D | OPC_SPECIAL,
249 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
250 OPC_SYNC = 0x0F | OPC_SPECIAL,
251
252 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
253 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
254 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
255 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
256 };
257
258 /* R6 Multiply and Divide instructions have the same Opcode
259 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
260 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
261
262 enum {
263 R6_OPC_MUL = OPC_MULT | (2 << 6),
264 R6_OPC_MUH = OPC_MULT | (3 << 6),
265 R6_OPC_MULU = OPC_MULTU | (2 << 6),
266 R6_OPC_MUHU = OPC_MULTU | (3 << 6),
267 R6_OPC_DIV = OPC_DIV | (2 << 6),
268 R6_OPC_MOD = OPC_DIV | (3 << 6),
269 R6_OPC_DIVU = OPC_DIVU | (2 << 6),
270 R6_OPC_MODU = OPC_DIVU | (3 << 6),
271
272 R6_OPC_DMUL = OPC_DMULT | (2 << 6),
273 R6_OPC_DMUH = OPC_DMULT | (3 << 6),
274 R6_OPC_DMULU = OPC_DMULTU | (2 << 6),
275 R6_OPC_DMUHU = OPC_DMULTU | (3 << 6),
276 R6_OPC_DDIV = OPC_DDIV | (2 << 6),
277 R6_OPC_DMOD = OPC_DDIV | (3 << 6),
278 R6_OPC_DDIVU = OPC_DDIVU | (2 << 6),
279 R6_OPC_DMODU = OPC_DDIVU | (3 << 6),
280
281 R6_OPC_CLZ = 0x10 | OPC_SPECIAL,
282 R6_OPC_CLO = 0x11 | OPC_SPECIAL,
283 R6_OPC_DCLZ = 0x12 | OPC_SPECIAL,
284 R6_OPC_DCLO = 0x13 | OPC_SPECIAL,
285 R6_OPC_SDBBP = 0x0e | OPC_SPECIAL,
286
287 OPC_LSA = 0x05 | OPC_SPECIAL,
288 OPC_DLSA = 0x15 | OPC_SPECIAL,
289 };
290
291 /* Multiplication variants of the vr54xx. */
292 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
293
294 enum {
295 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
296 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
297 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
298 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
299 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
300 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
301 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
302 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
303 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
304 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
305 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
306 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
307 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
308 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
309 };
310
311 /* REGIMM (rt field) opcodes */
312 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
313
314 enum {
315 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
316 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
317 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
318 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
319 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
320 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
321 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
322 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
323 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
324 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
325 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
326 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
327 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
328 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
329 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
330 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
331 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
332
333 OPC_DAHI = (0x06 << 16) | OPC_REGIMM,
334 OPC_DATI = (0x1e << 16) | OPC_REGIMM,
335 };
336
337 /* Special2 opcodes */
338 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
339
340 enum {
341 /* Multiply & xxx operations */
342 OPC_MADD = 0x00 | OPC_SPECIAL2,
343 OPC_MADDU = 0x01 | OPC_SPECIAL2,
344 OPC_MUL = 0x02 | OPC_SPECIAL2,
345 OPC_MSUB = 0x04 | OPC_SPECIAL2,
346 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
347 /* Loongson 2F */
348 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
349 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
350 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
351 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
352 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
353 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
354 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
355 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
356 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
357 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
358 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
359 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
360 /* Misc */
361 OPC_CLZ = 0x20 | OPC_SPECIAL2,
362 OPC_CLO = 0x21 | OPC_SPECIAL2,
363 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
364 OPC_DCLO = 0x25 | OPC_SPECIAL2,
365 /* Special */
366 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
367 };
368
369 /* Special3 opcodes */
370 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
371
372 enum {
373 OPC_EXT = 0x00 | OPC_SPECIAL3,
374 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
375 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
376 OPC_DEXT = 0x03 | OPC_SPECIAL3,
377 OPC_INS = 0x04 | OPC_SPECIAL3,
378 OPC_DINSM = 0x05 | OPC_SPECIAL3,
379 OPC_DINSU = 0x06 | OPC_SPECIAL3,
380 OPC_DINS = 0x07 | OPC_SPECIAL3,
381 OPC_FORK = 0x08 | OPC_SPECIAL3,
382 OPC_YIELD = 0x09 | OPC_SPECIAL3,
383 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
384 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
385 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
386
387 /* Loongson 2E */
388 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
389 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
390 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
391 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
392 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
393 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
394 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
395 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
396 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
397 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
398 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
399 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
400
401 /* MIPS DSP Load */
402 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
403 /* MIPS DSP Arithmetic */
404 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
405 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
406 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
407 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
408 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
409 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
410 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
411 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
412 /* MIPS DSP GPR-Based Shift Sub-class */
413 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
414 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
415 /* MIPS DSP Multiply Sub-class insns */
416 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
417 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
418 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
419 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
420 /* DSP Bit/Manipulation Sub-class */
421 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
422 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
423 /* MIPS DSP Append Sub-class */
424 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
425 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
426 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
427 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
428 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
429
430 /* R6 */
431 R6_OPC_PREF = 0x35 | OPC_SPECIAL3,
432 R6_OPC_CACHE = 0x25 | OPC_SPECIAL3,
433 R6_OPC_LL = 0x36 | OPC_SPECIAL3,
434 R6_OPC_SC = 0x26 | OPC_SPECIAL3,
435 R6_OPC_LLD = 0x37 | OPC_SPECIAL3,
436 R6_OPC_SCD = 0x27 | OPC_SPECIAL3,
437 };
438
439 /* BSHFL opcodes */
440 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
441
442 enum {
443 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
444 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
445 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
446 OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
447 OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
448 OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 00000 */
449 };
450
451 /* DBSHFL opcodes */
452 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
453
454 enum {
455 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
456 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
457 OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
458 OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
459 OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
460 };
461
462 /* MIPS DSP REGIMM opcodes */
463 enum {
464 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
465 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
466 };
467
468 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
469 /* MIPS DSP Load */
470 enum {
471 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
472 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
473 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
474 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
475 };
476
477 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
478 enum {
479 /* MIPS DSP Arithmetic Sub-class */
480 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
481 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
482 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
483 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
484 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
485 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
486 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
487 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
488 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
489 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
490 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
491 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
492 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
493 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
494 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
495 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
496 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
497 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
498 /* MIPS DSP Multiply Sub-class insns */
499 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
500 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
501 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
502 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
503 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
504 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
505 };
506
507 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
508 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
509 enum {
510 /* MIPS DSP Arithmetic Sub-class */
511 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
512 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
513 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
514 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
515 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
516 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
517 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
518 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
519 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
520 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
521 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
522 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
523 /* MIPS DSP Multiply Sub-class insns */
524 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
525 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
526 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
527 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
528 };
529
530 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
531 enum {
532 /* MIPS DSP Arithmetic Sub-class */
533 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
534 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
535 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
536 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
537 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
538 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
539 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
540 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
541 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
542 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
543 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
544 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
545 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
546 /* DSP Bit/Manipulation Sub-class */
547 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
548 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
549 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
550 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
551 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
552 };
553
554 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
555 enum {
556 /* MIPS DSP Arithmetic Sub-class */
557 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
558 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
559 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
560 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
561 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
562 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
563 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
564 /* DSP Compare-Pick Sub-class */
565 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
566 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
567 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
568 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
569 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
570 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
571 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
572 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
573 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
574 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
575 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
576 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
577 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
578 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
579 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
580 };
581
582 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583 enum {
584 /* MIPS DSP GPR-Based Shift Sub-class */
585 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
586 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
587 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
588 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
589 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
590 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
591 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
592 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
593 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
594 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
595 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
596 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
597 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
598 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
599 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
600 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
601 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
602 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
603 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
604 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
605 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
606 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
607 };
608
609 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
610 enum {
611 /* MIPS DSP Multiply Sub-class insns */
612 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
613 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
614 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
615 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
616 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
617 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
618 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
619 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
620 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
621 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
622 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
623 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
624 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
625 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
626 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
627 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
628 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
629 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
630 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
631 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
632 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
633 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
634 };
635
636 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 enum {
638 /* DSP Bit/Manipulation Sub-class */
639 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
640 };
641
642 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
643 enum {
644 /* MIPS DSP Append Sub-class */
645 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
646 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
647 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
648 };
649
650 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
651 enum {
652 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
653 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
654 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
655 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
656 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
657 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
658 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
659 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
660 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
661 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
662 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
663 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
664 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
665 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
666 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
667 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
668 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
669 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
670 };
671
672 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673 enum {
674 /* MIPS DSP Arithmetic Sub-class */
675 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
676 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
677 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
678 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
679 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
680 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
681 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
682 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
683 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
684 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
685 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
686 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
687 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
688 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
689 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
690 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
691 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
692 /* DSP Bit/Manipulation Sub-class */
693 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
694 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
695 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
696 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
697 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
698 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
699 };
700
701 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
702 enum {
703 /* MIPS DSP Multiply Sub-class insns */
704 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
705 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
706 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
707 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
708 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
709 /* MIPS DSP Arithmetic Sub-class */
710 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
711 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
712 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
713 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
714 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
715 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
716 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
717 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
718 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
719 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
720 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
721 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
722 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
723 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
724 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
725 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
726 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
727 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
728 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
729 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
730 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
731 };
732
733 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
734 enum {
735 /* DSP Compare-Pick Sub-class */
736 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
737 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
738 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
739 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
740 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
741 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
742 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
743 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
744 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
745 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
746 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
747 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
748 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
749 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
750 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
751 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
752 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
753 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
754 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
755 /* MIPS DSP Arithmetic Sub-class */
756 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
757 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
758 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
759 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
760 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
761 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
762 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
763 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
764 };
765
766 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
767 enum {
768 /* DSP Append Sub-class */
769 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
770 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
771 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
772 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
773 };
774
775 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
776 enum {
777 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
778 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
779 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
780 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
781 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
782 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
783 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
784 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
785 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
786 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
787 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
788 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
789 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
790 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
791 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
792 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
793 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
794 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
795 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
796 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
797 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
798 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
799 };
800
801 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
802 enum {
803 /* DSP Bit/Manipulation Sub-class */
804 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
805 };
806
807 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
808 enum {
809 /* MIPS DSP Multiply Sub-class insns */
810 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
811 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
812 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
813 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
814 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
815 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
816 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
817 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
818 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
819 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
820 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
821 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
822 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
823 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
824 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
825 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
826 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
827 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
828 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
829 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
830 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
831 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
832 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
833 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
834 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
835 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
836 };
837
838 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
839 enum {
840 /* MIPS DSP GPR-Based Shift Sub-class */
841 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
842 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
843 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
844 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
845 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
846 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
847 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
848 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
849 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
850 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
851 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
852 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
853 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
854 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
855 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
856 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
857 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
858 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
859 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
860 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
861 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
862 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
863 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
864 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
865 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
866 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
867 };
868
869 /* Coprocessor 0 (rs field) */
870 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
871
872 enum {
873 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
874 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
875 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
876 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
877 OPC_MFTR = (0x08 << 21) | OPC_CP0,
878 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
879 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
880 OPC_MTTR = (0x0C << 21) | OPC_CP0,
881 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
882 OPC_C0 = (0x10 << 21) | OPC_CP0,
883 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
884 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
885 };
886
887 /* MFMC0 opcodes */
888 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
889
890 enum {
891 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
892 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
893 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
894 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
895 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
896 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
897 };
898
899 /* Coprocessor 0 (with rs == C0) */
900 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
901
902 enum {
903 OPC_TLBR = 0x01 | OPC_C0,
904 OPC_TLBWI = 0x02 | OPC_C0,
905 OPC_TLBWR = 0x06 | OPC_C0,
906 OPC_TLBP = 0x08 | OPC_C0,
907 OPC_RFE = 0x10 | OPC_C0,
908 OPC_ERET = 0x18 | OPC_C0,
909 OPC_DERET = 0x1F | OPC_C0,
910 OPC_WAIT = 0x20 | OPC_C0,
911 };
912
913 /* Coprocessor 1 (rs field) */
914 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
915
916 /* Values for the fmt field in FP instructions */
917 enum {
918 /* 0 - 15 are reserved */
919 FMT_S = 16, /* single fp */
920 FMT_D = 17, /* double fp */
921 FMT_E = 18, /* extended fp */
922 FMT_Q = 19, /* quad fp */
923 FMT_W = 20, /* 32-bit fixed */
924 FMT_L = 21, /* 64-bit fixed */
925 FMT_PS = 22, /* paired single fp */
926 /* 23 - 31 are reserved */
927 };
928
929 enum {
930 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
931 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
932 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
933 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
934 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
935 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
936 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
937 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
938 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
939 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
940 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
941 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
942 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
943 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
944 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
945 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
946 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
947 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
948 OPC_BC1EQZ = (0x09 << 21) | OPC_CP1,
949 OPC_BC1NEZ = (0x0D << 21) | OPC_CP1,
950 };
951
952 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
953 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
954
955 enum {
956 OPC_BC1F = (0x00 << 16) | OPC_BC1,
957 OPC_BC1T = (0x01 << 16) | OPC_BC1,
958 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
959 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
960 };
961
962 enum {
963 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
964 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
965 };
966
967 enum {
968 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
969 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
970 };
971
972 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
973
974 enum {
975 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
976 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
977 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
978 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
979 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
980 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
981 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
982 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
983 OPC_BC2 = (0x08 << 21) | OPC_CP2,
984 OPC_BC2EQZ = (0x09 << 21) | OPC_CP2,
985 OPC_BC2NEZ = (0x0D << 21) | OPC_CP2,
986 };
987
988 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
989
990 enum {
991 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
992 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
993 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
994 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
995 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
996 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
997 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
998 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
999
1000 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
1001 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1002 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
1003 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
1004 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
1005 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1006 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
1007 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
1008
1009 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
1010 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1011 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1012 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1013 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
1014 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
1015 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
1016 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
1017
1018 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1019 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1020 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1021 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1022 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
1023 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
1024 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
1025 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
1026
1027 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
1028 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
1029 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
1030 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
1031 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
1032 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
1033
1034 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1035 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1036 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1037 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1038 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1039 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1040
1041 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
1042 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
1043 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
1044 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
1045 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
1046 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1047
1048 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
1049 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
1050 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
1051 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
1052 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1053 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1054
1055 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1056 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
1057 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
1058 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1059 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1060 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
1061
1062 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1063 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
1064 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
1065 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1066 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1067 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
1068
1069 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
1070 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1071 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
1072 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
1073 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1074 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
1075
1076 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
1077 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1078 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
1079 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1080 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
1081 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1082 };
1083
1084
1085 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1086
1087 enum {
1088 OPC_LWXC1 = 0x00 | OPC_CP3,
1089 OPC_LDXC1 = 0x01 | OPC_CP3,
1090 OPC_LUXC1 = 0x05 | OPC_CP3,
1091 OPC_SWXC1 = 0x08 | OPC_CP3,
1092 OPC_SDXC1 = 0x09 | OPC_CP3,
1093 OPC_SUXC1 = 0x0D | OPC_CP3,
1094 OPC_PREFX = 0x0F | OPC_CP3,
1095 OPC_ALNV_PS = 0x1E | OPC_CP3,
1096 OPC_MADD_S = 0x20 | OPC_CP3,
1097 OPC_MADD_D = 0x21 | OPC_CP3,
1098 OPC_MADD_PS = 0x26 | OPC_CP3,
1099 OPC_MSUB_S = 0x28 | OPC_CP3,
1100 OPC_MSUB_D = 0x29 | OPC_CP3,
1101 OPC_MSUB_PS = 0x2E | OPC_CP3,
1102 OPC_NMADD_S = 0x30 | OPC_CP3,
1103 OPC_NMADD_D = 0x31 | OPC_CP3,
1104 OPC_NMADD_PS= 0x36 | OPC_CP3,
1105 OPC_NMSUB_S = 0x38 | OPC_CP3,
1106 OPC_NMSUB_D = 0x39 | OPC_CP3,
1107 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1108 };
1109
1110 /* global register indices */
1111 static TCGv_ptr cpu_env;
1112 static TCGv cpu_gpr[32], cpu_PC;
1113 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1114 static TCGv cpu_dspctrl, btarget, bcond;
1115 static TCGv_i32 hflags;
1116 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1117 static TCGv_i64 fpu_f64[32];
1118
1119 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1120 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1121
1122 #include "exec/gen-icount.h"
1123
1124 #define gen_helper_0e0i(name, arg) do { \
1125 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1126 gen_helper_##name(cpu_env, helper_tmp); \
1127 tcg_temp_free_i32(helper_tmp); \
1128 } while(0)
1129
1130 #define gen_helper_0e1i(name, arg1, arg2) do { \
1131 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1132 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1133 tcg_temp_free_i32(helper_tmp); \
1134 } while(0)
1135
1136 #define gen_helper_1e0i(name, ret, arg1) do { \
1137 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1138 gen_helper_##name(ret, cpu_env, helper_tmp); \
1139 tcg_temp_free_i32(helper_tmp); \
1140 } while(0)
1141
1142 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1143 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1144 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1145 tcg_temp_free_i32(helper_tmp); \
1146 } while(0)
1147
1148 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1149 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1150 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1151 tcg_temp_free_i32(helper_tmp); \
1152 } while(0)
1153
1154 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1155 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1156 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1157 tcg_temp_free_i32(helper_tmp); \
1158 } while(0)
1159
1160 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1161 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1162 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1163 tcg_temp_free_i32(helper_tmp); \
1164 } while(0)
1165
1166 typedef struct DisasContext {
1167 struct TranslationBlock *tb;
1168 target_ulong pc, saved_pc;
1169 uint32_t opcode;
1170 int singlestep_enabled;
1171 int insn_flags;
1172 int32_t CP0_Config1;
1173 /* Routine used to access memory */
1174 int mem_idx;
1175 uint32_t hflags, saved_hflags;
1176 int bstate;
1177 target_ulong btarget;
1178 bool ulri;
1179 } DisasContext;
1180
1181 enum {
1182 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1183 * exception condition */
1184 BS_STOP = 1, /* We want to stop translation for any reason */
1185 BS_BRANCH = 2, /* We reached a branch condition */
1186 BS_EXCP = 3, /* We reached an exception condition */
1187 };
1188
1189 static const char * const regnames[] = {
1190 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1191 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1192 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1193 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1194 };
1195
1196 static const char * const regnames_HI[] = {
1197 "HI0", "HI1", "HI2", "HI3",
1198 };
1199
1200 static const char * const regnames_LO[] = {
1201 "LO0", "LO1", "LO2", "LO3",
1202 };
1203
1204 static const char * const regnames_ACX[] = {
1205 "ACX0", "ACX1", "ACX2", "ACX3",
1206 };
1207
1208 static const char * const fregnames[] = {
1209 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1210 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1211 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1212 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1213 };
1214
1215 #define MIPS_DEBUG(fmt, ...) \
1216 do { \
1217 if (MIPS_DEBUG_DISAS) { \
1218 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1219 TARGET_FMT_lx ": %08x " fmt "\n", \
1220 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1221 } \
1222 } while (0)
1223
1224 #define LOG_DISAS(...) \
1225 do { \
1226 if (MIPS_DEBUG_DISAS) { \
1227 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1228 } \
1229 } while (0)
1230
1231 #define MIPS_INVAL(op) \
1232 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1233 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1234
1235 /* General purpose registers moves. */
1236 static inline void gen_load_gpr (TCGv t, int reg)
1237 {
1238 if (reg == 0)
1239 tcg_gen_movi_tl(t, 0);
1240 else
1241 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1242 }
1243
1244 static inline void gen_store_gpr (TCGv t, int reg)
1245 {
1246 if (reg != 0)
1247 tcg_gen_mov_tl(cpu_gpr[reg], t);
1248 }
1249
1250 /* Moves to/from ACX register. */
1251 static inline void gen_load_ACX (TCGv t, int reg)
1252 {
1253 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1254 }
1255
1256 static inline void gen_store_ACX (TCGv t, int reg)
1257 {
1258 tcg_gen_mov_tl(cpu_ACX[reg], t);
1259 }
1260
1261 /* Moves to/from shadow registers. */
1262 static inline void gen_load_srsgpr (int from, int to)
1263 {
1264 TCGv t0 = tcg_temp_new();
1265
1266 if (from == 0)
1267 tcg_gen_movi_tl(t0, 0);
1268 else {
1269 TCGv_i32 t2 = tcg_temp_new_i32();
1270 TCGv_ptr addr = tcg_temp_new_ptr();
1271
1272 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1273 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1274 tcg_gen_andi_i32(t2, t2, 0xf);
1275 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1276 tcg_gen_ext_i32_ptr(addr, t2);
1277 tcg_gen_add_ptr(addr, cpu_env, addr);
1278
1279 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1280 tcg_temp_free_ptr(addr);
1281 tcg_temp_free_i32(t2);
1282 }
1283 gen_store_gpr(t0, to);
1284 tcg_temp_free(t0);
1285 }
1286
1287 static inline void gen_store_srsgpr (int from, int to)
1288 {
1289 if (to != 0) {
1290 TCGv t0 = tcg_temp_new();
1291 TCGv_i32 t2 = tcg_temp_new_i32();
1292 TCGv_ptr addr = tcg_temp_new_ptr();
1293
1294 gen_load_gpr(t0, from);
1295 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1296 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1297 tcg_gen_andi_i32(t2, t2, 0xf);
1298 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1299 tcg_gen_ext_i32_ptr(addr, t2);
1300 tcg_gen_add_ptr(addr, cpu_env, addr);
1301
1302 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1303 tcg_temp_free_ptr(addr);
1304 tcg_temp_free_i32(t2);
1305 tcg_temp_free(t0);
1306 }
1307 }
1308
1309 /* Floating point register moves. */
1310 static void gen_load_fpr32(TCGv_i32 t, int reg)
1311 {
1312 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1313 }
1314
1315 static void gen_store_fpr32(TCGv_i32 t, int reg)
1316 {
1317 TCGv_i64 t64 = tcg_temp_new_i64();
1318 tcg_gen_extu_i32_i64(t64, t);
1319 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1320 tcg_temp_free_i64(t64);
1321 }
1322
1323 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1324 {
1325 if (ctx->hflags & MIPS_HFLAG_F64) {
1326 TCGv_i64 t64 = tcg_temp_new_i64();
1327 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1328 tcg_gen_trunc_i64_i32(t, t64);
1329 tcg_temp_free_i64(t64);
1330 } else {
1331 gen_load_fpr32(t, reg | 1);
1332 }
1333 }
1334
1335 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1336 {
1337 if (ctx->hflags & MIPS_HFLAG_F64) {
1338 TCGv_i64 t64 = tcg_temp_new_i64();
1339 tcg_gen_extu_i32_i64(t64, t);
1340 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1341 tcg_temp_free_i64(t64);
1342 } else {
1343 gen_store_fpr32(t, reg | 1);
1344 }
1345 }
1346
1347 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1348 {
1349 if (ctx->hflags & MIPS_HFLAG_F64) {
1350 tcg_gen_mov_i64(t, fpu_f64[reg]);
1351 } else {
1352 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1353 }
1354 }
1355
1356 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1357 {
1358 if (ctx->hflags & MIPS_HFLAG_F64) {
1359 tcg_gen_mov_i64(fpu_f64[reg], t);
1360 } else {
1361 TCGv_i64 t0;
1362 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1363 t0 = tcg_temp_new_i64();
1364 tcg_gen_shri_i64(t0, t, 32);
1365 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1366 tcg_temp_free_i64(t0);
1367 }
1368 }
1369
1370 static inline int get_fp_bit (int cc)
1371 {
1372 if (cc)
1373 return 24 + cc;
1374 else
1375 return 23;
1376 }
1377
1378 /* Tests */
1379 static inline void gen_save_pc(target_ulong pc)
1380 {
1381 tcg_gen_movi_tl(cpu_PC, pc);
1382 }
1383
1384 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1385 {
1386 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1387 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1388 gen_save_pc(ctx->pc);
1389 ctx->saved_pc = ctx->pc;
1390 }
1391 if (ctx->hflags != ctx->saved_hflags) {
1392 tcg_gen_movi_i32(hflags, ctx->hflags);
1393 ctx->saved_hflags = ctx->hflags;
1394 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1395 case MIPS_HFLAG_BR:
1396 break;
1397 case MIPS_HFLAG_BC:
1398 case MIPS_HFLAG_BL:
1399 case MIPS_HFLAG_B:
1400 tcg_gen_movi_tl(btarget, ctx->btarget);
1401 break;
1402 }
1403 }
1404 }
1405
1406 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1407 {
1408 ctx->saved_hflags = ctx->hflags;
1409 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1410 case MIPS_HFLAG_BR:
1411 break;
1412 case MIPS_HFLAG_BC:
1413 case MIPS_HFLAG_BL:
1414 case MIPS_HFLAG_B:
1415 ctx->btarget = env->btarget;
1416 break;
1417 }
1418 }
1419
1420 static inline void
1421 generate_exception_err (DisasContext *ctx, int excp, int err)
1422 {
1423 TCGv_i32 texcp = tcg_const_i32(excp);
1424 TCGv_i32 terr = tcg_const_i32(err);
1425 save_cpu_state(ctx, 1);
1426 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1427 tcg_temp_free_i32(terr);
1428 tcg_temp_free_i32(texcp);
1429 }
1430
1431 static inline void
1432 generate_exception (DisasContext *ctx, int excp)
1433 {
1434 save_cpu_state(ctx, 1);
1435 gen_helper_0e0i(raise_exception, excp);
1436 }
1437
1438 /* Addresses computation */
1439 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1440 {
1441 tcg_gen_add_tl(ret, arg0, arg1);
1442
1443 #if defined(TARGET_MIPS64)
1444 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1445 tcg_gen_ext32s_i64(ret, ret);
1446 }
1447 #endif
1448 }
1449
1450 /* Addresses computation (translation time) */
1451 static target_long addr_add(DisasContext *ctx, target_long base,
1452 target_long offset)
1453 {
1454 target_long sum = base + offset;
1455
1456 #if defined(TARGET_MIPS64)
1457 if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1458 sum = (int32_t)sum;
1459 }
1460 #endif
1461 return sum;
1462 }
1463
1464 static inline void check_cp0_enabled(DisasContext *ctx)
1465 {
1466 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1467 generate_exception_err(ctx, EXCP_CpU, 0);
1468 }
1469
1470 static inline void check_cp1_enabled(DisasContext *ctx)
1471 {
1472 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1473 generate_exception_err(ctx, EXCP_CpU, 1);
1474 }
1475
1476 /* Verify that the processor is running with COP1X instructions enabled.
1477 This is associated with the nabla symbol in the MIPS32 and MIPS64
1478 opcode tables. */
1479
1480 static inline void check_cop1x(DisasContext *ctx)
1481 {
1482 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1483 generate_exception(ctx, EXCP_RI);
1484 }
1485
1486 /* Verify that the processor is running with 64-bit floating-point
1487 operations enabled. */
1488
1489 static inline void check_cp1_64bitmode(DisasContext *ctx)
1490 {
1491 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1492 generate_exception(ctx, EXCP_RI);
1493 }
1494
1495 /*
1496 * Verify if floating point register is valid; an operation is not defined
1497 * if bit 0 of any register specification is set and the FR bit in the
1498 * Status register equals zero, since the register numbers specify an
1499 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1500 * in the Status register equals one, both even and odd register numbers
1501 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1502 *
1503 * Multiple 64 bit wide registers can be checked by calling
1504 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1505 */
1506 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1507 {
1508 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1509 generate_exception(ctx, EXCP_RI);
1510 }
1511
1512 /* Verify that the processor is running with DSP instructions enabled.
1513 This is enabled by CP0 Status register MX(24) bit.
1514 */
1515
1516 static inline void check_dsp(DisasContext *ctx)
1517 {
1518 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1519 if (ctx->insn_flags & ASE_DSP) {
1520 generate_exception(ctx, EXCP_DSPDIS);
1521 } else {
1522 generate_exception(ctx, EXCP_RI);
1523 }
1524 }
1525 }
1526
1527 static inline void check_dspr2(DisasContext *ctx)
1528 {
1529 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1530 if (ctx->insn_flags & ASE_DSP) {
1531 generate_exception(ctx, EXCP_DSPDIS);
1532 } else {
1533 generate_exception(ctx, EXCP_RI);
1534 }
1535 }
1536 }
1537
1538 /* This code generates a "reserved instruction" exception if the
1539 CPU does not support the instruction set corresponding to flags. */
1540 static inline void check_insn(DisasContext *ctx, int flags)
1541 {
1542 if (unlikely(!(ctx->insn_flags & flags))) {
1543 generate_exception(ctx, EXCP_RI);
1544 }
1545 }
1546
1547 /* This code generates a "reserved instruction" exception if the
1548 CPU has corresponding flag set which indicates that the instruction
1549 has been removed. */
1550 static inline void check_insn_opc_removed(DisasContext *ctx, int flags)
1551 {
1552 if (unlikely(ctx->insn_flags & flags)) {
1553 generate_exception(ctx, EXCP_RI);
1554 }
1555 }
1556
1557 /* This code generates a "reserved instruction" exception if 64-bit
1558 instructions are not enabled. */
1559 static inline void check_mips_64(DisasContext *ctx)
1560 {
1561 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1562 generate_exception(ctx, EXCP_RI);
1563 }
1564
1565 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1566 calling interface for 32 and 64-bit FPRs. No sense in changing
1567 all callers for gen_load_fpr32 when we need the CTX parameter for
1568 this one use. */
1569 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1570 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1571 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1572 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1573 int ft, int fs, int cc) \
1574 { \
1575 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1576 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1577 switch (ifmt) { \
1578 case FMT_PS: \
1579 check_cp1_64bitmode(ctx); \
1580 break; \
1581 case FMT_D: \
1582 if (abs) { \
1583 check_cop1x(ctx); \
1584 } \
1585 check_cp1_registers(ctx, fs | ft); \
1586 break; \
1587 case FMT_S: \
1588 if (abs) { \
1589 check_cop1x(ctx); \
1590 } \
1591 break; \
1592 } \
1593 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1594 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1595 switch (n) { \
1596 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1597 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1598 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1599 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1600 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1601 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1602 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1603 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1604 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1605 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1606 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1607 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1608 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1609 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1610 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1611 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1612 default: abort(); \
1613 } \
1614 tcg_temp_free_i##bits (fp0); \
1615 tcg_temp_free_i##bits (fp1); \
1616 }
1617
1618 FOP_CONDS(, 0, d, FMT_D, 64)
1619 FOP_CONDS(abs, 1, d, FMT_D, 64)
1620 FOP_CONDS(, 0, s, FMT_S, 32)
1621 FOP_CONDS(abs, 1, s, FMT_S, 32)
1622 FOP_CONDS(, 0, ps, FMT_PS, 64)
1623 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1624 #undef FOP_CONDS
1625
1626 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1627 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1628 int ft, int fs, int fd) \
1629 { \
1630 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1631 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1632 switch (ifmt) { \
1633 case FMT_D: \
1634 check_cp1_registers(ctx, fs | ft | fd); \
1635 break; \
1636 } \
1637 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1638 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1639 switch (n) { \
1640 case 0: \
1641 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1642 break; \
1643 case 1: \
1644 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1645 break; \
1646 case 2: \
1647 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1648 break; \
1649 case 3: \
1650 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1651 break; \
1652 case 4: \
1653 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1654 break; \
1655 case 5: \
1656 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1657 break; \
1658 case 6: \
1659 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1660 break; \
1661 case 7: \
1662 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1663 break; \
1664 case 8: \
1665 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1666 break; \
1667 case 9: \
1668 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1669 break; \
1670 case 10: \
1671 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1672 break; \
1673 case 11: \
1674 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1675 break; \
1676 case 12: \
1677 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1678 break; \
1679 case 13: \
1680 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1681 break; \
1682 case 14: \
1683 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1684 break; \
1685 case 15: \
1686 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1687 break; \
1688 case 17: \
1689 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1690 break; \
1691 case 18: \
1692 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1693 break; \
1694 case 19: \
1695 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1696 break; \
1697 case 25: \
1698 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1699 break; \
1700 case 26: \
1701 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1702 break; \
1703 case 27: \
1704 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1705 break; \
1706 default: \
1707 abort(); \
1708 } \
1709 STORE; \
1710 tcg_temp_free_i ## bits (fp0); \
1711 tcg_temp_free_i ## bits (fp1); \
1712 }
1713
1714 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1715 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(fp0, fd))
1716 #undef FOP_CONDNS
1717 #undef gen_ldcmp_fpr32
1718 #undef gen_ldcmp_fpr64
1719
1720 /* load/store instructions. */
1721 #ifdef CONFIG_USER_ONLY
1722 #define OP_LD_ATOMIC(insn,fname) \
1723 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1724 { \
1725 TCGv t0 = tcg_temp_new(); \
1726 tcg_gen_mov_tl(t0, arg1); \
1727 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1728 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1729 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1730 tcg_temp_free(t0); \
1731 }
1732 #else
1733 #define OP_LD_ATOMIC(insn,fname) \
1734 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1735 { \
1736 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1737 }
1738 #endif
1739 OP_LD_ATOMIC(ll,ld32s);
1740 #if defined(TARGET_MIPS64)
1741 OP_LD_ATOMIC(lld,ld64);
1742 #endif
1743 #undef OP_LD_ATOMIC
1744
1745 #ifdef CONFIG_USER_ONLY
1746 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1747 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1748 { \
1749 TCGv t0 = tcg_temp_new(); \
1750 int l1 = gen_new_label(); \
1751 int l2 = gen_new_label(); \
1752 \
1753 tcg_gen_andi_tl(t0, arg2, almask); \
1754 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1755 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1756 generate_exception(ctx, EXCP_AdES); \
1757 gen_set_label(l1); \
1758 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1759 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1760 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1761 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1762 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1763 gen_helper_0e0i(raise_exception, EXCP_SC); \
1764 gen_set_label(l2); \
1765 tcg_gen_movi_tl(t0, 0); \
1766 gen_store_gpr(t0, rt); \
1767 tcg_temp_free(t0); \
1768 }
1769 #else
1770 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1771 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1772 { \
1773 TCGv t0 = tcg_temp_new(); \
1774 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1775 gen_store_gpr(t0, rt); \
1776 tcg_temp_free(t0); \
1777 }
1778 #endif
1779 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1780 #if defined(TARGET_MIPS64)
1781 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1782 #endif
1783 #undef OP_ST_ATOMIC
1784
1785 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1786 int base, int16_t offset)
1787 {
1788 if (base == 0) {
1789 tcg_gen_movi_tl(addr, offset);
1790 } else if (offset == 0) {
1791 gen_load_gpr(addr, base);
1792 } else {
1793 tcg_gen_movi_tl(addr, offset);
1794 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1795 }
1796 }
1797
1798 static target_ulong pc_relative_pc (DisasContext *ctx)
1799 {
1800 target_ulong pc = ctx->pc;
1801
1802 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1803 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1804
1805 pc -= branch_bytes;
1806 }
1807
1808 pc &= ~(target_ulong)3;
1809 return pc;
1810 }
1811
1812 /* Load */
1813 static void gen_ld(DisasContext *ctx, uint32_t opc,
1814 int rt, int base, int16_t offset)
1815 {
1816 const char *opn = "ld";
1817 TCGv t0, t1, t2;
1818
1819 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1820 /* Loongson CPU uses a load to zero register for prefetch.
1821 We emulate it as a NOP. On other CPU we must perform the
1822 actual memory access. */
1823 MIPS_DEBUG("NOP");
1824 return;
1825 }
1826
1827 t0 = tcg_temp_new();
1828 gen_base_offset_addr(ctx, t0, base, offset);
1829
1830 switch (opc) {
1831 #if defined(TARGET_MIPS64)
1832 case OPC_LWU:
1833 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1834 gen_store_gpr(t0, rt);
1835 opn = "lwu";
1836 break;
1837 case OPC_LD:
1838 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1839 gen_store_gpr(t0, rt);
1840 opn = "ld";
1841 break;
1842 case OPC_LLD:
1843 case R6_OPC_LLD:
1844 save_cpu_state(ctx, 1);
1845 op_ld_lld(t0, t0, ctx);
1846 gen_store_gpr(t0, rt);
1847 opn = "lld";
1848 break;
1849 case OPC_LDL:
1850 t1 = tcg_temp_new();
1851 tcg_gen_andi_tl(t1, t0, 7);
1852 #ifndef TARGET_WORDS_BIGENDIAN
1853 tcg_gen_xori_tl(t1, t1, 7);
1854 #endif
1855 tcg_gen_shli_tl(t1, t1, 3);
1856 tcg_gen_andi_tl(t0, t0, ~7);
1857 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1858 tcg_gen_shl_tl(t0, t0, t1);
1859 tcg_gen_xori_tl(t1, t1, 63);
1860 t2 = tcg_const_tl(0x7fffffffffffffffull);
1861 tcg_gen_shr_tl(t2, t2, t1);
1862 gen_load_gpr(t1, rt);
1863 tcg_gen_and_tl(t1, t1, t2);
1864 tcg_temp_free(t2);
1865 tcg_gen_or_tl(t0, t0, t1);
1866 tcg_temp_free(t1);
1867 gen_store_gpr(t0, rt);
1868 opn = "ldl";
1869 break;
1870 case OPC_LDR:
1871 t1 = tcg_temp_new();
1872 tcg_gen_andi_tl(t1, t0, 7);
1873 #ifdef TARGET_WORDS_BIGENDIAN
1874 tcg_gen_xori_tl(t1, t1, 7);
1875 #endif
1876 tcg_gen_shli_tl(t1, t1, 3);
1877 tcg_gen_andi_tl(t0, t0, ~7);
1878 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1879 tcg_gen_shr_tl(t0, t0, t1);
1880 tcg_gen_xori_tl(t1, t1, 63);
1881 t2 = tcg_const_tl(0xfffffffffffffffeull);
1882 tcg_gen_shl_tl(t2, t2, t1);
1883 gen_load_gpr(t1, rt);
1884 tcg_gen_and_tl(t1, t1, t2);
1885 tcg_temp_free(t2);
1886 tcg_gen_or_tl(t0, t0, t1);
1887 tcg_temp_free(t1);
1888 gen_store_gpr(t0, rt);
1889 opn = "ldr";
1890 break;
1891 case OPC_LDPC:
1892 t1 = tcg_const_tl(pc_relative_pc(ctx));
1893 gen_op_addr_add(ctx, t0, t0, t1);
1894 tcg_temp_free(t1);
1895 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1896 gen_store_gpr(t0, rt);
1897 opn = "ldpc";
1898 break;
1899 #endif
1900 case OPC_LWPC:
1901 t1 = tcg_const_tl(pc_relative_pc(ctx));
1902 gen_op_addr_add(ctx, t0, t0, t1);
1903 tcg_temp_free(t1);
1904 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1905 gen_store_gpr(t0, rt);
1906 opn = "lwpc";
1907 break;
1908 case OPC_LW:
1909 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1910 gen_store_gpr(t0, rt);
1911 opn = "lw";
1912 break;
1913 case OPC_LH:
1914 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
1915 gen_store_gpr(t0, rt);
1916 opn = "lh";
1917 break;
1918 case OPC_LHU:
1919 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
1920 gen_store_gpr(t0, rt);
1921 opn = "lhu";
1922 break;
1923 case OPC_LB:
1924 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
1925 gen_store_gpr(t0, rt);
1926 opn = "lb";
1927 break;
1928 case OPC_LBU:
1929 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
1930 gen_store_gpr(t0, rt);
1931 opn = "lbu";
1932 break;
1933 case OPC_LWL:
1934 t1 = tcg_temp_new();
1935 tcg_gen_andi_tl(t1, t0, 3);
1936 #ifndef TARGET_WORDS_BIGENDIAN
1937 tcg_gen_xori_tl(t1, t1, 3);
1938 #endif
1939 tcg_gen_shli_tl(t1, t1, 3);
1940 tcg_gen_andi_tl(t0, t0, ~3);
1941 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1942 tcg_gen_shl_tl(t0, t0, t1);
1943 tcg_gen_xori_tl(t1, t1, 31);
1944 t2 = tcg_const_tl(0x7fffffffull);
1945 tcg_gen_shr_tl(t2, t2, t1);
1946 gen_load_gpr(t1, rt);
1947 tcg_gen_and_tl(t1, t1, t2);
1948 tcg_temp_free(t2);
1949 tcg_gen_or_tl(t0, t0, t1);
1950 tcg_temp_free(t1);
1951 tcg_gen_ext32s_tl(t0, t0);
1952 gen_store_gpr(t0, rt);
1953 opn = "lwl";
1954 break;
1955 case OPC_LWR:
1956 t1 = tcg_temp_new();
1957 tcg_gen_andi_tl(t1, t0, 3);
1958 #ifdef TARGET_WORDS_BIGENDIAN
1959 tcg_gen_xori_tl(t1, t1, 3);
1960 #endif
1961 tcg_gen_shli_tl(t1, t1, 3);
1962 tcg_gen_andi_tl(t0, t0, ~3);
1963 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1964 tcg_gen_shr_tl(t0, t0, t1);
1965 tcg_gen_xori_tl(t1, t1, 31);
1966 t2 = tcg_const_tl(0xfffffffeull);
1967 tcg_gen_shl_tl(t2, t2, t1);
1968 gen_load_gpr(t1, rt);
1969 tcg_gen_and_tl(t1, t1, t2);
1970 tcg_temp_free(t2);
1971 tcg_gen_or_tl(t0, t0, t1);
1972 tcg_temp_free(t1);
1973 tcg_gen_ext32s_tl(t0, t0);
1974 gen_store_gpr(t0, rt);
1975 opn = "lwr";
1976 break;
1977 case OPC_LL:
1978 case R6_OPC_LL:
1979 save_cpu_state(ctx, 1);
1980 op_ld_ll(t0, t0, ctx);
1981 gen_store_gpr(t0, rt);
1982 opn = "ll";
1983 break;
1984 }
1985 (void)opn; /* avoid a compiler warning */
1986 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1987 tcg_temp_free(t0);
1988 }
1989
1990 /* Store */
1991 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1992 int base, int16_t offset)
1993 {
1994 const char *opn = "st";
1995 TCGv t0 = tcg_temp_new();
1996 TCGv t1 = tcg_temp_new();
1997
1998 gen_base_offset_addr(ctx, t0, base, offset);
1999 gen_load_gpr(t1, rt);
2000 switch (opc) {
2001 #if defined(TARGET_MIPS64)
2002 case OPC_SD:
2003 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
2004 opn = "sd";
2005 break;
2006 case OPC_SDL:
2007 save_cpu_state(ctx, 1);
2008 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
2009 opn = "sdl";
2010 break;
2011 case OPC_SDR:
2012 save_cpu_state(ctx, 1);
2013 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
2014 opn = "sdr";
2015 break;
2016 #endif
2017 case OPC_SW:
2018 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
2019 opn = "sw";
2020 break;
2021 case OPC_SH:
2022 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
2023 opn = "sh";
2024 break;
2025 case OPC_SB:
2026 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
2027 opn = "sb";
2028 break;
2029 case OPC_SWL:
2030 save_cpu_state(ctx, 1);
2031 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
2032 opn = "swl";
2033 break;
2034 case OPC_SWR:
2035 save_cpu_state(ctx, 1);
2036 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
2037 opn = "swr";
2038 break;
2039 }
2040 (void)opn; /* avoid a compiler warning */
2041 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2042 tcg_temp_free(t0);
2043 tcg_temp_free(t1);
2044 }
2045
2046
2047 /* Store conditional */
2048 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
2049 int base, int16_t offset)
2050 {
2051 const char *opn = "st_cond";
2052 TCGv t0, t1;
2053
2054 #ifdef CONFIG_USER_ONLY
2055 t0 = tcg_temp_local_new();
2056 t1 = tcg_temp_local_new();
2057 #else
2058 t0 = tcg_temp_new();
2059 t1 = tcg_temp_new();
2060 #endif
2061 gen_base_offset_addr(ctx, t0, base, offset);
2062 gen_load_gpr(t1, rt);
2063 switch (opc) {
2064 #if defined(TARGET_MIPS64)
2065 case OPC_SCD:
2066 case R6_OPC_SCD:
2067 save_cpu_state(ctx, 1);
2068 op_st_scd(t1, t0, rt, ctx);
2069 opn = "scd";
2070 break;
2071 #endif
2072 case OPC_SC:
2073 case R6_OPC_SC:
2074 save_cpu_state(ctx, 1);
2075 op_st_sc(t1, t0, rt, ctx);
2076 opn = "sc";
2077 break;
2078 }
2079 (void)opn; /* avoid a compiler warning */
2080 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
2081 tcg_temp_free(t1);
2082 tcg_temp_free(t0);
2083 }
2084
2085 /* Load and store */
2086 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
2087 int base, int16_t offset)
2088 {
2089 const char *opn = "flt_ldst";
2090 TCGv t0 = tcg_temp_new();
2091
2092 gen_base_offset_addr(ctx, t0, base, offset);
2093 /* Don't do NOP if destination is zero: we must perform the actual
2094 memory access. */
2095 switch (opc) {
2096 case OPC_LWC1:
2097 {
2098 TCGv_i32 fp0 = tcg_temp_new_i32();
2099 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
2100 gen_store_fpr32(fp0, ft);
2101 tcg_temp_free_i32(fp0);
2102 }
2103 opn = "lwc1";
2104 break;
2105 case OPC_SWC1:
2106 {
2107 TCGv_i32 fp0 = tcg_temp_new_i32();
2108 gen_load_fpr32(fp0, ft);
2109 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
2110 tcg_temp_free_i32(fp0);
2111 }
2112 opn = "swc1";
2113 break;
2114 case OPC_LDC1:
2115 {
2116 TCGv_i64 fp0 = tcg_temp_new_i64();
2117 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
2118 gen_store_fpr64(ctx, fp0, ft);
2119 tcg_temp_free_i64(fp0);
2120 }
2121 opn = "ldc1";
2122 break;
2123 case OPC_SDC1:
2124 {
2125 TCGv_i64 fp0 = tcg_temp_new_i64();
2126 gen_load_fpr64(ctx, fp0, ft);
2127 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
2128 tcg_temp_free_i64(fp0);
2129 }
2130 opn = "sdc1";
2131 break;
2132 default:
2133 MIPS_INVAL(opn);
2134 generate_exception(ctx, EXCP_RI);
2135 goto out;
2136 }
2137 (void)opn; /* avoid a compiler warning */
2138 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
2139 out:
2140 tcg_temp_free(t0);
2141 }
2142
2143 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2144 int rs, int16_t imm)
2145 {
2146 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2147 check_cp1_enabled(ctx);
2148 gen_flt_ldst(ctx, op, rt, rs, imm);
2149 } else {
2150 generate_exception_err(ctx, EXCP_CpU, 1);
2151 }
2152 }
2153
2154 /* Arithmetic with immediate operand */
2155 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2156 int rt, int rs, int16_t imm)
2157 {
2158 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2159 const char *opn = "imm arith";
2160
2161 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2162 /* If no destination, treat it as a NOP.
2163 For addi, we must generate the overflow exception when needed. */
2164 MIPS_DEBUG("NOP");
2165 return;
2166 }
2167 switch (opc) {
2168 case OPC_ADDI:
2169 {
2170 TCGv t0 = tcg_temp_local_new();
2171 TCGv t1 = tcg_temp_new();
2172 TCGv t2 = tcg_temp_new();
2173 int l1 = gen_new_label();
2174
2175 gen_load_gpr(t1, rs);
2176 tcg_gen_addi_tl(t0, t1, uimm);
2177 tcg_gen_ext32s_tl(t0, t0);
2178
2179 tcg_gen_xori_tl(t1, t1, ~uimm);
2180 tcg_gen_xori_tl(t2, t0, uimm);
2181 tcg_gen_and_tl(t1, t1, t2);
2182 tcg_temp_free(t2);
2183 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2184 tcg_temp_free(t1);
2185 /* operands of same sign, result different sign */
2186 generate_exception(ctx, EXCP_OVERFLOW);
2187 gen_set_label(l1);
2188 tcg_gen_ext32s_tl(t0, t0);
2189 gen_store_gpr(t0, rt);
2190 tcg_temp_free(t0);
2191 }
2192 opn = "addi";
2193 break;
2194 case OPC_ADDIU:
2195 if (rs != 0) {
2196 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2197 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2198 } else {
2199 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2200 }
2201 opn = "addiu";
2202 break;
2203 #if defined(TARGET_MIPS64)
2204 case OPC_DADDI:
2205 {
2206 TCGv t0 = tcg_temp_local_new();
2207 TCGv t1 = tcg_temp_new();
2208 TCGv t2 = tcg_temp_new();
2209 int l1 = gen_new_label();
2210
2211 gen_load_gpr(t1, rs);
2212 tcg_gen_addi_tl(t0, t1, uimm);
2213
2214 tcg_gen_xori_tl(t1, t1, ~uimm);
2215 tcg_gen_xori_tl(t2, t0, uimm);
2216 tcg_gen_and_tl(t1, t1, t2);
2217 tcg_temp_free(t2);
2218 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2219 tcg_temp_free(t1);
2220 /* operands of same sign, result different sign */
2221 generate_exception(ctx, EXCP_OVERFLOW);
2222 gen_set_label(l1);
2223 gen_store_gpr(t0, rt);
2224 tcg_temp_free(t0);
2225 }
2226 opn = "daddi";
2227 break;
2228 case OPC_DADDIU:
2229 if (rs != 0) {
2230 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2231 } else {
2232 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2233 }
2234 opn = "daddiu";
2235 break;
2236 #endif
2237 }
2238 (void)opn; /* avoid a compiler warning */
2239 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2240 }
2241
2242 /* Logic with immediate operand */
2243 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2244 int rt, int rs, int16_t imm)
2245 {
2246 target_ulong uimm;
2247
2248 if (rt == 0) {
2249 /* If no destination, treat it as a NOP. */
2250 MIPS_DEBUG("NOP");
2251 return;
2252 }
2253 uimm = (uint16_t)imm;
2254 switch (opc) {
2255 case OPC_ANDI:
2256 if (likely(rs != 0))
2257 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2258 else
2259 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2260 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2261 regnames[rs], uimm);
2262 break;
2263 case OPC_ORI:
2264 if (rs != 0)
2265 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2266 else
2267 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2268 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2269 regnames[rs], uimm);
2270 break;
2271 case OPC_XORI:
2272 if (likely(rs != 0))
2273 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2274 else
2275 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2276 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2277 regnames[rs], uimm);
2278 break;
2279 case OPC_LUI:
2280 if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
2281 /* OPC_AUI */
2282 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2283 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2284 MIPS_DEBUG("aui %s, %s, %04x", regnames[rt], regnames[rs], imm);
2285 } else {
2286 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2287 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2288 }
2289 break;
2290
2291 default:
2292 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2293 break;
2294 }
2295 }
2296
2297 /* Set on less than with immediate operand */
2298 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2299 int rt, int rs, int16_t imm)
2300 {
2301 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2302 const char *opn = "imm arith";
2303 TCGv t0;
2304
2305 if (rt == 0) {
2306 /* If no destination, treat it as a NOP. */
2307 MIPS_DEBUG("NOP");
2308 return;
2309 }
2310 t0 = tcg_temp_new();
2311 gen_load_gpr(t0, rs);
2312 switch (opc) {
2313 case OPC_SLTI:
2314 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2315 opn = "slti";
2316 break;
2317 case OPC_SLTIU:
2318 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2319 opn = "sltiu";
2320 break;
2321 }
2322 (void)opn; /* avoid a compiler warning */
2323 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2324 tcg_temp_free(t0);
2325 }
2326
2327 /* Shifts with immediate operand */
2328 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2329 int rt, int rs, int16_t imm)
2330 {
2331 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2332 const char *opn = "imm shift";
2333 TCGv t0;
2334
2335 if (rt == 0) {
2336 /* If no destination, treat it as a NOP. */
2337 MIPS_DEBUG("NOP");
2338 return;
2339 }
2340
2341 t0 = tcg_temp_new();
2342 gen_load_gpr(t0, rs);
2343 switch (opc) {
2344 case OPC_SLL:
2345 tcg_gen_shli_tl(t0, t0, uimm);
2346 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2347 opn = "sll";
2348 break;
2349 case OPC_SRA:
2350 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2351 opn = "sra";
2352 break;
2353 case OPC_SRL:
2354 if (uimm != 0) {
2355 tcg_gen_ext32u_tl(t0, t0);
2356 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2357 } else {
2358 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2359 }
2360 opn = "srl";
2361 break;
2362 case OPC_ROTR:
2363 if (uimm != 0) {
2364 TCGv_i32 t1 = tcg_temp_new_i32();
2365
2366 tcg_gen_trunc_tl_i32(t1, t0);
2367 tcg_gen_rotri_i32(t1, t1, uimm);
2368 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2369 tcg_temp_free_i32(t1);
2370 } else {
2371 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2372 }
2373 opn = "rotr";
2374 break;
2375 #if defined(TARGET_MIPS64)
2376 case OPC_DSLL:
2377 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2378 opn = "dsll";
2379 break;
2380 case OPC_DSRA:
2381 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2382 opn = "dsra";
2383 break;
2384 case OPC_DSRL:
2385 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2386 opn = "dsrl";
2387 break;
2388 case OPC_DROTR:
2389 if (uimm != 0) {
2390 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2391 } else {
2392 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2393 }
2394 opn = "drotr";
2395 break;
2396 case OPC_DSLL32:
2397 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2398 opn = "dsll32";
2399 break;
2400 case OPC_DSRA32:
2401 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2402 opn = "dsra32";
2403 break;
2404 case OPC_DSRL32:
2405 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2406 opn = "dsrl32";
2407 break;
2408 case OPC_DROTR32:
2409 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2410 opn = "drotr32";
2411 break;
2412 #endif
2413 }
2414 (void)opn; /* avoid a compiler warning */
2415 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2416 tcg_temp_free(t0);
2417 }
2418
2419 /* Arithmetic */
2420 static void gen_arith(DisasContext *ctx, uint32_t opc,
2421 int rd, int rs, int rt)
2422 {
2423 const char *opn = "arith";
2424
2425 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2426 && opc != OPC_DADD && opc != OPC_DSUB) {
2427 /* If no destination, treat it as a NOP.
2428 For add & sub, we must generate the overflow exception when needed. */
2429 MIPS_DEBUG("NOP");
2430 return;
2431 }
2432
2433 switch (opc) {
2434 case OPC_ADD:
2435 {
2436 TCGv t0 = tcg_temp_local_new();
2437 TCGv t1 = tcg_temp_new();
2438 TCGv t2 = tcg_temp_new();
2439 int l1 = gen_new_label();
2440
2441 gen_load_gpr(t1, rs);
2442 gen_load_gpr(t2, rt);
2443 tcg_gen_add_tl(t0, t1, t2);
2444 tcg_gen_ext32s_tl(t0, t0);
2445 tcg_gen_xor_tl(t1, t1, t2);
2446 tcg_gen_xor_tl(t2, t0, t2);
2447 tcg_gen_andc_tl(t1, t2, t1);
2448 tcg_temp_free(t2);
2449 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2450 tcg_temp_free(t1);
2451 /* operands of same sign, result different sign */
2452 generate_exception(ctx, EXCP_OVERFLOW);
2453 gen_set_label(l1);
2454 gen_store_gpr(t0, rd);
2455 tcg_temp_free(t0);
2456 }
2457 opn = "add";
2458 break;
2459 case OPC_ADDU:
2460 if (rs != 0 && rt != 0) {
2461 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2462 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2463 } else if (rs == 0 && rt != 0) {
2464 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2465 } else if (rs != 0 && rt == 0) {
2466 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2467 } else {
2468 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2469 }
2470 opn = "addu";
2471 break;
2472 case OPC_SUB:
2473 {
2474 TCGv t0 = tcg_temp_local_new();
2475 TCGv t1 = tcg_temp_new();
2476 TCGv t2 = tcg_temp_new();
2477 int l1 = gen_new_label();
2478
2479 gen_load_gpr(t1, rs);
2480 gen_load_gpr(t2, rt);
2481 tcg_gen_sub_tl(t0, t1, t2);
2482 tcg_gen_ext32s_tl(t0, t0);
2483 tcg_gen_xor_tl(t2, t1, t2);
2484 tcg_gen_xor_tl(t1, t0, t1);
2485 tcg_gen_and_tl(t1, t1, t2);
2486 tcg_temp_free(t2);
2487 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2488 tcg_temp_free(t1);
2489 /* operands of different sign, first operand and result different sign */
2490 generate_exception(ctx, EXCP_OVERFLOW);
2491 gen_set_label(l1);
2492 gen_store_gpr(t0, rd);
2493 tcg_temp_free(t0);
2494 }
2495 opn = "sub";
2496 break;
2497 case OPC_SUBU:
2498 if (rs != 0 && rt != 0) {
2499 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2500 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2501 } else if (rs == 0 && rt != 0) {
2502 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2503 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2504 } else if (rs != 0 && rt == 0) {
2505 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2506 } else {
2507 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2508 }
2509 opn = "subu";
2510 break;
2511 #if defined(TARGET_MIPS64)
2512 case OPC_DADD:
2513 {
2514 TCGv t0 = tcg_temp_local_new();
2515 TCGv t1 = tcg_temp_new();
2516 TCGv t2 = tcg_temp_new();
2517 int l1 = gen_new_label();
2518
2519 gen_load_gpr(t1, rs);
2520 gen_load_gpr(t2, rt);
2521 tcg_gen_add_tl(t0, t1, t2);
2522 tcg_gen_xor_tl(t1, t1, t2);
2523 tcg_gen_xor_tl(t2, t0, t2);
2524 tcg_gen_andc_tl(t1, t2, t1);
2525 tcg_temp_free(t2);
2526 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2527 tcg_temp_free(t1);
2528 /* operands of same sign, result different sign */
2529 generate_exception(ctx, EXCP_OVERFLOW);
2530 gen_set_label(l1);
2531 gen_store_gpr(t0, rd);
2532 tcg_temp_free(t0);
2533 }
2534 opn = "dadd";
2535 break;
2536 case OPC_DADDU:
2537 if (rs != 0 && rt != 0) {
2538 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2539 } else if (rs == 0 && rt != 0) {
2540 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2541 } else if (rs != 0 && rt == 0) {
2542 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2543 } else {
2544 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2545 }
2546 opn = "daddu";
2547 break;
2548 case OPC_DSUB:
2549 {
2550 TCGv t0 = tcg_temp_local_new();
2551 TCGv t1 = tcg_temp_new();
2552 TCGv t2 = tcg_temp_new();
2553 int l1 = gen_new_label();
2554
2555 gen_load_gpr(t1, rs);
2556 gen_load_gpr(t2, rt);
2557 tcg_gen_sub_tl(t0, t1, t2);
2558 tcg_gen_xor_tl(t2, t1, t2);
2559 tcg_gen_xor_tl(t1, t0, t1);
2560 tcg_gen_and_tl(t1, t1, t2);
2561 tcg_temp_free(t2);
2562 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2563 tcg_temp_free(t1);
2564 /* operands of different sign, first operand and result different sign */
2565 generate_exception(ctx, EXCP_OVERFLOW);
2566 gen_set_label(l1);
2567 gen_store_gpr(t0, rd);
2568 tcg_temp_free(t0);
2569 }
2570 opn = "dsub";
2571 break;
2572 case OPC_DSUBU:
2573 if (rs != 0 && rt != 0) {
2574 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2575 } else if (rs == 0 && rt != 0) {
2576 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2577 } else if (rs != 0 && rt == 0) {
2578 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2579 } else {
2580 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2581 }
2582 opn = "dsubu";
2583 break;
2584 #endif
2585 case OPC_MUL:
2586 if (likely(rs != 0 && rt != 0)) {
2587 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2588 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2589 } else {
2590 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2591 }
2592 opn = "mul";
2593 break;
2594 }
2595 (void)opn; /* avoid a compiler warning */
2596 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2597 }
2598
2599 /* Conditional move */
2600 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2601 int rd, int rs, int rt)
2602 {
2603 const char *opn = "cond move";
2604 TCGv t0, t1, t2;
2605
2606 if (rd == 0) {
2607 /* If no destination, treat it as a NOP. */
2608 MIPS_DEBUG("NOP");
2609 return;
2610 }
2611
2612 t0 = tcg_temp_new();
2613 gen_load_gpr(t0, rt);
2614 t1 = tcg_const_tl(0);
2615 t2 = tcg_temp_new();
2616 gen_load_gpr(t2, rs);
2617 switch (opc) {
2618 case OPC_MOVN:
2619 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2620 opn = "movn";
2621 break;
2622 case OPC_MOVZ:
2623 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2624 opn = "movz";
2625 break;
2626 case OPC_SELNEZ:
2627 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2628 opn = "selnez";
2629 break;
2630 case OPC_SELEQZ:
2631 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2632 opn = "seleqz";
2633 break;
2634 }
2635 tcg_temp_free(t2);
2636 tcg_temp_free(t1);
2637 tcg_temp_free(t0);
2638
2639 (void)opn; /* avoid a compiler warning */
2640 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2641 }
2642
2643 /* Logic */
2644 static void gen_logic(DisasContext *ctx, uint32_t opc,
2645 int rd, int rs, int rt)
2646 {
2647 const char *opn = "logic";
2648
2649 if (rd == 0) {
2650 /* If no destination, treat it as a NOP. */
2651 MIPS_DEBUG("NOP");
2652 return;
2653 }
2654
2655 switch (opc) {
2656 case OPC_AND:
2657 if (likely(rs != 0 && rt != 0)) {
2658 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2659 } else {
2660 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2661 }
2662 opn = "and";
2663 break;
2664 case OPC_NOR:
2665 if (rs != 0 && rt != 0) {
2666 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2667 } else if (rs == 0 && rt != 0) {
2668 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2669 } else if (rs != 0 && rt == 0) {
2670 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2671 } else {
2672 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2673 }
2674 opn = "nor";
2675 break;
2676 case OPC_OR:
2677 if (likely(rs != 0 && rt != 0)) {
2678 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2679 } else if (rs == 0 && rt != 0) {
2680 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2681 } else if (rs != 0 && rt == 0) {
2682 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2683 } else {
2684 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2685 }
2686 opn = "or";
2687 break;
2688 case OPC_XOR:
2689 if (likely(rs != 0 && rt != 0)) {
2690 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2691 } else if (rs == 0 && rt != 0) {
2692 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2693 } else if (rs != 0 && rt == 0) {
2694 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2695 } else {
2696 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2697 }
2698 opn = "xor";
2699 break;
2700 }
2701 (void)opn; /* avoid a compiler warning */
2702 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2703 }
2704
2705 /* Set on lower than */
2706 static void gen_slt(DisasContext *ctx, uint32_t opc,
2707 int rd, int rs, int rt)
2708 {
2709 const char *opn = "slt";
2710 TCGv t0, t1;
2711
2712 if (rd == 0) {
2713 /* If no destination, treat it as a NOP. */
2714 MIPS_DEBUG("NOP");
2715 return;
2716 }
2717
2718 t0 = tcg_temp_new();
2719 t1 = tcg_temp_new();
2720 gen_load_gpr(t0, rs);
2721 gen_load_gpr(t1, rt);
2722 switch (opc) {
2723 case OPC_SLT:
2724 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2725 opn = "slt";
2726 break;
2727 case OPC_SLTU:
2728 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2729 opn = "sltu";
2730 break;
2731 }
2732 (void)opn; /* avoid a compiler warning */
2733 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2734 tcg_temp_free(t0);
2735 tcg_temp_free(t1);
2736 }
2737
2738 /* Shifts */
2739 static void gen_shift(DisasContext *ctx, uint32_t opc,
2740 int rd, int rs, int rt)
2741 {
2742 const char *opn = "shifts";
2743 TCGv t0, t1;
2744
2745 if (rd == 0) {
2746 /* If no destination, treat it as a NOP.
2747 For add & sub, we must generate the overflow exception when needed. */
2748 MIPS_DEBUG("NOP");
2749 return;
2750 }
2751
2752 t0 = tcg_temp_new();
2753 t1 = tcg_temp_new();
2754 gen_load_gpr(t0, rs);
2755 gen_load_gpr(t1, rt);
2756 switch (opc) {
2757 case OPC_SLLV:
2758 tcg_gen_andi_tl(t0, t0, 0x1f);
2759 tcg_gen_shl_tl(t0, t1, t0);
2760 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2761 opn = "sllv";
2762 break;
2763 case OPC_SRAV:
2764 tcg_gen_andi_tl(t0, t0, 0x1f);
2765 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2766 opn = "srav";
2767 break;
2768 case OPC_SRLV:
2769 tcg_gen_ext32u_tl(t1, t1);
2770 tcg_gen_andi_tl(t0, t0, 0x1f);
2771 tcg_gen_shr_tl(t0, t1, t0);
2772 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2773 opn = "srlv";
2774 break;
2775 case OPC_ROTRV:
2776 {
2777 TCGv_i32 t2 = tcg_temp_new_i32();
2778 TCGv_i32 t3 = tcg_temp_new_i32();
2779
2780 tcg_gen_trunc_tl_i32(t2, t0);
2781 tcg_gen_trunc_tl_i32(t3, t1);
2782 tcg_gen_andi_i32(t2, t2, 0x1f);
2783 tcg_gen_rotr_i32(t2, t3, t2);
2784 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2785 tcg_temp_free_i32(t2);
2786 tcg_temp_free_i32(t3);
2787 opn = "rotrv";
2788 }
2789 break;
2790 #if defined(TARGET_MIPS64)
2791 case OPC_DSLLV:
2792 tcg_gen_andi_tl(t0, t0, 0x3f);
2793 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2794 opn = "dsllv";
2795 break;
2796 case OPC_DSRAV:
2797 tcg_gen_andi_tl(t0, t0, 0x3f);
2798 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2799 opn = "dsrav";
2800 break;
2801 case OPC_DSRLV:
2802 tcg_gen_andi_tl(t0, t0, 0x3f);
2803 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2804 opn = "dsrlv";
2805 break;
2806 case OPC_DROTRV:
2807 tcg_gen_andi_tl(t0, t0, 0x3f);
2808 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2809 opn = "drotrv";
2810 break;
2811 #endif
2812 }
2813 (void)opn; /* avoid a compiler warning */
2814 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2815 tcg_temp_free(t0);
2816 tcg_temp_free(t1);
2817 }
2818
2819 /* Arithmetic on HI/LO registers */
2820 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2821 {
2822 const char *opn = "hilo";
2823
2824 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2825 /* Treat as NOP. */
2826 MIPS_DEBUG("NOP");
2827 return;
2828 }
2829
2830 if (acc != 0) {
2831 check_dsp(ctx);
2832 }
2833
2834 switch (opc) {
2835 case OPC_MFHI:
2836 #if defined(TARGET_MIPS64)
2837 if (acc != 0) {
2838 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2839 } else
2840 #endif
2841 {
2842 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2843 }
2844 opn = "mfhi";
2845 break;
2846 case OPC_MFLO:
2847 #if defined(TARGET_MIPS64)
2848 if (acc != 0) {
2849 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2850 } else
2851 #endif
2852 {
2853 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2854 }
2855 opn = "mflo";
2856 break;
2857 case OPC_MTHI:
2858 if (reg != 0) {
2859 #if defined(TARGET_MIPS64)
2860 if (acc != 0) {
2861 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2862 } else
2863 #endif
2864 {
2865 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2866 }
2867 } else {
2868 tcg_gen_movi_tl(cpu_HI[acc], 0);
2869 }
2870 opn = "mthi";
2871 break;
2872 case OPC_MTLO:
2873 if (reg != 0) {
2874 #if defined(TARGET_MIPS64)
2875 if (acc != 0) {
2876 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2877 } else
2878 #endif
2879 {
2880 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2881 }
2882 } else {
2883 tcg_gen_movi_tl(cpu_LO[acc], 0);
2884 }
2885 opn = "mtlo";
2886 break;
2887 }
2888 (void)opn; /* avoid a compiler warning */
2889 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2890 }
2891
2892 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
2893 TCGMemOp memop)
2894 {
2895 TCGv t0 = tcg_const_tl(addr);
2896 tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
2897 gen_store_gpr(t0, reg);
2898 tcg_temp_free(t0);
2899 }
2900
2901 static inline void gen_pcrel(DisasContext *ctx, int rs, int16_t imm)
2902 {
2903 target_long offset;
2904 target_long addr;
2905
2906 switch (MASK_OPC_PCREL_TOP2BITS(ctx->opcode)) {
2907 case OPC_ADDIUPC:
2908 if (rs != 0) {
2909 offset = sextract32(ctx->opcode << 2, 0, 21);
2910 addr = addr_add(ctx, ctx->pc, offset);
2911 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2912 }
2913 break;
2914 case R6_OPC_LWPC:
2915 offset = sextract32(ctx->opcode << 2, 0, 21);
2916 addr = addr_add(ctx, ctx->pc, offset);
2917 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
2918 break;
2919 #if defined(TARGET_MIPS64)
2920 case OPC_LWUPC:
2921 check_mips_64(ctx);
2922 offset = sextract32(ctx->opcode << 2, 0, 21);
2923 addr = addr_add(ctx, ctx->pc, offset);
2924 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
2925 break;
2926 #endif
2927 default:
2928 switch (MASK_OPC_PCREL_TOP5BITS(ctx->opcode)) {
2929 case OPC_AUIPC:
2930 if (rs != 0) {
2931 offset = imm << 16;
2932 addr = addr_add(ctx, ctx->pc, offset);
2933 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2934 }
2935 break;
2936 case OPC_ALUIPC:
2937 if (rs != 0) {
2938 offset = imm << 16;
2939 addr = ~0xFFFF & addr_add(ctx, ctx->pc, offset);
2940 tcg_gen_movi_tl(cpu_gpr[rs], addr);
2941 }
2942 break;
2943 #if defined(TARGET_MIPS64)
2944 case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
2945 case R6_OPC_LDPC + (1 << 16):
2946 case R6_OPC_LDPC + (2 << 16):
2947 case R6_OPC_LDPC + (3 << 16):
2948 check_mips_64(ctx);
2949 offset = sextract32(ctx->opcode << 3, 0, 21);
2950 addr = addr_add(ctx, (ctx->pc & ~0x7), offset);
2951 gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
2952 break;
2953 #endif
2954 default:
2955 MIPS_INVAL("OPC_PCREL");
2956 generate_exception(ctx, EXCP_RI);
2957 break;
2958 }
2959 break;
2960 }
2961 }
2962
2963 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
2964 {
2965 const char *opn = "r6 mul/div";
2966 TCGv t0, t1;
2967
2968 if (rd == 0) {
2969 /* Treat as NOP. */
2970 MIPS_DEBUG("NOP");
2971 return;
2972 }
2973
2974 t0 = tcg_temp_new();
2975 t1 = tcg_temp_new();
2976
2977 gen_load_gpr(t0, rs);
2978 gen_load_gpr(t1, rt);
2979
2980 switch (opc) {
2981 case R6_OPC_DIV:
2982 {
2983 TCGv t2 = tcg_temp_new();
2984 TCGv t3 = tcg_temp_new();
2985 tcg_gen_ext32s_tl(t0, t0);
2986 tcg_gen_ext32s_tl(t1, t1);
2987 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2988 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2989 tcg_gen_and_tl(t2, t2, t3);
2990 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2991 tcg_gen_or_tl(t2, t2, t3);
2992 tcg_gen_movi_tl(t3, 0);
2993 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2994 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2995 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2996 tcg_temp_free(t3);
2997 tcg_temp_free(t2);
2998 }
2999 opn = "div";
3000 break;
3001 case R6_OPC_MOD:
3002 {
3003 TCGv t2 = tcg_temp_new();
3004 TCGv t3 = tcg_temp_new();
3005 tcg_gen_ext32s_tl(t0, t0);
3006 tcg_gen_ext32s_tl(t1, t1);
3007 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3008 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3009 tcg_gen_and_tl(t2, t2, t3);
3010 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3011 tcg_gen_or_tl(t2, t2, t3);
3012 tcg_gen_movi_tl(t3, 0);
3013 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3014 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3015 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3016 tcg_temp_free(t3);
3017 tcg_temp_free(t2);
3018 }
3019 opn = "mod";
3020 break;
3021 case R6_OPC_DIVU:
3022 {
3023 TCGv t2 = tcg_const_tl(0);
3024 TCGv t3 = tcg_const_tl(1);
3025 tcg_gen_ext32u_tl(t0, t0);
3026 tcg_gen_ext32u_tl(t1, t1);
3027 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3028 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3029 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3030 tcg_temp_free(t3);
3031 tcg_temp_free(t2);
3032 }
3033 opn = "divu";
3034 break;
3035 case R6_OPC_MODU:
3036 {
3037 TCGv t2 = tcg_const_tl(0);
3038 TCGv t3 = tcg_const_tl(1);
3039 tcg_gen_ext32u_tl(t0, t0);
3040 tcg_gen_ext32u_tl(t1, t1);
3041 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3042 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3043 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3044 tcg_temp_free(t3);
3045 tcg_temp_free(t2);
3046 }
3047 opn = "modu";
3048 break;
3049 case R6_OPC_MUL:
3050 {
3051 TCGv_i32 t2 = tcg_temp_new_i32();
3052 TCGv_i32 t3 = tcg_temp_new_i32();
3053 tcg_gen_trunc_tl_i32(t2, t0);
3054 tcg_gen_trunc_tl_i32(t3, t1);
3055 tcg_gen_mul_i32(t2, t2, t3);
3056 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3057 tcg_temp_free_i32(t2);
3058 tcg_temp_free_i32(t3);
3059 }
3060 opn = "mul";
3061 break;
3062 case R6_OPC_MUH:
3063 {
3064 TCGv_i32 t2 = tcg_temp_new_i32();
3065 TCGv_i32 t3 = tcg_temp_new_i32();
3066 tcg_gen_trunc_tl_i32(t2, t0);
3067 tcg_gen_trunc_tl_i32(t3, t1);
3068 tcg_gen_muls2_i32(t2, t3, t2, t3);
3069 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3070 tcg_temp_free_i32(t2);
3071 tcg_temp_free_i32(t3);
3072 }
3073 opn = "muh";
3074 break;
3075 case R6_OPC_MULU:
3076 {
3077 TCGv_i32 t2 = tcg_temp_new_i32();
3078 TCGv_i32 t3 = tcg_temp_new_i32();
3079 tcg_gen_trunc_tl_i32(t2, t0);
3080 tcg_gen_trunc_tl_i32(t3, t1);
3081 tcg_gen_mul_i32(t2, t2, t3);
3082 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3083 tcg_temp_free_i32(t2);
3084 tcg_temp_free_i32(t3);
3085 }
3086 opn = "mulu";
3087 break;
3088 case R6_OPC_MUHU:
3089 {
3090 TCGv_i32 t2 = tcg_temp_new_i32();
3091 TCGv_i32 t3 = tcg_temp_new_i32();
3092 tcg_gen_trunc_tl_i32(t2, t0);
3093 tcg_gen_trunc_tl_i32(t3, t1);
3094 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3095 tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3096 tcg_temp_free_i32(t2);
3097 tcg_temp_free_i32(t3);
3098 }
3099 opn = "muhu";
3100 break;
3101 #if defined(TARGET_MIPS64)
3102 case R6_OPC_DDIV:
3103 {
3104 TCGv t2 = tcg_temp_new();
3105 TCGv t3 = tcg_temp_new();
3106 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3107 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3108 tcg_gen_and_tl(t2, t2, t3);
3109 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3110 tcg_gen_or_tl(t2, t2, t3);
3111 tcg_gen_movi_tl(t3, 0);
3112 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3113 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3114 tcg_temp_free(t3);
3115 tcg_temp_free(t2);
3116 }
3117 opn = "ddiv";
3118 break;
3119 case R6_OPC_DMOD:
3120 {
3121 TCGv t2 = tcg_temp_new();
3122 TCGv t3 = tcg_temp_new();
3123 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3124 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3125 tcg_gen_and_tl(t2, t2, t3);
3126 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3127 tcg_gen_or_tl(t2, t2, t3);
3128 tcg_gen_movi_tl(t3, 0);
3129 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3130 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3131 tcg_temp_free(t3);
3132 tcg_temp_free(t2);
3133 }
3134 opn = "dmod";
3135 break;
3136 case R6_OPC_DDIVU:
3137 {
3138 TCGv t2 = tcg_const_tl(0);
3139 TCGv t3 = tcg_const_tl(1);
3140 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3141 tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3142 tcg_temp_free(t3);
3143 tcg_temp_free(t2);
3144 }
3145 opn = "ddivu";
3146 break;
3147 case R6_OPC_DMODU:
3148 {
3149 TCGv t2 = tcg_const_tl(0);
3150 TCGv t3 = tcg_const_tl(1);
3151 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3152 tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3153 tcg_temp_free(t3);
3154 tcg_temp_free(t2);
3155 }
3156 opn = "dmodu";
3157 break;
3158 case R6_OPC_DMUL:
3159 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3160 opn = "dmul";
3161 break;
3162 case R6_OPC_DMUH:
3163 {
3164 TCGv t2 = tcg_temp_new();
3165 tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3166 tcg_temp_free(t2);
3167 }
3168 opn = "dmuh";
3169 break;
3170 case R6_OPC_DMULU:
3171 tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3172 opn = "dmulu";
3173 break;
3174 case R6_OPC_DMUHU:
3175 {
3176 TCGv t2 = tcg_temp_new();
3177 tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3178 tcg_temp_free(t2);
3179 }
3180 opn = "dmuhu";
3181 break;
3182 #endif
3183 default:
3184 MIPS_INVAL(opn);
3185 generate_exception(ctx, EXCP_RI);
3186 goto out;
3187 }
3188 (void)opn; /* avoid a compiler warning */
3189 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3190 out:
3191 tcg_temp_free(t0);
3192 tcg_temp_free(t1);
3193 }
3194
3195 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3196 int acc, int rs, int rt)
3197 {
3198 const char *opn = "mul/div";
3199 TCGv t0, t1;
3200
3201 t0 = tcg_temp_new();
3202 t1 = tcg_temp_new();
3203
3204 gen_load_gpr(t0, rs);
3205 gen_load_gpr(t1, rt);
3206
3207 if (acc != 0) {
3208 check_dsp(ctx);
3209 }
3210
3211 switch (opc) {
3212 case OPC_DIV:
3213 {
3214 TCGv t2 = tcg_temp_new();
3215 TCGv t3 = tcg_temp_new();
3216 tcg_gen_ext32s_tl(t0, t0);
3217 tcg_gen_ext32s_tl(t1, t1);
3218 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3219 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3220 tcg_gen_and_tl(t2, t2, t3);
3221 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3222 tcg_gen_or_tl(t2, t2, t3);
3223 tcg_gen_movi_tl(t3, 0);
3224 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3225 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3226 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3227 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3228 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3229 tcg_temp_free(t3);
3230 tcg_temp_free(t2);
3231 }
3232 opn = "div";
3233 break;
3234 case OPC_DIVU:
3235 {
3236 TCGv t2 = tcg_const_tl(0);
3237 TCGv t3 = tcg_const_tl(1);
3238 tcg_gen_ext32u_tl(t0, t0);
3239 tcg_gen_ext32u_tl(t1, t1);
3240 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3241 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3242 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3243 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3244 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3245 tcg_temp_free(t3);
3246 tcg_temp_free(t2);
3247 }
3248 opn = "divu";
3249 break;
3250 case OPC_MULT:
3251 {
3252 TCGv_i32 t2 = tcg_temp_new_i32();
3253 TCGv_i32 t3 = tcg_temp_new_i32();
3254 tcg_gen_trunc_tl_i32(t2, t0);
3255 tcg_gen_trunc_tl_i32(t3, t1);
3256 tcg_gen_muls2_i32(t2, t3, t2, t3);
3257 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3258 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3259 tcg_temp_free_i32(t2);
3260 tcg_temp_free_i32(t3);
3261 }
3262 opn = "mult";
3263 break;
3264 case OPC_MULTU:
3265 {
3266 TCGv_i32 t2 = tcg_temp_new_i32();
3267 TCGv_i32 t3 = tcg_temp_new_i32();
3268 tcg_gen_trunc_tl_i32(t2, t0);
3269 tcg_gen_trunc_tl_i32(t3, t1);
3270 tcg_gen_mulu2_i32(t2, t3, t2, t3);
3271 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3272 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3273 tcg_temp_free_i32(t2);
3274 tcg_temp_free_i32(t3);
3275 }
3276 opn = "multu";
3277 break;
3278 #if defined(TARGET_MIPS64)
3279 case OPC_DDIV:
3280 {
3281 TCGv t2 = tcg_temp_new();
3282 TCGv t3 = tcg_temp_new();
3283 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3284 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3285 tcg_gen_and_tl(t2, t2, t3);
3286 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3287 tcg_gen_or_tl(t2, t2, t3);
3288 tcg_gen_movi_tl(t3, 0);
3289 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3290 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3291 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3292 tcg_temp_free(t3);
3293 tcg_temp_free(t2);
3294 }
3295 opn = "ddiv";
3296 break;
3297 case OPC_DDIVU:
3298 {
3299 TCGv t2 = tcg_const_tl(0);
3300 TCGv t3 = tcg_const_tl(1);
3301 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3302 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3303 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3304 tcg_temp_free(t3);
3305 tcg_temp_free(t2);
3306 }
3307 opn = "ddivu";
3308 break;
3309 case OPC_DMULT:
3310 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3311 opn = "dmult";
3312 break;
3313 case OPC_DMULTU:
3314 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3315 opn = "dmultu";
3316 break;
3317 #endif
3318 case OPC_MADD:
3319 {
3320 TCGv_i64 t2 = tcg_temp_new_i64();
3321 TCGv_i64 t3 = tcg_temp_new_i64();
3322
3323 tcg_gen_ext_tl_i64(t2, t0);
3324 tcg_gen_ext_tl_i64(t3, t1);
3325 tcg_gen_mul_i64(t2, t2, t3);
3326 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3327 tcg_gen_add_i64(t2, t2, t3);
3328 tcg_temp_free_i64(t3);
3329 tcg_gen_trunc_i64_tl(t0, t2);
3330 tcg_gen_shri_i64(t2, t2, 32);
3331 tcg_gen_trunc_i64_tl(t1, t2);
3332 tcg_temp_free_i64(t2);
3333 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3334 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
3335 }
3336 opn = "madd";
3337 break;
3338 case OPC_MADDU:
3339 {
3340 TCGv_i64 t2 = tcg_temp_new_i64();
3341 TCGv_i64 t3 = tcg_temp_new_i64();
3342
3343 tcg_gen_ext32u_tl(t0, t0);
3344 tcg_gen_ext32u_tl(t1, t1);
3345 tcg_gen_extu_tl_i64(t2, t0);
3346 tcg_gen_extu_tl_i64(t3, t1);
3347 tcg_gen_mul_i64(t2, t2, t3);
3348 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3349 tcg_gen_add_i64(t2, t2, t3);
3350 tcg_temp_free_i64(t3);
3351 tcg_gen_trunc_i64_tl(t0, t2);
3352 tcg_gen_shri_i64(t2, t2, 32);
3353 tcg_gen_trunc_i64_tl(t1, t2);
3354 tcg_temp_free_i64(t2);
3355 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3356 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
3357 }
3358 opn = "maddu";
3359 break;
3360 case OPC_MSUB:
3361 {
3362 TCGv_i64 t2 = tcg_temp_new_i64();
3363 TCGv_i64 t3 = tcg_temp_new_i64();
3364
3365 tcg_gen_ext_tl_i64(t2, t0);
3366 tcg_gen_ext_tl_i64(t3, t1);
3367 tcg_gen_mul_i64(t2, t2, t3);
3368 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3369 tcg_gen_sub_i64(t2, t3, t2);
3370 tcg_temp_free_i64(t3);
3371 tcg_gen_trunc_i64_tl(t0, t2);
3372 tcg_gen_shri_i64(t2, t2, 32);
3373 tcg_gen_trunc_i64_tl(t1, t2);
3374 tcg_temp_free_i64(t2);
3375 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3376 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
3377 }
3378 opn = "msub";
3379 break;
3380 case OPC_MSUBU:
3381 {
3382 TCGv_i64 t2 = tcg_temp_new_i64();
3383 TCGv_i64 t3 = tcg_temp_new_i64();
3384
3385 tcg_gen_ext32u_tl(t0, t0);
3386 tcg_gen_ext32u_tl(t1, t1);
3387 tcg_gen_extu_tl_i64(t2, t0);
3388 tcg_gen_extu_tl_i64(t3, t1);
3389 tcg_gen_mul_i64(t2, t2, t3);
3390 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3391 tcg_gen_sub_i64(t2, t3, t2);
3392 tcg_temp_free_i64(t3);
3393 tcg_gen_trunc_i64_tl(t0, t2);
3394 tcg_gen_shri_i64(t2, t2, 32);
3395 tcg_gen_trunc_i64_tl(t1, t2);
3396 tcg_temp_free_i64(t2);
3397 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
3398 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
3399 }
3400 opn = "msubu";
3401 break;
3402 default:
3403 MIPS_INVAL(opn);
3404 generate_exception(ctx, EXCP_RI);
3405 goto out;
3406 }
3407 (void)opn; /* avoid a compiler warning */
3408 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
3409 out:
3410 tcg_temp_free(t0);
3411 tcg_temp_free(t1);
3412 }
3413
3414 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
3415 int rd, int rs, int rt)
3416 {
3417 const char *opn = "mul vr54xx";
3418 TCGv t0 = tcg_temp_new();
3419 TCGv t1 = tcg_temp_new();
3420
3421 gen_load_gpr(t0, rs);
3422 gen_load_gpr(t1, rt);
3423
3424 switch (opc) {
3425 case OPC_VR54XX_MULS:
3426 gen_helper_muls(t0, cpu_env, t0, t1);
3427 opn = "muls";
3428 break;
3429 case OPC_VR54XX_MULSU:
3430 gen_helper_mulsu(t0, cpu_env, t0, t1);
3431 opn = "mulsu";
3432 break;
3433 case OPC_VR54XX_MACC:
3434 gen_helper_macc(t0, cpu_env, t0, t1);
3435 opn = "macc";
3436 break;
3437 case OPC_VR54XX_MACCU:
3438 gen_helper_maccu(t0, cpu_env, t0, t1);
3439 opn = "maccu";
3440 break;
3441 case OPC_VR54XX_MSAC:
3442 gen_helper_msac(t0, cpu_env, t0, t1);
3443 opn = "msac";
3444 break;
3445 case OPC_VR54XX_MSACU:
3446 gen_helper_msacu(t0, cpu_env, t0, t1);
3447 opn = "msacu";
3448 break;
3449 case OPC_VR54XX_MULHI:
3450 gen_helper_mulhi(t0, cpu_env, t0, t1);
3451 opn = "mulhi";
3452 break;
3453 case OPC_VR54XX_MULHIU:
3454 gen_helper_mulhiu(t0, cpu_env, t0, t1);
3455 opn = "mulhiu";
3456 break;
3457 case OPC_VR54XX_MULSHI:
3458 gen_helper_mulshi(t0, cpu_env, t0, t1);
3459 opn = "mulshi";
3460 break;
3461 case OPC_VR54XX_MULSHIU:
3462 gen_helper_mulshiu(t0, cpu_env, t0, t1);
3463 opn = "mulshiu";
3464 break;
3465 case OPC_VR54XX_MACCHI:
3466 gen_helper_macchi(t0, cpu_env, t0, t1);
3467 opn = "macchi";
3468 break;
3469 case OPC_VR54XX_MACCHIU:
3470 gen_helper_macchiu(t0, cpu_env, t0, t1);
3471 opn = "macchiu";
3472 break;
3473 case OPC_VR54XX_MSACHI:
3474 gen_helper_msachi(t0, cpu_env, t0, t1);
3475 opn = "msachi";
3476 break;
3477 case OPC_VR54XX_MSACHIU:
3478 gen_helper_msachiu(t0, cpu_env, t0, t1);
3479 opn = "msachiu";
3480 break;
3481 default:
3482 MIPS_INVAL("mul vr54xx");
3483 generate_exception(ctx, EXCP_RI);
3484 goto out;
3485 }
3486 gen_store_gpr(t0, rd);
3487 (void)opn; /* avoid a compiler warning */
3488 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
3489
3490 out:
3491 tcg_temp_free(t0);
3492 tcg_temp_free(t1);
3493 }
3494
3495 static void gen_cl (DisasContext *ctx, uint32_t opc,
3496 int rd, int rs)
3497 {
3498 const char *opn = "CLx";
3499 TCGv t0;
3500
3501 if (rd == 0) {
3502 /* Treat as NOP. */
3503 MIPS_DEBUG("NOP");
3504 return;
3505 }
3506 t0 = tcg_temp_new();
3507 gen_load_gpr(t0, rs);
3508 switch (opc) {
3509 case OPC_CLO:
3510 case R6_OPC_CLO:
3511 gen_helper_clo(cpu_gpr[rd], t0);
3512 opn = "clo";
3513 break;
3514 case OPC_CLZ:
3515 case R6_OPC_CLZ:
3516 gen_helper_clz(cpu_gpr[rd], t0);
3517 opn = "clz";
3518 break;
3519 #if defined(TARGET_MIPS64)
3520 case OPC_DCLO:
3521 case R6_OPC_DCLO:
3522 gen_helper_dclo(cpu_gpr[rd], t0);
3523 opn = "dclo";
3524 break;
3525 case OPC_DCLZ:
3526 case R6_OPC_DCLZ:
3527 gen_helper_dclz(cpu_gpr[rd], t0);
3528 opn = "dclz";
3529 break;
3530 #endif
3531 }
3532 (void)opn; /* avoid a compiler warning */
3533 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3534 tcg_temp_free(t0);
3535 }
3536
3537 /* Godson integer instructions */
3538 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3539 int rd, int rs, int rt)
3540 {
3541 const char *opn = "loongson";
3542 TCGv t0, t1;
3543
3544 if (rd == 0) {
3545 /* Treat as NOP. */
3546 MIPS_DEBUG("NOP");
3547 return;
3548 }
3549
3550 switch (opc) {
3551 case OPC_MULT_G_2E:
3552 case OPC_MULT_G_2F:
3553 case OPC_MULTU_G_2E:
3554 case OPC_MULTU_G_2F:
3555 #if defined(TARGET_MIPS64)
3556 case OPC_DMULT_G_2E:
3557 case OPC_DMULT_G_2F:
3558 case OPC_DMULTU_G_2E:
3559 case OPC_DMULTU_G_2F:
3560 #endif
3561 t0 = tcg_temp_new();
3562 t1 = tcg_temp_new();
3563 break;
3564 default:
3565 t0 = tcg_temp_local_new();
3566 t1 = tcg_temp_local_new();
3567 break;
3568 }
3569
3570 gen_load_gpr(t0, rs);
3571 gen_load_gpr(t1, rt);
3572
3573 switch (opc) {
3574 case OPC_MULT_G_2E:
3575 case OPC_MULT_G_2F:
3576 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3577 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3578 opn = "mult.g";
3579 break;
3580 case OPC_MULTU_G_2E:
3581 case OPC_MULTU_G_2F:
3582 tcg_gen_ext32u_tl(t0, t0);
3583 tcg_gen_ext32u_tl(t1, t1);
3584 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3585 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3586 opn = "multu.g";
3587 break;
3588 case OPC_DIV_G_2E:
3589 case OPC_DIV_G_2F:
3590 {
3591 int l1 = gen_new_label();
3592 int l2 = gen_new_label();
3593 int l3 = gen_new_label();
3594 tcg_gen_ext32s_tl(t0, t0);
3595 tcg_gen_ext32s_tl(t1, t1);
3596 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3597 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3598 tcg_gen_br(l3);
3599 gen_set_label(l1);
3600 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3601 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3602 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3603 tcg_gen_br(l3);
3604 gen_set_label(l2);
3605 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3606 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3607 gen_set_label(l3);
3608 }
3609 opn = "div.g";
3610 break;
3611 case OPC_DIVU_G_2E:
3612 case OPC_DIVU_G_2F:
3613 {
3614 int l1 = gen_new_label();
3615 int l2 = gen_new_label();
3616 tcg_gen_ext32u_tl(t0, t0);
3617 tcg_gen_ext32u_tl(t1, t1);
3618 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3619 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3620 tcg_gen_br(l2);
3621 gen_set_label(l1);
3622 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3623 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3624 gen_set_label(l2);
3625 }
3626 opn = "divu.g";
3627 break;
3628 case OPC_MOD_G_2E:
3629 case OPC_MOD_G_2F:
3630 {
3631 int l1 = gen_new_label();
3632 int l2 = gen_new_label();
3633 int l3 = gen_new_label();
3634 tcg_gen_ext32u_tl(t0, t0);
3635 tcg_gen_ext32u_tl(t1, t1);
3636 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3637 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3638 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3639 gen_set_label(l1);
3640 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3641 tcg_gen_br(l3);
3642 gen_set_label(l2);
3643 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3644 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3645 gen_set_label(l3);
3646 }
3647 opn = "mod.g";
3648 break;
3649 case OPC_MODU_G_2E:
3650 case OPC_MODU_G_2F:
3651 {
3652 int l1 = gen_new_label();
3653 int l2 = gen_new_label();
3654 tcg_gen_ext32u_tl(t0, t0);
3655 tcg_gen_ext32u_tl(t1, t1);
3656 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3657 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3658 tcg_gen_br(l2);
3659 gen_set_label(l1);
3660 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3661 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3662 gen_set_label(l2);
3663 }
3664 opn = "modu.g";
3665 break;
3666 #if defined(TARGET_MIPS64)
3667 case OPC_DMULT_G_2E:
3668 case OPC_DMULT_G_2F:
3669 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3670 opn = "dmult.g";
3671 break;
3672 case OPC_DMULTU_G_2E:
3673 case OPC_DMULTU_G_2F:
3674 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3675 opn = "dmultu.g";
3676 break;
3677 case OPC_DDIV_G_2E:
3678 case OPC_DDIV_G_2F:
3679 {
3680 int l1 = gen_new_label();
3681 int l2 = gen_new_label();
3682 int l3 = gen_new_label();
3683 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3684 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3685 tcg_gen_br(l3);
3686 gen_set_label(l1);
3687 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3688 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3689 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3690 tcg_gen_br(l3);
3691 gen_set_label(l2);
3692 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3693 gen_set_label(l3);
3694 }
3695 opn = "ddiv.g";
3696 break;
3697 case OPC_DDIVU_G_2E:
3698 case OPC_DDIVU_G_2F:
3699 {
3700 int l1 = gen_new_label();
3701 int l2 = gen_new_label();
3702 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3703 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3704 tcg_gen_br(l2);
3705 gen_set_label(l1);
3706 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3707 gen_set_label(l2);
3708 }
3709 opn = "ddivu.g";
3710 break;
3711 case OPC_DMOD_G_2E:
3712 case OPC_DMOD_G_2F:
3713 {
3714 int l1 = gen_new_label();
3715 int l2 = gen_new_label();
3716 int l3 = gen_new_label();
3717 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3718 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3719 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3720 gen_set_label(l1);
3721 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3722 tcg_gen_br(l3);
3723 gen_set_label(l2);
3724 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3725 gen_set_label(l3);
3726 }
3727 opn = "dmod.g";
3728 break;
3729 case OPC_DMODU_G_2E:
3730 case OPC_DMODU_G_2F:
3731 {
3732 int l1 = gen_new_label();
3733 int l2 = gen_new_label();
3734 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3735 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3736 tcg_gen_br(l2);
3737 gen_set_label(l1);
3738 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3739 gen_set_label(l2);
3740 }
3741 opn = "dmodu.g";
3742 break;
3743 #endif
3744 }
3745
3746 (void)opn; /* avoid a compiler warning */
3747 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3748 tcg_temp_free(t0);
3749 tcg_temp_free(t1);
3750 }
3751
3752 /* Loongson multimedia instructions */
3753 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3754 {
3755 const char *opn = "loongson_cp2";
3756 uint32_t opc, shift_max;
3757 TCGv_i64 t0, t1;
3758
3759 opc = MASK_LMI(ctx->opcode);
3760 switch (opc) {
3761 case OPC_ADD_CP2:
3762 case OPC_SUB_CP2:
3763 case OPC_DADD_CP2:
3764 case OPC_DSUB_CP2:
3765 t0 = tcg_temp_local_new_i64();
3766 t1 = tcg_temp_local_new_i64();
3767 break;
3768 default:
3769 t0 = tcg_temp_new_i64();
3770 t1 = tcg_temp_new_i64();
3771 break;
3772 }
3773
3774 gen_load_fpr64(ctx, t0, rs);
3775 gen_load_fpr64(ctx, t1, rt);
3776
3777 #define LMI_HELPER(UP, LO) \
3778 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3779 #define LMI_HELPER_1(UP, LO) \
3780 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3781 #define LMI_DIRECT(UP, LO, OP) \
3782 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3783
3784 switch (opc) {
3785 LMI_HELPER(PADDSH, paddsh);
3786 LMI_HELPER(PADDUSH, paddush);
3787 LMI_HELPER(PADDH, paddh);
3788 LMI_HELPER(PADDW, paddw);
3789 LMI_HELPER(PADDSB, paddsb);
3790 LMI_HELPER(PADDUSB, paddusb);
3791 LMI_HELPER(PADDB, paddb);
3792
3793 LMI_HELPER(PSUBSH, psubsh);
3794 LMI_HELPER(PSUBUSH, psubush);
3795 LMI_HELPER(PSUBH, psubh);
3796 LMI_HELPER(PSUBW, psubw);
3797 LMI_HELPER(PSUBSB, psubsb);
3798 LMI_HELPER(PSUBUSB, psubusb);
3799 LMI_HELPER(PSUBB, psubb);
3800
3801 LMI_HELPER(PSHUFH, pshufh);
3802 LMI_HELPER(PACKSSWH, packsswh);
3803 LMI_HELPER(PACKSSHB, packsshb);
3804 LMI_HELPER(PACKUSHB, packushb);
3805
3806 LMI_HELPER(PUNPCKLHW, punpcklhw);
3807 LMI_HELPER(PUNPCKHHW, punpckhhw);
3808 LMI_HELPER(PUNPCKLBH, punpcklbh);
3809 LMI_HELPER(PUNPCKHBH, punpckhbh);
3810 LMI_HELPER(PUNPCKLWD, punpcklwd);
3811 LMI_HELPER(PUNPCKHWD, punpckhwd);
3812
3813 LMI_HELPER(PAVGH, pavgh);
3814 LMI_HELPER(PAVGB, pavgb);
3815 LMI_HELPER(PMAXSH, pmaxsh);
3816 LMI_HELPER(PMINSH, pminsh);
3817 LMI_HELPER(PMAXUB, pmaxub);
3818 LMI_HELPER(PMINUB, pminub);
3819
3820 LMI_HELPER(PCMPEQW, pcmpeqw);
3821 LMI_HELPER(PCMPGTW, pcmpgtw);
3822 LMI_HELPER(PCMPEQH, pcmpeqh);
3823 LMI_HELPER(PCMPGTH, pcmpgth);
3824 LMI_HELPER(PCMPEQB, pcmpeqb);
3825 LMI_HELPER(PCMPGTB, pcmpgtb);
3826
3827 LMI_HELPER(PSLLW, psllw);
3828 LMI_HELPER(PSLLH, psllh);
3829 LMI_HELPER(PSRLW, psrlw);
3830 LMI_HELPER(PSRLH, psrlh);
3831 LMI_HELPER(PSRAW, psraw);
3832 LMI_HELPER(PSRAH, psrah);
3833
3834 LMI_HELPER(PMULLH, pmullh);
3835 LMI_HELPER(PMULHH, pmulhh);
3836 LMI_HELPER(PMULHUH, pmulhuh);
3837 LMI_HELPER(PMADDHW, pmaddhw);
3838
3839 LMI_HELPER(PASUBUB, pasubub);
3840 LMI_HELPER_1(BIADD, biadd);
3841 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3842
3843 LMI_DIRECT(PADDD, paddd, add);
3844 LMI_DIRECT(PSUBD, psubd, sub);
3845 LMI_DIRECT(XOR_CP2, xor, xor);
3846 LMI_DIRECT(NOR_CP2, nor, nor);
3847 LMI_DIRECT(AND_CP2, and, and);
3848 LMI_DIRECT(PANDN, pandn, andc);
3849 LMI_DIRECT(OR, or, or);
3850
3851 case OPC_PINSRH_0:
3852 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3853 opn = "pinsrh_0";
3854 break;
3855 case OPC_PINSRH_1:
3856 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3857 opn = "pinsrh_1";
3858 break;
3859 case OPC_PINSRH_2:
3860 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3861 opn = "pinsrh_2";
3862 break;
3863 case OPC_PINSRH_3:
3864 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3865 opn = "pinsrh_3";
3866 break;
3867
3868 case OPC_PEXTRH:
3869 tcg_gen_andi_i64(t1, t1, 3);
3870 tcg_gen_shli_i64(t1, t1, 4);
3871 tcg_gen_shr_i64(t0, t0, t1);
3872 tcg_gen_ext16u_i64(t0, t0);
3873 opn = "pextrh";
3874 break;
3875
3876 case OPC_ADDU_CP2:
3877 tcg_gen_add_i64(t0, t0, t1);
3878 tcg_gen_ext32s_i64(t0, t0);
3879 opn = "addu";
3880 break;
3881 case OPC_SUBU_CP2:
3882 tcg_gen_sub_i64(t0, t0, t1);
3883 tcg_gen_ext32s_i64(t0, t0);
3884 opn = "addu";
3885 break;
3886
3887 case OPC_SLL_CP2:
3888 opn = "sll";
3889 shift_max = 32;
3890 goto do_shift;
3891 case OPC_SRL_CP2:
3892 opn = "srl";
3893 shift_max = 32;
3894 goto do_shift;
3895 case OPC_SRA_CP2:
3896 opn = "sra";
3897 shift_max = 32;
3898 goto do_shift;
3899 case OPC_DSLL_CP2:
3900 opn = "dsll";
3901 shift_max = 64;
3902 goto do_shift;
3903 case OPC_DSRL_CP2:
3904 opn = "dsrl";
3905 shift_max = 64;
3906 goto do_shift;
3907 case OPC_DSRA_CP2:
3908 opn = "dsra";
3909 shift_max = 64;
3910 goto do_shift;
3911 do_shift:
3912 /* Make sure shift count isn't TCG undefined behaviour. */
3913 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3914
3915 switch (opc) {
3916 case OPC_SLL_CP2:
3917 case OPC_DSLL_CP2:
3918 tcg_gen_shl_i64(t0, t0, t1);
3919 break;
3920 case OPC_SRA_CP2:
3921 case OPC_DSRA_CP2:
3922 /* Since SRA is UndefinedResult without sign-extended inputs,
3923 we can treat SRA and DSRA the same. */
3924 tcg_gen_sar_i64(t0, t0, t1);
3925 break;
3926 case OPC_SRL_CP2:
3927 /* We want to shift in zeros for SRL; zero-extend first. */
3928 tcg_gen_ext32u_i64(t0, t0);
3929 /* FALLTHRU */
3930 case OPC_DSRL_CP2:
3931 tcg_gen_shr_i64(t0, t0, t1);
3932 break;
3933 }
3934
3935 if (shift_max == 32) {
3936 tcg_gen_ext32s_i64(t0, t0);
3937 }
3938
3939 /* Shifts larger than MAX produce zero. */
3940 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3941 tcg_gen_neg_i64(t1, t1);
3942 tcg_gen_and_i64(t0, t0, t1);
3943 break;
3944
3945 case OPC_ADD_CP2:
3946 case OPC_DADD_CP2:
3947 {
3948 TCGv_i64 t2 = tcg_temp_new_i64();
3949 int lab = gen_new_label();
3950
3951 tcg_gen_mov_i64(t2, t0);
3952 tcg_gen_add_i64(t0, t1, t2);
3953 if (opc == OPC_ADD_CP2) {
3954 tcg_gen_ext32s_i64(t0, t0);
3955 }
3956 tcg_gen_xor_i64(t1, t1, t2);
3957 tcg_gen_xor_i64(t2, t2, t0);
3958 tcg_gen_andc_i64(t1, t2, t1);
3959 tcg_temp_free_i64(t2);
3960 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3961 generate_exception(ctx, EXCP_OVERFLOW);
3962 gen_set_label(lab);
3963
3964 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3965 break;
3966 }
3967
3968 case OPC_SUB_CP2:
3969 case OPC_DSUB_CP2:
3970 {
3971 TCGv_i64 t2 = tcg_temp_new_i64();
3972 int lab = gen_new_label();
3973
3974 tcg_gen_mov_i64(t2, t0);
3975 tcg_gen_sub_i64(t0, t1, t2);
3976 if (opc == OPC_SUB_CP2) {
3977 tcg_gen_ext32s_i64(t0, t0);
3978 }
3979 tcg_gen_xor_i64(t1, t1, t2);
3980 tcg_gen_xor_i64(t2, t2, t0);
3981 tcg_gen_and_i64(t1, t1, t2);
3982 tcg_temp_free_i64(t2);
3983 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3984 generate_exception(ctx, EXCP_OVERFLOW);
3985 gen_set_label(lab);
3986
3987 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3988 break;
3989 }
3990
3991 case OPC_PMULUW:
3992 tcg_gen_ext32u_i64(t0, t0);
3993 tcg_gen_ext32u_i64(t1, t1);
3994 tcg_gen_mul_i64(t0, t0, t1);
3995 opn = "pmuluw";
3996 break;
3997
3998 case OPC_SEQU_CP2:
3999 case OPC_SEQ_CP2:
4000 case OPC_SLTU_CP2:
4001 case OPC_SLT_CP2:
4002 case OPC_SLEU_CP2:
4003 case OPC_SLE_CP2:
4004 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4005 FD field is the CC field? */
4006 default:
4007 MIPS_INVAL(opn);
4008 generate_exception(ctx, EXCP_RI);
4009 return;
4010 }
4011
4012 #undef LMI_HELPER
4013 #undef LMI_DIRECT
4014
4015 gen_store_fpr64(ctx, t0, rd);
4016
4017 (void)opn; /* avoid a compiler warning */
4018 MIPS_DEBUG("%s %s, %s, %s", opn,
4019 fregnames[rd], fregnames[rs], fregnames[rt]);
4020 tcg_temp_free_i64(t0);
4021 tcg_temp_free_i64(t1);
4022 }
4023
4024 /* Traps */
4025 static void gen_trap (DisasContext *ctx, uint32_t opc,
4026 int rs, int rt, int16_t imm)
4027 {
4028 int cond;
4029 TCGv t0 = tcg_temp_new();
4030 TCGv t1 = tcg_temp_new();
4031
4032 cond = 0;
4033 /* Load needed operands */
4034 switch (opc) {
4035 case OPC_TEQ:
4036 case OPC_TGE:
4037 case OPC_TGEU:
4038 case OPC_TLT:
4039 case OPC_TLTU:
4040 case OPC_TNE:
4041 /* Compare two registers */
4042 if (rs != rt) {
4043 gen_load_gpr(t0, rs);
4044 gen_load_gpr(t1, rt);
4045 cond = 1;
4046 }
4047 break;
4048 case OPC_TEQI:
4049 case OPC_TGEI:
4050 case OPC_TGEIU:
4051 case OPC_TLTI:
4052 case OPC_TLTIU:
4053 case OPC_TNEI:
4054 /* Compare register to immediate */
4055 if (rs != 0 || imm != 0) {
4056 gen_load_gpr(t0, rs);
4057 tcg_gen_movi_tl(t1, (int32_t)imm);
4058 cond = 1;
4059 }
4060 break;
4061 }
4062 if (cond == 0) {
4063 switch (opc) {
4064 case OPC_TEQ: /* rs == rs */
4065 case OPC_TEQI: /* r0 == 0 */
4066 case OPC_TGE: /* rs >= rs */
4067 case OPC_TGEI: /* r0 >= 0 */
4068 case OPC_TGEU: /* rs >= rs unsigned */
4069 case OPC_TGEIU: /* r0 >= 0 unsigned */
4070 /* Always trap */
4071 generate_exception(ctx, EXCP_TRAP);
4072 break;
4073 case OPC_TLT: /* rs < rs */
4074 case OPC_TLTI: /* r0 < 0 */
4075 case OPC_TLTU: /* rs < rs unsigned */
4076 case OPC_TLTIU: /* r0 < 0 unsigned */
4077 case OPC_TNE: /* rs != rs */
4078 case OPC_TNEI: /* r0 != 0 */
4079 /* Never trap: treat as NOP. */
4080 break;
4081 }
4082 } else {
4083 int l1 = gen_new_label();
4084
4085 switch (opc) {
4086 case OPC_TEQ:
4087 case OPC_TEQI:
4088 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4089 break;
4090 case OPC_TGE:
4091 case OPC_TGEI:
4092 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4093 break;
4094 case OPC_TGEU:
4095 case OPC_TGEIU:
4096 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4097 break;
4098 case OPC_TLT:
4099 case OPC_TLTI:
4100 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4101 break;
4102 case OPC_TLTU:
4103 case OPC_TLTIU:
4104 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4105 break;
4106 case OPC_TNE:
4107 case OPC_TNEI:
4108 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4109 break;
4110 }
4111 generate_exception(ctx, EXCP_TRAP);
4112 gen_set_label(l1);
4113 }
4114 tcg_temp_free(t0);
4115 tcg_temp_free(t1);
4116 }
4117
4118 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4119 {
4120 TranslationBlock *tb;
4121 tb = ctx->tb;
4122 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
4123 likely(!ctx->singlestep_enabled)) {
4124 tcg_gen_goto_tb(n);
4125 gen_save_pc(dest);
4126 tcg_gen_exit_tb((uintptr_t)tb + n);
4127 } else {
4128 gen_save_pc(dest);
4129 if (ctx->singlestep_enabled) {
4130 save_cpu_state(ctx, 0);
4131 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
4132 }
4133 tcg_gen_exit_tb(0);
4134 }
4135 }
4136
4137 /* Branches (before delay slot) */
4138 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
4139 int insn_bytes,
4140 int rs, int rt, int32_t offset)
4141 {
4142 target_ulong btgt = -1;
4143 int blink = 0;
4144 int bcond_compute = 0;
4145 TCGv t0 = tcg_temp_new();
4146 TCGv t1 = tcg_temp_new();
4147
4148 if (ctx->hflags & MIPS_HFLAG_BMASK) {
4149 #ifdef MIPS_DEBUG_DISAS
4150 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
4151 #endif
4152 generate_exception(ctx, EXCP_RI);
4153 goto out;
4154 }
4155
4156 /* Load needed operands */
4157 switch (opc) {
4158 case OPC_BEQ:
4159 case OPC_BEQL:
4160 case OPC_BNE:
4161 case OPC_BNEL:
4162 /* Compare two registers */
4163 if (rs != rt) {
4164 gen_load_gpr(t0, rs);
4165 gen_load_gpr(t1, rt);
4166 bcond_compute = 1;
4167 }
4168 btgt = ctx->pc + insn_bytes + offset;
4169 break;
4170 case OPC_BGEZ:
4171 case OPC_BGEZAL:
4172 case OPC_BGEZALS:
4173 case OPC_BGEZALL:
4174 case OPC_BGEZL:
4175 case OPC_BGTZ:
4176 case OPC_BGTZL:
4177 case OPC_BLEZ:
4178 case OPC_BLEZL:
4179 case OPC_BLTZ:
4180 case OPC_BLTZAL:
4181 case OPC_BLTZALS:
4182 case OPC_BLTZALL:
4183 case OPC_BLTZL:
4184 /* Compare to zero */
4185 if (rs != 0) {
4186 gen_load_gpr(t0, rs);
4187 bcond_compute = 1;
4188 }
4189 btgt = ctx->pc + insn_bytes + offset;
4190 break;
4191 case OPC_BPOSGE32:
4192 #if defined(TARGET_MIPS64)
4193 case OPC_BPOSGE64:
4194 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4195 #else
4196 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4197 #endif
4198 bcond_compute = 1;
4199 btgt = ctx->pc + insn_bytes + offset;
4200 break;
4201 case OPC_J:
4202 case OPC_JAL:
4203 case OPC_JALX:
4204 case OPC_JALS:
4205 case OPC_JALXS:
4206 /* Jump to immediate */
4207 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
4208 break;
4209 case OPC_JR:
4210 case OPC_JALR:
4211 case OPC_JALRC:
4212 case OPC_JALRS:
4213 /* Jump to register */
4214 if (offset != 0 && offset != 16) {
4215 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4216 others are reserved. */
4217 MIPS_INVAL("jump hint");
4218 generate_exception(ctx, EXCP_RI);
4219 goto out;
4220 }
4221 gen_load_gpr(btarget, rs);
4222 break;
4223 default:
4224 MIPS_INVAL("branch/jump");
4225 generate_exception(ctx, EXCP_RI);
4226 goto out;
4227 }
4228 if (bcond_compute == 0) {
4229 /* No condition to be computed */
4230 switch (opc) {
4231 case OPC_BEQ: /* rx == rx */
4232 case OPC_BEQL: /* rx == rx likely */
4233 case OPC_BGEZ: /* 0 >= 0 */
4234 case OPC_BGEZL: /* 0 >= 0 likely */
4235 case OPC_BLEZ: /* 0 <= 0 */
4236 case OPC_BLEZL: /* 0 <= 0 likely */
4237 /* Always take */
4238 ctx->hflags |= MIPS_HFLAG_B;
4239 MIPS_DEBUG("balways");
4240 break;
4241 case OPC_BGEZALS:
4242 case OPC_BGEZAL: /* 0 >= 0 */
4243 case OPC_BGEZALL: /* 0 >= 0 likely */
4244 ctx->hflags |= (opc == OPC_BGEZALS
4245 ? MIPS_HFLAG_BDS16
4246 : MIPS_HFLAG_BDS32);
4247 /* Always take and link */
4248 blink = 31;
4249 ctx->hflags |= MIPS_HFLAG_B;
4250 MIPS_DEBUG("balways and link");
4251 break;
4252 case OPC_BNE: /* rx != rx */
4253 case OPC_BGTZ: /* 0 > 0 */
4254 case OPC_BLTZ: /* 0 < 0 */
4255 /* Treat as NOP. */
4256 MIPS_DEBUG("bnever (NOP)");
4257 goto out;
4258 case OPC_BLTZALS:
4259 case OPC_BLTZAL: /* 0 < 0 */
4260 ctx->hflags |= (opc == OPC_BLTZALS
4261 ? MIPS_HFLAG_BDS16
4262 : MIPS_HFLAG_BDS32);
4263 /* Handle as an unconditional branch to get correct delay
4264 slot checking. */
4265 blink = 31;
4266 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
4267 ctx->hflags |= MIPS_HFLAG_B;
4268 MIPS_DEBUG("bnever and link");
4269 break;
4270 case OPC_BLTZALL: /* 0 < 0 likely */
4271 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
4272 /* Skip the instruction in the delay slot */
4273 MIPS_DEBUG("bnever, link and skip");
4274 ctx->pc += 4;
4275 goto out;
4276 case OPC_BNEL: /* rx != rx likely */
4277 case OPC_BGTZL: /* 0 > 0 likely */
4278 case OPC_BLTZL: /* 0 < 0 likely */
4279 /* Skip the instruction in the delay slot */
4280 MIPS_DEBUG("bnever and skip");
4281 ctx->pc += 4;
4282 goto out;
4283 case OPC_J:
4284 ctx->hflags |= MIPS_HFLAG_B;
4285 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
4286 break;
4287 case OPC_JALXS:
4288 case OPC_JALX:
4289 ctx->hflags |= MIPS_HFLAG_BX;
4290 /* Fallthrough */
4291 case OPC_JALS:
4292 case OPC_JAL:
4293 blink = 31;
4294 ctx->hflags |= MIPS_HFLAG_B;
4295 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
4296 ? MIPS_HFLAG_BDS16
4297 : MIPS_HFLAG_BDS32);
4298 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
4299 break;
4300 case OPC_JR:
4301 ctx->hflags |= MIPS_HFLAG_BR;
4302 if (insn_bytes == 4)
4303 ctx->hflags |= MIPS_HFLAG_BDS32;
4304 MIPS_DEBUG("jr %s", regnames[rs]);
4305 break;
4306 case OPC_JALRS:
4307 case OPC_JALR:
4308 case OPC_JALRC:
4309 blink = rt;
4310 ctx->hflags |= MIPS_HFLAG_BR;
4311 ctx->hflags |= (opc == OPC_JALRS
4312 ? MIPS_HFLAG_BDS16
4313 : MIPS_HFLAG_BDS32);
4314 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
4315 break;
4316 default:
4317 MIPS_INVAL("branch/jump");
4318 generate_exception(ctx, EXCP_RI);
4319 goto out;
4320 }
4321 } else {
4322 switch (opc) {
4323 case OPC_BEQ:
4324 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4325 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
4326 regnames[rs], regnames[rt], btgt);
4327 goto not_likely;
4328 case OPC_BEQL:
4329 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4330 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
4331 regnames[rs], regnames[rt], btgt);
4332 goto likely;
4333 case OPC_BNE:
4334 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4335 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
4336 regnames[rs], regnames[rt], btgt);
4337 goto not_likely;
4338 case OPC_BNEL:
4339 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4340 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
4341 regnames[rs], regnames[rt], btgt);
4342 goto likely;
4343 case OPC_BGEZ:
4344 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4345 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
4346 goto not_likely;
4347 case OPC_BGEZL:
4348 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4349 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4350 goto likely;
4351 case OPC_BGEZALS:
4352 case OPC_BGEZAL:
4353 ctx->hflags |= (opc == OPC_BGEZALS
4354 ? MIPS_HFLAG_BDS16
4355 : MIPS_HFLAG_BDS32);
4356 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4357 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
4358 blink = 31;
4359 goto not_likely;
4360 case OPC_BGEZALL:
4361 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
4362 blink = 31;
4363 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
4364 goto likely;
4365 case OPC_BGTZ:
4366 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4367 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
4368 goto not_likely;
4369 case OPC_BGTZL:
4370 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
4371 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4372 goto likely;
4373 case OPC_BLEZ:
4374 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4375 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
4376 goto not_likely;
4377 case OPC_BLEZL:
4378 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
4379 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4380 goto likely;
4381 case OPC_BLTZ:
4382 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4383 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
4384 goto not_likely;
4385 case OPC_BLTZL:
4386 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4387 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
4388 goto likely;
4389 case OPC_BPOSGE32:
4390 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
4391 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
4392 goto not_likely;
4393 #if defined(TARGET_MIPS64)
4394 case OPC_BPOSGE64:
4395 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
4396 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
4397 goto not_likely;
4398 #endif
4399 case OPC_BLTZALS:
4400 case OPC_BLTZAL:
4401 ctx->hflags |= (opc == OPC_BLTZALS
4402 ? MIPS_HFLAG_BDS16
4403 : MIPS_HFLAG_BDS32);
4404 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4405 blink = 31;
4406 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
4407 not_likely:
4408 ctx->hflags |= MIPS_HFLAG_BC;
4409 break;
4410 case OPC_BLTZALL:
4411 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
4412 blink = 31;
4413 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
4414 likely:
4415 ctx->hflags |= MIPS_HFLAG_BL;
4416 break;
4417 default:
4418 MIPS_INVAL("conditional branch/jump");
4419 generate_exception(ctx, EXCP_RI);
4420 goto out;
4421 }
4422 }
4423 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
4424 blink, ctx->hflags, btgt);
4425
4426 ctx->btarget = btgt;
4427 if (blink > 0) {
4428 int post_delay = insn_bytes;
4429 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
4430
4431 if (opc != OPC_JALRC)
4432 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
4433
4434 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
4435 }
4436
4437 out:
4438 if (insn_bytes == 2)
4439 ctx->hflags |= MIPS_HFLAG_B16;
4440 tcg_temp_free(t0);
4441 tcg_temp_free(t1);
4442 }
4443
4444 /* special3 bitfield operations */
4445 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
4446 int rs, int lsb, int msb)
4447 {
4448 TCGv t0 = tcg_temp_new();
4449 TCGv t1 = tcg_temp_new();
4450
4451 gen_load_gpr(t1, rs);
4452 switch (opc) {
4453 case OPC_EXT:
4454 if (lsb + msb > 31)
4455 goto fail;
4456 tcg_gen_shri_tl(t0, t1, lsb);
4457 if (msb != 31) {
4458 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
4459 } else {
4460 tcg_gen_ext32s_tl(t0, t0);
4461 }
4462 break;
4463 #if defined(TARGET_MIPS64)
4464 case OPC_DEXTM:
4465 tcg_gen_shri_tl(t0, t1, lsb);
4466 if (msb != 31) {
4467 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
4468 }
4469 break;
4470 case OPC_DEXTU:
4471 tcg_gen_shri_tl(t0, t1, lsb + 32);
4472 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4473 break;
4474 case OPC_DEXT:
4475 tcg_gen_shri_tl(t0, t1, lsb);
4476 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
4477 break;
4478 #endif
4479 case OPC_INS:
4480 if (lsb > msb)
4481 goto fail;
4482 gen_load_gpr(t0, rt);
4483 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4484 tcg_gen_ext32s_tl(t0, t0);
4485 break;
4486 #if defined(TARGET_MIPS64)
4487 case OPC_DINSM:
4488 gen_load_gpr(t0, rt);
4489 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
4490 break;
4491 case OPC_DINSU:
4492 gen_load_gpr(t0, rt);
4493 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
4494 break;
4495 case OPC_DINS:
4496 gen_load_gpr(t0, rt);
4497 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
4498 break;
4499 #endif
4500 default:
4501 fail:
4502 MIPS_INVAL("bitops");
4503 generate_exception(ctx, EXCP_RI);
4504 tcg_temp_free(t0);
4505 tcg_temp_free(t1);
4506 return;
4507 }
4508 gen_store_gpr(t0, rt);
4509 tcg_temp_free(t0);
4510 tcg_temp_free(t1);
4511 }
4512
4513 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4514 {
4515 TCGv t0;
4516
4517 if (rd == 0) {
4518 /* If no destination, treat it as a NOP. */
4519 MIPS_DEBUG("NOP");
4520 return;
4521 }
4522
4523 t0 = tcg_temp_new();
4524 gen_load_gpr(t0, rt);
4525 switch (op2) {
4526 case OPC_WSBH:
4527 {
4528 TCGv t1 = tcg_temp_new();
4529
4530 tcg_gen_shri_tl(t1, t0, 8);
4531 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4532 tcg_gen_shli_tl(t0, t0, 8);
4533 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4534 tcg_gen_or_tl(t0, t0, t1);
4535 tcg_temp_free(t1);
4536 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4537 }
4538 break;
4539 case OPC_SEB:
4540 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4541 break;
4542 case OPC_SEH:
4543 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4544 break;
4545 #if defined(TARGET_MIPS64)
4546 case OPC_DSBH:
4547 {
4548 TCGv t1 = tcg_temp_new();
4549
4550 tcg_gen_shri_tl(t1, t0, 8);
4551 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4552 tcg_gen_shli_tl(t0, t0, 8);
4553 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4554 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4555 tcg_temp_free(t1);
4556 }
4557 break;
4558 case OPC_DSHD:
4559 {
4560 TCGv t1 = tcg_temp_new();
4561
4562 tcg_gen_shri_tl(t1, t0, 16);
4563 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4564 tcg_gen_shli_tl(t0, t0, 16);
4565 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4566 tcg_gen_or_tl(t0, t0, t1);
4567 tcg_gen_shri_tl(t1, t0, 32);
4568 tcg_gen_shli_tl(t0, t0, 32);
4569 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4570 tcg_temp_free(t1);
4571 }
4572 break;
4573 #endif
4574 default:
4575 MIPS_INVAL("bsfhl");
4576 generate_exception(ctx, EXCP_RI);
4577 tcg_temp_free(t0);
4578 return;
4579 }
4580 tcg_temp_free(t0);
4581 }
4582
4583 #ifndef CONFIG_USER_ONLY
4584 /* CP0 (MMU and control) */
4585 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4586 {
4587 TCGv_i32 t0 = tcg_temp_new_i32();
4588
4589 tcg_gen_ld_i32(t0, cpu_env, off);
4590 tcg_gen_ext_i32_tl(arg, t0);
4591 tcg_temp_free_i32(t0);
4592 }
4593
4594 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4595 {
4596 tcg_gen_ld_tl(arg, cpu_env, off);
4597 tcg_gen_ext32s_tl(arg, arg);
4598 }
4599
4600 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4601 {
4602 TCGv_i32 t0 = tcg_temp_new_i32();
4603
4604 tcg_gen_trunc_tl_i32(t0, arg);
4605 tcg_gen_st_i32(t0, cpu_env, off);
4606 tcg_temp_free_i32(t0);
4607 }
4608
4609 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4610 {
4611 tcg_gen_ext32s_tl(arg, arg);
4612 tcg_gen_st_tl(arg, cpu_env, off);
4613 }
4614
4615 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4616 {
4617 const char *rn = "invalid";
4618
4619 if (sel != 0)
4620 check_insn(ctx, ISA_MIPS32);
4621
4622 switch (reg) {
4623 case 0:
4624 switch (sel) {
4625 case 0:
4626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4627 rn = "Index";
4628 break;
4629 case 1:
4630 check_insn(ctx, ASE_MT);
4631 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4632 rn = "MVPControl";
4633 break;
4634 case 2:
4635 check_insn(ctx, ASE_MT);
4636 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4637 rn = "MVPConf0";
4638 break;
4639 case 3:
4640 check_insn(ctx, ASE_MT);
4641 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4642 rn = "MVPConf1";
4643 break;
4644 default:
4645 goto die;
4646 }
4647 break;
4648 case 1:
4649 switch (sel) {
4650 case 0:
4651 gen_helper_mfc0_random(arg, cpu_env);
4652 rn = "Random";
4653 break;
4654 case 1:
4655 check_insn(ctx, ASE_MT);
4656 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4657 rn = "VPEControl";
4658 break;
4659 case 2:
4660 check_insn(ctx, ASE_MT);
4661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4662 rn = "VPEConf0";
4663 break;
4664 case 3:
4665 check_insn(ctx, ASE_MT);
4666 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4667 rn = "VPEConf1";
4668 break;
4669 case 4:
4670 check_insn(ctx, ASE_MT);
4671 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4672 rn = "YQMask";
4673 break;
4674 case 5:
4675 check_insn(ctx, ASE_MT);
4676 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4677 rn = "VPESchedule";
4678 break;
4679 case 6:
4680 check_insn(ctx, ASE_MT);
4681 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4682 rn = "VPEScheFBack";
4683 break;
4684 case 7:
4685 check_insn(ctx, ASE_MT);
4686 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4687 rn = "VPEOpt";
4688 break;
4689 default:
4690 goto die;
4691 }
4692 break;
4693 case 2:
4694 switch (sel) {
4695 case 0:
4696 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4697 tcg_gen_ext32s_tl(arg, arg);
4698 rn = "EntryLo0";
4699 break;
4700 case 1:
4701 check_insn(ctx, ASE_MT);
4702 gen_helper_mfc0_tcstatus(arg, cpu_env);
4703 rn = "TCStatus";
4704 break;
4705 case 2:
4706 check_insn(ctx, ASE_MT);
4707 gen_helper_mfc0_tcbind(arg, cpu_env);
4708 rn = "TCBind";
4709 break;
4710 case 3:
4711 check_insn(ctx, ASE_MT);
4712 gen_helper_mfc0_tcrestart(arg, cpu_env);
4713 rn = "TCRestart";
4714 break;
4715 case 4:
4716 check_insn(ctx, ASE_MT);
4717 gen_helper_mfc0_tchalt(arg, cpu_env);
4718 rn = "TCHalt";
4719 break;
4720 case 5:
4721 check_insn(ctx, ASE_MT);
4722 gen_helper_mfc0_tccontext(arg, cpu_env);
4723 rn = "TCContext";
4724 break;
4725 case 6:
4726 check_insn(ctx, ASE_MT);
4727 gen_helper_mfc0_tcschedule(arg, cpu_env);
4728 rn = "TCSchedule";
4729 break;
4730 case 7:
4731 check_insn(ctx, ASE_MT);
4732 gen_helper_mfc0_tcschefback(arg, cpu_env);
4733 rn = "TCScheFBack";
4734 break;
4735 default:
4736 goto die;
4737 }
4738 break;
4739 case 3:
4740 switch (sel) {
4741 case 0:
4742 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4743 tcg_gen_ext32s_tl(arg, arg);
4744 rn = "EntryLo1";
4745 break;
4746 default:
4747 goto die;
4748 }
4749 break;
4750 case 4:
4751 switch (sel) {
4752 case 0:
4753 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4754 tcg_gen_ext32s_tl(arg, arg);
4755 rn = "Context";
4756 break;
4757 case 1:
4758 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4759 rn = "ContextConfig";
4760 goto die;
4761 // break;
4762 case 2:
4763 if (ctx->ulri) {
4764 tcg_gen_ld32s_tl(arg, cpu_env,
4765 offsetof(CPUMIPSState,
4766 active_tc.CP0_UserLocal));
4767 rn = "UserLocal";
4768 } else {
4769 tcg_gen_movi_tl(arg, 0);
4770 }
4771 break;
4772 default:
4773 goto die;
4774 }
4775 break;
4776 case 5:
4777 switch (sel) {
4778 case 0:
4779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4780 rn = "PageMask";
4781 break;
4782 case 1:
4783 check_insn(ctx, ISA_MIPS32R2);
4784 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4785 rn = "PageGrain";
4786 break;
4787 default:
4788 goto die;
4789 }
4790 break;
4791 case 6:
4792 switch (sel) {
4793 case 0:
4794 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4795 rn = "Wired";
4796 break;
4797 case 1:
4798 check_insn(ctx, ISA_MIPS32R2);
4799 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4800 rn = "SRSConf0";
4801 break;
4802 case 2:
4803 check_insn(ctx, ISA_MIPS32R2);
4804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4805 rn = "SRSConf1";
4806 break;
4807 case 3:
4808 check_insn(ctx, ISA_MIPS32R2);
4809 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4810 rn = "SRSConf2";
4811 break;
4812 case 4:
4813 check_insn(ctx, ISA_MIPS32R2);
4814 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4815 rn = "SRSConf3";
4816 break;
4817 case 5:
4818 check_insn(ctx, ISA_MIPS32R2);
4819 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4820 rn = "SRSConf4";
4821 break;
4822 default:
4823 goto die;
4824 }
4825 break;
4826 case 7:
4827 switch (sel) {
4828 case 0:
4829 check_insn(ctx, ISA_MIPS32R2);
4830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4831 rn = "HWREna";
4832 break;
4833 default:
4834 goto die;
4835 }
4836 break;
4837 case 8:
4838 switch (sel) {
4839 case 0:
4840 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4841 tcg_gen_ext32s_tl(arg, arg);
4842 rn = "BadVAddr";
4843 break;
4844 default:
4845 goto die;
4846 }
4847 break;
4848 case 9:
4849 switch (sel) {
4850 case 0:
4851 /* Mark as an IO operation because we read the time. */
4852 if (use_icount)
4853 gen_io_start();
4854 gen_helper_mfc0_count(arg, cpu_env);
4855 if (use_icount) {
4856 gen_io_end();
4857 }
4858 /* Break the TB to be able to take timer interrupts immediately
4859 after reading count. */
4860 ctx->bstate = BS_STOP;
4861 rn = "Count";
4862 break;
4863 /* 6,7 are implementation dependent */
4864 default:
4865 goto die;
4866 }
4867 break;
4868 case 10:
4869 switch (sel) {
4870 case 0:
4871 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4872 tcg_gen_ext32s_tl(arg, arg);
4873 rn = "EntryHi";
4874 break;
4875 default:
4876 goto die;
4877 }
4878 break;
4879 case 11:
4880 switch (sel) {
4881 case 0:
4882 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4883 rn = "Compare";
4884 break;
4885 /* 6,7 are implementation dependent */
4886 default:
4887 goto die;
4888 }
4889 break;
4890 case 12:
4891 switch (sel) {
4892 case 0:
4893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4894 rn = "Status";
4895 break;
4896 case 1:
4897 check_insn(ctx, ISA_MIPS32R2);
4898 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4899 rn = "IntCtl";
4900 break;
4901 case 2:
4902 check_insn(ctx, ISA_MIPS32R2);
4903 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4904 rn = "SRSCtl";
4905 break;
4906 case 3:
4907 check_insn(ctx, ISA_MIPS32R2);
4908 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4909 rn = "SRSMap";
4910 break;
4911 default:
4912 goto die;
4913 }
4914 break;
4915 case 13:
4916 switch (sel) {
4917 case 0:
4918 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4919 rn = "Cause";
4920 break;
4921 default:
4922 goto die;
4923 }
4924 break;
4925 case 14:
4926 switch (sel) {
4927 case 0:
4928 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4929 tcg_gen_ext32s_tl(arg, arg);
4930 rn = "EPC";
4931 break;
4932 default:
4933 goto die;
4934 }
4935 break;
4936 case 15:
4937 switch (sel) {
4938 case 0:
4939 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4940 rn = "PRid";
4941 break;
4942 case 1:
4943 check_insn(ctx, ISA_MIPS32R2);
4944 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4945 rn = "EBase";
4946 break;
4947 default:
4948 goto die;
4949 }
4950 break;
4951 case 16:
4952 switch (sel) {
4953 case 0:
4954 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4955 rn = "Config";
4956 break;
4957 case 1:
4958 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4959 rn = "Config1";
4960 break;
4961 case 2:
4962 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4963 rn = "Config2";
4964 break;
4965 case 3:
4966 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4967 rn = "Config3";
4968 break;
4969 case 4:
4970 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4971 rn = "Config4";
4972 break;
4973 case 5:
4974 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4975 rn = "Config5";
4976 break;
4977 /* 6,7 are implementation dependent */
4978 case 6:
4979 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4980 rn = "Config6";
4981 break;
4982 case 7:
4983 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4984 rn = "Config7";
4985 break;
4986 default:
4987 goto die;
4988 }
4989 break;
4990 case 17:
4991 switch (sel) {
4992 case 0:
4993 gen_helper_mfc0_lladdr(arg, cpu_env);
4994 rn = "LLAddr";
4995 break;
4996 default:
4997 goto die;
4998 }
4999 break;
5000 case 18:
5001 switch (sel) {
5002 case 0 ... 7:
5003 gen_helper_1e0i(mfc0_watchlo, arg, sel);
5004 rn = "WatchLo";
5005 break;
5006 default:
5007 goto die;
5008 }
5009 break;
5010 case 19:
5011 switch (sel) {
5012 case 0 ...7:
5013 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5014 rn = "WatchHi";
5015 break;
5016 default:
5017 goto die;
5018 }
5019 break;
5020 case 20:
5021 switch (sel) {
5022 case 0:
5023 #if defined(TARGET_MIPS64)
5024 check_insn(ctx, ISA_MIPS3);
5025 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5026 tcg_gen_ext32s_tl(arg, arg);
5027 rn = "XContext";
5028 break;
5029 #endif
5030 default:
5031 goto die;
5032 }
5033 break;
5034 case 21:
5035 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5036 switch (sel) {
5037 case 0:
5038 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5039 rn = "Framemask";
5040 break;
5041 default:
5042 goto die;
5043 }
5044 break;
5045 case 22:
5046 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5047 rn = "'Diagnostic"; /* implementation dependent */
5048 break;
5049 case 23:
5050 switch (sel) {
5051 case 0:
5052 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5053 rn = "Debug";
5054 break;
5055 case 1:
5056 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5057 rn = "TraceControl";
5058 // break;
5059 case 2:
5060 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5061 rn = "TraceControl2";
5062 // break;
5063 case 3:
5064 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5065 rn = "UserTraceData";
5066 // break;
5067 case 4:
5068 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5069 rn = "TraceBPC";
5070 // break;
5071 default:
5072 goto die;
5073 }
5074 break;
5075 case 24:
5076 switch (sel) {
5077 case 0:
5078 /* EJTAG support */
5079 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5080 tcg_gen_ext32s_tl(arg, arg);
5081 rn = "DEPC";
5082 break;
5083 default:
5084 goto die;
5085 }
5086 break;
5087 case 25:
5088 switch (sel) {
5089 case 0:
5090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5091 rn = "Performance0";
5092 break;
5093 case 1:
5094 // gen_helper_mfc0_performance1(arg);
5095 rn = "Performance1";
5096 // break;
5097 case 2:
5098 // gen_helper_mfc0_performance2(arg);
5099 rn = "Performance2";
5100 // break;
5101 case 3:
5102 // gen_helper_mfc0_performance3(arg);
5103 rn = "Performance3";
5104 // break;
5105 case 4:
5106 // gen_helper_mfc0_performance4(arg);
5107 rn = "Performance4";
5108 // break;
5109 case 5:
5110 // gen_helper_mfc0_performance5(arg);
5111 rn = "Performance5";
5112 // break;
5113 case 6:
5114 // gen_helper_mfc0_performance6(arg);
5115 rn = "Performance6";
5116 // break;
5117 case 7:
5118 // gen_helper_mfc0_performance7(arg);
5119 rn = "Performance7";
5120 // break;
5121 default:
5122 goto die;
5123 }
5124 break;
5125 case 26:
5126 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5127 rn = "ECC";
5128 break;
5129 case 27:
5130 switch (sel) {
5131 case 0 ... 3:
5132 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5133 rn = "CacheErr";
5134 break;
5135 default:
5136 goto die;
5137 }
5138 break;
5139 case 28:
5140 switch (sel) {
5141 case 0:
5142 case 2:
5143 case 4:
5144 case 6:
5145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5146 rn = "TagLo";
5147 break;
5148 case 1:
5149 case 3:
5150 case 5:
5151 case 7:
5152 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5153 rn = "DataLo";
5154 break;
5155 default:
5156 goto die;
5157 }
5158 break;
5159 case 29:
5160 switch (sel) {
5161 case 0:
5162 case 2:
5163 case 4:
5164 case 6:
5165 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5166 rn = "TagHi";
5167 break;
5168 case 1:
5169 case 3:
5170 case 5:
5171 case 7:
5172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5173 rn = "DataHi";
5174 break;
5175 default:
5176 goto die;
5177 }
5178 break;
5179 case 30:
5180 switch (sel) {
5181 case 0:
5182 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5183 tcg_gen_ext32s_tl(arg, arg);
5184 rn = "ErrorEPC";
5185 break;
5186 default:
5187 goto die;
5188 }
5189 break;
5190 case 31:
5191 switch (sel) {
5192 case 0:
5193 /* EJTAG support */
5194 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5195 rn = "DESAVE";
5196 break;
5197 default:
5198 goto die;
5199 }
5200 break;
5201 default:
5202 goto die;
5203 }
5204 (void)rn; /* avoid a compiler warning */
5205 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5206 return;
5207
5208 die:
5209 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5210 generate_exception(ctx, EXCP_RI);
5211 }
5212
5213 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5214 {
5215 const char *rn = "invalid";
5216
5217 if (sel != 0)
5218 check_insn(ctx, ISA_MIPS32);
5219
5220 if (use_icount)
5221 gen_io_start();
5222
5223 switch (reg) {
5224 case 0:
5225 switch (sel) {
5226 case 0:
5227 gen_helper_mtc0_index(cpu_env, arg);
5228 rn = "Index";
5229 break;
5230 case 1:
5231 check_insn(ctx, ASE_MT);
5232 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5233 rn = "MVPControl";
5234 break;
5235 case 2:
5236 check_insn(ctx, ASE_MT);
5237 /* ignored */
5238 rn = "MVPConf0";
5239 break;
5240 case 3:
5241 check_insn(ctx, ASE_MT);
5242 /* ignored */
5243 rn = "MVPConf1";
5244 break;
5245 default:
5246 goto die;
5247 }
5248 break;
5249 case 1:
5250 switch (sel) {
5251 case 0:
5252 /* ignored */
5253 rn = "Random";
5254 break;
5255 case 1:
5256 check_insn(ctx, ASE_MT);
5257 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5258 rn = "VPEControl";
5259 break;
5260 case 2:
5261 check_insn(ctx, ASE_MT);
5262 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5263 rn = "VPEConf0";
5264 break;
5265 case 3:
5266 check_insn(ctx, ASE_MT);
5267 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5268 rn = "VPEConf1";
5269 break;
5270 case 4:
5271 check_insn(ctx, ASE_MT);
5272 gen_helper_mtc0_yqmask(cpu_env, arg);
5273 rn = "YQMask";
5274 break;
5275 case 5:
5276 check_insn(ctx, ASE_MT);
5277 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5278 rn = "VPESchedule";
5279 break;
5280 case 6:
5281 check_insn(ctx, ASE_MT);
5282 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5283 rn = "VPEScheFBack";
5284 break;
5285 case 7:
5286 check_insn(ctx, ASE_MT);
5287 gen_helper_mtc0_vpeopt(cpu_env, arg);
5288 rn = "VPEOpt";
5289 break;
5290 default:
5291 goto die;
5292 }
5293 break;
5294 case 2:
5295 switch (sel) {
5296 case 0:
5297 gen_helper_mtc0_entrylo0(cpu_env, arg);
5298 rn = "EntryLo0";
5299 break;
5300 case 1:
5301 check_insn(ctx, ASE_MT);
5302 gen_helper_mtc0_tcstatus(cpu_env, arg);
5303 rn = "TCStatus";
5304 break;
5305 case 2:
5306 check_insn(ctx, ASE_MT);
5307 gen_helper_mtc0_tcbind(cpu_env, arg);
5308 rn = "TCBind";
5309 break;
5310 case 3:
5311 check_insn(ctx, ASE_MT);
5312 gen_helper_mtc0_tcrestart(cpu_env, arg);
5313 rn = "TCRestart";
5314 break;
5315 case 4:
5316 check_insn(ctx, ASE_MT);
5317 gen_helper_mtc0_tchalt(cpu_env, arg);
5318 rn = "TCHalt";
5319 break;
5320 case 5:
5321 check_insn(ctx, ASE_MT);
5322 gen_helper_mtc0_tccontext(cpu_env, arg);
5323 rn = "TCContext";
5324 break;
5325 case 6:
5326 check_insn(ctx, ASE_MT);
5327 gen_helper_mtc0_tcschedule(cpu_env, arg);
5328 rn = "TCSchedule";
5329 break;
5330 case 7:
5331 check_insn(ctx, ASE_MT);
5332 gen_helper_mtc0_tcschefback(cpu_env, arg);
5333 rn = "TCScheFBack";
5334 break;
5335 default:
5336 goto die;
5337 }
5338 break;
5339 case 3:
5340 switch (sel) {
5341 case 0:
5342 gen_helper_mtc0_entrylo1(cpu_env, arg);
5343 rn = "EntryLo1";
5344 break;
5345 default:
5346 goto die;
5347 }
5348 break;
5349 case 4:
5350 switch (sel) {
5351 case 0:
5352 gen_helper_mtc0_context(cpu_env, arg);
5353 rn = "Context";
5354 break;
5355 case 1:
5356 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5357 rn = "ContextConfig";
5358 goto die;
5359 // break;
5360 case 2:
5361 if (ctx->ulri) {
5362 tcg_gen_st_tl(arg, cpu_env,
5363 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5364 rn = "UserLocal";
5365 }
5366 break;
5367 default:
5368 goto die;
5369 }
5370 break;
5371 case 5:
5372 switch (sel) {
5373 case 0:
5374 gen_helper_mtc0_pagemask(cpu_env, arg);
5375 rn = "PageMask";
5376 break;
5377 case 1:
5378 check_insn(ctx, ISA_MIPS32R2);
5379 gen_helper_mtc0_pagegrain(cpu_env, arg);
5380 rn = "PageGrain";
5381 break;
5382 default:
5383 goto die;
5384 }
5385 break;
5386 case 6:
5387 switch (sel) {
5388 case 0:
5389 gen_helper_mtc0_wired(cpu_env, arg);
5390 rn = "Wired";
5391 break;
5392 case 1:
5393 check_insn(ctx, ISA_MIPS32R2);
5394 gen_helper_mtc0_srsconf0(cpu_env, arg);
5395 rn = "SRSConf0";
5396 break;
5397 case 2:
5398 check_insn(ctx, ISA_MIPS32R2);
5399 gen_helper_mtc0_srsconf1(cpu_env, arg);
5400 rn = "SRSConf1";
5401 break;
5402 case 3:
5403 check_insn(ctx, ISA_MIPS32R2);
5404 gen_helper_mtc0_srsconf2(cpu_env, arg);
5405 rn = "SRSConf2";
5406 break;
5407 case 4:
5408 check_insn(ctx, ISA_MIPS32R2);
5409 gen_helper_mtc0_srsconf3(cpu_env, arg);
5410 rn = "SRSConf3";
5411 break;
5412 case 5:
5413 check_insn(ctx, ISA_MIPS32R2);
5414 gen_helper_mtc0_srsconf4(cpu_env, arg);
5415 rn = "SRSConf4";
5416 break;
5417 default:
5418 goto die;
5419 }
5420 break;
5421 case 7:
5422 switch (sel) {
5423 case 0:
5424 check_insn(ctx, ISA_MIPS32R2);
5425 gen_helper_mtc0_hwrena(cpu_env, arg);
5426 ctx->bstate = BS_STOP;
5427 rn = "HWREna";
5428 break;
5429 default:
5430 goto die;
5431 }
5432 break;
5433 case 8:
5434 /* ignored */
5435 rn = "BadVAddr";
5436 break;
5437 case 9:
5438 switch (sel) {
5439 case 0:
5440 gen_helper_mtc0_count(cpu_env, arg);
5441 rn = "Count";
5442 break;
5443 /* 6,7 are implementation dependent */
5444 default:
5445 goto die;
5446 }
5447 break;
5448 case 10:
5449 switch (sel) {
5450 case 0:
5451 gen_helper_mtc0_entryhi(cpu_env, arg);
5452 rn = "EntryHi";
5453 break;
5454 default:
5455 goto die;
5456 }
5457 break;
5458 case 11:
5459 switch (sel) {
5460 case 0:
5461 gen_helper_mtc0_compare(cpu_env, arg);
5462 rn = "Compare";
5463 break;
5464 /* 6,7 are implementation dependent */
5465 default:
5466 goto die;
5467 }
5468 break;
5469 case 12:
5470 switch (sel) {
5471 case 0:
5472 save_cpu_state(ctx, 1);
5473 gen_helper_mtc0_status(cpu_env, arg);
5474 /* BS_STOP isn't good enough here, hflags may have changed. */
5475 gen_save_pc(ctx->pc + 4);
5476 ctx->bstate = BS_EXCP;
5477 rn = "Status";
5478 break;
5479 case 1:
5480 check_insn(ctx, ISA_MIPS32R2);
5481 gen_helper_mtc0_intctl(cpu_env, arg);
5482 /* Stop translation as we may have switched the execution mode */
5483 ctx->bstate = BS_STOP;
5484 rn = "IntCtl";
5485 break;
5486 case 2:
5487 check_insn(ctx, ISA_MIPS32R2);
5488 gen_helper_mtc0_srsctl(cpu_env, arg);
5489 /* Stop translation as we may have switched the execution mode */
5490 ctx->bstate = BS_STOP;
5491 rn = "SRSCtl";
5492 break;
5493 case 3:
5494 check_insn(ctx, ISA_MIPS32R2);
5495 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5496 /* Stop translation as we may have switched the execution mode */
5497 ctx->bstate = BS_STOP;
5498 rn = "SRSMap";
5499 break;
5500 default:
5501 goto die;
5502 }
5503 break;
5504 case 13:
5505 switch (sel) {
5506 case 0:
5507 save_cpu_state(ctx, 1);
5508 gen_helper_mtc0_cause(cpu_env, arg);
5509 rn = "Cause";
5510 break;
5511 default:
5512 goto die;
5513 }
5514 break;
5515 case 14:
5516 switch (sel) {
5517 case 0:
5518 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5519 rn = "EPC";
5520 break;
5521 default:
5522 goto die;
5523 }
5524 break;
5525 case 15:
5526 switch (sel) {
5527 case 0:
5528 /* ignored */
5529 rn = "PRid";
5530 break;
5531 case 1:
5532 check_insn(ctx, ISA_MIPS32R2);
5533 gen_helper_mtc0_ebase(cpu_env, arg);
5534 rn = "EBase";
5535 break;
5536 default:
5537 goto die;
5538 }
5539 break;
5540 case 16:
5541 switch (sel) {
5542 case 0:
5543 gen_helper_mtc0_config0(cpu_env, arg);
5544 rn = "Config";
5545 /* Stop translation as we may have switched the execution mode */
5546 ctx->bstate = BS_STOP;
5547 break;
5548 case 1:
5549 /* ignored, read only */
5550 rn = "Config1";
5551 break;
5552 case 2:
5553 gen_helper_mtc0_config2(cpu_env, arg);
5554 rn = "Config2";
5555 /* Stop translation as we may have switched the execution mode */
5556 ctx->bstate = BS_STOP;
5557 break;
5558 case 3:
5559 /* ignored, read only */
5560 rn = "Config3";
5561 break;
5562 case 4:
5563 gen_helper_mtc0_config4(cpu_env, arg);
5564 rn = "Config4";
5565 ctx->bstate = BS_STOP;
5566 break;
5567 case 5:
5568 gen_helper_mtc0_config5(cpu_env, arg);
5569 rn = "Config5";
5570 /* Stop translation as we may have switched the execution mode */
5571 ctx->bstate = BS_STOP;
5572 break;
5573 /* 6,7 are implementation dependent */
5574 case 6:
5575 /* ignored */
5576 rn = "Config6";
5577 break;
5578 case 7:
5579 /* ignored */
5580 rn = "Config7";
5581 break;
5582 default:
5583 rn = "Invalid config selector";
5584 goto die;
5585 }
5586 break;
5587 case 17:
5588 switch (sel) {
5589 case 0:
5590 gen_helper_mtc0_lladdr(cpu_env, arg);
5591 rn = "LLAddr";
5592 break;
5593 default:
5594 goto die;
5595 }
5596 break;
5597 case 18:
5598 switch (sel) {
5599 case 0 ... 7:
5600 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5601 rn = "WatchLo";
5602 break;
5603 default:
5604 goto die;
5605 }
5606 break;
5607 case 19:
5608 switch (sel) {
5609 case 0 ... 7:
5610 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5611 rn = "WatchHi";
5612 break;
5613 default:
5614 goto die;
5615 }
5616 break;
5617 case 20:
5618 switch (sel) {
5619 case 0:
5620 #if defined(TARGET_MIPS64)
5621 check_insn(ctx, ISA_MIPS3);
5622 gen_helper_mtc0_xcontext(cpu_env, arg);
5623 rn = "XContext";
5624 break;
5625 #endif
5626 default:
5627 goto die;
5628 }
5629 break;
5630 case 21:
5631 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5632 switch (sel) {
5633 case 0:
5634 gen_helper_mtc0_framemask(cpu_env, arg);
5635 rn = "Framemask";
5636 break;
5637 default:
5638 goto die;
5639 }
5640 break;
5641 case 22:
5642 /* ignored */
5643 rn = "Diagnostic"; /* implementation dependent */
5644 break;
5645 case 23:
5646 switch (sel) {
5647 case 0:
5648 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5649 /* BS_STOP isn't good enough here, hflags may have changed. */
5650 gen_save_pc(ctx->pc + 4);
5651 ctx->bstate = BS_EXCP;
5652 rn = "Debug";
5653 break;
5654 case 1:
5655 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5656 rn = "TraceControl";
5657 /* Stop translation as we may have switched the execution mode */
5658 ctx->bstate = BS_STOP;
5659 // break;
5660 case 2:
5661 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5662 rn = "TraceControl2";
5663 /* Stop translation as we may have switched the execution mode */
5664 ctx->bstate = BS_STOP;
5665 // break;
5666 case 3:
5667 /* Stop translation as we may have switched the execution mode */
5668 ctx->bstate = BS_STOP;
5669 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5670 rn = "UserTraceData";
5671 /* Stop translation as we may have switched the execution mode */
5672 ctx->bstate = BS_STOP;
5673 // break;
5674 case 4:
5675 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5676 /* Stop translation as we may have switched the execution mode */
5677 ctx->bstate = BS_STOP;
5678 rn = "TraceBPC";
5679 // break;
5680 default:
5681 goto die;
5682 }
5683 break;
5684 case 24:
5685 switch (sel) {
5686 case 0:
5687 /* EJTAG support */
5688 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5689 rn = "DEPC";
5690 break;
5691 default:
5692 goto die;
5693 }
5694 break;
5695 case 25:
5696 switch (sel) {
5697 case 0:
5698 gen_helper_mtc0_performance0(cpu_env, arg);
5699 rn = "Performance0";
5700 break;
5701 case 1:
5702 // gen_helper_mtc0_performance1(arg);
5703 rn = "Performance1";
5704 // break;
5705 case 2:
5706 // gen_helper_mtc0_performance2(arg);
5707 rn = "Performance2";
5708 // break;
5709 case 3:
5710 // gen_helper_mtc0_performance3(arg);
5711 rn = "Performance3";
5712 // break;
5713 case 4:
5714 // gen_helper_mtc0_performance4(arg);
5715 rn = "Performance4";
5716 // break;
5717 case 5:
5718 // gen_helper_mtc0_performance5(arg);
5719 rn = "Performance5";
5720 // break;
5721 case 6:
5722 // gen_helper_mtc0_performance6(arg);
5723 rn = "Performance6";
5724 // break;
5725 case 7:
5726 // gen_helper_mtc0_performance7(arg);
5727 rn = "Performance7";
5728 // break;
5729 default:
5730 goto die;
5731 }
5732 break;
5733 case 26:
5734 /* ignored */
5735 rn = "ECC";
5736 break;
5737 case 27:
5738 switch (sel) {
5739 case 0 ... 3:
5740 /* ignored */
5741 rn = "CacheErr";
5742 break;
5743 default:
5744 goto die;
5745 }
5746 break;
5747 case 28:
5748 switch (sel) {
5749 case 0:
5750 case 2:
5751 case 4:
5752 case 6:
5753 gen_helper_mtc0_taglo(cpu_env, arg);
5754 rn = "TagLo";
5755 break;
5756 case 1:
5757 case 3:
5758 case 5:
5759 case 7:
5760 gen_helper_mtc0_datalo(cpu_env, arg);
5761 rn = "DataLo";
5762 break;
5763 default:
5764 goto die;
5765 }
5766 break;
5767 case 29:
5768 switch (sel) {
5769 case 0:
5770 case 2:
5771 case 4:
5772 case 6:
5773 gen_helper_mtc0_taghi(cpu_env, arg);
5774 rn = "TagHi";
5775 break;
5776 case 1:
5777 case 3:
5778 case 5:
5779 case 7:
5780 gen_helper_mtc0_datahi(cpu_env, arg);
5781 rn = "DataHi";
5782 break;
5783 default:
5784 rn = "invalid sel";
5785 goto die;
5786 }
5787 break;
5788 case 30:
5789 switch (sel) {
5790 case 0:
5791 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5792 rn = "ErrorEPC";
5793 break;
5794 default:
5795 goto die;
5796 }
5797 break;
5798 case 31:
5799 switch (sel) {
5800 case 0:
5801 /* EJTAG support */
5802 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5803 rn = "DESAVE";
5804 break;
5805 default:
5806 goto die;
5807 }
5808 /* Stop translation as we may have switched the execution mode */
5809 ctx->bstate = BS_STOP;
5810 break;
5811 default:
5812 goto die;
5813 }
5814 (void)rn; /* avoid a compiler warning */
5815 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5816 /* For simplicity assume that all writes can cause interrupts. */
5817 if (use_icount) {
5818 gen_io_end();
5819 ctx->bstate = BS_STOP;
5820 }
5821 return;
5822
5823 die:
5824 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5825 generate_exception(ctx, EXCP_RI);
5826 }
5827
5828 #if defined(TARGET_MIPS64)
5829 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5830 {
5831 const char *rn = "invalid";
5832
5833 if (sel != 0)
5834 check_insn(ctx, ISA_MIPS64);
5835
5836 switch (reg) {
5837 case 0:
5838 switch (sel) {
5839 case 0:
5840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5841 rn = "Index";
5842 break;
5843 case 1:
5844 check_insn(ctx, ASE_MT);
5845 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5846 rn = "MVPControl";
5847 break;
5848 case 2:
5849 check_insn(ctx, ASE_MT);
5850 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5851 rn = "MVPConf0";
5852 break;
5853 case 3:
5854 check_insn(ctx, ASE_MT);
5855 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5856 rn = "MVPConf1";
5857 break;
5858 default:
5859 goto die;
5860 }
5861 break;
5862 case 1:
5863 switch (sel) {
5864 case 0:
5865 gen_helper_mfc0_random(arg, cpu_env);
5866 rn = "Random";
5867 break;
5868 case 1:
5869 check_insn(ctx, ASE_MT);
5870 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5871 rn = "VPEControl";
5872 break;
5873 case 2:
5874 check_insn(ctx, ASE_MT);
5875 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5876 rn = "VPEConf0";
5877 break;
5878 case 3:
5879 check_insn(ctx, ASE_MT);
5880 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5881 rn = "VPEConf1";
5882 break;
5883 case 4:
5884 check_insn(ctx, ASE_MT);
5885 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5886 rn = "YQMask";
5887 break;
5888 case 5:
5889 check_insn(ctx, ASE_MT);
5890 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5891 rn = "VPESchedule";
5892 break;
5893 case 6:
5894 check_insn(ctx, ASE_MT);
5895 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5896 rn = "VPEScheFBack";
5897 break;
5898 case 7:
5899 check_insn(ctx, ASE_MT);
5900 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5901 rn = "VPEOpt";
5902 break;
5903 default:
5904 goto die;
5905 }
5906 break;
5907 case 2:
5908 switch (sel) {
5909 case 0:
5910 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5911 rn = "EntryLo0";
5912 break;
5913 case 1:
5914 check_insn(ctx, ASE_MT);
5915 gen_helper_mfc0_tcstatus(arg, cpu_env);
5916 rn = "TCStatus";
5917 break;
5918 case 2:
5919 check_insn(ctx, ASE_MT);
5920 gen_helper_mfc0_tcbind(arg, cpu_env);
5921 rn = "TCBind";
5922 break;
5923 case 3:
5924 check_insn(ctx, ASE_MT);
5925 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5926 rn = "TCRestart";
5927 break;
5928 case 4:
5929 check_insn(ctx, ASE_MT);
5930 gen_helper_dmfc0_tchalt(arg, cpu_env);
5931 rn = "TCHalt";
5932 break;
5933 case 5:
5934 check_insn(ctx, ASE_MT);
5935 gen_helper_dmfc0_tccontext(arg, cpu_env);
5936 rn = "TCContext";
5937 break;
5938 case 6:
5939 check_insn(ctx, ASE_MT);
5940 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5941 rn = "TCSchedule";
5942 break;
5943 case 7:
5944 check_insn(ctx, ASE_MT);
5945 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5946 rn = "TCScheFBack";
5947 break;
5948 default:
5949 goto die;
5950 }
5951 break;
5952 case 3:
5953 switch (sel) {
5954 case 0:
5955 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5956 rn = "EntryLo1";
5957 break;
5958 default:
5959 goto die;
5960 }
5961 break;
5962 case 4:
5963 switch (sel) {
5964 case 0:
5965 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5966 rn = "Context";
5967 break;
5968 case 1:
5969 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5970 rn = "ContextConfig";
5971 goto die;
5972 // break;
5973 case 2:
5974 if (ctx->ulri) {
5975 tcg_gen_ld_tl(arg, cpu_env,
5976 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5977 rn = "UserLocal";
5978 } else {
5979 tcg_gen_movi_tl(arg, 0);
5980 }
5981 break;
5982 default:
5983 goto die;
5984 }
5985 break;
5986 case 5:
5987 switch (sel) {
5988 case 0:
5989 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5990 rn = "PageMask";
5991 break;
5992 case 1:
5993 check_insn(ctx, ISA_MIPS32R2);
5994 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5995 rn = "PageGrain";
5996 break;
5997 default:
5998 goto die;
5999 }
6000 break;
6001 case 6:
6002 switch (sel) {
6003 case 0:
6004 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6005 rn = "Wired";
6006 break;
6007 case 1:
6008 check_insn(ctx, ISA_MIPS32R2);
6009 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6010 rn = "SRSConf0";
6011 break;
6012 case 2:
6013 check_insn(ctx, ISA_MIPS32R2);
6014 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6015 rn = "SRSConf1";
6016 break;
6017 case 3:
6018 check_insn(ctx, ISA_MIPS32R2);
6019 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6020 rn = "SRSConf2";
6021 break;
6022 case 4:
6023 check_insn(ctx, ISA_MIPS32R2);
6024 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6025 rn = "SRSConf3";
6026 break;
6027 case 5:
6028 check_insn(ctx, ISA_MIPS32R2);
6029 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6030 rn = "SRSConf4";
6031 break;
6032 default:
6033 goto die;
6034 }
6035 break;
6036 case 7:
6037 switch (sel) {
6038 case 0:
6039 check_insn(ctx, ISA_MIPS32R2);
6040 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6041 rn = "HWREna";
6042 break;
6043 default:
6044 goto die;
6045 }
6046 break;
6047 case 8:
6048 switch (sel) {
6049 case 0:
6050 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6051 rn = "BadVAddr";
6052 break;
6053 default:
6054 goto die;
6055 }
6056 break;
6057 case 9:
6058 switch (sel) {
6059 case 0:
6060 /* Mark as an IO operation because we read the time. */
6061 if (use_icount)
6062 gen_io_start();
6063 gen_helper_mfc0_count(arg, cpu_env);
6064 if (use_icount) {
6065 gen_io_end();
6066 }
6067 /* Break the TB to be able to take timer interrupts immediately
6068 after reading count. */
6069 ctx->bstate = BS_STOP;
6070 rn = "Count";
6071 break;
6072 /* 6,7 are implementation dependent */
6073 default:
6074 goto die;
6075 }
6076 break;
6077 case 10:
6078 switch (sel) {
6079 case 0:
6080 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6081 rn = "EntryHi";
6082 break;
6083 default:
6084 goto die;
6085 }
6086 break;
6087 case 11:
6088 switch (sel) {
6089 case 0:
6090 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6091 rn = "Compare";
6092 break;
6093 /* 6,7 are implementation dependent */
6094 default:
6095 goto die;
6096 }
6097 break;
6098 case 12:
6099 switch (sel) {
6100 case 0:
6101 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6102 rn = "Status";
6103 break;
6104 case 1:
6105 check_insn(ctx, ISA_MIPS32R2);
6106 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6107 rn = "IntCtl";
6108 break;
6109 case 2:
6110 check_insn(ctx, ISA_MIPS32R2);
6111 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6112 rn = "SRSCtl";
6113 break;
6114 case 3:
6115 check_insn(ctx, ISA_MIPS32R2);
6116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6117 rn = "SRSMap";
6118 break;
6119 default:
6120 goto die;
6121 }
6122 break;
6123 case 13:
6124 switch (sel) {
6125 case 0:
6126 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6127 rn = "Cause";
6128 break;
6129 default:
6130 goto die;
6131 }
6132 break;
6133 case 14:
6134 switch (sel) {
6135 case 0:
6136 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6137 rn = "EPC";
6138 break;
6139 default:
6140 goto die;
6141 }
6142 break;
6143 case 15:
6144 switch (sel) {
6145 case 0:
6146 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6147 rn = "PRid";
6148 break;
6149 case 1:
6150 check_insn(ctx, ISA_MIPS32R2);
6151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
6152 rn = "EBase";
6153 break;
6154 default:
6155 goto die;
6156 }
6157 break;
6158 case 16:
6159 switch (sel) {
6160 case 0:
6161 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6162 rn = "Config";
6163 break;
6164 case 1:
6165 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6166 rn = "Config1";
6167 break;
6168 case 2:
6169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6170 rn = "Config2";
6171 break;
6172 case 3:
6173 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6174 rn = "Config3";
6175 break;
6176 /* 6,7 are implementation dependent */
6177 case 6:
6178 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6179 rn = "Config6";
6180 break;
6181 case 7:
6182 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6183 rn = "Config7";
6184 break;
6185 default:
6186 goto die;
6187 }
6188 break;
6189 case 17:
6190 switch (sel) {
6191 case 0:
6192 gen_helper_dmfc0_lladdr(arg, cpu_env);
6193 rn = "LLAddr";
6194 break;
6195 default:
6196 goto die;
6197 }
6198 break;
6199 case 18:
6200 switch (sel) {
6201 case 0 ... 7:
6202 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
6203 rn = "WatchLo";
6204 break;
6205 default:
6206 goto die;
6207 }
6208 break;
6209 case 19:
6210 switch (sel) {
6211 case 0 ... 7:
6212 gen_helper_1e0i(mfc0_watchhi, arg, sel);
6213 rn = "WatchHi";
6214 break;
6215 default:
6216 goto die;
6217 }
6218 break;
6219 case 20:
6220 switch (sel) {
6221 case 0:
6222 check_insn(ctx, ISA_MIPS3);
6223 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6224 rn = "XContext";
6225 break;
6226 default:
6227 goto die;
6228 }
6229 break;
6230 case 21:
6231 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6232 switch (sel) {
6233 case 0:
6234 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6235 rn = "Framemask";
6236 break;
6237 default:
6238 goto die;
6239 }
6240 break;
6241 case 22:
6242 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6243 rn = "'Diagnostic"; /* implementation dependent */
6244 break;
6245 case 23:
6246 switch (sel) {
6247 case 0:
6248 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6249 rn = "Debug";
6250 break;
6251 case 1:
6252 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6253 rn = "TraceControl";
6254 // break;
6255 case 2:
6256 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6257 rn = "TraceControl2";
6258 // break;
6259 case 3:
6260 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6261 rn = "UserTraceData";
6262 // break;
6263 case 4:
6264 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6265 rn = "TraceBPC";
6266 // break;
6267 default:
6268 goto die;
6269 }
6270 break;
6271 case 24:
6272 switch (sel) {
6273 case 0:
6274 /* EJTAG support */
6275 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6276 rn = "DEPC";
6277 break;
6278 default:
6279 goto die;
6280 }
6281 break;
6282 case 25:
6283 switch (sel) {
6284 case 0:
6285 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6286 rn = "Performance0";
6287 break;
6288 case 1:
6289 // gen_helper_dmfc0_performance1(arg);
6290 rn = "Performance1";
6291 // break;
6292 case 2:
6293 // gen_helper_dmfc0_performance2(arg);
6294 rn = "Performance2";
6295 // break;
6296 case 3:
6297 // gen_helper_dmfc0_performance3(arg);
6298 rn = "Performance3";
6299 // break;
6300 case 4:
6301 // gen_helper_dmfc0_performance4(arg);
6302 rn = "Performance4";
6303 // break;
6304 case 5:
6305 // gen_helper_dmfc0_performance5(arg);
6306 rn = "Performance5";
6307 // break;
6308 case 6:
6309 // gen_helper_dmfc0_performance6(arg);
6310 rn = "Performance6";
6311 // break;
6312 case 7:
6313 // gen_helper_dmfc0_performance7(arg);
6314 rn = "Performance7";
6315 // break;
6316 default:
6317 goto die;
6318 }
6319 break;
6320 case 26:
6321 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6322 rn = "ECC";
6323 break;
6324 case 27:
6325 switch (sel) {
6326 /* ignored */
6327 case 0 ... 3:
6328 tcg_gen_movi_tl(arg, 0); /* unimplemented */
6329 rn = "CacheErr";
6330 break;
6331 default:
6332 goto die;
6333 }
6334 break;
6335 case 28:
6336 switch (sel) {
6337 case 0:
6338 case 2:
6339 case 4:
6340 case 6:
6341 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
6342 rn = "TagLo";
6343 break;
6344 case 1:
6345 case 3:
6346 case 5:
6347 case 7:
6348 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6349 rn = "DataLo";
6350 break;
6351 default:
6352 goto die;
6353 }
6354 break;
6355 case 29:
6356 switch (sel) {
6357 case 0:
6358 case 2:
6359 case 4:
6360 case 6:
6361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6362 rn = "TagHi";
6363 break;
6364 case 1:
6365 case 3:
6366 case 5:
6367 case 7:
6368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6369 rn = "DataHi";
6370 break;
6371 default:
6372 goto die;
6373 }
6374 break;
6375 case 30:
6376 switch (sel) {
6377 case 0:
6378 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6379 rn = "ErrorEPC";
6380 break;
6381 default:
6382 goto die;
6383 }
6384 break;
6385 case 31:
6386 switch (sel) {
6387 case 0:
6388 /* EJTAG support */
6389 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6390 rn = "DESAVE";
6391 break;
6392 default:
6393 goto die;
6394 }
6395 break;
6396 default:
6397 goto die;
6398 }
6399 (void)rn; /* avoid a compiler warning */
6400 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6401 return;
6402
6403 die:
6404 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6405 generate_exception(ctx, EXCP_RI);
6406 }
6407
6408 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6409 {
6410 const char *rn = "invalid";
6411
6412 if (sel != 0)
6413 check_insn(ctx, ISA_MIPS64);
6414
6415 if (use_icount)
6416 gen_io_start();
6417
6418 switch (reg) {
6419 case 0:
6420 switch (sel) {
6421 case 0:
6422 gen_helper_mtc0_index(cpu_env, arg);
6423 rn = "Index";
6424 break;
6425 case 1:
6426 check_insn(ctx, ASE_MT);
6427 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6428 rn = "MVPControl";
6429 break;
6430 case 2:
6431 check_insn(ctx, ASE_MT);
6432 /* ignored */
6433 rn = "MVPConf0";
6434 break;
6435 case 3:
6436 check_insn(ctx, ASE_MT);
6437 /* ignored */
6438 rn = "MVPConf1";
6439 break;
6440 default:
6441 goto die;
6442 }
6443 break;
6444 case 1:
6445 switch (sel) {
6446 case 0:
6447 /* ignored */
6448 rn = "Random";
6449 break;
6450 case 1:
6451 check_insn(ctx, ASE_MT);
6452 gen_helper_mtc0_vpecontrol(cpu_env, arg);
6453 rn = "VPEControl";
6454 break;
6455 case 2:
6456 check_insn(ctx, ASE_MT);
6457 gen_helper_mtc0_vpeconf0(cpu_env, arg);
6458 rn = "VPEConf0";
6459 break;
6460 case 3:
6461 check_insn(ctx, ASE_MT);
6462 gen_helper_mtc0_vpeconf1(cpu_env, arg);
6463 rn = "VPEConf1";
6464 break;
6465 case 4:
6466 check_insn(ctx, ASE_MT);
6467 gen_helper_mtc0_yqmask(cpu_env, arg);
6468 rn = "YQMask";
6469 break;
6470 case 5:
6471 check_insn(ctx, ASE_MT);
6472 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
6473 rn = "VPESchedule";
6474 break;
6475 case 6:
6476 check_insn(ctx, ASE_MT);
6477 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6478 rn = "VPEScheFBack";
6479 break;
6480 case 7:
6481 check_insn(ctx, ASE_MT);
6482 gen_helper_mtc0_vpeopt(cpu_env, arg);
6483 rn = "VPEOpt";
6484 break;
6485 default:
6486 goto die;
6487 }
6488 break;
6489 case 2:
6490 switch (sel) {
6491 case 0:
6492 gen_helper_mtc0_entrylo0(cpu_env, arg);
6493 rn = "EntryLo0";
6494 break;
6495 case 1:
6496 check_insn(ctx, ASE_MT);
6497 gen_helper_mtc0_tcstatus(cpu_env, arg);
6498 rn = "TCStatus";
6499 break;
6500 case 2:
6501 check_insn(ctx, ASE_MT);
6502 gen_helper_mtc0_tcbind(cpu_env, arg);
6503 rn = "TCBind";
6504 break;
6505 case 3:
6506 check_insn(ctx, ASE_MT);
6507 gen_helper_mtc0_tcrestart(cpu_env, arg);
6508 rn = "TCRestart";
6509 break;
6510 case 4:
6511 check_insn(ctx, ASE_MT);
6512 gen_helper_mtc0_tchalt(cpu_env, arg);
6513 rn = "TCHalt";
6514 break;
6515 case 5:
6516 check_insn(ctx, ASE_MT);
6517 gen_helper_mtc0_tccontext(cpu_env, arg);
6518 rn = "TCContext";
6519 break;
6520 case 6:
6521 check_insn(ctx, ASE_MT);
6522 gen_helper_mtc0_tcschedule(cpu_env, arg);
6523 rn = "TCSchedule";
6524 break;
6525 case 7:
6526 check_insn(ctx, ASE_MT);
6527 gen_helper_mtc0_tcschefback(cpu_env, arg);
6528 rn = "TCScheFBack";
6529 break;
6530 default:
6531 goto die;
6532 }
6533 break;
6534 case 3:
6535 switch (sel) {
6536 case 0:
6537 gen_helper_mtc0_entrylo1(cpu_env, arg);
6538 rn = "EntryLo1";
6539 break;
6540 default:
6541 goto die;
6542 }
6543 break;
6544 case 4:
6545 switch (sel) {
6546 case 0:
6547 gen_helper_mtc0_context(cpu_env, arg);
6548 rn = "Context";
6549 break;
6550 case 1:
6551 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6552 rn = "ContextConfig";
6553 goto die;
6554 // break;
6555 case 2:
6556 if (ctx->ulri) {
6557 tcg_gen_st_tl(arg, cpu_env,
6558 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6559 rn = "UserLocal";
6560 }
6561 break;
6562 default:
6563 goto die;
6564 }
6565 break;
6566 case 5:
6567 switch (sel) {
6568 case 0:
6569 gen_helper_mtc0_pagemask(cpu_env, arg);
6570 rn = "PageMask";
6571 break;
6572 case 1:
6573 check_insn(ctx, ISA_MIPS32R2);
6574 gen_helper_mtc0_pagegrain(cpu_env, arg);
6575 rn = "PageGrain";
6576 break;
6577 default:
6578 goto die;
6579 }
6580 break;
6581 case 6:
6582 switch (sel) {
6583 case 0:
6584 gen_helper_mtc0_wired(cpu_env, arg);
6585 rn = "Wired";
6586 break;
6587 case 1:
6588 check_insn(ctx, ISA_MIPS32R2);
6589 gen_helper_mtc0_srsconf0(cpu_env, arg);
6590 rn = "SRSConf0";
6591 break;
6592 case 2:
6593 check_insn(ctx, ISA_MIPS32R2);
6594 gen_helper_mtc0_srsconf1(cpu_env, arg);
6595 rn = "SRSConf1";
6596 break;
6597 case 3:
6598 check_insn(ctx, ISA_MIPS32R2);
6599 gen_helper_mtc0_srsconf2(cpu_env, arg);
6600 rn = "SRSConf2";
6601 break;
6602 case 4:
6603 check_insn(ctx, ISA_MIPS32R2);
6604 gen_helper_mtc0_srsconf3(cpu_env, arg);
6605 rn = "SRSConf3";
6606 break;
6607 case 5:
6608 check_insn(ctx, ISA_MIPS32R2);
6609 gen_helper_mtc0_srsconf4(cpu_env, arg);
6610 rn = "SRSConf4";
6611 break;
6612 default:
6613 goto die;
6614 }
6615 break;
6616 case 7:
6617 switch (sel) {
6618 case 0:
6619 check_insn(ctx, ISA_MIPS32R2);
6620 gen_helper_mtc0_hwrena(cpu_env, arg);
6621 ctx->bstate = BS_STOP;
6622 rn = "HWREna";
6623 break;
6624 default:
6625 goto die;
6626 }
6627 break;
6628 case 8:
6629 /* ignored */
6630 rn = "BadVAddr";
6631 break;
6632 case 9:
6633 switch (sel) {
6634 case 0:
6635 gen_helper_mtc0_count(cpu_env, arg);
6636 rn = "Count";
6637 break;
6638 /* 6,7 are implementation dependent */
6639 default:
6640 goto die;
6641 }
6642 /* Stop translation as we may have switched the execution mode */
6643 ctx->bstate = BS_STOP;
6644 break;
6645 case 10:
6646 switch (sel) {
6647 case 0:
6648 gen_helper_mtc0_entryhi(cpu_env, arg);
6649 rn = "EntryHi";
6650 break;
6651 default:
6652 goto die;
6653 }
6654 break;
6655 case 11:
6656 switch (sel) {
6657 case 0:
6658 gen_helper_mtc0_compare(cpu_env, arg);
6659 rn = "Compare";
6660 break;
6661 /* 6,7 are implementation dependent */
6662 default:
6663 goto die;
6664 }
6665 /* Stop translation as we may have switched the execution mode */
6666 ctx->bstate = BS_STOP;
6667 break;
6668 case 12:
6669 switch (sel) {
6670 case 0:
6671 save_cpu_state(ctx, 1);
6672 gen_helper_mtc0_status(cpu_env, arg);
6673 /* BS_STOP isn't good enough here, hflags may have changed. */
6674 gen_save_pc(ctx->pc + 4);
6675 ctx->bstate = BS_EXCP;
6676 rn = "Status";
6677 break;
6678 case 1:
6679 check_insn(ctx, ISA_MIPS32R2);
6680 gen_helper_mtc0_intctl(cpu_env, arg);
6681 /* Stop translation as we may have switched the execution mode */
6682 ctx->bstate = BS_STOP;
6683 rn = "IntCtl";
6684 break;
6685 case 2:
6686 check_insn(ctx, ISA_MIPS32R2);
6687 gen_helper_mtc0_srsctl(cpu_env, arg);
6688 /* Stop translation as we may have switched the execution mode */
6689 ctx->bstate = BS_STOP;
6690 rn = "SRSCtl";
6691 break;
6692 case 3:
6693 check_insn(ctx, ISA_MIPS32R2);
6694 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6695 /* Stop translation as we may have switched the execution mode */
6696 ctx->bstate = BS_STOP;
6697 rn = "SRSMap";
6698 break;
6699 default:
6700 goto die;
6701 }
6702 break;
6703 case 13:
6704 switch (sel) {
6705 case 0:
6706 save_cpu_state(ctx, 1);
6707 /* Mark as an IO operation because we may trigger a software
6708 interrupt. */
6709 if (use_icount) {
6710 gen_io_start();
6711 }
6712 gen_helper_mtc0_cause(cpu_env, arg);
6713 if (use_icount) {
6714 gen_io_end();
6715 }
6716 /* Stop translation as we may have triggered an intetrupt */
6717 ctx->bstate = BS_STOP;
6718 rn = "Cause";
6719 break;
6720 default:
6721 goto die;
6722 }
6723 break;
6724 case 14:
6725 switch (sel) {
6726 case 0:
6727 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6728 rn = "EPC";
6729 break;
6730 default:
6731 goto die;
6732 }
6733 break;
6734 case 15:
6735 switch (sel) {
6736 case 0:
6737 /* ignored */
6738 rn = "PRid";
6739 break;
6740 case 1:
6741 check_insn(ctx, ISA_MIPS32R2);
6742 gen_helper_mtc0_ebase(cpu_env, arg);
6743 rn = "EBase";
6744 break;
6745 default:
6746 goto die;
6747 }
6748 break;
6749 case 16:
6750 switch (sel) {
6751 case 0:
6752 gen_helper_mtc0_config0(cpu_env, arg);
6753 rn = "Config";
6754 /* Stop translation as we may have switched the execution mode */
6755 ctx->bstate = BS_STOP;
6756 break;
6757 case 1:
6758 /* ignored, read only */
6759 rn = "Config1";
6760 break;
6761 case 2:
6762 gen_helper_mtc0_config2(cpu_env, arg);
6763 rn = "Config2";
6764 /* Stop translation as we may have switched the execution mode */
6765 ctx->bstate = BS_STOP;
6766 break;
6767 case 3:
6768 /* ignored */
6769 rn = "Config3";
6770 break;
6771 /* 6,7 are implementation dependent */
6772 default:
6773 rn = "Invalid config selector";
6774 goto die;
6775 }
6776 break;
6777 case 17:
6778 switch (sel) {
6779 case 0:
6780 gen_helper_mtc0_lladdr(cpu_env, arg);
6781 rn = "LLAddr";
6782 break;
6783 default:
6784 goto die;
6785 }
6786 break;
6787 case 18:
6788 switch (sel) {
6789 case 0 ... 7:
6790 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6791 rn = "WatchLo";
6792 break;
6793 default:
6794 goto die;
6795 }
6796 break;
6797 case 19:
6798 switch (sel) {
6799 case 0 ... 7:
6800 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6801 rn = "WatchHi";
6802 break;
6803 default:
6804 goto die;
6805 }
6806 break;
6807 case 20:
6808 switch (sel) {
6809 case 0:
6810 check_insn(ctx, ISA_MIPS3);
6811 gen_helper_mtc0_xcontext(cpu_env, arg);
6812 rn = "XContext";
6813 break;
6814 default:
6815 goto die;
6816 }
6817 break;
6818 case 21:
6819 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6820 switch (sel) {
6821 case 0:
6822 gen_helper_mtc0_framemask(cpu_env, arg);
6823 rn = "Framemask";
6824 break;
6825 default:
6826 goto die;
6827 }
6828 break;
6829 case 22:
6830 /* ignored */
6831 rn = "Diagnostic"; /* implementation dependent */
6832 break;
6833 case 23:
6834 switch (sel) {
6835 case 0:
6836 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6837 /* BS_STOP isn't good enough here, hflags may have changed. */
6838 gen_save_pc(ctx->pc + 4);
6839 ctx->bstate = BS_EXCP;
6840 rn = "Debug";
6841 break;
6842 case 1:
6843 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6844 /* Stop translation as we may have switched the execution mode */
6845 ctx->bstate = BS_STOP;
6846 rn = "TraceControl";
6847 // break;
6848 case 2:
6849 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6850 /* Stop translation as we may have switched the execution mode */
6851 ctx->bstate = BS_STOP;
6852 rn = "TraceControl2";
6853 // break;
6854 case 3:
6855 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6856 /* Stop translation as we may have switched the execution mode */
6857 ctx->bstate = BS_STOP;
6858 rn = "UserTraceData";
6859 // break;
6860 case 4:
6861 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6862 /* Stop translation as we may have switched the execution mode */
6863 ctx->bstate = BS_STOP;
6864 rn = "TraceBPC";
6865 // break;
6866 default:
6867 goto die;
6868 }
6869 break;
6870 case 24:
6871 switch (sel) {
6872 case 0:
6873 /* EJTAG support */
6874 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6875 rn = "DEPC";
6876 break;
6877 default:
6878 goto die;
6879 }
6880 break;
6881 case 25:
6882 switch (sel) {
6883 case 0:
6884 gen_helper_mtc0_performance0(cpu_env, arg);
6885 rn = "Performance0";
6886 break;
6887 case 1:
6888 // gen_helper_mtc0_performance1(cpu_env, arg);
6889 rn = "Performance1";
6890 // break;
6891 case 2:
6892 // gen_helper_mtc0_performance2(cpu_env, arg);
6893 rn = "Performance2";
6894 // break;
6895 case 3:
6896 // gen_helper_mtc0_performance3(cpu_env, arg);
6897 rn = "Performance3";
6898 // break;
6899 case 4:
6900 // gen_helper_mtc0_performance4(cpu_env, arg);
6901 rn = "Performance4";
6902 // break;
6903 case 5:
6904 // gen_helper_mtc0_performance5(cpu_env, arg);
6905 rn = "Performance5";
6906 // break;
6907 case 6:
6908 // gen_helper_mtc0_performance6(cpu_env, arg);
6909 rn = "Performance6";
6910 // break;
6911 case 7:
6912 // gen_helper_mtc0_performance7(cpu_env, arg);
6913 rn = "Performance7";
6914 // break;
6915 default:
6916 goto die;
6917 }
6918 break;
6919 case 26:
6920 /* ignored */
6921 rn = "ECC";
6922 break;
6923 case 27:
6924 switch (sel) {
6925 case 0 ... 3:
6926 /* ignored */
6927 rn = "CacheErr";
6928 break;
6929 default:
6930 goto die;
6931 }
6932 break;
6933 case 28:
6934 switch (sel) {
6935 case 0:
6936 case 2:
6937 case 4:
6938 case 6:
6939 gen_helper_mtc0_taglo(cpu_env, arg);
6940 rn = "TagLo";
6941 break;
6942 case 1:
6943 case 3:
6944 case 5:
6945 case 7:
6946 gen_helper_mtc0_datalo(cpu_env, arg);
6947 rn = "DataLo";
6948 break;
6949 default:
6950 goto die;
6951 }
6952 break;
6953 case 29:
6954 switch (sel) {
6955 case 0:
6956 case 2:
6957 case 4:
6958 case 6:
6959 gen_helper_mtc0_taghi(cpu_env, arg);
6960 rn = "TagHi";
6961 break;
6962 case 1:
6963 case 3:
6964 case 5:
6965 case 7:
6966 gen_helper_mtc0_datahi(cpu_env, arg);
6967 rn = "DataHi";
6968 break;
6969 default:
6970 rn = "invalid sel";
6971 goto die;
6972 }
6973 break;
6974 case 30:
6975 switch (sel) {
6976 case 0:
6977 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6978 rn = "ErrorEPC";
6979 break;
6980 default:
6981 goto die;
6982 }
6983 break;
6984 case 31:
6985 switch (sel) {
6986 case 0:
6987 /* EJTAG support */
6988 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6989 rn = "DESAVE";
6990 break;
6991 default:
6992 goto die;
6993 }
6994 /* Stop translation as we may have switched the execution mode */
6995 ctx->bstate = BS_STOP;
6996 break;
6997 default:
6998 goto die;
6999 }
7000 (void)rn; /* avoid a compiler warning */
7001 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7002 /* For simplicity assume that all writes can cause interrupts. */
7003 if (use_icount) {
7004 gen_io_end();
7005 ctx->bstate = BS_STOP;
7006 }
7007 return;
7008
7009 die:
7010 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7011 generate_exception(ctx, EXCP_RI);
7012 }
7013 #endif /* TARGET_MIPS64 */
7014
7015 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
7016 int u, int sel, int h)
7017 {
7018 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7019 TCGv t0 = tcg_temp_local_new();
7020
7021 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7022 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7023 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7024 tcg_gen_movi_tl(t0, -1);
7025 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7026 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7027 tcg_gen_movi_tl(t0, -1);
7028 else if (u == 0) {
7029 switch (rt) {
7030 case 1:
7031 switch (sel) {
7032 case 1:
7033 gen_helper_mftc0_vpecontrol(t0, cpu_env);
7034 break;
7035 case 2:
7036 gen_helper_mftc0_vpeconf0(t0, cpu_env);
7037 break;
7038 default:
7039 goto die;
7040 break;
7041 }
7042 break;
7043 case 2:
7044 switch (sel) {
7045 case 1:
7046 gen_helper_mftc0_tcstatus(t0, cpu_env);
7047 break;
7048 case 2:
7049 gen_helper_mftc0_tcbind(t0, cpu_env);
7050 break;
7051 case 3:
7052 gen_helper_mftc0_tcrestart(t0, cpu_env);
7053 break;
7054 case 4:
7055 gen_helper_mftc0_tchalt(t0, cpu_env);
7056 break;
7057 case 5:
7058 gen_helper_mftc0_tccontext(t0, cpu_env);
7059 break;
7060 case 6:
7061 gen_helper_mftc0_tcschedule(t0, cpu_env);
7062 break;
7063 case 7:
7064 gen_helper_mftc0_tcschefback(t0, cpu_env);
7065 break;
7066 default:
7067 gen_mfc0(ctx, t0, rt, sel);
7068 break;
7069 }
7070 break;
7071 case 10:
7072 switch (sel) {
7073 case 0:
7074 gen_helper_mftc0_entryhi(t0, cpu_env);
7075 break;
7076 default:
7077 gen_mfc0(ctx, t0, rt, sel);
7078 break;
7079 }
7080 case 12:
7081 switch (sel) {
7082 case 0:
7083 gen_helper_mftc0_status(t0, cpu_env);
7084 break;
7085 default:
7086 gen_mfc0(ctx, t0, rt, sel);
7087 break;
7088 }
7089 case 13:
7090 switch (sel) {
7091 case 0:
7092 gen_helper_mftc0_cause(t0, cpu_env);
7093 break;
7094 default:
7095 goto die;
7096 break;
7097 }
7098 break;
7099 case 14:
7100 switch (sel) {
7101 case 0:
7102 gen_helper_mftc0_epc(t0, cpu_env);
7103 break;
7104 default:
7105 goto die;
7106 break;
7107 }
7108 break;
7109 case 15:
7110 switch (sel) {
7111 case 1:
7112 gen_helper_mftc0_ebase(t0, cpu_env);
7113 break;
7114 default:
7115 goto die;
7116 break;
7117 }
7118 break;
7119 case 16:
7120 switch (sel) {
7121 case 0 ... 7:
7122 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
7123 break;
7124 default:
7125 goto die;
7126 break;
7127 }
7128 break;
7129 case 23:
7130 switch (sel) {
7131 case 0:
7132 gen_helper_mftc0_debug(t0, cpu_env);
7133 break;
7134 default:
7135 gen_mfc0(ctx, t0, rt, sel);
7136 break;
7137 }
7138 break;
7139 default:
7140 gen_mfc0(ctx, t0, rt, sel);
7141 }
7142 } else switch (sel) {
7143 /* GPR registers. */
7144 case 0:
7145 gen_helper_1e0i(mftgpr, t0, rt);
7146 break;
7147 /* Auxiliary CPU registers */
7148 case 1:
7149 switch (rt) {
7150 case 0:
7151 gen_helper_1e0i(mftlo, t0, 0);
7152 break;
7153 case 1:
7154 gen_helper_1e0i(mfthi, t0, 0);
7155 break;
7156 case 2:
7157 gen_helper_1e0i(mftacx, t0, 0);
7158 break;
7159 case 4:
7160 gen_helper_1e0i(mftlo, t0, 1);
7161 break;
7162 case 5:
7163 gen_helper_1e0i(mfthi, t0, 1);
7164 break;
7165 case 6:
7166 gen_helper_1e0i(mftacx, t0, 1);
7167 break;
7168 case 8:
7169 gen_helper_1e0i(mftlo, t0, 2);
7170 break;
7171 case 9:
7172 gen_helper_1e0i(mfthi, t0, 2);
7173 break;
7174 case 10:
7175 gen_helper_1e0i(mftacx, t0, 2);
7176 break;
7177 case 12:
7178 gen_helper_1e0i(mftlo, t0, 3);
7179 break;
7180 case 13:
7181 gen_helper_1e0i(mfthi, t0, 3);
7182 break;
7183 case 14:
7184 gen_helper_1e0i(mftacx, t0, 3);
7185 break;
7186 case 16:
7187 gen_helper_mftdsp(t0, cpu_env);
7188 break;
7189 default:
7190 goto die;
7191 }
7192 break;
7193 /* Floating point (COP1). */
7194 case 2:
7195 /* XXX: For now we support only a single FPU context. */
7196 if (h == 0) {
7197 TCGv_i32 fp0 = tcg_temp_new_i32();
7198
7199 gen_load_fpr32(fp0, rt);
7200 tcg_gen_ext_i32_tl(t0, fp0);
7201 tcg_temp_free_i32(fp0);
7202 } else {
7203 TCGv_i32 fp0 = tcg_temp_new_i32();
7204
7205 gen_load_fpr32h(ctx, fp0, rt);
7206 tcg_gen_ext_i32_tl(t0, fp0);
7207 tcg_temp_free_i32(fp0);
7208 }
7209 break;
7210 case 3:
7211 /* XXX: For now we support only a single FPU context. */
7212 gen_helper_1e0i(cfc1, t0, rt);
7213 break;
7214 /* COP2: Not implemented. */
7215 case 4:
7216 case 5:
7217 /* fall through */
7218 default:
7219 goto die;
7220 }
7221 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7222 gen_store_gpr(t0, rd);
7223 tcg_temp_free(t0);
7224 return;
7225
7226 die:
7227 tcg_temp_free(t0);
7228 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
7229 generate_exception(ctx, EXCP_RI);
7230 }
7231
7232 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
7233 int u, int sel, int h)
7234 {
7235 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
7236 TCGv t0 = tcg_temp_local_new();
7237
7238 gen_load_gpr(t0, rt);
7239 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
7240 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
7241 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
7242 /* NOP */ ;
7243 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
7244 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
7245 /* NOP */ ;
7246 else if (u == 0) {
7247 switch (rd) {
7248 case 1:
7249 switch (sel) {
7250 case 1:
7251 gen_helper_mttc0_vpecontrol(cpu_env, t0);
7252 break;
7253 case 2:
7254 gen_helper_mttc0_vpeconf0(cpu_env, t0);
7255 break;
7256 default:
7257 goto die;
7258 break;
7259 }
7260 break;
7261 case 2:
7262 switch (sel) {
7263 case 1:
7264 gen_helper_mttc0_tcstatus(cpu_env, t0);
7265 break;
7266 case 2:
7267 gen_helper_mttc0_tcbind(cpu_env, t0);
7268 break;
7269 case 3:
7270 gen_helper_mttc0_tcrestart(cpu_env, t0);
7271 break;
7272 case 4:
7273 gen_helper_mttc0_tchalt(cpu_env, t0);
7274 break;
7275 case 5:
7276 gen_helper_mttc0_tccontext(cpu_env, t0);
7277 break;
7278 case 6:
7279 gen_helper_mttc0_tcschedule(cpu_env, t0);
7280 break;
7281 case 7:
7282 gen_helper_mttc0_tcschefback(cpu_env, t0);
7283 break;
7284 default:
7285 gen_mtc0(ctx, t0, rd, sel);
7286 break;
7287 }
7288 break;
7289 case 10:
7290 switch (sel) {
7291 case 0:
7292 gen_helper_mttc0_entryhi(cpu_env, t0);
7293 break;
7294 default:
7295 gen_mtc0(ctx, t0, rd, sel);
7296 break;
7297 }
7298 case 12:
7299 switch (sel) {
7300 case 0:
7301 gen_helper_mttc0_status(cpu_env, t0);
7302 break;
7303 default:
7304 gen_mtc0(ctx, t0, rd, sel);
7305 break;
7306 }
7307 case 13:
7308 switch (sel) {
7309 case 0:
7310 gen_helper_mttc0_cause(cpu_env, t0);
7311 break;
7312 default:
7313 goto die;
7314 break;
7315 }
7316 break;
7317 case 15:
7318 switch (sel) {
7319 case 1:
7320 gen_helper_mttc0_ebase(cpu_env, t0);
7321 break;
7322 default:
7323 goto die;
7324 break;
7325 }
7326 break;
7327 case 23:
7328 switch (sel) {
7329 case 0:
7330 gen_helper_mttc0_debug(cpu_env, t0);
7331 break;
7332 default:
7333 gen_mtc0(ctx, t0, rd, sel);
7334 break;
7335 }
7336 break;
7337 default:
7338 gen_mtc0(ctx, t0, rd, sel);
7339 }
7340 } else switch (sel) {
7341 /* GPR registers. */
7342 case 0:
7343 gen_helper_0e1i(mttgpr, t0, rd);
7344 break;
7345 /* Auxiliary CPU registers */
7346 case 1:
7347 switch (rd) {
7348 case 0:
7349 gen_helper_0e1i(mttlo, t0, 0);
7350 break;
7351 case 1:
7352 gen_helper_0e1i(mtthi, t0, 0);
7353 break;
7354 case 2:
7355 gen_helper_0e1i(mttacx, t0, 0);
7356 break;
7357 case 4:
7358 gen_helper_0e1i(mttlo, t0, 1);
7359 break;
7360 case 5:
7361 gen_helper_0e1i(mtthi, t0, 1);
7362 break;
7363 case 6:
7364 gen_helper_0e1i(mttacx, t0, 1);
7365 break;
7366 case 8:
7367 gen_helper_0e1i(mttlo, t0, 2);
7368 break;
7369 case 9:
7370 gen_helper_0e1i(mtthi, t0, 2);
7371 break;
7372 case 10:
7373 gen_helper_0e1i(mttacx, t0, 2);
7374 break;
7375 case 12:
7376 gen_helper_0e1i(mttlo, t0, 3);
7377 break;
7378 case 13:
7379 gen_helper_0e1i(mtthi, t0, 3);
7380 break;
7381 case 14:
7382 gen_helper_0e1i(mttacx, t0, 3);
7383 break;
7384 case 16:
7385 gen_helper_mttdsp(cpu_env, t0);
7386 break;
7387 default:
7388 goto die;
7389 }
7390 break;
7391 /* Floating point (COP1). */
7392 case 2:
7393 /* XXX: For now we support only a single FPU context. */
7394 if (h == 0) {
7395 TCGv_i32 fp0 = tcg_temp_new_i32();
7396
7397 tcg_gen_trunc_tl_i32(fp0, t0);
7398 gen_store_fpr32(fp0, rd);
7399 tcg_temp_free_i32(fp0);
7400 } else {
7401 TCGv_i32 fp0 = tcg_temp_new_i32();
7402
7403 tcg_gen_trunc_tl_i32(fp0, t0);
7404 gen_store_fpr32h(ctx, fp0, rd);
7405 tcg_temp_free_i32(fp0);
7406 }
7407 break;
7408 case 3:
7409 /* XXX: For now we support only a single FPU context. */
7410 {
7411 TCGv_i32 fs_tmp = tcg_const_i32(rd);
7412
7413 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7414 tcg_temp_free_i32(fs_tmp);
7415 }
7416 break;
7417 /* COP2: Not implemented. */
7418 case 4:
7419 case 5:
7420 /* fall through */
7421 default:
7422 goto die;
7423 }
7424 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7425 tcg_temp_free(t0);
7426 return;
7427
7428 die:
7429 tcg_temp_free(t0);
7430 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
7431 generate_exception(ctx, EXCP_RI);
7432 }
7433
7434 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
7435 {
7436 const char *opn = "ldst";
7437
7438 check_cp0_enabled(ctx);
7439 switch (opc) {
7440 case OPC_MFC0:
7441 if (rt == 0) {
7442 /* Treat as NOP. */
7443 return;
7444 }
7445 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7446 opn = "mfc0";
7447 break;
7448 case OPC_MTC0:
7449 {
7450 TCGv t0 = tcg_temp_new();
7451
7452 gen_load_gpr(t0, rt);
7453 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
7454 tcg_temp_free(t0);
7455 }
7456 opn = "mtc0";
7457 break;
7458 #if defined(TARGET_MIPS64)
7459 case OPC_DMFC0:
7460 check_insn(ctx, ISA_MIPS3);
7461 if (rt == 0) {
7462 /* Treat as NOP. */
7463 return;
7464 }
7465 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
7466 opn = "dmfc0";
7467 break;
7468 case OPC_DMTC0:
7469 check_insn(ctx, ISA_MIPS3);
7470 {
7471 TCGv t0 = tcg_temp_new();
7472
7473 gen_load_gpr(t0, rt);
7474 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
7475 tcg_temp_free(t0);
7476 }
7477 opn = "dmtc0";
7478 break;
7479 #endif
7480 case OPC_MFTR:
7481 check_insn(ctx, ASE_MT);
7482 if (rd == 0) {
7483 /* Treat as NOP. */
7484 return;
7485 }
7486 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
7487 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7488 opn = "mftr";
7489 break;
7490 case OPC_MTTR:
7491 check_insn(ctx, ASE_MT);
7492 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
7493 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
7494 opn = "mttr";
7495 break;
7496 case OPC_TLBWI:
7497 opn = "tlbwi";
7498 if (!env->tlb->helper_tlbwi)
7499 goto die;
7500 gen_helper_tlbwi(cpu_env);
7501 break;
7502 case OPC_TLBWR:
7503 opn = "tlbwr";
7504 if (!env->tlb->helper_tlbwr)
7505 goto die;
7506 gen_helper_tlbwr(cpu_env);
7507 break;
7508 case OPC_TLBP:
7509 opn = "tlbp";
7510 if (!env->tlb->helper_tlbp)
7511 goto die;
7512 gen_helper_tlbp(cpu_env);
7513 break;
7514 case OPC_TLBR:
7515 opn = "tlbr";
7516 if (!env->tlb->helper_tlbr)
7517 goto die;
7518 gen_helper_tlbr(cpu_env);
7519 break;
7520 case OPC_ERET:
7521 opn = "eret";
7522 check_insn(ctx, ISA_MIPS2);
7523 gen_helper_eret(cpu_env);
7524 ctx->bstate = BS_EXCP;
7525 break;
7526 case OPC_DERET:
7527 opn = "deret";
7528 check_insn(ctx, ISA_MIPS32);
7529 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7530 MIPS_INVAL(opn);
7531 generate_exception(ctx, EXCP_RI);
7532 } else {
7533 gen_helper_deret(cpu_env);
7534 ctx->bstate = BS_EXCP;
7535 }
7536 break;
7537 case OPC_WAIT:
7538 opn = "wait";
7539 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
7540 /* If we get an exception, we want to restart at next instruction */
7541 ctx->pc += 4;
7542 save_cpu_state(ctx, 1);
7543 ctx->pc -= 4;
7544 gen_helper_wait(cpu_env);
7545 ctx->bstate = BS_EXCP;
7546 break;
7547 default:
7548 die:
7549 MIPS_INVAL(opn);
7550 generate_exception(ctx, EXCP_RI);
7551 return;
7552 }
7553 (void)opn; /* avoid a compiler warning */
7554 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7555 }
7556 #endif /* !CONFIG_USER_ONLY */
7557
7558 /* CP1 Branches (before delay slot) */
7559 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
7560 int32_t cc, int32_t offset)
7561 {
7562 target_ulong btarget;
7563 const char *opn = "cp1 cond branch";
7564 TCGv_i32 t0 = tcg_temp_new_i32();
7565
7566 if (cc != 0)
7567 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
7568
7569 btarget = ctx->pc + 4 + offset;
7570
7571 switch (op) {
7572 case OPC_BC1F:
7573 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7574 tcg_gen_not_i32(t0, t0);
7575 tcg_gen_andi_i32(t0, t0, 1);
7576 tcg_gen_extu_i32_tl(bcond, t0);
7577 opn = "bc1f";
7578 goto not_likely;
7579 case OPC_BC1FL:
7580 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7581 tcg_gen_not_i32(t0, t0);
7582 tcg_gen_andi_i32(t0, t0, 1);
7583 tcg_gen_extu_i32_tl(bcond, t0);
7584 opn = "bc1fl";
7585 goto likely;
7586 case OPC_BC1T:
7587 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7588 tcg_gen_andi_i32(t0, t0, 1);
7589 tcg_gen_extu_i32_tl(bcond, t0);
7590 opn = "bc1t";
7591 goto not_likely;
7592 case OPC_BC1TL:
7593 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7594 tcg_gen_andi_i32(t0, t0, 1);
7595 tcg_gen_extu_i32_tl(bcond, t0);
7596 opn = "bc1tl";
7597 likely:
7598 ctx->hflags |= MIPS_HFLAG_BL;
7599 break;
7600 case OPC_BC1FANY2:
7601 {
7602 TCGv_i32 t1 = tcg_temp_new_i32();
7603 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7604 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7605 tcg_gen_nand_i32(t0, t0, t1);
7606 tcg_temp_free_i32(t1);
7607 tcg_gen_andi_i32(t0, t0, 1);
7608 tcg_gen_extu_i32_tl(bcond, t0);
7609 }
7610 opn = "bc1any2f";
7611 goto not_likely;
7612 case OPC_BC1TANY2:
7613 {
7614 TCGv_i32 t1 = tcg_temp_new_i32();
7615 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7616 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7617 tcg_gen_or_i32(t0, t0, t1);
7618 tcg_temp_free_i32(t1);
7619 tcg_gen_andi_i32(t0, t0, 1);
7620 tcg_gen_extu_i32_tl(bcond, t0);
7621 }
7622 opn = "bc1any2t";
7623 goto not_likely;
7624 case OPC_BC1FANY4:
7625 {
7626 TCGv_i32 t1 = tcg_temp_new_i32();
7627 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7628 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7629 tcg_gen_and_i32(t0, t0, t1);
7630 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7631 tcg_gen_and_i32(t0, t0, t1);
7632 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7633 tcg_gen_nand_i32(t0, t0, t1);
7634 tcg_temp_free_i32(t1);
7635 tcg_gen_andi_i32(t0, t0, 1);
7636 tcg_gen_extu_i32_tl(bcond, t0);
7637 }
7638 opn = "bc1any4f";
7639 goto not_likely;
7640 case OPC_BC1TANY4:
7641 {
7642 TCGv_i32 t1 = tcg_temp_new_i32();
7643 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7644 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7645 tcg_gen_or_i32(t0, t0, t1);
7646 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7647 tcg_gen_or_i32(t0, t0, t1);
7648 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7649 tcg_gen_or_i32(t0, t0, t1);
7650 tcg_temp_free_i32(t1);
7651 tcg_gen_andi_i32(t0, t0, 1);
7652 tcg_gen_extu_i32_tl(bcond, t0);
7653 }
7654 opn = "bc1any4t";
7655 not_likely:
7656 ctx->hflags |= MIPS_HFLAG_BC;
7657 break;
7658 default:
7659 MIPS_INVAL(opn);
7660 generate_exception (ctx, EXCP_RI);
7661 goto out;
7662 }
7663 (void)opn; /* avoid a compiler warning */
7664 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7665 ctx->hflags, btarget);
7666 ctx->btarget = btarget;
7667
7668 out:
7669 tcg_temp_free_i32(t0);
7670 }
7671
7672 /* R6 CP1 Branches */
7673 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
7674 int32_t ft, int32_t offset)
7675 {
7676 target_ulong btarget;
7677 const char *opn = "cp1 cond branch";
7678 TCGv_i64 t0 = tcg_temp_new_i64();
7679
7680 if (ctx->hflags & MIPS_HFLAG_BMASK) {
7681 #ifdef MIPS_DEBUG_DISAS
7682 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
7683 #endif
7684 generate_exception(ctx, EXCP_RI);
7685 goto out;
7686 }
7687
7688 gen_load_fpr64(ctx, t0, ft);
7689 tcg_gen_andi_i64(t0, t0, 1);
7690
7691 btarget = addr_add(ctx, ctx->pc + 4, offset);
7692
7693 switch (op) {
7694 case OPC_BC1EQZ:
7695 tcg_gen_xori_i64(t0, t0, 1);
7696 opn = "bc1eqz";
7697 ctx->hflags |= MIPS_HFLAG_BC;
7698 break;
7699 case OPC_BC1NEZ:
7700 /* t0 already set */
7701 opn = "bc1nez";
7702 ctx->hflags |= MIPS_HFLAG_BC;
7703 break;
7704 default:
7705 MIPS_INVAL(opn);
7706 generate_exception(ctx, EXCP_RI);
7707 goto out;
7708 }
7709
7710 tcg_gen_trunc_i64_tl(bcond, t0);
7711
7712 (void)opn; /* avoid a compiler warning */
7713 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7714 ctx->hflags, btarget);
7715 ctx->btarget = btarget;
7716
7717 out:
7718 tcg_temp_free_i64(t0);
7719 }
7720
7721 /* Coprocessor 1 (FPU) */
7722
7723 #define FOP(func, fmt) (((fmt) << 21) | (func))
7724
7725 enum fopcode {
7726 OPC_ADD_S = FOP(0, FMT_S),
7727 OPC_SUB_S = FOP(1, FMT_S),
7728 OPC_MUL_S = FOP(2, FMT_S),
7729 OPC_DIV_S = FOP(3, FMT_S),
7730 OPC_SQRT_S = FOP(4, FMT_S),
7731 OPC_ABS_S = FOP(5, FMT_S),
7732 OPC_MOV_S = FOP(6, FMT_S),
7733 OPC_NEG_S = FOP(7, FMT_S),
7734 OPC_ROUND_L_S = FOP(8, FMT_S),
7735 OPC_TRUNC_L_S = FOP(9, FMT_S),
7736 OPC_CEIL_L_S = FOP(10, FMT_S),
7737 OPC_FLOOR_L_S = FOP(11, FMT_S),
7738 OPC_ROUND_W_S = FOP(12, FMT_S),
7739 OPC_TRUNC_W_S = FOP(13, FMT_S),
7740 OPC_CEIL_W_S = FOP(14, FMT_S),
7741 OPC_FLOOR_W_S = FOP(15, FMT_S),
7742 OPC_SEL_S = FOP(16, FMT_S),
7743 OPC_MOVCF_S = FOP(17, FMT_S),
7744 OPC_MOVZ_S = FOP(18, FMT_S),
7745 OPC_MOVN_S = FOP(19, FMT_S),
7746 OPC_SELEQZ_S = FOP(20, FMT_S),
7747 OPC_RECIP_S = FOP(21, FMT_S),
7748 OPC_RSQRT_S = FOP(22, FMT_S),
7749 OPC_SELNEZ_S = FOP(23, FMT_S),
7750 OPC_MADDF_S = FOP(24, FMT_S),
7751 OPC_MSUBF_S = FOP(25, FMT_S),
7752 OPC_RINT_S = FOP(26, FMT_S),
7753 OPC_CLASS_S = FOP(27, FMT_S),
7754 OPC_MIN_S = FOP(28, FMT_S),
7755 OPC_RECIP2_S = FOP(28, FMT_S),
7756 OPC_MINA_S = FOP(29, FMT_S),
7757 OPC_RECIP1_S = FOP(29, FMT_S),
7758 OPC_MAX_S = FOP(30, FMT_S),
7759 OPC_RSQRT1_S = FOP(30, FMT_S),
7760 OPC_MAXA_S = FOP(31, FMT_S),
7761 OPC_RSQRT2_S = FOP(31, FMT_S),
7762 OPC_CVT_D_S = FOP(33, FMT_S),
7763 OPC_CVT_W_S = FOP(36, FMT_S),
7764 OPC_CVT_L_S = FOP(37, FMT_S),
7765 OPC_CVT_PS_S = FOP(38, FMT_S),
7766 OPC_CMP_F_S = FOP (48, FMT_S),
7767 OPC_CMP_UN_S = FOP (49, FMT_S),
7768 OPC_CMP_EQ_S = FOP (50, FMT_S),
7769 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7770 OPC_CMP_OLT_S = FOP (52, FMT_S),
7771 OPC_CMP_ULT_S = FOP (53, FMT_S),
7772 OPC_CMP_OLE_S = FOP (54, FMT_S),
7773 OPC_CMP_ULE_S = FOP (55, FMT_S),
7774 OPC_CMP_SF_S = FOP (56, FMT_S),
7775 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7776 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7777 OPC_CMP_NGL_S = FOP (59, FMT_S),
7778 OPC_CMP_LT_S = FOP (60, FMT_S),
7779 OPC_CMP_NGE_S = FOP (61, FMT_S),
7780 OPC_CMP_LE_S = FOP (62, FMT_S),
7781 OPC_CMP_NGT_S = FOP (63, FMT_S),
7782
7783 OPC_ADD_D = FOP(0, FMT_D),
7784 OPC_SUB_D = FOP(1, FMT_D),
7785 OPC_MUL_D = FOP(2, FMT_D),
7786 OPC_DIV_D = FOP(3, FMT_D),
7787 OPC_SQRT_D = FOP(4, FMT_D),
7788 OPC_ABS_D = FOP(5, FMT_D),
7789 OPC_MOV_D = FOP(6, FMT_D),
7790 OPC_NEG_D = FOP(7, FMT_D),
7791 OPC_ROUND_L_D = FOP(8, FMT_D),
7792 OPC_TRUNC_L_D = FOP(9, FMT_D),
7793 OPC_CEIL_L_D = FOP(10, FMT_D),
7794 OPC_FLOOR_L_D = FOP(11, FMT_D),
7795 OPC_ROUND_W_D = FOP(12, FMT_D),
7796 OPC_TRUNC_W_D = FOP(13, FMT_D),
7797 OPC_CEIL_W_D = FOP(14, FMT_D),
7798 OPC_FLOOR_W_D = FOP(15, FMT_D),
7799 OPC_SEL_D = FOP(16, FMT_D),
7800 OPC_MOVCF_D = FOP(17, FMT_D),
7801 OPC_MOVZ_D = FOP(18, FMT_D),
7802 OPC_MOVN_D = FOP(19, FMT_D),
7803 OPC_SELEQZ_D = FOP(20, FMT_D),
7804 OPC_RECIP_D = FOP(21, FMT_D),
7805 OPC_RSQRT_D = FOP(22, FMT_D),
7806 OPC_SELNEZ_D = FOP(23, FMT_D),
7807 OPC_MADDF_D = FOP(24, FMT_D),
7808 OPC_MSUBF_D = FOP(25, FMT_D),
7809 OPC_RINT_D = FOP(26, FMT_D),
7810 OPC_CLASS_D = FOP(27, FMT_D),
7811 OPC_MIN_D = FOP(28, FMT_D),
7812 OPC_RECIP2_D = FOP(28, FMT_D),
7813 OPC_MINA_D = FOP(29, FMT_D),
7814 OPC_RECIP1_D = FOP(29, FMT_D),
7815 OPC_MAX_D = FOP(30, FMT_D),
7816 OPC_RSQRT1_D = FOP(30, FMT_D),
7817 OPC_MAXA_D = FOP(31, FMT_D),
7818 OPC_RSQRT2_D = FOP(31, FMT_D),
7819 OPC_CVT_S_D = FOP(32, FMT_D),
7820 OPC_CVT_W_D = FOP(36, FMT_D),
7821 OPC_CVT_L_D = FOP(37, FMT_D),
7822 OPC_CMP_F_D = FOP (48, FMT_D),
7823 OPC_CMP_UN_D = FOP (49, FMT_D),
7824 OPC_CMP_EQ_D = FOP (50, FMT_D),
7825 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7826 OPC_CMP_OLT_D = FOP (52, FMT_D),
7827 OPC_CMP_ULT_D = FOP (53, FMT_D),
7828 OPC_CMP_OLE_D = FOP (54, FMT_D),
7829 OPC_CMP_ULE_D = FOP (55, FMT_D),
7830 OPC_CMP_SF_D = FOP (56, FMT_D),
7831 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7832 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7833 OPC_CMP_NGL_D = FOP (59, FMT_D),
7834 OPC_CMP_LT_D = FOP (60, FMT_D),
7835 OPC_CMP_NGE_D = FOP (61, FMT_D),
7836 OPC_CMP_LE_D = FOP (62, FMT_D),
7837 OPC_CMP_NGT_D = FOP (63, FMT_D),
7838
7839 OPC_CVT_S_W = FOP(32, FMT_W),
7840 OPC_CVT_D_W = FOP(33, FMT_W),
7841 OPC_CVT_S_L = FOP(32, FMT_L),
7842 OPC_CVT_D_L = FOP(33, FMT_L),
7843 OPC_CVT_PS_PW = FOP(38, FMT_W),
7844
7845 OPC_ADD_PS = FOP(0, FMT_PS),
7846 OPC_SUB_PS = FOP(1, FMT_PS),
7847 OPC_MUL_PS = FOP(2, FMT_PS),
7848 OPC_DIV_PS = FOP(3, FMT_PS),
7849 OPC_ABS_PS = FOP(5, FMT_PS),
7850 OPC_MOV_PS = FOP(6, FMT_PS),
7851 OPC_NEG_PS = FOP(7, FMT_PS),
7852 OPC_MOVCF_PS = FOP(17, FMT_PS),
7853 OPC_MOVZ_PS = FOP(18, FMT_PS),
7854 OPC_MOVN_PS = FOP(19, FMT_PS),
7855 OPC_ADDR_PS = FOP(24, FMT_PS),
7856 OPC_MULR_PS = FOP(26, FMT_PS),
7857 OPC_RECIP2_PS = FOP(28, FMT_PS),
7858 OPC_RECIP1_PS = FOP(29, FMT_PS),
7859 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7860 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7861
7862 OPC_CVT_S_PU = FOP(32, FMT_PS),
7863 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7864 OPC_CVT_S_PL = FOP(40, FMT_PS),
7865 OPC_PLL_PS = FOP(44, FMT_PS),
7866 OPC_PLU_PS = FOP(45, FMT_PS),
7867 OPC_PUL_PS = FOP(46, FMT_PS),
7868 OPC_PUU_PS = FOP(47, FMT_PS),
7869 OPC_CMP_F_PS = FOP (48, FMT_PS),
7870 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7871 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7872 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7873 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7874 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7875 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7876 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7877 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7878 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7879 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7880 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7881 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7882 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7883 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7884 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7885 };
7886
7887 enum r6_f_cmp_op {
7888 R6_OPC_CMP_AF_S = FOP(0, FMT_W),
7889 R6_OPC_CMP_UN_S = FOP(1, FMT_W),
7890 R6_OPC_CMP_EQ_S = FOP(2, FMT_W),
7891 R6_OPC_CMP_UEQ_S = FOP(3, FMT_W),
7892 R6_OPC_CMP_LT_S = FOP(4, FMT_W),
7893 R6_OPC_CMP_ULT_S = FOP(5, FMT_W),
7894 R6_OPC_CMP_LE_S = FOP(6, FMT_W),
7895 R6_OPC_CMP_ULE_S = FOP(7, FMT_W),
7896 R6_OPC_CMP_SAF_S = FOP(8, FMT_W),
7897 R6_OPC_CMP_SUN_S = FOP(9, FMT_W),
7898 R6_OPC_CMP_SEQ_S = FOP(10, FMT_W),
7899 R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
7900 R6_OPC_CMP_SLT_S = FOP(12, FMT_W),
7901 R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
7902 R6_OPC_CMP_SLE_S = FOP(14, FMT_W),
7903 R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
7904 R6_OPC_CMP_OR_S = FOP(17, FMT_W),
7905 R6_OPC_CMP_UNE_S = FOP(18, FMT_W),
7906 R6_OPC_CMP_NE_S = FOP(19, FMT_W),
7907 R6_OPC_CMP_SOR_S = FOP(25, FMT_W),
7908 R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
7909 R6_OPC_CMP_SNE_S = FOP(27, FMT_W),
7910
7911 R6_OPC_CMP_AF_D = FOP(0, FMT_L),
7912 R6_OPC_CMP_UN_D = FOP(1, FMT_L),
7913 R6_OPC_CMP_EQ_D = FOP(2, FMT_L),
7914 R6_OPC_CMP_UEQ_D = FOP(3, FMT_L),
7915 R6_OPC_CMP_LT_D = FOP(4, FMT_L),
7916 R6_OPC_CMP_ULT_D = FOP(5, FMT_L),
7917 R6_OPC_CMP_LE_D = FOP(6, FMT_L),
7918 R6_OPC_CMP_ULE_D = FOP(7, FMT_L),
7919 R6_OPC_CMP_SAF_D = FOP(8, FMT_L),
7920 R6_OPC_CMP_SUN_D = FOP(9, FMT_L),
7921 R6_OPC_CMP_SEQ_D = FOP(10, FMT_L),
7922 R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
7923 R6_OPC_CMP_SLT_D = FOP(12, FMT_L),
7924 R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
7925 R6_OPC_CMP_SLE_D = FOP(14, FMT_L),
7926 R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
7927 R6_OPC_CMP_OR_D = FOP(17, FMT_L),
7928 R6_OPC_CMP_UNE_D = FOP(18, FMT_L),
7929 R6_OPC_CMP_NE_D = FOP(19, FMT_L),
7930 R6_OPC_CMP_SOR_D = FOP(25, FMT_L),
7931 R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
7932 R6_OPC_CMP_SNE_D = FOP(27, FMT_L),
7933 };
7934 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7935 {
7936 const char *opn = "cp1 move";
7937 TCGv t0 = tcg_temp_new();
7938
7939 switch (opc) {
7940 case OPC_MFC1:
7941 {
7942 TCGv_i32 fp0 = tcg_temp_new_i32();
7943
7944 gen_load_fpr32(fp0, fs);
7945 tcg_gen_ext_i32_tl(t0, fp0);
7946 tcg_temp_free_i32(fp0);
7947 }
7948 gen_store_gpr(t0, rt);
7949 opn = "mfc1";
7950 break;
7951 case OPC_MTC1:
7952 gen_load_gpr(t0, rt);
7953 {
7954 TCGv_i32 fp0 = tcg_temp_new_i32();
7955
7956 tcg_gen_trunc_tl_i32(fp0, t0);
7957 gen_store_fpr32(fp0, fs);
7958 tcg_temp_free_i32(fp0);
7959 }
7960 opn = "mtc1";
7961 break;
7962 case OPC_CFC1:
7963 gen_helper_1e0i(cfc1, t0, fs);
7964 gen_store_gpr(t0, rt);
7965 opn = "cfc1";
7966 break;
7967 case OPC_CTC1:
7968 gen_load_gpr(t0, rt);
7969 {
7970 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7971
7972 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7973 tcg_temp_free_i32(fs_tmp);
7974 }
7975 opn = "ctc1";
7976 break;
7977 #if defined(TARGET_MIPS64)
7978 case OPC_DMFC1:
7979 gen_load_fpr64(ctx, t0, fs);
7980 gen_store_gpr(t0, rt);
7981 opn = "dmfc1";
7982 break;
7983 case OPC_DMTC1:
7984 gen_load_gpr(t0, rt);
7985 gen_store_fpr64(ctx, t0, fs);
7986 opn = "dmtc1";
7987 break;
7988 #endif
7989 case OPC_MFHC1:
7990 {
7991 TCGv_i32 fp0 = tcg_temp_new_i32();
7992
7993 gen_load_fpr32h(ctx, fp0, fs);
7994 tcg_gen_ext_i32_tl(t0, fp0);
7995 tcg_temp_free_i32(fp0);
7996 }
7997 gen_store_gpr(t0, rt);
7998 opn = "mfhc1";
7999 break;
8000 case OPC_MTHC1:
8001 gen_load_gpr(t0, rt);
8002 {
8003 TCGv_i32 fp0 = tcg_temp_new_i32();
8004
8005 tcg_gen_trunc_tl_i32(fp0, t0);
8006 gen_store_fpr32h(ctx, fp0, fs);
8007 tcg_temp_free_i32(fp0);
8008 }
8009 opn = "mthc1";
8010 break;
8011 default:
8012 MIPS_INVAL(opn);
8013 generate_exception (ctx, EXCP_RI);
8014 goto out;
8015 }
8016 (void)opn; /* avoid a compiler warning */
8017 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
8018
8019 out:
8020 tcg_temp_free(t0);
8021 }
8022
8023 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
8024 {
8025 int l1;
8026 TCGCond cond;
8027 TCGv_i32 t0;
8028
8029 if (rd == 0) {
8030 /* Treat as NOP. */
8031 return;
8032 }
8033
8034 if (tf)
8035 cond = TCG_COND_EQ;
8036 else
8037 cond = TCG_COND_NE;
8038
8039 l1 = gen_new_label();
8040 t0 = tcg_temp_new_i32();
8041 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8042 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8043 tcg_temp_free_i32(t0);
8044 if (rs == 0) {
8045 tcg_gen_movi_tl(cpu_gpr[rd], 0);
8046 } else {
8047 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
8048 }
8049 gen_set_label(l1);
8050 }
8051
8052 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
8053 {
8054 int cond;
8055 TCGv_i32 t0 = tcg_temp_new_i32();
8056 int l1 = gen_new_label();
8057
8058 if (tf)
8059 cond = TCG_COND_EQ;
8060 else
8061 cond = TCG_COND_NE;
8062
8063 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8064 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8065 gen_load_fpr32(t0, fs);
8066 gen_store_fpr32(t0, fd);
8067 gen_set_label(l1);
8068 tcg_temp_free_i32(t0);
8069 }
8070
8071 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
8072 {
8073 int cond;
8074 TCGv_i32 t0 = tcg_temp_new_i32();
8075 TCGv_i64 fp0;
8076 int l1 = gen_new_label();
8077
8078 if (tf)
8079 cond = TCG_COND_EQ;
8080 else
8081 cond = TCG_COND_NE;
8082
8083 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8084 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8085 tcg_temp_free_i32(t0);
8086 fp0 = tcg_temp_new_i64();
8087 gen_load_fpr64(ctx, fp0, fs);
8088 gen_store_fpr64(ctx, fp0, fd);
8089 tcg_temp_free_i64(fp0);
8090 gen_set_label(l1);
8091 }
8092
8093 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
8094 int cc, int tf)
8095 {
8096 int cond;
8097 TCGv_i32 t0 = tcg_temp_new_i32();
8098 int l1 = gen_new_label();
8099 int l2 = gen_new_label();
8100
8101 if (tf)
8102 cond = TCG_COND_EQ;
8103 else
8104 cond = TCG_COND_NE;
8105
8106 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
8107 tcg_gen_brcondi_i32(cond, t0, 0, l1);
8108 gen_load_fpr32(t0, fs);
8109 gen_store_fpr32(t0, fd);
8110 gen_set_label(l1);
8111
8112 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
8113 tcg_gen_brcondi_i32(cond, t0, 0, l2);
8114 gen_load_fpr32h(ctx, t0, fs);
8115 gen_store_fpr32h(ctx, t0, fd);
8116 tcg_temp_free_i32(t0);
8117 gen_set_label(l2);
8118 }
8119
8120 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8121 int fs)
8122 {
8123 TCGv_i32 t1 = tcg_const_i32(0);
8124 TCGv_i32 fp0 = tcg_temp_new_i32();
8125 TCGv_i32 fp1 = tcg_temp_new_i32();
8126 TCGv_i32 fp2 = tcg_temp_new_i32();
8127 gen_load_fpr32(fp0, fd);
8128 gen_load_fpr32(fp1, ft);
8129 gen_load_fpr32(fp2, fs);
8130
8131 switch (op1) {
8132 case OPC_SEL_S:
8133 tcg_gen_andi_i32(fp0, fp0, 1);
8134 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8135 break;
8136 case OPC_SELEQZ_S:
8137 tcg_gen_andi_i32(fp1, fp1, 1);
8138 tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8139 break;
8140 case OPC_SELNEZ_S:
8141 tcg_gen_andi_i32(fp1, fp1, 1);
8142 tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8143 break;
8144 default:
8145 MIPS_INVAL("gen_sel_s");
8146 generate_exception (ctx, EXCP_RI);
8147 break;
8148 }
8149
8150 gen_store_fpr32(fp0, fd);
8151 tcg_temp_free_i32(fp2);
8152 tcg_temp_free_i32(fp1);
8153 tcg_temp_free_i32(fp0);
8154 tcg_temp_free_i32(t1);
8155 }
8156
8157 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
8158 int fs)
8159 {
8160 TCGv_i64 t1 = tcg_const_i64(0);
8161 TCGv_i64 fp0 = tcg_temp_new_i64();
8162 TCGv_i64 fp1 = tcg_temp_new_i64();
8163 TCGv_i64 fp2 = tcg_temp_new_i64();
8164 gen_load_fpr64(ctx, fp0, fd);
8165 gen_load_fpr64(ctx, fp1, ft);
8166 gen_load_fpr64(ctx, fp2, fs);
8167
8168 switch (op1) {
8169 case OPC_SEL_D:
8170 tcg_gen_andi_i64(fp0, fp0, 1);
8171 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
8172 break;
8173 case OPC_SELEQZ_D:
8174 tcg_gen_andi_i64(fp1, fp1, 1);
8175 tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
8176 break;
8177 case OPC_SELNEZ_D:
8178 tcg_gen_andi_i64(fp1, fp1, 1);
8179 tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
8180 break;
8181 default:
8182 MIPS_INVAL("gen_sel_d");
8183 generate_exception (ctx, EXCP_RI);
8184 break;
8185 }
8186
8187 gen_store_fpr64(ctx, fp0, fd);
8188 tcg_temp_free_i64(fp2);
8189 tcg_temp_free_i64(fp1);
8190 tcg_temp_free_i64(fp0);
8191 tcg_temp_free_i64(t1);
8192 }
8193
8194 static void gen_farith (DisasContext *ctx, enum fopcode op1,
8195 int ft, int fs, int fd, int cc)
8196 {
8197 const char *opn = "farith";
8198 const char *condnames[] = {
8199 "c.f",
8200 "c.un",
8201 "c.eq",
8202 "c.ueq",
8203 "c.olt",
8204 "c.ult",
8205 "c.ole",
8206 "c.ule",
8207 "c.sf",
8208 "c.ngle",
8209 "c.seq",
8210 "c.ngl",
8211 "c.lt",
8212 "c.nge",
8213 "c.le",
8214 "c.ngt",
8215 };
8216 const char *condnames_abs[] = {
8217 "cabs.f",
8218 "cabs.un",
8219 "cabs.eq",
8220 "cabs.ueq",
8221 "cabs.olt",
8222 "cabs.ult",
8223 "cabs.ole",
8224 "cabs.ule",
8225 "cabs.sf",
8226 "cabs.ngle",
8227 "cabs.seq",
8228 "cabs.ngl",
8229 "cabs.lt",
8230 "cabs.nge",
8231 "cabs.le",
8232 "cabs.ngt",
8233 };
8234 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
8235 uint32_t func = ctx->opcode & 0x3f;
8236
8237 switch (op1) {
8238 case OPC_ADD_S:
8239 {
8240 TCGv_i32 fp0 = tcg_temp_new_i32();
8241 TCGv_i32 fp1 = tcg_temp_new_i32();
8242
8243 gen_load_fpr32(fp0, fs);
8244 gen_load_fpr32(fp1, ft);
8245 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
8246 tcg_temp_free_i32(fp1);
8247 gen_store_fpr32(fp0, fd);
8248 tcg_temp_free_i32(fp0);
8249 }
8250 opn = "add.s";
8251 optype = BINOP;
8252 break;
8253 case OPC_SUB_S:
8254 {
8255 TCGv_i32 fp0 = tcg_temp_new_i32();
8256 TCGv_i32 fp1 = tcg_temp_new_i32();
8257
8258 gen_load_fpr32(fp0, fs);
8259 gen_load_fpr32(fp1, ft);
8260 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
8261 tcg_temp_free_i32(fp1);
8262 gen_store_fpr32(fp0, fd);
8263 tcg_temp_free_i32(fp0);
8264 }
8265 opn = "sub.s";
8266 optype = BINOP;
8267 break;
8268 case OPC_MUL_S:
8269 {
8270 TCGv_i32 fp0 = tcg_temp_new_i32();
8271 TCGv_i32 fp1 = tcg_temp_new_i32();
8272
8273 gen_load_fpr32(fp0, fs);
8274 gen_load_fpr32(fp1, ft);
8275 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
8276 tcg_temp_free_i32(fp1);
8277 gen_store_fpr32(fp0, fd);
8278 tcg_temp_free_i32(fp0);
8279 }
8280 opn = "mul.s";
8281 optype = BINOP;
8282 break;
8283 case OPC_DIV_S:
8284 {
8285 TCGv_i32 fp0 = tcg_temp_new_i32();
8286 TCGv_i32 fp1 = tcg_temp_new_i32();
8287
8288 gen_load_fpr32(fp0, fs);
8289 gen_load_fpr32(fp1, ft);
8290 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
8291 tcg_temp_free_i32(fp1);
8292 gen_store_fpr32(fp0, fd);
8293 tcg_temp_free_i32(fp0);
8294 }
8295 opn = "div.s";
8296 optype = BINOP;
8297 break;
8298 case OPC_SQRT_S:
8299 {
8300 TCGv_i32 fp0 = tcg_temp_new_i32();
8301
8302 gen_load_fpr32(fp0, fs);
8303 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
8304 gen_store_fpr32(fp0, fd);
8305 tcg_temp_free_i32(fp0);
8306 }
8307 opn = "sqrt.s";
8308 break;
8309 case OPC_ABS_S:
8310 {
8311 TCGv_i32 fp0 = tcg_temp_new_i32();
8312
8313 gen_load_fpr32(fp0, fs);
8314 gen_helper_float_abs_s(fp0, fp0);
8315 gen_store_fpr32(fp0, fd);
8316 tcg_temp_free_i32(fp0);
8317 }
8318 opn = "abs.s";
8319 break;
8320 case OPC_MOV_S:
8321 {
8322 TCGv_i32 fp0 = tcg_temp_new_i32();
8323
8324 gen_load_fpr32(fp0, fs);
8325 gen_store_fpr32(fp0, fd);
8326 tcg_temp_free_i32(fp0);
8327 }
8328 opn = "mov.s";
8329 break;
8330 case OPC_NEG_S:
8331 {
8332 TCGv_i32 fp0 = tcg_temp_new_i32();
8333
8334 gen_load_fpr32(fp0, fs);
8335 gen_helper_float_chs_s(fp0, fp0);
8336 gen_store_fpr32(fp0, fd);
8337 tcg_temp_free_i32(fp0);
8338 }
8339 opn = "neg.s";
8340 break;
8341 case OPC_ROUND_L_S:
8342 check_cp1_64bitmode(ctx);
8343 {
8344 TCGv_i32 fp32 = tcg_temp_new_i32();
8345 TCGv_i64 fp64 = tcg_temp_new_i64();
8346
8347 gen_load_fpr32(fp32, fs);
8348 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
8349 tcg_temp_free_i32(fp32);
8350 gen_store_fpr64(ctx, fp64, fd);
8351 tcg_temp_free_i64(fp64);
8352 }
8353 opn = "round.l.s";
8354 break;
8355 case OPC_TRUNC_L_S:
8356 check_cp1_64bitmode(ctx);
8357 {
8358 TCGv_i32 fp32 = tcg_temp_new_i32();
8359 TCGv_i64 fp64 = tcg_temp_new_i64();
8360
8361 gen_load_fpr32(fp32, fs);
8362 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
8363 tcg_temp_free_i32(fp32);
8364 gen_store_fpr64(ctx, fp64, fd);
8365 tcg_temp_free_i64(fp64);
8366 }
8367 opn = "trunc.l.s";
8368 break;
8369 case OPC_CEIL_L_S:
8370 check_cp1_64bitmode(ctx);
8371 {
8372 TCGv_i32 fp32 = tcg_temp_new_i32();
8373 TCGv_i64 fp64 = tcg_temp_new_i64();
8374
8375 gen_load_fpr32(fp32, fs);
8376 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
8377 tcg_temp_free_i32(fp32);
8378 gen_store_fpr64(ctx, fp64, fd);
8379 tcg_temp_free_i64(fp64);
8380 }
8381 opn = "ceil.l.s";
8382 break;
8383 case OPC_FLOOR_L_S:
8384 check_cp1_64bitmode(ctx);
8385 {
8386 TCGv_i32 fp32 = tcg_temp_new_i32();
8387 TCGv_i64 fp64 = tcg_temp_new_i64();
8388
8389 gen_load_fpr32(fp32, fs);
8390 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
8391 tcg_temp_free_i32(fp32);
8392 gen_store_fpr64(ctx, fp64, fd);
8393 tcg_temp_free_i64(fp64);
8394 }
8395 opn = "floor.l.s";
8396 break;
8397 case OPC_ROUND_W_S:
8398 {
8399 TCGv_i32 fp0 = tcg_temp_new_i32();
8400
8401 gen_load_fpr32(fp0, fs);
8402 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
8403 gen_store_fpr32(fp0, fd);
8404 tcg_temp_free_i32(fp0);
8405 }
8406 opn = "round.w.s";
8407 break;
8408 case OPC_TRUNC_W_S:
8409 {
8410 TCGv_i32 fp0 = tcg_temp_new_i32();
8411
8412 gen_load_fpr32(fp0, fs);
8413 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
8414 gen_store_fpr32(fp0, fd);
8415 tcg_temp_free_i32(fp0);
8416 }
8417 opn = "trunc.w.s";
8418 break;
8419 case OPC_CEIL_W_S:
8420 {
8421 TCGv_i32 fp0 = tcg_temp_new_i32();
8422
8423 gen_load_fpr32(fp0, fs);
8424 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
8425 gen_store_fpr32(fp0, fd);
8426 tcg_temp_free_i32(fp0);
8427 }
8428 opn = "ceil.w.s";
8429 break;
8430 case OPC_FLOOR_W_S:
8431 {
8432 TCGv_i32 fp0 = tcg_temp_new_i32();
8433
8434 gen_load_fpr32(fp0, fs);
8435 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
8436 gen_store_fpr32(fp0, fd);
8437 tcg_temp_free_i32(fp0);
8438 }
8439 opn = "floor.w.s";
8440 break;
8441 case OPC_SEL_S:
8442 check_insn(ctx, ISA_MIPS32R6);
8443 gen_sel_s(ctx, op1, fd, ft, fs);
8444 opn = "sel.s";
8445 break;
8446 case OPC_SELEQZ_S:
8447 check_insn(ctx, ISA_MIPS32R6);
8448 gen_sel_s(ctx, op1, fd, ft, fs);
8449 opn = "seleqz.s";
8450 break;
8451 case OPC_SELNEZ_S:
8452 check_insn(ctx, ISA_MIPS32R6);
8453 gen_sel_s(ctx, op1, fd, ft, fs);
8454 opn = "selnez.s";
8455 break;
8456 case OPC_MOVCF_S:
8457 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8458 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8459 opn = "movcf.s";
8460 break;
8461 case OPC_MOVZ_S:
8462 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8463 {
8464 int l1 = gen_new_label();
8465 TCGv_i32 fp0;
8466
8467 if (ft != 0) {
8468 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8469 }
8470 fp0 = tcg_temp_new_i32();
8471 gen_load_fpr32(fp0, fs);
8472 gen_store_fpr32(fp0, fd);
8473 tcg_temp_free_i32(fp0);
8474 gen_set_label(l1);
8475 }
8476 opn = "movz.s";
8477 break;
8478 case OPC_MOVN_S:
8479 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8480 {
8481 int l1 = gen_new_label();
8482 TCGv_i32 fp0;
8483
8484 if (ft != 0) {
8485 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8486 fp0 = tcg_temp_new_i32();
8487 gen_load_fpr32(fp0, fs);
8488 gen_store_fpr32(fp0, fd);
8489 tcg_temp_free_i32(fp0);
8490 gen_set_label(l1);
8491 }
8492 }
8493 opn = "movn.s";
8494 break;
8495 case OPC_RECIP_S:
8496 check_cop1x(ctx);
8497 {
8498 TCGv_i32 fp0 = tcg_temp_new_i32();
8499
8500 gen_load_fpr32(fp0, fs);
8501 gen_helper_float_recip_s(fp0, cpu_env, fp0);
8502 gen_store_fpr32(fp0, fd);
8503 tcg_temp_free_i32(fp0);
8504 }
8505 opn = "recip.s";
8506 break;
8507 case OPC_RSQRT_S:
8508 check_cop1x(ctx);
8509 {
8510 TCGv_i32 fp0 = tcg_temp_new_i32();
8511
8512 gen_load_fpr32(fp0, fs);
8513 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
8514 gen_store_fpr32(fp0, fd);
8515 tcg_temp_free_i32(fp0);
8516 }
8517 opn = "rsqrt.s";
8518 break;
8519 case OPC_MADDF_S:
8520 check_insn(ctx, ISA_MIPS32R6);
8521 {
8522 TCGv_i32 fp0 = tcg_temp_new_i32();
8523 TCGv_i32 fp1 = tcg_temp_new_i32();
8524 TCGv_i32 fp2 = tcg_temp_new_i32();
8525 gen_load_fpr32(fp0, fs);
8526 gen_load_fpr32(fp1, ft);
8527 gen_load_fpr32(fp2, fd);
8528 gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
8529 gen_store_fpr32(fp2, fd);
8530 tcg_temp_free_i32(fp2);
8531 tcg_temp_free_i32(fp1);
8532 tcg_temp_free_i32(fp0);
8533 opn = "maddf.s";
8534 }
8535 break;
8536 case OPC_MSUBF_S:
8537 check_insn(ctx, ISA_MIPS32R6);
8538 {
8539 TCGv_i32 fp0 = tcg_temp_new_i32();
8540 TCGv_i32 fp1 = tcg_temp_new_i32();
8541 TCGv_i32 fp2 = tcg_temp_new_i32();
8542 gen_load_fpr32(fp0, fs);
8543 gen_load_fpr32(fp1, ft);
8544 gen_load_fpr32(fp2, fd);
8545 gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
8546 gen_store_fpr32(fp2, fd);
8547 tcg_temp_free_i32(fp2);
8548 tcg_temp_free_i32(fp1);
8549 tcg_temp_free_i32(fp0);
8550 opn = "msubf.s";
8551 }
8552 break;
8553 case OPC_RINT_S:
8554 check_insn(ctx, ISA_MIPS32R6);
8555 {
8556 TCGv_i32 fp0 = tcg_temp_new_i32();
8557 gen_load_fpr32(fp0, fs);
8558 gen_helper_float_rint_s(fp0, cpu_env, fp0);
8559 gen_store_fpr32(fp0, fd);
8560 tcg_temp_free_i32(fp0);
8561 opn = "rint.s";
8562 }
8563 break;
8564 case OPC_CLASS_S:
8565 check_insn(ctx, ISA_MIPS32R6);
8566 {
8567 TCGv_i32 fp0 = tcg_temp_new_i32();
8568 gen_load_fpr32(fp0, fs);
8569 gen_helper_float_class_s(fp0, fp0);
8570 gen_store_fpr32(fp0, fd);
8571 tcg_temp_free_i32(fp0);
8572 opn = "class.s";
8573 }
8574 break;
8575 case OPC_MIN_S: /* OPC_RECIP2_S */
8576 if (ctx->insn_flags & ISA_MIPS32R6) {
8577 /* OPC_MIN_S */
8578 TCGv_i32 fp0 = tcg_temp_new_i32();
8579 TCGv_i32 fp1 = tcg_temp_new_i32();
8580 TCGv_i32 fp2 = tcg_temp_new_i32();
8581 gen_load_fpr32(fp0, fs);
8582 gen_load_fpr32(fp1, ft);
8583 gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
8584 gen_store_fpr32(fp2, fd);
8585 tcg_temp_free_i32(fp2);
8586 tcg_temp_free_i32(fp1);
8587 tcg_temp_free_i32(fp0);
8588 opn = "min.s";
8589 } else {
8590 /* OPC_RECIP2_S */
8591 check_cp1_64bitmode(ctx);
8592 {
8593 TCGv_i32 fp0 = tcg_temp_new_i32();
8594 TCGv_i32 fp1 = tcg_temp_new_i32();
8595
8596 gen_load_fpr32(fp0, fs);
8597 gen_load_fpr32(fp1, ft);
8598 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
8599 tcg_temp_free_i32(fp1);
8600 gen_store_fpr32(fp0, fd);
8601 tcg_temp_free_i32(fp0);
8602 }
8603 opn = "recip2.s";
8604 }
8605 break;
8606 case OPC_MINA_S: /* OPC_RECIP1_S */
8607 if (ctx->insn_flags & ISA_MIPS32R6) {
8608 /* OPC_MINA_S */
8609 TCGv_i32 fp0 = tcg_temp_new_i32();
8610 TCGv_i32 fp1 = tcg_temp_new_i32();
8611 TCGv_i32 fp2 = tcg_temp_new_i32();
8612 gen_load_fpr32(fp0, fs);
8613 gen_load_fpr32(fp1, ft);
8614 gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
8615 gen_store_fpr32(fp2, fd);
8616 tcg_temp_free_i32(fp2);
8617 tcg_temp_free_i32(fp1);
8618 tcg_temp_free_i32(fp0);
8619 opn = "mina.s";
8620 } else {
8621 /* OPC_RECIP1_S */
8622 check_cp1_64bitmode(ctx);
8623 {
8624 TCGv_i32 fp0 = tcg_temp_new_i32();
8625
8626 gen_load_fpr32(fp0, fs);
8627 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
8628 gen_store_fpr32(fp0, fd);
8629 tcg_temp_free_i32(fp0);
8630 }
8631 opn = "recip1.s";
8632 }
8633 break;
8634 case OPC_MAX_S: /* OPC_RSQRT1_S */
8635 if (ctx->insn_flags & ISA_MIPS32R6) {
8636 /* OPC_MAX_S */
8637 TCGv_i32 fp0 = tcg_temp_new_i32();
8638 TCGv_i32 fp1 = tcg_temp_new_i32();
8639 gen_load_fpr32(fp0, fs);
8640 gen_load_fpr32(fp1, ft);
8641 gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
8642 gen_store_fpr32(fp1, fd);
8643 tcg_temp_free_i32(fp1);
8644 tcg_temp_free_i32(fp0);
8645 opn = "max.s";
8646 } else {
8647 /* OPC_RSQRT1_S */
8648 check_cp1_64bitmode(ctx);
8649 {
8650 TCGv_i32 fp0 = tcg_temp_new_i32();
8651
8652 gen_load_fpr32(fp0, fs);
8653 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
8654 gen_store_fpr32(fp0, fd);
8655 tcg_temp_free_i32(fp0);
8656 }
8657 opn = "rsqrt1.s";
8658 }
8659 break;
8660 case OPC_MAXA_S: /* OPC_RSQRT2_S */
8661 if (ctx->insn_flags & ISA_MIPS32R6) {
8662 /* OPC_MAXA_S */
8663 TCGv_i32 fp0 = tcg_temp_new_i32();
8664 TCGv_i32 fp1 = tcg_temp_new_i32();
8665 gen_load_fpr32(fp0, fs);
8666 gen_load_fpr32(fp1, ft);
8667 gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
8668 gen_store_fpr32(fp1, fd);
8669 tcg_temp_free_i32(fp1);
8670 tcg_temp_free_i32(fp0);
8671 opn = "maxa.s";
8672 } else {
8673 /* OPC_RSQRT2_S */
8674 check_cp1_64bitmode(ctx);
8675 {
8676 TCGv_i32 fp0 = tcg_temp_new_i32();
8677 TCGv_i32 fp1 = tcg_temp_new_i32();
8678
8679 gen_load_fpr32(fp0, fs);
8680 gen_load_fpr32(fp1, ft);
8681 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
8682 tcg_temp_free_i32(fp1);
8683 gen_store_fpr32(fp0, fd);
8684 tcg_temp_free_i32(fp0);
8685 }
8686 opn = "rsqrt2.s";
8687 }
8688 break;
8689 case OPC_CVT_D_S:
8690 check_cp1_registers(ctx, fd);
8691 {
8692 TCGv_i32 fp32 = tcg_temp_new_i32();
8693 TCGv_i64 fp64 = tcg_temp_new_i64();
8694
8695 gen_load_fpr32(fp32, fs);
8696 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
8697 tcg_temp_free_i32(fp32);
8698 gen_store_fpr64(ctx, fp64, fd);
8699 tcg_temp_free_i64(fp64);
8700 }
8701 opn = "cvt.d.s";
8702 break;
8703 case OPC_CVT_W_S:
8704 {
8705 TCGv_i32 fp0 = tcg_temp_new_i32();
8706
8707 gen_load_fpr32(fp0, fs);
8708 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
8709 gen_store_fpr32(fp0, fd);
8710 tcg_temp_free_i32(fp0);
8711 }
8712 opn = "cvt.w.s";
8713 break;
8714 case OPC_CVT_L_S:
8715 check_cp1_64bitmode(ctx);
8716 {
8717 TCGv_i32 fp32 = tcg_temp_new_i32();
8718 TCGv_i64 fp64 = tcg_temp_new_i64();
8719
8720 gen_load_fpr32(fp32, fs);
8721 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
8722 tcg_temp_free_i32(fp32);
8723 gen_store_fpr64(ctx, fp64, fd);
8724 tcg_temp_free_i64(fp64);
8725 }
8726 opn = "cvt.l.s";
8727 break;
8728 case OPC_CVT_PS_S:
8729 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8730 check_cp1_64bitmode(ctx);
8731 {
8732 TCGv_i64 fp64 = tcg_temp_new_i64();
8733 TCGv_i32 fp32_0 = tcg_temp_new_i32();
8734 TCGv_i32 fp32_1 = tcg_temp_new_i32();
8735
8736 gen_load_fpr32(fp32_0, fs);
8737 gen_load_fpr32(fp32_1, ft);
8738 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
8739 tcg_temp_free_i32(fp32_1);
8740 tcg_temp_free_i32(fp32_0);
8741 gen_store_fpr64(ctx, fp64, fd);
8742 tcg_temp_free_i64(fp64);
8743 }
8744 opn = "cvt.ps.s";
8745 break;
8746 case OPC_CMP_F_S:
8747 case OPC_CMP_UN_S:
8748 case OPC_CMP_EQ_S:
8749 case OPC_CMP_UEQ_S:
8750 case OPC_CMP_OLT_S:
8751 case OPC_CMP_ULT_S:
8752 case OPC_CMP_OLE_S:
8753 case OPC_CMP_ULE_S:
8754 case OPC_CMP_SF_S:
8755 case OPC_CMP_NGLE_S:
8756 case OPC_CMP_SEQ_S:
8757 case OPC_CMP_NGL_S:
8758 case OPC_CMP_LT_S:
8759 case OPC_CMP_NGE_S:
8760 case OPC_CMP_LE_S:
8761 case OPC_CMP_NGT_S:
8762 check_insn_opc_removed(ctx, ISA_MIPS32R6);
8763 if (ctx->opcode & (1 << 6)) {
8764 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
8765 opn = condnames_abs[func-48];
8766 } else {
8767 gen_cmp_s(ctx, func-48, ft, fs, cc);
8768 opn = condnames[func-48];
8769 }
8770 break;
8771 case OPC_ADD_D:
8772 check_cp1_registers(ctx, fs | ft | fd);
8773 {
8774 TCGv_i64 fp0 = tcg_temp_new_i64();
8775 TCGv_i64 fp1 = tcg_temp_new_i64();
8776
8777 gen_load_fpr64(ctx, fp0, fs);
8778 gen_load_fpr64(ctx, fp1, ft);
8779 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
8780 tcg_temp_free_i64(fp1);
8781 gen_store_fpr64(ctx, fp0, fd);
8782 tcg_temp_free_i64(fp0);
8783 }
8784 opn = "add.d";
8785 optype = BINOP;
8786 break;
8787 case OPC_SUB_D:
8788 check_cp1_registers(ctx, fs | ft | fd);
8789 {
8790 TCGv_i64 fp0 = tcg_temp_new_i64();
8791 TCGv_i64 fp1 = tcg_temp_new_i64();
8792
8793 gen_load_fpr64(ctx, fp0, fs);
8794 gen_load_fpr64(ctx, fp1, ft);
8795 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
8796 tcg_temp_free_i64(fp1);
8797 gen_store_fpr64(ctx, fp0, fd);
8798 tcg_temp_free_i64(fp0);
8799 }
8800 opn = "sub.d";
8801 optype = BINOP;
8802 break;
8803 case OPC_MUL_D:
8804 check_cp1_registers(ctx, fs | ft | fd);
8805 {
8806 TCGv_i64 fp0 = tcg_temp_new_i64();
8807 TCGv_i64 fp1 = tcg_temp_new_i64();
8808
8809 gen_load_fpr64(ctx, fp0, fs);
8810 gen_load_fpr64(ctx, fp1, ft);
8811 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
8812 tcg_temp_free_i64(fp1);
8813 gen_store_fpr64(ctx, fp0, fd);
8814 tcg_temp_free_i64(fp0);
8815 }
8816 opn = "mul.d";
8817 optype = BINOP;
8818 break;
8819 case OPC_DIV_D:
8820 check_cp1_registers(ctx, fs | ft | fd);
8821 {
8822 TCGv_i64 fp0 = tcg_temp_new_i64();
8823 TCGv_i64 fp1 = tcg_temp_new_i64();
8824
8825 gen_load_fpr64(ctx, fp0, fs);
8826 gen_load_fpr64(ctx, fp1, ft);
8827 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
8828 tcg_temp_free_i64(fp1);
8829 gen_store_fpr64(ctx, fp0, fd);
8830 tcg_temp_free_i64(fp0);
8831 }
8832 opn = "div.d";
8833 optype = BINOP;
8834 break;
8835 case OPC_SQRT_D:
8836 check_cp1_registers(ctx, fs | fd);
8837 {
8838 TCGv_i64 fp0 = tcg_temp_new_i64();
8839
8840 gen_load_fpr64(ctx, fp0, fs);
8841 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
8842 gen_store_fpr64(ctx, fp0, fd);
8843 tcg_temp_free_i64(fp0);
8844 }
8845 opn = "sqrt.d";
8846 break;
8847 case OPC_ABS_D:
8848 check_cp1_registers(ctx, fs | fd);
8849 {
8850 TCGv_i64 fp0 = tcg_temp_new_i64();
8851
8852 gen_load_fpr64(ctx, fp0, fs);
8853 gen_helper_float_abs_d(fp0, fp0);
8854 gen_store_fpr64(ctx, fp0, fd);
8855 tcg_temp_free_i64(fp0);
8856 }
8857 opn = "abs.d";
8858 break;
8859 case OPC_MOV_D:
8860 check_cp1_registers(ctx, fs | fd);
8861 {
8862 TCGv_i64 fp0 = tcg_temp_new_i64();
8863
8864 gen_load_fpr64(ctx, fp0, fs);
8865 gen_store_fpr64(ctx, fp0, fd);
8866 tcg_temp_free_i64(fp0);
8867 }
8868 opn = "mov.d";
8869 break;
8870 case OPC_NEG_D:
8871 check_cp1_registers(ctx, fs | fd);
8872 {
8873 TCGv_i64 fp0 = tcg_temp_new_i64();
8874
8875 gen_load_fpr64(ctx, fp0, fs);
8876 gen_helper_float_chs_d(fp0, fp0);
8877 gen_store_fpr64(ctx, fp0, fd);
8878 tcg_temp_free_i64(fp0);
8879 }
8880 opn = "neg.d";
8881 break;
8882 case OPC_ROUND_L_D:
8883 check_cp1_64bitmode(ctx);
8884 {
8885 TCGv_i64 fp0 = tcg_temp_new_i64();
8886
8887 gen_load_fpr64(ctx, fp0, fs);
8888 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
8889 gen_store_fpr64(ctx, fp0, fd);
8890 tcg_temp_free_i64(fp0);
8891 }
8892 opn = "round.l.d";
8893 break;
8894 case OPC_TRUNC_L_D:
8895 check_cp1_64bitmode(ctx);
8896 {
8897 TCGv_i64 fp0 = tcg_temp_new_i64();
8898
8899 gen_load_fpr64(ctx, fp0, fs);
8900 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8901 gen_store_fpr64(ctx, fp0, fd);
8902 tcg_temp_free_i64(fp0);
8903 }
8904 opn = "trunc.l.d";
8905 break;
8906 case OPC_CEIL_L_D:
8907 check_cp1_64bitmode(ctx);
8908 {
8909 TCGv_i64 fp0 = tcg_temp_new_i64();
8910
8911 gen_load_fpr64(ctx, fp0, fs);
8912 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8913 gen_store_fpr64(ctx, fp0, fd);
8914 tcg_temp_free_i64(fp0);
8915 }
8916 opn = "ceil.l.d";
8917 break;
8918 case OPC_FLOOR_L_D:
8919 check_cp1_64bitmode(ctx);
8920 {
8921 TCGv_i64 fp0 = tcg_temp_new_i64();
8922
8923 gen_load_fpr64(ctx, fp0, fs);
8924 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8925 gen_store_fpr64(ctx, fp0, fd);
8926 tcg_temp_free_i64(fp0);
8927 }
8928 opn = "floor.l.d";
8929 break;
8930 case OPC_ROUND_W_D:
8931 check_cp1_registers(ctx, fs);
8932 {
8933 TCGv_i32 fp32 = tcg_temp_new_i32();
8934 TCGv_i64 fp64 = tcg_temp_new_i64();
8935
8936 gen_load_fpr64(ctx, fp64, fs);
8937 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8938 tcg_temp_free_i64(fp64);
8939 gen_store_fpr32(fp32, fd);
8940 tcg_temp_free_i32(fp32);
8941 }
8942 opn = "round.w.d";
8943 break;
8944 case OPC_TRUNC_W_D:
8945 check_cp1_registers(ctx, fs);
8946 {
8947 TCGv_i32 fp32 = tcg_temp_new_i32();
8948 TCGv_i64 fp64 = tcg_temp_new_i64();
8949
8950 gen_load_fpr64(ctx, fp64, fs);
8951 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8952 tcg_temp_free_i64(fp64);
8953 gen_store_fpr32(fp32, fd);
8954 tcg_temp_free_i32(fp32);
8955 }
8956 opn = "trunc.w.d";
8957 break;
8958 case OPC_CEIL_W_D:
8959 check_cp1_registers(ctx, fs);
8960 {
8961 TCGv_i32 fp32 = tcg_temp_new_i32();
8962 TCGv_i64 fp64 = tcg_temp_new_i64();
8963
8964 gen_load_fpr64(ctx, fp64, fs);
8965 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8966 tcg_temp_free_i64(fp64);
8967 gen_store_fpr32(fp32, fd);
8968 tcg_temp_free_i32(fp32);
8969 }
8970 opn = "ceil.w.d";
8971 break;
8972 case OPC_FLOOR_W_D:
8973 check_cp1_registers(ctx, fs);
8974 {
8975 TCGv_i32 fp32 = tcg_temp_new_i32();
8976 TCGv_i64 fp64 = tcg_temp_new_i64();
8977
8978 gen_load_fpr64(ctx, fp64, fs);
8979 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8980 tcg_temp_free_i64(fp64);
8981 gen_store_fpr32(fp32, fd);
8982 tcg_temp_free_i32(fp32);
8983 }
8984 opn = "floor.w.d";
8985 break;
8986 case OPC_SEL_D:
8987 check_insn(ctx, ISA_MIPS32R6);
8988 gen_sel_d(ctx, op1, fd, ft, fs);
8989 opn = "sel.d";
8990 break;
8991 case OPC_SELEQZ_D:
8992 check_insn(ctx, ISA_MIPS32R6);
8993 gen_sel_d(ctx, op1, fd, ft, fs);
8994 opn = "seleqz.d";
8995 break;
8996 case OPC_SELNEZ_D:
8997 check_insn(ctx, ISA_MIPS32R6);
8998 gen_sel_d(ctx, op1, fd, ft, fs);
8999 opn = "selnez.d";
9000 break;
9001 case OPC_MOVCF_D:
9002 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9003 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9004 opn = "movcf.d";
9005 break;
9006 case OPC_MOVZ_D:
9007 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9008 {
9009 int l1 = gen_new_label();
9010 TCGv_i64 fp0;
9011
9012 if (ft != 0) {
9013 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9014 }
9015 fp0 = tcg_temp_new_i64();
9016 gen_load_fpr64(ctx, fp0, fs);
9017 gen_store_fpr64(ctx, fp0, fd);
9018 tcg_temp_free_i64(fp0);
9019 gen_set_label(l1);
9020 }
9021 opn = "movz.d";
9022 break;
9023 case OPC_MOVN_D:
9024 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9025 {
9026 int l1 = gen_new_label();
9027 TCGv_i64 fp0;
9028
9029 if (ft != 0) {
9030 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9031 fp0 = tcg_temp_new_i64();
9032 gen_load_fpr64(ctx, fp0, fs);
9033 gen_store_fpr64(ctx, fp0, fd);
9034 tcg_temp_free_i64(fp0);
9035 gen_set_label(l1);
9036 }
9037 }
9038 opn = "movn.d";
9039 break;
9040 case OPC_RECIP_D:
9041 check_cp1_64bitmode(ctx);
9042 {
9043 TCGv_i64 fp0 = tcg_temp_new_i64();
9044
9045 gen_load_fpr64(ctx, fp0, fs);
9046 gen_helper_float_recip_d(fp0, cpu_env, fp0);
9047 gen_store_fpr64(ctx, fp0, fd);
9048 tcg_temp_free_i64(fp0);
9049 }
9050 opn = "recip.d";
9051 break;
9052 case OPC_RSQRT_D:
9053 check_cp1_64bitmode(ctx);
9054 {
9055 TCGv_i64 fp0 = tcg_temp_new_i64();
9056
9057 gen_load_fpr64(ctx, fp0, fs);
9058 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
9059 gen_store_fpr64(ctx, fp0, fd);
9060 tcg_temp_free_i64(fp0);
9061 }
9062 opn = "rsqrt.d";
9063 break;
9064 case OPC_MADDF_D:
9065 check_insn(ctx, ISA_MIPS32R6);
9066 {
9067 TCGv_i64 fp0 = tcg_temp_new_i64();
9068 TCGv_i64 fp1 = tcg_temp_new_i64();
9069 TCGv_i64 fp2 = tcg_temp_new_i64();
9070 gen_load_fpr64(ctx, fp0, fs);
9071 gen_load_fpr64(ctx, fp1, ft);
9072 gen_load_fpr64(ctx, fp2, fd);
9073 gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
9074 gen_store_fpr64(ctx, fp2, fd);
9075 tcg_temp_free_i64(fp2);
9076 tcg_temp_free_i64(fp1);
9077 tcg_temp_free_i64(fp0);
9078 opn = "maddf.d";
9079 }
9080 break;
9081 case OPC_MSUBF_D:
9082 check_insn(ctx, ISA_MIPS32R6);
9083 {
9084 TCGv_i64 fp0 = tcg_temp_new_i64();
9085 TCGv_i64 fp1 = tcg_temp_new_i64();
9086 TCGv_i64 fp2 = tcg_temp_new_i64();
9087 gen_load_fpr64(ctx, fp0, fs);
9088 gen_load_fpr64(ctx, fp1, ft);
9089 gen_load_fpr64(ctx, fp2, fd);
9090 gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
9091 gen_store_fpr64(ctx, fp2, fd);
9092 tcg_temp_free_i64(fp2);
9093 tcg_temp_free_i64(fp1);
9094 tcg_temp_free_i64(fp0);
9095 opn = "msubf.d";
9096 }
9097 break;
9098 case OPC_RINT_D:
9099 check_insn(ctx, ISA_MIPS32R6);
9100 {
9101 TCGv_i64 fp0 = tcg_temp_new_i64();
9102 gen_load_fpr64(ctx, fp0, fs);
9103 gen_helper_float_rint_d(fp0, cpu_env, fp0);
9104 gen_store_fpr64(ctx, fp0, fd);
9105 tcg_temp_free_i64(fp0);
9106 opn = "rint.d";
9107 }
9108 break;
9109 case OPC_CLASS_D:
9110 check_insn(ctx, ISA_MIPS32R6);
9111 {
9112 TCGv_i64 fp0 = tcg_temp_new_i64();
9113 gen_load_fpr64(ctx, fp0, fs);
9114 gen_helper_float_class_d(fp0, fp0);
9115 gen_store_fpr64(ctx, fp0, fd);
9116 tcg_temp_free_i64(fp0);
9117 opn = "class.d";
9118 }
9119 break;
9120 case OPC_MIN_D: /* OPC_RECIP2_D */
9121 if (ctx->insn_flags & ISA_MIPS32R6) {
9122 /* OPC_MIN_D */
9123 TCGv_i64 fp0 = tcg_temp_new_i64();
9124 TCGv_i64 fp1 = tcg_temp_new_i64();
9125 gen_load_fpr64(ctx, fp0, fs);
9126 gen_load_fpr64(ctx, fp1, ft);
9127 gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
9128 gen_store_fpr64(ctx, fp1, fd);
9129 tcg_temp_free_i64(fp1);
9130 tcg_temp_free_i64(fp0);
9131 opn = "min.d";
9132 } else {
9133 /* OPC_RECIP2_D */
9134 check_cp1_64bitmode(ctx);
9135 {
9136 TCGv_i64 fp0 = tcg_temp_new_i64();
9137 TCGv_i64 fp1 = tcg_temp_new_i64();
9138
9139 gen_load_fpr64(ctx, fp0, fs);
9140 gen_load_fpr64(ctx, fp1, ft);
9141 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
9142 tcg_temp_free_i64(fp1);
9143 gen_store_fpr64(ctx, fp0, fd);
9144 tcg_temp_free_i64(fp0);
9145 }
9146 opn = "recip2.d";
9147 }
9148 break;
9149 case OPC_MINA_D: /* OPC_RECIP1_D */
9150 if (ctx->insn_flags & ISA_MIPS32R6) {
9151 /* OPC_MINA_D */
9152 TCGv_i64 fp0 = tcg_temp_new_i64();
9153 TCGv_i64 fp1 = tcg_temp_new_i64();
9154 gen_load_fpr64(ctx, fp0, fs);
9155 gen_load_fpr64(ctx, fp1, ft);
9156 gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
9157 gen_store_fpr64(ctx, fp1, fd);
9158 tcg_temp_free_i64(fp1);
9159 tcg_temp_free_i64(fp0);
9160 opn = "mina.d";
9161 } else {
9162 /* OPC_RECIP1_D */
9163 check_cp1_64bitmode(ctx);
9164 {
9165 TCGv_i64 fp0 = tcg_temp_new_i64();
9166
9167 gen_load_fpr64(ctx, fp0, fs);
9168 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
9169 gen_store_fpr64(ctx, fp0, fd);
9170 tcg_temp_free_i64(fp0);
9171 }
9172 opn = "recip1.d";
9173 }
9174 break;
9175 case OPC_MAX_D: /* OPC_RSQRT1_D */
9176 if (ctx->insn_flags & ISA_MIPS32R6) {
9177 /* OPC_MAX_D */
9178 TCGv_i64 fp0 = tcg_temp_new_i64();
9179 TCGv_i64 fp1 = tcg_temp_new_i64();
9180 gen_load_fpr64(ctx, fp0, fs);
9181 gen_load_fpr64(ctx, fp1, ft);
9182 gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
9183 gen_store_fpr64(ctx, fp1, fd);
9184 tcg_temp_free_i64(fp1);
9185 tcg_temp_free_i64(fp0);
9186 opn = "max.d";
9187 } else {
9188 /* OPC_RSQRT1_D */
9189 check_cp1_64bitmode(ctx);
9190 {
9191 TCGv_i64 fp0 = tcg_temp_new_i64();
9192
9193 gen_load_fpr64(ctx, fp0, fs);
9194 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
9195 gen_store_fpr64(ctx, fp0, fd);
9196 tcg_temp_free_i64(fp0);
9197 }
9198 opn = "rsqrt1.d";
9199 }
9200 break;
9201 case OPC_MAXA_D: /* OPC_RSQRT2_D */
9202 if (ctx->insn_flags & ISA_MIPS32R6) {
9203 /* OPC_MAXA_D */
9204 TCGv_i64 fp0 = tcg_temp_new_i64();
9205 TCGv_i64 fp1 = tcg_temp_new_i64();
9206 gen_load_fpr64(ctx, fp0, fs);
9207 gen_load_fpr64(ctx, fp1, ft);
9208 gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
9209 gen_store_fpr64(ctx, fp1, fd);
9210 tcg_temp_free_i64(fp1);
9211 tcg_temp_free_i64(fp0);
9212 opn = "maxa.d";
9213 } else {
9214 /* OPC_RSQRT2_D */
9215 check_cp1_64bitmode(ctx);
9216 {
9217 TCGv_i64 fp0 = tcg_temp_new_i64();
9218 TCGv_i64 fp1 = tcg_temp_new_i64();
9219
9220 gen_load_fpr64(ctx, fp0, fs);
9221 gen_load_fpr64(ctx, fp1, ft);
9222 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
9223 tcg_temp_free_i64(fp1);
9224 gen_store_fpr64(ctx, fp0, fd);
9225 tcg_temp_free_i64(fp0);
9226 }
9227 opn = "rsqrt2.d";
9228 }
9229 break;
9230 case OPC_CMP_F_D:
9231 case OPC_CMP_UN_D:
9232 case OPC_CMP_EQ_D:
9233 case OPC_CMP_UEQ_D:
9234 case OPC_CMP_OLT_D:
9235 case OPC_CMP_ULT_D:
9236 case OPC_CMP_OLE_D:
9237 case OPC_CMP_ULE_D:
9238 case OPC_CMP_SF_D:
9239 case OPC_CMP_NGLE_D:
9240 case OPC_CMP_SEQ_D:
9241 case OPC_CMP_NGL_D:
9242 case OPC_CMP_LT_D:
9243 case OPC_CMP_NGE_D:
9244 case OPC_CMP_LE_D:
9245 case OPC_CMP_NGT_D:
9246 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9247 if (ctx->opcode & (1 << 6)) {
9248 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
9249 opn = condnames_abs[func-48];
9250 } else {
9251 gen_cmp_d(ctx, func-48, ft, fs, cc);
9252 opn = condnames[func-48];
9253 }
9254 break;
9255 case OPC_CVT_S_D:
9256 check_cp1_registers(ctx, fs);
9257 {
9258 TCGv_i32 fp32 = tcg_temp_new_i32();
9259 TCGv_i64 fp64 = tcg_temp_new_i64();
9260
9261 gen_load_fpr64(ctx, fp64, fs);
9262 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
9263 tcg_temp_free_i64(fp64);
9264 gen_store_fpr32(fp32, fd);
9265 tcg_temp_free_i32(fp32);
9266 }
9267 opn = "cvt.s.d";
9268 break;
9269 case OPC_CVT_W_D:
9270 check_cp1_registers(ctx, fs);
9271 {
9272 TCGv_i32 fp32 = tcg_temp_new_i32();
9273 TCGv_i64 fp64 = tcg_temp_new_i64();
9274
9275 gen_load_fpr64(ctx, fp64, fs);
9276 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
9277 tcg_temp_free_i64(fp64);
9278 gen_store_fpr32(fp32, fd);
9279 tcg_temp_free_i32(fp32);
9280 }
9281 opn = "cvt.w.d";
9282 break;
9283 case OPC_CVT_L_D:
9284 check_cp1_64bitmode(ctx);
9285 {
9286 TCGv_i64 fp0 = tcg_temp_new_i64();
9287
9288 gen_load_fpr64(ctx, fp0, fs);
9289 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
9290 gen_store_fpr64(ctx, fp0, fd);
9291 tcg_temp_free_i64(fp0);
9292 }
9293 opn = "cvt.l.d";
9294 break;
9295 case OPC_CVT_S_W:
9296 {
9297 TCGv_i32 fp0 = tcg_temp_new_i32();
9298
9299 gen_load_fpr32(fp0, fs);
9300 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
9301 gen_store_fpr32(fp0, fd);
9302 tcg_temp_free_i32(fp0);
9303 }
9304 opn = "cvt.s.w";
9305 break;
9306 case OPC_CVT_D_W:
9307 check_cp1_registers(ctx, fd);
9308 {
9309 TCGv_i32 fp32 = tcg_temp_new_i32();
9310 TCGv_i64 fp64 = tcg_temp_new_i64();
9311
9312 gen_load_fpr32(fp32, fs);
9313 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
9314 tcg_temp_free_i32(fp32);
9315 gen_store_fpr64(ctx, fp64, fd);
9316 tcg_temp_free_i64(fp64);
9317 }
9318 opn = "cvt.d.w";
9319 break;
9320 case OPC_CVT_S_L:
9321 check_cp1_64bitmode(ctx);
9322 {
9323 TCGv_i32 fp32 = tcg_temp_new_i32();
9324 TCGv_i64 fp64 = tcg_temp_new_i64();
9325
9326 gen_load_fpr64(ctx, fp64, fs);
9327 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
9328 tcg_temp_free_i64(fp64);
9329 gen_store_fpr32(fp32, fd);
9330 tcg_temp_free_i32(fp32);
9331 }
9332 opn = "cvt.s.l";
9333 break;
9334 case OPC_CVT_D_L:
9335 check_cp1_64bitmode(ctx);
9336 {
9337 TCGv_i64 fp0 = tcg_temp_new_i64();
9338
9339 gen_load_fpr64(ctx, fp0, fs);
9340 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
9341 gen_store_fpr64(ctx, fp0, fd);
9342 tcg_temp_free_i64(fp0);
9343 }
9344 opn = "cvt.d.l";
9345 break;
9346 case OPC_CVT_PS_PW:
9347 check_insn_opc_removed(ctx, ISA_MIPS32R6);
9348 check_cp1_64bitmode(ctx);
9349 {
9350 TCGv_i64 fp0 = tcg_temp_new_i64();
9351
9352 gen_load_fpr64(ctx, fp0, fs);
9353 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
9354 gen_store_fpr64(ctx, fp0, fd);
9355 tcg_temp_free_i64(fp0);
9356 }
9357 opn = "cvt.ps.pw";
9358 break;
9359 case OPC_ADD_PS:
9360 check_cp1_64bitmode(ctx);
9361 {
9362 TCGv_i64 fp0 = tcg_temp_new_i64();
9363 TCGv_i64 fp1 = tcg_temp_new_i64();
9364
9365 gen_load_fpr64(ctx, fp0, fs);
9366 gen_load_fpr64(ctx, fp1, ft);
9367 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
9368 tcg_temp_free_i64(fp1);
9369 gen_store_fpr64(ctx, fp0, fd);
9370 tcg_temp_free_i64(fp0);
9371 }
9372 opn = "add.ps";
9373 break;
9374 case OPC_SUB_PS:
9375 check_cp1_64bitmode(ctx);
9376 {
9377 TCGv_i64 fp0 = tcg_temp_new_i64();
9378 TCGv_i64 fp1 = tcg_temp_new_i64();
9379
9380 gen_load_fpr64(ctx, fp0, fs);
9381 gen_load_fpr64(ctx, fp1, ft);
9382 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
9383 tcg_temp_free_i64(fp1);
9384 gen_store_fpr64(ctx, fp0, fd);
9385 tcg_temp_free_i64(fp0);
9386 }
9387 opn = "sub.ps";
9388 break;
9389 case OPC_MUL_PS:
9390 check_cp1_64bitmode(ctx);
9391 {
9392 TCGv_i64 fp0 = tcg_temp_new_i64();
9393 TCGv_i64 fp1 = tcg_temp_new_i64();
9394
9395 gen_load_fpr64(ctx, fp0, fs);
9396 gen_load_fpr64(ctx, fp1, ft);
9397 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
9398 tcg_temp_free_i64(fp1);
9399 gen_store_fpr64(ctx, fp0, fd);
9400 tcg_temp_free_i64(fp0);
9401 }
9402 opn = "mul.ps";
9403 break;
9404 case OPC_ABS_PS:
9405 check_cp1_64bitmode(ctx);
9406 {
9407 TCGv_i64 fp0 = tcg_temp_new_i64();
9408
9409 gen_load_fpr64(ctx, fp0, fs);
9410 gen_helper_float_abs_ps(fp0, fp0);
9411 gen_store_fpr64(ctx, fp0, fd);
9412 tcg_temp_free_i64(fp0);
9413 }
9414 opn = "abs.ps";
9415 break;
9416 case OPC_MOV_PS:
9417 check_cp1_64bitmode(ctx);
9418 {
9419 TCGv_i64 fp0 = tcg_temp_new_i64();
9420
9421 gen_load_fpr64(ctx, fp0, fs);
9422 gen_store_fpr64(ctx, fp0, fd);
9423 tcg_temp_free_i64(fp0);
9424 }
9425 opn = "mov.ps";
9426 break;
9427 case OPC_NEG_PS:
9428 check_cp1_64bitmode(ctx);
9429 {
9430 TCGv_i64 fp0 = tcg_temp_new_i64();
9431
9432 gen_load_fpr64(ctx, fp0, fs);
9433 gen_helper_float_chs_ps(fp0, fp0);
9434 gen_store_fpr64(ctx, fp0, fd);
9435 tcg_temp_free_i64(fp0);
9436 }
9437 opn = "neg.ps";
9438 break;
9439 case OPC_MOVCF_PS:
9440 check_cp1_64bitmode(ctx);
9441 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
9442 opn = "movcf.ps";
9443 break;
9444 case OPC_MOVZ_PS:
9445 check_cp1_64bitmode(ctx);
9446 {
9447 int l1 = gen_new_label();
9448 TCGv_i64 fp0;
9449
9450 if (ft != 0)
9451 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
9452 fp0 = tcg_temp_new_i64();
9453 gen_load_fpr64(ctx, fp0, fs);
9454 gen_store_fpr64(ctx, fp0, fd);
9455 tcg_temp_free_i64(fp0);
9456 gen_set_label(l1);
9457 }
9458 opn = "movz.ps";
9459 break;
9460 case OPC_MOVN_PS:
9461 check_cp1_64bitmode(ctx);
9462 {
9463 int l1 = gen_new_label();
9464 TCGv_i64 fp0;
9465
9466 if (ft != 0) {
9467 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
9468 fp0 = tcg_temp_new_i64();
9469 gen_load_fpr64(ctx, fp0, fs);
9470 gen_store_fpr64(ctx, fp0, fd);
9471 tcg_temp_free_i64(fp0);
9472 gen_set_label(l1);
9473 }
9474 }
9475 opn = "movn.ps";
9476 break;
9477 case OPC_ADDR_PS:
9478 check_cp1_64bitmode(ctx);
9479 {
9480 TCGv_i64 fp0 = tcg_temp_new_i64();
9481 TCGv_i64 fp1 = tcg_temp_new_i64();
9482
9483 gen_load_fpr64(ctx, fp0, ft);
9484 gen_load_fpr64(ctx, fp1, fs);
9485 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
9486 tcg_temp_free_i64(fp1);
9487 gen_store_fpr64(ctx, fp0, fd);
9488 tcg_temp_free_i64(fp0);
9489 }
9490 opn = "addr.ps";
9491 break;
9492 case OPC_MULR_PS:
9493 check_cp1_64bitmode(ctx);
9494 {
9495 TCGv_i64 fp0 = tcg_temp_new_i64();
9496 TCGv_i64 fp1 = tcg_temp_new_i64();
9497
9498 gen_load_fpr64(ctx, fp0, ft);
9499 gen_load_fpr64(ctx, fp1, fs);
9500 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
9501 tcg_temp_free_i64(fp1);
9502 gen_store_fpr64(ctx, fp0, fd);
9503 tcg_temp_free_i64(fp0);
9504 }
9505 opn = "mulr.ps";
9506 break;
9507 case OPC_RECIP2_PS:
9508 check_cp1_64bitmode(ctx);
9509 {
9510 TCGv_i64 fp0 = tcg_temp_new_i64();
9511 TCGv_i64 fp1 = tcg_temp_new_i64();
9512
9513 gen_load_fpr64(ctx, fp0, fs);
9514 gen_load_fpr64(ctx, fp1, ft);
9515 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
9516 tcg_temp_free_i64(fp1);
9517 gen_store_fpr64(ctx, fp0, fd);
9518 tcg_temp_free_i64(fp0);
9519 }
9520 opn = "recip2.ps";
9521 break;
9522 case OPC_RECIP1_PS:
9523 check_cp1_64bitmode(ctx);
9524 {
9525 TCGv_i64 fp0 = tcg_temp_new_i64();
9526
9527 gen_load_fpr64(ctx, fp0, fs);
9528 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
9529 gen_store_fpr64(ctx, fp0, fd);
9530 tcg_temp_free_i64(fp0);
9531 }
9532 opn = "recip1.ps";
9533 break;
9534 case OPC_RSQRT1_PS:
9535 check_cp1_64bitmode(ctx);
9536 {
9537 TCGv_i64 fp0 = tcg_temp_new_i64();
9538
9539 gen_load_fpr64(ctx, fp0, fs);
9540 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
9541 gen_store_fpr64(ctx, fp0, fd);
9542 tcg_temp_free_i64(fp0);
9543 }
9544 opn = "rsqrt1.ps";
9545 break;
9546 case OPC_RSQRT2_PS:
9547 check_cp1_64bitmode(ctx);
9548 {
9549 TCGv_i64 fp0 = tcg_temp_new_i64();
9550 TCGv_i64 fp1 = tcg_temp_new_i64();
9551
9552 gen_load_fpr64(ctx, fp0, fs);
9553 gen_load_fpr64(ctx, fp1, ft);
9554 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
9555 tcg_temp_free_i64(fp1);
9556 gen_store_fpr64(ctx, fp0, fd);
9557 tcg_temp_free_i64(fp0);
9558 }
9559 opn = "rsqrt2.ps";
9560 break;
9561 case OPC_CVT_S_PU:
9562 check_cp1_64bitmode(ctx);
9563 {
9564 TCGv_i32 fp0 = tcg_temp_new_i32();
9565
9566 gen_load_fpr32h(ctx, fp0, fs);
9567 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
9568 gen_store_fpr32(fp0, fd);
9569 tcg_temp_free_i32(fp0);
9570 }
9571 opn = "cvt.s.pu";
9572 break;
9573 case OPC_CVT_PW_PS:
9574 check_cp1_64bitmode(ctx);
9575 {
9576 TCGv_i64 fp0 = tcg_temp_new_i64();
9577
9578 gen_load_fpr64(ctx, fp0, fs);
9579 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
9580 gen_store_fpr64(ctx, fp0, fd);
9581 tcg_temp_free_i64(fp0);
9582 }
9583 opn = "cvt.pw.ps";
9584 break;
9585 case OPC_CVT_S_PL:
9586 check_cp1_64bitmode(ctx);
9587 {
9588 TCGv_i32 fp0 = tcg_temp_new_i32();
9589
9590 gen_load_fpr32(fp0, fs);
9591 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
9592 gen_store_fpr32(fp0, fd);
9593 tcg_temp_free_i32(fp0);
9594 }
9595 opn = "cvt.s.pl";
9596 break;
9597 case OPC_PLL_PS:
9598 check_cp1_64bitmode(ctx);
9599 {
9600 TCGv_i32 fp0 = tcg_temp_new_i32();
9601 TCGv_i32 fp1 = tcg_temp_new_i32();
9602
9603 gen_load_fpr32(fp0, fs);
9604 gen_load_fpr32(fp1, ft);
9605 gen_store_fpr32h(ctx, fp0, fd);
9606 gen_store_fpr32(fp1, fd);
9607 tcg_temp_free_i32(fp0);
9608 tcg_temp_free_i32(fp1);
9609 }
9610 opn = "pll.ps";
9611 break;
9612 case OPC_PLU_PS:
9613 check_cp1_64bitmode(ctx);
9614 {
9615 TCGv_i32 fp0 = tcg_temp_new_i32();
9616 TCGv_i32 fp1 = tcg_temp_new_i32();
9617
9618 gen_load_fpr32(fp0, fs);
9619 gen_load_fpr32h(ctx, fp1, ft);
9620 gen_store_fpr32(fp1, fd);
9621 gen_store_fpr32h(ctx, fp0, fd);
9622 tcg_temp_free_i32(fp0);
9623 tcg_temp_free_i32(fp1);
9624 }
9625 opn = "plu.ps";
9626 break;
9627 case OPC_PUL_PS:
9628 check_cp1_64bitmode(ctx);
9629 {
9630 TCGv_i32 fp0 = tcg_temp_new_i32();
9631 TCGv_i32 fp1 = tcg_temp_new_i32();
9632
9633 gen_load_fpr32h(ctx, fp0, fs);
9634 gen_load_fpr32(fp1, ft);
9635 gen_store_fpr32(fp1, fd);
9636 gen_store_fpr32h(ctx, fp0, fd);
9637 tcg_temp_free_i32(fp0);
9638 tcg_temp_free_i32(fp1);
9639 }
9640 opn = "pul.ps";
9641 break;
9642 case OPC_PUU_PS:
9643 check_cp1_64bitmode(ctx);
9644 {
9645 TCGv_i32 fp0 = tcg_temp_new_i32();
9646 TCGv_i32 fp1 = tcg_temp_new_i32();
9647
9648 gen_load_fpr32h(ctx, fp0, fs);
9649 gen_load_fpr32h(ctx, fp1, ft);
9650 gen_store_fpr32(fp1, fd);
9651 gen_store_fpr32h(ctx, fp0, fd);
9652 tcg_temp_free_i32(fp0);
9653 tcg_temp_free_i32(fp1);
9654 }
9655 opn = "puu.ps";
9656 break;
9657 case OPC_CMP_F_PS:
9658 case OPC_CMP_UN_PS:
9659 case OPC_CMP_EQ_PS:
9660 case OPC_CMP_UEQ_PS:
9661 case OPC_CMP_OLT_PS:
9662 case OPC_CMP_ULT_PS:
9663 case OPC_CMP_OLE_PS:
9664 case OPC_CMP_ULE_PS:
9665 case OPC_CMP_SF_PS:
9666 case OPC_CMP_NGLE_PS:
9667 case OPC_CMP_SEQ_PS:
9668 case OPC_CMP_NGL_PS:
9669 case OPC_CMP_LT_PS:
9670 case OPC_CMP_NGE_PS:
9671 case OPC_CMP_LE_PS:
9672 case OPC_CMP_NGT_PS:
9673 if (ctx->opcode & (1 << 6)) {
9674 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
9675 opn = condnames_abs[func-48];
9676 } else {
9677 gen_cmp_ps(ctx, func-48, ft, fs, cc);
9678 opn = condnames[func-48];
9679 }
9680 break;
9681 default:
9682 MIPS_INVAL(opn);
9683 generate_exception (ctx, EXCP_RI);
9684 return;
9685 }
9686 (void)opn; /* avoid a compiler warning */
9687 switch (optype) {
9688 case BINOP:
9689 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
9690 break;
9691 case CMPOP:
9692 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
9693 break;
9694 default:
9695 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
9696 break;
9697 }
9698 }
9699
9700 /* Coprocessor 3 (FPU) */
9701 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
9702 int fd, int fs, int base, int index)
9703 {
9704 const char *opn = "extended float load/store";
9705 int store = 0;
9706 TCGv t0 = tcg_temp_new();
9707
9708 if (base == 0) {
9709 gen_load_gpr(t0, index);
9710 } else if (index == 0) {
9711 gen_load_gpr(t0, base);
9712 } else {
9713 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
9714 }
9715 /* Don't do NOP if destination is zero: we must perform the actual
9716 memory access. */
9717 switch (opc) {
9718 case OPC_LWXC1:
9719 check_cop1x(ctx);
9720 {
9721 TCGv_i32 fp0 = tcg_temp_new_i32();
9722
9723 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
9724 tcg_gen_trunc_tl_i32(fp0, t0);
9725 gen_store_fpr32(fp0, fd);
9726 tcg_temp_free_i32(fp0);
9727 }
9728 opn = "lwxc1";
9729 break;
9730 case OPC_LDXC1:
9731 check_cop1x(ctx);
9732 check_cp1_registers(ctx, fd);
9733 {
9734 TCGv_i64 fp0 = tcg_temp_new_i64();
9735 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
9736 gen_store_fpr64(ctx, fp0, fd);
9737 tcg_temp_free_i64(fp0);
9738 }
9739 opn = "ldxc1";
9740 break;
9741 case OPC_LUXC1:
9742 check_cp1_64bitmode(ctx);
9743 tcg_gen_andi_tl(t0, t0, ~0x7);
9744 {
9745 TCGv_i64 fp0 = tcg_temp_new_i64();
9746
9747 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
9748 gen_store_fpr64(ctx, fp0, fd);
9749 tcg_temp_free_i64(fp0);
9750 }
9751 opn = "luxc1";
9752 break;
9753 case OPC_SWXC1:
9754 check_cop1x(ctx);
9755 {
9756 TCGv_i32 fp0 = tcg_temp_new_i32();
9757 gen_load_fpr32(fp0, fs);
9758 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
9759 tcg_temp_free_i32(fp0);
9760 }
9761 opn = "swxc1";
9762 store = 1;
9763 break;
9764 case OPC_SDXC1:
9765 check_cop1x(ctx);
9766 check_cp1_registers(ctx, fs);
9767 {
9768 TCGv_i64 fp0 = tcg_temp_new_i64();
9769 gen_load_fpr64(ctx, fp0, fs);
9770 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
9771 tcg_temp_free_i64(fp0);
9772 }
9773 opn = "sdxc1";
9774 store = 1;
9775 break;
9776 case OPC_SUXC1:
9777 check_cp1_64bitmode(ctx);
9778 tcg_gen_andi_tl(t0, t0, ~0x7);
9779 {
9780 TCGv_i64 fp0 = tcg_temp_new_i64();
9781 gen_load_fpr64(ctx, fp0, fs);
9782 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
9783 tcg_temp_free_i64(fp0);
9784 }
9785 opn = "suxc1";
9786 store = 1;
9787 break;
9788 }
9789 tcg_temp_free(t0);
9790 (void)opn; (void)store; /* avoid compiler warnings */
9791 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
9792 regnames[index], regnames[base]);
9793 }
9794
9795 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
9796 int fd, int fr, int fs, int ft)
9797 {
9798 const char *opn = "flt3_arith";
9799
9800 switch (opc) {
9801 case OPC_ALNV_PS:
9802 check_cp1_64bitmode(ctx);
9803 {
9804 TCGv t0 = tcg_temp_local_new();
9805 TCGv_i32 fp = tcg_temp_new_i32();
9806 TCGv_i32 fph = tcg_temp_new_i32();
9807 int l1 = gen_new_label();
9808 int l2 = gen_new_label();
9809
9810 gen_load_gpr(t0, fr);
9811 tcg_gen_andi_tl(t0, t0, 0x7);
9812
9813 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
9814 gen_load_fpr32(fp, fs);
9815 gen_load_fpr32h(ctx, fph, fs);
9816 gen_store_fpr32(fp, fd);
9817 gen_store_fpr32h(ctx, fph, fd);
9818 tcg_gen_br(l2);
9819 gen_set_label(l1);
9820 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
9821 tcg_temp_free(t0);
9822 #ifdef TARGET_WORDS_BIGENDIAN
9823 gen_load_fpr32(fp, fs);
9824 gen_load_fpr32h(ctx, fph, ft);
9825 gen_store_fpr32h(ctx, fp, fd);
9826 gen_store_fpr32(fph, fd);
9827 #else
9828 gen_load_fpr32h(ctx, fph, fs);
9829 gen_load_fpr32(fp, ft);
9830 gen_store_fpr32(fph, fd);
9831 gen_store_fpr32h(ctx, fp, fd);
9832 #endif
9833 gen_set_label(l2);
9834 tcg_temp_free_i32(fp);
9835 tcg_temp_free_i32(fph);
9836 }
9837 opn = "alnv.ps";
9838 break;
9839 case OPC_MADD_S:
9840 check_cop1x(ctx);
9841 {
9842 TCGv_i32 fp0 = tcg_temp_new_i32();
9843 TCGv_i32 fp1 = tcg_temp_new_i32();
9844 TCGv_i32 fp2 = tcg_temp_new_i32();
9845
9846 gen_load_fpr32(fp0, fs);
9847 gen_load_fpr32(fp1, ft);
9848 gen_load_fpr32(fp2, fr);
9849 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
9850 tcg_temp_free_i32(fp0);
9851 tcg_temp_free_i32(fp1);
9852 gen_store_fpr32(fp2, fd);
9853 tcg_temp_free_i32(fp2);
9854 }
9855 opn = "madd.s";
9856 break;
9857 case OPC_MADD_D:
9858 check_cop1x(ctx);
9859 check_cp1_registers(ctx, fd | fs | ft | fr);
9860 {
9861 TCGv_i64 fp0 = tcg_temp_new_i64();
9862 TCGv_i64 fp1 = tcg_temp_new_i64();
9863 TCGv_i64 fp2 = tcg_temp_new_i64();
9864
9865 gen_load_fpr64(ctx, fp0, fs);
9866 gen_load_fpr64(ctx, fp1, ft);
9867 gen_load_fpr64(ctx, fp2, fr);
9868 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
9869 tcg_temp_free_i64(fp0);
9870 tcg_temp_free_i64(fp1);
9871 gen_store_fpr64(ctx, fp2, fd);
9872 tcg_temp_free_i64(fp2);
9873 }
9874 opn = "madd.d";
9875 break;
9876 case OPC_MADD_PS:
9877 check_cp1_64bitmode(ctx);
9878 {
9879 TCGv_i64 fp0 = tcg_temp_new_i64();
9880 TCGv_i64 fp1 = tcg_temp_new_i64();
9881 TCGv_i64 fp2 = tcg_temp_new_i64();
9882
9883 gen_load_fpr64(ctx, fp0, fs);
9884 gen_load_fpr64(ctx, fp1, ft);
9885 gen_load_fpr64(ctx, fp2, fr);
9886 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
9887 tcg_temp_free_i64(fp0);
9888 tcg_temp_free_i64(fp1);
9889 gen_store_fpr64(ctx, fp2, fd);
9890 tcg_temp_free_i64(fp2);
9891 }
9892 opn = "madd.ps";
9893 break;
9894 case OPC_MSUB_S:
9895 check_cop1x(ctx);
9896 {
9897 TCGv_i32 fp0 = tcg_temp_new_i32();
9898 TCGv_i32 fp1 = tcg_temp_new_i32();
9899 TCGv_i32 fp2 = tcg_temp_new_i32();
9900
9901 gen_load_fpr32(fp0, fs);
9902 gen_load_fpr32(fp1, ft);
9903 gen_load_fpr32(fp2, fr);
9904 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
9905 tcg_temp_free_i32(fp0);
9906 tcg_temp_free_i32(fp1);
9907 gen_store_fpr32(fp2, fd);
9908 tcg_temp_free_i32(fp2);
9909 }
9910 opn = "msub.s";
9911 break;
9912 case OPC_MSUB_D:
9913 check_cop1x(ctx);
9914 check_cp1_registers(ctx, fd | fs | ft | fr);
9915 {
9916 TCGv_i64 fp0 = tcg_temp_new_i64();
9917 TCGv_i64 fp1 = tcg_temp_new_i64();
9918 TCGv_i64 fp2 = tcg_temp_new_i64();
9919
9920 gen_load_fpr64(ctx, fp0, fs);
9921 gen_load_fpr64(ctx, fp1, ft);
9922 gen_load_fpr64(ctx, fp2, fr);
9923 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
9924 tcg_temp_free_i64(fp0);
9925 tcg_temp_free_i64(fp1);
9926 gen_store_fpr64(ctx, fp2, fd);
9927 tcg_temp_free_i64(fp2);
9928 }
9929 opn = "msub.d";
9930 break;
9931 case OPC_MSUB_PS:
9932 check_cp1_64bitmode(ctx);
9933 {
9934 TCGv_i64 fp0 = tcg_temp_new_i64();
9935 TCGv_i64 fp1 = tcg_temp_new_i64();
9936 TCGv_i64 fp2 = tcg_temp_new_i64();
9937
9938 gen_load_fpr64(ctx, fp0, fs);
9939 gen_load_fpr64(ctx, fp1, ft);
9940 gen_load_fpr64(ctx, fp2, fr);
9941 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
9942 tcg_temp_free_i64(fp0);
9943 tcg_temp_free_i64(fp1);
9944 gen_store_fpr64(ctx, fp2, fd);
9945 tcg_temp_free_i64(fp2);
9946 }
9947 opn = "msub.ps";
9948 break;
9949 case OPC_NMADD_S:
9950 check_cop1x(ctx);
9951 {
9952 TCGv_i32 fp0 = tcg_temp_new_i32();
9953 TCGv_i32 fp1 = tcg_temp_new_i32();
9954 TCGv_i32 fp2 = tcg_temp_new_i32();
9955
9956 gen_load_fpr32(fp0, fs);
9957 gen_load_fpr32(fp1, ft);
9958 gen_load_fpr32(fp2, fr);
9959 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
9960 tcg_temp_free_i32(fp0);
9961 tcg_temp_free_i32(fp1);
9962 gen_store_fpr32(fp2, fd);
9963 tcg_temp_free_i32(fp2);
9964 }
9965 opn = "nmadd.s";
9966 break;
9967 case OPC_NMADD_D:
9968 check_cop1x(ctx);
9969 check_cp1_registers(ctx, fd | fs | ft | fr);
9970 {
9971 TCGv_i64 fp0 = tcg_temp_new_i64();
9972 TCGv_i64 fp1 = tcg_temp_new_i64();
9973 TCGv_i64 fp2 = tcg_temp_new_i64();
9974
9975 gen_load_fpr64(ctx, fp0, fs);
9976 gen_load_fpr64(ctx, fp1, ft);
9977 gen_load_fpr64(ctx, fp2, fr);
9978 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
9979 tcg_temp_free_i64(fp0);
9980 tcg_temp_free_i64(fp1);
9981 gen_store_fpr64(ctx, fp2, fd);
9982 tcg_temp_free_i64(fp2);
9983 }
9984 opn = "nmadd.d";
9985 break;
9986 case OPC_NMADD_PS:
9987 check_cp1_64bitmode(ctx);
9988 {
9989 TCGv_i64 fp0 = tcg_temp_new_i64();
9990 TCGv_i64 fp1 = tcg_temp_new_i64();
9991 TCGv_i64 fp2 = tcg_temp_new_i64();
9992
9993 gen_load_fpr64(ctx, fp0, fs);
9994 gen_load_fpr64(ctx, fp1, ft);
9995 gen_load_fpr64(ctx, fp2, fr);
9996 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
9997 tcg_temp_free_i64(fp0);
9998 tcg_temp_free_i64(fp1);
9999 gen_store_fpr64(ctx, fp2, fd);
10000 tcg_temp_free_i64(fp2);
10001 }
10002 opn = "nmadd.ps";
10003 break;
10004 case OPC_NMSUB_S:
10005 check_cop1x(ctx);
10006 {
10007 TCGv_i32 fp0 = tcg_temp_new_i32();
10008 TCGv_i32 fp1 = tcg_temp_new_i32();
10009 TCGv_i32 fp2 = tcg_temp_new_i32();
10010
10011 gen_load_fpr32(fp0, fs);
10012 gen_load_fpr32(fp1, ft);
10013 gen_load_fpr32(fp2, fr);
10014 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
10015 tcg_temp_free_i32(fp0);
10016 tcg_temp_free_i32(fp1);
10017 gen_store_fpr32(fp2, fd);
10018 tcg_temp_free_i32(fp2);
10019 }
10020 opn = "nmsub.s";
10021 break;
10022 case OPC_NMSUB_D:
10023 check_cop1x(ctx);
10024 check_cp1_registers(ctx, fd | fs | ft | fr);
10025 {
10026 TCGv_i64 fp0 = tcg_temp_new_i64();
10027 TCGv_i64 fp1 = tcg_temp_new_i64();
10028 TCGv_i64 fp2 = tcg_temp_new_i64();
10029
10030 gen_load_fpr64(ctx, fp0, fs);
10031 gen_load_fpr64(ctx, fp1, ft);
10032 gen_load_fpr64(ctx, fp2, fr);
10033 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
10034 tcg_temp_free_i64(fp0);
10035 tcg_temp_free_i64(fp1);
10036 gen_store_fpr64(ctx, fp2, fd);
10037 tcg_temp_free_i64(fp2);
10038 }
10039 opn = "nmsub.d";
10040 break;
10041 case OPC_NMSUB_PS:
10042 check_cp1_64bitmode(ctx);
10043 {
10044 TCGv_i64 fp0 = tcg_temp_new_i64();
10045 TCGv_i64 fp1 = tcg_temp_new_i64();
10046 TCGv_i64 fp2 = tcg_temp_new_i64();
10047
10048 gen_load_fpr64(ctx, fp0, fs);
10049 gen_load_fpr64(ctx, fp1, ft);
10050 gen_load_fpr64(ctx, fp2, fr);
10051 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
10052 tcg_temp_free_i64(fp0);
10053 tcg_temp_free_i64(fp1);
10054 gen_store_fpr64(ctx, fp2, fd);
10055 tcg_temp_free_i64(fp2);
10056 }
10057 opn = "nmsub.ps";
10058 break;
10059 default:
10060 MIPS_INVAL(opn);
10061 generate_exception (ctx, EXCP_RI);
10062 return;
10063 }
10064 (void)opn; /* avoid a compiler warning */
10065 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
10066 fregnames[fs], fregnames[ft]);
10067 }
10068
10069 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
10070 {
10071 TCGv t0;
10072
10073 #if !defined(CONFIG_USER_ONLY)
10074 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10075 Therefore only check the ISA in system mode. */
10076 check_insn(ctx, ISA_MIPS32R2);
10077 #endif
10078 t0 = tcg_temp_new();
10079
10080 switch (rd) {
10081 case 0:
10082 save_cpu_state(ctx, 1);
10083 gen_helper_rdhwr_cpunum(t0, cpu_env);
10084 gen_store_gpr(t0, rt);
10085 break;
10086 case 1:
10087 save_cpu_state(ctx, 1);
10088 gen_helper_rdhwr_synci_step(t0, cpu_env);
10089 gen_store_gpr(t0, rt);
10090 break;
10091 case 2:
10092 save_cpu_state(ctx, 1);
10093 gen_helper_rdhwr_cc(t0, cpu_env);
10094 gen_store_gpr(t0, rt);
10095 break;
10096 case 3:
10097 save_cpu_state(ctx, 1);
10098 gen_helper_rdhwr_ccres(t0, cpu_env);
10099 gen_store_gpr(t0, rt);
10100 break;
10101 case 29:
10102 #if defined(CONFIG_USER_ONLY)
10103 tcg_gen_ld_tl(t0, cpu_env,
10104 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10105 gen_store_gpr(t0, rt);
10106 break;
10107 #else
10108 if ((ctx->hflags & MIPS_HFLAG_CP0) ||
10109 (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
10110 tcg_gen_ld_tl(t0, cpu_env,
10111 offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
10112 gen_store_gpr(t0, rt);
10113 } else {
10114 generate_exception(ctx, EXCP_RI);
10115 }
10116 break;
10117 #endif
10118 default: /* Invalid */
10119 MIPS_INVAL("rdhwr");
10120 generate_exception(ctx, EXCP_RI);
10121 break;
10122 }
10123 tcg_temp_free(t0);
10124 }
10125
10126 static void gen_branch(DisasContext *ctx, int insn_bytes)
10127 {
10128 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10129 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
10130 /* Branches completion */
10131 ctx->hflags &= ~MIPS_HFLAG_BMASK;
10132 ctx->bstate = BS_BRANCH;
10133 save_cpu_state(ctx, 0);
10134 /* FIXME: Need to clear can_do_io. */
10135 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
10136 case MIPS_HFLAG_B:
10137 /* unconditional branch */
10138 MIPS_DEBUG("unconditional branch");
10139 if (proc_hflags & MIPS_HFLAG_BX) {
10140 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
10141 }
10142 gen_goto_tb(ctx, 0, ctx->btarget);
10143 break;
10144 case MIPS_HFLAG_BL:
10145 /* blikely taken case */
10146 MIPS_DEBUG("blikely branch taken");
10147 gen_goto_tb(ctx, 0, ctx->btarget);
10148 break;
10149 case MIPS_HFLAG_BC:
10150 /* Conditional branch */
10151 MIPS_DEBUG("conditional branch");
10152 {
10153 int l1 = gen_new_label();
10154
10155 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
10156 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
10157 gen_set_label(l1);
10158 gen_goto_tb(ctx, 0, ctx->btarget);
10159 }
10160 break;
10161 case MIPS_HFLAG_BR:
10162 /* unconditional branch to register */
10163 MIPS_DEBUG("branch to register");
10164 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
10165 TCGv t0 = tcg_temp_new();
10166 TCGv_i32 t1 = tcg_temp_new_i32();
10167
10168 tcg_gen_andi_tl(t0, btarget, 0x1);
10169 tcg_gen_trunc_tl_i32(t1, t0);
10170 tcg_temp_free(t0);
10171 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
10172 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
10173 tcg_gen_or_i32(hflags, hflags, t1);
10174 tcg_temp_free_i32(t1);
10175
10176 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
10177 } else {
10178 tcg_gen_mov_tl(cpu_PC, btarget);
10179 }
10180 if (ctx->singlestep_enabled) {
10181 save_cpu_state(ctx, 0);
10182 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
10183 }
10184 tcg_gen_exit_tb(0);
10185 break;
10186 default:
10187 MIPS_DEBUG("unknown branch");
10188 break;
10189 }
10190 }
10191 }
10192
10193 /* ISA extensions (ASEs) */
10194 /* MIPS16 extension to MIPS32 */
10195
10196 /* MIPS16 major opcodes */
10197 enum {
10198 M16_OPC_ADDIUSP = 0x00,
10199 M16_OPC_ADDIUPC = 0x01,
10200 M16_OPC_B = 0x02,
10201 M16_OPC_JAL = 0x03,
10202 M16_OPC_BEQZ = 0x04,
10203 M16_OPC_BNEQZ = 0x05,
10204 M16_OPC_SHIFT = 0x06,
10205 M16_OPC_LD = 0x07,
10206 M16_OPC_RRIA = 0x08,
10207 M16_OPC_ADDIU8 = 0x09,
10208 M16_OPC_SLTI = 0x0a,
10209 M16_OPC_SLTIU = 0x0b,
10210 M16_OPC_I8 = 0x0c,
10211 M16_OPC_LI = 0x0d,
10212 M16_OPC_CMPI = 0x0e,
10213 M16_OPC_SD = 0x0f,
10214 M16_OPC_LB = 0x10,
10215 M16_OPC_LH = 0x11,
10216 M16_OPC_LWSP = 0x12,
10217 M16_OPC_LW = 0x13,
10218 M16_OPC_LBU = 0x14,
10219 M16_OPC_LHU = 0x15,
10220 M16_OPC_LWPC = 0x16,
10221 M16_OPC_LWU = 0x17,
10222 M16_OPC_SB = 0x18,
10223 M16_OPC_SH = 0x19,
10224 M16_OPC_SWSP = 0x1a,
10225 M16_OPC_SW = 0x1b,
10226 M16_OPC_RRR = 0x1c,
10227 M16_OPC_RR = 0x1d,
10228 M16_OPC_EXTEND = 0x1e,
10229 M16_OPC_I64 = 0x1f
10230 };
10231
10232 /* I8 funct field */
10233 enum {
10234 I8_BTEQZ = 0x0,
10235 I8_BTNEZ = 0x1,
10236 I8_SWRASP = 0x2,
10237 I8_ADJSP = 0x3,
10238 I8_SVRS = 0x4,
10239 I8_MOV32R = 0x5,
10240 I8_MOVR32 = 0x7
10241 };
10242
10243 /* RRR f field */
10244 enum {
10245 RRR_DADDU = 0x0,
10246 RRR_ADDU = 0x1,
10247 RRR_DSUBU = 0x2,
10248 RRR_SUBU = 0x3
10249 };
10250
10251 /* RR funct field */
10252 enum {
10253 RR_JR = 0x00,
10254 RR_SDBBP = 0x01,
10255 RR_SLT = 0x02,
10256 RR_SLTU = 0x03,
10257 RR_SLLV = 0x04,
10258 RR_BREAK = 0x05,
10259 RR_SRLV = 0x06,
10260 RR_SRAV = 0x07,
10261 RR_DSRL = 0x08,
10262 RR_CMP = 0x0a,
10263 RR_NEG = 0x0b,
10264 RR_AND = 0x0c,
10265 RR_OR = 0x0d,
10266 RR_XOR = 0x0e,
10267 RR_NOT = 0x0f,
10268 RR_MFHI = 0x10,
10269 RR_CNVT = 0x11,
10270 RR_MFLO = 0x12,
10271 RR_DSRA = 0x13,
10272 RR_DSLLV = 0x14,
10273 RR_DSRLV = 0x16,
10274 RR_DSRAV = 0x17,
10275 RR_MULT = 0x18,
10276 RR_MULTU = 0x19,
10277 RR_DIV = 0x1a,
10278 RR_DIVU = 0x1b,
10279 RR_DMULT = 0x1c,
10280 RR_DMULTU = 0x1d,
10281 RR_DDIV = 0x1e,
10282 RR_DDIVU = 0x1f
10283 };
10284
10285 /* I64 funct field */
10286 enum {
10287 I64_LDSP = 0x0,
10288 I64_SDSP = 0x1,
10289 I64_SDRASP = 0x2,
10290 I64_DADJSP = 0x3,
10291 I64_LDPC = 0x4,
10292 I64_DADDIU5 = 0x5,
10293 I64_DADDIUPC = 0x6,
10294 I64_DADDIUSP = 0x7
10295 };
10296
10297 /* RR ry field for CNVT */
10298 enum {
10299 RR_RY_CNVT_ZEB = 0x0,
10300 RR_RY_CNVT_ZEH = 0x1,
10301 RR_RY_CNVT_ZEW = 0x2,
10302 RR_RY_CNVT_SEB = 0x4,
10303 RR_RY_CNVT_SEH = 0x5,
10304 RR_RY_CNVT_SEW = 0x6,
10305 };
10306
10307 static int xlat (int r)
10308 {
10309 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10310
10311 return map[r];
10312 }
10313
10314 static void gen_mips16_save (DisasContext *ctx,
10315 int xsregs, int aregs,
10316 int do_ra, int do_s0, int do_s1,
10317 int framesize)
10318 {
10319 TCGv t0 = tcg_temp_new();
10320 TCGv t1 = tcg_temp_new();
10321 int args, astatic;
10322
10323 switch (aregs) {
10324 case 0:
10325 case 1:
10326 case 2:
10327 case 3:
10328 case 11:
10329 args = 0;
10330 break;
10331 case 4:
10332 case 5:
10333 case 6:
10334 case 7:
10335 args = 1;
10336 break;
10337 case 8:
10338 case 9:
10339 case 10:
10340 args = 2;
10341 break;
10342 case 12:
10343 case 13:
10344 args = 3;
10345 break;
10346 case 14:
10347 args = 4;
10348 break;
10349 default:
10350 generate_exception(ctx, EXCP_RI);
10351 return;
10352 }
10353
10354 switch (args) {
10355 case 4:
10356 gen_base_offset_addr(ctx, t0, 29, 12);
10357 gen_load_gpr(t1, 7);
10358 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10359 /* Fall through */
10360 case 3:
10361 gen_base_offset_addr(ctx, t0, 29, 8);
10362 gen_load_gpr(t1, 6);
10363 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10364 /* Fall through */
10365 case 2:
10366 gen_base_offset_addr(ctx, t0, 29, 4);
10367 gen_load_gpr(t1, 5);
10368 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10369 /* Fall through */
10370 case 1:
10371 gen_base_offset_addr(ctx, t0, 29, 0);
10372 gen_load_gpr(t1, 4);
10373 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10374 }
10375
10376 gen_load_gpr(t0, 29);
10377
10378 #define DECR_AND_STORE(reg) do { \
10379 tcg_gen_subi_tl(t0, t0, 4); \
10380 gen_load_gpr(t1, reg); \
10381 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
10382 } while (0)
10383
10384 if (do_ra) {
10385 DECR_AND_STORE(31);
10386 }
10387
10388 switch (xsregs) {
10389 case 7:
10390 DECR_AND_STORE(30);
10391 /* Fall through */
10392 case 6:
10393 DECR_AND_STORE(23);
10394 /* Fall through */
10395 case 5:
10396 DECR_AND_STORE(22);
10397 /* Fall through */
10398 case 4:
10399 DECR_AND_STORE(21);
10400 /* Fall through */
10401 case 3:
10402 DECR_AND_STORE(20);
10403 /* Fall through */
10404 case 2:
10405 DECR_AND_STORE(19);
10406 /* Fall through */
10407 case 1:
10408 DECR_AND_STORE(18);
10409 }
10410
10411 if (do_s1) {
10412 DECR_AND_STORE(17);
10413 }
10414 if (do_s0) {
10415 DECR_AND_STORE(16);
10416 }
10417
10418 switch (aregs) {
10419 case 0:
10420 case 4:
10421 case 8:
10422 case 12:
10423 case 14:
10424 astatic = 0;
10425 break;
10426 case 1:
10427 case 5:
10428 case 9:
10429 case 13:
10430 astatic = 1;
10431 break;
10432 case 2:
10433 case 6:
10434 case 10:
10435 astatic = 2;
10436 break;
10437 case 3:
10438 case 7:
10439 astatic = 3;
10440 break;
10441 case 11:
10442 astatic = 4;
10443 break;
10444 default:
10445 generate_exception(ctx, EXCP_RI);
10446 return;
10447 }
10448
10449 if (astatic > 0) {
10450 DECR_AND_STORE(7);
10451 if (astatic > 1) {
10452 DECR_AND_STORE(6);
10453 if (astatic > 2) {
10454 DECR_AND_STORE(5);
10455 if (astatic > 3) {
10456 DECR_AND_STORE(4);
10457 }
10458 }
10459 }
10460 }
10461 #undef DECR_AND_STORE
10462
10463 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10464 tcg_temp_free(t0);
10465 tcg_temp_free(t1);
10466 }
10467
10468 static void gen_mips16_restore (DisasContext *ctx,
10469 int xsregs, int aregs,
10470 int do_ra, int do_s0, int do_s1,
10471 int framesize)
10472 {
10473 int astatic;
10474 TCGv t0 = tcg_temp_new();
10475 TCGv t1 = tcg_temp_new();
10476
10477 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
10478
10479 #define DECR_AND_LOAD(reg) do { \
10480 tcg_gen_subi_tl(t0, t0, 4); \
10481 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10482 gen_store_gpr(t1, reg); \
10483 } while (0)
10484
10485 if (do_ra) {
10486 DECR_AND_LOAD(31);
10487 }
10488
10489 switch (xsregs) {
10490 case 7:
10491 DECR_AND_LOAD(30);
10492 /* Fall through */
10493 case 6:
10494 DECR_AND_LOAD(23);
10495 /* Fall through */
10496 case 5:
10497 DECR_AND_LOAD(22);
10498 /* Fall through */
10499 case 4:
10500 DECR_AND_LOAD(21);
10501 /* Fall through */
10502 case 3:
10503 DECR_AND_LOAD(20);
10504 /* Fall through */
10505 case 2:
10506 DECR_AND_LOAD(19);
10507 /* Fall through */
10508 case 1:
10509 DECR_AND_LOAD(18);
10510 }
10511
10512 if (do_s1) {
10513 DECR_AND_LOAD(17);
10514 }
10515 if (do_s0) {
10516 DECR_AND_LOAD(16);
10517 }
10518
10519 switch (aregs) {
10520 case 0:
10521 case 4:
10522 case 8:
10523 case 12:
10524 case 14:
10525 astatic = 0;
10526 break;
10527 case 1:
10528 case 5:
10529 case 9:
10530 case 13:
10531 astatic = 1;
10532 break;
10533 case 2:
10534 case 6:
10535 case 10:
10536 astatic = 2;
10537 break;
10538 case 3:
10539 case 7:
10540 astatic = 3;
10541 break;
10542 case 11:
10543 astatic = 4;
10544 break;
10545 default:
10546 generate_exception(ctx, EXCP_RI);
10547 return;
10548 }
10549
10550 if (astatic > 0) {
10551 DECR_AND_LOAD(7);
10552 if (astatic > 1) {
10553 DECR_AND_LOAD(6);
10554 if (astatic > 2) {
10555 DECR_AND_LOAD(5);
10556 if (astatic > 3) {
10557 DECR_AND_LOAD(4);
10558 }
10559 }
10560 }
10561 }
10562 #undef DECR_AND_LOAD
10563
10564 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
10565 tcg_temp_free(t0);
10566 tcg_temp_free(t1);
10567 }
10568
10569 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
10570 int is_64_bit, int extended)
10571 {
10572 TCGv t0;
10573
10574 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10575 generate_exception(ctx, EXCP_RI);
10576 return;
10577 }
10578
10579 t0 = tcg_temp_new();
10580
10581 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
10582 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
10583 if (!is_64_bit) {
10584 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10585 }
10586
10587 tcg_temp_free(t0);
10588 }
10589
10590 #if defined(TARGET_MIPS64)
10591 static void decode_i64_mips16 (DisasContext *ctx,
10592 int ry, int funct, int16_t offset,
10593 int extended)
10594 {
10595 switch (funct) {
10596 case I64_LDSP:
10597 check_mips_64(ctx);
10598 offset = extended ? offset : offset << 3;
10599 gen_ld(ctx, OPC_LD, ry, 29, offset);
10600 break;
10601 case I64_SDSP:
10602 check_mips_64(ctx);
10603 offset = extended ? offset : offset << 3;
10604 gen_st(ctx, OPC_SD, ry, 29, offset);
10605 break;
10606 case I64_SDRASP:
10607 check_mips_64(ctx);
10608 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
10609 gen_st(ctx, OPC_SD, 31, 29, offset);
10610 break;
10611 case I64_DADJSP:
10612 check_mips_64(ctx);
10613 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
10614 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
10615 break;
10616 case I64_LDPC:
10617 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10618 generate_exception(ctx, EXCP_RI);
10619 } else {
10620 offset = extended ? offset : offset << 3;
10621 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
10622 }
10623 break;
10624 case I64_DADDIU5:
10625 check_mips_64(ctx);
10626 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
10627 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
10628 break;
10629 case I64_DADDIUPC:
10630 check_mips_64(ctx);
10631 offset = extended ? offset : offset << 2;
10632 gen_addiupc(ctx, ry, offset, 1, extended);
10633 break;
10634 case I64_DADDIUSP:
10635 check_mips_64(ctx);
10636 offset = extended ? offset : offset << 2;
10637 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
10638 break;
10639 }
10640 }
10641 #endif
10642
10643 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
10644 {
10645 int extend = cpu_lduw_code(env, ctx->pc + 2);
10646 int op, rx, ry, funct, sa;
10647 int16_t imm, offset;
10648
10649 ctx->opcode = (ctx->opcode << 16) | extend;
10650 op = (ctx->opcode >> 11) & 0x1f;
10651 sa = (ctx->opcode >> 22) & 0x1f;
10652 funct = (ctx->opcode >> 8) & 0x7;
10653 rx = xlat((ctx->opcode >> 8) & 0x7);
10654 ry = xlat((ctx->opcode >> 5) & 0x7);
10655 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
10656 | ((ctx->opcode >> 21) & 0x3f) << 5
10657 | (ctx->opcode & 0x1f));
10658
10659 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
10660 counterparts. */
10661 switch (op) {
10662 case M16_OPC_ADDIUSP:
10663 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
10664 break;
10665 case M16_OPC_ADDIUPC:
10666 gen_addiupc(ctx, rx, imm, 0, 1);
10667 break;
10668 case M16_OPC_B:
10669 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
10670 /* No delay slot, so just process as a normal instruction */
10671 break;
10672 case M16_OPC_BEQZ:
10673 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
10674 /* No delay slot, so just process as a normal instruction */
10675 break;
10676 case M16_OPC_BNEQZ:
10677 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
10678 /* No delay slot, so just process as a normal instruction */
10679 break;
10680 case M16_OPC_SHIFT:
10681 switch (ctx->opcode & 0x3) {
10682 case 0x0:
10683 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
10684 break;
10685 case 0x1:
10686 #if defined(TARGET_MIPS64)
10687 check_mips_64(ctx);
10688 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
10689 #else
10690 generate_exception(ctx, EXCP_RI);
10691 #endif
10692 break;
10693 case 0x2:
10694 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
10695 break;
10696 case 0x3:
10697 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
10698 break;
10699 }
10700 break;
10701 #if defined(TARGET_MIPS64)
10702 case M16_OPC_LD:
10703 check_mips_64(ctx);
10704 gen_ld(ctx, OPC_LD, ry, rx, offset);
10705 break;
10706 #endif
10707 case M16_OPC_RRIA:
10708 imm = ctx->opcode & 0xf;
10709 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
10710 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
10711 imm = (int16_t) (imm << 1) >> 1;
10712 if ((ctx->opcode >> 4) & 0x1) {
10713 #if defined(TARGET_MIPS64)
10714 check_mips_64(ctx);
10715 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
10716 #else
10717 generate_exception(ctx, EXCP_RI);
10718 #endif
10719 } else {
10720 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
10721 }
10722 break;
10723 case M16_OPC_ADDIU8:
10724 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
10725 break;
10726 case M16_OPC_SLTI:
10727 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
10728 break;
10729 case M16_OPC_SLTIU:
10730 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
10731 break;
10732 case M16_OPC_I8:
10733 switch (funct) {
10734 case I8_BTEQZ:
10735 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
10736 break;
10737 case I8_BTNEZ:
10738 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
10739 break;
10740 case I8_SWRASP:
10741 gen_st(ctx, OPC_SW, 31, 29, imm);
10742 break;
10743 case I8_ADJSP:
10744 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
10745 break;
10746 case I8_SVRS:
10747 {
10748 int xsregs = (ctx->opcode >> 24) & 0x7;
10749 int aregs = (ctx->opcode >> 16) & 0xf;
10750 int do_ra = (ctx->opcode >> 6) & 0x1;
10751 int do_s0 = (ctx->opcode >> 5) & 0x1;
10752 int do_s1 = (ctx->opcode >> 4) & 0x1;
10753 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
10754 | (ctx->opcode & 0xf)) << 3;
10755
10756 if (ctx->opcode & (1 << 7)) {
10757 gen_mips16_save(ctx, xsregs, aregs,
10758 do_ra, do_s0, do_s1,
10759 framesize);
10760 } else {
10761 gen_mips16_restore(ctx, xsregs, aregs,
10762 do_ra, do_s0, do_s1,
10763 framesize);
10764 }
10765 }
10766 break;
10767 default:
10768 generate_exception(ctx, EXCP_RI);
10769 break;
10770 }
10771 break;
10772 case M16_OPC_LI:
10773 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
10774 break;
10775 case M16_OPC_CMPI:
10776 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
10777 break;
10778 #if defined(TARGET_MIPS64)
10779 case M16_OPC_SD:
10780 gen_st(ctx, OPC_SD, ry, rx, offset);
10781 break;
10782 #endif
10783 case M16_OPC_LB:
10784 gen_ld(ctx, OPC_LB, ry, rx, offset);
10785 break;
10786 case M16_OPC_LH:
10787 gen_ld(ctx, OPC_LH, ry, rx, offset);
10788 break;
10789 case M16_OPC_LWSP:
10790 gen_ld(ctx, OPC_LW, rx, 29, offset);
10791 break;
10792 case M16_OPC_LW:
10793 gen_ld(ctx, OPC_LW, ry, rx, offset);
10794 break;
10795 case M16_OPC_LBU:
10796 gen_ld(ctx, OPC_LBU, ry, rx, offset);
10797 break;
10798 case M16_OPC_LHU:
10799 gen_ld(ctx, OPC_LHU, ry, rx, offset);
10800 break;
10801 case M16_OPC_LWPC:
10802 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
10803 break;
10804 #if defined(TARGET_MIPS64)
10805 case M16_OPC_LWU:
10806 gen_ld(ctx, OPC_LWU, ry, rx, offset);
10807 break;
10808 #endif
10809 case M16_OPC_SB:
10810 gen_st(ctx, OPC_SB, ry, rx, offset);
10811 break;
10812 case M16_OPC_SH:
10813 gen_st(ctx, OPC_SH, ry, rx, offset);
10814 break;
10815 case M16_OPC_SWSP:
10816 gen_st(ctx, OPC_SW, rx, 29, offset);
10817 break;
10818 case M16_OPC_SW:
10819 gen_st(ctx, OPC_SW, ry, rx, offset);
10820 break;
10821 #if defined(TARGET_MIPS64)
10822 case M16_OPC_I64:
10823 decode_i64_mips16(ctx, ry, funct, offset, 1);
10824 break;
10825 #endif
10826 default:
10827 generate_exception(ctx, EXCP_RI);
10828 break;
10829 }
10830
10831 return 4;
10832 }
10833
10834 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
10835 {
10836 int rx, ry;
10837 int sa;
10838 int op, cnvt_op, op1, offset;
10839 int funct;
10840 int n_bytes;
10841
10842 op = (ctx->opcode >> 11) & 0x1f;
10843 sa = (ctx->opcode >> 2) & 0x7;
10844 sa = sa == 0 ? 8 : sa;
10845 rx = xlat((ctx->opcode >> 8) & 0x7);
10846 cnvt_op = (ctx->opcode >> 5) & 0x7;
10847 ry = xlat((ctx->opcode >> 5) & 0x7);
10848 op1 = offset = ctx->opcode & 0x1f;
10849
10850 n_bytes = 2;
10851
10852 switch (op) {
10853 case M16_OPC_ADDIUSP:
10854 {
10855 int16_t imm = ((uint8_t) ctx->opcode) << 2;
10856
10857 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
10858 }
10859 break;
10860 case M16_OPC_ADDIUPC:
10861 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
10862 break;
10863 case M16_OPC_B:
10864 offset = (ctx->opcode & 0x7ff) << 1;
10865 offset = (int16_t)(offset << 4) >> 4;
10866 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
10867 /* No delay slot, so just process as a normal instruction */
10868 break;
10869 case M16_OPC_JAL:
10870 offset = cpu_lduw_code(env, ctx->pc + 2);
10871 offset = (((ctx->opcode & 0x1f) << 21)
10872 | ((ctx->opcode >> 5) & 0x1f) << 16
10873 | offset) << 2;
10874 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
10875 gen_compute_branch(ctx, op, 4, rx, ry, offset);
10876 n_bytes = 4;
10877 break;
10878 case M16_OPC_BEQZ:
10879 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
10880 /* No delay slot, so just process as a normal instruction */
10881 break;
10882 case M16_OPC_BNEQZ:
10883 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
10884 /* No delay slot, so just process as a normal instruction */
10885 break;
10886 case M16_OPC_SHIFT:
10887 switch (ctx->opcode & 0x3) {
10888 case 0x0:
10889 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
10890 break;
10891 case 0x1:
10892 #if defined(TARGET_MIPS64)
10893 check_mips_64(ctx);
10894 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
10895 #else
10896 generate_exception(ctx, EXCP_RI);
10897 #endif
10898 break;
10899 case 0x2:
10900 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
10901 break;
10902 case 0x3:
10903 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
10904 break;
10905 }
10906 break;
10907 #if defined(TARGET_MIPS64)
10908 case M16_OPC_LD:
10909 check_mips_64(ctx);
10910 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
10911 break;
10912 #endif
10913 case M16_OPC_RRIA:
10914 {
10915 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
10916
10917 if ((ctx->opcode >> 4) & 1) {
10918 #if defined(TARGET_MIPS64)
10919 check_mips_64(ctx);
10920 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
10921 #else
10922 generate_exception(ctx, EXCP_RI);
10923 #endif
10924 } else {
10925 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
10926 }
10927 }
10928 break;
10929 case M16_OPC_ADDIU8:
10930 {
10931 int16_t imm = (int8_t) ctx->opcode;
10932
10933 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
10934 }
10935 break;
10936 case M16_OPC_SLTI:
10937 {
10938 int16_t imm = (uint8_t) ctx->opcode;
10939 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
10940 }
10941 break;
10942 case M16_OPC_SLTIU:
10943 {
10944 int16_t imm = (uint8_t) ctx->opcode;
10945 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
10946 }
10947 break;
10948 case M16_OPC_I8:
10949 {
10950 int reg32;
10951
10952 funct = (ctx->opcode >> 8) & 0x7;
10953 switch (funct) {
10954 case I8_BTEQZ:
10955 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
10956 ((int8_t)ctx->opcode) << 1);
10957 break;
10958 case I8_BTNEZ:
10959 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
10960 ((int8_t)ctx->opcode) << 1);
10961 break;
10962 case I8_SWRASP:
10963 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
10964 break;
10965 case I8_ADJSP:
10966 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
10967 ((int8_t)ctx->opcode) << 3);
10968 break;
10969 case I8_SVRS:
10970 {
10971 int do_ra = ctx->opcode & (1 << 6);
10972 int do_s0 = ctx->opcode & (1 << 5);
10973 int do_s1 = ctx->opcode & (1 << 4);
10974 int framesize = ctx->opcode & 0xf;
10975
10976 if (framesize == 0) {
10977 framesize = 128;
10978 } else {
10979 framesize = framesize << 3;
10980 }
10981
10982 if (ctx->opcode & (1 << 7)) {
10983 gen_mips16_save(ctx, 0, 0,
10984 do_ra, do_s0, do_s1, framesize);
10985 } else {
10986 gen_mips16_restore(ctx, 0, 0,
10987 do_ra, do_s0, do_s1, framesize);
10988 }
10989 }
10990 break;
10991 case I8_MOV32R:
10992 {
10993 int rz = xlat(ctx->opcode & 0x7);
10994
10995 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
10996 ((ctx->opcode >> 5) & 0x7);
10997 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
10998 }
10999 break;
11000 case I8_MOVR32:
11001 reg32 = ctx->opcode & 0x1f;
11002 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
11003 break;
11004 default:
11005 generate_exception(ctx, EXCP_RI);
11006 break;
11007 }
11008 }
11009 break;
11010 case M16_OPC_LI:
11011 {
11012 int16_t imm = (uint8_t) ctx->opcode;
11013
11014 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
11015 }
11016 break;
11017 case M16_OPC_CMPI:
11018 {
11019 int16_t imm = (uint8_t) ctx->opcode;
11020 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
11021 }
11022 break;
11023 #if defined(TARGET_MIPS64)
11024 case M16_OPC_SD:
11025 check_mips_64(ctx);
11026 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
11027 break;
11028 #endif
11029 case M16_OPC_LB:
11030 gen_ld(ctx, OPC_LB, ry, rx, offset);
11031 break;
11032 case M16_OPC_LH:
11033 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
11034 break;
11035 case M16_OPC_LWSP:
11036 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11037 break;
11038 case M16_OPC_LW:
11039 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
11040 break;
11041 case M16_OPC_LBU:
11042 gen_ld(ctx, OPC_LBU, ry, rx, offset);
11043 break;
11044 case M16_OPC_LHU:
11045 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
11046 break;
11047 case M16_OPC_LWPC:
11048 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
11049 break;
11050 #if defined (TARGET_MIPS64)
11051 case M16_OPC_LWU:
11052 check_mips_64(ctx);
11053 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
11054 break;
11055 #endif
11056 case M16_OPC_SB:
11057 gen_st(ctx, OPC_SB, ry, rx, offset);
11058 break;
11059 case M16_OPC_SH:
11060 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
11061 break;
11062 case M16_OPC_SWSP:
11063 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
11064 break;
11065 case M16_OPC_SW:
11066 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
11067 break;
11068 case M16_OPC_RRR:
11069 {
11070 int rz = xlat((ctx->opcode >> 2) & 0x7);
11071 int mips32_op;
11072
11073 switch (ctx->opcode & 0x3) {
11074 case RRR_ADDU:
11075 mips32_op = OPC_ADDU;
11076 break;
11077 case RRR_SUBU:
11078 mips32_op = OPC_SUBU;
11079 break;
11080 #if defined(TARGET_MIPS64)
11081 case RRR_DADDU:
11082 mips32_op = OPC_DADDU;
11083 check_mips_64(ctx);
11084 break;
11085 case RRR_DSUBU:
11086 mips32_op = OPC_DSUBU;
11087 check_mips_64(ctx);
11088 break;
11089 #endif
11090 default:
11091 generate_exception(ctx, EXCP_RI);
11092 goto done;
11093 }
11094
11095 gen_arith(ctx, mips32_op, rz, rx, ry);
11096 done:
11097 ;
11098 }
11099 break;
11100 case M16_OPC_RR:
11101 switch (op1) {
11102 case RR_JR:
11103 {
11104 int nd = (ctx->opcode >> 7) & 0x1;
11105 int link = (ctx->opcode >> 6) & 0x1;
11106 int ra = (ctx->opcode >> 5) & 0x1;
11107
11108 if (link) {
11109 op = nd ? OPC_JALRC : OPC_JALRS;
11110 } else {
11111 op = OPC_JR;
11112 }
11113
11114 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
11115 }
11116 break;
11117 case RR_SDBBP:
11118 /* XXX: not clear which exception should be raised
11119 * when in debug mode...
11120 */
11121 check_insn(ctx, ISA_MIPS32);
11122 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11123 generate_exception(ctx, EXCP_DBp);
11124 } else {
11125 generate_exception(ctx, EXCP_DBp);
11126 }
11127 break;
11128 case RR_SLT:
11129 gen_slt(ctx, OPC_SLT, 24, rx, ry);
11130 break;
11131 case RR_SLTU:
11132 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
11133 break;
11134 case RR_BREAK:
11135 generate_exception(ctx, EXCP_BREAK);
11136 break;
11137 case RR_SLLV:
11138 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
11139 break;
11140 case RR_SRLV:
11141 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
11142 break;
11143 case RR_SRAV:
11144 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
11145 break;
11146 #if defined (TARGET_MIPS64)
11147 case RR_DSRL:
11148 check_mips_64(ctx);
11149 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
11150 break;
11151 #endif
11152 case RR_CMP:
11153 gen_logic(ctx, OPC_XOR, 24, rx, ry);
11154 break;
11155 case RR_NEG:
11156 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
11157 break;
11158 case RR_AND:
11159 gen_logic(ctx, OPC_AND, rx, rx, ry);
11160 break;
11161 case RR_OR:
11162 gen_logic(ctx, OPC_OR, rx, rx, ry);
11163 break;
11164 case RR_XOR:
11165 gen_logic(ctx, OPC_XOR, rx, rx, ry);
11166 break;
11167 case RR_NOT:
11168 gen_logic(ctx, OPC_NOR, rx, ry, 0);
11169 break;
11170 case RR_MFHI:
11171 gen_HILO(ctx, OPC_MFHI, 0, rx);
11172 break;
11173 case RR_CNVT:
11174 switch (cnvt_op) {
11175 case RR_RY_CNVT_ZEB:
11176 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11177 break;
11178 case RR_RY_CNVT_ZEH:
11179 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11180 break;
11181 case RR_RY_CNVT_SEB:
11182 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11183 break;
11184 case RR_RY_CNVT_SEH:
11185 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11186 break;
11187 #if defined (TARGET_MIPS64)
11188 case RR_RY_CNVT_ZEW:
11189 check_mips_64(ctx);
11190 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
11191 break;
11192 case RR_RY_CNVT_SEW:
11193 check_mips_64(ctx);
11194 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
11195 break;
11196 #endif
11197 default:
11198 generate_exception(ctx, EXCP_RI);
11199 break;
11200 }
11201 break;
11202 case RR_MFLO:
11203 gen_HILO(ctx, OPC_MFLO, 0, rx);
11204 break;
11205 #if defined (TARGET_MIPS64)
11206 case RR_DSRA:
11207 check_mips_64(ctx);
11208 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
11209 break;
11210 case RR_DSLLV:
11211 check_mips_64(ctx);
11212 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
11213 break;
11214 case RR_DSRLV:
11215 check_mips_64(ctx);
11216 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
11217 break;
11218 case RR_DSRAV:
11219 check_mips_64(ctx);
11220 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
11221 break;
11222 #endif
11223 case RR_MULT:
11224 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
11225 break;
11226 case RR_MULTU:
11227 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
11228 break;
11229 case RR_DIV:
11230 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
11231 break;
11232 case RR_DIVU:
11233 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
11234 break;
11235 #if defined (TARGET_MIPS64)
11236 case RR_DMULT:
11237 check_mips_64(ctx);
11238 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
11239 break;
11240 case RR_DMULTU:
11241 check_mips_64(ctx);
11242 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
11243 break;
11244 case RR_DDIV:
11245 check_mips_64(ctx);
11246 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
11247 break;
11248 case RR_DDIVU:
11249 check_mips_64(ctx);
11250 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
11251 break;
11252 #endif
11253 default:
11254 generate_exception(ctx, EXCP_RI);
11255 break;
11256 }
11257 break;
11258 case M16_OPC_EXTEND:
11259 decode_extended_mips16_opc(env, ctx);
11260 n_bytes = 4;
11261 break;
11262 #if defined(TARGET_MIPS64)
11263 case M16_OPC_I64:
11264 funct = (ctx->opcode >> 8) & 0x7;
11265 decode_i64_mips16(ctx, ry, funct, offset, 0);
11266 break;
11267 #endif
11268 default:
11269 generate_exception(ctx, EXCP_RI);
11270 break;
11271 }
11272
11273 return n_bytes;
11274 }
11275
11276 /* microMIPS extension to MIPS32/MIPS64 */
11277
11278 /*
11279 * microMIPS32/microMIPS64 major opcodes
11280 *
11281 * 1. MIPS Architecture for Programmers Volume II-B:
11282 * The microMIPS32 Instruction Set (Revision 3.05)
11283 *
11284 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11285 *
11286 * 2. MIPS Architecture For Programmers Volume II-A:
11287 * The MIPS64 Instruction Set (Revision 3.51)
11288 */
11289
11290 enum {
11291 POOL32A = 0x00,
11292 POOL16A = 0x01,
11293 LBU16 = 0x02,
11294 MOVE16 = 0x03,
11295 ADDI32 = 0x04,
11296 LBU32 = 0x05,
11297 SB32 = 0x06,
11298 LB32 = 0x07,
11299
11300 POOL32B = 0x08,
11301 POOL16B = 0x09,
11302 LHU16 = 0x0a,
11303 ANDI16 = 0x0b,
11304 ADDIU32 = 0x0c,
11305 LHU32 = 0x0d,
11306 SH32 = 0x0e,
11307 LH32 = 0x0f,
11308
11309 POOL32I = 0x10,
11310 POOL16C = 0x11,
11311 LWSP16 = 0x12,
11312 POOL16D = 0x13,
11313 ORI32 = 0x14,
11314 POOL32F = 0x15,
11315 POOL32S = 0x16, /* MIPS64 */
11316 DADDIU32 = 0x17, /* MIPS64 */
11317
11318 /* 0x1f is reserved */
11319 POOL32C = 0x18,
11320 LWGP16 = 0x19,
11321 LW16 = 0x1a,
11322 POOL16E = 0x1b,
11323 XORI32 = 0x1c,
11324 JALS32 = 0x1d,
11325 ADDIUPC = 0x1e,
11326
11327 /* 0x20 is reserved */
11328 RES_20 = 0x20,
11329 POOL16F = 0x21,
11330 SB16 = 0x22,
11331 BEQZ16 = 0x23,
11332 SLTI32 = 0x24,
11333 BEQ32 = 0x25,
11334 SWC132 = 0x26,
11335 LWC132 = 0x27,
11336
11337 /* 0x28 and 0x29 are reserved */
11338 RES_28 = 0x28,
11339 RES_29 = 0x29,
11340 SH16 = 0x2a,
11341 BNEZ16 = 0x2b,
11342 SLTIU32 = 0x2c,
11343 BNE32 = 0x2d,
11344 SDC132 = 0x2e,
11345 LDC132 = 0x2f,
11346
11347 /* 0x30 and 0x31 are reserved */
11348 RES_30 = 0x30,
11349 RES_31 = 0x31,
11350 SWSP16 = 0x32,
11351 B16 = 0x33,
11352 ANDI32 = 0x34,
11353 J32 = 0x35,
11354 SD32 = 0x36, /* MIPS64 */
11355 LD32 = 0x37, /* MIPS64 */
11356
11357 /* 0x38 and 0x39 are reserved */
11358 RES_38 = 0x38,
11359 RES_39 = 0x39,
11360 SW16 = 0x3a,
11361 LI16 = 0x3b,
11362 JALX32 = 0x3c,
11363 JAL32 = 0x3d,
11364 SW32 = 0x3e,
11365 LW32 = 0x3f
11366 };
11367
11368 /* POOL32A encoding of minor opcode field */
11369
11370 enum {
11371 /* These opcodes are distinguished only by bits 9..6; those bits are
11372 * what are recorded below. */
11373 SLL32 = 0x0,
11374 SRL32 = 0x1,
11375 SRA = 0x2,
11376 ROTR = 0x3,
11377
11378 SLLV = 0x0,
11379 SRLV = 0x1,
11380 SRAV = 0x2,
11381 ROTRV = 0x3,
11382 ADD = 0x4,
11383 ADDU32 = 0x5,
11384 SUB = 0x6,
11385 SUBU32 = 0x7,
11386 MUL = 0x8,
11387 AND = 0x9,
11388 OR32 = 0xa,
11389 NOR = 0xb,
11390 XOR32 = 0xc,
11391 SLT = 0xd,
11392 SLTU = 0xe,
11393
11394 MOVN = 0x0,
11395 MOVZ = 0x1,
11396 LWXS = 0x4,
11397
11398 /* The following can be distinguished by their lower 6 bits. */
11399 INS = 0x0c,
11400 EXT = 0x2c,
11401 POOL32AXF = 0x3c
11402 };
11403
11404 /* POOL32AXF encoding of minor opcode field extension */
11405
11406 /*
11407 * 1. MIPS Architecture for Programmers Volume II-B:
11408 * The microMIPS32 Instruction Set (Revision 3.05)
11409 *
11410 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11411 *
11412 * 2. MIPS Architecture for Programmers VolumeIV-e:
11413 * The MIPS DSP Application-Specific Extension
11414 * to the microMIPS32 Architecture (Revision 2.34)
11415 *
11416 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11417 */
11418
11419 enum {
11420 /* bits 11..6 */
11421 TEQ = 0x00,
11422 TGE = 0x08,
11423 TGEU = 0x10,
11424 TLT = 0x20,
11425 TLTU = 0x28,
11426 TNE = 0x30,
11427
11428 MFC0 = 0x03,
11429 MTC0 = 0x0b,
11430
11431 /* begin of microMIPS32 DSP */
11432
11433 /* bits 13..12 for 0x01 */
11434 MFHI_ACC = 0x0,
11435 MFLO_ACC = 0x1,
11436 MTHI_ACC = 0x2,
11437 MTLO_ACC = 0x3,
11438
11439 /* bits 13..12 for 0x2a */
11440 MADD_ACC = 0x0,
11441 MADDU_ACC = 0x1,
11442 MSUB_ACC = 0x2,
11443 MSUBU_ACC = 0x3,
11444
11445 /* bits 13..12 for 0x32 */
11446 MULT_ACC = 0x0,
11447 MULTU_ACC = 0x1,
11448
11449 /* end of microMIPS32 DSP */
11450
11451 /* bits 15..12 for 0x2c */
11452 SEB = 0x2,
11453 SEH = 0x3,
11454 CLO = 0x4,
11455 CLZ = 0x5,
11456 RDHWR = 0x6,
11457 WSBH = 0x7,
11458 MULT = 0x8,
11459 MULTU = 0x9,
11460 DIV = 0xa,
11461 DIVU = 0xb,
11462 MADD = 0xc,
11463 MADDU = 0xd,
11464 MSUB = 0xe,
11465 MSUBU = 0xf,
11466
11467 /* bits 15..12 for 0x34 */
11468 MFC2 = 0x4,
11469 MTC2 = 0x5,
11470 MFHC2 = 0x8,
11471 MTHC2 = 0x9,
11472 CFC2 = 0xc,
11473 CTC2 = 0xd,
11474
11475 /* bits 15..12 for 0x3c */
11476 JALR = 0x0,
11477 JR = 0x0, /* alias */
11478 JALR_HB = 0x1,
11479 JALRS = 0x4,
11480 JALRS_HB = 0x5,
11481
11482 /* bits 15..12 for 0x05 */
11483 RDPGPR = 0xe,
11484 WRPGPR = 0xf,
11485
11486 /* bits 15..12 for 0x0d */
11487 TLBP = 0x0,
11488 TLBR = 0x1,
11489 TLBWI = 0x2,
11490 TLBWR = 0x3,
11491 WAIT = 0x9,
11492 IRET = 0xd,
11493 DERET = 0xe,
11494 ERET = 0xf,
11495
11496 /* bits 15..12 for 0x15 */
11497 DMT = 0x0,
11498 DVPE = 0x1,
11499 EMT = 0x2,
11500 EVPE = 0x3,
11501
11502 /* bits 15..12 for 0x1d */
11503 DI = 0x4,
11504 EI = 0x5,
11505
11506 /* bits 15..12 for 0x2d */
11507 SYNC = 0x6,
11508 SYSCALL = 0x8,
11509 SDBBP = 0xd,
11510
11511 /* bits 15..12 for 0x35 */
11512 MFHI32 = 0x0,
11513 MFLO32 = 0x1,
11514 MTHI32 = 0x2,
11515 MTLO32 = 0x3,
11516 };
11517
11518 /* POOL32B encoding of minor opcode field (bits 15..12) */
11519
11520 enum {
11521 LWC2 = 0x0,
11522 LWP = 0x1,
11523 LDP = 0x4,
11524 LWM32 = 0x5,
11525 CACHE = 0x6,
11526 LDM = 0x7,
11527 SWC2 = 0x8,
11528 SWP = 0x9,
11529 SDP = 0xc,
11530 SWM32 = 0xd,
11531 SDM = 0xf
11532 };
11533
11534 /* POOL32C encoding of minor opcode field (bits 15..12) */
11535
11536 enum {
11537 LWL = 0x0,
11538 SWL = 0x8,
11539 LWR = 0x1,
11540 SWR = 0x9,
11541 PREF = 0x2,
11542 /* 0xa is reserved */
11543 LL = 0x3,
11544 SC = 0xb,
11545 LDL = 0x4,
11546 SDL = 0xc,
11547 LDR = 0x5,
11548 SDR = 0xd,
11549 /* 0x6 is reserved */
11550 LWU = 0xe,
11551 LLD = 0x7,
11552 SCD = 0xf
11553 };
11554
11555 /* POOL32F encoding of minor opcode field (bits 5..0) */
11556
11557 enum {
11558 /* These are the bit 7..6 values */
11559 ADD_FMT = 0x0,
11560 MOVN_FMT = 0x0,
11561
11562 SUB_FMT = 0x1,
11563 MOVZ_FMT = 0x1,
11564
11565 MUL_FMT = 0x2,
11566
11567 DIV_FMT = 0x3,
11568
11569 /* These are the bit 8..6 values */
11570 RSQRT2_FMT = 0x0,
11571 MOVF_FMT = 0x0,
11572
11573 LWXC1 = 0x1,
11574 MOVT_FMT = 0x1,
11575
11576 PLL_PS = 0x2,
11577 SWXC1 = 0x2,
11578
11579 PLU_PS = 0x3,
11580 LDXC1 = 0x3,
11581
11582 PUL_PS = 0x4,
11583 SDXC1 = 0x4,
11584 RECIP2_FMT = 0x4,
11585
11586 PUU_PS = 0x5,
11587 LUXC1 = 0x5,
11588
11589 CVT_PS_S = 0x6,
11590 SUXC1 = 0x6,
11591 ADDR_PS = 0x6,
11592 PREFX = 0x6,
11593
11594 MULR_PS = 0x7,
11595
11596 MADD_S = 0x01,
11597 MADD_D = 0x09,
11598 MADD_PS = 0x11,
11599 ALNV_PS = 0x19,
11600 MSUB_S = 0x21,
11601 MSUB_D = 0x29,
11602 MSUB_PS = 0x31,
11603
11604 NMADD_S = 0x02,
11605 NMADD_D = 0x0a,
11606 NMADD_PS = 0x12,
11607 NMSUB_S = 0x22,
11608 NMSUB_D = 0x2a,
11609 NMSUB_PS = 0x32,
11610
11611 POOL32FXF = 0x3b,
11612
11613 CABS_COND_FMT = 0x1c, /* MIPS3D */
11614 C_COND_FMT = 0x3c
11615 };
11616
11617 /* POOL32Fxf encoding of minor opcode extension field */
11618
11619 enum {
11620 CVT_L = 0x04,
11621 RSQRT_FMT = 0x08,
11622 FLOOR_L = 0x0c,
11623 CVT_PW_PS = 0x1c,
11624 CVT_W = 0x24,
11625 SQRT_FMT = 0x28,
11626 FLOOR_W = 0x2c,
11627 CVT_PS_PW = 0x3c,
11628 CFC1 = 0x40,
11629 RECIP_FMT = 0x48,
11630 CEIL_L = 0x4c,
11631 CTC1 = 0x60,
11632 CEIL_W = 0x6c,
11633 MFC1 = 0x80,
11634 CVT_S_PL = 0x84,
11635 TRUNC_L = 0x8c,
11636 MTC1 = 0xa0,
11637 CVT_S_PU = 0xa4,
11638 TRUNC_W = 0xac,
11639 MFHC1 = 0xc0,
11640 ROUND_L = 0xcc,
11641 MTHC1 = 0xe0,
11642 ROUND_W = 0xec,
11643
11644 MOV_FMT = 0x01,
11645 MOVF = 0x05,
11646 ABS_FMT = 0x0d,
11647 RSQRT1_FMT = 0x1d,
11648 MOVT = 0x25,
11649 NEG_FMT = 0x2d,
11650 CVT_D = 0x4d,
11651 RECIP1_FMT = 0x5d,
11652 CVT_S = 0x6d
11653 };
11654
11655 /* POOL32I encoding of minor opcode field (bits 25..21) */
11656
11657 enum {
11658 BLTZ = 0x00,
11659 BLTZAL = 0x01,
11660 BGEZ = 0x02,
11661 BGEZAL = 0x03,
11662 BLEZ = 0x04,
11663 BNEZC = 0x05,
11664 BGTZ = 0x06,
11665 BEQZC = 0x07,
11666 TLTI = 0x08,
11667 TGEI = 0x09,
11668 TLTIU = 0x0a,
11669 TGEIU = 0x0b,
11670 TNEI = 0x0c,
11671 LUI = 0x0d,
11672 TEQI = 0x0e,
11673 SYNCI = 0x10,
11674 BLTZALS = 0x11,
11675 BGEZALS = 0x13,
11676 BC2F = 0x14,
11677 BC2T = 0x15,
11678 BPOSGE64 = 0x1a,
11679 BPOSGE32 = 0x1b,
11680 /* These overlap and are distinguished by bit16 of the instruction */
11681 BC1F = 0x1c,
11682 BC1T = 0x1d,
11683 BC1ANY2F = 0x1c,
11684 BC1ANY2T = 0x1d,
11685 BC1ANY4F = 0x1e,
11686 BC1ANY4T = 0x1f
11687 };
11688
11689 /* POOL16A encoding of minor opcode field */
11690
11691 enum {
11692 ADDU16 = 0x0,
11693 SUBU16 = 0x1
11694 };
11695
11696 /* POOL16B encoding of minor opcode field */
11697
11698 enum {
11699 SLL16 = 0x0,
11700 SRL16 = 0x1
11701 };
11702
11703 /* POOL16C encoding of minor opcode field */
11704
11705 enum {
11706 NOT16 = 0x00,
11707 XOR16 = 0x04,
11708 AND16 = 0x08,
11709 OR16 = 0x0c,
11710 LWM16 = 0x10,
11711 SWM16 = 0x14,
11712 JR16 = 0x18,
11713 JRC16 = 0x1a,
11714 JALR16 = 0x1c,
11715 JALR16S = 0x1e,
11716 MFHI16 = 0x20,
11717 MFLO16 = 0x24,
11718 BREAK16 = 0x28,
11719 SDBBP16 = 0x2c,
11720 JRADDIUSP = 0x30
11721 };
11722
11723 /* POOL16D encoding of minor opcode field */
11724
11725 enum {
11726 ADDIUS5 = 0x0,
11727 ADDIUSP = 0x1
11728 };
11729
11730 /* POOL16E encoding of minor opcode field */
11731
11732 enum {
11733 ADDIUR2 = 0x0,
11734 ADDIUR1SP = 0x1
11735 };
11736
11737 static int mmreg (int r)
11738 {
11739 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11740
11741 return map[r];
11742 }
11743
11744 /* Used for 16-bit store instructions. */
11745 static int mmreg2 (int r)
11746 {
11747 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
11748
11749 return map[r];
11750 }
11751
11752 #define uMIPS_RD(op) ((op >> 7) & 0x7)
11753 #define uMIPS_RS(op) ((op >> 4) & 0x7)
11754 #define uMIPS_RS2(op) uMIPS_RS(op)
11755 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
11756 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
11757 #define uMIPS_RS5(op) (op & 0x1f)
11758
11759 /* Signed immediate */
11760 #define SIMM(op, start, width) \
11761 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
11762 << (32-width)) \
11763 >> (32-width))
11764 /* Zero-extended immediate */
11765 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
11766
11767 static void gen_addiur1sp(DisasContext *ctx)
11768 {
11769 int rd = mmreg(uMIPS_RD(ctx->opcode));
11770
11771 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
11772 }
11773
11774 static void gen_addiur2(DisasContext *ctx)
11775 {
11776 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
11777 int rd = mmreg(uMIPS_RD(ctx->opcode));
11778 int rs = mmreg(uMIPS_RS(ctx->opcode));
11779
11780 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
11781 }
11782
11783 static void gen_addiusp(DisasContext *ctx)
11784 {
11785 int encoded = ZIMM(ctx->opcode, 1, 9);
11786 int decoded;
11787
11788 if (encoded <= 1) {
11789 decoded = 256 + encoded;
11790 } else if (encoded <= 255) {
11791 decoded = encoded;
11792 } else if (encoded <= 509) {
11793 decoded = encoded - 512;
11794 } else {
11795 decoded = encoded - 768;
11796 }
11797
11798 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
11799 }
11800
11801 static void gen_addius5(DisasContext *ctx)
11802 {
11803 int imm = SIMM(ctx->opcode, 1, 4);
11804 int rd = (ctx->opcode >> 5) & 0x1f;
11805
11806 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
11807 }
11808
11809 static void gen_andi16(DisasContext *ctx)
11810 {
11811 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
11812 31, 32, 63, 64, 255, 32768, 65535 };
11813 int rd = mmreg(uMIPS_RD(ctx->opcode));
11814 int rs = mmreg(uMIPS_RS(ctx->opcode));
11815 int encoded = ZIMM(ctx->opcode, 0, 4);
11816
11817 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
11818 }
11819
11820 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
11821 int base, int16_t offset)
11822 {
11823 const char *opn = "ldst_multiple";
11824 TCGv t0, t1;
11825 TCGv_i32 t2;
11826
11827 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11828 generate_exception(ctx, EXCP_RI);
11829 return;
11830 }
11831
11832 t0 = tcg_temp_new();
11833
11834 gen_base_offset_addr(ctx, t0, base, offset);
11835
11836 t1 = tcg_const_tl(reglist);
11837 t2 = tcg_const_i32(ctx->mem_idx);
11838
11839 save_cpu_state(ctx, 1);
11840 switch (opc) {
11841 case LWM32:
11842 gen_helper_lwm(cpu_env, t0, t1, t2);
11843 opn = "lwm";
11844 break;
11845 case SWM32:
11846 gen_helper_swm(cpu_env, t0, t1, t2);
11847 opn = "swm";
11848 break;
11849 #ifdef TARGET_MIPS64
11850 case LDM:
11851 gen_helper_ldm(cpu_env, t0, t1, t2);
11852 opn = "ldm";
11853 break;
11854 case SDM:
11855 gen_helper_sdm(cpu_env, t0, t1, t2);
11856 opn = "sdm";
11857 break;
11858 #endif
11859 }
11860 (void)opn;
11861 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
11862 tcg_temp_free(t0);
11863 tcg_temp_free(t1);
11864 tcg_temp_free_i32(t2);
11865 }
11866
11867
11868 static void gen_pool16c_insn(DisasContext *ctx)
11869 {
11870 int rd = mmreg((ctx->opcode >> 3) & 0x7);
11871 int rs = mmreg(ctx->opcode & 0x7);
11872 int opc;
11873
11874 switch (((ctx->opcode) >> 4) & 0x3f) {
11875 case NOT16 + 0:
11876 case NOT16 + 1:
11877 case NOT16 + 2:
11878 case NOT16 + 3:
11879 gen_logic(ctx, OPC_NOR, rd, rs, 0);
11880 break;
11881 case XOR16 + 0:
11882 case XOR16 + 1:
11883 case XOR16 + 2:
11884 case XOR16 + 3:
11885 gen_logic(ctx, OPC_XOR, rd, rd, rs);
11886 break;
11887 case AND16 + 0:
11888 case AND16 + 1:
11889 case AND16 + 2:
11890 case AND16 + 3:
11891 gen_logic(ctx, OPC_AND, rd, rd, rs);
11892 break;
11893 case OR16 + 0:
11894 case OR16 + 1:
11895 case OR16 + 2:
11896 case OR16 + 3:
11897 gen_logic(ctx, OPC_OR, rd, rd, rs);
11898 break;
11899 case LWM16 + 0:
11900 case LWM16 + 1:
11901 case LWM16 + 2:
11902 case LWM16 + 3:
11903 {
11904 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
11905 int offset = ZIMM(ctx->opcode, 0, 4);
11906
11907 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
11908 29, offset << 2);
11909 }
11910 break;
11911 case SWM16 + 0:
11912 case SWM16 + 1:
11913 case SWM16 + 2:
11914 case SWM16 + 3:
11915 {
11916 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
11917 int offset = ZIMM(ctx->opcode, 0, 4);
11918
11919 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
11920 29, offset << 2);
11921 }
11922 break;
11923 case JR16 + 0:
11924 case JR16 + 1:
11925 {
11926 int reg = ctx->opcode & 0x1f;
11927
11928 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
11929 }
11930 break;
11931 case JRC16 + 0:
11932 case JRC16 + 1:
11933 {
11934 int reg = ctx->opcode & 0x1f;
11935
11936 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
11937 /* Let normal delay slot handling in our caller take us
11938 to the branch target. */
11939 }
11940 break;
11941 case JALR16 + 0:
11942 case JALR16 + 1:
11943 opc = OPC_JALR;
11944 goto do_jalr;
11945 case JALR16S + 0:
11946 case JALR16S + 1:
11947 opc = OPC_JALRS;
11948 do_jalr:
11949 {
11950 int reg = ctx->opcode & 0x1f;
11951
11952 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
11953 }
11954 break;
11955 case MFHI16 + 0:
11956 case MFHI16 + 1:
11957 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
11958 break;
11959 case MFLO16 + 0:
11960 case MFLO16 + 1:
11961 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
11962 break;
11963 case BREAK16:
11964 generate_exception(ctx, EXCP_BREAK);
11965 break;
11966 case SDBBP16:
11967 /* XXX: not clear which exception should be raised
11968 * when in debug mode...
11969 */
11970 check_insn(ctx, ISA_MIPS32);
11971 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11972 generate_exception(ctx, EXCP_DBp);
11973 } else {
11974 generate_exception(ctx, EXCP_DBp);
11975 }
11976 break;
11977 case JRADDIUSP + 0:
11978 case JRADDIUSP + 1:
11979 {
11980 int imm = ZIMM(ctx->opcode, 0, 5);
11981
11982 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
11983 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
11984 /* Let normal delay slot handling in our caller take us
11985 to the branch target. */
11986 }
11987 break;
11988 default:
11989 generate_exception(ctx, EXCP_RI);
11990 break;
11991 }
11992 }
11993
11994 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
11995 {
11996 TCGv t0 = tcg_temp_new();
11997 TCGv t1 = tcg_temp_new();
11998
11999 gen_load_gpr(t0, base);
12000
12001 if (index != 0) {
12002 gen_load_gpr(t1, index);
12003 tcg_gen_shli_tl(t1, t1, 2);
12004 gen_op_addr_add(ctx, t0, t1, t0);
12005 }
12006
12007 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12008 gen_store_gpr(t1, rd);
12009
12010 tcg_temp_free(t0);
12011 tcg_temp_free(t1);
12012 }
12013
12014 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
12015 int base, int16_t offset)
12016 {
12017 const char *opn = "ldst_pair";
12018 TCGv t0, t1;
12019
12020 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
12021 generate_exception(ctx, EXCP_RI);
12022 return;
12023 }
12024
12025 t0 = tcg_temp_new();
12026 t1 = tcg_temp_new();
12027
12028 gen_base_offset_addr(ctx, t0, base, offset);
12029
12030 switch (opc) {
12031 case LWP:
12032 if (rd == base) {
12033 generate_exception(ctx, EXCP_RI);
12034 return;
12035 }
12036 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12037 gen_store_gpr(t1, rd);
12038 tcg_gen_movi_tl(t1, 4);
12039 gen_op_addr_add(ctx, t0, t0, t1);
12040 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12041 gen_store_gpr(t1, rd+1);
12042 opn = "lwp";
12043 break;
12044 case SWP:
12045 gen_load_gpr(t1, rd);
12046 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12047 tcg_gen_movi_tl(t1, 4);
12048 gen_op_addr_add(ctx, t0, t0, t1);
12049 gen_load_gpr(t1, rd+1);
12050 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12051 opn = "swp";
12052 break;
12053 #ifdef TARGET_MIPS64
12054 case LDP:
12055 if (rd == base) {
12056 generate_exception(ctx, EXCP_RI);
12057 return;
12058 }
12059 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12060 gen_store_gpr(t1, rd);
12061 tcg_gen_movi_tl(t1, 8);
12062 gen_op_addr_add(ctx, t0, t0, t1);
12063 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12064 gen_store_gpr(t1, rd+1);
12065 opn = "ldp";
12066 break;
12067 case SDP:
12068 gen_load_gpr(t1, rd);
12069 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12070 tcg_gen_movi_tl(t1, 8);
12071 gen_op_addr_add(ctx, t0, t0, t1);
12072 gen_load_gpr(t1, rd+1);
12073 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
12074 opn = "sdp";
12075 break;
12076 #endif
12077 }
12078 (void)opn; /* avoid a compiler warning */
12079 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
12080 tcg_temp_free(t0);
12081 tcg_temp_free(t1);
12082 }
12083
12084 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
12085 {
12086 int extension = (ctx->opcode >> 6) & 0x3f;
12087 int minor = (ctx->opcode >> 12) & 0xf;
12088 uint32_t mips32_op;
12089
12090 switch (extension) {
12091 case TEQ:
12092 mips32_op = OPC_TEQ;
12093 goto do_trap;
12094 case TGE:
12095 mips32_op = OPC_TGE;
12096 goto do_trap;
12097 case TGEU:
12098 mips32_op = OPC_TGEU;
12099 goto do_trap;
12100 case TLT:
12101 mips32_op = OPC_TLT;
12102 goto do_trap;
12103 case TLTU:
12104 mips32_op = OPC_TLTU;
12105 goto do_trap;
12106 case TNE:
12107 mips32_op = OPC_TNE;
12108 do_trap:
12109 gen_trap(ctx, mips32_op, rs, rt, -1);
12110 break;
12111 #ifndef CONFIG_USER_ONLY
12112 case MFC0:
12113 case MFC0 + 32:
12114 check_cp0_enabled(ctx);
12115 if (rt == 0) {
12116 /* Treat as NOP. */
12117 break;
12118 }
12119 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
12120 break;
12121 case MTC0:
12122 case MTC0 + 32:
12123 check_cp0_enabled(ctx);
12124 {
12125 TCGv t0 = tcg_temp_new();
12126
12127 gen_load_gpr(t0, rt);
12128 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
12129 tcg_temp_free(t0);
12130 }
12131 break;
12132 #endif
12133 case 0x2a:
12134 switch (minor & 3) {
12135 case MADD_ACC:
12136 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
12137 break;
12138 case MADDU_ACC:
12139 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
12140 break;
12141 case MSUB_ACC:
12142 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
12143 break;
12144 case MSUBU_ACC:
12145 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
12146 break;
12147 default:
12148 goto pool32axf_invalid;
12149 }
12150 break;
12151 case 0x32:
12152 switch (minor & 3) {
12153 case MULT_ACC:
12154 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
12155 break;
12156 case MULTU_ACC:
12157 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
12158 break;
12159 default:
12160 goto pool32axf_invalid;
12161 }
12162 break;
12163 case 0x2c:
12164 switch (minor) {
12165 case SEB:
12166 gen_bshfl(ctx, OPC_SEB, rs, rt);
12167 break;
12168 case SEH:
12169 gen_bshfl(ctx, OPC_SEH, rs, rt);
12170 break;
12171 case CLO:
12172 mips32_op = OPC_CLO;
12173 goto do_cl;
12174 case CLZ:
12175 mips32_op = OPC_CLZ;
12176 do_cl:
12177 check_insn(ctx, ISA_MIPS32);
12178 gen_cl(ctx, mips32_op, rt, rs);
12179 break;
12180 case RDHWR:
12181 gen_rdhwr(ctx, rt, rs);
12182 break;
12183 case WSBH:
12184 gen_bshfl(ctx, OPC_WSBH, rs, rt);
12185 break;
12186 case MULT:
12187 mips32_op = OPC_MULT;
12188 goto do_mul;
12189 case MULTU:
12190 mips32_op = OPC_MULTU;
12191 goto do_mul;
12192 case DIV:
12193 mips32_op = OPC_DIV;
12194 goto do_div;
12195 case DIVU:
12196 mips32_op = OPC_DIVU;
12197 goto do_div;
12198 do_div:
12199 check_insn(ctx, ISA_MIPS32);
12200 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12201 break;
12202 case MADD:
12203 mips32_op = OPC_MADD;
12204 goto do_mul;
12205 case MADDU:
12206 mips32_op = OPC_MADDU;
12207 goto do_mul;
12208 case MSUB:
12209 mips32_op = OPC_MSUB;
12210 goto do_mul;
12211 case MSUBU:
12212 mips32_op = OPC_MSUBU;
12213 do_mul:
12214 check_insn(ctx, ISA_MIPS32);
12215 gen_muldiv(ctx, mips32_op, 0, rs, rt);
12216 break;
12217 default:
12218 goto pool32axf_invalid;
12219 }
12220 break;
12221 case 0x34:
12222 switch (minor) {
12223 case MFC2:
12224 case MTC2:
12225 case MFHC2:
12226 case MTHC2:
12227 case CFC2:
12228 case CTC2:
12229 generate_exception_err(ctx, EXCP_CpU, 2);
12230 break;
12231 default:
12232 goto pool32axf_invalid;
12233 }
12234 break;
12235 case 0x3c:
12236 switch (minor) {
12237 case JALR:
12238 case JALR_HB:
12239 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
12240 break;
12241 case JALRS:
12242 case JALRS_HB:
12243 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
12244 break;
12245 default:
12246 goto pool32axf_invalid;
12247 }
12248 break;
12249 case 0x05:
12250 switch (minor) {
12251 case RDPGPR:
12252 check_cp0_enabled(ctx);
12253 check_insn(ctx, ISA_MIPS32R2);
12254 gen_load_srsgpr(rt, rs);
12255 break;
12256 case WRPGPR:
12257 check_cp0_enabled(ctx);
12258 check_insn(ctx, ISA_MIPS32R2);
12259 gen_store_srsgpr(rt, rs);
12260 break;
12261 default:
12262 goto pool32axf_invalid;
12263 }
12264 break;
12265 #ifndef CONFIG_USER_ONLY
12266 case 0x0d:
12267 switch (minor) {
12268 case TLBP:
12269 mips32_op = OPC_TLBP;
12270 goto do_cp0;
12271 case TLBR:
12272 mips32_op = OPC_TLBR;
12273 goto do_cp0;
12274 case TLBWI:
12275 mips32_op = OPC_TLBWI;
12276 goto do_cp0;
12277 case TLBWR:
12278 mips32_op = OPC_TLBWR;
12279 goto do_cp0;
12280 case WAIT:
12281 mips32_op = OPC_WAIT;
12282 goto do_cp0;
12283 case DERET:
12284 mips32_op = OPC_DERET;
12285 goto do_cp0;
12286 case ERET:
12287 mips32_op = OPC_ERET;
12288 do_cp0:
12289 gen_cp0(env, ctx, mips32_op, rt, rs);
12290 break;
12291 default:
12292 goto pool32axf_invalid;
12293 }
12294 break;
12295 case 0x1d:
12296 switch (minor) {
12297 case DI:
12298 check_cp0_enabled(ctx);
12299 {
12300 TCGv t0 = tcg_temp_new();
12301
12302 save_cpu_state(ctx, 1);
12303 gen_helper_di(t0, cpu_env);
12304 gen_store_gpr(t0, rs);
12305 /* Stop translation as we may have switched the execution mode */
12306 ctx->bstate = BS_STOP;
12307 tcg_temp_free(t0);
12308 }
12309 break;
12310 case EI:
12311 check_cp0_enabled(ctx);
12312 {
12313 TCGv t0 = tcg_temp_new();
12314
12315 save_cpu_state(ctx, 1);
12316 gen_helper_ei(t0, cpu_env);
12317 gen_store_gpr(t0, rs);
12318 /* Stop translation as we may have switched the execution mode */
12319 ctx->bstate = BS_STOP;
12320 tcg_temp_free(t0);
12321 }
12322 break;
12323 default:
12324 goto pool32axf_invalid;
12325 }
12326 break;
12327 #endif
12328 case 0x2d:
12329 switch (minor) {
12330 case SYNC:
12331 /* NOP */
12332 break;
12333 case SYSCALL:
12334 generate_exception(ctx, EXCP_SYSCALL);
12335 ctx->bstate = BS_STOP;
12336 break;
12337 case SDBBP:
12338 check_insn(ctx, ISA_MIPS32);
12339 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12340 generate_exception(ctx, EXCP_DBp);
12341 } else {
12342 generate_exception(ctx, EXCP_DBp);
12343 }
12344 break;
12345 default:
12346 goto pool32axf_invalid;
12347 }
12348 break;
12349 case 0x01:
12350 switch (minor & 3) {
12351 case MFHI_ACC:
12352 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
12353 break;
12354 case MFLO_ACC:
12355 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
12356 break;
12357 case MTHI_ACC:
12358 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
12359 break;
12360 case MTLO_ACC:
12361 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
12362 break;
12363 default:
12364 goto pool32axf_invalid;
12365 }
12366 break;
12367 case 0x35:
12368 switch (minor) {
12369 case MFHI32:
12370 gen_HILO(ctx, OPC_MFHI, 0, rs);
12371 break;
12372 case MFLO32:
12373 gen_HILO(ctx, OPC_MFLO, 0, rs);
12374 break;
12375 case MTHI32:
12376 gen_HILO(ctx, OPC_MTHI, 0, rs);
12377 break;
12378 case MTLO32:
12379 gen_HILO(ctx, OPC_MTLO, 0, rs);
12380 break;
12381 default:
12382 goto pool32axf_invalid;
12383 }
12384 break;
12385 default:
12386 pool32axf_invalid:
12387 MIPS_INVAL("pool32axf");
12388 generate_exception(ctx, EXCP_RI);
12389 break;
12390 }
12391 }
12392
12393 /* Values for microMIPS fmt field. Variable-width, depending on which
12394 formats the instruction supports. */
12395
12396 enum {
12397 FMT_SD_S = 0,
12398 FMT_SD_D = 1,
12399
12400 FMT_SDPS_S = 0,
12401 FMT_SDPS_D = 1,
12402 FMT_SDPS_PS = 2,
12403
12404 FMT_SWL_S = 0,
12405 FMT_SWL_W = 1,
12406 FMT_SWL_L = 2,
12407
12408 FMT_DWL_D = 0,
12409 FMT_DWL_W = 1,
12410 FMT_DWL_L = 2
12411 };
12412
12413 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
12414 {
12415 int extension = (ctx->opcode >> 6) & 0x3ff;
12416 uint32_t mips32_op;
12417
12418 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12419 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12420 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12421
12422 switch (extension) {
12423 case FLOAT_1BIT_FMT(CFC1, 0):
12424 mips32_op = OPC_CFC1;
12425 goto do_cp1;
12426 case FLOAT_1BIT_FMT(CTC1, 0):
12427 mips32_op = OPC_CTC1;
12428 goto do_cp1;
12429 case FLOAT_1BIT_FMT(MFC1, 0):
12430 mips32_op = OPC_MFC1;
12431 goto do_cp1;
12432 case FLOAT_1BIT_FMT(MTC1, 0):
12433 mips32_op = OPC_MTC1;
12434 goto do_cp1;
12435 case FLOAT_1BIT_FMT(MFHC1, 0):
12436 mips32_op = OPC_MFHC1;
12437 goto do_cp1;
12438 case FLOAT_1BIT_FMT(MTHC1, 0):
12439 mips32_op = OPC_MTHC1;
12440 do_cp1:
12441 gen_cp1(ctx, mips32_op, rt, rs);
12442 break;
12443
12444 /* Reciprocal square root */
12445 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
12446 mips32_op = OPC_RSQRT_S;
12447 goto do_unaryfp;
12448 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
12449 mips32_op = OPC_RSQRT_D;
12450 goto do_unaryfp;
12451
12452 /* Square root */
12453 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
12454 mips32_op = OPC_SQRT_S;
12455 goto do_unaryfp;
12456 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
12457 mips32_op = OPC_SQRT_D;
12458 goto do_unaryfp;
12459
12460 /* Reciprocal */
12461 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
12462 mips32_op = OPC_RECIP_S;
12463 goto do_unaryfp;
12464 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
12465 mips32_op = OPC_RECIP_D;
12466 goto do_unaryfp;
12467
12468 /* Floor */
12469 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
12470 mips32_op = OPC_FLOOR_L_S;
12471 goto do_unaryfp;
12472 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
12473 mips32_op = OPC_FLOOR_L_D;
12474 goto do_unaryfp;
12475 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
12476 mips32_op = OPC_FLOOR_W_S;
12477 goto do_unaryfp;
12478 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
12479 mips32_op = OPC_FLOOR_W_D;
12480 goto do_unaryfp;
12481
12482 /* Ceiling */
12483 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
12484 mips32_op = OPC_CEIL_L_S;
12485 goto do_unaryfp;
12486 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
12487 mips32_op = OPC_CEIL_L_D;
12488 goto do_unaryfp;
12489 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
12490 mips32_op = OPC_CEIL_W_S;
12491 goto do_unaryfp;
12492 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
12493 mips32_op = OPC_CEIL_W_D;
12494 goto do_unaryfp;
12495
12496 /* Truncation */
12497 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
12498 mips32_op = OPC_TRUNC_L_S;
12499 goto do_unaryfp;
12500 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
12501 mips32_op = OPC_TRUNC_L_D;
12502 goto do_unaryfp;
12503 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
12504 mips32_op = OPC_TRUNC_W_S;
12505 goto do_unaryfp;
12506 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
12507 mips32_op = OPC_TRUNC_W_D;
12508 goto do_unaryfp;
12509
12510 /* Round */
12511 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
12512 mips32_op = OPC_ROUND_L_S;
12513 goto do_unaryfp;
12514 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
12515 mips32_op = OPC_ROUND_L_D;
12516 goto do_unaryfp;
12517 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
12518 mips32_op = OPC_ROUND_W_S;
12519 goto do_unaryfp;
12520 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
12521 mips32_op = OPC_ROUND_W_D;
12522 goto do_unaryfp;
12523
12524 /* Integer to floating-point conversion */
12525 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
12526 mips32_op = OPC_CVT_L_S;
12527 goto do_unaryfp;
12528 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
12529 mips32_op = OPC_CVT_L_D;
12530 goto do_unaryfp;
12531 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
12532 mips32_op = OPC_CVT_W_S;
12533 goto do_unaryfp;
12534 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
12535 mips32_op = OPC_CVT_W_D;
12536 goto do_unaryfp;
12537
12538 /* Paired-foo conversions */
12539 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
12540 mips32_op = OPC_CVT_S_PL;
12541 goto do_unaryfp;
12542 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
12543 mips32_op = OPC_CVT_S_PU;
12544 goto do_unaryfp;
12545 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
12546 mips32_op = OPC_CVT_PW_PS;
12547 goto do_unaryfp;
12548 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
12549 mips32_op = OPC_CVT_PS_PW;
12550 goto do_unaryfp;
12551
12552 /* Floating-point moves */
12553 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
12554 mips32_op = OPC_MOV_S;
12555 goto do_unaryfp;
12556 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
12557 mips32_op = OPC_MOV_D;
12558 goto do_unaryfp;
12559 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
12560 mips32_op = OPC_MOV_PS;
12561 goto do_unaryfp;
12562
12563 /* Absolute value */
12564 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
12565 mips32_op = OPC_ABS_S;
12566 goto do_unaryfp;
12567 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
12568 mips32_op = OPC_ABS_D;
12569 goto do_unaryfp;
12570 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
12571 mips32_op = OPC_ABS_PS;
12572 goto do_unaryfp;
12573
12574 /* Negation */
12575 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
12576 mips32_op = OPC_NEG_S;
12577 goto do_unaryfp;
12578 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
12579 mips32_op = OPC_NEG_D;
12580 goto do_unaryfp;
12581 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
12582 mips32_op = OPC_NEG_PS;
12583 goto do_unaryfp;
12584
12585 /* Reciprocal square root step */
12586 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
12587 mips32_op = OPC_RSQRT1_S;
12588 goto do_unaryfp;
12589 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
12590 mips32_op = OPC_RSQRT1_D;
12591 goto do_unaryfp;
12592 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
12593 mips32_op = OPC_RSQRT1_PS;
12594 goto do_unaryfp;
12595
12596 /* Reciprocal step */
12597 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
12598 mips32_op = OPC_RECIP1_S;
12599 goto do_unaryfp;
12600 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
12601 mips32_op = OPC_RECIP1_S;
12602 goto do_unaryfp;
12603 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
12604 mips32_op = OPC_RECIP1_PS;
12605 goto do_unaryfp;
12606
12607 /* Conversions from double */
12608 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
12609 mips32_op = OPC_CVT_D_S;
12610 goto do_unaryfp;
12611 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
12612 mips32_op = OPC_CVT_D_W;
12613 goto do_unaryfp;
12614 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
12615 mips32_op = OPC_CVT_D_L;
12616 goto do_unaryfp;
12617
12618 /* Conversions from single */
12619 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
12620 mips32_op = OPC_CVT_S_D;
12621 goto do_unaryfp;
12622 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
12623 mips32_op = OPC_CVT_S_W;
12624 goto do_unaryfp;
12625 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
12626 mips32_op = OPC_CVT_S_L;
12627 do_unaryfp:
12628 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
12629 break;
12630
12631 /* Conditional moves on floating-point codes */
12632 case COND_FLOAT_MOV(MOVT, 0):
12633 case COND_FLOAT_MOV(MOVT, 1):
12634 case COND_FLOAT_MOV(MOVT, 2):
12635 case COND_FLOAT_MOV(MOVT, 3):
12636 case COND_FLOAT_MOV(MOVT, 4):
12637 case COND_FLOAT_MOV(MOVT, 5):
12638 case COND_FLOAT_MOV(MOVT, 6):
12639 case COND_FLOAT_MOV(MOVT, 7):
12640 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
12641 break;
12642 case COND_FLOAT_MOV(MOVF, 0):
12643 case COND_FLOAT_MOV(MOVF, 1):
12644 case COND_FLOAT_MOV(MOVF, 2):
12645 case COND_FLOAT_MOV(MOVF, 3):
12646 case COND_FLOAT_MOV(MOVF, 4):
12647 case COND_FLOAT_MOV(MOVF, 5):
12648 case COND_FLOAT_MOV(MOVF, 6):
12649 case COND_FLOAT_MOV(MOVF, 7):
12650 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
12651 break;
12652 default:
12653 MIPS_INVAL("pool32fxf");
12654 generate_exception(ctx, EXCP_RI);
12655 break;
12656 }
12657 }
12658
12659 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
12660 uint16_t insn_hw1)
12661 {
12662 int32_t offset;
12663 uint16_t insn;
12664 int rt, rs, rd, rr;
12665 int16_t imm;
12666 uint32_t op, minor, mips32_op;
12667 uint32_t cond, fmt, cc;
12668
12669 insn = cpu_lduw_code(env, ctx->pc + 2);
12670 ctx->opcode = (ctx->opcode << 16) | insn;
12671
12672 rt = (ctx->opcode >> 21) & 0x1f;
12673 rs = (ctx->opcode >> 16) & 0x1f;
12674 rd = (ctx->opcode >> 11) & 0x1f;
12675 rr = (ctx->opcode >> 6) & 0x1f;
12676 imm = (int16_t) ctx->opcode;
12677
12678 op = (ctx->opcode >> 26) & 0x3f;
12679 switch (op) {
12680 case POOL32A:
12681 minor = ctx->opcode & 0x3f;
12682 switch (minor) {
12683 case 0x00:
12684 minor = (ctx->opcode >> 6) & 0xf;
12685 switch (minor) {
12686 case SLL32:
12687 mips32_op = OPC_SLL;
12688 goto do_shifti;
12689 case SRA:
12690 mips32_op = OPC_SRA;
12691 goto do_shifti;
12692 case SRL32:
12693 mips32_op = OPC_SRL;
12694 goto do_shifti;
12695 case ROTR:
12696 mips32_op = OPC_ROTR;
12697 do_shifti:
12698 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
12699 break;
12700 default:
12701 goto pool32a_invalid;
12702 }
12703 break;
12704 case 0x10:
12705 minor = (ctx->opcode >> 6) & 0xf;
12706 switch (minor) {
12707 /* Arithmetic */
12708 case ADD:
12709 mips32_op = OPC_ADD;
12710 goto do_arith;
12711 case ADDU32:
12712 mips32_op = OPC_ADDU;
12713 goto do_arith;
12714 case SUB:
12715 mips32_op = OPC_SUB;
12716 goto do_arith;
12717 case SUBU32:
12718 mips32_op = OPC_SUBU;
12719 goto do_arith;
12720 case MUL:
12721 mips32_op = OPC_MUL;
12722 do_arith:
12723 gen_arith(ctx, mips32_op, rd, rs, rt);
12724 break;
12725 /* Shifts */
12726 case SLLV:
12727 mips32_op = OPC_SLLV;
12728 goto do_shift;
12729 case SRLV:
12730 mips32_op = OPC_SRLV;
12731 goto do_shift;
12732 case SRAV:
12733 mips32_op = OPC_SRAV;
12734 goto do_shift;
12735 case ROTRV:
12736 mips32_op = OPC_ROTRV;
12737 do_shift:
12738 gen_shift(ctx, mips32_op, rd, rs, rt);
12739 break;
12740 /* Logical operations */
12741 case AND:
12742 mips32_op = OPC_AND;
12743 goto do_logic;
12744 case OR32:
12745 mips32_op = OPC_OR;
12746 goto do_logic;
12747 case NOR:
12748 mips32_op = OPC_NOR;
12749 goto do_logic;
12750 case XOR32:
12751 mips32_op = OPC_XOR;
12752 do_logic:
12753 gen_logic(ctx, mips32_op, rd, rs, rt);
12754 break;
12755 /* Set less than */
12756 case SLT:
12757 mips32_op = OPC_SLT;
12758 goto do_slt;
12759 case SLTU:
12760 mips32_op = OPC_SLTU;
12761 do_slt:
12762 gen_slt(ctx, mips32_op, rd, rs, rt);
12763 break;
12764 default:
12765 goto pool32a_invalid;
12766 }
12767 break;
12768 case 0x18:
12769 minor = (ctx->opcode >> 6) & 0xf;
12770 switch (minor) {
12771 /* Conditional moves */
12772 case MOVN:
12773 mips32_op = OPC_MOVN;
12774 goto do_cmov;
12775 case MOVZ:
12776 mips32_op = OPC_MOVZ;
12777 do_cmov:
12778 gen_cond_move(ctx, mips32_op, rd, rs, rt);
12779 break;
12780 case LWXS:
12781 gen_ldxs(ctx, rs, rt, rd);
12782 break;
12783 default:
12784 goto pool32a_invalid;
12785 }
12786 break;
12787 case INS:
12788 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
12789 return;
12790 case EXT:
12791 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
12792 return;
12793 case POOL32AXF:
12794 gen_pool32axf(env, ctx, rt, rs);
12795 break;
12796 case 0x07:
12797 generate_exception(ctx, EXCP_BREAK);
12798 break;
12799 default:
12800 pool32a_invalid:
12801 MIPS_INVAL("pool32a");
12802 generate_exception(ctx, EXCP_RI);
12803 break;
12804 }
12805 break;
12806 case POOL32B:
12807 minor = (ctx->opcode >> 12) & 0xf;
12808 switch (minor) {
12809 case CACHE:
12810 check_cp0_enabled(ctx);
12811 /* Treat as no-op. */
12812 break;
12813 case LWC2:
12814 case SWC2:
12815 /* COP2: Not implemented. */
12816 generate_exception_err(ctx, EXCP_CpU, 2);
12817 break;
12818 case LWP:
12819 case SWP:
12820 #ifdef TARGET_MIPS64
12821 case LDP:
12822 case SDP:
12823 #endif
12824 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
12825 break;
12826 case LWM32:
12827 case SWM32:
12828 #ifdef TARGET_MIPS64
12829 case LDM:
12830 case SDM:
12831 #endif
12832 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
12833 break;
12834 default:
12835 MIPS_INVAL("pool32b");
12836 generate_exception(ctx, EXCP_RI);
12837 break;
12838 }
12839 break;
12840 case POOL32F:
12841 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
12842 minor = ctx->opcode & 0x3f;
12843 check_cp1_enabled(ctx);
12844 switch (minor) {
12845 case ALNV_PS:
12846 mips32_op = OPC_ALNV_PS;
12847 goto do_madd;
12848 case MADD_S:
12849 mips32_op = OPC_MADD_S;
12850 goto do_madd;
12851 case MADD_D:
12852 mips32_op = OPC_MADD_D;
12853 goto do_madd;
12854 case MADD_PS:
12855 mips32_op = OPC_MADD_PS;
12856 goto do_madd;
12857 case MSUB_S:
12858 mips32_op = OPC_MSUB_S;
12859 goto do_madd;
12860 case MSUB_D:
12861 mips32_op = OPC_MSUB_D;
12862 goto do_madd;
12863 case MSUB_PS:
12864 mips32_op = OPC_MSUB_PS;
12865 goto do_madd;
12866 case NMADD_S:
12867 mips32_op = OPC_NMADD_S;
12868 goto do_madd;
12869 case NMADD_D:
12870 mips32_op = OPC_NMADD_D;
12871 goto do_madd;
12872 case NMADD_PS:
12873 mips32_op = OPC_NMADD_PS;
12874 goto do_madd;
12875 case NMSUB_S:
12876 mips32_op = OPC_NMSUB_S;
12877 goto do_madd;
12878 case NMSUB_D:
12879 mips32_op = OPC_NMSUB_D;
12880 goto do_madd;
12881 case NMSUB_PS:
12882 mips32_op = OPC_NMSUB_PS;
12883 do_madd:
12884 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
12885 break;
12886 case CABS_COND_FMT:
12887 cond = (ctx->opcode >> 6) & 0xf;
12888 cc = (ctx->opcode >> 13) & 0x7;
12889 fmt = (ctx->opcode >> 10) & 0x3;
12890 switch (fmt) {
12891 case 0x0:
12892 gen_cmpabs_s(ctx, cond, rt, rs, cc);
12893 break;
12894 case 0x1:
12895 gen_cmpabs_d(ctx, cond, rt, rs, cc);
12896 break;
12897 case 0x2:
12898 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
12899 break;
12900 default:
12901 goto pool32f_invalid;
12902 }
12903 break;
12904 case C_COND_FMT:
12905 cond = (ctx->opcode >> 6) & 0xf;
12906 cc = (ctx->opcode >> 13) & 0x7;
12907 fmt = (ctx->opcode >> 10) & 0x3;
12908 switch (fmt) {
12909 case 0x0:
12910 gen_cmp_s(ctx, cond, rt, rs, cc);
12911 break;
12912 case 0x1:
12913 gen_cmp_d(ctx, cond, rt, rs, cc);
12914 break;
12915 case 0x2:
12916 gen_cmp_ps(ctx, cond, rt, rs, cc);
12917 break;
12918 default:
12919 goto pool32f_invalid;
12920 }
12921 break;
12922 case POOL32FXF:
12923 gen_pool32fxf(ctx, rt, rs);
12924 break;
12925 case 0x00:
12926 /* PLL foo */
12927 switch ((ctx->opcode >> 6) & 0x7) {
12928 case PLL_PS:
12929 mips32_op = OPC_PLL_PS;
12930 goto do_ps;
12931 case PLU_PS:
12932 mips32_op = OPC_PLU_PS;
12933 goto do_ps;
12934 case PUL_PS:
12935 mips32_op = OPC_PUL_PS;
12936 goto do_ps;
12937 case PUU_PS:
12938 mips32_op = OPC_PUU_PS;
12939 goto do_ps;
12940 case CVT_PS_S:
12941 mips32_op = OPC_CVT_PS_S;
12942 do_ps:
12943 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12944 break;
12945 default:
12946 goto pool32f_invalid;
12947 }
12948 break;
12949 case 0x08:
12950 /* [LS][WDU]XC1 */
12951 switch ((ctx->opcode >> 6) & 0x7) {
12952 case LWXC1:
12953 mips32_op = OPC_LWXC1;
12954 goto do_ldst_cp1;
12955 case SWXC1:
12956 mips32_op = OPC_SWXC1;
12957 goto do_ldst_cp1;
12958 case LDXC1:
12959 mips32_op = OPC_LDXC1;
12960 goto do_ldst_cp1;
12961 case SDXC1:
12962 mips32_op = OPC_SDXC1;
12963 goto do_ldst_cp1;
12964 case LUXC1:
12965 mips32_op = OPC_LUXC1;
12966 goto do_ldst_cp1;
12967 case SUXC1:
12968 mips32_op = OPC_SUXC1;
12969 do_ldst_cp1:
12970 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
12971 break;
12972 default:
12973 goto pool32f_invalid;
12974 }
12975 break;
12976 case 0x18:
12977 /* 3D insns */
12978 fmt = (ctx->opcode >> 9) & 0x3;
12979 switch ((ctx->opcode >> 6) & 0x7) {
12980 case RSQRT2_FMT:
12981 switch (fmt) {
12982 case FMT_SDPS_S:
12983 mips32_op = OPC_RSQRT2_S;
12984 goto do_3d;
12985 case FMT_SDPS_D:
12986 mips32_op = OPC_RSQRT2_D;
12987 goto do_3d;
12988 case FMT_SDPS_PS:
12989 mips32_op = OPC_RSQRT2_PS;
12990 goto do_3d;
12991 default:
12992 goto pool32f_invalid;
12993 }
12994 break;
12995 case RECIP2_FMT:
12996 switch (fmt) {
12997 case FMT_SDPS_S:
12998 mips32_op = OPC_RECIP2_S;
12999 goto do_3d;
13000 case FMT_SDPS_D:
13001 mips32_op = OPC_RECIP2_D;
13002 goto do_3d;
13003 case FMT_SDPS_PS:
13004 mips32_op = OPC_RECIP2_PS;
13005 goto do_3d;
13006 default:
13007 goto pool32f_invalid;
13008 }
13009 break;
13010 case ADDR_PS:
13011 mips32_op = OPC_ADDR_PS;
13012 goto do_3d;
13013 case MULR_PS:
13014 mips32_op = OPC_MULR_PS;
13015 do_3d:
13016 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13017 break;
13018 default:
13019 goto pool32f_invalid;
13020 }
13021 break;
13022 case 0x20:
13023 /* MOV[FT].fmt and PREFX */
13024 cc = (ctx->opcode >> 13) & 0x7;
13025 fmt = (ctx->opcode >> 9) & 0x3;
13026 switch ((ctx->opcode >> 6) & 0x7) {
13027 case MOVF_FMT:
13028 switch (fmt) {
13029 case FMT_SDPS_S:
13030 gen_movcf_s(rs, rt, cc, 0);
13031 break;
13032 case FMT_SDPS_D:
13033 gen_movcf_d(ctx, rs, rt, cc, 0);
13034 break;
13035 case FMT_SDPS_PS:
13036 gen_movcf_ps(ctx, rs, rt, cc, 0);
13037 break;
13038 default:
13039 goto pool32f_invalid;
13040 }
13041 break;
13042 case MOVT_FMT:
13043 switch (fmt) {
13044 case FMT_SDPS_S:
13045 gen_movcf_s(rs, rt, cc, 1);
13046 break;
13047 case FMT_SDPS_D:
13048 gen_movcf_d(ctx, rs, rt, cc, 1);
13049 break;
13050 case FMT_SDPS_PS:
13051 gen_movcf_ps(ctx, rs, rt, cc, 1);
13052 break;
13053 default:
13054 goto pool32f_invalid;
13055 }
13056 break;
13057 case PREFX:
13058 break;
13059 default:
13060 goto pool32f_invalid;
13061 }
13062 break;
13063 #define FINSN_3ARG_SDPS(prfx) \
13064 switch ((ctx->opcode >> 8) & 0x3) { \
13065 case FMT_SDPS_S: \
13066 mips32_op = OPC_##prfx##_S; \
13067 goto do_fpop; \
13068 case FMT_SDPS_D: \
13069 mips32_op = OPC_##prfx##_D; \
13070 goto do_fpop; \
13071 case FMT_SDPS_PS: \
13072 mips32_op = OPC_##prfx##_PS; \
13073 goto do_fpop; \
13074 default: \
13075 goto pool32f_invalid; \
13076 }
13077 case 0x30:
13078 /* regular FP ops */
13079 switch ((ctx->opcode >> 6) & 0x3) {
13080 case ADD_FMT:
13081 FINSN_3ARG_SDPS(ADD);
13082 break;
13083 case SUB_FMT:
13084 FINSN_3ARG_SDPS(SUB);
13085 break;
13086 case MUL_FMT:
13087 FINSN_3ARG_SDPS(MUL);
13088 break;
13089 case DIV_FMT:
13090 fmt = (ctx->opcode >> 8) & 0x3;
13091 if (fmt == 1) {
13092 mips32_op = OPC_DIV_D;
13093 } else if (fmt == 0) {
13094 mips32_op = OPC_DIV_S;
13095 } else {
13096 goto pool32f_invalid;
13097 }
13098 goto do_fpop;
13099 default:
13100 goto pool32f_invalid;
13101 }
13102 break;
13103 case 0x38:
13104 /* cmovs */
13105 switch ((ctx->opcode >> 6) & 0x3) {
13106 case MOVN_FMT:
13107 FINSN_3ARG_SDPS(MOVN);
13108 break;
13109 case MOVZ_FMT:
13110 FINSN_3ARG_SDPS(MOVZ);
13111 break;
13112 default:
13113 goto pool32f_invalid;
13114 }
13115 break;
13116 do_fpop:
13117 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
13118 break;
13119 default:
13120 pool32f_invalid:
13121 MIPS_INVAL("pool32f");
13122 generate_exception(ctx, EXCP_RI);
13123 break;
13124 }
13125 } else {
13126 generate_exception_err(ctx, EXCP_CpU, 1);
13127 }
13128 break;
13129 case POOL32I:
13130 minor = (ctx->opcode >> 21) & 0x1f;
13131 switch (minor) {
13132 case BLTZ:
13133 mips32_op = OPC_BLTZ;
13134 goto do_branch;
13135 case BLTZAL:
13136 mips32_op = OPC_BLTZAL;
13137 goto do_branch;
13138 case BLTZALS:
13139 mips32_op = OPC_BLTZALS;
13140 goto do_branch;
13141 case BGEZ:
13142 mips32_op = OPC_BGEZ;
13143 goto do_branch;
13144 case BGEZAL:
13145 mips32_op = OPC_BGEZAL;
13146 goto do_branch;
13147 case BGEZALS:
13148 mips32_op = OPC_BGEZALS;
13149 goto do_branch;
13150 case BLEZ:
13151 mips32_op = OPC_BLEZ;
13152 goto do_branch;
13153 case BGTZ:
13154 mips32_op = OPC_BGTZ;
13155 do_branch:
13156 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
13157 break;
13158
13159 /* Traps */
13160 case TLTI:
13161 mips32_op = OPC_TLTI;
13162 goto do_trapi;
13163 case TGEI:
13164 mips32_op = OPC_TGEI;
13165 goto do_trapi;
13166 case TLTIU:
13167 mips32_op = OPC_TLTIU;
13168 goto do_trapi;
13169 case TGEIU:
13170 mips32_op = OPC_TGEIU;
13171 goto do_trapi;
13172 case TNEI:
13173 mips32_op = OPC_TNEI;
13174 goto do_trapi;
13175 case TEQI:
13176 mips32_op = OPC_TEQI;
13177 do_trapi:
13178 gen_trap(ctx, mips32_op, rs, -1, imm);
13179 break;
13180
13181 case BNEZC:
13182 case BEQZC:
13183 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
13184 4, rs, 0, imm << 1);
13185 /* Compact branches don't have a delay slot, so just let
13186 the normal delay slot handling take us to the branch
13187 target. */
13188 break;
13189 case LUI:
13190 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
13191 break;
13192 case SYNCI:
13193 break;
13194 case BC2F:
13195 case BC2T:
13196 /* COP2: Not implemented. */
13197 generate_exception_err(ctx, EXCP_CpU, 2);
13198 break;
13199 case BC1F:
13200 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
13201 goto do_cp1branch;
13202 case BC1T:
13203 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
13204 goto do_cp1branch;
13205 case BC1ANY4F:
13206 mips32_op = OPC_BC1FANY4;
13207 goto do_cp1mips3d;
13208 case BC1ANY4T:
13209 mips32_op = OPC_BC1TANY4;
13210 do_cp1mips3d:
13211 check_cop1x(ctx);
13212 check_insn(ctx, ASE_MIPS3D);
13213 /* Fall through */
13214 do_cp1branch:
13215 gen_compute_branch1(ctx, mips32_op,
13216 (ctx->opcode >> 18) & 0x7, imm << 1);
13217 break;
13218 case BPOSGE64:
13219 case BPOSGE32:
13220 /* MIPS DSP: not implemented */
13221 /* Fall through */
13222 default:
13223 MIPS_INVAL("pool32i");
13224 generate_exception(ctx, EXCP_RI);
13225 break;
13226 }
13227 break;
13228 case POOL32C:
13229 minor = (ctx->opcode >> 12) & 0xf;
13230 switch (minor) {
13231 case LWL:
13232 mips32_op = OPC_LWL;
13233 goto do_ld_lr;
13234 case SWL:
13235 mips32_op = OPC_SWL;
13236 goto do_st_lr;
13237 case LWR:
13238 mips32_op = OPC_LWR;
13239 goto do_ld_lr;
13240 case SWR:
13241 mips32_op = OPC_SWR;
13242 goto do_st_lr;
13243 #if defined(TARGET_MIPS64)
13244 case LDL:
13245 mips32_op = OPC_LDL;
13246 goto do_ld_lr;
13247 case SDL:
13248 mips32_op = OPC_SDL;
13249 goto do_st_lr;
13250 case LDR:
13251 mips32_op = OPC_LDR;
13252 goto do_ld_lr;
13253 case SDR:
13254 mips32_op = OPC_SDR;
13255 goto do_st_lr;
13256 case LWU:
13257 mips32_op = OPC_LWU;
13258 goto do_ld_lr;
13259 case LLD:
13260 mips32_op = OPC_LLD;
13261 goto do_ld_lr;
13262 #endif
13263 case LL:
13264 mips32_op = OPC_LL;
13265 goto do_ld_lr;
13266 do_ld_lr:
13267 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
13268 break;
13269 do_st_lr:
13270 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
13271 break;
13272 case SC:
13273 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
13274 break;
13275 #if defined(TARGET_MIPS64)
13276 case SCD:
13277 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
13278 break;
13279 #endif
13280 case PREF:
13281 /* Treat as no-op */
13282 break;
13283 default:
13284 MIPS_INVAL("pool32c");
13285 generate_exception(ctx, EXCP_RI);
13286 break;
13287 }
13288 break;
13289 case ADDI32:
13290 mips32_op = OPC_ADDI;
13291 goto do_addi;
13292 case ADDIU32:
13293 mips32_op = OPC_ADDIU;
13294 do_addi:
13295 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
13296 break;
13297
13298 /* Logical operations */
13299 case ORI32:
13300 mips32_op = OPC_ORI;
13301 goto do_logici;
13302 case XORI32:
13303 mips32_op = OPC_XORI;
13304 goto do_logici;
13305 case ANDI32:
13306 mips32_op = OPC_ANDI;
13307 do_logici:
13308 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
13309 break;
13310
13311 /* Set less than immediate */
13312 case SLTI32:
13313 mips32_op = OPC_SLTI;
13314 goto do_slti;
13315 case SLTIU32:
13316 mips32_op = OPC_SLTIU;
13317 do_slti:
13318 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
13319 break;
13320 case JALX32:
13321 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
13322 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
13323 break;
13324 case JALS32:
13325 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
13326 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
13327 break;
13328 case BEQ32:
13329 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
13330 break;
13331 case BNE32:
13332 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
13333 break;
13334 case J32:
13335 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
13336 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
13337 break;
13338 case JAL32:
13339 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
13340 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
13341 break;
13342 /* Floating point (COP1) */
13343 case LWC132:
13344 mips32_op = OPC_LWC1;
13345 goto do_cop1;
13346 case LDC132:
13347 mips32_op = OPC_LDC1;
13348 goto do_cop1;
13349 case SWC132:
13350 mips32_op = OPC_SWC1;
13351 goto do_cop1;
13352 case SDC132:
13353 mips32_op = OPC_SDC1;
13354 do_cop1:
13355 gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
13356 break;
13357 case ADDIUPC:
13358 {
13359 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
13360 int offset = SIMM(ctx->opcode, 0, 23) << 2;
13361
13362 gen_addiupc(ctx, reg, offset, 0, 0);
13363 }
13364 break;
13365 /* Loads and stores */
13366 case LB32:
13367 mips32_op = OPC_LB;
13368 goto do_ld;
13369 case LBU32:
13370 mips32_op = OPC_LBU;
13371 goto do_ld;
13372 case LH32:
13373 mips32_op = OPC_LH;
13374 goto do_ld;
13375 case LHU32:
13376 mips32_op = OPC_LHU;
13377 goto do_ld;
13378 case LW32:
13379 mips32_op = OPC_LW;
13380 goto do_ld;
13381 #ifdef TARGET_MIPS64
13382 case LD32:
13383 mips32_op = OPC_LD;
13384 goto do_ld;
13385 case SD32:
13386 mips32_op = OPC_SD;
13387 goto do_st;
13388 #endif
13389 case SB32:
13390 mips32_op = OPC_SB;
13391 goto do_st;
13392 case SH32:
13393 mips32_op = OPC_SH;
13394 goto do_st;
13395 case SW32:
13396 mips32_op = OPC_SW;
13397 goto do_st;
13398 do_ld:
13399 gen_ld(ctx, mips32_op, rt, rs, imm);
13400 break;
13401 do_st:
13402 gen_st(ctx, mips32_op, rt, rs, imm);
13403 break;
13404 default:
13405 generate_exception(ctx, EXCP_RI);
13406 break;
13407 }
13408 }
13409
13410 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
13411 {
13412 uint32_t op;
13413
13414 /* make sure instructions are on a halfword boundary */
13415 if (ctx->pc & 0x1) {
13416 env->CP0_BadVAddr = ctx->pc;
13417 generate_exception(ctx, EXCP_AdEL);
13418 ctx->bstate = BS_STOP;
13419 return 2;
13420 }
13421
13422 op = (ctx->opcode >> 10) & 0x3f;
13423 /* Enforce properly-sized instructions in a delay slot */
13424 if (ctx->hflags & MIPS_HFLAG_BMASK) {
13425 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
13426
13427 switch (op) {
13428 case POOL32A:
13429 case POOL32B:
13430 case POOL32I:
13431 case POOL32C:
13432 case ADDI32:
13433 case ADDIU32:
13434 case ORI32:
13435 case XORI32:
13436 case SLTI32:
13437 case SLTIU32:
13438 case ANDI32:
13439 case JALX32:
13440 case LBU32:
13441 case LHU32:
13442 case POOL32F:
13443 case JALS32:
13444 case BEQ32:
13445 case BNE32:
13446 case J32:
13447 case JAL32:
13448 case SB32:
13449 case SH32:
13450 case POOL32S:
13451 case ADDIUPC:
13452 case SWC132:
13453 case SDC132:
13454 case SD32:
13455 case SW32:
13456 case LB32:
13457 case LH32:
13458 case DADDIU32:
13459 case LWC132:
13460 case LDC132:
13461 case LD32:
13462 case LW32:
13463 if (bits & MIPS_HFLAG_BDS16) {
13464 generate_exception(ctx, EXCP_RI);
13465 /* Just stop translation; the user is confused. */
13466 ctx->bstate = BS_STOP;
13467 return 2;
13468 }
13469 break;
13470 case POOL16A:
13471 case POOL16B:
13472 case POOL16C:
13473 case LWGP16:
13474 case POOL16F:
13475 case LBU16:
13476 case LHU16:
13477 case LWSP16:
13478 case LW16:
13479 case SB16:
13480 case SH16:
13481 case SWSP16:
13482 case SW16:
13483 case MOVE16:
13484 case ANDI16:
13485 case POOL16D:
13486 case POOL16E:
13487 case BEQZ16:
13488 case BNEZ16:
13489 case B16:
13490 case LI16:
13491 if (bits & MIPS_HFLAG_BDS32) {
13492 generate_exception(ctx, EXCP_RI);
13493 /* Just stop translation; the user is confused. */
13494 ctx->bstate = BS_STOP;
13495 return 2;
13496 }
13497 break;
13498 default:
13499 break;
13500 }
13501 }
13502 switch (op) {
13503 case POOL16A:
13504 {
13505 int rd = mmreg(uMIPS_RD(ctx->opcode));
13506 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
13507 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
13508 uint32_t opc = 0;
13509
13510 switch (ctx->opcode & 0x1) {
13511 case ADDU16:
13512 opc = OPC_ADDU;
13513 break;
13514 case SUBU16:
13515 opc = OPC_SUBU;
13516 break;
13517 }
13518
13519 gen_arith(ctx, opc, rd, rs1, rs2);
13520 }
13521 break;
13522 case POOL16B:
13523 {
13524 int rd = mmreg(uMIPS_RD(ctx->opcode));
13525 int rs = mmreg(uMIPS_RS(ctx->opcode));
13526 int amount = (ctx->opcode >> 1) & 0x7;
13527 uint32_t opc = 0;
13528 amount = amount == 0 ? 8 : amount;
13529
13530 switch (ctx->opcode & 0x1) {
13531 case SLL16:
13532 opc = OPC_SLL;
13533 break;
13534 case SRL16:
13535 opc = OPC_SRL;
13536 break;
13537 }
13538
13539 gen_shift_imm(ctx, opc, rd, rs, amount);
13540 }
13541 break;
13542 case POOL16C:
13543 gen_pool16c_insn(ctx);
13544 break;
13545 case LWGP16:
13546 {
13547 int rd = mmreg(uMIPS_RD(ctx->opcode));
13548 int rb = 28; /* GP */
13549 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
13550
13551 gen_ld(ctx, OPC_LW, rd, rb, offset);
13552 }
13553 break;
13554 case POOL16F:
13555 if (ctx->opcode & 1) {
13556 generate_exception(ctx, EXCP_RI);
13557 } else {
13558 /* MOVEP */
13559 int enc_dest = uMIPS_RD(ctx->opcode);
13560 int enc_rt = uMIPS_RS2(ctx->opcode);
13561 int enc_rs = uMIPS_RS1(ctx->opcode);
13562 int rd, rs, re, rt;
13563 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13564 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13565 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13566
13567 rd = rd_enc[enc_dest];
13568 re = re_enc[enc_dest];
13569 rs = rs_rt_enc[enc_rs];
13570 rt = rs_rt_enc[enc_rt];
13571
13572 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
13573 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
13574 }
13575 break;
13576 case LBU16:
13577 {
13578 int rd = mmreg(uMIPS_RD(ctx->opcode));
13579 int rb = mmreg(uMIPS_RS(ctx->opcode));
13580 int16_t offset = ZIMM(ctx->opcode, 0, 4);
13581 offset = (offset == 0xf ? -1 : offset);
13582
13583 gen_ld(ctx, OPC_LBU, rd, rb, offset);
13584 }
13585 break;
13586 case LHU16:
13587 {
13588 int rd = mmreg(uMIPS_RD(ctx->opcode));
13589 int rb = mmreg(uMIPS_RS(ctx->opcode));
13590 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
13591
13592 gen_ld(ctx, OPC_LHU, rd, rb, offset);
13593 }
13594 break;
13595 case LWSP16:
13596 {
13597 int rd = (ctx->opcode >> 5) & 0x1f;
13598 int rb = 29; /* SP */
13599 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
13600
13601 gen_ld(ctx, OPC_LW, rd, rb, offset);
13602 }
13603 break;
13604 case LW16:
13605 {
13606 int rd = mmreg(uMIPS_RD(ctx->opcode));
13607 int rb = mmreg(uMIPS_RS(ctx->opcode));
13608 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
13609
13610 gen_ld(ctx, OPC_LW, rd, rb, offset);
13611 }
13612 break;
13613 case SB16:
13614 {
13615 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13616 int rb = mmreg(uMIPS_RS(ctx->opcode));
13617 int16_t offset = ZIMM(ctx->opcode, 0, 4);
13618
13619 gen_st(ctx, OPC_SB, rd, rb, offset);
13620 }
13621 break;
13622 case SH16:
13623 {
13624 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13625 int rb = mmreg(uMIPS_RS(ctx->opcode));
13626 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
13627
13628 gen_st(ctx, OPC_SH, rd, rb, offset);
13629 }
13630 break;
13631 case SWSP16:
13632 {
13633 int rd = (ctx->opcode >> 5) & 0x1f;
13634 int rb = 29; /* SP */
13635 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
13636
13637 gen_st(ctx, OPC_SW, rd, rb, offset);
13638 }
13639 break;
13640 case SW16:
13641 {
13642 int rd = mmreg2(uMIPS_RD(ctx->opcode));
13643 int rb = mmreg(uMIPS_RS(ctx->opcode));
13644 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
13645
13646 gen_st(ctx, OPC_SW, rd, rb, offset);
13647 }
13648 break;
13649 case MOVE16:
13650 {
13651 int rd = uMIPS_RD5(ctx->opcode);
13652 int rs = uMIPS_RS5(ctx->opcode);
13653
13654 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
13655 }
13656 break;
13657 case ANDI16:
13658 gen_andi16(ctx);
13659 break;
13660 case POOL16D:
13661 switch (ctx->opcode & 0x1) {
13662 case ADDIUS5:
13663 gen_addius5(ctx);
13664 break;
13665 case ADDIUSP:
13666 gen_addiusp(ctx);
13667 break;
13668 }
13669 break;
13670 case POOL16E:
13671 switch (ctx->opcode & 0x1) {
13672 case ADDIUR2:
13673 gen_addiur2(ctx);
13674 break;
13675 case ADDIUR1SP:
13676 gen_addiur1sp(ctx);
13677 break;
13678 }
13679 break;
13680 case B16:
13681 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
13682 SIMM(ctx->opcode, 0, 10) << 1);
13683 break;
13684 case BNEZ16:
13685 case BEQZ16:
13686 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
13687 mmreg(uMIPS_RD(ctx->opcode)),
13688 0, SIMM(ctx->opcode, 0, 7) << 1);
13689 break;
13690 case LI16:
13691 {
13692 int reg = mmreg(uMIPS_RD(ctx->opcode));
13693 int imm = ZIMM(ctx->opcode, 0, 7);
13694
13695 imm = (imm == 0x7f ? -1 : imm);
13696 tcg_gen_movi_tl(cpu_gpr[reg], imm);
13697 }
13698 break;
13699 case RES_20:
13700 case RES_28:
13701 case RES_29:
13702 case RES_30:
13703 case RES_31:
13704 case RES_38:
13705 case RES_39:
13706 generate_exception(ctx, EXCP_RI);
13707 break;
13708 default:
13709 decode_micromips32_opc (env, ctx, op);
13710 return 4;
13711 }
13712
13713 return 2;
13714 }
13715
13716 /* SmartMIPS extension to MIPS32 */
13717
13718 #if defined(TARGET_MIPS64)
13719
13720 /* MDMX extension to MIPS64 */
13721
13722 #endif
13723
13724 /* MIPSDSP functions. */
13725 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
13726 int rd, int base, int offset)
13727 {
13728 const char *opn = "ldx";
13729 TCGv t0;
13730
13731 check_dsp(ctx);
13732 t0 = tcg_temp_new();
13733
13734 if (base == 0) {
13735 gen_load_gpr(t0, offset);
13736 } else if (offset == 0) {
13737 gen_load_gpr(t0, base);
13738 } else {
13739 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
13740 }
13741
13742 switch (opc) {
13743 case OPC_LBUX:
13744 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
13745 gen_store_gpr(t0, rd);
13746 opn = "lbux";
13747 break;
13748 case OPC_LHX:
13749 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
13750 gen_store_gpr(t0, rd);
13751 opn = "lhx";
13752 break;
13753 case OPC_LWX:
13754 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
13755 gen_store_gpr(t0, rd);
13756 opn = "lwx";
13757 break;
13758 #if defined(TARGET_MIPS64)
13759 case OPC_LDX:
13760 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
13761 gen_store_gpr(t0, rd);
13762 opn = "ldx";
13763 break;
13764 #endif
13765 }
13766 (void)opn; /* avoid a compiler warning */
13767 MIPS_DEBUG("%s %s, %s(%s)", opn,
13768 regnames[rd], regnames[offset], regnames[base]);
13769 tcg_temp_free(t0);
13770 }
13771
13772 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
13773 int ret, int v1, int v2)
13774 {
13775 const char *opn = "mipsdsp arith";
13776 TCGv v1_t;
13777 TCGv v2_t;
13778
13779 if (ret == 0) {
13780 /* Treat as NOP. */
13781 MIPS_DEBUG("NOP");
13782 return;
13783 }
13784
13785 v1_t = tcg_temp_new();
13786 v2_t = tcg_temp_new();
13787
13788 gen_load_gpr(v1_t, v1);
13789 gen_load_gpr(v2_t, v2);
13790
13791 switch (op1) {
13792 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
13793 case OPC_MULT_G_2E:
13794 check_dspr2(ctx);
13795 switch (op2) {
13796 case OPC_ADDUH_QB:
13797 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
13798 break;
13799 case OPC_ADDUH_R_QB:
13800 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
13801 break;
13802 case OPC_ADDQH_PH:
13803 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
13804 break;
13805 case OPC_ADDQH_R_PH:
13806 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
13807 break;
13808 case OPC_ADDQH_W:
13809 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
13810 break;
13811 case OPC_ADDQH_R_W:
13812 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
13813 break;
13814 case OPC_SUBUH_QB:
13815 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
13816 break;
13817 case OPC_SUBUH_R_QB:
13818 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
13819 break;
13820 case OPC_SUBQH_PH:
13821 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
13822 break;
13823 case OPC_SUBQH_R_PH:
13824 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
13825 break;
13826 case OPC_SUBQH_W:
13827 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
13828 break;
13829 case OPC_SUBQH_R_W:
13830 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
13831 break;
13832 }
13833 break;
13834 case OPC_ABSQ_S_PH_DSP:
13835 switch (op2) {
13836 case OPC_ABSQ_S_QB:
13837 check_dspr2(ctx);
13838 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
13839 break;
13840 case OPC_ABSQ_S_PH:
13841 check_dsp(ctx);
13842 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
13843 break;
13844 case OPC_ABSQ_S_W:
13845 check_dsp(ctx);
13846 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
13847 break;
13848 case OPC_PRECEQ_W_PHL:
13849 check_dsp(ctx);
13850 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
13851 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13852 break;
13853 case OPC_PRECEQ_W_PHR:
13854 check_dsp(ctx);
13855 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
13856 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
13857 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13858 break;
13859 case OPC_PRECEQU_PH_QBL:
13860 check_dsp(ctx);
13861 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
13862 break;
13863 case OPC_PRECEQU_PH_QBR:
13864 check_dsp(ctx);
13865 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
13866 break;
13867 case OPC_PRECEQU_PH_QBLA:
13868 check_dsp(ctx);
13869 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
13870 break;
13871 case OPC_PRECEQU_PH_QBRA:
13872 check_dsp(ctx);
13873 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
13874 break;
13875 case OPC_PRECEU_PH_QBL:
13876 check_dsp(ctx);
13877 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
13878 break;
13879 case OPC_PRECEU_PH_QBR:
13880 check_dsp(ctx);
13881 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
13882 break;
13883 case OPC_PRECEU_PH_QBLA:
13884 check_dsp(ctx);
13885 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
13886 break;
13887 case OPC_PRECEU_PH_QBRA:
13888 check_dsp(ctx);
13889 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
13890 break;
13891 }
13892 break;
13893 case OPC_ADDU_QB_DSP:
13894 switch (op2) {
13895 case OPC_ADDQ_PH:
13896 check_dsp(ctx);
13897 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13898 break;
13899 case OPC_ADDQ_S_PH:
13900 check_dsp(ctx);
13901 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13902 break;
13903 case OPC_ADDQ_S_W:
13904 check_dsp(ctx);
13905 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13906 break;
13907 case OPC_ADDU_QB:
13908 check_dsp(ctx);
13909 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13910 break;
13911 case OPC_ADDU_S_QB:
13912 check_dsp(ctx);
13913 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13914 break;
13915 case OPC_ADDU_PH:
13916 check_dspr2(ctx);
13917 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13918 break;
13919 case OPC_ADDU_S_PH:
13920 check_dspr2(ctx);
13921 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13922 break;
13923 case OPC_SUBQ_PH:
13924 check_dsp(ctx);
13925 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13926 break;
13927 case OPC_SUBQ_S_PH:
13928 check_dsp(ctx);
13929 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13930 break;
13931 case OPC_SUBQ_S_W:
13932 check_dsp(ctx);
13933 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13934 break;
13935 case OPC_SUBU_QB:
13936 check_dsp(ctx);
13937 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13938 break;
13939 case OPC_SUBU_S_QB:
13940 check_dsp(ctx);
13941 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13942 break;
13943 case OPC_SUBU_PH:
13944 check_dspr2(ctx);
13945 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13946 break;
13947 case OPC_SUBU_S_PH:
13948 check_dspr2(ctx);
13949 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13950 break;
13951 case OPC_ADDSC:
13952 check_dsp(ctx);
13953 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13954 break;
13955 case OPC_ADDWC:
13956 check_dsp(ctx);
13957 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13958 break;
13959 case OPC_MODSUB:
13960 check_dsp(ctx);
13961 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
13962 break;
13963 case OPC_RADDU_W_QB:
13964 check_dsp(ctx);
13965 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
13966 break;
13967 }
13968 break;
13969 case OPC_CMPU_EQ_QB_DSP:
13970 switch (op2) {
13971 case OPC_PRECR_QB_PH:
13972 check_dspr2(ctx);
13973 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
13974 break;
13975 case OPC_PRECRQ_QB_PH:
13976 check_dsp(ctx);
13977 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
13978 break;
13979 case OPC_PRECR_SRA_PH_W:
13980 check_dspr2(ctx);
13981 {
13982 TCGv_i32 sa_t = tcg_const_i32(v2);
13983 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
13984 cpu_gpr[ret]);
13985 tcg_temp_free_i32(sa_t);
13986 break;
13987 }
13988 case OPC_PRECR_SRA_R_PH_W:
13989 check_dspr2(ctx);
13990 {
13991 TCGv_i32 sa_t = tcg_const_i32(v2);
13992 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
13993 cpu_gpr[ret]);
13994 tcg_temp_free_i32(sa_t);
13995 break;
13996 }
13997 case OPC_PRECRQ_PH_W:
13998 check_dsp(ctx);
13999 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
14000 break;
14001 case OPC_PRECRQ_RS_PH_W:
14002 check_dsp(ctx);
14003 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14004 break;
14005 case OPC_PRECRQU_S_QB_PH:
14006 check_dsp(ctx);
14007 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14008 break;
14009 }
14010 break;
14011 #ifdef TARGET_MIPS64
14012 case OPC_ABSQ_S_QH_DSP:
14013 switch (op2) {
14014 case OPC_PRECEQ_L_PWL:
14015 check_dsp(ctx);
14016 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
14017 break;
14018 case OPC_PRECEQ_L_PWR:
14019 check_dsp(ctx);
14020 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
14021 break;
14022 case OPC_PRECEQ_PW_QHL:
14023 check_dsp(ctx);
14024 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
14025 break;
14026 case OPC_PRECEQ_PW_QHR:
14027 check_dsp(ctx);
14028 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
14029 break;
14030 case OPC_PRECEQ_PW_QHLA:
14031 check_dsp(ctx);
14032 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
14033 break;
14034 case OPC_PRECEQ_PW_QHRA:
14035 check_dsp(ctx);
14036 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
14037 break;
14038 case OPC_PRECEQU_QH_OBL:
14039 check_dsp(ctx);
14040 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
14041 break;
14042 case OPC_PRECEQU_QH_OBR:
14043 check_dsp(ctx);
14044 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
14045 break;
14046 case OPC_PRECEQU_QH_OBLA:
14047 check_dsp(ctx);
14048 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
14049 break;
14050 case OPC_PRECEQU_QH_OBRA:
14051 check_dsp(ctx);
14052 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
14053 break;
14054 case OPC_PRECEU_QH_OBL:
14055 check_dsp(ctx);
14056 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
14057 break;
14058 case OPC_PRECEU_QH_OBR:
14059 check_dsp(ctx);
14060 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
14061 break;
14062 case OPC_PRECEU_QH_OBLA:
14063 check_dsp(ctx);
14064 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
14065 break;
14066 case OPC_PRECEU_QH_OBRA:
14067 check_dsp(ctx);
14068 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
14069 break;
14070 case OPC_ABSQ_S_OB:
14071 check_dspr2(ctx);
14072 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
14073 break;
14074 case OPC_ABSQ_S_PW:
14075 check_dsp(ctx);
14076 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
14077 break;
14078 case OPC_ABSQ_S_QH:
14079 check_dsp(ctx);
14080 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
14081 break;
14082 }
14083 break;
14084 case OPC_ADDU_OB_DSP:
14085 switch (op2) {
14086 case OPC_RADDU_L_OB:
14087 check_dsp(ctx);
14088 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
14089 break;
14090 case OPC_SUBQ_PW:
14091 check_dsp(ctx);
14092 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14093 break;
14094 case OPC_SUBQ_S_PW:
14095 check_dsp(ctx);
14096 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14097 break;
14098 case OPC_SUBQ_QH:
14099 check_dsp(ctx);
14100 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14101 break;
14102 case OPC_SUBQ_S_QH:
14103 check_dsp(ctx);
14104 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14105 break;
14106 case OPC_SUBU_OB:
14107 check_dsp(ctx);
14108 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14109 break;
14110 case OPC_SUBU_S_OB:
14111 check_dsp(ctx);
14112 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14113 break;
14114 case OPC_SUBU_QH:
14115 check_dspr2(ctx);
14116 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14117 break;
14118 case OPC_SUBU_S_QH:
14119 check_dspr2(ctx);
14120 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14121 break;
14122 case OPC_SUBUH_OB:
14123 check_dspr2(ctx);
14124 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
14125 break;
14126 case OPC_SUBUH_R_OB:
14127 check_dspr2(ctx);
14128 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14129 break;
14130 case OPC_ADDQ_PW:
14131 check_dsp(ctx);
14132 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14133 break;
14134 case OPC_ADDQ_S_PW:
14135 check_dsp(ctx);
14136 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14137 break;
14138 case OPC_ADDQ_QH:
14139 check_dsp(ctx);
14140 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14141 break;
14142 case OPC_ADDQ_S_QH:
14143 check_dsp(ctx);
14144 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14145 break;
14146 case OPC_ADDU_OB:
14147 check_dsp(ctx);
14148 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14149 break;
14150 case OPC_ADDU_S_OB:
14151 check_dsp(ctx);
14152 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14153 break;
14154 case OPC_ADDU_QH:
14155 check_dspr2(ctx);
14156 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14157 break;
14158 case OPC_ADDU_S_QH:
14159 check_dspr2(ctx);
14160 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14161 break;
14162 case OPC_ADDUH_OB:
14163 check_dspr2(ctx);
14164 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
14165 break;
14166 case OPC_ADDUH_R_OB:
14167 check_dspr2(ctx);
14168 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
14169 break;
14170 }
14171 break;
14172 case OPC_CMPU_EQ_OB_DSP:
14173 switch (op2) {
14174 case OPC_PRECR_OB_QH:
14175 check_dspr2(ctx);
14176 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14177 break;
14178 case OPC_PRECR_SRA_QH_PW:
14179 check_dspr2(ctx);
14180 {
14181 TCGv_i32 ret_t = tcg_const_i32(ret);
14182 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
14183 tcg_temp_free_i32(ret_t);
14184 break;
14185 }
14186 case OPC_PRECR_SRA_R_QH_PW:
14187 check_dspr2(ctx);
14188 {
14189 TCGv_i32 sa_v = tcg_const_i32(ret);
14190 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
14191 tcg_temp_free_i32(sa_v);
14192 break;
14193 }
14194 case OPC_PRECRQ_OB_QH:
14195 check_dsp(ctx);
14196 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
14197 break;
14198 case OPC_PRECRQ_PW_L:
14199 check_dsp(ctx);
14200 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
14201 break;
14202 case OPC_PRECRQ_QH_PW:
14203 check_dsp(ctx);
14204 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
14205 break;
14206 case OPC_PRECRQ_RS_QH_PW:
14207 check_dsp(ctx);
14208 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14209 break;
14210 case OPC_PRECRQU_S_OB_QH:
14211 check_dsp(ctx);
14212 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14213 break;
14214 }
14215 break;
14216 #endif
14217 }
14218
14219 tcg_temp_free(v1_t);
14220 tcg_temp_free(v2_t);
14221
14222 (void)opn; /* avoid a compiler warning */
14223 MIPS_DEBUG("%s", opn);
14224 }
14225
14226 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
14227 int ret, int v1, int v2)
14228 {
14229 uint32_t op2;
14230 const char *opn = "mipsdsp shift";
14231 TCGv t0;
14232 TCGv v1_t;
14233 TCGv v2_t;
14234
14235 if (ret == 0) {
14236 /* Treat as NOP. */
14237 MIPS_DEBUG("NOP");
14238 return;
14239 }
14240
14241 t0 = tcg_temp_new();
14242 v1_t = tcg_temp_new();
14243 v2_t = tcg_temp_new();
14244
14245 tcg_gen_movi_tl(t0, v1);
14246 gen_load_gpr(v1_t, v1);
14247 gen_load_gpr(v2_t, v2);
14248
14249 switch (opc) {
14250 case OPC_SHLL_QB_DSP:
14251 {
14252 op2 = MASK_SHLL_QB(ctx->opcode);
14253 switch (op2) {
14254 case OPC_SHLL_QB:
14255 check_dsp(ctx);
14256 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
14257 break;
14258 case OPC_SHLLV_QB:
14259 check_dsp(ctx);
14260 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14261 break;
14262 case OPC_SHLL_PH:
14263 check_dsp(ctx);
14264 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14265 break;
14266 case OPC_SHLLV_PH:
14267 check_dsp(ctx);
14268 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14269 break;
14270 case OPC_SHLL_S_PH:
14271 check_dsp(ctx);
14272 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
14273 break;
14274 case OPC_SHLLV_S_PH:
14275 check_dsp(ctx);
14276 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14277 break;
14278 case OPC_SHLL_S_W:
14279 check_dsp(ctx);
14280 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
14281 break;
14282 case OPC_SHLLV_S_W:
14283 check_dsp(ctx);
14284 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14285 break;
14286 case OPC_SHRL_QB:
14287 check_dsp(ctx);
14288 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
14289 break;
14290 case OPC_SHRLV_QB:
14291 check_dsp(ctx);
14292 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
14293 break;
14294 case OPC_SHRL_PH:
14295 check_dspr2(ctx);
14296 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
14297 break;
14298 case OPC_SHRLV_PH:
14299 check_dspr2(ctx);
14300 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
14301 break;
14302 case OPC_SHRA_QB:
14303 check_dspr2(ctx);
14304 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
14305 break;
14306 case OPC_SHRA_R_QB:
14307 check_dspr2(ctx);
14308 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
14309 break;
14310 case OPC_SHRAV_QB:
14311 check_dspr2(ctx);
14312 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
14313 break;
14314 case OPC_SHRAV_R_QB:
14315 check_dspr2(ctx);
14316 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
14317 break;
14318 case OPC_SHRA_PH:
14319 check_dsp(ctx);
14320 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
14321 break;
14322 case OPC_SHRA_R_PH:
14323 check_dsp(ctx);
14324 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
14325 break;
14326 case OPC_SHRAV_PH:
14327 check_dsp(ctx);
14328 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
14329 break;
14330 case OPC_SHRAV_R_PH:
14331 check_dsp(ctx);
14332 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
14333 break;
14334 case OPC_SHRA_R_W:
14335 check_dsp(ctx);
14336 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
14337 break;
14338 case OPC_SHRAV_R_W:
14339 check_dsp(ctx);
14340 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
14341 break;
14342 default: /* Invalid */
14343 MIPS_INVAL("MASK SHLL.QB");
14344 generate_exception(ctx, EXCP_RI);
14345 break;
14346 }
14347 break;
14348 }
14349 #ifdef TARGET_MIPS64
14350 case OPC_SHLL_OB_DSP:
14351 op2 = MASK_SHLL_OB(ctx->opcode);
14352 switch (op2) {
14353 case OPC_SHLL_PW:
14354 check_dsp(ctx);
14355 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14356 break;
14357 case OPC_SHLLV_PW:
14358 check_dsp(ctx);
14359 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14360 break;
14361 case OPC_SHLL_S_PW:
14362 check_dsp(ctx);
14363 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
14364 break;
14365 case OPC_SHLLV_S_PW:
14366 check_dsp(ctx);
14367 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14368 break;
14369 case OPC_SHLL_OB:
14370 check_dsp(ctx);
14371 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
14372 break;
14373 case OPC_SHLLV_OB:
14374 check_dsp(ctx);
14375 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14376 break;
14377 case OPC_SHLL_QH:
14378 check_dsp(ctx);
14379 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14380 break;
14381 case OPC_SHLLV_QH:
14382 check_dsp(ctx);
14383 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14384 break;
14385 case OPC_SHLL_S_QH:
14386 check_dsp(ctx);
14387 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
14388 break;
14389 case OPC_SHLLV_S_QH:
14390 check_dsp(ctx);
14391 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
14392 break;
14393 case OPC_SHRA_OB:
14394 check_dspr2(ctx);
14395 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
14396 break;
14397 case OPC_SHRAV_OB:
14398 check_dspr2(ctx);
14399 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
14400 break;
14401 case OPC_SHRA_R_OB:
14402 check_dspr2(ctx);
14403 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
14404 break;
14405 case OPC_SHRAV_R_OB:
14406 check_dspr2(ctx);
14407 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
14408 break;
14409 case OPC_SHRA_PW:
14410 check_dsp(ctx);
14411 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
14412 break;
14413 case OPC_SHRAV_PW:
14414 check_dsp(ctx);
14415 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
14416 break;
14417 case OPC_SHRA_R_PW:
14418 check_dsp(ctx);
14419 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
14420 break;
14421 case OPC_SHRAV_R_PW:
14422 check_dsp(ctx);
14423 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
14424 break;
14425 case OPC_SHRA_QH:
14426 check_dsp(ctx);
14427 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
14428 break;
14429 case OPC_SHRAV_QH:
14430 check_dsp(ctx);
14431 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
14432 break;
14433 case OPC_SHRA_R_QH:
14434 check_dsp(ctx);
14435 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
14436 break;
14437 case OPC_SHRAV_R_QH:
14438 check_dsp(ctx);
14439 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
14440 break;
14441 case OPC_SHRL_OB:
14442 check_dsp(ctx);
14443 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
14444 break;
14445 case OPC_SHRLV_OB:
14446 check_dsp(ctx);
14447 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
14448 break;
14449 case OPC_SHRL_QH:
14450 check_dspr2(ctx);
14451 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
14452 break;
14453 case OPC_SHRLV_QH:
14454 check_dspr2(ctx);
14455 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
14456 break;
14457 default: /* Invalid */
14458 MIPS_INVAL("MASK SHLL.OB");
14459 generate_exception(ctx, EXCP_RI);
14460 break;
14461 }
14462 break;
14463 #endif
14464 }
14465
14466 tcg_temp_free(t0);
14467 tcg_temp_free(v1_t);
14468 tcg_temp_free(v2_t);
14469 (void)opn; /* avoid a compiler warning */
14470 MIPS_DEBUG("%s", opn);
14471 }
14472
14473 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
14474 int ret, int v1, int v2, int check_ret)
14475 {
14476 const char *opn = "mipsdsp multiply";
14477 TCGv_i32 t0;
14478 TCGv v1_t;
14479 TCGv v2_t;
14480
14481 if ((ret == 0) && (check_ret == 1)) {
14482 /* Treat as NOP. */
14483 MIPS_DEBUG("NOP");
14484 return;
14485 }
14486
14487 t0 = tcg_temp_new_i32();
14488 v1_t = tcg_temp_new();
14489 v2_t = tcg_temp_new();
14490
14491 tcg_gen_movi_i32(t0, ret);
14492 gen_load_gpr(v1_t, v1);
14493 gen_load_gpr(v2_t, v2);
14494
14495 switch (op1) {
14496 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14497 * the same mask and op1. */
14498 case OPC_MULT_G_2E:
14499 check_dspr2(ctx);
14500 switch (op2) {
14501 case OPC_MUL_PH:
14502 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14503 break;
14504 case OPC_MUL_S_PH:
14505 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14506 break;
14507 case OPC_MULQ_S_W:
14508 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14509 break;
14510 case OPC_MULQ_RS_W:
14511 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14512 break;
14513 }
14514 break;
14515 case OPC_DPA_W_PH_DSP:
14516 switch (op2) {
14517 case OPC_DPAU_H_QBL:
14518 check_dsp(ctx);
14519 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
14520 break;
14521 case OPC_DPAU_H_QBR:
14522 check_dsp(ctx);
14523 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
14524 break;
14525 case OPC_DPSU_H_QBL:
14526 check_dsp(ctx);
14527 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
14528 break;
14529 case OPC_DPSU_H_QBR:
14530 check_dsp(ctx);
14531 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
14532 break;
14533 case OPC_DPA_W_PH:
14534 check_dspr2(ctx);
14535 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
14536 break;
14537 case OPC_DPAX_W_PH:
14538 check_dspr2(ctx);
14539 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
14540 break;
14541 case OPC_DPAQ_S_W_PH:
14542 check_dsp(ctx);
14543 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14544 break;
14545 case OPC_DPAQX_S_W_PH:
14546 check_dspr2(ctx);
14547 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14548 break;
14549 case OPC_DPAQX_SA_W_PH:
14550 check_dspr2(ctx);
14551 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14552 break;
14553 case OPC_DPS_W_PH:
14554 check_dspr2(ctx);
14555 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
14556 break;
14557 case OPC_DPSX_W_PH:
14558 check_dspr2(ctx);
14559 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
14560 break;
14561 case OPC_DPSQ_S_W_PH:
14562 check_dsp(ctx);
14563 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14564 break;
14565 case OPC_DPSQX_S_W_PH:
14566 check_dspr2(ctx);
14567 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
14568 break;
14569 case OPC_DPSQX_SA_W_PH:
14570 check_dspr2(ctx);
14571 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
14572 break;
14573 case OPC_MULSAQ_S_W_PH:
14574 check_dsp(ctx);
14575 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
14576 break;
14577 case OPC_DPAQ_SA_L_W:
14578 check_dsp(ctx);
14579 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
14580 break;
14581 case OPC_DPSQ_SA_L_W:
14582 check_dsp(ctx);
14583 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
14584 break;
14585 case OPC_MAQ_S_W_PHL:
14586 check_dsp(ctx);
14587 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
14588 break;
14589 case OPC_MAQ_S_W_PHR:
14590 check_dsp(ctx);
14591 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
14592 break;
14593 case OPC_MAQ_SA_W_PHL:
14594 check_dsp(ctx);
14595 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
14596 break;
14597 case OPC_MAQ_SA_W_PHR:
14598 check_dsp(ctx);
14599 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
14600 break;
14601 case OPC_MULSA_W_PH:
14602 check_dspr2(ctx);
14603 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
14604 break;
14605 }
14606 break;
14607 #ifdef TARGET_MIPS64
14608 case OPC_DPAQ_W_QH_DSP:
14609 {
14610 int ac = ret & 0x03;
14611 tcg_gen_movi_i32(t0, ac);
14612
14613 switch (op2) {
14614 case OPC_DMADD:
14615 check_dsp(ctx);
14616 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
14617 break;
14618 case OPC_DMADDU:
14619 check_dsp(ctx);
14620 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
14621 break;
14622 case OPC_DMSUB:
14623 check_dsp(ctx);
14624 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
14625 break;
14626 case OPC_DMSUBU:
14627 check_dsp(ctx);
14628 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
14629 break;
14630 case OPC_DPA_W_QH:
14631 check_dspr2(ctx);
14632 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
14633 break;
14634 case OPC_DPAQ_S_W_QH:
14635 check_dsp(ctx);
14636 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14637 break;
14638 case OPC_DPAQ_SA_L_PW:
14639 check_dsp(ctx);
14640 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
14641 break;
14642 case OPC_DPAU_H_OBL:
14643 check_dsp(ctx);
14644 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
14645 break;
14646 case OPC_DPAU_H_OBR:
14647 check_dsp(ctx);
14648 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
14649 break;
14650 case OPC_DPS_W_QH:
14651 check_dspr2(ctx);
14652 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
14653 break;
14654 case OPC_DPSQ_S_W_QH:
14655 check_dsp(ctx);
14656 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14657 break;
14658 case OPC_DPSQ_SA_L_PW:
14659 check_dsp(ctx);
14660 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
14661 break;
14662 case OPC_DPSU_H_OBL:
14663 check_dsp(ctx);
14664 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
14665 break;
14666 case OPC_DPSU_H_OBR:
14667 check_dsp(ctx);
14668 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
14669 break;
14670 case OPC_MAQ_S_L_PWL:
14671 check_dsp(ctx);
14672 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
14673 break;
14674 case OPC_MAQ_S_L_PWR:
14675 check_dsp(ctx);
14676 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
14677 break;
14678 case OPC_MAQ_S_W_QHLL:
14679 check_dsp(ctx);
14680 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
14681 break;
14682 case OPC_MAQ_SA_W_QHLL:
14683 check_dsp(ctx);
14684 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
14685 break;
14686 case OPC_MAQ_S_W_QHLR:
14687 check_dsp(ctx);
14688 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
14689 break;
14690 case OPC_MAQ_SA_W_QHLR:
14691 check_dsp(ctx);
14692 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
14693 break;
14694 case OPC_MAQ_S_W_QHRL:
14695 check_dsp(ctx);
14696 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
14697 break;
14698 case OPC_MAQ_SA_W_QHRL:
14699 check_dsp(ctx);
14700 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
14701 break;
14702 case OPC_MAQ_S_W_QHRR:
14703 check_dsp(ctx);
14704 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
14705 break;
14706 case OPC_MAQ_SA_W_QHRR:
14707 check_dsp(ctx);
14708 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
14709 break;
14710 case OPC_MULSAQ_S_L_PW:
14711 check_dsp(ctx);
14712 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
14713 break;
14714 case OPC_MULSAQ_S_W_QH:
14715 check_dsp(ctx);
14716 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
14717 break;
14718 }
14719 }
14720 break;
14721 #endif
14722 case OPC_ADDU_QB_DSP:
14723 switch (op2) {
14724 case OPC_MULEU_S_PH_QBL:
14725 check_dsp(ctx);
14726 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14727 break;
14728 case OPC_MULEU_S_PH_QBR:
14729 check_dsp(ctx);
14730 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14731 break;
14732 case OPC_MULQ_RS_PH:
14733 check_dsp(ctx);
14734 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14735 break;
14736 case OPC_MULEQ_S_W_PHL:
14737 check_dsp(ctx);
14738 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14739 break;
14740 case OPC_MULEQ_S_W_PHR:
14741 check_dsp(ctx);
14742 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14743 break;
14744 case OPC_MULQ_S_PH:
14745 check_dspr2(ctx);
14746 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14747 break;
14748 }
14749 break;
14750 #ifdef TARGET_MIPS64
14751 case OPC_ADDU_OB_DSP:
14752 switch (op2) {
14753 case OPC_MULEQ_S_PW_QHL:
14754 check_dsp(ctx);
14755 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14756 break;
14757 case OPC_MULEQ_S_PW_QHR:
14758 check_dsp(ctx);
14759 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14760 break;
14761 case OPC_MULEU_S_QH_OBL:
14762 check_dsp(ctx);
14763 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14764 break;
14765 case OPC_MULEU_S_QH_OBR:
14766 check_dsp(ctx);
14767 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14768 break;
14769 case OPC_MULQ_RS_QH:
14770 check_dsp(ctx);
14771 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14772 break;
14773 }
14774 break;
14775 #endif
14776 }
14777
14778 tcg_temp_free_i32(t0);
14779 tcg_temp_free(v1_t);
14780 tcg_temp_free(v2_t);
14781
14782 (void)opn; /* avoid a compiler warning */
14783 MIPS_DEBUG("%s", opn);
14784
14785 }
14786
14787 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14788 int ret, int val)
14789 {
14790 const char *opn = "mipsdsp Bit/ Manipulation";
14791 int16_t imm;
14792 TCGv t0;
14793 TCGv val_t;
14794
14795 if (ret == 0) {
14796 /* Treat as NOP. */
14797 MIPS_DEBUG("NOP");
14798 return;
14799 }
14800
14801 t0 = tcg_temp_new();
14802 val_t = tcg_temp_new();
14803 gen_load_gpr(val_t, val);
14804
14805 switch (op1) {
14806 case OPC_ABSQ_S_PH_DSP:
14807 switch (op2) {
14808 case OPC_BITREV:
14809 check_dsp(ctx);
14810 gen_helper_bitrev(cpu_gpr[ret], val_t);
14811 break;
14812 case OPC_REPL_QB:
14813 check_dsp(ctx);
14814 {
14815 target_long result;
14816 imm = (ctx->opcode >> 16) & 0xFF;
14817 result = (uint32_t)imm << 24 |
14818 (uint32_t)imm << 16 |
14819 (uint32_t)imm << 8 |
14820 (uint32_t)imm;
14821 result = (int32_t)result;
14822 tcg_gen_movi_tl(cpu_gpr[ret], result);
14823 }
14824 break;
14825 case OPC_REPLV_QB:
14826 check_dsp(ctx);
14827 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
14828 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
14829 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14830 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14831 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14832 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14833 break;
14834 case OPC_REPL_PH:
14835 check_dsp(ctx);
14836 {
14837 imm = (ctx->opcode >> 16) & 0x03FF;
14838 imm = (int16_t)(imm << 6) >> 6;
14839 tcg_gen_movi_tl(cpu_gpr[ret], \
14840 (target_long)((int32_t)imm << 16 | \
14841 (uint16_t)imm));
14842 }
14843 break;
14844 case OPC_REPLV_PH:
14845 check_dsp(ctx);
14846 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
14847 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14848 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14849 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
14850 break;
14851 }
14852 break;
14853 #ifdef TARGET_MIPS64
14854 case OPC_ABSQ_S_QH_DSP:
14855 switch (op2) {
14856 case OPC_REPL_OB:
14857 check_dsp(ctx);
14858 {
14859 target_long temp;
14860
14861 imm = (ctx->opcode >> 16) & 0xFF;
14862 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
14863 temp = (temp << 16) | temp;
14864 temp = (temp << 32) | temp;
14865 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14866 break;
14867 }
14868 case OPC_REPL_PW:
14869 check_dsp(ctx);
14870 {
14871 target_long temp;
14872
14873 imm = (ctx->opcode >> 16) & 0x03FF;
14874 imm = (int16_t)(imm << 6) >> 6;
14875 temp = ((target_long)imm << 32) \
14876 | ((target_long)imm & 0xFFFFFFFF);
14877 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14878 break;
14879 }
14880 case OPC_REPL_QH:
14881 check_dsp(ctx);
14882 {
14883 target_long temp;
14884
14885 imm = (ctx->opcode >> 16) & 0x03FF;
14886 imm = (int16_t)(imm << 6) >> 6;
14887
14888 temp = ((uint64_t)(uint16_t)imm << 48) |
14889 ((uint64_t)(uint16_t)imm << 32) |
14890 ((uint64_t)(uint16_t)imm << 16) |
14891 (uint64_t)(uint16_t)imm;
14892 tcg_gen_movi_tl(cpu_gpr[ret], temp);
14893 break;
14894 }
14895 case OPC_REPLV_OB:
14896 check_dsp(ctx);
14897 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
14898 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
14899 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14900 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14901 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14902 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14903 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14904 break;
14905 case OPC_REPLV_PW:
14906 check_dsp(ctx);
14907 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
14908 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14909 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14910 break;
14911 case OPC_REPLV_QH:
14912 check_dsp(ctx);
14913 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
14914 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
14915 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14916 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
14917 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
14918 break;
14919 }
14920 break;
14921 #endif
14922 }
14923 tcg_temp_free(t0);
14924 tcg_temp_free(val_t);
14925
14926 (void)opn; /* avoid a compiler warning */
14927 MIPS_DEBUG("%s", opn);
14928 }
14929
14930 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
14931 uint32_t op1, uint32_t op2,
14932 int ret, int v1, int v2, int check_ret)
14933 {
14934 const char *opn = "mipsdsp add compare pick";
14935 TCGv t1;
14936 TCGv v1_t;
14937 TCGv v2_t;
14938
14939 if ((ret == 0) && (check_ret == 1)) {
14940 /* Treat as NOP. */
14941 MIPS_DEBUG("NOP");
14942 return;
14943 }
14944
14945 t1 = tcg_temp_new();
14946 v1_t = tcg_temp_new();
14947 v2_t = tcg_temp_new();
14948
14949 gen_load_gpr(v1_t, v1);
14950 gen_load_gpr(v2_t, v2);
14951
14952 switch (op1) {
14953 case OPC_CMPU_EQ_QB_DSP:
14954 switch (op2) {
14955 case OPC_CMPU_EQ_QB:
14956 check_dsp(ctx);
14957 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
14958 break;
14959 case OPC_CMPU_LT_QB:
14960 check_dsp(ctx);
14961 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
14962 break;
14963 case OPC_CMPU_LE_QB:
14964 check_dsp(ctx);
14965 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
14966 break;
14967 case OPC_CMPGU_EQ_QB:
14968 check_dsp(ctx);
14969 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
14970 break;
14971 case OPC_CMPGU_LT_QB:
14972 check_dsp(ctx);
14973 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
14974 break;
14975 case OPC_CMPGU_LE_QB:
14976 check_dsp(ctx);
14977 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
14978 break;
14979 case OPC_CMPGDU_EQ_QB:
14980 check_dspr2(ctx);
14981 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
14982 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14983 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14984 tcg_gen_shli_tl(t1, t1, 24);
14985 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14986 break;
14987 case OPC_CMPGDU_LT_QB:
14988 check_dspr2(ctx);
14989 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
14990 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14991 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
14992 tcg_gen_shli_tl(t1, t1, 24);
14993 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
14994 break;
14995 case OPC_CMPGDU_LE_QB:
14996 check_dspr2(ctx);
14997 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
14998 tcg_gen_mov_tl(cpu_gpr[ret], t1);
14999 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
15000 tcg_gen_shli_tl(t1, t1, 24);
15001 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
15002 break;
15003 case OPC_CMP_EQ_PH:
15004 check_dsp(ctx);
15005 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
15006 break;
15007 case OPC_CMP_LT_PH:
15008 check_dsp(ctx);
15009 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
15010 break;
15011 case OPC_CMP_LE_PH:
15012 check_dsp(ctx);
15013 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
15014 break;
15015 case OPC_PICK_QB:
15016 check_dsp(ctx);
15017 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15018 break;
15019 case OPC_PICK_PH:
15020 check_dsp(ctx);
15021 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15022 break;
15023 case OPC_PACKRL_PH:
15024 check_dsp(ctx);
15025 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
15026 break;
15027 }
15028 break;
15029 #ifdef TARGET_MIPS64
15030 case OPC_CMPU_EQ_OB_DSP:
15031 switch (op2) {
15032 case OPC_CMP_EQ_PW:
15033 check_dsp(ctx);
15034 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
15035 break;
15036 case OPC_CMP_LT_PW:
15037 check_dsp(ctx);
15038 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
15039 break;
15040 case OPC_CMP_LE_PW:
15041 check_dsp(ctx);
15042 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
15043 break;
15044 case OPC_CMP_EQ_QH:
15045 check_dsp(ctx);
15046 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
15047 break;
15048 case OPC_CMP_LT_QH:
15049 check_dsp(ctx);
15050 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
15051 break;
15052 case OPC_CMP_LE_QH:
15053 check_dsp(ctx);
15054 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
15055 break;
15056 case OPC_CMPGDU_EQ_OB:
15057 check_dspr2(ctx);
15058 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15059 break;
15060 case OPC_CMPGDU_LT_OB:
15061 check_dspr2(ctx);
15062 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15063 break;
15064 case OPC_CMPGDU_LE_OB:
15065 check_dspr2(ctx);
15066 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15067 break;
15068 case OPC_CMPGU_EQ_OB:
15069 check_dsp(ctx);
15070 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
15071 break;
15072 case OPC_CMPGU_LT_OB:
15073 check_dsp(ctx);
15074 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
15075 break;
15076 case OPC_CMPGU_LE_OB:
15077 check_dsp(ctx);
15078 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
15079 break;
15080 case OPC_CMPU_EQ_OB:
15081 check_dsp(ctx);
15082 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
15083 break;
15084 case OPC_CMPU_LT_OB:
15085 check_dsp(ctx);
15086 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
15087 break;
15088 case OPC_CMPU_LE_OB:
15089 check_dsp(ctx);
15090 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
15091 break;
15092 case OPC_PACKRL_PW:
15093 check_dsp(ctx);
15094 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
15095 break;
15096 case OPC_PICK_OB:
15097 check_dsp(ctx);
15098 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15099 break;
15100 case OPC_PICK_PW:
15101 check_dsp(ctx);
15102 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15103 break;
15104 case OPC_PICK_QH:
15105 check_dsp(ctx);
15106 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
15107 break;
15108 }
15109 break;
15110 #endif
15111 }
15112
15113 tcg_temp_free(t1);
15114 tcg_temp_free(v1_t);
15115 tcg_temp_free(v2_t);
15116
15117 (void)opn; /* avoid a compiler warning */
15118 MIPS_DEBUG("%s", opn);
15119 }
15120
15121 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
15122 uint32_t op1, int rt, int rs, int sa)
15123 {
15124 const char *opn = "mipsdsp append/dappend";
15125 TCGv t0;
15126
15127 check_dspr2(ctx);
15128
15129 if (rt == 0) {
15130 /* Treat as NOP. */
15131 MIPS_DEBUG("NOP");
15132 return;
15133 }
15134
15135 t0 = tcg_temp_new();
15136 gen_load_gpr(t0, rs);
15137
15138 switch (op1) {
15139 case OPC_APPEND_DSP:
15140 switch (MASK_APPEND(ctx->opcode)) {
15141 case OPC_APPEND:
15142 if (sa != 0) {
15143 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
15144 }
15145 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15146 break;
15147 case OPC_PREPEND:
15148 if (sa != 0) {
15149 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
15150 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15151 tcg_gen_shli_tl(t0, t0, 32 - sa);
15152 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15153 }
15154 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15155 break;
15156 case OPC_BALIGN:
15157 sa &= 3;
15158 if (sa != 0 && sa != 2) {
15159 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15160 tcg_gen_ext32u_tl(t0, t0);
15161 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
15162 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15163 }
15164 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
15165 break;
15166 default: /* Invalid */
15167 MIPS_INVAL("MASK APPEND");
15168 generate_exception(ctx, EXCP_RI);
15169 break;
15170 }
15171 break;
15172 #ifdef TARGET_MIPS64
15173 case OPC_DAPPEND_DSP:
15174 switch (MASK_DAPPEND(ctx->opcode)) {
15175 case OPC_DAPPEND:
15176 if (sa != 0) {
15177 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
15178 }
15179 break;
15180 case OPC_PREPENDD:
15181 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
15182 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
15183 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
15184 break;
15185 case OPC_PREPENDW:
15186 if (sa != 0) {
15187 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
15188 tcg_gen_shli_tl(t0, t0, 64 - sa);
15189 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15190 }
15191 break;
15192 case OPC_DBALIGN:
15193 sa &= 7;
15194 if (sa != 0 && sa != 2 && sa != 4) {
15195 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
15196 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
15197 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
15198 }
15199 break;
15200 default: /* Invalid */
15201 MIPS_INVAL("MASK DAPPEND");
15202 generate_exception(ctx, EXCP_RI);
15203 break;
15204 }
15205 break;
15206 #endif
15207 }
15208 tcg_temp_free(t0);
15209 (void)opn; /* avoid a compiler warning */
15210 MIPS_DEBUG("%s", opn);
15211 }
15212
15213 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
15214 int ret, int v1, int v2, int check_ret)
15215
15216 {
15217 const char *opn = "mipsdsp accumulator";
15218 TCGv t0;
15219 TCGv t1;
15220 TCGv v1_t;
15221 TCGv v2_t;
15222 int16_t imm;
15223
15224 if ((ret == 0) && (check_ret == 1)) {
15225 /* Treat as NOP. */
15226 MIPS_DEBUG("NOP");
15227 return;
15228 }
15229
15230 t0 = tcg_temp_new();
15231 t1 = tcg_temp_new();
15232 v1_t = tcg_temp_new();
15233 v2_t = tcg_temp_new();
15234
15235 gen_load_gpr(v1_t, v1);
15236 gen_load_gpr(v2_t, v2);
15237
15238 switch (op1) {
15239 case OPC_EXTR_W_DSP:
15240 check_dsp(ctx);
15241 switch (op2) {
15242 case OPC_EXTR_W:
15243 tcg_gen_movi_tl(t0, v2);
15244 tcg_gen_movi_tl(t1, v1);
15245 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
15246 break;
15247 case OPC_EXTR_R_W:
15248 tcg_gen_movi_tl(t0, v2);
15249 tcg_gen_movi_tl(t1, v1);
15250 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15251 break;
15252 case OPC_EXTR_RS_W:
15253 tcg_gen_movi_tl(t0, v2);
15254 tcg_gen_movi_tl(t1, v1);
15255 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15256 break;
15257 case OPC_EXTR_S_H:
15258 tcg_gen_movi_tl(t0, v2);
15259 tcg_gen_movi_tl(t1, v1);
15260 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15261 break;
15262 case OPC_EXTRV_S_H:
15263 tcg_gen_movi_tl(t0, v2);
15264 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
15265 break;
15266 case OPC_EXTRV_W:
15267 tcg_gen_movi_tl(t0, v2);
15268 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15269 break;
15270 case OPC_EXTRV_R_W:
15271 tcg_gen_movi_tl(t0, v2);
15272 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15273 break;
15274 case OPC_EXTRV_RS_W:
15275 tcg_gen_movi_tl(t0, v2);
15276 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15277 break;
15278 case OPC_EXTP:
15279 tcg_gen_movi_tl(t0, v2);
15280 tcg_gen_movi_tl(t1, v1);
15281 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
15282 break;
15283 case OPC_EXTPV:
15284 tcg_gen_movi_tl(t0, v2);
15285 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
15286 break;
15287 case OPC_EXTPDP:
15288 tcg_gen_movi_tl(t0, v2);
15289 tcg_gen_movi_tl(t1, v1);
15290 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
15291 break;
15292 case OPC_EXTPDPV:
15293 tcg_gen_movi_tl(t0, v2);
15294 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15295 break;
15296 case OPC_SHILO:
15297 imm = (ctx->opcode >> 20) & 0x3F;
15298 tcg_gen_movi_tl(t0, ret);
15299 tcg_gen_movi_tl(t1, imm);
15300 gen_helper_shilo(t0, t1, cpu_env);
15301 break;
15302 case OPC_SHILOV:
15303 tcg_gen_movi_tl(t0, ret);
15304 gen_helper_shilo(t0, v1_t, cpu_env);
15305 break;
15306 case OPC_MTHLIP:
15307 tcg_gen_movi_tl(t0, ret);
15308 gen_helper_mthlip(t0, v1_t, cpu_env);
15309 break;
15310 case OPC_WRDSP:
15311 imm = (ctx->opcode >> 11) & 0x3FF;
15312 tcg_gen_movi_tl(t0, imm);
15313 gen_helper_wrdsp(v1_t, t0, cpu_env);
15314 break;
15315 case OPC_RDDSP:
15316 imm = (ctx->opcode >> 16) & 0x03FF;
15317 tcg_gen_movi_tl(t0, imm);
15318 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
15319 break;
15320 }
15321 break;
15322 #ifdef TARGET_MIPS64
15323 case OPC_DEXTR_W_DSP:
15324 check_dsp(ctx);
15325 switch (op2) {
15326 case OPC_DMTHLIP:
15327 tcg_gen_movi_tl(t0, ret);
15328 gen_helper_dmthlip(v1_t, t0, cpu_env);
15329 break;
15330 case OPC_DSHILO:
15331 {
15332 int shift = (ctx->opcode >> 19) & 0x7F;
15333 int ac = (ctx->opcode >> 11) & 0x03;
15334 tcg_gen_movi_tl(t0, shift);
15335 tcg_gen_movi_tl(t1, ac);
15336 gen_helper_dshilo(t0, t1, cpu_env);
15337 break;
15338 }
15339 case OPC_DSHILOV:
15340 {
15341 int ac = (ctx->opcode >> 11) & 0x03;
15342 tcg_gen_movi_tl(t0, ac);
15343 gen_helper_dshilo(v1_t, t0, cpu_env);
15344 break;
15345 }
15346 case OPC_DEXTP:
15347 tcg_gen_movi_tl(t0, v2);
15348 tcg_gen_movi_tl(t1, v1);
15349
15350 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
15351 break;
15352 case OPC_DEXTPV:
15353 tcg_gen_movi_tl(t0, v2);
15354 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
15355 break;
15356 case OPC_DEXTPDP:
15357 tcg_gen_movi_tl(t0, v2);
15358 tcg_gen_movi_tl(t1, v1);
15359 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
15360 break;
15361 case OPC_DEXTPDPV:
15362 tcg_gen_movi_tl(t0, v2);
15363 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
15364 break;
15365 case OPC_DEXTR_L:
15366 tcg_gen_movi_tl(t0, v2);
15367 tcg_gen_movi_tl(t1, v1);
15368 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
15369 break;
15370 case OPC_DEXTR_R_L:
15371 tcg_gen_movi_tl(t0, v2);
15372 tcg_gen_movi_tl(t1, v1);
15373 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
15374 break;
15375 case OPC_DEXTR_RS_L:
15376 tcg_gen_movi_tl(t0, v2);
15377 tcg_gen_movi_tl(t1, v1);
15378 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
15379 break;
15380 case OPC_DEXTR_W:
15381 tcg_gen_movi_tl(t0, v2);
15382 tcg_gen_movi_tl(t1, v1);
15383 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
15384 break;
15385 case OPC_DEXTR_R_W:
15386 tcg_gen_movi_tl(t0, v2);
15387 tcg_gen_movi_tl(t1, v1);
15388 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
15389 break;
15390 case OPC_DEXTR_RS_W:
15391 tcg_gen_movi_tl(t0, v2);
15392 tcg_gen_movi_tl(t1, v1);
15393 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
15394 break;
15395 case OPC_DEXTR_S_H:
15396 tcg_gen_movi_tl(t0, v2);
15397 tcg_gen_movi_tl(t1, v1);
15398 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15399 break;
15400 case OPC_DEXTRV_S_H:
15401 tcg_gen_movi_tl(t0, v2);
15402 tcg_gen_movi_tl(t1, v1);
15403 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
15404 break;
15405 case OPC_DEXTRV_L:
15406 tcg_gen_movi_tl(t0, v2);
15407 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15408 break;
15409 case OPC_DEXTRV_R_L:
15410 tcg_gen_movi_tl(t0, v2);
15411 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15412 break;
15413 case OPC_DEXTRV_RS_L:
15414 tcg_gen_movi_tl(t0, v2);
15415 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
15416 break;
15417 case OPC_DEXTRV_W:
15418 tcg_gen_movi_tl(t0, v2);
15419 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15420 break;
15421 case OPC_DEXTRV_R_W:
15422 tcg_gen_movi_tl(t0, v2);
15423 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15424 break;
15425 case OPC_DEXTRV_RS_W:
15426 tcg_gen_movi_tl(t0, v2);
15427 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
15428 break;
15429 }
15430 break;
15431 #endif
15432 }
15433
15434 tcg_temp_free(t0);
15435 tcg_temp_free(t1);
15436 tcg_temp_free(v1_t);
15437 tcg_temp_free(v2_t);
15438
15439 (void)opn; /* avoid a compiler warning */
15440 MIPS_DEBUG("%s", opn);
15441 }
15442
15443 /* End MIPSDSP functions. */
15444
15445 /* Compact Branches */
15446 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
15447 int rs, int rt, int32_t offset)
15448 {
15449 int bcond_compute = 0;
15450 TCGv t0 = tcg_temp_new();
15451 TCGv t1 = tcg_temp_new();
15452
15453 if (ctx->hflags & MIPS_HFLAG_BMASK) {
15454 #ifdef MIPS_DEBUG_DISAS
15455 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
15456 #endif
15457 generate_exception(ctx, EXCP_RI);
15458 goto out;
15459 }
15460
15461 /* Load needed operands and calculate btarget */
15462 switch (opc) {
15463 /* compact branch */
15464 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15465 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15466 gen_load_gpr(t0, rs);
15467 gen_load_gpr(t1, rt);
15468 bcond_compute = 1;
15469 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15470 if (rs <= rt && rs == 0) {
15471 /* OPC_BEQZALC, OPC_BNEZALC */
15472 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15473 }
15474 break;
15475 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15476 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15477 gen_load_gpr(t0, rs);
15478 gen_load_gpr(t1, rt);
15479 bcond_compute = 1;
15480 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15481 break;
15482 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15483 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15484 if (rs == 0 || rs == rt) {
15485 /* OPC_BLEZALC, OPC_BGEZALC */
15486 /* OPC_BGTZALC, OPC_BLTZALC */
15487 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15488 }
15489 gen_load_gpr(t0, rs);
15490 gen_load_gpr(t1, rt);
15491 bcond_compute = 1;
15492 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15493 break;
15494 case OPC_BC:
15495 case OPC_BALC:
15496 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15497 break;
15498 case OPC_BEQZC:
15499 case OPC_BNEZC:
15500 if (rs != 0) {
15501 /* OPC_BEQZC, OPC_BNEZC */
15502 gen_load_gpr(t0, rs);
15503 bcond_compute = 1;
15504 ctx->btarget = addr_add(ctx, ctx->pc + 4, offset);
15505 } else {
15506 /* OPC_JIC, OPC_JIALC */
15507 TCGv tbase = tcg_temp_new();
15508 TCGv toffset = tcg_temp_new();
15509
15510 gen_load_gpr(tbase, rt);
15511 tcg_gen_movi_tl(toffset, offset);
15512 gen_op_addr_add(ctx, btarget, tbase, toffset);
15513 tcg_temp_free(tbase);
15514 tcg_temp_free(toffset);
15515 }
15516 break;
15517 default:
15518 MIPS_INVAL("Compact branch/jump");
15519 generate_exception(ctx, EXCP_RI);
15520 goto out;
15521 }
15522
15523 if (bcond_compute == 0) {
15524 /* Uncoditional compact branch */
15525 switch (opc) {
15526 case OPC_JIALC:
15527 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15528 /* Fallthrough */
15529 case OPC_JIC:
15530 ctx->hflags |= MIPS_HFLAG_BR;
15531 break;
15532 case OPC_BALC:
15533 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 4);
15534 /* Fallthrough */
15535 case OPC_BC:
15536 ctx->hflags |= MIPS_HFLAG_B;
15537 break;
15538 default:
15539 MIPS_INVAL("Compact branch/jump");
15540 generate_exception(ctx, EXCP_RI);
15541 goto out;
15542 }
15543
15544 /* Generating branch here as compact branches don't have delay slot */
15545 gen_branch(ctx, 4);
15546 } else {
15547 /* Conditional compact branch */
15548 int l1 = gen_new_label();
15549 save_cpu_state(ctx, 0);
15550
15551 switch (opc) {
15552 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
15553 if (rs == 0 && rt != 0) {
15554 /* OPC_BLEZALC */
15555 tcg_gen_brcondi_tl(TCG_COND_LE, t1, 0, l1);
15556 } else if (rs != 0 && rt != 0 && rs == rt) {
15557 /* OPC_BGEZALC */
15558 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
15559 } else {
15560 /* OPC_BGEUC */
15561 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
15562 }
15563 break;
15564 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
15565 if (rs == 0 && rt != 0) {
15566 /* OPC_BGTZALC */
15567 tcg_gen_brcondi_tl(TCG_COND_GT, t1, 0, l1);
15568 } else if (rs != 0 && rt != 0 && rs == rt) {
15569 /* OPC_BLTZALC */
15570 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
15571 } else {
15572 /* OPC_BLTUC */
15573 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
15574 }
15575 break;
15576 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
15577 if (rs == 0 && rt != 0) {
15578 /* OPC_BLEZC */
15579 tcg_gen_brcondi_tl(TCG_COND_LE, t1, 0, l1);
15580 } else if (rs != 0 && rt != 0 && rs == rt) {
15581 /* OPC_BGEZC */
15582 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
15583 } else {
15584 /* OPC_BGEC */
15585 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
15586 }
15587 break;
15588 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
15589 if (rs == 0 && rt != 0) {
15590 /* OPC_BGTZC */
15591 tcg_gen_brcondi_tl(TCG_COND_GT, t1, 0, l1);
15592 } else if (rs != 0 && rt != 0 && rs == rt) {
15593 /* OPC_BLTZC */
15594 tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1);
15595 } else {
15596 /* OPC_BLTC */
15597 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
15598 }
15599 break;
15600 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
15601 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15602 if (rs >= rt) {
15603 /* OPC_BOVC, OPC_BNVC */
15604 TCGv t2 = tcg_temp_new();
15605 TCGv t3 = tcg_temp_new();
15606 TCGv t4 = tcg_temp_new();
15607 TCGv input_overflow = tcg_temp_new();
15608
15609 gen_load_gpr(t0, rs);
15610 gen_load_gpr(t1, rt);
15611 tcg_gen_ext32s_tl(t2, t0);
15612 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
15613 tcg_gen_ext32s_tl(t3, t1);
15614 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
15615 tcg_gen_or_tl(input_overflow, input_overflow, t4);
15616
15617 tcg_gen_add_tl(t4, t2, t3);
15618 tcg_gen_ext32s_tl(t4, t4);
15619 tcg_gen_xor_tl(t2, t2, t3);
15620 tcg_gen_xor_tl(t3, t4, t3);
15621 tcg_gen_andc_tl(t2, t3, t2);
15622 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
15623 tcg_gen_or_tl(t4, t4, input_overflow);
15624 if (opc == OPC_BOVC) {
15625 /* OPC_BOVC */
15626 tcg_gen_brcondi_tl(TCG_COND_NE, t4, 0, l1);
15627 } else {
15628 /* OPC_BNVC */
15629 tcg_gen_brcondi_tl(TCG_COND_EQ, t4, 0, l1);
15630 }
15631 tcg_temp_free(input_overflow);
15632 tcg_temp_free(t4);
15633 tcg_temp_free(t3);
15634 tcg_temp_free(t2);
15635 } else if (rs < rt && rs == 0) {
15636 /* OPC_BEQZALC, OPC_BNEZALC */
15637 if (opc == OPC_BEQZALC) {
15638 /* OPC_BEQZALC */
15639 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
15640 } else {
15641 /* OPC_BNEZALC */
15642 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
15643 }
15644 } else {
15645 /* OPC_BEQC, OPC_BNEC */
15646 if (opc == OPC_BEQC) {
15647 /* OPC_BEQC */
15648 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
15649 } else {
15650 /* OPC_BNEC */
15651 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
15652 }
15653 }
15654 break;
15655 case OPC_BEQZC:
15656 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
15657 break;
15658 case OPC_BNEZC:
15659 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
15660 break;
15661 default:
15662 MIPS_INVAL("Compact conditional branch/jump");
15663 generate_exception(ctx, EXCP_RI);
15664 goto out;
15665 }
15666
15667 /* Generating branch here as compact branches don't have delay slot */
15668 /* TODO: implement forbidden slot */
15669 gen_goto_tb(ctx, 1, ctx->pc + 4);
15670 gen_set_label(l1);
15671 gen_goto_tb(ctx, 0, ctx->btarget);
15672 MIPS_DEBUG("Compact conditional branch");
15673 ctx->bstate = BS_BRANCH;
15674 }
15675
15676 out:
15677 tcg_temp_free(t0);
15678 tcg_temp_free(t1);
15679 }
15680
15681 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
15682 {
15683 int rs, rt, rd, sa;
15684 uint32_t op1, op2;
15685
15686 rs = (ctx->opcode >> 21) & 0x1f;
15687 rt = (ctx->opcode >> 16) & 0x1f;
15688 rd = (ctx->opcode >> 11) & 0x1f;
15689 sa = (ctx->opcode >> 6) & 0x1f;
15690
15691 op1 = MASK_SPECIAL(ctx->opcode);
15692 switch (op1) {
15693 case OPC_LSA:
15694 if (rd != 0) {
15695 int imm2 = extract32(ctx->opcode, 6, 3);
15696 TCGv t0 = tcg_temp_new();
15697 TCGv t1 = tcg_temp_new();
15698 gen_load_gpr(t0, rs);
15699 gen_load_gpr(t1, rt);
15700 tcg_gen_shli_tl(t0, t0, imm2 + 1);
15701 tcg_gen_add_tl(t0, t0, t1);
15702 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
15703 tcg_temp_free(t1);
15704 tcg_temp_free(t0);
15705 }
15706 break;
15707 case OPC_MULT ... OPC_DIVU:
15708 op2 = MASK_R6_MULDIV(ctx->opcode);
15709 switch (op2) {
15710 case R6_OPC_MUL:
15711 case R6_OPC_MUH:
15712 case R6_OPC_MULU:
15713 case R6_OPC_MUHU:
15714 case R6_OPC_DIV:
15715 case R6_OPC_MOD:
15716 case R6_OPC_DIVU:
15717 case R6_OPC_MODU:
15718 gen_r6_muldiv(ctx, op2, rd, rs, rt);
15719 break;
15720 default:
15721 MIPS_INVAL("special_r6 muldiv");
15722 generate_exception(ctx, EXCP_RI);
15723 break;
15724 }
15725 break;
15726 case OPC_SELEQZ:
15727 case OPC_SELNEZ:
15728 gen_cond_move(ctx, op1, rd, rs, rt);
15729 break;
15730 case R6_OPC_CLO:
15731 case R6_OPC_CLZ:
15732 if (rt == 0 && sa == 1) {
15733 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15734 We need additionally to check other fields */
15735 gen_cl(ctx, op1, rd, rs);
15736 } else {
15737 generate_exception(ctx, EXCP_RI);
15738 }
15739 break;
15740 case R6_OPC_SDBBP:
15741 generate_exception(ctx, EXCP_DBp);
15742 break;
15743 #if defined(TARGET_MIPS64)
15744 case OPC_DLSA:
15745 check_mips_64(ctx);
15746 if (rd != 0) {
15747 int imm2 = extract32(ctx->opcode, 6, 3);
15748 TCGv t0 = tcg_temp_new();
15749 TCGv t1 = tcg_temp_new();
15750 gen_load_gpr(t0, rs);
15751 gen_load_gpr(t1, rt);
15752 tcg_gen_shli_tl(t0, t0, imm2 + 1);
15753 tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
15754 tcg_temp_free(t1);
15755 tcg_temp_free(t0);
15756 }
15757 break;
15758 case R6_OPC_DCLO:
15759 case R6_OPC_DCLZ:
15760 if (rt == 0 && sa == 1) {
15761 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15762 We need additionally to check other fields */
15763 check_mips_64(ctx);
15764 gen_cl(ctx, op1, rd, rs);
15765 } else {
15766 generate_exception(ctx, EXCP_RI);
15767 }
15768 break;
15769 case OPC_DMULT ... OPC_DDIVU:
15770 op2 = MASK_R6_MULDIV(ctx->opcode);
15771 switch (op2) {
15772 case R6_OPC_DMUL:
15773 case R6_OPC_DMUH:
15774 case R6_OPC_DMULU:
15775 case R6_OPC_DMUHU:
15776 case R6_OPC_DDIV:
15777 case R6_OPC_DMOD:
15778 case R6_OPC_DDIVU:
15779 case R6_OPC_DMODU:
15780 check_mips_64(ctx);
15781 gen_r6_muldiv(ctx, op2, rd, rs, rt);
15782 break;
15783 default:
15784 MIPS_INVAL("special_r6 muldiv");
15785 generate_exception(ctx, EXCP_RI);
15786 break;
15787 }
15788 break;
15789 #endif
15790 default: /* Invalid */
15791 MIPS_INVAL("special_r6");
15792 generate_exception(ctx, EXCP_RI);
15793 break;
15794 }
15795 }
15796
15797 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
15798 {
15799 int rs, rt, rd, sa;
15800 uint32_t op1;
15801
15802 rs = (ctx->opcode >> 21) & 0x1f;
15803 rt = (ctx->opcode >> 16) & 0x1f;
15804 rd = (ctx->opcode >> 11) & 0x1f;
15805 sa = (ctx->opcode >> 6) & 0x1f;
15806
15807 op1 = MASK_SPECIAL(ctx->opcode);
15808 switch (op1) {
15809 case OPC_MOVN: /* Conditional move */
15810 case OPC_MOVZ:
15811 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
15812 INSN_LOONGSON2E | INSN_LOONGSON2F);
15813 gen_cond_move(ctx, op1, rd, rs, rt);
15814 break;
15815 case OPC_MFHI: /* Move from HI/LO */
15816 case OPC_MFLO:
15817 gen_HILO(ctx, op1, rs & 3, rd);
15818 break;
15819 case OPC_MTHI:
15820 case OPC_MTLO: /* Move to HI/LO */
15821 gen_HILO(ctx, op1, rd & 3, rs);
15822 break;
15823 case OPC_MOVCI:
15824 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15825 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15826 check_cp1_enabled(ctx);
15827 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
15828 (ctx->opcode >> 16) & 1);
15829 } else {
15830 generate_exception_err(ctx, EXCP_CpU, 1);
15831 }
15832 break;
15833 case OPC_MULT:
15834 case OPC_MULTU:
15835 if (sa) {
15836 check_insn(ctx, INSN_VR54XX);
15837 op1 = MASK_MUL_VR54XX(ctx->opcode);
15838 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
15839 } else {
15840 gen_muldiv(ctx, op1, rd & 3, rs, rt);
15841 }
15842 break;
15843 case OPC_DIV:
15844 case OPC_DIVU:
15845 gen_muldiv(ctx, op1, 0, rs, rt);
15846 break;
15847 #if defined(TARGET_MIPS64)
15848 case OPC_DMULT ... OPC_DDIVU:
15849 check_insn(ctx, ISA_MIPS3);
15850 check_mips_64(ctx);
15851 gen_muldiv(ctx, op1, 0, rs, rt);
15852 break;
15853 #endif
15854 case OPC_SPIM:
15855 #ifdef MIPS_STRICT_STANDARD
15856 MIPS_INVAL("SPIM");
15857 generate_exception(ctx, EXCP_RI);
15858 #else
15859 /* Implemented as RI exception for now. */
15860 MIPS_INVAL("spim (unofficial)");
15861 generate_exception(ctx, EXCP_RI);
15862 #endif
15863 break;
15864 default: /* Invalid */
15865 MIPS_INVAL("special_legacy");
15866 generate_exception(ctx, EXCP_RI);
15867 break;
15868 }
15869 }
15870
15871 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
15872 {
15873 int rs, rt, rd, sa;
15874 uint32_t op1;
15875
15876 rs = (ctx->opcode >> 21) & 0x1f;
15877 rt = (ctx->opcode >> 16) & 0x1f;
15878 rd = (ctx->opcode >> 11) & 0x1f;
15879 sa = (ctx->opcode >> 6) & 0x1f;
15880
15881 op1 = MASK_SPECIAL(ctx->opcode);
15882 switch (op1) {
15883 case OPC_SLL: /* Shift with immediate */
15884 case OPC_SRA:
15885 gen_shift_imm(ctx, op1, rd, rt, sa);
15886 break;
15887 case OPC_SRL:
15888 switch ((ctx->opcode >> 21) & 0x1f) {
15889 case 1:
15890 /* rotr is decoded as srl on non-R2 CPUs */
15891 if (ctx->insn_flags & ISA_MIPS32R2) {
15892 op1 = OPC_ROTR;
15893 }
15894 /* Fallthrough */
15895 case 0:
15896 gen_shift_imm(ctx, op1, rd, rt, sa);
15897 break;
15898 default:
15899 generate_exception(ctx, EXCP_RI);
15900 break;
15901 }
15902 break;
15903 case OPC_ADD ... OPC_SUBU:
15904 gen_arith(ctx, op1, rd, rs, rt);
15905 break;
15906 case OPC_SLLV: /* Shifts */
15907 case OPC_SRAV:
15908 gen_shift(ctx, op1, rd, rs, rt);
15909 break;
15910 case OPC_SRLV:
15911 switch ((ctx->opcode >> 6) & 0x1f) {
15912 case 1:
15913 /* rotrv is decoded as srlv on non-R2 CPUs */
15914 if (ctx->insn_flags & ISA_MIPS32R2) {
15915 op1 = OPC_ROTRV;
15916 }
15917 /* Fallthrough */
15918 case 0:
15919 gen_shift(ctx, op1, rd, rs, rt);
15920 break;
15921 default:
15922 generate_exception(ctx, EXCP_RI);
15923 break;
15924 }
15925 break;
15926 case OPC_SLT: /* Set on less than */
15927 case OPC_SLTU:
15928 gen_slt(ctx, op1, rd, rs, rt);
15929 break;
15930 case OPC_AND: /* Logic*/
15931 case OPC_OR:
15932 case OPC_NOR:
15933 case OPC_XOR:
15934 gen_logic(ctx, op1, rd, rs, rt);
15935 break;
15936 case OPC_JR ... OPC_JALR:
15937 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
15938 break;
15939 case OPC_TGE ... OPC_TEQ: /* Traps */
15940 case OPC_TNE:
15941 gen_trap(ctx, op1, rs, rt, -1);
15942 break;
15943 case OPC_LSA: /* OPC_PMON */
15944 if (ctx->insn_flags & ISA_MIPS32R6) {
15945 decode_opc_special_r6(env, ctx);
15946 } else {
15947 /* Pmon entry point, also R4010 selsl */
15948 #ifdef MIPS_STRICT_STANDARD
15949 MIPS_INVAL("PMON / selsl");
15950 generate_exception(ctx, EXCP_RI);
15951 #else
15952 gen_helper_0e0i(pmon, sa);
15953 #endif
15954 }
15955 break;
15956 case OPC_SYSCALL:
15957 generate_exception(ctx, EXCP_SYSCALL);
15958 ctx->bstate = BS_STOP;
15959 break;
15960 case OPC_BREAK:
15961 generate_exception(ctx, EXCP_BREAK);
15962 break;
15963 case OPC_SYNC:
15964 /* Treat as NOP. */
15965 break;
15966
15967 #if defined(TARGET_MIPS64)
15968 /* MIPS64 specific opcodes */
15969 case OPC_DSLL:
15970 case OPC_DSRA:
15971 case OPC_DSLL32:
15972 case OPC_DSRA32:
15973 check_insn(ctx, ISA_MIPS3);
15974 check_mips_64(ctx);
15975 gen_shift_imm(ctx, op1, rd, rt, sa);
15976 break;
15977 case OPC_DSRL:
15978 switch ((ctx->opcode >> 21) & 0x1f) {
15979 case 1:
15980 /* drotr is decoded as dsrl on non-R2 CPUs */
15981 if (ctx->insn_flags & ISA_MIPS32R2) {
15982 op1 = OPC_DROTR;
15983 }
15984 /* Fallthrough */
15985 case 0:
15986 check_insn(ctx, ISA_MIPS3);
15987 check_mips_64(ctx);
15988 gen_shift_imm(ctx, op1, rd, rt, sa);
15989 break;
15990 default:
15991 generate_exception(ctx, EXCP_RI);
15992 break;
15993 }
15994 break;
15995 case OPC_DSRL32:
15996 switch ((ctx->opcode >> 21) & 0x1f) {
15997 case 1:
15998 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
15999 if (ctx->insn_flags & ISA_MIPS32R2) {
16000 op1 = OPC_DROTR32;
16001 }
16002 /* Fallthrough */
16003 case 0:
16004 check_insn(ctx, ISA_MIPS3);
16005 check_mips_64(ctx);
16006 gen_shift_imm(ctx, op1, rd, rt, sa);
16007 break;
16008 default:
16009 generate_exception(ctx, EXCP_RI);
16010 break;
16011 }
16012 break;
16013 case OPC_DADD ... OPC_DSUBU:
16014 check_insn(ctx, ISA_MIPS3);
16015 check_mips_64(ctx);
16016 gen_arith(ctx, op1, rd, rs, rt);
16017 break;
16018 case OPC_DSLLV:
16019 case OPC_DSRAV:
16020 check_insn(ctx, ISA_MIPS3);
16021 check_mips_64(ctx);
16022 gen_shift(ctx, op1, rd, rs, rt);
16023 break;
16024 case OPC_DSRLV:
16025 switch ((ctx->opcode >> 6) & 0x1f) {
16026 case 1:
16027 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16028 if (ctx->insn_flags & ISA_MIPS32R2) {
16029 op1 = OPC_DROTRV;
16030 }
16031 /* Fallthrough */
16032 case 0:
16033 check_insn(ctx, ISA_MIPS3);
16034 check_mips_64(ctx);
16035 gen_shift(ctx, op1, rd, rs, rt);
16036 break;
16037 default:
16038 generate_exception(ctx, EXCP_RI);
16039 break;
16040 }
16041 break;
16042 #endif
16043 default:
16044 if (ctx->insn_flags & ISA_MIPS32R6) {
16045 decode_opc_special_r6(env, ctx);
16046 } else {
16047 decode_opc_special_legacy(env, ctx);
16048 }
16049 }
16050 }
16051
16052 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
16053 {
16054 int rs, rt, rd;
16055 uint32_t op1;
16056
16057 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16058
16059 rs = (ctx->opcode >> 21) & 0x1f;
16060 rt = (ctx->opcode >> 16) & 0x1f;
16061 rd = (ctx->opcode >> 11) & 0x1f;
16062
16063 op1 = MASK_SPECIAL2(ctx->opcode);
16064 switch (op1) {
16065 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
16066 case OPC_MSUB ... OPC_MSUBU:
16067 check_insn(ctx, ISA_MIPS32);
16068 gen_muldiv(ctx, op1, rd & 3, rs, rt);
16069 break;
16070 case OPC_MUL:
16071 gen_arith(ctx, op1, rd, rs, rt);
16072 break;
16073 case OPC_DIV_G_2F:
16074 case OPC_DIVU_G_2F:
16075 case OPC_MULT_G_2F:
16076 case OPC_MULTU_G_2F:
16077 case OPC_MOD_G_2F:
16078 case OPC_MODU_G_2F:
16079 check_insn(ctx, INSN_LOONGSON2F);
16080 gen_loongson_integer(ctx, op1, rd, rs, rt);
16081 break;
16082 case OPC_CLO:
16083 case OPC_CLZ:
16084 check_insn(ctx, ISA_MIPS32);
16085 gen_cl(ctx, op1, rd, rs);
16086 break;
16087 case OPC_SDBBP:
16088 /* XXX: not clear which exception should be raised
16089 * when in debug mode...
16090 */
16091 check_insn(ctx, ISA_MIPS32);
16092 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
16093 generate_exception(ctx, EXCP_DBp);
16094 } else {
16095 generate_exception(ctx, EXCP_DBp);
16096 }
16097 /* Treat as NOP. */
16098 break;
16099 #if defined(TARGET_MIPS64)
16100 case OPC_DCLO:
16101 case OPC_DCLZ:
16102 check_insn(ctx, ISA_MIPS64);
16103 check_mips_64(ctx);
16104 gen_cl(ctx, op1, rd, rs);
16105 break;
16106 case OPC_DMULT_G_2F:
16107 case OPC_DMULTU_G_2F:
16108 case OPC_DDIV_G_2F:
16109 case OPC_DDIVU_G_2F:
16110 case OPC_DMOD_G_2F:
16111 case OPC_DMODU_G_2F:
16112 check_insn(ctx, INSN_LOONGSON2F);
16113 gen_loongson_integer(ctx, op1, rd, rs, rt);
16114 break;
16115 #endif
16116 default: /* Invalid */
16117 MIPS_INVAL("special2_legacy");
16118 generate_exception(ctx, EXCP_RI);
16119 break;
16120 }
16121 }
16122
16123 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
16124 {
16125 int rs, rt, rd, sa;
16126 uint32_t op1, op2;
16127 int16_t imm;
16128
16129 rs = (ctx->opcode >> 21) & 0x1f;
16130 rt = (ctx->opcode >> 16) & 0x1f;
16131 rd = (ctx->opcode >> 11) & 0x1f;
16132 sa = (ctx->opcode >> 6) & 0x1f;
16133 imm = (int16_t)ctx->opcode >> 7;
16134
16135 op1 = MASK_SPECIAL3(ctx->opcode);
16136 switch (op1) {
16137 case R6_OPC_PREF:
16138 if (rt >= 24) {
16139 /* hint codes 24-31 are reserved and signal RI */
16140 generate_exception(ctx, EXCP_RI);
16141 }
16142 /* Treat as NOP. */
16143 break;
16144 case R6_OPC_CACHE:
16145 /* Treat as NOP. */
16146 break;
16147 case R6_OPC_SC:
16148 gen_st_cond(ctx, op1, rt, rs, imm);
16149 break;
16150 case R6_OPC_LL:
16151 gen_ld(ctx, op1, rt, rs, imm);
16152 break;
16153 case OPC_BSHFL:
16154 {
16155 if (rd == 0) {
16156 /* Treat as NOP. */
16157 break;
16158 }
16159 TCGv t0 = tcg_temp_new();
16160 gen_load_gpr(t0, rt);
16161
16162 op2 = MASK_BSHFL(ctx->opcode);
16163 switch (op2) {
16164 case OPC_ALIGN ... OPC_ALIGN_END:
16165 sa &= 3;
16166 if (sa == 0) {
16167 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16168 } else {
16169 TCGv t1 = tcg_temp_new();
16170 TCGv_i64 t2 = tcg_temp_new_i64();
16171 gen_load_gpr(t1, rs);
16172 tcg_gen_concat_tl_i64(t2, t1, t0);
16173 tcg_gen_shri_i64(t2, t2, 8 * (4 - sa));
16174 #if defined(TARGET_MIPS64)
16175 tcg_gen_ext32s_i64(cpu_gpr[rd], t2);
16176 #else
16177 tcg_gen_trunc_i64_i32(cpu_gpr[rd], t2);
16178 #endif
16179 tcg_temp_free_i64(t2);
16180 tcg_temp_free(t1);
16181 }
16182 break;
16183 case OPC_BITSWAP:
16184 gen_helper_bitswap(cpu_gpr[rd], t0);
16185 break;
16186 }
16187 tcg_temp_free(t0);
16188 }
16189 break;
16190 #if defined(TARGET_MIPS64)
16191 case R6_OPC_SCD:
16192 gen_st_cond(ctx, op1, rt, rs, imm);
16193 break;
16194 case R6_OPC_LLD:
16195 gen_ld(ctx, op1, rt, rs, imm);
16196 break;
16197 case OPC_DBSHFL:
16198 check_mips_64(ctx);
16199 {
16200 if (rd == 0) {
16201 /* Treat as NOP. */
16202 break;
16203 }
16204 TCGv t0 = tcg_temp_new();
16205 gen_load_gpr(t0, rt);
16206
16207 op2 = MASK_DBSHFL(ctx->opcode);
16208 switch (op2) {
16209 case OPC_DALIGN ... OPC_DALIGN_END:
16210 sa &= 7;
16211 if (sa == 0) {
16212 tcg_gen_mov_tl(cpu_gpr[rd], t0);
16213 } else {
16214 TCGv t1 = tcg_temp_new();
16215 gen_load_gpr(t1, rs);
16216 tcg_gen_shli_tl(t0, t0, 8 * sa);
16217 tcg_gen_shri_tl(t1, t1, 8 * (8 - sa));
16218 tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
16219 tcg_temp_free(t1);
16220 }
16221 break;
16222 case OPC_DBITSWAP:
16223 gen_helper_dbitswap(cpu_gpr[rd], t0);
16224 break;
16225 }
16226 tcg_temp_free(t0);
16227 }
16228 break;
16229 #endif
16230 default: /* Invalid */
16231 MIPS_INVAL("special3_r6");
16232 generate_exception(ctx, EXCP_RI);
16233 break;
16234 }
16235 }
16236
16237 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
16238 {
16239 int rs, rt, rd;
16240 uint32_t op1, op2;
16241
16242 rs = (ctx->opcode >> 21) & 0x1f;
16243 rt = (ctx->opcode >> 16) & 0x1f;
16244 rd = (ctx->opcode >> 11) & 0x1f;
16245
16246 op1 = MASK_SPECIAL3(ctx->opcode);
16247 switch (op1) {
16248 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
16249 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
16250 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
16251 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16252 * the same mask and op1. */
16253 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
16254 op2 = MASK_ADDUH_QB(ctx->opcode);
16255 switch (op2) {
16256 case OPC_ADDUH_QB:
16257 case OPC_ADDUH_R_QB:
16258 case OPC_ADDQH_PH:
16259 case OPC_ADDQH_R_PH:
16260 case OPC_ADDQH_W:
16261 case OPC_ADDQH_R_W:
16262 case OPC_SUBUH_QB:
16263 case OPC_SUBUH_R_QB:
16264 case OPC_SUBQH_PH:
16265 case OPC_SUBQH_R_PH:
16266 case OPC_SUBQH_W:
16267 case OPC_SUBQH_R_W:
16268 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16269 break;
16270 case OPC_MUL_PH:
16271 case OPC_MUL_S_PH:
16272 case OPC_MULQ_S_W:
16273 case OPC_MULQ_RS_W:
16274 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16275 break;
16276 default:
16277 MIPS_INVAL("MASK ADDUH.QB");
16278 generate_exception(ctx, EXCP_RI);
16279 break;
16280 }
16281 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
16282 gen_loongson_integer(ctx, op1, rd, rs, rt);
16283 } else {
16284 generate_exception(ctx, EXCP_RI);
16285 }
16286 break;
16287 case OPC_LX_DSP:
16288 op2 = MASK_LX(ctx->opcode);
16289 switch (op2) {
16290 #if defined(TARGET_MIPS64)
16291 case OPC_LDX:
16292 #endif
16293 case OPC_LBUX:
16294 case OPC_LHX:
16295 case OPC_LWX:
16296 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
16297 break;
16298 default: /* Invalid */
16299 MIPS_INVAL("MASK LX");
16300 generate_exception(ctx, EXCP_RI);
16301 break;
16302 }
16303 break;
16304 case OPC_ABSQ_S_PH_DSP:
16305 op2 = MASK_ABSQ_S_PH(ctx->opcode);
16306 switch (op2) {
16307 case OPC_ABSQ_S_QB:
16308 case OPC_ABSQ_S_PH:
16309 case OPC_ABSQ_S_W:
16310 case OPC_PRECEQ_W_PHL:
16311 case OPC_PRECEQ_W_PHR:
16312 case OPC_PRECEQU_PH_QBL:
16313 case OPC_PRECEQU_PH_QBR:
16314 case OPC_PRECEQU_PH_QBLA:
16315 case OPC_PRECEQU_PH_QBRA:
16316 case OPC_PRECEU_PH_QBL:
16317 case OPC_PRECEU_PH_QBR:
16318 case OPC_PRECEU_PH_QBLA:
16319 case OPC_PRECEU_PH_QBRA:
16320 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16321 break;
16322 case OPC_BITREV:
16323 case OPC_REPL_QB:
16324 case OPC_REPLV_QB:
16325 case OPC_REPL_PH:
16326 case OPC_REPLV_PH:
16327 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16328 break;
16329 default:
16330 MIPS_INVAL("MASK ABSQ_S.PH");
16331 generate_exception(ctx, EXCP_RI);
16332 break;
16333 }
16334 break;
16335 case OPC_ADDU_QB_DSP:
16336 op2 = MASK_ADDU_QB(ctx->opcode);
16337 switch (op2) {
16338 case OPC_ADDQ_PH:
16339 case OPC_ADDQ_S_PH:
16340 case OPC_ADDQ_S_W:
16341 case OPC_ADDU_QB:
16342 case OPC_ADDU_S_QB:
16343 case OPC_ADDU_PH:
16344 case OPC_ADDU_S_PH:
16345 case OPC_SUBQ_PH:
16346 case OPC_SUBQ_S_PH:
16347 case OPC_SUBQ_S_W:
16348 case OPC_SUBU_QB:
16349 case OPC_SUBU_S_QB:
16350 case OPC_SUBU_PH:
16351 case OPC_SUBU_S_PH:
16352 case OPC_ADDSC:
16353 case OPC_ADDWC:
16354 case OPC_MODSUB:
16355 case OPC_RADDU_W_QB:
16356 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16357 break;
16358 case OPC_MULEU_S_PH_QBL:
16359 case OPC_MULEU_S_PH_QBR:
16360 case OPC_MULQ_RS_PH:
16361 case OPC_MULEQ_S_W_PHL:
16362 case OPC_MULEQ_S_W_PHR:
16363 case OPC_MULQ_S_PH:
16364 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16365 break;
16366 default: /* Invalid */
16367 MIPS_INVAL("MASK ADDU.QB");
16368 generate_exception(ctx, EXCP_RI);
16369 break;
16370
16371 }
16372 break;
16373 case OPC_CMPU_EQ_QB_DSP:
16374 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
16375 switch (op2) {
16376 case OPC_PRECR_SRA_PH_W:
16377 case OPC_PRECR_SRA_R_PH_W:
16378 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
16379 break;
16380 case OPC_PRECR_QB_PH:
16381 case OPC_PRECRQ_QB_PH:
16382 case OPC_PRECRQ_PH_W:
16383 case OPC_PRECRQ_RS_PH_W:
16384 case OPC_PRECRQU_S_QB_PH:
16385 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16386 break;
16387 case OPC_CMPU_EQ_QB:
16388 case OPC_CMPU_LT_QB:
16389 case OPC_CMPU_LE_QB:
16390 case OPC_CMP_EQ_PH:
16391 case OPC_CMP_LT_PH:
16392 case OPC_CMP_LE_PH:
16393 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
16394 break;
16395 case OPC_CMPGU_EQ_QB:
16396 case OPC_CMPGU_LT_QB:
16397 case OPC_CMPGU_LE_QB:
16398 case OPC_CMPGDU_EQ_QB:
16399 case OPC_CMPGDU_LT_QB:
16400 case OPC_CMPGDU_LE_QB:
16401 case OPC_PICK_QB:
16402 case OPC_PICK_PH:
16403 case OPC_PACKRL_PH:
16404 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16405 break;
16406 default: /* Invalid */
16407 MIPS_INVAL("MASK CMPU.EQ.QB");
16408 generate_exception(ctx, EXCP_RI);
16409 break;
16410 }
16411 break;
16412 case OPC_SHLL_QB_DSP:
16413 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16414 break;
16415 case OPC_DPA_W_PH_DSP:
16416 op2 = MASK_DPA_W_PH(ctx->opcode);
16417 switch (op2) {
16418 case OPC_DPAU_H_QBL:
16419 case OPC_DPAU_H_QBR:
16420 case OPC_DPSU_H_QBL:
16421 case OPC_DPSU_H_QBR:
16422 case OPC_DPA_W_PH:
16423 case OPC_DPAX_W_PH:
16424 case OPC_DPAQ_S_W_PH:
16425 case OPC_DPAQX_S_W_PH:
16426 case OPC_DPAQX_SA_W_PH:
16427 case OPC_DPS_W_PH:
16428 case OPC_DPSX_W_PH:
16429 case OPC_DPSQ_S_W_PH:
16430 case OPC_DPSQX_S_W_PH:
16431 case OPC_DPSQX_SA_W_PH:
16432 case OPC_MULSAQ_S_W_PH:
16433 case OPC_DPAQ_SA_L_W:
16434 case OPC_DPSQ_SA_L_W:
16435 case OPC_MAQ_S_W_PHL:
16436 case OPC_MAQ_S_W_PHR:
16437 case OPC_MAQ_SA_W_PHL:
16438 case OPC_MAQ_SA_W_PHR:
16439 case OPC_MULSA_W_PH:
16440 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16441 break;
16442 default: /* Invalid */
16443 MIPS_INVAL("MASK DPAW.PH");
16444 generate_exception(ctx, EXCP_RI);
16445 break;
16446 }
16447 break;
16448 case OPC_INSV_DSP:
16449 op2 = MASK_INSV(ctx->opcode);
16450 switch (op2) {
16451 case OPC_INSV:
16452 check_dsp(ctx);
16453 {
16454 TCGv t0, t1;
16455
16456 if (rt == 0) {
16457 MIPS_DEBUG("NOP");
16458 break;
16459 }
16460
16461 t0 = tcg_temp_new();
16462 t1 = tcg_temp_new();
16463
16464 gen_load_gpr(t0, rt);
16465 gen_load_gpr(t1, rs);
16466
16467 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
16468
16469 tcg_temp_free(t0);
16470 tcg_temp_free(t1);
16471 break;
16472 }
16473 default: /* Invalid */
16474 MIPS_INVAL("MASK INSV");
16475 generate_exception(ctx, EXCP_RI);
16476 break;
16477 }
16478 break;
16479 case OPC_APPEND_DSP:
16480 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16481 break;
16482 case OPC_EXTR_W_DSP:
16483 op2 = MASK_EXTR_W(ctx->opcode);
16484 switch (op2) {
16485 case OPC_EXTR_W:
16486 case OPC_EXTR_R_W:
16487 case OPC_EXTR_RS_W:
16488 case OPC_EXTR_S_H:
16489 case OPC_EXTRV_S_H:
16490 case OPC_EXTRV_W:
16491 case OPC_EXTRV_R_W:
16492 case OPC_EXTRV_RS_W:
16493 case OPC_EXTP:
16494 case OPC_EXTPV:
16495 case OPC_EXTPDP:
16496 case OPC_EXTPDPV:
16497 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
16498 break;
16499 case OPC_RDDSP:
16500 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
16501 break;
16502 case OPC_SHILO:
16503 case OPC_SHILOV:
16504 case OPC_MTHLIP:
16505 case OPC_WRDSP:
16506 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
16507 break;
16508 default: /* Invalid */
16509 MIPS_INVAL("MASK EXTR.W");
16510 generate_exception(ctx, EXCP_RI);
16511 break;
16512 }
16513 break;
16514 #if defined(TARGET_MIPS64)
16515 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
16516 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
16517 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
16518 check_insn(ctx, INSN_LOONGSON2E);
16519 gen_loongson_integer(ctx, op1, rd, rs, rt);
16520 break;
16521 case OPC_ABSQ_S_QH_DSP:
16522 op2 = MASK_ABSQ_S_QH(ctx->opcode);
16523 switch (op2) {
16524 case OPC_PRECEQ_L_PWL:
16525 case OPC_PRECEQ_L_PWR:
16526 case OPC_PRECEQ_PW_QHL:
16527 case OPC_PRECEQ_PW_QHR:
16528 case OPC_PRECEQ_PW_QHLA:
16529 case OPC_PRECEQ_PW_QHRA:
16530 case OPC_PRECEQU_QH_OBL:
16531 case OPC_PRECEQU_QH_OBR:
16532 case OPC_PRECEQU_QH_OBLA:
16533 case OPC_PRECEQU_QH_OBRA:
16534 case OPC_PRECEU_QH_OBL:
16535 case OPC_PRECEU_QH_OBR:
16536 case OPC_PRECEU_QH_OBLA:
16537 case OPC_PRECEU_QH_OBRA:
16538 case OPC_ABSQ_S_OB:
16539 case OPC_ABSQ_S_PW:
16540 case OPC_ABSQ_S_QH:
16541 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16542 break;
16543 case OPC_REPL_OB:
16544 case OPC_REPL_PW:
16545 case OPC_REPL_QH:
16546 case OPC_REPLV_OB:
16547 case OPC_REPLV_PW:
16548 case OPC_REPLV_QH:
16549 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
16550 break;
16551 default: /* Invalid */
16552 MIPS_INVAL("MASK ABSQ_S.QH");
16553 generate_exception(ctx, EXCP_RI);
16554 break;
16555 }
16556 break;
16557 case OPC_ADDU_OB_DSP:
16558 op2 = MASK_ADDU_OB(ctx->opcode);
16559 switch (op2) {
16560 case OPC_RADDU_L_OB:
16561 case OPC_SUBQ_PW:
16562 case OPC_SUBQ_S_PW:
16563 case OPC_SUBQ_QH:
16564 case OPC_SUBQ_S_QH:
16565 case OPC_SUBU_OB:
16566 case OPC_SUBU_S_OB:
16567 case OPC_SUBU_QH:
16568 case OPC_SUBU_S_QH:
16569 case OPC_SUBUH_OB:
16570 case OPC_SUBUH_R_OB:
16571 case OPC_ADDQ_PW:
16572 case OPC_ADDQ_S_PW:
16573 case OPC_ADDQ_QH:
16574 case OPC_ADDQ_S_QH:
16575 case OPC_ADDU_OB:
16576 case OPC_ADDU_S_OB:
16577 case OPC_ADDU_QH:
16578 case OPC_ADDU_S_QH:
16579 case OPC_ADDUH_OB:
16580 case OPC_ADDUH_R_OB:
16581 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16582 break;
16583 case OPC_MULEQ_S_PW_QHL:
16584 case OPC_MULEQ_S_PW_QHR:
16585 case OPC_MULEU_S_QH_OBL:
16586 case OPC_MULEU_S_QH_OBR:
16587 case OPC_MULQ_RS_QH:
16588 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
16589 break;
16590 default: /* Invalid */
16591 MIPS_INVAL("MASK ADDU.OB");
16592 generate_exception(ctx, EXCP_RI);
16593 break;
16594 }
16595 break;
16596 case OPC_CMPU_EQ_OB_DSP:
16597 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
16598 switch (op2) {
16599 case OPC_PRECR_SRA_QH_PW:
16600 case OPC_PRECR_SRA_R_QH_PW:
16601 /* Return value is rt. */
16602 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
16603 break;
16604 case OPC_PRECR_OB_QH:
16605 case OPC_PRECRQ_OB_QH:
16606 case OPC_PRECRQ_PW_L:
16607 case OPC_PRECRQ_QH_PW:
16608 case OPC_PRECRQ_RS_QH_PW:
16609 case OPC_PRECRQU_S_OB_QH:
16610 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
16611 break;
16612 case OPC_CMPU_EQ_OB:
16613 case OPC_CMPU_LT_OB:
16614 case OPC_CMPU_LE_OB:
16615 case OPC_CMP_EQ_QH:
16616 case OPC_CMP_LT_QH:
16617 case OPC_CMP_LE_QH:
16618 case OPC_CMP_EQ_PW:
16619 case OPC_CMP_LT_PW:
16620 case OPC_CMP_LE_PW:
16621 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
16622 break;
16623 case OPC_CMPGDU_EQ_OB:
16624 case OPC_CMPGDU_LT_OB:
16625 case OPC_CMPGDU_LE_OB:
16626 case OPC_CMPGU_EQ_OB:
16627 case OPC_CMPGU_LT_OB:
16628 case OPC_CMPGU_LE_OB:
16629 case OPC_PACKRL_PW:
16630 case OPC_PICK_OB:
16631 case OPC_PICK_PW:
16632 case OPC_PICK_QH:
16633 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
16634 break;
16635 default: /* Invalid */
16636 MIPS_INVAL("MASK CMPU_EQ.OB");
16637 generate_exception(ctx, EXCP_RI);
16638 break;
16639 }
16640 break;
16641 case OPC_DAPPEND_DSP:
16642 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
16643 break;
16644 case OPC_DEXTR_W_DSP:
16645 op2 = MASK_DEXTR_W(ctx->opcode);
16646 switch (op2) {
16647 case OPC_DEXTP:
16648 case OPC_DEXTPDP:
16649 case OPC_DEXTPDPV:
16650 case OPC_DEXTPV:
16651 case OPC_DEXTR_L:
16652 case OPC_DEXTR_R_L:
16653 case OPC_DEXTR_RS_L:
16654 case OPC_DEXTR_W:
16655 case OPC_DEXTR_R_W:
16656 case OPC_DEXTR_RS_W:
16657 case OPC_DEXTR_S_H:
16658 case OPC_DEXTRV_L:
16659 case OPC_DEXTRV_R_L:
16660 case OPC_DEXTRV_RS_L:
16661 case OPC_DEXTRV_S_H:
16662 case OPC_DEXTRV_W:
16663 case OPC_DEXTRV_R_W:
16664 case OPC_DEXTRV_RS_W:
16665 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
16666 break;
16667 case OPC_DMTHLIP:
16668 case OPC_DSHILO:
16669 case OPC_DSHILOV:
16670 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
16671 break;
16672 default: /* Invalid */
16673 MIPS_INVAL("MASK EXTR.W");
16674 generate_exception(ctx, EXCP_RI);
16675 break;
16676 }
16677 break;
16678 case OPC_DPAQ_W_QH_DSP:
16679 op2 = MASK_DPAQ_W_QH(ctx->opcode);
16680 switch (op2) {
16681 case OPC_DPAU_H_OBL:
16682 case OPC_DPAU_H_OBR:
16683 case OPC_DPSU_H_OBL:
16684 case OPC_DPSU_H_OBR:
16685 case OPC_DPA_W_QH:
16686 case OPC_DPAQ_S_W_QH:
16687 case OPC_DPS_W_QH:
16688 case OPC_DPSQ_S_W_QH:
16689 case OPC_MULSAQ_S_W_QH:
16690 case OPC_DPAQ_SA_L_PW:
16691 case OPC_DPSQ_SA_L_PW:
16692 case OPC_MULSAQ_S_L_PW:
16693 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16694 break;
16695 case OPC_MAQ_S_W_QHLL:
16696 case OPC_MAQ_S_W_QHLR:
16697 case OPC_MAQ_S_W_QHRL:
16698 case OPC_MAQ_S_W_QHRR:
16699 case OPC_MAQ_SA_W_QHLL:
16700 case OPC_MAQ_SA_W_QHLR:
16701 case OPC_MAQ_SA_W_QHRL:
16702 case OPC_MAQ_SA_W_QHRR:
16703 case OPC_MAQ_S_L_PWL:
16704 case OPC_MAQ_S_L_PWR:
16705 case OPC_DMADD:
16706 case OPC_DMADDU:
16707 case OPC_DMSUB:
16708 case OPC_DMSUBU:
16709 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
16710 break;
16711 default: /* Invalid */
16712 MIPS_INVAL("MASK DPAQ.W.QH");
16713 generate_exception(ctx, EXCP_RI);
16714 break;
16715 }
16716 break;
16717 case OPC_DINSV_DSP:
16718 op2 = MASK_INSV(ctx->opcode);
16719 switch (op2) {
16720 case OPC_DINSV:
16721 {
16722 TCGv t0, t1;
16723
16724 if (rt == 0) {
16725 MIPS_DEBUG("NOP");
16726 break;
16727 }
16728 check_dsp(ctx);
16729
16730 t0 = tcg_temp_new();
16731 t1 = tcg_temp_new();
16732
16733 gen_load_gpr(t0, rt);
16734 gen_load_gpr(t1, rs);
16735
16736 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
16737
16738 tcg_temp_free(t0);
16739 tcg_temp_free(t1);
16740 break;
16741 }
16742 default: /* Invalid */
16743 MIPS_INVAL("MASK DINSV");
16744 generate_exception(ctx, EXCP_RI);
16745 break;
16746 }
16747 break;
16748 case OPC_SHLL_OB_DSP:
16749 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
16750 break;
16751 #endif
16752 default: /* Invalid */
16753 MIPS_INVAL("special3_legacy");
16754 generate_exception(ctx, EXCP_RI);
16755 break;
16756 }
16757 }
16758
16759 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
16760 {
16761 int rs, rt, rd, sa;
16762 uint32_t op1, op2;
16763
16764 rs = (ctx->opcode >> 21) & 0x1f;
16765 rt = (ctx->opcode >> 16) & 0x1f;
16766 rd = (ctx->opcode >> 11) & 0x1f;
16767 sa = (ctx->opcode >> 6) & 0x1f;
16768
16769 op1 = MASK_SPECIAL3(ctx->opcode);
16770 switch (op1) {
16771 case OPC_EXT:
16772 case OPC_INS:
16773 check_insn(ctx, ISA_MIPS32R2);
16774 gen_bitops(ctx, op1, rt, rs, sa, rd);
16775 break;
16776 case OPC_BSHFL:
16777 op2 = MASK_BSHFL(ctx->opcode);
16778 switch (op2) {
16779 case OPC_ALIGN ... OPC_ALIGN_END:
16780 case OPC_BITSWAP:
16781 check_insn(ctx, ISA_MIPS32R6);
16782 decode_opc_special3_r6(env, ctx);
16783 break;
16784 default:
16785 check_insn(ctx, ISA_MIPS32R2);
16786 gen_bshfl(ctx, op2, rt, rd);
16787 break;
16788 }
16789 break;
16790 #if defined(TARGET_MIPS64)
16791 case OPC_DEXTM ... OPC_DEXT:
16792 case OPC_DINSM ... OPC_DINS:
16793 check_insn(ctx, ISA_MIPS64R2);
16794 check_mips_64(ctx);
16795 gen_bitops(ctx, op1, rt, rs, sa, rd);
16796 break;
16797 case OPC_DBSHFL:
16798 op2 = MASK_DBSHFL(ctx->opcode);
16799 switch (op2) {
16800 case OPC_DALIGN ... OPC_DALIGN_END:
16801 case OPC_DBITSWAP:
16802 check_insn(ctx, ISA_MIPS32R6);
16803 decode_opc_special3_r6(env, ctx);
16804 break;
16805 default:
16806 check_insn(ctx, ISA_MIPS64R2);
16807 check_mips_64(ctx);
16808 op2 = MASK_DBSHFL(ctx->opcode);
16809 gen_bshfl(ctx, op2, rt, rd);
16810 break;
16811 }
16812 break;
16813 #endif
16814 case OPC_RDHWR:
16815 gen_rdhwr(ctx, rt, rd);
16816 break;
16817 case OPC_FORK:
16818 check_insn(ctx, ASE_MT);
16819 {
16820 TCGv t0 = tcg_temp_new();
16821 TCGv t1 = tcg_temp_new();
16822
16823 gen_load_gpr(t0, rt);
16824 gen_load_gpr(t1, rs);
16825 gen_helper_fork(t0, t1);
16826 tcg_temp_free(t0);
16827 tcg_temp_free(t1);
16828 }
16829 break;
16830 case OPC_YIELD:
16831 check_insn(ctx, ASE_MT);
16832 {
16833 TCGv t0 = tcg_temp_new();
16834
16835 save_cpu_state(ctx, 1);
16836 gen_load_gpr(t0, rs);
16837 gen_helper_yield(t0, cpu_env, t0);
16838 gen_store_gpr(t0, rd);
16839 tcg_temp_free(t0);
16840 }
16841 break;
16842 default:
16843 if (ctx->insn_flags & ISA_MIPS32R6) {
16844 decode_opc_special3_r6(env, ctx);
16845 } else {
16846 decode_opc_special3_legacy(env, ctx);
16847 }
16848 }
16849 }
16850
16851 static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
16852 {
16853 int32_t offset;
16854 int rs, rt, rd, sa;
16855 uint32_t op, op1;
16856 int16_t imm;
16857
16858 /* make sure instructions are on a word boundary */
16859 if (ctx->pc & 0x3) {
16860 env->CP0_BadVAddr = ctx->pc;
16861 generate_exception(ctx, EXCP_AdEL);
16862 return;
16863 }
16864
16865 /* Handle blikely not taken case */
16866 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
16867 int l1 = gen_new_label();
16868
16869 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
16870 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
16871 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
16872 gen_goto_tb(ctx, 1, ctx->pc + 4);
16873 gen_set_label(l1);
16874 }
16875
16876 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
16877 tcg_gen_debug_insn_start(ctx->pc);
16878 }
16879
16880 op = MASK_OP_MAJOR(ctx->opcode);
16881 rs = (ctx->opcode >> 21) & 0x1f;
16882 rt = (ctx->opcode >> 16) & 0x1f;
16883 rd = (ctx->opcode >> 11) & 0x1f;
16884 sa = (ctx->opcode >> 6) & 0x1f;
16885 imm = (int16_t)ctx->opcode;
16886 switch (op) {
16887 case OPC_SPECIAL:
16888 decode_opc_special(env, ctx);
16889 break;
16890 case OPC_SPECIAL2:
16891 decode_opc_special2_legacy(env, ctx);
16892 break;
16893 case OPC_SPECIAL3:
16894 decode_opc_special3(env, ctx);
16895 break;
16896 case OPC_REGIMM:
16897 op1 = MASK_REGIMM(ctx->opcode);
16898 switch (op1) {
16899 case OPC_BLTZL: /* REGIMM branches */
16900 case OPC_BGEZL:
16901 case OPC_BLTZALL:
16902 case OPC_BGEZALL:
16903 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16904 case OPC_BLTZ:
16905 case OPC_BGEZ:
16906 case OPC_BLTZAL:
16907 case OPC_BGEZAL:
16908 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
16909 break;
16910 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
16911 case OPC_TNEI:
16912 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16913 gen_trap(ctx, op1, rs, -1, imm);
16914 break;
16915 case OPC_SYNCI:
16916 check_insn(ctx, ISA_MIPS32R2);
16917 /* Treat as NOP. */
16918 break;
16919 case OPC_BPOSGE32: /* MIPS DSP branch */
16920 #if defined(TARGET_MIPS64)
16921 case OPC_BPOSGE64:
16922 #endif
16923 check_dsp(ctx);
16924 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
16925 break;
16926 #if defined(TARGET_MIPS64)
16927 case OPC_DAHI:
16928 check_insn(ctx, ISA_MIPS32R6);
16929 check_mips_64(ctx);
16930 if (rs != 0) {
16931 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
16932 }
16933 MIPS_DEBUG("dahi %s, %04x", regnames[rs], imm);
16934 break;
16935 case OPC_DATI:
16936 check_insn(ctx, ISA_MIPS32R6);
16937 check_mips_64(ctx);
16938 if (rs != 0) {
16939 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
16940 }
16941 MIPS_DEBUG("dati %s, %04x", regnames[rs], imm);
16942 break;
16943 #endif
16944 default: /* Invalid */
16945 MIPS_INVAL("regimm");
16946 generate_exception(ctx, EXCP_RI);
16947 break;
16948 }
16949 break;
16950 case OPC_CP0:
16951 check_cp0_enabled(ctx);
16952 op1 = MASK_CP0(ctx->opcode);
16953 switch (op1) {
16954 case OPC_MFC0:
16955 case OPC_MTC0:
16956 case OPC_MFTR:
16957 case OPC_MTTR:
16958 #if defined(TARGET_MIPS64)
16959 case OPC_DMFC0:
16960 case OPC_DMTC0:
16961 #endif
16962 #ifndef CONFIG_USER_ONLY
16963 gen_cp0(env, ctx, op1, rt, rd);
16964 #endif /* !CONFIG_USER_ONLY */
16965 break;
16966 case OPC_C0_FIRST ... OPC_C0_LAST:
16967 #ifndef CONFIG_USER_ONLY
16968 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
16969 #endif /* !CONFIG_USER_ONLY */
16970 break;
16971 case OPC_MFMC0:
16972 #ifndef CONFIG_USER_ONLY
16973 {
16974 uint32_t op2;
16975 TCGv t0 = tcg_temp_new();
16976
16977 op2 = MASK_MFMC0(ctx->opcode);
16978 switch (op2) {
16979 case OPC_DMT:
16980 check_insn(ctx, ASE_MT);
16981 gen_helper_dmt(t0);
16982 gen_store_gpr(t0, rt);
16983 break;
16984 case OPC_EMT:
16985 check_insn(ctx, ASE_MT);
16986 gen_helper_emt(t0);
16987 gen_store_gpr(t0, rt);
16988 break;
16989 case OPC_DVPE:
16990 check_insn(ctx, ASE_MT);
16991 gen_helper_dvpe(t0, cpu_env);
16992 gen_store_gpr(t0, rt);
16993 break;
16994 case OPC_EVPE:
16995 check_insn(ctx, ASE_MT);
16996 gen_helper_evpe(t0, cpu_env);
16997 gen_store_gpr(t0, rt);
16998 break;
16999 case OPC_DI:
17000 check_insn(ctx, ISA_MIPS32R2);
17001 save_cpu_state(ctx, 1);
17002 gen_helper_di(t0, cpu_env);
17003 gen_store_gpr(t0, rt);
17004 /* Stop translation as we may have switched the execution mode */
17005 ctx->bstate = BS_STOP;
17006 break;
17007 case OPC_EI:
17008 check_insn(ctx, ISA_MIPS32R2);
17009 save_cpu_state(ctx, 1);
17010 gen_helper_ei(t0, cpu_env);
17011 gen_store_gpr(t0, rt);
17012 /* Stop translation as we may have switched the execution mode */
17013 ctx->bstate = BS_STOP;
17014 break;
17015 default: /* Invalid */
17016 MIPS_INVAL("mfmc0");
17017 generate_exception(ctx, EXCP_RI);
17018 break;
17019 }
17020 tcg_temp_free(t0);
17021 }
17022 #endif /* !CONFIG_USER_ONLY */
17023 break;
17024 case OPC_RDPGPR:
17025 check_insn(ctx, ISA_MIPS32R2);
17026 gen_load_srsgpr(rt, rd);
17027 break;
17028 case OPC_WRPGPR:
17029 check_insn(ctx, ISA_MIPS32R2);
17030 gen_store_srsgpr(rt, rd);
17031 break;
17032 default:
17033 MIPS_INVAL("cp0");
17034 generate_exception(ctx, EXCP_RI);
17035 break;
17036 }
17037 break;
17038 case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
17039 if (ctx->insn_flags & ISA_MIPS32R6) {
17040 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
17041 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17042 } else {
17043 /* OPC_ADDI */
17044 /* Arithmetic with immediate opcode */
17045 gen_arith_imm(ctx, op, rt, rs, imm);
17046 }
17047 break;
17048 case OPC_ADDIU:
17049 gen_arith_imm(ctx, op, rt, rs, imm);
17050 break;
17051 case OPC_SLTI: /* Set on less than with immediate opcode */
17052 case OPC_SLTIU:
17053 gen_slt_imm(ctx, op, rt, rs, imm);
17054 break;
17055 case OPC_ANDI: /* Arithmetic with immediate opcode */
17056 case OPC_LUI: /* OPC_AUI */
17057 case OPC_ORI:
17058 case OPC_XORI:
17059 gen_logic_imm(ctx, op, rt, rs, imm);
17060 break;
17061 case OPC_J ... OPC_JAL: /* Jump */
17062 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17063 gen_compute_branch(ctx, op, 4, rs, rt, offset);
17064 break;
17065 /* Branch */
17066 case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
17067 if (ctx->insn_flags & ISA_MIPS32R6) {
17068 if (rt == 0) {
17069 generate_exception(ctx, EXCP_RI);
17070 break;
17071 }
17072 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
17073 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17074 } else {
17075 /* OPC_BLEZL */
17076 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
17077 }
17078 break;
17079 case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
17080 if (ctx->insn_flags & ISA_MIPS32R6) {
17081 if (rt == 0) {
17082 generate_exception(ctx, EXCP_RI);
17083 break;
17084 }
17085 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
17086 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17087 } else {
17088 /* OPC_BGTZL */
17089 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
17090 }
17091 break;
17092 case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
17093 if (rt == 0) {
17094 /* OPC_BLEZ */
17095 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
17096 } else {
17097 check_insn(ctx, ISA_MIPS32R6);
17098 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
17099 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17100 }
17101 break;
17102 case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
17103 if (rt == 0) {
17104 /* OPC_BGTZ */
17105 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
17106 } else {
17107 check_insn(ctx, ISA_MIPS32R6);
17108 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
17109 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17110 }
17111 break;
17112 case OPC_BEQL:
17113 case OPC_BNEL:
17114 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17115 case OPC_BEQ:
17116 case OPC_BNE:
17117 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
17118 break;
17119 case OPC_LWL: /* Load and stores */
17120 case OPC_LWR:
17121 case OPC_LL:
17122 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17123 case OPC_LB ... OPC_LH:
17124 case OPC_LW ... OPC_LHU:
17125 gen_ld(ctx, op, rt, rs, imm);
17126 break;
17127 case OPC_SWL:
17128 case OPC_SWR:
17129 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17130 case OPC_SB ... OPC_SH:
17131 case OPC_SW:
17132 gen_st(ctx, op, rt, rs, imm);
17133 break;
17134 case OPC_SC:
17135 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17136 gen_st_cond(ctx, op, rt, rs, imm);
17137 break;
17138 case OPC_CACHE:
17139 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17140 check_cp0_enabled(ctx);
17141 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
17142 /* Treat as NOP. */
17143 break;
17144 case OPC_PREF:
17145 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17146 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
17147 /* Treat as NOP. */
17148 break;
17149
17150 /* Floating point (COP1). */
17151 case OPC_LWC1:
17152 case OPC_LDC1:
17153 case OPC_SWC1:
17154 case OPC_SDC1:
17155 gen_cop1_ldst(ctx, op, rt, rs, imm);
17156 break;
17157
17158 case OPC_CP1:
17159 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
17160 check_cp1_enabled(ctx);
17161 op1 = MASK_CP1(ctx->opcode);
17162 switch (op1) {
17163 case OPC_MFHC1:
17164 case OPC_MTHC1:
17165 check_insn(ctx, ISA_MIPS32R2);
17166 case OPC_MFC1:
17167 case OPC_CFC1:
17168 case OPC_MTC1:
17169 case OPC_CTC1:
17170 gen_cp1(ctx, op1, rt, rd);
17171 break;
17172 #if defined(TARGET_MIPS64)
17173 case OPC_DMFC1:
17174 case OPC_DMTC1:
17175 check_insn(ctx, ISA_MIPS3);
17176 gen_cp1(ctx, op1, rt, rd);
17177 break;
17178 #endif
17179 case OPC_BC1EQZ: /* OPC_BC1ANY2 */
17180 if (ctx->insn_flags & ISA_MIPS32R6) {
17181 /* OPC_BC1EQZ */
17182 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
17183 rt, imm << 2);
17184 } else {
17185 /* OPC_BC1ANY2 */
17186 check_cop1x(ctx);
17187 check_insn(ctx, ASE_MIPS3D);
17188 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
17189 (rt >> 2) & 0x7, imm << 2);
17190 }
17191 break;
17192 case OPC_BC1NEZ:
17193 check_insn(ctx, ISA_MIPS32R6);
17194 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
17195 rt, imm << 2);
17196 break;
17197 case OPC_BC1ANY4:
17198 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17199 check_cop1x(ctx);
17200 check_insn(ctx, ASE_MIPS3D);
17201 /* fall through */
17202 case OPC_BC1:
17203 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17204 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
17205 (rt >> 2) & 0x7, imm << 2);
17206 break;
17207 case OPC_PS_FMT:
17208 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17209 case OPC_S_FMT:
17210 case OPC_D_FMT:
17211 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
17212 (imm >> 8) & 0x7);
17213 break;
17214 case OPC_W_FMT:
17215 case OPC_L_FMT:
17216 {
17217 int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
17218 if (ctx->insn_flags & ISA_MIPS32R6) {
17219 switch (r6_op) {
17220 case R6_OPC_CMP_AF_S:
17221 case R6_OPC_CMP_UN_S:
17222 case R6_OPC_CMP_EQ_S:
17223 case R6_OPC_CMP_UEQ_S:
17224 case R6_OPC_CMP_LT_S:
17225 case R6_OPC_CMP_ULT_S:
17226 case R6_OPC_CMP_LE_S:
17227 case R6_OPC_CMP_ULE_S:
17228 case R6_OPC_CMP_SAF_S:
17229 case R6_OPC_CMP_SUN_S:
17230 case R6_OPC_CMP_SEQ_S:
17231 case R6_OPC_CMP_SEUQ_S:
17232 case R6_OPC_CMP_SLT_S:
17233 case R6_OPC_CMP_SULT_S:
17234 case R6_OPC_CMP_SLE_S:
17235 case R6_OPC_CMP_SULE_S:
17236 case R6_OPC_CMP_OR_S:
17237 case R6_OPC_CMP_UNE_S:
17238 case R6_OPC_CMP_NE_S:
17239 case R6_OPC_CMP_SOR_S:
17240 case R6_OPC_CMP_SUNE_S:
17241 case R6_OPC_CMP_SNE_S:
17242 gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
17243 break;
17244 case R6_OPC_CMP_AF_D:
17245 case R6_OPC_CMP_UN_D:
17246 case R6_OPC_CMP_EQ_D:
17247 case R6_OPC_CMP_UEQ_D:
17248 case R6_OPC_CMP_LT_D:
17249 case R6_OPC_CMP_ULT_D:
17250 case R6_OPC_CMP_LE_D:
17251 case R6_OPC_CMP_ULE_D:
17252 case R6_OPC_CMP_SAF_D:
17253 case R6_OPC_CMP_SUN_D:
17254 case R6_OPC_CMP_SEQ_D:
17255 case R6_OPC_CMP_SEUQ_D:
17256 case R6_OPC_CMP_SLT_D:
17257 case R6_OPC_CMP_SULT_D:
17258 case R6_OPC_CMP_SLE_D:
17259 case R6_OPC_CMP_SULE_D:
17260 case R6_OPC_CMP_OR_D:
17261 case R6_OPC_CMP_UNE_D:
17262 case R6_OPC_CMP_NE_D:
17263 case R6_OPC_CMP_SOR_D:
17264 case R6_OPC_CMP_SUNE_D:
17265 case R6_OPC_CMP_SNE_D:
17266 gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
17267 break;
17268 default:
17269 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
17270 (imm >> 8) & 0x7);
17271 break;
17272 }
17273 } else {
17274 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
17275 (imm >> 8) & 0x7);
17276 }
17277 break;
17278 }
17279 default:
17280 MIPS_INVAL("cp1");
17281 generate_exception (ctx, EXCP_RI);
17282 break;
17283 }
17284 } else {
17285 generate_exception_err(ctx, EXCP_CpU, 1);
17286 }
17287 break;
17288
17289 /* Compact branches [R6] and COP2 [non-R6] */
17290 case OPC_BC: /* OPC_LWC2 */
17291 case OPC_BALC: /* OPC_SWC2 */
17292 if (ctx->insn_flags & ISA_MIPS32R6) {
17293 /* OPC_BC, OPC_BALC */
17294 gen_compute_compact_branch(ctx, op, 0, 0,
17295 sextract32(ctx->opcode << 2, 0, 28));
17296 } else {
17297 /* OPC_LWC2, OPC_SWC2 */
17298 /* COP2: Not implemented. */
17299 generate_exception_err(ctx, EXCP_CpU, 2);
17300 }
17301 break;
17302 case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
17303 case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
17304 if (ctx->insn_flags & ISA_MIPS32R6) {
17305 if (rs != 0) {
17306 /* OPC_BEQZC, OPC_BNEZC */
17307 gen_compute_compact_branch(ctx, op, rs, 0,
17308 sextract32(ctx->opcode << 2, 0, 23));
17309 } else {
17310 /* OPC_JIC, OPC_JIALC */
17311 gen_compute_compact_branch(ctx, op, 0, rt, imm);
17312 }
17313 } else {
17314 /* OPC_LWC2, OPC_SWC2 */
17315 /* COP2: Not implemented. */
17316 generate_exception_err(ctx, EXCP_CpU, 2);
17317 }
17318 break;
17319 case OPC_CP2:
17320 check_insn(ctx, INSN_LOONGSON2F);
17321 /* Note that these instructions use different fields. */
17322 gen_loongson_multimedia(ctx, sa, rd, rt);
17323 break;
17324
17325 case OPC_CP3:
17326 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17327 if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
17328 check_cp1_enabled(ctx);
17329 op1 = MASK_CP3(ctx->opcode);
17330 switch (op1) {
17331 case OPC_LWXC1:
17332 case OPC_LDXC1:
17333 case OPC_LUXC1:
17334 case OPC_SWXC1:
17335 case OPC_SDXC1:
17336 case OPC_SUXC1:
17337 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
17338 break;
17339 case OPC_PREFX:
17340 /* Treat as NOP. */
17341 break;
17342 case OPC_ALNV_PS:
17343 case OPC_MADD_S:
17344 case OPC_MADD_D:
17345 case OPC_MADD_PS:
17346 case OPC_MSUB_S:
17347 case OPC_MSUB_D:
17348 case OPC_MSUB_PS:
17349 case OPC_NMADD_S:
17350 case OPC_NMADD_D:
17351 case OPC_NMADD_PS:
17352 case OPC_NMSUB_S:
17353 case OPC_NMSUB_D:
17354 case OPC_NMSUB_PS:
17355 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
17356 break;
17357 default:
17358 MIPS_INVAL("cp3");
17359 generate_exception (ctx, EXCP_RI);
17360 break;
17361 }
17362 } else {
17363 generate_exception_err(ctx, EXCP_CpU, 1);
17364 }
17365 break;
17366
17367 #if defined(TARGET_MIPS64)
17368 /* MIPS64 opcodes */
17369 case OPC_LDL ... OPC_LDR:
17370 case OPC_LLD:
17371 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17372 case OPC_LWU:
17373 case OPC_LD:
17374 check_insn(ctx, ISA_MIPS3);
17375 check_mips_64(ctx);
17376 gen_ld(ctx, op, rt, rs, imm);
17377 break;
17378 case OPC_SDL ... OPC_SDR:
17379 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17380 case OPC_SD:
17381 check_insn(ctx, ISA_MIPS3);
17382 check_mips_64(ctx);
17383 gen_st(ctx, op, rt, rs, imm);
17384 break;
17385 case OPC_SCD:
17386 check_insn_opc_removed(ctx, ISA_MIPS32R6);
17387 check_insn(ctx, ISA_MIPS3);
17388 check_mips_64(ctx);
17389 gen_st_cond(ctx, op, rt, rs, imm);
17390 break;
17391 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
17392 if (ctx->insn_flags & ISA_MIPS32R6) {
17393 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
17394 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17395 } else {
17396 /* OPC_DADDI */
17397 check_insn(ctx, ISA_MIPS3);
17398 check_mips_64(ctx);
17399 gen_arith_imm(ctx, op, rt, rs, imm);
17400 }
17401 break;
17402 case OPC_DADDIU:
17403 check_insn(ctx, ISA_MIPS3);
17404 check_mips_64(ctx);
17405 gen_arith_imm(ctx, op, rt, rs, imm);
17406 break;
17407 #else
17408 case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
17409 if (ctx->insn_flags & ISA_MIPS32R6) {
17410 gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
17411 } else {
17412 MIPS_INVAL("major opcode");
17413 generate_exception(ctx, EXCP_RI);
17414 }
17415 break;
17416 #endif
17417 case OPC_DAUI: /* OPC_JALX */
17418 if (ctx->insn_flags & ISA_MIPS32R6) {
17419 #if defined(TARGET_MIPS64)
17420 /* OPC_DAUI */
17421 check_mips_64(ctx);
17422 if (rt != 0) {
17423 TCGv t0 = tcg_temp_new();
17424 gen_load_gpr(t0, rs);
17425 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
17426 tcg_temp_free(t0);
17427 }
17428 MIPS_DEBUG("daui %s, %s, %04x", regnames[rt], regnames[rs], imm);
17429 #else
17430 generate_exception(ctx, EXCP_RI);
17431 MIPS_INVAL("major opcode");
17432 #endif
17433 } else {
17434 /* OPC_JALX */
17435 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
17436 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17437 gen_compute_branch(ctx, op, 4, rs, rt, offset);
17438 }
17439 break;
17440 case OPC_MDMX:
17441 check_insn(ctx, ASE_MDMX);
17442 /* MDMX: Not implemented. */
17443 break;
17444 case OPC_PCREL:
17445 check_insn(ctx, ISA_MIPS32R6);
17446 gen_pcrel(ctx, rs, imm);
17447 break;
17448 default: /* Invalid */
17449 MIPS_INVAL("major opcode");
17450 generate_exception(ctx, EXCP_RI);
17451 break;
17452 }
17453 }
17454
17455 static inline void
17456 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
17457 bool search_pc)
17458 {
17459 CPUState *cs = CPU(cpu);
17460 CPUMIPSState *env = &cpu->env;
17461 DisasContext ctx;
17462 target_ulong pc_start;
17463 uint16_t *gen_opc_end;
17464 CPUBreakpoint *bp;
17465 int j, lj = -1;
17466 int num_insns;
17467 int max_insns;
17468 int insn_bytes;
17469 int is_delay;
17470
17471 if (search_pc)
17472 qemu_log("search pc %d\n", search_pc);
17473
17474 pc_start = tb->pc;
17475 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
17476 ctx.pc = pc_start;
17477 ctx.saved_pc = -1;
17478 ctx.singlestep_enabled = cs->singlestep_enabled;
17479 ctx.insn_flags = env->insn_flags;
17480 ctx.CP0_Config1 = env->CP0_Config1;
17481 ctx.tb = tb;
17482 ctx.bstate = BS_NONE;
17483 /* Restore delay slot state from the tb context. */
17484 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
17485 ctx.ulri = env->CP0_Config3 & (1 << CP0C3_ULRI);
17486 restore_cpu_state(env, &ctx);
17487 #ifdef CONFIG_USER_ONLY
17488 ctx.mem_idx = MIPS_HFLAG_UM;
17489 #else
17490 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
17491 #endif
17492 num_insns = 0;
17493 max_insns = tb->cflags & CF_COUNT_MASK;
17494 if (max_insns == 0)
17495 max_insns = CF_COUNT_MASK;
17496 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
17497 gen_tb_start();
17498 while (ctx.bstate == BS_NONE) {
17499 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
17500 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
17501 if (bp->pc == ctx.pc) {
17502 save_cpu_state(&ctx, 1);
17503 ctx.bstate = BS_BRANCH;
17504 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
17505 /* Include the breakpoint location or the tb won't
17506 * be flushed when it must be. */
17507 ctx.pc += 4;
17508 goto done_generating;
17509 }
17510 }
17511 }
17512
17513 if (search_pc) {
17514 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
17515 if (lj < j) {
17516 lj++;
17517 while (lj < j)
17518 tcg_ctx.gen_opc_instr_start[lj++] = 0;
17519 }
17520 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
17521 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
17522 gen_opc_btarget[lj] = ctx.btarget;
17523 tcg_ctx.gen_opc_instr_start[lj] = 1;
17524 tcg_ctx.gen_opc_icount[lj] = num_insns;
17525 }
17526 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
17527 gen_io_start();
17528
17529 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
17530 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
17531 ctx.opcode = cpu_ldl_code(env, ctx.pc);
17532 insn_bytes = 4;
17533 decode_opc(env, &ctx);
17534 } else if (ctx.insn_flags & ASE_MICROMIPS) {
17535 ctx.opcode = cpu_lduw_code(env, ctx.pc);
17536 insn_bytes = decode_micromips_opc(env, &ctx);
17537 } else if (ctx.insn_flags & ASE_MIPS16) {
17538 ctx.opcode = cpu_lduw_code(env, ctx.pc);
17539 insn_bytes = decode_mips16_opc(env, &ctx);
17540 } else {
17541 generate_exception(&ctx, EXCP_RI);
17542 ctx.bstate = BS_STOP;
17543 break;
17544 }
17545
17546 if (is_delay) {
17547 gen_branch(&ctx, insn_bytes);
17548 }
17549 ctx.pc += insn_bytes;
17550
17551 num_insns++;
17552
17553 /* Execute a branch and its delay slot as a single instruction.
17554 This is what GDB expects and is consistent with what the
17555 hardware does (e.g. if a delay slot instruction faults, the
17556 reported PC is the PC of the branch). */
17557 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
17558 break;
17559 }
17560
17561 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
17562 break;
17563
17564 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
17565 break;
17566 }
17567
17568 if (num_insns >= max_insns)
17569 break;
17570
17571 if (singlestep)
17572 break;
17573 }
17574 if (tb->cflags & CF_LAST_IO) {
17575 gen_io_end();
17576 }
17577 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
17578 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
17579 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
17580 } else {
17581 switch (ctx.bstate) {
17582 case BS_STOP:
17583 gen_goto_tb(&ctx, 0, ctx.pc);
17584 break;
17585 case BS_NONE:
17586 save_cpu_state(&ctx, 0);
17587 gen_goto_tb(&ctx, 0, ctx.pc);
17588 break;
17589 case BS_EXCP:
17590 tcg_gen_exit_tb(0);
17591 break;
17592 case BS_BRANCH:
17593 default:
17594 break;
17595 }
17596 }
17597 done_generating:
17598 gen_tb_end(tb, num_insns);
17599 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
17600 if (search_pc) {
17601 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
17602 lj++;
17603 while (lj <= j)
17604 tcg_ctx.gen_opc_instr_start[lj++] = 0;
17605 } else {
17606 tb->size = ctx.pc - pc_start;
17607 tb->icount = num_insns;
17608 }
17609 #ifdef DEBUG_DISAS
17610 LOG_DISAS("\n");
17611 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
17612 qemu_log("IN: %s\n", lookup_symbol(pc_start));
17613 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
17614 qemu_log("\n");
17615 }
17616 #endif
17617 }
17618
17619 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
17620 {
17621 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
17622 }
17623
17624 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
17625 {
17626 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
17627 }
17628
17629 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
17630 int flags)
17631 {
17632 int i;
17633 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
17634
17635 #define printfpr(fp) \
17636 do { \
17637 if (is_fpu64) \
17638 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17639 " fd:%13g fs:%13g psu: %13g\n", \
17640 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
17641 (double)(fp)->fd, \
17642 (double)(fp)->fs[FP_ENDIAN_IDX], \
17643 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
17644 else { \
17645 fpr_t tmp; \
17646 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
17647 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
17648 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17649 " fd:%13g fs:%13g psu:%13g\n", \
17650 tmp.w[FP_ENDIAN_IDX], tmp.d, \
17651 (double)tmp.fd, \
17652 (double)tmp.fs[FP_ENDIAN_IDX], \
17653 (double)tmp.fs[!FP_ENDIAN_IDX]); \
17654 } \
17655 } while(0)
17656
17657
17658 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
17659 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
17660 get_float_exception_flags(&env->active_fpu.fp_status));
17661 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
17662 fpu_fprintf(f, "%3s: ", fregnames[i]);
17663 printfpr(&env->active_fpu.fpr[i]);
17664 }
17665
17666 #undef printfpr
17667 }
17668
17669 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
17670 /* Debug help: The architecture requires 32bit code to maintain proper
17671 sign-extended values on 64bit machines. */
17672
17673 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
17674
17675 static void
17676 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
17677 fprintf_function cpu_fprintf,
17678 int flags)
17679 {
17680 int i;
17681
17682 if (!SIGN_EXT_P(env->active_tc.PC))
17683 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
17684 if (!SIGN_EXT_P(env->active_tc.HI[0]))
17685 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
17686 if (!SIGN_EXT_P(env->active_tc.LO[0]))
17687 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
17688 if (!SIGN_EXT_P(env->btarget))
17689 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
17690
17691 for (i = 0; i < 32; i++) {
17692 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
17693 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
17694 }
17695
17696 if (!SIGN_EXT_P(env->CP0_EPC))
17697 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
17698 if (!SIGN_EXT_P(env->lladdr))
17699 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
17700 }
17701 #endif
17702
17703 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
17704 int flags)
17705 {
17706 MIPSCPU *cpu = MIPS_CPU(cs);
17707 CPUMIPSState *env = &cpu->env;
17708 int i;
17709
17710 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
17711 " LO=0x" TARGET_FMT_lx " ds %04x "
17712 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
17713 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
17714 env->hflags, env->btarget, env->bcond);
17715 for (i = 0; i < 32; i++) {
17716 if ((i & 3) == 0)
17717 cpu_fprintf(f, "GPR%02d:", i);
17718 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
17719 if ((i & 3) == 3)
17720 cpu_fprintf(f, "\n");
17721 }
17722
17723 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
17724 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
17725 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
17726 env->CP0_Config0, env->CP0_Config1, env->lladdr);
17727 if (env->hflags & MIPS_HFLAG_FPU)
17728 fpu_dump_state(env, f, cpu_fprintf, flags);
17729 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
17730 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
17731 #endif
17732 }
17733
17734 void mips_tcg_init(void)
17735 {
17736 int i;
17737 static int inited;
17738
17739 /* Initialize various static tables. */
17740 if (inited)
17741 return;
17742
17743 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
17744 TCGV_UNUSED(cpu_gpr[0]);
17745 for (i = 1; i < 32; i++)
17746 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
17747 offsetof(CPUMIPSState, active_tc.gpr[i]),
17748 regnames[i]);
17749
17750 for (i = 0; i < 32; i++) {
17751 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
17752 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
17753 }
17754
17755 cpu_PC = tcg_global_mem_new(TCG_AREG0,
17756 offsetof(CPUMIPSState, active_tc.PC), "PC");
17757 for (i = 0; i < MIPS_DSP_ACC; i++) {
17758 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
17759 offsetof(CPUMIPSState, active_tc.HI[i]),
17760 regnames_HI[i]);
17761 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
17762 offsetof(CPUMIPSState, active_tc.LO[i]),
17763 regnames_LO[i]);
17764 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
17765 offsetof(CPUMIPSState, active_tc.ACX[i]),
17766 regnames_ACX[i]);
17767 }
17768 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
17769 offsetof(CPUMIPSState, active_tc.DSPControl),
17770 "DSPControl");
17771 bcond = tcg_global_mem_new(TCG_AREG0,
17772 offsetof(CPUMIPSState, bcond), "bcond");
17773 btarget = tcg_global_mem_new(TCG_AREG0,
17774 offsetof(CPUMIPSState, btarget), "btarget");
17775 hflags = tcg_global_mem_new_i32(TCG_AREG0,
17776 offsetof(CPUMIPSState, hflags), "hflags");
17777
17778 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
17779 offsetof(CPUMIPSState, active_fpu.fcr0),
17780 "fcr0");
17781 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
17782 offsetof(CPUMIPSState, active_fpu.fcr31),
17783 "fcr31");
17784
17785 inited = 1;
17786 }
17787
17788 #include "translate_init.c"
17789
17790 MIPSCPU *cpu_mips_init(const char *cpu_model)
17791 {
17792 MIPSCPU *cpu;
17793 CPUMIPSState *env;
17794 const mips_def_t *def;
17795
17796 def = cpu_mips_find_by_name(cpu_model);
17797 if (!def)
17798 return NULL;
17799 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
17800 env = &cpu->env;
17801 env->cpu_model = def;
17802
17803 #ifndef CONFIG_USER_ONLY
17804 mmu_init(env, def);
17805 #endif
17806 fpu_init(env, def);
17807 mvp_init(env, def);
17808
17809 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
17810
17811 return cpu;
17812 }
17813
17814 void cpu_state_reset(CPUMIPSState *env)
17815 {
17816 MIPSCPU *cpu = mips_env_get_cpu(env);
17817 CPUState *cs = CPU(cpu);
17818
17819 /* Reset registers to their default values */
17820 env->CP0_PRid = env->cpu_model->CP0_PRid;
17821 env->CP0_Config0 = env->cpu_model->CP0_Config0;
17822 #ifdef TARGET_WORDS_BIGENDIAN
17823 env->CP0_Config0 |= (1 << CP0C0_BE);
17824 #endif
17825 env->CP0_Config1 = env->cpu_model->CP0_Config1;
17826 env->CP0_Config2 = env->cpu_model->CP0_Config2;
17827 env->CP0_Config3 = env->cpu_model->CP0_Config3;
17828 env->CP0_Config4 = env->cpu_model->CP0_Config4;
17829 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
17830 env->CP0_Config5 = env->cpu_model->CP0_Config5;
17831 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
17832 env->CP0_Config6 = env->cpu_model->CP0_Config6;
17833 env->CP0_Config7 = env->cpu_model->CP0_Config7;
17834 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
17835 << env->cpu_model->CP0_LLAddr_shift;
17836 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
17837 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
17838 env->CCRes = env->cpu_model->CCRes;
17839 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
17840 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
17841 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
17842 env->current_tc = 0;
17843 env->SEGBITS = env->cpu_model->SEGBITS;
17844 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
17845 #if defined(TARGET_MIPS64)
17846 if (env->cpu_model->insn_flags & ISA_MIPS3) {
17847 env->SEGMask |= 3ULL << 62;
17848 }
17849 #endif
17850 env->PABITS = env->cpu_model->PABITS;
17851 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
17852 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
17853 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
17854 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
17855 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
17856 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
17857 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
17858 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
17859 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
17860 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
17861 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
17862 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
17863 env->insn_flags = env->cpu_model->insn_flags;
17864
17865 #if defined(CONFIG_USER_ONLY)
17866 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
17867 # ifdef TARGET_MIPS64
17868 /* Enable 64-bit register mode. */
17869 env->CP0_Status |= (1 << CP0St_PX);
17870 # endif
17871 # ifdef TARGET_ABI_MIPSN64
17872 /* Enable 64-bit address mode. */
17873 env->CP0_Status |= (1 << CP0St_UX);
17874 # endif
17875 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
17876 hardware registers. */
17877 env->CP0_HWREna |= 0x0000000F;
17878 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
17879 env->CP0_Status |= (1 << CP0St_CU1);
17880 }
17881 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
17882 env->CP0_Status |= (1 << CP0St_MX);
17883 }
17884 # if defined(TARGET_MIPS64)
17885 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
17886 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
17887 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
17888 env->CP0_Status |= (1 << CP0St_FR);
17889 }
17890 # endif
17891 #else
17892 if (env->hflags & MIPS_HFLAG_BMASK) {
17893 /* If the exception was raised from a delay slot,
17894 come back to the jump. */
17895 env->CP0_ErrorEPC = env->active_tc.PC - 4;
17896 } else {
17897 env->CP0_ErrorEPC = env->active_tc.PC;
17898 }
17899 env->active_tc.PC = (int32_t)0xBFC00000;
17900 env->CP0_Random = env->tlb->nb_tlb - 1;
17901 env->tlb->tlb_in_use = env->tlb->nb_tlb;
17902 env->CP0_Wired = 0;
17903 env->CP0_EBase = (cs->cpu_index & 0x3FF);
17904 if (kvm_enabled()) {
17905 env->CP0_EBase |= 0x40000000;
17906 } else {
17907 env->CP0_EBase |= 0x80000000;
17908 }
17909 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
17910 /* vectored interrupts not implemented, timer on int 7,
17911 no performance counters. */
17912 env->CP0_IntCtl = 0xe0000000;
17913 {
17914 int i;
17915
17916 for (i = 0; i < 7; i++) {
17917 env->CP0_WatchLo[i] = 0;
17918 env->CP0_WatchHi[i] = 0x80000000;
17919 }
17920 env->CP0_WatchLo[7] = 0;
17921 env->CP0_WatchHi[7] = 0;
17922 }
17923 /* Count register increments in debug mode, EJTAG version 1 */
17924 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
17925
17926 cpu_mips_store_count(env, 1);
17927
17928 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
17929 int i;
17930
17931 /* Only TC0 on VPE 0 starts as active. */
17932 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
17933 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
17934 env->tcs[i].CP0_TCHalt = 1;
17935 }
17936 env->active_tc.CP0_TCHalt = 1;
17937 cs->halted = 1;
17938
17939 if (cs->cpu_index == 0) {
17940 /* VPE0 starts up enabled. */
17941 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
17942 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
17943
17944 /* TC0 starts up unhalted. */
17945 cs->halted = 0;
17946 env->active_tc.CP0_TCHalt = 0;
17947 env->tcs[0].CP0_TCHalt = 0;
17948 /* With thread 0 active. */
17949 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
17950 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
17951 }
17952 }
17953 #endif
17954 if ((env->insn_flags & ISA_MIPS32R6) &&
17955 (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
17956 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
17957 env->CP0_Status |= (1 << CP0St_FR);
17958 }
17959
17960 compute_hflags(env);
17961 cs->exception_index = EXCP_NONE;
17962 }
17963
17964 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
17965 {
17966 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
17967 env->hflags &= ~MIPS_HFLAG_BMASK;
17968 env->hflags |= gen_opc_hflags[pc_pos];
17969 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
17970 case MIPS_HFLAG_BR:
17971 break;
17972 case MIPS_HFLAG_BC:
17973 case MIPS_HFLAG_BL:
17974 case MIPS_HFLAG_B:
17975 env->btarget = gen_opc_btarget[pc_pos];
17976 break;
17977 }
17978 }