]> git.proxmox.com Git - mirror_qemu.git/blob - target-mips/translate.c
target-mips: Add ASE DSP compare-pick instructions
[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.h"
26 #include "tcg-op.h"
27
28 #include "helper.h"
29 #define GEN_HELPER 1
30 #include "helper.h"
31
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
34
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
37
38 enum {
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
62 OPC_J = (0x02 << 26),
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
75 /* Load and stores */
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
117 };
118
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
121
122 enum {
123 /* Shifts */
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
171 /* Jumps */
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
176 /* Traps */
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
191
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
193
194 /* Special */
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
200
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
208 };
209
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
212
213 enum {
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
228 };
229
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
232
233 enum {
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
251 };
252
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
255
256 enum {
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
263 /* Loongson 2F */
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
276 /* Misc */
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
281 /* Special */
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
283 };
284
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
287
288 enum {
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
302
303 /* Loongson 2E */
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
316
317 /* MIPS DSP Load */
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 #if defined(TARGET_MIPS64)
322 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
323 #endif
324 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
325 #if defined(TARGET_MIPS64)
326 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
327 #endif
328 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
329 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
330 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
331 #if defined(TARGET_MIPS64)
332 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
333 #endif
334 /* MIPS DSP GPR-Based Shift Sub-class */
335 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
336 #if defined(TARGET_MIPS64)
337 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
338 #endif
339 /* MIPS DSP Multiply Sub-class insns */
340 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
341 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
342 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
343 #if defined(TARGET_MIPS64)
344 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
345 #endif
346 /* DSP Bit/Manipulation Sub-class */
347 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
348 #if defined(TARGET_MIPS64)
349 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
350 #endif
351 /* MIPS DSP Compare-Pick Sub-class */
352 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
353 #if defined(TARGET_MIPS64)
354 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
355 #endif
356 };
357
358 /* BSHFL opcodes */
359 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360
361 enum {
362 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
363 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
364 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
365 };
366
367 /* DBSHFL opcodes */
368 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
369
370 enum {
371 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
372 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
373 };
374
375 /* MIPS DSP REGIMM opcodes */
376 enum {
377 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
378 #if defined(TARGET_MIPS64)
379 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
380 #endif
381 };
382
383 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
384 /* MIPS DSP Load */
385 enum {
386 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
387 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
388 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
389 #if defined(TARGET_MIPS64)
390 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
391 #endif
392 };
393
394 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
395 enum {
396 /* MIPS DSP Arithmetic Sub-class */
397 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
398 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
399 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
400 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
401 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
402 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
403 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
404 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
405 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
406 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
407 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
408 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
409 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
410 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
411 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
412 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
413 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
414 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
415 /* MIPS DSP Multiply Sub-class insns */
416 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
417 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
418 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
419 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
420 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
421 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
422 };
423
424 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
425 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
426 enum {
427 /* MIPS DSP Arithmetic Sub-class */
428 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
430 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
431 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
432 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
433 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
434 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
435 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
436 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
437 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
438 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
439 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
440 /* MIPS DSP Multiply Sub-class insns */
441 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
442 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
443 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
444 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
445 };
446
447 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
448 enum {
449 /* MIPS DSP Arithmetic Sub-class */
450 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
454 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
455 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
456 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
457 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
458 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
459 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
460 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
461 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
462 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
463 /* DSP Bit/Manipulation Sub-class */
464 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
465 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
466 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
467 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
468 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
469 };
470
471 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
472 enum {
473 /* MIPS DSP Arithmetic Sub-class */
474 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
481 /* DSP Compare-Pick Sub-class */
482 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
483 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
484 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
485 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
486 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
487 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
488 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
489 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
490 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
491 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
492 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
493 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
494 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
495 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
496 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
497 };
498
499 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
500 enum {
501 /* MIPS DSP GPR-Based Shift Sub-class */
502 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
509 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
510 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
511 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
512 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
513 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
514 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
515 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
516 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
517 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
518 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
519 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
520 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
521 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
522 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
523 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
524 };
525
526 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
527 enum {
528 /* MIPS DSP Multiply Sub-class insns */
529 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
531 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
532 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
533 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
536 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
537 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
538 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
539 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
540 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
541 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
542 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
543 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
544 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
545 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
546 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
547 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
548 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
549 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
550 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
551 };
552
553 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 enum {
555 /* DSP Bit/Manipulation Sub-class */
556 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
557 };
558
559 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
560 enum {
561 /* MIPS DSP Compare-Pick Sub-class */
562 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
563 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
564 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
565 };
566
567 #if defined(TARGET_MIPS64)
568 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
569 enum {
570 /* MIPS DSP Arithmetic Sub-class */
571 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
572 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
573 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
574 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
575 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
576 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
577 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
588 /* DSP Bit/Manipulation Sub-class */
589 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
594 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
595 };
596 #endif
597
598 #if defined(TARGET_MIPS64)
599 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
600 enum {
601 /* MIPS DSP Multiply Sub-class insns */
602 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
603 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
604 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
605 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
606 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
607 /* MIPS DSP Arithmetic Sub-class */
608 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
609 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
610 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
611 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
612 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
619 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
620 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
621 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
622 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
629 };
630 #endif
631
632 #if defined(TARGET_MIPS64)
633 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
634 enum {
635 /* DSP Compare-Pick Sub-class */
636 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
637 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
638 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
655 /* MIPS DSP Arithmetic Sub-class */
656 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
657 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
658 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
664 };
665 #endif
666
667 #if defined(TARGET_MIPS64)
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669 enum {
670 /* DSP Compare-Pick Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
675 };
676 #endif
677
678 #if defined(TARGET_MIPS64)
679 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
680 enum {
681 /* DSP Bit/Manipulation Sub-class */
682 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
683 };
684 #endif
685
686 #if defined(TARGET_MIPS64)
687 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
688 enum {
689 /* MIPS DSP Multiply Sub-class insns */
690 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
691 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
692 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
693 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
694 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
695 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
696 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
697 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
698 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
699 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
700 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
701 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
702 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
703 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
704 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
705 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
706 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
707 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
708 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
709 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
710 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
711 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
712 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
716 };
717 #endif
718
719 #if defined(TARGET_MIPS64)
720 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
721 enum {
722 /* MIPS DSP GPR-Based Shift Sub-class */
723 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
724 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
725 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
726 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
727 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
728 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
729 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
730 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
731 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
732 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
733 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
734 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
735 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
736 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
737 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
738 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
739 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
740 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
741 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
742 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
743 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
749 };
750 #endif
751
752 /* Coprocessor 0 (rs field) */
753 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
754
755 enum {
756 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
757 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
758 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
759 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
760 OPC_MFTR = (0x08 << 21) | OPC_CP0,
761 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
762 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
763 OPC_MTTR = (0x0C << 21) | OPC_CP0,
764 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
765 OPC_C0 = (0x10 << 21) | OPC_CP0,
766 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
767 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
768 };
769
770 /* MFMC0 opcodes */
771 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
772
773 enum {
774 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
775 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
776 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
777 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
778 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
779 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
780 };
781
782 /* Coprocessor 0 (with rs == C0) */
783 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
784
785 enum {
786 OPC_TLBR = 0x01 | OPC_C0,
787 OPC_TLBWI = 0x02 | OPC_C0,
788 OPC_TLBWR = 0x06 | OPC_C0,
789 OPC_TLBP = 0x08 | OPC_C0,
790 OPC_RFE = 0x10 | OPC_C0,
791 OPC_ERET = 0x18 | OPC_C0,
792 OPC_DERET = 0x1F | OPC_C0,
793 OPC_WAIT = 0x20 | OPC_C0,
794 };
795
796 /* Coprocessor 1 (rs field) */
797 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
798
799 /* Values for the fmt field in FP instructions */
800 enum {
801 /* 0 - 15 are reserved */
802 FMT_S = 16, /* single fp */
803 FMT_D = 17, /* double fp */
804 FMT_E = 18, /* extended fp */
805 FMT_Q = 19, /* quad fp */
806 FMT_W = 20, /* 32-bit fixed */
807 FMT_L = 21, /* 64-bit fixed */
808 FMT_PS = 22, /* paired single fp */
809 /* 23 - 31 are reserved */
810 };
811
812 enum {
813 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
814 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
815 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
816 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
817 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
818 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
819 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
820 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
821 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
822 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
823 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
824 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
825 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
826 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
827 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
828 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
829 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
830 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
831 };
832
833 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
834 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
835
836 enum {
837 OPC_BC1F = (0x00 << 16) | OPC_BC1,
838 OPC_BC1T = (0x01 << 16) | OPC_BC1,
839 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
840 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
841 };
842
843 enum {
844 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
845 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
846 };
847
848 enum {
849 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
850 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
851 };
852
853 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
854
855 enum {
856 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
857 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
858 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
859 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
860 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
861 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
862 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
863 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
864 OPC_BC2 = (0x08 << 21) | OPC_CP2,
865 };
866
867 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
868
869 enum {
870 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
871 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
872 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
873 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
874 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
875 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
876 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
877 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
878
879 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
880 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
881 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
882 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
883 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
884 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
885 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
886 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
887
888 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
889 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
890 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
891 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
892 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
893 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
894 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
895 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
896
897 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
898 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
899 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
900 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
901 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
902 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
903 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
904 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
905
906 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
907 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
908 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
909 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
910 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
911 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
912
913 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
914 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
915 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
916 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
917 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
918 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
919
920 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
921 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
922 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
923 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
924 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
925 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
926
927 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
928 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
929 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
930 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
931 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
932 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
933
934 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
935 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
936 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
937 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
938 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
939 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
940
941 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
942 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
943 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
944 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
945 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
946 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
947
948 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
949 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
950 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
951 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
952 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
953 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
954
955 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
956 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
957 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
958 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
959 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
960 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
961 };
962
963
964 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
965
966 enum {
967 OPC_LWXC1 = 0x00 | OPC_CP3,
968 OPC_LDXC1 = 0x01 | OPC_CP3,
969 OPC_LUXC1 = 0x05 | OPC_CP3,
970 OPC_SWXC1 = 0x08 | OPC_CP3,
971 OPC_SDXC1 = 0x09 | OPC_CP3,
972 OPC_SUXC1 = 0x0D | OPC_CP3,
973 OPC_PREFX = 0x0F | OPC_CP3,
974 OPC_ALNV_PS = 0x1E | OPC_CP3,
975 OPC_MADD_S = 0x20 | OPC_CP3,
976 OPC_MADD_D = 0x21 | OPC_CP3,
977 OPC_MADD_PS = 0x26 | OPC_CP3,
978 OPC_MSUB_S = 0x28 | OPC_CP3,
979 OPC_MSUB_D = 0x29 | OPC_CP3,
980 OPC_MSUB_PS = 0x2E | OPC_CP3,
981 OPC_NMADD_S = 0x30 | OPC_CP3,
982 OPC_NMADD_D = 0x31 | OPC_CP3,
983 OPC_NMADD_PS= 0x36 | OPC_CP3,
984 OPC_NMSUB_S = 0x38 | OPC_CP3,
985 OPC_NMSUB_D = 0x39 | OPC_CP3,
986 OPC_NMSUB_PS= 0x3E | OPC_CP3,
987 };
988
989 /* global register indices */
990 static TCGv_ptr cpu_env;
991 static TCGv cpu_gpr[32], cpu_PC;
992 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
993 static TCGv cpu_dspctrl, btarget, bcond;
994 static TCGv_i32 hflags;
995 static TCGv_i32 fpu_fcr0, fpu_fcr31;
996 static TCGv_i64 fpu_f64[32];
997
998 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
999
1000 #include "gen-icount.h"
1001
1002 #define gen_helper_0e0i(name, arg) do { \
1003 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1004 gen_helper_##name(cpu_env, helper_tmp); \
1005 tcg_temp_free_i32(helper_tmp); \
1006 } while(0)
1007
1008 #define gen_helper_0e1i(name, arg1, arg2) do { \
1009 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1010 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1011 tcg_temp_free_i32(helper_tmp); \
1012 } while(0)
1013
1014 #define gen_helper_1e0i(name, ret, arg1) do { \
1015 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1016 gen_helper_##name(ret, cpu_env, helper_tmp); \
1017 tcg_temp_free_i32(helper_tmp); \
1018 } while(0)
1019
1020 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1021 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1022 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1023 tcg_temp_free_i32(helper_tmp); \
1024 } while(0)
1025
1026 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1027 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1028 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1029 tcg_temp_free_i32(helper_tmp); \
1030 } while(0)
1031
1032 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1033 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1034 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1035 tcg_temp_free_i32(helper_tmp); \
1036 } while(0)
1037
1038 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1039 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1040 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1041 tcg_temp_free_i32(helper_tmp); \
1042 } while(0)
1043
1044 typedef struct DisasContext {
1045 struct TranslationBlock *tb;
1046 target_ulong pc, saved_pc;
1047 uint32_t opcode;
1048 int singlestep_enabled;
1049 /* Routine used to access memory */
1050 int mem_idx;
1051 uint32_t hflags, saved_hflags;
1052 int bstate;
1053 target_ulong btarget;
1054 } DisasContext;
1055
1056 enum {
1057 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1058 * exception condition */
1059 BS_STOP = 1, /* We want to stop translation for any reason */
1060 BS_BRANCH = 2, /* We reached a branch condition */
1061 BS_EXCP = 3, /* We reached an exception condition */
1062 };
1063
1064 static const char * const regnames[] = {
1065 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1066 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1067 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1068 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1069 };
1070
1071 static const char * const regnames_HI[] = {
1072 "HI0", "HI1", "HI2", "HI3",
1073 };
1074
1075 static const char * const regnames_LO[] = {
1076 "LO0", "LO1", "LO2", "LO3",
1077 };
1078
1079 static const char * const regnames_ACX[] = {
1080 "ACX0", "ACX1", "ACX2", "ACX3",
1081 };
1082
1083 static const char * const fregnames[] = {
1084 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1085 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1086 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1087 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1088 };
1089
1090 #define MIPS_DEBUG(fmt, ...) \
1091 do { \
1092 if (MIPS_DEBUG_DISAS) { \
1093 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1094 TARGET_FMT_lx ": %08x " fmt "\n", \
1095 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1096 } \
1097 } while (0)
1098
1099 #define LOG_DISAS(...) \
1100 do { \
1101 if (MIPS_DEBUG_DISAS) { \
1102 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1103 } \
1104 } while (0)
1105
1106 #define MIPS_INVAL(op) \
1107 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1108 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1109
1110 /* General purpose registers moves. */
1111 static inline void gen_load_gpr (TCGv t, int reg)
1112 {
1113 if (reg == 0)
1114 tcg_gen_movi_tl(t, 0);
1115 else
1116 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1117 }
1118
1119 static inline void gen_store_gpr (TCGv t, int reg)
1120 {
1121 if (reg != 0)
1122 tcg_gen_mov_tl(cpu_gpr[reg], t);
1123 }
1124
1125 /* Moves to/from ACX register. */
1126 static inline void gen_load_ACX (TCGv t, int reg)
1127 {
1128 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1129 }
1130
1131 static inline void gen_store_ACX (TCGv t, int reg)
1132 {
1133 tcg_gen_mov_tl(cpu_ACX[reg], t);
1134 }
1135
1136 /* Moves to/from shadow registers. */
1137 static inline void gen_load_srsgpr (int from, int to)
1138 {
1139 TCGv t0 = tcg_temp_new();
1140
1141 if (from == 0)
1142 tcg_gen_movi_tl(t0, 0);
1143 else {
1144 TCGv_i32 t2 = tcg_temp_new_i32();
1145 TCGv_ptr addr = tcg_temp_new_ptr();
1146
1147 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1148 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1149 tcg_gen_andi_i32(t2, t2, 0xf);
1150 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1151 tcg_gen_ext_i32_ptr(addr, t2);
1152 tcg_gen_add_ptr(addr, cpu_env, addr);
1153
1154 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1155 tcg_temp_free_ptr(addr);
1156 tcg_temp_free_i32(t2);
1157 }
1158 gen_store_gpr(t0, to);
1159 tcg_temp_free(t0);
1160 }
1161
1162 static inline void gen_store_srsgpr (int from, int to)
1163 {
1164 if (to != 0) {
1165 TCGv t0 = tcg_temp_new();
1166 TCGv_i32 t2 = tcg_temp_new_i32();
1167 TCGv_ptr addr = tcg_temp_new_ptr();
1168
1169 gen_load_gpr(t0, from);
1170 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1171 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1172 tcg_gen_andi_i32(t2, t2, 0xf);
1173 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1174 tcg_gen_ext_i32_ptr(addr, t2);
1175 tcg_gen_add_ptr(addr, cpu_env, addr);
1176
1177 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1178 tcg_temp_free_ptr(addr);
1179 tcg_temp_free_i32(t2);
1180 tcg_temp_free(t0);
1181 }
1182 }
1183
1184 /* Floating point register moves. */
1185 static void gen_load_fpr32(TCGv_i32 t, int reg)
1186 {
1187 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1188 }
1189
1190 static void gen_store_fpr32(TCGv_i32 t, int reg)
1191 {
1192 TCGv_i64 t64 = tcg_temp_new_i64();
1193 tcg_gen_extu_i32_i64(t64, t);
1194 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1195 tcg_temp_free_i64(t64);
1196 }
1197
1198 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1199 {
1200 TCGv_i64 t64 = tcg_temp_new_i64();
1201 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1202 tcg_gen_trunc_i64_i32(t, t64);
1203 tcg_temp_free_i64(t64);
1204 }
1205
1206 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1207 {
1208 TCGv_i64 t64 = tcg_temp_new_i64();
1209 tcg_gen_extu_i32_i64(t64, t);
1210 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1211 tcg_temp_free_i64(t64);
1212 }
1213
1214 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1215 {
1216 if (ctx->hflags & MIPS_HFLAG_F64) {
1217 tcg_gen_mov_i64(t, fpu_f64[reg]);
1218 } else {
1219 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1220 }
1221 }
1222
1223 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1224 {
1225 if (ctx->hflags & MIPS_HFLAG_F64) {
1226 tcg_gen_mov_i64(fpu_f64[reg], t);
1227 } else {
1228 TCGv_i64 t0;
1229 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1230 t0 = tcg_temp_new_i64();
1231 tcg_gen_shri_i64(t0, t, 32);
1232 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1233 tcg_temp_free_i64(t0);
1234 }
1235 }
1236
1237 static inline int get_fp_bit (int cc)
1238 {
1239 if (cc)
1240 return 24 + cc;
1241 else
1242 return 23;
1243 }
1244
1245 /* Tests */
1246 static inline void gen_save_pc(target_ulong pc)
1247 {
1248 tcg_gen_movi_tl(cpu_PC, pc);
1249 }
1250
1251 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1252 {
1253 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1254 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1255 gen_save_pc(ctx->pc);
1256 ctx->saved_pc = ctx->pc;
1257 }
1258 if (ctx->hflags != ctx->saved_hflags) {
1259 tcg_gen_movi_i32(hflags, ctx->hflags);
1260 ctx->saved_hflags = ctx->hflags;
1261 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1262 case MIPS_HFLAG_BR:
1263 break;
1264 case MIPS_HFLAG_BC:
1265 case MIPS_HFLAG_BL:
1266 case MIPS_HFLAG_B:
1267 tcg_gen_movi_tl(btarget, ctx->btarget);
1268 break;
1269 }
1270 }
1271 }
1272
1273 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1274 {
1275 ctx->saved_hflags = ctx->hflags;
1276 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1277 case MIPS_HFLAG_BR:
1278 break;
1279 case MIPS_HFLAG_BC:
1280 case MIPS_HFLAG_BL:
1281 case MIPS_HFLAG_B:
1282 ctx->btarget = env->btarget;
1283 break;
1284 }
1285 }
1286
1287 static inline void
1288 generate_exception_err (DisasContext *ctx, int excp, int err)
1289 {
1290 TCGv_i32 texcp = tcg_const_i32(excp);
1291 TCGv_i32 terr = tcg_const_i32(err);
1292 save_cpu_state(ctx, 1);
1293 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1294 tcg_temp_free_i32(terr);
1295 tcg_temp_free_i32(texcp);
1296 }
1297
1298 static inline void
1299 generate_exception (DisasContext *ctx, int excp)
1300 {
1301 save_cpu_state(ctx, 1);
1302 gen_helper_0e0i(raise_exception, excp);
1303 }
1304
1305 /* Addresses computation */
1306 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1307 {
1308 tcg_gen_add_tl(ret, arg0, arg1);
1309
1310 #if defined(TARGET_MIPS64)
1311 /* For compatibility with 32-bit code, data reference in user mode
1312 with Status_UX = 0 should be casted to 32-bit and sign extended.
1313 See the MIPS64 PRA manual, section 4.10. */
1314 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1315 !(ctx->hflags & MIPS_HFLAG_UX)) {
1316 tcg_gen_ext32s_i64(ret, ret);
1317 }
1318 #endif
1319 }
1320
1321 static inline void check_cp0_enabled(DisasContext *ctx)
1322 {
1323 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1324 generate_exception_err(ctx, EXCP_CpU, 0);
1325 }
1326
1327 static inline void check_cp1_enabled(DisasContext *ctx)
1328 {
1329 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1330 generate_exception_err(ctx, EXCP_CpU, 1);
1331 }
1332
1333 /* Verify that the processor is running with COP1X instructions enabled.
1334 This is associated with the nabla symbol in the MIPS32 and MIPS64
1335 opcode tables. */
1336
1337 static inline void check_cop1x(DisasContext *ctx)
1338 {
1339 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1340 generate_exception(ctx, EXCP_RI);
1341 }
1342
1343 /* Verify that the processor is running with 64-bit floating-point
1344 operations enabled. */
1345
1346 static inline void check_cp1_64bitmode(DisasContext *ctx)
1347 {
1348 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1349 generate_exception(ctx, EXCP_RI);
1350 }
1351
1352 /*
1353 * Verify if floating point register is valid; an operation is not defined
1354 * if bit 0 of any register specification is set and the FR bit in the
1355 * Status register equals zero, since the register numbers specify an
1356 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1357 * in the Status register equals one, both even and odd register numbers
1358 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1359 *
1360 * Multiple 64 bit wide registers can be checked by calling
1361 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1362 */
1363 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1364 {
1365 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1366 generate_exception(ctx, EXCP_RI);
1367 }
1368
1369 /* Verify that the processor is running with DSP instructions enabled.
1370 This is enabled by CP0 Status register MX(24) bit.
1371 */
1372
1373 static inline void check_dsp(DisasContext *ctx)
1374 {
1375 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1376 generate_exception(ctx, EXCP_DSPDIS);
1377 }
1378 }
1379
1380 static inline void check_dspr2(DisasContext *ctx)
1381 {
1382 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1383 generate_exception(ctx, EXCP_DSPDIS);
1384 }
1385 }
1386
1387 /* This code generates a "reserved instruction" exception if the
1388 CPU does not support the instruction set corresponding to flags. */
1389 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1390 {
1391 if (unlikely(!(env->insn_flags & flags)))
1392 generate_exception(ctx, EXCP_RI);
1393 }
1394
1395 /* This code generates a "reserved instruction" exception if 64-bit
1396 instructions are not enabled. */
1397 static inline void check_mips_64(DisasContext *ctx)
1398 {
1399 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1400 generate_exception(ctx, EXCP_RI);
1401 }
1402
1403 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1404 calling interface for 32 and 64-bit FPRs. No sense in changing
1405 all callers for gen_load_fpr32 when we need the CTX parameter for
1406 this one use. */
1407 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1408 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1409 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1410 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1411 int ft, int fs, int cc) \
1412 { \
1413 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1414 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1415 switch (ifmt) { \
1416 case FMT_PS: \
1417 check_cp1_64bitmode(ctx); \
1418 break; \
1419 case FMT_D: \
1420 if (abs) { \
1421 check_cop1x(ctx); \
1422 } \
1423 check_cp1_registers(ctx, fs | ft); \
1424 break; \
1425 case FMT_S: \
1426 if (abs) { \
1427 check_cop1x(ctx); \
1428 } \
1429 break; \
1430 } \
1431 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1432 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1433 switch (n) { \
1434 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1435 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1436 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1437 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1438 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1439 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1440 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1441 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1442 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1443 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1444 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1445 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1446 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1447 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1448 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1449 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1450 default: abort(); \
1451 } \
1452 tcg_temp_free_i##bits (fp0); \
1453 tcg_temp_free_i##bits (fp1); \
1454 }
1455
1456 FOP_CONDS(, 0, d, FMT_D, 64)
1457 FOP_CONDS(abs, 1, d, FMT_D, 64)
1458 FOP_CONDS(, 0, s, FMT_S, 32)
1459 FOP_CONDS(abs, 1, s, FMT_S, 32)
1460 FOP_CONDS(, 0, ps, FMT_PS, 64)
1461 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1462 #undef FOP_CONDS
1463 #undef gen_ldcmp_fpr32
1464 #undef gen_ldcmp_fpr64
1465
1466 /* load/store instructions. */
1467 #define OP_LD(insn,fname) \
1468 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1469 { \
1470 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1471 }
1472 OP_LD(lb,ld8s);
1473 OP_LD(lbu,ld8u);
1474 OP_LD(lh,ld16s);
1475 OP_LD(lhu,ld16u);
1476 OP_LD(lw,ld32s);
1477 #if defined(TARGET_MIPS64)
1478 OP_LD(lwu,ld32u);
1479 OP_LD(ld,ld64);
1480 #endif
1481 #undef OP_LD
1482
1483 #define OP_ST(insn,fname) \
1484 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
1485 { \
1486 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
1487 }
1488 OP_ST(sb,st8);
1489 OP_ST(sh,st16);
1490 OP_ST(sw,st32);
1491 #if defined(TARGET_MIPS64)
1492 OP_ST(sd,st64);
1493 #endif
1494 #undef OP_ST
1495
1496 #ifdef CONFIG_USER_ONLY
1497 #define OP_LD_ATOMIC(insn,fname) \
1498 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1499 { \
1500 TCGv t0 = tcg_temp_new(); \
1501 tcg_gen_mov_tl(t0, arg1); \
1502 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1503 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1504 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1505 tcg_temp_free(t0); \
1506 }
1507 #else
1508 #define OP_LD_ATOMIC(insn,fname) \
1509 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1510 { \
1511 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1512 }
1513 #endif
1514 OP_LD_ATOMIC(ll,ld32s);
1515 #if defined(TARGET_MIPS64)
1516 OP_LD_ATOMIC(lld,ld64);
1517 #endif
1518 #undef OP_LD_ATOMIC
1519
1520 #ifdef CONFIG_USER_ONLY
1521 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1522 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1523 { \
1524 TCGv t0 = tcg_temp_new(); \
1525 int l1 = gen_new_label(); \
1526 int l2 = gen_new_label(); \
1527 \
1528 tcg_gen_andi_tl(t0, arg2, almask); \
1529 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1530 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1531 generate_exception(ctx, EXCP_AdES); \
1532 gen_set_label(l1); \
1533 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1534 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1535 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1536 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1537 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1538 gen_helper_0e0i(raise_exception, EXCP_SC); \
1539 gen_set_label(l2); \
1540 tcg_gen_movi_tl(t0, 0); \
1541 gen_store_gpr(t0, rt); \
1542 tcg_temp_free(t0); \
1543 }
1544 #else
1545 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1546 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1547 { \
1548 TCGv t0 = tcg_temp_new(); \
1549 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1550 gen_store_gpr(t0, rt); \
1551 tcg_temp_free(t0); \
1552 }
1553 #endif
1554 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1555 #if defined(TARGET_MIPS64)
1556 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1557 #endif
1558 #undef OP_ST_ATOMIC
1559
1560 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1561 int base, int16_t offset)
1562 {
1563 if (base == 0) {
1564 tcg_gen_movi_tl(addr, offset);
1565 } else if (offset == 0) {
1566 gen_load_gpr(addr, base);
1567 } else {
1568 tcg_gen_movi_tl(addr, offset);
1569 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1570 }
1571 }
1572
1573 static target_ulong pc_relative_pc (DisasContext *ctx)
1574 {
1575 target_ulong pc = ctx->pc;
1576
1577 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1578 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1579
1580 pc -= branch_bytes;
1581 }
1582
1583 pc &= ~(target_ulong)3;
1584 return pc;
1585 }
1586
1587 /* Load */
1588 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1589 int rt, int base, int16_t offset)
1590 {
1591 const char *opn = "ld";
1592 TCGv t0, t1;
1593
1594 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1595 /* Loongson CPU uses a load to zero register for prefetch.
1596 We emulate it as a NOP. On other CPU we must perform the
1597 actual memory access. */
1598 MIPS_DEBUG("NOP");
1599 return;
1600 }
1601
1602 t0 = tcg_temp_new();
1603 t1 = tcg_temp_new();
1604 gen_base_offset_addr(ctx, t0, base, offset);
1605
1606 switch (opc) {
1607 #if defined(TARGET_MIPS64)
1608 case OPC_LWU:
1609 save_cpu_state(ctx, 0);
1610 op_ld_lwu(t0, t0, ctx);
1611 gen_store_gpr(t0, rt);
1612 opn = "lwu";
1613 break;
1614 case OPC_LD:
1615 save_cpu_state(ctx, 0);
1616 op_ld_ld(t0, t0, ctx);
1617 gen_store_gpr(t0, rt);
1618 opn = "ld";
1619 break;
1620 case OPC_LLD:
1621 save_cpu_state(ctx, 1);
1622 op_ld_lld(t0, t0, ctx);
1623 gen_store_gpr(t0, rt);
1624 opn = "lld";
1625 break;
1626 case OPC_LDL:
1627 save_cpu_state(ctx, 1);
1628 gen_load_gpr(t1, rt);
1629 gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
1630 gen_store_gpr(t1, rt);
1631 opn = "ldl";
1632 break;
1633 case OPC_LDR:
1634 save_cpu_state(ctx, 1);
1635 gen_load_gpr(t1, rt);
1636 gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
1637 gen_store_gpr(t1, rt);
1638 opn = "ldr";
1639 break;
1640 case OPC_LDPC:
1641 save_cpu_state(ctx, 0);
1642 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1643 gen_op_addr_add(ctx, t0, t0, t1);
1644 op_ld_ld(t0, t0, ctx);
1645 gen_store_gpr(t0, rt);
1646 opn = "ldpc";
1647 break;
1648 #endif
1649 case OPC_LWPC:
1650 save_cpu_state(ctx, 0);
1651 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1652 gen_op_addr_add(ctx, t0, t0, t1);
1653 op_ld_lw(t0, t0, ctx);
1654 gen_store_gpr(t0, rt);
1655 opn = "lwpc";
1656 break;
1657 case OPC_LW:
1658 save_cpu_state(ctx, 0);
1659 op_ld_lw(t0, t0, ctx);
1660 gen_store_gpr(t0, rt);
1661 opn = "lw";
1662 break;
1663 case OPC_LH:
1664 save_cpu_state(ctx, 0);
1665 op_ld_lh(t0, t0, ctx);
1666 gen_store_gpr(t0, rt);
1667 opn = "lh";
1668 break;
1669 case OPC_LHU:
1670 save_cpu_state(ctx, 0);
1671 op_ld_lhu(t0, t0, ctx);
1672 gen_store_gpr(t0, rt);
1673 opn = "lhu";
1674 break;
1675 case OPC_LB:
1676 save_cpu_state(ctx, 0);
1677 op_ld_lb(t0, t0, ctx);
1678 gen_store_gpr(t0, rt);
1679 opn = "lb";
1680 break;
1681 case OPC_LBU:
1682 save_cpu_state(ctx, 0);
1683 op_ld_lbu(t0, t0, ctx);
1684 gen_store_gpr(t0, rt);
1685 opn = "lbu";
1686 break;
1687 case OPC_LWL:
1688 save_cpu_state(ctx, 1);
1689 gen_load_gpr(t1, rt);
1690 gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
1691 gen_store_gpr(t1, rt);
1692 opn = "lwl";
1693 break;
1694 case OPC_LWR:
1695 save_cpu_state(ctx, 1);
1696 gen_load_gpr(t1, rt);
1697 gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
1698 gen_store_gpr(t1, rt);
1699 opn = "lwr";
1700 break;
1701 case OPC_LL:
1702 save_cpu_state(ctx, 1);
1703 op_ld_ll(t0, t0, ctx);
1704 gen_store_gpr(t0, rt);
1705 opn = "ll";
1706 break;
1707 }
1708 (void)opn; /* avoid a compiler warning */
1709 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1710 tcg_temp_free(t0);
1711 tcg_temp_free(t1);
1712 }
1713
1714 /* Store */
1715 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1716 int base, int16_t offset)
1717 {
1718 const char *opn = "st";
1719 TCGv t0 = tcg_temp_new();
1720 TCGv t1 = tcg_temp_new();
1721
1722 gen_base_offset_addr(ctx, t0, base, offset);
1723 gen_load_gpr(t1, rt);
1724 switch (opc) {
1725 #if defined(TARGET_MIPS64)
1726 case OPC_SD:
1727 save_cpu_state(ctx, 0);
1728 op_st_sd(t1, t0, ctx);
1729 opn = "sd";
1730 break;
1731 case OPC_SDL:
1732 save_cpu_state(ctx, 1);
1733 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1734 opn = "sdl";
1735 break;
1736 case OPC_SDR:
1737 save_cpu_state(ctx, 1);
1738 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1739 opn = "sdr";
1740 break;
1741 #endif
1742 case OPC_SW:
1743 save_cpu_state(ctx, 0);
1744 op_st_sw(t1, t0, ctx);
1745 opn = "sw";
1746 break;
1747 case OPC_SH:
1748 save_cpu_state(ctx, 0);
1749 op_st_sh(t1, t0, ctx);
1750 opn = "sh";
1751 break;
1752 case OPC_SB:
1753 save_cpu_state(ctx, 0);
1754 op_st_sb(t1, t0, ctx);
1755 opn = "sb";
1756 break;
1757 case OPC_SWL:
1758 save_cpu_state(ctx, 1);
1759 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1760 opn = "swl";
1761 break;
1762 case OPC_SWR:
1763 save_cpu_state(ctx, 1);
1764 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1765 opn = "swr";
1766 break;
1767 }
1768 (void)opn; /* avoid a compiler warning */
1769 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1770 tcg_temp_free(t0);
1771 tcg_temp_free(t1);
1772 }
1773
1774
1775 /* Store conditional */
1776 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1777 int base, int16_t offset)
1778 {
1779 const char *opn = "st_cond";
1780 TCGv t0, t1;
1781
1782 t0 = tcg_temp_local_new();
1783
1784 gen_base_offset_addr(ctx, t0, base, offset);
1785 /* Don't do NOP if destination is zero: we must perform the actual
1786 memory access. */
1787
1788 t1 = tcg_temp_local_new();
1789 gen_load_gpr(t1, rt);
1790 switch (opc) {
1791 #if defined(TARGET_MIPS64)
1792 case OPC_SCD:
1793 save_cpu_state(ctx, 1);
1794 op_st_scd(t1, t0, rt, ctx);
1795 opn = "scd";
1796 break;
1797 #endif
1798 case OPC_SC:
1799 save_cpu_state(ctx, 1);
1800 op_st_sc(t1, t0, rt, ctx);
1801 opn = "sc";
1802 break;
1803 }
1804 (void)opn; /* avoid a compiler warning */
1805 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1806 tcg_temp_free(t1);
1807 tcg_temp_free(t0);
1808 }
1809
1810 /* Load and store */
1811 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1812 int base, int16_t offset)
1813 {
1814 const char *opn = "flt_ldst";
1815 TCGv t0 = tcg_temp_new();
1816
1817 gen_base_offset_addr(ctx, t0, base, offset);
1818 /* Don't do NOP if destination is zero: we must perform the actual
1819 memory access. */
1820 switch (opc) {
1821 case OPC_LWC1:
1822 {
1823 TCGv_i32 fp0 = tcg_temp_new_i32();
1824
1825 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1826 tcg_gen_trunc_tl_i32(fp0, t0);
1827 gen_store_fpr32(fp0, ft);
1828 tcg_temp_free_i32(fp0);
1829 }
1830 opn = "lwc1";
1831 break;
1832 case OPC_SWC1:
1833 {
1834 TCGv_i32 fp0 = tcg_temp_new_i32();
1835 TCGv t1 = tcg_temp_new();
1836
1837 gen_load_fpr32(fp0, ft);
1838 tcg_gen_extu_i32_tl(t1, fp0);
1839 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1840 tcg_temp_free(t1);
1841 tcg_temp_free_i32(fp0);
1842 }
1843 opn = "swc1";
1844 break;
1845 case OPC_LDC1:
1846 {
1847 TCGv_i64 fp0 = tcg_temp_new_i64();
1848
1849 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1850 gen_store_fpr64(ctx, fp0, ft);
1851 tcg_temp_free_i64(fp0);
1852 }
1853 opn = "ldc1";
1854 break;
1855 case OPC_SDC1:
1856 {
1857 TCGv_i64 fp0 = tcg_temp_new_i64();
1858
1859 gen_load_fpr64(ctx, fp0, ft);
1860 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1861 tcg_temp_free_i64(fp0);
1862 }
1863 opn = "sdc1";
1864 break;
1865 default:
1866 MIPS_INVAL(opn);
1867 generate_exception(ctx, EXCP_RI);
1868 goto out;
1869 }
1870 (void)opn; /* avoid a compiler warning */
1871 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1872 out:
1873 tcg_temp_free(t0);
1874 }
1875
1876 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1877 uint32_t op, int rt, int rs, int16_t imm)
1878 {
1879 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1880 check_cp1_enabled(ctx);
1881 gen_flt_ldst(ctx, op, rt, rs, imm);
1882 } else {
1883 generate_exception_err(ctx, EXCP_CpU, 1);
1884 }
1885 }
1886
1887 /* Arithmetic with immediate operand */
1888 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1889 int rt, int rs, int16_t imm)
1890 {
1891 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1892 const char *opn = "imm arith";
1893
1894 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1895 /* If no destination, treat it as a NOP.
1896 For addi, we must generate the overflow exception when needed. */
1897 MIPS_DEBUG("NOP");
1898 return;
1899 }
1900 switch (opc) {
1901 case OPC_ADDI:
1902 {
1903 TCGv t0 = tcg_temp_local_new();
1904 TCGv t1 = tcg_temp_new();
1905 TCGv t2 = tcg_temp_new();
1906 int l1 = gen_new_label();
1907
1908 gen_load_gpr(t1, rs);
1909 tcg_gen_addi_tl(t0, t1, uimm);
1910 tcg_gen_ext32s_tl(t0, t0);
1911
1912 tcg_gen_xori_tl(t1, t1, ~uimm);
1913 tcg_gen_xori_tl(t2, t0, uimm);
1914 tcg_gen_and_tl(t1, t1, t2);
1915 tcg_temp_free(t2);
1916 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1917 tcg_temp_free(t1);
1918 /* operands of same sign, result different sign */
1919 generate_exception(ctx, EXCP_OVERFLOW);
1920 gen_set_label(l1);
1921 tcg_gen_ext32s_tl(t0, t0);
1922 gen_store_gpr(t0, rt);
1923 tcg_temp_free(t0);
1924 }
1925 opn = "addi";
1926 break;
1927 case OPC_ADDIU:
1928 if (rs != 0) {
1929 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1930 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1931 } else {
1932 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1933 }
1934 opn = "addiu";
1935 break;
1936 #if defined(TARGET_MIPS64)
1937 case OPC_DADDI:
1938 {
1939 TCGv t0 = tcg_temp_local_new();
1940 TCGv t1 = tcg_temp_new();
1941 TCGv t2 = tcg_temp_new();
1942 int l1 = gen_new_label();
1943
1944 gen_load_gpr(t1, rs);
1945 tcg_gen_addi_tl(t0, t1, uimm);
1946
1947 tcg_gen_xori_tl(t1, t1, ~uimm);
1948 tcg_gen_xori_tl(t2, t0, uimm);
1949 tcg_gen_and_tl(t1, t1, t2);
1950 tcg_temp_free(t2);
1951 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1952 tcg_temp_free(t1);
1953 /* operands of same sign, result different sign */
1954 generate_exception(ctx, EXCP_OVERFLOW);
1955 gen_set_label(l1);
1956 gen_store_gpr(t0, rt);
1957 tcg_temp_free(t0);
1958 }
1959 opn = "daddi";
1960 break;
1961 case OPC_DADDIU:
1962 if (rs != 0) {
1963 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1964 } else {
1965 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1966 }
1967 opn = "daddiu";
1968 break;
1969 #endif
1970 }
1971 (void)opn; /* avoid a compiler warning */
1972 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1973 }
1974
1975 /* Logic with immediate operand */
1976 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1977 int rt, int rs, int16_t imm)
1978 {
1979 target_ulong uimm;
1980 const char *opn = "imm logic";
1981
1982 if (rt == 0) {
1983 /* If no destination, treat it as a NOP. */
1984 MIPS_DEBUG("NOP");
1985 return;
1986 }
1987 uimm = (uint16_t)imm;
1988 switch (opc) {
1989 case OPC_ANDI:
1990 if (likely(rs != 0))
1991 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1992 else
1993 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1994 opn = "andi";
1995 break;
1996 case OPC_ORI:
1997 if (rs != 0)
1998 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1999 else
2000 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2001 opn = "ori";
2002 break;
2003 case OPC_XORI:
2004 if (likely(rs != 0))
2005 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2006 else
2007 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2008 opn = "xori";
2009 break;
2010 case OPC_LUI:
2011 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2012 opn = "lui";
2013 break;
2014 }
2015 (void)opn; /* avoid a compiler warning */
2016 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2017 }
2018
2019 /* Set on less than with immediate operand */
2020 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2021 int rt, int rs, int16_t imm)
2022 {
2023 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2024 const char *opn = "imm arith";
2025 TCGv t0;
2026
2027 if (rt == 0) {
2028 /* If no destination, treat it as a NOP. */
2029 MIPS_DEBUG("NOP");
2030 return;
2031 }
2032 t0 = tcg_temp_new();
2033 gen_load_gpr(t0, rs);
2034 switch (opc) {
2035 case OPC_SLTI:
2036 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2037 opn = "slti";
2038 break;
2039 case OPC_SLTIU:
2040 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2041 opn = "sltiu";
2042 break;
2043 }
2044 (void)opn; /* avoid a compiler warning */
2045 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2046 tcg_temp_free(t0);
2047 }
2048
2049 /* Shifts with immediate operand */
2050 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2051 int rt, int rs, int16_t imm)
2052 {
2053 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2054 const char *opn = "imm shift";
2055 TCGv t0;
2056
2057 if (rt == 0) {
2058 /* If no destination, treat it as a NOP. */
2059 MIPS_DEBUG("NOP");
2060 return;
2061 }
2062
2063 t0 = tcg_temp_new();
2064 gen_load_gpr(t0, rs);
2065 switch (opc) {
2066 case OPC_SLL:
2067 tcg_gen_shli_tl(t0, t0, uimm);
2068 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2069 opn = "sll";
2070 break;
2071 case OPC_SRA:
2072 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2073 opn = "sra";
2074 break;
2075 case OPC_SRL:
2076 if (uimm != 0) {
2077 tcg_gen_ext32u_tl(t0, t0);
2078 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2079 } else {
2080 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2081 }
2082 opn = "srl";
2083 break;
2084 case OPC_ROTR:
2085 if (uimm != 0) {
2086 TCGv_i32 t1 = tcg_temp_new_i32();
2087
2088 tcg_gen_trunc_tl_i32(t1, t0);
2089 tcg_gen_rotri_i32(t1, t1, uimm);
2090 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2091 tcg_temp_free_i32(t1);
2092 } else {
2093 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2094 }
2095 opn = "rotr";
2096 break;
2097 #if defined(TARGET_MIPS64)
2098 case OPC_DSLL:
2099 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2100 opn = "dsll";
2101 break;
2102 case OPC_DSRA:
2103 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2104 opn = "dsra";
2105 break;
2106 case OPC_DSRL:
2107 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2108 opn = "dsrl";
2109 break;
2110 case OPC_DROTR:
2111 if (uimm != 0) {
2112 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2113 } else {
2114 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2115 }
2116 opn = "drotr";
2117 break;
2118 case OPC_DSLL32:
2119 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2120 opn = "dsll32";
2121 break;
2122 case OPC_DSRA32:
2123 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2124 opn = "dsra32";
2125 break;
2126 case OPC_DSRL32:
2127 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2128 opn = "dsrl32";
2129 break;
2130 case OPC_DROTR32:
2131 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2132 opn = "drotr32";
2133 break;
2134 #endif
2135 }
2136 (void)opn; /* avoid a compiler warning */
2137 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2138 tcg_temp_free(t0);
2139 }
2140
2141 /* Arithmetic */
2142 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2143 int rd, int rs, int rt)
2144 {
2145 const char *opn = "arith";
2146
2147 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2148 && opc != OPC_DADD && opc != OPC_DSUB) {
2149 /* If no destination, treat it as a NOP.
2150 For add & sub, we must generate the overflow exception when needed. */
2151 MIPS_DEBUG("NOP");
2152 return;
2153 }
2154
2155 switch (opc) {
2156 case OPC_ADD:
2157 {
2158 TCGv t0 = tcg_temp_local_new();
2159 TCGv t1 = tcg_temp_new();
2160 TCGv t2 = tcg_temp_new();
2161 int l1 = gen_new_label();
2162
2163 gen_load_gpr(t1, rs);
2164 gen_load_gpr(t2, rt);
2165 tcg_gen_add_tl(t0, t1, t2);
2166 tcg_gen_ext32s_tl(t0, t0);
2167 tcg_gen_xor_tl(t1, t1, t2);
2168 tcg_gen_xor_tl(t2, t0, t2);
2169 tcg_gen_andc_tl(t1, t2, t1);
2170 tcg_temp_free(t2);
2171 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2172 tcg_temp_free(t1);
2173 /* operands of same sign, result different sign */
2174 generate_exception(ctx, EXCP_OVERFLOW);
2175 gen_set_label(l1);
2176 gen_store_gpr(t0, rd);
2177 tcg_temp_free(t0);
2178 }
2179 opn = "add";
2180 break;
2181 case OPC_ADDU:
2182 if (rs != 0 && rt != 0) {
2183 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2184 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2185 } else if (rs == 0 && rt != 0) {
2186 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2187 } else if (rs != 0 && rt == 0) {
2188 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2189 } else {
2190 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2191 }
2192 opn = "addu";
2193 break;
2194 case OPC_SUB:
2195 {
2196 TCGv t0 = tcg_temp_local_new();
2197 TCGv t1 = tcg_temp_new();
2198 TCGv t2 = tcg_temp_new();
2199 int l1 = gen_new_label();
2200
2201 gen_load_gpr(t1, rs);
2202 gen_load_gpr(t2, rt);
2203 tcg_gen_sub_tl(t0, t1, t2);
2204 tcg_gen_ext32s_tl(t0, t0);
2205 tcg_gen_xor_tl(t2, t1, t2);
2206 tcg_gen_xor_tl(t1, t0, t1);
2207 tcg_gen_and_tl(t1, t1, t2);
2208 tcg_temp_free(t2);
2209 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2210 tcg_temp_free(t1);
2211 /* operands of different sign, first operand and result different sign */
2212 generate_exception(ctx, EXCP_OVERFLOW);
2213 gen_set_label(l1);
2214 gen_store_gpr(t0, rd);
2215 tcg_temp_free(t0);
2216 }
2217 opn = "sub";
2218 break;
2219 case OPC_SUBU:
2220 if (rs != 0 && rt != 0) {
2221 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2222 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2223 } else if (rs == 0 && rt != 0) {
2224 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2225 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2226 } else if (rs != 0 && rt == 0) {
2227 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2228 } else {
2229 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2230 }
2231 opn = "subu";
2232 break;
2233 #if defined(TARGET_MIPS64)
2234 case OPC_DADD:
2235 {
2236 TCGv t0 = tcg_temp_local_new();
2237 TCGv t1 = tcg_temp_new();
2238 TCGv t2 = tcg_temp_new();
2239 int l1 = gen_new_label();
2240
2241 gen_load_gpr(t1, rs);
2242 gen_load_gpr(t2, rt);
2243 tcg_gen_add_tl(t0, t1, t2);
2244 tcg_gen_xor_tl(t1, t1, t2);
2245 tcg_gen_xor_tl(t2, t0, t2);
2246 tcg_gen_andc_tl(t1, t2, t1);
2247 tcg_temp_free(t2);
2248 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2249 tcg_temp_free(t1);
2250 /* operands of same sign, result different sign */
2251 generate_exception(ctx, EXCP_OVERFLOW);
2252 gen_set_label(l1);
2253 gen_store_gpr(t0, rd);
2254 tcg_temp_free(t0);
2255 }
2256 opn = "dadd";
2257 break;
2258 case OPC_DADDU:
2259 if (rs != 0 && rt != 0) {
2260 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2261 } else if (rs == 0 && rt != 0) {
2262 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2263 } else if (rs != 0 && rt == 0) {
2264 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2265 } else {
2266 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2267 }
2268 opn = "daddu";
2269 break;
2270 case OPC_DSUB:
2271 {
2272 TCGv t0 = tcg_temp_local_new();
2273 TCGv t1 = tcg_temp_new();
2274 TCGv t2 = tcg_temp_new();
2275 int l1 = gen_new_label();
2276
2277 gen_load_gpr(t1, rs);
2278 gen_load_gpr(t2, rt);
2279 tcg_gen_sub_tl(t0, t1, t2);
2280 tcg_gen_xor_tl(t2, t1, t2);
2281 tcg_gen_xor_tl(t1, t0, t1);
2282 tcg_gen_and_tl(t1, t1, t2);
2283 tcg_temp_free(t2);
2284 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2285 tcg_temp_free(t1);
2286 /* operands of different sign, first operand and result different sign */
2287 generate_exception(ctx, EXCP_OVERFLOW);
2288 gen_set_label(l1);
2289 gen_store_gpr(t0, rd);
2290 tcg_temp_free(t0);
2291 }
2292 opn = "dsub";
2293 break;
2294 case OPC_DSUBU:
2295 if (rs != 0 && rt != 0) {
2296 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2297 } else if (rs == 0 && rt != 0) {
2298 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2299 } else if (rs != 0 && rt == 0) {
2300 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2301 } else {
2302 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2303 }
2304 opn = "dsubu";
2305 break;
2306 #endif
2307 case OPC_MUL:
2308 if (likely(rs != 0 && rt != 0)) {
2309 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2310 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2311 } else {
2312 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2313 }
2314 opn = "mul";
2315 break;
2316 }
2317 (void)opn; /* avoid a compiler warning */
2318 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2319 }
2320
2321 /* Conditional move */
2322 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2323 int rd, int rs, int rt)
2324 {
2325 const char *opn = "cond move";
2326 int l1;
2327
2328 if (rd == 0) {
2329 /* If no destination, treat it as a NOP.
2330 For add & sub, we must generate the overflow exception when needed. */
2331 MIPS_DEBUG("NOP");
2332 return;
2333 }
2334
2335 l1 = gen_new_label();
2336 switch (opc) {
2337 case OPC_MOVN:
2338 if (likely(rt != 0))
2339 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2340 else
2341 tcg_gen_br(l1);
2342 opn = "movn";
2343 break;
2344 case OPC_MOVZ:
2345 if (likely(rt != 0))
2346 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2347 opn = "movz";
2348 break;
2349 }
2350 if (rs != 0)
2351 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2352 else
2353 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2354 gen_set_label(l1);
2355
2356 (void)opn; /* avoid a compiler warning */
2357 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2358 }
2359
2360 /* Logic */
2361 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2362 int rd, int rs, int rt)
2363 {
2364 const char *opn = "logic";
2365
2366 if (rd == 0) {
2367 /* If no destination, treat it as a NOP. */
2368 MIPS_DEBUG("NOP");
2369 return;
2370 }
2371
2372 switch (opc) {
2373 case OPC_AND:
2374 if (likely(rs != 0 && rt != 0)) {
2375 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2376 } else {
2377 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2378 }
2379 opn = "and";
2380 break;
2381 case OPC_NOR:
2382 if (rs != 0 && rt != 0) {
2383 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2384 } else if (rs == 0 && rt != 0) {
2385 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2386 } else if (rs != 0 && rt == 0) {
2387 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2388 } else {
2389 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2390 }
2391 opn = "nor";
2392 break;
2393 case OPC_OR:
2394 if (likely(rs != 0 && rt != 0)) {
2395 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2396 } else if (rs == 0 && rt != 0) {
2397 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2398 } else if (rs != 0 && rt == 0) {
2399 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2400 } else {
2401 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2402 }
2403 opn = "or";
2404 break;
2405 case OPC_XOR:
2406 if (likely(rs != 0 && rt != 0)) {
2407 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2408 } else if (rs == 0 && rt != 0) {
2409 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2410 } else if (rs != 0 && rt == 0) {
2411 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2412 } else {
2413 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2414 }
2415 opn = "xor";
2416 break;
2417 }
2418 (void)opn; /* avoid a compiler warning */
2419 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2420 }
2421
2422 /* Set on lower than */
2423 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2424 int rd, int rs, int rt)
2425 {
2426 const char *opn = "slt";
2427 TCGv t0, t1;
2428
2429 if (rd == 0) {
2430 /* If no destination, treat it as a NOP. */
2431 MIPS_DEBUG("NOP");
2432 return;
2433 }
2434
2435 t0 = tcg_temp_new();
2436 t1 = tcg_temp_new();
2437 gen_load_gpr(t0, rs);
2438 gen_load_gpr(t1, rt);
2439 switch (opc) {
2440 case OPC_SLT:
2441 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2442 opn = "slt";
2443 break;
2444 case OPC_SLTU:
2445 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2446 opn = "sltu";
2447 break;
2448 }
2449 (void)opn; /* avoid a compiler warning */
2450 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2451 tcg_temp_free(t0);
2452 tcg_temp_free(t1);
2453 }
2454
2455 /* Shifts */
2456 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2457 int rd, int rs, int rt)
2458 {
2459 const char *opn = "shifts";
2460 TCGv t0, t1;
2461
2462 if (rd == 0) {
2463 /* If no destination, treat it as a NOP.
2464 For add & sub, we must generate the overflow exception when needed. */
2465 MIPS_DEBUG("NOP");
2466 return;
2467 }
2468
2469 t0 = tcg_temp_new();
2470 t1 = tcg_temp_new();
2471 gen_load_gpr(t0, rs);
2472 gen_load_gpr(t1, rt);
2473 switch (opc) {
2474 case OPC_SLLV:
2475 tcg_gen_andi_tl(t0, t0, 0x1f);
2476 tcg_gen_shl_tl(t0, t1, t0);
2477 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2478 opn = "sllv";
2479 break;
2480 case OPC_SRAV:
2481 tcg_gen_andi_tl(t0, t0, 0x1f);
2482 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2483 opn = "srav";
2484 break;
2485 case OPC_SRLV:
2486 tcg_gen_ext32u_tl(t1, t1);
2487 tcg_gen_andi_tl(t0, t0, 0x1f);
2488 tcg_gen_shr_tl(t0, t1, t0);
2489 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2490 opn = "srlv";
2491 break;
2492 case OPC_ROTRV:
2493 {
2494 TCGv_i32 t2 = tcg_temp_new_i32();
2495 TCGv_i32 t3 = tcg_temp_new_i32();
2496
2497 tcg_gen_trunc_tl_i32(t2, t0);
2498 tcg_gen_trunc_tl_i32(t3, t1);
2499 tcg_gen_andi_i32(t2, t2, 0x1f);
2500 tcg_gen_rotr_i32(t2, t3, t2);
2501 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2502 tcg_temp_free_i32(t2);
2503 tcg_temp_free_i32(t3);
2504 opn = "rotrv";
2505 }
2506 break;
2507 #if defined(TARGET_MIPS64)
2508 case OPC_DSLLV:
2509 tcg_gen_andi_tl(t0, t0, 0x3f);
2510 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2511 opn = "dsllv";
2512 break;
2513 case OPC_DSRAV:
2514 tcg_gen_andi_tl(t0, t0, 0x3f);
2515 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2516 opn = "dsrav";
2517 break;
2518 case OPC_DSRLV:
2519 tcg_gen_andi_tl(t0, t0, 0x3f);
2520 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2521 opn = "dsrlv";
2522 break;
2523 case OPC_DROTRV:
2524 tcg_gen_andi_tl(t0, t0, 0x3f);
2525 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2526 opn = "drotrv";
2527 break;
2528 #endif
2529 }
2530 (void)opn; /* avoid a compiler warning */
2531 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2532 tcg_temp_free(t0);
2533 tcg_temp_free(t1);
2534 }
2535
2536 /* Arithmetic on HI/LO registers */
2537 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2538 {
2539 const char *opn = "hilo";
2540 unsigned int acc;
2541
2542 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2543 /* Treat as NOP. */
2544 MIPS_DEBUG("NOP");
2545 return;
2546 }
2547
2548 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2549 acc = ((ctx->opcode) >> 21) & 0x03;
2550 } else {
2551 acc = ((ctx->opcode) >> 11) & 0x03;
2552 }
2553
2554 if (acc != 0) {
2555 check_dsp(ctx);
2556 }
2557
2558 switch (opc) {
2559 case OPC_MFHI:
2560 #if defined(TARGET_MIPS64)
2561 if (acc != 0) {
2562 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2563 } else
2564 #endif
2565 {
2566 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2567 }
2568 opn = "mfhi";
2569 break;
2570 case OPC_MFLO:
2571 #if defined(TARGET_MIPS64)
2572 if (acc != 0) {
2573 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2574 } else
2575 #endif
2576 {
2577 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2578 }
2579 opn = "mflo";
2580 break;
2581 case OPC_MTHI:
2582 if (reg != 0) {
2583 #if defined(TARGET_MIPS64)
2584 if (acc != 0) {
2585 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2586 } else
2587 #endif
2588 {
2589 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2590 }
2591 } else {
2592 tcg_gen_movi_tl(cpu_HI[acc], 0);
2593 }
2594 opn = "mthi";
2595 break;
2596 case OPC_MTLO:
2597 if (reg != 0) {
2598 #if defined(TARGET_MIPS64)
2599 if (acc != 0) {
2600 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2601 } else
2602 #endif
2603 {
2604 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2605 }
2606 } else {
2607 tcg_gen_movi_tl(cpu_LO[acc], 0);
2608 }
2609 opn = "mtlo";
2610 break;
2611 }
2612 (void)opn; /* avoid a compiler warning */
2613 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2614 }
2615
2616 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2617 int rs, int rt)
2618 {
2619 const char *opn = "mul/div";
2620 TCGv t0, t1;
2621 unsigned int acc;
2622
2623 switch (opc) {
2624 case OPC_DIV:
2625 case OPC_DIVU:
2626 #if defined(TARGET_MIPS64)
2627 case OPC_DDIV:
2628 case OPC_DDIVU:
2629 #endif
2630 t0 = tcg_temp_local_new();
2631 t1 = tcg_temp_local_new();
2632 break;
2633 default:
2634 t0 = tcg_temp_new();
2635 t1 = tcg_temp_new();
2636 break;
2637 }
2638
2639 gen_load_gpr(t0, rs);
2640 gen_load_gpr(t1, rt);
2641 switch (opc) {
2642 case OPC_DIV:
2643 {
2644 int l1 = gen_new_label();
2645 int l2 = gen_new_label();
2646
2647 tcg_gen_ext32s_tl(t0, t0);
2648 tcg_gen_ext32s_tl(t1, t1);
2649 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2650 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2651 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2652
2653 tcg_gen_mov_tl(cpu_LO[0], t0);
2654 tcg_gen_movi_tl(cpu_HI[0], 0);
2655 tcg_gen_br(l1);
2656 gen_set_label(l2);
2657 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2658 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2659 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2660 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2661 gen_set_label(l1);
2662 }
2663 opn = "div";
2664 break;
2665 case OPC_DIVU:
2666 {
2667 int l1 = gen_new_label();
2668
2669 tcg_gen_ext32u_tl(t0, t0);
2670 tcg_gen_ext32u_tl(t1, t1);
2671 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2672 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2673 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2674 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2675 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2676 gen_set_label(l1);
2677 }
2678 opn = "divu";
2679 break;
2680 case OPC_MULT:
2681 {
2682 TCGv_i64 t2 = tcg_temp_new_i64();
2683 TCGv_i64 t3 = tcg_temp_new_i64();
2684 acc = ((ctx->opcode) >> 11) & 0x03;
2685 if (acc != 0) {
2686 check_dsp(ctx);
2687 }
2688
2689 tcg_gen_ext_tl_i64(t2, t0);
2690 tcg_gen_ext_tl_i64(t3, t1);
2691 tcg_gen_mul_i64(t2, t2, t3);
2692 tcg_temp_free_i64(t3);
2693 tcg_gen_trunc_i64_tl(t0, t2);
2694 tcg_gen_shri_i64(t2, t2, 32);
2695 tcg_gen_trunc_i64_tl(t1, t2);
2696 tcg_temp_free_i64(t2);
2697 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2698 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2699 }
2700 opn = "mult";
2701 break;
2702 case OPC_MULTU:
2703 {
2704 TCGv_i64 t2 = tcg_temp_new_i64();
2705 TCGv_i64 t3 = tcg_temp_new_i64();
2706 acc = ((ctx->opcode) >> 11) & 0x03;
2707 if (acc != 0) {
2708 check_dsp(ctx);
2709 }
2710
2711 tcg_gen_ext32u_tl(t0, t0);
2712 tcg_gen_ext32u_tl(t1, t1);
2713 tcg_gen_extu_tl_i64(t2, t0);
2714 tcg_gen_extu_tl_i64(t3, t1);
2715 tcg_gen_mul_i64(t2, t2, t3);
2716 tcg_temp_free_i64(t3);
2717 tcg_gen_trunc_i64_tl(t0, t2);
2718 tcg_gen_shri_i64(t2, t2, 32);
2719 tcg_gen_trunc_i64_tl(t1, t2);
2720 tcg_temp_free_i64(t2);
2721 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2722 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2723 }
2724 opn = "multu";
2725 break;
2726 #if defined(TARGET_MIPS64)
2727 case OPC_DDIV:
2728 {
2729 int l1 = gen_new_label();
2730 int l2 = gen_new_label();
2731
2732 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2733 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2734 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2735 tcg_gen_mov_tl(cpu_LO[0], t0);
2736 tcg_gen_movi_tl(cpu_HI[0], 0);
2737 tcg_gen_br(l1);
2738 gen_set_label(l2);
2739 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2740 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2741 gen_set_label(l1);
2742 }
2743 opn = "ddiv";
2744 break;
2745 case OPC_DDIVU:
2746 {
2747 int l1 = gen_new_label();
2748
2749 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2750 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2751 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2752 gen_set_label(l1);
2753 }
2754 opn = "ddivu";
2755 break;
2756 case OPC_DMULT:
2757 gen_helper_dmult(cpu_env, t0, t1);
2758 opn = "dmult";
2759 break;
2760 case OPC_DMULTU:
2761 gen_helper_dmultu(cpu_env, t0, t1);
2762 opn = "dmultu";
2763 break;
2764 #endif
2765 case OPC_MADD:
2766 {
2767 TCGv_i64 t2 = tcg_temp_new_i64();
2768 TCGv_i64 t3 = tcg_temp_new_i64();
2769 acc = ((ctx->opcode) >> 11) & 0x03;
2770 if (acc != 0) {
2771 check_dsp(ctx);
2772 }
2773
2774 tcg_gen_ext_tl_i64(t2, t0);
2775 tcg_gen_ext_tl_i64(t3, t1);
2776 tcg_gen_mul_i64(t2, t2, t3);
2777 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2778 tcg_gen_add_i64(t2, t2, t3);
2779 tcg_temp_free_i64(t3);
2780 tcg_gen_trunc_i64_tl(t0, t2);
2781 tcg_gen_shri_i64(t2, t2, 32);
2782 tcg_gen_trunc_i64_tl(t1, t2);
2783 tcg_temp_free_i64(t2);
2784 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2785 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2786 }
2787 opn = "madd";
2788 break;
2789 case OPC_MADDU:
2790 {
2791 TCGv_i64 t2 = tcg_temp_new_i64();
2792 TCGv_i64 t3 = tcg_temp_new_i64();
2793 acc = ((ctx->opcode) >> 11) & 0x03;
2794 if (acc != 0) {
2795 check_dsp(ctx);
2796 }
2797
2798 tcg_gen_ext32u_tl(t0, t0);
2799 tcg_gen_ext32u_tl(t1, t1);
2800 tcg_gen_extu_tl_i64(t2, t0);
2801 tcg_gen_extu_tl_i64(t3, t1);
2802 tcg_gen_mul_i64(t2, t2, t3);
2803 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2804 tcg_gen_add_i64(t2, t2, t3);
2805 tcg_temp_free_i64(t3);
2806 tcg_gen_trunc_i64_tl(t0, t2);
2807 tcg_gen_shri_i64(t2, t2, 32);
2808 tcg_gen_trunc_i64_tl(t1, t2);
2809 tcg_temp_free_i64(t2);
2810 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2811 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2812 }
2813 opn = "maddu";
2814 break;
2815 case OPC_MSUB:
2816 {
2817 TCGv_i64 t2 = tcg_temp_new_i64();
2818 TCGv_i64 t3 = tcg_temp_new_i64();
2819 acc = ((ctx->opcode) >> 11) & 0x03;
2820 if (acc != 0) {
2821 check_dsp(ctx);
2822 }
2823
2824 tcg_gen_ext_tl_i64(t2, t0);
2825 tcg_gen_ext_tl_i64(t3, t1);
2826 tcg_gen_mul_i64(t2, t2, t3);
2827 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2828 tcg_gen_sub_i64(t2, t3, t2);
2829 tcg_temp_free_i64(t3);
2830 tcg_gen_trunc_i64_tl(t0, t2);
2831 tcg_gen_shri_i64(t2, t2, 32);
2832 tcg_gen_trunc_i64_tl(t1, t2);
2833 tcg_temp_free_i64(t2);
2834 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2835 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2836 }
2837 opn = "msub";
2838 break;
2839 case OPC_MSUBU:
2840 {
2841 TCGv_i64 t2 = tcg_temp_new_i64();
2842 TCGv_i64 t3 = tcg_temp_new_i64();
2843 acc = ((ctx->opcode) >> 11) & 0x03;
2844 if (acc != 0) {
2845 check_dsp(ctx);
2846 }
2847
2848 tcg_gen_ext32u_tl(t0, t0);
2849 tcg_gen_ext32u_tl(t1, t1);
2850 tcg_gen_extu_tl_i64(t2, t0);
2851 tcg_gen_extu_tl_i64(t3, t1);
2852 tcg_gen_mul_i64(t2, t2, t3);
2853 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2854 tcg_gen_sub_i64(t2, t3, t2);
2855 tcg_temp_free_i64(t3);
2856 tcg_gen_trunc_i64_tl(t0, t2);
2857 tcg_gen_shri_i64(t2, t2, 32);
2858 tcg_gen_trunc_i64_tl(t1, t2);
2859 tcg_temp_free_i64(t2);
2860 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2861 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2862 }
2863 opn = "msubu";
2864 break;
2865 default:
2866 MIPS_INVAL(opn);
2867 generate_exception(ctx, EXCP_RI);
2868 goto out;
2869 }
2870 (void)opn; /* avoid a compiler warning */
2871 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2872 out:
2873 tcg_temp_free(t0);
2874 tcg_temp_free(t1);
2875 }
2876
2877 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2878 int rd, int rs, int rt)
2879 {
2880 const char *opn = "mul vr54xx";
2881 TCGv t0 = tcg_temp_new();
2882 TCGv t1 = tcg_temp_new();
2883
2884 gen_load_gpr(t0, rs);
2885 gen_load_gpr(t1, rt);
2886
2887 switch (opc) {
2888 case OPC_VR54XX_MULS:
2889 gen_helper_muls(t0, cpu_env, t0, t1);
2890 opn = "muls";
2891 break;
2892 case OPC_VR54XX_MULSU:
2893 gen_helper_mulsu(t0, cpu_env, t0, t1);
2894 opn = "mulsu";
2895 break;
2896 case OPC_VR54XX_MACC:
2897 gen_helper_macc(t0, cpu_env, t0, t1);
2898 opn = "macc";
2899 break;
2900 case OPC_VR54XX_MACCU:
2901 gen_helper_maccu(t0, cpu_env, t0, t1);
2902 opn = "maccu";
2903 break;
2904 case OPC_VR54XX_MSAC:
2905 gen_helper_msac(t0, cpu_env, t0, t1);
2906 opn = "msac";
2907 break;
2908 case OPC_VR54XX_MSACU:
2909 gen_helper_msacu(t0, cpu_env, t0, t1);
2910 opn = "msacu";
2911 break;
2912 case OPC_VR54XX_MULHI:
2913 gen_helper_mulhi(t0, cpu_env, t0, t1);
2914 opn = "mulhi";
2915 break;
2916 case OPC_VR54XX_MULHIU:
2917 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2918 opn = "mulhiu";
2919 break;
2920 case OPC_VR54XX_MULSHI:
2921 gen_helper_mulshi(t0, cpu_env, t0, t1);
2922 opn = "mulshi";
2923 break;
2924 case OPC_VR54XX_MULSHIU:
2925 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2926 opn = "mulshiu";
2927 break;
2928 case OPC_VR54XX_MACCHI:
2929 gen_helper_macchi(t0, cpu_env, t0, t1);
2930 opn = "macchi";
2931 break;
2932 case OPC_VR54XX_MACCHIU:
2933 gen_helper_macchiu(t0, cpu_env, t0, t1);
2934 opn = "macchiu";
2935 break;
2936 case OPC_VR54XX_MSACHI:
2937 gen_helper_msachi(t0, cpu_env, t0, t1);
2938 opn = "msachi";
2939 break;
2940 case OPC_VR54XX_MSACHIU:
2941 gen_helper_msachiu(t0, cpu_env, t0, t1);
2942 opn = "msachiu";
2943 break;
2944 default:
2945 MIPS_INVAL("mul vr54xx");
2946 generate_exception(ctx, EXCP_RI);
2947 goto out;
2948 }
2949 gen_store_gpr(t0, rd);
2950 (void)opn; /* avoid a compiler warning */
2951 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2952
2953 out:
2954 tcg_temp_free(t0);
2955 tcg_temp_free(t1);
2956 }
2957
2958 static void gen_cl (DisasContext *ctx, uint32_t opc,
2959 int rd, int rs)
2960 {
2961 const char *opn = "CLx";
2962 TCGv t0;
2963
2964 if (rd == 0) {
2965 /* Treat as NOP. */
2966 MIPS_DEBUG("NOP");
2967 return;
2968 }
2969 t0 = tcg_temp_new();
2970 gen_load_gpr(t0, rs);
2971 switch (opc) {
2972 case OPC_CLO:
2973 gen_helper_clo(cpu_gpr[rd], t0);
2974 opn = "clo";
2975 break;
2976 case OPC_CLZ:
2977 gen_helper_clz(cpu_gpr[rd], t0);
2978 opn = "clz";
2979 break;
2980 #if defined(TARGET_MIPS64)
2981 case OPC_DCLO:
2982 gen_helper_dclo(cpu_gpr[rd], t0);
2983 opn = "dclo";
2984 break;
2985 case OPC_DCLZ:
2986 gen_helper_dclz(cpu_gpr[rd], t0);
2987 opn = "dclz";
2988 break;
2989 #endif
2990 }
2991 (void)opn; /* avoid a compiler warning */
2992 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2993 tcg_temp_free(t0);
2994 }
2995
2996 /* Godson integer instructions */
2997 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2998 int rd, int rs, int rt)
2999 {
3000 const char *opn = "loongson";
3001 TCGv t0, t1;
3002
3003 if (rd == 0) {
3004 /* Treat as NOP. */
3005 MIPS_DEBUG("NOP");
3006 return;
3007 }
3008
3009 switch (opc) {
3010 case OPC_MULT_G_2E:
3011 case OPC_MULT_G_2F:
3012 case OPC_MULTU_G_2E:
3013 case OPC_MULTU_G_2F:
3014 #if defined(TARGET_MIPS64)
3015 case OPC_DMULT_G_2E:
3016 case OPC_DMULT_G_2F:
3017 case OPC_DMULTU_G_2E:
3018 case OPC_DMULTU_G_2F:
3019 #endif
3020 t0 = tcg_temp_new();
3021 t1 = tcg_temp_new();
3022 break;
3023 default:
3024 t0 = tcg_temp_local_new();
3025 t1 = tcg_temp_local_new();
3026 break;
3027 }
3028
3029 gen_load_gpr(t0, rs);
3030 gen_load_gpr(t1, rt);
3031
3032 switch (opc) {
3033 case OPC_MULT_G_2E:
3034 case OPC_MULT_G_2F:
3035 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3036 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3037 opn = "mult.g";
3038 break;
3039 case OPC_MULTU_G_2E:
3040 case OPC_MULTU_G_2F:
3041 tcg_gen_ext32u_tl(t0, t0);
3042 tcg_gen_ext32u_tl(t1, t1);
3043 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3044 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3045 opn = "multu.g";
3046 break;
3047 case OPC_DIV_G_2E:
3048 case OPC_DIV_G_2F:
3049 {
3050 int l1 = gen_new_label();
3051 int l2 = gen_new_label();
3052 int l3 = gen_new_label();
3053 tcg_gen_ext32s_tl(t0, t0);
3054 tcg_gen_ext32s_tl(t1, t1);
3055 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3056 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3057 tcg_gen_br(l3);
3058 gen_set_label(l1);
3059 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3060 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3061 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3062 tcg_gen_br(l3);
3063 gen_set_label(l2);
3064 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3065 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3066 gen_set_label(l3);
3067 }
3068 opn = "div.g";
3069 break;
3070 case OPC_DIVU_G_2E:
3071 case OPC_DIVU_G_2F:
3072 {
3073 int l1 = gen_new_label();
3074 int l2 = gen_new_label();
3075 tcg_gen_ext32u_tl(t0, t0);
3076 tcg_gen_ext32u_tl(t1, t1);
3077 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3078 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3079 tcg_gen_br(l2);
3080 gen_set_label(l1);
3081 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3082 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3083 gen_set_label(l2);
3084 }
3085 opn = "divu.g";
3086 break;
3087 case OPC_MOD_G_2E:
3088 case OPC_MOD_G_2F:
3089 {
3090 int l1 = gen_new_label();
3091 int l2 = gen_new_label();
3092 int l3 = gen_new_label();
3093 tcg_gen_ext32u_tl(t0, t0);
3094 tcg_gen_ext32u_tl(t1, t1);
3095 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3097 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3098 gen_set_label(l1);
3099 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3100 tcg_gen_br(l3);
3101 gen_set_label(l2);
3102 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3103 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3104 gen_set_label(l3);
3105 }
3106 opn = "mod.g";
3107 break;
3108 case OPC_MODU_G_2E:
3109 case OPC_MODU_G_2F:
3110 {
3111 int l1 = gen_new_label();
3112 int l2 = gen_new_label();
3113 tcg_gen_ext32u_tl(t0, t0);
3114 tcg_gen_ext32u_tl(t1, t1);
3115 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3116 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3117 tcg_gen_br(l2);
3118 gen_set_label(l1);
3119 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3120 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3121 gen_set_label(l2);
3122 }
3123 opn = "modu.g";
3124 break;
3125 #if defined(TARGET_MIPS64)
3126 case OPC_DMULT_G_2E:
3127 case OPC_DMULT_G_2F:
3128 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3129 opn = "dmult.g";
3130 break;
3131 case OPC_DMULTU_G_2E:
3132 case OPC_DMULTU_G_2F:
3133 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3134 opn = "dmultu.g";
3135 break;
3136 case OPC_DDIV_G_2E:
3137 case OPC_DDIV_G_2F:
3138 {
3139 int l1 = gen_new_label();
3140 int l2 = gen_new_label();
3141 int l3 = gen_new_label();
3142 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3143 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3144 tcg_gen_br(l3);
3145 gen_set_label(l1);
3146 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3147 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3148 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3149 tcg_gen_br(l3);
3150 gen_set_label(l2);
3151 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3152 gen_set_label(l3);
3153 }
3154 opn = "ddiv.g";
3155 break;
3156 case OPC_DDIVU_G_2E:
3157 case OPC_DDIVU_G_2F:
3158 {
3159 int l1 = gen_new_label();
3160 int l2 = gen_new_label();
3161 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3162 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3163 tcg_gen_br(l2);
3164 gen_set_label(l1);
3165 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3166 gen_set_label(l2);
3167 }
3168 opn = "ddivu.g";
3169 break;
3170 case OPC_DMOD_G_2E:
3171 case OPC_DMOD_G_2F:
3172 {
3173 int l1 = gen_new_label();
3174 int l2 = gen_new_label();
3175 int l3 = gen_new_label();
3176 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3177 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3178 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3179 gen_set_label(l1);
3180 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3181 tcg_gen_br(l3);
3182 gen_set_label(l2);
3183 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3184 gen_set_label(l3);
3185 }
3186 opn = "dmod.g";
3187 break;
3188 case OPC_DMODU_G_2E:
3189 case OPC_DMODU_G_2F:
3190 {
3191 int l1 = gen_new_label();
3192 int l2 = gen_new_label();
3193 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3194 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3195 tcg_gen_br(l2);
3196 gen_set_label(l1);
3197 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3198 gen_set_label(l2);
3199 }
3200 opn = "dmodu.g";
3201 break;
3202 #endif
3203 }
3204
3205 (void)opn; /* avoid a compiler warning */
3206 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3207 tcg_temp_free(t0);
3208 tcg_temp_free(t1);
3209 }
3210
3211 /* Loongson multimedia instructions */
3212 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3213 {
3214 const char *opn = "loongson_cp2";
3215 uint32_t opc, shift_max;
3216 TCGv_i64 t0, t1;
3217
3218 opc = MASK_LMI(ctx->opcode);
3219 switch (opc) {
3220 case OPC_ADD_CP2:
3221 case OPC_SUB_CP2:
3222 case OPC_DADD_CP2:
3223 case OPC_DSUB_CP2:
3224 t0 = tcg_temp_local_new_i64();
3225 t1 = tcg_temp_local_new_i64();
3226 break;
3227 default:
3228 t0 = tcg_temp_new_i64();
3229 t1 = tcg_temp_new_i64();
3230 break;
3231 }
3232
3233 gen_load_fpr64(ctx, t0, rs);
3234 gen_load_fpr64(ctx, t1, rt);
3235
3236 #define LMI_HELPER(UP, LO) \
3237 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3238 #define LMI_HELPER_1(UP, LO) \
3239 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3240 #define LMI_DIRECT(UP, LO, OP) \
3241 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3242
3243 switch (opc) {
3244 LMI_HELPER(PADDSH, paddsh);
3245 LMI_HELPER(PADDUSH, paddush);
3246 LMI_HELPER(PADDH, paddh);
3247 LMI_HELPER(PADDW, paddw);
3248 LMI_HELPER(PADDSB, paddsb);
3249 LMI_HELPER(PADDUSB, paddusb);
3250 LMI_HELPER(PADDB, paddb);
3251
3252 LMI_HELPER(PSUBSH, psubsh);
3253 LMI_HELPER(PSUBUSH, psubush);
3254 LMI_HELPER(PSUBH, psubh);
3255 LMI_HELPER(PSUBW, psubw);
3256 LMI_HELPER(PSUBSB, psubsb);
3257 LMI_HELPER(PSUBUSB, psubusb);
3258 LMI_HELPER(PSUBB, psubb);
3259
3260 LMI_HELPER(PSHUFH, pshufh);
3261 LMI_HELPER(PACKSSWH, packsswh);
3262 LMI_HELPER(PACKSSHB, packsshb);
3263 LMI_HELPER(PACKUSHB, packushb);
3264
3265 LMI_HELPER(PUNPCKLHW, punpcklhw);
3266 LMI_HELPER(PUNPCKHHW, punpckhhw);
3267 LMI_HELPER(PUNPCKLBH, punpcklbh);
3268 LMI_HELPER(PUNPCKHBH, punpckhbh);
3269 LMI_HELPER(PUNPCKLWD, punpcklwd);
3270 LMI_HELPER(PUNPCKHWD, punpckhwd);
3271
3272 LMI_HELPER(PAVGH, pavgh);
3273 LMI_HELPER(PAVGB, pavgb);
3274 LMI_HELPER(PMAXSH, pmaxsh);
3275 LMI_HELPER(PMINSH, pminsh);
3276 LMI_HELPER(PMAXUB, pmaxub);
3277 LMI_HELPER(PMINUB, pminub);
3278
3279 LMI_HELPER(PCMPEQW, pcmpeqw);
3280 LMI_HELPER(PCMPGTW, pcmpgtw);
3281 LMI_HELPER(PCMPEQH, pcmpeqh);
3282 LMI_HELPER(PCMPGTH, pcmpgth);
3283 LMI_HELPER(PCMPEQB, pcmpeqb);
3284 LMI_HELPER(PCMPGTB, pcmpgtb);
3285
3286 LMI_HELPER(PSLLW, psllw);
3287 LMI_HELPER(PSLLH, psllh);
3288 LMI_HELPER(PSRLW, psrlw);
3289 LMI_HELPER(PSRLH, psrlh);
3290 LMI_HELPER(PSRAW, psraw);
3291 LMI_HELPER(PSRAH, psrah);
3292
3293 LMI_HELPER(PMULLH, pmullh);
3294 LMI_HELPER(PMULHH, pmulhh);
3295 LMI_HELPER(PMULHUH, pmulhuh);
3296 LMI_HELPER(PMADDHW, pmaddhw);
3297
3298 LMI_HELPER(PASUBUB, pasubub);
3299 LMI_HELPER_1(BIADD, biadd);
3300 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3301
3302 LMI_DIRECT(PADDD, paddd, add);
3303 LMI_DIRECT(PSUBD, psubd, sub);
3304 LMI_DIRECT(XOR_CP2, xor, xor);
3305 LMI_DIRECT(NOR_CP2, nor, nor);
3306 LMI_DIRECT(AND_CP2, and, and);
3307 LMI_DIRECT(PANDN, pandn, andc);
3308 LMI_DIRECT(OR, or, or);
3309
3310 case OPC_PINSRH_0:
3311 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3312 opn = "pinsrh_0";
3313 break;
3314 case OPC_PINSRH_1:
3315 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3316 opn = "pinsrh_1";
3317 break;
3318 case OPC_PINSRH_2:
3319 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3320 opn = "pinsrh_2";
3321 break;
3322 case OPC_PINSRH_3:
3323 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3324 opn = "pinsrh_3";
3325 break;
3326
3327 case OPC_PEXTRH:
3328 tcg_gen_andi_i64(t1, t1, 3);
3329 tcg_gen_shli_i64(t1, t1, 4);
3330 tcg_gen_shr_i64(t0, t0, t1);
3331 tcg_gen_ext16u_i64(t0, t0);
3332 opn = "pextrh";
3333 break;
3334
3335 case OPC_ADDU_CP2:
3336 tcg_gen_add_i64(t0, t0, t1);
3337 tcg_gen_ext32s_i64(t0, t0);
3338 opn = "addu";
3339 break;
3340 case OPC_SUBU_CP2:
3341 tcg_gen_sub_i64(t0, t0, t1);
3342 tcg_gen_ext32s_i64(t0, t0);
3343 opn = "addu";
3344 break;
3345
3346 case OPC_SLL_CP2:
3347 opn = "sll";
3348 shift_max = 32;
3349 goto do_shift;
3350 case OPC_SRL_CP2:
3351 opn = "srl";
3352 shift_max = 32;
3353 goto do_shift;
3354 case OPC_SRA_CP2:
3355 opn = "sra";
3356 shift_max = 32;
3357 goto do_shift;
3358 case OPC_DSLL_CP2:
3359 opn = "dsll";
3360 shift_max = 64;
3361 goto do_shift;
3362 case OPC_DSRL_CP2:
3363 opn = "dsrl";
3364 shift_max = 64;
3365 goto do_shift;
3366 case OPC_DSRA_CP2:
3367 opn = "dsra";
3368 shift_max = 64;
3369 goto do_shift;
3370 do_shift:
3371 /* Make sure shift count isn't TCG undefined behaviour. */
3372 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3373
3374 switch (opc) {
3375 case OPC_SLL_CP2:
3376 case OPC_DSLL_CP2:
3377 tcg_gen_shl_i64(t0, t0, t1);
3378 break;
3379 case OPC_SRA_CP2:
3380 case OPC_DSRA_CP2:
3381 /* Since SRA is UndefinedResult without sign-extended inputs,
3382 we can treat SRA and DSRA the same. */
3383 tcg_gen_sar_i64(t0, t0, t1);
3384 break;
3385 case OPC_SRL_CP2:
3386 /* We want to shift in zeros for SRL; zero-extend first. */
3387 tcg_gen_ext32u_i64(t0, t0);
3388 /* FALLTHRU */
3389 case OPC_DSRL_CP2:
3390 tcg_gen_shr_i64(t0, t0, t1);
3391 break;
3392 }
3393
3394 if (shift_max == 32) {
3395 tcg_gen_ext32s_i64(t0, t0);
3396 }
3397
3398 /* Shifts larger than MAX produce zero. */
3399 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3400 tcg_gen_neg_i64(t1, t1);
3401 tcg_gen_and_i64(t0, t0, t1);
3402 break;
3403
3404 case OPC_ADD_CP2:
3405 case OPC_DADD_CP2:
3406 {
3407 TCGv_i64 t2 = tcg_temp_new_i64();
3408 int lab = gen_new_label();
3409
3410 tcg_gen_mov_i64(t2, t0);
3411 tcg_gen_add_i64(t0, t1, t2);
3412 if (opc == OPC_ADD_CP2) {
3413 tcg_gen_ext32s_i64(t0, t0);
3414 }
3415 tcg_gen_xor_i64(t1, t1, t2);
3416 tcg_gen_xor_i64(t2, t2, t0);
3417 tcg_gen_andc_i64(t1, t2, t1);
3418 tcg_temp_free_i64(t2);
3419 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3420 generate_exception(ctx, EXCP_OVERFLOW);
3421 gen_set_label(lab);
3422
3423 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3424 break;
3425 }
3426
3427 case OPC_SUB_CP2:
3428 case OPC_DSUB_CP2:
3429 {
3430 TCGv_i64 t2 = tcg_temp_new_i64();
3431 int lab = gen_new_label();
3432
3433 tcg_gen_mov_i64(t2, t0);
3434 tcg_gen_sub_i64(t0, t1, t2);
3435 if (opc == OPC_SUB_CP2) {
3436 tcg_gen_ext32s_i64(t0, t0);
3437 }
3438 tcg_gen_xor_i64(t1, t1, t2);
3439 tcg_gen_xor_i64(t2, t2, t0);
3440 tcg_gen_and_i64(t1, t1, t2);
3441 tcg_temp_free_i64(t2);
3442 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3443 generate_exception(ctx, EXCP_OVERFLOW);
3444 gen_set_label(lab);
3445
3446 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3447 break;
3448 }
3449
3450 case OPC_PMULUW:
3451 tcg_gen_ext32u_i64(t0, t0);
3452 tcg_gen_ext32u_i64(t1, t1);
3453 tcg_gen_mul_i64(t0, t0, t1);
3454 opn = "pmuluw";
3455 break;
3456
3457 case OPC_SEQU_CP2:
3458 case OPC_SEQ_CP2:
3459 case OPC_SLTU_CP2:
3460 case OPC_SLT_CP2:
3461 case OPC_SLEU_CP2:
3462 case OPC_SLE_CP2:
3463 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3464 FD field is the CC field? */
3465 default:
3466 MIPS_INVAL(opn);
3467 generate_exception(ctx, EXCP_RI);
3468 return;
3469 }
3470
3471 #undef LMI_HELPER
3472 #undef LMI_DIRECT
3473
3474 gen_store_fpr64(ctx, t0, rd);
3475
3476 (void)opn; /* avoid a compiler warning */
3477 MIPS_DEBUG("%s %s, %s, %s", opn,
3478 fregnames[rd], fregnames[rs], fregnames[rt]);
3479 tcg_temp_free_i64(t0);
3480 tcg_temp_free_i64(t1);
3481 }
3482
3483 /* Traps */
3484 static void gen_trap (DisasContext *ctx, uint32_t opc,
3485 int rs, int rt, int16_t imm)
3486 {
3487 int cond;
3488 TCGv t0 = tcg_temp_new();
3489 TCGv t1 = tcg_temp_new();
3490
3491 cond = 0;
3492 /* Load needed operands */
3493 switch (opc) {
3494 case OPC_TEQ:
3495 case OPC_TGE:
3496 case OPC_TGEU:
3497 case OPC_TLT:
3498 case OPC_TLTU:
3499 case OPC_TNE:
3500 /* Compare two registers */
3501 if (rs != rt) {
3502 gen_load_gpr(t0, rs);
3503 gen_load_gpr(t1, rt);
3504 cond = 1;
3505 }
3506 break;
3507 case OPC_TEQI:
3508 case OPC_TGEI:
3509 case OPC_TGEIU:
3510 case OPC_TLTI:
3511 case OPC_TLTIU:
3512 case OPC_TNEI:
3513 /* Compare register to immediate */
3514 if (rs != 0 || imm != 0) {
3515 gen_load_gpr(t0, rs);
3516 tcg_gen_movi_tl(t1, (int32_t)imm);
3517 cond = 1;
3518 }
3519 break;
3520 }
3521 if (cond == 0) {
3522 switch (opc) {
3523 case OPC_TEQ: /* rs == rs */
3524 case OPC_TEQI: /* r0 == 0 */
3525 case OPC_TGE: /* rs >= rs */
3526 case OPC_TGEI: /* r0 >= 0 */
3527 case OPC_TGEU: /* rs >= rs unsigned */
3528 case OPC_TGEIU: /* r0 >= 0 unsigned */
3529 /* Always trap */
3530 generate_exception(ctx, EXCP_TRAP);
3531 break;
3532 case OPC_TLT: /* rs < rs */
3533 case OPC_TLTI: /* r0 < 0 */
3534 case OPC_TLTU: /* rs < rs unsigned */
3535 case OPC_TLTIU: /* r0 < 0 unsigned */
3536 case OPC_TNE: /* rs != rs */
3537 case OPC_TNEI: /* r0 != 0 */
3538 /* Never trap: treat as NOP. */
3539 break;
3540 }
3541 } else {
3542 int l1 = gen_new_label();
3543
3544 switch (opc) {
3545 case OPC_TEQ:
3546 case OPC_TEQI:
3547 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3548 break;
3549 case OPC_TGE:
3550 case OPC_TGEI:
3551 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3552 break;
3553 case OPC_TGEU:
3554 case OPC_TGEIU:
3555 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3556 break;
3557 case OPC_TLT:
3558 case OPC_TLTI:
3559 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3560 break;
3561 case OPC_TLTU:
3562 case OPC_TLTIU:
3563 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3564 break;
3565 case OPC_TNE:
3566 case OPC_TNEI:
3567 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3568 break;
3569 }
3570 generate_exception(ctx, EXCP_TRAP);
3571 gen_set_label(l1);
3572 }
3573 tcg_temp_free(t0);
3574 tcg_temp_free(t1);
3575 }
3576
3577 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3578 {
3579 TranslationBlock *tb;
3580 tb = ctx->tb;
3581 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3582 likely(!ctx->singlestep_enabled)) {
3583 tcg_gen_goto_tb(n);
3584 gen_save_pc(dest);
3585 tcg_gen_exit_tb((tcg_target_long)tb + n);
3586 } else {
3587 gen_save_pc(dest);
3588 if (ctx->singlestep_enabled) {
3589 save_cpu_state(ctx, 0);
3590 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3591 }
3592 tcg_gen_exit_tb(0);
3593 }
3594 }
3595
3596 /* Branches (before delay slot) */
3597 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3598 int insn_bytes,
3599 int rs, int rt, int32_t offset)
3600 {
3601 target_ulong btgt = -1;
3602 int blink = 0;
3603 int bcond_compute = 0;
3604 TCGv t0 = tcg_temp_new();
3605 TCGv t1 = tcg_temp_new();
3606
3607 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3608 #ifdef MIPS_DEBUG_DISAS
3609 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3610 #endif
3611 generate_exception(ctx, EXCP_RI);
3612 goto out;
3613 }
3614
3615 /* Load needed operands */
3616 switch (opc) {
3617 case OPC_BEQ:
3618 case OPC_BEQL:
3619 case OPC_BNE:
3620 case OPC_BNEL:
3621 /* Compare two registers */
3622 if (rs != rt) {
3623 gen_load_gpr(t0, rs);
3624 gen_load_gpr(t1, rt);
3625 bcond_compute = 1;
3626 }
3627 btgt = ctx->pc + insn_bytes + offset;
3628 break;
3629 case OPC_BGEZ:
3630 case OPC_BGEZAL:
3631 case OPC_BGEZALS:
3632 case OPC_BGEZALL:
3633 case OPC_BGEZL:
3634 case OPC_BGTZ:
3635 case OPC_BGTZL:
3636 case OPC_BLEZ:
3637 case OPC_BLEZL:
3638 case OPC_BLTZ:
3639 case OPC_BLTZAL:
3640 case OPC_BLTZALS:
3641 case OPC_BLTZALL:
3642 case OPC_BLTZL:
3643 /* Compare to zero */
3644 if (rs != 0) {
3645 gen_load_gpr(t0, rs);
3646 bcond_compute = 1;
3647 }
3648 btgt = ctx->pc + insn_bytes + offset;
3649 break;
3650 case OPC_BPOSGE32:
3651 #if defined(TARGET_MIPS64)
3652 case OPC_BPOSGE64:
3653 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3654 #else
3655 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3656 #endif
3657 bcond_compute = 1;
3658 btgt = ctx->pc + insn_bytes + offset;
3659 break;
3660 case OPC_J:
3661 case OPC_JAL:
3662 case OPC_JALX:
3663 case OPC_JALS:
3664 case OPC_JALXS:
3665 /* Jump to immediate */
3666 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3667 break;
3668 case OPC_JR:
3669 case OPC_JALR:
3670 case OPC_JALRC:
3671 case OPC_JALRS:
3672 /* Jump to register */
3673 if (offset != 0 && offset != 16) {
3674 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3675 others are reserved. */
3676 MIPS_INVAL("jump hint");
3677 generate_exception(ctx, EXCP_RI);
3678 goto out;
3679 }
3680 gen_load_gpr(btarget, rs);
3681 break;
3682 default:
3683 MIPS_INVAL("branch/jump");
3684 generate_exception(ctx, EXCP_RI);
3685 goto out;
3686 }
3687 if (bcond_compute == 0) {
3688 /* No condition to be computed */
3689 switch (opc) {
3690 case OPC_BEQ: /* rx == rx */
3691 case OPC_BEQL: /* rx == rx likely */
3692 case OPC_BGEZ: /* 0 >= 0 */
3693 case OPC_BGEZL: /* 0 >= 0 likely */
3694 case OPC_BLEZ: /* 0 <= 0 */
3695 case OPC_BLEZL: /* 0 <= 0 likely */
3696 /* Always take */
3697 ctx->hflags |= MIPS_HFLAG_B;
3698 MIPS_DEBUG("balways");
3699 break;
3700 case OPC_BGEZALS:
3701 case OPC_BGEZAL: /* 0 >= 0 */
3702 case OPC_BGEZALL: /* 0 >= 0 likely */
3703 ctx->hflags |= (opc == OPC_BGEZALS
3704 ? MIPS_HFLAG_BDS16
3705 : MIPS_HFLAG_BDS32);
3706 /* Always take and link */
3707 blink = 31;
3708 ctx->hflags |= MIPS_HFLAG_B;
3709 MIPS_DEBUG("balways and link");
3710 break;
3711 case OPC_BNE: /* rx != rx */
3712 case OPC_BGTZ: /* 0 > 0 */
3713 case OPC_BLTZ: /* 0 < 0 */
3714 /* Treat as NOP. */
3715 MIPS_DEBUG("bnever (NOP)");
3716 goto out;
3717 case OPC_BLTZALS:
3718 case OPC_BLTZAL: /* 0 < 0 */
3719 ctx->hflags |= (opc == OPC_BLTZALS
3720 ? MIPS_HFLAG_BDS16
3721 : MIPS_HFLAG_BDS32);
3722 /* Handle as an unconditional branch to get correct delay
3723 slot checking. */
3724 blink = 31;
3725 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3726 ctx->hflags |= MIPS_HFLAG_B;
3727 MIPS_DEBUG("bnever and link");
3728 break;
3729 case OPC_BLTZALL: /* 0 < 0 likely */
3730 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3731 /* Skip the instruction in the delay slot */
3732 MIPS_DEBUG("bnever, link and skip");
3733 ctx->pc += 4;
3734 goto out;
3735 case OPC_BNEL: /* rx != rx likely */
3736 case OPC_BGTZL: /* 0 > 0 likely */
3737 case OPC_BLTZL: /* 0 < 0 likely */
3738 /* Skip the instruction in the delay slot */
3739 MIPS_DEBUG("bnever and skip");
3740 ctx->pc += 4;
3741 goto out;
3742 case OPC_J:
3743 ctx->hflags |= MIPS_HFLAG_B;
3744 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3745 break;
3746 case OPC_JALXS:
3747 case OPC_JALX:
3748 ctx->hflags |= MIPS_HFLAG_BX;
3749 /* Fallthrough */
3750 case OPC_JALS:
3751 case OPC_JAL:
3752 blink = 31;
3753 ctx->hflags |= MIPS_HFLAG_B;
3754 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3755 ? MIPS_HFLAG_BDS16
3756 : MIPS_HFLAG_BDS32);
3757 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3758 break;
3759 case OPC_JR:
3760 ctx->hflags |= MIPS_HFLAG_BR;
3761 if (insn_bytes == 4)
3762 ctx->hflags |= MIPS_HFLAG_BDS32;
3763 MIPS_DEBUG("jr %s", regnames[rs]);
3764 break;
3765 case OPC_JALRS:
3766 case OPC_JALR:
3767 case OPC_JALRC:
3768 blink = rt;
3769 ctx->hflags |= MIPS_HFLAG_BR;
3770 ctx->hflags |= (opc == OPC_JALRS
3771 ? MIPS_HFLAG_BDS16
3772 : MIPS_HFLAG_BDS32);
3773 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3774 break;
3775 default:
3776 MIPS_INVAL("branch/jump");
3777 generate_exception(ctx, EXCP_RI);
3778 goto out;
3779 }
3780 } else {
3781 switch (opc) {
3782 case OPC_BEQ:
3783 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3784 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3785 regnames[rs], regnames[rt], btgt);
3786 goto not_likely;
3787 case OPC_BEQL:
3788 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3789 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3790 regnames[rs], regnames[rt], btgt);
3791 goto likely;
3792 case OPC_BNE:
3793 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3794 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3795 regnames[rs], regnames[rt], btgt);
3796 goto not_likely;
3797 case OPC_BNEL:
3798 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3799 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3800 regnames[rs], regnames[rt], btgt);
3801 goto likely;
3802 case OPC_BGEZ:
3803 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3804 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3805 goto not_likely;
3806 case OPC_BGEZL:
3807 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3808 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3809 goto likely;
3810 case OPC_BGEZALS:
3811 case OPC_BGEZAL:
3812 ctx->hflags |= (opc == OPC_BGEZALS
3813 ? MIPS_HFLAG_BDS16
3814 : MIPS_HFLAG_BDS32);
3815 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3816 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3817 blink = 31;
3818 goto not_likely;
3819 case OPC_BGEZALL:
3820 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3821 blink = 31;
3822 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3823 goto likely;
3824 case OPC_BGTZ:
3825 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3826 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3827 goto not_likely;
3828 case OPC_BGTZL:
3829 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3830 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3831 goto likely;
3832 case OPC_BLEZ:
3833 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3834 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3835 goto not_likely;
3836 case OPC_BLEZL:
3837 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3838 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3839 goto likely;
3840 case OPC_BLTZ:
3841 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3842 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3843 goto not_likely;
3844 case OPC_BLTZL:
3845 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3846 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3847 goto likely;
3848 case OPC_BPOSGE32:
3849 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3850 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3851 goto not_likely;
3852 #if defined(TARGET_MIPS64)
3853 case OPC_BPOSGE64:
3854 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3855 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3856 goto not_likely;
3857 #endif
3858 case OPC_BLTZALS:
3859 case OPC_BLTZAL:
3860 ctx->hflags |= (opc == OPC_BLTZALS
3861 ? MIPS_HFLAG_BDS16
3862 : MIPS_HFLAG_BDS32);
3863 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3864 blink = 31;
3865 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3866 not_likely:
3867 ctx->hflags |= MIPS_HFLAG_BC;
3868 break;
3869 case OPC_BLTZALL:
3870 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3871 blink = 31;
3872 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3873 likely:
3874 ctx->hflags |= MIPS_HFLAG_BL;
3875 break;
3876 default:
3877 MIPS_INVAL("conditional branch/jump");
3878 generate_exception(ctx, EXCP_RI);
3879 goto out;
3880 }
3881 }
3882 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3883 blink, ctx->hflags, btgt);
3884
3885 ctx->btarget = btgt;
3886 if (blink > 0) {
3887 int post_delay = insn_bytes;
3888 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3889
3890 if (opc != OPC_JALRC)
3891 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3892
3893 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3894 }
3895
3896 out:
3897 if (insn_bytes == 2)
3898 ctx->hflags |= MIPS_HFLAG_B16;
3899 tcg_temp_free(t0);
3900 tcg_temp_free(t1);
3901 }
3902
3903 /* special3 bitfield operations */
3904 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3905 int rs, int lsb, int msb)
3906 {
3907 TCGv t0 = tcg_temp_new();
3908 TCGv t1 = tcg_temp_new();
3909 target_ulong mask;
3910
3911 gen_load_gpr(t1, rs);
3912 switch (opc) {
3913 case OPC_EXT:
3914 if (lsb + msb > 31)
3915 goto fail;
3916 tcg_gen_shri_tl(t0, t1, lsb);
3917 if (msb != 31) {
3918 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3919 } else {
3920 tcg_gen_ext32s_tl(t0, t0);
3921 }
3922 break;
3923 #if defined(TARGET_MIPS64)
3924 case OPC_DEXTM:
3925 tcg_gen_shri_tl(t0, t1, lsb);
3926 if (msb != 31) {
3927 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3928 }
3929 break;
3930 case OPC_DEXTU:
3931 tcg_gen_shri_tl(t0, t1, lsb + 32);
3932 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3933 break;
3934 case OPC_DEXT:
3935 tcg_gen_shri_tl(t0, t1, lsb);
3936 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3937 break;
3938 #endif
3939 case OPC_INS:
3940 if (lsb > msb)
3941 goto fail;
3942 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3943 gen_load_gpr(t0, rt);
3944 tcg_gen_andi_tl(t0, t0, ~mask);
3945 tcg_gen_shli_tl(t1, t1, lsb);
3946 tcg_gen_andi_tl(t1, t1, mask);
3947 tcg_gen_or_tl(t0, t0, t1);
3948 tcg_gen_ext32s_tl(t0, t0);
3949 break;
3950 #if defined(TARGET_MIPS64)
3951 case OPC_DINSM:
3952 if (lsb > msb)
3953 goto fail;
3954 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3955 gen_load_gpr(t0, rt);
3956 tcg_gen_andi_tl(t0, t0, ~mask);
3957 tcg_gen_shli_tl(t1, t1, lsb);
3958 tcg_gen_andi_tl(t1, t1, mask);
3959 tcg_gen_or_tl(t0, t0, t1);
3960 break;
3961 case OPC_DINSU:
3962 if (lsb > msb)
3963 goto fail;
3964 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3965 gen_load_gpr(t0, rt);
3966 tcg_gen_andi_tl(t0, t0, ~mask);
3967 tcg_gen_shli_tl(t1, t1, lsb + 32);
3968 tcg_gen_andi_tl(t1, t1, mask);
3969 tcg_gen_or_tl(t0, t0, t1);
3970 break;
3971 case OPC_DINS:
3972 if (lsb > msb)
3973 goto fail;
3974 gen_load_gpr(t0, rt);
3975 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3976 gen_load_gpr(t0, rt);
3977 tcg_gen_andi_tl(t0, t0, ~mask);
3978 tcg_gen_shli_tl(t1, t1, lsb);
3979 tcg_gen_andi_tl(t1, t1, mask);
3980 tcg_gen_or_tl(t0, t0, t1);
3981 break;
3982 #endif
3983 default:
3984 fail:
3985 MIPS_INVAL("bitops");
3986 generate_exception(ctx, EXCP_RI);
3987 tcg_temp_free(t0);
3988 tcg_temp_free(t1);
3989 return;
3990 }
3991 gen_store_gpr(t0, rt);
3992 tcg_temp_free(t0);
3993 tcg_temp_free(t1);
3994 }
3995
3996 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3997 {
3998 TCGv t0;
3999
4000 if (rd == 0) {
4001 /* If no destination, treat it as a NOP. */
4002 MIPS_DEBUG("NOP");
4003 return;
4004 }
4005
4006 t0 = tcg_temp_new();
4007 gen_load_gpr(t0, rt);
4008 switch (op2) {
4009 case OPC_WSBH:
4010 {
4011 TCGv t1 = tcg_temp_new();
4012
4013 tcg_gen_shri_tl(t1, t0, 8);
4014 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4015 tcg_gen_shli_tl(t0, t0, 8);
4016 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4017 tcg_gen_or_tl(t0, t0, t1);
4018 tcg_temp_free(t1);
4019 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4020 }
4021 break;
4022 case OPC_SEB:
4023 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4024 break;
4025 case OPC_SEH:
4026 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4027 break;
4028 #if defined(TARGET_MIPS64)
4029 case OPC_DSBH:
4030 {
4031 TCGv t1 = tcg_temp_new();
4032
4033 tcg_gen_shri_tl(t1, t0, 8);
4034 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4035 tcg_gen_shli_tl(t0, t0, 8);
4036 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4037 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4038 tcg_temp_free(t1);
4039 }
4040 break;
4041 case OPC_DSHD:
4042 {
4043 TCGv t1 = tcg_temp_new();
4044
4045 tcg_gen_shri_tl(t1, t0, 16);
4046 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4047 tcg_gen_shli_tl(t0, t0, 16);
4048 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4049 tcg_gen_or_tl(t0, t0, t1);
4050 tcg_gen_shri_tl(t1, t0, 32);
4051 tcg_gen_shli_tl(t0, t0, 32);
4052 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4053 tcg_temp_free(t1);
4054 }
4055 break;
4056 #endif
4057 default:
4058 MIPS_INVAL("bsfhl");
4059 generate_exception(ctx, EXCP_RI);
4060 tcg_temp_free(t0);
4061 return;
4062 }
4063 tcg_temp_free(t0);
4064 }
4065
4066 #ifndef CONFIG_USER_ONLY
4067 /* CP0 (MMU and control) */
4068 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4069 {
4070 TCGv_i32 t0 = tcg_temp_new_i32();
4071
4072 tcg_gen_ld_i32(t0, cpu_env, off);
4073 tcg_gen_ext_i32_tl(arg, t0);
4074 tcg_temp_free_i32(t0);
4075 }
4076
4077 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4078 {
4079 tcg_gen_ld_tl(arg, cpu_env, off);
4080 tcg_gen_ext32s_tl(arg, arg);
4081 }
4082
4083 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4084 {
4085 TCGv_i32 t0 = tcg_temp_new_i32();
4086
4087 tcg_gen_trunc_tl_i32(t0, arg);
4088 tcg_gen_st_i32(t0, cpu_env, off);
4089 tcg_temp_free_i32(t0);
4090 }
4091
4092 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4093 {
4094 tcg_gen_ext32s_tl(arg, arg);
4095 tcg_gen_st_tl(arg, cpu_env, off);
4096 }
4097
4098 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4099 {
4100 const char *rn = "invalid";
4101
4102 if (sel != 0)
4103 check_insn(env, ctx, ISA_MIPS32);
4104
4105 switch (reg) {
4106 case 0:
4107 switch (sel) {
4108 case 0:
4109 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4110 rn = "Index";
4111 break;
4112 case 1:
4113 check_insn(env, ctx, ASE_MT);
4114 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4115 rn = "MVPControl";
4116 break;
4117 case 2:
4118 check_insn(env, ctx, ASE_MT);
4119 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4120 rn = "MVPConf0";
4121 break;
4122 case 3:
4123 check_insn(env, ctx, ASE_MT);
4124 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4125 rn = "MVPConf1";
4126 break;
4127 default:
4128 goto die;
4129 }
4130 break;
4131 case 1:
4132 switch (sel) {
4133 case 0:
4134 gen_helper_mfc0_random(arg, cpu_env);
4135 rn = "Random";
4136 break;
4137 case 1:
4138 check_insn(env, ctx, ASE_MT);
4139 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4140 rn = "VPEControl";
4141 break;
4142 case 2:
4143 check_insn(env, ctx, ASE_MT);
4144 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4145 rn = "VPEConf0";
4146 break;
4147 case 3:
4148 check_insn(env, ctx, ASE_MT);
4149 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4150 rn = "VPEConf1";
4151 break;
4152 case 4:
4153 check_insn(env, ctx, ASE_MT);
4154 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4155 rn = "YQMask";
4156 break;
4157 case 5:
4158 check_insn(env, ctx, ASE_MT);
4159 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4160 rn = "VPESchedule";
4161 break;
4162 case 6:
4163 check_insn(env, ctx, ASE_MT);
4164 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4165 rn = "VPEScheFBack";
4166 break;
4167 case 7:
4168 check_insn(env, ctx, ASE_MT);
4169 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4170 rn = "VPEOpt";
4171 break;
4172 default:
4173 goto die;
4174 }
4175 break;
4176 case 2:
4177 switch (sel) {
4178 case 0:
4179 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4180 tcg_gen_ext32s_tl(arg, arg);
4181 rn = "EntryLo0";
4182 break;
4183 case 1:
4184 check_insn(env, ctx, ASE_MT);
4185 gen_helper_mfc0_tcstatus(arg, cpu_env);
4186 rn = "TCStatus";
4187 break;
4188 case 2:
4189 check_insn(env, ctx, ASE_MT);
4190 gen_helper_mfc0_tcbind(arg, cpu_env);
4191 rn = "TCBind";
4192 break;
4193 case 3:
4194 check_insn(env, ctx, ASE_MT);
4195 gen_helper_mfc0_tcrestart(arg, cpu_env);
4196 rn = "TCRestart";
4197 break;
4198 case 4:
4199 check_insn(env, ctx, ASE_MT);
4200 gen_helper_mfc0_tchalt(arg, cpu_env);
4201 rn = "TCHalt";
4202 break;
4203 case 5:
4204 check_insn(env, ctx, ASE_MT);
4205 gen_helper_mfc0_tccontext(arg, cpu_env);
4206 rn = "TCContext";
4207 break;
4208 case 6:
4209 check_insn(env, ctx, ASE_MT);
4210 gen_helper_mfc0_tcschedule(arg, cpu_env);
4211 rn = "TCSchedule";
4212 break;
4213 case 7:
4214 check_insn(env, ctx, ASE_MT);
4215 gen_helper_mfc0_tcschefback(arg, cpu_env);
4216 rn = "TCScheFBack";
4217 break;
4218 default:
4219 goto die;
4220 }
4221 break;
4222 case 3:
4223 switch (sel) {
4224 case 0:
4225 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4226 tcg_gen_ext32s_tl(arg, arg);
4227 rn = "EntryLo1";
4228 break;
4229 default:
4230 goto die;
4231 }
4232 break;
4233 case 4:
4234 switch (sel) {
4235 case 0:
4236 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4237 tcg_gen_ext32s_tl(arg, arg);
4238 rn = "Context";
4239 break;
4240 case 1:
4241 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4242 rn = "ContextConfig";
4243 // break;
4244 default:
4245 goto die;
4246 }
4247 break;
4248 case 5:
4249 switch (sel) {
4250 case 0:
4251 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4252 rn = "PageMask";
4253 break;
4254 case 1:
4255 check_insn(env, ctx, ISA_MIPS32R2);
4256 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4257 rn = "PageGrain";
4258 break;
4259 default:
4260 goto die;
4261 }
4262 break;
4263 case 6:
4264 switch (sel) {
4265 case 0:
4266 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4267 rn = "Wired";
4268 break;
4269 case 1:
4270 check_insn(env, ctx, ISA_MIPS32R2);
4271 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4272 rn = "SRSConf0";
4273 break;
4274 case 2:
4275 check_insn(env, ctx, ISA_MIPS32R2);
4276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4277 rn = "SRSConf1";
4278 break;
4279 case 3:
4280 check_insn(env, ctx, ISA_MIPS32R2);
4281 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4282 rn = "SRSConf2";
4283 break;
4284 case 4:
4285 check_insn(env, ctx, ISA_MIPS32R2);
4286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4287 rn = "SRSConf3";
4288 break;
4289 case 5:
4290 check_insn(env, ctx, ISA_MIPS32R2);
4291 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4292 rn = "SRSConf4";
4293 break;
4294 default:
4295 goto die;
4296 }
4297 break;
4298 case 7:
4299 switch (sel) {
4300 case 0:
4301 check_insn(env, ctx, ISA_MIPS32R2);
4302 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4303 rn = "HWREna";
4304 break;
4305 default:
4306 goto die;
4307 }
4308 break;
4309 case 8:
4310 switch (sel) {
4311 case 0:
4312 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4313 tcg_gen_ext32s_tl(arg, arg);
4314 rn = "BadVAddr";
4315 break;
4316 default:
4317 goto die;
4318 }
4319 break;
4320 case 9:
4321 switch (sel) {
4322 case 0:
4323 /* Mark as an IO operation because we read the time. */
4324 if (use_icount)
4325 gen_io_start();
4326 gen_helper_mfc0_count(arg, cpu_env);
4327 if (use_icount) {
4328 gen_io_end();
4329 }
4330 /* Break the TB to be able to take timer interrupts immediately
4331 after reading count. */
4332 ctx->bstate = BS_STOP;
4333 rn = "Count";
4334 break;
4335 /* 6,7 are implementation dependent */
4336 default:
4337 goto die;
4338 }
4339 break;
4340 case 10:
4341 switch (sel) {
4342 case 0:
4343 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4344 tcg_gen_ext32s_tl(arg, arg);
4345 rn = "EntryHi";
4346 break;
4347 default:
4348 goto die;
4349 }
4350 break;
4351 case 11:
4352 switch (sel) {
4353 case 0:
4354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4355 rn = "Compare";
4356 break;
4357 /* 6,7 are implementation dependent */
4358 default:
4359 goto die;
4360 }
4361 break;
4362 case 12:
4363 switch (sel) {
4364 case 0:
4365 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4366 rn = "Status";
4367 break;
4368 case 1:
4369 check_insn(env, ctx, ISA_MIPS32R2);
4370 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4371 rn = "IntCtl";
4372 break;
4373 case 2:
4374 check_insn(env, ctx, ISA_MIPS32R2);
4375 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4376 rn = "SRSCtl";
4377 break;
4378 case 3:
4379 check_insn(env, ctx, ISA_MIPS32R2);
4380 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4381 rn = "SRSMap";
4382 break;
4383 default:
4384 goto die;
4385 }
4386 break;
4387 case 13:
4388 switch (sel) {
4389 case 0:
4390 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4391 rn = "Cause";
4392 break;
4393 default:
4394 goto die;
4395 }
4396 break;
4397 case 14:
4398 switch (sel) {
4399 case 0:
4400 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4401 tcg_gen_ext32s_tl(arg, arg);
4402 rn = "EPC";
4403 break;
4404 default:
4405 goto die;
4406 }
4407 break;
4408 case 15:
4409 switch (sel) {
4410 case 0:
4411 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4412 rn = "PRid";
4413 break;
4414 case 1:
4415 check_insn(env, ctx, ISA_MIPS32R2);
4416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4417 rn = "EBase";
4418 break;
4419 default:
4420 goto die;
4421 }
4422 break;
4423 case 16:
4424 switch (sel) {
4425 case 0:
4426 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4427 rn = "Config";
4428 break;
4429 case 1:
4430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4431 rn = "Config1";
4432 break;
4433 case 2:
4434 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4435 rn = "Config2";
4436 break;
4437 case 3:
4438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4439 rn = "Config3";
4440 break;
4441 /* 4,5 are reserved */
4442 /* 6,7 are implementation dependent */
4443 case 6:
4444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4445 rn = "Config6";
4446 break;
4447 case 7:
4448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4449 rn = "Config7";
4450 break;
4451 default:
4452 goto die;
4453 }
4454 break;
4455 case 17:
4456 switch (sel) {
4457 case 0:
4458 gen_helper_mfc0_lladdr(arg, cpu_env);
4459 rn = "LLAddr";
4460 break;
4461 default:
4462 goto die;
4463 }
4464 break;
4465 case 18:
4466 switch (sel) {
4467 case 0 ... 7:
4468 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4469 rn = "WatchLo";
4470 break;
4471 default:
4472 goto die;
4473 }
4474 break;
4475 case 19:
4476 switch (sel) {
4477 case 0 ...7:
4478 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4479 rn = "WatchHi";
4480 break;
4481 default:
4482 goto die;
4483 }
4484 break;
4485 case 20:
4486 switch (sel) {
4487 case 0:
4488 #if defined(TARGET_MIPS64)
4489 check_insn(env, ctx, ISA_MIPS3);
4490 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4491 tcg_gen_ext32s_tl(arg, arg);
4492 rn = "XContext";
4493 break;
4494 #endif
4495 default:
4496 goto die;
4497 }
4498 break;
4499 case 21:
4500 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4501 switch (sel) {
4502 case 0:
4503 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4504 rn = "Framemask";
4505 break;
4506 default:
4507 goto die;
4508 }
4509 break;
4510 case 22:
4511 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4512 rn = "'Diagnostic"; /* implementation dependent */
4513 break;
4514 case 23:
4515 switch (sel) {
4516 case 0:
4517 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4518 rn = "Debug";
4519 break;
4520 case 1:
4521 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4522 rn = "TraceControl";
4523 // break;
4524 case 2:
4525 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4526 rn = "TraceControl2";
4527 // break;
4528 case 3:
4529 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4530 rn = "UserTraceData";
4531 // break;
4532 case 4:
4533 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4534 rn = "TraceBPC";
4535 // break;
4536 default:
4537 goto die;
4538 }
4539 break;
4540 case 24:
4541 switch (sel) {
4542 case 0:
4543 /* EJTAG support */
4544 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4545 tcg_gen_ext32s_tl(arg, arg);
4546 rn = "DEPC";
4547 break;
4548 default:
4549 goto die;
4550 }
4551 break;
4552 case 25:
4553 switch (sel) {
4554 case 0:
4555 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4556 rn = "Performance0";
4557 break;
4558 case 1:
4559 // gen_helper_mfc0_performance1(arg);
4560 rn = "Performance1";
4561 // break;
4562 case 2:
4563 // gen_helper_mfc0_performance2(arg);
4564 rn = "Performance2";
4565 // break;
4566 case 3:
4567 // gen_helper_mfc0_performance3(arg);
4568 rn = "Performance3";
4569 // break;
4570 case 4:
4571 // gen_helper_mfc0_performance4(arg);
4572 rn = "Performance4";
4573 // break;
4574 case 5:
4575 // gen_helper_mfc0_performance5(arg);
4576 rn = "Performance5";
4577 // break;
4578 case 6:
4579 // gen_helper_mfc0_performance6(arg);
4580 rn = "Performance6";
4581 // break;
4582 case 7:
4583 // gen_helper_mfc0_performance7(arg);
4584 rn = "Performance7";
4585 // break;
4586 default:
4587 goto die;
4588 }
4589 break;
4590 case 26:
4591 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4592 rn = "ECC";
4593 break;
4594 case 27:
4595 switch (sel) {
4596 case 0 ... 3:
4597 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4598 rn = "CacheErr";
4599 break;
4600 default:
4601 goto die;
4602 }
4603 break;
4604 case 28:
4605 switch (sel) {
4606 case 0:
4607 case 2:
4608 case 4:
4609 case 6:
4610 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4611 rn = "TagLo";
4612 break;
4613 case 1:
4614 case 3:
4615 case 5:
4616 case 7:
4617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4618 rn = "DataLo";
4619 break;
4620 default:
4621 goto die;
4622 }
4623 break;
4624 case 29:
4625 switch (sel) {
4626 case 0:
4627 case 2:
4628 case 4:
4629 case 6:
4630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4631 rn = "TagHi";
4632 break;
4633 case 1:
4634 case 3:
4635 case 5:
4636 case 7:
4637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4638 rn = "DataHi";
4639 break;
4640 default:
4641 goto die;
4642 }
4643 break;
4644 case 30:
4645 switch (sel) {
4646 case 0:
4647 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4648 tcg_gen_ext32s_tl(arg, arg);
4649 rn = "ErrorEPC";
4650 break;
4651 default:
4652 goto die;
4653 }
4654 break;
4655 case 31:
4656 switch (sel) {
4657 case 0:
4658 /* EJTAG support */
4659 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4660 rn = "DESAVE";
4661 break;
4662 default:
4663 goto die;
4664 }
4665 break;
4666 default:
4667 goto die;
4668 }
4669 (void)rn; /* avoid a compiler warning */
4670 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4671 return;
4672
4673 die:
4674 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4675 generate_exception(ctx, EXCP_RI);
4676 }
4677
4678 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4679 {
4680 const char *rn = "invalid";
4681
4682 if (sel != 0)
4683 check_insn(env, ctx, ISA_MIPS32);
4684
4685 if (use_icount)
4686 gen_io_start();
4687
4688 switch (reg) {
4689 case 0:
4690 switch (sel) {
4691 case 0:
4692 gen_helper_mtc0_index(cpu_env, arg);
4693 rn = "Index";
4694 break;
4695 case 1:
4696 check_insn(env, ctx, ASE_MT);
4697 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4698 rn = "MVPControl";
4699 break;
4700 case 2:
4701 check_insn(env, ctx, ASE_MT);
4702 /* ignored */
4703 rn = "MVPConf0";
4704 break;
4705 case 3:
4706 check_insn(env, ctx, ASE_MT);
4707 /* ignored */
4708 rn = "MVPConf1";
4709 break;
4710 default:
4711 goto die;
4712 }
4713 break;
4714 case 1:
4715 switch (sel) {
4716 case 0:
4717 /* ignored */
4718 rn = "Random";
4719 break;
4720 case 1:
4721 check_insn(env, ctx, ASE_MT);
4722 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4723 rn = "VPEControl";
4724 break;
4725 case 2:
4726 check_insn(env, ctx, ASE_MT);
4727 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4728 rn = "VPEConf0";
4729 break;
4730 case 3:
4731 check_insn(env, ctx, ASE_MT);
4732 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4733 rn = "VPEConf1";
4734 break;
4735 case 4:
4736 check_insn(env, ctx, ASE_MT);
4737 gen_helper_mtc0_yqmask(cpu_env, arg);
4738 rn = "YQMask";
4739 break;
4740 case 5:
4741 check_insn(env, ctx, ASE_MT);
4742 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4743 rn = "VPESchedule";
4744 break;
4745 case 6:
4746 check_insn(env, ctx, ASE_MT);
4747 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4748 rn = "VPEScheFBack";
4749 break;
4750 case 7:
4751 check_insn(env, ctx, ASE_MT);
4752 gen_helper_mtc0_vpeopt(cpu_env, arg);
4753 rn = "VPEOpt";
4754 break;
4755 default:
4756 goto die;
4757 }
4758 break;
4759 case 2:
4760 switch (sel) {
4761 case 0:
4762 gen_helper_mtc0_entrylo0(cpu_env, arg);
4763 rn = "EntryLo0";
4764 break;
4765 case 1:
4766 check_insn(env, ctx, ASE_MT);
4767 gen_helper_mtc0_tcstatus(cpu_env, arg);
4768 rn = "TCStatus";
4769 break;
4770 case 2:
4771 check_insn(env, ctx, ASE_MT);
4772 gen_helper_mtc0_tcbind(cpu_env, arg);
4773 rn = "TCBind";
4774 break;
4775 case 3:
4776 check_insn(env, ctx, ASE_MT);
4777 gen_helper_mtc0_tcrestart(cpu_env, arg);
4778 rn = "TCRestart";
4779 break;
4780 case 4:
4781 check_insn(env, ctx, ASE_MT);
4782 gen_helper_mtc0_tchalt(cpu_env, arg);
4783 rn = "TCHalt";
4784 break;
4785 case 5:
4786 check_insn(env, ctx, ASE_MT);
4787 gen_helper_mtc0_tccontext(cpu_env, arg);
4788 rn = "TCContext";
4789 break;
4790 case 6:
4791 check_insn(env, ctx, ASE_MT);
4792 gen_helper_mtc0_tcschedule(cpu_env, arg);
4793 rn = "TCSchedule";
4794 break;
4795 case 7:
4796 check_insn(env, ctx, ASE_MT);
4797 gen_helper_mtc0_tcschefback(cpu_env, arg);
4798 rn = "TCScheFBack";
4799 break;
4800 default:
4801 goto die;
4802 }
4803 break;
4804 case 3:
4805 switch (sel) {
4806 case 0:
4807 gen_helper_mtc0_entrylo1(cpu_env, arg);
4808 rn = "EntryLo1";
4809 break;
4810 default:
4811 goto die;
4812 }
4813 break;
4814 case 4:
4815 switch (sel) {
4816 case 0:
4817 gen_helper_mtc0_context(cpu_env, arg);
4818 rn = "Context";
4819 break;
4820 case 1:
4821 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4822 rn = "ContextConfig";
4823 // break;
4824 default:
4825 goto die;
4826 }
4827 break;
4828 case 5:
4829 switch (sel) {
4830 case 0:
4831 gen_helper_mtc0_pagemask(cpu_env, arg);
4832 rn = "PageMask";
4833 break;
4834 case 1:
4835 check_insn(env, ctx, ISA_MIPS32R2);
4836 gen_helper_mtc0_pagegrain(cpu_env, arg);
4837 rn = "PageGrain";
4838 break;
4839 default:
4840 goto die;
4841 }
4842 break;
4843 case 6:
4844 switch (sel) {
4845 case 0:
4846 gen_helper_mtc0_wired(cpu_env, arg);
4847 rn = "Wired";
4848 break;
4849 case 1:
4850 check_insn(env, ctx, ISA_MIPS32R2);
4851 gen_helper_mtc0_srsconf0(cpu_env, arg);
4852 rn = "SRSConf0";
4853 break;
4854 case 2:
4855 check_insn(env, ctx, ISA_MIPS32R2);
4856 gen_helper_mtc0_srsconf1(cpu_env, arg);
4857 rn = "SRSConf1";
4858 break;
4859 case 3:
4860 check_insn(env, ctx, ISA_MIPS32R2);
4861 gen_helper_mtc0_srsconf2(cpu_env, arg);
4862 rn = "SRSConf2";
4863 break;
4864 case 4:
4865 check_insn(env, ctx, ISA_MIPS32R2);
4866 gen_helper_mtc0_srsconf3(cpu_env, arg);
4867 rn = "SRSConf3";
4868 break;
4869 case 5:
4870 check_insn(env, ctx, ISA_MIPS32R2);
4871 gen_helper_mtc0_srsconf4(cpu_env, arg);
4872 rn = "SRSConf4";
4873 break;
4874 default:
4875 goto die;
4876 }
4877 break;
4878 case 7:
4879 switch (sel) {
4880 case 0:
4881 check_insn(env, ctx, ISA_MIPS32R2);
4882 gen_helper_mtc0_hwrena(cpu_env, arg);
4883 rn = "HWREna";
4884 break;
4885 default:
4886 goto die;
4887 }
4888 break;
4889 case 8:
4890 /* ignored */
4891 rn = "BadVAddr";
4892 break;
4893 case 9:
4894 switch (sel) {
4895 case 0:
4896 gen_helper_mtc0_count(cpu_env, arg);
4897 rn = "Count";
4898 break;
4899 /* 6,7 are implementation dependent */
4900 default:
4901 goto die;
4902 }
4903 break;
4904 case 10:
4905 switch (sel) {
4906 case 0:
4907 gen_helper_mtc0_entryhi(cpu_env, arg);
4908 rn = "EntryHi";
4909 break;
4910 default:
4911 goto die;
4912 }
4913 break;
4914 case 11:
4915 switch (sel) {
4916 case 0:
4917 gen_helper_mtc0_compare(cpu_env, arg);
4918 rn = "Compare";
4919 break;
4920 /* 6,7 are implementation dependent */
4921 default:
4922 goto die;
4923 }
4924 break;
4925 case 12:
4926 switch (sel) {
4927 case 0:
4928 save_cpu_state(ctx, 1);
4929 gen_helper_mtc0_status(cpu_env, arg);
4930 /* BS_STOP isn't good enough here, hflags may have changed. */
4931 gen_save_pc(ctx->pc + 4);
4932 ctx->bstate = BS_EXCP;
4933 rn = "Status";
4934 break;
4935 case 1:
4936 check_insn(env, ctx, ISA_MIPS32R2);
4937 gen_helper_mtc0_intctl(cpu_env, arg);
4938 /* Stop translation as we may have switched the execution mode */
4939 ctx->bstate = BS_STOP;
4940 rn = "IntCtl";
4941 break;
4942 case 2:
4943 check_insn(env, ctx, ISA_MIPS32R2);
4944 gen_helper_mtc0_srsctl(cpu_env, arg);
4945 /* Stop translation as we may have switched the execution mode */
4946 ctx->bstate = BS_STOP;
4947 rn = "SRSCtl";
4948 break;
4949 case 3:
4950 check_insn(env, ctx, ISA_MIPS32R2);
4951 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4952 /* Stop translation as we may have switched the execution mode */
4953 ctx->bstate = BS_STOP;
4954 rn = "SRSMap";
4955 break;
4956 default:
4957 goto die;
4958 }
4959 break;
4960 case 13:
4961 switch (sel) {
4962 case 0:
4963 save_cpu_state(ctx, 1);
4964 gen_helper_mtc0_cause(cpu_env, arg);
4965 rn = "Cause";
4966 break;
4967 default:
4968 goto die;
4969 }
4970 break;
4971 case 14:
4972 switch (sel) {
4973 case 0:
4974 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4975 rn = "EPC";
4976 break;
4977 default:
4978 goto die;
4979 }
4980 break;
4981 case 15:
4982 switch (sel) {
4983 case 0:
4984 /* ignored */
4985 rn = "PRid";
4986 break;
4987 case 1:
4988 check_insn(env, ctx, ISA_MIPS32R2);
4989 gen_helper_mtc0_ebase(cpu_env, arg);
4990 rn = "EBase";
4991 break;
4992 default:
4993 goto die;
4994 }
4995 break;
4996 case 16:
4997 switch (sel) {
4998 case 0:
4999 gen_helper_mtc0_config0(cpu_env, arg);
5000 rn = "Config";
5001 /* Stop translation as we may have switched the execution mode */
5002 ctx->bstate = BS_STOP;
5003 break;
5004 case 1:
5005 /* ignored, read only */
5006 rn = "Config1";
5007 break;
5008 case 2:
5009 gen_helper_mtc0_config2(cpu_env, arg);
5010 rn = "Config2";
5011 /* Stop translation as we may have switched the execution mode */
5012 ctx->bstate = BS_STOP;
5013 break;
5014 case 3:
5015 /* ignored, read only */
5016 rn = "Config3";
5017 break;
5018 /* 4,5 are reserved */
5019 /* 6,7 are implementation dependent */
5020 case 6:
5021 /* ignored */
5022 rn = "Config6";
5023 break;
5024 case 7:
5025 /* ignored */
5026 rn = "Config7";
5027 break;
5028 default:
5029 rn = "Invalid config selector";
5030 goto die;
5031 }
5032 break;
5033 case 17:
5034 switch (sel) {
5035 case 0:
5036 gen_helper_mtc0_lladdr(cpu_env, arg);
5037 rn = "LLAddr";
5038 break;
5039 default:
5040 goto die;
5041 }
5042 break;
5043 case 18:
5044 switch (sel) {
5045 case 0 ... 7:
5046 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5047 rn = "WatchLo";
5048 break;
5049 default:
5050 goto die;
5051 }
5052 break;
5053 case 19:
5054 switch (sel) {
5055 case 0 ... 7:
5056 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5057 rn = "WatchHi";
5058 break;
5059 default:
5060 goto die;
5061 }
5062 break;
5063 case 20:
5064 switch (sel) {
5065 case 0:
5066 #if defined(TARGET_MIPS64)
5067 check_insn(env, ctx, ISA_MIPS3);
5068 gen_helper_mtc0_xcontext(cpu_env, arg);
5069 rn = "XContext";
5070 break;
5071 #endif
5072 default:
5073 goto die;
5074 }
5075 break;
5076 case 21:
5077 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5078 switch (sel) {
5079 case 0:
5080 gen_helper_mtc0_framemask(cpu_env, arg);
5081 rn = "Framemask";
5082 break;
5083 default:
5084 goto die;
5085 }
5086 break;
5087 case 22:
5088 /* ignored */
5089 rn = "Diagnostic"; /* implementation dependent */
5090 break;
5091 case 23:
5092 switch (sel) {
5093 case 0:
5094 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5095 /* BS_STOP isn't good enough here, hflags may have changed. */
5096 gen_save_pc(ctx->pc + 4);
5097 ctx->bstate = BS_EXCP;
5098 rn = "Debug";
5099 break;
5100 case 1:
5101 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5102 rn = "TraceControl";
5103 /* Stop translation as we may have switched the execution mode */
5104 ctx->bstate = BS_STOP;
5105 // break;
5106 case 2:
5107 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5108 rn = "TraceControl2";
5109 /* Stop translation as we may have switched the execution mode */
5110 ctx->bstate = BS_STOP;
5111 // break;
5112 case 3:
5113 /* Stop translation as we may have switched the execution mode */
5114 ctx->bstate = BS_STOP;
5115 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5116 rn = "UserTraceData";
5117 /* Stop translation as we may have switched the execution mode */
5118 ctx->bstate = BS_STOP;
5119 // break;
5120 case 4:
5121 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5122 /* Stop translation as we may have switched the execution mode */
5123 ctx->bstate = BS_STOP;
5124 rn = "TraceBPC";
5125 // break;
5126 default:
5127 goto die;
5128 }
5129 break;
5130 case 24:
5131 switch (sel) {
5132 case 0:
5133 /* EJTAG support */
5134 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5135 rn = "DEPC";
5136 break;
5137 default:
5138 goto die;
5139 }
5140 break;
5141 case 25:
5142 switch (sel) {
5143 case 0:
5144 gen_helper_mtc0_performance0(cpu_env, arg);
5145 rn = "Performance0";
5146 break;
5147 case 1:
5148 // gen_helper_mtc0_performance1(arg);
5149 rn = "Performance1";
5150 // break;
5151 case 2:
5152 // gen_helper_mtc0_performance2(arg);
5153 rn = "Performance2";
5154 // break;
5155 case 3:
5156 // gen_helper_mtc0_performance3(arg);
5157 rn = "Performance3";
5158 // break;
5159 case 4:
5160 // gen_helper_mtc0_performance4(arg);
5161 rn = "Performance4";
5162 // break;
5163 case 5:
5164 // gen_helper_mtc0_performance5(arg);
5165 rn = "Performance5";
5166 // break;
5167 case 6:
5168 // gen_helper_mtc0_performance6(arg);
5169 rn = "Performance6";
5170 // break;
5171 case 7:
5172 // gen_helper_mtc0_performance7(arg);
5173 rn = "Performance7";
5174 // break;
5175 default:
5176 goto die;
5177 }
5178 break;
5179 case 26:
5180 /* ignored */
5181 rn = "ECC";
5182 break;
5183 case 27:
5184 switch (sel) {
5185 case 0 ... 3:
5186 /* ignored */
5187 rn = "CacheErr";
5188 break;
5189 default:
5190 goto die;
5191 }
5192 break;
5193 case 28:
5194 switch (sel) {
5195 case 0:
5196 case 2:
5197 case 4:
5198 case 6:
5199 gen_helper_mtc0_taglo(cpu_env, arg);
5200 rn = "TagLo";
5201 break;
5202 case 1:
5203 case 3:
5204 case 5:
5205 case 7:
5206 gen_helper_mtc0_datalo(cpu_env, arg);
5207 rn = "DataLo";
5208 break;
5209 default:
5210 goto die;
5211 }
5212 break;
5213 case 29:
5214 switch (sel) {
5215 case 0:
5216 case 2:
5217 case 4:
5218 case 6:
5219 gen_helper_mtc0_taghi(cpu_env, arg);
5220 rn = "TagHi";
5221 break;
5222 case 1:
5223 case 3:
5224 case 5:
5225 case 7:
5226 gen_helper_mtc0_datahi(cpu_env, arg);
5227 rn = "DataHi";
5228 break;
5229 default:
5230 rn = "invalid sel";
5231 goto die;
5232 }
5233 break;
5234 case 30:
5235 switch (sel) {
5236 case 0:
5237 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5238 rn = "ErrorEPC";
5239 break;
5240 default:
5241 goto die;
5242 }
5243 break;
5244 case 31:
5245 switch (sel) {
5246 case 0:
5247 /* EJTAG support */
5248 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5249 rn = "DESAVE";
5250 break;
5251 default:
5252 goto die;
5253 }
5254 /* Stop translation as we may have switched the execution mode */
5255 ctx->bstate = BS_STOP;
5256 break;
5257 default:
5258 goto die;
5259 }
5260 (void)rn; /* avoid a compiler warning */
5261 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5262 /* For simplicity assume that all writes can cause interrupts. */
5263 if (use_icount) {
5264 gen_io_end();
5265 ctx->bstate = BS_STOP;
5266 }
5267 return;
5268
5269 die:
5270 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5271 generate_exception(ctx, EXCP_RI);
5272 }
5273
5274 #if defined(TARGET_MIPS64)
5275 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5276 {
5277 const char *rn = "invalid";
5278
5279 if (sel != 0)
5280 check_insn(env, ctx, ISA_MIPS64);
5281
5282 switch (reg) {
5283 case 0:
5284 switch (sel) {
5285 case 0:
5286 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5287 rn = "Index";
5288 break;
5289 case 1:
5290 check_insn(env, ctx, ASE_MT);
5291 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5292 rn = "MVPControl";
5293 break;
5294 case 2:
5295 check_insn(env, ctx, ASE_MT);
5296 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5297 rn = "MVPConf0";
5298 break;
5299 case 3:
5300 check_insn(env, ctx, ASE_MT);
5301 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5302 rn = "MVPConf1";
5303 break;
5304 default:
5305 goto die;
5306 }
5307 break;
5308 case 1:
5309 switch (sel) {
5310 case 0:
5311 gen_helper_mfc0_random(arg, cpu_env);
5312 rn = "Random";
5313 break;
5314 case 1:
5315 check_insn(env, ctx, ASE_MT);
5316 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5317 rn = "VPEControl";
5318 break;
5319 case 2:
5320 check_insn(env, ctx, ASE_MT);
5321 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5322 rn = "VPEConf0";
5323 break;
5324 case 3:
5325 check_insn(env, ctx, ASE_MT);
5326 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5327 rn = "VPEConf1";
5328 break;
5329 case 4:
5330 check_insn(env, ctx, ASE_MT);
5331 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5332 rn = "YQMask";
5333 break;
5334 case 5:
5335 check_insn(env, ctx, ASE_MT);
5336 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5337 rn = "VPESchedule";
5338 break;
5339 case 6:
5340 check_insn(env, ctx, ASE_MT);
5341 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5342 rn = "VPEScheFBack";
5343 break;
5344 case 7:
5345 check_insn(env, ctx, ASE_MT);
5346 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5347 rn = "VPEOpt";
5348 break;
5349 default:
5350 goto die;
5351 }
5352 break;
5353 case 2:
5354 switch (sel) {
5355 case 0:
5356 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5357 rn = "EntryLo0";
5358 break;
5359 case 1:
5360 check_insn(env, ctx, ASE_MT);
5361 gen_helper_mfc0_tcstatus(arg, cpu_env);
5362 rn = "TCStatus";
5363 break;
5364 case 2:
5365 check_insn(env, ctx, ASE_MT);
5366 gen_helper_mfc0_tcbind(arg, cpu_env);
5367 rn = "TCBind";
5368 break;
5369 case 3:
5370 check_insn(env, ctx, ASE_MT);
5371 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5372 rn = "TCRestart";
5373 break;
5374 case 4:
5375 check_insn(env, ctx, ASE_MT);
5376 gen_helper_dmfc0_tchalt(arg, cpu_env);
5377 rn = "TCHalt";
5378 break;
5379 case 5:
5380 check_insn(env, ctx, ASE_MT);
5381 gen_helper_dmfc0_tccontext(arg, cpu_env);
5382 rn = "TCContext";
5383 break;
5384 case 6:
5385 check_insn(env, ctx, ASE_MT);
5386 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5387 rn = "TCSchedule";
5388 break;
5389 case 7:
5390 check_insn(env, ctx, ASE_MT);
5391 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5392 rn = "TCScheFBack";
5393 break;
5394 default:
5395 goto die;
5396 }
5397 break;
5398 case 3:
5399 switch (sel) {
5400 case 0:
5401 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5402 rn = "EntryLo1";
5403 break;
5404 default:
5405 goto die;
5406 }
5407 break;
5408 case 4:
5409 switch (sel) {
5410 case 0:
5411 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5412 rn = "Context";
5413 break;
5414 case 1:
5415 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5416 rn = "ContextConfig";
5417 // break;
5418 default:
5419 goto die;
5420 }
5421 break;
5422 case 5:
5423 switch (sel) {
5424 case 0:
5425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5426 rn = "PageMask";
5427 break;
5428 case 1:
5429 check_insn(env, ctx, ISA_MIPS32R2);
5430 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5431 rn = "PageGrain";
5432 break;
5433 default:
5434 goto die;
5435 }
5436 break;
5437 case 6:
5438 switch (sel) {
5439 case 0:
5440 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5441 rn = "Wired";
5442 break;
5443 case 1:
5444 check_insn(env, ctx, ISA_MIPS32R2);
5445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5446 rn = "SRSConf0";
5447 break;
5448 case 2:
5449 check_insn(env, ctx, ISA_MIPS32R2);
5450 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5451 rn = "SRSConf1";
5452 break;
5453 case 3:
5454 check_insn(env, ctx, ISA_MIPS32R2);
5455 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5456 rn = "SRSConf2";
5457 break;
5458 case 4:
5459 check_insn(env, ctx, ISA_MIPS32R2);
5460 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5461 rn = "SRSConf3";
5462 break;
5463 case 5:
5464 check_insn(env, ctx, ISA_MIPS32R2);
5465 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5466 rn = "SRSConf4";
5467 break;
5468 default:
5469 goto die;
5470 }
5471 break;
5472 case 7:
5473 switch (sel) {
5474 case 0:
5475 check_insn(env, ctx, ISA_MIPS32R2);
5476 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5477 rn = "HWREna";
5478 break;
5479 default:
5480 goto die;
5481 }
5482 break;
5483 case 8:
5484 switch (sel) {
5485 case 0:
5486 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5487 rn = "BadVAddr";
5488 break;
5489 default:
5490 goto die;
5491 }
5492 break;
5493 case 9:
5494 switch (sel) {
5495 case 0:
5496 /* Mark as an IO operation because we read the time. */
5497 if (use_icount)
5498 gen_io_start();
5499 gen_helper_mfc0_count(arg, cpu_env);
5500 if (use_icount) {
5501 gen_io_end();
5502 }
5503 /* Break the TB to be able to take timer interrupts immediately
5504 after reading count. */
5505 ctx->bstate = BS_STOP;
5506 rn = "Count";
5507 break;
5508 /* 6,7 are implementation dependent */
5509 default:
5510 goto die;
5511 }
5512 break;
5513 case 10:
5514 switch (sel) {
5515 case 0:
5516 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5517 rn = "EntryHi";
5518 break;
5519 default:
5520 goto die;
5521 }
5522 break;
5523 case 11:
5524 switch (sel) {
5525 case 0:
5526 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5527 rn = "Compare";
5528 break;
5529 /* 6,7 are implementation dependent */
5530 default:
5531 goto die;
5532 }
5533 break;
5534 case 12:
5535 switch (sel) {
5536 case 0:
5537 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5538 rn = "Status";
5539 break;
5540 case 1:
5541 check_insn(env, ctx, ISA_MIPS32R2);
5542 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5543 rn = "IntCtl";
5544 break;
5545 case 2:
5546 check_insn(env, ctx, ISA_MIPS32R2);
5547 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5548 rn = "SRSCtl";
5549 break;
5550 case 3:
5551 check_insn(env, ctx, ISA_MIPS32R2);
5552 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5553 rn = "SRSMap";
5554 break;
5555 default:
5556 goto die;
5557 }
5558 break;
5559 case 13:
5560 switch (sel) {
5561 case 0:
5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5563 rn = "Cause";
5564 break;
5565 default:
5566 goto die;
5567 }
5568 break;
5569 case 14:
5570 switch (sel) {
5571 case 0:
5572 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5573 rn = "EPC";
5574 break;
5575 default:
5576 goto die;
5577 }
5578 break;
5579 case 15:
5580 switch (sel) {
5581 case 0:
5582 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5583 rn = "PRid";
5584 break;
5585 case 1:
5586 check_insn(env, ctx, ISA_MIPS32R2);
5587 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5588 rn = "EBase";
5589 break;
5590 default:
5591 goto die;
5592 }
5593 break;
5594 case 16:
5595 switch (sel) {
5596 case 0:
5597 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5598 rn = "Config";
5599 break;
5600 case 1:
5601 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5602 rn = "Config1";
5603 break;
5604 case 2:
5605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5606 rn = "Config2";
5607 break;
5608 case 3:
5609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5610 rn = "Config3";
5611 break;
5612 /* 6,7 are implementation dependent */
5613 case 6:
5614 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5615 rn = "Config6";
5616 break;
5617 case 7:
5618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5619 rn = "Config7";
5620 break;
5621 default:
5622 goto die;
5623 }
5624 break;
5625 case 17:
5626 switch (sel) {
5627 case 0:
5628 gen_helper_dmfc0_lladdr(arg, cpu_env);
5629 rn = "LLAddr";
5630 break;
5631 default:
5632 goto die;
5633 }
5634 break;
5635 case 18:
5636 switch (sel) {
5637 case 0 ... 7:
5638 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5639 rn = "WatchLo";
5640 break;
5641 default:
5642 goto die;
5643 }
5644 break;
5645 case 19:
5646 switch (sel) {
5647 case 0 ... 7:
5648 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5649 rn = "WatchHi";
5650 break;
5651 default:
5652 goto die;
5653 }
5654 break;
5655 case 20:
5656 switch (sel) {
5657 case 0:
5658 check_insn(env, ctx, ISA_MIPS3);
5659 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5660 rn = "XContext";
5661 break;
5662 default:
5663 goto die;
5664 }
5665 break;
5666 case 21:
5667 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5668 switch (sel) {
5669 case 0:
5670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5671 rn = "Framemask";
5672 break;
5673 default:
5674 goto die;
5675 }
5676 break;
5677 case 22:
5678 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5679 rn = "'Diagnostic"; /* implementation dependent */
5680 break;
5681 case 23:
5682 switch (sel) {
5683 case 0:
5684 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5685 rn = "Debug";
5686 break;
5687 case 1:
5688 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5689 rn = "TraceControl";
5690 // break;
5691 case 2:
5692 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5693 rn = "TraceControl2";
5694 // break;
5695 case 3:
5696 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5697 rn = "UserTraceData";
5698 // break;
5699 case 4:
5700 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5701 rn = "TraceBPC";
5702 // break;
5703 default:
5704 goto die;
5705 }
5706 break;
5707 case 24:
5708 switch (sel) {
5709 case 0:
5710 /* EJTAG support */
5711 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5712 rn = "DEPC";
5713 break;
5714 default:
5715 goto die;
5716 }
5717 break;
5718 case 25:
5719 switch (sel) {
5720 case 0:
5721 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5722 rn = "Performance0";
5723 break;
5724 case 1:
5725 // gen_helper_dmfc0_performance1(arg);
5726 rn = "Performance1";
5727 // break;
5728 case 2:
5729 // gen_helper_dmfc0_performance2(arg);
5730 rn = "Performance2";
5731 // break;
5732 case 3:
5733 // gen_helper_dmfc0_performance3(arg);
5734 rn = "Performance3";
5735 // break;
5736 case 4:
5737 // gen_helper_dmfc0_performance4(arg);
5738 rn = "Performance4";
5739 // break;
5740 case 5:
5741 // gen_helper_dmfc0_performance5(arg);
5742 rn = "Performance5";
5743 // break;
5744 case 6:
5745 // gen_helper_dmfc0_performance6(arg);
5746 rn = "Performance6";
5747 // break;
5748 case 7:
5749 // gen_helper_dmfc0_performance7(arg);
5750 rn = "Performance7";
5751 // break;
5752 default:
5753 goto die;
5754 }
5755 break;
5756 case 26:
5757 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5758 rn = "ECC";
5759 break;
5760 case 27:
5761 switch (sel) {
5762 /* ignored */
5763 case 0 ... 3:
5764 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5765 rn = "CacheErr";
5766 break;
5767 default:
5768 goto die;
5769 }
5770 break;
5771 case 28:
5772 switch (sel) {
5773 case 0:
5774 case 2:
5775 case 4:
5776 case 6:
5777 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5778 rn = "TagLo";
5779 break;
5780 case 1:
5781 case 3:
5782 case 5:
5783 case 7:
5784 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5785 rn = "DataLo";
5786 break;
5787 default:
5788 goto die;
5789 }
5790 break;
5791 case 29:
5792 switch (sel) {
5793 case 0:
5794 case 2:
5795 case 4:
5796 case 6:
5797 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5798 rn = "TagHi";
5799 break;
5800 case 1:
5801 case 3:
5802 case 5:
5803 case 7:
5804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5805 rn = "DataHi";
5806 break;
5807 default:
5808 goto die;
5809 }
5810 break;
5811 case 30:
5812 switch (sel) {
5813 case 0:
5814 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5815 rn = "ErrorEPC";
5816 break;
5817 default:
5818 goto die;
5819 }
5820 break;
5821 case 31:
5822 switch (sel) {
5823 case 0:
5824 /* EJTAG support */
5825 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5826 rn = "DESAVE";
5827 break;
5828 default:
5829 goto die;
5830 }
5831 break;
5832 default:
5833 goto die;
5834 }
5835 (void)rn; /* avoid a compiler warning */
5836 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5837 return;
5838
5839 die:
5840 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5841 generate_exception(ctx, EXCP_RI);
5842 }
5843
5844 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5845 {
5846 const char *rn = "invalid";
5847
5848 if (sel != 0)
5849 check_insn(env, ctx, ISA_MIPS64);
5850
5851 if (use_icount)
5852 gen_io_start();
5853
5854 switch (reg) {
5855 case 0:
5856 switch (sel) {
5857 case 0:
5858 gen_helper_mtc0_index(cpu_env, arg);
5859 rn = "Index";
5860 break;
5861 case 1:
5862 check_insn(env, ctx, ASE_MT);
5863 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5864 rn = "MVPControl";
5865 break;
5866 case 2:
5867 check_insn(env, ctx, ASE_MT);
5868 /* ignored */
5869 rn = "MVPConf0";
5870 break;
5871 case 3:
5872 check_insn(env, ctx, ASE_MT);
5873 /* ignored */
5874 rn = "MVPConf1";
5875 break;
5876 default:
5877 goto die;
5878 }
5879 break;
5880 case 1:
5881 switch (sel) {
5882 case 0:
5883 /* ignored */
5884 rn = "Random";
5885 break;
5886 case 1:
5887 check_insn(env, ctx, ASE_MT);
5888 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5889 rn = "VPEControl";
5890 break;
5891 case 2:
5892 check_insn(env, ctx, ASE_MT);
5893 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5894 rn = "VPEConf0";
5895 break;
5896 case 3:
5897 check_insn(env, ctx, ASE_MT);
5898 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5899 rn = "VPEConf1";
5900 break;
5901 case 4:
5902 check_insn(env, ctx, ASE_MT);
5903 gen_helper_mtc0_yqmask(cpu_env, arg);
5904 rn = "YQMask";
5905 break;
5906 case 5:
5907 check_insn(env, ctx, ASE_MT);
5908 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5909 rn = "VPESchedule";
5910 break;
5911 case 6:
5912 check_insn(env, ctx, ASE_MT);
5913 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5914 rn = "VPEScheFBack";
5915 break;
5916 case 7:
5917 check_insn(env, ctx, ASE_MT);
5918 gen_helper_mtc0_vpeopt(cpu_env, arg);
5919 rn = "VPEOpt";
5920 break;
5921 default:
5922 goto die;
5923 }
5924 break;
5925 case 2:
5926 switch (sel) {
5927 case 0:
5928 gen_helper_mtc0_entrylo0(cpu_env, arg);
5929 rn = "EntryLo0";
5930 break;
5931 case 1:
5932 check_insn(env, ctx, ASE_MT);
5933 gen_helper_mtc0_tcstatus(cpu_env, arg);
5934 rn = "TCStatus";
5935 break;
5936 case 2:
5937 check_insn(env, ctx, ASE_MT);
5938 gen_helper_mtc0_tcbind(cpu_env, arg);
5939 rn = "TCBind";
5940 break;
5941 case 3:
5942 check_insn(env, ctx, ASE_MT);
5943 gen_helper_mtc0_tcrestart(cpu_env, arg);
5944 rn = "TCRestart";
5945 break;
5946 case 4:
5947 check_insn(env, ctx, ASE_MT);
5948 gen_helper_mtc0_tchalt(cpu_env, arg);
5949 rn = "TCHalt";
5950 break;
5951 case 5:
5952 check_insn(env, ctx, ASE_MT);
5953 gen_helper_mtc0_tccontext(cpu_env, arg);
5954 rn = "TCContext";
5955 break;
5956 case 6:
5957 check_insn(env, ctx, ASE_MT);
5958 gen_helper_mtc0_tcschedule(cpu_env, arg);
5959 rn = "TCSchedule";
5960 break;
5961 case 7:
5962 check_insn(env, ctx, ASE_MT);
5963 gen_helper_mtc0_tcschefback(cpu_env, arg);
5964 rn = "TCScheFBack";
5965 break;
5966 default:
5967 goto die;
5968 }
5969 break;
5970 case 3:
5971 switch (sel) {
5972 case 0:
5973 gen_helper_mtc0_entrylo1(cpu_env, arg);
5974 rn = "EntryLo1";
5975 break;
5976 default:
5977 goto die;
5978 }
5979 break;
5980 case 4:
5981 switch (sel) {
5982 case 0:
5983 gen_helper_mtc0_context(cpu_env, arg);
5984 rn = "Context";
5985 break;
5986 case 1:
5987 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5988 rn = "ContextConfig";
5989 // break;
5990 default:
5991 goto die;
5992 }
5993 break;
5994 case 5:
5995 switch (sel) {
5996 case 0:
5997 gen_helper_mtc0_pagemask(cpu_env, arg);
5998 rn = "PageMask";
5999 break;
6000 case 1:
6001 check_insn(env, ctx, ISA_MIPS32R2);
6002 gen_helper_mtc0_pagegrain(cpu_env, arg);
6003 rn = "PageGrain";
6004 break;
6005 default:
6006 goto die;
6007 }
6008 break;
6009 case 6:
6010 switch (sel) {
6011 case 0:
6012 gen_helper_mtc0_wired(cpu_env, arg);
6013 rn = "Wired";
6014 break;
6015 case 1:
6016 check_insn(env, ctx, ISA_MIPS32R2);
6017 gen_helper_mtc0_srsconf0(cpu_env, arg);
6018 rn = "SRSConf0";
6019 break;
6020 case 2:
6021 check_insn(env, ctx, ISA_MIPS32R2);
6022 gen_helper_mtc0_srsconf1(cpu_env, arg);
6023 rn = "SRSConf1";
6024 break;
6025 case 3:
6026 check_insn(env, ctx, ISA_MIPS32R2);
6027 gen_helper_mtc0_srsconf2(cpu_env, arg);
6028 rn = "SRSConf2";
6029 break;
6030 case 4:
6031 check_insn(env, ctx, ISA_MIPS32R2);
6032 gen_helper_mtc0_srsconf3(cpu_env, arg);
6033 rn = "SRSConf3";
6034 break;
6035 case 5:
6036 check_insn(env, ctx, ISA_MIPS32R2);
6037 gen_helper_mtc0_srsconf4(cpu_env, arg);
6038 rn = "SRSConf4";
6039 break;
6040 default:
6041 goto die;
6042 }
6043 break;
6044 case 7:
6045 switch (sel) {
6046 case 0:
6047 check_insn(env, ctx, ISA_MIPS32R2);
6048 gen_helper_mtc0_hwrena(cpu_env, arg);
6049 rn = "HWREna";
6050 break;
6051 default:
6052 goto die;
6053 }
6054 break;
6055 case 8:
6056 /* ignored */
6057 rn = "BadVAddr";
6058 break;
6059 case 9:
6060 switch (sel) {
6061 case 0:
6062 gen_helper_mtc0_count(cpu_env, arg);
6063 rn = "Count";
6064 break;
6065 /* 6,7 are implementation dependent */
6066 default:
6067 goto die;
6068 }
6069 /* Stop translation as we may have switched the execution mode */
6070 ctx->bstate = BS_STOP;
6071 break;
6072 case 10:
6073 switch (sel) {
6074 case 0:
6075 gen_helper_mtc0_entryhi(cpu_env, arg);
6076 rn = "EntryHi";
6077 break;
6078 default:
6079 goto die;
6080 }
6081 break;
6082 case 11:
6083 switch (sel) {
6084 case 0:
6085 gen_helper_mtc0_compare(cpu_env, arg);
6086 rn = "Compare";
6087 break;
6088 /* 6,7 are implementation dependent */
6089 default:
6090 goto die;
6091 }
6092 /* Stop translation as we may have switched the execution mode */
6093 ctx->bstate = BS_STOP;
6094 break;
6095 case 12:
6096 switch (sel) {
6097 case 0:
6098 save_cpu_state(ctx, 1);
6099 gen_helper_mtc0_status(cpu_env, arg);
6100 /* BS_STOP isn't good enough here, hflags may have changed. */
6101 gen_save_pc(ctx->pc + 4);
6102 ctx->bstate = BS_EXCP;
6103 rn = "Status";
6104 break;
6105 case 1:
6106 check_insn(env, ctx, ISA_MIPS32R2);
6107 gen_helper_mtc0_intctl(cpu_env, arg);
6108 /* Stop translation as we may have switched the execution mode */
6109 ctx->bstate = BS_STOP;
6110 rn = "IntCtl";
6111 break;
6112 case 2:
6113 check_insn(env, ctx, ISA_MIPS32R2);
6114 gen_helper_mtc0_srsctl(cpu_env, arg);
6115 /* Stop translation as we may have switched the execution mode */
6116 ctx->bstate = BS_STOP;
6117 rn = "SRSCtl";
6118 break;
6119 case 3:
6120 check_insn(env, ctx, ISA_MIPS32R2);
6121 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6122 /* Stop translation as we may have switched the execution mode */
6123 ctx->bstate = BS_STOP;
6124 rn = "SRSMap";
6125 break;
6126 default:
6127 goto die;
6128 }
6129 break;
6130 case 13:
6131 switch (sel) {
6132 case 0:
6133 save_cpu_state(ctx, 1);
6134 /* Mark as an IO operation because we may trigger a software
6135 interrupt. */
6136 if (use_icount) {
6137 gen_io_start();
6138 }
6139 gen_helper_mtc0_cause(cpu_env, arg);
6140 if (use_icount) {
6141 gen_io_end();
6142 }
6143 /* Stop translation as we may have triggered an intetrupt */
6144 ctx->bstate = BS_STOP;
6145 rn = "Cause";
6146 break;
6147 default:
6148 goto die;
6149 }
6150 break;
6151 case 14:
6152 switch (sel) {
6153 case 0:
6154 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6155 rn = "EPC";
6156 break;
6157 default:
6158 goto die;
6159 }
6160 break;
6161 case 15:
6162 switch (sel) {
6163 case 0:
6164 /* ignored */
6165 rn = "PRid";
6166 break;
6167 case 1:
6168 check_insn(env, ctx, ISA_MIPS32R2);
6169 gen_helper_mtc0_ebase(cpu_env, arg);
6170 rn = "EBase";
6171 break;
6172 default:
6173 goto die;
6174 }
6175 break;
6176 case 16:
6177 switch (sel) {
6178 case 0:
6179 gen_helper_mtc0_config0(cpu_env, arg);
6180 rn = "Config";
6181 /* Stop translation as we may have switched the execution mode */
6182 ctx->bstate = BS_STOP;
6183 break;
6184 case 1:
6185 /* ignored, read only */
6186 rn = "Config1";
6187 break;
6188 case 2:
6189 gen_helper_mtc0_config2(cpu_env, arg);
6190 rn = "Config2";
6191 /* Stop translation as we may have switched the execution mode */
6192 ctx->bstate = BS_STOP;
6193 break;
6194 case 3:
6195 /* ignored */
6196 rn = "Config3";
6197 break;
6198 /* 6,7 are implementation dependent */
6199 default:
6200 rn = "Invalid config selector";
6201 goto die;
6202 }
6203 break;
6204 case 17:
6205 switch (sel) {
6206 case 0:
6207 gen_helper_mtc0_lladdr(cpu_env, arg);
6208 rn = "LLAddr";
6209 break;
6210 default:
6211 goto die;
6212 }
6213 break;
6214 case 18:
6215 switch (sel) {
6216 case 0 ... 7:
6217 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6218 rn = "WatchLo";
6219 break;
6220 default:
6221 goto die;
6222 }
6223 break;
6224 case 19:
6225 switch (sel) {
6226 case 0 ... 7:
6227 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6228 rn = "WatchHi";
6229 break;
6230 default:
6231 goto die;
6232 }
6233 break;
6234 case 20:
6235 switch (sel) {
6236 case 0:
6237 check_insn(env, ctx, ISA_MIPS3);
6238 gen_helper_mtc0_xcontext(cpu_env, arg);
6239 rn = "XContext";
6240 break;
6241 default:
6242 goto die;
6243 }
6244 break;
6245 case 21:
6246 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6247 switch (sel) {
6248 case 0:
6249 gen_helper_mtc0_framemask(cpu_env, arg);
6250 rn = "Framemask";
6251 break;
6252 default:
6253 goto die;
6254 }
6255 break;
6256 case 22:
6257 /* ignored */
6258 rn = "Diagnostic"; /* implementation dependent */
6259 break;
6260 case 23:
6261 switch (sel) {
6262 case 0:
6263 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6264 /* BS_STOP isn't good enough here, hflags may have changed. */
6265 gen_save_pc(ctx->pc + 4);
6266 ctx->bstate = BS_EXCP;
6267 rn = "Debug";
6268 break;
6269 case 1:
6270 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6271 /* Stop translation as we may have switched the execution mode */
6272 ctx->bstate = BS_STOP;
6273 rn = "TraceControl";
6274 // break;
6275 case 2:
6276 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6277 /* Stop translation as we may have switched the execution mode */
6278 ctx->bstate = BS_STOP;
6279 rn = "TraceControl2";
6280 // break;
6281 case 3:
6282 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6283 /* Stop translation as we may have switched the execution mode */
6284 ctx->bstate = BS_STOP;
6285 rn = "UserTraceData";
6286 // break;
6287 case 4:
6288 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6289 /* Stop translation as we may have switched the execution mode */
6290 ctx->bstate = BS_STOP;
6291 rn = "TraceBPC";
6292 // break;
6293 default:
6294 goto die;
6295 }
6296 break;
6297 case 24:
6298 switch (sel) {
6299 case 0:
6300 /* EJTAG support */
6301 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6302 rn = "DEPC";
6303 break;
6304 default:
6305 goto die;
6306 }
6307 break;
6308 case 25:
6309 switch (sel) {
6310 case 0:
6311 gen_helper_mtc0_performance0(cpu_env, arg);
6312 rn = "Performance0";
6313 break;
6314 case 1:
6315 // gen_helper_mtc0_performance1(cpu_env, arg);
6316 rn = "Performance1";
6317 // break;
6318 case 2:
6319 // gen_helper_mtc0_performance2(cpu_env, arg);
6320 rn = "Performance2";
6321 // break;
6322 case 3:
6323 // gen_helper_mtc0_performance3(cpu_env, arg);
6324 rn = "Performance3";
6325 // break;
6326 case 4:
6327 // gen_helper_mtc0_performance4(cpu_env, arg);
6328 rn = "Performance4";
6329 // break;
6330 case 5:
6331 // gen_helper_mtc0_performance5(cpu_env, arg);
6332 rn = "Performance5";
6333 // break;
6334 case 6:
6335 // gen_helper_mtc0_performance6(cpu_env, arg);
6336 rn = "Performance6";
6337 // break;
6338 case 7:
6339 // gen_helper_mtc0_performance7(cpu_env, arg);
6340 rn = "Performance7";
6341 // break;
6342 default:
6343 goto die;
6344 }
6345 break;
6346 case 26:
6347 /* ignored */
6348 rn = "ECC";
6349 break;
6350 case 27:
6351 switch (sel) {
6352 case 0 ... 3:
6353 /* ignored */
6354 rn = "CacheErr";
6355 break;
6356 default:
6357 goto die;
6358 }
6359 break;
6360 case 28:
6361 switch (sel) {
6362 case 0:
6363 case 2:
6364 case 4:
6365 case 6:
6366 gen_helper_mtc0_taglo(cpu_env, arg);
6367 rn = "TagLo";
6368 break;
6369 case 1:
6370 case 3:
6371 case 5:
6372 case 7:
6373 gen_helper_mtc0_datalo(cpu_env, arg);
6374 rn = "DataLo";
6375 break;
6376 default:
6377 goto die;
6378 }
6379 break;
6380 case 29:
6381 switch (sel) {
6382 case 0:
6383 case 2:
6384 case 4:
6385 case 6:
6386 gen_helper_mtc0_taghi(cpu_env, arg);
6387 rn = "TagHi";
6388 break;
6389 case 1:
6390 case 3:
6391 case 5:
6392 case 7:
6393 gen_helper_mtc0_datahi(cpu_env, arg);
6394 rn = "DataHi";
6395 break;
6396 default:
6397 rn = "invalid sel";
6398 goto die;
6399 }
6400 break;
6401 case 30:
6402 switch (sel) {
6403 case 0:
6404 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6405 rn = "ErrorEPC";
6406 break;
6407 default:
6408 goto die;
6409 }
6410 break;
6411 case 31:
6412 switch (sel) {
6413 case 0:
6414 /* EJTAG support */
6415 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6416 rn = "DESAVE";
6417 break;
6418 default:
6419 goto die;
6420 }
6421 /* Stop translation as we may have switched the execution mode */
6422 ctx->bstate = BS_STOP;
6423 break;
6424 default:
6425 goto die;
6426 }
6427 (void)rn; /* avoid a compiler warning */
6428 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6429 /* For simplicity assume that all writes can cause interrupts. */
6430 if (use_icount) {
6431 gen_io_end();
6432 ctx->bstate = BS_STOP;
6433 }
6434 return;
6435
6436 die:
6437 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6438 generate_exception(ctx, EXCP_RI);
6439 }
6440 #endif /* TARGET_MIPS64 */
6441
6442 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6443 int u, int sel, int h)
6444 {
6445 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6446 TCGv t0 = tcg_temp_local_new();
6447
6448 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6449 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6450 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6451 tcg_gen_movi_tl(t0, -1);
6452 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6453 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6454 tcg_gen_movi_tl(t0, -1);
6455 else if (u == 0) {
6456 switch (rt) {
6457 case 1:
6458 switch (sel) {
6459 case 1:
6460 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6461 break;
6462 case 2:
6463 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6464 break;
6465 default:
6466 goto die;
6467 break;
6468 }
6469 break;
6470 case 2:
6471 switch (sel) {
6472 case 1:
6473 gen_helper_mftc0_tcstatus(t0, cpu_env);
6474 break;
6475 case 2:
6476 gen_helper_mftc0_tcbind(t0, cpu_env);
6477 break;
6478 case 3:
6479 gen_helper_mftc0_tcrestart(t0, cpu_env);
6480 break;
6481 case 4:
6482 gen_helper_mftc0_tchalt(t0, cpu_env);
6483 break;
6484 case 5:
6485 gen_helper_mftc0_tccontext(t0, cpu_env);
6486 break;
6487 case 6:
6488 gen_helper_mftc0_tcschedule(t0, cpu_env);
6489 break;
6490 case 7:
6491 gen_helper_mftc0_tcschefback(t0, cpu_env);
6492 break;
6493 default:
6494 gen_mfc0(env, ctx, t0, rt, sel);
6495 break;
6496 }
6497 break;
6498 case 10:
6499 switch (sel) {
6500 case 0:
6501 gen_helper_mftc0_entryhi(t0, cpu_env);
6502 break;
6503 default:
6504 gen_mfc0(env, ctx, t0, rt, sel);
6505 break;
6506 }
6507 case 12:
6508 switch (sel) {
6509 case 0:
6510 gen_helper_mftc0_status(t0, cpu_env);
6511 break;
6512 default:
6513 gen_mfc0(env, ctx, t0, rt, sel);
6514 break;
6515 }
6516 case 13:
6517 switch (sel) {
6518 case 0:
6519 gen_helper_mftc0_cause(t0, cpu_env);
6520 break;
6521 default:
6522 goto die;
6523 break;
6524 }
6525 break;
6526 case 14:
6527 switch (sel) {
6528 case 0:
6529 gen_helper_mftc0_epc(t0, cpu_env);
6530 break;
6531 default:
6532 goto die;
6533 break;
6534 }
6535 break;
6536 case 15:
6537 switch (sel) {
6538 case 1:
6539 gen_helper_mftc0_ebase(t0, cpu_env);
6540 break;
6541 default:
6542 goto die;
6543 break;
6544 }
6545 break;
6546 case 16:
6547 switch (sel) {
6548 case 0 ... 7:
6549 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6550 break;
6551 default:
6552 goto die;
6553 break;
6554 }
6555 break;
6556 case 23:
6557 switch (sel) {
6558 case 0:
6559 gen_helper_mftc0_debug(t0, cpu_env);
6560 break;
6561 default:
6562 gen_mfc0(env, ctx, t0, rt, sel);
6563 break;
6564 }
6565 break;
6566 default:
6567 gen_mfc0(env, ctx, t0, rt, sel);
6568 }
6569 } else switch (sel) {
6570 /* GPR registers. */
6571 case 0:
6572 gen_helper_1e0i(mftgpr, t0, rt);
6573 break;
6574 /* Auxiliary CPU registers */
6575 case 1:
6576 switch (rt) {
6577 case 0:
6578 gen_helper_1e0i(mftlo, t0, 0);
6579 break;
6580 case 1:
6581 gen_helper_1e0i(mfthi, t0, 0);
6582 break;
6583 case 2:
6584 gen_helper_1e0i(mftacx, t0, 0);
6585 break;
6586 case 4:
6587 gen_helper_1e0i(mftlo, t0, 1);
6588 break;
6589 case 5:
6590 gen_helper_1e0i(mfthi, t0, 1);
6591 break;
6592 case 6:
6593 gen_helper_1e0i(mftacx, t0, 1);
6594 break;
6595 case 8:
6596 gen_helper_1e0i(mftlo, t0, 2);
6597 break;
6598 case 9:
6599 gen_helper_1e0i(mfthi, t0, 2);
6600 break;
6601 case 10:
6602 gen_helper_1e0i(mftacx, t0, 2);
6603 break;
6604 case 12:
6605 gen_helper_1e0i(mftlo, t0, 3);
6606 break;
6607 case 13:
6608 gen_helper_1e0i(mfthi, t0, 3);
6609 break;
6610 case 14:
6611 gen_helper_1e0i(mftacx, t0, 3);
6612 break;
6613 case 16:
6614 gen_helper_mftdsp(t0, cpu_env);
6615 break;
6616 default:
6617 goto die;
6618 }
6619 break;
6620 /* Floating point (COP1). */
6621 case 2:
6622 /* XXX: For now we support only a single FPU context. */
6623 if (h == 0) {
6624 TCGv_i32 fp0 = tcg_temp_new_i32();
6625
6626 gen_load_fpr32(fp0, rt);
6627 tcg_gen_ext_i32_tl(t0, fp0);
6628 tcg_temp_free_i32(fp0);
6629 } else {
6630 TCGv_i32 fp0 = tcg_temp_new_i32();
6631
6632 gen_load_fpr32h(fp0, rt);
6633 tcg_gen_ext_i32_tl(t0, fp0);
6634 tcg_temp_free_i32(fp0);
6635 }
6636 break;
6637 case 3:
6638 /* XXX: For now we support only a single FPU context. */
6639 gen_helper_1e0i(cfc1, t0, rt);
6640 break;
6641 /* COP2: Not implemented. */
6642 case 4:
6643 case 5:
6644 /* fall through */
6645 default:
6646 goto die;
6647 }
6648 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6649 gen_store_gpr(t0, rd);
6650 tcg_temp_free(t0);
6651 return;
6652
6653 die:
6654 tcg_temp_free(t0);
6655 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6656 generate_exception(ctx, EXCP_RI);
6657 }
6658
6659 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6660 int u, int sel, int h)
6661 {
6662 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6663 TCGv t0 = tcg_temp_local_new();
6664
6665 gen_load_gpr(t0, rt);
6666 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6667 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6668 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6669 /* NOP */ ;
6670 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6671 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6672 /* NOP */ ;
6673 else if (u == 0) {
6674 switch (rd) {
6675 case 1:
6676 switch (sel) {
6677 case 1:
6678 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6679 break;
6680 case 2:
6681 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6682 break;
6683 default:
6684 goto die;
6685 break;
6686 }
6687 break;
6688 case 2:
6689 switch (sel) {
6690 case 1:
6691 gen_helper_mttc0_tcstatus(cpu_env, t0);
6692 break;
6693 case 2:
6694 gen_helper_mttc0_tcbind(cpu_env, t0);
6695 break;
6696 case 3:
6697 gen_helper_mttc0_tcrestart(cpu_env, t0);
6698 break;
6699 case 4:
6700 gen_helper_mttc0_tchalt(cpu_env, t0);
6701 break;
6702 case 5:
6703 gen_helper_mttc0_tccontext(cpu_env, t0);
6704 break;
6705 case 6:
6706 gen_helper_mttc0_tcschedule(cpu_env, t0);
6707 break;
6708 case 7:
6709 gen_helper_mttc0_tcschefback(cpu_env, t0);
6710 break;
6711 default:
6712 gen_mtc0(env, ctx, t0, rd, sel);
6713 break;
6714 }
6715 break;
6716 case 10:
6717 switch (sel) {
6718 case 0:
6719 gen_helper_mttc0_entryhi(cpu_env, t0);
6720 break;
6721 default:
6722 gen_mtc0(env, ctx, t0, rd, sel);
6723 break;
6724 }
6725 case 12:
6726 switch (sel) {
6727 case 0:
6728 gen_helper_mttc0_status(cpu_env, t0);
6729 break;
6730 default:
6731 gen_mtc0(env, ctx, t0, rd, sel);
6732 break;
6733 }
6734 case 13:
6735 switch (sel) {
6736 case 0:
6737 gen_helper_mttc0_cause(cpu_env, t0);
6738 break;
6739 default:
6740 goto die;
6741 break;
6742 }
6743 break;
6744 case 15:
6745 switch (sel) {
6746 case 1:
6747 gen_helper_mttc0_ebase(cpu_env, t0);
6748 break;
6749 default:
6750 goto die;
6751 break;
6752 }
6753 break;
6754 case 23:
6755 switch (sel) {
6756 case 0:
6757 gen_helper_mttc0_debug(cpu_env, t0);
6758 break;
6759 default:
6760 gen_mtc0(env, ctx, t0, rd, sel);
6761 break;
6762 }
6763 break;
6764 default:
6765 gen_mtc0(env, ctx, t0, rd, sel);
6766 }
6767 } else switch (sel) {
6768 /* GPR registers. */
6769 case 0:
6770 gen_helper_0e1i(mttgpr, t0, rd);
6771 break;
6772 /* Auxiliary CPU registers */
6773 case 1:
6774 switch (rd) {
6775 case 0:
6776 gen_helper_0e1i(mttlo, t0, 0);
6777 break;
6778 case 1:
6779 gen_helper_0e1i(mtthi, t0, 0);
6780 break;
6781 case 2:
6782 gen_helper_0e1i(mttacx, t0, 0);
6783 break;
6784 case 4:
6785 gen_helper_0e1i(mttlo, t0, 1);
6786 break;
6787 case 5:
6788 gen_helper_0e1i(mtthi, t0, 1);
6789 break;
6790 case 6:
6791 gen_helper_0e1i(mttacx, t0, 1);
6792 break;
6793 case 8:
6794 gen_helper_0e1i(mttlo, t0, 2);
6795 break;
6796 case 9:
6797 gen_helper_0e1i(mtthi, t0, 2);
6798 break;
6799 case 10:
6800 gen_helper_0e1i(mttacx, t0, 2);
6801 break;
6802 case 12:
6803 gen_helper_0e1i(mttlo, t0, 3);
6804 break;
6805 case 13:
6806 gen_helper_0e1i(mtthi, t0, 3);
6807 break;
6808 case 14:
6809 gen_helper_0e1i(mttacx, t0, 3);
6810 break;
6811 case 16:
6812 gen_helper_mttdsp(cpu_env, t0);
6813 break;
6814 default:
6815 goto die;
6816 }
6817 break;
6818 /* Floating point (COP1). */
6819 case 2:
6820 /* XXX: For now we support only a single FPU context. */
6821 if (h == 0) {
6822 TCGv_i32 fp0 = tcg_temp_new_i32();
6823
6824 tcg_gen_trunc_tl_i32(fp0, t0);
6825 gen_store_fpr32(fp0, rd);
6826 tcg_temp_free_i32(fp0);
6827 } else {
6828 TCGv_i32 fp0 = tcg_temp_new_i32();
6829
6830 tcg_gen_trunc_tl_i32(fp0, t0);
6831 gen_store_fpr32h(fp0, rd);
6832 tcg_temp_free_i32(fp0);
6833 }
6834 break;
6835 case 3:
6836 /* XXX: For now we support only a single FPU context. */
6837 gen_helper_0e1i(ctc1, t0, rd);
6838 break;
6839 /* COP2: Not implemented. */
6840 case 4:
6841 case 5:
6842 /* fall through */
6843 default:
6844 goto die;
6845 }
6846 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6847 tcg_temp_free(t0);
6848 return;
6849
6850 die:
6851 tcg_temp_free(t0);
6852 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6853 generate_exception(ctx, EXCP_RI);
6854 }
6855
6856 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6857 {
6858 const char *opn = "ldst";
6859
6860 check_cp0_enabled(ctx);
6861 switch (opc) {
6862 case OPC_MFC0:
6863 if (rt == 0) {
6864 /* Treat as NOP. */
6865 return;
6866 }
6867 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6868 opn = "mfc0";
6869 break;
6870 case OPC_MTC0:
6871 {
6872 TCGv t0 = tcg_temp_new();
6873
6874 gen_load_gpr(t0, rt);
6875 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6876 tcg_temp_free(t0);
6877 }
6878 opn = "mtc0";
6879 break;
6880 #if defined(TARGET_MIPS64)
6881 case OPC_DMFC0:
6882 check_insn(env, ctx, ISA_MIPS3);
6883 if (rt == 0) {
6884 /* Treat as NOP. */
6885 return;
6886 }
6887 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6888 opn = "dmfc0";
6889 break;
6890 case OPC_DMTC0:
6891 check_insn(env, ctx, ISA_MIPS3);
6892 {
6893 TCGv t0 = tcg_temp_new();
6894
6895 gen_load_gpr(t0, rt);
6896 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6897 tcg_temp_free(t0);
6898 }
6899 opn = "dmtc0";
6900 break;
6901 #endif
6902 case OPC_MFTR:
6903 check_insn(env, ctx, ASE_MT);
6904 if (rd == 0) {
6905 /* Treat as NOP. */
6906 return;
6907 }
6908 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6909 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6910 opn = "mftr";
6911 break;
6912 case OPC_MTTR:
6913 check_insn(env, ctx, ASE_MT);
6914 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6915 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6916 opn = "mttr";
6917 break;
6918 case OPC_TLBWI:
6919 opn = "tlbwi";
6920 if (!env->tlb->helper_tlbwi)
6921 goto die;
6922 gen_helper_tlbwi(cpu_env);
6923 break;
6924 case OPC_TLBWR:
6925 opn = "tlbwr";
6926 if (!env->tlb->helper_tlbwr)
6927 goto die;
6928 gen_helper_tlbwr(cpu_env);
6929 break;
6930 case OPC_TLBP:
6931 opn = "tlbp";
6932 if (!env->tlb->helper_tlbp)
6933 goto die;
6934 gen_helper_tlbp(cpu_env);
6935 break;
6936 case OPC_TLBR:
6937 opn = "tlbr";
6938 if (!env->tlb->helper_tlbr)
6939 goto die;
6940 gen_helper_tlbr(cpu_env);
6941 break;
6942 case OPC_ERET:
6943 opn = "eret";
6944 check_insn(env, ctx, ISA_MIPS2);
6945 gen_helper_eret(cpu_env);
6946 ctx->bstate = BS_EXCP;
6947 break;
6948 case OPC_DERET:
6949 opn = "deret";
6950 check_insn(env, ctx, ISA_MIPS32);
6951 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6952 MIPS_INVAL(opn);
6953 generate_exception(ctx, EXCP_RI);
6954 } else {
6955 gen_helper_deret(cpu_env);
6956 ctx->bstate = BS_EXCP;
6957 }
6958 break;
6959 case OPC_WAIT:
6960 opn = "wait";
6961 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6962 /* If we get an exception, we want to restart at next instruction */
6963 ctx->pc += 4;
6964 save_cpu_state(ctx, 1);
6965 ctx->pc -= 4;
6966 gen_helper_wait(cpu_env);
6967 ctx->bstate = BS_EXCP;
6968 break;
6969 default:
6970 die:
6971 MIPS_INVAL(opn);
6972 generate_exception(ctx, EXCP_RI);
6973 return;
6974 }
6975 (void)opn; /* avoid a compiler warning */
6976 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6977 }
6978 #endif /* !CONFIG_USER_ONLY */
6979
6980 /* CP1 Branches (before delay slot) */
6981 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
6982 int32_t cc, int32_t offset)
6983 {
6984 target_ulong btarget;
6985 const char *opn = "cp1 cond branch";
6986 TCGv_i32 t0 = tcg_temp_new_i32();
6987
6988 if (cc != 0)
6989 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6990
6991 btarget = ctx->pc + 4 + offset;
6992
6993 switch (op) {
6994 case OPC_BC1F:
6995 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6996 tcg_gen_not_i32(t0, t0);
6997 tcg_gen_andi_i32(t0, t0, 1);
6998 tcg_gen_extu_i32_tl(bcond, t0);
6999 opn = "bc1f";
7000 goto not_likely;
7001 case OPC_BC1FL:
7002 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7003 tcg_gen_not_i32(t0, t0);
7004 tcg_gen_andi_i32(t0, t0, 1);
7005 tcg_gen_extu_i32_tl(bcond, t0);
7006 opn = "bc1fl";
7007 goto likely;
7008 case OPC_BC1T:
7009 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7010 tcg_gen_andi_i32(t0, t0, 1);
7011 tcg_gen_extu_i32_tl(bcond, t0);
7012 opn = "bc1t";
7013 goto not_likely;
7014 case OPC_BC1TL:
7015 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7016 tcg_gen_andi_i32(t0, t0, 1);
7017 tcg_gen_extu_i32_tl(bcond, t0);
7018 opn = "bc1tl";
7019 likely:
7020 ctx->hflags |= MIPS_HFLAG_BL;
7021 break;
7022 case OPC_BC1FANY2:
7023 {
7024 TCGv_i32 t1 = tcg_temp_new_i32();
7025 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7026 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7027 tcg_gen_nand_i32(t0, t0, t1);
7028 tcg_temp_free_i32(t1);
7029 tcg_gen_andi_i32(t0, t0, 1);
7030 tcg_gen_extu_i32_tl(bcond, t0);
7031 }
7032 opn = "bc1any2f";
7033 goto not_likely;
7034 case OPC_BC1TANY2:
7035 {
7036 TCGv_i32 t1 = tcg_temp_new_i32();
7037 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7038 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7039 tcg_gen_or_i32(t0, t0, t1);
7040 tcg_temp_free_i32(t1);
7041 tcg_gen_andi_i32(t0, t0, 1);
7042 tcg_gen_extu_i32_tl(bcond, t0);
7043 }
7044 opn = "bc1any2t";
7045 goto not_likely;
7046 case OPC_BC1FANY4:
7047 {
7048 TCGv_i32 t1 = tcg_temp_new_i32();
7049 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7050 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7051 tcg_gen_and_i32(t0, t0, t1);
7052 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7053 tcg_gen_and_i32(t0, t0, t1);
7054 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7055 tcg_gen_nand_i32(t0, t0, t1);
7056 tcg_temp_free_i32(t1);
7057 tcg_gen_andi_i32(t0, t0, 1);
7058 tcg_gen_extu_i32_tl(bcond, t0);
7059 }
7060 opn = "bc1any4f";
7061 goto not_likely;
7062 case OPC_BC1TANY4:
7063 {
7064 TCGv_i32 t1 = tcg_temp_new_i32();
7065 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7066 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7067 tcg_gen_or_i32(t0, t0, t1);
7068 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7069 tcg_gen_or_i32(t0, t0, t1);
7070 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7071 tcg_gen_or_i32(t0, t0, t1);
7072 tcg_temp_free_i32(t1);
7073 tcg_gen_andi_i32(t0, t0, 1);
7074 tcg_gen_extu_i32_tl(bcond, t0);
7075 }
7076 opn = "bc1any4t";
7077 not_likely:
7078 ctx->hflags |= MIPS_HFLAG_BC;
7079 break;
7080 default:
7081 MIPS_INVAL(opn);
7082 generate_exception (ctx, EXCP_RI);
7083 goto out;
7084 }
7085 (void)opn; /* avoid a compiler warning */
7086 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7087 ctx->hflags, btarget);
7088 ctx->btarget = btarget;
7089
7090 out:
7091 tcg_temp_free_i32(t0);
7092 }
7093
7094 /* Coprocessor 1 (FPU) */
7095
7096 #define FOP(func, fmt) (((fmt) << 21) | (func))
7097
7098 enum fopcode {
7099 OPC_ADD_S = FOP(0, FMT_S),
7100 OPC_SUB_S = FOP(1, FMT_S),
7101 OPC_MUL_S = FOP(2, FMT_S),
7102 OPC_DIV_S = FOP(3, FMT_S),
7103 OPC_SQRT_S = FOP(4, FMT_S),
7104 OPC_ABS_S = FOP(5, FMT_S),
7105 OPC_MOV_S = FOP(6, FMT_S),
7106 OPC_NEG_S = FOP(7, FMT_S),
7107 OPC_ROUND_L_S = FOP(8, FMT_S),
7108 OPC_TRUNC_L_S = FOP(9, FMT_S),
7109 OPC_CEIL_L_S = FOP(10, FMT_S),
7110 OPC_FLOOR_L_S = FOP(11, FMT_S),
7111 OPC_ROUND_W_S = FOP(12, FMT_S),
7112 OPC_TRUNC_W_S = FOP(13, FMT_S),
7113 OPC_CEIL_W_S = FOP(14, FMT_S),
7114 OPC_FLOOR_W_S = FOP(15, FMT_S),
7115 OPC_MOVCF_S = FOP(17, FMT_S),
7116 OPC_MOVZ_S = FOP(18, FMT_S),
7117 OPC_MOVN_S = FOP(19, FMT_S),
7118 OPC_RECIP_S = FOP(21, FMT_S),
7119 OPC_RSQRT_S = FOP(22, FMT_S),
7120 OPC_RECIP2_S = FOP(28, FMT_S),
7121 OPC_RECIP1_S = FOP(29, FMT_S),
7122 OPC_RSQRT1_S = FOP(30, FMT_S),
7123 OPC_RSQRT2_S = FOP(31, FMT_S),
7124 OPC_CVT_D_S = FOP(33, FMT_S),
7125 OPC_CVT_W_S = FOP(36, FMT_S),
7126 OPC_CVT_L_S = FOP(37, FMT_S),
7127 OPC_CVT_PS_S = FOP(38, FMT_S),
7128 OPC_CMP_F_S = FOP (48, FMT_S),
7129 OPC_CMP_UN_S = FOP (49, FMT_S),
7130 OPC_CMP_EQ_S = FOP (50, FMT_S),
7131 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7132 OPC_CMP_OLT_S = FOP (52, FMT_S),
7133 OPC_CMP_ULT_S = FOP (53, FMT_S),
7134 OPC_CMP_OLE_S = FOP (54, FMT_S),
7135 OPC_CMP_ULE_S = FOP (55, FMT_S),
7136 OPC_CMP_SF_S = FOP (56, FMT_S),
7137 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7138 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7139 OPC_CMP_NGL_S = FOP (59, FMT_S),
7140 OPC_CMP_LT_S = FOP (60, FMT_S),
7141 OPC_CMP_NGE_S = FOP (61, FMT_S),
7142 OPC_CMP_LE_S = FOP (62, FMT_S),
7143 OPC_CMP_NGT_S = FOP (63, FMT_S),
7144
7145 OPC_ADD_D = FOP(0, FMT_D),
7146 OPC_SUB_D = FOP(1, FMT_D),
7147 OPC_MUL_D = FOP(2, FMT_D),
7148 OPC_DIV_D = FOP(3, FMT_D),
7149 OPC_SQRT_D = FOP(4, FMT_D),
7150 OPC_ABS_D = FOP(5, FMT_D),
7151 OPC_MOV_D = FOP(6, FMT_D),
7152 OPC_NEG_D = FOP(7, FMT_D),
7153 OPC_ROUND_L_D = FOP(8, FMT_D),
7154 OPC_TRUNC_L_D = FOP(9, FMT_D),
7155 OPC_CEIL_L_D = FOP(10, FMT_D),
7156 OPC_FLOOR_L_D = FOP(11, FMT_D),
7157 OPC_ROUND_W_D = FOP(12, FMT_D),
7158 OPC_TRUNC_W_D = FOP(13, FMT_D),
7159 OPC_CEIL_W_D = FOP(14, FMT_D),
7160 OPC_FLOOR_W_D = FOP(15, FMT_D),
7161 OPC_MOVCF_D = FOP(17, FMT_D),
7162 OPC_MOVZ_D = FOP(18, FMT_D),
7163 OPC_MOVN_D = FOP(19, FMT_D),
7164 OPC_RECIP_D = FOP(21, FMT_D),
7165 OPC_RSQRT_D = FOP(22, FMT_D),
7166 OPC_RECIP2_D = FOP(28, FMT_D),
7167 OPC_RECIP1_D = FOP(29, FMT_D),
7168 OPC_RSQRT1_D = FOP(30, FMT_D),
7169 OPC_RSQRT2_D = FOP(31, FMT_D),
7170 OPC_CVT_S_D = FOP(32, FMT_D),
7171 OPC_CVT_W_D = FOP(36, FMT_D),
7172 OPC_CVT_L_D = FOP(37, FMT_D),
7173 OPC_CMP_F_D = FOP (48, FMT_D),
7174 OPC_CMP_UN_D = FOP (49, FMT_D),
7175 OPC_CMP_EQ_D = FOP (50, FMT_D),
7176 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7177 OPC_CMP_OLT_D = FOP (52, FMT_D),
7178 OPC_CMP_ULT_D = FOP (53, FMT_D),
7179 OPC_CMP_OLE_D = FOP (54, FMT_D),
7180 OPC_CMP_ULE_D = FOP (55, FMT_D),
7181 OPC_CMP_SF_D = FOP (56, FMT_D),
7182 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7183 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7184 OPC_CMP_NGL_D = FOP (59, FMT_D),
7185 OPC_CMP_LT_D = FOP (60, FMT_D),
7186 OPC_CMP_NGE_D = FOP (61, FMT_D),
7187 OPC_CMP_LE_D = FOP (62, FMT_D),
7188 OPC_CMP_NGT_D = FOP (63, FMT_D),
7189
7190 OPC_CVT_S_W = FOP(32, FMT_W),
7191 OPC_CVT_D_W = FOP(33, FMT_W),
7192 OPC_CVT_S_L = FOP(32, FMT_L),
7193 OPC_CVT_D_L = FOP(33, FMT_L),
7194 OPC_CVT_PS_PW = FOP(38, FMT_W),
7195
7196 OPC_ADD_PS = FOP(0, FMT_PS),
7197 OPC_SUB_PS = FOP(1, FMT_PS),
7198 OPC_MUL_PS = FOP(2, FMT_PS),
7199 OPC_DIV_PS = FOP(3, FMT_PS),
7200 OPC_ABS_PS = FOP(5, FMT_PS),
7201 OPC_MOV_PS = FOP(6, FMT_PS),
7202 OPC_NEG_PS = FOP(7, FMT_PS),
7203 OPC_MOVCF_PS = FOP(17, FMT_PS),
7204 OPC_MOVZ_PS = FOP(18, FMT_PS),
7205 OPC_MOVN_PS = FOP(19, FMT_PS),
7206 OPC_ADDR_PS = FOP(24, FMT_PS),
7207 OPC_MULR_PS = FOP(26, FMT_PS),
7208 OPC_RECIP2_PS = FOP(28, FMT_PS),
7209 OPC_RECIP1_PS = FOP(29, FMT_PS),
7210 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7211 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7212
7213 OPC_CVT_S_PU = FOP(32, FMT_PS),
7214 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7215 OPC_CVT_S_PL = FOP(40, FMT_PS),
7216 OPC_PLL_PS = FOP(44, FMT_PS),
7217 OPC_PLU_PS = FOP(45, FMT_PS),
7218 OPC_PUL_PS = FOP(46, FMT_PS),
7219 OPC_PUU_PS = FOP(47, FMT_PS),
7220 OPC_CMP_F_PS = FOP (48, FMT_PS),
7221 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7222 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7223 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7224 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7225 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7226 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7227 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7228 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7229 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7230 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7231 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7232 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7233 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7234 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7235 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7236 };
7237
7238 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7239 {
7240 const char *opn = "cp1 move";
7241 TCGv t0 = tcg_temp_new();
7242
7243 switch (opc) {
7244 case OPC_MFC1:
7245 {
7246 TCGv_i32 fp0 = tcg_temp_new_i32();
7247
7248 gen_load_fpr32(fp0, fs);
7249 tcg_gen_ext_i32_tl(t0, fp0);
7250 tcg_temp_free_i32(fp0);
7251 }
7252 gen_store_gpr(t0, rt);
7253 opn = "mfc1";
7254 break;
7255 case OPC_MTC1:
7256 gen_load_gpr(t0, rt);
7257 {
7258 TCGv_i32 fp0 = tcg_temp_new_i32();
7259
7260 tcg_gen_trunc_tl_i32(fp0, t0);
7261 gen_store_fpr32(fp0, fs);
7262 tcg_temp_free_i32(fp0);
7263 }
7264 opn = "mtc1";
7265 break;
7266 case OPC_CFC1:
7267 gen_helper_1e0i(cfc1, t0, fs);
7268 gen_store_gpr(t0, rt);
7269 opn = "cfc1";
7270 break;
7271 case OPC_CTC1:
7272 gen_load_gpr(t0, rt);
7273 gen_helper_0e1i(ctc1, t0, fs);
7274 opn = "ctc1";
7275 break;
7276 #if defined(TARGET_MIPS64)
7277 case OPC_DMFC1:
7278 gen_load_fpr64(ctx, t0, fs);
7279 gen_store_gpr(t0, rt);
7280 opn = "dmfc1";
7281 break;
7282 case OPC_DMTC1:
7283 gen_load_gpr(t0, rt);
7284 gen_store_fpr64(ctx, t0, fs);
7285 opn = "dmtc1";
7286 break;
7287 #endif
7288 case OPC_MFHC1:
7289 {
7290 TCGv_i32 fp0 = tcg_temp_new_i32();
7291
7292 gen_load_fpr32h(fp0, fs);
7293 tcg_gen_ext_i32_tl(t0, fp0);
7294 tcg_temp_free_i32(fp0);
7295 }
7296 gen_store_gpr(t0, rt);
7297 opn = "mfhc1";
7298 break;
7299 case OPC_MTHC1:
7300 gen_load_gpr(t0, rt);
7301 {
7302 TCGv_i32 fp0 = tcg_temp_new_i32();
7303
7304 tcg_gen_trunc_tl_i32(fp0, t0);
7305 gen_store_fpr32h(fp0, fs);
7306 tcg_temp_free_i32(fp0);
7307 }
7308 opn = "mthc1";
7309 break;
7310 default:
7311 MIPS_INVAL(opn);
7312 generate_exception (ctx, EXCP_RI);
7313 goto out;
7314 }
7315 (void)opn; /* avoid a compiler warning */
7316 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7317
7318 out:
7319 tcg_temp_free(t0);
7320 }
7321
7322 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7323 {
7324 int l1;
7325 TCGCond cond;
7326 TCGv_i32 t0;
7327
7328 if (rd == 0) {
7329 /* Treat as NOP. */
7330 return;
7331 }
7332
7333 if (tf)
7334 cond = TCG_COND_EQ;
7335 else
7336 cond = TCG_COND_NE;
7337
7338 l1 = gen_new_label();
7339 t0 = tcg_temp_new_i32();
7340 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7341 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7342 tcg_temp_free_i32(t0);
7343 if (rs == 0) {
7344 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7345 } else {
7346 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7347 }
7348 gen_set_label(l1);
7349 }
7350
7351 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7352 {
7353 int cond;
7354 TCGv_i32 t0 = tcg_temp_new_i32();
7355 int l1 = gen_new_label();
7356
7357 if (tf)
7358 cond = TCG_COND_EQ;
7359 else
7360 cond = TCG_COND_NE;
7361
7362 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7363 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7364 gen_load_fpr32(t0, fs);
7365 gen_store_fpr32(t0, fd);
7366 gen_set_label(l1);
7367 tcg_temp_free_i32(t0);
7368 }
7369
7370 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7371 {
7372 int cond;
7373 TCGv_i32 t0 = tcg_temp_new_i32();
7374 TCGv_i64 fp0;
7375 int l1 = gen_new_label();
7376
7377 if (tf)
7378 cond = TCG_COND_EQ;
7379 else
7380 cond = TCG_COND_NE;
7381
7382 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7383 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7384 tcg_temp_free_i32(t0);
7385 fp0 = tcg_temp_new_i64();
7386 gen_load_fpr64(ctx, fp0, fs);
7387 gen_store_fpr64(ctx, fp0, fd);
7388 tcg_temp_free_i64(fp0);
7389 gen_set_label(l1);
7390 }
7391
7392 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7393 {
7394 int cond;
7395 TCGv_i32 t0 = tcg_temp_new_i32();
7396 int l1 = gen_new_label();
7397 int l2 = gen_new_label();
7398
7399 if (tf)
7400 cond = TCG_COND_EQ;
7401 else
7402 cond = TCG_COND_NE;
7403
7404 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7405 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7406 gen_load_fpr32(t0, fs);
7407 gen_store_fpr32(t0, fd);
7408 gen_set_label(l1);
7409
7410 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7411 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7412 gen_load_fpr32h(t0, fs);
7413 gen_store_fpr32h(t0, fd);
7414 tcg_temp_free_i32(t0);
7415 gen_set_label(l2);
7416 }
7417
7418
7419 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7420 int ft, int fs, int fd, int cc)
7421 {
7422 const char *opn = "farith";
7423 const char *condnames[] = {
7424 "c.f",
7425 "c.un",
7426 "c.eq",
7427 "c.ueq",
7428 "c.olt",
7429 "c.ult",
7430 "c.ole",
7431 "c.ule",
7432 "c.sf",
7433 "c.ngle",
7434 "c.seq",
7435 "c.ngl",
7436 "c.lt",
7437 "c.nge",
7438 "c.le",
7439 "c.ngt",
7440 };
7441 const char *condnames_abs[] = {
7442 "cabs.f",
7443 "cabs.un",
7444 "cabs.eq",
7445 "cabs.ueq",
7446 "cabs.olt",
7447 "cabs.ult",
7448 "cabs.ole",
7449 "cabs.ule",
7450 "cabs.sf",
7451 "cabs.ngle",
7452 "cabs.seq",
7453 "cabs.ngl",
7454 "cabs.lt",
7455 "cabs.nge",
7456 "cabs.le",
7457 "cabs.ngt",
7458 };
7459 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7460 uint32_t func = ctx->opcode & 0x3f;
7461
7462 switch (op1) {
7463 case OPC_ADD_S:
7464 {
7465 TCGv_i32 fp0 = tcg_temp_new_i32();
7466 TCGv_i32 fp1 = tcg_temp_new_i32();
7467
7468 gen_load_fpr32(fp0, fs);
7469 gen_load_fpr32(fp1, ft);
7470 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7471 tcg_temp_free_i32(fp1);
7472 gen_store_fpr32(fp0, fd);
7473 tcg_temp_free_i32(fp0);
7474 }
7475 opn = "add.s";
7476 optype = BINOP;
7477 break;
7478 case OPC_SUB_S:
7479 {
7480 TCGv_i32 fp0 = tcg_temp_new_i32();
7481 TCGv_i32 fp1 = tcg_temp_new_i32();
7482
7483 gen_load_fpr32(fp0, fs);
7484 gen_load_fpr32(fp1, ft);
7485 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7486 tcg_temp_free_i32(fp1);
7487 gen_store_fpr32(fp0, fd);
7488 tcg_temp_free_i32(fp0);
7489 }
7490 opn = "sub.s";
7491 optype = BINOP;
7492 break;
7493 case OPC_MUL_S:
7494 {
7495 TCGv_i32 fp0 = tcg_temp_new_i32();
7496 TCGv_i32 fp1 = tcg_temp_new_i32();
7497
7498 gen_load_fpr32(fp0, fs);
7499 gen_load_fpr32(fp1, ft);
7500 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7501 tcg_temp_free_i32(fp1);
7502 gen_store_fpr32(fp0, fd);
7503 tcg_temp_free_i32(fp0);
7504 }
7505 opn = "mul.s";
7506 optype = BINOP;
7507 break;
7508 case OPC_DIV_S:
7509 {
7510 TCGv_i32 fp0 = tcg_temp_new_i32();
7511 TCGv_i32 fp1 = tcg_temp_new_i32();
7512
7513 gen_load_fpr32(fp0, fs);
7514 gen_load_fpr32(fp1, ft);
7515 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7516 tcg_temp_free_i32(fp1);
7517 gen_store_fpr32(fp0, fd);
7518 tcg_temp_free_i32(fp0);
7519 }
7520 opn = "div.s";
7521 optype = BINOP;
7522 break;
7523 case OPC_SQRT_S:
7524 {
7525 TCGv_i32 fp0 = tcg_temp_new_i32();
7526
7527 gen_load_fpr32(fp0, fs);
7528 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7529 gen_store_fpr32(fp0, fd);
7530 tcg_temp_free_i32(fp0);
7531 }
7532 opn = "sqrt.s";
7533 break;
7534 case OPC_ABS_S:
7535 {
7536 TCGv_i32 fp0 = tcg_temp_new_i32();
7537
7538 gen_load_fpr32(fp0, fs);
7539 gen_helper_float_abs_s(fp0, fp0);
7540 gen_store_fpr32(fp0, fd);
7541 tcg_temp_free_i32(fp0);
7542 }
7543 opn = "abs.s";
7544 break;
7545 case OPC_MOV_S:
7546 {
7547 TCGv_i32 fp0 = tcg_temp_new_i32();
7548
7549 gen_load_fpr32(fp0, fs);
7550 gen_store_fpr32(fp0, fd);
7551 tcg_temp_free_i32(fp0);
7552 }
7553 opn = "mov.s";
7554 break;
7555 case OPC_NEG_S:
7556 {
7557 TCGv_i32 fp0 = tcg_temp_new_i32();
7558
7559 gen_load_fpr32(fp0, fs);
7560 gen_helper_float_chs_s(fp0, fp0);
7561 gen_store_fpr32(fp0, fd);
7562 tcg_temp_free_i32(fp0);
7563 }
7564 opn = "neg.s";
7565 break;
7566 case OPC_ROUND_L_S:
7567 check_cp1_64bitmode(ctx);
7568 {
7569 TCGv_i32 fp32 = tcg_temp_new_i32();
7570 TCGv_i64 fp64 = tcg_temp_new_i64();
7571
7572 gen_load_fpr32(fp32, fs);
7573 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7574 tcg_temp_free_i32(fp32);
7575 gen_store_fpr64(ctx, fp64, fd);
7576 tcg_temp_free_i64(fp64);
7577 }
7578 opn = "round.l.s";
7579 break;
7580 case OPC_TRUNC_L_S:
7581 check_cp1_64bitmode(ctx);
7582 {
7583 TCGv_i32 fp32 = tcg_temp_new_i32();
7584 TCGv_i64 fp64 = tcg_temp_new_i64();
7585
7586 gen_load_fpr32(fp32, fs);
7587 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7588 tcg_temp_free_i32(fp32);
7589 gen_store_fpr64(ctx, fp64, fd);
7590 tcg_temp_free_i64(fp64);
7591 }
7592 opn = "trunc.l.s";
7593 break;
7594 case OPC_CEIL_L_S:
7595 check_cp1_64bitmode(ctx);
7596 {
7597 TCGv_i32 fp32 = tcg_temp_new_i32();
7598 TCGv_i64 fp64 = tcg_temp_new_i64();
7599
7600 gen_load_fpr32(fp32, fs);
7601 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7602 tcg_temp_free_i32(fp32);
7603 gen_store_fpr64(ctx, fp64, fd);
7604 tcg_temp_free_i64(fp64);
7605 }
7606 opn = "ceil.l.s";
7607 break;
7608 case OPC_FLOOR_L_S:
7609 check_cp1_64bitmode(ctx);
7610 {
7611 TCGv_i32 fp32 = tcg_temp_new_i32();
7612 TCGv_i64 fp64 = tcg_temp_new_i64();
7613
7614 gen_load_fpr32(fp32, fs);
7615 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7616 tcg_temp_free_i32(fp32);
7617 gen_store_fpr64(ctx, fp64, fd);
7618 tcg_temp_free_i64(fp64);
7619 }
7620 opn = "floor.l.s";
7621 break;
7622 case OPC_ROUND_W_S:
7623 {
7624 TCGv_i32 fp0 = tcg_temp_new_i32();
7625
7626 gen_load_fpr32(fp0, fs);
7627 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7628 gen_store_fpr32(fp0, fd);
7629 tcg_temp_free_i32(fp0);
7630 }
7631 opn = "round.w.s";
7632 break;
7633 case OPC_TRUNC_W_S:
7634 {
7635 TCGv_i32 fp0 = tcg_temp_new_i32();
7636
7637 gen_load_fpr32(fp0, fs);
7638 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7639 gen_store_fpr32(fp0, fd);
7640 tcg_temp_free_i32(fp0);
7641 }
7642 opn = "trunc.w.s";
7643 break;
7644 case OPC_CEIL_W_S:
7645 {
7646 TCGv_i32 fp0 = tcg_temp_new_i32();
7647
7648 gen_load_fpr32(fp0, fs);
7649 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7650 gen_store_fpr32(fp0, fd);
7651 tcg_temp_free_i32(fp0);
7652 }
7653 opn = "ceil.w.s";
7654 break;
7655 case OPC_FLOOR_W_S:
7656 {
7657 TCGv_i32 fp0 = tcg_temp_new_i32();
7658
7659 gen_load_fpr32(fp0, fs);
7660 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7661 gen_store_fpr32(fp0, fd);
7662 tcg_temp_free_i32(fp0);
7663 }
7664 opn = "floor.w.s";
7665 break;
7666 case OPC_MOVCF_S:
7667 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7668 opn = "movcf.s";
7669 break;
7670 case OPC_MOVZ_S:
7671 {
7672 int l1 = gen_new_label();
7673 TCGv_i32 fp0;
7674
7675 if (ft != 0) {
7676 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7677 }
7678 fp0 = tcg_temp_new_i32();
7679 gen_load_fpr32(fp0, fs);
7680 gen_store_fpr32(fp0, fd);
7681 tcg_temp_free_i32(fp0);
7682 gen_set_label(l1);
7683 }
7684 opn = "movz.s";
7685 break;
7686 case OPC_MOVN_S:
7687 {
7688 int l1 = gen_new_label();
7689 TCGv_i32 fp0;
7690
7691 if (ft != 0) {
7692 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7693 fp0 = tcg_temp_new_i32();
7694 gen_load_fpr32(fp0, fs);
7695 gen_store_fpr32(fp0, fd);
7696 tcg_temp_free_i32(fp0);
7697 gen_set_label(l1);
7698 }
7699 }
7700 opn = "movn.s";
7701 break;
7702 case OPC_RECIP_S:
7703 check_cop1x(ctx);
7704 {
7705 TCGv_i32 fp0 = tcg_temp_new_i32();
7706
7707 gen_load_fpr32(fp0, fs);
7708 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7709 gen_store_fpr32(fp0, fd);
7710 tcg_temp_free_i32(fp0);
7711 }
7712 opn = "recip.s";
7713 break;
7714 case OPC_RSQRT_S:
7715 check_cop1x(ctx);
7716 {
7717 TCGv_i32 fp0 = tcg_temp_new_i32();
7718
7719 gen_load_fpr32(fp0, fs);
7720 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7721 gen_store_fpr32(fp0, fd);
7722 tcg_temp_free_i32(fp0);
7723 }
7724 opn = "rsqrt.s";
7725 break;
7726 case OPC_RECIP2_S:
7727 check_cp1_64bitmode(ctx);
7728 {
7729 TCGv_i32 fp0 = tcg_temp_new_i32();
7730 TCGv_i32 fp1 = tcg_temp_new_i32();
7731
7732 gen_load_fpr32(fp0, fs);
7733 gen_load_fpr32(fp1, ft);
7734 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7735 tcg_temp_free_i32(fp1);
7736 gen_store_fpr32(fp0, fd);
7737 tcg_temp_free_i32(fp0);
7738 }
7739 opn = "recip2.s";
7740 break;
7741 case OPC_RECIP1_S:
7742 check_cp1_64bitmode(ctx);
7743 {
7744 TCGv_i32 fp0 = tcg_temp_new_i32();
7745
7746 gen_load_fpr32(fp0, fs);
7747 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7748 gen_store_fpr32(fp0, fd);
7749 tcg_temp_free_i32(fp0);
7750 }
7751 opn = "recip1.s";
7752 break;
7753 case OPC_RSQRT1_S:
7754 check_cp1_64bitmode(ctx);
7755 {
7756 TCGv_i32 fp0 = tcg_temp_new_i32();
7757
7758 gen_load_fpr32(fp0, fs);
7759 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7760 gen_store_fpr32(fp0, fd);
7761 tcg_temp_free_i32(fp0);
7762 }
7763 opn = "rsqrt1.s";
7764 break;
7765 case OPC_RSQRT2_S:
7766 check_cp1_64bitmode(ctx);
7767 {
7768 TCGv_i32 fp0 = tcg_temp_new_i32();
7769 TCGv_i32 fp1 = tcg_temp_new_i32();
7770
7771 gen_load_fpr32(fp0, fs);
7772 gen_load_fpr32(fp1, ft);
7773 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7774 tcg_temp_free_i32(fp1);
7775 gen_store_fpr32(fp0, fd);
7776 tcg_temp_free_i32(fp0);
7777 }
7778 opn = "rsqrt2.s";
7779 break;
7780 case OPC_CVT_D_S:
7781 check_cp1_registers(ctx, fd);
7782 {
7783 TCGv_i32 fp32 = tcg_temp_new_i32();
7784 TCGv_i64 fp64 = tcg_temp_new_i64();
7785
7786 gen_load_fpr32(fp32, fs);
7787 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7788 tcg_temp_free_i32(fp32);
7789 gen_store_fpr64(ctx, fp64, fd);
7790 tcg_temp_free_i64(fp64);
7791 }
7792 opn = "cvt.d.s";
7793 break;
7794 case OPC_CVT_W_S:
7795 {
7796 TCGv_i32 fp0 = tcg_temp_new_i32();
7797
7798 gen_load_fpr32(fp0, fs);
7799 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7800 gen_store_fpr32(fp0, fd);
7801 tcg_temp_free_i32(fp0);
7802 }
7803 opn = "cvt.w.s";
7804 break;
7805 case OPC_CVT_L_S:
7806 check_cp1_64bitmode(ctx);
7807 {
7808 TCGv_i32 fp32 = tcg_temp_new_i32();
7809 TCGv_i64 fp64 = tcg_temp_new_i64();
7810
7811 gen_load_fpr32(fp32, fs);
7812 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7813 tcg_temp_free_i32(fp32);
7814 gen_store_fpr64(ctx, fp64, fd);
7815 tcg_temp_free_i64(fp64);
7816 }
7817 opn = "cvt.l.s";
7818 break;
7819 case OPC_CVT_PS_S:
7820 check_cp1_64bitmode(ctx);
7821 {
7822 TCGv_i64 fp64 = tcg_temp_new_i64();
7823 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7824 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7825
7826 gen_load_fpr32(fp32_0, fs);
7827 gen_load_fpr32(fp32_1, ft);
7828 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7829 tcg_temp_free_i32(fp32_1);
7830 tcg_temp_free_i32(fp32_0);
7831 gen_store_fpr64(ctx, fp64, fd);
7832 tcg_temp_free_i64(fp64);
7833 }
7834 opn = "cvt.ps.s";
7835 break;
7836 case OPC_CMP_F_S:
7837 case OPC_CMP_UN_S:
7838 case OPC_CMP_EQ_S:
7839 case OPC_CMP_UEQ_S:
7840 case OPC_CMP_OLT_S:
7841 case OPC_CMP_ULT_S:
7842 case OPC_CMP_OLE_S:
7843 case OPC_CMP_ULE_S:
7844 case OPC_CMP_SF_S:
7845 case OPC_CMP_NGLE_S:
7846 case OPC_CMP_SEQ_S:
7847 case OPC_CMP_NGL_S:
7848 case OPC_CMP_LT_S:
7849 case OPC_CMP_NGE_S:
7850 case OPC_CMP_LE_S:
7851 case OPC_CMP_NGT_S:
7852 if (ctx->opcode & (1 << 6)) {
7853 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7854 opn = condnames_abs[func-48];
7855 } else {
7856 gen_cmp_s(ctx, func-48, ft, fs, cc);
7857 opn = condnames[func-48];
7858 }
7859 break;
7860 case OPC_ADD_D:
7861 check_cp1_registers(ctx, fs | ft | fd);
7862 {
7863 TCGv_i64 fp0 = tcg_temp_new_i64();
7864 TCGv_i64 fp1 = tcg_temp_new_i64();
7865
7866 gen_load_fpr64(ctx, fp0, fs);
7867 gen_load_fpr64(ctx, fp1, ft);
7868 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7869 tcg_temp_free_i64(fp1);
7870 gen_store_fpr64(ctx, fp0, fd);
7871 tcg_temp_free_i64(fp0);
7872 }
7873 opn = "add.d";
7874 optype = BINOP;
7875 break;
7876 case OPC_SUB_D:
7877 check_cp1_registers(ctx, fs | ft | fd);
7878 {
7879 TCGv_i64 fp0 = tcg_temp_new_i64();
7880 TCGv_i64 fp1 = tcg_temp_new_i64();
7881
7882 gen_load_fpr64(ctx, fp0, fs);
7883 gen_load_fpr64(ctx, fp1, ft);
7884 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7885 tcg_temp_free_i64(fp1);
7886 gen_store_fpr64(ctx, fp0, fd);
7887 tcg_temp_free_i64(fp0);
7888 }
7889 opn = "sub.d";
7890 optype = BINOP;
7891 break;
7892 case OPC_MUL_D:
7893 check_cp1_registers(ctx, fs | ft | fd);
7894 {
7895 TCGv_i64 fp0 = tcg_temp_new_i64();
7896 TCGv_i64 fp1 = tcg_temp_new_i64();
7897
7898 gen_load_fpr64(ctx, fp0, fs);
7899 gen_load_fpr64(ctx, fp1, ft);
7900 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7901 tcg_temp_free_i64(fp1);
7902 gen_store_fpr64(ctx, fp0, fd);
7903 tcg_temp_free_i64(fp0);
7904 }
7905 opn = "mul.d";
7906 optype = BINOP;
7907 break;
7908 case OPC_DIV_D:
7909 check_cp1_registers(ctx, fs | ft | fd);
7910 {
7911 TCGv_i64 fp0 = tcg_temp_new_i64();
7912 TCGv_i64 fp1 = tcg_temp_new_i64();
7913
7914 gen_load_fpr64(ctx, fp0, fs);
7915 gen_load_fpr64(ctx, fp1, ft);
7916 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7917 tcg_temp_free_i64(fp1);
7918 gen_store_fpr64(ctx, fp0, fd);
7919 tcg_temp_free_i64(fp0);
7920 }
7921 opn = "div.d";
7922 optype = BINOP;
7923 break;
7924 case OPC_SQRT_D:
7925 check_cp1_registers(ctx, fs | fd);
7926 {
7927 TCGv_i64 fp0 = tcg_temp_new_i64();
7928
7929 gen_load_fpr64(ctx, fp0, fs);
7930 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7931 gen_store_fpr64(ctx, fp0, fd);
7932 tcg_temp_free_i64(fp0);
7933 }
7934 opn = "sqrt.d";
7935 break;
7936 case OPC_ABS_D:
7937 check_cp1_registers(ctx, fs | fd);
7938 {
7939 TCGv_i64 fp0 = tcg_temp_new_i64();
7940
7941 gen_load_fpr64(ctx, fp0, fs);
7942 gen_helper_float_abs_d(fp0, fp0);
7943 gen_store_fpr64(ctx, fp0, fd);
7944 tcg_temp_free_i64(fp0);
7945 }
7946 opn = "abs.d";
7947 break;
7948 case OPC_MOV_D:
7949 check_cp1_registers(ctx, fs | fd);
7950 {
7951 TCGv_i64 fp0 = tcg_temp_new_i64();
7952
7953 gen_load_fpr64(ctx, fp0, fs);
7954 gen_store_fpr64(ctx, fp0, fd);
7955 tcg_temp_free_i64(fp0);
7956 }
7957 opn = "mov.d";
7958 break;
7959 case OPC_NEG_D:
7960 check_cp1_registers(ctx, fs | fd);
7961 {
7962 TCGv_i64 fp0 = tcg_temp_new_i64();
7963
7964 gen_load_fpr64(ctx, fp0, fs);
7965 gen_helper_float_chs_d(fp0, fp0);
7966 gen_store_fpr64(ctx, fp0, fd);
7967 tcg_temp_free_i64(fp0);
7968 }
7969 opn = "neg.d";
7970 break;
7971 case OPC_ROUND_L_D:
7972 check_cp1_64bitmode(ctx);
7973 {
7974 TCGv_i64 fp0 = tcg_temp_new_i64();
7975
7976 gen_load_fpr64(ctx, fp0, fs);
7977 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7978 gen_store_fpr64(ctx, fp0, fd);
7979 tcg_temp_free_i64(fp0);
7980 }
7981 opn = "round.l.d";
7982 break;
7983 case OPC_TRUNC_L_D:
7984 check_cp1_64bitmode(ctx);
7985 {
7986 TCGv_i64 fp0 = tcg_temp_new_i64();
7987
7988 gen_load_fpr64(ctx, fp0, fs);
7989 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7990 gen_store_fpr64(ctx, fp0, fd);
7991 tcg_temp_free_i64(fp0);
7992 }
7993 opn = "trunc.l.d";
7994 break;
7995 case OPC_CEIL_L_D:
7996 check_cp1_64bitmode(ctx);
7997 {
7998 TCGv_i64 fp0 = tcg_temp_new_i64();
7999
8000 gen_load_fpr64(ctx, fp0, fs);
8001 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8002 gen_store_fpr64(ctx, fp0, fd);
8003 tcg_temp_free_i64(fp0);
8004 }
8005 opn = "ceil.l.d";
8006 break;
8007 case OPC_FLOOR_L_D:
8008 check_cp1_64bitmode(ctx);
8009 {
8010 TCGv_i64 fp0 = tcg_temp_new_i64();
8011
8012 gen_load_fpr64(ctx, fp0, fs);
8013 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8014 gen_store_fpr64(ctx, fp0, fd);
8015 tcg_temp_free_i64(fp0);
8016 }
8017 opn = "floor.l.d";
8018 break;
8019 case OPC_ROUND_W_D:
8020 check_cp1_registers(ctx, fs);
8021 {
8022 TCGv_i32 fp32 = tcg_temp_new_i32();
8023 TCGv_i64 fp64 = tcg_temp_new_i64();
8024
8025 gen_load_fpr64(ctx, fp64, fs);
8026 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8027 tcg_temp_free_i64(fp64);
8028 gen_store_fpr32(fp32, fd);
8029 tcg_temp_free_i32(fp32);
8030 }
8031 opn = "round.w.d";
8032 break;
8033 case OPC_TRUNC_W_D:
8034 check_cp1_registers(ctx, fs);
8035 {
8036 TCGv_i32 fp32 = tcg_temp_new_i32();
8037 TCGv_i64 fp64 = tcg_temp_new_i64();
8038
8039 gen_load_fpr64(ctx, fp64, fs);
8040 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8041 tcg_temp_free_i64(fp64);
8042 gen_store_fpr32(fp32, fd);
8043 tcg_temp_free_i32(fp32);
8044 }
8045 opn = "trunc.w.d";
8046 break;
8047 case OPC_CEIL_W_D:
8048 check_cp1_registers(ctx, fs);
8049 {
8050 TCGv_i32 fp32 = tcg_temp_new_i32();
8051 TCGv_i64 fp64 = tcg_temp_new_i64();
8052
8053 gen_load_fpr64(ctx, fp64, fs);
8054 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8055 tcg_temp_free_i64(fp64);
8056 gen_store_fpr32(fp32, fd);
8057 tcg_temp_free_i32(fp32);
8058 }
8059 opn = "ceil.w.d";
8060 break;
8061 case OPC_FLOOR_W_D:
8062 check_cp1_registers(ctx, fs);
8063 {
8064 TCGv_i32 fp32 = tcg_temp_new_i32();
8065 TCGv_i64 fp64 = tcg_temp_new_i64();
8066
8067 gen_load_fpr64(ctx, fp64, fs);
8068 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8069 tcg_temp_free_i64(fp64);
8070 gen_store_fpr32(fp32, fd);
8071 tcg_temp_free_i32(fp32);
8072 }
8073 opn = "floor.w.d";
8074 break;
8075 case OPC_MOVCF_D:
8076 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8077 opn = "movcf.d";
8078 break;
8079 case OPC_MOVZ_D:
8080 {
8081 int l1 = gen_new_label();
8082 TCGv_i64 fp0;
8083
8084 if (ft != 0) {
8085 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8086 }
8087 fp0 = tcg_temp_new_i64();
8088 gen_load_fpr64(ctx, fp0, fs);
8089 gen_store_fpr64(ctx, fp0, fd);
8090 tcg_temp_free_i64(fp0);
8091 gen_set_label(l1);
8092 }
8093 opn = "movz.d";
8094 break;
8095 case OPC_MOVN_D:
8096 {
8097 int l1 = gen_new_label();
8098 TCGv_i64 fp0;
8099
8100 if (ft != 0) {
8101 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8102 fp0 = tcg_temp_new_i64();
8103 gen_load_fpr64(ctx, fp0, fs);
8104 gen_store_fpr64(ctx, fp0, fd);
8105 tcg_temp_free_i64(fp0);
8106 gen_set_label(l1);
8107 }
8108 }
8109 opn = "movn.d";
8110 break;
8111 case OPC_RECIP_D:
8112 check_cp1_64bitmode(ctx);
8113 {
8114 TCGv_i64 fp0 = tcg_temp_new_i64();
8115
8116 gen_load_fpr64(ctx, fp0, fs);
8117 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8118 gen_store_fpr64(ctx, fp0, fd);
8119 tcg_temp_free_i64(fp0);
8120 }
8121 opn = "recip.d";
8122 break;
8123 case OPC_RSQRT_D:
8124 check_cp1_64bitmode(ctx);
8125 {
8126 TCGv_i64 fp0 = tcg_temp_new_i64();
8127
8128 gen_load_fpr64(ctx, fp0, fs);
8129 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8130 gen_store_fpr64(ctx, fp0, fd);
8131 tcg_temp_free_i64(fp0);
8132 }
8133 opn = "rsqrt.d";
8134 break;
8135 case OPC_RECIP2_D:
8136 check_cp1_64bitmode(ctx);
8137 {
8138 TCGv_i64 fp0 = tcg_temp_new_i64();
8139 TCGv_i64 fp1 = tcg_temp_new_i64();
8140
8141 gen_load_fpr64(ctx, fp0, fs);
8142 gen_load_fpr64(ctx, fp1, ft);
8143 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8144 tcg_temp_free_i64(fp1);
8145 gen_store_fpr64(ctx, fp0, fd);
8146 tcg_temp_free_i64(fp0);
8147 }
8148 opn = "recip2.d";
8149 break;
8150 case OPC_RECIP1_D:
8151 check_cp1_64bitmode(ctx);
8152 {
8153 TCGv_i64 fp0 = tcg_temp_new_i64();
8154
8155 gen_load_fpr64(ctx, fp0, fs);
8156 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8157 gen_store_fpr64(ctx, fp0, fd);
8158 tcg_temp_free_i64(fp0);
8159 }
8160 opn = "recip1.d";
8161 break;
8162 case OPC_RSQRT1_D:
8163 check_cp1_64bitmode(ctx);
8164 {
8165 TCGv_i64 fp0 = tcg_temp_new_i64();
8166
8167 gen_load_fpr64(ctx, fp0, fs);
8168 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8169 gen_store_fpr64(ctx, fp0, fd);
8170 tcg_temp_free_i64(fp0);
8171 }
8172 opn = "rsqrt1.d";
8173 break;
8174 case OPC_RSQRT2_D:
8175 check_cp1_64bitmode(ctx);
8176 {
8177 TCGv_i64 fp0 = tcg_temp_new_i64();
8178 TCGv_i64 fp1 = tcg_temp_new_i64();
8179
8180 gen_load_fpr64(ctx, fp0, fs);
8181 gen_load_fpr64(ctx, fp1, ft);
8182 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8183 tcg_temp_free_i64(fp1);
8184 gen_store_fpr64(ctx, fp0, fd);
8185 tcg_temp_free_i64(fp0);
8186 }
8187 opn = "rsqrt2.d";
8188 break;
8189 case OPC_CMP_F_D:
8190 case OPC_CMP_UN_D:
8191 case OPC_CMP_EQ_D:
8192 case OPC_CMP_UEQ_D:
8193 case OPC_CMP_OLT_D:
8194 case OPC_CMP_ULT_D:
8195 case OPC_CMP_OLE_D:
8196 case OPC_CMP_ULE_D:
8197 case OPC_CMP_SF_D:
8198 case OPC_CMP_NGLE_D:
8199 case OPC_CMP_SEQ_D:
8200 case OPC_CMP_NGL_D:
8201 case OPC_CMP_LT_D:
8202 case OPC_CMP_NGE_D:
8203 case OPC_CMP_LE_D:
8204 case OPC_CMP_NGT_D:
8205 if (ctx->opcode & (1 << 6)) {
8206 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8207 opn = condnames_abs[func-48];
8208 } else {
8209 gen_cmp_d(ctx, func-48, ft, fs, cc);
8210 opn = condnames[func-48];
8211 }
8212 break;
8213 case OPC_CVT_S_D:
8214 check_cp1_registers(ctx, fs);
8215 {
8216 TCGv_i32 fp32 = tcg_temp_new_i32();
8217 TCGv_i64 fp64 = tcg_temp_new_i64();
8218
8219 gen_load_fpr64(ctx, fp64, fs);
8220 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8221 tcg_temp_free_i64(fp64);
8222 gen_store_fpr32(fp32, fd);
8223 tcg_temp_free_i32(fp32);
8224 }
8225 opn = "cvt.s.d";
8226 break;
8227 case OPC_CVT_W_D:
8228 check_cp1_registers(ctx, fs);
8229 {
8230 TCGv_i32 fp32 = tcg_temp_new_i32();
8231 TCGv_i64 fp64 = tcg_temp_new_i64();
8232
8233 gen_load_fpr64(ctx, fp64, fs);
8234 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8235 tcg_temp_free_i64(fp64);
8236 gen_store_fpr32(fp32, fd);
8237 tcg_temp_free_i32(fp32);
8238 }
8239 opn = "cvt.w.d";
8240 break;
8241 case OPC_CVT_L_D:
8242 check_cp1_64bitmode(ctx);
8243 {
8244 TCGv_i64 fp0 = tcg_temp_new_i64();
8245
8246 gen_load_fpr64(ctx, fp0, fs);
8247 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8248 gen_store_fpr64(ctx, fp0, fd);
8249 tcg_temp_free_i64(fp0);
8250 }
8251 opn = "cvt.l.d";
8252 break;
8253 case OPC_CVT_S_W:
8254 {
8255 TCGv_i32 fp0 = tcg_temp_new_i32();
8256
8257 gen_load_fpr32(fp0, fs);
8258 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8259 gen_store_fpr32(fp0, fd);
8260 tcg_temp_free_i32(fp0);
8261 }
8262 opn = "cvt.s.w";
8263 break;
8264 case OPC_CVT_D_W:
8265 check_cp1_registers(ctx, fd);
8266 {
8267 TCGv_i32 fp32 = tcg_temp_new_i32();
8268 TCGv_i64 fp64 = tcg_temp_new_i64();
8269
8270 gen_load_fpr32(fp32, fs);
8271 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8272 tcg_temp_free_i32(fp32);
8273 gen_store_fpr64(ctx, fp64, fd);
8274 tcg_temp_free_i64(fp64);
8275 }
8276 opn = "cvt.d.w";
8277 break;
8278 case OPC_CVT_S_L:
8279 check_cp1_64bitmode(ctx);
8280 {
8281 TCGv_i32 fp32 = tcg_temp_new_i32();
8282 TCGv_i64 fp64 = tcg_temp_new_i64();
8283
8284 gen_load_fpr64(ctx, fp64, fs);
8285 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8286 tcg_temp_free_i64(fp64);
8287 gen_store_fpr32(fp32, fd);
8288 tcg_temp_free_i32(fp32);
8289 }
8290 opn = "cvt.s.l";
8291 break;
8292 case OPC_CVT_D_L:
8293 check_cp1_64bitmode(ctx);
8294 {
8295 TCGv_i64 fp0 = tcg_temp_new_i64();
8296
8297 gen_load_fpr64(ctx, fp0, fs);
8298 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8299 gen_store_fpr64(ctx, fp0, fd);
8300 tcg_temp_free_i64(fp0);
8301 }
8302 opn = "cvt.d.l";
8303 break;
8304 case OPC_CVT_PS_PW:
8305 check_cp1_64bitmode(ctx);
8306 {
8307 TCGv_i64 fp0 = tcg_temp_new_i64();
8308
8309 gen_load_fpr64(ctx, fp0, fs);
8310 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8311 gen_store_fpr64(ctx, fp0, fd);
8312 tcg_temp_free_i64(fp0);
8313 }
8314 opn = "cvt.ps.pw";
8315 break;
8316 case OPC_ADD_PS:
8317 check_cp1_64bitmode(ctx);
8318 {
8319 TCGv_i64 fp0 = tcg_temp_new_i64();
8320 TCGv_i64 fp1 = tcg_temp_new_i64();
8321
8322 gen_load_fpr64(ctx, fp0, fs);
8323 gen_load_fpr64(ctx, fp1, ft);
8324 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8325 tcg_temp_free_i64(fp1);
8326 gen_store_fpr64(ctx, fp0, fd);
8327 tcg_temp_free_i64(fp0);
8328 }
8329 opn = "add.ps";
8330 break;
8331 case OPC_SUB_PS:
8332 check_cp1_64bitmode(ctx);
8333 {
8334 TCGv_i64 fp0 = tcg_temp_new_i64();
8335 TCGv_i64 fp1 = tcg_temp_new_i64();
8336
8337 gen_load_fpr64(ctx, fp0, fs);
8338 gen_load_fpr64(ctx, fp1, ft);
8339 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8340 tcg_temp_free_i64(fp1);
8341 gen_store_fpr64(ctx, fp0, fd);
8342 tcg_temp_free_i64(fp0);
8343 }
8344 opn = "sub.ps";
8345 break;
8346 case OPC_MUL_PS:
8347 check_cp1_64bitmode(ctx);
8348 {
8349 TCGv_i64 fp0 = tcg_temp_new_i64();
8350 TCGv_i64 fp1 = tcg_temp_new_i64();
8351
8352 gen_load_fpr64(ctx, fp0, fs);
8353 gen_load_fpr64(ctx, fp1, ft);
8354 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8355 tcg_temp_free_i64(fp1);
8356 gen_store_fpr64(ctx, fp0, fd);
8357 tcg_temp_free_i64(fp0);
8358 }
8359 opn = "mul.ps";
8360 break;
8361 case OPC_ABS_PS:
8362 check_cp1_64bitmode(ctx);
8363 {
8364 TCGv_i64 fp0 = tcg_temp_new_i64();
8365
8366 gen_load_fpr64(ctx, fp0, fs);
8367 gen_helper_float_abs_ps(fp0, fp0);
8368 gen_store_fpr64(ctx, fp0, fd);
8369 tcg_temp_free_i64(fp0);
8370 }
8371 opn = "abs.ps";
8372 break;
8373 case OPC_MOV_PS:
8374 check_cp1_64bitmode(ctx);
8375 {
8376 TCGv_i64 fp0 = tcg_temp_new_i64();
8377
8378 gen_load_fpr64(ctx, fp0, fs);
8379 gen_store_fpr64(ctx, fp0, fd);
8380 tcg_temp_free_i64(fp0);
8381 }
8382 opn = "mov.ps";
8383 break;
8384 case OPC_NEG_PS:
8385 check_cp1_64bitmode(ctx);
8386 {
8387 TCGv_i64 fp0 = tcg_temp_new_i64();
8388
8389 gen_load_fpr64(ctx, fp0, fs);
8390 gen_helper_float_chs_ps(fp0, fp0);
8391 gen_store_fpr64(ctx, fp0, fd);
8392 tcg_temp_free_i64(fp0);
8393 }
8394 opn = "neg.ps";
8395 break;
8396 case OPC_MOVCF_PS:
8397 check_cp1_64bitmode(ctx);
8398 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8399 opn = "movcf.ps";
8400 break;
8401 case OPC_MOVZ_PS:
8402 check_cp1_64bitmode(ctx);
8403 {
8404 int l1 = gen_new_label();
8405 TCGv_i64 fp0;
8406
8407 if (ft != 0)
8408 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8409 fp0 = tcg_temp_new_i64();
8410 gen_load_fpr64(ctx, fp0, fs);
8411 gen_store_fpr64(ctx, fp0, fd);
8412 tcg_temp_free_i64(fp0);
8413 gen_set_label(l1);
8414 }
8415 opn = "movz.ps";
8416 break;
8417 case OPC_MOVN_PS:
8418 check_cp1_64bitmode(ctx);
8419 {
8420 int l1 = gen_new_label();
8421 TCGv_i64 fp0;
8422
8423 if (ft != 0) {
8424 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8425 fp0 = tcg_temp_new_i64();
8426 gen_load_fpr64(ctx, fp0, fs);
8427 gen_store_fpr64(ctx, fp0, fd);
8428 tcg_temp_free_i64(fp0);
8429 gen_set_label(l1);
8430 }
8431 }
8432 opn = "movn.ps";
8433 break;
8434 case OPC_ADDR_PS:
8435 check_cp1_64bitmode(ctx);
8436 {
8437 TCGv_i64 fp0 = tcg_temp_new_i64();
8438 TCGv_i64 fp1 = tcg_temp_new_i64();
8439
8440 gen_load_fpr64(ctx, fp0, ft);
8441 gen_load_fpr64(ctx, fp1, fs);
8442 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8443 tcg_temp_free_i64(fp1);
8444 gen_store_fpr64(ctx, fp0, fd);
8445 tcg_temp_free_i64(fp0);
8446 }
8447 opn = "addr.ps";
8448 break;
8449 case OPC_MULR_PS:
8450 check_cp1_64bitmode(ctx);
8451 {
8452 TCGv_i64 fp0 = tcg_temp_new_i64();
8453 TCGv_i64 fp1 = tcg_temp_new_i64();
8454
8455 gen_load_fpr64(ctx, fp0, ft);
8456 gen_load_fpr64(ctx, fp1, fs);
8457 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8458 tcg_temp_free_i64(fp1);
8459 gen_store_fpr64(ctx, fp0, fd);
8460 tcg_temp_free_i64(fp0);
8461 }
8462 opn = "mulr.ps";
8463 break;
8464 case OPC_RECIP2_PS:
8465 check_cp1_64bitmode(ctx);
8466 {
8467 TCGv_i64 fp0 = tcg_temp_new_i64();
8468 TCGv_i64 fp1 = tcg_temp_new_i64();
8469
8470 gen_load_fpr64(ctx, fp0, fs);
8471 gen_load_fpr64(ctx, fp1, ft);
8472 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8473 tcg_temp_free_i64(fp1);
8474 gen_store_fpr64(ctx, fp0, fd);
8475 tcg_temp_free_i64(fp0);
8476 }
8477 opn = "recip2.ps";
8478 break;
8479 case OPC_RECIP1_PS:
8480 check_cp1_64bitmode(ctx);
8481 {
8482 TCGv_i64 fp0 = tcg_temp_new_i64();
8483
8484 gen_load_fpr64(ctx, fp0, fs);
8485 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8486 gen_store_fpr64(ctx, fp0, fd);
8487 tcg_temp_free_i64(fp0);
8488 }
8489 opn = "recip1.ps";
8490 break;
8491 case OPC_RSQRT1_PS:
8492 check_cp1_64bitmode(ctx);
8493 {
8494 TCGv_i64 fp0 = tcg_temp_new_i64();
8495
8496 gen_load_fpr64(ctx, fp0, fs);
8497 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8498 gen_store_fpr64(ctx, fp0, fd);
8499 tcg_temp_free_i64(fp0);
8500 }
8501 opn = "rsqrt1.ps";
8502 break;
8503 case OPC_RSQRT2_PS:
8504 check_cp1_64bitmode(ctx);
8505 {
8506 TCGv_i64 fp0 = tcg_temp_new_i64();
8507 TCGv_i64 fp1 = tcg_temp_new_i64();
8508
8509 gen_load_fpr64(ctx, fp0, fs);
8510 gen_load_fpr64(ctx, fp1, ft);
8511 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8512 tcg_temp_free_i64(fp1);
8513 gen_store_fpr64(ctx, fp0, fd);
8514 tcg_temp_free_i64(fp0);
8515 }
8516 opn = "rsqrt2.ps";
8517 break;
8518 case OPC_CVT_S_PU:
8519 check_cp1_64bitmode(ctx);
8520 {
8521 TCGv_i32 fp0 = tcg_temp_new_i32();
8522
8523 gen_load_fpr32h(fp0, fs);
8524 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8525 gen_store_fpr32(fp0, fd);
8526 tcg_temp_free_i32(fp0);
8527 }
8528 opn = "cvt.s.pu";
8529 break;
8530 case OPC_CVT_PW_PS:
8531 check_cp1_64bitmode(ctx);
8532 {
8533 TCGv_i64 fp0 = tcg_temp_new_i64();
8534
8535 gen_load_fpr64(ctx, fp0, fs);
8536 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8537 gen_store_fpr64(ctx, fp0, fd);
8538 tcg_temp_free_i64(fp0);
8539 }
8540 opn = "cvt.pw.ps";
8541 break;
8542 case OPC_CVT_S_PL:
8543 check_cp1_64bitmode(ctx);
8544 {
8545 TCGv_i32 fp0 = tcg_temp_new_i32();
8546
8547 gen_load_fpr32(fp0, fs);
8548 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8549 gen_store_fpr32(fp0, fd);
8550 tcg_temp_free_i32(fp0);
8551 }
8552 opn = "cvt.s.pl";
8553 break;
8554 case OPC_PLL_PS:
8555 check_cp1_64bitmode(ctx);
8556 {
8557 TCGv_i32 fp0 = tcg_temp_new_i32();
8558 TCGv_i32 fp1 = tcg_temp_new_i32();
8559
8560 gen_load_fpr32(fp0, fs);
8561 gen_load_fpr32(fp1, ft);
8562 gen_store_fpr32h(fp0, fd);
8563 gen_store_fpr32(fp1, fd);
8564 tcg_temp_free_i32(fp0);
8565 tcg_temp_free_i32(fp1);
8566 }
8567 opn = "pll.ps";
8568 break;
8569 case OPC_PLU_PS:
8570 check_cp1_64bitmode(ctx);
8571 {
8572 TCGv_i32 fp0 = tcg_temp_new_i32();
8573 TCGv_i32 fp1 = tcg_temp_new_i32();
8574
8575 gen_load_fpr32(fp0, fs);
8576 gen_load_fpr32h(fp1, ft);
8577 gen_store_fpr32(fp1, fd);
8578 gen_store_fpr32h(fp0, fd);
8579 tcg_temp_free_i32(fp0);
8580 tcg_temp_free_i32(fp1);
8581 }
8582 opn = "plu.ps";
8583 break;
8584 case OPC_PUL_PS:
8585 check_cp1_64bitmode(ctx);
8586 {
8587 TCGv_i32 fp0 = tcg_temp_new_i32();
8588 TCGv_i32 fp1 = tcg_temp_new_i32();
8589
8590 gen_load_fpr32h(fp0, fs);
8591 gen_load_fpr32(fp1, ft);
8592 gen_store_fpr32(fp1, fd);
8593 gen_store_fpr32h(fp0, fd);
8594 tcg_temp_free_i32(fp0);
8595 tcg_temp_free_i32(fp1);
8596 }
8597 opn = "pul.ps";
8598 break;
8599 case OPC_PUU_PS:
8600 check_cp1_64bitmode(ctx);
8601 {
8602 TCGv_i32 fp0 = tcg_temp_new_i32();
8603 TCGv_i32 fp1 = tcg_temp_new_i32();
8604
8605 gen_load_fpr32h(fp0, fs);
8606 gen_load_fpr32h(fp1, ft);
8607 gen_store_fpr32(fp1, fd);
8608 gen_store_fpr32h(fp0, fd);
8609 tcg_temp_free_i32(fp0);
8610 tcg_temp_free_i32(fp1);
8611 }
8612 opn = "puu.ps";
8613 break;
8614 case OPC_CMP_F_PS:
8615 case OPC_CMP_UN_PS:
8616 case OPC_CMP_EQ_PS:
8617 case OPC_CMP_UEQ_PS:
8618 case OPC_CMP_OLT_PS:
8619 case OPC_CMP_ULT_PS:
8620 case OPC_CMP_OLE_PS:
8621 case OPC_CMP_ULE_PS:
8622 case OPC_CMP_SF_PS:
8623 case OPC_CMP_NGLE_PS:
8624 case OPC_CMP_SEQ_PS:
8625 case OPC_CMP_NGL_PS:
8626 case OPC_CMP_LT_PS:
8627 case OPC_CMP_NGE_PS:
8628 case OPC_CMP_LE_PS:
8629 case OPC_CMP_NGT_PS:
8630 if (ctx->opcode & (1 << 6)) {
8631 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8632 opn = condnames_abs[func-48];
8633 } else {
8634 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8635 opn = condnames[func-48];
8636 }
8637 break;
8638 default:
8639 MIPS_INVAL(opn);
8640 generate_exception (ctx, EXCP_RI);
8641 return;
8642 }
8643 (void)opn; /* avoid a compiler warning */
8644 switch (optype) {
8645 case BINOP:
8646 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8647 break;
8648 case CMPOP:
8649 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8650 break;
8651 default:
8652 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8653 break;
8654 }
8655 }
8656
8657 /* Coprocessor 3 (FPU) */
8658 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8659 int fd, int fs, int base, int index)
8660 {
8661 const char *opn = "extended float load/store";
8662 int store = 0;
8663 TCGv t0 = tcg_temp_new();
8664
8665 if (base == 0) {
8666 gen_load_gpr(t0, index);
8667 } else if (index == 0) {
8668 gen_load_gpr(t0, base);
8669 } else {
8670 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8671 }
8672 /* Don't do NOP if destination is zero: we must perform the actual
8673 memory access. */
8674 save_cpu_state(ctx, 0);
8675 switch (opc) {
8676 case OPC_LWXC1:
8677 check_cop1x(ctx);
8678 {
8679 TCGv_i32 fp0 = tcg_temp_new_i32();
8680
8681 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8682 tcg_gen_trunc_tl_i32(fp0, t0);
8683 gen_store_fpr32(fp0, fd);
8684 tcg_temp_free_i32(fp0);
8685 }
8686 opn = "lwxc1";
8687 break;
8688 case OPC_LDXC1:
8689 check_cop1x(ctx);
8690 check_cp1_registers(ctx, fd);
8691 {
8692 TCGv_i64 fp0 = tcg_temp_new_i64();
8693
8694 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8695 gen_store_fpr64(ctx, fp0, fd);
8696 tcg_temp_free_i64(fp0);
8697 }
8698 opn = "ldxc1";
8699 break;
8700 case OPC_LUXC1:
8701 check_cp1_64bitmode(ctx);
8702 tcg_gen_andi_tl(t0, t0, ~0x7);
8703 {
8704 TCGv_i64 fp0 = tcg_temp_new_i64();
8705
8706 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8707 gen_store_fpr64(ctx, fp0, fd);
8708 tcg_temp_free_i64(fp0);
8709 }
8710 opn = "luxc1";
8711 break;
8712 case OPC_SWXC1:
8713 check_cop1x(ctx);
8714 {
8715 TCGv_i32 fp0 = tcg_temp_new_i32();
8716 TCGv t1 = tcg_temp_new();
8717
8718 gen_load_fpr32(fp0, fs);
8719 tcg_gen_extu_i32_tl(t1, fp0);
8720 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8721 tcg_temp_free_i32(fp0);
8722 tcg_temp_free(t1);
8723 }
8724 opn = "swxc1";
8725 store = 1;
8726 break;
8727 case OPC_SDXC1:
8728 check_cop1x(ctx);
8729 check_cp1_registers(ctx, fs);
8730 {
8731 TCGv_i64 fp0 = tcg_temp_new_i64();
8732
8733 gen_load_fpr64(ctx, fp0, fs);
8734 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8735 tcg_temp_free_i64(fp0);
8736 }
8737 opn = "sdxc1";
8738 store = 1;
8739 break;
8740 case OPC_SUXC1:
8741 check_cp1_64bitmode(ctx);
8742 tcg_gen_andi_tl(t0, t0, ~0x7);
8743 {
8744 TCGv_i64 fp0 = tcg_temp_new_i64();
8745
8746 gen_load_fpr64(ctx, fp0, fs);
8747 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8748 tcg_temp_free_i64(fp0);
8749 }
8750 opn = "suxc1";
8751 store = 1;
8752 break;
8753 }
8754 tcg_temp_free(t0);
8755 (void)opn; (void)store; /* avoid compiler warnings */
8756 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8757 regnames[index], regnames[base]);
8758 }
8759
8760 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8761 int fd, int fr, int fs, int ft)
8762 {
8763 const char *opn = "flt3_arith";
8764
8765 switch (opc) {
8766 case OPC_ALNV_PS:
8767 check_cp1_64bitmode(ctx);
8768 {
8769 TCGv t0 = tcg_temp_local_new();
8770 TCGv_i32 fp = tcg_temp_new_i32();
8771 TCGv_i32 fph = tcg_temp_new_i32();
8772 int l1 = gen_new_label();
8773 int l2 = gen_new_label();
8774
8775 gen_load_gpr(t0, fr);
8776 tcg_gen_andi_tl(t0, t0, 0x7);
8777
8778 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8779 gen_load_fpr32(fp, fs);
8780 gen_load_fpr32h(fph, fs);
8781 gen_store_fpr32(fp, fd);
8782 gen_store_fpr32h(fph, fd);
8783 tcg_gen_br(l2);
8784 gen_set_label(l1);
8785 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8786 tcg_temp_free(t0);
8787 #ifdef TARGET_WORDS_BIGENDIAN
8788 gen_load_fpr32(fp, fs);
8789 gen_load_fpr32h(fph, ft);
8790 gen_store_fpr32h(fp, fd);
8791 gen_store_fpr32(fph, fd);
8792 #else
8793 gen_load_fpr32h(fph, fs);
8794 gen_load_fpr32(fp, ft);
8795 gen_store_fpr32(fph, fd);
8796 gen_store_fpr32h(fp, fd);
8797 #endif
8798 gen_set_label(l2);
8799 tcg_temp_free_i32(fp);
8800 tcg_temp_free_i32(fph);
8801 }
8802 opn = "alnv.ps";
8803 break;
8804 case OPC_MADD_S:
8805 check_cop1x(ctx);
8806 {
8807 TCGv_i32 fp0 = tcg_temp_new_i32();
8808 TCGv_i32 fp1 = tcg_temp_new_i32();
8809 TCGv_i32 fp2 = tcg_temp_new_i32();
8810
8811 gen_load_fpr32(fp0, fs);
8812 gen_load_fpr32(fp1, ft);
8813 gen_load_fpr32(fp2, fr);
8814 gen_helper_float_muladd_s(fp2, cpu_env, fp0, fp1, fp2);
8815 tcg_temp_free_i32(fp0);
8816 tcg_temp_free_i32(fp1);
8817 gen_store_fpr32(fp2, fd);
8818 tcg_temp_free_i32(fp2);
8819 }
8820 opn = "madd.s";
8821 break;
8822 case OPC_MADD_D:
8823 check_cop1x(ctx);
8824 check_cp1_registers(ctx, fd | fs | ft | fr);
8825 {
8826 TCGv_i64 fp0 = tcg_temp_new_i64();
8827 TCGv_i64 fp1 = tcg_temp_new_i64();
8828 TCGv_i64 fp2 = tcg_temp_new_i64();
8829
8830 gen_load_fpr64(ctx, fp0, fs);
8831 gen_load_fpr64(ctx, fp1, ft);
8832 gen_load_fpr64(ctx, fp2, fr);
8833 gen_helper_float_muladd_d(fp2, cpu_env, fp0, fp1, fp2);
8834 tcg_temp_free_i64(fp0);
8835 tcg_temp_free_i64(fp1);
8836 gen_store_fpr64(ctx, fp2, fd);
8837 tcg_temp_free_i64(fp2);
8838 }
8839 opn = "madd.d";
8840 break;
8841 case OPC_MADD_PS:
8842 check_cp1_64bitmode(ctx);
8843 {
8844 TCGv_i64 fp0 = tcg_temp_new_i64();
8845 TCGv_i64 fp1 = tcg_temp_new_i64();
8846 TCGv_i64 fp2 = tcg_temp_new_i64();
8847
8848 gen_load_fpr64(ctx, fp0, fs);
8849 gen_load_fpr64(ctx, fp1, ft);
8850 gen_load_fpr64(ctx, fp2, fr);
8851 gen_helper_float_muladd_ps(fp2, cpu_env, fp0, fp1, fp2);
8852 tcg_temp_free_i64(fp0);
8853 tcg_temp_free_i64(fp1);
8854 gen_store_fpr64(ctx, fp2, fd);
8855 tcg_temp_free_i64(fp2);
8856 }
8857 opn = "madd.ps";
8858 break;
8859 case OPC_MSUB_S:
8860 check_cop1x(ctx);
8861 {
8862 TCGv_i32 fp0 = tcg_temp_new_i32();
8863 TCGv_i32 fp1 = tcg_temp_new_i32();
8864 TCGv_i32 fp2 = tcg_temp_new_i32();
8865
8866 gen_load_fpr32(fp0, fs);
8867 gen_load_fpr32(fp1, ft);
8868 gen_load_fpr32(fp2, fr);
8869 gen_helper_float_mulsub_s(fp2, cpu_env, fp0, fp1, fp2);
8870 tcg_temp_free_i32(fp0);
8871 tcg_temp_free_i32(fp1);
8872 gen_store_fpr32(fp2, fd);
8873 tcg_temp_free_i32(fp2);
8874 }
8875 opn = "msub.s";
8876 break;
8877 case OPC_MSUB_D:
8878 check_cop1x(ctx);
8879 check_cp1_registers(ctx, fd | fs | ft | fr);
8880 {
8881 TCGv_i64 fp0 = tcg_temp_new_i64();
8882 TCGv_i64 fp1 = tcg_temp_new_i64();
8883 TCGv_i64 fp2 = tcg_temp_new_i64();
8884
8885 gen_load_fpr64(ctx, fp0, fs);
8886 gen_load_fpr64(ctx, fp1, ft);
8887 gen_load_fpr64(ctx, fp2, fr);
8888 gen_helper_float_mulsub_d(fp2, cpu_env, fp0, fp1, fp2);
8889 tcg_temp_free_i64(fp0);
8890 tcg_temp_free_i64(fp1);
8891 gen_store_fpr64(ctx, fp2, fd);
8892 tcg_temp_free_i64(fp2);
8893 }
8894 opn = "msub.d";
8895 break;
8896 case OPC_MSUB_PS:
8897 check_cp1_64bitmode(ctx);
8898 {
8899 TCGv_i64 fp0 = tcg_temp_new_i64();
8900 TCGv_i64 fp1 = tcg_temp_new_i64();
8901 TCGv_i64 fp2 = tcg_temp_new_i64();
8902
8903 gen_load_fpr64(ctx, fp0, fs);
8904 gen_load_fpr64(ctx, fp1, ft);
8905 gen_load_fpr64(ctx, fp2, fr);
8906 gen_helper_float_mulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8907 tcg_temp_free_i64(fp0);
8908 tcg_temp_free_i64(fp1);
8909 gen_store_fpr64(ctx, fp2, fd);
8910 tcg_temp_free_i64(fp2);
8911 }
8912 opn = "msub.ps";
8913 break;
8914 case OPC_NMADD_S:
8915 check_cop1x(ctx);
8916 {
8917 TCGv_i32 fp0 = tcg_temp_new_i32();
8918 TCGv_i32 fp1 = tcg_temp_new_i32();
8919 TCGv_i32 fp2 = tcg_temp_new_i32();
8920
8921 gen_load_fpr32(fp0, fs);
8922 gen_load_fpr32(fp1, ft);
8923 gen_load_fpr32(fp2, fr);
8924 gen_helper_float_nmuladd_s(fp2, cpu_env, fp0, fp1, fp2);
8925 tcg_temp_free_i32(fp0);
8926 tcg_temp_free_i32(fp1);
8927 gen_store_fpr32(fp2, fd);
8928 tcg_temp_free_i32(fp2);
8929 }
8930 opn = "nmadd.s";
8931 break;
8932 case OPC_NMADD_D:
8933 check_cop1x(ctx);
8934 check_cp1_registers(ctx, fd | fs | ft | fr);
8935 {
8936 TCGv_i64 fp0 = tcg_temp_new_i64();
8937 TCGv_i64 fp1 = tcg_temp_new_i64();
8938 TCGv_i64 fp2 = tcg_temp_new_i64();
8939
8940 gen_load_fpr64(ctx, fp0, fs);
8941 gen_load_fpr64(ctx, fp1, ft);
8942 gen_load_fpr64(ctx, fp2, fr);
8943 gen_helper_float_nmuladd_d(fp2, cpu_env, fp0, fp1, fp2);
8944 tcg_temp_free_i64(fp0);
8945 tcg_temp_free_i64(fp1);
8946 gen_store_fpr64(ctx, fp2, fd);
8947 tcg_temp_free_i64(fp2);
8948 }
8949 opn = "nmadd.d";
8950 break;
8951 case OPC_NMADD_PS:
8952 check_cp1_64bitmode(ctx);
8953 {
8954 TCGv_i64 fp0 = tcg_temp_new_i64();
8955 TCGv_i64 fp1 = tcg_temp_new_i64();
8956 TCGv_i64 fp2 = tcg_temp_new_i64();
8957
8958 gen_load_fpr64(ctx, fp0, fs);
8959 gen_load_fpr64(ctx, fp1, ft);
8960 gen_load_fpr64(ctx, fp2, fr);
8961 gen_helper_float_nmuladd_ps(fp2, cpu_env, fp0, fp1, fp2);
8962 tcg_temp_free_i64(fp0);
8963 tcg_temp_free_i64(fp1);
8964 gen_store_fpr64(ctx, fp2, fd);
8965 tcg_temp_free_i64(fp2);
8966 }
8967 opn = "nmadd.ps";
8968 break;
8969 case OPC_NMSUB_S:
8970 check_cop1x(ctx);
8971 {
8972 TCGv_i32 fp0 = tcg_temp_new_i32();
8973 TCGv_i32 fp1 = tcg_temp_new_i32();
8974 TCGv_i32 fp2 = tcg_temp_new_i32();
8975
8976 gen_load_fpr32(fp0, fs);
8977 gen_load_fpr32(fp1, ft);
8978 gen_load_fpr32(fp2, fr);
8979 gen_helper_float_nmulsub_s(fp2, cpu_env, fp0, fp1, fp2);
8980 tcg_temp_free_i32(fp0);
8981 tcg_temp_free_i32(fp1);
8982 gen_store_fpr32(fp2, fd);
8983 tcg_temp_free_i32(fp2);
8984 }
8985 opn = "nmsub.s";
8986 break;
8987 case OPC_NMSUB_D:
8988 check_cop1x(ctx);
8989 check_cp1_registers(ctx, fd | fs | ft | fr);
8990 {
8991 TCGv_i64 fp0 = tcg_temp_new_i64();
8992 TCGv_i64 fp1 = tcg_temp_new_i64();
8993 TCGv_i64 fp2 = tcg_temp_new_i64();
8994
8995 gen_load_fpr64(ctx, fp0, fs);
8996 gen_load_fpr64(ctx, fp1, ft);
8997 gen_load_fpr64(ctx, fp2, fr);
8998 gen_helper_float_nmulsub_d(fp2, cpu_env, fp0, fp1, fp2);
8999 tcg_temp_free_i64(fp0);
9000 tcg_temp_free_i64(fp1);
9001 gen_store_fpr64(ctx, fp2, fd);
9002 tcg_temp_free_i64(fp2);
9003 }
9004 opn = "nmsub.d";
9005 break;
9006 case OPC_NMSUB_PS:
9007 check_cp1_64bitmode(ctx);
9008 {
9009 TCGv_i64 fp0 = tcg_temp_new_i64();
9010 TCGv_i64 fp1 = tcg_temp_new_i64();
9011 TCGv_i64 fp2 = tcg_temp_new_i64();
9012
9013 gen_load_fpr64(ctx, fp0, fs);
9014 gen_load_fpr64(ctx, fp1, ft);
9015 gen_load_fpr64(ctx, fp2, fr);
9016 gen_helper_float_nmulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9017 tcg_temp_free_i64(fp0);
9018 tcg_temp_free_i64(fp1);
9019 gen_store_fpr64(ctx, fp2, fd);
9020 tcg_temp_free_i64(fp2);
9021 }
9022 opn = "nmsub.ps";
9023 break;
9024 default:
9025 MIPS_INVAL(opn);
9026 generate_exception (ctx, EXCP_RI);
9027 return;
9028 }
9029 (void)opn; /* avoid a compiler warning */
9030 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9031 fregnames[fs], fregnames[ft]);
9032 }
9033
9034 static void
9035 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9036 {
9037 TCGv t0;
9038
9039 #if !defined(CONFIG_USER_ONLY)
9040 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9041 Therefore only check the ISA in system mode. */
9042 check_insn(env, ctx, ISA_MIPS32R2);
9043 #endif
9044 t0 = tcg_temp_new();
9045
9046 switch (rd) {
9047 case 0:
9048 save_cpu_state(ctx, 1);
9049 gen_helper_rdhwr_cpunum(t0, cpu_env);
9050 gen_store_gpr(t0, rt);
9051 break;
9052 case 1:
9053 save_cpu_state(ctx, 1);
9054 gen_helper_rdhwr_synci_step(t0, cpu_env);
9055 gen_store_gpr(t0, rt);
9056 break;
9057 case 2:
9058 save_cpu_state(ctx, 1);
9059 gen_helper_rdhwr_cc(t0, cpu_env);
9060 gen_store_gpr(t0, rt);
9061 break;
9062 case 3:
9063 save_cpu_state(ctx, 1);
9064 gen_helper_rdhwr_ccres(t0, cpu_env);
9065 gen_store_gpr(t0, rt);
9066 break;
9067 case 29:
9068 #if defined(CONFIG_USER_ONLY)
9069 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9070 gen_store_gpr(t0, rt);
9071 break;
9072 #else
9073 /* XXX: Some CPUs implement this in hardware.
9074 Not supported yet. */
9075 #endif
9076 default: /* Invalid */
9077 MIPS_INVAL("rdhwr");
9078 generate_exception(ctx, EXCP_RI);
9079 break;
9080 }
9081 tcg_temp_free(t0);
9082 }
9083
9084 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9085 int insn_bytes)
9086 {
9087 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9088 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9089 /* Branches completion */
9090 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9091 ctx->bstate = BS_BRANCH;
9092 save_cpu_state(ctx, 0);
9093 /* FIXME: Need to clear can_do_io. */
9094 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9095 case MIPS_HFLAG_B:
9096 /* unconditional branch */
9097 MIPS_DEBUG("unconditional branch");
9098 if (proc_hflags & MIPS_HFLAG_BX) {
9099 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9100 }
9101 gen_goto_tb(ctx, 0, ctx->btarget);
9102 break;
9103 case MIPS_HFLAG_BL:
9104 /* blikely taken case */
9105 MIPS_DEBUG("blikely branch taken");
9106 gen_goto_tb(ctx, 0, ctx->btarget);
9107 break;
9108 case MIPS_HFLAG_BC:
9109 /* Conditional branch */
9110 MIPS_DEBUG("conditional branch");
9111 {
9112 int l1 = gen_new_label();
9113
9114 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9115 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9116 gen_set_label(l1);
9117 gen_goto_tb(ctx, 0, ctx->btarget);
9118 }
9119 break;
9120 case MIPS_HFLAG_BR:
9121 /* unconditional branch to register */
9122 MIPS_DEBUG("branch to register");
9123 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9124 TCGv t0 = tcg_temp_new();
9125 TCGv_i32 t1 = tcg_temp_new_i32();
9126
9127 tcg_gen_andi_tl(t0, btarget, 0x1);
9128 tcg_gen_trunc_tl_i32(t1, t0);
9129 tcg_temp_free(t0);
9130 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9131 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9132 tcg_gen_or_i32(hflags, hflags, t1);
9133 tcg_temp_free_i32(t1);
9134
9135 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9136 } else {
9137 tcg_gen_mov_tl(cpu_PC, btarget);
9138 }
9139 if (ctx->singlestep_enabled) {
9140 save_cpu_state(ctx, 0);
9141 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9142 }
9143 tcg_gen_exit_tb(0);
9144 break;
9145 default:
9146 MIPS_DEBUG("unknown branch");
9147 break;
9148 }
9149 }
9150 }
9151
9152 /* ISA extensions (ASEs) */
9153 /* MIPS16 extension to MIPS32 */
9154
9155 /* MIPS16 major opcodes */
9156 enum {
9157 M16_OPC_ADDIUSP = 0x00,
9158 M16_OPC_ADDIUPC = 0x01,
9159 M16_OPC_B = 0x02,
9160 M16_OPC_JAL = 0x03,
9161 M16_OPC_BEQZ = 0x04,
9162 M16_OPC_BNEQZ = 0x05,
9163 M16_OPC_SHIFT = 0x06,
9164 M16_OPC_LD = 0x07,
9165 M16_OPC_RRIA = 0x08,
9166 M16_OPC_ADDIU8 = 0x09,
9167 M16_OPC_SLTI = 0x0a,
9168 M16_OPC_SLTIU = 0x0b,
9169 M16_OPC_I8 = 0x0c,
9170 M16_OPC_LI = 0x0d,
9171 M16_OPC_CMPI = 0x0e,
9172 M16_OPC_SD = 0x0f,
9173 M16_OPC_LB = 0x10,
9174 M16_OPC_LH = 0x11,
9175 M16_OPC_LWSP = 0x12,
9176 M16_OPC_LW = 0x13,
9177 M16_OPC_LBU = 0x14,
9178 M16_OPC_LHU = 0x15,
9179 M16_OPC_LWPC = 0x16,
9180 M16_OPC_LWU = 0x17,
9181 M16_OPC_SB = 0x18,
9182 M16_OPC_SH = 0x19,
9183 M16_OPC_SWSP = 0x1a,
9184 M16_OPC_SW = 0x1b,
9185 M16_OPC_RRR = 0x1c,
9186 M16_OPC_RR = 0x1d,
9187 M16_OPC_EXTEND = 0x1e,
9188 M16_OPC_I64 = 0x1f
9189 };
9190
9191 /* I8 funct field */
9192 enum {
9193 I8_BTEQZ = 0x0,
9194 I8_BTNEZ = 0x1,
9195 I8_SWRASP = 0x2,
9196 I8_ADJSP = 0x3,
9197 I8_SVRS = 0x4,
9198 I8_MOV32R = 0x5,
9199 I8_MOVR32 = 0x7
9200 };
9201
9202 /* RRR f field */
9203 enum {
9204 RRR_DADDU = 0x0,
9205 RRR_ADDU = 0x1,
9206 RRR_DSUBU = 0x2,
9207 RRR_SUBU = 0x3
9208 };
9209
9210 /* RR funct field */
9211 enum {
9212 RR_JR = 0x00,
9213 RR_SDBBP = 0x01,
9214 RR_SLT = 0x02,
9215 RR_SLTU = 0x03,
9216 RR_SLLV = 0x04,
9217 RR_BREAK = 0x05,
9218 RR_SRLV = 0x06,
9219 RR_SRAV = 0x07,
9220 RR_DSRL = 0x08,
9221 RR_CMP = 0x0a,
9222 RR_NEG = 0x0b,
9223 RR_AND = 0x0c,
9224 RR_OR = 0x0d,
9225 RR_XOR = 0x0e,
9226 RR_NOT = 0x0f,
9227 RR_MFHI = 0x10,
9228 RR_CNVT = 0x11,
9229 RR_MFLO = 0x12,
9230 RR_DSRA = 0x13,
9231 RR_DSLLV = 0x14,
9232 RR_DSRLV = 0x16,
9233 RR_DSRAV = 0x17,
9234 RR_MULT = 0x18,
9235 RR_MULTU = 0x19,
9236 RR_DIV = 0x1a,
9237 RR_DIVU = 0x1b,
9238 RR_DMULT = 0x1c,
9239 RR_DMULTU = 0x1d,
9240 RR_DDIV = 0x1e,
9241 RR_DDIVU = 0x1f
9242 };
9243
9244 /* I64 funct field */
9245 enum {
9246 I64_LDSP = 0x0,
9247 I64_SDSP = 0x1,
9248 I64_SDRASP = 0x2,
9249 I64_DADJSP = 0x3,
9250 I64_LDPC = 0x4,
9251 I64_DADDIU5 = 0x5,
9252 I64_DADDIUPC = 0x6,
9253 I64_DADDIUSP = 0x7
9254 };
9255
9256 /* RR ry field for CNVT */
9257 enum {
9258 RR_RY_CNVT_ZEB = 0x0,
9259 RR_RY_CNVT_ZEH = 0x1,
9260 RR_RY_CNVT_ZEW = 0x2,
9261 RR_RY_CNVT_SEB = 0x4,
9262 RR_RY_CNVT_SEH = 0x5,
9263 RR_RY_CNVT_SEW = 0x6,
9264 };
9265
9266 static int xlat (int r)
9267 {
9268 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9269
9270 return map[r];
9271 }
9272
9273 static void gen_mips16_save (DisasContext *ctx,
9274 int xsregs, int aregs,
9275 int do_ra, int do_s0, int do_s1,
9276 int framesize)
9277 {
9278 TCGv t0 = tcg_temp_new();
9279 TCGv t1 = tcg_temp_new();
9280 int args, astatic;
9281
9282 switch (aregs) {
9283 case 0:
9284 case 1:
9285 case 2:
9286 case 3:
9287 case 11:
9288 args = 0;
9289 break;
9290 case 4:
9291 case 5:
9292 case 6:
9293 case 7:
9294 args = 1;
9295 break;
9296 case 8:
9297 case 9:
9298 case 10:
9299 args = 2;
9300 break;
9301 case 12:
9302 case 13:
9303 args = 3;
9304 break;
9305 case 14:
9306 args = 4;
9307 break;
9308 default:
9309 generate_exception(ctx, EXCP_RI);
9310 return;
9311 }
9312
9313 switch (args) {
9314 case 4:
9315 gen_base_offset_addr(ctx, t0, 29, 12);
9316 gen_load_gpr(t1, 7);
9317 op_st_sw(t1, t0, ctx);
9318 /* Fall through */
9319 case 3:
9320 gen_base_offset_addr(ctx, t0, 29, 8);
9321 gen_load_gpr(t1, 6);
9322 op_st_sw(t1, t0, ctx);
9323 /* Fall through */
9324 case 2:
9325 gen_base_offset_addr(ctx, t0, 29, 4);
9326 gen_load_gpr(t1, 5);
9327 op_st_sw(t1, t0, ctx);
9328 /* Fall through */
9329 case 1:
9330 gen_base_offset_addr(ctx, t0, 29, 0);
9331 gen_load_gpr(t1, 4);
9332 op_st_sw(t1, t0, ctx);
9333 }
9334
9335 gen_load_gpr(t0, 29);
9336
9337 #define DECR_AND_STORE(reg) do { \
9338 tcg_gen_subi_tl(t0, t0, 4); \
9339 gen_load_gpr(t1, reg); \
9340 op_st_sw(t1, t0, ctx); \
9341 } while (0)
9342
9343 if (do_ra) {
9344 DECR_AND_STORE(31);
9345 }
9346
9347 switch (xsregs) {
9348 case 7:
9349 DECR_AND_STORE(30);
9350 /* Fall through */
9351 case 6:
9352 DECR_AND_STORE(23);
9353 /* Fall through */
9354 case 5:
9355 DECR_AND_STORE(22);
9356 /* Fall through */
9357 case 4:
9358 DECR_AND_STORE(21);
9359 /* Fall through */
9360 case 3:
9361 DECR_AND_STORE(20);
9362 /* Fall through */
9363 case 2:
9364 DECR_AND_STORE(19);
9365 /* Fall through */
9366 case 1:
9367 DECR_AND_STORE(18);
9368 }
9369
9370 if (do_s1) {
9371 DECR_AND_STORE(17);
9372 }
9373 if (do_s0) {
9374 DECR_AND_STORE(16);
9375 }
9376
9377 switch (aregs) {
9378 case 0:
9379 case 4:
9380 case 8:
9381 case 12:
9382 case 14:
9383 astatic = 0;
9384 break;
9385 case 1:
9386 case 5:
9387 case 9:
9388 case 13:
9389 astatic = 1;
9390 break;
9391 case 2:
9392 case 6:
9393 case 10:
9394 astatic = 2;
9395 break;
9396 case 3:
9397 case 7:
9398 astatic = 3;
9399 break;
9400 case 11:
9401 astatic = 4;
9402 break;
9403 default:
9404 generate_exception(ctx, EXCP_RI);
9405 return;
9406 }
9407
9408 if (astatic > 0) {
9409 DECR_AND_STORE(7);
9410 if (astatic > 1) {
9411 DECR_AND_STORE(6);
9412 if (astatic > 2) {
9413 DECR_AND_STORE(5);
9414 if (astatic > 3) {
9415 DECR_AND_STORE(4);
9416 }
9417 }
9418 }
9419 }
9420 #undef DECR_AND_STORE
9421
9422 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9423 tcg_temp_free(t0);
9424 tcg_temp_free(t1);
9425 }
9426
9427 static void gen_mips16_restore (DisasContext *ctx,
9428 int xsregs, int aregs,
9429 int do_ra, int do_s0, int do_s1,
9430 int framesize)
9431 {
9432 int astatic;
9433 TCGv t0 = tcg_temp_new();
9434 TCGv t1 = tcg_temp_new();
9435
9436 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9437
9438 #define DECR_AND_LOAD(reg) do { \
9439 tcg_gen_subi_tl(t0, t0, 4); \
9440 op_ld_lw(t1, t0, ctx); \
9441 gen_store_gpr(t1, reg); \
9442 } while (0)
9443
9444 if (do_ra) {
9445 DECR_AND_LOAD(31);
9446 }
9447
9448 switch (xsregs) {
9449 case 7:
9450 DECR_AND_LOAD(30);
9451 /* Fall through */
9452 case 6:
9453 DECR_AND_LOAD(23);
9454 /* Fall through */
9455 case 5:
9456 DECR_AND_LOAD(22);
9457 /* Fall through */
9458 case 4:
9459 DECR_AND_LOAD(21);
9460 /* Fall through */
9461 case 3:
9462 DECR_AND_LOAD(20);
9463 /* Fall through */
9464 case 2:
9465 DECR_AND_LOAD(19);
9466 /* Fall through */
9467 case 1:
9468 DECR_AND_LOAD(18);
9469 }
9470
9471 if (do_s1) {
9472 DECR_AND_LOAD(17);
9473 }
9474 if (do_s0) {
9475 DECR_AND_LOAD(16);
9476 }
9477
9478 switch (aregs) {
9479 case 0:
9480 case 4:
9481 case 8:
9482 case 12:
9483 case 14:
9484 astatic = 0;
9485 break;
9486 case 1:
9487 case 5:
9488 case 9:
9489 case 13:
9490 astatic = 1;
9491 break;
9492 case 2:
9493 case 6:
9494 case 10:
9495 astatic = 2;
9496 break;
9497 case 3:
9498 case 7:
9499 astatic = 3;
9500 break;
9501 case 11:
9502 astatic = 4;
9503 break;
9504 default:
9505 generate_exception(ctx, EXCP_RI);
9506 return;
9507 }
9508
9509 if (astatic > 0) {
9510 DECR_AND_LOAD(7);
9511 if (astatic > 1) {
9512 DECR_AND_LOAD(6);
9513 if (astatic > 2) {
9514 DECR_AND_LOAD(5);
9515 if (astatic > 3) {
9516 DECR_AND_LOAD(4);
9517 }
9518 }
9519 }
9520 }
9521 #undef DECR_AND_LOAD
9522
9523 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9524 tcg_temp_free(t0);
9525 tcg_temp_free(t1);
9526 }
9527
9528 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9529 int is_64_bit, int extended)
9530 {
9531 TCGv t0;
9532
9533 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9534 generate_exception(ctx, EXCP_RI);
9535 return;
9536 }
9537
9538 t0 = tcg_temp_new();
9539
9540 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9541 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9542 if (!is_64_bit) {
9543 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9544 }
9545
9546 tcg_temp_free(t0);
9547 }
9548
9549 #if defined(TARGET_MIPS64)
9550 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9551 int ry, int funct, int16_t offset,
9552 int extended)
9553 {
9554 switch (funct) {
9555 case I64_LDSP:
9556 check_mips_64(ctx);
9557 offset = extended ? offset : offset << 3;
9558 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9559 break;
9560 case I64_SDSP:
9561 check_mips_64(ctx);
9562 offset = extended ? offset : offset << 3;
9563 gen_st(ctx, OPC_SD, ry, 29, offset);
9564 break;
9565 case I64_SDRASP:
9566 check_mips_64(ctx);
9567 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9568 gen_st(ctx, OPC_SD, 31, 29, offset);
9569 break;
9570 case I64_DADJSP:
9571 check_mips_64(ctx);
9572 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9573 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9574 break;
9575 case I64_LDPC:
9576 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9577 generate_exception(ctx, EXCP_RI);
9578 } else {
9579 offset = extended ? offset : offset << 3;
9580 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9581 }
9582 break;
9583 case I64_DADDIU5:
9584 check_mips_64(ctx);
9585 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9586 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9587 break;
9588 case I64_DADDIUPC:
9589 check_mips_64(ctx);
9590 offset = extended ? offset : offset << 2;
9591 gen_addiupc(ctx, ry, offset, 1, extended);
9592 break;
9593 case I64_DADDIUSP:
9594 check_mips_64(ctx);
9595 offset = extended ? offset : offset << 2;
9596 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9597 break;
9598 }
9599 }
9600 #endif
9601
9602 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9603 int *is_branch)
9604 {
9605 int extend = cpu_lduw_code(env, ctx->pc + 2);
9606 int op, rx, ry, funct, sa;
9607 int16_t imm, offset;
9608
9609 ctx->opcode = (ctx->opcode << 16) | extend;
9610 op = (ctx->opcode >> 11) & 0x1f;
9611 sa = (ctx->opcode >> 22) & 0x1f;
9612 funct = (ctx->opcode >> 8) & 0x7;
9613 rx = xlat((ctx->opcode >> 8) & 0x7);
9614 ry = xlat((ctx->opcode >> 5) & 0x7);
9615 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9616 | ((ctx->opcode >> 21) & 0x3f) << 5
9617 | (ctx->opcode & 0x1f));
9618
9619 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9620 counterparts. */
9621 switch (op) {
9622 case M16_OPC_ADDIUSP:
9623 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9624 break;
9625 case M16_OPC_ADDIUPC:
9626 gen_addiupc(ctx, rx, imm, 0, 1);
9627 break;
9628 case M16_OPC_B:
9629 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9630 /* No delay slot, so just process as a normal instruction */
9631 break;
9632 case M16_OPC_BEQZ:
9633 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9634 /* No delay slot, so just process as a normal instruction */
9635 break;
9636 case M16_OPC_BNEQZ:
9637 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9638 /* No delay slot, so just process as a normal instruction */
9639 break;
9640 case M16_OPC_SHIFT:
9641 switch (ctx->opcode & 0x3) {
9642 case 0x0:
9643 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9644 break;
9645 case 0x1:
9646 #if defined(TARGET_MIPS64)
9647 check_mips_64(ctx);
9648 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9649 #else
9650 generate_exception(ctx, EXCP_RI);
9651 #endif
9652 break;
9653 case 0x2:
9654 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9655 break;
9656 case 0x3:
9657 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9658 break;
9659 }
9660 break;
9661 #if defined(TARGET_MIPS64)
9662 case M16_OPC_LD:
9663 check_mips_64(ctx);
9664 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9665 break;
9666 #endif
9667 case M16_OPC_RRIA:
9668 imm = ctx->opcode & 0xf;
9669 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9670 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9671 imm = (int16_t) (imm << 1) >> 1;
9672 if ((ctx->opcode >> 4) & 0x1) {
9673 #if defined(TARGET_MIPS64)
9674 check_mips_64(ctx);
9675 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9676 #else
9677 generate_exception(ctx, EXCP_RI);
9678 #endif
9679 } else {
9680 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9681 }
9682 break;
9683 case M16_OPC_ADDIU8:
9684 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9685 break;
9686 case M16_OPC_SLTI:
9687 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9688 break;
9689 case M16_OPC_SLTIU:
9690 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9691 break;
9692 case M16_OPC_I8:
9693 switch (funct) {
9694 case I8_BTEQZ:
9695 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9696 break;
9697 case I8_BTNEZ:
9698 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9699 break;
9700 case I8_SWRASP:
9701 gen_st(ctx, OPC_SW, 31, 29, imm);
9702 break;
9703 case I8_ADJSP:
9704 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9705 break;
9706 case I8_SVRS:
9707 {
9708 int xsregs = (ctx->opcode >> 24) & 0x7;
9709 int aregs = (ctx->opcode >> 16) & 0xf;
9710 int do_ra = (ctx->opcode >> 6) & 0x1;
9711 int do_s0 = (ctx->opcode >> 5) & 0x1;
9712 int do_s1 = (ctx->opcode >> 4) & 0x1;
9713 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9714 | (ctx->opcode & 0xf)) << 3;
9715
9716 if (ctx->opcode & (1 << 7)) {
9717 gen_mips16_save(ctx, xsregs, aregs,
9718 do_ra, do_s0, do_s1,
9719 framesize);
9720 } else {
9721 gen_mips16_restore(ctx, xsregs, aregs,
9722 do_ra, do_s0, do_s1,
9723 framesize);
9724 }
9725 }
9726 break;
9727 default:
9728 generate_exception(ctx, EXCP_RI);
9729 break;
9730 }
9731 break;
9732 case M16_OPC_LI:
9733 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9734 break;
9735 case M16_OPC_CMPI:
9736 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9737 break;
9738 #if defined(TARGET_MIPS64)
9739 case M16_OPC_SD:
9740 gen_st(ctx, OPC_SD, ry, rx, offset);
9741 break;
9742 #endif
9743 case M16_OPC_LB:
9744 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9745 break;
9746 case M16_OPC_LH:
9747 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9748 break;
9749 case M16_OPC_LWSP:
9750 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9751 break;
9752 case M16_OPC_LW:
9753 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9754 break;
9755 case M16_OPC_LBU:
9756 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9757 break;
9758 case M16_OPC_LHU:
9759 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9760 break;
9761 case M16_OPC_LWPC:
9762 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9763 break;
9764 #if defined(TARGET_MIPS64)
9765 case M16_OPC_LWU:
9766 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9767 break;
9768 #endif
9769 case M16_OPC_SB:
9770 gen_st(ctx, OPC_SB, ry, rx, offset);
9771 break;
9772 case M16_OPC_SH:
9773 gen_st(ctx, OPC_SH, ry, rx, offset);
9774 break;
9775 case M16_OPC_SWSP:
9776 gen_st(ctx, OPC_SW, rx, 29, offset);
9777 break;
9778 case M16_OPC_SW:
9779 gen_st(ctx, OPC_SW, ry, rx, offset);
9780 break;
9781 #if defined(TARGET_MIPS64)
9782 case M16_OPC_I64:
9783 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9784 break;
9785 #endif
9786 default:
9787 generate_exception(ctx, EXCP_RI);
9788 break;
9789 }
9790
9791 return 4;
9792 }
9793
9794 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9795 int *is_branch)
9796 {
9797 int rx, ry;
9798 int sa;
9799 int op, cnvt_op, op1, offset;
9800 int funct;
9801 int n_bytes;
9802
9803 op = (ctx->opcode >> 11) & 0x1f;
9804 sa = (ctx->opcode >> 2) & 0x7;
9805 sa = sa == 0 ? 8 : sa;
9806 rx = xlat((ctx->opcode >> 8) & 0x7);
9807 cnvt_op = (ctx->opcode >> 5) & 0x7;
9808 ry = xlat((ctx->opcode >> 5) & 0x7);
9809 op1 = offset = ctx->opcode & 0x1f;
9810
9811 n_bytes = 2;
9812
9813 switch (op) {
9814 case M16_OPC_ADDIUSP:
9815 {
9816 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9817
9818 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9819 }
9820 break;
9821 case M16_OPC_ADDIUPC:
9822 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9823 break;
9824 case M16_OPC_B:
9825 offset = (ctx->opcode & 0x7ff) << 1;
9826 offset = (int16_t)(offset << 4) >> 4;
9827 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9828 /* No delay slot, so just process as a normal instruction */
9829 break;
9830 case M16_OPC_JAL:
9831 offset = cpu_lduw_code(env, ctx->pc + 2);
9832 offset = (((ctx->opcode & 0x1f) << 21)
9833 | ((ctx->opcode >> 5) & 0x1f) << 16
9834 | offset) << 2;
9835 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9836 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9837 n_bytes = 4;
9838 *is_branch = 1;
9839 break;
9840 case M16_OPC_BEQZ:
9841 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9842 /* No delay slot, so just process as a normal instruction */
9843 break;
9844 case M16_OPC_BNEQZ:
9845 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9846 /* No delay slot, so just process as a normal instruction */
9847 break;
9848 case M16_OPC_SHIFT:
9849 switch (ctx->opcode & 0x3) {
9850 case 0x0:
9851 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9852 break;
9853 case 0x1:
9854 #if defined(TARGET_MIPS64)
9855 check_mips_64(ctx);
9856 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9857 #else
9858 generate_exception(ctx, EXCP_RI);
9859 #endif
9860 break;
9861 case 0x2:
9862 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9863 break;
9864 case 0x3:
9865 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9866 break;
9867 }
9868 break;
9869 #if defined(TARGET_MIPS64)
9870 case M16_OPC_LD:
9871 check_mips_64(ctx);
9872 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9873 break;
9874 #endif
9875 case M16_OPC_RRIA:
9876 {
9877 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9878
9879 if ((ctx->opcode >> 4) & 1) {
9880 #if defined(TARGET_MIPS64)
9881 check_mips_64(ctx);
9882 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9883 #else
9884 generate_exception(ctx, EXCP_RI);
9885 #endif
9886 } else {
9887 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9888 }
9889 }
9890 break;
9891 case M16_OPC_ADDIU8:
9892 {
9893 int16_t imm = (int8_t) ctx->opcode;
9894
9895 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9896 }
9897 break;
9898 case M16_OPC_SLTI:
9899 {
9900 int16_t imm = (uint8_t) ctx->opcode;
9901 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9902 }
9903 break;
9904 case M16_OPC_SLTIU:
9905 {
9906 int16_t imm = (uint8_t) ctx->opcode;
9907 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9908 }
9909 break;
9910 case M16_OPC_I8:
9911 {
9912 int reg32;
9913
9914 funct = (ctx->opcode >> 8) & 0x7;
9915 switch (funct) {
9916 case I8_BTEQZ:
9917 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9918 ((int8_t)ctx->opcode) << 1);
9919 break;
9920 case I8_BTNEZ:
9921 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9922 ((int8_t)ctx->opcode) << 1);
9923 break;
9924 case I8_SWRASP:
9925 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9926 break;
9927 case I8_ADJSP:
9928 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9929 ((int8_t)ctx->opcode) << 3);
9930 break;
9931 case I8_SVRS:
9932 {
9933 int do_ra = ctx->opcode & (1 << 6);
9934 int do_s0 = ctx->opcode & (1 << 5);
9935 int do_s1 = ctx->opcode & (1 << 4);
9936 int framesize = ctx->opcode & 0xf;
9937
9938 if (framesize == 0) {
9939 framesize = 128;
9940 } else {
9941 framesize = framesize << 3;
9942 }
9943
9944 if (ctx->opcode & (1 << 7)) {
9945 gen_mips16_save(ctx, 0, 0,
9946 do_ra, do_s0, do_s1, framesize);
9947 } else {
9948 gen_mips16_restore(ctx, 0, 0,
9949 do_ra, do_s0, do_s1, framesize);
9950 }
9951 }
9952 break;
9953 case I8_MOV32R:
9954 {
9955 int rz = xlat(ctx->opcode & 0x7);
9956
9957 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9958 ((ctx->opcode >> 5) & 0x7);
9959 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9960 }
9961 break;
9962 case I8_MOVR32:
9963 reg32 = ctx->opcode & 0x1f;
9964 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9965 break;
9966 default:
9967 generate_exception(ctx, EXCP_RI);
9968 break;
9969 }
9970 }
9971 break;
9972 case M16_OPC_LI:
9973 {
9974 int16_t imm = (uint8_t) ctx->opcode;
9975
9976 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9977 }
9978 break;
9979 case M16_OPC_CMPI:
9980 {
9981 int16_t imm = (uint8_t) ctx->opcode;
9982 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
9983 }
9984 break;
9985 #if defined(TARGET_MIPS64)
9986 case M16_OPC_SD:
9987 check_mips_64(ctx);
9988 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9989 break;
9990 #endif
9991 case M16_OPC_LB:
9992 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9993 break;
9994 case M16_OPC_LH:
9995 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9996 break;
9997 case M16_OPC_LWSP:
9998 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9999 break;
10000 case M16_OPC_LW:
10001 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10002 break;
10003 case M16_OPC_LBU:
10004 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10005 break;
10006 case M16_OPC_LHU:
10007 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10008 break;
10009 case M16_OPC_LWPC:
10010 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10011 break;
10012 #if defined (TARGET_MIPS64)
10013 case M16_OPC_LWU:
10014 check_mips_64(ctx);
10015 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10016 break;
10017 #endif
10018 case M16_OPC_SB:
10019 gen_st(ctx, OPC_SB, ry, rx, offset);
10020 break;
10021 case M16_OPC_SH:
10022 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10023 break;
10024 case M16_OPC_SWSP:
10025 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10026 break;
10027 case M16_OPC_SW:
10028 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10029 break;
10030 case M16_OPC_RRR:
10031 {
10032 int rz = xlat((ctx->opcode >> 2) & 0x7);
10033 int mips32_op;
10034
10035 switch (ctx->opcode & 0x3) {
10036 case RRR_ADDU:
10037 mips32_op = OPC_ADDU;
10038 break;
10039 case RRR_SUBU:
10040 mips32_op = OPC_SUBU;
10041 break;
10042 #if defined(TARGET_MIPS64)
10043 case RRR_DADDU:
10044 mips32_op = OPC_DADDU;
10045 check_mips_64(ctx);
10046 break;
10047 case RRR_DSUBU:
10048 mips32_op = OPC_DSUBU;
10049 check_mips_64(ctx);
10050 break;
10051 #endif
10052 default:
10053 generate_exception(ctx, EXCP_RI);
10054 goto done;
10055 }
10056
10057 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10058 done:
10059 ;
10060 }
10061 break;
10062 case M16_OPC_RR:
10063 switch (op1) {
10064 case RR_JR:
10065 {
10066 int nd = (ctx->opcode >> 7) & 0x1;
10067 int link = (ctx->opcode >> 6) & 0x1;
10068 int ra = (ctx->opcode >> 5) & 0x1;
10069
10070 if (link) {
10071 op = nd ? OPC_JALRC : OPC_JALRS;
10072 } else {
10073 op = OPC_JR;
10074 }
10075
10076 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10077 if (!nd) {
10078 *is_branch = 1;
10079 }
10080 }
10081 break;
10082 case RR_SDBBP:
10083 /* XXX: not clear which exception should be raised
10084 * when in debug mode...
10085 */
10086 check_insn(env, ctx, ISA_MIPS32);
10087 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10088 generate_exception(ctx, EXCP_DBp);
10089 } else {
10090 generate_exception(ctx, EXCP_DBp);
10091 }
10092 break;
10093 case RR_SLT:
10094 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10095 break;
10096 case RR_SLTU:
10097 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10098 break;
10099 case RR_BREAK:
10100 generate_exception(ctx, EXCP_BREAK);
10101 break;
10102 case RR_SLLV:
10103 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10104 break;
10105 case RR_SRLV:
10106 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10107 break;
10108 case RR_SRAV:
10109 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10110 break;
10111 #if defined (TARGET_MIPS64)
10112 case RR_DSRL:
10113 check_mips_64(ctx);
10114 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10115 break;
10116 #endif
10117 case RR_CMP:
10118 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10119 break;
10120 case RR_NEG:
10121 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10122 break;
10123 case RR_AND:
10124 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10125 break;
10126 case RR_OR:
10127 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10128 break;
10129 case RR_XOR:
10130 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10131 break;
10132 case RR_NOT:
10133 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10134 break;
10135 case RR_MFHI:
10136 gen_HILO(ctx, OPC_MFHI, rx);
10137 break;
10138 case RR_CNVT:
10139 switch (cnvt_op) {
10140 case RR_RY_CNVT_ZEB:
10141 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10142 break;
10143 case RR_RY_CNVT_ZEH:
10144 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10145 break;
10146 case RR_RY_CNVT_SEB:
10147 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10148 break;
10149 case RR_RY_CNVT_SEH:
10150 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10151 break;
10152 #if defined (TARGET_MIPS64)
10153 case RR_RY_CNVT_ZEW:
10154 check_mips_64(ctx);
10155 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10156 break;
10157 case RR_RY_CNVT_SEW:
10158 check_mips_64(ctx);
10159 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10160 break;
10161 #endif
10162 default:
10163 generate_exception(ctx, EXCP_RI);
10164 break;
10165 }
10166 break;
10167 case RR_MFLO:
10168 gen_HILO(ctx, OPC_MFLO, rx);
10169 break;
10170 #if defined (TARGET_MIPS64)
10171 case RR_DSRA:
10172 check_mips_64(ctx);
10173 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10174 break;
10175 case RR_DSLLV:
10176 check_mips_64(ctx);
10177 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10178 break;
10179 case RR_DSRLV:
10180 check_mips_64(ctx);
10181 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10182 break;
10183 case RR_DSRAV:
10184 check_mips_64(ctx);
10185 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10186 break;
10187 #endif
10188 case RR_MULT:
10189 gen_muldiv(ctx, OPC_MULT, rx, ry);
10190 break;
10191 case RR_MULTU:
10192 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10193 break;
10194 case RR_DIV:
10195 gen_muldiv(ctx, OPC_DIV, rx, ry);
10196 break;
10197 case RR_DIVU:
10198 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10199 break;
10200 #if defined (TARGET_MIPS64)
10201 case RR_DMULT:
10202 check_mips_64(ctx);
10203 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10204 break;
10205 case RR_DMULTU:
10206 check_mips_64(ctx);
10207 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10208 break;
10209 case RR_DDIV:
10210 check_mips_64(ctx);
10211 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10212 break;
10213 case RR_DDIVU:
10214 check_mips_64(ctx);
10215 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10216 break;
10217 #endif
10218 default:
10219 generate_exception(ctx, EXCP_RI);
10220 break;
10221 }
10222 break;
10223 case M16_OPC_EXTEND:
10224 decode_extended_mips16_opc(env, ctx, is_branch);
10225 n_bytes = 4;
10226 break;
10227 #if defined(TARGET_MIPS64)
10228 case M16_OPC_I64:
10229 funct = (ctx->opcode >> 8) & 0x7;
10230 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10231 break;
10232 #endif
10233 default:
10234 generate_exception(ctx, EXCP_RI);
10235 break;
10236 }
10237
10238 return n_bytes;
10239 }
10240
10241 /* microMIPS extension to MIPS32 */
10242
10243 /* microMIPS32 major opcodes */
10244
10245 enum {
10246 POOL32A = 0x00,
10247 POOL16A = 0x01,
10248 LBU16 = 0x02,
10249 MOVE16 = 0x03,
10250 ADDI32 = 0x04,
10251 LBU32 = 0x05,
10252 SB32 = 0x06,
10253 LB32 = 0x07,
10254
10255 POOL32B = 0x08,
10256 POOL16B = 0x09,
10257 LHU16 = 0x0a,
10258 ANDI16 = 0x0b,
10259 ADDIU32 = 0x0c,
10260 LHU32 = 0x0d,
10261 SH32 = 0x0e,
10262 LH32 = 0x0f,
10263
10264 POOL32I = 0x10,
10265 POOL16C = 0x11,
10266 LWSP16 = 0x12,
10267 POOL16D = 0x13,
10268 ORI32 = 0x14,
10269 POOL32F = 0x15,
10270 POOL32S = 0x16,
10271 DADDIU32 = 0x17,
10272
10273 POOL32C = 0x18,
10274 LWGP16 = 0x19,
10275 LW16 = 0x1a,
10276 POOL16E = 0x1b,
10277 XORI32 = 0x1c,
10278 JALS32 = 0x1d,
10279 ADDIUPC = 0x1e,
10280 POOL48A = 0x1f,
10281
10282 /* 0x20 is reserved */
10283 RES_20 = 0x20,
10284 POOL16F = 0x21,
10285 SB16 = 0x22,
10286 BEQZ16 = 0x23,
10287 SLTI32 = 0x24,
10288 BEQ32 = 0x25,
10289 SWC132 = 0x26,
10290 LWC132 = 0x27,
10291
10292 /* 0x28 and 0x29 are reserved */
10293 RES_28 = 0x28,
10294 RES_29 = 0x29,
10295 SH16 = 0x2a,
10296 BNEZ16 = 0x2b,
10297 SLTIU32 = 0x2c,
10298 BNE32 = 0x2d,
10299 SDC132 = 0x2e,
10300 LDC132 = 0x2f,
10301
10302 /* 0x30 and 0x31 are reserved */
10303 RES_30 = 0x30,
10304 RES_31 = 0x31,
10305 SWSP16 = 0x32,
10306 B16 = 0x33,
10307 ANDI32 = 0x34,
10308 J32 = 0x35,
10309 SD32 = 0x36,
10310 LD32 = 0x37,
10311
10312 /* 0x38 and 0x39 are reserved */
10313 RES_38 = 0x38,
10314 RES_39 = 0x39,
10315 SW16 = 0x3a,
10316 LI16 = 0x3b,
10317 JALX32 = 0x3c,
10318 JAL32 = 0x3d,
10319 SW32 = 0x3e,
10320 LW32 = 0x3f
10321 };
10322
10323 /* POOL32A encoding of minor opcode field */
10324
10325 enum {
10326 /* These opcodes are distinguished only by bits 9..6; those bits are
10327 * what are recorded below. */
10328 SLL32 = 0x0,
10329 SRL32 = 0x1,
10330 SRA = 0x2,
10331 ROTR = 0x3,
10332
10333 SLLV = 0x0,
10334 SRLV = 0x1,
10335 SRAV = 0x2,
10336 ROTRV = 0x3,
10337 ADD = 0x4,
10338 ADDU32 = 0x5,
10339 SUB = 0x6,
10340 SUBU32 = 0x7,
10341 MUL = 0x8,
10342 AND = 0x9,
10343 OR32 = 0xa,
10344 NOR = 0xb,
10345 XOR32 = 0xc,
10346 SLT = 0xd,
10347 SLTU = 0xe,
10348
10349 MOVN = 0x0,
10350 MOVZ = 0x1,
10351 LWXS = 0x4,
10352
10353 /* The following can be distinguished by their lower 6 bits. */
10354 INS = 0x0c,
10355 EXT = 0x2c,
10356 POOL32AXF = 0x3c
10357 };
10358
10359 /* POOL32AXF encoding of minor opcode field extension */
10360
10361 enum {
10362 /* bits 11..6 */
10363 TEQ = 0x00,
10364 TGE = 0x08,
10365 TGEU = 0x10,
10366 TLT = 0x20,
10367 TLTU = 0x28,
10368 TNE = 0x30,
10369
10370 MFC0 = 0x03,
10371 MTC0 = 0x0b,
10372
10373 /* bits 13..12 for 0x01 */
10374 MFHI_ACC = 0x0,
10375 MFLO_ACC = 0x1,
10376 MTHI_ACC = 0x2,
10377 MTLO_ACC = 0x3,
10378
10379 /* bits 13..12 for 0x2a */
10380 MADD_ACC = 0x0,
10381 MADDU_ACC = 0x1,
10382 MSUB_ACC = 0x2,
10383 MSUBU_ACC = 0x3,
10384
10385 /* bits 13..12 for 0x32 */
10386 MULT_ACC = 0x0,
10387 MULTU_ACC = 0x0,
10388
10389 /* bits 15..12 for 0x2c */
10390 SEB = 0x2,
10391 SEH = 0x3,
10392 CLO = 0x4,
10393 CLZ = 0x5,
10394 RDHWR = 0x6,
10395 WSBH = 0x7,
10396 MULT = 0x8,
10397 MULTU = 0x9,
10398 DIV = 0xa,
10399 DIVU = 0xb,
10400 MADD = 0xc,
10401 MADDU = 0xd,
10402 MSUB = 0xe,
10403 MSUBU = 0xf,
10404
10405 /* bits 15..12 for 0x34 */
10406 MFC2 = 0x4,
10407 MTC2 = 0x5,
10408 MFHC2 = 0x8,
10409 MTHC2 = 0x9,
10410 CFC2 = 0xc,
10411 CTC2 = 0xd,
10412
10413 /* bits 15..12 for 0x3c */
10414 JALR = 0x0,
10415 JR = 0x0, /* alias */
10416 JALR_HB = 0x1,
10417 JALRS = 0x4,
10418 JALRS_HB = 0x5,
10419
10420 /* bits 15..12 for 0x05 */
10421 RDPGPR = 0xe,
10422 WRPGPR = 0xf,
10423
10424 /* bits 15..12 for 0x0d */
10425 TLBP = 0x0,
10426 TLBR = 0x1,
10427 TLBWI = 0x2,
10428 TLBWR = 0x3,
10429 WAIT = 0x9,
10430 IRET = 0xd,
10431 DERET = 0xe,
10432 ERET = 0xf,
10433
10434 /* bits 15..12 for 0x15 */
10435 DMT = 0x0,
10436 DVPE = 0x1,
10437 EMT = 0x2,
10438 EVPE = 0x3,
10439
10440 /* bits 15..12 for 0x1d */
10441 DI = 0x4,
10442 EI = 0x5,
10443
10444 /* bits 15..12 for 0x2d */
10445 SYNC = 0x6,
10446 SYSCALL = 0x8,
10447 SDBBP = 0xd,
10448
10449 /* bits 15..12 for 0x35 */
10450 MFHI32 = 0x0,
10451 MFLO32 = 0x1,
10452 MTHI32 = 0x2,
10453 MTLO32 = 0x3,
10454 };
10455
10456 /* POOL32B encoding of minor opcode field (bits 15..12) */
10457
10458 enum {
10459 LWC2 = 0x0,
10460 LWP = 0x1,
10461 LDP = 0x4,
10462 LWM32 = 0x5,
10463 CACHE = 0x6,
10464 LDM = 0x7,
10465 SWC2 = 0x8,
10466 SWP = 0x9,
10467 SDP = 0xc,
10468 SWM32 = 0xd,
10469 SDM = 0xf
10470 };
10471
10472 /* POOL32C encoding of minor opcode field (bits 15..12) */
10473
10474 enum {
10475 LWL = 0x0,
10476 SWL = 0x8,
10477 LWR = 0x1,
10478 SWR = 0x9,
10479 PREF = 0x2,
10480 /* 0xa is reserved */
10481 LL = 0x3,
10482 SC = 0xb,
10483 LDL = 0x4,
10484 SDL = 0xc,
10485 LDR = 0x5,
10486 SDR = 0xd,
10487 /* 0x6 is reserved */
10488 LWU = 0xe,
10489 LLD = 0x7,
10490 SCD = 0xf
10491 };
10492
10493 /* POOL32F encoding of minor opcode field (bits 5..0) */
10494
10495 enum {
10496 /* These are the bit 7..6 values */
10497 ADD_FMT = 0x0,
10498 MOVN_FMT = 0x0,
10499
10500 SUB_FMT = 0x1,
10501 MOVZ_FMT = 0x1,
10502
10503 MUL_FMT = 0x2,
10504
10505 DIV_FMT = 0x3,
10506
10507 /* These are the bit 8..6 values */
10508 RSQRT2_FMT = 0x0,
10509 MOVF_FMT = 0x0,
10510
10511 LWXC1 = 0x1,
10512 MOVT_FMT = 0x1,
10513
10514 PLL_PS = 0x2,
10515 SWXC1 = 0x2,
10516
10517 PLU_PS = 0x3,
10518 LDXC1 = 0x3,
10519
10520 PUL_PS = 0x4,
10521 SDXC1 = 0x4,
10522 RECIP2_FMT = 0x4,
10523
10524 PUU_PS = 0x5,
10525 LUXC1 = 0x5,
10526
10527 CVT_PS_S = 0x6,
10528 SUXC1 = 0x6,
10529 ADDR_PS = 0x6,
10530 PREFX = 0x6,
10531
10532 MULR_PS = 0x7,
10533
10534 MADD_S = 0x01,
10535 MADD_D = 0x09,
10536 MADD_PS = 0x11,
10537 ALNV_PS = 0x19,
10538 MSUB_S = 0x21,
10539 MSUB_D = 0x29,
10540 MSUB_PS = 0x31,
10541
10542 NMADD_S = 0x02,
10543 NMADD_D = 0x0a,
10544 NMADD_PS = 0x12,
10545 NMSUB_S = 0x22,
10546 NMSUB_D = 0x2a,
10547 NMSUB_PS = 0x32,
10548
10549 POOL32FXF = 0x3b,
10550
10551 CABS_COND_FMT = 0x1c, /* MIPS3D */
10552 C_COND_FMT = 0x3c
10553 };
10554
10555 /* POOL32Fxf encoding of minor opcode extension field */
10556
10557 enum {
10558 CVT_L = 0x04,
10559 RSQRT_FMT = 0x08,
10560 FLOOR_L = 0x0c,
10561 CVT_PW_PS = 0x1c,
10562 CVT_W = 0x24,
10563 SQRT_FMT = 0x28,
10564 FLOOR_W = 0x2c,
10565 CVT_PS_PW = 0x3c,
10566 CFC1 = 0x40,
10567 RECIP_FMT = 0x48,
10568 CEIL_L = 0x4c,
10569 CTC1 = 0x60,
10570 CEIL_W = 0x6c,
10571 MFC1 = 0x80,
10572 CVT_S_PL = 0x84,
10573 TRUNC_L = 0x8c,
10574 MTC1 = 0xa0,
10575 CVT_S_PU = 0xa4,
10576 TRUNC_W = 0xac,
10577 MFHC1 = 0xc0,
10578 ROUND_L = 0xcc,
10579 MTHC1 = 0xe0,
10580 ROUND_W = 0xec,
10581
10582 MOV_FMT = 0x01,
10583 MOVF = 0x05,
10584 ABS_FMT = 0x0d,
10585 RSQRT1_FMT = 0x1d,
10586 MOVT = 0x25,
10587 NEG_FMT = 0x2d,
10588 CVT_D = 0x4d,
10589 RECIP1_FMT = 0x5d,
10590 CVT_S = 0x6d
10591 };
10592
10593 /* POOL32I encoding of minor opcode field (bits 25..21) */
10594
10595 enum {
10596 BLTZ = 0x00,
10597 BLTZAL = 0x01,
10598 BGEZ = 0x02,
10599 BGEZAL = 0x03,
10600 BLEZ = 0x04,
10601 BNEZC = 0x05,
10602 BGTZ = 0x06,
10603 BEQZC = 0x07,
10604 TLTI = 0x08,
10605 TGEI = 0x09,
10606 TLTIU = 0x0a,
10607 TGEIU = 0x0b,
10608 TNEI = 0x0c,
10609 LUI = 0x0d,
10610 TEQI = 0x0e,
10611 SYNCI = 0x10,
10612 BLTZALS = 0x11,
10613 BGEZALS = 0x13,
10614 BC2F = 0x14,
10615 BC2T = 0x15,
10616 BPOSGE64 = 0x1a,
10617 BPOSGE32 = 0x1b,
10618 /* These overlap and are distinguished by bit16 of the instruction */
10619 BC1F = 0x1c,
10620 BC1T = 0x1d,
10621 BC1ANY2F = 0x1c,
10622 BC1ANY2T = 0x1d,
10623 BC1ANY4F = 0x1e,
10624 BC1ANY4T = 0x1f
10625 };
10626
10627 /* POOL16A encoding of minor opcode field */
10628
10629 enum {
10630 ADDU16 = 0x0,
10631 SUBU16 = 0x1
10632 };
10633
10634 /* POOL16B encoding of minor opcode field */
10635
10636 enum {
10637 SLL16 = 0x0,
10638 SRL16 = 0x1
10639 };
10640
10641 /* POOL16C encoding of minor opcode field */
10642
10643 enum {
10644 NOT16 = 0x00,
10645 XOR16 = 0x04,
10646 AND16 = 0x08,
10647 OR16 = 0x0c,
10648 LWM16 = 0x10,
10649 SWM16 = 0x14,
10650 JR16 = 0x18,
10651 JRC16 = 0x1a,
10652 JALR16 = 0x1c,
10653 JALR16S = 0x1e,
10654 MFHI16 = 0x20,
10655 MFLO16 = 0x24,
10656 BREAK16 = 0x28,
10657 SDBBP16 = 0x2c,
10658 JRADDIUSP = 0x30
10659 };
10660
10661 /* POOL16D encoding of minor opcode field */
10662
10663 enum {
10664 ADDIUS5 = 0x0,
10665 ADDIUSP = 0x1
10666 };
10667
10668 /* POOL16E encoding of minor opcode field */
10669
10670 enum {
10671 ADDIUR2 = 0x0,
10672 ADDIUR1SP = 0x1
10673 };
10674
10675 static int mmreg (int r)
10676 {
10677 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10678
10679 return map[r];
10680 }
10681
10682 /* Used for 16-bit store instructions. */
10683 static int mmreg2 (int r)
10684 {
10685 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10686
10687 return map[r];
10688 }
10689
10690 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10691 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10692 #define uMIPS_RS2(op) uMIPS_RS(op)
10693 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10694 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10695 #define uMIPS_RS5(op) (op & 0x1f)
10696
10697 /* Signed immediate */
10698 #define SIMM(op, start, width) \
10699 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10700 << (32-width)) \
10701 >> (32-width))
10702 /* Zero-extended immediate */
10703 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10704
10705 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10706 {
10707 int rd = mmreg(uMIPS_RD(ctx->opcode));
10708
10709 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10710 }
10711
10712 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10713 {
10714 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10715 int rd = mmreg(uMIPS_RD(ctx->opcode));
10716 int rs = mmreg(uMIPS_RS(ctx->opcode));
10717
10718 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10719 }
10720
10721 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10722 {
10723 int encoded = ZIMM(ctx->opcode, 1, 9);
10724 int decoded;
10725
10726 if (encoded <= 1) {
10727 decoded = 256 + encoded;
10728 } else if (encoded <= 255) {
10729 decoded = encoded;
10730 } else if (encoded <= 509) {
10731 decoded = encoded - 512;
10732 } else {
10733 decoded = encoded - 768;
10734 }
10735
10736 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10737 }
10738
10739 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10740 {
10741 int imm = SIMM(ctx->opcode, 1, 4);
10742 int rd = (ctx->opcode >> 5) & 0x1f;
10743
10744 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10745 }
10746
10747 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10748 {
10749 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10750 31, 32, 63, 64, 255, 32768, 65535 };
10751 int rd = mmreg(uMIPS_RD(ctx->opcode));
10752 int rs = mmreg(uMIPS_RS(ctx->opcode));
10753 int encoded = ZIMM(ctx->opcode, 0, 4);
10754
10755 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10756 }
10757
10758 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10759 int base, int16_t offset)
10760 {
10761 const char *opn = "ldst_multiple";
10762 TCGv t0, t1;
10763 TCGv_i32 t2;
10764
10765 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10766 generate_exception(ctx, EXCP_RI);
10767 return;
10768 }
10769
10770 t0 = tcg_temp_new();
10771
10772 gen_base_offset_addr(ctx, t0, base, offset);
10773
10774 t1 = tcg_const_tl(reglist);
10775 t2 = tcg_const_i32(ctx->mem_idx);
10776
10777 save_cpu_state(ctx, 1);
10778 switch (opc) {
10779 case LWM32:
10780 gen_helper_lwm(cpu_env, t0, t1, t2);
10781 opn = "lwm";
10782 break;
10783 case SWM32:
10784 gen_helper_swm(cpu_env, t0, t1, t2);
10785 opn = "swm";
10786 break;
10787 #ifdef TARGET_MIPS64
10788 case LDM:
10789 gen_helper_ldm(cpu_env, t0, t1, t2);
10790 opn = "ldm";
10791 break;
10792 case SDM:
10793 gen_helper_sdm(cpu_env, t0, t1, t2);
10794 opn = "sdm";
10795 break;
10796 #endif
10797 }
10798 (void)opn;
10799 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10800 tcg_temp_free(t0);
10801 tcg_temp_free(t1);
10802 tcg_temp_free_i32(t2);
10803 }
10804
10805
10806 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10807 {
10808 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10809 int rs = mmreg(ctx->opcode & 0x7);
10810 int opc;
10811
10812 switch (((ctx->opcode) >> 4) & 0x3f) {
10813 case NOT16 + 0:
10814 case NOT16 + 1:
10815 case NOT16 + 2:
10816 case NOT16 + 3:
10817 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10818 break;
10819 case XOR16 + 0:
10820 case XOR16 + 1:
10821 case XOR16 + 2:
10822 case XOR16 + 3:
10823 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10824 break;
10825 case AND16 + 0:
10826 case AND16 + 1:
10827 case AND16 + 2:
10828 case AND16 + 3:
10829 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10830 break;
10831 case OR16 + 0:
10832 case OR16 + 1:
10833 case OR16 + 2:
10834 case OR16 + 3:
10835 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10836 break;
10837 case LWM16 + 0:
10838 case LWM16 + 1:
10839 case LWM16 + 2:
10840 case LWM16 + 3:
10841 {
10842 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10843 int offset = ZIMM(ctx->opcode, 0, 4);
10844
10845 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10846 29, offset << 2);
10847 }
10848 break;
10849 case SWM16 + 0:
10850 case SWM16 + 1:
10851 case SWM16 + 2:
10852 case SWM16 + 3:
10853 {
10854 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10855 int offset = ZIMM(ctx->opcode, 0, 4);
10856
10857 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10858 29, offset << 2);
10859 }
10860 break;
10861 case JR16 + 0:
10862 case JR16 + 1:
10863 {
10864 int reg = ctx->opcode & 0x1f;
10865
10866 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10867 }
10868 *is_branch = 1;
10869 break;
10870 case JRC16 + 0:
10871 case JRC16 + 1:
10872 {
10873 int reg = ctx->opcode & 0x1f;
10874
10875 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10876 /* Let normal delay slot handling in our caller take us
10877 to the branch target. */
10878 }
10879 break;
10880 case JALR16 + 0:
10881 case JALR16 + 1:
10882 opc = OPC_JALR;
10883 goto do_jalr;
10884 case JALR16S + 0:
10885 case JALR16S + 1:
10886 opc = OPC_JALRS;
10887 do_jalr:
10888 {
10889 int reg = ctx->opcode & 0x1f;
10890
10891 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10892 }
10893 *is_branch = 1;
10894 break;
10895 case MFHI16 + 0:
10896 case MFHI16 + 1:
10897 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10898 break;
10899 case MFLO16 + 0:
10900 case MFLO16 + 1:
10901 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10902 break;
10903 case BREAK16:
10904 generate_exception(ctx, EXCP_BREAK);
10905 break;
10906 case SDBBP16:
10907 /* XXX: not clear which exception should be raised
10908 * when in debug mode...
10909 */
10910 check_insn(env, ctx, ISA_MIPS32);
10911 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10912 generate_exception(ctx, EXCP_DBp);
10913 } else {
10914 generate_exception(ctx, EXCP_DBp);
10915 }
10916 break;
10917 case JRADDIUSP + 0:
10918 case JRADDIUSP + 1:
10919 {
10920 int imm = ZIMM(ctx->opcode, 0, 5);
10921
10922 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10923 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10924 /* Let normal delay slot handling in our caller take us
10925 to the branch target. */
10926 }
10927 break;
10928 default:
10929 generate_exception(ctx, EXCP_RI);
10930 break;
10931 }
10932 }
10933
10934 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10935 {
10936 TCGv t0 = tcg_temp_new();
10937 TCGv t1 = tcg_temp_new();
10938
10939 gen_load_gpr(t0, base);
10940
10941 if (index != 0) {
10942 gen_load_gpr(t1, index);
10943 tcg_gen_shli_tl(t1, t1, 2);
10944 gen_op_addr_add(ctx, t0, t1, t0);
10945 }
10946
10947 save_cpu_state(ctx, 0);
10948 op_ld_lw(t1, t0, ctx);
10949 gen_store_gpr(t1, rd);
10950
10951 tcg_temp_free(t0);
10952 tcg_temp_free(t1);
10953 }
10954
10955 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10956 int base, int16_t offset)
10957 {
10958 const char *opn = "ldst_pair";
10959 TCGv t0, t1;
10960
10961 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10962 generate_exception(ctx, EXCP_RI);
10963 return;
10964 }
10965
10966 t0 = tcg_temp_new();
10967 t1 = tcg_temp_new();
10968
10969 gen_base_offset_addr(ctx, t0, base, offset);
10970
10971 switch (opc) {
10972 case LWP:
10973 if (rd == base) {
10974 generate_exception(ctx, EXCP_RI);
10975 return;
10976 }
10977 save_cpu_state(ctx, 0);
10978 op_ld_lw(t1, t0, ctx);
10979 gen_store_gpr(t1, rd);
10980 tcg_gen_movi_tl(t1, 4);
10981 gen_op_addr_add(ctx, t0, t0, t1);
10982 op_ld_lw(t1, t0, ctx);
10983 gen_store_gpr(t1, rd+1);
10984 opn = "lwp";
10985 break;
10986 case SWP:
10987 save_cpu_state(ctx, 0);
10988 gen_load_gpr(t1, rd);
10989 op_st_sw(t1, t0, ctx);
10990 tcg_gen_movi_tl(t1, 4);
10991 gen_op_addr_add(ctx, t0, t0, t1);
10992 gen_load_gpr(t1, rd+1);
10993 op_st_sw(t1, t0, ctx);
10994 opn = "swp";
10995 break;
10996 #ifdef TARGET_MIPS64
10997 case LDP:
10998 if (rd == base) {
10999 generate_exception(ctx, EXCP_RI);
11000 return;
11001 }
11002 save_cpu_state(ctx, 0);
11003 op_ld_ld(t1, t0, ctx);
11004 gen_store_gpr(t1, rd);
11005 tcg_gen_movi_tl(t1, 8);
11006 gen_op_addr_add(ctx, t0, t0, t1);
11007 op_ld_ld(t1, t0, ctx);
11008 gen_store_gpr(t1, rd+1);
11009 opn = "ldp";
11010 break;
11011 case SDP:
11012 save_cpu_state(ctx, 0);
11013 gen_load_gpr(t1, rd);
11014 op_st_sd(t1, t0, ctx);
11015 tcg_gen_movi_tl(t1, 8);
11016 gen_op_addr_add(ctx, t0, t0, t1);
11017 gen_load_gpr(t1, rd+1);
11018 op_st_sd(t1, t0, ctx);
11019 opn = "sdp";
11020 break;
11021 #endif
11022 }
11023 (void)opn; /* avoid a compiler warning */
11024 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11025 tcg_temp_free(t0);
11026 tcg_temp_free(t1);
11027 }
11028
11029 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11030 int *is_branch)
11031 {
11032 int extension = (ctx->opcode >> 6) & 0x3f;
11033 int minor = (ctx->opcode >> 12) & 0xf;
11034 uint32_t mips32_op;
11035
11036 switch (extension) {
11037 case TEQ:
11038 mips32_op = OPC_TEQ;
11039 goto do_trap;
11040 case TGE:
11041 mips32_op = OPC_TGE;
11042 goto do_trap;
11043 case TGEU:
11044 mips32_op = OPC_TGEU;
11045 goto do_trap;
11046 case TLT:
11047 mips32_op = OPC_TLT;
11048 goto do_trap;
11049 case TLTU:
11050 mips32_op = OPC_TLTU;
11051 goto do_trap;
11052 case TNE:
11053 mips32_op = OPC_TNE;
11054 do_trap:
11055 gen_trap(ctx, mips32_op, rs, rt, -1);
11056 break;
11057 #ifndef CONFIG_USER_ONLY
11058 case MFC0:
11059 case MFC0 + 32:
11060 check_cp0_enabled(ctx);
11061 if (rt == 0) {
11062 /* Treat as NOP. */
11063 break;
11064 }
11065 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11066 break;
11067 case MTC0:
11068 case MTC0 + 32:
11069 check_cp0_enabled(ctx);
11070 {
11071 TCGv t0 = tcg_temp_new();
11072
11073 gen_load_gpr(t0, rt);
11074 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11075 tcg_temp_free(t0);
11076 }
11077 break;
11078 #endif
11079 case 0x2c:
11080 switch (minor) {
11081 case SEB:
11082 gen_bshfl(ctx, OPC_SEB, rs, rt);
11083 break;
11084 case SEH:
11085 gen_bshfl(ctx, OPC_SEH, rs, rt);
11086 break;
11087 case CLO:
11088 mips32_op = OPC_CLO;
11089 goto do_cl;
11090 case CLZ:
11091 mips32_op = OPC_CLZ;
11092 do_cl:
11093 check_insn(env, ctx, ISA_MIPS32);
11094 gen_cl(ctx, mips32_op, rt, rs);
11095 break;
11096 case RDHWR:
11097 gen_rdhwr(env, ctx, rt, rs);
11098 break;
11099 case WSBH:
11100 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11101 break;
11102 case MULT:
11103 mips32_op = OPC_MULT;
11104 goto do_muldiv;
11105 case MULTU:
11106 mips32_op = OPC_MULTU;
11107 goto do_muldiv;
11108 case DIV:
11109 mips32_op = OPC_DIV;
11110 goto do_muldiv;
11111 case DIVU:
11112 mips32_op = OPC_DIVU;
11113 goto do_muldiv;
11114 case MADD:
11115 mips32_op = OPC_MADD;
11116 goto do_muldiv;
11117 case MADDU:
11118 mips32_op = OPC_MADDU;
11119 goto do_muldiv;
11120 case MSUB:
11121 mips32_op = OPC_MSUB;
11122 goto do_muldiv;
11123 case MSUBU:
11124 mips32_op = OPC_MSUBU;
11125 do_muldiv:
11126 check_insn(env, ctx, ISA_MIPS32);
11127 gen_muldiv(ctx, mips32_op, rs, rt);
11128 break;
11129 default:
11130 goto pool32axf_invalid;
11131 }
11132 break;
11133 case 0x34:
11134 switch (minor) {
11135 case MFC2:
11136 case MTC2:
11137 case MFHC2:
11138 case MTHC2:
11139 case CFC2:
11140 case CTC2:
11141 generate_exception_err(ctx, EXCP_CpU, 2);
11142 break;
11143 default:
11144 goto pool32axf_invalid;
11145 }
11146 break;
11147 case 0x3c:
11148 switch (minor) {
11149 case JALR:
11150 case JALR_HB:
11151 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11152 *is_branch = 1;
11153 break;
11154 case JALRS:
11155 case JALRS_HB:
11156 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11157 *is_branch = 1;
11158 break;
11159 default:
11160 goto pool32axf_invalid;
11161 }
11162 break;
11163 case 0x05:
11164 switch (minor) {
11165 case RDPGPR:
11166 check_cp0_enabled(ctx);
11167 check_insn(env, ctx, ISA_MIPS32R2);
11168 gen_load_srsgpr(rt, rs);
11169 break;
11170 case WRPGPR:
11171 check_cp0_enabled(ctx);
11172 check_insn(env, ctx, ISA_MIPS32R2);
11173 gen_store_srsgpr(rt, rs);
11174 break;
11175 default:
11176 goto pool32axf_invalid;
11177 }
11178 break;
11179 #ifndef CONFIG_USER_ONLY
11180 case 0x0d:
11181 switch (minor) {
11182 case TLBP:
11183 mips32_op = OPC_TLBP;
11184 goto do_cp0;
11185 case TLBR:
11186 mips32_op = OPC_TLBR;
11187 goto do_cp0;
11188 case TLBWI:
11189 mips32_op = OPC_TLBWI;
11190 goto do_cp0;
11191 case TLBWR:
11192 mips32_op = OPC_TLBWR;
11193 goto do_cp0;
11194 case WAIT:
11195 mips32_op = OPC_WAIT;
11196 goto do_cp0;
11197 case DERET:
11198 mips32_op = OPC_DERET;
11199 goto do_cp0;
11200 case ERET:
11201 mips32_op = OPC_ERET;
11202 do_cp0:
11203 gen_cp0(env, ctx, mips32_op, rt, rs);
11204 break;
11205 default:
11206 goto pool32axf_invalid;
11207 }
11208 break;
11209 case 0x1d:
11210 switch (minor) {
11211 case DI:
11212 check_cp0_enabled(ctx);
11213 {
11214 TCGv t0 = tcg_temp_new();
11215
11216 save_cpu_state(ctx, 1);
11217 gen_helper_di(t0, cpu_env);
11218 gen_store_gpr(t0, rs);
11219 /* Stop translation as we may have switched the execution mode */
11220 ctx->bstate = BS_STOP;
11221 tcg_temp_free(t0);
11222 }
11223 break;
11224 case EI:
11225 check_cp0_enabled(ctx);
11226 {
11227 TCGv t0 = tcg_temp_new();
11228
11229 save_cpu_state(ctx, 1);
11230 gen_helper_ei(t0, cpu_env);
11231 gen_store_gpr(t0, rs);
11232 /* Stop translation as we may have switched the execution mode */
11233 ctx->bstate = BS_STOP;
11234 tcg_temp_free(t0);
11235 }
11236 break;
11237 default:
11238 goto pool32axf_invalid;
11239 }
11240 break;
11241 #endif
11242 case 0x2d:
11243 switch (minor) {
11244 case SYNC:
11245 /* NOP */
11246 break;
11247 case SYSCALL:
11248 generate_exception(ctx, EXCP_SYSCALL);
11249 ctx->bstate = BS_STOP;
11250 break;
11251 case SDBBP:
11252 check_insn(env, ctx, ISA_MIPS32);
11253 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11254 generate_exception(ctx, EXCP_DBp);
11255 } else {
11256 generate_exception(ctx, EXCP_DBp);
11257 }
11258 break;
11259 default:
11260 goto pool32axf_invalid;
11261 }
11262 break;
11263 case 0x35:
11264 switch (minor) {
11265 case MFHI32:
11266 gen_HILO(ctx, OPC_MFHI, rs);
11267 break;
11268 case MFLO32:
11269 gen_HILO(ctx, OPC_MFLO, rs);
11270 break;
11271 case MTHI32:
11272 gen_HILO(ctx, OPC_MTHI, rs);
11273 break;
11274 case MTLO32:
11275 gen_HILO(ctx, OPC_MTLO, rs);
11276 break;
11277 default:
11278 goto pool32axf_invalid;
11279 }
11280 break;
11281 default:
11282 pool32axf_invalid:
11283 MIPS_INVAL("pool32axf");
11284 generate_exception(ctx, EXCP_RI);
11285 break;
11286 }
11287 }
11288
11289 /* Values for microMIPS fmt field. Variable-width, depending on which
11290 formats the instruction supports. */
11291
11292 enum {
11293 FMT_SD_S = 0,
11294 FMT_SD_D = 1,
11295
11296 FMT_SDPS_S = 0,
11297 FMT_SDPS_D = 1,
11298 FMT_SDPS_PS = 2,
11299
11300 FMT_SWL_S = 0,
11301 FMT_SWL_W = 1,
11302 FMT_SWL_L = 2,
11303
11304 FMT_DWL_D = 0,
11305 FMT_DWL_W = 1,
11306 FMT_DWL_L = 2
11307 };
11308
11309 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11310 {
11311 int extension = (ctx->opcode >> 6) & 0x3ff;
11312 uint32_t mips32_op;
11313
11314 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11315 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11316 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11317
11318 switch (extension) {
11319 case FLOAT_1BIT_FMT(CFC1, 0):
11320 mips32_op = OPC_CFC1;
11321 goto do_cp1;
11322 case FLOAT_1BIT_FMT(CTC1, 0):
11323 mips32_op = OPC_CTC1;
11324 goto do_cp1;
11325 case FLOAT_1BIT_FMT(MFC1, 0):
11326 mips32_op = OPC_MFC1;
11327 goto do_cp1;
11328 case FLOAT_1BIT_FMT(MTC1, 0):
11329 mips32_op = OPC_MTC1;
11330 goto do_cp1;
11331 case FLOAT_1BIT_FMT(MFHC1, 0):
11332 mips32_op = OPC_MFHC1;
11333 goto do_cp1;
11334 case FLOAT_1BIT_FMT(MTHC1, 0):
11335 mips32_op = OPC_MTHC1;
11336 do_cp1:
11337 gen_cp1(ctx, mips32_op, rt, rs);
11338 break;
11339
11340 /* Reciprocal square root */
11341 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11342 mips32_op = OPC_RSQRT_S;
11343 goto do_unaryfp;
11344 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11345 mips32_op = OPC_RSQRT_D;
11346 goto do_unaryfp;
11347
11348 /* Square root */
11349 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11350 mips32_op = OPC_SQRT_S;
11351 goto do_unaryfp;
11352 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11353 mips32_op = OPC_SQRT_D;
11354 goto do_unaryfp;
11355
11356 /* Reciprocal */
11357 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11358 mips32_op = OPC_RECIP_S;
11359 goto do_unaryfp;
11360 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11361 mips32_op = OPC_RECIP_D;
11362 goto do_unaryfp;
11363
11364 /* Floor */
11365 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11366 mips32_op = OPC_FLOOR_L_S;
11367 goto do_unaryfp;
11368 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11369 mips32_op = OPC_FLOOR_L_D;
11370 goto do_unaryfp;
11371 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11372 mips32_op = OPC_FLOOR_W_S;
11373 goto do_unaryfp;
11374 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11375 mips32_op = OPC_FLOOR_W_D;
11376 goto do_unaryfp;
11377
11378 /* Ceiling */
11379 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11380 mips32_op = OPC_CEIL_L_S;
11381 goto do_unaryfp;
11382 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11383 mips32_op = OPC_CEIL_L_D;
11384 goto do_unaryfp;
11385 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11386 mips32_op = OPC_CEIL_W_S;
11387 goto do_unaryfp;
11388 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11389 mips32_op = OPC_CEIL_W_D;
11390 goto do_unaryfp;
11391
11392 /* Truncation */
11393 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11394 mips32_op = OPC_TRUNC_L_S;
11395 goto do_unaryfp;
11396 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11397 mips32_op = OPC_TRUNC_L_D;
11398 goto do_unaryfp;
11399 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11400 mips32_op = OPC_TRUNC_W_S;
11401 goto do_unaryfp;
11402 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11403 mips32_op = OPC_TRUNC_W_D;
11404 goto do_unaryfp;
11405
11406 /* Round */
11407 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11408 mips32_op = OPC_ROUND_L_S;
11409 goto do_unaryfp;
11410 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11411 mips32_op = OPC_ROUND_L_D;
11412 goto do_unaryfp;
11413 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11414 mips32_op = OPC_ROUND_W_S;
11415 goto do_unaryfp;
11416 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11417 mips32_op = OPC_ROUND_W_D;
11418 goto do_unaryfp;
11419
11420 /* Integer to floating-point conversion */
11421 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11422 mips32_op = OPC_CVT_L_S;
11423 goto do_unaryfp;
11424 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11425 mips32_op = OPC_CVT_L_D;
11426 goto do_unaryfp;
11427 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11428 mips32_op = OPC_CVT_W_S;
11429 goto do_unaryfp;
11430 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11431 mips32_op = OPC_CVT_W_D;
11432 goto do_unaryfp;
11433
11434 /* Paired-foo conversions */
11435 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11436 mips32_op = OPC_CVT_S_PL;
11437 goto do_unaryfp;
11438 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11439 mips32_op = OPC_CVT_S_PU;
11440 goto do_unaryfp;
11441 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11442 mips32_op = OPC_CVT_PW_PS;
11443 goto do_unaryfp;
11444 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11445 mips32_op = OPC_CVT_PS_PW;
11446 goto do_unaryfp;
11447
11448 /* Floating-point moves */
11449 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11450 mips32_op = OPC_MOV_S;
11451 goto do_unaryfp;
11452 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11453 mips32_op = OPC_MOV_D;
11454 goto do_unaryfp;
11455 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11456 mips32_op = OPC_MOV_PS;
11457 goto do_unaryfp;
11458
11459 /* Absolute value */
11460 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11461 mips32_op = OPC_ABS_S;
11462 goto do_unaryfp;
11463 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11464 mips32_op = OPC_ABS_D;
11465 goto do_unaryfp;
11466 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11467 mips32_op = OPC_ABS_PS;
11468 goto do_unaryfp;
11469
11470 /* Negation */
11471 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11472 mips32_op = OPC_NEG_S;
11473 goto do_unaryfp;
11474 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11475 mips32_op = OPC_NEG_D;
11476 goto do_unaryfp;
11477 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11478 mips32_op = OPC_NEG_PS;
11479 goto do_unaryfp;
11480
11481 /* Reciprocal square root step */
11482 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11483 mips32_op = OPC_RSQRT1_S;
11484 goto do_unaryfp;
11485 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11486 mips32_op = OPC_RSQRT1_D;
11487 goto do_unaryfp;
11488 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11489 mips32_op = OPC_RSQRT1_PS;
11490 goto do_unaryfp;
11491
11492 /* Reciprocal step */
11493 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11494 mips32_op = OPC_RECIP1_S;
11495 goto do_unaryfp;
11496 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11497 mips32_op = OPC_RECIP1_S;
11498 goto do_unaryfp;
11499 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11500 mips32_op = OPC_RECIP1_PS;
11501 goto do_unaryfp;
11502
11503 /* Conversions from double */
11504 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11505 mips32_op = OPC_CVT_D_S;
11506 goto do_unaryfp;
11507 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11508 mips32_op = OPC_CVT_D_W;
11509 goto do_unaryfp;
11510 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11511 mips32_op = OPC_CVT_D_L;
11512 goto do_unaryfp;
11513
11514 /* Conversions from single */
11515 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11516 mips32_op = OPC_CVT_S_D;
11517 goto do_unaryfp;
11518 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11519 mips32_op = OPC_CVT_S_W;
11520 goto do_unaryfp;
11521 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11522 mips32_op = OPC_CVT_S_L;
11523 do_unaryfp:
11524 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11525 break;
11526
11527 /* Conditional moves on floating-point codes */
11528 case COND_FLOAT_MOV(MOVT, 0):
11529 case COND_FLOAT_MOV(MOVT, 1):
11530 case COND_FLOAT_MOV(MOVT, 2):
11531 case COND_FLOAT_MOV(MOVT, 3):
11532 case COND_FLOAT_MOV(MOVT, 4):
11533 case COND_FLOAT_MOV(MOVT, 5):
11534 case COND_FLOAT_MOV(MOVT, 6):
11535 case COND_FLOAT_MOV(MOVT, 7):
11536 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11537 break;
11538 case COND_FLOAT_MOV(MOVF, 0):
11539 case COND_FLOAT_MOV(MOVF, 1):
11540 case COND_FLOAT_MOV(MOVF, 2):
11541 case COND_FLOAT_MOV(MOVF, 3):
11542 case COND_FLOAT_MOV(MOVF, 4):
11543 case COND_FLOAT_MOV(MOVF, 5):
11544 case COND_FLOAT_MOV(MOVF, 6):
11545 case COND_FLOAT_MOV(MOVF, 7):
11546 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11547 break;
11548 default:
11549 MIPS_INVAL("pool32fxf");
11550 generate_exception(ctx, EXCP_RI);
11551 break;
11552 }
11553 }
11554
11555 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11556 uint16_t insn_hw1, int *is_branch)
11557 {
11558 int32_t offset;
11559 uint16_t insn;
11560 int rt, rs, rd, rr;
11561 int16_t imm;
11562 uint32_t op, minor, mips32_op;
11563 uint32_t cond, fmt, cc;
11564
11565 insn = cpu_lduw_code(env, ctx->pc + 2);
11566 ctx->opcode = (ctx->opcode << 16) | insn;
11567
11568 rt = (ctx->opcode >> 21) & 0x1f;
11569 rs = (ctx->opcode >> 16) & 0x1f;
11570 rd = (ctx->opcode >> 11) & 0x1f;
11571 rr = (ctx->opcode >> 6) & 0x1f;
11572 imm = (int16_t) ctx->opcode;
11573
11574 op = (ctx->opcode >> 26) & 0x3f;
11575 switch (op) {
11576 case POOL32A:
11577 minor = ctx->opcode & 0x3f;
11578 switch (minor) {
11579 case 0x00:
11580 minor = (ctx->opcode >> 6) & 0xf;
11581 switch (minor) {
11582 case SLL32:
11583 mips32_op = OPC_SLL;
11584 goto do_shifti;
11585 case SRA:
11586 mips32_op = OPC_SRA;
11587 goto do_shifti;
11588 case SRL32:
11589 mips32_op = OPC_SRL;
11590 goto do_shifti;
11591 case ROTR:
11592 mips32_op = OPC_ROTR;
11593 do_shifti:
11594 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11595 break;
11596 default:
11597 goto pool32a_invalid;
11598 }
11599 break;
11600 case 0x10:
11601 minor = (ctx->opcode >> 6) & 0xf;
11602 switch (minor) {
11603 /* Arithmetic */
11604 case ADD:
11605 mips32_op = OPC_ADD;
11606 goto do_arith;
11607 case ADDU32:
11608 mips32_op = OPC_ADDU;
11609 goto do_arith;
11610 case SUB:
11611 mips32_op = OPC_SUB;
11612 goto do_arith;
11613 case SUBU32:
11614 mips32_op = OPC_SUBU;
11615 goto do_arith;
11616 case MUL:
11617 mips32_op = OPC_MUL;
11618 do_arith:
11619 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11620 break;
11621 /* Shifts */
11622 case SLLV:
11623 mips32_op = OPC_SLLV;
11624 goto do_shift;
11625 case SRLV:
11626 mips32_op = OPC_SRLV;
11627 goto do_shift;
11628 case SRAV:
11629 mips32_op = OPC_SRAV;
11630 goto do_shift;
11631 case ROTRV:
11632 mips32_op = OPC_ROTRV;
11633 do_shift:
11634 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11635 break;
11636 /* Logical operations */
11637 case AND:
11638 mips32_op = OPC_AND;
11639 goto do_logic;
11640 case OR32:
11641 mips32_op = OPC_OR;
11642 goto do_logic;
11643 case NOR:
11644 mips32_op = OPC_NOR;
11645 goto do_logic;
11646 case XOR32:
11647 mips32_op = OPC_XOR;
11648 do_logic:
11649 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11650 break;
11651 /* Set less than */
11652 case SLT:
11653 mips32_op = OPC_SLT;
11654 goto do_slt;
11655 case SLTU:
11656 mips32_op = OPC_SLTU;
11657 do_slt:
11658 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11659 break;
11660 default:
11661 goto pool32a_invalid;
11662 }
11663 break;
11664 case 0x18:
11665 minor = (ctx->opcode >> 6) & 0xf;
11666 switch (minor) {
11667 /* Conditional moves */
11668 case MOVN:
11669 mips32_op = OPC_MOVN;
11670 goto do_cmov;
11671 case MOVZ:
11672 mips32_op = OPC_MOVZ;
11673 do_cmov:
11674 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11675 break;
11676 case LWXS:
11677 gen_ldxs(ctx, rs, rt, rd);
11678 break;
11679 default:
11680 goto pool32a_invalid;
11681 }
11682 break;
11683 case INS:
11684 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11685 return;
11686 case EXT:
11687 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11688 return;
11689 case POOL32AXF:
11690 gen_pool32axf(env, ctx, rt, rs, is_branch);
11691 break;
11692 case 0x07:
11693 generate_exception(ctx, EXCP_BREAK);
11694 break;
11695 default:
11696 pool32a_invalid:
11697 MIPS_INVAL("pool32a");
11698 generate_exception(ctx, EXCP_RI);
11699 break;
11700 }
11701 break;
11702 case POOL32B:
11703 minor = (ctx->opcode >> 12) & 0xf;
11704 switch (minor) {
11705 case CACHE:
11706 check_cp0_enabled(ctx);
11707 /* Treat as no-op. */
11708 break;
11709 case LWC2:
11710 case SWC2:
11711 /* COP2: Not implemented. */
11712 generate_exception_err(ctx, EXCP_CpU, 2);
11713 break;
11714 case LWP:
11715 case SWP:
11716 #ifdef TARGET_MIPS64
11717 case LDP:
11718 case SDP:
11719 #endif
11720 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11721 break;
11722 case LWM32:
11723 case SWM32:
11724 #ifdef TARGET_MIPS64
11725 case LDM:
11726 case SDM:
11727 #endif
11728 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11729 break;
11730 default:
11731 MIPS_INVAL("pool32b");
11732 generate_exception(ctx, EXCP_RI);
11733 break;
11734 }
11735 break;
11736 case POOL32F:
11737 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11738 minor = ctx->opcode & 0x3f;
11739 check_cp1_enabled(ctx);
11740 switch (minor) {
11741 case ALNV_PS:
11742 mips32_op = OPC_ALNV_PS;
11743 goto do_madd;
11744 case MADD_S:
11745 mips32_op = OPC_MADD_S;
11746 goto do_madd;
11747 case MADD_D:
11748 mips32_op = OPC_MADD_D;
11749 goto do_madd;
11750 case MADD_PS:
11751 mips32_op = OPC_MADD_PS;
11752 goto do_madd;
11753 case MSUB_S:
11754 mips32_op = OPC_MSUB_S;
11755 goto do_madd;
11756 case MSUB_D:
11757 mips32_op = OPC_MSUB_D;
11758 goto do_madd;
11759 case MSUB_PS:
11760 mips32_op = OPC_MSUB_PS;
11761 goto do_madd;
11762 case NMADD_S:
11763 mips32_op = OPC_NMADD_S;
11764 goto do_madd;
11765 case NMADD_D:
11766 mips32_op = OPC_NMADD_D;
11767 goto do_madd;
11768 case NMADD_PS:
11769 mips32_op = OPC_NMADD_PS;
11770 goto do_madd;
11771 case NMSUB_S:
11772 mips32_op = OPC_NMSUB_S;
11773 goto do_madd;
11774 case NMSUB_D:
11775 mips32_op = OPC_NMSUB_D;
11776 goto do_madd;
11777 case NMSUB_PS:
11778 mips32_op = OPC_NMSUB_PS;
11779 do_madd:
11780 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11781 break;
11782 case CABS_COND_FMT:
11783 cond = (ctx->opcode >> 6) & 0xf;
11784 cc = (ctx->opcode >> 13) & 0x7;
11785 fmt = (ctx->opcode >> 10) & 0x3;
11786 switch (fmt) {
11787 case 0x0:
11788 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11789 break;
11790 case 0x1:
11791 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11792 break;
11793 case 0x2:
11794 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11795 break;
11796 default:
11797 goto pool32f_invalid;
11798 }
11799 break;
11800 case C_COND_FMT:
11801 cond = (ctx->opcode >> 6) & 0xf;
11802 cc = (ctx->opcode >> 13) & 0x7;
11803 fmt = (ctx->opcode >> 10) & 0x3;
11804 switch (fmt) {
11805 case 0x0:
11806 gen_cmp_s(ctx, cond, rt, rs, cc);
11807 break;
11808 case 0x1:
11809 gen_cmp_d(ctx, cond, rt, rs, cc);
11810 break;
11811 case 0x2:
11812 gen_cmp_ps(ctx, cond, rt, rs, cc);
11813 break;
11814 default:
11815 goto pool32f_invalid;
11816 }
11817 break;
11818 case POOL32FXF:
11819 gen_pool32fxf(env, ctx, rt, rs);
11820 break;
11821 case 0x00:
11822 /* PLL foo */
11823 switch ((ctx->opcode >> 6) & 0x7) {
11824 case PLL_PS:
11825 mips32_op = OPC_PLL_PS;
11826 goto do_ps;
11827 case PLU_PS:
11828 mips32_op = OPC_PLU_PS;
11829 goto do_ps;
11830 case PUL_PS:
11831 mips32_op = OPC_PUL_PS;
11832 goto do_ps;
11833 case PUU_PS:
11834 mips32_op = OPC_PUU_PS;
11835 goto do_ps;
11836 case CVT_PS_S:
11837 mips32_op = OPC_CVT_PS_S;
11838 do_ps:
11839 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11840 break;
11841 default:
11842 goto pool32f_invalid;
11843 }
11844 break;
11845 case 0x08:
11846 /* [LS][WDU]XC1 */
11847 switch ((ctx->opcode >> 6) & 0x7) {
11848 case LWXC1:
11849 mips32_op = OPC_LWXC1;
11850 goto do_ldst_cp1;
11851 case SWXC1:
11852 mips32_op = OPC_SWXC1;
11853 goto do_ldst_cp1;
11854 case LDXC1:
11855 mips32_op = OPC_LDXC1;
11856 goto do_ldst_cp1;
11857 case SDXC1:
11858 mips32_op = OPC_SDXC1;
11859 goto do_ldst_cp1;
11860 case LUXC1:
11861 mips32_op = OPC_LUXC1;
11862 goto do_ldst_cp1;
11863 case SUXC1:
11864 mips32_op = OPC_SUXC1;
11865 do_ldst_cp1:
11866 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11867 break;
11868 default:
11869 goto pool32f_invalid;
11870 }
11871 break;
11872 case 0x18:
11873 /* 3D insns */
11874 fmt = (ctx->opcode >> 9) & 0x3;
11875 switch ((ctx->opcode >> 6) & 0x7) {
11876 case RSQRT2_FMT:
11877 switch (fmt) {
11878 case FMT_SDPS_S:
11879 mips32_op = OPC_RSQRT2_S;
11880 goto do_3d;
11881 case FMT_SDPS_D:
11882 mips32_op = OPC_RSQRT2_D;
11883 goto do_3d;
11884 case FMT_SDPS_PS:
11885 mips32_op = OPC_RSQRT2_PS;
11886 goto do_3d;
11887 default:
11888 goto pool32f_invalid;
11889 }
11890 break;
11891 case RECIP2_FMT:
11892 switch (fmt) {
11893 case FMT_SDPS_S:
11894 mips32_op = OPC_RECIP2_S;
11895 goto do_3d;
11896 case FMT_SDPS_D:
11897 mips32_op = OPC_RECIP2_D;
11898 goto do_3d;
11899 case FMT_SDPS_PS:
11900 mips32_op = OPC_RECIP2_PS;
11901 goto do_3d;
11902 default:
11903 goto pool32f_invalid;
11904 }
11905 break;
11906 case ADDR_PS:
11907 mips32_op = OPC_ADDR_PS;
11908 goto do_3d;
11909 case MULR_PS:
11910 mips32_op = OPC_MULR_PS;
11911 do_3d:
11912 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11913 break;
11914 default:
11915 goto pool32f_invalid;
11916 }
11917 break;
11918 case 0x20:
11919 /* MOV[FT].fmt and PREFX */
11920 cc = (ctx->opcode >> 13) & 0x7;
11921 fmt = (ctx->opcode >> 9) & 0x3;
11922 switch ((ctx->opcode >> 6) & 0x7) {
11923 case MOVF_FMT:
11924 switch (fmt) {
11925 case FMT_SDPS_S:
11926 gen_movcf_s(rs, rt, cc, 0);
11927 break;
11928 case FMT_SDPS_D:
11929 gen_movcf_d(ctx, rs, rt, cc, 0);
11930 break;
11931 case FMT_SDPS_PS:
11932 gen_movcf_ps(rs, rt, cc, 0);
11933 break;
11934 default:
11935 goto pool32f_invalid;
11936 }
11937 break;
11938 case MOVT_FMT:
11939 switch (fmt) {
11940 case FMT_SDPS_S:
11941 gen_movcf_s(rs, rt, cc, 1);
11942 break;
11943 case FMT_SDPS_D:
11944 gen_movcf_d(ctx, rs, rt, cc, 1);
11945 break;
11946 case FMT_SDPS_PS:
11947 gen_movcf_ps(rs, rt, cc, 1);
11948 break;
11949 default:
11950 goto pool32f_invalid;
11951 }
11952 break;
11953 case PREFX:
11954 break;
11955 default:
11956 goto pool32f_invalid;
11957 }
11958 break;
11959 #define FINSN_3ARG_SDPS(prfx) \
11960 switch ((ctx->opcode >> 8) & 0x3) { \
11961 case FMT_SDPS_S: \
11962 mips32_op = OPC_##prfx##_S; \
11963 goto do_fpop; \
11964 case FMT_SDPS_D: \
11965 mips32_op = OPC_##prfx##_D; \
11966 goto do_fpop; \
11967 case FMT_SDPS_PS: \
11968 mips32_op = OPC_##prfx##_PS; \
11969 goto do_fpop; \
11970 default: \
11971 goto pool32f_invalid; \
11972 }
11973 case 0x30:
11974 /* regular FP ops */
11975 switch ((ctx->opcode >> 6) & 0x3) {
11976 case ADD_FMT:
11977 FINSN_3ARG_SDPS(ADD);
11978 break;
11979 case SUB_FMT:
11980 FINSN_3ARG_SDPS(SUB);
11981 break;
11982 case MUL_FMT:
11983 FINSN_3ARG_SDPS(MUL);
11984 break;
11985 case DIV_FMT:
11986 fmt = (ctx->opcode >> 8) & 0x3;
11987 if (fmt == 1) {
11988 mips32_op = OPC_DIV_D;
11989 } else if (fmt == 0) {
11990 mips32_op = OPC_DIV_S;
11991 } else {
11992 goto pool32f_invalid;
11993 }
11994 goto do_fpop;
11995 default:
11996 goto pool32f_invalid;
11997 }
11998 break;
11999 case 0x38:
12000 /* cmovs */
12001 switch ((ctx->opcode >> 6) & 0x3) {
12002 case MOVN_FMT:
12003 FINSN_3ARG_SDPS(MOVN);
12004 break;
12005 case MOVZ_FMT:
12006 FINSN_3ARG_SDPS(MOVZ);
12007 break;
12008 default:
12009 goto pool32f_invalid;
12010 }
12011 break;
12012 do_fpop:
12013 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12014 break;
12015 default:
12016 pool32f_invalid:
12017 MIPS_INVAL("pool32f");
12018 generate_exception(ctx, EXCP_RI);
12019 break;
12020 }
12021 } else {
12022 generate_exception_err(ctx, EXCP_CpU, 1);
12023 }
12024 break;
12025 case POOL32I:
12026 minor = (ctx->opcode >> 21) & 0x1f;
12027 switch (minor) {
12028 case BLTZ:
12029 mips32_op = OPC_BLTZ;
12030 goto do_branch;
12031 case BLTZAL:
12032 mips32_op = OPC_BLTZAL;
12033 goto do_branch;
12034 case BLTZALS:
12035 mips32_op = OPC_BLTZALS;
12036 goto do_branch;
12037 case BGEZ:
12038 mips32_op = OPC_BGEZ;
12039 goto do_branch;
12040 case BGEZAL:
12041 mips32_op = OPC_BGEZAL;
12042 goto do_branch;
12043 case BGEZALS:
12044 mips32_op = OPC_BGEZALS;
12045 goto do_branch;
12046 case BLEZ:
12047 mips32_op = OPC_BLEZ;
12048 goto do_branch;
12049 case BGTZ:
12050 mips32_op = OPC_BGTZ;
12051 do_branch:
12052 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12053 *is_branch = 1;
12054 break;
12055
12056 /* Traps */
12057 case TLTI:
12058 mips32_op = OPC_TLTI;
12059 goto do_trapi;
12060 case TGEI:
12061 mips32_op = OPC_TGEI;
12062 goto do_trapi;
12063 case TLTIU:
12064 mips32_op = OPC_TLTIU;
12065 goto do_trapi;
12066 case TGEIU:
12067 mips32_op = OPC_TGEIU;
12068 goto do_trapi;
12069 case TNEI:
12070 mips32_op = OPC_TNEI;
12071 goto do_trapi;
12072 case TEQI:
12073 mips32_op = OPC_TEQI;
12074 do_trapi:
12075 gen_trap(ctx, mips32_op, rs, -1, imm);
12076 break;
12077
12078 case BNEZC:
12079 case BEQZC:
12080 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12081 4, rs, 0, imm << 1);
12082 /* Compact branches don't have a delay slot, so just let
12083 the normal delay slot handling take us to the branch
12084 target. */
12085 break;
12086 case LUI:
12087 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12088 break;
12089 case SYNCI:
12090 break;
12091 case BC2F:
12092 case BC2T:
12093 /* COP2: Not implemented. */
12094 generate_exception_err(ctx, EXCP_CpU, 2);
12095 break;
12096 case BC1F:
12097 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12098 goto do_cp1branch;
12099 case BC1T:
12100 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12101 goto do_cp1branch;
12102 case BC1ANY4F:
12103 mips32_op = OPC_BC1FANY4;
12104 goto do_cp1mips3d;
12105 case BC1ANY4T:
12106 mips32_op = OPC_BC1TANY4;
12107 do_cp1mips3d:
12108 check_cop1x(ctx);
12109 check_insn(env, ctx, ASE_MIPS3D);
12110 /* Fall through */
12111 do_cp1branch:
12112 gen_compute_branch1(env, ctx, mips32_op,
12113 (ctx->opcode >> 18) & 0x7, imm << 1);
12114 *is_branch = 1;
12115 break;
12116 case BPOSGE64:
12117 case BPOSGE32:
12118 /* MIPS DSP: not implemented */
12119 /* Fall through */
12120 default:
12121 MIPS_INVAL("pool32i");
12122 generate_exception(ctx, EXCP_RI);
12123 break;
12124 }
12125 break;
12126 case POOL32C:
12127 minor = (ctx->opcode >> 12) & 0xf;
12128 switch (minor) {
12129 case LWL:
12130 mips32_op = OPC_LWL;
12131 goto do_ld_lr;
12132 case SWL:
12133 mips32_op = OPC_SWL;
12134 goto do_st_lr;
12135 case LWR:
12136 mips32_op = OPC_LWR;
12137 goto do_ld_lr;
12138 case SWR:
12139 mips32_op = OPC_SWR;
12140 goto do_st_lr;
12141 #if defined(TARGET_MIPS64)
12142 case LDL:
12143 mips32_op = OPC_LDL;
12144 goto do_ld_lr;
12145 case SDL:
12146 mips32_op = OPC_SDL;
12147 goto do_st_lr;
12148 case LDR:
12149 mips32_op = OPC_LDR;
12150 goto do_ld_lr;
12151 case SDR:
12152 mips32_op = OPC_SDR;
12153 goto do_st_lr;
12154 case LWU:
12155 mips32_op = OPC_LWU;
12156 goto do_ld_lr;
12157 case LLD:
12158 mips32_op = OPC_LLD;
12159 goto do_ld_lr;
12160 #endif
12161 case LL:
12162 mips32_op = OPC_LL;
12163 goto do_ld_lr;
12164 do_ld_lr:
12165 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12166 break;
12167 do_st_lr:
12168 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12169 break;
12170 case SC:
12171 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12172 break;
12173 #if defined(TARGET_MIPS64)
12174 case SCD:
12175 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12176 break;
12177 #endif
12178 case PREF:
12179 /* Treat as no-op */
12180 break;
12181 default:
12182 MIPS_INVAL("pool32c");
12183 generate_exception(ctx, EXCP_RI);
12184 break;
12185 }
12186 break;
12187 case ADDI32:
12188 mips32_op = OPC_ADDI;
12189 goto do_addi;
12190 case ADDIU32:
12191 mips32_op = OPC_ADDIU;
12192 do_addi:
12193 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12194 break;
12195
12196 /* Logical operations */
12197 case ORI32:
12198 mips32_op = OPC_ORI;
12199 goto do_logici;
12200 case XORI32:
12201 mips32_op = OPC_XORI;
12202 goto do_logici;
12203 case ANDI32:
12204 mips32_op = OPC_ANDI;
12205 do_logici:
12206 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12207 break;
12208
12209 /* Set less than immediate */
12210 case SLTI32:
12211 mips32_op = OPC_SLTI;
12212 goto do_slti;
12213 case SLTIU32:
12214 mips32_op = OPC_SLTIU;
12215 do_slti:
12216 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12217 break;
12218 case JALX32:
12219 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12220 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12221 *is_branch = 1;
12222 break;
12223 case JALS32:
12224 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12225 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12226 *is_branch = 1;
12227 break;
12228 case BEQ32:
12229 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12230 *is_branch = 1;
12231 break;
12232 case BNE32:
12233 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12234 *is_branch = 1;
12235 break;
12236 case J32:
12237 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12238 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12239 *is_branch = 1;
12240 break;
12241 case JAL32:
12242 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12243 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12244 *is_branch = 1;
12245 break;
12246 /* Floating point (COP1) */
12247 case LWC132:
12248 mips32_op = OPC_LWC1;
12249 goto do_cop1;
12250 case LDC132:
12251 mips32_op = OPC_LDC1;
12252 goto do_cop1;
12253 case SWC132:
12254 mips32_op = OPC_SWC1;
12255 goto do_cop1;
12256 case SDC132:
12257 mips32_op = OPC_SDC1;
12258 do_cop1:
12259 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12260 break;
12261 case ADDIUPC:
12262 {
12263 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12264 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12265
12266 gen_addiupc(ctx, reg, offset, 0, 0);
12267 }
12268 break;
12269 /* Loads and stores */
12270 case LB32:
12271 mips32_op = OPC_LB;
12272 goto do_ld;
12273 case LBU32:
12274 mips32_op = OPC_LBU;
12275 goto do_ld;
12276 case LH32:
12277 mips32_op = OPC_LH;
12278 goto do_ld;
12279 case LHU32:
12280 mips32_op = OPC_LHU;
12281 goto do_ld;
12282 case LW32:
12283 mips32_op = OPC_LW;
12284 goto do_ld;
12285 #ifdef TARGET_MIPS64
12286 case LD32:
12287 mips32_op = OPC_LD;
12288 goto do_ld;
12289 case SD32:
12290 mips32_op = OPC_SD;
12291 goto do_st;
12292 #endif
12293 case SB32:
12294 mips32_op = OPC_SB;
12295 goto do_st;
12296 case SH32:
12297 mips32_op = OPC_SH;
12298 goto do_st;
12299 case SW32:
12300 mips32_op = OPC_SW;
12301 goto do_st;
12302 do_ld:
12303 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12304 break;
12305 do_st:
12306 gen_st(ctx, mips32_op, rt, rs, imm);
12307 break;
12308 default:
12309 generate_exception(ctx, EXCP_RI);
12310 break;
12311 }
12312 }
12313
12314 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12315 {
12316 uint32_t op;
12317
12318 /* make sure instructions are on a halfword boundary */
12319 if (ctx->pc & 0x1) {
12320 env->CP0_BadVAddr = ctx->pc;
12321 generate_exception(ctx, EXCP_AdEL);
12322 ctx->bstate = BS_STOP;
12323 return 2;
12324 }
12325
12326 op = (ctx->opcode >> 10) & 0x3f;
12327 /* Enforce properly-sized instructions in a delay slot */
12328 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12329 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12330
12331 switch (op) {
12332 case POOL32A:
12333 case POOL32B:
12334 case POOL32I:
12335 case POOL32C:
12336 case ADDI32:
12337 case ADDIU32:
12338 case ORI32:
12339 case XORI32:
12340 case SLTI32:
12341 case SLTIU32:
12342 case ANDI32:
12343 case JALX32:
12344 case LBU32:
12345 case LHU32:
12346 case POOL32F:
12347 case JALS32:
12348 case BEQ32:
12349 case BNE32:
12350 case J32:
12351 case JAL32:
12352 case SB32:
12353 case SH32:
12354 case POOL32S:
12355 case ADDIUPC:
12356 case SWC132:
12357 case SDC132:
12358 case SD32:
12359 case SW32:
12360 case LB32:
12361 case LH32:
12362 case DADDIU32:
12363 case POOL48A: /* ??? */
12364 case LWC132:
12365 case LDC132:
12366 case LD32:
12367 case LW32:
12368 if (bits & MIPS_HFLAG_BDS16) {
12369 generate_exception(ctx, EXCP_RI);
12370 /* Just stop translation; the user is confused. */
12371 ctx->bstate = BS_STOP;
12372 return 2;
12373 }
12374 break;
12375 case POOL16A:
12376 case POOL16B:
12377 case POOL16C:
12378 case LWGP16:
12379 case POOL16F:
12380 case LBU16:
12381 case LHU16:
12382 case LWSP16:
12383 case LW16:
12384 case SB16:
12385 case SH16:
12386 case SWSP16:
12387 case SW16:
12388 case MOVE16:
12389 case ANDI16:
12390 case POOL16D:
12391 case POOL16E:
12392 case BEQZ16:
12393 case BNEZ16:
12394 case B16:
12395 case LI16:
12396 if (bits & MIPS_HFLAG_BDS32) {
12397 generate_exception(ctx, EXCP_RI);
12398 /* Just stop translation; the user is confused. */
12399 ctx->bstate = BS_STOP;
12400 return 2;
12401 }
12402 break;
12403 default:
12404 break;
12405 }
12406 }
12407 switch (op) {
12408 case POOL16A:
12409 {
12410 int rd = mmreg(uMIPS_RD(ctx->opcode));
12411 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12412 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12413 uint32_t opc = 0;
12414
12415 switch (ctx->opcode & 0x1) {
12416 case ADDU16:
12417 opc = OPC_ADDU;
12418 break;
12419 case SUBU16:
12420 opc = OPC_SUBU;
12421 break;
12422 }
12423
12424 gen_arith(env, ctx, opc, rd, rs1, rs2);
12425 }
12426 break;
12427 case POOL16B:
12428 {
12429 int rd = mmreg(uMIPS_RD(ctx->opcode));
12430 int rs = mmreg(uMIPS_RS(ctx->opcode));
12431 int amount = (ctx->opcode >> 1) & 0x7;
12432 uint32_t opc = 0;
12433 amount = amount == 0 ? 8 : amount;
12434
12435 switch (ctx->opcode & 0x1) {
12436 case SLL16:
12437 opc = OPC_SLL;
12438 break;
12439 case SRL16:
12440 opc = OPC_SRL;
12441 break;
12442 }
12443
12444 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12445 }
12446 break;
12447 case POOL16C:
12448 gen_pool16c_insn(env, ctx, is_branch);
12449 break;
12450 case LWGP16:
12451 {
12452 int rd = mmreg(uMIPS_RD(ctx->opcode));
12453 int rb = 28; /* GP */
12454 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12455
12456 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12457 }
12458 break;
12459 case POOL16F:
12460 if (ctx->opcode & 1) {
12461 generate_exception(ctx, EXCP_RI);
12462 } else {
12463 /* MOVEP */
12464 int enc_dest = uMIPS_RD(ctx->opcode);
12465 int enc_rt = uMIPS_RS2(ctx->opcode);
12466 int enc_rs = uMIPS_RS1(ctx->opcode);
12467 int rd, rs, re, rt;
12468 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12469 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12470 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12471
12472 rd = rd_enc[enc_dest];
12473 re = re_enc[enc_dest];
12474 rs = rs_rt_enc[enc_rs];
12475 rt = rs_rt_enc[enc_rt];
12476
12477 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12478 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12479 }
12480 break;
12481 case LBU16:
12482 {
12483 int rd = mmreg(uMIPS_RD(ctx->opcode));
12484 int rb = mmreg(uMIPS_RS(ctx->opcode));
12485 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12486 offset = (offset == 0xf ? -1 : offset);
12487
12488 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12489 }
12490 break;
12491 case LHU16:
12492 {
12493 int rd = mmreg(uMIPS_RD(ctx->opcode));
12494 int rb = mmreg(uMIPS_RS(ctx->opcode));
12495 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12496
12497 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12498 }
12499 break;
12500 case LWSP16:
12501 {
12502 int rd = (ctx->opcode >> 5) & 0x1f;
12503 int rb = 29; /* SP */
12504 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12505
12506 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12507 }
12508 break;
12509 case LW16:
12510 {
12511 int rd = mmreg(uMIPS_RD(ctx->opcode));
12512 int rb = mmreg(uMIPS_RS(ctx->opcode));
12513 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12514
12515 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12516 }
12517 break;
12518 case SB16:
12519 {
12520 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12521 int rb = mmreg(uMIPS_RS(ctx->opcode));
12522 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12523
12524 gen_st(ctx, OPC_SB, rd, rb, offset);
12525 }
12526 break;
12527 case SH16:
12528 {
12529 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12530 int rb = mmreg(uMIPS_RS(ctx->opcode));
12531 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12532
12533 gen_st(ctx, OPC_SH, rd, rb, offset);
12534 }
12535 break;
12536 case SWSP16:
12537 {
12538 int rd = (ctx->opcode >> 5) & 0x1f;
12539 int rb = 29; /* SP */
12540 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12541
12542 gen_st(ctx, OPC_SW, rd, rb, offset);
12543 }
12544 break;
12545 case SW16:
12546 {
12547 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12548 int rb = mmreg(uMIPS_RS(ctx->opcode));
12549 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12550
12551 gen_st(ctx, OPC_SW, rd, rb, offset);
12552 }
12553 break;
12554 case MOVE16:
12555 {
12556 int rd = uMIPS_RD5(ctx->opcode);
12557 int rs = uMIPS_RS5(ctx->opcode);
12558
12559 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12560 }
12561 break;
12562 case ANDI16:
12563 gen_andi16(env, ctx);
12564 break;
12565 case POOL16D:
12566 switch (ctx->opcode & 0x1) {
12567 case ADDIUS5:
12568 gen_addius5(env, ctx);
12569 break;
12570 case ADDIUSP:
12571 gen_addiusp(env, ctx);
12572 break;
12573 }
12574 break;
12575 case POOL16E:
12576 switch (ctx->opcode & 0x1) {
12577 case ADDIUR2:
12578 gen_addiur2(env, ctx);
12579 break;
12580 case ADDIUR1SP:
12581 gen_addiur1sp(env, ctx);
12582 break;
12583 }
12584 break;
12585 case B16:
12586 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12587 SIMM(ctx->opcode, 0, 10) << 1);
12588 *is_branch = 1;
12589 break;
12590 case BNEZ16:
12591 case BEQZ16:
12592 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12593 mmreg(uMIPS_RD(ctx->opcode)),
12594 0, SIMM(ctx->opcode, 0, 7) << 1);
12595 *is_branch = 1;
12596 break;
12597 case LI16:
12598 {
12599 int reg = mmreg(uMIPS_RD(ctx->opcode));
12600 int imm = ZIMM(ctx->opcode, 0, 7);
12601
12602 imm = (imm == 0x7f ? -1 : imm);
12603 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12604 }
12605 break;
12606 case RES_20:
12607 case RES_28:
12608 case RES_29:
12609 case RES_30:
12610 case RES_31:
12611 case RES_38:
12612 case RES_39:
12613 generate_exception(ctx, EXCP_RI);
12614 break;
12615 default:
12616 decode_micromips32_opc (env, ctx, op, is_branch);
12617 return 4;
12618 }
12619
12620 return 2;
12621 }
12622
12623 /* SmartMIPS extension to MIPS32 */
12624
12625 #if defined(TARGET_MIPS64)
12626
12627 /* MDMX extension to MIPS64 */
12628
12629 #endif
12630
12631 /* MIPSDSP functions. */
12632 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12633 int rd, int base, int offset)
12634 {
12635 const char *opn = "ldx";
12636 TCGv t0;
12637
12638 if (rd == 0) {
12639 MIPS_DEBUG("NOP");
12640 return;
12641 }
12642
12643 check_dsp(ctx);
12644 t0 = tcg_temp_new();
12645
12646 if (base == 0) {
12647 gen_load_gpr(t0, offset);
12648 } else if (offset == 0) {
12649 gen_load_gpr(t0, base);
12650 } else {
12651 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12652 }
12653
12654 save_cpu_state(ctx, 0);
12655 switch (opc) {
12656 case OPC_LBUX:
12657 op_ld_lbu(t0, t0, ctx);
12658 gen_store_gpr(t0, rd);
12659 opn = "lbux";
12660 break;
12661 case OPC_LHX:
12662 op_ld_lh(t0, t0, ctx);
12663 gen_store_gpr(t0, rd);
12664 opn = "lhx";
12665 break;
12666 case OPC_LWX:
12667 op_ld_lw(t0, t0, ctx);
12668 gen_store_gpr(t0, rd);
12669 opn = "lwx";
12670 break;
12671 #if defined(TARGET_MIPS64)
12672 case OPC_LDX:
12673 op_ld_ld(t0, t0, ctx);
12674 gen_store_gpr(t0, rd);
12675 opn = "ldx";
12676 break;
12677 #endif
12678 }
12679 (void)opn; /* avoid a compiler warning */
12680 MIPS_DEBUG("%s %s, %s(%s)", opn,
12681 regnames[rd], regnames[offset], regnames[base]);
12682 tcg_temp_free(t0);
12683 }
12684
12685 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12686 int ret, int v1, int v2)
12687 {
12688 const char *opn = "mipsdsp arith";
12689 TCGv v1_t;
12690 TCGv v2_t;
12691
12692 if (ret == 0) {
12693 /* Treat as NOP. */
12694 MIPS_DEBUG("NOP");
12695 return;
12696 }
12697
12698 v1_t = tcg_temp_new();
12699 v2_t = tcg_temp_new();
12700
12701 gen_load_gpr(v1_t, v1);
12702 gen_load_gpr(v2_t, v2);
12703
12704 switch (op1) {
12705 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12706 case OPC_MULT_G_2E:
12707 check_dspr2(ctx);
12708 switch (op2) {
12709 case OPC_ADDUH_QB:
12710 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12711 break;
12712 case OPC_ADDUH_R_QB:
12713 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12714 break;
12715 case OPC_ADDQH_PH:
12716 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12717 break;
12718 case OPC_ADDQH_R_PH:
12719 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12720 break;
12721 case OPC_ADDQH_W:
12722 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12723 break;
12724 case OPC_ADDQH_R_W:
12725 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12726 break;
12727 case OPC_SUBUH_QB:
12728 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12729 break;
12730 case OPC_SUBUH_R_QB:
12731 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12732 break;
12733 case OPC_SUBQH_PH:
12734 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12735 break;
12736 case OPC_SUBQH_R_PH:
12737 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12738 break;
12739 case OPC_SUBQH_W:
12740 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12741 break;
12742 case OPC_SUBQH_R_W:
12743 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12744 break;
12745 }
12746 break;
12747 case OPC_ABSQ_S_PH_DSP:
12748 switch (op2) {
12749 case OPC_ABSQ_S_QB:
12750 check_dspr2(ctx);
12751 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12752 break;
12753 case OPC_ABSQ_S_PH:
12754 check_dsp(ctx);
12755 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12756 break;
12757 case OPC_ABSQ_S_W:
12758 check_dsp(ctx);
12759 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12760 break;
12761 case OPC_PRECEQ_W_PHL:
12762 check_dsp(ctx);
12763 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12764 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12765 break;
12766 case OPC_PRECEQ_W_PHR:
12767 check_dsp(ctx);
12768 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12769 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12770 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12771 break;
12772 case OPC_PRECEQU_PH_QBL:
12773 check_dsp(ctx);
12774 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12775 break;
12776 case OPC_PRECEQU_PH_QBR:
12777 check_dsp(ctx);
12778 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12779 break;
12780 case OPC_PRECEQU_PH_QBLA:
12781 check_dsp(ctx);
12782 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12783 break;
12784 case OPC_PRECEQU_PH_QBRA:
12785 check_dsp(ctx);
12786 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12787 break;
12788 case OPC_PRECEU_PH_QBL:
12789 check_dsp(ctx);
12790 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12791 break;
12792 case OPC_PRECEU_PH_QBR:
12793 check_dsp(ctx);
12794 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12795 break;
12796 case OPC_PRECEU_PH_QBLA:
12797 check_dsp(ctx);
12798 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12799 break;
12800 case OPC_PRECEU_PH_QBRA:
12801 check_dsp(ctx);
12802 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12803 break;
12804 }
12805 break;
12806 case OPC_ADDU_QB_DSP:
12807 switch (op2) {
12808 case OPC_ADDQ_PH:
12809 check_dsp(ctx);
12810 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12811 break;
12812 case OPC_ADDQ_S_PH:
12813 check_dsp(ctx);
12814 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12815 break;
12816 case OPC_ADDQ_S_W:
12817 check_dsp(ctx);
12818 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12819 break;
12820 case OPC_ADDU_QB:
12821 check_dsp(ctx);
12822 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12823 break;
12824 case OPC_ADDU_S_QB:
12825 check_dsp(ctx);
12826 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12827 break;
12828 case OPC_ADDU_PH:
12829 check_dspr2(ctx);
12830 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12831 break;
12832 case OPC_ADDU_S_PH:
12833 check_dspr2(ctx);
12834 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12835 break;
12836 case OPC_SUBQ_PH:
12837 check_dsp(ctx);
12838 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12839 break;
12840 case OPC_SUBQ_S_PH:
12841 check_dsp(ctx);
12842 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12843 break;
12844 case OPC_SUBQ_S_W:
12845 check_dsp(ctx);
12846 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12847 break;
12848 case OPC_SUBU_QB:
12849 check_dsp(ctx);
12850 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12851 break;
12852 case OPC_SUBU_S_QB:
12853 check_dsp(ctx);
12854 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12855 break;
12856 case OPC_SUBU_PH:
12857 check_dspr2(ctx);
12858 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12859 break;
12860 case OPC_SUBU_S_PH:
12861 check_dspr2(ctx);
12862 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12863 break;
12864 case OPC_ADDSC:
12865 check_dsp(ctx);
12866 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12867 break;
12868 case OPC_ADDWC:
12869 check_dsp(ctx);
12870 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12871 break;
12872 case OPC_MODSUB:
12873 check_dsp(ctx);
12874 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12875 break;
12876 case OPC_RADDU_W_QB:
12877 check_dsp(ctx);
12878 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12879 break;
12880 }
12881 break;
12882 case OPC_CMPU_EQ_QB_DSP:
12883 switch (op2) {
12884 case OPC_PRECR_QB_PH:
12885 check_dspr2(ctx);
12886 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12887 break;
12888 case OPC_PRECRQ_QB_PH:
12889 check_dsp(ctx);
12890 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12891 break;
12892 case OPC_PRECR_SRA_PH_W:
12893 check_dspr2(ctx);
12894 {
12895 TCGv_i32 sa_t = tcg_const_i32(v2);
12896 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12897 cpu_gpr[ret]);
12898 tcg_temp_free_i32(sa_t);
12899 break;
12900 }
12901 case OPC_PRECR_SRA_R_PH_W:
12902 check_dspr2(ctx);
12903 {
12904 TCGv_i32 sa_t = tcg_const_i32(v2);
12905 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12906 cpu_gpr[ret]);
12907 tcg_temp_free_i32(sa_t);
12908 break;
12909 }
12910 case OPC_PRECRQ_PH_W:
12911 check_dsp(ctx);
12912 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12913 break;
12914 case OPC_PRECRQ_RS_PH_W:
12915 check_dsp(ctx);
12916 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12917 break;
12918 case OPC_PRECRQU_S_QB_PH:
12919 check_dsp(ctx);
12920 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12921 break;
12922 }
12923 break;
12924 #ifdef TARGET_MIPS64
12925 case OPC_ABSQ_S_QH_DSP:
12926 switch (op2) {
12927 case OPC_PRECEQ_L_PWL:
12928 check_dsp(ctx);
12929 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12930 break;
12931 case OPC_PRECEQ_L_PWR:
12932 check_dsp(ctx);
12933 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12934 break;
12935 case OPC_PRECEQ_PW_QHL:
12936 check_dsp(ctx);
12937 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12938 break;
12939 case OPC_PRECEQ_PW_QHR:
12940 check_dsp(ctx);
12941 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12942 break;
12943 case OPC_PRECEQ_PW_QHLA:
12944 check_dsp(ctx);
12945 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12946 break;
12947 case OPC_PRECEQ_PW_QHRA:
12948 check_dsp(ctx);
12949 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12950 break;
12951 case OPC_PRECEQU_QH_OBL:
12952 check_dsp(ctx);
12953 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12954 break;
12955 case OPC_PRECEQU_QH_OBR:
12956 check_dsp(ctx);
12957 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12958 break;
12959 case OPC_PRECEQU_QH_OBLA:
12960 check_dsp(ctx);
12961 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12962 break;
12963 case OPC_PRECEQU_QH_OBRA:
12964 check_dsp(ctx);
12965 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12966 break;
12967 case OPC_PRECEU_QH_OBL:
12968 check_dsp(ctx);
12969 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12970 break;
12971 case OPC_PRECEU_QH_OBR:
12972 check_dsp(ctx);
12973 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12974 break;
12975 case OPC_PRECEU_QH_OBLA:
12976 check_dsp(ctx);
12977 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12978 break;
12979 case OPC_PRECEU_QH_OBRA:
12980 check_dsp(ctx);
12981 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12982 break;
12983 case OPC_ABSQ_S_OB:
12984 check_dspr2(ctx);
12985 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12986 break;
12987 case OPC_ABSQ_S_PW:
12988 check_dsp(ctx);
12989 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12990 break;
12991 case OPC_ABSQ_S_QH:
12992 check_dsp(ctx);
12993 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12994 break;
12995 }
12996 break;
12997 case OPC_ADDU_OB_DSP:
12998 switch (op2) {
12999 case OPC_RADDU_L_OB:
13000 check_dsp(ctx);
13001 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13002 break;
13003 case OPC_SUBQ_PW:
13004 check_dsp(ctx);
13005 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13006 break;
13007 case OPC_SUBQ_S_PW:
13008 check_dsp(ctx);
13009 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13010 break;
13011 case OPC_SUBQ_QH:
13012 check_dsp(ctx);
13013 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13014 break;
13015 case OPC_SUBQ_S_QH:
13016 check_dsp(ctx);
13017 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13018 break;
13019 case OPC_SUBU_OB:
13020 check_dsp(ctx);
13021 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13022 break;
13023 case OPC_SUBU_S_OB:
13024 check_dsp(ctx);
13025 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13026 break;
13027 case OPC_SUBU_QH:
13028 check_dspr2(ctx);
13029 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13030 break;
13031 case OPC_SUBU_S_QH:
13032 check_dspr2(ctx);
13033 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13034 break;
13035 case OPC_SUBUH_OB:
13036 check_dspr2(ctx);
13037 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13038 break;
13039 case OPC_SUBUH_R_OB:
13040 check_dspr2(ctx);
13041 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13042 break;
13043 case OPC_ADDQ_PW:
13044 check_dsp(ctx);
13045 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13046 break;
13047 case OPC_ADDQ_S_PW:
13048 check_dsp(ctx);
13049 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13050 break;
13051 case OPC_ADDQ_QH:
13052 check_dsp(ctx);
13053 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13054 break;
13055 case OPC_ADDQ_S_QH:
13056 check_dsp(ctx);
13057 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13058 break;
13059 case OPC_ADDU_OB:
13060 check_dsp(ctx);
13061 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13062 break;
13063 case OPC_ADDU_S_OB:
13064 check_dsp(ctx);
13065 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13066 break;
13067 case OPC_ADDU_QH:
13068 check_dspr2(ctx);
13069 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13070 break;
13071 case OPC_ADDU_S_QH:
13072 check_dspr2(ctx);
13073 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13074 break;
13075 case OPC_ADDUH_OB:
13076 check_dspr2(ctx);
13077 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13078 break;
13079 case OPC_ADDUH_R_OB:
13080 check_dspr2(ctx);
13081 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13082 break;
13083 }
13084 break;
13085 case OPC_CMPU_EQ_OB_DSP:
13086 switch (op2) {
13087 case OPC_PRECR_OB_QH:
13088 check_dspr2(ctx);
13089 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13090 break;
13091 case OPC_PRECR_SRA_QH_PW:
13092 check_dspr2(ctx);
13093 {
13094 TCGv_i32 ret_t = tcg_const_i32(ret);
13095 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13096 tcg_temp_free_i32(ret_t);
13097 break;
13098 }
13099 case OPC_PRECR_SRA_R_QH_PW:
13100 check_dspr2(ctx);
13101 {
13102 TCGv_i32 sa_v = tcg_const_i32(ret);
13103 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13104 tcg_temp_free_i32(sa_v);
13105 break;
13106 }
13107 case OPC_PRECRQ_OB_QH:
13108 check_dsp(ctx);
13109 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13110 break;
13111 case OPC_PRECRQ_PW_L:
13112 check_dsp(ctx);
13113 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13114 break;
13115 case OPC_PRECRQ_QH_PW:
13116 check_dsp(ctx);
13117 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13118 break;
13119 case OPC_PRECRQ_RS_QH_PW:
13120 check_dsp(ctx);
13121 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13122 break;
13123 case OPC_PRECRQU_S_OB_QH:
13124 check_dsp(ctx);
13125 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13126 break;
13127 }
13128 break;
13129 #endif
13130 }
13131
13132 tcg_temp_free(v1_t);
13133 tcg_temp_free(v2_t);
13134
13135 (void)opn; /* avoid a compiler warning */
13136 MIPS_DEBUG("%s", opn);
13137 }
13138
13139 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13140 int ret, int v1, int v2)
13141 {
13142 uint32_t op2;
13143 const char *opn = "mipsdsp shift";
13144 TCGv t0;
13145 TCGv v1_t;
13146 TCGv v2_t;
13147
13148 if (ret == 0) {
13149 /* Treat as NOP. */
13150 MIPS_DEBUG("NOP");
13151 return;
13152 }
13153
13154 t0 = tcg_temp_new();
13155 v1_t = tcg_temp_new();
13156 v2_t = tcg_temp_new();
13157
13158 tcg_gen_movi_tl(t0, v1);
13159 gen_load_gpr(v1_t, v1);
13160 gen_load_gpr(v2_t, v2);
13161
13162 switch (opc) {
13163 case OPC_SHLL_QB_DSP:
13164 {
13165 op2 = MASK_SHLL_QB(ctx->opcode);
13166 switch (op2) {
13167 case OPC_SHLL_QB:
13168 check_dsp(ctx);
13169 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13170 break;
13171 case OPC_SHLLV_QB:
13172 check_dsp(ctx);
13173 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13174 break;
13175 case OPC_SHLL_PH:
13176 check_dsp(ctx);
13177 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13178 break;
13179 case OPC_SHLLV_PH:
13180 check_dsp(ctx);
13181 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13182 break;
13183 case OPC_SHLL_S_PH:
13184 check_dsp(ctx);
13185 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13186 break;
13187 case OPC_SHLLV_S_PH:
13188 check_dsp(ctx);
13189 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13190 break;
13191 case OPC_SHLL_S_W:
13192 check_dsp(ctx);
13193 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13194 break;
13195 case OPC_SHLLV_S_W:
13196 check_dsp(ctx);
13197 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13198 break;
13199 case OPC_SHRL_QB:
13200 check_dsp(ctx);
13201 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13202 break;
13203 case OPC_SHRLV_QB:
13204 check_dsp(ctx);
13205 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13206 break;
13207 case OPC_SHRL_PH:
13208 check_dspr2(ctx);
13209 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13210 break;
13211 case OPC_SHRLV_PH:
13212 check_dspr2(ctx);
13213 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13214 break;
13215 case OPC_SHRA_QB:
13216 check_dspr2(ctx);
13217 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13218 break;
13219 case OPC_SHRA_R_QB:
13220 check_dspr2(ctx);
13221 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13222 break;
13223 case OPC_SHRAV_QB:
13224 check_dspr2(ctx);
13225 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13226 break;
13227 case OPC_SHRAV_R_QB:
13228 check_dspr2(ctx);
13229 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13230 break;
13231 case OPC_SHRA_PH:
13232 check_dsp(ctx);
13233 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13234 break;
13235 case OPC_SHRA_R_PH:
13236 check_dsp(ctx);
13237 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13238 break;
13239 case OPC_SHRAV_PH:
13240 check_dsp(ctx);
13241 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13242 break;
13243 case OPC_SHRAV_R_PH:
13244 check_dsp(ctx);
13245 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13246 break;
13247 case OPC_SHRA_R_W:
13248 check_dsp(ctx);
13249 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13250 break;
13251 case OPC_SHRAV_R_W:
13252 check_dsp(ctx);
13253 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13254 break;
13255 default: /* Invalid */
13256 MIPS_INVAL("MASK SHLL.QB");
13257 generate_exception(ctx, EXCP_RI);
13258 break;
13259 }
13260 break;
13261 }
13262 #ifdef TARGET_MIPS64
13263 case OPC_SHLL_OB_DSP:
13264 op2 = MASK_SHLL_OB(ctx->opcode);
13265 switch (op2) {
13266 case OPC_SHLL_PW:
13267 check_dsp(ctx);
13268 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13269 break;
13270 case OPC_SHLLV_PW:
13271 check_dsp(ctx);
13272 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13273 break;
13274 case OPC_SHLL_S_PW:
13275 check_dsp(ctx);
13276 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13277 break;
13278 case OPC_SHLLV_S_PW:
13279 check_dsp(ctx);
13280 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13281 break;
13282 case OPC_SHLL_OB:
13283 check_dsp(ctx);
13284 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13285 break;
13286 case OPC_SHLLV_OB:
13287 check_dsp(ctx);
13288 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13289 break;
13290 case OPC_SHLL_QH:
13291 check_dsp(ctx);
13292 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13293 break;
13294 case OPC_SHLLV_QH:
13295 check_dsp(ctx);
13296 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13297 break;
13298 case OPC_SHLL_S_QH:
13299 check_dsp(ctx);
13300 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13301 break;
13302 case OPC_SHLLV_S_QH:
13303 check_dsp(ctx);
13304 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13305 break;
13306 case OPC_SHRA_OB:
13307 check_dspr2(ctx);
13308 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13309 break;
13310 case OPC_SHRAV_OB:
13311 check_dspr2(ctx);
13312 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13313 break;
13314 case OPC_SHRA_R_OB:
13315 check_dspr2(ctx);
13316 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13317 break;
13318 case OPC_SHRAV_R_OB:
13319 check_dspr2(ctx);
13320 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13321 break;
13322 case OPC_SHRA_PW:
13323 check_dsp(ctx);
13324 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13325 break;
13326 case OPC_SHRAV_PW:
13327 check_dsp(ctx);
13328 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13329 break;
13330 case OPC_SHRA_R_PW:
13331 check_dsp(ctx);
13332 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13333 break;
13334 case OPC_SHRAV_R_PW:
13335 check_dsp(ctx);
13336 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13337 break;
13338 case OPC_SHRA_QH:
13339 check_dsp(ctx);
13340 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13341 break;
13342 case OPC_SHRAV_QH:
13343 check_dsp(ctx);
13344 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13345 break;
13346 case OPC_SHRA_R_QH:
13347 check_dsp(ctx);
13348 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13349 break;
13350 case OPC_SHRAV_R_QH:
13351 check_dsp(ctx);
13352 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13353 break;
13354 case OPC_SHRL_OB:
13355 check_dsp(ctx);
13356 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13357 break;
13358 case OPC_SHRLV_OB:
13359 check_dsp(ctx);
13360 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13361 break;
13362 case OPC_SHRL_QH:
13363 check_dspr2(ctx);
13364 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13365 break;
13366 case OPC_SHRLV_QH:
13367 check_dspr2(ctx);
13368 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13369 break;
13370 default: /* Invalid */
13371 MIPS_INVAL("MASK SHLL.OB");
13372 generate_exception(ctx, EXCP_RI);
13373 break;
13374 }
13375 break;
13376 #endif
13377 }
13378
13379 tcg_temp_free(t0);
13380 tcg_temp_free(v1_t);
13381 tcg_temp_free(v2_t);
13382 (void)opn; /* avoid a compiler warning */
13383 MIPS_DEBUG("%s", opn);
13384 }
13385
13386 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13387 int ret, int v1, int v2, int check_ret)
13388 {
13389 const char *opn = "mipsdsp multiply";
13390 TCGv_i32 t0;
13391 TCGv v1_t;
13392 TCGv v2_t;
13393
13394 if ((ret == 0) && (check_ret == 1)) {
13395 /* Treat as NOP. */
13396 MIPS_DEBUG("NOP");
13397 return;
13398 }
13399
13400 t0 = tcg_temp_new_i32();
13401 v1_t = tcg_temp_new();
13402 v2_t = tcg_temp_new();
13403
13404 tcg_gen_movi_i32(t0, ret);
13405 gen_load_gpr(v1_t, v1);
13406 gen_load_gpr(v2_t, v2);
13407
13408 switch (op1) {
13409 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13410 * the same mask and op1. */
13411 case OPC_MULT_G_2E:
13412 switch (op2) {
13413 case OPC_MUL_PH:
13414 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13415 break;
13416 case OPC_MUL_S_PH:
13417 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13418 break;
13419 case OPC_MULQ_S_W:
13420 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13421 break;
13422 case OPC_MULQ_RS_W:
13423 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13424 break;
13425 }
13426 break;
13427 case OPC_DPA_W_PH_DSP:
13428 switch (op2) {
13429 case OPC_DPAU_H_QBL:
13430 check_dsp(ctx);
13431 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13432 break;
13433 case OPC_DPAU_H_QBR:
13434 check_dsp(ctx);
13435 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13436 break;
13437 case OPC_DPSU_H_QBL:
13438 check_dsp(ctx);
13439 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13440 break;
13441 case OPC_DPSU_H_QBR:
13442 check_dsp(ctx);
13443 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13444 break;
13445 case OPC_DPA_W_PH:
13446 check_dspr2(ctx);
13447 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13448 break;
13449 case OPC_DPAX_W_PH:
13450 check_dspr2(ctx);
13451 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13452 break;
13453 case OPC_DPAQ_S_W_PH:
13454 check_dsp(ctx);
13455 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13456 break;
13457 case OPC_DPAQX_S_W_PH:
13458 check_dspr2(ctx);
13459 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13460 break;
13461 case OPC_DPAQX_SA_W_PH:
13462 check_dspr2(ctx);
13463 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13464 break;
13465 case OPC_DPS_W_PH:
13466 check_dspr2(ctx);
13467 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13468 break;
13469 case OPC_DPSX_W_PH:
13470 check_dspr2(ctx);
13471 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13472 break;
13473 case OPC_DPSQ_S_W_PH:
13474 check_dsp(ctx);
13475 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13476 break;
13477 case OPC_DPSQX_S_W_PH:
13478 check_dspr2(ctx);
13479 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13480 break;
13481 case OPC_DPSQX_SA_W_PH:
13482 check_dspr2(ctx);
13483 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13484 break;
13485 case OPC_MULSAQ_S_W_PH:
13486 check_dsp(ctx);
13487 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13488 break;
13489 case OPC_DPAQ_SA_L_W:
13490 check_dsp(ctx);
13491 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13492 break;
13493 case OPC_DPSQ_SA_L_W:
13494 check_dsp(ctx);
13495 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13496 break;
13497 case OPC_MAQ_S_W_PHL:
13498 check_dsp(ctx);
13499 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13500 break;
13501 case OPC_MAQ_S_W_PHR:
13502 check_dsp(ctx);
13503 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13504 break;
13505 case OPC_MAQ_SA_W_PHL:
13506 check_dsp(ctx);
13507 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13508 break;
13509 case OPC_MAQ_SA_W_PHR:
13510 check_dsp(ctx);
13511 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13512 break;
13513 case OPC_MULSA_W_PH:
13514 check_dspr2(ctx);
13515 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13516 break;
13517 }
13518 break;
13519 #ifdef TARGET_MIPS64
13520 case OPC_DPAQ_W_QH_DSP:
13521 {
13522 int ac = ret & 0x03;
13523 tcg_gen_movi_i32(t0, ac);
13524
13525 switch (op2) {
13526 case OPC_DMADD:
13527 check_dsp(ctx);
13528 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13529 break;
13530 case OPC_DMADDU:
13531 check_dsp(ctx);
13532 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13533 break;
13534 case OPC_DMSUB:
13535 check_dsp(ctx);
13536 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13537 break;
13538 case OPC_DMSUBU:
13539 check_dsp(ctx);
13540 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13541 break;
13542 case OPC_DPA_W_QH:
13543 check_dspr2(ctx);
13544 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13545 break;
13546 case OPC_DPAQ_S_W_QH:
13547 check_dsp(ctx);
13548 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13549 break;
13550 case OPC_DPAQ_SA_L_PW:
13551 check_dsp(ctx);
13552 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13553 break;
13554 case OPC_DPAU_H_OBL:
13555 check_dsp(ctx);
13556 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13557 break;
13558 case OPC_DPAU_H_OBR:
13559 check_dsp(ctx);
13560 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13561 break;
13562 case OPC_DPS_W_QH:
13563 check_dspr2(ctx);
13564 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13565 break;
13566 case OPC_DPSQ_S_W_QH:
13567 check_dsp(ctx);
13568 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13569 break;
13570 case OPC_DPSQ_SA_L_PW:
13571 check_dsp(ctx);
13572 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13573 break;
13574 case OPC_DPSU_H_OBL:
13575 check_dsp(ctx);
13576 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13577 break;
13578 case OPC_DPSU_H_OBR:
13579 check_dsp(ctx);
13580 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13581 break;
13582 case OPC_MAQ_S_L_PWL:
13583 check_dsp(ctx);
13584 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13585 break;
13586 case OPC_MAQ_S_L_PWR:
13587 check_dsp(ctx);
13588 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13589 break;
13590 case OPC_MAQ_S_W_QHLL:
13591 check_dsp(ctx);
13592 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13593 break;
13594 case OPC_MAQ_SA_W_QHLL:
13595 check_dsp(ctx);
13596 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13597 break;
13598 case OPC_MAQ_S_W_QHLR:
13599 check_dsp(ctx);
13600 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13601 break;
13602 case OPC_MAQ_SA_W_QHLR:
13603 check_dsp(ctx);
13604 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13605 break;
13606 case OPC_MAQ_S_W_QHRL:
13607 check_dsp(ctx);
13608 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13609 break;
13610 case OPC_MAQ_SA_W_QHRL:
13611 check_dsp(ctx);
13612 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13613 break;
13614 case OPC_MAQ_S_W_QHRR:
13615 check_dsp(ctx);
13616 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13617 break;
13618 case OPC_MAQ_SA_W_QHRR:
13619 check_dsp(ctx);
13620 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13621 break;
13622 case OPC_MULSAQ_S_L_PW:
13623 check_dsp(ctx);
13624 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13625 break;
13626 case OPC_MULSAQ_S_W_QH:
13627 check_dsp(ctx);
13628 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13629 break;
13630 }
13631 }
13632 break;
13633 #endif
13634 case OPC_ADDU_QB_DSP:
13635 switch (op2) {
13636 case OPC_MULEU_S_PH_QBL:
13637 check_dsp(ctx);
13638 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13639 break;
13640 case OPC_MULEU_S_PH_QBR:
13641 check_dsp(ctx);
13642 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13643 break;
13644 case OPC_MULQ_RS_PH:
13645 check_dsp(ctx);
13646 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13647 break;
13648 case OPC_MULEQ_S_W_PHL:
13649 check_dsp(ctx);
13650 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13651 break;
13652 case OPC_MULEQ_S_W_PHR:
13653 check_dsp(ctx);
13654 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13655 break;
13656 case OPC_MULQ_S_PH:
13657 check_dspr2(ctx);
13658 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13659 break;
13660 }
13661 break;
13662 #ifdef TARGET_MIPS64
13663 case OPC_ADDU_OB_DSP:
13664 switch (op2) {
13665 case OPC_MULEQ_S_PW_QHL:
13666 check_dsp(ctx);
13667 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 break;
13669 case OPC_MULEQ_S_PW_QHR:
13670 check_dsp(ctx);
13671 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 break;
13673 case OPC_MULEU_S_QH_OBL:
13674 check_dsp(ctx);
13675 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 break;
13677 case OPC_MULEU_S_QH_OBR:
13678 check_dsp(ctx);
13679 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13680 break;
13681 case OPC_MULQ_RS_QH:
13682 check_dsp(ctx);
13683 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13684 break;
13685 }
13686 break;
13687 #endif
13688 }
13689
13690 tcg_temp_free_i32(t0);
13691 tcg_temp_free(v1_t);
13692 tcg_temp_free(v2_t);
13693
13694 (void)opn; /* avoid a compiler warning */
13695 MIPS_DEBUG("%s", opn);
13696
13697 }
13698
13699 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13700 uint32_t op1, uint32_t op2,
13701 int ret, int val)
13702 {
13703 const char *opn = "mipsdsp Bit/ Manipulation";
13704 int16_t imm;
13705 TCGv t0;
13706 TCGv val_t;
13707
13708 if (ret == 0) {
13709 /* Treat as NOP. */
13710 MIPS_DEBUG("NOP");
13711 return;
13712 }
13713
13714 t0 = tcg_temp_new();
13715 val_t = tcg_temp_new();
13716 gen_load_gpr(val_t, val);
13717
13718 switch (op1) {
13719 case OPC_ABSQ_S_PH_DSP:
13720 switch (op2) {
13721 case OPC_BITREV:
13722 check_dsp(ctx);
13723 gen_helper_bitrev(cpu_gpr[ret], val_t);
13724 break;
13725 case OPC_REPL_QB:
13726 check_dsp(ctx);
13727 {
13728 target_long result;
13729 imm = (ctx->opcode >> 16) & 0xFF;
13730 result = (uint32_t)imm << 24 |
13731 (uint32_t)imm << 16 |
13732 (uint32_t)imm << 8 |
13733 (uint32_t)imm;
13734 result = (int32_t)result;
13735 tcg_gen_movi_tl(cpu_gpr[ret], result);
13736 }
13737 break;
13738 case OPC_REPLV_QB:
13739 check_dsp(ctx);
13740 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13741 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13742 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13743 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13744 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13745 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13746 break;
13747 case OPC_REPL_PH:
13748 check_dsp(ctx);
13749 {
13750 imm = (ctx->opcode >> 16) & 0x03FF;
13751 tcg_gen_movi_tl(cpu_gpr[ret], \
13752 (target_long)((int32_t)imm << 16 | \
13753 (uint32_t)(uint16_t)imm));
13754 }
13755 break;
13756 case OPC_REPLV_PH:
13757 check_dsp(ctx);
13758 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13759 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13760 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13761 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13762 break;
13763 }
13764 break;
13765 #ifdef TARGET_MIPS64
13766 case OPC_ABSQ_S_QH_DSP:
13767 switch (op2) {
13768 case OPC_REPL_OB:
13769 check_dsp(ctx);
13770 {
13771 target_long temp;
13772
13773 imm = (ctx->opcode >> 16) & 0xFF;
13774 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13775 temp = (temp << 16) | temp;
13776 temp = (temp << 32) | temp;
13777 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13778 break;
13779 }
13780 case OPC_REPL_PW:
13781 check_dsp(ctx);
13782 {
13783 target_long temp;
13784
13785 imm = (ctx->opcode >> 16) & 0x03FF;
13786 imm = (int16_t)(imm << 6) >> 6;
13787 temp = ((target_long)imm << 32) \
13788 | ((target_long)imm & 0xFFFFFFFF);
13789 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13790 break;
13791 }
13792 case OPC_REPL_QH:
13793 check_dsp(ctx);
13794 {
13795 target_long temp;
13796
13797 imm = (ctx->opcode >> 16) & 0x03FF;
13798 imm = (int16_t)(imm << 6) >> 6;
13799
13800 temp = ((uint64_t)(uint16_t)imm << 48) |
13801 ((uint64_t)(uint16_t)imm << 32) |
13802 ((uint64_t)(uint16_t)imm << 16) |
13803 (uint64_t)(uint16_t)imm;
13804 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13805 break;
13806 }
13807 case OPC_REPLV_OB:
13808 check_dsp(ctx);
13809 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13810 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13811 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13812 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13813 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13814 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13815 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13816 break;
13817 case OPC_REPLV_PW:
13818 check_dsp(ctx);
13819 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13820 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13821 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13822 break;
13823 case OPC_REPLV_QH:
13824 check_dsp(ctx);
13825 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13826 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13827 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13828 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13829 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13830 break;
13831 }
13832 break;
13833 #endif
13834 }
13835 tcg_temp_free(t0);
13836 tcg_temp_free(val_t);
13837
13838 (void)opn; /* avoid a compiler warning */
13839 MIPS_DEBUG("%s", opn);
13840 }
13841
13842 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13843 uint32_t op1, uint32_t op2,
13844 int ret, int v1, int v2, int check_ret)
13845 {
13846 const char *opn = "mipsdsp add compare pick";
13847 TCGv_i32 t0;
13848 TCGv t1;
13849 TCGv v1_t;
13850 TCGv v2_t;
13851
13852 if ((ret == 0) && (check_ret == 1)) {
13853 /* Treat as NOP. */
13854 MIPS_DEBUG("NOP");
13855 return;
13856 }
13857
13858 t0 = tcg_temp_new_i32();
13859 t1 = tcg_temp_new();
13860 v1_t = tcg_temp_new();
13861 v2_t = tcg_temp_new();
13862
13863 gen_load_gpr(v1_t, v1);
13864 gen_load_gpr(v2_t, v2);
13865
13866 switch (op1) {
13867 case OPC_APPEND_DSP:
13868 switch (op2) {
13869 case OPC_APPEND:
13870 tcg_gen_movi_i32(t0, v2);
13871 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13872 break;
13873 case OPC_PREPEND:
13874 tcg_gen_movi_i32(t0, v2);
13875 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13876 break;
13877 case OPC_BALIGN:
13878 tcg_gen_movi_i32(t0, v2);
13879 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13880 break;
13881 default: /* Invid */
13882 MIPS_INVAL("MASK APPEND");
13883 generate_exception(ctx, EXCP_RI);
13884 break;
13885 }
13886 break;
13887 case OPC_CMPU_EQ_QB_DSP:
13888 switch (op2) {
13889 case OPC_CMPU_EQ_QB:
13890 check_dsp(ctx);
13891 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13892 break;
13893 case OPC_CMPU_LT_QB:
13894 check_dsp(ctx);
13895 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13896 break;
13897 case OPC_CMPU_LE_QB:
13898 check_dsp(ctx);
13899 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13900 break;
13901 case OPC_CMPGU_EQ_QB:
13902 check_dsp(ctx);
13903 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13904 break;
13905 case OPC_CMPGU_LT_QB:
13906 check_dsp(ctx);
13907 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13908 break;
13909 case OPC_CMPGU_LE_QB:
13910 check_dsp(ctx);
13911 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13912 break;
13913 case OPC_CMPGDU_EQ_QB:
13914 check_dspr2(ctx);
13915 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13916 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13917 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13918 tcg_gen_shli_tl(t1, t1, 24);
13919 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13920 break;
13921 case OPC_CMPGDU_LT_QB:
13922 check_dspr2(ctx);
13923 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13924 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13925 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13926 tcg_gen_shli_tl(t1, t1, 24);
13927 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13928 break;
13929 case OPC_CMPGDU_LE_QB:
13930 check_dspr2(ctx);
13931 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13932 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13933 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13934 tcg_gen_shli_tl(t1, t1, 24);
13935 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13936 break;
13937 case OPC_CMP_EQ_PH:
13938 check_dsp(ctx);
13939 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13940 break;
13941 case OPC_CMP_LT_PH:
13942 check_dsp(ctx);
13943 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13944 break;
13945 case OPC_CMP_LE_PH:
13946 check_dsp(ctx);
13947 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13948 break;
13949 case OPC_PICK_QB:
13950 check_dsp(ctx);
13951 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13952 break;
13953 case OPC_PICK_PH:
13954 check_dsp(ctx);
13955 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13956 break;
13957 case OPC_PACKRL_PH:
13958 check_dsp(ctx);
13959 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13960 break;
13961 }
13962 break;
13963 #ifdef TARGET_MIPS64
13964 case OPC_CMPU_EQ_OB_DSP:
13965 switch (op2) {
13966 case OPC_CMP_EQ_PW:
13967 check_dsp(ctx);
13968 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13969 break;
13970 case OPC_CMP_LT_PW:
13971 check_dsp(ctx);
13972 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13973 break;
13974 case OPC_CMP_LE_PW:
13975 check_dsp(ctx);
13976 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13977 break;
13978 case OPC_CMP_EQ_QH:
13979 check_dsp(ctx);
13980 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13981 break;
13982 case OPC_CMP_LT_QH:
13983 check_dsp(ctx);
13984 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13985 break;
13986 case OPC_CMP_LE_QH:
13987 check_dsp(ctx);
13988 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13989 break;
13990 case OPC_CMPGDU_EQ_OB:
13991 check_dspr2(ctx);
13992 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13993 break;
13994 case OPC_CMPGDU_LT_OB:
13995 check_dspr2(ctx);
13996 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13997 break;
13998 case OPC_CMPGDU_LE_OB:
13999 check_dspr2(ctx);
14000 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14001 break;
14002 case OPC_CMPGU_EQ_OB:
14003 check_dsp(ctx);
14004 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14005 break;
14006 case OPC_CMPGU_LT_OB:
14007 check_dsp(ctx);
14008 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14009 break;
14010 case OPC_CMPGU_LE_OB:
14011 check_dsp(ctx);
14012 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14013 break;
14014 case OPC_CMPU_EQ_OB:
14015 check_dsp(ctx);
14016 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14017 break;
14018 case OPC_CMPU_LT_OB:
14019 check_dsp(ctx);
14020 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14021 break;
14022 case OPC_CMPU_LE_OB:
14023 check_dsp(ctx);
14024 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14025 break;
14026 case OPC_PACKRL_PW:
14027 check_dsp(ctx);
14028 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14029 break;
14030 case OPC_PICK_OB:
14031 check_dsp(ctx);
14032 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14033 break;
14034 case OPC_PICK_PW:
14035 check_dsp(ctx);
14036 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14037 break;
14038 case OPC_PICK_QH:
14039 check_dsp(ctx);
14040 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14041 break;
14042 }
14043 break;
14044 case OPC_DAPPEND_DSP:
14045 switch (op2) {
14046 case OPC_DAPPEND:
14047 tcg_gen_movi_i32(t0, v2);
14048 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14049 break;
14050 case OPC_PREPENDD:
14051 tcg_gen_movi_i32(t0, v2);
14052 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14053 break;
14054 case OPC_PREPENDW:
14055 tcg_gen_movi_i32(t0, v2);
14056 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14057 break;
14058 case OPC_DBALIGN:
14059 tcg_gen_movi_i32(t0, v2);
14060 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14061 break;
14062 default: /* Invalid */
14063 MIPS_INVAL("MASK DAPPEND");
14064 generate_exception(ctx, EXCP_RI);
14065 break;
14066 }
14067 break;
14068 #endif
14069 }
14070
14071 tcg_temp_free_i32(t0);
14072 tcg_temp_free(t1);
14073 tcg_temp_free(v1_t);
14074 tcg_temp_free(v2_t);
14075
14076 (void)opn; /* avoid a compiler warning */
14077 MIPS_DEBUG("%s", opn);
14078 }
14079
14080 /* End MIPSDSP functions. */
14081
14082 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14083 {
14084 int32_t offset;
14085 int rs, rt, rd, sa;
14086 uint32_t op, op1, op2;
14087 int16_t imm;
14088
14089 /* make sure instructions are on a word boundary */
14090 if (ctx->pc & 0x3) {
14091 env->CP0_BadVAddr = ctx->pc;
14092 generate_exception(ctx, EXCP_AdEL);
14093 return;
14094 }
14095
14096 /* Handle blikely not taken case */
14097 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14098 int l1 = gen_new_label();
14099
14100 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14101 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14102 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14103 gen_goto_tb(ctx, 1, ctx->pc + 4);
14104 gen_set_label(l1);
14105 }
14106
14107 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14108 tcg_gen_debug_insn_start(ctx->pc);
14109 }
14110
14111 op = MASK_OP_MAJOR(ctx->opcode);
14112 rs = (ctx->opcode >> 21) & 0x1f;
14113 rt = (ctx->opcode >> 16) & 0x1f;
14114 rd = (ctx->opcode >> 11) & 0x1f;
14115 sa = (ctx->opcode >> 6) & 0x1f;
14116 imm = (int16_t)ctx->opcode;
14117 switch (op) {
14118 case OPC_SPECIAL:
14119 op1 = MASK_SPECIAL(ctx->opcode);
14120 switch (op1) {
14121 case OPC_SLL: /* Shift with immediate */
14122 case OPC_SRA:
14123 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14124 break;
14125 case OPC_SRL:
14126 switch ((ctx->opcode >> 21) & 0x1f) {
14127 case 1:
14128 /* rotr is decoded as srl on non-R2 CPUs */
14129 if (env->insn_flags & ISA_MIPS32R2) {
14130 op1 = OPC_ROTR;
14131 }
14132 /* Fallthrough */
14133 case 0:
14134 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14135 break;
14136 default:
14137 generate_exception(ctx, EXCP_RI);
14138 break;
14139 }
14140 break;
14141 case OPC_MOVN: /* Conditional move */
14142 case OPC_MOVZ:
14143 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14144 INSN_LOONGSON2E | INSN_LOONGSON2F);
14145 gen_cond_move(env, ctx, op1, rd, rs, rt);
14146 break;
14147 case OPC_ADD ... OPC_SUBU:
14148 gen_arith(env, ctx, op1, rd, rs, rt);
14149 break;
14150 case OPC_SLLV: /* Shifts */
14151 case OPC_SRAV:
14152 gen_shift(env, ctx, op1, rd, rs, rt);
14153 break;
14154 case OPC_SRLV:
14155 switch ((ctx->opcode >> 6) & 0x1f) {
14156 case 1:
14157 /* rotrv is decoded as srlv on non-R2 CPUs */
14158 if (env->insn_flags & ISA_MIPS32R2) {
14159 op1 = OPC_ROTRV;
14160 }
14161 /* Fallthrough */
14162 case 0:
14163 gen_shift(env, ctx, op1, rd, rs, rt);
14164 break;
14165 default:
14166 generate_exception(ctx, EXCP_RI);
14167 break;
14168 }
14169 break;
14170 case OPC_SLT: /* Set on less than */
14171 case OPC_SLTU:
14172 gen_slt(env, ctx, op1, rd, rs, rt);
14173 break;
14174 case OPC_AND: /* Logic*/
14175 case OPC_OR:
14176 case OPC_NOR:
14177 case OPC_XOR:
14178 gen_logic(env, ctx, op1, rd, rs, rt);
14179 break;
14180 case OPC_MULT ... OPC_DIVU:
14181 if (sa) {
14182 check_insn(env, ctx, INSN_VR54XX);
14183 op1 = MASK_MUL_VR54XX(ctx->opcode);
14184 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14185 } else
14186 gen_muldiv(ctx, op1, rs, rt);
14187 break;
14188 case OPC_JR ... OPC_JALR:
14189 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14190 *is_branch = 1;
14191 break;
14192 case OPC_TGE ... OPC_TEQ: /* Traps */
14193 case OPC_TNE:
14194 gen_trap(ctx, op1, rs, rt, -1);
14195 break;
14196 case OPC_MFHI: /* Move from HI/LO */
14197 case OPC_MFLO:
14198 gen_HILO(ctx, op1, rd);
14199 break;
14200 case OPC_MTHI:
14201 case OPC_MTLO: /* Move to HI/LO */
14202 gen_HILO(ctx, op1, rs);
14203 break;
14204 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14205 #ifdef MIPS_STRICT_STANDARD
14206 MIPS_INVAL("PMON / selsl");
14207 generate_exception(ctx, EXCP_RI);
14208 #else
14209 gen_helper_0e0i(pmon, sa);
14210 #endif
14211 break;
14212 case OPC_SYSCALL:
14213 generate_exception(ctx, EXCP_SYSCALL);
14214 ctx->bstate = BS_STOP;
14215 break;
14216 case OPC_BREAK:
14217 generate_exception(ctx, EXCP_BREAK);
14218 break;
14219 case OPC_SPIM:
14220 #ifdef MIPS_STRICT_STANDARD
14221 MIPS_INVAL("SPIM");
14222 generate_exception(ctx, EXCP_RI);
14223 #else
14224 /* Implemented as RI exception for now. */
14225 MIPS_INVAL("spim (unofficial)");
14226 generate_exception(ctx, EXCP_RI);
14227 #endif
14228 break;
14229 case OPC_SYNC:
14230 /* Treat as NOP. */
14231 break;
14232
14233 case OPC_MOVCI:
14234 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14235 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14236 check_cp1_enabled(ctx);
14237 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14238 (ctx->opcode >> 16) & 1);
14239 } else {
14240 generate_exception_err(ctx, EXCP_CpU, 1);
14241 }
14242 break;
14243
14244 #if defined(TARGET_MIPS64)
14245 /* MIPS64 specific opcodes */
14246 case OPC_DSLL:
14247 case OPC_DSRA:
14248 case OPC_DSLL32:
14249 case OPC_DSRA32:
14250 check_insn(env, ctx, ISA_MIPS3);
14251 check_mips_64(ctx);
14252 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14253 break;
14254 case OPC_DSRL:
14255 switch ((ctx->opcode >> 21) & 0x1f) {
14256 case 1:
14257 /* drotr is decoded as dsrl on non-R2 CPUs */
14258 if (env->insn_flags & ISA_MIPS32R2) {
14259 op1 = OPC_DROTR;
14260 }
14261 /* Fallthrough */
14262 case 0:
14263 check_insn(env, ctx, ISA_MIPS3);
14264 check_mips_64(ctx);
14265 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14266 break;
14267 default:
14268 generate_exception(ctx, EXCP_RI);
14269 break;
14270 }
14271 break;
14272 case OPC_DSRL32:
14273 switch ((ctx->opcode >> 21) & 0x1f) {
14274 case 1:
14275 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14276 if (env->insn_flags & ISA_MIPS32R2) {
14277 op1 = OPC_DROTR32;
14278 }
14279 /* Fallthrough */
14280 case 0:
14281 check_insn(env, ctx, ISA_MIPS3);
14282 check_mips_64(ctx);
14283 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14284 break;
14285 default:
14286 generate_exception(ctx, EXCP_RI);
14287 break;
14288 }
14289 break;
14290 case OPC_DADD ... OPC_DSUBU:
14291 check_insn(env, ctx, ISA_MIPS3);
14292 check_mips_64(ctx);
14293 gen_arith(env, ctx, op1, rd, rs, rt);
14294 break;
14295 case OPC_DSLLV:
14296 case OPC_DSRAV:
14297 check_insn(env, ctx, ISA_MIPS3);
14298 check_mips_64(ctx);
14299 gen_shift(env, ctx, op1, rd, rs, rt);
14300 break;
14301 case OPC_DSRLV:
14302 switch ((ctx->opcode >> 6) & 0x1f) {
14303 case 1:
14304 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14305 if (env->insn_flags & ISA_MIPS32R2) {
14306 op1 = OPC_DROTRV;
14307 }
14308 /* Fallthrough */
14309 case 0:
14310 check_insn(env, ctx, ISA_MIPS3);
14311 check_mips_64(ctx);
14312 gen_shift(env, ctx, op1, rd, rs, rt);
14313 break;
14314 default:
14315 generate_exception(ctx, EXCP_RI);
14316 break;
14317 }
14318 break;
14319 case OPC_DMULT ... OPC_DDIVU:
14320 check_insn(env, ctx, ISA_MIPS3);
14321 check_mips_64(ctx);
14322 gen_muldiv(ctx, op1, rs, rt);
14323 break;
14324 #endif
14325 default: /* Invalid */
14326 MIPS_INVAL("special");
14327 generate_exception(ctx, EXCP_RI);
14328 break;
14329 }
14330 break;
14331 case OPC_SPECIAL2:
14332 op1 = MASK_SPECIAL2(ctx->opcode);
14333 switch (op1) {
14334 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14335 case OPC_MSUB ... OPC_MSUBU:
14336 check_insn(env, ctx, ISA_MIPS32);
14337 gen_muldiv(ctx, op1, rs, rt);
14338 break;
14339 case OPC_MUL:
14340 gen_arith(env, ctx, op1, rd, rs, rt);
14341 break;
14342 case OPC_CLO:
14343 case OPC_CLZ:
14344 check_insn(env, ctx, ISA_MIPS32);
14345 gen_cl(ctx, op1, rd, rs);
14346 break;
14347 case OPC_SDBBP:
14348 /* XXX: not clear which exception should be raised
14349 * when in debug mode...
14350 */
14351 check_insn(env, ctx, ISA_MIPS32);
14352 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14353 generate_exception(ctx, EXCP_DBp);
14354 } else {
14355 generate_exception(ctx, EXCP_DBp);
14356 }
14357 /* Treat as NOP. */
14358 break;
14359 case OPC_DIV_G_2F:
14360 case OPC_DIVU_G_2F:
14361 case OPC_MULT_G_2F:
14362 case OPC_MULTU_G_2F:
14363 case OPC_MOD_G_2F:
14364 case OPC_MODU_G_2F:
14365 check_insn(env, ctx, INSN_LOONGSON2F);
14366 gen_loongson_integer(ctx, op1, rd, rs, rt);
14367 break;
14368 #if defined(TARGET_MIPS64)
14369 case OPC_DCLO:
14370 case OPC_DCLZ:
14371 check_insn(env, ctx, ISA_MIPS64);
14372 check_mips_64(ctx);
14373 gen_cl(ctx, op1, rd, rs);
14374 break;
14375 case OPC_DMULT_G_2F:
14376 case OPC_DMULTU_G_2F:
14377 case OPC_DDIV_G_2F:
14378 case OPC_DDIVU_G_2F:
14379 case OPC_DMOD_G_2F:
14380 case OPC_DMODU_G_2F:
14381 check_insn(env, ctx, INSN_LOONGSON2F);
14382 gen_loongson_integer(ctx, op1, rd, rs, rt);
14383 break;
14384 #endif
14385 default: /* Invalid */
14386 MIPS_INVAL("special2");
14387 generate_exception(ctx, EXCP_RI);
14388 break;
14389 }
14390 break;
14391 case OPC_SPECIAL3:
14392 op1 = MASK_SPECIAL3(ctx->opcode);
14393 switch (op1) {
14394 case OPC_EXT:
14395 case OPC_INS:
14396 check_insn(env, ctx, ISA_MIPS32R2);
14397 gen_bitops(ctx, op1, rt, rs, sa, rd);
14398 break;
14399 case OPC_BSHFL:
14400 check_insn(env, ctx, ISA_MIPS32R2);
14401 op2 = MASK_BSHFL(ctx->opcode);
14402 gen_bshfl(ctx, op2, rt, rd);
14403 break;
14404 case OPC_RDHWR:
14405 gen_rdhwr(env, ctx, rt, rd);
14406 break;
14407 case OPC_FORK:
14408 check_insn(env, ctx, ASE_MT);
14409 {
14410 TCGv t0 = tcg_temp_new();
14411 TCGv t1 = tcg_temp_new();
14412
14413 gen_load_gpr(t0, rt);
14414 gen_load_gpr(t1, rs);
14415 gen_helper_fork(t0, t1);
14416 tcg_temp_free(t0);
14417 tcg_temp_free(t1);
14418 }
14419 break;
14420 case OPC_YIELD:
14421 check_insn(env, ctx, ASE_MT);
14422 {
14423 TCGv t0 = tcg_temp_new();
14424
14425 save_cpu_state(ctx, 1);
14426 gen_load_gpr(t0, rs);
14427 gen_helper_yield(t0, cpu_env, t0);
14428 gen_store_gpr(t0, rd);
14429 tcg_temp_free(t0);
14430 }
14431 break;
14432 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14433 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14434 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14435 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14436 * the same mask and op1. */
14437 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14438 op2 = MASK_ADDUH_QB(ctx->opcode);
14439 switch (op2) {
14440 case OPC_ADDUH_QB:
14441 case OPC_ADDUH_R_QB:
14442 case OPC_ADDQH_PH:
14443 case OPC_ADDQH_R_PH:
14444 case OPC_ADDQH_W:
14445 case OPC_ADDQH_R_W:
14446 case OPC_SUBUH_QB:
14447 case OPC_SUBUH_R_QB:
14448 case OPC_SUBQH_PH:
14449 case OPC_SUBQH_R_PH:
14450 case OPC_SUBQH_W:
14451 case OPC_SUBQH_R_W:
14452 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14453 break;
14454 case OPC_MUL_PH:
14455 case OPC_MUL_S_PH:
14456 case OPC_MULQ_S_W:
14457 case OPC_MULQ_RS_W:
14458 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14459 break;
14460 default:
14461 MIPS_INVAL("MASK ADDUH.QB");
14462 generate_exception(ctx, EXCP_RI);
14463 break;
14464 }
14465 } else if (env->insn_flags & INSN_LOONGSON2E) {
14466 gen_loongson_integer(ctx, op1, rd, rs, rt);
14467 } else {
14468 generate_exception(ctx, EXCP_RI);
14469 }
14470 break;
14471 case OPC_LX_DSP:
14472 op2 = MASK_LX(ctx->opcode);
14473 switch (op2) {
14474 #if defined(TARGET_MIPS64)
14475 case OPC_LDX:
14476 #endif
14477 case OPC_LBUX:
14478 case OPC_LHX:
14479 case OPC_LWX:
14480 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14481 break;
14482 default: /* Invalid */
14483 MIPS_INVAL("MASK LX");
14484 generate_exception(ctx, EXCP_RI);
14485 break;
14486 }
14487 break;
14488 case OPC_ABSQ_S_PH_DSP:
14489 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14490 switch (op2) {
14491 case OPC_ABSQ_S_QB:
14492 case OPC_ABSQ_S_PH:
14493 case OPC_ABSQ_S_W:
14494 case OPC_PRECEQ_W_PHL:
14495 case OPC_PRECEQ_W_PHR:
14496 case OPC_PRECEQU_PH_QBL:
14497 case OPC_PRECEQU_PH_QBR:
14498 case OPC_PRECEQU_PH_QBLA:
14499 case OPC_PRECEQU_PH_QBRA:
14500 case OPC_PRECEU_PH_QBL:
14501 case OPC_PRECEU_PH_QBR:
14502 case OPC_PRECEU_PH_QBLA:
14503 case OPC_PRECEU_PH_QBRA:
14504 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14505 break;
14506 case OPC_BITREV:
14507 case OPC_REPL_QB:
14508 case OPC_REPLV_QB:
14509 case OPC_REPL_PH:
14510 case OPC_REPLV_PH:
14511 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14512 break;
14513 default:
14514 MIPS_INVAL("MASK ABSQ_S.PH");
14515 generate_exception(ctx, EXCP_RI);
14516 break;
14517 }
14518 break;
14519 case OPC_ADDU_QB_DSP:
14520 op2 = MASK_ADDU_QB(ctx->opcode);
14521 switch (op2) {
14522 case OPC_ADDQ_PH:
14523 case OPC_ADDQ_S_PH:
14524 case OPC_ADDQ_S_W:
14525 case OPC_ADDU_QB:
14526 case OPC_ADDU_S_QB:
14527 case OPC_ADDU_PH:
14528 case OPC_ADDU_S_PH:
14529 case OPC_SUBQ_PH:
14530 case OPC_SUBQ_S_PH:
14531 case OPC_SUBQ_S_W:
14532 case OPC_SUBU_QB:
14533 case OPC_SUBU_S_QB:
14534 case OPC_SUBU_PH:
14535 case OPC_SUBU_S_PH:
14536 case OPC_ADDSC:
14537 case OPC_ADDWC:
14538 case OPC_MODSUB:
14539 case OPC_RADDU_W_QB:
14540 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14541 break;
14542 case OPC_MULEU_S_PH_QBL:
14543 case OPC_MULEU_S_PH_QBR:
14544 case OPC_MULQ_RS_PH:
14545 case OPC_MULEQ_S_W_PHL:
14546 case OPC_MULEQ_S_W_PHR:
14547 case OPC_MULQ_S_PH:
14548 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14549 break;
14550 default: /* Invalid */
14551 MIPS_INVAL("MASK ADDU.QB");
14552 generate_exception(ctx, EXCP_RI);
14553 break;
14554
14555 }
14556 break;
14557 case OPC_CMPU_EQ_QB_DSP:
14558 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14559 switch (op2) {
14560 case OPC_PRECR_SRA_PH_W:
14561 case OPC_PRECR_SRA_R_PH_W:
14562 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14563 break;
14564 case OPC_PRECR_QB_PH:
14565 case OPC_PRECRQ_QB_PH:
14566 case OPC_PRECRQ_PH_W:
14567 case OPC_PRECRQ_RS_PH_W:
14568 case OPC_PRECRQU_S_QB_PH:
14569 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14570 break;
14571 case OPC_CMPU_EQ_QB:
14572 case OPC_CMPU_LT_QB:
14573 case OPC_CMPU_LE_QB:
14574 case OPC_CMP_EQ_PH:
14575 case OPC_CMP_LT_PH:
14576 case OPC_CMP_LE_PH:
14577 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14578 break;
14579 case OPC_CMPGU_EQ_QB:
14580 case OPC_CMPGU_LT_QB:
14581 case OPC_CMPGU_LE_QB:
14582 case OPC_CMPGDU_EQ_QB:
14583 case OPC_CMPGDU_LT_QB:
14584 case OPC_CMPGDU_LE_QB:
14585 case OPC_PICK_QB:
14586 case OPC_PICK_PH:
14587 case OPC_PACKRL_PH:
14588 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14589 break;
14590 default: /* Invalid */
14591 MIPS_INVAL("MASK CMPU.EQ.QB");
14592 generate_exception(ctx, EXCP_RI);
14593 break;
14594 }
14595 break;
14596 case OPC_SHLL_QB_DSP:
14597 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14598 break;
14599 case OPC_DPA_W_PH_DSP:
14600 op2 = MASK_DPA_W_PH(ctx->opcode);
14601 switch (op2) {
14602 case OPC_DPAU_H_QBL:
14603 case OPC_DPAU_H_QBR:
14604 case OPC_DPSU_H_QBL:
14605 case OPC_DPSU_H_QBR:
14606 case OPC_DPA_W_PH:
14607 case OPC_DPAX_W_PH:
14608 case OPC_DPAQ_S_W_PH:
14609 case OPC_DPAQX_S_W_PH:
14610 case OPC_DPAQX_SA_W_PH:
14611 case OPC_DPS_W_PH:
14612 case OPC_DPSX_W_PH:
14613 case OPC_DPSQ_S_W_PH:
14614 case OPC_DPSQX_S_W_PH:
14615 case OPC_DPSQX_SA_W_PH:
14616 case OPC_MULSAQ_S_W_PH:
14617 case OPC_DPAQ_SA_L_W:
14618 case OPC_DPSQ_SA_L_W:
14619 case OPC_MAQ_S_W_PHL:
14620 case OPC_MAQ_S_W_PHR:
14621 case OPC_MAQ_SA_W_PHL:
14622 case OPC_MAQ_SA_W_PHR:
14623 case OPC_MULSA_W_PH:
14624 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14625 break;
14626 default: /* Invalid */
14627 MIPS_INVAL("MASK DPAW.PH");
14628 generate_exception(ctx, EXCP_RI);
14629 break;
14630 }
14631 break;
14632 case OPC_INSV_DSP:
14633 op2 = MASK_INSV(ctx->opcode);
14634 switch (op2) {
14635 case OPC_INSV:
14636 check_dsp(ctx);
14637 {
14638 TCGv t0, t1;
14639
14640 if (rt == 0) {
14641 MIPS_DEBUG("NOP");
14642 break;
14643 }
14644
14645 t0 = tcg_temp_new();
14646 t1 = tcg_temp_new();
14647
14648 gen_load_gpr(t0, rt);
14649 gen_load_gpr(t1, rs);
14650
14651 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14652
14653 tcg_temp_free(t0);
14654 tcg_temp_free(t1);
14655 break;
14656 }
14657 default: /* Invalid */
14658 MIPS_INVAL("MASK INSV");
14659 generate_exception(ctx, EXCP_RI);
14660 break;
14661 }
14662 break;
14663 case OPC_APPEND_DSP:
14664 check_dspr2(ctx);
14665 op2 = MASK_APPEND(ctx->opcode);
14666 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14667 break;
14668 #if defined(TARGET_MIPS64)
14669 case OPC_DEXTM ... OPC_DEXT:
14670 case OPC_DINSM ... OPC_DINS:
14671 check_insn(env, ctx, ISA_MIPS64R2);
14672 check_mips_64(ctx);
14673 gen_bitops(ctx, op1, rt, rs, sa, rd);
14674 break;
14675 case OPC_DBSHFL:
14676 check_insn(env, ctx, ISA_MIPS64R2);
14677 check_mips_64(ctx);
14678 op2 = MASK_DBSHFL(ctx->opcode);
14679 gen_bshfl(ctx, op2, rt, rd);
14680 break;
14681 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14682 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14683 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14684 check_insn(env, ctx, INSN_LOONGSON2E);
14685 gen_loongson_integer(ctx, op1, rd, rs, rt);
14686 break;
14687 case OPC_ABSQ_S_QH_DSP:
14688 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14689 switch (op2) {
14690 case OPC_PRECEQ_L_PWL:
14691 case OPC_PRECEQ_L_PWR:
14692 case OPC_PRECEQ_PW_QHL:
14693 case OPC_PRECEQ_PW_QHR:
14694 case OPC_PRECEQ_PW_QHLA:
14695 case OPC_PRECEQ_PW_QHRA:
14696 case OPC_PRECEQU_QH_OBL:
14697 case OPC_PRECEQU_QH_OBR:
14698 case OPC_PRECEQU_QH_OBLA:
14699 case OPC_PRECEQU_QH_OBRA:
14700 case OPC_PRECEU_QH_OBL:
14701 case OPC_PRECEU_QH_OBR:
14702 case OPC_PRECEU_QH_OBLA:
14703 case OPC_PRECEU_QH_OBRA:
14704 case OPC_ABSQ_S_OB:
14705 case OPC_ABSQ_S_PW:
14706 case OPC_ABSQ_S_QH:
14707 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14708 break;
14709 case OPC_REPL_OB:
14710 case OPC_REPL_PW:
14711 case OPC_REPL_QH:
14712 case OPC_REPLV_OB:
14713 case OPC_REPLV_PW:
14714 case OPC_REPLV_QH:
14715 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14716 break;
14717 default: /* Invalid */
14718 MIPS_INVAL("MASK ABSQ_S.QH");
14719 generate_exception(ctx, EXCP_RI);
14720 break;
14721 }
14722 break;
14723 case OPC_ADDU_OB_DSP:
14724 op2 = MASK_ADDU_OB(ctx->opcode);
14725 switch (op2) {
14726 case OPC_RADDU_L_OB:
14727 case OPC_SUBQ_PW:
14728 case OPC_SUBQ_S_PW:
14729 case OPC_SUBQ_QH:
14730 case OPC_SUBQ_S_QH:
14731 case OPC_SUBU_OB:
14732 case OPC_SUBU_S_OB:
14733 case OPC_SUBU_QH:
14734 case OPC_SUBU_S_QH:
14735 case OPC_SUBUH_OB:
14736 case OPC_SUBUH_R_OB:
14737 case OPC_ADDQ_PW:
14738 case OPC_ADDQ_S_PW:
14739 case OPC_ADDQ_QH:
14740 case OPC_ADDQ_S_QH:
14741 case OPC_ADDU_OB:
14742 case OPC_ADDU_S_OB:
14743 case OPC_ADDU_QH:
14744 case OPC_ADDU_S_QH:
14745 case OPC_ADDUH_OB:
14746 case OPC_ADDUH_R_OB:
14747 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14748 break;
14749 case OPC_MULEQ_S_PW_QHL:
14750 case OPC_MULEQ_S_PW_QHR:
14751 case OPC_MULEU_S_QH_OBL:
14752 case OPC_MULEU_S_QH_OBR:
14753 case OPC_MULQ_RS_QH:
14754 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14755 break;
14756 default: /* Invalid */
14757 MIPS_INVAL("MASK ADDU.OB");
14758 generate_exception(ctx, EXCP_RI);
14759 break;
14760 }
14761 break;
14762 case OPC_CMPU_EQ_OB_DSP:
14763 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14764 switch (op2) {
14765 case OPC_PRECR_SRA_QH_PW:
14766 case OPC_PRECR_SRA_R_QH_PW:
14767 /* Return value is rt. */
14768 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14769 break;
14770 case OPC_PRECR_OB_QH:
14771 case OPC_PRECRQ_OB_QH:
14772 case OPC_PRECRQ_PW_L:
14773 case OPC_PRECRQ_QH_PW:
14774 case OPC_PRECRQ_RS_QH_PW:
14775 case OPC_PRECRQU_S_OB_QH:
14776 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14777 break;
14778 case OPC_CMPU_EQ_OB:
14779 case OPC_CMPU_LT_OB:
14780 case OPC_CMPU_LE_OB:
14781 case OPC_CMP_EQ_QH:
14782 case OPC_CMP_LT_QH:
14783 case OPC_CMP_LE_QH:
14784 case OPC_CMP_EQ_PW:
14785 case OPC_CMP_LT_PW:
14786 case OPC_CMP_LE_PW:
14787 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14788 break;
14789 case OPC_CMPGDU_EQ_OB:
14790 case OPC_CMPGDU_LT_OB:
14791 case OPC_CMPGDU_LE_OB:
14792 case OPC_CMPGU_EQ_OB:
14793 case OPC_CMPGU_LT_OB:
14794 case OPC_CMPGU_LE_OB:
14795 case OPC_PACKRL_PW:
14796 case OPC_PICK_OB:
14797 case OPC_PICK_PW:
14798 case OPC_PICK_QH:
14799 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14800 break;
14801 default: /* Invalid */
14802 MIPS_INVAL("MASK CMPU_EQ.OB");
14803 generate_exception(ctx, EXCP_RI);
14804 break;
14805 }
14806 break;
14807 case OPC_DAPPEND_DSP:
14808 check_dspr2(ctx);
14809 op2 = MASK_DAPPEND(ctx->opcode);
14810 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14811 break;
14812 case OPC_DPAQ_W_QH_DSP:
14813 op2 = MASK_DPAQ_W_QH(ctx->opcode);
14814 switch (op2) {
14815 case OPC_DPAU_H_OBL:
14816 case OPC_DPAU_H_OBR:
14817 case OPC_DPSU_H_OBL:
14818 case OPC_DPSU_H_OBR:
14819 case OPC_DPA_W_QH:
14820 case OPC_DPAQ_S_W_QH:
14821 case OPC_DPS_W_QH:
14822 case OPC_DPSQ_S_W_QH:
14823 case OPC_MULSAQ_S_W_QH:
14824 case OPC_DPAQ_SA_L_PW:
14825 case OPC_DPSQ_SA_L_PW:
14826 case OPC_MULSAQ_S_L_PW:
14827 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14828 break;
14829 case OPC_MAQ_S_W_QHLL:
14830 case OPC_MAQ_S_W_QHLR:
14831 case OPC_MAQ_S_W_QHRL:
14832 case OPC_MAQ_S_W_QHRR:
14833 case OPC_MAQ_SA_W_QHLL:
14834 case OPC_MAQ_SA_W_QHLR:
14835 case OPC_MAQ_SA_W_QHRL:
14836 case OPC_MAQ_SA_W_QHRR:
14837 case OPC_MAQ_S_L_PWL:
14838 case OPC_MAQ_S_L_PWR:
14839 case OPC_DMADD:
14840 case OPC_DMADDU:
14841 case OPC_DMSUB:
14842 case OPC_DMSUBU:
14843 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14844 break;
14845 default: /* Invalid */
14846 MIPS_INVAL("MASK DPAQ.W.QH");
14847 generate_exception(ctx, EXCP_RI);
14848 break;
14849 }
14850 break;
14851 case OPC_DINSV_DSP:
14852 op2 = MASK_INSV(ctx->opcode);
14853 switch (op2) {
14854 case OPC_DINSV:
14855 {
14856 TCGv t0, t1;
14857
14858 if (rt == 0) {
14859 MIPS_DEBUG("NOP");
14860 break;
14861 }
14862 check_dsp(ctx);
14863
14864 t0 = tcg_temp_new();
14865 t1 = tcg_temp_new();
14866
14867 gen_load_gpr(t0, rt);
14868 gen_load_gpr(t1, rs);
14869
14870 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
14871 break;
14872 }
14873 default: /* Invalid */
14874 MIPS_INVAL("MASK DINSV");
14875 generate_exception(ctx, EXCP_RI);
14876 break;
14877 }
14878 break;
14879 case OPC_SHLL_OB_DSP:
14880 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14881 break;
14882 #endif
14883 default: /* Invalid */
14884 MIPS_INVAL("special3");
14885 generate_exception(ctx, EXCP_RI);
14886 break;
14887 }
14888 break;
14889 case OPC_REGIMM:
14890 op1 = MASK_REGIMM(ctx->opcode);
14891 switch (op1) {
14892 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
14893 case OPC_BLTZAL ... OPC_BGEZALL:
14894 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
14895 *is_branch = 1;
14896 break;
14897 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
14898 case OPC_TNEI:
14899 gen_trap(ctx, op1, rs, -1, imm);
14900 break;
14901 case OPC_SYNCI:
14902 check_insn(env, ctx, ISA_MIPS32R2);
14903 /* Treat as NOP. */
14904 break;
14905 case OPC_BPOSGE32: /* MIPS DSP branch */
14906 #if defined(TARGET_MIPS64)
14907 case OPC_BPOSGE64:
14908 #endif
14909 check_dsp(ctx);
14910 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
14911 *is_branch = 1;
14912 break;
14913 default: /* Invalid */
14914 MIPS_INVAL("regimm");
14915 generate_exception(ctx, EXCP_RI);
14916 break;
14917 }
14918 break;
14919 case OPC_CP0:
14920 check_cp0_enabled(ctx);
14921 op1 = MASK_CP0(ctx->opcode);
14922 switch (op1) {
14923 case OPC_MFC0:
14924 case OPC_MTC0:
14925 case OPC_MFTR:
14926 case OPC_MTTR:
14927 #if defined(TARGET_MIPS64)
14928 case OPC_DMFC0:
14929 case OPC_DMTC0:
14930 #endif
14931 #ifndef CONFIG_USER_ONLY
14932 gen_cp0(env, ctx, op1, rt, rd);
14933 #endif /* !CONFIG_USER_ONLY */
14934 break;
14935 case OPC_C0_FIRST ... OPC_C0_LAST:
14936 #ifndef CONFIG_USER_ONLY
14937 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
14938 #endif /* !CONFIG_USER_ONLY */
14939 break;
14940 case OPC_MFMC0:
14941 #ifndef CONFIG_USER_ONLY
14942 {
14943 TCGv t0 = tcg_temp_new();
14944
14945 op2 = MASK_MFMC0(ctx->opcode);
14946 switch (op2) {
14947 case OPC_DMT:
14948 check_insn(env, ctx, ASE_MT);
14949 gen_helper_dmt(t0);
14950 gen_store_gpr(t0, rt);
14951 break;
14952 case OPC_EMT:
14953 check_insn(env, ctx, ASE_MT);
14954 gen_helper_emt(t0);
14955 gen_store_gpr(t0, rt);
14956 break;
14957 case OPC_DVPE:
14958 check_insn(env, ctx, ASE_MT);
14959 gen_helper_dvpe(t0, cpu_env);
14960 gen_store_gpr(t0, rt);
14961 break;
14962 case OPC_EVPE:
14963 check_insn(env, ctx, ASE_MT);
14964 gen_helper_evpe(t0, cpu_env);
14965 gen_store_gpr(t0, rt);
14966 break;
14967 case OPC_DI:
14968 check_insn(env, ctx, ISA_MIPS32R2);
14969 save_cpu_state(ctx, 1);
14970 gen_helper_di(t0, cpu_env);
14971 gen_store_gpr(t0, rt);
14972 /* Stop translation as we may have switched the execution mode */
14973 ctx->bstate = BS_STOP;
14974 break;
14975 case OPC_EI:
14976 check_insn(env, ctx, ISA_MIPS32R2);
14977 save_cpu_state(ctx, 1);
14978 gen_helper_ei(t0, cpu_env);
14979 gen_store_gpr(t0, rt);
14980 /* Stop translation as we may have switched the execution mode */
14981 ctx->bstate = BS_STOP;
14982 break;
14983 default: /* Invalid */
14984 MIPS_INVAL("mfmc0");
14985 generate_exception(ctx, EXCP_RI);
14986 break;
14987 }
14988 tcg_temp_free(t0);
14989 }
14990 #endif /* !CONFIG_USER_ONLY */
14991 break;
14992 case OPC_RDPGPR:
14993 check_insn(env, ctx, ISA_MIPS32R2);
14994 gen_load_srsgpr(rt, rd);
14995 break;
14996 case OPC_WRPGPR:
14997 check_insn(env, ctx, ISA_MIPS32R2);
14998 gen_store_srsgpr(rt, rd);
14999 break;
15000 default:
15001 MIPS_INVAL("cp0");
15002 generate_exception(ctx, EXCP_RI);
15003 break;
15004 }
15005 break;
15006 case OPC_ADDI: /* Arithmetic with immediate opcode */
15007 case OPC_ADDIU:
15008 gen_arith_imm(env, ctx, op, rt, rs, imm);
15009 break;
15010 case OPC_SLTI: /* Set on less than with immediate opcode */
15011 case OPC_SLTIU:
15012 gen_slt_imm(env, ctx, op, rt, rs, imm);
15013 break;
15014 case OPC_ANDI: /* Arithmetic with immediate opcode */
15015 case OPC_LUI:
15016 case OPC_ORI:
15017 case OPC_XORI:
15018 gen_logic_imm(env, ctx, op, rt, rs, imm);
15019 break;
15020 case OPC_J ... OPC_JAL: /* Jump */
15021 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15022 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15023 *is_branch = 1;
15024 break;
15025 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15026 case OPC_BEQL ... OPC_BGTZL:
15027 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15028 *is_branch = 1;
15029 break;
15030 case OPC_LB ... OPC_LWR: /* Load and stores */
15031 case OPC_LL:
15032 gen_ld(env, ctx, op, rt, rs, imm);
15033 break;
15034 case OPC_SB ... OPC_SW:
15035 case OPC_SWR:
15036 gen_st(ctx, op, rt, rs, imm);
15037 break;
15038 case OPC_SC:
15039 gen_st_cond(ctx, op, rt, rs, imm);
15040 break;
15041 case OPC_CACHE:
15042 check_cp0_enabled(ctx);
15043 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15044 /* Treat as NOP. */
15045 break;
15046 case OPC_PREF:
15047 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15048 /* Treat as NOP. */
15049 break;
15050
15051 /* Floating point (COP1). */
15052 case OPC_LWC1:
15053 case OPC_LDC1:
15054 case OPC_SWC1:
15055 case OPC_SDC1:
15056 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15057 break;
15058
15059 case OPC_CP1:
15060 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15061 check_cp1_enabled(ctx);
15062 op1 = MASK_CP1(ctx->opcode);
15063 switch (op1) {
15064 case OPC_MFHC1:
15065 case OPC_MTHC1:
15066 check_insn(env, ctx, ISA_MIPS32R2);
15067 case OPC_MFC1:
15068 case OPC_CFC1:
15069 case OPC_MTC1:
15070 case OPC_CTC1:
15071 gen_cp1(ctx, op1, rt, rd);
15072 break;
15073 #if defined(TARGET_MIPS64)
15074 case OPC_DMFC1:
15075 case OPC_DMTC1:
15076 check_insn(env, ctx, ISA_MIPS3);
15077 gen_cp1(ctx, op1, rt, rd);
15078 break;
15079 #endif
15080 case OPC_BC1ANY2:
15081 case OPC_BC1ANY4:
15082 check_cop1x(ctx);
15083 check_insn(env, ctx, ASE_MIPS3D);
15084 /* fall through */
15085 case OPC_BC1:
15086 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15087 (rt >> 2) & 0x7, imm << 2);
15088 *is_branch = 1;
15089 break;
15090 case OPC_S_FMT:
15091 case OPC_D_FMT:
15092 case OPC_W_FMT:
15093 case OPC_L_FMT:
15094 case OPC_PS_FMT:
15095 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15096 (imm >> 8) & 0x7);
15097 break;
15098 default:
15099 MIPS_INVAL("cp1");
15100 generate_exception (ctx, EXCP_RI);
15101 break;
15102 }
15103 } else {
15104 generate_exception_err(ctx, EXCP_CpU, 1);
15105 }
15106 break;
15107
15108 /* COP2. */
15109 case OPC_LWC2:
15110 case OPC_LDC2:
15111 case OPC_SWC2:
15112 case OPC_SDC2:
15113 /* COP2: Not implemented. */
15114 generate_exception_err(ctx, EXCP_CpU, 2);
15115 break;
15116 case OPC_CP2:
15117 check_insn(env, ctx, INSN_LOONGSON2F);
15118 /* Note that these instructions use different fields. */
15119 gen_loongson_multimedia(ctx, sa, rd, rt);
15120 break;
15121
15122 case OPC_CP3:
15123 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15124 check_cp1_enabled(ctx);
15125 op1 = MASK_CP3(ctx->opcode);
15126 switch (op1) {
15127 case OPC_LWXC1:
15128 case OPC_LDXC1:
15129 case OPC_LUXC1:
15130 case OPC_SWXC1:
15131 case OPC_SDXC1:
15132 case OPC_SUXC1:
15133 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15134 break;
15135 case OPC_PREFX:
15136 /* Treat as NOP. */
15137 break;
15138 case OPC_ALNV_PS:
15139 case OPC_MADD_S:
15140 case OPC_MADD_D:
15141 case OPC_MADD_PS:
15142 case OPC_MSUB_S:
15143 case OPC_MSUB_D:
15144 case OPC_MSUB_PS:
15145 case OPC_NMADD_S:
15146 case OPC_NMADD_D:
15147 case OPC_NMADD_PS:
15148 case OPC_NMSUB_S:
15149 case OPC_NMSUB_D:
15150 case OPC_NMSUB_PS:
15151 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15152 break;
15153 default:
15154 MIPS_INVAL("cp3");
15155 generate_exception (ctx, EXCP_RI);
15156 break;
15157 }
15158 } else {
15159 generate_exception_err(ctx, EXCP_CpU, 1);
15160 }
15161 break;
15162
15163 #if defined(TARGET_MIPS64)
15164 /* MIPS64 opcodes */
15165 case OPC_LWU:
15166 case OPC_LDL ... OPC_LDR:
15167 case OPC_LLD:
15168 case OPC_LD:
15169 check_insn(env, ctx, ISA_MIPS3);
15170 check_mips_64(ctx);
15171 gen_ld(env, ctx, op, rt, rs, imm);
15172 break;
15173 case OPC_SDL ... OPC_SDR:
15174 case OPC_SD:
15175 check_insn(env, ctx, ISA_MIPS3);
15176 check_mips_64(ctx);
15177 gen_st(ctx, op, rt, rs, imm);
15178 break;
15179 case OPC_SCD:
15180 check_insn(env, ctx, ISA_MIPS3);
15181 check_mips_64(ctx);
15182 gen_st_cond(ctx, op, rt, rs, imm);
15183 break;
15184 case OPC_DADDI:
15185 case OPC_DADDIU:
15186 check_insn(env, ctx, ISA_MIPS3);
15187 check_mips_64(ctx);
15188 gen_arith_imm(env, ctx, op, rt, rs, imm);
15189 break;
15190 #endif
15191 case OPC_JALX:
15192 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15193 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15194 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15195 *is_branch = 1;
15196 break;
15197 case OPC_MDMX:
15198 check_insn(env, ctx, ASE_MDMX);
15199 /* MDMX: Not implemented. */
15200 default: /* Invalid */
15201 MIPS_INVAL("major opcode");
15202 generate_exception(ctx, EXCP_RI);
15203 break;
15204 }
15205 }
15206
15207 static inline void
15208 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15209 int search_pc)
15210 {
15211 DisasContext ctx;
15212 target_ulong pc_start;
15213 uint16_t *gen_opc_end;
15214 CPUBreakpoint *bp;
15215 int j, lj = -1;
15216 int num_insns;
15217 int max_insns;
15218 int insn_bytes;
15219 int is_branch;
15220
15221 if (search_pc)
15222 qemu_log("search pc %d\n", search_pc);
15223
15224 pc_start = tb->pc;
15225 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15226 ctx.pc = pc_start;
15227 ctx.saved_pc = -1;
15228 ctx.singlestep_enabled = env->singlestep_enabled;
15229 ctx.tb = tb;
15230 ctx.bstate = BS_NONE;
15231 /* Restore delay slot state from the tb context. */
15232 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15233 restore_cpu_state(env, &ctx);
15234 #ifdef CONFIG_USER_ONLY
15235 ctx.mem_idx = MIPS_HFLAG_UM;
15236 #else
15237 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15238 #endif
15239 num_insns = 0;
15240 max_insns = tb->cflags & CF_COUNT_MASK;
15241 if (max_insns == 0)
15242 max_insns = CF_COUNT_MASK;
15243 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15244 gen_icount_start();
15245 while (ctx.bstate == BS_NONE) {
15246 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15247 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15248 if (bp->pc == ctx.pc) {
15249 save_cpu_state(&ctx, 1);
15250 ctx.bstate = BS_BRANCH;
15251 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15252 /* Include the breakpoint location or the tb won't
15253 * be flushed when it must be. */
15254 ctx.pc += 4;
15255 goto done_generating;
15256 }
15257 }
15258 }
15259
15260 if (search_pc) {
15261 j = gen_opc_ptr - gen_opc_buf;
15262 if (lj < j) {
15263 lj++;
15264 while (lj < j)
15265 gen_opc_instr_start[lj++] = 0;
15266 }
15267 gen_opc_pc[lj] = ctx.pc;
15268 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15269 gen_opc_instr_start[lj] = 1;
15270 gen_opc_icount[lj] = num_insns;
15271 }
15272 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15273 gen_io_start();
15274
15275 is_branch = 0;
15276 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15277 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15278 insn_bytes = 4;
15279 decode_opc(env, &ctx, &is_branch);
15280 } else if (env->insn_flags & ASE_MICROMIPS) {
15281 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15282 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15283 } else if (env->insn_flags & ASE_MIPS16) {
15284 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15285 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15286 } else {
15287 generate_exception(&ctx, EXCP_RI);
15288 ctx.bstate = BS_STOP;
15289 break;
15290 }
15291 if (!is_branch) {
15292 handle_delay_slot(env, &ctx, insn_bytes);
15293 }
15294 ctx.pc += insn_bytes;
15295
15296 num_insns++;
15297
15298 /* Execute a branch and its delay slot as a single instruction.
15299 This is what GDB expects and is consistent with what the
15300 hardware does (e.g. if a delay slot instruction faults, the
15301 reported PC is the PC of the branch). */
15302 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15303 break;
15304
15305 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15306 break;
15307
15308 if (gen_opc_ptr >= gen_opc_end)
15309 break;
15310
15311 if (num_insns >= max_insns)
15312 break;
15313
15314 if (singlestep)
15315 break;
15316 }
15317 if (tb->cflags & CF_LAST_IO)
15318 gen_io_end();
15319 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15320 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15321 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15322 } else {
15323 switch (ctx.bstate) {
15324 case BS_STOP:
15325 gen_goto_tb(&ctx, 0, ctx.pc);
15326 break;
15327 case BS_NONE:
15328 save_cpu_state(&ctx, 0);
15329 gen_goto_tb(&ctx, 0, ctx.pc);
15330 break;
15331 case BS_EXCP:
15332 tcg_gen_exit_tb(0);
15333 break;
15334 case BS_BRANCH:
15335 default:
15336 break;
15337 }
15338 }
15339 done_generating:
15340 gen_icount_end(tb, num_insns);
15341 *gen_opc_ptr = INDEX_op_end;
15342 if (search_pc) {
15343 j = gen_opc_ptr - gen_opc_buf;
15344 lj++;
15345 while (lj <= j)
15346 gen_opc_instr_start[lj++] = 0;
15347 } else {
15348 tb->size = ctx.pc - pc_start;
15349 tb->icount = num_insns;
15350 }
15351 #ifdef DEBUG_DISAS
15352 LOG_DISAS("\n");
15353 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15354 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15355 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15356 qemu_log("\n");
15357 }
15358 #endif
15359 }
15360
15361 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15362 {
15363 gen_intermediate_code_internal(env, tb, 0);
15364 }
15365
15366 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15367 {
15368 gen_intermediate_code_internal(env, tb, 1);
15369 }
15370
15371 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15372 int flags)
15373 {
15374 int i;
15375 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15376
15377 #define printfpr(fp) \
15378 do { \
15379 if (is_fpu64) \
15380 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15381 " fd:%13g fs:%13g psu: %13g\n", \
15382 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15383 (double)(fp)->fd, \
15384 (double)(fp)->fs[FP_ENDIAN_IDX], \
15385 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15386 else { \
15387 fpr_t tmp; \
15388 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15389 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15390 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15391 " fd:%13g fs:%13g psu:%13g\n", \
15392 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15393 (double)tmp.fd, \
15394 (double)tmp.fs[FP_ENDIAN_IDX], \
15395 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15396 } \
15397 } while(0)
15398
15399
15400 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15401 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15402 get_float_exception_flags(&env->active_fpu.fp_status));
15403 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15404 fpu_fprintf(f, "%3s: ", fregnames[i]);
15405 printfpr(&env->active_fpu.fpr[i]);
15406 }
15407
15408 #undef printfpr
15409 }
15410
15411 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15412 /* Debug help: The architecture requires 32bit code to maintain proper
15413 sign-extended values on 64bit machines. */
15414
15415 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15416
15417 static void
15418 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15419 fprintf_function cpu_fprintf,
15420 int flags)
15421 {
15422 int i;
15423
15424 if (!SIGN_EXT_P(env->active_tc.PC))
15425 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15426 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15427 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15428 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15429 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15430 if (!SIGN_EXT_P(env->btarget))
15431 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15432
15433 for (i = 0; i < 32; i++) {
15434 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15435 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15436 }
15437
15438 if (!SIGN_EXT_P(env->CP0_EPC))
15439 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15440 if (!SIGN_EXT_P(env->lladdr))
15441 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15442 }
15443 #endif
15444
15445 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15446 int flags)
15447 {
15448 int i;
15449
15450 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15451 " LO=0x" TARGET_FMT_lx " ds %04x "
15452 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15453 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15454 env->hflags, env->btarget, env->bcond);
15455 for (i = 0; i < 32; i++) {
15456 if ((i & 3) == 0)
15457 cpu_fprintf(f, "GPR%02d:", i);
15458 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15459 if ((i & 3) == 3)
15460 cpu_fprintf(f, "\n");
15461 }
15462
15463 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15464 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15465 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15466 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15467 if (env->hflags & MIPS_HFLAG_FPU)
15468 fpu_dump_state(env, f, cpu_fprintf, flags);
15469 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15470 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15471 #endif
15472 }
15473
15474 static void mips_tcg_init(void)
15475 {
15476 int i;
15477 static int inited;
15478
15479 /* Initialize various static tables. */
15480 if (inited)
15481 return;
15482
15483 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15484 TCGV_UNUSED(cpu_gpr[0]);
15485 for (i = 1; i < 32; i++)
15486 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15487 offsetof(CPUMIPSState, active_tc.gpr[i]),
15488 regnames[i]);
15489
15490 for (i = 0; i < 32; i++) {
15491 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15492 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15493 }
15494
15495 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15496 offsetof(CPUMIPSState, active_tc.PC), "PC");
15497 for (i = 0; i < MIPS_DSP_ACC; i++) {
15498 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15499 offsetof(CPUMIPSState, active_tc.HI[i]),
15500 regnames_HI[i]);
15501 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15502 offsetof(CPUMIPSState, active_tc.LO[i]),
15503 regnames_LO[i]);
15504 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15505 offsetof(CPUMIPSState, active_tc.ACX[i]),
15506 regnames_ACX[i]);
15507 }
15508 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15509 offsetof(CPUMIPSState, active_tc.DSPControl),
15510 "DSPControl");
15511 bcond = tcg_global_mem_new(TCG_AREG0,
15512 offsetof(CPUMIPSState, bcond), "bcond");
15513 btarget = tcg_global_mem_new(TCG_AREG0,
15514 offsetof(CPUMIPSState, btarget), "btarget");
15515 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15516 offsetof(CPUMIPSState, hflags), "hflags");
15517
15518 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15519 offsetof(CPUMIPSState, active_fpu.fcr0),
15520 "fcr0");
15521 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15522 offsetof(CPUMIPSState, active_fpu.fcr31),
15523 "fcr31");
15524
15525 /* register helpers */
15526 #define GEN_HELPER 2
15527 #include "helper.h"
15528
15529 inited = 1;
15530 }
15531
15532 #include "translate_init.c"
15533
15534 MIPSCPU *cpu_mips_init(const char *cpu_model)
15535 {
15536 MIPSCPU *cpu;
15537 CPUMIPSState *env;
15538 const mips_def_t *def;
15539
15540 def = cpu_mips_find_by_name(cpu_model);
15541 if (!def)
15542 return NULL;
15543 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15544 env = &cpu->env;
15545 env->cpu_model = def;
15546 env->cpu_model_str = cpu_model;
15547
15548 #ifndef CONFIG_USER_ONLY
15549 mmu_init(env, def);
15550 #endif
15551 fpu_init(env, def);
15552 mvp_init(env, def);
15553 mips_tcg_init();
15554 cpu_reset(CPU(cpu));
15555 qemu_init_vcpu(env);
15556 return cpu;
15557 }
15558
15559 void cpu_state_reset(CPUMIPSState *env)
15560 {
15561 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15562 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15563 log_cpu_state(env, 0);
15564 }
15565
15566 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15567 tlb_flush(env, 1);
15568
15569 /* Reset registers to their default values */
15570 env->CP0_PRid = env->cpu_model->CP0_PRid;
15571 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15572 #ifdef TARGET_WORDS_BIGENDIAN
15573 env->CP0_Config0 |= (1 << CP0C0_BE);
15574 #endif
15575 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15576 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15577 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15578 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15579 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15580 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15581 << env->cpu_model->CP0_LLAddr_shift;
15582 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15583 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15584 env->CCRes = env->cpu_model->CCRes;
15585 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15586 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15587 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15588 env->current_tc = 0;
15589 env->SEGBITS = env->cpu_model->SEGBITS;
15590 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15591 #if defined(TARGET_MIPS64)
15592 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15593 env->SEGMask |= 3ULL << 62;
15594 }
15595 #endif
15596 env->PABITS = env->cpu_model->PABITS;
15597 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15598 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15599 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15600 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15601 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15602 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15603 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15604 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15605 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15606 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15607 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15608 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15609 env->insn_flags = env->cpu_model->insn_flags;
15610
15611 #if defined(CONFIG_USER_ONLY)
15612 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15613 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15614 hardware registers. */
15615 env->CP0_HWREna |= 0x0000000F;
15616 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15617 env->CP0_Status |= (1 << CP0St_CU1);
15618 }
15619 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15620 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15621 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15622 env->hflags |= MIPS_HFLAG_DSP;
15623 }
15624 #else
15625 if (env->hflags & MIPS_HFLAG_BMASK) {
15626 /* If the exception was raised from a delay slot,
15627 come back to the jump. */
15628 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15629 } else {
15630 env->CP0_ErrorEPC = env->active_tc.PC;
15631 }
15632 env->active_tc.PC = (int32_t)0xBFC00000;
15633 env->CP0_Random = env->tlb->nb_tlb - 1;
15634 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15635 env->CP0_Wired = 0;
15636 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15637 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15638 /* vectored interrupts not implemented, timer on int 7,
15639 no performance counters. */
15640 env->CP0_IntCtl = 0xe0000000;
15641 {
15642 int i;
15643
15644 for (i = 0; i < 7; i++) {
15645 env->CP0_WatchLo[i] = 0;
15646 env->CP0_WatchHi[i] = 0x80000000;
15647 }
15648 env->CP0_WatchLo[7] = 0;
15649 env->CP0_WatchHi[7] = 0;
15650 }
15651 /* Count register increments in debug mode, EJTAG version 1 */
15652 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15653
15654 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15655 int i;
15656
15657 /* Only TC0 on VPE 0 starts as active. */
15658 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15659 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15660 env->tcs[i].CP0_TCHalt = 1;
15661 }
15662 env->active_tc.CP0_TCHalt = 1;
15663 env->halted = 1;
15664
15665 if (!env->cpu_index) {
15666 /* VPE0 starts up enabled. */
15667 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15668 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15669
15670 /* TC0 starts up unhalted. */
15671 env->halted = 0;
15672 env->active_tc.CP0_TCHalt = 0;
15673 env->tcs[0].CP0_TCHalt = 0;
15674 /* With thread 0 active. */
15675 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15676 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15677 }
15678 }
15679 #endif
15680 compute_hflags(env);
15681 env->exception_index = EXCP_NONE;
15682 }
15683
15684 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
15685 {
15686 env->active_tc.PC = gen_opc_pc[pc_pos];
15687 env->hflags &= ~MIPS_HFLAG_BMASK;
15688 env->hflags |= gen_opc_hflags[pc_pos];
15689 }