]> git.proxmox.com Git - mirror_qemu.git/blob - target-mips/translate.c
target-mips: don't use local temps for store conditional
[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 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Compare-Pick Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
345 };
346
347 /* BSHFL opcodes */
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
349
350 enum {
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
354 };
355
356 /* DBSHFL opcodes */
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
358
359 enum {
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
362 };
363
364 /* MIPS DSP REGIMM opcodes */
365 enum {
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
368 };
369
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
371 /* MIPS DSP Load */
372 enum {
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
377 };
378
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
380 enum {
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
407 };
408
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
411 enum {
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
430 };
431
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
433 enum {
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
454 };
455
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457 enum {
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
482 };
483
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485 enum {
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
509 };
510
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
512 enum {
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
536 };
537
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539 enum {
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
542 };
543
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545 enum {
546 /* MIPS DSP Compare-Pick Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
550 };
551
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 enum {
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
572 };
573
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575 enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
601 };
602
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604 enum {
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
633 };
634
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636 enum {
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
666 };
667
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
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678 enum {
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
701 };
702
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704 enum {
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
707 };
708
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710 enum {
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
738 };
739
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741 enum {
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
769 };
770
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
773
774 enum {
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
787 };
788
789 /* MFMC0 opcodes */
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
791
792 enum {
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
799 };
800
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
803
804 enum {
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
813 };
814
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
817
818 /* Values for the fmt field in FP instructions */
819 enum {
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
829 };
830
831 enum {
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
850 };
851
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
854
855 enum {
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
860 };
861
862 enum {
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
865 };
866
867 enum {
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
870 };
871
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
873
874 enum {
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
884 };
885
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
887
888 enum {
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
897
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
906
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
915
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
924
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
931
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
938
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
945
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
952
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
959
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
966
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
973
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
980 };
981
982
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
984
985 enum {
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1006 };
1007
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1016
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1019
1020 #include "gen-icount.h"
1021
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1026 } while(0)
1027
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1032 } while(0)
1033
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1038 } while(0)
1039
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1044 } while(0)
1045
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1050 } while(0)
1051
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1056 } while(0)
1057
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1062 } while(0)
1063
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1067 uint32_t opcode;
1068 int singlestep_enabled;
1069 /* Routine used to access memory */
1070 int mem_idx;
1071 uint32_t hflags, saved_hflags;
1072 int bstate;
1073 target_ulong btarget;
1074 } DisasContext;
1075
1076 enum {
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1078 * exception condition */
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1082 };
1083
1084 static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1089 };
1090
1091 static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1093 };
1094
1095 static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1097 };
1098
1099 static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1101 };
1102
1103 static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1108 };
1109
1110 #define MIPS_DEBUG(fmt, ...) \
1111 do { \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1116 } \
1117 } while (0)
1118
1119 #define LOG_DISAS(...) \
1120 do { \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1123 } \
1124 } while (0)
1125
1126 #define MIPS_INVAL(op) \
1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1129
1130 /* General purpose registers moves. */
1131 static inline void gen_load_gpr (TCGv t, int reg)
1132 {
1133 if (reg == 0)
1134 tcg_gen_movi_tl(t, 0);
1135 else
1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1137 }
1138
1139 static inline void gen_store_gpr (TCGv t, int reg)
1140 {
1141 if (reg != 0)
1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
1143 }
1144
1145 /* Moves to/from ACX register. */
1146 static inline void gen_load_ACX (TCGv t, int reg)
1147 {
1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1149 }
1150
1151 static inline void gen_store_ACX (TCGv t, int reg)
1152 {
1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
1154 }
1155
1156 /* Moves to/from shadow registers. */
1157 static inline void gen_load_srsgpr (int from, int to)
1158 {
1159 TCGv t0 = tcg_temp_new();
1160
1161 if (from == 0)
1162 tcg_gen_movi_tl(t0, 0);
1163 else {
1164 TCGv_i32 t2 = tcg_temp_new_i32();
1165 TCGv_ptr addr = tcg_temp_new_ptr();
1166
1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
1172 tcg_gen_add_ptr(addr, cpu_env, addr);
1173
1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1175 tcg_temp_free_ptr(addr);
1176 tcg_temp_free_i32(t2);
1177 }
1178 gen_store_gpr(t0, to);
1179 tcg_temp_free(t0);
1180 }
1181
1182 static inline void gen_store_srsgpr (int from, int to)
1183 {
1184 if (to != 0) {
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
1187 TCGv_ptr addr = tcg_temp_new_ptr();
1188
1189 gen_load_gpr(t0, from);
1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
1195 tcg_gen_add_ptr(addr, cpu_env, addr);
1196
1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1198 tcg_temp_free_ptr(addr);
1199 tcg_temp_free_i32(t2);
1200 tcg_temp_free(t0);
1201 }
1202 }
1203
1204 /* Floating point register moves. */
1205 static void gen_load_fpr32(TCGv_i32 t, int reg)
1206 {
1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1208 }
1209
1210 static void gen_store_fpr32(TCGv_i32 t, int reg)
1211 {
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
1216 }
1217
1218 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1219 {
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
1224 }
1225
1226 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1227 {
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
1232 }
1233
1234 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1235 {
1236 if (ctx->hflags & MIPS_HFLAG_F64) {
1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
1238 } else {
1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1240 }
1241 }
1242
1243 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1244 {
1245 if (ctx->hflags & MIPS_HFLAG_F64) {
1246 tcg_gen_mov_i64(fpu_f64[reg], t);
1247 } else {
1248 TCGv_i64 t0;
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
1251 tcg_gen_shri_i64(t0, t, 32);
1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1253 tcg_temp_free_i64(t0);
1254 }
1255 }
1256
1257 static inline int get_fp_bit (int cc)
1258 {
1259 if (cc)
1260 return 24 + cc;
1261 else
1262 return 23;
1263 }
1264
1265 /* Tests */
1266 static inline void gen_save_pc(target_ulong pc)
1267 {
1268 tcg_gen_movi_tl(cpu_PC, pc);
1269 }
1270
1271 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1272 {
1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1275 gen_save_pc(ctx->pc);
1276 ctx->saved_pc = ctx->pc;
1277 }
1278 if (ctx->hflags != ctx->saved_hflags) {
1279 tcg_gen_movi_i32(hflags, ctx->hflags);
1280 ctx->saved_hflags = ctx->hflags;
1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1282 case MIPS_HFLAG_BR:
1283 break;
1284 case MIPS_HFLAG_BC:
1285 case MIPS_HFLAG_BL:
1286 case MIPS_HFLAG_B:
1287 tcg_gen_movi_tl(btarget, ctx->btarget);
1288 break;
1289 }
1290 }
1291 }
1292
1293 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1294 {
1295 ctx->saved_hflags = ctx->hflags;
1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1297 case MIPS_HFLAG_BR:
1298 break;
1299 case MIPS_HFLAG_BC:
1300 case MIPS_HFLAG_BL:
1301 case MIPS_HFLAG_B:
1302 ctx->btarget = env->btarget;
1303 break;
1304 }
1305 }
1306
1307 static inline void
1308 generate_exception_err (DisasContext *ctx, int excp, int err)
1309 {
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
1312 save_cpu_state(ctx, 1);
1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
1316 }
1317
1318 static inline void
1319 generate_exception (DisasContext *ctx, int excp)
1320 {
1321 save_cpu_state(ctx, 1);
1322 gen_helper_0e0i(raise_exception, excp);
1323 }
1324
1325 /* Addresses computation */
1326 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1327 {
1328 tcg_gen_add_tl(ret, arg0, arg1);
1329
1330 #if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
1336 tcg_gen_ext32s_i64(ret, ret);
1337 }
1338 #endif
1339 }
1340
1341 static inline void check_cp0_enabled(DisasContext *ctx)
1342 {
1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1344 generate_exception_err(ctx, EXCP_CpU, 0);
1345 }
1346
1347 static inline void check_cp1_enabled(DisasContext *ctx)
1348 {
1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1351 }
1352
1353 /* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1355 opcode tables. */
1356
1357 static inline void check_cop1x(DisasContext *ctx)
1358 {
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1361 }
1362
1363 /* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1365
1366 static inline void check_cp1_64bitmode(DisasContext *ctx)
1367 {
1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1369 generate_exception(ctx, EXCP_RI);
1370 }
1371
1372 /*
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1379 *
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1382 */
1383 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1384 {
1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1386 generate_exception(ctx, EXCP_RI);
1387 }
1388
1389 /* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1391 */
1392
1393 static inline void check_dsp(DisasContext *ctx)
1394 {
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1397 }
1398 }
1399
1400 static inline void check_dspr2(DisasContext *ctx)
1401 {
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1404 }
1405 }
1406
1407 /* This code generates a "reserved instruction" exception if the
1408 CPU does not support the instruction set corresponding to flags. */
1409 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1410 {
1411 if (unlikely(!(env->insn_flags & flags)))
1412 generate_exception(ctx, EXCP_RI);
1413 }
1414
1415 /* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
1417 static inline void check_mips_64(DisasContext *ctx)
1418 {
1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1420 generate_exception(ctx, EXCP_RI);
1421 }
1422
1423 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1426 this one use. */
1427 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1432 { \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1435 switch (ifmt) { \
1436 case FMT_PS: \
1437 check_cp1_64bitmode(ctx); \
1438 break; \
1439 case FMT_D: \
1440 if (abs) { \
1441 check_cop1x(ctx); \
1442 } \
1443 check_cp1_registers(ctx, fs | ft); \
1444 break; \
1445 case FMT_S: \
1446 if (abs) { \
1447 check_cop1x(ctx); \
1448 } \
1449 break; \
1450 } \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1453 switch (n) { \
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1470 default: abort(); \
1471 } \
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1474 }
1475
1476 FOP_CONDS(, 0, d, FMT_D, 64)
1477 FOP_CONDS(abs, 1, d, FMT_D, 64)
1478 FOP_CONDS(, 0, s, FMT_S, 32)
1479 FOP_CONDS(abs, 1, s, FMT_S, 32)
1480 FOP_CONDS(, 0, ps, FMT_PS, 64)
1481 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1482 #undef FOP_CONDS
1483 #undef gen_ldcmp_fpr32
1484 #undef gen_ldcmp_fpr64
1485
1486 /* load/store instructions. */
1487 #ifdef CONFIG_USER_ONLY
1488 #define OP_LD_ATOMIC(insn,fname) \
1489 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1490 { \
1491 TCGv t0 = tcg_temp_new(); \
1492 tcg_gen_mov_tl(t0, arg1); \
1493 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1494 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1495 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1496 tcg_temp_free(t0); \
1497 }
1498 #else
1499 #define OP_LD_ATOMIC(insn,fname) \
1500 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1501 { \
1502 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1503 }
1504 #endif
1505 OP_LD_ATOMIC(ll,ld32s);
1506 #if defined(TARGET_MIPS64)
1507 OP_LD_ATOMIC(lld,ld64);
1508 #endif
1509 #undef OP_LD_ATOMIC
1510
1511 #ifdef CONFIG_USER_ONLY
1512 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1513 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1514 { \
1515 TCGv t0 = tcg_temp_new(); \
1516 int l1 = gen_new_label(); \
1517 int l2 = gen_new_label(); \
1518 \
1519 tcg_gen_andi_tl(t0, arg2, almask); \
1520 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1521 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1522 generate_exception(ctx, EXCP_AdES); \
1523 gen_set_label(l1); \
1524 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1525 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1526 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1527 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1528 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1529 gen_helper_0e0i(raise_exception, EXCP_SC); \
1530 gen_set_label(l2); \
1531 tcg_gen_movi_tl(t0, 0); \
1532 gen_store_gpr(t0, rt); \
1533 tcg_temp_free(t0); \
1534 }
1535 #else
1536 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1537 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1538 { \
1539 TCGv t0 = tcg_temp_new(); \
1540 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1541 gen_store_gpr(t0, rt); \
1542 tcg_temp_free(t0); \
1543 }
1544 #endif
1545 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1546 #if defined(TARGET_MIPS64)
1547 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1548 #endif
1549 #undef OP_ST_ATOMIC
1550
1551 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1552 int base, int16_t offset)
1553 {
1554 if (base == 0) {
1555 tcg_gen_movi_tl(addr, offset);
1556 } else if (offset == 0) {
1557 gen_load_gpr(addr, base);
1558 } else {
1559 tcg_gen_movi_tl(addr, offset);
1560 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1561 }
1562 }
1563
1564 static target_ulong pc_relative_pc (DisasContext *ctx)
1565 {
1566 target_ulong pc = ctx->pc;
1567
1568 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1569 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1570
1571 pc -= branch_bytes;
1572 }
1573
1574 pc &= ~(target_ulong)3;
1575 return pc;
1576 }
1577
1578 /* Load */
1579 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1580 int rt, int base, int16_t offset)
1581 {
1582 const char *opn = "ld";
1583 TCGv t0, t1, t2;
1584
1585 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1586 /* Loongson CPU uses a load to zero register for prefetch.
1587 We emulate it as a NOP. On other CPU we must perform the
1588 actual memory access. */
1589 MIPS_DEBUG("NOP");
1590 return;
1591 }
1592
1593 t0 = tcg_temp_new();
1594 gen_base_offset_addr(ctx, t0, base, offset);
1595
1596 switch (opc) {
1597 #if defined(TARGET_MIPS64)
1598 case OPC_LWU:
1599 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1600 gen_store_gpr(t0, rt);
1601 opn = "lwu";
1602 break;
1603 case OPC_LD:
1604 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1605 gen_store_gpr(t0, rt);
1606 opn = "ld";
1607 break;
1608 case OPC_LLD:
1609 save_cpu_state(ctx, 1);
1610 op_ld_lld(t0, t0, ctx);
1611 gen_store_gpr(t0, rt);
1612 opn = "lld";
1613 break;
1614 case OPC_LDL:
1615 t1 = tcg_temp_new();
1616 tcg_gen_andi_tl(t1, t0, 7);
1617 #ifndef TARGET_WORDS_BIGENDIAN
1618 tcg_gen_xori_tl(t1, t1, 7);
1619 #endif
1620 tcg_gen_shli_tl(t1, t1, 3);
1621 tcg_gen_andi_tl(t0, t0, ~7);
1622 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1623 tcg_gen_shl_tl(t0, t0, t1);
1624 tcg_gen_xori_tl(t1, t1, 63);
1625 t2 = tcg_const_tl(0x7fffffffffffffffull);
1626 tcg_gen_shr_tl(t2, t2, t1);
1627 gen_load_gpr(t1, rt);
1628 tcg_gen_and_tl(t1, t1, t2);
1629 tcg_temp_free(t2);
1630 tcg_gen_or_tl(t0, t0, t1);
1631 tcg_temp_free(t1);
1632 gen_store_gpr(t0, rt);
1633 opn = "ldl";
1634 break;
1635 case OPC_LDR:
1636 t1 = tcg_temp_new();
1637 tcg_gen_andi_tl(t1, t0, 7);
1638 #ifdef TARGET_WORDS_BIGENDIAN
1639 tcg_gen_xori_tl(t1, t1, 7);
1640 #endif
1641 tcg_gen_shli_tl(t1, t1, 3);
1642 tcg_gen_andi_tl(t0, t0, ~7);
1643 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1644 tcg_gen_shr_tl(t0, t0, t1);
1645 tcg_gen_xori_tl(t1, t1, 63);
1646 t2 = tcg_const_tl(0xfffffffffffffffeull);
1647 tcg_gen_shl_tl(t2, t2, t1);
1648 gen_load_gpr(t1, rt);
1649 tcg_gen_and_tl(t1, t1, t2);
1650 tcg_temp_free(t2);
1651 tcg_gen_or_tl(t0, t0, t1);
1652 tcg_temp_free(t1);
1653 gen_store_gpr(t0, rt);
1654 opn = "ldr";
1655 break;
1656 case OPC_LDPC:
1657 t1 = tcg_const_tl(pc_relative_pc(ctx));
1658 gen_op_addr_add(ctx, t0, t0, t1);
1659 tcg_temp_free(t1);
1660 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1661 gen_store_gpr(t0, rt);
1662 opn = "ldpc";
1663 break;
1664 #endif
1665 case OPC_LWPC:
1666 t1 = tcg_const_tl(pc_relative_pc(ctx));
1667 gen_op_addr_add(ctx, t0, t0, t1);
1668 tcg_temp_free(t1);
1669 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1670 gen_store_gpr(t0, rt);
1671 opn = "lwpc";
1672 break;
1673 case OPC_LW:
1674 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1675 gen_store_gpr(t0, rt);
1676 opn = "lw";
1677 break;
1678 case OPC_LH:
1679 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1680 gen_store_gpr(t0, rt);
1681 opn = "lh";
1682 break;
1683 case OPC_LHU:
1684 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1685 gen_store_gpr(t0, rt);
1686 opn = "lhu";
1687 break;
1688 case OPC_LB:
1689 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1690 gen_store_gpr(t0, rt);
1691 opn = "lb";
1692 break;
1693 case OPC_LBU:
1694 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1695 gen_store_gpr(t0, rt);
1696 opn = "lbu";
1697 break;
1698 case OPC_LWL:
1699 t1 = tcg_temp_new();
1700 tcg_gen_andi_tl(t1, t0, 3);
1701 #ifndef TARGET_WORDS_BIGENDIAN
1702 tcg_gen_xori_tl(t1, t1, 3);
1703 #endif
1704 tcg_gen_shli_tl(t1, t1, 3);
1705 tcg_gen_andi_tl(t0, t0, ~3);
1706 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1707 tcg_gen_shl_tl(t0, t0, t1);
1708 tcg_gen_xori_tl(t1, t1, 31);
1709 t2 = tcg_const_tl(0x7fffffffull);
1710 tcg_gen_shr_tl(t2, t2, t1);
1711 gen_load_gpr(t1, rt);
1712 tcg_gen_and_tl(t1, t1, t2);
1713 tcg_temp_free(t2);
1714 tcg_gen_or_tl(t0, t0, t1);
1715 tcg_temp_free(t1);
1716 tcg_gen_ext32s_tl(t0, t0);
1717 gen_store_gpr(t0, rt);
1718 opn = "lwl";
1719 break;
1720 case OPC_LWR:
1721 t1 = tcg_temp_new();
1722 tcg_gen_andi_tl(t1, t0, 3);
1723 #ifdef TARGET_WORDS_BIGENDIAN
1724 tcg_gen_xori_tl(t1, t1, 3);
1725 #endif
1726 tcg_gen_shli_tl(t1, t1, 3);
1727 tcg_gen_andi_tl(t0, t0, ~3);
1728 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1729 tcg_gen_shr_tl(t0, t0, t1);
1730 tcg_gen_xori_tl(t1, t1, 31);
1731 t2 = tcg_const_tl(0xfffffffeull);
1732 tcg_gen_shl_tl(t2, t2, t1);
1733 gen_load_gpr(t1, rt);
1734 tcg_gen_and_tl(t1, t1, t2);
1735 tcg_temp_free(t2);
1736 tcg_gen_or_tl(t0, t0, t1);
1737 tcg_temp_free(t1);
1738 gen_store_gpr(t0, rt);
1739 opn = "lwr";
1740 break;
1741 case OPC_LL:
1742 save_cpu_state(ctx, 1);
1743 op_ld_ll(t0, t0, ctx);
1744 gen_store_gpr(t0, rt);
1745 opn = "ll";
1746 break;
1747 }
1748 (void)opn; /* avoid a compiler warning */
1749 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1750 tcg_temp_free(t0);
1751 }
1752
1753 /* Store */
1754 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1755 int base, int16_t offset)
1756 {
1757 const char *opn = "st";
1758 TCGv t0 = tcg_temp_new();
1759 TCGv t1 = tcg_temp_new();
1760
1761 gen_base_offset_addr(ctx, t0, base, offset);
1762 gen_load_gpr(t1, rt);
1763 switch (opc) {
1764 #if defined(TARGET_MIPS64)
1765 case OPC_SD:
1766 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1767 opn = "sd";
1768 break;
1769 case OPC_SDL:
1770 save_cpu_state(ctx, 1);
1771 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1772 opn = "sdl";
1773 break;
1774 case OPC_SDR:
1775 save_cpu_state(ctx, 1);
1776 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1777 opn = "sdr";
1778 break;
1779 #endif
1780 case OPC_SW:
1781 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1782 opn = "sw";
1783 break;
1784 case OPC_SH:
1785 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1786 opn = "sh";
1787 break;
1788 case OPC_SB:
1789 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1790 opn = "sb";
1791 break;
1792 case OPC_SWL:
1793 save_cpu_state(ctx, 1);
1794 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1795 opn = "swl";
1796 break;
1797 case OPC_SWR:
1798 save_cpu_state(ctx, 1);
1799 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1800 opn = "swr";
1801 break;
1802 }
1803 (void)opn; /* avoid a compiler warning */
1804 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1805 tcg_temp_free(t0);
1806 tcg_temp_free(t1);
1807 }
1808
1809
1810 /* Store conditional */
1811 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1812 int base, int16_t offset)
1813 {
1814 const char *opn = "st_cond";
1815 TCGv t0, t1;
1816
1817 #ifdef CONFIG_USER_ONLY
1818 t0 = tcg_temp_local_new();
1819 t1 = tcg_temp_local_new();
1820 #else
1821 t0 = tcg_temp_new();
1822 t1 = tcg_temp_new();
1823 #endif
1824 gen_base_offset_addr(ctx, t0, base, offset);
1825 gen_load_gpr(t1, rt);
1826 switch (opc) {
1827 #if defined(TARGET_MIPS64)
1828 case OPC_SCD:
1829 save_cpu_state(ctx, 1);
1830 op_st_scd(t1, t0, rt, ctx);
1831 opn = "scd";
1832 break;
1833 #endif
1834 case OPC_SC:
1835 save_cpu_state(ctx, 1);
1836 op_st_sc(t1, t0, rt, ctx);
1837 opn = "sc";
1838 break;
1839 }
1840 (void)opn; /* avoid a compiler warning */
1841 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1842 tcg_temp_free(t1);
1843 tcg_temp_free(t0);
1844 }
1845
1846 /* Load and store */
1847 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1848 int base, int16_t offset)
1849 {
1850 const char *opn = "flt_ldst";
1851 TCGv t0 = tcg_temp_new();
1852
1853 gen_base_offset_addr(ctx, t0, base, offset);
1854 /* Don't do NOP if destination is zero: we must perform the actual
1855 memory access. */
1856 switch (opc) {
1857 case OPC_LWC1:
1858 {
1859 TCGv_i32 fp0 = tcg_temp_new_i32();
1860
1861 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1862 tcg_gen_trunc_tl_i32(fp0, t0);
1863 gen_store_fpr32(fp0, ft);
1864 tcg_temp_free_i32(fp0);
1865 }
1866 opn = "lwc1";
1867 break;
1868 case OPC_SWC1:
1869 {
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 TCGv t1 = tcg_temp_new();
1872
1873 gen_load_fpr32(fp0, ft);
1874 tcg_gen_extu_i32_tl(t1, fp0);
1875 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1876 tcg_temp_free(t1);
1877 tcg_temp_free_i32(fp0);
1878 }
1879 opn = "swc1";
1880 break;
1881 case OPC_LDC1:
1882 {
1883 TCGv_i64 fp0 = tcg_temp_new_i64();
1884
1885 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1886 gen_store_fpr64(ctx, fp0, ft);
1887 tcg_temp_free_i64(fp0);
1888 }
1889 opn = "ldc1";
1890 break;
1891 case OPC_SDC1:
1892 {
1893 TCGv_i64 fp0 = tcg_temp_new_i64();
1894
1895 gen_load_fpr64(ctx, fp0, ft);
1896 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1897 tcg_temp_free_i64(fp0);
1898 }
1899 opn = "sdc1";
1900 break;
1901 default:
1902 MIPS_INVAL(opn);
1903 generate_exception(ctx, EXCP_RI);
1904 goto out;
1905 }
1906 (void)opn; /* avoid a compiler warning */
1907 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1908 out:
1909 tcg_temp_free(t0);
1910 }
1911
1912 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1913 uint32_t op, int rt, int rs, int16_t imm)
1914 {
1915 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1916 check_cp1_enabled(ctx);
1917 gen_flt_ldst(ctx, op, rt, rs, imm);
1918 } else {
1919 generate_exception_err(ctx, EXCP_CpU, 1);
1920 }
1921 }
1922
1923 /* Arithmetic with immediate operand */
1924 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1925 int rt, int rs, int16_t imm)
1926 {
1927 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1928 const char *opn = "imm arith";
1929
1930 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1931 /* If no destination, treat it as a NOP.
1932 For addi, we must generate the overflow exception when needed. */
1933 MIPS_DEBUG("NOP");
1934 return;
1935 }
1936 switch (opc) {
1937 case OPC_ADDI:
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 tcg_gen_ext32s_tl(t0, t0);
1947
1948 tcg_gen_xori_tl(t1, t1, ~uimm);
1949 tcg_gen_xori_tl(t2, t0, uimm);
1950 tcg_gen_and_tl(t1, t1, t2);
1951 tcg_temp_free(t2);
1952 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1953 tcg_temp_free(t1);
1954 /* operands of same sign, result different sign */
1955 generate_exception(ctx, EXCP_OVERFLOW);
1956 gen_set_label(l1);
1957 tcg_gen_ext32s_tl(t0, t0);
1958 gen_store_gpr(t0, rt);
1959 tcg_temp_free(t0);
1960 }
1961 opn = "addi";
1962 break;
1963 case OPC_ADDIU:
1964 if (rs != 0) {
1965 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1966 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1967 } else {
1968 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1969 }
1970 opn = "addiu";
1971 break;
1972 #if defined(TARGET_MIPS64)
1973 case OPC_DADDI:
1974 {
1975 TCGv t0 = tcg_temp_local_new();
1976 TCGv t1 = tcg_temp_new();
1977 TCGv t2 = tcg_temp_new();
1978 int l1 = gen_new_label();
1979
1980 gen_load_gpr(t1, rs);
1981 tcg_gen_addi_tl(t0, t1, uimm);
1982
1983 tcg_gen_xori_tl(t1, t1, ~uimm);
1984 tcg_gen_xori_tl(t2, t0, uimm);
1985 tcg_gen_and_tl(t1, t1, t2);
1986 tcg_temp_free(t2);
1987 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1988 tcg_temp_free(t1);
1989 /* operands of same sign, result different sign */
1990 generate_exception(ctx, EXCP_OVERFLOW);
1991 gen_set_label(l1);
1992 gen_store_gpr(t0, rt);
1993 tcg_temp_free(t0);
1994 }
1995 opn = "daddi";
1996 break;
1997 case OPC_DADDIU:
1998 if (rs != 0) {
1999 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2000 } else {
2001 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2002 }
2003 opn = "daddiu";
2004 break;
2005 #endif
2006 }
2007 (void)opn; /* avoid a compiler warning */
2008 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2009 }
2010
2011 /* Logic with immediate operand */
2012 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2013 int rt, int rs, int16_t imm)
2014 {
2015 target_ulong uimm;
2016 const char *opn = "imm logic";
2017
2018 if (rt == 0) {
2019 /* If no destination, treat it as a NOP. */
2020 MIPS_DEBUG("NOP");
2021 return;
2022 }
2023 uimm = (uint16_t)imm;
2024 switch (opc) {
2025 case OPC_ANDI:
2026 if (likely(rs != 0))
2027 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2028 else
2029 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2030 opn = "andi";
2031 break;
2032 case OPC_ORI:
2033 if (rs != 0)
2034 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2035 else
2036 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2037 opn = "ori";
2038 break;
2039 case OPC_XORI:
2040 if (likely(rs != 0))
2041 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2042 else
2043 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2044 opn = "xori";
2045 break;
2046 case OPC_LUI:
2047 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2048 opn = "lui";
2049 break;
2050 }
2051 (void)opn; /* avoid a compiler warning */
2052 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2053 }
2054
2055 /* Set on less than with immediate operand */
2056 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2057 int rt, int rs, int16_t imm)
2058 {
2059 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2060 const char *opn = "imm arith";
2061 TCGv t0;
2062
2063 if (rt == 0) {
2064 /* If no destination, treat it as a NOP. */
2065 MIPS_DEBUG("NOP");
2066 return;
2067 }
2068 t0 = tcg_temp_new();
2069 gen_load_gpr(t0, rs);
2070 switch (opc) {
2071 case OPC_SLTI:
2072 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2073 opn = "slti";
2074 break;
2075 case OPC_SLTIU:
2076 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2077 opn = "sltiu";
2078 break;
2079 }
2080 (void)opn; /* avoid a compiler warning */
2081 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2082 tcg_temp_free(t0);
2083 }
2084
2085 /* Shifts with immediate operand */
2086 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2087 int rt, int rs, int16_t imm)
2088 {
2089 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2090 const char *opn = "imm shift";
2091 TCGv t0;
2092
2093 if (rt == 0) {
2094 /* If no destination, treat it as a NOP. */
2095 MIPS_DEBUG("NOP");
2096 return;
2097 }
2098
2099 t0 = tcg_temp_new();
2100 gen_load_gpr(t0, rs);
2101 switch (opc) {
2102 case OPC_SLL:
2103 tcg_gen_shli_tl(t0, t0, uimm);
2104 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2105 opn = "sll";
2106 break;
2107 case OPC_SRA:
2108 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2109 opn = "sra";
2110 break;
2111 case OPC_SRL:
2112 if (uimm != 0) {
2113 tcg_gen_ext32u_tl(t0, t0);
2114 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2115 } else {
2116 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2117 }
2118 opn = "srl";
2119 break;
2120 case OPC_ROTR:
2121 if (uimm != 0) {
2122 TCGv_i32 t1 = tcg_temp_new_i32();
2123
2124 tcg_gen_trunc_tl_i32(t1, t0);
2125 tcg_gen_rotri_i32(t1, t1, uimm);
2126 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2127 tcg_temp_free_i32(t1);
2128 } else {
2129 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2130 }
2131 opn = "rotr";
2132 break;
2133 #if defined(TARGET_MIPS64)
2134 case OPC_DSLL:
2135 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2136 opn = "dsll";
2137 break;
2138 case OPC_DSRA:
2139 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2140 opn = "dsra";
2141 break;
2142 case OPC_DSRL:
2143 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2144 opn = "dsrl";
2145 break;
2146 case OPC_DROTR:
2147 if (uimm != 0) {
2148 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2149 } else {
2150 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2151 }
2152 opn = "drotr";
2153 break;
2154 case OPC_DSLL32:
2155 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2156 opn = "dsll32";
2157 break;
2158 case OPC_DSRA32:
2159 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2160 opn = "dsra32";
2161 break;
2162 case OPC_DSRL32:
2163 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2164 opn = "dsrl32";
2165 break;
2166 case OPC_DROTR32:
2167 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2168 opn = "drotr32";
2169 break;
2170 #endif
2171 }
2172 (void)opn; /* avoid a compiler warning */
2173 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2174 tcg_temp_free(t0);
2175 }
2176
2177 /* Arithmetic */
2178 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2179 int rd, int rs, int rt)
2180 {
2181 const char *opn = "arith";
2182
2183 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2184 && opc != OPC_DADD && opc != OPC_DSUB) {
2185 /* If no destination, treat it as a NOP.
2186 For add & sub, we must generate the overflow exception when needed. */
2187 MIPS_DEBUG("NOP");
2188 return;
2189 }
2190
2191 switch (opc) {
2192 case OPC_ADD:
2193 {
2194 TCGv t0 = tcg_temp_local_new();
2195 TCGv t1 = tcg_temp_new();
2196 TCGv t2 = tcg_temp_new();
2197 int l1 = gen_new_label();
2198
2199 gen_load_gpr(t1, rs);
2200 gen_load_gpr(t2, rt);
2201 tcg_gen_add_tl(t0, t1, t2);
2202 tcg_gen_ext32s_tl(t0, t0);
2203 tcg_gen_xor_tl(t1, t1, t2);
2204 tcg_gen_xor_tl(t2, t0, t2);
2205 tcg_gen_andc_tl(t1, t2, t1);
2206 tcg_temp_free(t2);
2207 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2208 tcg_temp_free(t1);
2209 /* operands of same sign, result different sign */
2210 generate_exception(ctx, EXCP_OVERFLOW);
2211 gen_set_label(l1);
2212 gen_store_gpr(t0, rd);
2213 tcg_temp_free(t0);
2214 }
2215 opn = "add";
2216 break;
2217 case OPC_ADDU:
2218 if (rs != 0 && rt != 0) {
2219 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2220 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2221 } else if (rs == 0 && rt != 0) {
2222 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2223 } else if (rs != 0 && rt == 0) {
2224 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2225 } else {
2226 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2227 }
2228 opn = "addu";
2229 break;
2230 case OPC_SUB:
2231 {
2232 TCGv t0 = tcg_temp_local_new();
2233 TCGv t1 = tcg_temp_new();
2234 TCGv t2 = tcg_temp_new();
2235 int l1 = gen_new_label();
2236
2237 gen_load_gpr(t1, rs);
2238 gen_load_gpr(t2, rt);
2239 tcg_gen_sub_tl(t0, t1, t2);
2240 tcg_gen_ext32s_tl(t0, t0);
2241 tcg_gen_xor_tl(t2, t1, t2);
2242 tcg_gen_xor_tl(t1, t0, t1);
2243 tcg_gen_and_tl(t1, t1, t2);
2244 tcg_temp_free(t2);
2245 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2246 tcg_temp_free(t1);
2247 /* operands of different sign, first operand and result different sign */
2248 generate_exception(ctx, EXCP_OVERFLOW);
2249 gen_set_label(l1);
2250 gen_store_gpr(t0, rd);
2251 tcg_temp_free(t0);
2252 }
2253 opn = "sub";
2254 break;
2255 case OPC_SUBU:
2256 if (rs != 0 && rt != 0) {
2257 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2258 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2259 } else if (rs == 0 && rt != 0) {
2260 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2261 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2262 } else if (rs != 0 && rt == 0) {
2263 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2264 } else {
2265 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2266 }
2267 opn = "subu";
2268 break;
2269 #if defined(TARGET_MIPS64)
2270 case OPC_DADD:
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_add_tl(t0, t1, t2);
2280 tcg_gen_xor_tl(t1, t1, t2);
2281 tcg_gen_xor_tl(t2, t0, t2);
2282 tcg_gen_andc_tl(t1, t2, t1);
2283 tcg_temp_free(t2);
2284 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2285 tcg_temp_free(t1);
2286 /* operands of same sign, 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 = "dadd";
2293 break;
2294 case OPC_DADDU:
2295 if (rs != 0 && rt != 0) {
2296 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2297 } else if (rs == 0 && rt != 0) {
2298 tcg_gen_mov_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 = "daddu";
2305 break;
2306 case OPC_DSUB:
2307 {
2308 TCGv t0 = tcg_temp_local_new();
2309 TCGv t1 = tcg_temp_new();
2310 TCGv t2 = tcg_temp_new();
2311 int l1 = gen_new_label();
2312
2313 gen_load_gpr(t1, rs);
2314 gen_load_gpr(t2, rt);
2315 tcg_gen_sub_tl(t0, t1, t2);
2316 tcg_gen_xor_tl(t2, t1, t2);
2317 tcg_gen_xor_tl(t1, t0, t1);
2318 tcg_gen_and_tl(t1, t1, t2);
2319 tcg_temp_free(t2);
2320 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2321 tcg_temp_free(t1);
2322 /* operands of different sign, first operand and result different sign */
2323 generate_exception(ctx, EXCP_OVERFLOW);
2324 gen_set_label(l1);
2325 gen_store_gpr(t0, rd);
2326 tcg_temp_free(t0);
2327 }
2328 opn = "dsub";
2329 break;
2330 case OPC_DSUBU:
2331 if (rs != 0 && rt != 0) {
2332 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2333 } else if (rs == 0 && rt != 0) {
2334 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2335 } else if (rs != 0 && rt == 0) {
2336 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2337 } else {
2338 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2339 }
2340 opn = "dsubu";
2341 break;
2342 #endif
2343 case OPC_MUL:
2344 if (likely(rs != 0 && rt != 0)) {
2345 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2346 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2347 } else {
2348 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2349 }
2350 opn = "mul";
2351 break;
2352 }
2353 (void)opn; /* avoid a compiler warning */
2354 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2355 }
2356
2357 /* Conditional move */
2358 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2359 int rd, int rs, int rt)
2360 {
2361 const char *opn = "cond move";
2362 int l1;
2363
2364 if (rd == 0) {
2365 /* If no destination, treat it as a NOP.
2366 For add & sub, we must generate the overflow exception when needed. */
2367 MIPS_DEBUG("NOP");
2368 return;
2369 }
2370
2371 l1 = gen_new_label();
2372 switch (opc) {
2373 case OPC_MOVN:
2374 if (likely(rt != 0))
2375 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2376 else
2377 tcg_gen_br(l1);
2378 opn = "movn";
2379 break;
2380 case OPC_MOVZ:
2381 if (likely(rt != 0))
2382 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2383 opn = "movz";
2384 break;
2385 }
2386 if (rs != 0)
2387 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2388 else
2389 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2390 gen_set_label(l1);
2391
2392 (void)opn; /* avoid a compiler warning */
2393 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2394 }
2395
2396 /* Logic */
2397 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2398 int rd, int rs, int rt)
2399 {
2400 const char *opn = "logic";
2401
2402 if (rd == 0) {
2403 /* If no destination, treat it as a NOP. */
2404 MIPS_DEBUG("NOP");
2405 return;
2406 }
2407
2408 switch (opc) {
2409 case OPC_AND:
2410 if (likely(rs != 0 && rt != 0)) {
2411 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2412 } else {
2413 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2414 }
2415 opn = "and";
2416 break;
2417 case OPC_NOR:
2418 if (rs != 0 && rt != 0) {
2419 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2420 } else if (rs == 0 && rt != 0) {
2421 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2422 } else if (rs != 0 && rt == 0) {
2423 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2424 } else {
2425 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2426 }
2427 opn = "nor";
2428 break;
2429 case OPC_OR:
2430 if (likely(rs != 0 && rt != 0)) {
2431 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2432 } else if (rs == 0 && rt != 0) {
2433 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2434 } else if (rs != 0 && rt == 0) {
2435 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2436 } else {
2437 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2438 }
2439 opn = "or";
2440 break;
2441 case OPC_XOR:
2442 if (likely(rs != 0 && rt != 0)) {
2443 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2444 } else if (rs == 0 && rt != 0) {
2445 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2446 } else if (rs != 0 && rt == 0) {
2447 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2448 } else {
2449 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2450 }
2451 opn = "xor";
2452 break;
2453 }
2454 (void)opn; /* avoid a compiler warning */
2455 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2456 }
2457
2458 /* Set on lower than */
2459 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2460 int rd, int rs, int rt)
2461 {
2462 const char *opn = "slt";
2463 TCGv t0, t1;
2464
2465 if (rd == 0) {
2466 /* If no destination, treat it as a NOP. */
2467 MIPS_DEBUG("NOP");
2468 return;
2469 }
2470
2471 t0 = tcg_temp_new();
2472 t1 = tcg_temp_new();
2473 gen_load_gpr(t0, rs);
2474 gen_load_gpr(t1, rt);
2475 switch (opc) {
2476 case OPC_SLT:
2477 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2478 opn = "slt";
2479 break;
2480 case OPC_SLTU:
2481 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2482 opn = "sltu";
2483 break;
2484 }
2485 (void)opn; /* avoid a compiler warning */
2486 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2487 tcg_temp_free(t0);
2488 tcg_temp_free(t1);
2489 }
2490
2491 /* Shifts */
2492 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2493 int rd, int rs, int rt)
2494 {
2495 const char *opn = "shifts";
2496 TCGv t0, t1;
2497
2498 if (rd == 0) {
2499 /* If no destination, treat it as a NOP.
2500 For add & sub, we must generate the overflow exception when needed. */
2501 MIPS_DEBUG("NOP");
2502 return;
2503 }
2504
2505 t0 = tcg_temp_new();
2506 t1 = tcg_temp_new();
2507 gen_load_gpr(t0, rs);
2508 gen_load_gpr(t1, rt);
2509 switch (opc) {
2510 case OPC_SLLV:
2511 tcg_gen_andi_tl(t0, t0, 0x1f);
2512 tcg_gen_shl_tl(t0, t1, t0);
2513 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2514 opn = "sllv";
2515 break;
2516 case OPC_SRAV:
2517 tcg_gen_andi_tl(t0, t0, 0x1f);
2518 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2519 opn = "srav";
2520 break;
2521 case OPC_SRLV:
2522 tcg_gen_ext32u_tl(t1, t1);
2523 tcg_gen_andi_tl(t0, t0, 0x1f);
2524 tcg_gen_shr_tl(t0, t1, t0);
2525 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2526 opn = "srlv";
2527 break;
2528 case OPC_ROTRV:
2529 {
2530 TCGv_i32 t2 = tcg_temp_new_i32();
2531 TCGv_i32 t3 = tcg_temp_new_i32();
2532
2533 tcg_gen_trunc_tl_i32(t2, t0);
2534 tcg_gen_trunc_tl_i32(t3, t1);
2535 tcg_gen_andi_i32(t2, t2, 0x1f);
2536 tcg_gen_rotr_i32(t2, t3, t2);
2537 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2538 tcg_temp_free_i32(t2);
2539 tcg_temp_free_i32(t3);
2540 opn = "rotrv";
2541 }
2542 break;
2543 #if defined(TARGET_MIPS64)
2544 case OPC_DSLLV:
2545 tcg_gen_andi_tl(t0, t0, 0x3f);
2546 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2547 opn = "dsllv";
2548 break;
2549 case OPC_DSRAV:
2550 tcg_gen_andi_tl(t0, t0, 0x3f);
2551 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2552 opn = "dsrav";
2553 break;
2554 case OPC_DSRLV:
2555 tcg_gen_andi_tl(t0, t0, 0x3f);
2556 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2557 opn = "dsrlv";
2558 break;
2559 case OPC_DROTRV:
2560 tcg_gen_andi_tl(t0, t0, 0x3f);
2561 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2562 opn = "drotrv";
2563 break;
2564 #endif
2565 }
2566 (void)opn; /* avoid a compiler warning */
2567 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2568 tcg_temp_free(t0);
2569 tcg_temp_free(t1);
2570 }
2571
2572 /* Arithmetic on HI/LO registers */
2573 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2574 {
2575 const char *opn = "hilo";
2576 unsigned int acc;
2577
2578 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2579 /* Treat as NOP. */
2580 MIPS_DEBUG("NOP");
2581 return;
2582 }
2583
2584 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2585 acc = ((ctx->opcode) >> 21) & 0x03;
2586 } else {
2587 acc = ((ctx->opcode) >> 11) & 0x03;
2588 }
2589
2590 if (acc != 0) {
2591 check_dsp(ctx);
2592 }
2593
2594 switch (opc) {
2595 case OPC_MFHI:
2596 #if defined(TARGET_MIPS64)
2597 if (acc != 0) {
2598 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2599 } else
2600 #endif
2601 {
2602 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2603 }
2604 opn = "mfhi";
2605 break;
2606 case OPC_MFLO:
2607 #if defined(TARGET_MIPS64)
2608 if (acc != 0) {
2609 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2610 } else
2611 #endif
2612 {
2613 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2614 }
2615 opn = "mflo";
2616 break;
2617 case OPC_MTHI:
2618 if (reg != 0) {
2619 #if defined(TARGET_MIPS64)
2620 if (acc != 0) {
2621 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2622 } else
2623 #endif
2624 {
2625 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2626 }
2627 } else {
2628 tcg_gen_movi_tl(cpu_HI[acc], 0);
2629 }
2630 opn = "mthi";
2631 break;
2632 case OPC_MTLO:
2633 if (reg != 0) {
2634 #if defined(TARGET_MIPS64)
2635 if (acc != 0) {
2636 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2637 } else
2638 #endif
2639 {
2640 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2641 }
2642 } else {
2643 tcg_gen_movi_tl(cpu_LO[acc], 0);
2644 }
2645 opn = "mtlo";
2646 break;
2647 }
2648 (void)opn; /* avoid a compiler warning */
2649 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2650 }
2651
2652 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2653 int rs, int rt)
2654 {
2655 const char *opn = "mul/div";
2656 TCGv t0, t1;
2657 unsigned int acc;
2658
2659 switch (opc) {
2660 case OPC_DIV:
2661 case OPC_DIVU:
2662 #if defined(TARGET_MIPS64)
2663 case OPC_DDIV:
2664 case OPC_DDIVU:
2665 #endif
2666 t0 = tcg_temp_local_new();
2667 t1 = tcg_temp_local_new();
2668 break;
2669 default:
2670 t0 = tcg_temp_new();
2671 t1 = tcg_temp_new();
2672 break;
2673 }
2674
2675 gen_load_gpr(t0, rs);
2676 gen_load_gpr(t1, rt);
2677 switch (opc) {
2678 case OPC_DIV:
2679 {
2680 int l1 = gen_new_label();
2681 int l2 = gen_new_label();
2682
2683 tcg_gen_ext32s_tl(t0, t0);
2684 tcg_gen_ext32s_tl(t1, t1);
2685 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2686 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2687 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2688
2689 tcg_gen_mov_tl(cpu_LO[0], t0);
2690 tcg_gen_movi_tl(cpu_HI[0], 0);
2691 tcg_gen_br(l1);
2692 gen_set_label(l2);
2693 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2694 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2695 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2696 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2697 gen_set_label(l1);
2698 }
2699 opn = "div";
2700 break;
2701 case OPC_DIVU:
2702 {
2703 int l1 = gen_new_label();
2704
2705 tcg_gen_ext32u_tl(t0, t0);
2706 tcg_gen_ext32u_tl(t1, t1);
2707 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2708 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2709 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2710 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2711 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2712 gen_set_label(l1);
2713 }
2714 opn = "divu";
2715 break;
2716 case OPC_MULT:
2717 {
2718 TCGv_i64 t2 = tcg_temp_new_i64();
2719 TCGv_i64 t3 = tcg_temp_new_i64();
2720 acc = ((ctx->opcode) >> 11) & 0x03;
2721 if (acc != 0) {
2722 check_dsp(ctx);
2723 }
2724
2725 tcg_gen_ext_tl_i64(t2, t0);
2726 tcg_gen_ext_tl_i64(t3, t1);
2727 tcg_gen_mul_i64(t2, t2, t3);
2728 tcg_temp_free_i64(t3);
2729 tcg_gen_trunc_i64_tl(t0, t2);
2730 tcg_gen_shri_i64(t2, t2, 32);
2731 tcg_gen_trunc_i64_tl(t1, t2);
2732 tcg_temp_free_i64(t2);
2733 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2734 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2735 }
2736 opn = "mult";
2737 break;
2738 case OPC_MULTU:
2739 {
2740 TCGv_i64 t2 = tcg_temp_new_i64();
2741 TCGv_i64 t3 = tcg_temp_new_i64();
2742 acc = ((ctx->opcode) >> 11) & 0x03;
2743 if (acc != 0) {
2744 check_dsp(ctx);
2745 }
2746
2747 tcg_gen_ext32u_tl(t0, t0);
2748 tcg_gen_ext32u_tl(t1, t1);
2749 tcg_gen_extu_tl_i64(t2, t0);
2750 tcg_gen_extu_tl_i64(t3, t1);
2751 tcg_gen_mul_i64(t2, t2, t3);
2752 tcg_temp_free_i64(t3);
2753 tcg_gen_trunc_i64_tl(t0, t2);
2754 tcg_gen_shri_i64(t2, t2, 32);
2755 tcg_gen_trunc_i64_tl(t1, t2);
2756 tcg_temp_free_i64(t2);
2757 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2758 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2759 }
2760 opn = "multu";
2761 break;
2762 #if defined(TARGET_MIPS64)
2763 case OPC_DDIV:
2764 {
2765 int l1 = gen_new_label();
2766 int l2 = gen_new_label();
2767
2768 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2769 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2770 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2771 tcg_gen_mov_tl(cpu_LO[0], t0);
2772 tcg_gen_movi_tl(cpu_HI[0], 0);
2773 tcg_gen_br(l1);
2774 gen_set_label(l2);
2775 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2776 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2777 gen_set_label(l1);
2778 }
2779 opn = "ddiv";
2780 break;
2781 case OPC_DDIVU:
2782 {
2783 int l1 = gen_new_label();
2784
2785 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2786 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2787 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2788 gen_set_label(l1);
2789 }
2790 opn = "ddivu";
2791 break;
2792 case OPC_DMULT:
2793 gen_helper_dmult(cpu_env, t0, t1);
2794 opn = "dmult";
2795 break;
2796 case OPC_DMULTU:
2797 gen_helper_dmultu(cpu_env, t0, t1);
2798 opn = "dmultu";
2799 break;
2800 #endif
2801 case OPC_MADD:
2802 {
2803 TCGv_i64 t2 = tcg_temp_new_i64();
2804 TCGv_i64 t3 = tcg_temp_new_i64();
2805 acc = ((ctx->opcode) >> 11) & 0x03;
2806 if (acc != 0) {
2807 check_dsp(ctx);
2808 }
2809
2810 tcg_gen_ext_tl_i64(t2, t0);
2811 tcg_gen_ext_tl_i64(t3, t1);
2812 tcg_gen_mul_i64(t2, t2, t3);
2813 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2814 tcg_gen_add_i64(t2, t2, t3);
2815 tcg_temp_free_i64(t3);
2816 tcg_gen_trunc_i64_tl(t0, t2);
2817 tcg_gen_shri_i64(t2, t2, 32);
2818 tcg_gen_trunc_i64_tl(t1, t2);
2819 tcg_temp_free_i64(t2);
2820 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2821 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2822 }
2823 opn = "madd";
2824 break;
2825 case OPC_MADDU:
2826 {
2827 TCGv_i64 t2 = tcg_temp_new_i64();
2828 TCGv_i64 t3 = tcg_temp_new_i64();
2829 acc = ((ctx->opcode) >> 11) & 0x03;
2830 if (acc != 0) {
2831 check_dsp(ctx);
2832 }
2833
2834 tcg_gen_ext32u_tl(t0, t0);
2835 tcg_gen_ext32u_tl(t1, t1);
2836 tcg_gen_extu_tl_i64(t2, t0);
2837 tcg_gen_extu_tl_i64(t3, t1);
2838 tcg_gen_mul_i64(t2, t2, t3);
2839 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2840 tcg_gen_add_i64(t2, t2, t3);
2841 tcg_temp_free_i64(t3);
2842 tcg_gen_trunc_i64_tl(t0, t2);
2843 tcg_gen_shri_i64(t2, t2, 32);
2844 tcg_gen_trunc_i64_tl(t1, t2);
2845 tcg_temp_free_i64(t2);
2846 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2847 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2848 }
2849 opn = "maddu";
2850 break;
2851 case OPC_MSUB:
2852 {
2853 TCGv_i64 t2 = tcg_temp_new_i64();
2854 TCGv_i64 t3 = tcg_temp_new_i64();
2855 acc = ((ctx->opcode) >> 11) & 0x03;
2856 if (acc != 0) {
2857 check_dsp(ctx);
2858 }
2859
2860 tcg_gen_ext_tl_i64(t2, t0);
2861 tcg_gen_ext_tl_i64(t3, t1);
2862 tcg_gen_mul_i64(t2, t2, t3);
2863 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2864 tcg_gen_sub_i64(t2, t3, t2);
2865 tcg_temp_free_i64(t3);
2866 tcg_gen_trunc_i64_tl(t0, t2);
2867 tcg_gen_shri_i64(t2, t2, 32);
2868 tcg_gen_trunc_i64_tl(t1, t2);
2869 tcg_temp_free_i64(t2);
2870 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2871 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2872 }
2873 opn = "msub";
2874 break;
2875 case OPC_MSUBU:
2876 {
2877 TCGv_i64 t2 = tcg_temp_new_i64();
2878 TCGv_i64 t3 = tcg_temp_new_i64();
2879 acc = ((ctx->opcode) >> 11) & 0x03;
2880 if (acc != 0) {
2881 check_dsp(ctx);
2882 }
2883
2884 tcg_gen_ext32u_tl(t0, t0);
2885 tcg_gen_ext32u_tl(t1, t1);
2886 tcg_gen_extu_tl_i64(t2, t0);
2887 tcg_gen_extu_tl_i64(t3, t1);
2888 tcg_gen_mul_i64(t2, t2, t3);
2889 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2890 tcg_gen_sub_i64(t2, t3, t2);
2891 tcg_temp_free_i64(t3);
2892 tcg_gen_trunc_i64_tl(t0, t2);
2893 tcg_gen_shri_i64(t2, t2, 32);
2894 tcg_gen_trunc_i64_tl(t1, t2);
2895 tcg_temp_free_i64(t2);
2896 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2897 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2898 }
2899 opn = "msubu";
2900 break;
2901 default:
2902 MIPS_INVAL(opn);
2903 generate_exception(ctx, EXCP_RI);
2904 goto out;
2905 }
2906 (void)opn; /* avoid a compiler warning */
2907 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2908 out:
2909 tcg_temp_free(t0);
2910 tcg_temp_free(t1);
2911 }
2912
2913 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2914 int rd, int rs, int rt)
2915 {
2916 const char *opn = "mul vr54xx";
2917 TCGv t0 = tcg_temp_new();
2918 TCGv t1 = tcg_temp_new();
2919
2920 gen_load_gpr(t0, rs);
2921 gen_load_gpr(t1, rt);
2922
2923 switch (opc) {
2924 case OPC_VR54XX_MULS:
2925 gen_helper_muls(t0, cpu_env, t0, t1);
2926 opn = "muls";
2927 break;
2928 case OPC_VR54XX_MULSU:
2929 gen_helper_mulsu(t0, cpu_env, t0, t1);
2930 opn = "mulsu";
2931 break;
2932 case OPC_VR54XX_MACC:
2933 gen_helper_macc(t0, cpu_env, t0, t1);
2934 opn = "macc";
2935 break;
2936 case OPC_VR54XX_MACCU:
2937 gen_helper_maccu(t0, cpu_env, t0, t1);
2938 opn = "maccu";
2939 break;
2940 case OPC_VR54XX_MSAC:
2941 gen_helper_msac(t0, cpu_env, t0, t1);
2942 opn = "msac";
2943 break;
2944 case OPC_VR54XX_MSACU:
2945 gen_helper_msacu(t0, cpu_env, t0, t1);
2946 opn = "msacu";
2947 break;
2948 case OPC_VR54XX_MULHI:
2949 gen_helper_mulhi(t0, cpu_env, t0, t1);
2950 opn = "mulhi";
2951 break;
2952 case OPC_VR54XX_MULHIU:
2953 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2954 opn = "mulhiu";
2955 break;
2956 case OPC_VR54XX_MULSHI:
2957 gen_helper_mulshi(t0, cpu_env, t0, t1);
2958 opn = "mulshi";
2959 break;
2960 case OPC_VR54XX_MULSHIU:
2961 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2962 opn = "mulshiu";
2963 break;
2964 case OPC_VR54XX_MACCHI:
2965 gen_helper_macchi(t0, cpu_env, t0, t1);
2966 opn = "macchi";
2967 break;
2968 case OPC_VR54XX_MACCHIU:
2969 gen_helper_macchiu(t0, cpu_env, t0, t1);
2970 opn = "macchiu";
2971 break;
2972 case OPC_VR54XX_MSACHI:
2973 gen_helper_msachi(t0, cpu_env, t0, t1);
2974 opn = "msachi";
2975 break;
2976 case OPC_VR54XX_MSACHIU:
2977 gen_helper_msachiu(t0, cpu_env, t0, t1);
2978 opn = "msachiu";
2979 break;
2980 default:
2981 MIPS_INVAL("mul vr54xx");
2982 generate_exception(ctx, EXCP_RI);
2983 goto out;
2984 }
2985 gen_store_gpr(t0, rd);
2986 (void)opn; /* avoid a compiler warning */
2987 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2988
2989 out:
2990 tcg_temp_free(t0);
2991 tcg_temp_free(t1);
2992 }
2993
2994 static void gen_cl (DisasContext *ctx, uint32_t opc,
2995 int rd, int rs)
2996 {
2997 const char *opn = "CLx";
2998 TCGv t0;
2999
3000 if (rd == 0) {
3001 /* Treat as NOP. */
3002 MIPS_DEBUG("NOP");
3003 return;
3004 }
3005 t0 = tcg_temp_new();
3006 gen_load_gpr(t0, rs);
3007 switch (opc) {
3008 case OPC_CLO:
3009 gen_helper_clo(cpu_gpr[rd], t0);
3010 opn = "clo";
3011 break;
3012 case OPC_CLZ:
3013 gen_helper_clz(cpu_gpr[rd], t0);
3014 opn = "clz";
3015 break;
3016 #if defined(TARGET_MIPS64)
3017 case OPC_DCLO:
3018 gen_helper_dclo(cpu_gpr[rd], t0);
3019 opn = "dclo";
3020 break;
3021 case OPC_DCLZ:
3022 gen_helper_dclz(cpu_gpr[rd], t0);
3023 opn = "dclz";
3024 break;
3025 #endif
3026 }
3027 (void)opn; /* avoid a compiler warning */
3028 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3029 tcg_temp_free(t0);
3030 }
3031
3032 /* Godson integer instructions */
3033 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3034 int rd, int rs, int rt)
3035 {
3036 const char *opn = "loongson";
3037 TCGv t0, t1;
3038
3039 if (rd == 0) {
3040 /* Treat as NOP. */
3041 MIPS_DEBUG("NOP");
3042 return;
3043 }
3044
3045 switch (opc) {
3046 case OPC_MULT_G_2E:
3047 case OPC_MULT_G_2F:
3048 case OPC_MULTU_G_2E:
3049 case OPC_MULTU_G_2F:
3050 #if defined(TARGET_MIPS64)
3051 case OPC_DMULT_G_2E:
3052 case OPC_DMULT_G_2F:
3053 case OPC_DMULTU_G_2E:
3054 case OPC_DMULTU_G_2F:
3055 #endif
3056 t0 = tcg_temp_new();
3057 t1 = tcg_temp_new();
3058 break;
3059 default:
3060 t0 = tcg_temp_local_new();
3061 t1 = tcg_temp_local_new();
3062 break;
3063 }
3064
3065 gen_load_gpr(t0, rs);
3066 gen_load_gpr(t1, rt);
3067
3068 switch (opc) {
3069 case OPC_MULT_G_2E:
3070 case OPC_MULT_G_2F:
3071 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3072 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3073 opn = "mult.g";
3074 break;
3075 case OPC_MULTU_G_2E:
3076 case OPC_MULTU_G_2F:
3077 tcg_gen_ext32u_tl(t0, t0);
3078 tcg_gen_ext32u_tl(t1, t1);
3079 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3080 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3081 opn = "multu.g";
3082 break;
3083 case OPC_DIV_G_2E:
3084 case OPC_DIV_G_2F:
3085 {
3086 int l1 = gen_new_label();
3087 int l2 = gen_new_label();
3088 int l3 = gen_new_label();
3089 tcg_gen_ext32s_tl(t0, t0);
3090 tcg_gen_ext32s_tl(t1, t1);
3091 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3092 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3093 tcg_gen_br(l3);
3094 gen_set_label(l1);
3095 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3096 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3097 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3098 tcg_gen_br(l3);
3099 gen_set_label(l2);
3100 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3101 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3102 gen_set_label(l3);
3103 }
3104 opn = "div.g";
3105 break;
3106 case OPC_DIVU_G_2E:
3107 case OPC_DIVU_G_2F:
3108 {
3109 int l1 = gen_new_label();
3110 int l2 = gen_new_label();
3111 tcg_gen_ext32u_tl(t0, t0);
3112 tcg_gen_ext32u_tl(t1, t1);
3113 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3114 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3115 tcg_gen_br(l2);
3116 gen_set_label(l1);
3117 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3118 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3119 gen_set_label(l2);
3120 }
3121 opn = "divu.g";
3122 break;
3123 case OPC_MOD_G_2E:
3124 case OPC_MOD_G_2F:
3125 {
3126 int l1 = gen_new_label();
3127 int l2 = gen_new_label();
3128 int l3 = gen_new_label();
3129 tcg_gen_ext32u_tl(t0, t0);
3130 tcg_gen_ext32u_tl(t1, t1);
3131 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3132 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3133 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3134 gen_set_label(l1);
3135 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3136 tcg_gen_br(l3);
3137 gen_set_label(l2);
3138 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3139 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3140 gen_set_label(l3);
3141 }
3142 opn = "mod.g";
3143 break;
3144 case OPC_MODU_G_2E:
3145 case OPC_MODU_G_2F:
3146 {
3147 int l1 = gen_new_label();
3148 int l2 = gen_new_label();
3149 tcg_gen_ext32u_tl(t0, t0);
3150 tcg_gen_ext32u_tl(t1, t1);
3151 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3152 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3153 tcg_gen_br(l2);
3154 gen_set_label(l1);
3155 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3156 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3157 gen_set_label(l2);
3158 }
3159 opn = "modu.g";
3160 break;
3161 #if defined(TARGET_MIPS64)
3162 case OPC_DMULT_G_2E:
3163 case OPC_DMULT_G_2F:
3164 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3165 opn = "dmult.g";
3166 break;
3167 case OPC_DMULTU_G_2E:
3168 case OPC_DMULTU_G_2F:
3169 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3170 opn = "dmultu.g";
3171 break;
3172 case OPC_DDIV_G_2E:
3173 case OPC_DDIV_G_2F:
3174 {
3175 int l1 = gen_new_label();
3176 int l2 = gen_new_label();
3177 int l3 = gen_new_label();
3178 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3179 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3180 tcg_gen_br(l3);
3181 gen_set_label(l1);
3182 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3183 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3184 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3185 tcg_gen_br(l3);
3186 gen_set_label(l2);
3187 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3188 gen_set_label(l3);
3189 }
3190 opn = "ddiv.g";
3191 break;
3192 case OPC_DDIVU_G_2E:
3193 case OPC_DDIVU_G_2F:
3194 {
3195 int l1 = gen_new_label();
3196 int l2 = gen_new_label();
3197 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3198 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3199 tcg_gen_br(l2);
3200 gen_set_label(l1);
3201 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3202 gen_set_label(l2);
3203 }
3204 opn = "ddivu.g";
3205 break;
3206 case OPC_DMOD_G_2E:
3207 case OPC_DMOD_G_2F:
3208 {
3209 int l1 = gen_new_label();
3210 int l2 = gen_new_label();
3211 int l3 = gen_new_label();
3212 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3213 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3214 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3215 gen_set_label(l1);
3216 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3217 tcg_gen_br(l3);
3218 gen_set_label(l2);
3219 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3220 gen_set_label(l3);
3221 }
3222 opn = "dmod.g";
3223 break;
3224 case OPC_DMODU_G_2E:
3225 case OPC_DMODU_G_2F:
3226 {
3227 int l1 = gen_new_label();
3228 int l2 = gen_new_label();
3229 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3230 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3231 tcg_gen_br(l2);
3232 gen_set_label(l1);
3233 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3234 gen_set_label(l2);
3235 }
3236 opn = "dmodu.g";
3237 break;
3238 #endif
3239 }
3240
3241 (void)opn; /* avoid a compiler warning */
3242 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3243 tcg_temp_free(t0);
3244 tcg_temp_free(t1);
3245 }
3246
3247 /* Loongson multimedia instructions */
3248 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3249 {
3250 const char *opn = "loongson_cp2";
3251 uint32_t opc, shift_max;
3252 TCGv_i64 t0, t1;
3253
3254 opc = MASK_LMI(ctx->opcode);
3255 switch (opc) {
3256 case OPC_ADD_CP2:
3257 case OPC_SUB_CP2:
3258 case OPC_DADD_CP2:
3259 case OPC_DSUB_CP2:
3260 t0 = tcg_temp_local_new_i64();
3261 t1 = tcg_temp_local_new_i64();
3262 break;
3263 default:
3264 t0 = tcg_temp_new_i64();
3265 t1 = tcg_temp_new_i64();
3266 break;
3267 }
3268
3269 gen_load_fpr64(ctx, t0, rs);
3270 gen_load_fpr64(ctx, t1, rt);
3271
3272 #define LMI_HELPER(UP, LO) \
3273 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3274 #define LMI_HELPER_1(UP, LO) \
3275 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3276 #define LMI_DIRECT(UP, LO, OP) \
3277 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3278
3279 switch (opc) {
3280 LMI_HELPER(PADDSH, paddsh);
3281 LMI_HELPER(PADDUSH, paddush);
3282 LMI_HELPER(PADDH, paddh);
3283 LMI_HELPER(PADDW, paddw);
3284 LMI_HELPER(PADDSB, paddsb);
3285 LMI_HELPER(PADDUSB, paddusb);
3286 LMI_HELPER(PADDB, paddb);
3287
3288 LMI_HELPER(PSUBSH, psubsh);
3289 LMI_HELPER(PSUBUSH, psubush);
3290 LMI_HELPER(PSUBH, psubh);
3291 LMI_HELPER(PSUBW, psubw);
3292 LMI_HELPER(PSUBSB, psubsb);
3293 LMI_HELPER(PSUBUSB, psubusb);
3294 LMI_HELPER(PSUBB, psubb);
3295
3296 LMI_HELPER(PSHUFH, pshufh);
3297 LMI_HELPER(PACKSSWH, packsswh);
3298 LMI_HELPER(PACKSSHB, packsshb);
3299 LMI_HELPER(PACKUSHB, packushb);
3300
3301 LMI_HELPER(PUNPCKLHW, punpcklhw);
3302 LMI_HELPER(PUNPCKHHW, punpckhhw);
3303 LMI_HELPER(PUNPCKLBH, punpcklbh);
3304 LMI_HELPER(PUNPCKHBH, punpckhbh);
3305 LMI_HELPER(PUNPCKLWD, punpcklwd);
3306 LMI_HELPER(PUNPCKHWD, punpckhwd);
3307
3308 LMI_HELPER(PAVGH, pavgh);
3309 LMI_HELPER(PAVGB, pavgb);
3310 LMI_HELPER(PMAXSH, pmaxsh);
3311 LMI_HELPER(PMINSH, pminsh);
3312 LMI_HELPER(PMAXUB, pmaxub);
3313 LMI_HELPER(PMINUB, pminub);
3314
3315 LMI_HELPER(PCMPEQW, pcmpeqw);
3316 LMI_HELPER(PCMPGTW, pcmpgtw);
3317 LMI_HELPER(PCMPEQH, pcmpeqh);
3318 LMI_HELPER(PCMPGTH, pcmpgth);
3319 LMI_HELPER(PCMPEQB, pcmpeqb);
3320 LMI_HELPER(PCMPGTB, pcmpgtb);
3321
3322 LMI_HELPER(PSLLW, psllw);
3323 LMI_HELPER(PSLLH, psllh);
3324 LMI_HELPER(PSRLW, psrlw);
3325 LMI_HELPER(PSRLH, psrlh);
3326 LMI_HELPER(PSRAW, psraw);
3327 LMI_HELPER(PSRAH, psrah);
3328
3329 LMI_HELPER(PMULLH, pmullh);
3330 LMI_HELPER(PMULHH, pmulhh);
3331 LMI_HELPER(PMULHUH, pmulhuh);
3332 LMI_HELPER(PMADDHW, pmaddhw);
3333
3334 LMI_HELPER(PASUBUB, pasubub);
3335 LMI_HELPER_1(BIADD, biadd);
3336 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3337
3338 LMI_DIRECT(PADDD, paddd, add);
3339 LMI_DIRECT(PSUBD, psubd, sub);
3340 LMI_DIRECT(XOR_CP2, xor, xor);
3341 LMI_DIRECT(NOR_CP2, nor, nor);
3342 LMI_DIRECT(AND_CP2, and, and);
3343 LMI_DIRECT(PANDN, pandn, andc);
3344 LMI_DIRECT(OR, or, or);
3345
3346 case OPC_PINSRH_0:
3347 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3348 opn = "pinsrh_0";
3349 break;
3350 case OPC_PINSRH_1:
3351 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3352 opn = "pinsrh_1";
3353 break;
3354 case OPC_PINSRH_2:
3355 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3356 opn = "pinsrh_2";
3357 break;
3358 case OPC_PINSRH_3:
3359 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3360 opn = "pinsrh_3";
3361 break;
3362
3363 case OPC_PEXTRH:
3364 tcg_gen_andi_i64(t1, t1, 3);
3365 tcg_gen_shli_i64(t1, t1, 4);
3366 tcg_gen_shr_i64(t0, t0, t1);
3367 tcg_gen_ext16u_i64(t0, t0);
3368 opn = "pextrh";
3369 break;
3370
3371 case OPC_ADDU_CP2:
3372 tcg_gen_add_i64(t0, t0, t1);
3373 tcg_gen_ext32s_i64(t0, t0);
3374 opn = "addu";
3375 break;
3376 case OPC_SUBU_CP2:
3377 tcg_gen_sub_i64(t0, t0, t1);
3378 tcg_gen_ext32s_i64(t0, t0);
3379 opn = "addu";
3380 break;
3381
3382 case OPC_SLL_CP2:
3383 opn = "sll";
3384 shift_max = 32;
3385 goto do_shift;
3386 case OPC_SRL_CP2:
3387 opn = "srl";
3388 shift_max = 32;
3389 goto do_shift;
3390 case OPC_SRA_CP2:
3391 opn = "sra";
3392 shift_max = 32;
3393 goto do_shift;
3394 case OPC_DSLL_CP2:
3395 opn = "dsll";
3396 shift_max = 64;
3397 goto do_shift;
3398 case OPC_DSRL_CP2:
3399 opn = "dsrl";
3400 shift_max = 64;
3401 goto do_shift;
3402 case OPC_DSRA_CP2:
3403 opn = "dsra";
3404 shift_max = 64;
3405 goto do_shift;
3406 do_shift:
3407 /* Make sure shift count isn't TCG undefined behaviour. */
3408 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3409
3410 switch (opc) {
3411 case OPC_SLL_CP2:
3412 case OPC_DSLL_CP2:
3413 tcg_gen_shl_i64(t0, t0, t1);
3414 break;
3415 case OPC_SRA_CP2:
3416 case OPC_DSRA_CP2:
3417 /* Since SRA is UndefinedResult without sign-extended inputs,
3418 we can treat SRA and DSRA the same. */
3419 tcg_gen_sar_i64(t0, t0, t1);
3420 break;
3421 case OPC_SRL_CP2:
3422 /* We want to shift in zeros for SRL; zero-extend first. */
3423 tcg_gen_ext32u_i64(t0, t0);
3424 /* FALLTHRU */
3425 case OPC_DSRL_CP2:
3426 tcg_gen_shr_i64(t0, t0, t1);
3427 break;
3428 }
3429
3430 if (shift_max == 32) {
3431 tcg_gen_ext32s_i64(t0, t0);
3432 }
3433
3434 /* Shifts larger than MAX produce zero. */
3435 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3436 tcg_gen_neg_i64(t1, t1);
3437 tcg_gen_and_i64(t0, t0, t1);
3438 break;
3439
3440 case OPC_ADD_CP2:
3441 case OPC_DADD_CP2:
3442 {
3443 TCGv_i64 t2 = tcg_temp_new_i64();
3444 int lab = gen_new_label();
3445
3446 tcg_gen_mov_i64(t2, t0);
3447 tcg_gen_add_i64(t0, t1, t2);
3448 if (opc == OPC_ADD_CP2) {
3449 tcg_gen_ext32s_i64(t0, t0);
3450 }
3451 tcg_gen_xor_i64(t1, t1, t2);
3452 tcg_gen_xor_i64(t2, t2, t0);
3453 tcg_gen_andc_i64(t1, t2, t1);
3454 tcg_temp_free_i64(t2);
3455 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3456 generate_exception(ctx, EXCP_OVERFLOW);
3457 gen_set_label(lab);
3458
3459 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3460 break;
3461 }
3462
3463 case OPC_SUB_CP2:
3464 case OPC_DSUB_CP2:
3465 {
3466 TCGv_i64 t2 = tcg_temp_new_i64();
3467 int lab = gen_new_label();
3468
3469 tcg_gen_mov_i64(t2, t0);
3470 tcg_gen_sub_i64(t0, t1, t2);
3471 if (opc == OPC_SUB_CP2) {
3472 tcg_gen_ext32s_i64(t0, t0);
3473 }
3474 tcg_gen_xor_i64(t1, t1, t2);
3475 tcg_gen_xor_i64(t2, t2, t0);
3476 tcg_gen_and_i64(t1, t1, t2);
3477 tcg_temp_free_i64(t2);
3478 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3479 generate_exception(ctx, EXCP_OVERFLOW);
3480 gen_set_label(lab);
3481
3482 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3483 break;
3484 }
3485
3486 case OPC_PMULUW:
3487 tcg_gen_ext32u_i64(t0, t0);
3488 tcg_gen_ext32u_i64(t1, t1);
3489 tcg_gen_mul_i64(t0, t0, t1);
3490 opn = "pmuluw";
3491 break;
3492
3493 case OPC_SEQU_CP2:
3494 case OPC_SEQ_CP2:
3495 case OPC_SLTU_CP2:
3496 case OPC_SLT_CP2:
3497 case OPC_SLEU_CP2:
3498 case OPC_SLE_CP2:
3499 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3500 FD field is the CC field? */
3501 default:
3502 MIPS_INVAL(opn);
3503 generate_exception(ctx, EXCP_RI);
3504 return;
3505 }
3506
3507 #undef LMI_HELPER
3508 #undef LMI_DIRECT
3509
3510 gen_store_fpr64(ctx, t0, rd);
3511
3512 (void)opn; /* avoid a compiler warning */
3513 MIPS_DEBUG("%s %s, %s, %s", opn,
3514 fregnames[rd], fregnames[rs], fregnames[rt]);
3515 tcg_temp_free_i64(t0);
3516 tcg_temp_free_i64(t1);
3517 }
3518
3519 /* Traps */
3520 static void gen_trap (DisasContext *ctx, uint32_t opc,
3521 int rs, int rt, int16_t imm)
3522 {
3523 int cond;
3524 TCGv t0 = tcg_temp_new();
3525 TCGv t1 = tcg_temp_new();
3526
3527 cond = 0;
3528 /* Load needed operands */
3529 switch (opc) {
3530 case OPC_TEQ:
3531 case OPC_TGE:
3532 case OPC_TGEU:
3533 case OPC_TLT:
3534 case OPC_TLTU:
3535 case OPC_TNE:
3536 /* Compare two registers */
3537 if (rs != rt) {
3538 gen_load_gpr(t0, rs);
3539 gen_load_gpr(t1, rt);
3540 cond = 1;
3541 }
3542 break;
3543 case OPC_TEQI:
3544 case OPC_TGEI:
3545 case OPC_TGEIU:
3546 case OPC_TLTI:
3547 case OPC_TLTIU:
3548 case OPC_TNEI:
3549 /* Compare register to immediate */
3550 if (rs != 0 || imm != 0) {
3551 gen_load_gpr(t0, rs);
3552 tcg_gen_movi_tl(t1, (int32_t)imm);
3553 cond = 1;
3554 }
3555 break;
3556 }
3557 if (cond == 0) {
3558 switch (opc) {
3559 case OPC_TEQ: /* rs == rs */
3560 case OPC_TEQI: /* r0 == 0 */
3561 case OPC_TGE: /* rs >= rs */
3562 case OPC_TGEI: /* r0 >= 0 */
3563 case OPC_TGEU: /* rs >= rs unsigned */
3564 case OPC_TGEIU: /* r0 >= 0 unsigned */
3565 /* Always trap */
3566 generate_exception(ctx, EXCP_TRAP);
3567 break;
3568 case OPC_TLT: /* rs < rs */
3569 case OPC_TLTI: /* r0 < 0 */
3570 case OPC_TLTU: /* rs < rs unsigned */
3571 case OPC_TLTIU: /* r0 < 0 unsigned */
3572 case OPC_TNE: /* rs != rs */
3573 case OPC_TNEI: /* r0 != 0 */
3574 /* Never trap: treat as NOP. */
3575 break;
3576 }
3577 } else {
3578 int l1 = gen_new_label();
3579
3580 switch (opc) {
3581 case OPC_TEQ:
3582 case OPC_TEQI:
3583 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3584 break;
3585 case OPC_TGE:
3586 case OPC_TGEI:
3587 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3588 break;
3589 case OPC_TGEU:
3590 case OPC_TGEIU:
3591 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3592 break;
3593 case OPC_TLT:
3594 case OPC_TLTI:
3595 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3596 break;
3597 case OPC_TLTU:
3598 case OPC_TLTIU:
3599 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3600 break;
3601 case OPC_TNE:
3602 case OPC_TNEI:
3603 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3604 break;
3605 }
3606 generate_exception(ctx, EXCP_TRAP);
3607 gen_set_label(l1);
3608 }
3609 tcg_temp_free(t0);
3610 tcg_temp_free(t1);
3611 }
3612
3613 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3614 {
3615 TranslationBlock *tb;
3616 tb = ctx->tb;
3617 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3618 likely(!ctx->singlestep_enabled)) {
3619 tcg_gen_goto_tb(n);
3620 gen_save_pc(dest);
3621 tcg_gen_exit_tb((tcg_target_long)tb + n);
3622 } else {
3623 gen_save_pc(dest);
3624 if (ctx->singlestep_enabled) {
3625 save_cpu_state(ctx, 0);
3626 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3627 }
3628 tcg_gen_exit_tb(0);
3629 }
3630 }
3631
3632 /* Branches (before delay slot) */
3633 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3634 int insn_bytes,
3635 int rs, int rt, int32_t offset)
3636 {
3637 target_ulong btgt = -1;
3638 int blink = 0;
3639 int bcond_compute = 0;
3640 TCGv t0 = tcg_temp_new();
3641 TCGv t1 = tcg_temp_new();
3642
3643 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3644 #ifdef MIPS_DEBUG_DISAS
3645 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3646 #endif
3647 generate_exception(ctx, EXCP_RI);
3648 goto out;
3649 }
3650
3651 /* Load needed operands */
3652 switch (opc) {
3653 case OPC_BEQ:
3654 case OPC_BEQL:
3655 case OPC_BNE:
3656 case OPC_BNEL:
3657 /* Compare two registers */
3658 if (rs != rt) {
3659 gen_load_gpr(t0, rs);
3660 gen_load_gpr(t1, rt);
3661 bcond_compute = 1;
3662 }
3663 btgt = ctx->pc + insn_bytes + offset;
3664 break;
3665 case OPC_BGEZ:
3666 case OPC_BGEZAL:
3667 case OPC_BGEZALS:
3668 case OPC_BGEZALL:
3669 case OPC_BGEZL:
3670 case OPC_BGTZ:
3671 case OPC_BGTZL:
3672 case OPC_BLEZ:
3673 case OPC_BLEZL:
3674 case OPC_BLTZ:
3675 case OPC_BLTZAL:
3676 case OPC_BLTZALS:
3677 case OPC_BLTZALL:
3678 case OPC_BLTZL:
3679 /* Compare to zero */
3680 if (rs != 0) {
3681 gen_load_gpr(t0, rs);
3682 bcond_compute = 1;
3683 }
3684 btgt = ctx->pc + insn_bytes + offset;
3685 break;
3686 case OPC_BPOSGE32:
3687 #if defined(TARGET_MIPS64)
3688 case OPC_BPOSGE64:
3689 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3690 #else
3691 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3692 #endif
3693 bcond_compute = 1;
3694 btgt = ctx->pc + insn_bytes + offset;
3695 break;
3696 case OPC_J:
3697 case OPC_JAL:
3698 case OPC_JALX:
3699 case OPC_JALS:
3700 case OPC_JALXS:
3701 /* Jump to immediate */
3702 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3703 break;
3704 case OPC_JR:
3705 case OPC_JALR:
3706 case OPC_JALRC:
3707 case OPC_JALRS:
3708 /* Jump to register */
3709 if (offset != 0 && offset != 16) {
3710 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3711 others are reserved. */
3712 MIPS_INVAL("jump hint");
3713 generate_exception(ctx, EXCP_RI);
3714 goto out;
3715 }
3716 gen_load_gpr(btarget, rs);
3717 break;
3718 default:
3719 MIPS_INVAL("branch/jump");
3720 generate_exception(ctx, EXCP_RI);
3721 goto out;
3722 }
3723 if (bcond_compute == 0) {
3724 /* No condition to be computed */
3725 switch (opc) {
3726 case OPC_BEQ: /* rx == rx */
3727 case OPC_BEQL: /* rx == rx likely */
3728 case OPC_BGEZ: /* 0 >= 0 */
3729 case OPC_BGEZL: /* 0 >= 0 likely */
3730 case OPC_BLEZ: /* 0 <= 0 */
3731 case OPC_BLEZL: /* 0 <= 0 likely */
3732 /* Always take */
3733 ctx->hflags |= MIPS_HFLAG_B;
3734 MIPS_DEBUG("balways");
3735 break;
3736 case OPC_BGEZALS:
3737 case OPC_BGEZAL: /* 0 >= 0 */
3738 case OPC_BGEZALL: /* 0 >= 0 likely */
3739 ctx->hflags |= (opc == OPC_BGEZALS
3740 ? MIPS_HFLAG_BDS16
3741 : MIPS_HFLAG_BDS32);
3742 /* Always take and link */
3743 blink = 31;
3744 ctx->hflags |= MIPS_HFLAG_B;
3745 MIPS_DEBUG("balways and link");
3746 break;
3747 case OPC_BNE: /* rx != rx */
3748 case OPC_BGTZ: /* 0 > 0 */
3749 case OPC_BLTZ: /* 0 < 0 */
3750 /* Treat as NOP. */
3751 MIPS_DEBUG("bnever (NOP)");
3752 goto out;
3753 case OPC_BLTZALS:
3754 case OPC_BLTZAL: /* 0 < 0 */
3755 ctx->hflags |= (opc == OPC_BLTZALS
3756 ? MIPS_HFLAG_BDS16
3757 : MIPS_HFLAG_BDS32);
3758 /* Handle as an unconditional branch to get correct delay
3759 slot checking. */
3760 blink = 31;
3761 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3762 ctx->hflags |= MIPS_HFLAG_B;
3763 MIPS_DEBUG("bnever and link");
3764 break;
3765 case OPC_BLTZALL: /* 0 < 0 likely */
3766 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3767 /* Skip the instruction in the delay slot */
3768 MIPS_DEBUG("bnever, link and skip");
3769 ctx->pc += 4;
3770 goto out;
3771 case OPC_BNEL: /* rx != rx likely */
3772 case OPC_BGTZL: /* 0 > 0 likely */
3773 case OPC_BLTZL: /* 0 < 0 likely */
3774 /* Skip the instruction in the delay slot */
3775 MIPS_DEBUG("bnever and skip");
3776 ctx->pc += 4;
3777 goto out;
3778 case OPC_J:
3779 ctx->hflags |= MIPS_HFLAG_B;
3780 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3781 break;
3782 case OPC_JALXS:
3783 case OPC_JALX:
3784 ctx->hflags |= MIPS_HFLAG_BX;
3785 /* Fallthrough */
3786 case OPC_JALS:
3787 case OPC_JAL:
3788 blink = 31;
3789 ctx->hflags |= MIPS_HFLAG_B;
3790 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3791 ? MIPS_HFLAG_BDS16
3792 : MIPS_HFLAG_BDS32);
3793 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3794 break;
3795 case OPC_JR:
3796 ctx->hflags |= MIPS_HFLAG_BR;
3797 if (insn_bytes == 4)
3798 ctx->hflags |= MIPS_HFLAG_BDS32;
3799 MIPS_DEBUG("jr %s", regnames[rs]);
3800 break;
3801 case OPC_JALRS:
3802 case OPC_JALR:
3803 case OPC_JALRC:
3804 blink = rt;
3805 ctx->hflags |= MIPS_HFLAG_BR;
3806 ctx->hflags |= (opc == OPC_JALRS
3807 ? MIPS_HFLAG_BDS16
3808 : MIPS_HFLAG_BDS32);
3809 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3810 break;
3811 default:
3812 MIPS_INVAL("branch/jump");
3813 generate_exception(ctx, EXCP_RI);
3814 goto out;
3815 }
3816 } else {
3817 switch (opc) {
3818 case OPC_BEQ:
3819 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3820 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3821 regnames[rs], regnames[rt], btgt);
3822 goto not_likely;
3823 case OPC_BEQL:
3824 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3825 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3826 regnames[rs], regnames[rt], btgt);
3827 goto likely;
3828 case OPC_BNE:
3829 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3830 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3831 regnames[rs], regnames[rt], btgt);
3832 goto not_likely;
3833 case OPC_BNEL:
3834 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3835 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3836 regnames[rs], regnames[rt], btgt);
3837 goto likely;
3838 case OPC_BGEZ:
3839 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3840 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3841 goto not_likely;
3842 case OPC_BGEZL:
3843 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3844 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3845 goto likely;
3846 case OPC_BGEZALS:
3847 case OPC_BGEZAL:
3848 ctx->hflags |= (opc == OPC_BGEZALS
3849 ? MIPS_HFLAG_BDS16
3850 : MIPS_HFLAG_BDS32);
3851 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3852 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3853 blink = 31;
3854 goto not_likely;
3855 case OPC_BGEZALL:
3856 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3857 blink = 31;
3858 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3859 goto likely;
3860 case OPC_BGTZ:
3861 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3862 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3863 goto not_likely;
3864 case OPC_BGTZL:
3865 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3866 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3867 goto likely;
3868 case OPC_BLEZ:
3869 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3870 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3871 goto not_likely;
3872 case OPC_BLEZL:
3873 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3874 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3875 goto likely;
3876 case OPC_BLTZ:
3877 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3878 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3879 goto not_likely;
3880 case OPC_BLTZL:
3881 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3882 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3883 goto likely;
3884 case OPC_BPOSGE32:
3885 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3886 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3887 goto not_likely;
3888 #if defined(TARGET_MIPS64)
3889 case OPC_BPOSGE64:
3890 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3891 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3892 goto not_likely;
3893 #endif
3894 case OPC_BLTZALS:
3895 case OPC_BLTZAL:
3896 ctx->hflags |= (opc == OPC_BLTZALS
3897 ? MIPS_HFLAG_BDS16
3898 : MIPS_HFLAG_BDS32);
3899 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3900 blink = 31;
3901 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3902 not_likely:
3903 ctx->hflags |= MIPS_HFLAG_BC;
3904 break;
3905 case OPC_BLTZALL:
3906 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3907 blink = 31;
3908 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3909 likely:
3910 ctx->hflags |= MIPS_HFLAG_BL;
3911 break;
3912 default:
3913 MIPS_INVAL("conditional branch/jump");
3914 generate_exception(ctx, EXCP_RI);
3915 goto out;
3916 }
3917 }
3918 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3919 blink, ctx->hflags, btgt);
3920
3921 ctx->btarget = btgt;
3922 if (blink > 0) {
3923 int post_delay = insn_bytes;
3924 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3925
3926 if (opc != OPC_JALRC)
3927 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3928
3929 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3930 }
3931
3932 out:
3933 if (insn_bytes == 2)
3934 ctx->hflags |= MIPS_HFLAG_B16;
3935 tcg_temp_free(t0);
3936 tcg_temp_free(t1);
3937 }
3938
3939 /* special3 bitfield operations */
3940 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3941 int rs, int lsb, int msb)
3942 {
3943 TCGv t0 = tcg_temp_new();
3944 TCGv t1 = tcg_temp_new();
3945 target_ulong mask;
3946
3947 gen_load_gpr(t1, rs);
3948 switch (opc) {
3949 case OPC_EXT:
3950 if (lsb + msb > 31)
3951 goto fail;
3952 tcg_gen_shri_tl(t0, t1, lsb);
3953 if (msb != 31) {
3954 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3955 } else {
3956 tcg_gen_ext32s_tl(t0, t0);
3957 }
3958 break;
3959 #if defined(TARGET_MIPS64)
3960 case OPC_DEXTM:
3961 tcg_gen_shri_tl(t0, t1, lsb);
3962 if (msb != 31) {
3963 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3964 }
3965 break;
3966 case OPC_DEXTU:
3967 tcg_gen_shri_tl(t0, t1, lsb + 32);
3968 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3969 break;
3970 case OPC_DEXT:
3971 tcg_gen_shri_tl(t0, t1, lsb);
3972 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3973 break;
3974 #endif
3975 case OPC_INS:
3976 if (lsb > msb)
3977 goto fail;
3978 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3979 gen_load_gpr(t0, rt);
3980 tcg_gen_andi_tl(t0, t0, ~mask);
3981 tcg_gen_shli_tl(t1, t1, lsb);
3982 tcg_gen_andi_tl(t1, t1, mask);
3983 tcg_gen_or_tl(t0, t0, t1);
3984 tcg_gen_ext32s_tl(t0, t0);
3985 break;
3986 #if defined(TARGET_MIPS64)
3987 case OPC_DINSM:
3988 if (lsb > msb)
3989 goto fail;
3990 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3991 gen_load_gpr(t0, rt);
3992 tcg_gen_andi_tl(t0, t0, ~mask);
3993 tcg_gen_shli_tl(t1, t1, lsb);
3994 tcg_gen_andi_tl(t1, t1, mask);
3995 tcg_gen_or_tl(t0, t0, t1);
3996 break;
3997 case OPC_DINSU:
3998 if (lsb > msb)
3999 goto fail;
4000 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
4001 gen_load_gpr(t0, rt);
4002 tcg_gen_andi_tl(t0, t0, ~mask);
4003 tcg_gen_shli_tl(t1, t1, lsb + 32);
4004 tcg_gen_andi_tl(t1, t1, mask);
4005 tcg_gen_or_tl(t0, t0, t1);
4006 break;
4007 case OPC_DINS:
4008 if (lsb > msb)
4009 goto fail;
4010 gen_load_gpr(t0, rt);
4011 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
4012 gen_load_gpr(t0, rt);
4013 tcg_gen_andi_tl(t0, t0, ~mask);
4014 tcg_gen_shli_tl(t1, t1, lsb);
4015 tcg_gen_andi_tl(t1, t1, mask);
4016 tcg_gen_or_tl(t0, t0, t1);
4017 break;
4018 #endif
4019 default:
4020 fail:
4021 MIPS_INVAL("bitops");
4022 generate_exception(ctx, EXCP_RI);
4023 tcg_temp_free(t0);
4024 tcg_temp_free(t1);
4025 return;
4026 }
4027 gen_store_gpr(t0, rt);
4028 tcg_temp_free(t0);
4029 tcg_temp_free(t1);
4030 }
4031
4032 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4033 {
4034 TCGv t0;
4035
4036 if (rd == 0) {
4037 /* If no destination, treat it as a NOP. */
4038 MIPS_DEBUG("NOP");
4039 return;
4040 }
4041
4042 t0 = tcg_temp_new();
4043 gen_load_gpr(t0, rt);
4044 switch (op2) {
4045 case OPC_WSBH:
4046 {
4047 TCGv t1 = tcg_temp_new();
4048
4049 tcg_gen_shri_tl(t1, t0, 8);
4050 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4051 tcg_gen_shli_tl(t0, t0, 8);
4052 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4053 tcg_gen_or_tl(t0, t0, t1);
4054 tcg_temp_free(t1);
4055 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4056 }
4057 break;
4058 case OPC_SEB:
4059 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4060 break;
4061 case OPC_SEH:
4062 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4063 break;
4064 #if defined(TARGET_MIPS64)
4065 case OPC_DSBH:
4066 {
4067 TCGv t1 = tcg_temp_new();
4068
4069 tcg_gen_shri_tl(t1, t0, 8);
4070 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4071 tcg_gen_shli_tl(t0, t0, 8);
4072 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4073 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4074 tcg_temp_free(t1);
4075 }
4076 break;
4077 case OPC_DSHD:
4078 {
4079 TCGv t1 = tcg_temp_new();
4080
4081 tcg_gen_shri_tl(t1, t0, 16);
4082 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4083 tcg_gen_shli_tl(t0, t0, 16);
4084 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4085 tcg_gen_or_tl(t0, t0, t1);
4086 tcg_gen_shri_tl(t1, t0, 32);
4087 tcg_gen_shli_tl(t0, t0, 32);
4088 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4089 tcg_temp_free(t1);
4090 }
4091 break;
4092 #endif
4093 default:
4094 MIPS_INVAL("bsfhl");
4095 generate_exception(ctx, EXCP_RI);
4096 tcg_temp_free(t0);
4097 return;
4098 }
4099 tcg_temp_free(t0);
4100 }
4101
4102 #ifndef CONFIG_USER_ONLY
4103 /* CP0 (MMU and control) */
4104 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4105 {
4106 TCGv_i32 t0 = tcg_temp_new_i32();
4107
4108 tcg_gen_ld_i32(t0, cpu_env, off);
4109 tcg_gen_ext_i32_tl(arg, t0);
4110 tcg_temp_free_i32(t0);
4111 }
4112
4113 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4114 {
4115 tcg_gen_ld_tl(arg, cpu_env, off);
4116 tcg_gen_ext32s_tl(arg, arg);
4117 }
4118
4119 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4120 {
4121 TCGv_i32 t0 = tcg_temp_new_i32();
4122
4123 tcg_gen_trunc_tl_i32(t0, arg);
4124 tcg_gen_st_i32(t0, cpu_env, off);
4125 tcg_temp_free_i32(t0);
4126 }
4127
4128 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4129 {
4130 tcg_gen_ext32s_tl(arg, arg);
4131 tcg_gen_st_tl(arg, cpu_env, off);
4132 }
4133
4134 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4135 {
4136 const char *rn = "invalid";
4137
4138 if (sel != 0)
4139 check_insn(env, ctx, ISA_MIPS32);
4140
4141 switch (reg) {
4142 case 0:
4143 switch (sel) {
4144 case 0:
4145 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4146 rn = "Index";
4147 break;
4148 case 1:
4149 check_insn(env, ctx, ASE_MT);
4150 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4151 rn = "MVPControl";
4152 break;
4153 case 2:
4154 check_insn(env, ctx, ASE_MT);
4155 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4156 rn = "MVPConf0";
4157 break;
4158 case 3:
4159 check_insn(env, ctx, ASE_MT);
4160 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4161 rn = "MVPConf1";
4162 break;
4163 default:
4164 goto die;
4165 }
4166 break;
4167 case 1:
4168 switch (sel) {
4169 case 0:
4170 gen_helper_mfc0_random(arg, cpu_env);
4171 rn = "Random";
4172 break;
4173 case 1:
4174 check_insn(env, ctx, ASE_MT);
4175 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4176 rn = "VPEControl";
4177 break;
4178 case 2:
4179 check_insn(env, ctx, ASE_MT);
4180 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4181 rn = "VPEConf0";
4182 break;
4183 case 3:
4184 check_insn(env, ctx, ASE_MT);
4185 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4186 rn = "VPEConf1";
4187 break;
4188 case 4:
4189 check_insn(env, ctx, ASE_MT);
4190 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4191 rn = "YQMask";
4192 break;
4193 case 5:
4194 check_insn(env, ctx, ASE_MT);
4195 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4196 rn = "VPESchedule";
4197 break;
4198 case 6:
4199 check_insn(env, ctx, ASE_MT);
4200 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4201 rn = "VPEScheFBack";
4202 break;
4203 case 7:
4204 check_insn(env, ctx, ASE_MT);
4205 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4206 rn = "VPEOpt";
4207 break;
4208 default:
4209 goto die;
4210 }
4211 break;
4212 case 2:
4213 switch (sel) {
4214 case 0:
4215 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4216 tcg_gen_ext32s_tl(arg, arg);
4217 rn = "EntryLo0";
4218 break;
4219 case 1:
4220 check_insn(env, ctx, ASE_MT);
4221 gen_helper_mfc0_tcstatus(arg, cpu_env);
4222 rn = "TCStatus";
4223 break;
4224 case 2:
4225 check_insn(env, ctx, ASE_MT);
4226 gen_helper_mfc0_tcbind(arg, cpu_env);
4227 rn = "TCBind";
4228 break;
4229 case 3:
4230 check_insn(env, ctx, ASE_MT);
4231 gen_helper_mfc0_tcrestart(arg, cpu_env);
4232 rn = "TCRestart";
4233 break;
4234 case 4:
4235 check_insn(env, ctx, ASE_MT);
4236 gen_helper_mfc0_tchalt(arg, cpu_env);
4237 rn = "TCHalt";
4238 break;
4239 case 5:
4240 check_insn(env, ctx, ASE_MT);
4241 gen_helper_mfc0_tccontext(arg, cpu_env);
4242 rn = "TCContext";
4243 break;
4244 case 6:
4245 check_insn(env, ctx, ASE_MT);
4246 gen_helper_mfc0_tcschedule(arg, cpu_env);
4247 rn = "TCSchedule";
4248 break;
4249 case 7:
4250 check_insn(env, ctx, ASE_MT);
4251 gen_helper_mfc0_tcschefback(arg, cpu_env);
4252 rn = "TCScheFBack";
4253 break;
4254 default:
4255 goto die;
4256 }
4257 break;
4258 case 3:
4259 switch (sel) {
4260 case 0:
4261 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4262 tcg_gen_ext32s_tl(arg, arg);
4263 rn = "EntryLo1";
4264 break;
4265 default:
4266 goto die;
4267 }
4268 break;
4269 case 4:
4270 switch (sel) {
4271 case 0:
4272 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4273 tcg_gen_ext32s_tl(arg, arg);
4274 rn = "Context";
4275 break;
4276 case 1:
4277 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4278 rn = "ContextConfig";
4279 // break;
4280 default:
4281 goto die;
4282 }
4283 break;
4284 case 5:
4285 switch (sel) {
4286 case 0:
4287 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4288 rn = "PageMask";
4289 break;
4290 case 1:
4291 check_insn(env, ctx, ISA_MIPS32R2);
4292 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4293 rn = "PageGrain";
4294 break;
4295 default:
4296 goto die;
4297 }
4298 break;
4299 case 6:
4300 switch (sel) {
4301 case 0:
4302 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4303 rn = "Wired";
4304 break;
4305 case 1:
4306 check_insn(env, ctx, ISA_MIPS32R2);
4307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4308 rn = "SRSConf0";
4309 break;
4310 case 2:
4311 check_insn(env, ctx, ISA_MIPS32R2);
4312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4313 rn = "SRSConf1";
4314 break;
4315 case 3:
4316 check_insn(env, ctx, ISA_MIPS32R2);
4317 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4318 rn = "SRSConf2";
4319 break;
4320 case 4:
4321 check_insn(env, ctx, ISA_MIPS32R2);
4322 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4323 rn = "SRSConf3";
4324 break;
4325 case 5:
4326 check_insn(env, ctx, ISA_MIPS32R2);
4327 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4328 rn = "SRSConf4";
4329 break;
4330 default:
4331 goto die;
4332 }
4333 break;
4334 case 7:
4335 switch (sel) {
4336 case 0:
4337 check_insn(env, ctx, ISA_MIPS32R2);
4338 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4339 rn = "HWREna";
4340 break;
4341 default:
4342 goto die;
4343 }
4344 break;
4345 case 8:
4346 switch (sel) {
4347 case 0:
4348 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4349 tcg_gen_ext32s_tl(arg, arg);
4350 rn = "BadVAddr";
4351 break;
4352 default:
4353 goto die;
4354 }
4355 break;
4356 case 9:
4357 switch (sel) {
4358 case 0:
4359 /* Mark as an IO operation because we read the time. */
4360 if (use_icount)
4361 gen_io_start();
4362 gen_helper_mfc0_count(arg, cpu_env);
4363 if (use_icount) {
4364 gen_io_end();
4365 }
4366 /* Break the TB to be able to take timer interrupts immediately
4367 after reading count. */
4368 ctx->bstate = BS_STOP;
4369 rn = "Count";
4370 break;
4371 /* 6,7 are implementation dependent */
4372 default:
4373 goto die;
4374 }
4375 break;
4376 case 10:
4377 switch (sel) {
4378 case 0:
4379 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4380 tcg_gen_ext32s_tl(arg, arg);
4381 rn = "EntryHi";
4382 break;
4383 default:
4384 goto die;
4385 }
4386 break;
4387 case 11:
4388 switch (sel) {
4389 case 0:
4390 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4391 rn = "Compare";
4392 break;
4393 /* 6,7 are implementation dependent */
4394 default:
4395 goto die;
4396 }
4397 break;
4398 case 12:
4399 switch (sel) {
4400 case 0:
4401 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4402 rn = "Status";
4403 break;
4404 case 1:
4405 check_insn(env, ctx, ISA_MIPS32R2);
4406 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4407 rn = "IntCtl";
4408 break;
4409 case 2:
4410 check_insn(env, ctx, ISA_MIPS32R2);
4411 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4412 rn = "SRSCtl";
4413 break;
4414 case 3:
4415 check_insn(env, ctx, ISA_MIPS32R2);
4416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4417 rn = "SRSMap";
4418 break;
4419 default:
4420 goto die;
4421 }
4422 break;
4423 case 13:
4424 switch (sel) {
4425 case 0:
4426 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4427 rn = "Cause";
4428 break;
4429 default:
4430 goto die;
4431 }
4432 break;
4433 case 14:
4434 switch (sel) {
4435 case 0:
4436 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4437 tcg_gen_ext32s_tl(arg, arg);
4438 rn = "EPC";
4439 break;
4440 default:
4441 goto die;
4442 }
4443 break;
4444 case 15:
4445 switch (sel) {
4446 case 0:
4447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4448 rn = "PRid";
4449 break;
4450 case 1:
4451 check_insn(env, ctx, ISA_MIPS32R2);
4452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4453 rn = "EBase";
4454 break;
4455 default:
4456 goto die;
4457 }
4458 break;
4459 case 16:
4460 switch (sel) {
4461 case 0:
4462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4463 rn = "Config";
4464 break;
4465 case 1:
4466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4467 rn = "Config1";
4468 break;
4469 case 2:
4470 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4471 rn = "Config2";
4472 break;
4473 case 3:
4474 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4475 rn = "Config3";
4476 break;
4477 /* 4,5 are reserved */
4478 /* 6,7 are implementation dependent */
4479 case 6:
4480 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4481 rn = "Config6";
4482 break;
4483 case 7:
4484 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4485 rn = "Config7";
4486 break;
4487 default:
4488 goto die;
4489 }
4490 break;
4491 case 17:
4492 switch (sel) {
4493 case 0:
4494 gen_helper_mfc0_lladdr(arg, cpu_env);
4495 rn = "LLAddr";
4496 break;
4497 default:
4498 goto die;
4499 }
4500 break;
4501 case 18:
4502 switch (sel) {
4503 case 0 ... 7:
4504 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4505 rn = "WatchLo";
4506 break;
4507 default:
4508 goto die;
4509 }
4510 break;
4511 case 19:
4512 switch (sel) {
4513 case 0 ...7:
4514 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4515 rn = "WatchHi";
4516 break;
4517 default:
4518 goto die;
4519 }
4520 break;
4521 case 20:
4522 switch (sel) {
4523 case 0:
4524 #if defined(TARGET_MIPS64)
4525 check_insn(env, ctx, ISA_MIPS3);
4526 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4527 tcg_gen_ext32s_tl(arg, arg);
4528 rn = "XContext";
4529 break;
4530 #endif
4531 default:
4532 goto die;
4533 }
4534 break;
4535 case 21:
4536 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4537 switch (sel) {
4538 case 0:
4539 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4540 rn = "Framemask";
4541 break;
4542 default:
4543 goto die;
4544 }
4545 break;
4546 case 22:
4547 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4548 rn = "'Diagnostic"; /* implementation dependent */
4549 break;
4550 case 23:
4551 switch (sel) {
4552 case 0:
4553 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4554 rn = "Debug";
4555 break;
4556 case 1:
4557 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4558 rn = "TraceControl";
4559 // break;
4560 case 2:
4561 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4562 rn = "TraceControl2";
4563 // break;
4564 case 3:
4565 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4566 rn = "UserTraceData";
4567 // break;
4568 case 4:
4569 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4570 rn = "TraceBPC";
4571 // break;
4572 default:
4573 goto die;
4574 }
4575 break;
4576 case 24:
4577 switch (sel) {
4578 case 0:
4579 /* EJTAG support */
4580 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4581 tcg_gen_ext32s_tl(arg, arg);
4582 rn = "DEPC";
4583 break;
4584 default:
4585 goto die;
4586 }
4587 break;
4588 case 25:
4589 switch (sel) {
4590 case 0:
4591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4592 rn = "Performance0";
4593 break;
4594 case 1:
4595 // gen_helper_mfc0_performance1(arg);
4596 rn = "Performance1";
4597 // break;
4598 case 2:
4599 // gen_helper_mfc0_performance2(arg);
4600 rn = "Performance2";
4601 // break;
4602 case 3:
4603 // gen_helper_mfc0_performance3(arg);
4604 rn = "Performance3";
4605 // break;
4606 case 4:
4607 // gen_helper_mfc0_performance4(arg);
4608 rn = "Performance4";
4609 // break;
4610 case 5:
4611 // gen_helper_mfc0_performance5(arg);
4612 rn = "Performance5";
4613 // break;
4614 case 6:
4615 // gen_helper_mfc0_performance6(arg);
4616 rn = "Performance6";
4617 // break;
4618 case 7:
4619 // gen_helper_mfc0_performance7(arg);
4620 rn = "Performance7";
4621 // break;
4622 default:
4623 goto die;
4624 }
4625 break;
4626 case 26:
4627 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4628 rn = "ECC";
4629 break;
4630 case 27:
4631 switch (sel) {
4632 case 0 ... 3:
4633 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4634 rn = "CacheErr";
4635 break;
4636 default:
4637 goto die;
4638 }
4639 break;
4640 case 28:
4641 switch (sel) {
4642 case 0:
4643 case 2:
4644 case 4:
4645 case 6:
4646 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4647 rn = "TagLo";
4648 break;
4649 case 1:
4650 case 3:
4651 case 5:
4652 case 7:
4653 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4654 rn = "DataLo";
4655 break;
4656 default:
4657 goto die;
4658 }
4659 break;
4660 case 29:
4661 switch (sel) {
4662 case 0:
4663 case 2:
4664 case 4:
4665 case 6:
4666 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4667 rn = "TagHi";
4668 break;
4669 case 1:
4670 case 3:
4671 case 5:
4672 case 7:
4673 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4674 rn = "DataHi";
4675 break;
4676 default:
4677 goto die;
4678 }
4679 break;
4680 case 30:
4681 switch (sel) {
4682 case 0:
4683 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4684 tcg_gen_ext32s_tl(arg, arg);
4685 rn = "ErrorEPC";
4686 break;
4687 default:
4688 goto die;
4689 }
4690 break;
4691 case 31:
4692 switch (sel) {
4693 case 0:
4694 /* EJTAG support */
4695 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4696 rn = "DESAVE";
4697 break;
4698 default:
4699 goto die;
4700 }
4701 break;
4702 default:
4703 goto die;
4704 }
4705 (void)rn; /* avoid a compiler warning */
4706 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4707 return;
4708
4709 die:
4710 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4711 generate_exception(ctx, EXCP_RI);
4712 }
4713
4714 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4715 {
4716 const char *rn = "invalid";
4717
4718 if (sel != 0)
4719 check_insn(env, ctx, ISA_MIPS32);
4720
4721 if (use_icount)
4722 gen_io_start();
4723
4724 switch (reg) {
4725 case 0:
4726 switch (sel) {
4727 case 0:
4728 gen_helper_mtc0_index(cpu_env, arg);
4729 rn = "Index";
4730 break;
4731 case 1:
4732 check_insn(env, ctx, ASE_MT);
4733 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4734 rn = "MVPControl";
4735 break;
4736 case 2:
4737 check_insn(env, ctx, ASE_MT);
4738 /* ignored */
4739 rn = "MVPConf0";
4740 break;
4741 case 3:
4742 check_insn(env, ctx, ASE_MT);
4743 /* ignored */
4744 rn = "MVPConf1";
4745 break;
4746 default:
4747 goto die;
4748 }
4749 break;
4750 case 1:
4751 switch (sel) {
4752 case 0:
4753 /* ignored */
4754 rn = "Random";
4755 break;
4756 case 1:
4757 check_insn(env, ctx, ASE_MT);
4758 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4759 rn = "VPEControl";
4760 break;
4761 case 2:
4762 check_insn(env, ctx, ASE_MT);
4763 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4764 rn = "VPEConf0";
4765 break;
4766 case 3:
4767 check_insn(env, ctx, ASE_MT);
4768 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4769 rn = "VPEConf1";
4770 break;
4771 case 4:
4772 check_insn(env, ctx, ASE_MT);
4773 gen_helper_mtc0_yqmask(cpu_env, arg);
4774 rn = "YQMask";
4775 break;
4776 case 5:
4777 check_insn(env, ctx, ASE_MT);
4778 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4779 rn = "VPESchedule";
4780 break;
4781 case 6:
4782 check_insn(env, ctx, ASE_MT);
4783 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4784 rn = "VPEScheFBack";
4785 break;
4786 case 7:
4787 check_insn(env, ctx, ASE_MT);
4788 gen_helper_mtc0_vpeopt(cpu_env, arg);
4789 rn = "VPEOpt";
4790 break;
4791 default:
4792 goto die;
4793 }
4794 break;
4795 case 2:
4796 switch (sel) {
4797 case 0:
4798 gen_helper_mtc0_entrylo0(cpu_env, arg);
4799 rn = "EntryLo0";
4800 break;
4801 case 1:
4802 check_insn(env, ctx, ASE_MT);
4803 gen_helper_mtc0_tcstatus(cpu_env, arg);
4804 rn = "TCStatus";
4805 break;
4806 case 2:
4807 check_insn(env, ctx, ASE_MT);
4808 gen_helper_mtc0_tcbind(cpu_env, arg);
4809 rn = "TCBind";
4810 break;
4811 case 3:
4812 check_insn(env, ctx, ASE_MT);
4813 gen_helper_mtc0_tcrestart(cpu_env, arg);
4814 rn = "TCRestart";
4815 break;
4816 case 4:
4817 check_insn(env, ctx, ASE_MT);
4818 gen_helper_mtc0_tchalt(cpu_env, arg);
4819 rn = "TCHalt";
4820 break;
4821 case 5:
4822 check_insn(env, ctx, ASE_MT);
4823 gen_helper_mtc0_tccontext(cpu_env, arg);
4824 rn = "TCContext";
4825 break;
4826 case 6:
4827 check_insn(env, ctx, ASE_MT);
4828 gen_helper_mtc0_tcschedule(cpu_env, arg);
4829 rn = "TCSchedule";
4830 break;
4831 case 7:
4832 check_insn(env, ctx, ASE_MT);
4833 gen_helper_mtc0_tcschefback(cpu_env, arg);
4834 rn = "TCScheFBack";
4835 break;
4836 default:
4837 goto die;
4838 }
4839 break;
4840 case 3:
4841 switch (sel) {
4842 case 0:
4843 gen_helper_mtc0_entrylo1(cpu_env, arg);
4844 rn = "EntryLo1";
4845 break;
4846 default:
4847 goto die;
4848 }
4849 break;
4850 case 4:
4851 switch (sel) {
4852 case 0:
4853 gen_helper_mtc0_context(cpu_env, arg);
4854 rn = "Context";
4855 break;
4856 case 1:
4857 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4858 rn = "ContextConfig";
4859 // break;
4860 default:
4861 goto die;
4862 }
4863 break;
4864 case 5:
4865 switch (sel) {
4866 case 0:
4867 gen_helper_mtc0_pagemask(cpu_env, arg);
4868 rn = "PageMask";
4869 break;
4870 case 1:
4871 check_insn(env, ctx, ISA_MIPS32R2);
4872 gen_helper_mtc0_pagegrain(cpu_env, arg);
4873 rn = "PageGrain";
4874 break;
4875 default:
4876 goto die;
4877 }
4878 break;
4879 case 6:
4880 switch (sel) {
4881 case 0:
4882 gen_helper_mtc0_wired(cpu_env, arg);
4883 rn = "Wired";
4884 break;
4885 case 1:
4886 check_insn(env, ctx, ISA_MIPS32R2);
4887 gen_helper_mtc0_srsconf0(cpu_env, arg);
4888 rn = "SRSConf0";
4889 break;
4890 case 2:
4891 check_insn(env, ctx, ISA_MIPS32R2);
4892 gen_helper_mtc0_srsconf1(cpu_env, arg);
4893 rn = "SRSConf1";
4894 break;
4895 case 3:
4896 check_insn(env, ctx, ISA_MIPS32R2);
4897 gen_helper_mtc0_srsconf2(cpu_env, arg);
4898 rn = "SRSConf2";
4899 break;
4900 case 4:
4901 check_insn(env, ctx, ISA_MIPS32R2);
4902 gen_helper_mtc0_srsconf3(cpu_env, arg);
4903 rn = "SRSConf3";
4904 break;
4905 case 5:
4906 check_insn(env, ctx, ISA_MIPS32R2);
4907 gen_helper_mtc0_srsconf4(cpu_env, arg);
4908 rn = "SRSConf4";
4909 break;
4910 default:
4911 goto die;
4912 }
4913 break;
4914 case 7:
4915 switch (sel) {
4916 case 0:
4917 check_insn(env, ctx, ISA_MIPS32R2);
4918 gen_helper_mtc0_hwrena(cpu_env, arg);
4919 rn = "HWREna";
4920 break;
4921 default:
4922 goto die;
4923 }
4924 break;
4925 case 8:
4926 /* ignored */
4927 rn = "BadVAddr";
4928 break;
4929 case 9:
4930 switch (sel) {
4931 case 0:
4932 gen_helper_mtc0_count(cpu_env, arg);
4933 rn = "Count";
4934 break;
4935 /* 6,7 are implementation dependent */
4936 default:
4937 goto die;
4938 }
4939 break;
4940 case 10:
4941 switch (sel) {
4942 case 0:
4943 gen_helper_mtc0_entryhi(cpu_env, arg);
4944 rn = "EntryHi";
4945 break;
4946 default:
4947 goto die;
4948 }
4949 break;
4950 case 11:
4951 switch (sel) {
4952 case 0:
4953 gen_helper_mtc0_compare(cpu_env, arg);
4954 rn = "Compare";
4955 break;
4956 /* 6,7 are implementation dependent */
4957 default:
4958 goto die;
4959 }
4960 break;
4961 case 12:
4962 switch (sel) {
4963 case 0:
4964 save_cpu_state(ctx, 1);
4965 gen_helper_mtc0_status(cpu_env, arg);
4966 /* BS_STOP isn't good enough here, hflags may have changed. */
4967 gen_save_pc(ctx->pc + 4);
4968 ctx->bstate = BS_EXCP;
4969 rn = "Status";
4970 break;
4971 case 1:
4972 check_insn(env, ctx, ISA_MIPS32R2);
4973 gen_helper_mtc0_intctl(cpu_env, arg);
4974 /* Stop translation as we may have switched the execution mode */
4975 ctx->bstate = BS_STOP;
4976 rn = "IntCtl";
4977 break;
4978 case 2:
4979 check_insn(env, ctx, ISA_MIPS32R2);
4980 gen_helper_mtc0_srsctl(cpu_env, arg);
4981 /* Stop translation as we may have switched the execution mode */
4982 ctx->bstate = BS_STOP;
4983 rn = "SRSCtl";
4984 break;
4985 case 3:
4986 check_insn(env, ctx, ISA_MIPS32R2);
4987 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4988 /* Stop translation as we may have switched the execution mode */
4989 ctx->bstate = BS_STOP;
4990 rn = "SRSMap";
4991 break;
4992 default:
4993 goto die;
4994 }
4995 break;
4996 case 13:
4997 switch (sel) {
4998 case 0:
4999 save_cpu_state(ctx, 1);
5000 gen_helper_mtc0_cause(cpu_env, arg);
5001 rn = "Cause";
5002 break;
5003 default:
5004 goto die;
5005 }
5006 break;
5007 case 14:
5008 switch (sel) {
5009 case 0:
5010 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5011 rn = "EPC";
5012 break;
5013 default:
5014 goto die;
5015 }
5016 break;
5017 case 15:
5018 switch (sel) {
5019 case 0:
5020 /* ignored */
5021 rn = "PRid";
5022 break;
5023 case 1:
5024 check_insn(env, ctx, ISA_MIPS32R2);
5025 gen_helper_mtc0_ebase(cpu_env, arg);
5026 rn = "EBase";
5027 break;
5028 default:
5029 goto die;
5030 }
5031 break;
5032 case 16:
5033 switch (sel) {
5034 case 0:
5035 gen_helper_mtc0_config0(cpu_env, arg);
5036 rn = "Config";
5037 /* Stop translation as we may have switched the execution mode */
5038 ctx->bstate = BS_STOP;
5039 break;
5040 case 1:
5041 /* ignored, read only */
5042 rn = "Config1";
5043 break;
5044 case 2:
5045 gen_helper_mtc0_config2(cpu_env, arg);
5046 rn = "Config2";
5047 /* Stop translation as we may have switched the execution mode */
5048 ctx->bstate = BS_STOP;
5049 break;
5050 case 3:
5051 /* ignored, read only */
5052 rn = "Config3";
5053 break;
5054 /* 4,5 are reserved */
5055 /* 6,7 are implementation dependent */
5056 case 6:
5057 /* ignored */
5058 rn = "Config6";
5059 break;
5060 case 7:
5061 /* ignored */
5062 rn = "Config7";
5063 break;
5064 default:
5065 rn = "Invalid config selector";
5066 goto die;
5067 }
5068 break;
5069 case 17:
5070 switch (sel) {
5071 case 0:
5072 gen_helper_mtc0_lladdr(cpu_env, arg);
5073 rn = "LLAddr";
5074 break;
5075 default:
5076 goto die;
5077 }
5078 break;
5079 case 18:
5080 switch (sel) {
5081 case 0 ... 7:
5082 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5083 rn = "WatchLo";
5084 break;
5085 default:
5086 goto die;
5087 }
5088 break;
5089 case 19:
5090 switch (sel) {
5091 case 0 ... 7:
5092 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5093 rn = "WatchHi";
5094 break;
5095 default:
5096 goto die;
5097 }
5098 break;
5099 case 20:
5100 switch (sel) {
5101 case 0:
5102 #if defined(TARGET_MIPS64)
5103 check_insn(env, ctx, ISA_MIPS3);
5104 gen_helper_mtc0_xcontext(cpu_env, arg);
5105 rn = "XContext";
5106 break;
5107 #endif
5108 default:
5109 goto die;
5110 }
5111 break;
5112 case 21:
5113 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5114 switch (sel) {
5115 case 0:
5116 gen_helper_mtc0_framemask(cpu_env, arg);
5117 rn = "Framemask";
5118 break;
5119 default:
5120 goto die;
5121 }
5122 break;
5123 case 22:
5124 /* ignored */
5125 rn = "Diagnostic"; /* implementation dependent */
5126 break;
5127 case 23:
5128 switch (sel) {
5129 case 0:
5130 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5131 /* BS_STOP isn't good enough here, hflags may have changed. */
5132 gen_save_pc(ctx->pc + 4);
5133 ctx->bstate = BS_EXCP;
5134 rn = "Debug";
5135 break;
5136 case 1:
5137 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5138 rn = "TraceControl";
5139 /* Stop translation as we may have switched the execution mode */
5140 ctx->bstate = BS_STOP;
5141 // break;
5142 case 2:
5143 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5144 rn = "TraceControl2";
5145 /* Stop translation as we may have switched the execution mode */
5146 ctx->bstate = BS_STOP;
5147 // break;
5148 case 3:
5149 /* Stop translation as we may have switched the execution mode */
5150 ctx->bstate = BS_STOP;
5151 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5152 rn = "UserTraceData";
5153 /* Stop translation as we may have switched the execution mode */
5154 ctx->bstate = BS_STOP;
5155 // break;
5156 case 4:
5157 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5158 /* Stop translation as we may have switched the execution mode */
5159 ctx->bstate = BS_STOP;
5160 rn = "TraceBPC";
5161 // break;
5162 default:
5163 goto die;
5164 }
5165 break;
5166 case 24:
5167 switch (sel) {
5168 case 0:
5169 /* EJTAG support */
5170 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5171 rn = "DEPC";
5172 break;
5173 default:
5174 goto die;
5175 }
5176 break;
5177 case 25:
5178 switch (sel) {
5179 case 0:
5180 gen_helper_mtc0_performance0(cpu_env, arg);
5181 rn = "Performance0";
5182 break;
5183 case 1:
5184 // gen_helper_mtc0_performance1(arg);
5185 rn = "Performance1";
5186 // break;
5187 case 2:
5188 // gen_helper_mtc0_performance2(arg);
5189 rn = "Performance2";
5190 // break;
5191 case 3:
5192 // gen_helper_mtc0_performance3(arg);
5193 rn = "Performance3";
5194 // break;
5195 case 4:
5196 // gen_helper_mtc0_performance4(arg);
5197 rn = "Performance4";
5198 // break;
5199 case 5:
5200 // gen_helper_mtc0_performance5(arg);
5201 rn = "Performance5";
5202 // break;
5203 case 6:
5204 // gen_helper_mtc0_performance6(arg);
5205 rn = "Performance6";
5206 // break;
5207 case 7:
5208 // gen_helper_mtc0_performance7(arg);
5209 rn = "Performance7";
5210 // break;
5211 default:
5212 goto die;
5213 }
5214 break;
5215 case 26:
5216 /* ignored */
5217 rn = "ECC";
5218 break;
5219 case 27:
5220 switch (sel) {
5221 case 0 ... 3:
5222 /* ignored */
5223 rn = "CacheErr";
5224 break;
5225 default:
5226 goto die;
5227 }
5228 break;
5229 case 28:
5230 switch (sel) {
5231 case 0:
5232 case 2:
5233 case 4:
5234 case 6:
5235 gen_helper_mtc0_taglo(cpu_env, arg);
5236 rn = "TagLo";
5237 break;
5238 case 1:
5239 case 3:
5240 case 5:
5241 case 7:
5242 gen_helper_mtc0_datalo(cpu_env, arg);
5243 rn = "DataLo";
5244 break;
5245 default:
5246 goto die;
5247 }
5248 break;
5249 case 29:
5250 switch (sel) {
5251 case 0:
5252 case 2:
5253 case 4:
5254 case 6:
5255 gen_helper_mtc0_taghi(cpu_env, arg);
5256 rn = "TagHi";
5257 break;
5258 case 1:
5259 case 3:
5260 case 5:
5261 case 7:
5262 gen_helper_mtc0_datahi(cpu_env, arg);
5263 rn = "DataHi";
5264 break;
5265 default:
5266 rn = "invalid sel";
5267 goto die;
5268 }
5269 break;
5270 case 30:
5271 switch (sel) {
5272 case 0:
5273 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5274 rn = "ErrorEPC";
5275 break;
5276 default:
5277 goto die;
5278 }
5279 break;
5280 case 31:
5281 switch (sel) {
5282 case 0:
5283 /* EJTAG support */
5284 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5285 rn = "DESAVE";
5286 break;
5287 default:
5288 goto die;
5289 }
5290 /* Stop translation as we may have switched the execution mode */
5291 ctx->bstate = BS_STOP;
5292 break;
5293 default:
5294 goto die;
5295 }
5296 (void)rn; /* avoid a compiler warning */
5297 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5298 /* For simplicity assume that all writes can cause interrupts. */
5299 if (use_icount) {
5300 gen_io_end();
5301 ctx->bstate = BS_STOP;
5302 }
5303 return;
5304
5305 die:
5306 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5307 generate_exception(ctx, EXCP_RI);
5308 }
5309
5310 #if defined(TARGET_MIPS64)
5311 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5312 {
5313 const char *rn = "invalid";
5314
5315 if (sel != 0)
5316 check_insn(env, ctx, ISA_MIPS64);
5317
5318 switch (reg) {
5319 case 0:
5320 switch (sel) {
5321 case 0:
5322 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5323 rn = "Index";
5324 break;
5325 case 1:
5326 check_insn(env, ctx, ASE_MT);
5327 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5328 rn = "MVPControl";
5329 break;
5330 case 2:
5331 check_insn(env, ctx, ASE_MT);
5332 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5333 rn = "MVPConf0";
5334 break;
5335 case 3:
5336 check_insn(env, ctx, ASE_MT);
5337 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5338 rn = "MVPConf1";
5339 break;
5340 default:
5341 goto die;
5342 }
5343 break;
5344 case 1:
5345 switch (sel) {
5346 case 0:
5347 gen_helper_mfc0_random(arg, cpu_env);
5348 rn = "Random";
5349 break;
5350 case 1:
5351 check_insn(env, ctx, ASE_MT);
5352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5353 rn = "VPEControl";
5354 break;
5355 case 2:
5356 check_insn(env, ctx, ASE_MT);
5357 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5358 rn = "VPEConf0";
5359 break;
5360 case 3:
5361 check_insn(env, ctx, ASE_MT);
5362 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5363 rn = "VPEConf1";
5364 break;
5365 case 4:
5366 check_insn(env, ctx, ASE_MT);
5367 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5368 rn = "YQMask";
5369 break;
5370 case 5:
5371 check_insn(env, ctx, ASE_MT);
5372 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5373 rn = "VPESchedule";
5374 break;
5375 case 6:
5376 check_insn(env, ctx, ASE_MT);
5377 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5378 rn = "VPEScheFBack";
5379 break;
5380 case 7:
5381 check_insn(env, ctx, ASE_MT);
5382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5383 rn = "VPEOpt";
5384 break;
5385 default:
5386 goto die;
5387 }
5388 break;
5389 case 2:
5390 switch (sel) {
5391 case 0:
5392 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5393 rn = "EntryLo0";
5394 break;
5395 case 1:
5396 check_insn(env, ctx, ASE_MT);
5397 gen_helper_mfc0_tcstatus(arg, cpu_env);
5398 rn = "TCStatus";
5399 break;
5400 case 2:
5401 check_insn(env, ctx, ASE_MT);
5402 gen_helper_mfc0_tcbind(arg, cpu_env);
5403 rn = "TCBind";
5404 break;
5405 case 3:
5406 check_insn(env, ctx, ASE_MT);
5407 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5408 rn = "TCRestart";
5409 break;
5410 case 4:
5411 check_insn(env, ctx, ASE_MT);
5412 gen_helper_dmfc0_tchalt(arg, cpu_env);
5413 rn = "TCHalt";
5414 break;
5415 case 5:
5416 check_insn(env, ctx, ASE_MT);
5417 gen_helper_dmfc0_tccontext(arg, cpu_env);
5418 rn = "TCContext";
5419 break;
5420 case 6:
5421 check_insn(env, ctx, ASE_MT);
5422 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5423 rn = "TCSchedule";
5424 break;
5425 case 7:
5426 check_insn(env, ctx, ASE_MT);
5427 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5428 rn = "TCScheFBack";
5429 break;
5430 default:
5431 goto die;
5432 }
5433 break;
5434 case 3:
5435 switch (sel) {
5436 case 0:
5437 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5438 rn = "EntryLo1";
5439 break;
5440 default:
5441 goto die;
5442 }
5443 break;
5444 case 4:
5445 switch (sel) {
5446 case 0:
5447 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5448 rn = "Context";
5449 break;
5450 case 1:
5451 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5452 rn = "ContextConfig";
5453 // break;
5454 default:
5455 goto die;
5456 }
5457 break;
5458 case 5:
5459 switch (sel) {
5460 case 0:
5461 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5462 rn = "PageMask";
5463 break;
5464 case 1:
5465 check_insn(env, ctx, ISA_MIPS32R2);
5466 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5467 rn = "PageGrain";
5468 break;
5469 default:
5470 goto die;
5471 }
5472 break;
5473 case 6:
5474 switch (sel) {
5475 case 0:
5476 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5477 rn = "Wired";
5478 break;
5479 case 1:
5480 check_insn(env, ctx, ISA_MIPS32R2);
5481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5482 rn = "SRSConf0";
5483 break;
5484 case 2:
5485 check_insn(env, ctx, ISA_MIPS32R2);
5486 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5487 rn = "SRSConf1";
5488 break;
5489 case 3:
5490 check_insn(env, ctx, ISA_MIPS32R2);
5491 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5492 rn = "SRSConf2";
5493 break;
5494 case 4:
5495 check_insn(env, ctx, ISA_MIPS32R2);
5496 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5497 rn = "SRSConf3";
5498 break;
5499 case 5:
5500 check_insn(env, ctx, ISA_MIPS32R2);
5501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5502 rn = "SRSConf4";
5503 break;
5504 default:
5505 goto die;
5506 }
5507 break;
5508 case 7:
5509 switch (sel) {
5510 case 0:
5511 check_insn(env, ctx, ISA_MIPS32R2);
5512 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5513 rn = "HWREna";
5514 break;
5515 default:
5516 goto die;
5517 }
5518 break;
5519 case 8:
5520 switch (sel) {
5521 case 0:
5522 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5523 rn = "BadVAddr";
5524 break;
5525 default:
5526 goto die;
5527 }
5528 break;
5529 case 9:
5530 switch (sel) {
5531 case 0:
5532 /* Mark as an IO operation because we read the time. */
5533 if (use_icount)
5534 gen_io_start();
5535 gen_helper_mfc0_count(arg, cpu_env);
5536 if (use_icount) {
5537 gen_io_end();
5538 }
5539 /* Break the TB to be able to take timer interrupts immediately
5540 after reading count. */
5541 ctx->bstate = BS_STOP;
5542 rn = "Count";
5543 break;
5544 /* 6,7 are implementation dependent */
5545 default:
5546 goto die;
5547 }
5548 break;
5549 case 10:
5550 switch (sel) {
5551 case 0:
5552 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5553 rn = "EntryHi";
5554 break;
5555 default:
5556 goto die;
5557 }
5558 break;
5559 case 11:
5560 switch (sel) {
5561 case 0:
5562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5563 rn = "Compare";
5564 break;
5565 /* 6,7 are implementation dependent */
5566 default:
5567 goto die;
5568 }
5569 break;
5570 case 12:
5571 switch (sel) {
5572 case 0:
5573 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5574 rn = "Status";
5575 break;
5576 case 1:
5577 check_insn(env, ctx, ISA_MIPS32R2);
5578 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5579 rn = "IntCtl";
5580 break;
5581 case 2:
5582 check_insn(env, ctx, ISA_MIPS32R2);
5583 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5584 rn = "SRSCtl";
5585 break;
5586 case 3:
5587 check_insn(env, ctx, ISA_MIPS32R2);
5588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5589 rn = "SRSMap";
5590 break;
5591 default:
5592 goto die;
5593 }
5594 break;
5595 case 13:
5596 switch (sel) {
5597 case 0:
5598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5599 rn = "Cause";
5600 break;
5601 default:
5602 goto die;
5603 }
5604 break;
5605 case 14:
5606 switch (sel) {
5607 case 0:
5608 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5609 rn = "EPC";
5610 break;
5611 default:
5612 goto die;
5613 }
5614 break;
5615 case 15:
5616 switch (sel) {
5617 case 0:
5618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5619 rn = "PRid";
5620 break;
5621 case 1:
5622 check_insn(env, ctx, ISA_MIPS32R2);
5623 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5624 rn = "EBase";
5625 break;
5626 default:
5627 goto die;
5628 }
5629 break;
5630 case 16:
5631 switch (sel) {
5632 case 0:
5633 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5634 rn = "Config";
5635 break;
5636 case 1:
5637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5638 rn = "Config1";
5639 break;
5640 case 2:
5641 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5642 rn = "Config2";
5643 break;
5644 case 3:
5645 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5646 rn = "Config3";
5647 break;
5648 /* 6,7 are implementation dependent */
5649 case 6:
5650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5651 rn = "Config6";
5652 break;
5653 case 7:
5654 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5655 rn = "Config7";
5656 break;
5657 default:
5658 goto die;
5659 }
5660 break;
5661 case 17:
5662 switch (sel) {
5663 case 0:
5664 gen_helper_dmfc0_lladdr(arg, cpu_env);
5665 rn = "LLAddr";
5666 break;
5667 default:
5668 goto die;
5669 }
5670 break;
5671 case 18:
5672 switch (sel) {
5673 case 0 ... 7:
5674 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5675 rn = "WatchLo";
5676 break;
5677 default:
5678 goto die;
5679 }
5680 break;
5681 case 19:
5682 switch (sel) {
5683 case 0 ... 7:
5684 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5685 rn = "WatchHi";
5686 break;
5687 default:
5688 goto die;
5689 }
5690 break;
5691 case 20:
5692 switch (sel) {
5693 case 0:
5694 check_insn(env, ctx, ISA_MIPS3);
5695 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5696 rn = "XContext";
5697 break;
5698 default:
5699 goto die;
5700 }
5701 break;
5702 case 21:
5703 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5704 switch (sel) {
5705 case 0:
5706 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5707 rn = "Framemask";
5708 break;
5709 default:
5710 goto die;
5711 }
5712 break;
5713 case 22:
5714 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5715 rn = "'Diagnostic"; /* implementation dependent */
5716 break;
5717 case 23:
5718 switch (sel) {
5719 case 0:
5720 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5721 rn = "Debug";
5722 break;
5723 case 1:
5724 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5725 rn = "TraceControl";
5726 // break;
5727 case 2:
5728 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5729 rn = "TraceControl2";
5730 // break;
5731 case 3:
5732 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5733 rn = "UserTraceData";
5734 // break;
5735 case 4:
5736 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5737 rn = "TraceBPC";
5738 // break;
5739 default:
5740 goto die;
5741 }
5742 break;
5743 case 24:
5744 switch (sel) {
5745 case 0:
5746 /* EJTAG support */
5747 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5748 rn = "DEPC";
5749 break;
5750 default:
5751 goto die;
5752 }
5753 break;
5754 case 25:
5755 switch (sel) {
5756 case 0:
5757 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5758 rn = "Performance0";
5759 break;
5760 case 1:
5761 // gen_helper_dmfc0_performance1(arg);
5762 rn = "Performance1";
5763 // break;
5764 case 2:
5765 // gen_helper_dmfc0_performance2(arg);
5766 rn = "Performance2";
5767 // break;
5768 case 3:
5769 // gen_helper_dmfc0_performance3(arg);
5770 rn = "Performance3";
5771 // break;
5772 case 4:
5773 // gen_helper_dmfc0_performance4(arg);
5774 rn = "Performance4";
5775 // break;
5776 case 5:
5777 // gen_helper_dmfc0_performance5(arg);
5778 rn = "Performance5";
5779 // break;
5780 case 6:
5781 // gen_helper_dmfc0_performance6(arg);
5782 rn = "Performance6";
5783 // break;
5784 case 7:
5785 // gen_helper_dmfc0_performance7(arg);
5786 rn = "Performance7";
5787 // break;
5788 default:
5789 goto die;
5790 }
5791 break;
5792 case 26:
5793 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5794 rn = "ECC";
5795 break;
5796 case 27:
5797 switch (sel) {
5798 /* ignored */
5799 case 0 ... 3:
5800 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5801 rn = "CacheErr";
5802 break;
5803 default:
5804 goto die;
5805 }
5806 break;
5807 case 28:
5808 switch (sel) {
5809 case 0:
5810 case 2:
5811 case 4:
5812 case 6:
5813 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5814 rn = "TagLo";
5815 break;
5816 case 1:
5817 case 3:
5818 case 5:
5819 case 7:
5820 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5821 rn = "DataLo";
5822 break;
5823 default:
5824 goto die;
5825 }
5826 break;
5827 case 29:
5828 switch (sel) {
5829 case 0:
5830 case 2:
5831 case 4:
5832 case 6:
5833 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5834 rn = "TagHi";
5835 break;
5836 case 1:
5837 case 3:
5838 case 5:
5839 case 7:
5840 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5841 rn = "DataHi";
5842 break;
5843 default:
5844 goto die;
5845 }
5846 break;
5847 case 30:
5848 switch (sel) {
5849 case 0:
5850 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5851 rn = "ErrorEPC";
5852 break;
5853 default:
5854 goto die;
5855 }
5856 break;
5857 case 31:
5858 switch (sel) {
5859 case 0:
5860 /* EJTAG support */
5861 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5862 rn = "DESAVE";
5863 break;
5864 default:
5865 goto die;
5866 }
5867 break;
5868 default:
5869 goto die;
5870 }
5871 (void)rn; /* avoid a compiler warning */
5872 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5873 return;
5874
5875 die:
5876 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5877 generate_exception(ctx, EXCP_RI);
5878 }
5879
5880 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5881 {
5882 const char *rn = "invalid";
5883
5884 if (sel != 0)
5885 check_insn(env, ctx, ISA_MIPS64);
5886
5887 if (use_icount)
5888 gen_io_start();
5889
5890 switch (reg) {
5891 case 0:
5892 switch (sel) {
5893 case 0:
5894 gen_helper_mtc0_index(cpu_env, arg);
5895 rn = "Index";
5896 break;
5897 case 1:
5898 check_insn(env, ctx, ASE_MT);
5899 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5900 rn = "MVPControl";
5901 break;
5902 case 2:
5903 check_insn(env, ctx, ASE_MT);
5904 /* ignored */
5905 rn = "MVPConf0";
5906 break;
5907 case 3:
5908 check_insn(env, ctx, ASE_MT);
5909 /* ignored */
5910 rn = "MVPConf1";
5911 break;
5912 default:
5913 goto die;
5914 }
5915 break;
5916 case 1:
5917 switch (sel) {
5918 case 0:
5919 /* ignored */
5920 rn = "Random";
5921 break;
5922 case 1:
5923 check_insn(env, ctx, ASE_MT);
5924 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5925 rn = "VPEControl";
5926 break;
5927 case 2:
5928 check_insn(env, ctx, ASE_MT);
5929 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5930 rn = "VPEConf0";
5931 break;
5932 case 3:
5933 check_insn(env, ctx, ASE_MT);
5934 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5935 rn = "VPEConf1";
5936 break;
5937 case 4:
5938 check_insn(env, ctx, ASE_MT);
5939 gen_helper_mtc0_yqmask(cpu_env, arg);
5940 rn = "YQMask";
5941 break;
5942 case 5:
5943 check_insn(env, ctx, ASE_MT);
5944 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5945 rn = "VPESchedule";
5946 break;
5947 case 6:
5948 check_insn(env, ctx, ASE_MT);
5949 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5950 rn = "VPEScheFBack";
5951 break;
5952 case 7:
5953 check_insn(env, ctx, ASE_MT);
5954 gen_helper_mtc0_vpeopt(cpu_env, arg);
5955 rn = "VPEOpt";
5956 break;
5957 default:
5958 goto die;
5959 }
5960 break;
5961 case 2:
5962 switch (sel) {
5963 case 0:
5964 gen_helper_mtc0_entrylo0(cpu_env, arg);
5965 rn = "EntryLo0";
5966 break;
5967 case 1:
5968 check_insn(env, ctx, ASE_MT);
5969 gen_helper_mtc0_tcstatus(cpu_env, arg);
5970 rn = "TCStatus";
5971 break;
5972 case 2:
5973 check_insn(env, ctx, ASE_MT);
5974 gen_helper_mtc0_tcbind(cpu_env, arg);
5975 rn = "TCBind";
5976 break;
5977 case 3:
5978 check_insn(env, ctx, ASE_MT);
5979 gen_helper_mtc0_tcrestart(cpu_env, arg);
5980 rn = "TCRestart";
5981 break;
5982 case 4:
5983 check_insn(env, ctx, ASE_MT);
5984 gen_helper_mtc0_tchalt(cpu_env, arg);
5985 rn = "TCHalt";
5986 break;
5987 case 5:
5988 check_insn(env, ctx, ASE_MT);
5989 gen_helper_mtc0_tccontext(cpu_env, arg);
5990 rn = "TCContext";
5991 break;
5992 case 6:
5993 check_insn(env, ctx, ASE_MT);
5994 gen_helper_mtc0_tcschedule(cpu_env, arg);
5995 rn = "TCSchedule";
5996 break;
5997 case 7:
5998 check_insn(env, ctx, ASE_MT);
5999 gen_helper_mtc0_tcschefback(cpu_env, arg);
6000 rn = "TCScheFBack";
6001 break;
6002 default:
6003 goto die;
6004 }
6005 break;
6006 case 3:
6007 switch (sel) {
6008 case 0:
6009 gen_helper_mtc0_entrylo1(cpu_env, arg);
6010 rn = "EntryLo1";
6011 break;
6012 default:
6013 goto die;
6014 }
6015 break;
6016 case 4:
6017 switch (sel) {
6018 case 0:
6019 gen_helper_mtc0_context(cpu_env, arg);
6020 rn = "Context";
6021 break;
6022 case 1:
6023 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6024 rn = "ContextConfig";
6025 // break;
6026 default:
6027 goto die;
6028 }
6029 break;
6030 case 5:
6031 switch (sel) {
6032 case 0:
6033 gen_helper_mtc0_pagemask(cpu_env, arg);
6034 rn = "PageMask";
6035 break;
6036 case 1:
6037 check_insn(env, ctx, ISA_MIPS32R2);
6038 gen_helper_mtc0_pagegrain(cpu_env, arg);
6039 rn = "PageGrain";
6040 break;
6041 default:
6042 goto die;
6043 }
6044 break;
6045 case 6:
6046 switch (sel) {
6047 case 0:
6048 gen_helper_mtc0_wired(cpu_env, arg);
6049 rn = "Wired";
6050 break;
6051 case 1:
6052 check_insn(env, ctx, ISA_MIPS32R2);
6053 gen_helper_mtc0_srsconf0(cpu_env, arg);
6054 rn = "SRSConf0";
6055 break;
6056 case 2:
6057 check_insn(env, ctx, ISA_MIPS32R2);
6058 gen_helper_mtc0_srsconf1(cpu_env, arg);
6059 rn = "SRSConf1";
6060 break;
6061 case 3:
6062 check_insn(env, ctx, ISA_MIPS32R2);
6063 gen_helper_mtc0_srsconf2(cpu_env, arg);
6064 rn = "SRSConf2";
6065 break;
6066 case 4:
6067 check_insn(env, ctx, ISA_MIPS32R2);
6068 gen_helper_mtc0_srsconf3(cpu_env, arg);
6069 rn = "SRSConf3";
6070 break;
6071 case 5:
6072 check_insn(env, ctx, ISA_MIPS32R2);
6073 gen_helper_mtc0_srsconf4(cpu_env, arg);
6074 rn = "SRSConf4";
6075 break;
6076 default:
6077 goto die;
6078 }
6079 break;
6080 case 7:
6081 switch (sel) {
6082 case 0:
6083 check_insn(env, ctx, ISA_MIPS32R2);
6084 gen_helper_mtc0_hwrena(cpu_env, arg);
6085 rn = "HWREna";
6086 break;
6087 default:
6088 goto die;
6089 }
6090 break;
6091 case 8:
6092 /* ignored */
6093 rn = "BadVAddr";
6094 break;
6095 case 9:
6096 switch (sel) {
6097 case 0:
6098 gen_helper_mtc0_count(cpu_env, arg);
6099 rn = "Count";
6100 break;
6101 /* 6,7 are implementation dependent */
6102 default:
6103 goto die;
6104 }
6105 /* Stop translation as we may have switched the execution mode */
6106 ctx->bstate = BS_STOP;
6107 break;
6108 case 10:
6109 switch (sel) {
6110 case 0:
6111 gen_helper_mtc0_entryhi(cpu_env, arg);
6112 rn = "EntryHi";
6113 break;
6114 default:
6115 goto die;
6116 }
6117 break;
6118 case 11:
6119 switch (sel) {
6120 case 0:
6121 gen_helper_mtc0_compare(cpu_env, arg);
6122 rn = "Compare";
6123 break;
6124 /* 6,7 are implementation dependent */
6125 default:
6126 goto die;
6127 }
6128 /* Stop translation as we may have switched the execution mode */
6129 ctx->bstate = BS_STOP;
6130 break;
6131 case 12:
6132 switch (sel) {
6133 case 0:
6134 save_cpu_state(ctx, 1);
6135 gen_helper_mtc0_status(cpu_env, arg);
6136 /* BS_STOP isn't good enough here, hflags may have changed. */
6137 gen_save_pc(ctx->pc + 4);
6138 ctx->bstate = BS_EXCP;
6139 rn = "Status";
6140 break;
6141 case 1:
6142 check_insn(env, ctx, ISA_MIPS32R2);
6143 gen_helper_mtc0_intctl(cpu_env, arg);
6144 /* Stop translation as we may have switched the execution mode */
6145 ctx->bstate = BS_STOP;
6146 rn = "IntCtl";
6147 break;
6148 case 2:
6149 check_insn(env, ctx, ISA_MIPS32R2);
6150 gen_helper_mtc0_srsctl(cpu_env, arg);
6151 /* Stop translation as we may have switched the execution mode */
6152 ctx->bstate = BS_STOP;
6153 rn = "SRSCtl";
6154 break;
6155 case 3:
6156 check_insn(env, ctx, ISA_MIPS32R2);
6157 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6158 /* Stop translation as we may have switched the execution mode */
6159 ctx->bstate = BS_STOP;
6160 rn = "SRSMap";
6161 break;
6162 default:
6163 goto die;
6164 }
6165 break;
6166 case 13:
6167 switch (sel) {
6168 case 0:
6169 save_cpu_state(ctx, 1);
6170 /* Mark as an IO operation because we may trigger a software
6171 interrupt. */
6172 if (use_icount) {
6173 gen_io_start();
6174 }
6175 gen_helper_mtc0_cause(cpu_env, arg);
6176 if (use_icount) {
6177 gen_io_end();
6178 }
6179 /* Stop translation as we may have triggered an intetrupt */
6180 ctx->bstate = BS_STOP;
6181 rn = "Cause";
6182 break;
6183 default:
6184 goto die;
6185 }
6186 break;
6187 case 14:
6188 switch (sel) {
6189 case 0:
6190 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6191 rn = "EPC";
6192 break;
6193 default:
6194 goto die;
6195 }
6196 break;
6197 case 15:
6198 switch (sel) {
6199 case 0:
6200 /* ignored */
6201 rn = "PRid";
6202 break;
6203 case 1:
6204 check_insn(env, ctx, ISA_MIPS32R2);
6205 gen_helper_mtc0_ebase(cpu_env, arg);
6206 rn = "EBase";
6207 break;
6208 default:
6209 goto die;
6210 }
6211 break;
6212 case 16:
6213 switch (sel) {
6214 case 0:
6215 gen_helper_mtc0_config0(cpu_env, arg);
6216 rn = "Config";
6217 /* Stop translation as we may have switched the execution mode */
6218 ctx->bstate = BS_STOP;
6219 break;
6220 case 1:
6221 /* ignored, read only */
6222 rn = "Config1";
6223 break;
6224 case 2:
6225 gen_helper_mtc0_config2(cpu_env, arg);
6226 rn = "Config2";
6227 /* Stop translation as we may have switched the execution mode */
6228 ctx->bstate = BS_STOP;
6229 break;
6230 case 3:
6231 /* ignored */
6232 rn = "Config3";
6233 break;
6234 /* 6,7 are implementation dependent */
6235 default:
6236 rn = "Invalid config selector";
6237 goto die;
6238 }
6239 break;
6240 case 17:
6241 switch (sel) {
6242 case 0:
6243 gen_helper_mtc0_lladdr(cpu_env, arg);
6244 rn = "LLAddr";
6245 break;
6246 default:
6247 goto die;
6248 }
6249 break;
6250 case 18:
6251 switch (sel) {
6252 case 0 ... 7:
6253 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6254 rn = "WatchLo";
6255 break;
6256 default:
6257 goto die;
6258 }
6259 break;
6260 case 19:
6261 switch (sel) {
6262 case 0 ... 7:
6263 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6264 rn = "WatchHi";
6265 break;
6266 default:
6267 goto die;
6268 }
6269 break;
6270 case 20:
6271 switch (sel) {
6272 case 0:
6273 check_insn(env, ctx, ISA_MIPS3);
6274 gen_helper_mtc0_xcontext(cpu_env, arg);
6275 rn = "XContext";
6276 break;
6277 default:
6278 goto die;
6279 }
6280 break;
6281 case 21:
6282 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6283 switch (sel) {
6284 case 0:
6285 gen_helper_mtc0_framemask(cpu_env, arg);
6286 rn = "Framemask";
6287 break;
6288 default:
6289 goto die;
6290 }
6291 break;
6292 case 22:
6293 /* ignored */
6294 rn = "Diagnostic"; /* implementation dependent */
6295 break;
6296 case 23:
6297 switch (sel) {
6298 case 0:
6299 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6300 /* BS_STOP isn't good enough here, hflags may have changed. */
6301 gen_save_pc(ctx->pc + 4);
6302 ctx->bstate = BS_EXCP;
6303 rn = "Debug";
6304 break;
6305 case 1:
6306 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6307 /* Stop translation as we may have switched the execution mode */
6308 ctx->bstate = BS_STOP;
6309 rn = "TraceControl";
6310 // break;
6311 case 2:
6312 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6313 /* Stop translation as we may have switched the execution mode */
6314 ctx->bstate = BS_STOP;
6315 rn = "TraceControl2";
6316 // break;
6317 case 3:
6318 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6319 /* Stop translation as we may have switched the execution mode */
6320 ctx->bstate = BS_STOP;
6321 rn = "UserTraceData";
6322 // break;
6323 case 4:
6324 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6325 /* Stop translation as we may have switched the execution mode */
6326 ctx->bstate = BS_STOP;
6327 rn = "TraceBPC";
6328 // break;
6329 default:
6330 goto die;
6331 }
6332 break;
6333 case 24:
6334 switch (sel) {
6335 case 0:
6336 /* EJTAG support */
6337 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6338 rn = "DEPC";
6339 break;
6340 default:
6341 goto die;
6342 }
6343 break;
6344 case 25:
6345 switch (sel) {
6346 case 0:
6347 gen_helper_mtc0_performance0(cpu_env, arg);
6348 rn = "Performance0";
6349 break;
6350 case 1:
6351 // gen_helper_mtc0_performance1(cpu_env, arg);
6352 rn = "Performance1";
6353 // break;
6354 case 2:
6355 // gen_helper_mtc0_performance2(cpu_env, arg);
6356 rn = "Performance2";
6357 // break;
6358 case 3:
6359 // gen_helper_mtc0_performance3(cpu_env, arg);
6360 rn = "Performance3";
6361 // break;
6362 case 4:
6363 // gen_helper_mtc0_performance4(cpu_env, arg);
6364 rn = "Performance4";
6365 // break;
6366 case 5:
6367 // gen_helper_mtc0_performance5(cpu_env, arg);
6368 rn = "Performance5";
6369 // break;
6370 case 6:
6371 // gen_helper_mtc0_performance6(cpu_env, arg);
6372 rn = "Performance6";
6373 // break;
6374 case 7:
6375 // gen_helper_mtc0_performance7(cpu_env, arg);
6376 rn = "Performance7";
6377 // break;
6378 default:
6379 goto die;
6380 }
6381 break;
6382 case 26:
6383 /* ignored */
6384 rn = "ECC";
6385 break;
6386 case 27:
6387 switch (sel) {
6388 case 0 ... 3:
6389 /* ignored */
6390 rn = "CacheErr";
6391 break;
6392 default:
6393 goto die;
6394 }
6395 break;
6396 case 28:
6397 switch (sel) {
6398 case 0:
6399 case 2:
6400 case 4:
6401 case 6:
6402 gen_helper_mtc0_taglo(cpu_env, arg);
6403 rn = "TagLo";
6404 break;
6405 case 1:
6406 case 3:
6407 case 5:
6408 case 7:
6409 gen_helper_mtc0_datalo(cpu_env, arg);
6410 rn = "DataLo";
6411 break;
6412 default:
6413 goto die;
6414 }
6415 break;
6416 case 29:
6417 switch (sel) {
6418 case 0:
6419 case 2:
6420 case 4:
6421 case 6:
6422 gen_helper_mtc0_taghi(cpu_env, arg);
6423 rn = "TagHi";
6424 break;
6425 case 1:
6426 case 3:
6427 case 5:
6428 case 7:
6429 gen_helper_mtc0_datahi(cpu_env, arg);
6430 rn = "DataHi";
6431 break;
6432 default:
6433 rn = "invalid sel";
6434 goto die;
6435 }
6436 break;
6437 case 30:
6438 switch (sel) {
6439 case 0:
6440 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6441 rn = "ErrorEPC";
6442 break;
6443 default:
6444 goto die;
6445 }
6446 break;
6447 case 31:
6448 switch (sel) {
6449 case 0:
6450 /* EJTAG support */
6451 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6452 rn = "DESAVE";
6453 break;
6454 default:
6455 goto die;
6456 }
6457 /* Stop translation as we may have switched the execution mode */
6458 ctx->bstate = BS_STOP;
6459 break;
6460 default:
6461 goto die;
6462 }
6463 (void)rn; /* avoid a compiler warning */
6464 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6465 /* For simplicity assume that all writes can cause interrupts. */
6466 if (use_icount) {
6467 gen_io_end();
6468 ctx->bstate = BS_STOP;
6469 }
6470 return;
6471
6472 die:
6473 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6474 generate_exception(ctx, EXCP_RI);
6475 }
6476 #endif /* TARGET_MIPS64 */
6477
6478 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6479 int u, int sel, int h)
6480 {
6481 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6482 TCGv t0 = tcg_temp_local_new();
6483
6484 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6485 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6486 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6487 tcg_gen_movi_tl(t0, -1);
6488 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6489 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6490 tcg_gen_movi_tl(t0, -1);
6491 else if (u == 0) {
6492 switch (rt) {
6493 case 1:
6494 switch (sel) {
6495 case 1:
6496 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6497 break;
6498 case 2:
6499 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6500 break;
6501 default:
6502 goto die;
6503 break;
6504 }
6505 break;
6506 case 2:
6507 switch (sel) {
6508 case 1:
6509 gen_helper_mftc0_tcstatus(t0, cpu_env);
6510 break;
6511 case 2:
6512 gen_helper_mftc0_tcbind(t0, cpu_env);
6513 break;
6514 case 3:
6515 gen_helper_mftc0_tcrestart(t0, cpu_env);
6516 break;
6517 case 4:
6518 gen_helper_mftc0_tchalt(t0, cpu_env);
6519 break;
6520 case 5:
6521 gen_helper_mftc0_tccontext(t0, cpu_env);
6522 break;
6523 case 6:
6524 gen_helper_mftc0_tcschedule(t0, cpu_env);
6525 break;
6526 case 7:
6527 gen_helper_mftc0_tcschefback(t0, cpu_env);
6528 break;
6529 default:
6530 gen_mfc0(env, ctx, t0, rt, sel);
6531 break;
6532 }
6533 break;
6534 case 10:
6535 switch (sel) {
6536 case 0:
6537 gen_helper_mftc0_entryhi(t0, cpu_env);
6538 break;
6539 default:
6540 gen_mfc0(env, ctx, t0, rt, sel);
6541 break;
6542 }
6543 case 12:
6544 switch (sel) {
6545 case 0:
6546 gen_helper_mftc0_status(t0, cpu_env);
6547 break;
6548 default:
6549 gen_mfc0(env, ctx, t0, rt, sel);
6550 break;
6551 }
6552 case 13:
6553 switch (sel) {
6554 case 0:
6555 gen_helper_mftc0_cause(t0, cpu_env);
6556 break;
6557 default:
6558 goto die;
6559 break;
6560 }
6561 break;
6562 case 14:
6563 switch (sel) {
6564 case 0:
6565 gen_helper_mftc0_epc(t0, cpu_env);
6566 break;
6567 default:
6568 goto die;
6569 break;
6570 }
6571 break;
6572 case 15:
6573 switch (sel) {
6574 case 1:
6575 gen_helper_mftc0_ebase(t0, cpu_env);
6576 break;
6577 default:
6578 goto die;
6579 break;
6580 }
6581 break;
6582 case 16:
6583 switch (sel) {
6584 case 0 ... 7:
6585 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6586 break;
6587 default:
6588 goto die;
6589 break;
6590 }
6591 break;
6592 case 23:
6593 switch (sel) {
6594 case 0:
6595 gen_helper_mftc0_debug(t0, cpu_env);
6596 break;
6597 default:
6598 gen_mfc0(env, ctx, t0, rt, sel);
6599 break;
6600 }
6601 break;
6602 default:
6603 gen_mfc0(env, ctx, t0, rt, sel);
6604 }
6605 } else switch (sel) {
6606 /* GPR registers. */
6607 case 0:
6608 gen_helper_1e0i(mftgpr, t0, rt);
6609 break;
6610 /* Auxiliary CPU registers */
6611 case 1:
6612 switch (rt) {
6613 case 0:
6614 gen_helper_1e0i(mftlo, t0, 0);
6615 break;
6616 case 1:
6617 gen_helper_1e0i(mfthi, t0, 0);
6618 break;
6619 case 2:
6620 gen_helper_1e0i(mftacx, t0, 0);
6621 break;
6622 case 4:
6623 gen_helper_1e0i(mftlo, t0, 1);
6624 break;
6625 case 5:
6626 gen_helper_1e0i(mfthi, t0, 1);
6627 break;
6628 case 6:
6629 gen_helper_1e0i(mftacx, t0, 1);
6630 break;
6631 case 8:
6632 gen_helper_1e0i(mftlo, t0, 2);
6633 break;
6634 case 9:
6635 gen_helper_1e0i(mfthi, t0, 2);
6636 break;
6637 case 10:
6638 gen_helper_1e0i(mftacx, t0, 2);
6639 break;
6640 case 12:
6641 gen_helper_1e0i(mftlo, t0, 3);
6642 break;
6643 case 13:
6644 gen_helper_1e0i(mfthi, t0, 3);
6645 break;
6646 case 14:
6647 gen_helper_1e0i(mftacx, t0, 3);
6648 break;
6649 case 16:
6650 gen_helper_mftdsp(t0, cpu_env);
6651 break;
6652 default:
6653 goto die;
6654 }
6655 break;
6656 /* Floating point (COP1). */
6657 case 2:
6658 /* XXX: For now we support only a single FPU context. */
6659 if (h == 0) {
6660 TCGv_i32 fp0 = tcg_temp_new_i32();
6661
6662 gen_load_fpr32(fp0, rt);
6663 tcg_gen_ext_i32_tl(t0, fp0);
6664 tcg_temp_free_i32(fp0);
6665 } else {
6666 TCGv_i32 fp0 = tcg_temp_new_i32();
6667
6668 gen_load_fpr32h(fp0, rt);
6669 tcg_gen_ext_i32_tl(t0, fp0);
6670 tcg_temp_free_i32(fp0);
6671 }
6672 break;
6673 case 3:
6674 /* XXX: For now we support only a single FPU context. */
6675 gen_helper_1e0i(cfc1, t0, rt);
6676 break;
6677 /* COP2: Not implemented. */
6678 case 4:
6679 case 5:
6680 /* fall through */
6681 default:
6682 goto die;
6683 }
6684 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6685 gen_store_gpr(t0, rd);
6686 tcg_temp_free(t0);
6687 return;
6688
6689 die:
6690 tcg_temp_free(t0);
6691 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6692 generate_exception(ctx, EXCP_RI);
6693 }
6694
6695 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6696 int u, int sel, int h)
6697 {
6698 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6699 TCGv t0 = tcg_temp_local_new();
6700
6701 gen_load_gpr(t0, rt);
6702 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6703 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6704 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6705 /* NOP */ ;
6706 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6707 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6708 /* NOP */ ;
6709 else if (u == 0) {
6710 switch (rd) {
6711 case 1:
6712 switch (sel) {
6713 case 1:
6714 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6715 break;
6716 case 2:
6717 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6718 break;
6719 default:
6720 goto die;
6721 break;
6722 }
6723 break;
6724 case 2:
6725 switch (sel) {
6726 case 1:
6727 gen_helper_mttc0_tcstatus(cpu_env, t0);
6728 break;
6729 case 2:
6730 gen_helper_mttc0_tcbind(cpu_env, t0);
6731 break;
6732 case 3:
6733 gen_helper_mttc0_tcrestart(cpu_env, t0);
6734 break;
6735 case 4:
6736 gen_helper_mttc0_tchalt(cpu_env, t0);
6737 break;
6738 case 5:
6739 gen_helper_mttc0_tccontext(cpu_env, t0);
6740 break;
6741 case 6:
6742 gen_helper_mttc0_tcschedule(cpu_env, t0);
6743 break;
6744 case 7:
6745 gen_helper_mttc0_tcschefback(cpu_env, t0);
6746 break;
6747 default:
6748 gen_mtc0(env, ctx, t0, rd, sel);
6749 break;
6750 }
6751 break;
6752 case 10:
6753 switch (sel) {
6754 case 0:
6755 gen_helper_mttc0_entryhi(cpu_env, t0);
6756 break;
6757 default:
6758 gen_mtc0(env, ctx, t0, rd, sel);
6759 break;
6760 }
6761 case 12:
6762 switch (sel) {
6763 case 0:
6764 gen_helper_mttc0_status(cpu_env, t0);
6765 break;
6766 default:
6767 gen_mtc0(env, ctx, t0, rd, sel);
6768 break;
6769 }
6770 case 13:
6771 switch (sel) {
6772 case 0:
6773 gen_helper_mttc0_cause(cpu_env, t0);
6774 break;
6775 default:
6776 goto die;
6777 break;
6778 }
6779 break;
6780 case 15:
6781 switch (sel) {
6782 case 1:
6783 gen_helper_mttc0_ebase(cpu_env, t0);
6784 break;
6785 default:
6786 goto die;
6787 break;
6788 }
6789 break;
6790 case 23:
6791 switch (sel) {
6792 case 0:
6793 gen_helper_mttc0_debug(cpu_env, t0);
6794 break;
6795 default:
6796 gen_mtc0(env, ctx, t0, rd, sel);
6797 break;
6798 }
6799 break;
6800 default:
6801 gen_mtc0(env, ctx, t0, rd, sel);
6802 }
6803 } else switch (sel) {
6804 /* GPR registers. */
6805 case 0:
6806 gen_helper_0e1i(mttgpr, t0, rd);
6807 break;
6808 /* Auxiliary CPU registers */
6809 case 1:
6810 switch (rd) {
6811 case 0:
6812 gen_helper_0e1i(mttlo, t0, 0);
6813 break;
6814 case 1:
6815 gen_helper_0e1i(mtthi, t0, 0);
6816 break;
6817 case 2:
6818 gen_helper_0e1i(mttacx, t0, 0);
6819 break;
6820 case 4:
6821 gen_helper_0e1i(mttlo, t0, 1);
6822 break;
6823 case 5:
6824 gen_helper_0e1i(mtthi, t0, 1);
6825 break;
6826 case 6:
6827 gen_helper_0e1i(mttacx, t0, 1);
6828 break;
6829 case 8:
6830 gen_helper_0e1i(mttlo, t0, 2);
6831 break;
6832 case 9:
6833 gen_helper_0e1i(mtthi, t0, 2);
6834 break;
6835 case 10:
6836 gen_helper_0e1i(mttacx, t0, 2);
6837 break;
6838 case 12:
6839 gen_helper_0e1i(mttlo, t0, 3);
6840 break;
6841 case 13:
6842 gen_helper_0e1i(mtthi, t0, 3);
6843 break;
6844 case 14:
6845 gen_helper_0e1i(mttacx, t0, 3);
6846 break;
6847 case 16:
6848 gen_helper_mttdsp(cpu_env, t0);
6849 break;
6850 default:
6851 goto die;
6852 }
6853 break;
6854 /* Floating point (COP1). */
6855 case 2:
6856 /* XXX: For now we support only a single FPU context. */
6857 if (h == 0) {
6858 TCGv_i32 fp0 = tcg_temp_new_i32();
6859
6860 tcg_gen_trunc_tl_i32(fp0, t0);
6861 gen_store_fpr32(fp0, rd);
6862 tcg_temp_free_i32(fp0);
6863 } else {
6864 TCGv_i32 fp0 = tcg_temp_new_i32();
6865
6866 tcg_gen_trunc_tl_i32(fp0, t0);
6867 gen_store_fpr32h(fp0, rd);
6868 tcg_temp_free_i32(fp0);
6869 }
6870 break;
6871 case 3:
6872 /* XXX: For now we support only a single FPU context. */
6873 gen_helper_0e1i(ctc1, t0, rd);
6874 break;
6875 /* COP2: Not implemented. */
6876 case 4:
6877 case 5:
6878 /* fall through */
6879 default:
6880 goto die;
6881 }
6882 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6883 tcg_temp_free(t0);
6884 return;
6885
6886 die:
6887 tcg_temp_free(t0);
6888 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6889 generate_exception(ctx, EXCP_RI);
6890 }
6891
6892 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6893 {
6894 const char *opn = "ldst";
6895
6896 check_cp0_enabled(ctx);
6897 switch (opc) {
6898 case OPC_MFC0:
6899 if (rt == 0) {
6900 /* Treat as NOP. */
6901 return;
6902 }
6903 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6904 opn = "mfc0";
6905 break;
6906 case OPC_MTC0:
6907 {
6908 TCGv t0 = tcg_temp_new();
6909
6910 gen_load_gpr(t0, rt);
6911 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6912 tcg_temp_free(t0);
6913 }
6914 opn = "mtc0";
6915 break;
6916 #if defined(TARGET_MIPS64)
6917 case OPC_DMFC0:
6918 check_insn(env, ctx, ISA_MIPS3);
6919 if (rt == 0) {
6920 /* Treat as NOP. */
6921 return;
6922 }
6923 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6924 opn = "dmfc0";
6925 break;
6926 case OPC_DMTC0:
6927 check_insn(env, ctx, ISA_MIPS3);
6928 {
6929 TCGv t0 = tcg_temp_new();
6930
6931 gen_load_gpr(t0, rt);
6932 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6933 tcg_temp_free(t0);
6934 }
6935 opn = "dmtc0";
6936 break;
6937 #endif
6938 case OPC_MFTR:
6939 check_insn(env, ctx, ASE_MT);
6940 if (rd == 0) {
6941 /* Treat as NOP. */
6942 return;
6943 }
6944 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6945 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6946 opn = "mftr";
6947 break;
6948 case OPC_MTTR:
6949 check_insn(env, ctx, ASE_MT);
6950 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6951 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6952 opn = "mttr";
6953 break;
6954 case OPC_TLBWI:
6955 opn = "tlbwi";
6956 if (!env->tlb->helper_tlbwi)
6957 goto die;
6958 gen_helper_tlbwi(cpu_env);
6959 break;
6960 case OPC_TLBWR:
6961 opn = "tlbwr";
6962 if (!env->tlb->helper_tlbwr)
6963 goto die;
6964 gen_helper_tlbwr(cpu_env);
6965 break;
6966 case OPC_TLBP:
6967 opn = "tlbp";
6968 if (!env->tlb->helper_tlbp)
6969 goto die;
6970 gen_helper_tlbp(cpu_env);
6971 break;
6972 case OPC_TLBR:
6973 opn = "tlbr";
6974 if (!env->tlb->helper_tlbr)
6975 goto die;
6976 gen_helper_tlbr(cpu_env);
6977 break;
6978 case OPC_ERET:
6979 opn = "eret";
6980 check_insn(env, ctx, ISA_MIPS2);
6981 gen_helper_eret(cpu_env);
6982 ctx->bstate = BS_EXCP;
6983 break;
6984 case OPC_DERET:
6985 opn = "deret";
6986 check_insn(env, ctx, ISA_MIPS32);
6987 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6988 MIPS_INVAL(opn);
6989 generate_exception(ctx, EXCP_RI);
6990 } else {
6991 gen_helper_deret(cpu_env);
6992 ctx->bstate = BS_EXCP;
6993 }
6994 break;
6995 case OPC_WAIT:
6996 opn = "wait";
6997 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6998 /* If we get an exception, we want to restart at next instruction */
6999 ctx->pc += 4;
7000 save_cpu_state(ctx, 1);
7001 ctx->pc -= 4;
7002 gen_helper_wait(cpu_env);
7003 ctx->bstate = BS_EXCP;
7004 break;
7005 default:
7006 die:
7007 MIPS_INVAL(opn);
7008 generate_exception(ctx, EXCP_RI);
7009 return;
7010 }
7011 (void)opn; /* avoid a compiler warning */
7012 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7013 }
7014 #endif /* !CONFIG_USER_ONLY */
7015
7016 /* CP1 Branches (before delay slot) */
7017 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
7018 int32_t cc, int32_t offset)
7019 {
7020 target_ulong btarget;
7021 const char *opn = "cp1 cond branch";
7022 TCGv_i32 t0 = tcg_temp_new_i32();
7023
7024 if (cc != 0)
7025 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7026
7027 btarget = ctx->pc + 4 + offset;
7028
7029 switch (op) {
7030 case OPC_BC1F:
7031 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7032 tcg_gen_not_i32(t0, t0);
7033 tcg_gen_andi_i32(t0, t0, 1);
7034 tcg_gen_extu_i32_tl(bcond, t0);
7035 opn = "bc1f";
7036 goto not_likely;
7037 case OPC_BC1FL:
7038 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7039 tcg_gen_not_i32(t0, t0);
7040 tcg_gen_andi_i32(t0, t0, 1);
7041 tcg_gen_extu_i32_tl(bcond, t0);
7042 opn = "bc1fl";
7043 goto likely;
7044 case OPC_BC1T:
7045 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7046 tcg_gen_andi_i32(t0, t0, 1);
7047 tcg_gen_extu_i32_tl(bcond, t0);
7048 opn = "bc1t";
7049 goto not_likely;
7050 case OPC_BC1TL:
7051 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7052 tcg_gen_andi_i32(t0, t0, 1);
7053 tcg_gen_extu_i32_tl(bcond, t0);
7054 opn = "bc1tl";
7055 likely:
7056 ctx->hflags |= MIPS_HFLAG_BL;
7057 break;
7058 case OPC_BC1FANY2:
7059 {
7060 TCGv_i32 t1 = tcg_temp_new_i32();
7061 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7062 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7063 tcg_gen_nand_i32(t0, t0, t1);
7064 tcg_temp_free_i32(t1);
7065 tcg_gen_andi_i32(t0, t0, 1);
7066 tcg_gen_extu_i32_tl(bcond, t0);
7067 }
7068 opn = "bc1any2f";
7069 goto not_likely;
7070 case OPC_BC1TANY2:
7071 {
7072 TCGv_i32 t1 = tcg_temp_new_i32();
7073 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7074 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7075 tcg_gen_or_i32(t0, t0, t1);
7076 tcg_temp_free_i32(t1);
7077 tcg_gen_andi_i32(t0, t0, 1);
7078 tcg_gen_extu_i32_tl(bcond, t0);
7079 }
7080 opn = "bc1any2t";
7081 goto not_likely;
7082 case OPC_BC1FANY4:
7083 {
7084 TCGv_i32 t1 = tcg_temp_new_i32();
7085 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7086 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7087 tcg_gen_and_i32(t0, t0, t1);
7088 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7089 tcg_gen_and_i32(t0, t0, t1);
7090 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7091 tcg_gen_nand_i32(t0, t0, t1);
7092 tcg_temp_free_i32(t1);
7093 tcg_gen_andi_i32(t0, t0, 1);
7094 tcg_gen_extu_i32_tl(bcond, t0);
7095 }
7096 opn = "bc1any4f";
7097 goto not_likely;
7098 case OPC_BC1TANY4:
7099 {
7100 TCGv_i32 t1 = tcg_temp_new_i32();
7101 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7102 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7103 tcg_gen_or_i32(t0, t0, t1);
7104 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7105 tcg_gen_or_i32(t0, t0, t1);
7106 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7107 tcg_gen_or_i32(t0, t0, t1);
7108 tcg_temp_free_i32(t1);
7109 tcg_gen_andi_i32(t0, t0, 1);
7110 tcg_gen_extu_i32_tl(bcond, t0);
7111 }
7112 opn = "bc1any4t";
7113 not_likely:
7114 ctx->hflags |= MIPS_HFLAG_BC;
7115 break;
7116 default:
7117 MIPS_INVAL(opn);
7118 generate_exception (ctx, EXCP_RI);
7119 goto out;
7120 }
7121 (void)opn; /* avoid a compiler warning */
7122 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7123 ctx->hflags, btarget);
7124 ctx->btarget = btarget;
7125
7126 out:
7127 tcg_temp_free_i32(t0);
7128 }
7129
7130 /* Coprocessor 1 (FPU) */
7131
7132 #define FOP(func, fmt) (((fmt) << 21) | (func))
7133
7134 enum fopcode {
7135 OPC_ADD_S = FOP(0, FMT_S),
7136 OPC_SUB_S = FOP(1, FMT_S),
7137 OPC_MUL_S = FOP(2, FMT_S),
7138 OPC_DIV_S = FOP(3, FMT_S),
7139 OPC_SQRT_S = FOP(4, FMT_S),
7140 OPC_ABS_S = FOP(5, FMT_S),
7141 OPC_MOV_S = FOP(6, FMT_S),
7142 OPC_NEG_S = FOP(7, FMT_S),
7143 OPC_ROUND_L_S = FOP(8, FMT_S),
7144 OPC_TRUNC_L_S = FOP(9, FMT_S),
7145 OPC_CEIL_L_S = FOP(10, FMT_S),
7146 OPC_FLOOR_L_S = FOP(11, FMT_S),
7147 OPC_ROUND_W_S = FOP(12, FMT_S),
7148 OPC_TRUNC_W_S = FOP(13, FMT_S),
7149 OPC_CEIL_W_S = FOP(14, FMT_S),
7150 OPC_FLOOR_W_S = FOP(15, FMT_S),
7151 OPC_MOVCF_S = FOP(17, FMT_S),
7152 OPC_MOVZ_S = FOP(18, FMT_S),
7153 OPC_MOVN_S = FOP(19, FMT_S),
7154 OPC_RECIP_S = FOP(21, FMT_S),
7155 OPC_RSQRT_S = FOP(22, FMT_S),
7156 OPC_RECIP2_S = FOP(28, FMT_S),
7157 OPC_RECIP1_S = FOP(29, FMT_S),
7158 OPC_RSQRT1_S = FOP(30, FMT_S),
7159 OPC_RSQRT2_S = FOP(31, FMT_S),
7160 OPC_CVT_D_S = FOP(33, FMT_S),
7161 OPC_CVT_W_S = FOP(36, FMT_S),
7162 OPC_CVT_L_S = FOP(37, FMT_S),
7163 OPC_CVT_PS_S = FOP(38, FMT_S),
7164 OPC_CMP_F_S = FOP (48, FMT_S),
7165 OPC_CMP_UN_S = FOP (49, FMT_S),
7166 OPC_CMP_EQ_S = FOP (50, FMT_S),
7167 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7168 OPC_CMP_OLT_S = FOP (52, FMT_S),
7169 OPC_CMP_ULT_S = FOP (53, FMT_S),
7170 OPC_CMP_OLE_S = FOP (54, FMT_S),
7171 OPC_CMP_ULE_S = FOP (55, FMT_S),
7172 OPC_CMP_SF_S = FOP (56, FMT_S),
7173 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7174 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7175 OPC_CMP_NGL_S = FOP (59, FMT_S),
7176 OPC_CMP_LT_S = FOP (60, FMT_S),
7177 OPC_CMP_NGE_S = FOP (61, FMT_S),
7178 OPC_CMP_LE_S = FOP (62, FMT_S),
7179 OPC_CMP_NGT_S = FOP (63, FMT_S),
7180
7181 OPC_ADD_D = FOP(0, FMT_D),
7182 OPC_SUB_D = FOP(1, FMT_D),
7183 OPC_MUL_D = FOP(2, FMT_D),
7184 OPC_DIV_D = FOP(3, FMT_D),
7185 OPC_SQRT_D = FOP(4, FMT_D),
7186 OPC_ABS_D = FOP(5, FMT_D),
7187 OPC_MOV_D = FOP(6, FMT_D),
7188 OPC_NEG_D = FOP(7, FMT_D),
7189 OPC_ROUND_L_D = FOP(8, FMT_D),
7190 OPC_TRUNC_L_D = FOP(9, FMT_D),
7191 OPC_CEIL_L_D = FOP(10, FMT_D),
7192 OPC_FLOOR_L_D = FOP(11, FMT_D),
7193 OPC_ROUND_W_D = FOP(12, FMT_D),
7194 OPC_TRUNC_W_D = FOP(13, FMT_D),
7195 OPC_CEIL_W_D = FOP(14, FMT_D),
7196 OPC_FLOOR_W_D = FOP(15, FMT_D),
7197 OPC_MOVCF_D = FOP(17, FMT_D),
7198 OPC_MOVZ_D = FOP(18, FMT_D),
7199 OPC_MOVN_D = FOP(19, FMT_D),
7200 OPC_RECIP_D = FOP(21, FMT_D),
7201 OPC_RSQRT_D = FOP(22, FMT_D),
7202 OPC_RECIP2_D = FOP(28, FMT_D),
7203 OPC_RECIP1_D = FOP(29, FMT_D),
7204 OPC_RSQRT1_D = FOP(30, FMT_D),
7205 OPC_RSQRT2_D = FOP(31, FMT_D),
7206 OPC_CVT_S_D = FOP(32, FMT_D),
7207 OPC_CVT_W_D = FOP(36, FMT_D),
7208 OPC_CVT_L_D = FOP(37, FMT_D),
7209 OPC_CMP_F_D = FOP (48, FMT_D),
7210 OPC_CMP_UN_D = FOP (49, FMT_D),
7211 OPC_CMP_EQ_D = FOP (50, FMT_D),
7212 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7213 OPC_CMP_OLT_D = FOP (52, FMT_D),
7214 OPC_CMP_ULT_D = FOP (53, FMT_D),
7215 OPC_CMP_OLE_D = FOP (54, FMT_D),
7216 OPC_CMP_ULE_D = FOP (55, FMT_D),
7217 OPC_CMP_SF_D = FOP (56, FMT_D),
7218 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7219 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7220 OPC_CMP_NGL_D = FOP (59, FMT_D),
7221 OPC_CMP_LT_D = FOP (60, FMT_D),
7222 OPC_CMP_NGE_D = FOP (61, FMT_D),
7223 OPC_CMP_LE_D = FOP (62, FMT_D),
7224 OPC_CMP_NGT_D = FOP (63, FMT_D),
7225
7226 OPC_CVT_S_W = FOP(32, FMT_W),
7227 OPC_CVT_D_W = FOP(33, FMT_W),
7228 OPC_CVT_S_L = FOP(32, FMT_L),
7229 OPC_CVT_D_L = FOP(33, FMT_L),
7230 OPC_CVT_PS_PW = FOP(38, FMT_W),
7231
7232 OPC_ADD_PS = FOP(0, FMT_PS),
7233 OPC_SUB_PS = FOP(1, FMT_PS),
7234 OPC_MUL_PS = FOP(2, FMT_PS),
7235 OPC_DIV_PS = FOP(3, FMT_PS),
7236 OPC_ABS_PS = FOP(5, FMT_PS),
7237 OPC_MOV_PS = FOP(6, FMT_PS),
7238 OPC_NEG_PS = FOP(7, FMT_PS),
7239 OPC_MOVCF_PS = FOP(17, FMT_PS),
7240 OPC_MOVZ_PS = FOP(18, FMT_PS),
7241 OPC_MOVN_PS = FOP(19, FMT_PS),
7242 OPC_ADDR_PS = FOP(24, FMT_PS),
7243 OPC_MULR_PS = FOP(26, FMT_PS),
7244 OPC_RECIP2_PS = FOP(28, FMT_PS),
7245 OPC_RECIP1_PS = FOP(29, FMT_PS),
7246 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7247 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7248
7249 OPC_CVT_S_PU = FOP(32, FMT_PS),
7250 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7251 OPC_CVT_S_PL = FOP(40, FMT_PS),
7252 OPC_PLL_PS = FOP(44, FMT_PS),
7253 OPC_PLU_PS = FOP(45, FMT_PS),
7254 OPC_PUL_PS = FOP(46, FMT_PS),
7255 OPC_PUU_PS = FOP(47, FMT_PS),
7256 OPC_CMP_F_PS = FOP (48, FMT_PS),
7257 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7258 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7259 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7260 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7261 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7262 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7263 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7264 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7265 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7266 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7267 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7268 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7269 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7270 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7271 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7272 };
7273
7274 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7275 {
7276 const char *opn = "cp1 move";
7277 TCGv t0 = tcg_temp_new();
7278
7279 switch (opc) {
7280 case OPC_MFC1:
7281 {
7282 TCGv_i32 fp0 = tcg_temp_new_i32();
7283
7284 gen_load_fpr32(fp0, fs);
7285 tcg_gen_ext_i32_tl(t0, fp0);
7286 tcg_temp_free_i32(fp0);
7287 }
7288 gen_store_gpr(t0, rt);
7289 opn = "mfc1";
7290 break;
7291 case OPC_MTC1:
7292 gen_load_gpr(t0, rt);
7293 {
7294 TCGv_i32 fp0 = tcg_temp_new_i32();
7295
7296 tcg_gen_trunc_tl_i32(fp0, t0);
7297 gen_store_fpr32(fp0, fs);
7298 tcg_temp_free_i32(fp0);
7299 }
7300 opn = "mtc1";
7301 break;
7302 case OPC_CFC1:
7303 gen_helper_1e0i(cfc1, t0, fs);
7304 gen_store_gpr(t0, rt);
7305 opn = "cfc1";
7306 break;
7307 case OPC_CTC1:
7308 gen_load_gpr(t0, rt);
7309 gen_helper_0e1i(ctc1, t0, fs);
7310 opn = "ctc1";
7311 break;
7312 #if defined(TARGET_MIPS64)
7313 case OPC_DMFC1:
7314 gen_load_fpr64(ctx, t0, fs);
7315 gen_store_gpr(t0, rt);
7316 opn = "dmfc1";
7317 break;
7318 case OPC_DMTC1:
7319 gen_load_gpr(t0, rt);
7320 gen_store_fpr64(ctx, t0, fs);
7321 opn = "dmtc1";
7322 break;
7323 #endif
7324 case OPC_MFHC1:
7325 {
7326 TCGv_i32 fp0 = tcg_temp_new_i32();
7327
7328 gen_load_fpr32h(fp0, fs);
7329 tcg_gen_ext_i32_tl(t0, fp0);
7330 tcg_temp_free_i32(fp0);
7331 }
7332 gen_store_gpr(t0, rt);
7333 opn = "mfhc1";
7334 break;
7335 case OPC_MTHC1:
7336 gen_load_gpr(t0, rt);
7337 {
7338 TCGv_i32 fp0 = tcg_temp_new_i32();
7339
7340 tcg_gen_trunc_tl_i32(fp0, t0);
7341 gen_store_fpr32h(fp0, fs);
7342 tcg_temp_free_i32(fp0);
7343 }
7344 opn = "mthc1";
7345 break;
7346 default:
7347 MIPS_INVAL(opn);
7348 generate_exception (ctx, EXCP_RI);
7349 goto out;
7350 }
7351 (void)opn; /* avoid a compiler warning */
7352 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7353
7354 out:
7355 tcg_temp_free(t0);
7356 }
7357
7358 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7359 {
7360 int l1;
7361 TCGCond cond;
7362 TCGv_i32 t0;
7363
7364 if (rd == 0) {
7365 /* Treat as NOP. */
7366 return;
7367 }
7368
7369 if (tf)
7370 cond = TCG_COND_EQ;
7371 else
7372 cond = TCG_COND_NE;
7373
7374 l1 = gen_new_label();
7375 t0 = tcg_temp_new_i32();
7376 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7377 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7378 tcg_temp_free_i32(t0);
7379 if (rs == 0) {
7380 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7381 } else {
7382 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7383 }
7384 gen_set_label(l1);
7385 }
7386
7387 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7388 {
7389 int cond;
7390 TCGv_i32 t0 = tcg_temp_new_i32();
7391 int l1 = gen_new_label();
7392
7393 if (tf)
7394 cond = TCG_COND_EQ;
7395 else
7396 cond = TCG_COND_NE;
7397
7398 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7399 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7400 gen_load_fpr32(t0, fs);
7401 gen_store_fpr32(t0, fd);
7402 gen_set_label(l1);
7403 tcg_temp_free_i32(t0);
7404 }
7405
7406 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7407 {
7408 int cond;
7409 TCGv_i32 t0 = tcg_temp_new_i32();
7410 TCGv_i64 fp0;
7411 int l1 = gen_new_label();
7412
7413 if (tf)
7414 cond = TCG_COND_EQ;
7415 else
7416 cond = TCG_COND_NE;
7417
7418 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7419 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7420 tcg_temp_free_i32(t0);
7421 fp0 = tcg_temp_new_i64();
7422 gen_load_fpr64(ctx, fp0, fs);
7423 gen_store_fpr64(ctx, fp0, fd);
7424 tcg_temp_free_i64(fp0);
7425 gen_set_label(l1);
7426 }
7427
7428 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7429 {
7430 int cond;
7431 TCGv_i32 t0 = tcg_temp_new_i32();
7432 int l1 = gen_new_label();
7433 int l2 = gen_new_label();
7434
7435 if (tf)
7436 cond = TCG_COND_EQ;
7437 else
7438 cond = TCG_COND_NE;
7439
7440 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7441 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7442 gen_load_fpr32(t0, fs);
7443 gen_store_fpr32(t0, fd);
7444 gen_set_label(l1);
7445
7446 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7447 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7448 gen_load_fpr32h(t0, fs);
7449 gen_store_fpr32h(t0, fd);
7450 tcg_temp_free_i32(t0);
7451 gen_set_label(l2);
7452 }
7453
7454
7455 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7456 int ft, int fs, int fd, int cc)
7457 {
7458 const char *opn = "farith";
7459 const char *condnames[] = {
7460 "c.f",
7461 "c.un",
7462 "c.eq",
7463 "c.ueq",
7464 "c.olt",
7465 "c.ult",
7466 "c.ole",
7467 "c.ule",
7468 "c.sf",
7469 "c.ngle",
7470 "c.seq",
7471 "c.ngl",
7472 "c.lt",
7473 "c.nge",
7474 "c.le",
7475 "c.ngt",
7476 };
7477 const char *condnames_abs[] = {
7478 "cabs.f",
7479 "cabs.un",
7480 "cabs.eq",
7481 "cabs.ueq",
7482 "cabs.olt",
7483 "cabs.ult",
7484 "cabs.ole",
7485 "cabs.ule",
7486 "cabs.sf",
7487 "cabs.ngle",
7488 "cabs.seq",
7489 "cabs.ngl",
7490 "cabs.lt",
7491 "cabs.nge",
7492 "cabs.le",
7493 "cabs.ngt",
7494 };
7495 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7496 uint32_t func = ctx->opcode & 0x3f;
7497
7498 switch (op1) {
7499 case OPC_ADD_S:
7500 {
7501 TCGv_i32 fp0 = tcg_temp_new_i32();
7502 TCGv_i32 fp1 = tcg_temp_new_i32();
7503
7504 gen_load_fpr32(fp0, fs);
7505 gen_load_fpr32(fp1, ft);
7506 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7507 tcg_temp_free_i32(fp1);
7508 gen_store_fpr32(fp0, fd);
7509 tcg_temp_free_i32(fp0);
7510 }
7511 opn = "add.s";
7512 optype = BINOP;
7513 break;
7514 case OPC_SUB_S:
7515 {
7516 TCGv_i32 fp0 = tcg_temp_new_i32();
7517 TCGv_i32 fp1 = tcg_temp_new_i32();
7518
7519 gen_load_fpr32(fp0, fs);
7520 gen_load_fpr32(fp1, ft);
7521 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7522 tcg_temp_free_i32(fp1);
7523 gen_store_fpr32(fp0, fd);
7524 tcg_temp_free_i32(fp0);
7525 }
7526 opn = "sub.s";
7527 optype = BINOP;
7528 break;
7529 case OPC_MUL_S:
7530 {
7531 TCGv_i32 fp0 = tcg_temp_new_i32();
7532 TCGv_i32 fp1 = tcg_temp_new_i32();
7533
7534 gen_load_fpr32(fp0, fs);
7535 gen_load_fpr32(fp1, ft);
7536 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7537 tcg_temp_free_i32(fp1);
7538 gen_store_fpr32(fp0, fd);
7539 tcg_temp_free_i32(fp0);
7540 }
7541 opn = "mul.s";
7542 optype = BINOP;
7543 break;
7544 case OPC_DIV_S:
7545 {
7546 TCGv_i32 fp0 = tcg_temp_new_i32();
7547 TCGv_i32 fp1 = tcg_temp_new_i32();
7548
7549 gen_load_fpr32(fp0, fs);
7550 gen_load_fpr32(fp1, ft);
7551 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7552 tcg_temp_free_i32(fp1);
7553 gen_store_fpr32(fp0, fd);
7554 tcg_temp_free_i32(fp0);
7555 }
7556 opn = "div.s";
7557 optype = BINOP;
7558 break;
7559 case OPC_SQRT_S:
7560 {
7561 TCGv_i32 fp0 = tcg_temp_new_i32();
7562
7563 gen_load_fpr32(fp0, fs);
7564 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7565 gen_store_fpr32(fp0, fd);
7566 tcg_temp_free_i32(fp0);
7567 }
7568 opn = "sqrt.s";
7569 break;
7570 case OPC_ABS_S:
7571 {
7572 TCGv_i32 fp0 = tcg_temp_new_i32();
7573
7574 gen_load_fpr32(fp0, fs);
7575 gen_helper_float_abs_s(fp0, fp0);
7576 gen_store_fpr32(fp0, fd);
7577 tcg_temp_free_i32(fp0);
7578 }
7579 opn = "abs.s";
7580 break;
7581 case OPC_MOV_S:
7582 {
7583 TCGv_i32 fp0 = tcg_temp_new_i32();
7584
7585 gen_load_fpr32(fp0, fs);
7586 gen_store_fpr32(fp0, fd);
7587 tcg_temp_free_i32(fp0);
7588 }
7589 opn = "mov.s";
7590 break;
7591 case OPC_NEG_S:
7592 {
7593 TCGv_i32 fp0 = tcg_temp_new_i32();
7594
7595 gen_load_fpr32(fp0, fs);
7596 gen_helper_float_chs_s(fp0, fp0);
7597 gen_store_fpr32(fp0, fd);
7598 tcg_temp_free_i32(fp0);
7599 }
7600 opn = "neg.s";
7601 break;
7602 case OPC_ROUND_L_S:
7603 check_cp1_64bitmode(ctx);
7604 {
7605 TCGv_i32 fp32 = tcg_temp_new_i32();
7606 TCGv_i64 fp64 = tcg_temp_new_i64();
7607
7608 gen_load_fpr32(fp32, fs);
7609 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7610 tcg_temp_free_i32(fp32);
7611 gen_store_fpr64(ctx, fp64, fd);
7612 tcg_temp_free_i64(fp64);
7613 }
7614 opn = "round.l.s";
7615 break;
7616 case OPC_TRUNC_L_S:
7617 check_cp1_64bitmode(ctx);
7618 {
7619 TCGv_i32 fp32 = tcg_temp_new_i32();
7620 TCGv_i64 fp64 = tcg_temp_new_i64();
7621
7622 gen_load_fpr32(fp32, fs);
7623 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7624 tcg_temp_free_i32(fp32);
7625 gen_store_fpr64(ctx, fp64, fd);
7626 tcg_temp_free_i64(fp64);
7627 }
7628 opn = "trunc.l.s";
7629 break;
7630 case OPC_CEIL_L_S:
7631 check_cp1_64bitmode(ctx);
7632 {
7633 TCGv_i32 fp32 = tcg_temp_new_i32();
7634 TCGv_i64 fp64 = tcg_temp_new_i64();
7635
7636 gen_load_fpr32(fp32, fs);
7637 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7638 tcg_temp_free_i32(fp32);
7639 gen_store_fpr64(ctx, fp64, fd);
7640 tcg_temp_free_i64(fp64);
7641 }
7642 opn = "ceil.l.s";
7643 break;
7644 case OPC_FLOOR_L_S:
7645 check_cp1_64bitmode(ctx);
7646 {
7647 TCGv_i32 fp32 = tcg_temp_new_i32();
7648 TCGv_i64 fp64 = tcg_temp_new_i64();
7649
7650 gen_load_fpr32(fp32, fs);
7651 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7652 tcg_temp_free_i32(fp32);
7653 gen_store_fpr64(ctx, fp64, fd);
7654 tcg_temp_free_i64(fp64);
7655 }
7656 opn = "floor.l.s";
7657 break;
7658 case OPC_ROUND_W_S:
7659 {
7660 TCGv_i32 fp0 = tcg_temp_new_i32();
7661
7662 gen_load_fpr32(fp0, fs);
7663 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7664 gen_store_fpr32(fp0, fd);
7665 tcg_temp_free_i32(fp0);
7666 }
7667 opn = "round.w.s";
7668 break;
7669 case OPC_TRUNC_W_S:
7670 {
7671 TCGv_i32 fp0 = tcg_temp_new_i32();
7672
7673 gen_load_fpr32(fp0, fs);
7674 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7675 gen_store_fpr32(fp0, fd);
7676 tcg_temp_free_i32(fp0);
7677 }
7678 opn = "trunc.w.s";
7679 break;
7680 case OPC_CEIL_W_S:
7681 {
7682 TCGv_i32 fp0 = tcg_temp_new_i32();
7683
7684 gen_load_fpr32(fp0, fs);
7685 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7686 gen_store_fpr32(fp0, fd);
7687 tcg_temp_free_i32(fp0);
7688 }
7689 opn = "ceil.w.s";
7690 break;
7691 case OPC_FLOOR_W_S:
7692 {
7693 TCGv_i32 fp0 = tcg_temp_new_i32();
7694
7695 gen_load_fpr32(fp0, fs);
7696 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7697 gen_store_fpr32(fp0, fd);
7698 tcg_temp_free_i32(fp0);
7699 }
7700 opn = "floor.w.s";
7701 break;
7702 case OPC_MOVCF_S:
7703 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7704 opn = "movcf.s";
7705 break;
7706 case OPC_MOVZ_S:
7707 {
7708 int l1 = gen_new_label();
7709 TCGv_i32 fp0;
7710
7711 if (ft != 0) {
7712 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7713 }
7714 fp0 = tcg_temp_new_i32();
7715 gen_load_fpr32(fp0, fs);
7716 gen_store_fpr32(fp0, fd);
7717 tcg_temp_free_i32(fp0);
7718 gen_set_label(l1);
7719 }
7720 opn = "movz.s";
7721 break;
7722 case OPC_MOVN_S:
7723 {
7724 int l1 = gen_new_label();
7725 TCGv_i32 fp0;
7726
7727 if (ft != 0) {
7728 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7729 fp0 = tcg_temp_new_i32();
7730 gen_load_fpr32(fp0, fs);
7731 gen_store_fpr32(fp0, fd);
7732 tcg_temp_free_i32(fp0);
7733 gen_set_label(l1);
7734 }
7735 }
7736 opn = "movn.s";
7737 break;
7738 case OPC_RECIP_S:
7739 check_cop1x(ctx);
7740 {
7741 TCGv_i32 fp0 = tcg_temp_new_i32();
7742
7743 gen_load_fpr32(fp0, fs);
7744 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7745 gen_store_fpr32(fp0, fd);
7746 tcg_temp_free_i32(fp0);
7747 }
7748 opn = "recip.s";
7749 break;
7750 case OPC_RSQRT_S:
7751 check_cop1x(ctx);
7752 {
7753 TCGv_i32 fp0 = tcg_temp_new_i32();
7754
7755 gen_load_fpr32(fp0, fs);
7756 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7757 gen_store_fpr32(fp0, fd);
7758 tcg_temp_free_i32(fp0);
7759 }
7760 opn = "rsqrt.s";
7761 break;
7762 case OPC_RECIP2_S:
7763 check_cp1_64bitmode(ctx);
7764 {
7765 TCGv_i32 fp0 = tcg_temp_new_i32();
7766 TCGv_i32 fp1 = tcg_temp_new_i32();
7767
7768 gen_load_fpr32(fp0, fs);
7769 gen_load_fpr32(fp1, ft);
7770 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7771 tcg_temp_free_i32(fp1);
7772 gen_store_fpr32(fp0, fd);
7773 tcg_temp_free_i32(fp0);
7774 }
7775 opn = "recip2.s";
7776 break;
7777 case OPC_RECIP1_S:
7778 check_cp1_64bitmode(ctx);
7779 {
7780 TCGv_i32 fp0 = tcg_temp_new_i32();
7781
7782 gen_load_fpr32(fp0, fs);
7783 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7784 gen_store_fpr32(fp0, fd);
7785 tcg_temp_free_i32(fp0);
7786 }
7787 opn = "recip1.s";
7788 break;
7789 case OPC_RSQRT1_S:
7790 check_cp1_64bitmode(ctx);
7791 {
7792 TCGv_i32 fp0 = tcg_temp_new_i32();
7793
7794 gen_load_fpr32(fp0, fs);
7795 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7796 gen_store_fpr32(fp0, fd);
7797 tcg_temp_free_i32(fp0);
7798 }
7799 opn = "rsqrt1.s";
7800 break;
7801 case OPC_RSQRT2_S:
7802 check_cp1_64bitmode(ctx);
7803 {
7804 TCGv_i32 fp0 = tcg_temp_new_i32();
7805 TCGv_i32 fp1 = tcg_temp_new_i32();
7806
7807 gen_load_fpr32(fp0, fs);
7808 gen_load_fpr32(fp1, ft);
7809 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7810 tcg_temp_free_i32(fp1);
7811 gen_store_fpr32(fp0, fd);
7812 tcg_temp_free_i32(fp0);
7813 }
7814 opn = "rsqrt2.s";
7815 break;
7816 case OPC_CVT_D_S:
7817 check_cp1_registers(ctx, fd);
7818 {
7819 TCGv_i32 fp32 = tcg_temp_new_i32();
7820 TCGv_i64 fp64 = tcg_temp_new_i64();
7821
7822 gen_load_fpr32(fp32, fs);
7823 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7824 tcg_temp_free_i32(fp32);
7825 gen_store_fpr64(ctx, fp64, fd);
7826 tcg_temp_free_i64(fp64);
7827 }
7828 opn = "cvt.d.s";
7829 break;
7830 case OPC_CVT_W_S:
7831 {
7832 TCGv_i32 fp0 = tcg_temp_new_i32();
7833
7834 gen_load_fpr32(fp0, fs);
7835 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7836 gen_store_fpr32(fp0, fd);
7837 tcg_temp_free_i32(fp0);
7838 }
7839 opn = "cvt.w.s";
7840 break;
7841 case OPC_CVT_L_S:
7842 check_cp1_64bitmode(ctx);
7843 {
7844 TCGv_i32 fp32 = tcg_temp_new_i32();
7845 TCGv_i64 fp64 = tcg_temp_new_i64();
7846
7847 gen_load_fpr32(fp32, fs);
7848 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7849 tcg_temp_free_i32(fp32);
7850 gen_store_fpr64(ctx, fp64, fd);
7851 tcg_temp_free_i64(fp64);
7852 }
7853 opn = "cvt.l.s";
7854 break;
7855 case OPC_CVT_PS_S:
7856 check_cp1_64bitmode(ctx);
7857 {
7858 TCGv_i64 fp64 = tcg_temp_new_i64();
7859 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7860 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7861
7862 gen_load_fpr32(fp32_0, fs);
7863 gen_load_fpr32(fp32_1, ft);
7864 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7865 tcg_temp_free_i32(fp32_1);
7866 tcg_temp_free_i32(fp32_0);
7867 gen_store_fpr64(ctx, fp64, fd);
7868 tcg_temp_free_i64(fp64);
7869 }
7870 opn = "cvt.ps.s";
7871 break;
7872 case OPC_CMP_F_S:
7873 case OPC_CMP_UN_S:
7874 case OPC_CMP_EQ_S:
7875 case OPC_CMP_UEQ_S:
7876 case OPC_CMP_OLT_S:
7877 case OPC_CMP_ULT_S:
7878 case OPC_CMP_OLE_S:
7879 case OPC_CMP_ULE_S:
7880 case OPC_CMP_SF_S:
7881 case OPC_CMP_NGLE_S:
7882 case OPC_CMP_SEQ_S:
7883 case OPC_CMP_NGL_S:
7884 case OPC_CMP_LT_S:
7885 case OPC_CMP_NGE_S:
7886 case OPC_CMP_LE_S:
7887 case OPC_CMP_NGT_S:
7888 if (ctx->opcode & (1 << 6)) {
7889 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7890 opn = condnames_abs[func-48];
7891 } else {
7892 gen_cmp_s(ctx, func-48, ft, fs, cc);
7893 opn = condnames[func-48];
7894 }
7895 break;
7896 case OPC_ADD_D:
7897 check_cp1_registers(ctx, fs | ft | fd);
7898 {
7899 TCGv_i64 fp0 = tcg_temp_new_i64();
7900 TCGv_i64 fp1 = tcg_temp_new_i64();
7901
7902 gen_load_fpr64(ctx, fp0, fs);
7903 gen_load_fpr64(ctx, fp1, ft);
7904 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7905 tcg_temp_free_i64(fp1);
7906 gen_store_fpr64(ctx, fp0, fd);
7907 tcg_temp_free_i64(fp0);
7908 }
7909 opn = "add.d";
7910 optype = BINOP;
7911 break;
7912 case OPC_SUB_D:
7913 check_cp1_registers(ctx, fs | ft | fd);
7914 {
7915 TCGv_i64 fp0 = tcg_temp_new_i64();
7916 TCGv_i64 fp1 = tcg_temp_new_i64();
7917
7918 gen_load_fpr64(ctx, fp0, fs);
7919 gen_load_fpr64(ctx, fp1, ft);
7920 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7921 tcg_temp_free_i64(fp1);
7922 gen_store_fpr64(ctx, fp0, fd);
7923 tcg_temp_free_i64(fp0);
7924 }
7925 opn = "sub.d";
7926 optype = BINOP;
7927 break;
7928 case OPC_MUL_D:
7929 check_cp1_registers(ctx, fs | ft | fd);
7930 {
7931 TCGv_i64 fp0 = tcg_temp_new_i64();
7932 TCGv_i64 fp1 = tcg_temp_new_i64();
7933
7934 gen_load_fpr64(ctx, fp0, fs);
7935 gen_load_fpr64(ctx, fp1, ft);
7936 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7937 tcg_temp_free_i64(fp1);
7938 gen_store_fpr64(ctx, fp0, fd);
7939 tcg_temp_free_i64(fp0);
7940 }
7941 opn = "mul.d";
7942 optype = BINOP;
7943 break;
7944 case OPC_DIV_D:
7945 check_cp1_registers(ctx, fs | ft | fd);
7946 {
7947 TCGv_i64 fp0 = tcg_temp_new_i64();
7948 TCGv_i64 fp1 = tcg_temp_new_i64();
7949
7950 gen_load_fpr64(ctx, fp0, fs);
7951 gen_load_fpr64(ctx, fp1, ft);
7952 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7953 tcg_temp_free_i64(fp1);
7954 gen_store_fpr64(ctx, fp0, fd);
7955 tcg_temp_free_i64(fp0);
7956 }
7957 opn = "div.d";
7958 optype = BINOP;
7959 break;
7960 case OPC_SQRT_D:
7961 check_cp1_registers(ctx, fs | fd);
7962 {
7963 TCGv_i64 fp0 = tcg_temp_new_i64();
7964
7965 gen_load_fpr64(ctx, fp0, fs);
7966 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7967 gen_store_fpr64(ctx, fp0, fd);
7968 tcg_temp_free_i64(fp0);
7969 }
7970 opn = "sqrt.d";
7971 break;
7972 case OPC_ABS_D:
7973 check_cp1_registers(ctx, fs | fd);
7974 {
7975 TCGv_i64 fp0 = tcg_temp_new_i64();
7976
7977 gen_load_fpr64(ctx, fp0, fs);
7978 gen_helper_float_abs_d(fp0, fp0);
7979 gen_store_fpr64(ctx, fp0, fd);
7980 tcg_temp_free_i64(fp0);
7981 }
7982 opn = "abs.d";
7983 break;
7984 case OPC_MOV_D:
7985 check_cp1_registers(ctx, fs | fd);
7986 {
7987 TCGv_i64 fp0 = tcg_temp_new_i64();
7988
7989 gen_load_fpr64(ctx, fp0, fs);
7990 gen_store_fpr64(ctx, fp0, fd);
7991 tcg_temp_free_i64(fp0);
7992 }
7993 opn = "mov.d";
7994 break;
7995 case OPC_NEG_D:
7996 check_cp1_registers(ctx, fs | fd);
7997 {
7998 TCGv_i64 fp0 = tcg_temp_new_i64();
7999
8000 gen_load_fpr64(ctx, fp0, fs);
8001 gen_helper_float_chs_d(fp0, fp0);
8002 gen_store_fpr64(ctx, fp0, fd);
8003 tcg_temp_free_i64(fp0);
8004 }
8005 opn = "neg.d";
8006 break;
8007 case OPC_ROUND_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_roundl_d(fp0, cpu_env, fp0);
8014 gen_store_fpr64(ctx, fp0, fd);
8015 tcg_temp_free_i64(fp0);
8016 }
8017 opn = "round.l.d";
8018 break;
8019 case OPC_TRUNC_L_D:
8020 check_cp1_64bitmode(ctx);
8021 {
8022 TCGv_i64 fp0 = tcg_temp_new_i64();
8023
8024 gen_load_fpr64(ctx, fp0, fs);
8025 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8026 gen_store_fpr64(ctx, fp0, fd);
8027 tcg_temp_free_i64(fp0);
8028 }
8029 opn = "trunc.l.d";
8030 break;
8031 case OPC_CEIL_L_D:
8032 check_cp1_64bitmode(ctx);
8033 {
8034 TCGv_i64 fp0 = tcg_temp_new_i64();
8035
8036 gen_load_fpr64(ctx, fp0, fs);
8037 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8038 gen_store_fpr64(ctx, fp0, fd);
8039 tcg_temp_free_i64(fp0);
8040 }
8041 opn = "ceil.l.d";
8042 break;
8043 case OPC_FLOOR_L_D:
8044 check_cp1_64bitmode(ctx);
8045 {
8046 TCGv_i64 fp0 = tcg_temp_new_i64();
8047
8048 gen_load_fpr64(ctx, fp0, fs);
8049 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8050 gen_store_fpr64(ctx, fp0, fd);
8051 tcg_temp_free_i64(fp0);
8052 }
8053 opn = "floor.l.d";
8054 break;
8055 case OPC_ROUND_W_D:
8056 check_cp1_registers(ctx, fs);
8057 {
8058 TCGv_i32 fp32 = tcg_temp_new_i32();
8059 TCGv_i64 fp64 = tcg_temp_new_i64();
8060
8061 gen_load_fpr64(ctx, fp64, fs);
8062 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8063 tcg_temp_free_i64(fp64);
8064 gen_store_fpr32(fp32, fd);
8065 tcg_temp_free_i32(fp32);
8066 }
8067 opn = "round.w.d";
8068 break;
8069 case OPC_TRUNC_W_D:
8070 check_cp1_registers(ctx, fs);
8071 {
8072 TCGv_i32 fp32 = tcg_temp_new_i32();
8073 TCGv_i64 fp64 = tcg_temp_new_i64();
8074
8075 gen_load_fpr64(ctx, fp64, fs);
8076 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8077 tcg_temp_free_i64(fp64);
8078 gen_store_fpr32(fp32, fd);
8079 tcg_temp_free_i32(fp32);
8080 }
8081 opn = "trunc.w.d";
8082 break;
8083 case OPC_CEIL_W_D:
8084 check_cp1_registers(ctx, fs);
8085 {
8086 TCGv_i32 fp32 = tcg_temp_new_i32();
8087 TCGv_i64 fp64 = tcg_temp_new_i64();
8088
8089 gen_load_fpr64(ctx, fp64, fs);
8090 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8091 tcg_temp_free_i64(fp64);
8092 gen_store_fpr32(fp32, fd);
8093 tcg_temp_free_i32(fp32);
8094 }
8095 opn = "ceil.w.d";
8096 break;
8097 case OPC_FLOOR_W_D:
8098 check_cp1_registers(ctx, fs);
8099 {
8100 TCGv_i32 fp32 = tcg_temp_new_i32();
8101 TCGv_i64 fp64 = tcg_temp_new_i64();
8102
8103 gen_load_fpr64(ctx, fp64, fs);
8104 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8105 tcg_temp_free_i64(fp64);
8106 gen_store_fpr32(fp32, fd);
8107 tcg_temp_free_i32(fp32);
8108 }
8109 opn = "floor.w.d";
8110 break;
8111 case OPC_MOVCF_D:
8112 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8113 opn = "movcf.d";
8114 break;
8115 case OPC_MOVZ_D:
8116 {
8117 int l1 = gen_new_label();
8118 TCGv_i64 fp0;
8119
8120 if (ft != 0) {
8121 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8122 }
8123 fp0 = tcg_temp_new_i64();
8124 gen_load_fpr64(ctx, fp0, fs);
8125 gen_store_fpr64(ctx, fp0, fd);
8126 tcg_temp_free_i64(fp0);
8127 gen_set_label(l1);
8128 }
8129 opn = "movz.d";
8130 break;
8131 case OPC_MOVN_D:
8132 {
8133 int l1 = gen_new_label();
8134 TCGv_i64 fp0;
8135
8136 if (ft != 0) {
8137 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8138 fp0 = tcg_temp_new_i64();
8139 gen_load_fpr64(ctx, fp0, fs);
8140 gen_store_fpr64(ctx, fp0, fd);
8141 tcg_temp_free_i64(fp0);
8142 gen_set_label(l1);
8143 }
8144 }
8145 opn = "movn.d";
8146 break;
8147 case OPC_RECIP_D:
8148 check_cp1_64bitmode(ctx);
8149 {
8150 TCGv_i64 fp0 = tcg_temp_new_i64();
8151
8152 gen_load_fpr64(ctx, fp0, fs);
8153 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8154 gen_store_fpr64(ctx, fp0, fd);
8155 tcg_temp_free_i64(fp0);
8156 }
8157 opn = "recip.d";
8158 break;
8159 case OPC_RSQRT_D:
8160 check_cp1_64bitmode(ctx);
8161 {
8162 TCGv_i64 fp0 = tcg_temp_new_i64();
8163
8164 gen_load_fpr64(ctx, fp0, fs);
8165 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8166 gen_store_fpr64(ctx, fp0, fd);
8167 tcg_temp_free_i64(fp0);
8168 }
8169 opn = "rsqrt.d";
8170 break;
8171 case OPC_RECIP2_D:
8172 check_cp1_64bitmode(ctx);
8173 {
8174 TCGv_i64 fp0 = tcg_temp_new_i64();
8175 TCGv_i64 fp1 = tcg_temp_new_i64();
8176
8177 gen_load_fpr64(ctx, fp0, fs);
8178 gen_load_fpr64(ctx, fp1, ft);
8179 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8180 tcg_temp_free_i64(fp1);
8181 gen_store_fpr64(ctx, fp0, fd);
8182 tcg_temp_free_i64(fp0);
8183 }
8184 opn = "recip2.d";
8185 break;
8186 case OPC_RECIP1_D:
8187 check_cp1_64bitmode(ctx);
8188 {
8189 TCGv_i64 fp0 = tcg_temp_new_i64();
8190
8191 gen_load_fpr64(ctx, fp0, fs);
8192 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8193 gen_store_fpr64(ctx, fp0, fd);
8194 tcg_temp_free_i64(fp0);
8195 }
8196 opn = "recip1.d";
8197 break;
8198 case OPC_RSQRT1_D:
8199 check_cp1_64bitmode(ctx);
8200 {
8201 TCGv_i64 fp0 = tcg_temp_new_i64();
8202
8203 gen_load_fpr64(ctx, fp0, fs);
8204 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8205 gen_store_fpr64(ctx, fp0, fd);
8206 tcg_temp_free_i64(fp0);
8207 }
8208 opn = "rsqrt1.d";
8209 break;
8210 case OPC_RSQRT2_D:
8211 check_cp1_64bitmode(ctx);
8212 {
8213 TCGv_i64 fp0 = tcg_temp_new_i64();
8214 TCGv_i64 fp1 = tcg_temp_new_i64();
8215
8216 gen_load_fpr64(ctx, fp0, fs);
8217 gen_load_fpr64(ctx, fp1, ft);
8218 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8219 tcg_temp_free_i64(fp1);
8220 gen_store_fpr64(ctx, fp0, fd);
8221 tcg_temp_free_i64(fp0);
8222 }
8223 opn = "rsqrt2.d";
8224 break;
8225 case OPC_CMP_F_D:
8226 case OPC_CMP_UN_D:
8227 case OPC_CMP_EQ_D:
8228 case OPC_CMP_UEQ_D:
8229 case OPC_CMP_OLT_D:
8230 case OPC_CMP_ULT_D:
8231 case OPC_CMP_OLE_D:
8232 case OPC_CMP_ULE_D:
8233 case OPC_CMP_SF_D:
8234 case OPC_CMP_NGLE_D:
8235 case OPC_CMP_SEQ_D:
8236 case OPC_CMP_NGL_D:
8237 case OPC_CMP_LT_D:
8238 case OPC_CMP_NGE_D:
8239 case OPC_CMP_LE_D:
8240 case OPC_CMP_NGT_D:
8241 if (ctx->opcode & (1 << 6)) {
8242 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8243 opn = condnames_abs[func-48];
8244 } else {
8245 gen_cmp_d(ctx, func-48, ft, fs, cc);
8246 opn = condnames[func-48];
8247 }
8248 break;
8249 case OPC_CVT_S_D:
8250 check_cp1_registers(ctx, fs);
8251 {
8252 TCGv_i32 fp32 = tcg_temp_new_i32();
8253 TCGv_i64 fp64 = tcg_temp_new_i64();
8254
8255 gen_load_fpr64(ctx, fp64, fs);
8256 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8257 tcg_temp_free_i64(fp64);
8258 gen_store_fpr32(fp32, fd);
8259 tcg_temp_free_i32(fp32);
8260 }
8261 opn = "cvt.s.d";
8262 break;
8263 case OPC_CVT_W_D:
8264 check_cp1_registers(ctx, fs);
8265 {
8266 TCGv_i32 fp32 = tcg_temp_new_i32();
8267 TCGv_i64 fp64 = tcg_temp_new_i64();
8268
8269 gen_load_fpr64(ctx, fp64, fs);
8270 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8271 tcg_temp_free_i64(fp64);
8272 gen_store_fpr32(fp32, fd);
8273 tcg_temp_free_i32(fp32);
8274 }
8275 opn = "cvt.w.d";
8276 break;
8277 case OPC_CVT_L_D:
8278 check_cp1_64bitmode(ctx);
8279 {
8280 TCGv_i64 fp0 = tcg_temp_new_i64();
8281
8282 gen_load_fpr64(ctx, fp0, fs);
8283 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8284 gen_store_fpr64(ctx, fp0, fd);
8285 tcg_temp_free_i64(fp0);
8286 }
8287 opn = "cvt.l.d";
8288 break;
8289 case OPC_CVT_S_W:
8290 {
8291 TCGv_i32 fp0 = tcg_temp_new_i32();
8292
8293 gen_load_fpr32(fp0, fs);
8294 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8295 gen_store_fpr32(fp0, fd);
8296 tcg_temp_free_i32(fp0);
8297 }
8298 opn = "cvt.s.w";
8299 break;
8300 case OPC_CVT_D_W:
8301 check_cp1_registers(ctx, fd);
8302 {
8303 TCGv_i32 fp32 = tcg_temp_new_i32();
8304 TCGv_i64 fp64 = tcg_temp_new_i64();
8305
8306 gen_load_fpr32(fp32, fs);
8307 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8308 tcg_temp_free_i32(fp32);
8309 gen_store_fpr64(ctx, fp64, fd);
8310 tcg_temp_free_i64(fp64);
8311 }
8312 opn = "cvt.d.w";
8313 break;
8314 case OPC_CVT_S_L:
8315 check_cp1_64bitmode(ctx);
8316 {
8317 TCGv_i32 fp32 = tcg_temp_new_i32();
8318 TCGv_i64 fp64 = tcg_temp_new_i64();
8319
8320 gen_load_fpr64(ctx, fp64, fs);
8321 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8322 tcg_temp_free_i64(fp64);
8323 gen_store_fpr32(fp32, fd);
8324 tcg_temp_free_i32(fp32);
8325 }
8326 opn = "cvt.s.l";
8327 break;
8328 case OPC_CVT_D_L:
8329 check_cp1_64bitmode(ctx);
8330 {
8331 TCGv_i64 fp0 = tcg_temp_new_i64();
8332
8333 gen_load_fpr64(ctx, fp0, fs);
8334 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8335 gen_store_fpr64(ctx, fp0, fd);
8336 tcg_temp_free_i64(fp0);
8337 }
8338 opn = "cvt.d.l";
8339 break;
8340 case OPC_CVT_PS_PW:
8341 check_cp1_64bitmode(ctx);
8342 {
8343 TCGv_i64 fp0 = tcg_temp_new_i64();
8344
8345 gen_load_fpr64(ctx, fp0, fs);
8346 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8347 gen_store_fpr64(ctx, fp0, fd);
8348 tcg_temp_free_i64(fp0);
8349 }
8350 opn = "cvt.ps.pw";
8351 break;
8352 case OPC_ADD_PS:
8353 check_cp1_64bitmode(ctx);
8354 {
8355 TCGv_i64 fp0 = tcg_temp_new_i64();
8356 TCGv_i64 fp1 = tcg_temp_new_i64();
8357
8358 gen_load_fpr64(ctx, fp0, fs);
8359 gen_load_fpr64(ctx, fp1, ft);
8360 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8361 tcg_temp_free_i64(fp1);
8362 gen_store_fpr64(ctx, fp0, fd);
8363 tcg_temp_free_i64(fp0);
8364 }
8365 opn = "add.ps";
8366 break;
8367 case OPC_SUB_PS:
8368 check_cp1_64bitmode(ctx);
8369 {
8370 TCGv_i64 fp0 = tcg_temp_new_i64();
8371 TCGv_i64 fp1 = tcg_temp_new_i64();
8372
8373 gen_load_fpr64(ctx, fp0, fs);
8374 gen_load_fpr64(ctx, fp1, ft);
8375 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8376 tcg_temp_free_i64(fp1);
8377 gen_store_fpr64(ctx, fp0, fd);
8378 tcg_temp_free_i64(fp0);
8379 }
8380 opn = "sub.ps";
8381 break;
8382 case OPC_MUL_PS:
8383 check_cp1_64bitmode(ctx);
8384 {
8385 TCGv_i64 fp0 = tcg_temp_new_i64();
8386 TCGv_i64 fp1 = tcg_temp_new_i64();
8387
8388 gen_load_fpr64(ctx, fp0, fs);
8389 gen_load_fpr64(ctx, fp1, ft);
8390 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8391 tcg_temp_free_i64(fp1);
8392 gen_store_fpr64(ctx, fp0, fd);
8393 tcg_temp_free_i64(fp0);
8394 }
8395 opn = "mul.ps";
8396 break;
8397 case OPC_ABS_PS:
8398 check_cp1_64bitmode(ctx);
8399 {
8400 TCGv_i64 fp0 = tcg_temp_new_i64();
8401
8402 gen_load_fpr64(ctx, fp0, fs);
8403 gen_helper_float_abs_ps(fp0, fp0);
8404 gen_store_fpr64(ctx, fp0, fd);
8405 tcg_temp_free_i64(fp0);
8406 }
8407 opn = "abs.ps";
8408 break;
8409 case OPC_MOV_PS:
8410 check_cp1_64bitmode(ctx);
8411 {
8412 TCGv_i64 fp0 = tcg_temp_new_i64();
8413
8414 gen_load_fpr64(ctx, fp0, fs);
8415 gen_store_fpr64(ctx, fp0, fd);
8416 tcg_temp_free_i64(fp0);
8417 }
8418 opn = "mov.ps";
8419 break;
8420 case OPC_NEG_PS:
8421 check_cp1_64bitmode(ctx);
8422 {
8423 TCGv_i64 fp0 = tcg_temp_new_i64();
8424
8425 gen_load_fpr64(ctx, fp0, fs);
8426 gen_helper_float_chs_ps(fp0, fp0);
8427 gen_store_fpr64(ctx, fp0, fd);
8428 tcg_temp_free_i64(fp0);
8429 }
8430 opn = "neg.ps";
8431 break;
8432 case OPC_MOVCF_PS:
8433 check_cp1_64bitmode(ctx);
8434 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8435 opn = "movcf.ps";
8436 break;
8437 case OPC_MOVZ_PS:
8438 check_cp1_64bitmode(ctx);
8439 {
8440 int l1 = gen_new_label();
8441 TCGv_i64 fp0;
8442
8443 if (ft != 0)
8444 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8445 fp0 = tcg_temp_new_i64();
8446 gen_load_fpr64(ctx, fp0, fs);
8447 gen_store_fpr64(ctx, fp0, fd);
8448 tcg_temp_free_i64(fp0);
8449 gen_set_label(l1);
8450 }
8451 opn = "movz.ps";
8452 break;
8453 case OPC_MOVN_PS:
8454 check_cp1_64bitmode(ctx);
8455 {
8456 int l1 = gen_new_label();
8457 TCGv_i64 fp0;
8458
8459 if (ft != 0) {
8460 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8461 fp0 = tcg_temp_new_i64();
8462 gen_load_fpr64(ctx, fp0, fs);
8463 gen_store_fpr64(ctx, fp0, fd);
8464 tcg_temp_free_i64(fp0);
8465 gen_set_label(l1);
8466 }
8467 }
8468 opn = "movn.ps";
8469 break;
8470 case OPC_ADDR_PS:
8471 check_cp1_64bitmode(ctx);
8472 {
8473 TCGv_i64 fp0 = tcg_temp_new_i64();
8474 TCGv_i64 fp1 = tcg_temp_new_i64();
8475
8476 gen_load_fpr64(ctx, fp0, ft);
8477 gen_load_fpr64(ctx, fp1, fs);
8478 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8479 tcg_temp_free_i64(fp1);
8480 gen_store_fpr64(ctx, fp0, fd);
8481 tcg_temp_free_i64(fp0);
8482 }
8483 opn = "addr.ps";
8484 break;
8485 case OPC_MULR_PS:
8486 check_cp1_64bitmode(ctx);
8487 {
8488 TCGv_i64 fp0 = tcg_temp_new_i64();
8489 TCGv_i64 fp1 = tcg_temp_new_i64();
8490
8491 gen_load_fpr64(ctx, fp0, ft);
8492 gen_load_fpr64(ctx, fp1, fs);
8493 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8494 tcg_temp_free_i64(fp1);
8495 gen_store_fpr64(ctx, fp0, fd);
8496 tcg_temp_free_i64(fp0);
8497 }
8498 opn = "mulr.ps";
8499 break;
8500 case OPC_RECIP2_PS:
8501 check_cp1_64bitmode(ctx);
8502 {
8503 TCGv_i64 fp0 = tcg_temp_new_i64();
8504 TCGv_i64 fp1 = tcg_temp_new_i64();
8505
8506 gen_load_fpr64(ctx, fp0, fs);
8507 gen_load_fpr64(ctx, fp1, ft);
8508 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8509 tcg_temp_free_i64(fp1);
8510 gen_store_fpr64(ctx, fp0, fd);
8511 tcg_temp_free_i64(fp0);
8512 }
8513 opn = "recip2.ps";
8514 break;
8515 case OPC_RECIP1_PS:
8516 check_cp1_64bitmode(ctx);
8517 {
8518 TCGv_i64 fp0 = tcg_temp_new_i64();
8519
8520 gen_load_fpr64(ctx, fp0, fs);
8521 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8522 gen_store_fpr64(ctx, fp0, fd);
8523 tcg_temp_free_i64(fp0);
8524 }
8525 opn = "recip1.ps";
8526 break;
8527 case OPC_RSQRT1_PS:
8528 check_cp1_64bitmode(ctx);
8529 {
8530 TCGv_i64 fp0 = tcg_temp_new_i64();
8531
8532 gen_load_fpr64(ctx, fp0, fs);
8533 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8534 gen_store_fpr64(ctx, fp0, fd);
8535 tcg_temp_free_i64(fp0);
8536 }
8537 opn = "rsqrt1.ps";
8538 break;
8539 case OPC_RSQRT2_PS:
8540 check_cp1_64bitmode(ctx);
8541 {
8542 TCGv_i64 fp0 = tcg_temp_new_i64();
8543 TCGv_i64 fp1 = tcg_temp_new_i64();
8544
8545 gen_load_fpr64(ctx, fp0, fs);
8546 gen_load_fpr64(ctx, fp1, ft);
8547 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8548 tcg_temp_free_i64(fp1);
8549 gen_store_fpr64(ctx, fp0, fd);
8550 tcg_temp_free_i64(fp0);
8551 }
8552 opn = "rsqrt2.ps";
8553 break;
8554 case OPC_CVT_S_PU:
8555 check_cp1_64bitmode(ctx);
8556 {
8557 TCGv_i32 fp0 = tcg_temp_new_i32();
8558
8559 gen_load_fpr32h(fp0, fs);
8560 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8561 gen_store_fpr32(fp0, fd);
8562 tcg_temp_free_i32(fp0);
8563 }
8564 opn = "cvt.s.pu";
8565 break;
8566 case OPC_CVT_PW_PS:
8567 check_cp1_64bitmode(ctx);
8568 {
8569 TCGv_i64 fp0 = tcg_temp_new_i64();
8570
8571 gen_load_fpr64(ctx, fp0, fs);
8572 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8573 gen_store_fpr64(ctx, fp0, fd);
8574 tcg_temp_free_i64(fp0);
8575 }
8576 opn = "cvt.pw.ps";
8577 break;
8578 case OPC_CVT_S_PL:
8579 check_cp1_64bitmode(ctx);
8580 {
8581 TCGv_i32 fp0 = tcg_temp_new_i32();
8582
8583 gen_load_fpr32(fp0, fs);
8584 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8585 gen_store_fpr32(fp0, fd);
8586 tcg_temp_free_i32(fp0);
8587 }
8588 opn = "cvt.s.pl";
8589 break;
8590 case OPC_PLL_PS:
8591 check_cp1_64bitmode(ctx);
8592 {
8593 TCGv_i32 fp0 = tcg_temp_new_i32();
8594 TCGv_i32 fp1 = tcg_temp_new_i32();
8595
8596 gen_load_fpr32(fp0, fs);
8597 gen_load_fpr32(fp1, ft);
8598 gen_store_fpr32h(fp0, fd);
8599 gen_store_fpr32(fp1, fd);
8600 tcg_temp_free_i32(fp0);
8601 tcg_temp_free_i32(fp1);
8602 }
8603 opn = "pll.ps";
8604 break;
8605 case OPC_PLU_PS:
8606 check_cp1_64bitmode(ctx);
8607 {
8608 TCGv_i32 fp0 = tcg_temp_new_i32();
8609 TCGv_i32 fp1 = tcg_temp_new_i32();
8610
8611 gen_load_fpr32(fp0, fs);
8612 gen_load_fpr32h(fp1, ft);
8613 gen_store_fpr32(fp1, fd);
8614 gen_store_fpr32h(fp0, fd);
8615 tcg_temp_free_i32(fp0);
8616 tcg_temp_free_i32(fp1);
8617 }
8618 opn = "plu.ps";
8619 break;
8620 case OPC_PUL_PS:
8621 check_cp1_64bitmode(ctx);
8622 {
8623 TCGv_i32 fp0 = tcg_temp_new_i32();
8624 TCGv_i32 fp1 = tcg_temp_new_i32();
8625
8626 gen_load_fpr32h(fp0, fs);
8627 gen_load_fpr32(fp1, ft);
8628 gen_store_fpr32(fp1, fd);
8629 gen_store_fpr32h(fp0, fd);
8630 tcg_temp_free_i32(fp0);
8631 tcg_temp_free_i32(fp1);
8632 }
8633 opn = "pul.ps";
8634 break;
8635 case OPC_PUU_PS:
8636 check_cp1_64bitmode(ctx);
8637 {
8638 TCGv_i32 fp0 = tcg_temp_new_i32();
8639 TCGv_i32 fp1 = tcg_temp_new_i32();
8640
8641 gen_load_fpr32h(fp0, fs);
8642 gen_load_fpr32h(fp1, ft);
8643 gen_store_fpr32(fp1, fd);
8644 gen_store_fpr32h(fp0, fd);
8645 tcg_temp_free_i32(fp0);
8646 tcg_temp_free_i32(fp1);
8647 }
8648 opn = "puu.ps";
8649 break;
8650 case OPC_CMP_F_PS:
8651 case OPC_CMP_UN_PS:
8652 case OPC_CMP_EQ_PS:
8653 case OPC_CMP_UEQ_PS:
8654 case OPC_CMP_OLT_PS:
8655 case OPC_CMP_ULT_PS:
8656 case OPC_CMP_OLE_PS:
8657 case OPC_CMP_ULE_PS:
8658 case OPC_CMP_SF_PS:
8659 case OPC_CMP_NGLE_PS:
8660 case OPC_CMP_SEQ_PS:
8661 case OPC_CMP_NGL_PS:
8662 case OPC_CMP_LT_PS:
8663 case OPC_CMP_NGE_PS:
8664 case OPC_CMP_LE_PS:
8665 case OPC_CMP_NGT_PS:
8666 if (ctx->opcode & (1 << 6)) {
8667 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8668 opn = condnames_abs[func-48];
8669 } else {
8670 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8671 opn = condnames[func-48];
8672 }
8673 break;
8674 default:
8675 MIPS_INVAL(opn);
8676 generate_exception (ctx, EXCP_RI);
8677 return;
8678 }
8679 (void)opn; /* avoid a compiler warning */
8680 switch (optype) {
8681 case BINOP:
8682 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8683 break;
8684 case CMPOP:
8685 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8686 break;
8687 default:
8688 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8689 break;
8690 }
8691 }
8692
8693 /* Coprocessor 3 (FPU) */
8694 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8695 int fd, int fs, int base, int index)
8696 {
8697 const char *opn = "extended float load/store";
8698 int store = 0;
8699 TCGv t0 = tcg_temp_new();
8700
8701 if (base == 0) {
8702 gen_load_gpr(t0, index);
8703 } else if (index == 0) {
8704 gen_load_gpr(t0, base);
8705 } else {
8706 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8707 }
8708 /* Don't do NOP if destination is zero: we must perform the actual
8709 memory access. */
8710 switch (opc) {
8711 case OPC_LWXC1:
8712 check_cop1x(ctx);
8713 {
8714 TCGv_i32 fp0 = tcg_temp_new_i32();
8715
8716 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8717 tcg_gen_trunc_tl_i32(fp0, t0);
8718 gen_store_fpr32(fp0, fd);
8719 tcg_temp_free_i32(fp0);
8720 }
8721 opn = "lwxc1";
8722 break;
8723 case OPC_LDXC1:
8724 check_cop1x(ctx);
8725 check_cp1_registers(ctx, fd);
8726 {
8727 TCGv_i64 fp0 = tcg_temp_new_i64();
8728
8729 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8730 gen_store_fpr64(ctx, fp0, fd);
8731 tcg_temp_free_i64(fp0);
8732 }
8733 opn = "ldxc1";
8734 break;
8735 case OPC_LUXC1:
8736 check_cp1_64bitmode(ctx);
8737 tcg_gen_andi_tl(t0, t0, ~0x7);
8738 {
8739 TCGv_i64 fp0 = tcg_temp_new_i64();
8740
8741 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8742 gen_store_fpr64(ctx, fp0, fd);
8743 tcg_temp_free_i64(fp0);
8744 }
8745 opn = "luxc1";
8746 break;
8747 case OPC_SWXC1:
8748 check_cop1x(ctx);
8749 {
8750 TCGv_i32 fp0 = tcg_temp_new_i32();
8751 TCGv t1 = tcg_temp_new();
8752
8753 gen_load_fpr32(fp0, fs);
8754 tcg_gen_extu_i32_tl(t1, fp0);
8755 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8756 tcg_temp_free_i32(fp0);
8757 tcg_temp_free(t1);
8758 }
8759 opn = "swxc1";
8760 store = 1;
8761 break;
8762 case OPC_SDXC1:
8763 check_cop1x(ctx);
8764 check_cp1_registers(ctx, fs);
8765 {
8766 TCGv_i64 fp0 = tcg_temp_new_i64();
8767
8768 gen_load_fpr64(ctx, fp0, fs);
8769 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8770 tcg_temp_free_i64(fp0);
8771 }
8772 opn = "sdxc1";
8773 store = 1;
8774 break;
8775 case OPC_SUXC1:
8776 check_cp1_64bitmode(ctx);
8777 tcg_gen_andi_tl(t0, t0, ~0x7);
8778 {
8779 TCGv_i64 fp0 = tcg_temp_new_i64();
8780
8781 gen_load_fpr64(ctx, fp0, fs);
8782 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8783 tcg_temp_free_i64(fp0);
8784 }
8785 opn = "suxc1";
8786 store = 1;
8787 break;
8788 }
8789 tcg_temp_free(t0);
8790 (void)opn; (void)store; /* avoid compiler warnings */
8791 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8792 regnames[index], regnames[base]);
8793 }
8794
8795 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8796 int fd, int fr, int fs, int ft)
8797 {
8798 const char *opn = "flt3_arith";
8799
8800 switch (opc) {
8801 case OPC_ALNV_PS:
8802 check_cp1_64bitmode(ctx);
8803 {
8804 TCGv t0 = tcg_temp_local_new();
8805 TCGv_i32 fp = tcg_temp_new_i32();
8806 TCGv_i32 fph = tcg_temp_new_i32();
8807 int l1 = gen_new_label();
8808 int l2 = gen_new_label();
8809
8810 gen_load_gpr(t0, fr);
8811 tcg_gen_andi_tl(t0, t0, 0x7);
8812
8813 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8814 gen_load_fpr32(fp, fs);
8815 gen_load_fpr32h(fph, fs);
8816 gen_store_fpr32(fp, fd);
8817 gen_store_fpr32h(fph, fd);
8818 tcg_gen_br(l2);
8819 gen_set_label(l1);
8820 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8821 tcg_temp_free(t0);
8822 #ifdef TARGET_WORDS_BIGENDIAN
8823 gen_load_fpr32(fp, fs);
8824 gen_load_fpr32h(fph, ft);
8825 gen_store_fpr32h(fp, fd);
8826 gen_store_fpr32(fph, fd);
8827 #else
8828 gen_load_fpr32h(fph, fs);
8829 gen_load_fpr32(fp, ft);
8830 gen_store_fpr32(fph, fd);
8831 gen_store_fpr32h(fp, fd);
8832 #endif
8833 gen_set_label(l2);
8834 tcg_temp_free_i32(fp);
8835 tcg_temp_free_i32(fph);
8836 }
8837 opn = "alnv.ps";
8838 break;
8839 case OPC_MADD_S:
8840 check_cop1x(ctx);
8841 {
8842 TCGv_i32 fp0 = tcg_temp_new_i32();
8843 TCGv_i32 fp1 = tcg_temp_new_i32();
8844 TCGv_i32 fp2 = tcg_temp_new_i32();
8845
8846 gen_load_fpr32(fp0, fs);
8847 gen_load_fpr32(fp1, ft);
8848 gen_load_fpr32(fp2, fr);
8849 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8850 tcg_temp_free_i32(fp0);
8851 tcg_temp_free_i32(fp1);
8852 gen_store_fpr32(fp2, fd);
8853 tcg_temp_free_i32(fp2);
8854 }
8855 opn = "madd.s";
8856 break;
8857 case OPC_MADD_D:
8858 check_cop1x(ctx);
8859 check_cp1_registers(ctx, fd | fs | ft | fr);
8860 {
8861 TCGv_i64 fp0 = tcg_temp_new_i64();
8862 TCGv_i64 fp1 = tcg_temp_new_i64();
8863 TCGv_i64 fp2 = tcg_temp_new_i64();
8864
8865 gen_load_fpr64(ctx, fp0, fs);
8866 gen_load_fpr64(ctx, fp1, ft);
8867 gen_load_fpr64(ctx, fp2, fr);
8868 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8869 tcg_temp_free_i64(fp0);
8870 tcg_temp_free_i64(fp1);
8871 gen_store_fpr64(ctx, fp2, fd);
8872 tcg_temp_free_i64(fp2);
8873 }
8874 opn = "madd.d";
8875 break;
8876 case OPC_MADD_PS:
8877 check_cp1_64bitmode(ctx);
8878 {
8879 TCGv_i64 fp0 = tcg_temp_new_i64();
8880 TCGv_i64 fp1 = tcg_temp_new_i64();
8881 TCGv_i64 fp2 = tcg_temp_new_i64();
8882
8883 gen_load_fpr64(ctx, fp0, fs);
8884 gen_load_fpr64(ctx, fp1, ft);
8885 gen_load_fpr64(ctx, fp2, fr);
8886 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8887 tcg_temp_free_i64(fp0);
8888 tcg_temp_free_i64(fp1);
8889 gen_store_fpr64(ctx, fp2, fd);
8890 tcg_temp_free_i64(fp2);
8891 }
8892 opn = "madd.ps";
8893 break;
8894 case OPC_MSUB_S:
8895 check_cop1x(ctx);
8896 {
8897 TCGv_i32 fp0 = tcg_temp_new_i32();
8898 TCGv_i32 fp1 = tcg_temp_new_i32();
8899 TCGv_i32 fp2 = tcg_temp_new_i32();
8900
8901 gen_load_fpr32(fp0, fs);
8902 gen_load_fpr32(fp1, ft);
8903 gen_load_fpr32(fp2, fr);
8904 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8905 tcg_temp_free_i32(fp0);
8906 tcg_temp_free_i32(fp1);
8907 gen_store_fpr32(fp2, fd);
8908 tcg_temp_free_i32(fp2);
8909 }
8910 opn = "msub.s";
8911 break;
8912 case OPC_MSUB_D:
8913 check_cop1x(ctx);
8914 check_cp1_registers(ctx, fd | fs | ft | fr);
8915 {
8916 TCGv_i64 fp0 = tcg_temp_new_i64();
8917 TCGv_i64 fp1 = tcg_temp_new_i64();
8918 TCGv_i64 fp2 = tcg_temp_new_i64();
8919
8920 gen_load_fpr64(ctx, fp0, fs);
8921 gen_load_fpr64(ctx, fp1, ft);
8922 gen_load_fpr64(ctx, fp2, fr);
8923 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8924 tcg_temp_free_i64(fp0);
8925 tcg_temp_free_i64(fp1);
8926 gen_store_fpr64(ctx, fp2, fd);
8927 tcg_temp_free_i64(fp2);
8928 }
8929 opn = "msub.d";
8930 break;
8931 case OPC_MSUB_PS:
8932 check_cp1_64bitmode(ctx);
8933 {
8934 TCGv_i64 fp0 = tcg_temp_new_i64();
8935 TCGv_i64 fp1 = tcg_temp_new_i64();
8936 TCGv_i64 fp2 = tcg_temp_new_i64();
8937
8938 gen_load_fpr64(ctx, fp0, fs);
8939 gen_load_fpr64(ctx, fp1, ft);
8940 gen_load_fpr64(ctx, fp2, fr);
8941 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8942 tcg_temp_free_i64(fp0);
8943 tcg_temp_free_i64(fp1);
8944 gen_store_fpr64(ctx, fp2, fd);
8945 tcg_temp_free_i64(fp2);
8946 }
8947 opn = "msub.ps";
8948 break;
8949 case OPC_NMADD_S:
8950 check_cop1x(ctx);
8951 {
8952 TCGv_i32 fp0 = tcg_temp_new_i32();
8953 TCGv_i32 fp1 = tcg_temp_new_i32();
8954 TCGv_i32 fp2 = tcg_temp_new_i32();
8955
8956 gen_load_fpr32(fp0, fs);
8957 gen_load_fpr32(fp1, ft);
8958 gen_load_fpr32(fp2, fr);
8959 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8960 tcg_temp_free_i32(fp0);
8961 tcg_temp_free_i32(fp1);
8962 gen_store_fpr32(fp2, fd);
8963 tcg_temp_free_i32(fp2);
8964 }
8965 opn = "nmadd.s";
8966 break;
8967 case OPC_NMADD_D:
8968 check_cop1x(ctx);
8969 check_cp1_registers(ctx, fd | fs | ft | fr);
8970 {
8971 TCGv_i64 fp0 = tcg_temp_new_i64();
8972 TCGv_i64 fp1 = tcg_temp_new_i64();
8973 TCGv_i64 fp2 = tcg_temp_new_i64();
8974
8975 gen_load_fpr64(ctx, fp0, fs);
8976 gen_load_fpr64(ctx, fp1, ft);
8977 gen_load_fpr64(ctx, fp2, fr);
8978 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8979 tcg_temp_free_i64(fp0);
8980 tcg_temp_free_i64(fp1);
8981 gen_store_fpr64(ctx, fp2, fd);
8982 tcg_temp_free_i64(fp2);
8983 }
8984 opn = "nmadd.d";
8985 break;
8986 case OPC_NMADD_PS:
8987 check_cp1_64bitmode(ctx);
8988 {
8989 TCGv_i64 fp0 = tcg_temp_new_i64();
8990 TCGv_i64 fp1 = tcg_temp_new_i64();
8991 TCGv_i64 fp2 = tcg_temp_new_i64();
8992
8993 gen_load_fpr64(ctx, fp0, fs);
8994 gen_load_fpr64(ctx, fp1, ft);
8995 gen_load_fpr64(ctx, fp2, fr);
8996 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8997 tcg_temp_free_i64(fp0);
8998 tcg_temp_free_i64(fp1);
8999 gen_store_fpr64(ctx, fp2, fd);
9000 tcg_temp_free_i64(fp2);
9001 }
9002 opn = "nmadd.ps";
9003 break;
9004 case OPC_NMSUB_S:
9005 check_cop1x(ctx);
9006 {
9007 TCGv_i32 fp0 = tcg_temp_new_i32();
9008 TCGv_i32 fp1 = tcg_temp_new_i32();
9009 TCGv_i32 fp2 = tcg_temp_new_i32();
9010
9011 gen_load_fpr32(fp0, fs);
9012 gen_load_fpr32(fp1, ft);
9013 gen_load_fpr32(fp2, fr);
9014 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
9015 tcg_temp_free_i32(fp0);
9016 tcg_temp_free_i32(fp1);
9017 gen_store_fpr32(fp2, fd);
9018 tcg_temp_free_i32(fp2);
9019 }
9020 opn = "nmsub.s";
9021 break;
9022 case OPC_NMSUB_D:
9023 check_cop1x(ctx);
9024 check_cp1_registers(ctx, fd | fs | ft | fr);
9025 {
9026 TCGv_i64 fp0 = tcg_temp_new_i64();
9027 TCGv_i64 fp1 = tcg_temp_new_i64();
9028 TCGv_i64 fp2 = tcg_temp_new_i64();
9029
9030 gen_load_fpr64(ctx, fp0, fs);
9031 gen_load_fpr64(ctx, fp1, ft);
9032 gen_load_fpr64(ctx, fp2, fr);
9033 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9034 tcg_temp_free_i64(fp0);
9035 tcg_temp_free_i64(fp1);
9036 gen_store_fpr64(ctx, fp2, fd);
9037 tcg_temp_free_i64(fp2);
9038 }
9039 opn = "nmsub.d";
9040 break;
9041 case OPC_NMSUB_PS:
9042 check_cp1_64bitmode(ctx);
9043 {
9044 TCGv_i64 fp0 = tcg_temp_new_i64();
9045 TCGv_i64 fp1 = tcg_temp_new_i64();
9046 TCGv_i64 fp2 = tcg_temp_new_i64();
9047
9048 gen_load_fpr64(ctx, fp0, fs);
9049 gen_load_fpr64(ctx, fp1, ft);
9050 gen_load_fpr64(ctx, fp2, fr);
9051 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9052 tcg_temp_free_i64(fp0);
9053 tcg_temp_free_i64(fp1);
9054 gen_store_fpr64(ctx, fp2, fd);
9055 tcg_temp_free_i64(fp2);
9056 }
9057 opn = "nmsub.ps";
9058 break;
9059 default:
9060 MIPS_INVAL(opn);
9061 generate_exception (ctx, EXCP_RI);
9062 return;
9063 }
9064 (void)opn; /* avoid a compiler warning */
9065 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9066 fregnames[fs], fregnames[ft]);
9067 }
9068
9069 static void
9070 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9071 {
9072 TCGv t0;
9073
9074 #if !defined(CONFIG_USER_ONLY)
9075 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9076 Therefore only check the ISA in system mode. */
9077 check_insn(env, ctx, ISA_MIPS32R2);
9078 #endif
9079 t0 = tcg_temp_new();
9080
9081 switch (rd) {
9082 case 0:
9083 save_cpu_state(ctx, 1);
9084 gen_helper_rdhwr_cpunum(t0, cpu_env);
9085 gen_store_gpr(t0, rt);
9086 break;
9087 case 1:
9088 save_cpu_state(ctx, 1);
9089 gen_helper_rdhwr_synci_step(t0, cpu_env);
9090 gen_store_gpr(t0, rt);
9091 break;
9092 case 2:
9093 save_cpu_state(ctx, 1);
9094 gen_helper_rdhwr_cc(t0, cpu_env);
9095 gen_store_gpr(t0, rt);
9096 break;
9097 case 3:
9098 save_cpu_state(ctx, 1);
9099 gen_helper_rdhwr_ccres(t0, cpu_env);
9100 gen_store_gpr(t0, rt);
9101 break;
9102 case 29:
9103 #if defined(CONFIG_USER_ONLY)
9104 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9105 gen_store_gpr(t0, rt);
9106 break;
9107 #else
9108 /* XXX: Some CPUs implement this in hardware.
9109 Not supported yet. */
9110 #endif
9111 default: /* Invalid */
9112 MIPS_INVAL("rdhwr");
9113 generate_exception(ctx, EXCP_RI);
9114 break;
9115 }
9116 tcg_temp_free(t0);
9117 }
9118
9119 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9120 int insn_bytes)
9121 {
9122 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9123 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9124 /* Branches completion */
9125 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9126 ctx->bstate = BS_BRANCH;
9127 save_cpu_state(ctx, 0);
9128 /* FIXME: Need to clear can_do_io. */
9129 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9130 case MIPS_HFLAG_B:
9131 /* unconditional branch */
9132 MIPS_DEBUG("unconditional branch");
9133 if (proc_hflags & MIPS_HFLAG_BX) {
9134 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9135 }
9136 gen_goto_tb(ctx, 0, ctx->btarget);
9137 break;
9138 case MIPS_HFLAG_BL:
9139 /* blikely taken case */
9140 MIPS_DEBUG("blikely branch taken");
9141 gen_goto_tb(ctx, 0, ctx->btarget);
9142 break;
9143 case MIPS_HFLAG_BC:
9144 /* Conditional branch */
9145 MIPS_DEBUG("conditional branch");
9146 {
9147 int l1 = gen_new_label();
9148
9149 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9150 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9151 gen_set_label(l1);
9152 gen_goto_tb(ctx, 0, ctx->btarget);
9153 }
9154 break;
9155 case MIPS_HFLAG_BR:
9156 /* unconditional branch to register */
9157 MIPS_DEBUG("branch to register");
9158 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9159 TCGv t0 = tcg_temp_new();
9160 TCGv_i32 t1 = tcg_temp_new_i32();
9161
9162 tcg_gen_andi_tl(t0, btarget, 0x1);
9163 tcg_gen_trunc_tl_i32(t1, t0);
9164 tcg_temp_free(t0);
9165 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9166 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9167 tcg_gen_or_i32(hflags, hflags, t1);
9168 tcg_temp_free_i32(t1);
9169
9170 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9171 } else {
9172 tcg_gen_mov_tl(cpu_PC, btarget);
9173 }
9174 if (ctx->singlestep_enabled) {
9175 save_cpu_state(ctx, 0);
9176 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9177 }
9178 tcg_gen_exit_tb(0);
9179 break;
9180 default:
9181 MIPS_DEBUG("unknown branch");
9182 break;
9183 }
9184 }
9185 }
9186
9187 /* ISA extensions (ASEs) */
9188 /* MIPS16 extension to MIPS32 */
9189
9190 /* MIPS16 major opcodes */
9191 enum {
9192 M16_OPC_ADDIUSP = 0x00,
9193 M16_OPC_ADDIUPC = 0x01,
9194 M16_OPC_B = 0x02,
9195 M16_OPC_JAL = 0x03,
9196 M16_OPC_BEQZ = 0x04,
9197 M16_OPC_BNEQZ = 0x05,
9198 M16_OPC_SHIFT = 0x06,
9199 M16_OPC_LD = 0x07,
9200 M16_OPC_RRIA = 0x08,
9201 M16_OPC_ADDIU8 = 0x09,
9202 M16_OPC_SLTI = 0x0a,
9203 M16_OPC_SLTIU = 0x0b,
9204 M16_OPC_I8 = 0x0c,
9205 M16_OPC_LI = 0x0d,
9206 M16_OPC_CMPI = 0x0e,
9207 M16_OPC_SD = 0x0f,
9208 M16_OPC_LB = 0x10,
9209 M16_OPC_LH = 0x11,
9210 M16_OPC_LWSP = 0x12,
9211 M16_OPC_LW = 0x13,
9212 M16_OPC_LBU = 0x14,
9213 M16_OPC_LHU = 0x15,
9214 M16_OPC_LWPC = 0x16,
9215 M16_OPC_LWU = 0x17,
9216 M16_OPC_SB = 0x18,
9217 M16_OPC_SH = 0x19,
9218 M16_OPC_SWSP = 0x1a,
9219 M16_OPC_SW = 0x1b,
9220 M16_OPC_RRR = 0x1c,
9221 M16_OPC_RR = 0x1d,
9222 M16_OPC_EXTEND = 0x1e,
9223 M16_OPC_I64 = 0x1f
9224 };
9225
9226 /* I8 funct field */
9227 enum {
9228 I8_BTEQZ = 0x0,
9229 I8_BTNEZ = 0x1,
9230 I8_SWRASP = 0x2,
9231 I8_ADJSP = 0x3,
9232 I8_SVRS = 0x4,
9233 I8_MOV32R = 0x5,
9234 I8_MOVR32 = 0x7
9235 };
9236
9237 /* RRR f field */
9238 enum {
9239 RRR_DADDU = 0x0,
9240 RRR_ADDU = 0x1,
9241 RRR_DSUBU = 0x2,
9242 RRR_SUBU = 0x3
9243 };
9244
9245 /* RR funct field */
9246 enum {
9247 RR_JR = 0x00,
9248 RR_SDBBP = 0x01,
9249 RR_SLT = 0x02,
9250 RR_SLTU = 0x03,
9251 RR_SLLV = 0x04,
9252 RR_BREAK = 0x05,
9253 RR_SRLV = 0x06,
9254 RR_SRAV = 0x07,
9255 RR_DSRL = 0x08,
9256 RR_CMP = 0x0a,
9257 RR_NEG = 0x0b,
9258 RR_AND = 0x0c,
9259 RR_OR = 0x0d,
9260 RR_XOR = 0x0e,
9261 RR_NOT = 0x0f,
9262 RR_MFHI = 0x10,
9263 RR_CNVT = 0x11,
9264 RR_MFLO = 0x12,
9265 RR_DSRA = 0x13,
9266 RR_DSLLV = 0x14,
9267 RR_DSRLV = 0x16,
9268 RR_DSRAV = 0x17,
9269 RR_MULT = 0x18,
9270 RR_MULTU = 0x19,
9271 RR_DIV = 0x1a,
9272 RR_DIVU = 0x1b,
9273 RR_DMULT = 0x1c,
9274 RR_DMULTU = 0x1d,
9275 RR_DDIV = 0x1e,
9276 RR_DDIVU = 0x1f
9277 };
9278
9279 /* I64 funct field */
9280 enum {
9281 I64_LDSP = 0x0,
9282 I64_SDSP = 0x1,
9283 I64_SDRASP = 0x2,
9284 I64_DADJSP = 0x3,
9285 I64_LDPC = 0x4,
9286 I64_DADDIU5 = 0x5,
9287 I64_DADDIUPC = 0x6,
9288 I64_DADDIUSP = 0x7
9289 };
9290
9291 /* RR ry field for CNVT */
9292 enum {
9293 RR_RY_CNVT_ZEB = 0x0,
9294 RR_RY_CNVT_ZEH = 0x1,
9295 RR_RY_CNVT_ZEW = 0x2,
9296 RR_RY_CNVT_SEB = 0x4,
9297 RR_RY_CNVT_SEH = 0x5,
9298 RR_RY_CNVT_SEW = 0x6,
9299 };
9300
9301 static int xlat (int r)
9302 {
9303 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9304
9305 return map[r];
9306 }
9307
9308 static void gen_mips16_save (DisasContext *ctx,
9309 int xsregs, int aregs,
9310 int do_ra, int do_s0, int do_s1,
9311 int framesize)
9312 {
9313 TCGv t0 = tcg_temp_new();
9314 TCGv t1 = tcg_temp_new();
9315 int args, astatic;
9316
9317 switch (aregs) {
9318 case 0:
9319 case 1:
9320 case 2:
9321 case 3:
9322 case 11:
9323 args = 0;
9324 break;
9325 case 4:
9326 case 5:
9327 case 6:
9328 case 7:
9329 args = 1;
9330 break;
9331 case 8:
9332 case 9:
9333 case 10:
9334 args = 2;
9335 break;
9336 case 12:
9337 case 13:
9338 args = 3;
9339 break;
9340 case 14:
9341 args = 4;
9342 break;
9343 default:
9344 generate_exception(ctx, EXCP_RI);
9345 return;
9346 }
9347
9348 switch (args) {
9349 case 4:
9350 gen_base_offset_addr(ctx, t0, 29, 12);
9351 gen_load_gpr(t1, 7);
9352 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9353 /* Fall through */
9354 case 3:
9355 gen_base_offset_addr(ctx, t0, 29, 8);
9356 gen_load_gpr(t1, 6);
9357 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9358 /* Fall through */
9359 case 2:
9360 gen_base_offset_addr(ctx, t0, 29, 4);
9361 gen_load_gpr(t1, 5);
9362 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9363 /* Fall through */
9364 case 1:
9365 gen_base_offset_addr(ctx, t0, 29, 0);
9366 gen_load_gpr(t1, 4);
9367 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9368 }
9369
9370 gen_load_gpr(t0, 29);
9371
9372 #define DECR_AND_STORE(reg) do { \
9373 tcg_gen_subi_tl(t0, t0, 4); \
9374 gen_load_gpr(t1, reg); \
9375 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9376 } while (0)
9377
9378 if (do_ra) {
9379 DECR_AND_STORE(31);
9380 }
9381
9382 switch (xsregs) {
9383 case 7:
9384 DECR_AND_STORE(30);
9385 /* Fall through */
9386 case 6:
9387 DECR_AND_STORE(23);
9388 /* Fall through */
9389 case 5:
9390 DECR_AND_STORE(22);
9391 /* Fall through */
9392 case 4:
9393 DECR_AND_STORE(21);
9394 /* Fall through */
9395 case 3:
9396 DECR_AND_STORE(20);
9397 /* Fall through */
9398 case 2:
9399 DECR_AND_STORE(19);
9400 /* Fall through */
9401 case 1:
9402 DECR_AND_STORE(18);
9403 }
9404
9405 if (do_s1) {
9406 DECR_AND_STORE(17);
9407 }
9408 if (do_s0) {
9409 DECR_AND_STORE(16);
9410 }
9411
9412 switch (aregs) {
9413 case 0:
9414 case 4:
9415 case 8:
9416 case 12:
9417 case 14:
9418 astatic = 0;
9419 break;
9420 case 1:
9421 case 5:
9422 case 9:
9423 case 13:
9424 astatic = 1;
9425 break;
9426 case 2:
9427 case 6:
9428 case 10:
9429 astatic = 2;
9430 break;
9431 case 3:
9432 case 7:
9433 astatic = 3;
9434 break;
9435 case 11:
9436 astatic = 4;
9437 break;
9438 default:
9439 generate_exception(ctx, EXCP_RI);
9440 return;
9441 }
9442
9443 if (astatic > 0) {
9444 DECR_AND_STORE(7);
9445 if (astatic > 1) {
9446 DECR_AND_STORE(6);
9447 if (astatic > 2) {
9448 DECR_AND_STORE(5);
9449 if (astatic > 3) {
9450 DECR_AND_STORE(4);
9451 }
9452 }
9453 }
9454 }
9455 #undef DECR_AND_STORE
9456
9457 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9458 tcg_temp_free(t0);
9459 tcg_temp_free(t1);
9460 }
9461
9462 static void gen_mips16_restore (DisasContext *ctx,
9463 int xsregs, int aregs,
9464 int do_ra, int do_s0, int do_s1,
9465 int framesize)
9466 {
9467 int astatic;
9468 TCGv t0 = tcg_temp_new();
9469 TCGv t1 = tcg_temp_new();
9470
9471 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9472
9473 #define DECR_AND_LOAD(reg) do { \
9474 tcg_gen_subi_tl(t0, t0, 4); \
9475 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9476 gen_store_gpr(t1, reg); \
9477 } while (0)
9478
9479 if (do_ra) {
9480 DECR_AND_LOAD(31);
9481 }
9482
9483 switch (xsregs) {
9484 case 7:
9485 DECR_AND_LOAD(30);
9486 /* Fall through */
9487 case 6:
9488 DECR_AND_LOAD(23);
9489 /* Fall through */
9490 case 5:
9491 DECR_AND_LOAD(22);
9492 /* Fall through */
9493 case 4:
9494 DECR_AND_LOAD(21);
9495 /* Fall through */
9496 case 3:
9497 DECR_AND_LOAD(20);
9498 /* Fall through */
9499 case 2:
9500 DECR_AND_LOAD(19);
9501 /* Fall through */
9502 case 1:
9503 DECR_AND_LOAD(18);
9504 }
9505
9506 if (do_s1) {
9507 DECR_AND_LOAD(17);
9508 }
9509 if (do_s0) {
9510 DECR_AND_LOAD(16);
9511 }
9512
9513 switch (aregs) {
9514 case 0:
9515 case 4:
9516 case 8:
9517 case 12:
9518 case 14:
9519 astatic = 0;
9520 break;
9521 case 1:
9522 case 5:
9523 case 9:
9524 case 13:
9525 astatic = 1;
9526 break;
9527 case 2:
9528 case 6:
9529 case 10:
9530 astatic = 2;
9531 break;
9532 case 3:
9533 case 7:
9534 astatic = 3;
9535 break;
9536 case 11:
9537 astatic = 4;
9538 break;
9539 default:
9540 generate_exception(ctx, EXCP_RI);
9541 return;
9542 }
9543
9544 if (astatic > 0) {
9545 DECR_AND_LOAD(7);
9546 if (astatic > 1) {
9547 DECR_AND_LOAD(6);
9548 if (astatic > 2) {
9549 DECR_AND_LOAD(5);
9550 if (astatic > 3) {
9551 DECR_AND_LOAD(4);
9552 }
9553 }
9554 }
9555 }
9556 #undef DECR_AND_LOAD
9557
9558 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9559 tcg_temp_free(t0);
9560 tcg_temp_free(t1);
9561 }
9562
9563 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9564 int is_64_bit, int extended)
9565 {
9566 TCGv t0;
9567
9568 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9569 generate_exception(ctx, EXCP_RI);
9570 return;
9571 }
9572
9573 t0 = tcg_temp_new();
9574
9575 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9576 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9577 if (!is_64_bit) {
9578 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9579 }
9580
9581 tcg_temp_free(t0);
9582 }
9583
9584 #if defined(TARGET_MIPS64)
9585 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9586 int ry, int funct, int16_t offset,
9587 int extended)
9588 {
9589 switch (funct) {
9590 case I64_LDSP:
9591 check_mips_64(ctx);
9592 offset = extended ? offset : offset << 3;
9593 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9594 break;
9595 case I64_SDSP:
9596 check_mips_64(ctx);
9597 offset = extended ? offset : offset << 3;
9598 gen_st(ctx, OPC_SD, ry, 29, offset);
9599 break;
9600 case I64_SDRASP:
9601 check_mips_64(ctx);
9602 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9603 gen_st(ctx, OPC_SD, 31, 29, offset);
9604 break;
9605 case I64_DADJSP:
9606 check_mips_64(ctx);
9607 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9608 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9609 break;
9610 case I64_LDPC:
9611 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9612 generate_exception(ctx, EXCP_RI);
9613 } else {
9614 offset = extended ? offset : offset << 3;
9615 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9616 }
9617 break;
9618 case I64_DADDIU5:
9619 check_mips_64(ctx);
9620 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9621 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9622 break;
9623 case I64_DADDIUPC:
9624 check_mips_64(ctx);
9625 offset = extended ? offset : offset << 2;
9626 gen_addiupc(ctx, ry, offset, 1, extended);
9627 break;
9628 case I64_DADDIUSP:
9629 check_mips_64(ctx);
9630 offset = extended ? offset : offset << 2;
9631 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9632 break;
9633 }
9634 }
9635 #endif
9636
9637 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9638 int *is_branch)
9639 {
9640 int extend = cpu_lduw_code(env, ctx->pc + 2);
9641 int op, rx, ry, funct, sa;
9642 int16_t imm, offset;
9643
9644 ctx->opcode = (ctx->opcode << 16) | extend;
9645 op = (ctx->opcode >> 11) & 0x1f;
9646 sa = (ctx->opcode >> 22) & 0x1f;
9647 funct = (ctx->opcode >> 8) & 0x7;
9648 rx = xlat((ctx->opcode >> 8) & 0x7);
9649 ry = xlat((ctx->opcode >> 5) & 0x7);
9650 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9651 | ((ctx->opcode >> 21) & 0x3f) << 5
9652 | (ctx->opcode & 0x1f));
9653
9654 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9655 counterparts. */
9656 switch (op) {
9657 case M16_OPC_ADDIUSP:
9658 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9659 break;
9660 case M16_OPC_ADDIUPC:
9661 gen_addiupc(ctx, rx, imm, 0, 1);
9662 break;
9663 case M16_OPC_B:
9664 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9665 /* No delay slot, so just process as a normal instruction */
9666 break;
9667 case M16_OPC_BEQZ:
9668 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9669 /* No delay slot, so just process as a normal instruction */
9670 break;
9671 case M16_OPC_BNEQZ:
9672 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9673 /* No delay slot, so just process as a normal instruction */
9674 break;
9675 case M16_OPC_SHIFT:
9676 switch (ctx->opcode & 0x3) {
9677 case 0x0:
9678 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9679 break;
9680 case 0x1:
9681 #if defined(TARGET_MIPS64)
9682 check_mips_64(ctx);
9683 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9684 #else
9685 generate_exception(ctx, EXCP_RI);
9686 #endif
9687 break;
9688 case 0x2:
9689 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9690 break;
9691 case 0x3:
9692 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9693 break;
9694 }
9695 break;
9696 #if defined(TARGET_MIPS64)
9697 case M16_OPC_LD:
9698 check_mips_64(ctx);
9699 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9700 break;
9701 #endif
9702 case M16_OPC_RRIA:
9703 imm = ctx->opcode & 0xf;
9704 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9705 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9706 imm = (int16_t) (imm << 1) >> 1;
9707 if ((ctx->opcode >> 4) & 0x1) {
9708 #if defined(TARGET_MIPS64)
9709 check_mips_64(ctx);
9710 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9711 #else
9712 generate_exception(ctx, EXCP_RI);
9713 #endif
9714 } else {
9715 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9716 }
9717 break;
9718 case M16_OPC_ADDIU8:
9719 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9720 break;
9721 case M16_OPC_SLTI:
9722 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9723 break;
9724 case M16_OPC_SLTIU:
9725 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9726 break;
9727 case M16_OPC_I8:
9728 switch (funct) {
9729 case I8_BTEQZ:
9730 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9731 break;
9732 case I8_BTNEZ:
9733 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9734 break;
9735 case I8_SWRASP:
9736 gen_st(ctx, OPC_SW, 31, 29, imm);
9737 break;
9738 case I8_ADJSP:
9739 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9740 break;
9741 case I8_SVRS:
9742 {
9743 int xsregs = (ctx->opcode >> 24) & 0x7;
9744 int aregs = (ctx->opcode >> 16) & 0xf;
9745 int do_ra = (ctx->opcode >> 6) & 0x1;
9746 int do_s0 = (ctx->opcode >> 5) & 0x1;
9747 int do_s1 = (ctx->opcode >> 4) & 0x1;
9748 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9749 | (ctx->opcode & 0xf)) << 3;
9750
9751 if (ctx->opcode & (1 << 7)) {
9752 gen_mips16_save(ctx, xsregs, aregs,
9753 do_ra, do_s0, do_s1,
9754 framesize);
9755 } else {
9756 gen_mips16_restore(ctx, xsregs, aregs,
9757 do_ra, do_s0, do_s1,
9758 framesize);
9759 }
9760 }
9761 break;
9762 default:
9763 generate_exception(ctx, EXCP_RI);
9764 break;
9765 }
9766 break;
9767 case M16_OPC_LI:
9768 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9769 break;
9770 case M16_OPC_CMPI:
9771 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9772 break;
9773 #if defined(TARGET_MIPS64)
9774 case M16_OPC_SD:
9775 gen_st(ctx, OPC_SD, ry, rx, offset);
9776 break;
9777 #endif
9778 case M16_OPC_LB:
9779 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9780 break;
9781 case M16_OPC_LH:
9782 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9783 break;
9784 case M16_OPC_LWSP:
9785 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9786 break;
9787 case M16_OPC_LW:
9788 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9789 break;
9790 case M16_OPC_LBU:
9791 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9792 break;
9793 case M16_OPC_LHU:
9794 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9795 break;
9796 case M16_OPC_LWPC:
9797 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9798 break;
9799 #if defined(TARGET_MIPS64)
9800 case M16_OPC_LWU:
9801 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9802 break;
9803 #endif
9804 case M16_OPC_SB:
9805 gen_st(ctx, OPC_SB, ry, rx, offset);
9806 break;
9807 case M16_OPC_SH:
9808 gen_st(ctx, OPC_SH, ry, rx, offset);
9809 break;
9810 case M16_OPC_SWSP:
9811 gen_st(ctx, OPC_SW, rx, 29, offset);
9812 break;
9813 case M16_OPC_SW:
9814 gen_st(ctx, OPC_SW, ry, rx, offset);
9815 break;
9816 #if defined(TARGET_MIPS64)
9817 case M16_OPC_I64:
9818 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9819 break;
9820 #endif
9821 default:
9822 generate_exception(ctx, EXCP_RI);
9823 break;
9824 }
9825
9826 return 4;
9827 }
9828
9829 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9830 int *is_branch)
9831 {
9832 int rx, ry;
9833 int sa;
9834 int op, cnvt_op, op1, offset;
9835 int funct;
9836 int n_bytes;
9837
9838 op = (ctx->opcode >> 11) & 0x1f;
9839 sa = (ctx->opcode >> 2) & 0x7;
9840 sa = sa == 0 ? 8 : sa;
9841 rx = xlat((ctx->opcode >> 8) & 0x7);
9842 cnvt_op = (ctx->opcode >> 5) & 0x7;
9843 ry = xlat((ctx->opcode >> 5) & 0x7);
9844 op1 = offset = ctx->opcode & 0x1f;
9845
9846 n_bytes = 2;
9847
9848 switch (op) {
9849 case M16_OPC_ADDIUSP:
9850 {
9851 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9852
9853 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9854 }
9855 break;
9856 case M16_OPC_ADDIUPC:
9857 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9858 break;
9859 case M16_OPC_B:
9860 offset = (ctx->opcode & 0x7ff) << 1;
9861 offset = (int16_t)(offset << 4) >> 4;
9862 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9863 /* No delay slot, so just process as a normal instruction */
9864 break;
9865 case M16_OPC_JAL:
9866 offset = cpu_lduw_code(env, ctx->pc + 2);
9867 offset = (((ctx->opcode & 0x1f) << 21)
9868 | ((ctx->opcode >> 5) & 0x1f) << 16
9869 | offset) << 2;
9870 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9871 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9872 n_bytes = 4;
9873 *is_branch = 1;
9874 break;
9875 case M16_OPC_BEQZ:
9876 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9877 /* No delay slot, so just process as a normal instruction */
9878 break;
9879 case M16_OPC_BNEQZ:
9880 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9881 /* No delay slot, so just process as a normal instruction */
9882 break;
9883 case M16_OPC_SHIFT:
9884 switch (ctx->opcode & 0x3) {
9885 case 0x0:
9886 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9887 break;
9888 case 0x1:
9889 #if defined(TARGET_MIPS64)
9890 check_mips_64(ctx);
9891 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9892 #else
9893 generate_exception(ctx, EXCP_RI);
9894 #endif
9895 break;
9896 case 0x2:
9897 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9898 break;
9899 case 0x3:
9900 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9901 break;
9902 }
9903 break;
9904 #if defined(TARGET_MIPS64)
9905 case M16_OPC_LD:
9906 check_mips_64(ctx);
9907 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9908 break;
9909 #endif
9910 case M16_OPC_RRIA:
9911 {
9912 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9913
9914 if ((ctx->opcode >> 4) & 1) {
9915 #if defined(TARGET_MIPS64)
9916 check_mips_64(ctx);
9917 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9918 #else
9919 generate_exception(ctx, EXCP_RI);
9920 #endif
9921 } else {
9922 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9923 }
9924 }
9925 break;
9926 case M16_OPC_ADDIU8:
9927 {
9928 int16_t imm = (int8_t) ctx->opcode;
9929
9930 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9931 }
9932 break;
9933 case M16_OPC_SLTI:
9934 {
9935 int16_t imm = (uint8_t) ctx->opcode;
9936 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9937 }
9938 break;
9939 case M16_OPC_SLTIU:
9940 {
9941 int16_t imm = (uint8_t) ctx->opcode;
9942 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9943 }
9944 break;
9945 case M16_OPC_I8:
9946 {
9947 int reg32;
9948
9949 funct = (ctx->opcode >> 8) & 0x7;
9950 switch (funct) {
9951 case I8_BTEQZ:
9952 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9953 ((int8_t)ctx->opcode) << 1);
9954 break;
9955 case I8_BTNEZ:
9956 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9957 ((int8_t)ctx->opcode) << 1);
9958 break;
9959 case I8_SWRASP:
9960 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9961 break;
9962 case I8_ADJSP:
9963 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9964 ((int8_t)ctx->opcode) << 3);
9965 break;
9966 case I8_SVRS:
9967 {
9968 int do_ra = ctx->opcode & (1 << 6);
9969 int do_s0 = ctx->opcode & (1 << 5);
9970 int do_s1 = ctx->opcode & (1 << 4);
9971 int framesize = ctx->opcode & 0xf;
9972
9973 if (framesize == 0) {
9974 framesize = 128;
9975 } else {
9976 framesize = framesize << 3;
9977 }
9978
9979 if (ctx->opcode & (1 << 7)) {
9980 gen_mips16_save(ctx, 0, 0,
9981 do_ra, do_s0, do_s1, framesize);
9982 } else {
9983 gen_mips16_restore(ctx, 0, 0,
9984 do_ra, do_s0, do_s1, framesize);
9985 }
9986 }
9987 break;
9988 case I8_MOV32R:
9989 {
9990 int rz = xlat(ctx->opcode & 0x7);
9991
9992 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9993 ((ctx->opcode >> 5) & 0x7);
9994 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9995 }
9996 break;
9997 case I8_MOVR32:
9998 reg32 = ctx->opcode & 0x1f;
9999 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
10000 break;
10001 default:
10002 generate_exception(ctx, EXCP_RI);
10003 break;
10004 }
10005 }
10006 break;
10007 case M16_OPC_LI:
10008 {
10009 int16_t imm = (uint8_t) ctx->opcode;
10010
10011 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10012 }
10013 break;
10014 case M16_OPC_CMPI:
10015 {
10016 int16_t imm = (uint8_t) ctx->opcode;
10017 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
10018 }
10019 break;
10020 #if defined(TARGET_MIPS64)
10021 case M16_OPC_SD:
10022 check_mips_64(ctx);
10023 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10024 break;
10025 #endif
10026 case M16_OPC_LB:
10027 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10028 break;
10029 case M16_OPC_LH:
10030 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10031 break;
10032 case M16_OPC_LWSP:
10033 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10034 break;
10035 case M16_OPC_LW:
10036 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10037 break;
10038 case M16_OPC_LBU:
10039 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10040 break;
10041 case M16_OPC_LHU:
10042 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10043 break;
10044 case M16_OPC_LWPC:
10045 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10046 break;
10047 #if defined (TARGET_MIPS64)
10048 case M16_OPC_LWU:
10049 check_mips_64(ctx);
10050 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10051 break;
10052 #endif
10053 case M16_OPC_SB:
10054 gen_st(ctx, OPC_SB, ry, rx, offset);
10055 break;
10056 case M16_OPC_SH:
10057 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10058 break;
10059 case M16_OPC_SWSP:
10060 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10061 break;
10062 case M16_OPC_SW:
10063 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10064 break;
10065 case M16_OPC_RRR:
10066 {
10067 int rz = xlat((ctx->opcode >> 2) & 0x7);
10068 int mips32_op;
10069
10070 switch (ctx->opcode & 0x3) {
10071 case RRR_ADDU:
10072 mips32_op = OPC_ADDU;
10073 break;
10074 case RRR_SUBU:
10075 mips32_op = OPC_SUBU;
10076 break;
10077 #if defined(TARGET_MIPS64)
10078 case RRR_DADDU:
10079 mips32_op = OPC_DADDU;
10080 check_mips_64(ctx);
10081 break;
10082 case RRR_DSUBU:
10083 mips32_op = OPC_DSUBU;
10084 check_mips_64(ctx);
10085 break;
10086 #endif
10087 default:
10088 generate_exception(ctx, EXCP_RI);
10089 goto done;
10090 }
10091
10092 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10093 done:
10094 ;
10095 }
10096 break;
10097 case M16_OPC_RR:
10098 switch (op1) {
10099 case RR_JR:
10100 {
10101 int nd = (ctx->opcode >> 7) & 0x1;
10102 int link = (ctx->opcode >> 6) & 0x1;
10103 int ra = (ctx->opcode >> 5) & 0x1;
10104
10105 if (link) {
10106 op = nd ? OPC_JALRC : OPC_JALRS;
10107 } else {
10108 op = OPC_JR;
10109 }
10110
10111 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10112 if (!nd) {
10113 *is_branch = 1;
10114 }
10115 }
10116 break;
10117 case RR_SDBBP:
10118 /* XXX: not clear which exception should be raised
10119 * when in debug mode...
10120 */
10121 check_insn(env, ctx, ISA_MIPS32);
10122 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10123 generate_exception(ctx, EXCP_DBp);
10124 } else {
10125 generate_exception(ctx, EXCP_DBp);
10126 }
10127 break;
10128 case RR_SLT:
10129 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10130 break;
10131 case RR_SLTU:
10132 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10133 break;
10134 case RR_BREAK:
10135 generate_exception(ctx, EXCP_BREAK);
10136 break;
10137 case RR_SLLV:
10138 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10139 break;
10140 case RR_SRLV:
10141 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10142 break;
10143 case RR_SRAV:
10144 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10145 break;
10146 #if defined (TARGET_MIPS64)
10147 case RR_DSRL:
10148 check_mips_64(ctx);
10149 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10150 break;
10151 #endif
10152 case RR_CMP:
10153 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10154 break;
10155 case RR_NEG:
10156 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10157 break;
10158 case RR_AND:
10159 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10160 break;
10161 case RR_OR:
10162 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10163 break;
10164 case RR_XOR:
10165 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10166 break;
10167 case RR_NOT:
10168 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10169 break;
10170 case RR_MFHI:
10171 gen_HILO(ctx, OPC_MFHI, rx);
10172 break;
10173 case RR_CNVT:
10174 switch (cnvt_op) {
10175 case RR_RY_CNVT_ZEB:
10176 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10177 break;
10178 case RR_RY_CNVT_ZEH:
10179 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10180 break;
10181 case RR_RY_CNVT_SEB:
10182 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10183 break;
10184 case RR_RY_CNVT_SEH:
10185 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10186 break;
10187 #if defined (TARGET_MIPS64)
10188 case RR_RY_CNVT_ZEW:
10189 check_mips_64(ctx);
10190 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10191 break;
10192 case RR_RY_CNVT_SEW:
10193 check_mips_64(ctx);
10194 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10195 break;
10196 #endif
10197 default:
10198 generate_exception(ctx, EXCP_RI);
10199 break;
10200 }
10201 break;
10202 case RR_MFLO:
10203 gen_HILO(ctx, OPC_MFLO, rx);
10204 break;
10205 #if defined (TARGET_MIPS64)
10206 case RR_DSRA:
10207 check_mips_64(ctx);
10208 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10209 break;
10210 case RR_DSLLV:
10211 check_mips_64(ctx);
10212 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10213 break;
10214 case RR_DSRLV:
10215 check_mips_64(ctx);
10216 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10217 break;
10218 case RR_DSRAV:
10219 check_mips_64(ctx);
10220 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10221 break;
10222 #endif
10223 case RR_MULT:
10224 gen_muldiv(ctx, OPC_MULT, rx, ry);
10225 break;
10226 case RR_MULTU:
10227 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10228 break;
10229 case RR_DIV:
10230 gen_muldiv(ctx, OPC_DIV, rx, ry);
10231 break;
10232 case RR_DIVU:
10233 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10234 break;
10235 #if defined (TARGET_MIPS64)
10236 case RR_DMULT:
10237 check_mips_64(ctx);
10238 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10239 break;
10240 case RR_DMULTU:
10241 check_mips_64(ctx);
10242 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10243 break;
10244 case RR_DDIV:
10245 check_mips_64(ctx);
10246 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10247 break;
10248 case RR_DDIVU:
10249 check_mips_64(ctx);
10250 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10251 break;
10252 #endif
10253 default:
10254 generate_exception(ctx, EXCP_RI);
10255 break;
10256 }
10257 break;
10258 case M16_OPC_EXTEND:
10259 decode_extended_mips16_opc(env, ctx, is_branch);
10260 n_bytes = 4;
10261 break;
10262 #if defined(TARGET_MIPS64)
10263 case M16_OPC_I64:
10264 funct = (ctx->opcode >> 8) & 0x7;
10265 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10266 break;
10267 #endif
10268 default:
10269 generate_exception(ctx, EXCP_RI);
10270 break;
10271 }
10272
10273 return n_bytes;
10274 }
10275
10276 /* microMIPS extension to MIPS32 */
10277
10278 /* microMIPS32 major opcodes */
10279
10280 enum {
10281 POOL32A = 0x00,
10282 POOL16A = 0x01,
10283 LBU16 = 0x02,
10284 MOVE16 = 0x03,
10285 ADDI32 = 0x04,
10286 LBU32 = 0x05,
10287 SB32 = 0x06,
10288 LB32 = 0x07,
10289
10290 POOL32B = 0x08,
10291 POOL16B = 0x09,
10292 LHU16 = 0x0a,
10293 ANDI16 = 0x0b,
10294 ADDIU32 = 0x0c,
10295 LHU32 = 0x0d,
10296 SH32 = 0x0e,
10297 LH32 = 0x0f,
10298
10299 POOL32I = 0x10,
10300 POOL16C = 0x11,
10301 LWSP16 = 0x12,
10302 POOL16D = 0x13,
10303 ORI32 = 0x14,
10304 POOL32F = 0x15,
10305 POOL32S = 0x16,
10306 DADDIU32 = 0x17,
10307
10308 POOL32C = 0x18,
10309 LWGP16 = 0x19,
10310 LW16 = 0x1a,
10311 POOL16E = 0x1b,
10312 XORI32 = 0x1c,
10313 JALS32 = 0x1d,
10314 ADDIUPC = 0x1e,
10315 POOL48A = 0x1f,
10316
10317 /* 0x20 is reserved */
10318 RES_20 = 0x20,
10319 POOL16F = 0x21,
10320 SB16 = 0x22,
10321 BEQZ16 = 0x23,
10322 SLTI32 = 0x24,
10323 BEQ32 = 0x25,
10324 SWC132 = 0x26,
10325 LWC132 = 0x27,
10326
10327 /* 0x28 and 0x29 are reserved */
10328 RES_28 = 0x28,
10329 RES_29 = 0x29,
10330 SH16 = 0x2a,
10331 BNEZ16 = 0x2b,
10332 SLTIU32 = 0x2c,
10333 BNE32 = 0x2d,
10334 SDC132 = 0x2e,
10335 LDC132 = 0x2f,
10336
10337 /* 0x30 and 0x31 are reserved */
10338 RES_30 = 0x30,
10339 RES_31 = 0x31,
10340 SWSP16 = 0x32,
10341 B16 = 0x33,
10342 ANDI32 = 0x34,
10343 J32 = 0x35,
10344 SD32 = 0x36,
10345 LD32 = 0x37,
10346
10347 /* 0x38 and 0x39 are reserved */
10348 RES_38 = 0x38,
10349 RES_39 = 0x39,
10350 SW16 = 0x3a,
10351 LI16 = 0x3b,
10352 JALX32 = 0x3c,
10353 JAL32 = 0x3d,
10354 SW32 = 0x3e,
10355 LW32 = 0x3f
10356 };
10357
10358 /* POOL32A encoding of minor opcode field */
10359
10360 enum {
10361 /* These opcodes are distinguished only by bits 9..6; those bits are
10362 * what are recorded below. */
10363 SLL32 = 0x0,
10364 SRL32 = 0x1,
10365 SRA = 0x2,
10366 ROTR = 0x3,
10367
10368 SLLV = 0x0,
10369 SRLV = 0x1,
10370 SRAV = 0x2,
10371 ROTRV = 0x3,
10372 ADD = 0x4,
10373 ADDU32 = 0x5,
10374 SUB = 0x6,
10375 SUBU32 = 0x7,
10376 MUL = 0x8,
10377 AND = 0x9,
10378 OR32 = 0xa,
10379 NOR = 0xb,
10380 XOR32 = 0xc,
10381 SLT = 0xd,
10382 SLTU = 0xe,
10383
10384 MOVN = 0x0,
10385 MOVZ = 0x1,
10386 LWXS = 0x4,
10387
10388 /* The following can be distinguished by their lower 6 bits. */
10389 INS = 0x0c,
10390 EXT = 0x2c,
10391 POOL32AXF = 0x3c
10392 };
10393
10394 /* POOL32AXF encoding of minor opcode field extension */
10395
10396 enum {
10397 /* bits 11..6 */
10398 TEQ = 0x00,
10399 TGE = 0x08,
10400 TGEU = 0x10,
10401 TLT = 0x20,
10402 TLTU = 0x28,
10403 TNE = 0x30,
10404
10405 MFC0 = 0x03,
10406 MTC0 = 0x0b,
10407
10408 /* bits 13..12 for 0x01 */
10409 MFHI_ACC = 0x0,
10410 MFLO_ACC = 0x1,
10411 MTHI_ACC = 0x2,
10412 MTLO_ACC = 0x3,
10413
10414 /* bits 13..12 for 0x2a */
10415 MADD_ACC = 0x0,
10416 MADDU_ACC = 0x1,
10417 MSUB_ACC = 0x2,
10418 MSUBU_ACC = 0x3,
10419
10420 /* bits 13..12 for 0x32 */
10421 MULT_ACC = 0x0,
10422 MULTU_ACC = 0x0,
10423
10424 /* bits 15..12 for 0x2c */
10425 SEB = 0x2,
10426 SEH = 0x3,
10427 CLO = 0x4,
10428 CLZ = 0x5,
10429 RDHWR = 0x6,
10430 WSBH = 0x7,
10431 MULT = 0x8,
10432 MULTU = 0x9,
10433 DIV = 0xa,
10434 DIVU = 0xb,
10435 MADD = 0xc,
10436 MADDU = 0xd,
10437 MSUB = 0xe,
10438 MSUBU = 0xf,
10439
10440 /* bits 15..12 for 0x34 */
10441 MFC2 = 0x4,
10442 MTC2 = 0x5,
10443 MFHC2 = 0x8,
10444 MTHC2 = 0x9,
10445 CFC2 = 0xc,
10446 CTC2 = 0xd,
10447
10448 /* bits 15..12 for 0x3c */
10449 JALR = 0x0,
10450 JR = 0x0, /* alias */
10451 JALR_HB = 0x1,
10452 JALRS = 0x4,
10453 JALRS_HB = 0x5,
10454
10455 /* bits 15..12 for 0x05 */
10456 RDPGPR = 0xe,
10457 WRPGPR = 0xf,
10458
10459 /* bits 15..12 for 0x0d */
10460 TLBP = 0x0,
10461 TLBR = 0x1,
10462 TLBWI = 0x2,
10463 TLBWR = 0x3,
10464 WAIT = 0x9,
10465 IRET = 0xd,
10466 DERET = 0xe,
10467 ERET = 0xf,
10468
10469 /* bits 15..12 for 0x15 */
10470 DMT = 0x0,
10471 DVPE = 0x1,
10472 EMT = 0x2,
10473 EVPE = 0x3,
10474
10475 /* bits 15..12 for 0x1d */
10476 DI = 0x4,
10477 EI = 0x5,
10478
10479 /* bits 15..12 for 0x2d */
10480 SYNC = 0x6,
10481 SYSCALL = 0x8,
10482 SDBBP = 0xd,
10483
10484 /* bits 15..12 for 0x35 */
10485 MFHI32 = 0x0,
10486 MFLO32 = 0x1,
10487 MTHI32 = 0x2,
10488 MTLO32 = 0x3,
10489 };
10490
10491 /* POOL32B encoding of minor opcode field (bits 15..12) */
10492
10493 enum {
10494 LWC2 = 0x0,
10495 LWP = 0x1,
10496 LDP = 0x4,
10497 LWM32 = 0x5,
10498 CACHE = 0x6,
10499 LDM = 0x7,
10500 SWC2 = 0x8,
10501 SWP = 0x9,
10502 SDP = 0xc,
10503 SWM32 = 0xd,
10504 SDM = 0xf
10505 };
10506
10507 /* POOL32C encoding of minor opcode field (bits 15..12) */
10508
10509 enum {
10510 LWL = 0x0,
10511 SWL = 0x8,
10512 LWR = 0x1,
10513 SWR = 0x9,
10514 PREF = 0x2,
10515 /* 0xa is reserved */
10516 LL = 0x3,
10517 SC = 0xb,
10518 LDL = 0x4,
10519 SDL = 0xc,
10520 LDR = 0x5,
10521 SDR = 0xd,
10522 /* 0x6 is reserved */
10523 LWU = 0xe,
10524 LLD = 0x7,
10525 SCD = 0xf
10526 };
10527
10528 /* POOL32F encoding of minor opcode field (bits 5..0) */
10529
10530 enum {
10531 /* These are the bit 7..6 values */
10532 ADD_FMT = 0x0,
10533 MOVN_FMT = 0x0,
10534
10535 SUB_FMT = 0x1,
10536 MOVZ_FMT = 0x1,
10537
10538 MUL_FMT = 0x2,
10539
10540 DIV_FMT = 0x3,
10541
10542 /* These are the bit 8..6 values */
10543 RSQRT2_FMT = 0x0,
10544 MOVF_FMT = 0x0,
10545
10546 LWXC1 = 0x1,
10547 MOVT_FMT = 0x1,
10548
10549 PLL_PS = 0x2,
10550 SWXC1 = 0x2,
10551
10552 PLU_PS = 0x3,
10553 LDXC1 = 0x3,
10554
10555 PUL_PS = 0x4,
10556 SDXC1 = 0x4,
10557 RECIP2_FMT = 0x4,
10558
10559 PUU_PS = 0x5,
10560 LUXC1 = 0x5,
10561
10562 CVT_PS_S = 0x6,
10563 SUXC1 = 0x6,
10564 ADDR_PS = 0x6,
10565 PREFX = 0x6,
10566
10567 MULR_PS = 0x7,
10568
10569 MADD_S = 0x01,
10570 MADD_D = 0x09,
10571 MADD_PS = 0x11,
10572 ALNV_PS = 0x19,
10573 MSUB_S = 0x21,
10574 MSUB_D = 0x29,
10575 MSUB_PS = 0x31,
10576
10577 NMADD_S = 0x02,
10578 NMADD_D = 0x0a,
10579 NMADD_PS = 0x12,
10580 NMSUB_S = 0x22,
10581 NMSUB_D = 0x2a,
10582 NMSUB_PS = 0x32,
10583
10584 POOL32FXF = 0x3b,
10585
10586 CABS_COND_FMT = 0x1c, /* MIPS3D */
10587 C_COND_FMT = 0x3c
10588 };
10589
10590 /* POOL32Fxf encoding of minor opcode extension field */
10591
10592 enum {
10593 CVT_L = 0x04,
10594 RSQRT_FMT = 0x08,
10595 FLOOR_L = 0x0c,
10596 CVT_PW_PS = 0x1c,
10597 CVT_W = 0x24,
10598 SQRT_FMT = 0x28,
10599 FLOOR_W = 0x2c,
10600 CVT_PS_PW = 0x3c,
10601 CFC1 = 0x40,
10602 RECIP_FMT = 0x48,
10603 CEIL_L = 0x4c,
10604 CTC1 = 0x60,
10605 CEIL_W = 0x6c,
10606 MFC1 = 0x80,
10607 CVT_S_PL = 0x84,
10608 TRUNC_L = 0x8c,
10609 MTC1 = 0xa0,
10610 CVT_S_PU = 0xa4,
10611 TRUNC_W = 0xac,
10612 MFHC1 = 0xc0,
10613 ROUND_L = 0xcc,
10614 MTHC1 = 0xe0,
10615 ROUND_W = 0xec,
10616
10617 MOV_FMT = 0x01,
10618 MOVF = 0x05,
10619 ABS_FMT = 0x0d,
10620 RSQRT1_FMT = 0x1d,
10621 MOVT = 0x25,
10622 NEG_FMT = 0x2d,
10623 CVT_D = 0x4d,
10624 RECIP1_FMT = 0x5d,
10625 CVT_S = 0x6d
10626 };
10627
10628 /* POOL32I encoding of minor opcode field (bits 25..21) */
10629
10630 enum {
10631 BLTZ = 0x00,
10632 BLTZAL = 0x01,
10633 BGEZ = 0x02,
10634 BGEZAL = 0x03,
10635 BLEZ = 0x04,
10636 BNEZC = 0x05,
10637 BGTZ = 0x06,
10638 BEQZC = 0x07,
10639 TLTI = 0x08,
10640 TGEI = 0x09,
10641 TLTIU = 0x0a,
10642 TGEIU = 0x0b,
10643 TNEI = 0x0c,
10644 LUI = 0x0d,
10645 TEQI = 0x0e,
10646 SYNCI = 0x10,
10647 BLTZALS = 0x11,
10648 BGEZALS = 0x13,
10649 BC2F = 0x14,
10650 BC2T = 0x15,
10651 BPOSGE64 = 0x1a,
10652 BPOSGE32 = 0x1b,
10653 /* These overlap and are distinguished by bit16 of the instruction */
10654 BC1F = 0x1c,
10655 BC1T = 0x1d,
10656 BC1ANY2F = 0x1c,
10657 BC1ANY2T = 0x1d,
10658 BC1ANY4F = 0x1e,
10659 BC1ANY4T = 0x1f
10660 };
10661
10662 /* POOL16A encoding of minor opcode field */
10663
10664 enum {
10665 ADDU16 = 0x0,
10666 SUBU16 = 0x1
10667 };
10668
10669 /* POOL16B encoding of minor opcode field */
10670
10671 enum {
10672 SLL16 = 0x0,
10673 SRL16 = 0x1
10674 };
10675
10676 /* POOL16C encoding of minor opcode field */
10677
10678 enum {
10679 NOT16 = 0x00,
10680 XOR16 = 0x04,
10681 AND16 = 0x08,
10682 OR16 = 0x0c,
10683 LWM16 = 0x10,
10684 SWM16 = 0x14,
10685 JR16 = 0x18,
10686 JRC16 = 0x1a,
10687 JALR16 = 0x1c,
10688 JALR16S = 0x1e,
10689 MFHI16 = 0x20,
10690 MFLO16 = 0x24,
10691 BREAK16 = 0x28,
10692 SDBBP16 = 0x2c,
10693 JRADDIUSP = 0x30
10694 };
10695
10696 /* POOL16D encoding of minor opcode field */
10697
10698 enum {
10699 ADDIUS5 = 0x0,
10700 ADDIUSP = 0x1
10701 };
10702
10703 /* POOL16E encoding of minor opcode field */
10704
10705 enum {
10706 ADDIUR2 = 0x0,
10707 ADDIUR1SP = 0x1
10708 };
10709
10710 static int mmreg (int r)
10711 {
10712 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10713
10714 return map[r];
10715 }
10716
10717 /* Used for 16-bit store instructions. */
10718 static int mmreg2 (int r)
10719 {
10720 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10721
10722 return map[r];
10723 }
10724
10725 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10726 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10727 #define uMIPS_RS2(op) uMIPS_RS(op)
10728 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10729 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10730 #define uMIPS_RS5(op) (op & 0x1f)
10731
10732 /* Signed immediate */
10733 #define SIMM(op, start, width) \
10734 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10735 << (32-width)) \
10736 >> (32-width))
10737 /* Zero-extended immediate */
10738 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10739
10740 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10741 {
10742 int rd = mmreg(uMIPS_RD(ctx->opcode));
10743
10744 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10745 }
10746
10747 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10748 {
10749 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10750 int rd = mmreg(uMIPS_RD(ctx->opcode));
10751 int rs = mmreg(uMIPS_RS(ctx->opcode));
10752
10753 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10754 }
10755
10756 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10757 {
10758 int encoded = ZIMM(ctx->opcode, 1, 9);
10759 int decoded;
10760
10761 if (encoded <= 1) {
10762 decoded = 256 + encoded;
10763 } else if (encoded <= 255) {
10764 decoded = encoded;
10765 } else if (encoded <= 509) {
10766 decoded = encoded - 512;
10767 } else {
10768 decoded = encoded - 768;
10769 }
10770
10771 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10772 }
10773
10774 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10775 {
10776 int imm = SIMM(ctx->opcode, 1, 4);
10777 int rd = (ctx->opcode >> 5) & 0x1f;
10778
10779 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10780 }
10781
10782 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10783 {
10784 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10785 31, 32, 63, 64, 255, 32768, 65535 };
10786 int rd = mmreg(uMIPS_RD(ctx->opcode));
10787 int rs = mmreg(uMIPS_RS(ctx->opcode));
10788 int encoded = ZIMM(ctx->opcode, 0, 4);
10789
10790 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10791 }
10792
10793 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10794 int base, int16_t offset)
10795 {
10796 const char *opn = "ldst_multiple";
10797 TCGv t0, t1;
10798 TCGv_i32 t2;
10799
10800 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10801 generate_exception(ctx, EXCP_RI);
10802 return;
10803 }
10804
10805 t0 = tcg_temp_new();
10806
10807 gen_base_offset_addr(ctx, t0, base, offset);
10808
10809 t1 = tcg_const_tl(reglist);
10810 t2 = tcg_const_i32(ctx->mem_idx);
10811
10812 save_cpu_state(ctx, 1);
10813 switch (opc) {
10814 case LWM32:
10815 gen_helper_lwm(cpu_env, t0, t1, t2);
10816 opn = "lwm";
10817 break;
10818 case SWM32:
10819 gen_helper_swm(cpu_env, t0, t1, t2);
10820 opn = "swm";
10821 break;
10822 #ifdef TARGET_MIPS64
10823 case LDM:
10824 gen_helper_ldm(cpu_env, t0, t1, t2);
10825 opn = "ldm";
10826 break;
10827 case SDM:
10828 gen_helper_sdm(cpu_env, t0, t1, t2);
10829 opn = "sdm";
10830 break;
10831 #endif
10832 }
10833 (void)opn;
10834 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10835 tcg_temp_free(t0);
10836 tcg_temp_free(t1);
10837 tcg_temp_free_i32(t2);
10838 }
10839
10840
10841 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10842 {
10843 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10844 int rs = mmreg(ctx->opcode & 0x7);
10845 int opc;
10846
10847 switch (((ctx->opcode) >> 4) & 0x3f) {
10848 case NOT16 + 0:
10849 case NOT16 + 1:
10850 case NOT16 + 2:
10851 case NOT16 + 3:
10852 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10853 break;
10854 case XOR16 + 0:
10855 case XOR16 + 1:
10856 case XOR16 + 2:
10857 case XOR16 + 3:
10858 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10859 break;
10860 case AND16 + 0:
10861 case AND16 + 1:
10862 case AND16 + 2:
10863 case AND16 + 3:
10864 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10865 break;
10866 case OR16 + 0:
10867 case OR16 + 1:
10868 case OR16 + 2:
10869 case OR16 + 3:
10870 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10871 break;
10872 case LWM16 + 0:
10873 case LWM16 + 1:
10874 case LWM16 + 2:
10875 case LWM16 + 3:
10876 {
10877 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10878 int offset = ZIMM(ctx->opcode, 0, 4);
10879
10880 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10881 29, offset << 2);
10882 }
10883 break;
10884 case SWM16 + 0:
10885 case SWM16 + 1:
10886 case SWM16 + 2:
10887 case SWM16 + 3:
10888 {
10889 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10890 int offset = ZIMM(ctx->opcode, 0, 4);
10891
10892 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10893 29, offset << 2);
10894 }
10895 break;
10896 case JR16 + 0:
10897 case JR16 + 1:
10898 {
10899 int reg = ctx->opcode & 0x1f;
10900
10901 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10902 }
10903 *is_branch = 1;
10904 break;
10905 case JRC16 + 0:
10906 case JRC16 + 1:
10907 {
10908 int reg = ctx->opcode & 0x1f;
10909
10910 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10911 /* Let normal delay slot handling in our caller take us
10912 to the branch target. */
10913 }
10914 break;
10915 case JALR16 + 0:
10916 case JALR16 + 1:
10917 opc = OPC_JALR;
10918 goto do_jalr;
10919 case JALR16S + 0:
10920 case JALR16S + 1:
10921 opc = OPC_JALRS;
10922 do_jalr:
10923 {
10924 int reg = ctx->opcode & 0x1f;
10925
10926 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10927 }
10928 *is_branch = 1;
10929 break;
10930 case MFHI16 + 0:
10931 case MFHI16 + 1:
10932 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10933 break;
10934 case MFLO16 + 0:
10935 case MFLO16 + 1:
10936 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10937 break;
10938 case BREAK16:
10939 generate_exception(ctx, EXCP_BREAK);
10940 break;
10941 case SDBBP16:
10942 /* XXX: not clear which exception should be raised
10943 * when in debug mode...
10944 */
10945 check_insn(env, ctx, ISA_MIPS32);
10946 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10947 generate_exception(ctx, EXCP_DBp);
10948 } else {
10949 generate_exception(ctx, EXCP_DBp);
10950 }
10951 break;
10952 case JRADDIUSP + 0:
10953 case JRADDIUSP + 1:
10954 {
10955 int imm = ZIMM(ctx->opcode, 0, 5);
10956
10957 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10958 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10959 /* Let normal delay slot handling in our caller take us
10960 to the branch target. */
10961 }
10962 break;
10963 default:
10964 generate_exception(ctx, EXCP_RI);
10965 break;
10966 }
10967 }
10968
10969 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10970 {
10971 TCGv t0 = tcg_temp_new();
10972 TCGv t1 = tcg_temp_new();
10973
10974 gen_load_gpr(t0, base);
10975
10976 if (index != 0) {
10977 gen_load_gpr(t1, index);
10978 tcg_gen_shli_tl(t1, t1, 2);
10979 gen_op_addr_add(ctx, t0, t1, t0);
10980 }
10981
10982 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10983 gen_store_gpr(t1, rd);
10984
10985 tcg_temp_free(t0);
10986 tcg_temp_free(t1);
10987 }
10988
10989 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10990 int base, int16_t offset)
10991 {
10992 const char *opn = "ldst_pair";
10993 TCGv t0, t1;
10994
10995 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10996 generate_exception(ctx, EXCP_RI);
10997 return;
10998 }
10999
11000 t0 = tcg_temp_new();
11001 t1 = tcg_temp_new();
11002
11003 gen_base_offset_addr(ctx, t0, base, offset);
11004
11005 switch (opc) {
11006 case LWP:
11007 if (rd == base) {
11008 generate_exception(ctx, EXCP_RI);
11009 return;
11010 }
11011 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11012 gen_store_gpr(t1, rd);
11013 tcg_gen_movi_tl(t1, 4);
11014 gen_op_addr_add(ctx, t0, t0, t1);
11015 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11016 gen_store_gpr(t1, rd+1);
11017 opn = "lwp";
11018 break;
11019 case SWP:
11020 gen_load_gpr(t1, rd);
11021 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11022 tcg_gen_movi_tl(t1, 4);
11023 gen_op_addr_add(ctx, t0, t0, t1);
11024 gen_load_gpr(t1, rd+1);
11025 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11026 opn = "swp";
11027 break;
11028 #ifdef TARGET_MIPS64
11029 case LDP:
11030 if (rd == base) {
11031 generate_exception(ctx, EXCP_RI);
11032 return;
11033 }
11034 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11035 gen_store_gpr(t1, rd);
11036 tcg_gen_movi_tl(t1, 8);
11037 gen_op_addr_add(ctx, t0, t0, t1);
11038 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11039 gen_store_gpr(t1, rd+1);
11040 opn = "ldp";
11041 break;
11042 case SDP:
11043 gen_load_gpr(t1, rd);
11044 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11045 tcg_gen_movi_tl(t1, 8);
11046 gen_op_addr_add(ctx, t0, t0, t1);
11047 gen_load_gpr(t1, rd+1);
11048 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11049 opn = "sdp";
11050 break;
11051 #endif
11052 }
11053 (void)opn; /* avoid a compiler warning */
11054 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11055 tcg_temp_free(t0);
11056 tcg_temp_free(t1);
11057 }
11058
11059 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11060 int *is_branch)
11061 {
11062 int extension = (ctx->opcode >> 6) & 0x3f;
11063 int minor = (ctx->opcode >> 12) & 0xf;
11064 uint32_t mips32_op;
11065
11066 switch (extension) {
11067 case TEQ:
11068 mips32_op = OPC_TEQ;
11069 goto do_trap;
11070 case TGE:
11071 mips32_op = OPC_TGE;
11072 goto do_trap;
11073 case TGEU:
11074 mips32_op = OPC_TGEU;
11075 goto do_trap;
11076 case TLT:
11077 mips32_op = OPC_TLT;
11078 goto do_trap;
11079 case TLTU:
11080 mips32_op = OPC_TLTU;
11081 goto do_trap;
11082 case TNE:
11083 mips32_op = OPC_TNE;
11084 do_trap:
11085 gen_trap(ctx, mips32_op, rs, rt, -1);
11086 break;
11087 #ifndef CONFIG_USER_ONLY
11088 case MFC0:
11089 case MFC0 + 32:
11090 check_cp0_enabled(ctx);
11091 if (rt == 0) {
11092 /* Treat as NOP. */
11093 break;
11094 }
11095 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11096 break;
11097 case MTC0:
11098 case MTC0 + 32:
11099 check_cp0_enabled(ctx);
11100 {
11101 TCGv t0 = tcg_temp_new();
11102
11103 gen_load_gpr(t0, rt);
11104 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11105 tcg_temp_free(t0);
11106 }
11107 break;
11108 #endif
11109 case 0x2c:
11110 switch (minor) {
11111 case SEB:
11112 gen_bshfl(ctx, OPC_SEB, rs, rt);
11113 break;
11114 case SEH:
11115 gen_bshfl(ctx, OPC_SEH, rs, rt);
11116 break;
11117 case CLO:
11118 mips32_op = OPC_CLO;
11119 goto do_cl;
11120 case CLZ:
11121 mips32_op = OPC_CLZ;
11122 do_cl:
11123 check_insn(env, ctx, ISA_MIPS32);
11124 gen_cl(ctx, mips32_op, rt, rs);
11125 break;
11126 case RDHWR:
11127 gen_rdhwr(env, ctx, rt, rs);
11128 break;
11129 case WSBH:
11130 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11131 break;
11132 case MULT:
11133 mips32_op = OPC_MULT;
11134 goto do_muldiv;
11135 case MULTU:
11136 mips32_op = OPC_MULTU;
11137 goto do_muldiv;
11138 case DIV:
11139 mips32_op = OPC_DIV;
11140 goto do_muldiv;
11141 case DIVU:
11142 mips32_op = OPC_DIVU;
11143 goto do_muldiv;
11144 case MADD:
11145 mips32_op = OPC_MADD;
11146 goto do_muldiv;
11147 case MADDU:
11148 mips32_op = OPC_MADDU;
11149 goto do_muldiv;
11150 case MSUB:
11151 mips32_op = OPC_MSUB;
11152 goto do_muldiv;
11153 case MSUBU:
11154 mips32_op = OPC_MSUBU;
11155 do_muldiv:
11156 check_insn(env, ctx, ISA_MIPS32);
11157 gen_muldiv(ctx, mips32_op, rs, rt);
11158 break;
11159 default:
11160 goto pool32axf_invalid;
11161 }
11162 break;
11163 case 0x34:
11164 switch (minor) {
11165 case MFC2:
11166 case MTC2:
11167 case MFHC2:
11168 case MTHC2:
11169 case CFC2:
11170 case CTC2:
11171 generate_exception_err(ctx, EXCP_CpU, 2);
11172 break;
11173 default:
11174 goto pool32axf_invalid;
11175 }
11176 break;
11177 case 0x3c:
11178 switch (minor) {
11179 case JALR:
11180 case JALR_HB:
11181 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11182 *is_branch = 1;
11183 break;
11184 case JALRS:
11185 case JALRS_HB:
11186 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11187 *is_branch = 1;
11188 break;
11189 default:
11190 goto pool32axf_invalid;
11191 }
11192 break;
11193 case 0x05:
11194 switch (minor) {
11195 case RDPGPR:
11196 check_cp0_enabled(ctx);
11197 check_insn(env, ctx, ISA_MIPS32R2);
11198 gen_load_srsgpr(rt, rs);
11199 break;
11200 case WRPGPR:
11201 check_cp0_enabled(ctx);
11202 check_insn(env, ctx, ISA_MIPS32R2);
11203 gen_store_srsgpr(rt, rs);
11204 break;
11205 default:
11206 goto pool32axf_invalid;
11207 }
11208 break;
11209 #ifndef CONFIG_USER_ONLY
11210 case 0x0d:
11211 switch (minor) {
11212 case TLBP:
11213 mips32_op = OPC_TLBP;
11214 goto do_cp0;
11215 case TLBR:
11216 mips32_op = OPC_TLBR;
11217 goto do_cp0;
11218 case TLBWI:
11219 mips32_op = OPC_TLBWI;
11220 goto do_cp0;
11221 case TLBWR:
11222 mips32_op = OPC_TLBWR;
11223 goto do_cp0;
11224 case WAIT:
11225 mips32_op = OPC_WAIT;
11226 goto do_cp0;
11227 case DERET:
11228 mips32_op = OPC_DERET;
11229 goto do_cp0;
11230 case ERET:
11231 mips32_op = OPC_ERET;
11232 do_cp0:
11233 gen_cp0(env, ctx, mips32_op, rt, rs);
11234 break;
11235 default:
11236 goto pool32axf_invalid;
11237 }
11238 break;
11239 case 0x1d:
11240 switch (minor) {
11241 case DI:
11242 check_cp0_enabled(ctx);
11243 {
11244 TCGv t0 = tcg_temp_new();
11245
11246 save_cpu_state(ctx, 1);
11247 gen_helper_di(t0, cpu_env);
11248 gen_store_gpr(t0, rs);
11249 /* Stop translation as we may have switched the execution mode */
11250 ctx->bstate = BS_STOP;
11251 tcg_temp_free(t0);
11252 }
11253 break;
11254 case EI:
11255 check_cp0_enabled(ctx);
11256 {
11257 TCGv t0 = tcg_temp_new();
11258
11259 save_cpu_state(ctx, 1);
11260 gen_helper_ei(t0, cpu_env);
11261 gen_store_gpr(t0, rs);
11262 /* Stop translation as we may have switched the execution mode */
11263 ctx->bstate = BS_STOP;
11264 tcg_temp_free(t0);
11265 }
11266 break;
11267 default:
11268 goto pool32axf_invalid;
11269 }
11270 break;
11271 #endif
11272 case 0x2d:
11273 switch (minor) {
11274 case SYNC:
11275 /* NOP */
11276 break;
11277 case SYSCALL:
11278 generate_exception(ctx, EXCP_SYSCALL);
11279 ctx->bstate = BS_STOP;
11280 break;
11281 case SDBBP:
11282 check_insn(env, ctx, ISA_MIPS32);
11283 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11284 generate_exception(ctx, EXCP_DBp);
11285 } else {
11286 generate_exception(ctx, EXCP_DBp);
11287 }
11288 break;
11289 default:
11290 goto pool32axf_invalid;
11291 }
11292 break;
11293 case 0x35:
11294 switch (minor) {
11295 case MFHI32:
11296 gen_HILO(ctx, OPC_MFHI, rs);
11297 break;
11298 case MFLO32:
11299 gen_HILO(ctx, OPC_MFLO, rs);
11300 break;
11301 case MTHI32:
11302 gen_HILO(ctx, OPC_MTHI, rs);
11303 break;
11304 case MTLO32:
11305 gen_HILO(ctx, OPC_MTLO, rs);
11306 break;
11307 default:
11308 goto pool32axf_invalid;
11309 }
11310 break;
11311 default:
11312 pool32axf_invalid:
11313 MIPS_INVAL("pool32axf");
11314 generate_exception(ctx, EXCP_RI);
11315 break;
11316 }
11317 }
11318
11319 /* Values for microMIPS fmt field. Variable-width, depending on which
11320 formats the instruction supports. */
11321
11322 enum {
11323 FMT_SD_S = 0,
11324 FMT_SD_D = 1,
11325
11326 FMT_SDPS_S = 0,
11327 FMT_SDPS_D = 1,
11328 FMT_SDPS_PS = 2,
11329
11330 FMT_SWL_S = 0,
11331 FMT_SWL_W = 1,
11332 FMT_SWL_L = 2,
11333
11334 FMT_DWL_D = 0,
11335 FMT_DWL_W = 1,
11336 FMT_DWL_L = 2
11337 };
11338
11339 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11340 {
11341 int extension = (ctx->opcode >> 6) & 0x3ff;
11342 uint32_t mips32_op;
11343
11344 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11345 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11346 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11347
11348 switch (extension) {
11349 case FLOAT_1BIT_FMT(CFC1, 0):
11350 mips32_op = OPC_CFC1;
11351 goto do_cp1;
11352 case FLOAT_1BIT_FMT(CTC1, 0):
11353 mips32_op = OPC_CTC1;
11354 goto do_cp1;
11355 case FLOAT_1BIT_FMT(MFC1, 0):
11356 mips32_op = OPC_MFC1;
11357 goto do_cp1;
11358 case FLOAT_1BIT_FMT(MTC1, 0):
11359 mips32_op = OPC_MTC1;
11360 goto do_cp1;
11361 case FLOAT_1BIT_FMT(MFHC1, 0):
11362 mips32_op = OPC_MFHC1;
11363 goto do_cp1;
11364 case FLOAT_1BIT_FMT(MTHC1, 0):
11365 mips32_op = OPC_MTHC1;
11366 do_cp1:
11367 gen_cp1(ctx, mips32_op, rt, rs);
11368 break;
11369
11370 /* Reciprocal square root */
11371 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11372 mips32_op = OPC_RSQRT_S;
11373 goto do_unaryfp;
11374 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11375 mips32_op = OPC_RSQRT_D;
11376 goto do_unaryfp;
11377
11378 /* Square root */
11379 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11380 mips32_op = OPC_SQRT_S;
11381 goto do_unaryfp;
11382 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11383 mips32_op = OPC_SQRT_D;
11384 goto do_unaryfp;
11385
11386 /* Reciprocal */
11387 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11388 mips32_op = OPC_RECIP_S;
11389 goto do_unaryfp;
11390 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11391 mips32_op = OPC_RECIP_D;
11392 goto do_unaryfp;
11393
11394 /* Floor */
11395 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11396 mips32_op = OPC_FLOOR_L_S;
11397 goto do_unaryfp;
11398 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11399 mips32_op = OPC_FLOOR_L_D;
11400 goto do_unaryfp;
11401 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11402 mips32_op = OPC_FLOOR_W_S;
11403 goto do_unaryfp;
11404 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11405 mips32_op = OPC_FLOOR_W_D;
11406 goto do_unaryfp;
11407
11408 /* Ceiling */
11409 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11410 mips32_op = OPC_CEIL_L_S;
11411 goto do_unaryfp;
11412 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11413 mips32_op = OPC_CEIL_L_D;
11414 goto do_unaryfp;
11415 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11416 mips32_op = OPC_CEIL_W_S;
11417 goto do_unaryfp;
11418 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11419 mips32_op = OPC_CEIL_W_D;
11420 goto do_unaryfp;
11421
11422 /* Truncation */
11423 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11424 mips32_op = OPC_TRUNC_L_S;
11425 goto do_unaryfp;
11426 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11427 mips32_op = OPC_TRUNC_L_D;
11428 goto do_unaryfp;
11429 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11430 mips32_op = OPC_TRUNC_W_S;
11431 goto do_unaryfp;
11432 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11433 mips32_op = OPC_TRUNC_W_D;
11434 goto do_unaryfp;
11435
11436 /* Round */
11437 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11438 mips32_op = OPC_ROUND_L_S;
11439 goto do_unaryfp;
11440 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11441 mips32_op = OPC_ROUND_L_D;
11442 goto do_unaryfp;
11443 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11444 mips32_op = OPC_ROUND_W_S;
11445 goto do_unaryfp;
11446 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11447 mips32_op = OPC_ROUND_W_D;
11448 goto do_unaryfp;
11449
11450 /* Integer to floating-point conversion */
11451 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11452 mips32_op = OPC_CVT_L_S;
11453 goto do_unaryfp;
11454 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11455 mips32_op = OPC_CVT_L_D;
11456 goto do_unaryfp;
11457 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11458 mips32_op = OPC_CVT_W_S;
11459 goto do_unaryfp;
11460 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11461 mips32_op = OPC_CVT_W_D;
11462 goto do_unaryfp;
11463
11464 /* Paired-foo conversions */
11465 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11466 mips32_op = OPC_CVT_S_PL;
11467 goto do_unaryfp;
11468 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11469 mips32_op = OPC_CVT_S_PU;
11470 goto do_unaryfp;
11471 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11472 mips32_op = OPC_CVT_PW_PS;
11473 goto do_unaryfp;
11474 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11475 mips32_op = OPC_CVT_PS_PW;
11476 goto do_unaryfp;
11477
11478 /* Floating-point moves */
11479 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11480 mips32_op = OPC_MOV_S;
11481 goto do_unaryfp;
11482 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11483 mips32_op = OPC_MOV_D;
11484 goto do_unaryfp;
11485 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11486 mips32_op = OPC_MOV_PS;
11487 goto do_unaryfp;
11488
11489 /* Absolute value */
11490 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11491 mips32_op = OPC_ABS_S;
11492 goto do_unaryfp;
11493 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11494 mips32_op = OPC_ABS_D;
11495 goto do_unaryfp;
11496 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11497 mips32_op = OPC_ABS_PS;
11498 goto do_unaryfp;
11499
11500 /* Negation */
11501 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11502 mips32_op = OPC_NEG_S;
11503 goto do_unaryfp;
11504 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11505 mips32_op = OPC_NEG_D;
11506 goto do_unaryfp;
11507 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11508 mips32_op = OPC_NEG_PS;
11509 goto do_unaryfp;
11510
11511 /* Reciprocal square root step */
11512 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11513 mips32_op = OPC_RSQRT1_S;
11514 goto do_unaryfp;
11515 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11516 mips32_op = OPC_RSQRT1_D;
11517 goto do_unaryfp;
11518 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11519 mips32_op = OPC_RSQRT1_PS;
11520 goto do_unaryfp;
11521
11522 /* Reciprocal step */
11523 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11524 mips32_op = OPC_RECIP1_S;
11525 goto do_unaryfp;
11526 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11527 mips32_op = OPC_RECIP1_S;
11528 goto do_unaryfp;
11529 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11530 mips32_op = OPC_RECIP1_PS;
11531 goto do_unaryfp;
11532
11533 /* Conversions from double */
11534 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11535 mips32_op = OPC_CVT_D_S;
11536 goto do_unaryfp;
11537 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11538 mips32_op = OPC_CVT_D_W;
11539 goto do_unaryfp;
11540 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11541 mips32_op = OPC_CVT_D_L;
11542 goto do_unaryfp;
11543
11544 /* Conversions from single */
11545 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11546 mips32_op = OPC_CVT_S_D;
11547 goto do_unaryfp;
11548 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11549 mips32_op = OPC_CVT_S_W;
11550 goto do_unaryfp;
11551 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11552 mips32_op = OPC_CVT_S_L;
11553 do_unaryfp:
11554 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11555 break;
11556
11557 /* Conditional moves on floating-point codes */
11558 case COND_FLOAT_MOV(MOVT, 0):
11559 case COND_FLOAT_MOV(MOVT, 1):
11560 case COND_FLOAT_MOV(MOVT, 2):
11561 case COND_FLOAT_MOV(MOVT, 3):
11562 case COND_FLOAT_MOV(MOVT, 4):
11563 case COND_FLOAT_MOV(MOVT, 5):
11564 case COND_FLOAT_MOV(MOVT, 6):
11565 case COND_FLOAT_MOV(MOVT, 7):
11566 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11567 break;
11568 case COND_FLOAT_MOV(MOVF, 0):
11569 case COND_FLOAT_MOV(MOVF, 1):
11570 case COND_FLOAT_MOV(MOVF, 2):
11571 case COND_FLOAT_MOV(MOVF, 3):
11572 case COND_FLOAT_MOV(MOVF, 4):
11573 case COND_FLOAT_MOV(MOVF, 5):
11574 case COND_FLOAT_MOV(MOVF, 6):
11575 case COND_FLOAT_MOV(MOVF, 7):
11576 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11577 break;
11578 default:
11579 MIPS_INVAL("pool32fxf");
11580 generate_exception(ctx, EXCP_RI);
11581 break;
11582 }
11583 }
11584
11585 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11586 uint16_t insn_hw1, int *is_branch)
11587 {
11588 int32_t offset;
11589 uint16_t insn;
11590 int rt, rs, rd, rr;
11591 int16_t imm;
11592 uint32_t op, minor, mips32_op;
11593 uint32_t cond, fmt, cc;
11594
11595 insn = cpu_lduw_code(env, ctx->pc + 2);
11596 ctx->opcode = (ctx->opcode << 16) | insn;
11597
11598 rt = (ctx->opcode >> 21) & 0x1f;
11599 rs = (ctx->opcode >> 16) & 0x1f;
11600 rd = (ctx->opcode >> 11) & 0x1f;
11601 rr = (ctx->opcode >> 6) & 0x1f;
11602 imm = (int16_t) ctx->opcode;
11603
11604 op = (ctx->opcode >> 26) & 0x3f;
11605 switch (op) {
11606 case POOL32A:
11607 minor = ctx->opcode & 0x3f;
11608 switch (minor) {
11609 case 0x00:
11610 minor = (ctx->opcode >> 6) & 0xf;
11611 switch (minor) {
11612 case SLL32:
11613 mips32_op = OPC_SLL;
11614 goto do_shifti;
11615 case SRA:
11616 mips32_op = OPC_SRA;
11617 goto do_shifti;
11618 case SRL32:
11619 mips32_op = OPC_SRL;
11620 goto do_shifti;
11621 case ROTR:
11622 mips32_op = OPC_ROTR;
11623 do_shifti:
11624 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11625 break;
11626 default:
11627 goto pool32a_invalid;
11628 }
11629 break;
11630 case 0x10:
11631 minor = (ctx->opcode >> 6) & 0xf;
11632 switch (minor) {
11633 /* Arithmetic */
11634 case ADD:
11635 mips32_op = OPC_ADD;
11636 goto do_arith;
11637 case ADDU32:
11638 mips32_op = OPC_ADDU;
11639 goto do_arith;
11640 case SUB:
11641 mips32_op = OPC_SUB;
11642 goto do_arith;
11643 case SUBU32:
11644 mips32_op = OPC_SUBU;
11645 goto do_arith;
11646 case MUL:
11647 mips32_op = OPC_MUL;
11648 do_arith:
11649 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11650 break;
11651 /* Shifts */
11652 case SLLV:
11653 mips32_op = OPC_SLLV;
11654 goto do_shift;
11655 case SRLV:
11656 mips32_op = OPC_SRLV;
11657 goto do_shift;
11658 case SRAV:
11659 mips32_op = OPC_SRAV;
11660 goto do_shift;
11661 case ROTRV:
11662 mips32_op = OPC_ROTRV;
11663 do_shift:
11664 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11665 break;
11666 /* Logical operations */
11667 case AND:
11668 mips32_op = OPC_AND;
11669 goto do_logic;
11670 case OR32:
11671 mips32_op = OPC_OR;
11672 goto do_logic;
11673 case NOR:
11674 mips32_op = OPC_NOR;
11675 goto do_logic;
11676 case XOR32:
11677 mips32_op = OPC_XOR;
11678 do_logic:
11679 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11680 break;
11681 /* Set less than */
11682 case SLT:
11683 mips32_op = OPC_SLT;
11684 goto do_slt;
11685 case SLTU:
11686 mips32_op = OPC_SLTU;
11687 do_slt:
11688 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11689 break;
11690 default:
11691 goto pool32a_invalid;
11692 }
11693 break;
11694 case 0x18:
11695 minor = (ctx->opcode >> 6) & 0xf;
11696 switch (minor) {
11697 /* Conditional moves */
11698 case MOVN:
11699 mips32_op = OPC_MOVN;
11700 goto do_cmov;
11701 case MOVZ:
11702 mips32_op = OPC_MOVZ;
11703 do_cmov:
11704 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11705 break;
11706 case LWXS:
11707 gen_ldxs(ctx, rs, rt, rd);
11708 break;
11709 default:
11710 goto pool32a_invalid;
11711 }
11712 break;
11713 case INS:
11714 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11715 return;
11716 case EXT:
11717 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11718 return;
11719 case POOL32AXF:
11720 gen_pool32axf(env, ctx, rt, rs, is_branch);
11721 break;
11722 case 0x07:
11723 generate_exception(ctx, EXCP_BREAK);
11724 break;
11725 default:
11726 pool32a_invalid:
11727 MIPS_INVAL("pool32a");
11728 generate_exception(ctx, EXCP_RI);
11729 break;
11730 }
11731 break;
11732 case POOL32B:
11733 minor = (ctx->opcode >> 12) & 0xf;
11734 switch (minor) {
11735 case CACHE:
11736 check_cp0_enabled(ctx);
11737 /* Treat as no-op. */
11738 break;
11739 case LWC2:
11740 case SWC2:
11741 /* COP2: Not implemented. */
11742 generate_exception_err(ctx, EXCP_CpU, 2);
11743 break;
11744 case LWP:
11745 case SWP:
11746 #ifdef TARGET_MIPS64
11747 case LDP:
11748 case SDP:
11749 #endif
11750 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11751 break;
11752 case LWM32:
11753 case SWM32:
11754 #ifdef TARGET_MIPS64
11755 case LDM:
11756 case SDM:
11757 #endif
11758 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11759 break;
11760 default:
11761 MIPS_INVAL("pool32b");
11762 generate_exception(ctx, EXCP_RI);
11763 break;
11764 }
11765 break;
11766 case POOL32F:
11767 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11768 minor = ctx->opcode & 0x3f;
11769 check_cp1_enabled(ctx);
11770 switch (minor) {
11771 case ALNV_PS:
11772 mips32_op = OPC_ALNV_PS;
11773 goto do_madd;
11774 case MADD_S:
11775 mips32_op = OPC_MADD_S;
11776 goto do_madd;
11777 case MADD_D:
11778 mips32_op = OPC_MADD_D;
11779 goto do_madd;
11780 case MADD_PS:
11781 mips32_op = OPC_MADD_PS;
11782 goto do_madd;
11783 case MSUB_S:
11784 mips32_op = OPC_MSUB_S;
11785 goto do_madd;
11786 case MSUB_D:
11787 mips32_op = OPC_MSUB_D;
11788 goto do_madd;
11789 case MSUB_PS:
11790 mips32_op = OPC_MSUB_PS;
11791 goto do_madd;
11792 case NMADD_S:
11793 mips32_op = OPC_NMADD_S;
11794 goto do_madd;
11795 case NMADD_D:
11796 mips32_op = OPC_NMADD_D;
11797 goto do_madd;
11798 case NMADD_PS:
11799 mips32_op = OPC_NMADD_PS;
11800 goto do_madd;
11801 case NMSUB_S:
11802 mips32_op = OPC_NMSUB_S;
11803 goto do_madd;
11804 case NMSUB_D:
11805 mips32_op = OPC_NMSUB_D;
11806 goto do_madd;
11807 case NMSUB_PS:
11808 mips32_op = OPC_NMSUB_PS;
11809 do_madd:
11810 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11811 break;
11812 case CABS_COND_FMT:
11813 cond = (ctx->opcode >> 6) & 0xf;
11814 cc = (ctx->opcode >> 13) & 0x7;
11815 fmt = (ctx->opcode >> 10) & 0x3;
11816 switch (fmt) {
11817 case 0x0:
11818 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11819 break;
11820 case 0x1:
11821 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11822 break;
11823 case 0x2:
11824 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11825 break;
11826 default:
11827 goto pool32f_invalid;
11828 }
11829 break;
11830 case C_COND_FMT:
11831 cond = (ctx->opcode >> 6) & 0xf;
11832 cc = (ctx->opcode >> 13) & 0x7;
11833 fmt = (ctx->opcode >> 10) & 0x3;
11834 switch (fmt) {
11835 case 0x0:
11836 gen_cmp_s(ctx, cond, rt, rs, cc);
11837 break;
11838 case 0x1:
11839 gen_cmp_d(ctx, cond, rt, rs, cc);
11840 break;
11841 case 0x2:
11842 gen_cmp_ps(ctx, cond, rt, rs, cc);
11843 break;
11844 default:
11845 goto pool32f_invalid;
11846 }
11847 break;
11848 case POOL32FXF:
11849 gen_pool32fxf(env, ctx, rt, rs);
11850 break;
11851 case 0x00:
11852 /* PLL foo */
11853 switch ((ctx->opcode >> 6) & 0x7) {
11854 case PLL_PS:
11855 mips32_op = OPC_PLL_PS;
11856 goto do_ps;
11857 case PLU_PS:
11858 mips32_op = OPC_PLU_PS;
11859 goto do_ps;
11860 case PUL_PS:
11861 mips32_op = OPC_PUL_PS;
11862 goto do_ps;
11863 case PUU_PS:
11864 mips32_op = OPC_PUU_PS;
11865 goto do_ps;
11866 case CVT_PS_S:
11867 mips32_op = OPC_CVT_PS_S;
11868 do_ps:
11869 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11870 break;
11871 default:
11872 goto pool32f_invalid;
11873 }
11874 break;
11875 case 0x08:
11876 /* [LS][WDU]XC1 */
11877 switch ((ctx->opcode >> 6) & 0x7) {
11878 case LWXC1:
11879 mips32_op = OPC_LWXC1;
11880 goto do_ldst_cp1;
11881 case SWXC1:
11882 mips32_op = OPC_SWXC1;
11883 goto do_ldst_cp1;
11884 case LDXC1:
11885 mips32_op = OPC_LDXC1;
11886 goto do_ldst_cp1;
11887 case SDXC1:
11888 mips32_op = OPC_SDXC1;
11889 goto do_ldst_cp1;
11890 case LUXC1:
11891 mips32_op = OPC_LUXC1;
11892 goto do_ldst_cp1;
11893 case SUXC1:
11894 mips32_op = OPC_SUXC1;
11895 do_ldst_cp1:
11896 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11897 break;
11898 default:
11899 goto pool32f_invalid;
11900 }
11901 break;
11902 case 0x18:
11903 /* 3D insns */
11904 fmt = (ctx->opcode >> 9) & 0x3;
11905 switch ((ctx->opcode >> 6) & 0x7) {
11906 case RSQRT2_FMT:
11907 switch (fmt) {
11908 case FMT_SDPS_S:
11909 mips32_op = OPC_RSQRT2_S;
11910 goto do_3d;
11911 case FMT_SDPS_D:
11912 mips32_op = OPC_RSQRT2_D;
11913 goto do_3d;
11914 case FMT_SDPS_PS:
11915 mips32_op = OPC_RSQRT2_PS;
11916 goto do_3d;
11917 default:
11918 goto pool32f_invalid;
11919 }
11920 break;
11921 case RECIP2_FMT:
11922 switch (fmt) {
11923 case FMT_SDPS_S:
11924 mips32_op = OPC_RECIP2_S;
11925 goto do_3d;
11926 case FMT_SDPS_D:
11927 mips32_op = OPC_RECIP2_D;
11928 goto do_3d;
11929 case FMT_SDPS_PS:
11930 mips32_op = OPC_RECIP2_PS;
11931 goto do_3d;
11932 default:
11933 goto pool32f_invalid;
11934 }
11935 break;
11936 case ADDR_PS:
11937 mips32_op = OPC_ADDR_PS;
11938 goto do_3d;
11939 case MULR_PS:
11940 mips32_op = OPC_MULR_PS;
11941 do_3d:
11942 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11943 break;
11944 default:
11945 goto pool32f_invalid;
11946 }
11947 break;
11948 case 0x20:
11949 /* MOV[FT].fmt and PREFX */
11950 cc = (ctx->opcode >> 13) & 0x7;
11951 fmt = (ctx->opcode >> 9) & 0x3;
11952 switch ((ctx->opcode >> 6) & 0x7) {
11953 case MOVF_FMT:
11954 switch (fmt) {
11955 case FMT_SDPS_S:
11956 gen_movcf_s(rs, rt, cc, 0);
11957 break;
11958 case FMT_SDPS_D:
11959 gen_movcf_d(ctx, rs, rt, cc, 0);
11960 break;
11961 case FMT_SDPS_PS:
11962 gen_movcf_ps(rs, rt, cc, 0);
11963 break;
11964 default:
11965 goto pool32f_invalid;
11966 }
11967 break;
11968 case MOVT_FMT:
11969 switch (fmt) {
11970 case FMT_SDPS_S:
11971 gen_movcf_s(rs, rt, cc, 1);
11972 break;
11973 case FMT_SDPS_D:
11974 gen_movcf_d(ctx, rs, rt, cc, 1);
11975 break;
11976 case FMT_SDPS_PS:
11977 gen_movcf_ps(rs, rt, cc, 1);
11978 break;
11979 default:
11980 goto pool32f_invalid;
11981 }
11982 break;
11983 case PREFX:
11984 break;
11985 default:
11986 goto pool32f_invalid;
11987 }
11988 break;
11989 #define FINSN_3ARG_SDPS(prfx) \
11990 switch ((ctx->opcode >> 8) & 0x3) { \
11991 case FMT_SDPS_S: \
11992 mips32_op = OPC_##prfx##_S; \
11993 goto do_fpop; \
11994 case FMT_SDPS_D: \
11995 mips32_op = OPC_##prfx##_D; \
11996 goto do_fpop; \
11997 case FMT_SDPS_PS: \
11998 mips32_op = OPC_##prfx##_PS; \
11999 goto do_fpop; \
12000 default: \
12001 goto pool32f_invalid; \
12002 }
12003 case 0x30:
12004 /* regular FP ops */
12005 switch ((ctx->opcode >> 6) & 0x3) {
12006 case ADD_FMT:
12007 FINSN_3ARG_SDPS(ADD);
12008 break;
12009 case SUB_FMT:
12010 FINSN_3ARG_SDPS(SUB);
12011 break;
12012 case MUL_FMT:
12013 FINSN_3ARG_SDPS(MUL);
12014 break;
12015 case DIV_FMT:
12016 fmt = (ctx->opcode >> 8) & 0x3;
12017 if (fmt == 1) {
12018 mips32_op = OPC_DIV_D;
12019 } else if (fmt == 0) {
12020 mips32_op = OPC_DIV_S;
12021 } else {
12022 goto pool32f_invalid;
12023 }
12024 goto do_fpop;
12025 default:
12026 goto pool32f_invalid;
12027 }
12028 break;
12029 case 0x38:
12030 /* cmovs */
12031 switch ((ctx->opcode >> 6) & 0x3) {
12032 case MOVN_FMT:
12033 FINSN_3ARG_SDPS(MOVN);
12034 break;
12035 case MOVZ_FMT:
12036 FINSN_3ARG_SDPS(MOVZ);
12037 break;
12038 default:
12039 goto pool32f_invalid;
12040 }
12041 break;
12042 do_fpop:
12043 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12044 break;
12045 default:
12046 pool32f_invalid:
12047 MIPS_INVAL("pool32f");
12048 generate_exception(ctx, EXCP_RI);
12049 break;
12050 }
12051 } else {
12052 generate_exception_err(ctx, EXCP_CpU, 1);
12053 }
12054 break;
12055 case POOL32I:
12056 minor = (ctx->opcode >> 21) & 0x1f;
12057 switch (minor) {
12058 case BLTZ:
12059 mips32_op = OPC_BLTZ;
12060 goto do_branch;
12061 case BLTZAL:
12062 mips32_op = OPC_BLTZAL;
12063 goto do_branch;
12064 case BLTZALS:
12065 mips32_op = OPC_BLTZALS;
12066 goto do_branch;
12067 case BGEZ:
12068 mips32_op = OPC_BGEZ;
12069 goto do_branch;
12070 case BGEZAL:
12071 mips32_op = OPC_BGEZAL;
12072 goto do_branch;
12073 case BGEZALS:
12074 mips32_op = OPC_BGEZALS;
12075 goto do_branch;
12076 case BLEZ:
12077 mips32_op = OPC_BLEZ;
12078 goto do_branch;
12079 case BGTZ:
12080 mips32_op = OPC_BGTZ;
12081 do_branch:
12082 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12083 *is_branch = 1;
12084 break;
12085
12086 /* Traps */
12087 case TLTI:
12088 mips32_op = OPC_TLTI;
12089 goto do_trapi;
12090 case TGEI:
12091 mips32_op = OPC_TGEI;
12092 goto do_trapi;
12093 case TLTIU:
12094 mips32_op = OPC_TLTIU;
12095 goto do_trapi;
12096 case TGEIU:
12097 mips32_op = OPC_TGEIU;
12098 goto do_trapi;
12099 case TNEI:
12100 mips32_op = OPC_TNEI;
12101 goto do_trapi;
12102 case TEQI:
12103 mips32_op = OPC_TEQI;
12104 do_trapi:
12105 gen_trap(ctx, mips32_op, rs, -1, imm);
12106 break;
12107
12108 case BNEZC:
12109 case BEQZC:
12110 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12111 4, rs, 0, imm << 1);
12112 /* Compact branches don't have a delay slot, so just let
12113 the normal delay slot handling take us to the branch
12114 target. */
12115 break;
12116 case LUI:
12117 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12118 break;
12119 case SYNCI:
12120 break;
12121 case BC2F:
12122 case BC2T:
12123 /* COP2: Not implemented. */
12124 generate_exception_err(ctx, EXCP_CpU, 2);
12125 break;
12126 case BC1F:
12127 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12128 goto do_cp1branch;
12129 case BC1T:
12130 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12131 goto do_cp1branch;
12132 case BC1ANY4F:
12133 mips32_op = OPC_BC1FANY4;
12134 goto do_cp1mips3d;
12135 case BC1ANY4T:
12136 mips32_op = OPC_BC1TANY4;
12137 do_cp1mips3d:
12138 check_cop1x(ctx);
12139 check_insn(env, ctx, ASE_MIPS3D);
12140 /* Fall through */
12141 do_cp1branch:
12142 gen_compute_branch1(env, ctx, mips32_op,
12143 (ctx->opcode >> 18) & 0x7, imm << 1);
12144 *is_branch = 1;
12145 break;
12146 case BPOSGE64:
12147 case BPOSGE32:
12148 /* MIPS DSP: not implemented */
12149 /* Fall through */
12150 default:
12151 MIPS_INVAL("pool32i");
12152 generate_exception(ctx, EXCP_RI);
12153 break;
12154 }
12155 break;
12156 case POOL32C:
12157 minor = (ctx->opcode >> 12) & 0xf;
12158 switch (minor) {
12159 case LWL:
12160 mips32_op = OPC_LWL;
12161 goto do_ld_lr;
12162 case SWL:
12163 mips32_op = OPC_SWL;
12164 goto do_st_lr;
12165 case LWR:
12166 mips32_op = OPC_LWR;
12167 goto do_ld_lr;
12168 case SWR:
12169 mips32_op = OPC_SWR;
12170 goto do_st_lr;
12171 #if defined(TARGET_MIPS64)
12172 case LDL:
12173 mips32_op = OPC_LDL;
12174 goto do_ld_lr;
12175 case SDL:
12176 mips32_op = OPC_SDL;
12177 goto do_st_lr;
12178 case LDR:
12179 mips32_op = OPC_LDR;
12180 goto do_ld_lr;
12181 case SDR:
12182 mips32_op = OPC_SDR;
12183 goto do_st_lr;
12184 case LWU:
12185 mips32_op = OPC_LWU;
12186 goto do_ld_lr;
12187 case LLD:
12188 mips32_op = OPC_LLD;
12189 goto do_ld_lr;
12190 #endif
12191 case LL:
12192 mips32_op = OPC_LL;
12193 goto do_ld_lr;
12194 do_ld_lr:
12195 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12196 break;
12197 do_st_lr:
12198 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12199 break;
12200 case SC:
12201 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12202 break;
12203 #if defined(TARGET_MIPS64)
12204 case SCD:
12205 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12206 break;
12207 #endif
12208 case PREF:
12209 /* Treat as no-op */
12210 break;
12211 default:
12212 MIPS_INVAL("pool32c");
12213 generate_exception(ctx, EXCP_RI);
12214 break;
12215 }
12216 break;
12217 case ADDI32:
12218 mips32_op = OPC_ADDI;
12219 goto do_addi;
12220 case ADDIU32:
12221 mips32_op = OPC_ADDIU;
12222 do_addi:
12223 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12224 break;
12225
12226 /* Logical operations */
12227 case ORI32:
12228 mips32_op = OPC_ORI;
12229 goto do_logici;
12230 case XORI32:
12231 mips32_op = OPC_XORI;
12232 goto do_logici;
12233 case ANDI32:
12234 mips32_op = OPC_ANDI;
12235 do_logici:
12236 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12237 break;
12238
12239 /* Set less than immediate */
12240 case SLTI32:
12241 mips32_op = OPC_SLTI;
12242 goto do_slti;
12243 case SLTIU32:
12244 mips32_op = OPC_SLTIU;
12245 do_slti:
12246 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12247 break;
12248 case JALX32:
12249 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12250 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12251 *is_branch = 1;
12252 break;
12253 case JALS32:
12254 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12255 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12256 *is_branch = 1;
12257 break;
12258 case BEQ32:
12259 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12260 *is_branch = 1;
12261 break;
12262 case BNE32:
12263 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12264 *is_branch = 1;
12265 break;
12266 case J32:
12267 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12268 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12269 *is_branch = 1;
12270 break;
12271 case JAL32:
12272 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12273 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12274 *is_branch = 1;
12275 break;
12276 /* Floating point (COP1) */
12277 case LWC132:
12278 mips32_op = OPC_LWC1;
12279 goto do_cop1;
12280 case LDC132:
12281 mips32_op = OPC_LDC1;
12282 goto do_cop1;
12283 case SWC132:
12284 mips32_op = OPC_SWC1;
12285 goto do_cop1;
12286 case SDC132:
12287 mips32_op = OPC_SDC1;
12288 do_cop1:
12289 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12290 break;
12291 case ADDIUPC:
12292 {
12293 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12294 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12295
12296 gen_addiupc(ctx, reg, offset, 0, 0);
12297 }
12298 break;
12299 /* Loads and stores */
12300 case LB32:
12301 mips32_op = OPC_LB;
12302 goto do_ld;
12303 case LBU32:
12304 mips32_op = OPC_LBU;
12305 goto do_ld;
12306 case LH32:
12307 mips32_op = OPC_LH;
12308 goto do_ld;
12309 case LHU32:
12310 mips32_op = OPC_LHU;
12311 goto do_ld;
12312 case LW32:
12313 mips32_op = OPC_LW;
12314 goto do_ld;
12315 #ifdef TARGET_MIPS64
12316 case LD32:
12317 mips32_op = OPC_LD;
12318 goto do_ld;
12319 case SD32:
12320 mips32_op = OPC_SD;
12321 goto do_st;
12322 #endif
12323 case SB32:
12324 mips32_op = OPC_SB;
12325 goto do_st;
12326 case SH32:
12327 mips32_op = OPC_SH;
12328 goto do_st;
12329 case SW32:
12330 mips32_op = OPC_SW;
12331 goto do_st;
12332 do_ld:
12333 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12334 break;
12335 do_st:
12336 gen_st(ctx, mips32_op, rt, rs, imm);
12337 break;
12338 default:
12339 generate_exception(ctx, EXCP_RI);
12340 break;
12341 }
12342 }
12343
12344 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12345 {
12346 uint32_t op;
12347
12348 /* make sure instructions are on a halfword boundary */
12349 if (ctx->pc & 0x1) {
12350 env->CP0_BadVAddr = ctx->pc;
12351 generate_exception(ctx, EXCP_AdEL);
12352 ctx->bstate = BS_STOP;
12353 return 2;
12354 }
12355
12356 op = (ctx->opcode >> 10) & 0x3f;
12357 /* Enforce properly-sized instructions in a delay slot */
12358 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12359 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12360
12361 switch (op) {
12362 case POOL32A:
12363 case POOL32B:
12364 case POOL32I:
12365 case POOL32C:
12366 case ADDI32:
12367 case ADDIU32:
12368 case ORI32:
12369 case XORI32:
12370 case SLTI32:
12371 case SLTIU32:
12372 case ANDI32:
12373 case JALX32:
12374 case LBU32:
12375 case LHU32:
12376 case POOL32F:
12377 case JALS32:
12378 case BEQ32:
12379 case BNE32:
12380 case J32:
12381 case JAL32:
12382 case SB32:
12383 case SH32:
12384 case POOL32S:
12385 case ADDIUPC:
12386 case SWC132:
12387 case SDC132:
12388 case SD32:
12389 case SW32:
12390 case LB32:
12391 case LH32:
12392 case DADDIU32:
12393 case POOL48A: /* ??? */
12394 case LWC132:
12395 case LDC132:
12396 case LD32:
12397 case LW32:
12398 if (bits & MIPS_HFLAG_BDS16) {
12399 generate_exception(ctx, EXCP_RI);
12400 /* Just stop translation; the user is confused. */
12401 ctx->bstate = BS_STOP;
12402 return 2;
12403 }
12404 break;
12405 case POOL16A:
12406 case POOL16B:
12407 case POOL16C:
12408 case LWGP16:
12409 case POOL16F:
12410 case LBU16:
12411 case LHU16:
12412 case LWSP16:
12413 case LW16:
12414 case SB16:
12415 case SH16:
12416 case SWSP16:
12417 case SW16:
12418 case MOVE16:
12419 case ANDI16:
12420 case POOL16D:
12421 case POOL16E:
12422 case BEQZ16:
12423 case BNEZ16:
12424 case B16:
12425 case LI16:
12426 if (bits & MIPS_HFLAG_BDS32) {
12427 generate_exception(ctx, EXCP_RI);
12428 /* Just stop translation; the user is confused. */
12429 ctx->bstate = BS_STOP;
12430 return 2;
12431 }
12432 break;
12433 default:
12434 break;
12435 }
12436 }
12437 switch (op) {
12438 case POOL16A:
12439 {
12440 int rd = mmreg(uMIPS_RD(ctx->opcode));
12441 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12442 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12443 uint32_t opc = 0;
12444
12445 switch (ctx->opcode & 0x1) {
12446 case ADDU16:
12447 opc = OPC_ADDU;
12448 break;
12449 case SUBU16:
12450 opc = OPC_SUBU;
12451 break;
12452 }
12453
12454 gen_arith(env, ctx, opc, rd, rs1, rs2);
12455 }
12456 break;
12457 case POOL16B:
12458 {
12459 int rd = mmreg(uMIPS_RD(ctx->opcode));
12460 int rs = mmreg(uMIPS_RS(ctx->opcode));
12461 int amount = (ctx->opcode >> 1) & 0x7;
12462 uint32_t opc = 0;
12463 amount = amount == 0 ? 8 : amount;
12464
12465 switch (ctx->opcode & 0x1) {
12466 case SLL16:
12467 opc = OPC_SLL;
12468 break;
12469 case SRL16:
12470 opc = OPC_SRL;
12471 break;
12472 }
12473
12474 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12475 }
12476 break;
12477 case POOL16C:
12478 gen_pool16c_insn(env, ctx, is_branch);
12479 break;
12480 case LWGP16:
12481 {
12482 int rd = mmreg(uMIPS_RD(ctx->opcode));
12483 int rb = 28; /* GP */
12484 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12485
12486 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12487 }
12488 break;
12489 case POOL16F:
12490 if (ctx->opcode & 1) {
12491 generate_exception(ctx, EXCP_RI);
12492 } else {
12493 /* MOVEP */
12494 int enc_dest = uMIPS_RD(ctx->opcode);
12495 int enc_rt = uMIPS_RS2(ctx->opcode);
12496 int enc_rs = uMIPS_RS1(ctx->opcode);
12497 int rd, rs, re, rt;
12498 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12499 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12500 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12501
12502 rd = rd_enc[enc_dest];
12503 re = re_enc[enc_dest];
12504 rs = rs_rt_enc[enc_rs];
12505 rt = rs_rt_enc[enc_rt];
12506
12507 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12508 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12509 }
12510 break;
12511 case LBU16:
12512 {
12513 int rd = mmreg(uMIPS_RD(ctx->opcode));
12514 int rb = mmreg(uMIPS_RS(ctx->opcode));
12515 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12516 offset = (offset == 0xf ? -1 : offset);
12517
12518 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12519 }
12520 break;
12521 case LHU16:
12522 {
12523 int rd = mmreg(uMIPS_RD(ctx->opcode));
12524 int rb = mmreg(uMIPS_RS(ctx->opcode));
12525 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12526
12527 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12528 }
12529 break;
12530 case LWSP16:
12531 {
12532 int rd = (ctx->opcode >> 5) & 0x1f;
12533 int rb = 29; /* SP */
12534 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12535
12536 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12537 }
12538 break;
12539 case LW16:
12540 {
12541 int rd = mmreg(uMIPS_RD(ctx->opcode));
12542 int rb = mmreg(uMIPS_RS(ctx->opcode));
12543 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12544
12545 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12546 }
12547 break;
12548 case SB16:
12549 {
12550 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12551 int rb = mmreg(uMIPS_RS(ctx->opcode));
12552 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12553
12554 gen_st(ctx, OPC_SB, rd, rb, offset);
12555 }
12556 break;
12557 case SH16:
12558 {
12559 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12560 int rb = mmreg(uMIPS_RS(ctx->opcode));
12561 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12562
12563 gen_st(ctx, OPC_SH, rd, rb, offset);
12564 }
12565 break;
12566 case SWSP16:
12567 {
12568 int rd = (ctx->opcode >> 5) & 0x1f;
12569 int rb = 29; /* SP */
12570 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12571
12572 gen_st(ctx, OPC_SW, rd, rb, offset);
12573 }
12574 break;
12575 case SW16:
12576 {
12577 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12578 int rb = mmreg(uMIPS_RS(ctx->opcode));
12579 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12580
12581 gen_st(ctx, OPC_SW, rd, rb, offset);
12582 }
12583 break;
12584 case MOVE16:
12585 {
12586 int rd = uMIPS_RD5(ctx->opcode);
12587 int rs = uMIPS_RS5(ctx->opcode);
12588
12589 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12590 }
12591 break;
12592 case ANDI16:
12593 gen_andi16(env, ctx);
12594 break;
12595 case POOL16D:
12596 switch (ctx->opcode & 0x1) {
12597 case ADDIUS5:
12598 gen_addius5(env, ctx);
12599 break;
12600 case ADDIUSP:
12601 gen_addiusp(env, ctx);
12602 break;
12603 }
12604 break;
12605 case POOL16E:
12606 switch (ctx->opcode & 0x1) {
12607 case ADDIUR2:
12608 gen_addiur2(env, ctx);
12609 break;
12610 case ADDIUR1SP:
12611 gen_addiur1sp(env, ctx);
12612 break;
12613 }
12614 break;
12615 case B16:
12616 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12617 SIMM(ctx->opcode, 0, 10) << 1);
12618 *is_branch = 1;
12619 break;
12620 case BNEZ16:
12621 case BEQZ16:
12622 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12623 mmreg(uMIPS_RD(ctx->opcode)),
12624 0, SIMM(ctx->opcode, 0, 7) << 1);
12625 *is_branch = 1;
12626 break;
12627 case LI16:
12628 {
12629 int reg = mmreg(uMIPS_RD(ctx->opcode));
12630 int imm = ZIMM(ctx->opcode, 0, 7);
12631
12632 imm = (imm == 0x7f ? -1 : imm);
12633 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12634 }
12635 break;
12636 case RES_20:
12637 case RES_28:
12638 case RES_29:
12639 case RES_30:
12640 case RES_31:
12641 case RES_38:
12642 case RES_39:
12643 generate_exception(ctx, EXCP_RI);
12644 break;
12645 default:
12646 decode_micromips32_opc (env, ctx, op, is_branch);
12647 return 4;
12648 }
12649
12650 return 2;
12651 }
12652
12653 /* SmartMIPS extension to MIPS32 */
12654
12655 #if defined(TARGET_MIPS64)
12656
12657 /* MDMX extension to MIPS64 */
12658
12659 #endif
12660
12661 /* MIPSDSP functions. */
12662 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12663 int rd, int base, int offset)
12664 {
12665 const char *opn = "ldx";
12666 TCGv t0;
12667
12668 if (rd == 0) {
12669 MIPS_DEBUG("NOP");
12670 return;
12671 }
12672
12673 check_dsp(ctx);
12674 t0 = tcg_temp_new();
12675
12676 if (base == 0) {
12677 gen_load_gpr(t0, offset);
12678 } else if (offset == 0) {
12679 gen_load_gpr(t0, base);
12680 } else {
12681 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12682 }
12683
12684 switch (opc) {
12685 case OPC_LBUX:
12686 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12687 gen_store_gpr(t0, rd);
12688 opn = "lbux";
12689 break;
12690 case OPC_LHX:
12691 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12692 gen_store_gpr(t0, rd);
12693 opn = "lhx";
12694 break;
12695 case OPC_LWX:
12696 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12697 gen_store_gpr(t0, rd);
12698 opn = "lwx";
12699 break;
12700 #if defined(TARGET_MIPS64)
12701 case OPC_LDX:
12702 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12703 gen_store_gpr(t0, rd);
12704 opn = "ldx";
12705 break;
12706 #endif
12707 }
12708 (void)opn; /* avoid a compiler warning */
12709 MIPS_DEBUG("%s %s, %s(%s)", opn,
12710 regnames[rd], regnames[offset], regnames[base]);
12711 tcg_temp_free(t0);
12712 }
12713
12714 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12715 int ret, int v1, int v2)
12716 {
12717 const char *opn = "mipsdsp arith";
12718 TCGv v1_t;
12719 TCGv v2_t;
12720
12721 if (ret == 0) {
12722 /* Treat as NOP. */
12723 MIPS_DEBUG("NOP");
12724 return;
12725 }
12726
12727 v1_t = tcg_temp_new();
12728 v2_t = tcg_temp_new();
12729
12730 gen_load_gpr(v1_t, v1);
12731 gen_load_gpr(v2_t, v2);
12732
12733 switch (op1) {
12734 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12735 case OPC_MULT_G_2E:
12736 check_dspr2(ctx);
12737 switch (op2) {
12738 case OPC_ADDUH_QB:
12739 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12740 break;
12741 case OPC_ADDUH_R_QB:
12742 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12743 break;
12744 case OPC_ADDQH_PH:
12745 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12746 break;
12747 case OPC_ADDQH_R_PH:
12748 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12749 break;
12750 case OPC_ADDQH_W:
12751 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12752 break;
12753 case OPC_ADDQH_R_W:
12754 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12755 break;
12756 case OPC_SUBUH_QB:
12757 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12758 break;
12759 case OPC_SUBUH_R_QB:
12760 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12761 break;
12762 case OPC_SUBQH_PH:
12763 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12764 break;
12765 case OPC_SUBQH_R_PH:
12766 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12767 break;
12768 case OPC_SUBQH_W:
12769 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12770 break;
12771 case OPC_SUBQH_R_W:
12772 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12773 break;
12774 }
12775 break;
12776 case OPC_ABSQ_S_PH_DSP:
12777 switch (op2) {
12778 case OPC_ABSQ_S_QB:
12779 check_dspr2(ctx);
12780 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12781 break;
12782 case OPC_ABSQ_S_PH:
12783 check_dsp(ctx);
12784 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12785 break;
12786 case OPC_ABSQ_S_W:
12787 check_dsp(ctx);
12788 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12789 break;
12790 case OPC_PRECEQ_W_PHL:
12791 check_dsp(ctx);
12792 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12793 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12794 break;
12795 case OPC_PRECEQ_W_PHR:
12796 check_dsp(ctx);
12797 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12798 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12799 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12800 break;
12801 case OPC_PRECEQU_PH_QBL:
12802 check_dsp(ctx);
12803 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12804 break;
12805 case OPC_PRECEQU_PH_QBR:
12806 check_dsp(ctx);
12807 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12808 break;
12809 case OPC_PRECEQU_PH_QBLA:
12810 check_dsp(ctx);
12811 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12812 break;
12813 case OPC_PRECEQU_PH_QBRA:
12814 check_dsp(ctx);
12815 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12816 break;
12817 case OPC_PRECEU_PH_QBL:
12818 check_dsp(ctx);
12819 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12820 break;
12821 case OPC_PRECEU_PH_QBR:
12822 check_dsp(ctx);
12823 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12824 break;
12825 case OPC_PRECEU_PH_QBLA:
12826 check_dsp(ctx);
12827 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12828 break;
12829 case OPC_PRECEU_PH_QBRA:
12830 check_dsp(ctx);
12831 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12832 break;
12833 }
12834 break;
12835 case OPC_ADDU_QB_DSP:
12836 switch (op2) {
12837 case OPC_ADDQ_PH:
12838 check_dsp(ctx);
12839 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12840 break;
12841 case OPC_ADDQ_S_PH:
12842 check_dsp(ctx);
12843 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12844 break;
12845 case OPC_ADDQ_S_W:
12846 check_dsp(ctx);
12847 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12848 break;
12849 case OPC_ADDU_QB:
12850 check_dsp(ctx);
12851 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12852 break;
12853 case OPC_ADDU_S_QB:
12854 check_dsp(ctx);
12855 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12856 break;
12857 case OPC_ADDU_PH:
12858 check_dspr2(ctx);
12859 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12860 break;
12861 case OPC_ADDU_S_PH:
12862 check_dspr2(ctx);
12863 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12864 break;
12865 case OPC_SUBQ_PH:
12866 check_dsp(ctx);
12867 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12868 break;
12869 case OPC_SUBQ_S_PH:
12870 check_dsp(ctx);
12871 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12872 break;
12873 case OPC_SUBQ_S_W:
12874 check_dsp(ctx);
12875 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12876 break;
12877 case OPC_SUBU_QB:
12878 check_dsp(ctx);
12879 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12880 break;
12881 case OPC_SUBU_S_QB:
12882 check_dsp(ctx);
12883 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12884 break;
12885 case OPC_SUBU_PH:
12886 check_dspr2(ctx);
12887 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12888 break;
12889 case OPC_SUBU_S_PH:
12890 check_dspr2(ctx);
12891 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12892 break;
12893 case OPC_ADDSC:
12894 check_dsp(ctx);
12895 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12896 break;
12897 case OPC_ADDWC:
12898 check_dsp(ctx);
12899 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12900 break;
12901 case OPC_MODSUB:
12902 check_dsp(ctx);
12903 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12904 break;
12905 case OPC_RADDU_W_QB:
12906 check_dsp(ctx);
12907 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12908 break;
12909 }
12910 break;
12911 case OPC_CMPU_EQ_QB_DSP:
12912 switch (op2) {
12913 case OPC_PRECR_QB_PH:
12914 check_dspr2(ctx);
12915 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12916 break;
12917 case OPC_PRECRQ_QB_PH:
12918 check_dsp(ctx);
12919 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12920 break;
12921 case OPC_PRECR_SRA_PH_W:
12922 check_dspr2(ctx);
12923 {
12924 TCGv_i32 sa_t = tcg_const_i32(v2);
12925 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12926 cpu_gpr[ret]);
12927 tcg_temp_free_i32(sa_t);
12928 break;
12929 }
12930 case OPC_PRECR_SRA_R_PH_W:
12931 check_dspr2(ctx);
12932 {
12933 TCGv_i32 sa_t = tcg_const_i32(v2);
12934 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12935 cpu_gpr[ret]);
12936 tcg_temp_free_i32(sa_t);
12937 break;
12938 }
12939 case OPC_PRECRQ_PH_W:
12940 check_dsp(ctx);
12941 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12942 break;
12943 case OPC_PRECRQ_RS_PH_W:
12944 check_dsp(ctx);
12945 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12946 break;
12947 case OPC_PRECRQU_S_QB_PH:
12948 check_dsp(ctx);
12949 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12950 break;
12951 }
12952 break;
12953 #ifdef TARGET_MIPS64
12954 case OPC_ABSQ_S_QH_DSP:
12955 switch (op2) {
12956 case OPC_PRECEQ_L_PWL:
12957 check_dsp(ctx);
12958 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12959 break;
12960 case OPC_PRECEQ_L_PWR:
12961 check_dsp(ctx);
12962 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12963 break;
12964 case OPC_PRECEQ_PW_QHL:
12965 check_dsp(ctx);
12966 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12967 break;
12968 case OPC_PRECEQ_PW_QHR:
12969 check_dsp(ctx);
12970 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12971 break;
12972 case OPC_PRECEQ_PW_QHLA:
12973 check_dsp(ctx);
12974 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12975 break;
12976 case OPC_PRECEQ_PW_QHRA:
12977 check_dsp(ctx);
12978 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12979 break;
12980 case OPC_PRECEQU_QH_OBL:
12981 check_dsp(ctx);
12982 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12983 break;
12984 case OPC_PRECEQU_QH_OBR:
12985 check_dsp(ctx);
12986 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12987 break;
12988 case OPC_PRECEQU_QH_OBLA:
12989 check_dsp(ctx);
12990 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12991 break;
12992 case OPC_PRECEQU_QH_OBRA:
12993 check_dsp(ctx);
12994 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12995 break;
12996 case OPC_PRECEU_QH_OBL:
12997 check_dsp(ctx);
12998 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12999 break;
13000 case OPC_PRECEU_QH_OBR:
13001 check_dsp(ctx);
13002 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13003 break;
13004 case OPC_PRECEU_QH_OBLA:
13005 check_dsp(ctx);
13006 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13007 break;
13008 case OPC_PRECEU_QH_OBRA:
13009 check_dsp(ctx);
13010 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13011 break;
13012 case OPC_ABSQ_S_OB:
13013 check_dspr2(ctx);
13014 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13015 break;
13016 case OPC_ABSQ_S_PW:
13017 check_dsp(ctx);
13018 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13019 break;
13020 case OPC_ABSQ_S_QH:
13021 check_dsp(ctx);
13022 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13023 break;
13024 }
13025 break;
13026 case OPC_ADDU_OB_DSP:
13027 switch (op2) {
13028 case OPC_RADDU_L_OB:
13029 check_dsp(ctx);
13030 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13031 break;
13032 case OPC_SUBQ_PW:
13033 check_dsp(ctx);
13034 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13035 break;
13036 case OPC_SUBQ_S_PW:
13037 check_dsp(ctx);
13038 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13039 break;
13040 case OPC_SUBQ_QH:
13041 check_dsp(ctx);
13042 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13043 break;
13044 case OPC_SUBQ_S_QH:
13045 check_dsp(ctx);
13046 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13047 break;
13048 case OPC_SUBU_OB:
13049 check_dsp(ctx);
13050 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13051 break;
13052 case OPC_SUBU_S_OB:
13053 check_dsp(ctx);
13054 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13055 break;
13056 case OPC_SUBU_QH:
13057 check_dspr2(ctx);
13058 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13059 break;
13060 case OPC_SUBU_S_QH:
13061 check_dspr2(ctx);
13062 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13063 break;
13064 case OPC_SUBUH_OB:
13065 check_dspr2(ctx);
13066 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13067 break;
13068 case OPC_SUBUH_R_OB:
13069 check_dspr2(ctx);
13070 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13071 break;
13072 case OPC_ADDQ_PW:
13073 check_dsp(ctx);
13074 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13075 break;
13076 case OPC_ADDQ_S_PW:
13077 check_dsp(ctx);
13078 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13079 break;
13080 case OPC_ADDQ_QH:
13081 check_dsp(ctx);
13082 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13083 break;
13084 case OPC_ADDQ_S_QH:
13085 check_dsp(ctx);
13086 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13087 break;
13088 case OPC_ADDU_OB:
13089 check_dsp(ctx);
13090 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13091 break;
13092 case OPC_ADDU_S_OB:
13093 check_dsp(ctx);
13094 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13095 break;
13096 case OPC_ADDU_QH:
13097 check_dspr2(ctx);
13098 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13099 break;
13100 case OPC_ADDU_S_QH:
13101 check_dspr2(ctx);
13102 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13103 break;
13104 case OPC_ADDUH_OB:
13105 check_dspr2(ctx);
13106 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13107 break;
13108 case OPC_ADDUH_R_OB:
13109 check_dspr2(ctx);
13110 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13111 break;
13112 }
13113 break;
13114 case OPC_CMPU_EQ_OB_DSP:
13115 switch (op2) {
13116 case OPC_PRECR_OB_QH:
13117 check_dspr2(ctx);
13118 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13119 break;
13120 case OPC_PRECR_SRA_QH_PW:
13121 check_dspr2(ctx);
13122 {
13123 TCGv_i32 ret_t = tcg_const_i32(ret);
13124 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13125 tcg_temp_free_i32(ret_t);
13126 break;
13127 }
13128 case OPC_PRECR_SRA_R_QH_PW:
13129 check_dspr2(ctx);
13130 {
13131 TCGv_i32 sa_v = tcg_const_i32(ret);
13132 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13133 tcg_temp_free_i32(sa_v);
13134 break;
13135 }
13136 case OPC_PRECRQ_OB_QH:
13137 check_dsp(ctx);
13138 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13139 break;
13140 case OPC_PRECRQ_PW_L:
13141 check_dsp(ctx);
13142 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13143 break;
13144 case OPC_PRECRQ_QH_PW:
13145 check_dsp(ctx);
13146 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13147 break;
13148 case OPC_PRECRQ_RS_QH_PW:
13149 check_dsp(ctx);
13150 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13151 break;
13152 case OPC_PRECRQU_S_OB_QH:
13153 check_dsp(ctx);
13154 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13155 break;
13156 }
13157 break;
13158 #endif
13159 }
13160
13161 tcg_temp_free(v1_t);
13162 tcg_temp_free(v2_t);
13163
13164 (void)opn; /* avoid a compiler warning */
13165 MIPS_DEBUG("%s", opn);
13166 }
13167
13168 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13169 int ret, int v1, int v2)
13170 {
13171 uint32_t op2;
13172 const char *opn = "mipsdsp shift";
13173 TCGv t0;
13174 TCGv v1_t;
13175 TCGv v2_t;
13176
13177 if (ret == 0) {
13178 /* Treat as NOP. */
13179 MIPS_DEBUG("NOP");
13180 return;
13181 }
13182
13183 t0 = tcg_temp_new();
13184 v1_t = tcg_temp_new();
13185 v2_t = tcg_temp_new();
13186
13187 tcg_gen_movi_tl(t0, v1);
13188 gen_load_gpr(v1_t, v1);
13189 gen_load_gpr(v2_t, v2);
13190
13191 switch (opc) {
13192 case OPC_SHLL_QB_DSP:
13193 {
13194 op2 = MASK_SHLL_QB(ctx->opcode);
13195 switch (op2) {
13196 case OPC_SHLL_QB:
13197 check_dsp(ctx);
13198 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13199 break;
13200 case OPC_SHLLV_QB:
13201 check_dsp(ctx);
13202 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13203 break;
13204 case OPC_SHLL_PH:
13205 check_dsp(ctx);
13206 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13207 break;
13208 case OPC_SHLLV_PH:
13209 check_dsp(ctx);
13210 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13211 break;
13212 case OPC_SHLL_S_PH:
13213 check_dsp(ctx);
13214 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13215 break;
13216 case OPC_SHLLV_S_PH:
13217 check_dsp(ctx);
13218 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13219 break;
13220 case OPC_SHLL_S_W:
13221 check_dsp(ctx);
13222 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13223 break;
13224 case OPC_SHLLV_S_W:
13225 check_dsp(ctx);
13226 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13227 break;
13228 case OPC_SHRL_QB:
13229 check_dsp(ctx);
13230 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13231 break;
13232 case OPC_SHRLV_QB:
13233 check_dsp(ctx);
13234 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13235 break;
13236 case OPC_SHRL_PH:
13237 check_dspr2(ctx);
13238 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13239 break;
13240 case OPC_SHRLV_PH:
13241 check_dspr2(ctx);
13242 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13243 break;
13244 case OPC_SHRA_QB:
13245 check_dspr2(ctx);
13246 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13247 break;
13248 case OPC_SHRA_R_QB:
13249 check_dspr2(ctx);
13250 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13251 break;
13252 case OPC_SHRAV_QB:
13253 check_dspr2(ctx);
13254 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13255 break;
13256 case OPC_SHRAV_R_QB:
13257 check_dspr2(ctx);
13258 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13259 break;
13260 case OPC_SHRA_PH:
13261 check_dsp(ctx);
13262 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13263 break;
13264 case OPC_SHRA_R_PH:
13265 check_dsp(ctx);
13266 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13267 break;
13268 case OPC_SHRAV_PH:
13269 check_dsp(ctx);
13270 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13271 break;
13272 case OPC_SHRAV_R_PH:
13273 check_dsp(ctx);
13274 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13275 break;
13276 case OPC_SHRA_R_W:
13277 check_dsp(ctx);
13278 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13279 break;
13280 case OPC_SHRAV_R_W:
13281 check_dsp(ctx);
13282 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13283 break;
13284 default: /* Invalid */
13285 MIPS_INVAL("MASK SHLL.QB");
13286 generate_exception(ctx, EXCP_RI);
13287 break;
13288 }
13289 break;
13290 }
13291 #ifdef TARGET_MIPS64
13292 case OPC_SHLL_OB_DSP:
13293 op2 = MASK_SHLL_OB(ctx->opcode);
13294 switch (op2) {
13295 case OPC_SHLL_PW:
13296 check_dsp(ctx);
13297 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13298 break;
13299 case OPC_SHLLV_PW:
13300 check_dsp(ctx);
13301 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13302 break;
13303 case OPC_SHLL_S_PW:
13304 check_dsp(ctx);
13305 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13306 break;
13307 case OPC_SHLLV_S_PW:
13308 check_dsp(ctx);
13309 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13310 break;
13311 case OPC_SHLL_OB:
13312 check_dsp(ctx);
13313 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13314 break;
13315 case OPC_SHLLV_OB:
13316 check_dsp(ctx);
13317 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13318 break;
13319 case OPC_SHLL_QH:
13320 check_dsp(ctx);
13321 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13322 break;
13323 case OPC_SHLLV_QH:
13324 check_dsp(ctx);
13325 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13326 break;
13327 case OPC_SHLL_S_QH:
13328 check_dsp(ctx);
13329 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13330 break;
13331 case OPC_SHLLV_S_QH:
13332 check_dsp(ctx);
13333 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13334 break;
13335 case OPC_SHRA_OB:
13336 check_dspr2(ctx);
13337 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13338 break;
13339 case OPC_SHRAV_OB:
13340 check_dspr2(ctx);
13341 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13342 break;
13343 case OPC_SHRA_R_OB:
13344 check_dspr2(ctx);
13345 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13346 break;
13347 case OPC_SHRAV_R_OB:
13348 check_dspr2(ctx);
13349 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13350 break;
13351 case OPC_SHRA_PW:
13352 check_dsp(ctx);
13353 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13354 break;
13355 case OPC_SHRAV_PW:
13356 check_dsp(ctx);
13357 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13358 break;
13359 case OPC_SHRA_R_PW:
13360 check_dsp(ctx);
13361 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13362 break;
13363 case OPC_SHRAV_R_PW:
13364 check_dsp(ctx);
13365 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13366 break;
13367 case OPC_SHRA_QH:
13368 check_dsp(ctx);
13369 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13370 break;
13371 case OPC_SHRAV_QH:
13372 check_dsp(ctx);
13373 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13374 break;
13375 case OPC_SHRA_R_QH:
13376 check_dsp(ctx);
13377 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13378 break;
13379 case OPC_SHRAV_R_QH:
13380 check_dsp(ctx);
13381 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13382 break;
13383 case OPC_SHRL_OB:
13384 check_dsp(ctx);
13385 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13386 break;
13387 case OPC_SHRLV_OB:
13388 check_dsp(ctx);
13389 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13390 break;
13391 case OPC_SHRL_QH:
13392 check_dspr2(ctx);
13393 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13394 break;
13395 case OPC_SHRLV_QH:
13396 check_dspr2(ctx);
13397 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13398 break;
13399 default: /* Invalid */
13400 MIPS_INVAL("MASK SHLL.OB");
13401 generate_exception(ctx, EXCP_RI);
13402 break;
13403 }
13404 break;
13405 #endif
13406 }
13407
13408 tcg_temp_free(t0);
13409 tcg_temp_free(v1_t);
13410 tcg_temp_free(v2_t);
13411 (void)opn; /* avoid a compiler warning */
13412 MIPS_DEBUG("%s", opn);
13413 }
13414
13415 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13416 int ret, int v1, int v2, int check_ret)
13417 {
13418 const char *opn = "mipsdsp multiply";
13419 TCGv_i32 t0;
13420 TCGv v1_t;
13421 TCGv v2_t;
13422
13423 if ((ret == 0) && (check_ret == 1)) {
13424 /* Treat as NOP. */
13425 MIPS_DEBUG("NOP");
13426 return;
13427 }
13428
13429 t0 = tcg_temp_new_i32();
13430 v1_t = tcg_temp_new();
13431 v2_t = tcg_temp_new();
13432
13433 tcg_gen_movi_i32(t0, ret);
13434 gen_load_gpr(v1_t, v1);
13435 gen_load_gpr(v2_t, v2);
13436
13437 switch (op1) {
13438 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13439 * the same mask and op1. */
13440 case OPC_MULT_G_2E:
13441 switch (op2) {
13442 case OPC_MUL_PH:
13443 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13444 break;
13445 case OPC_MUL_S_PH:
13446 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13447 break;
13448 case OPC_MULQ_S_W:
13449 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13450 break;
13451 case OPC_MULQ_RS_W:
13452 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13453 break;
13454 }
13455 break;
13456 case OPC_DPA_W_PH_DSP:
13457 switch (op2) {
13458 case OPC_DPAU_H_QBL:
13459 check_dsp(ctx);
13460 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13461 break;
13462 case OPC_DPAU_H_QBR:
13463 check_dsp(ctx);
13464 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13465 break;
13466 case OPC_DPSU_H_QBL:
13467 check_dsp(ctx);
13468 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13469 break;
13470 case OPC_DPSU_H_QBR:
13471 check_dsp(ctx);
13472 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13473 break;
13474 case OPC_DPA_W_PH:
13475 check_dspr2(ctx);
13476 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13477 break;
13478 case OPC_DPAX_W_PH:
13479 check_dspr2(ctx);
13480 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13481 break;
13482 case OPC_DPAQ_S_W_PH:
13483 check_dsp(ctx);
13484 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13485 break;
13486 case OPC_DPAQX_S_W_PH:
13487 check_dspr2(ctx);
13488 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13489 break;
13490 case OPC_DPAQX_SA_W_PH:
13491 check_dspr2(ctx);
13492 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13493 break;
13494 case OPC_DPS_W_PH:
13495 check_dspr2(ctx);
13496 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13497 break;
13498 case OPC_DPSX_W_PH:
13499 check_dspr2(ctx);
13500 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13501 break;
13502 case OPC_DPSQ_S_W_PH:
13503 check_dsp(ctx);
13504 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13505 break;
13506 case OPC_DPSQX_S_W_PH:
13507 check_dspr2(ctx);
13508 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13509 break;
13510 case OPC_DPSQX_SA_W_PH:
13511 check_dspr2(ctx);
13512 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13513 break;
13514 case OPC_MULSAQ_S_W_PH:
13515 check_dsp(ctx);
13516 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13517 break;
13518 case OPC_DPAQ_SA_L_W:
13519 check_dsp(ctx);
13520 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13521 break;
13522 case OPC_DPSQ_SA_L_W:
13523 check_dsp(ctx);
13524 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13525 break;
13526 case OPC_MAQ_S_W_PHL:
13527 check_dsp(ctx);
13528 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13529 break;
13530 case OPC_MAQ_S_W_PHR:
13531 check_dsp(ctx);
13532 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13533 break;
13534 case OPC_MAQ_SA_W_PHL:
13535 check_dsp(ctx);
13536 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13537 break;
13538 case OPC_MAQ_SA_W_PHR:
13539 check_dsp(ctx);
13540 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13541 break;
13542 case OPC_MULSA_W_PH:
13543 check_dspr2(ctx);
13544 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13545 break;
13546 }
13547 break;
13548 #ifdef TARGET_MIPS64
13549 case OPC_DPAQ_W_QH_DSP:
13550 {
13551 int ac = ret & 0x03;
13552 tcg_gen_movi_i32(t0, ac);
13553
13554 switch (op2) {
13555 case OPC_DMADD:
13556 check_dsp(ctx);
13557 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13558 break;
13559 case OPC_DMADDU:
13560 check_dsp(ctx);
13561 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13562 break;
13563 case OPC_DMSUB:
13564 check_dsp(ctx);
13565 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13566 break;
13567 case OPC_DMSUBU:
13568 check_dsp(ctx);
13569 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13570 break;
13571 case OPC_DPA_W_QH:
13572 check_dspr2(ctx);
13573 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13574 break;
13575 case OPC_DPAQ_S_W_QH:
13576 check_dsp(ctx);
13577 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13578 break;
13579 case OPC_DPAQ_SA_L_PW:
13580 check_dsp(ctx);
13581 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13582 break;
13583 case OPC_DPAU_H_OBL:
13584 check_dsp(ctx);
13585 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13586 break;
13587 case OPC_DPAU_H_OBR:
13588 check_dsp(ctx);
13589 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13590 break;
13591 case OPC_DPS_W_QH:
13592 check_dspr2(ctx);
13593 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13594 break;
13595 case OPC_DPSQ_S_W_QH:
13596 check_dsp(ctx);
13597 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13598 break;
13599 case OPC_DPSQ_SA_L_PW:
13600 check_dsp(ctx);
13601 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13602 break;
13603 case OPC_DPSU_H_OBL:
13604 check_dsp(ctx);
13605 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13606 break;
13607 case OPC_DPSU_H_OBR:
13608 check_dsp(ctx);
13609 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13610 break;
13611 case OPC_MAQ_S_L_PWL:
13612 check_dsp(ctx);
13613 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13614 break;
13615 case OPC_MAQ_S_L_PWR:
13616 check_dsp(ctx);
13617 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13618 break;
13619 case OPC_MAQ_S_W_QHLL:
13620 check_dsp(ctx);
13621 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13622 break;
13623 case OPC_MAQ_SA_W_QHLL:
13624 check_dsp(ctx);
13625 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13626 break;
13627 case OPC_MAQ_S_W_QHLR:
13628 check_dsp(ctx);
13629 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13630 break;
13631 case OPC_MAQ_SA_W_QHLR:
13632 check_dsp(ctx);
13633 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13634 break;
13635 case OPC_MAQ_S_W_QHRL:
13636 check_dsp(ctx);
13637 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13638 break;
13639 case OPC_MAQ_SA_W_QHRL:
13640 check_dsp(ctx);
13641 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13642 break;
13643 case OPC_MAQ_S_W_QHRR:
13644 check_dsp(ctx);
13645 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13646 break;
13647 case OPC_MAQ_SA_W_QHRR:
13648 check_dsp(ctx);
13649 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13650 break;
13651 case OPC_MULSAQ_S_L_PW:
13652 check_dsp(ctx);
13653 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13654 break;
13655 case OPC_MULSAQ_S_W_QH:
13656 check_dsp(ctx);
13657 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13658 break;
13659 }
13660 }
13661 break;
13662 #endif
13663 case OPC_ADDU_QB_DSP:
13664 switch (op2) {
13665 case OPC_MULEU_S_PH_QBL:
13666 check_dsp(ctx);
13667 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 break;
13669 case OPC_MULEU_S_PH_QBR:
13670 check_dsp(ctx);
13671 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 break;
13673 case OPC_MULQ_RS_PH:
13674 check_dsp(ctx);
13675 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 break;
13677 case OPC_MULEQ_S_W_PHL:
13678 check_dsp(ctx);
13679 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13680 break;
13681 case OPC_MULEQ_S_W_PHR:
13682 check_dsp(ctx);
13683 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13684 break;
13685 case OPC_MULQ_S_PH:
13686 check_dspr2(ctx);
13687 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13688 break;
13689 }
13690 break;
13691 #ifdef TARGET_MIPS64
13692 case OPC_ADDU_OB_DSP:
13693 switch (op2) {
13694 case OPC_MULEQ_S_PW_QHL:
13695 check_dsp(ctx);
13696 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13697 break;
13698 case OPC_MULEQ_S_PW_QHR:
13699 check_dsp(ctx);
13700 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13701 break;
13702 case OPC_MULEU_S_QH_OBL:
13703 check_dsp(ctx);
13704 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13705 break;
13706 case OPC_MULEU_S_QH_OBR:
13707 check_dsp(ctx);
13708 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13709 break;
13710 case OPC_MULQ_RS_QH:
13711 check_dsp(ctx);
13712 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13713 break;
13714 }
13715 break;
13716 #endif
13717 }
13718
13719 tcg_temp_free_i32(t0);
13720 tcg_temp_free(v1_t);
13721 tcg_temp_free(v2_t);
13722
13723 (void)opn; /* avoid a compiler warning */
13724 MIPS_DEBUG("%s", opn);
13725
13726 }
13727
13728 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13729 uint32_t op1, uint32_t op2,
13730 int ret, int val)
13731 {
13732 const char *opn = "mipsdsp Bit/ Manipulation";
13733 int16_t imm;
13734 TCGv t0;
13735 TCGv val_t;
13736
13737 if (ret == 0) {
13738 /* Treat as NOP. */
13739 MIPS_DEBUG("NOP");
13740 return;
13741 }
13742
13743 t0 = tcg_temp_new();
13744 val_t = tcg_temp_new();
13745 gen_load_gpr(val_t, val);
13746
13747 switch (op1) {
13748 case OPC_ABSQ_S_PH_DSP:
13749 switch (op2) {
13750 case OPC_BITREV:
13751 check_dsp(ctx);
13752 gen_helper_bitrev(cpu_gpr[ret], val_t);
13753 break;
13754 case OPC_REPL_QB:
13755 check_dsp(ctx);
13756 {
13757 target_long result;
13758 imm = (ctx->opcode >> 16) & 0xFF;
13759 result = (uint32_t)imm << 24 |
13760 (uint32_t)imm << 16 |
13761 (uint32_t)imm << 8 |
13762 (uint32_t)imm;
13763 result = (int32_t)result;
13764 tcg_gen_movi_tl(cpu_gpr[ret], result);
13765 }
13766 break;
13767 case OPC_REPLV_QB:
13768 check_dsp(ctx);
13769 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13770 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13771 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13772 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13773 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13774 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13775 break;
13776 case OPC_REPL_PH:
13777 check_dsp(ctx);
13778 {
13779 imm = (ctx->opcode >> 16) & 0x03FF;
13780 tcg_gen_movi_tl(cpu_gpr[ret], \
13781 (target_long)((int32_t)imm << 16 | \
13782 (uint32_t)(uint16_t)imm));
13783 }
13784 break;
13785 case OPC_REPLV_PH:
13786 check_dsp(ctx);
13787 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13788 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13789 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13790 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13791 break;
13792 }
13793 break;
13794 #ifdef TARGET_MIPS64
13795 case OPC_ABSQ_S_QH_DSP:
13796 switch (op2) {
13797 case OPC_REPL_OB:
13798 check_dsp(ctx);
13799 {
13800 target_long temp;
13801
13802 imm = (ctx->opcode >> 16) & 0xFF;
13803 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13804 temp = (temp << 16) | temp;
13805 temp = (temp << 32) | temp;
13806 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13807 break;
13808 }
13809 case OPC_REPL_PW:
13810 check_dsp(ctx);
13811 {
13812 target_long temp;
13813
13814 imm = (ctx->opcode >> 16) & 0x03FF;
13815 imm = (int16_t)(imm << 6) >> 6;
13816 temp = ((target_long)imm << 32) \
13817 | ((target_long)imm & 0xFFFFFFFF);
13818 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13819 break;
13820 }
13821 case OPC_REPL_QH:
13822 check_dsp(ctx);
13823 {
13824 target_long temp;
13825
13826 imm = (ctx->opcode >> 16) & 0x03FF;
13827 imm = (int16_t)(imm << 6) >> 6;
13828
13829 temp = ((uint64_t)(uint16_t)imm << 48) |
13830 ((uint64_t)(uint16_t)imm << 32) |
13831 ((uint64_t)(uint16_t)imm << 16) |
13832 (uint64_t)(uint16_t)imm;
13833 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13834 break;
13835 }
13836 case OPC_REPLV_OB:
13837 check_dsp(ctx);
13838 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13839 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13840 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13841 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13842 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13843 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13844 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13845 break;
13846 case OPC_REPLV_PW:
13847 check_dsp(ctx);
13848 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13849 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13850 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13851 break;
13852 case OPC_REPLV_QH:
13853 check_dsp(ctx);
13854 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13855 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13856 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13857 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13858 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13859 break;
13860 }
13861 break;
13862 #endif
13863 }
13864 tcg_temp_free(t0);
13865 tcg_temp_free(val_t);
13866
13867 (void)opn; /* avoid a compiler warning */
13868 MIPS_DEBUG("%s", opn);
13869 }
13870
13871 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13872 uint32_t op1, uint32_t op2,
13873 int ret, int v1, int v2, int check_ret)
13874 {
13875 const char *opn = "mipsdsp add compare pick";
13876 TCGv_i32 t0;
13877 TCGv t1;
13878 TCGv v1_t;
13879 TCGv v2_t;
13880
13881 if ((ret == 0) && (check_ret == 1)) {
13882 /* Treat as NOP. */
13883 MIPS_DEBUG("NOP");
13884 return;
13885 }
13886
13887 t0 = tcg_temp_new_i32();
13888 t1 = tcg_temp_new();
13889 v1_t = tcg_temp_new();
13890 v2_t = tcg_temp_new();
13891
13892 gen_load_gpr(v1_t, v1);
13893 gen_load_gpr(v2_t, v2);
13894
13895 switch (op1) {
13896 case OPC_APPEND_DSP:
13897 switch (op2) {
13898 case OPC_APPEND:
13899 tcg_gen_movi_i32(t0, v2);
13900 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13901 break;
13902 case OPC_PREPEND:
13903 tcg_gen_movi_i32(t0, v2);
13904 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13905 break;
13906 case OPC_BALIGN:
13907 tcg_gen_movi_i32(t0, v2);
13908 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13909 break;
13910 default: /* Invid */
13911 MIPS_INVAL("MASK APPEND");
13912 generate_exception(ctx, EXCP_RI);
13913 break;
13914 }
13915 break;
13916 case OPC_CMPU_EQ_QB_DSP:
13917 switch (op2) {
13918 case OPC_CMPU_EQ_QB:
13919 check_dsp(ctx);
13920 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13921 break;
13922 case OPC_CMPU_LT_QB:
13923 check_dsp(ctx);
13924 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13925 break;
13926 case OPC_CMPU_LE_QB:
13927 check_dsp(ctx);
13928 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13929 break;
13930 case OPC_CMPGU_EQ_QB:
13931 check_dsp(ctx);
13932 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13933 break;
13934 case OPC_CMPGU_LT_QB:
13935 check_dsp(ctx);
13936 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13937 break;
13938 case OPC_CMPGU_LE_QB:
13939 check_dsp(ctx);
13940 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13941 break;
13942 case OPC_CMPGDU_EQ_QB:
13943 check_dspr2(ctx);
13944 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13945 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13946 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13947 tcg_gen_shli_tl(t1, t1, 24);
13948 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13949 break;
13950 case OPC_CMPGDU_LT_QB:
13951 check_dspr2(ctx);
13952 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13953 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13954 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13955 tcg_gen_shli_tl(t1, t1, 24);
13956 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13957 break;
13958 case OPC_CMPGDU_LE_QB:
13959 check_dspr2(ctx);
13960 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13961 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13962 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13963 tcg_gen_shli_tl(t1, t1, 24);
13964 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13965 break;
13966 case OPC_CMP_EQ_PH:
13967 check_dsp(ctx);
13968 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13969 break;
13970 case OPC_CMP_LT_PH:
13971 check_dsp(ctx);
13972 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13973 break;
13974 case OPC_CMP_LE_PH:
13975 check_dsp(ctx);
13976 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13977 break;
13978 case OPC_PICK_QB:
13979 check_dsp(ctx);
13980 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13981 break;
13982 case OPC_PICK_PH:
13983 check_dsp(ctx);
13984 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13985 break;
13986 case OPC_PACKRL_PH:
13987 check_dsp(ctx);
13988 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13989 break;
13990 }
13991 break;
13992 #ifdef TARGET_MIPS64
13993 case OPC_CMPU_EQ_OB_DSP:
13994 switch (op2) {
13995 case OPC_CMP_EQ_PW:
13996 check_dsp(ctx);
13997 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13998 break;
13999 case OPC_CMP_LT_PW:
14000 check_dsp(ctx);
14001 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
14002 break;
14003 case OPC_CMP_LE_PW:
14004 check_dsp(ctx);
14005 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14006 break;
14007 case OPC_CMP_EQ_QH:
14008 check_dsp(ctx);
14009 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14010 break;
14011 case OPC_CMP_LT_QH:
14012 check_dsp(ctx);
14013 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14014 break;
14015 case OPC_CMP_LE_QH:
14016 check_dsp(ctx);
14017 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14018 break;
14019 case OPC_CMPGDU_EQ_OB:
14020 check_dspr2(ctx);
14021 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14022 break;
14023 case OPC_CMPGDU_LT_OB:
14024 check_dspr2(ctx);
14025 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14026 break;
14027 case OPC_CMPGDU_LE_OB:
14028 check_dspr2(ctx);
14029 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14030 break;
14031 case OPC_CMPGU_EQ_OB:
14032 check_dsp(ctx);
14033 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14034 break;
14035 case OPC_CMPGU_LT_OB:
14036 check_dsp(ctx);
14037 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14038 break;
14039 case OPC_CMPGU_LE_OB:
14040 check_dsp(ctx);
14041 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14042 break;
14043 case OPC_CMPU_EQ_OB:
14044 check_dsp(ctx);
14045 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14046 break;
14047 case OPC_CMPU_LT_OB:
14048 check_dsp(ctx);
14049 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14050 break;
14051 case OPC_CMPU_LE_OB:
14052 check_dsp(ctx);
14053 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14054 break;
14055 case OPC_PACKRL_PW:
14056 check_dsp(ctx);
14057 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14058 break;
14059 case OPC_PICK_OB:
14060 check_dsp(ctx);
14061 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14062 break;
14063 case OPC_PICK_PW:
14064 check_dsp(ctx);
14065 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14066 break;
14067 case OPC_PICK_QH:
14068 check_dsp(ctx);
14069 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14070 break;
14071 }
14072 break;
14073 case OPC_DAPPEND_DSP:
14074 switch (op2) {
14075 case OPC_DAPPEND:
14076 tcg_gen_movi_i32(t0, v2);
14077 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14078 break;
14079 case OPC_PREPENDD:
14080 tcg_gen_movi_i32(t0, v2);
14081 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14082 break;
14083 case OPC_PREPENDW:
14084 tcg_gen_movi_i32(t0, v2);
14085 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14086 break;
14087 case OPC_DBALIGN:
14088 tcg_gen_movi_i32(t0, v2);
14089 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14090 break;
14091 default: /* Invalid */
14092 MIPS_INVAL("MASK DAPPEND");
14093 generate_exception(ctx, EXCP_RI);
14094 break;
14095 }
14096 break;
14097 #endif
14098 }
14099
14100 tcg_temp_free_i32(t0);
14101 tcg_temp_free(t1);
14102 tcg_temp_free(v1_t);
14103 tcg_temp_free(v2_t);
14104
14105 (void)opn; /* avoid a compiler warning */
14106 MIPS_DEBUG("%s", opn);
14107 }
14108
14109 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14110 int ret, int v1, int v2, int check_ret)
14111
14112 {
14113 const char *opn = "mipsdsp accumulator";
14114 TCGv t0;
14115 TCGv t1;
14116 TCGv v1_t;
14117 TCGv v2_t;
14118 int16_t imm;
14119
14120 if ((ret == 0) && (check_ret == 1)) {
14121 /* Treat as NOP. */
14122 MIPS_DEBUG("NOP");
14123 return;
14124 }
14125
14126 t0 = tcg_temp_new();
14127 t1 = tcg_temp_new();
14128 v1_t = tcg_temp_new();
14129 v2_t = tcg_temp_new();
14130
14131 gen_load_gpr(v1_t, v1);
14132 gen_load_gpr(v2_t, v2);
14133
14134 switch (op1) {
14135 case OPC_EXTR_W_DSP:
14136 check_dsp(ctx);
14137 switch (op2) {
14138 case OPC_EXTR_W:
14139 tcg_gen_movi_tl(t0, v2);
14140 tcg_gen_movi_tl(t1, v1);
14141 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14142 break;
14143 case OPC_EXTR_R_W:
14144 tcg_gen_movi_tl(t0, v2);
14145 tcg_gen_movi_tl(t1, v1);
14146 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14147 break;
14148 case OPC_EXTR_RS_W:
14149 tcg_gen_movi_tl(t0, v2);
14150 tcg_gen_movi_tl(t1, v1);
14151 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14152 break;
14153 case OPC_EXTR_S_H:
14154 tcg_gen_movi_tl(t0, v2);
14155 tcg_gen_movi_tl(t1, v1);
14156 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14157 break;
14158 case OPC_EXTRV_S_H:
14159 tcg_gen_movi_tl(t0, v2);
14160 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14161 break;
14162 case OPC_EXTRV_W:
14163 tcg_gen_movi_tl(t0, v2);
14164 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14165 break;
14166 case OPC_EXTRV_R_W:
14167 tcg_gen_movi_tl(t0, v2);
14168 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14169 break;
14170 case OPC_EXTRV_RS_W:
14171 tcg_gen_movi_tl(t0, v2);
14172 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14173 break;
14174 case OPC_EXTP:
14175 tcg_gen_movi_tl(t0, v2);
14176 tcg_gen_movi_tl(t1, v1);
14177 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14178 break;
14179 case OPC_EXTPV:
14180 tcg_gen_movi_tl(t0, v2);
14181 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14182 break;
14183 case OPC_EXTPDP:
14184 tcg_gen_movi_tl(t0, v2);
14185 tcg_gen_movi_tl(t1, v1);
14186 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14187 break;
14188 case OPC_EXTPDPV:
14189 tcg_gen_movi_tl(t0, v2);
14190 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14191 break;
14192 case OPC_SHILO:
14193 imm = (ctx->opcode >> 20) & 0x3F;
14194 tcg_gen_movi_tl(t0, ret);
14195 tcg_gen_movi_tl(t1, imm);
14196 gen_helper_shilo(t0, t1, cpu_env);
14197 break;
14198 case OPC_SHILOV:
14199 tcg_gen_movi_tl(t0, ret);
14200 gen_helper_shilo(t0, v1_t, cpu_env);
14201 break;
14202 case OPC_MTHLIP:
14203 tcg_gen_movi_tl(t0, ret);
14204 gen_helper_mthlip(t0, v1_t, cpu_env);
14205 break;
14206 case OPC_WRDSP:
14207 imm = (ctx->opcode >> 11) & 0x3FF;
14208 tcg_gen_movi_tl(t0, imm);
14209 gen_helper_wrdsp(v1_t, t0, cpu_env);
14210 break;
14211 case OPC_RDDSP:
14212 imm = (ctx->opcode >> 16) & 0x03FF;
14213 tcg_gen_movi_tl(t0, imm);
14214 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14215 break;
14216 }
14217 break;
14218 #ifdef TARGET_MIPS64
14219 case OPC_DEXTR_W_DSP:
14220 check_dsp(ctx);
14221 switch (op2) {
14222 case OPC_DMTHLIP:
14223 tcg_gen_movi_tl(t0, ret);
14224 gen_helper_dmthlip(v1_t, t0, cpu_env);
14225 break;
14226 case OPC_DSHILO:
14227 {
14228 int shift = (ctx->opcode >> 19) & 0x7F;
14229 int ac = (ctx->opcode >> 11) & 0x03;
14230 tcg_gen_movi_tl(t0, shift);
14231 tcg_gen_movi_tl(t1, ac);
14232 gen_helper_dshilo(t0, t1, cpu_env);
14233 break;
14234 }
14235 case OPC_DSHILOV:
14236 {
14237 int ac = (ctx->opcode >> 11) & 0x03;
14238 tcg_gen_movi_tl(t0, ac);
14239 gen_helper_dshilo(v1_t, t0, cpu_env);
14240 break;
14241 }
14242 case OPC_DEXTP:
14243 tcg_gen_movi_tl(t0, v2);
14244 tcg_gen_movi_tl(t1, v1);
14245
14246 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14247 break;
14248 case OPC_DEXTPV:
14249 tcg_gen_movi_tl(t0, v2);
14250 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14251 break;
14252 case OPC_DEXTPDP:
14253 tcg_gen_movi_tl(t0, v2);
14254 tcg_gen_movi_tl(t1, v1);
14255 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14256 break;
14257 case OPC_DEXTPDPV:
14258 tcg_gen_movi_tl(t0, v2);
14259 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14260 break;
14261 case OPC_DEXTR_L:
14262 tcg_gen_movi_tl(t0, v2);
14263 tcg_gen_movi_tl(t1, v1);
14264 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14265 break;
14266 case OPC_DEXTR_R_L:
14267 tcg_gen_movi_tl(t0, v2);
14268 tcg_gen_movi_tl(t1, v1);
14269 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14270 break;
14271 case OPC_DEXTR_RS_L:
14272 tcg_gen_movi_tl(t0, v2);
14273 tcg_gen_movi_tl(t1, v1);
14274 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14275 break;
14276 case OPC_DEXTR_W:
14277 tcg_gen_movi_tl(t0, v2);
14278 tcg_gen_movi_tl(t1, v1);
14279 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14280 break;
14281 case OPC_DEXTR_R_W:
14282 tcg_gen_movi_tl(t0, v2);
14283 tcg_gen_movi_tl(t1, v1);
14284 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14285 break;
14286 case OPC_DEXTR_RS_W:
14287 tcg_gen_movi_tl(t0, v2);
14288 tcg_gen_movi_tl(t1, v1);
14289 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14290 break;
14291 case OPC_DEXTR_S_H:
14292 tcg_gen_movi_tl(t0, v2);
14293 tcg_gen_movi_tl(t1, v1);
14294 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14295 break;
14296 case OPC_DEXTRV_S_H:
14297 tcg_gen_movi_tl(t0, v2);
14298 tcg_gen_movi_tl(t1, v1);
14299 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14300 break;
14301 case OPC_DEXTRV_L:
14302 tcg_gen_movi_tl(t0, v2);
14303 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14304 break;
14305 case OPC_DEXTRV_R_L:
14306 tcg_gen_movi_tl(t0, v2);
14307 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14308 break;
14309 case OPC_DEXTRV_RS_L:
14310 tcg_gen_movi_tl(t0, v2);
14311 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14312 break;
14313 case OPC_DEXTRV_W:
14314 tcg_gen_movi_tl(t0, v2);
14315 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14316 break;
14317 case OPC_DEXTRV_R_W:
14318 tcg_gen_movi_tl(t0, v2);
14319 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14320 break;
14321 case OPC_DEXTRV_RS_W:
14322 tcg_gen_movi_tl(t0, v2);
14323 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14324 break;
14325 }
14326 break;
14327 #endif
14328 }
14329
14330 tcg_temp_free(t0);
14331 tcg_temp_free(t1);
14332 tcg_temp_free(v1_t);
14333 tcg_temp_free(v2_t);
14334
14335 (void)opn; /* avoid a compiler warning */
14336 MIPS_DEBUG("%s", opn);
14337 }
14338
14339 /* End MIPSDSP functions. */
14340
14341 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14342 {
14343 int32_t offset;
14344 int rs, rt, rd, sa;
14345 uint32_t op, op1, op2;
14346 int16_t imm;
14347
14348 /* make sure instructions are on a word boundary */
14349 if (ctx->pc & 0x3) {
14350 env->CP0_BadVAddr = ctx->pc;
14351 generate_exception(ctx, EXCP_AdEL);
14352 return;
14353 }
14354
14355 /* Handle blikely not taken case */
14356 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14357 int l1 = gen_new_label();
14358
14359 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14360 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14361 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14362 gen_goto_tb(ctx, 1, ctx->pc + 4);
14363 gen_set_label(l1);
14364 }
14365
14366 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14367 tcg_gen_debug_insn_start(ctx->pc);
14368 }
14369
14370 op = MASK_OP_MAJOR(ctx->opcode);
14371 rs = (ctx->opcode >> 21) & 0x1f;
14372 rt = (ctx->opcode >> 16) & 0x1f;
14373 rd = (ctx->opcode >> 11) & 0x1f;
14374 sa = (ctx->opcode >> 6) & 0x1f;
14375 imm = (int16_t)ctx->opcode;
14376 switch (op) {
14377 case OPC_SPECIAL:
14378 op1 = MASK_SPECIAL(ctx->opcode);
14379 switch (op1) {
14380 case OPC_SLL: /* Shift with immediate */
14381 case OPC_SRA:
14382 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14383 break;
14384 case OPC_SRL:
14385 switch ((ctx->opcode >> 21) & 0x1f) {
14386 case 1:
14387 /* rotr is decoded as srl on non-R2 CPUs */
14388 if (env->insn_flags & ISA_MIPS32R2) {
14389 op1 = OPC_ROTR;
14390 }
14391 /* Fallthrough */
14392 case 0:
14393 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14394 break;
14395 default:
14396 generate_exception(ctx, EXCP_RI);
14397 break;
14398 }
14399 break;
14400 case OPC_MOVN: /* Conditional move */
14401 case OPC_MOVZ:
14402 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14403 INSN_LOONGSON2E | INSN_LOONGSON2F);
14404 gen_cond_move(env, ctx, op1, rd, rs, rt);
14405 break;
14406 case OPC_ADD ... OPC_SUBU:
14407 gen_arith(env, ctx, op1, rd, rs, rt);
14408 break;
14409 case OPC_SLLV: /* Shifts */
14410 case OPC_SRAV:
14411 gen_shift(env, ctx, op1, rd, rs, rt);
14412 break;
14413 case OPC_SRLV:
14414 switch ((ctx->opcode >> 6) & 0x1f) {
14415 case 1:
14416 /* rotrv is decoded as srlv on non-R2 CPUs */
14417 if (env->insn_flags & ISA_MIPS32R2) {
14418 op1 = OPC_ROTRV;
14419 }
14420 /* Fallthrough */
14421 case 0:
14422 gen_shift(env, ctx, op1, rd, rs, rt);
14423 break;
14424 default:
14425 generate_exception(ctx, EXCP_RI);
14426 break;
14427 }
14428 break;
14429 case OPC_SLT: /* Set on less than */
14430 case OPC_SLTU:
14431 gen_slt(env, ctx, op1, rd, rs, rt);
14432 break;
14433 case OPC_AND: /* Logic*/
14434 case OPC_OR:
14435 case OPC_NOR:
14436 case OPC_XOR:
14437 gen_logic(env, ctx, op1, rd, rs, rt);
14438 break;
14439 case OPC_MULT ... OPC_DIVU:
14440 if (sa) {
14441 check_insn(env, ctx, INSN_VR54XX);
14442 op1 = MASK_MUL_VR54XX(ctx->opcode);
14443 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14444 } else
14445 gen_muldiv(ctx, op1, rs, rt);
14446 break;
14447 case OPC_JR ... OPC_JALR:
14448 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14449 *is_branch = 1;
14450 break;
14451 case OPC_TGE ... OPC_TEQ: /* Traps */
14452 case OPC_TNE:
14453 gen_trap(ctx, op1, rs, rt, -1);
14454 break;
14455 case OPC_MFHI: /* Move from HI/LO */
14456 case OPC_MFLO:
14457 gen_HILO(ctx, op1, rd);
14458 break;
14459 case OPC_MTHI:
14460 case OPC_MTLO: /* Move to HI/LO */
14461 gen_HILO(ctx, op1, rs);
14462 break;
14463 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14464 #ifdef MIPS_STRICT_STANDARD
14465 MIPS_INVAL("PMON / selsl");
14466 generate_exception(ctx, EXCP_RI);
14467 #else
14468 gen_helper_0e0i(pmon, sa);
14469 #endif
14470 break;
14471 case OPC_SYSCALL:
14472 generate_exception(ctx, EXCP_SYSCALL);
14473 ctx->bstate = BS_STOP;
14474 break;
14475 case OPC_BREAK:
14476 generate_exception(ctx, EXCP_BREAK);
14477 break;
14478 case OPC_SPIM:
14479 #ifdef MIPS_STRICT_STANDARD
14480 MIPS_INVAL("SPIM");
14481 generate_exception(ctx, EXCP_RI);
14482 #else
14483 /* Implemented as RI exception for now. */
14484 MIPS_INVAL("spim (unofficial)");
14485 generate_exception(ctx, EXCP_RI);
14486 #endif
14487 break;
14488 case OPC_SYNC:
14489 /* Treat as NOP. */
14490 break;
14491
14492 case OPC_MOVCI:
14493 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14494 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14495 check_cp1_enabled(ctx);
14496 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14497 (ctx->opcode >> 16) & 1);
14498 } else {
14499 generate_exception_err(ctx, EXCP_CpU, 1);
14500 }
14501 break;
14502
14503 #if defined(TARGET_MIPS64)
14504 /* MIPS64 specific opcodes */
14505 case OPC_DSLL:
14506 case OPC_DSRA:
14507 case OPC_DSLL32:
14508 case OPC_DSRA32:
14509 check_insn(env, ctx, ISA_MIPS3);
14510 check_mips_64(ctx);
14511 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14512 break;
14513 case OPC_DSRL:
14514 switch ((ctx->opcode >> 21) & 0x1f) {
14515 case 1:
14516 /* drotr is decoded as dsrl on non-R2 CPUs */
14517 if (env->insn_flags & ISA_MIPS32R2) {
14518 op1 = OPC_DROTR;
14519 }
14520 /* Fallthrough */
14521 case 0:
14522 check_insn(env, ctx, ISA_MIPS3);
14523 check_mips_64(ctx);
14524 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14525 break;
14526 default:
14527 generate_exception(ctx, EXCP_RI);
14528 break;
14529 }
14530 break;
14531 case OPC_DSRL32:
14532 switch ((ctx->opcode >> 21) & 0x1f) {
14533 case 1:
14534 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14535 if (env->insn_flags & ISA_MIPS32R2) {
14536 op1 = OPC_DROTR32;
14537 }
14538 /* Fallthrough */
14539 case 0:
14540 check_insn(env, ctx, ISA_MIPS3);
14541 check_mips_64(ctx);
14542 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14543 break;
14544 default:
14545 generate_exception(ctx, EXCP_RI);
14546 break;
14547 }
14548 break;
14549 case OPC_DADD ... OPC_DSUBU:
14550 check_insn(env, ctx, ISA_MIPS3);
14551 check_mips_64(ctx);
14552 gen_arith(env, ctx, op1, rd, rs, rt);
14553 break;
14554 case OPC_DSLLV:
14555 case OPC_DSRAV:
14556 check_insn(env, ctx, ISA_MIPS3);
14557 check_mips_64(ctx);
14558 gen_shift(env, ctx, op1, rd, rs, rt);
14559 break;
14560 case OPC_DSRLV:
14561 switch ((ctx->opcode >> 6) & 0x1f) {
14562 case 1:
14563 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14564 if (env->insn_flags & ISA_MIPS32R2) {
14565 op1 = OPC_DROTRV;
14566 }
14567 /* Fallthrough */
14568 case 0:
14569 check_insn(env, ctx, ISA_MIPS3);
14570 check_mips_64(ctx);
14571 gen_shift(env, ctx, op1, rd, rs, rt);
14572 break;
14573 default:
14574 generate_exception(ctx, EXCP_RI);
14575 break;
14576 }
14577 break;
14578 case OPC_DMULT ... OPC_DDIVU:
14579 check_insn(env, ctx, ISA_MIPS3);
14580 check_mips_64(ctx);
14581 gen_muldiv(ctx, op1, rs, rt);
14582 break;
14583 #endif
14584 default: /* Invalid */
14585 MIPS_INVAL("special");
14586 generate_exception(ctx, EXCP_RI);
14587 break;
14588 }
14589 break;
14590 case OPC_SPECIAL2:
14591 op1 = MASK_SPECIAL2(ctx->opcode);
14592 switch (op1) {
14593 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14594 case OPC_MSUB ... OPC_MSUBU:
14595 check_insn(env, ctx, ISA_MIPS32);
14596 gen_muldiv(ctx, op1, rs, rt);
14597 break;
14598 case OPC_MUL:
14599 gen_arith(env, ctx, op1, rd, rs, rt);
14600 break;
14601 case OPC_CLO:
14602 case OPC_CLZ:
14603 check_insn(env, ctx, ISA_MIPS32);
14604 gen_cl(ctx, op1, rd, rs);
14605 break;
14606 case OPC_SDBBP:
14607 /* XXX: not clear which exception should be raised
14608 * when in debug mode...
14609 */
14610 check_insn(env, ctx, ISA_MIPS32);
14611 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14612 generate_exception(ctx, EXCP_DBp);
14613 } else {
14614 generate_exception(ctx, EXCP_DBp);
14615 }
14616 /* Treat as NOP. */
14617 break;
14618 case OPC_DIV_G_2F:
14619 case OPC_DIVU_G_2F:
14620 case OPC_MULT_G_2F:
14621 case OPC_MULTU_G_2F:
14622 case OPC_MOD_G_2F:
14623 case OPC_MODU_G_2F:
14624 check_insn(env, ctx, INSN_LOONGSON2F);
14625 gen_loongson_integer(ctx, op1, rd, rs, rt);
14626 break;
14627 #if defined(TARGET_MIPS64)
14628 case OPC_DCLO:
14629 case OPC_DCLZ:
14630 check_insn(env, ctx, ISA_MIPS64);
14631 check_mips_64(ctx);
14632 gen_cl(ctx, op1, rd, rs);
14633 break;
14634 case OPC_DMULT_G_2F:
14635 case OPC_DMULTU_G_2F:
14636 case OPC_DDIV_G_2F:
14637 case OPC_DDIVU_G_2F:
14638 case OPC_DMOD_G_2F:
14639 case OPC_DMODU_G_2F:
14640 check_insn(env, ctx, INSN_LOONGSON2F);
14641 gen_loongson_integer(ctx, op1, rd, rs, rt);
14642 break;
14643 #endif
14644 default: /* Invalid */
14645 MIPS_INVAL("special2");
14646 generate_exception(ctx, EXCP_RI);
14647 break;
14648 }
14649 break;
14650 case OPC_SPECIAL3:
14651 op1 = MASK_SPECIAL3(ctx->opcode);
14652 switch (op1) {
14653 case OPC_EXT:
14654 case OPC_INS:
14655 check_insn(env, ctx, ISA_MIPS32R2);
14656 gen_bitops(ctx, op1, rt, rs, sa, rd);
14657 break;
14658 case OPC_BSHFL:
14659 check_insn(env, ctx, ISA_MIPS32R2);
14660 op2 = MASK_BSHFL(ctx->opcode);
14661 gen_bshfl(ctx, op2, rt, rd);
14662 break;
14663 case OPC_RDHWR:
14664 gen_rdhwr(env, ctx, rt, rd);
14665 break;
14666 case OPC_FORK:
14667 check_insn(env, ctx, ASE_MT);
14668 {
14669 TCGv t0 = tcg_temp_new();
14670 TCGv t1 = tcg_temp_new();
14671
14672 gen_load_gpr(t0, rt);
14673 gen_load_gpr(t1, rs);
14674 gen_helper_fork(t0, t1);
14675 tcg_temp_free(t0);
14676 tcg_temp_free(t1);
14677 }
14678 break;
14679 case OPC_YIELD:
14680 check_insn(env, ctx, ASE_MT);
14681 {
14682 TCGv t0 = tcg_temp_new();
14683
14684 save_cpu_state(ctx, 1);
14685 gen_load_gpr(t0, rs);
14686 gen_helper_yield(t0, cpu_env, t0);
14687 gen_store_gpr(t0, rd);
14688 tcg_temp_free(t0);
14689 }
14690 break;
14691 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14692 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14693 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14694 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14695 * the same mask and op1. */
14696 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14697 op2 = MASK_ADDUH_QB(ctx->opcode);
14698 switch (op2) {
14699 case OPC_ADDUH_QB:
14700 case OPC_ADDUH_R_QB:
14701 case OPC_ADDQH_PH:
14702 case OPC_ADDQH_R_PH:
14703 case OPC_ADDQH_W:
14704 case OPC_ADDQH_R_W:
14705 case OPC_SUBUH_QB:
14706 case OPC_SUBUH_R_QB:
14707 case OPC_SUBQH_PH:
14708 case OPC_SUBQH_R_PH:
14709 case OPC_SUBQH_W:
14710 case OPC_SUBQH_R_W:
14711 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14712 break;
14713 case OPC_MUL_PH:
14714 case OPC_MUL_S_PH:
14715 case OPC_MULQ_S_W:
14716 case OPC_MULQ_RS_W:
14717 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14718 break;
14719 default:
14720 MIPS_INVAL("MASK ADDUH.QB");
14721 generate_exception(ctx, EXCP_RI);
14722 break;
14723 }
14724 } else if (env->insn_flags & INSN_LOONGSON2E) {
14725 gen_loongson_integer(ctx, op1, rd, rs, rt);
14726 } else {
14727 generate_exception(ctx, EXCP_RI);
14728 }
14729 break;
14730 case OPC_LX_DSP:
14731 op2 = MASK_LX(ctx->opcode);
14732 switch (op2) {
14733 #if defined(TARGET_MIPS64)
14734 case OPC_LDX:
14735 #endif
14736 case OPC_LBUX:
14737 case OPC_LHX:
14738 case OPC_LWX:
14739 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14740 break;
14741 default: /* Invalid */
14742 MIPS_INVAL("MASK LX");
14743 generate_exception(ctx, EXCP_RI);
14744 break;
14745 }
14746 break;
14747 case OPC_ABSQ_S_PH_DSP:
14748 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14749 switch (op2) {
14750 case OPC_ABSQ_S_QB:
14751 case OPC_ABSQ_S_PH:
14752 case OPC_ABSQ_S_W:
14753 case OPC_PRECEQ_W_PHL:
14754 case OPC_PRECEQ_W_PHR:
14755 case OPC_PRECEQU_PH_QBL:
14756 case OPC_PRECEQU_PH_QBR:
14757 case OPC_PRECEQU_PH_QBLA:
14758 case OPC_PRECEQU_PH_QBRA:
14759 case OPC_PRECEU_PH_QBL:
14760 case OPC_PRECEU_PH_QBR:
14761 case OPC_PRECEU_PH_QBLA:
14762 case OPC_PRECEU_PH_QBRA:
14763 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14764 break;
14765 case OPC_BITREV:
14766 case OPC_REPL_QB:
14767 case OPC_REPLV_QB:
14768 case OPC_REPL_PH:
14769 case OPC_REPLV_PH:
14770 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14771 break;
14772 default:
14773 MIPS_INVAL("MASK ABSQ_S.PH");
14774 generate_exception(ctx, EXCP_RI);
14775 break;
14776 }
14777 break;
14778 case OPC_ADDU_QB_DSP:
14779 op2 = MASK_ADDU_QB(ctx->opcode);
14780 switch (op2) {
14781 case OPC_ADDQ_PH:
14782 case OPC_ADDQ_S_PH:
14783 case OPC_ADDQ_S_W:
14784 case OPC_ADDU_QB:
14785 case OPC_ADDU_S_QB:
14786 case OPC_ADDU_PH:
14787 case OPC_ADDU_S_PH:
14788 case OPC_SUBQ_PH:
14789 case OPC_SUBQ_S_PH:
14790 case OPC_SUBQ_S_W:
14791 case OPC_SUBU_QB:
14792 case OPC_SUBU_S_QB:
14793 case OPC_SUBU_PH:
14794 case OPC_SUBU_S_PH:
14795 case OPC_ADDSC:
14796 case OPC_ADDWC:
14797 case OPC_MODSUB:
14798 case OPC_RADDU_W_QB:
14799 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14800 break;
14801 case OPC_MULEU_S_PH_QBL:
14802 case OPC_MULEU_S_PH_QBR:
14803 case OPC_MULQ_RS_PH:
14804 case OPC_MULEQ_S_W_PHL:
14805 case OPC_MULEQ_S_W_PHR:
14806 case OPC_MULQ_S_PH:
14807 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14808 break;
14809 default: /* Invalid */
14810 MIPS_INVAL("MASK ADDU.QB");
14811 generate_exception(ctx, EXCP_RI);
14812 break;
14813
14814 }
14815 break;
14816 case OPC_CMPU_EQ_QB_DSP:
14817 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14818 switch (op2) {
14819 case OPC_PRECR_SRA_PH_W:
14820 case OPC_PRECR_SRA_R_PH_W:
14821 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14822 break;
14823 case OPC_PRECR_QB_PH:
14824 case OPC_PRECRQ_QB_PH:
14825 case OPC_PRECRQ_PH_W:
14826 case OPC_PRECRQ_RS_PH_W:
14827 case OPC_PRECRQU_S_QB_PH:
14828 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14829 break;
14830 case OPC_CMPU_EQ_QB:
14831 case OPC_CMPU_LT_QB:
14832 case OPC_CMPU_LE_QB:
14833 case OPC_CMP_EQ_PH:
14834 case OPC_CMP_LT_PH:
14835 case OPC_CMP_LE_PH:
14836 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14837 break;
14838 case OPC_CMPGU_EQ_QB:
14839 case OPC_CMPGU_LT_QB:
14840 case OPC_CMPGU_LE_QB:
14841 case OPC_CMPGDU_EQ_QB:
14842 case OPC_CMPGDU_LT_QB:
14843 case OPC_CMPGDU_LE_QB:
14844 case OPC_PICK_QB:
14845 case OPC_PICK_PH:
14846 case OPC_PACKRL_PH:
14847 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14848 break;
14849 default: /* Invalid */
14850 MIPS_INVAL("MASK CMPU.EQ.QB");
14851 generate_exception(ctx, EXCP_RI);
14852 break;
14853 }
14854 break;
14855 case OPC_SHLL_QB_DSP:
14856 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14857 break;
14858 case OPC_DPA_W_PH_DSP:
14859 op2 = MASK_DPA_W_PH(ctx->opcode);
14860 switch (op2) {
14861 case OPC_DPAU_H_QBL:
14862 case OPC_DPAU_H_QBR:
14863 case OPC_DPSU_H_QBL:
14864 case OPC_DPSU_H_QBR:
14865 case OPC_DPA_W_PH:
14866 case OPC_DPAX_W_PH:
14867 case OPC_DPAQ_S_W_PH:
14868 case OPC_DPAQX_S_W_PH:
14869 case OPC_DPAQX_SA_W_PH:
14870 case OPC_DPS_W_PH:
14871 case OPC_DPSX_W_PH:
14872 case OPC_DPSQ_S_W_PH:
14873 case OPC_DPSQX_S_W_PH:
14874 case OPC_DPSQX_SA_W_PH:
14875 case OPC_MULSAQ_S_W_PH:
14876 case OPC_DPAQ_SA_L_W:
14877 case OPC_DPSQ_SA_L_W:
14878 case OPC_MAQ_S_W_PHL:
14879 case OPC_MAQ_S_W_PHR:
14880 case OPC_MAQ_SA_W_PHL:
14881 case OPC_MAQ_SA_W_PHR:
14882 case OPC_MULSA_W_PH:
14883 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14884 break;
14885 default: /* Invalid */
14886 MIPS_INVAL("MASK DPAW.PH");
14887 generate_exception(ctx, EXCP_RI);
14888 break;
14889 }
14890 break;
14891 case OPC_INSV_DSP:
14892 op2 = MASK_INSV(ctx->opcode);
14893 switch (op2) {
14894 case OPC_INSV:
14895 check_dsp(ctx);
14896 {
14897 TCGv t0, t1;
14898
14899 if (rt == 0) {
14900 MIPS_DEBUG("NOP");
14901 break;
14902 }
14903
14904 t0 = tcg_temp_new();
14905 t1 = tcg_temp_new();
14906
14907 gen_load_gpr(t0, rt);
14908 gen_load_gpr(t1, rs);
14909
14910 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14911
14912 tcg_temp_free(t0);
14913 tcg_temp_free(t1);
14914 break;
14915 }
14916 default: /* Invalid */
14917 MIPS_INVAL("MASK INSV");
14918 generate_exception(ctx, EXCP_RI);
14919 break;
14920 }
14921 break;
14922 case OPC_APPEND_DSP:
14923 check_dspr2(ctx);
14924 op2 = MASK_APPEND(ctx->opcode);
14925 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14926 break;
14927 case OPC_EXTR_W_DSP:
14928 op2 = MASK_EXTR_W(ctx->opcode);
14929 switch (op2) {
14930 case OPC_EXTR_W:
14931 case OPC_EXTR_R_W:
14932 case OPC_EXTR_RS_W:
14933 case OPC_EXTR_S_H:
14934 case OPC_EXTRV_S_H:
14935 case OPC_EXTRV_W:
14936 case OPC_EXTRV_R_W:
14937 case OPC_EXTRV_RS_W:
14938 case OPC_EXTP:
14939 case OPC_EXTPV:
14940 case OPC_EXTPDP:
14941 case OPC_EXTPDPV:
14942 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14943 break;
14944 case OPC_RDDSP:
14945 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14946 break;
14947 case OPC_SHILO:
14948 case OPC_SHILOV:
14949 case OPC_MTHLIP:
14950 case OPC_WRDSP:
14951 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14952 break;
14953 default: /* Invalid */
14954 MIPS_INVAL("MASK EXTR.W");
14955 generate_exception(ctx, EXCP_RI);
14956 break;
14957 }
14958 break;
14959 #if defined(TARGET_MIPS64)
14960 case OPC_DEXTM ... OPC_DEXT:
14961 case OPC_DINSM ... OPC_DINS:
14962 check_insn(env, ctx, ISA_MIPS64R2);
14963 check_mips_64(ctx);
14964 gen_bitops(ctx, op1, rt, rs, sa, rd);
14965 break;
14966 case OPC_DBSHFL:
14967 check_insn(env, ctx, ISA_MIPS64R2);
14968 check_mips_64(ctx);
14969 op2 = MASK_DBSHFL(ctx->opcode);
14970 gen_bshfl(ctx, op2, rt, rd);
14971 break;
14972 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14973 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14974 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14975 check_insn(env, ctx, INSN_LOONGSON2E);
14976 gen_loongson_integer(ctx, op1, rd, rs, rt);
14977 break;
14978 case OPC_ABSQ_S_QH_DSP:
14979 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14980 switch (op2) {
14981 case OPC_PRECEQ_L_PWL:
14982 case OPC_PRECEQ_L_PWR:
14983 case OPC_PRECEQ_PW_QHL:
14984 case OPC_PRECEQ_PW_QHR:
14985 case OPC_PRECEQ_PW_QHLA:
14986 case OPC_PRECEQ_PW_QHRA:
14987 case OPC_PRECEQU_QH_OBL:
14988 case OPC_PRECEQU_QH_OBR:
14989 case OPC_PRECEQU_QH_OBLA:
14990 case OPC_PRECEQU_QH_OBRA:
14991 case OPC_PRECEU_QH_OBL:
14992 case OPC_PRECEU_QH_OBR:
14993 case OPC_PRECEU_QH_OBLA:
14994 case OPC_PRECEU_QH_OBRA:
14995 case OPC_ABSQ_S_OB:
14996 case OPC_ABSQ_S_PW:
14997 case OPC_ABSQ_S_QH:
14998 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14999 break;
15000 case OPC_REPL_OB:
15001 case OPC_REPL_PW:
15002 case OPC_REPL_QH:
15003 case OPC_REPLV_OB:
15004 case OPC_REPLV_PW:
15005 case OPC_REPLV_QH:
15006 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
15007 break;
15008 default: /* Invalid */
15009 MIPS_INVAL("MASK ABSQ_S.QH");
15010 generate_exception(ctx, EXCP_RI);
15011 break;
15012 }
15013 break;
15014 case OPC_ADDU_OB_DSP:
15015 op2 = MASK_ADDU_OB(ctx->opcode);
15016 switch (op2) {
15017 case OPC_RADDU_L_OB:
15018 case OPC_SUBQ_PW:
15019 case OPC_SUBQ_S_PW:
15020 case OPC_SUBQ_QH:
15021 case OPC_SUBQ_S_QH:
15022 case OPC_SUBU_OB:
15023 case OPC_SUBU_S_OB:
15024 case OPC_SUBU_QH:
15025 case OPC_SUBU_S_QH:
15026 case OPC_SUBUH_OB:
15027 case OPC_SUBUH_R_OB:
15028 case OPC_ADDQ_PW:
15029 case OPC_ADDQ_S_PW:
15030 case OPC_ADDQ_QH:
15031 case OPC_ADDQ_S_QH:
15032 case OPC_ADDU_OB:
15033 case OPC_ADDU_S_OB:
15034 case OPC_ADDU_QH:
15035 case OPC_ADDU_S_QH:
15036 case OPC_ADDUH_OB:
15037 case OPC_ADDUH_R_OB:
15038 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15039 break;
15040 case OPC_MULEQ_S_PW_QHL:
15041 case OPC_MULEQ_S_PW_QHR:
15042 case OPC_MULEU_S_QH_OBL:
15043 case OPC_MULEU_S_QH_OBR:
15044 case OPC_MULQ_RS_QH:
15045 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15046 break;
15047 default: /* Invalid */
15048 MIPS_INVAL("MASK ADDU.OB");
15049 generate_exception(ctx, EXCP_RI);
15050 break;
15051 }
15052 break;
15053 case OPC_CMPU_EQ_OB_DSP:
15054 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15055 switch (op2) {
15056 case OPC_PRECR_SRA_QH_PW:
15057 case OPC_PRECR_SRA_R_QH_PW:
15058 /* Return value is rt. */
15059 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15060 break;
15061 case OPC_PRECR_OB_QH:
15062 case OPC_PRECRQ_OB_QH:
15063 case OPC_PRECRQ_PW_L:
15064 case OPC_PRECRQ_QH_PW:
15065 case OPC_PRECRQ_RS_QH_PW:
15066 case OPC_PRECRQU_S_OB_QH:
15067 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15068 break;
15069 case OPC_CMPU_EQ_OB:
15070 case OPC_CMPU_LT_OB:
15071 case OPC_CMPU_LE_OB:
15072 case OPC_CMP_EQ_QH:
15073 case OPC_CMP_LT_QH:
15074 case OPC_CMP_LE_QH:
15075 case OPC_CMP_EQ_PW:
15076 case OPC_CMP_LT_PW:
15077 case OPC_CMP_LE_PW:
15078 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15079 break;
15080 case OPC_CMPGDU_EQ_OB:
15081 case OPC_CMPGDU_LT_OB:
15082 case OPC_CMPGDU_LE_OB:
15083 case OPC_CMPGU_EQ_OB:
15084 case OPC_CMPGU_LT_OB:
15085 case OPC_CMPGU_LE_OB:
15086 case OPC_PACKRL_PW:
15087 case OPC_PICK_OB:
15088 case OPC_PICK_PW:
15089 case OPC_PICK_QH:
15090 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15091 break;
15092 default: /* Invalid */
15093 MIPS_INVAL("MASK CMPU_EQ.OB");
15094 generate_exception(ctx, EXCP_RI);
15095 break;
15096 }
15097 break;
15098 case OPC_DAPPEND_DSP:
15099 check_dspr2(ctx);
15100 op2 = MASK_DAPPEND(ctx->opcode);
15101 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15102 break;
15103 case OPC_DEXTR_W_DSP:
15104 op2 = MASK_DEXTR_W(ctx->opcode);
15105 switch (op2) {
15106 case OPC_DEXTP:
15107 case OPC_DEXTPDP:
15108 case OPC_DEXTPDPV:
15109 case OPC_DEXTPV:
15110 case OPC_DEXTR_L:
15111 case OPC_DEXTR_R_L:
15112 case OPC_DEXTR_RS_L:
15113 case OPC_DEXTR_W:
15114 case OPC_DEXTR_R_W:
15115 case OPC_DEXTR_RS_W:
15116 case OPC_DEXTR_S_H:
15117 case OPC_DEXTRV_L:
15118 case OPC_DEXTRV_R_L:
15119 case OPC_DEXTRV_RS_L:
15120 case OPC_DEXTRV_S_H:
15121 case OPC_DEXTRV_W:
15122 case OPC_DEXTRV_R_W:
15123 case OPC_DEXTRV_RS_W:
15124 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15125 break;
15126 case OPC_DMTHLIP:
15127 case OPC_DSHILO:
15128 case OPC_DSHILOV:
15129 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15130 break;
15131 default: /* Invalid */
15132 MIPS_INVAL("MASK EXTR.W");
15133 generate_exception(ctx, EXCP_RI);
15134 break;
15135 }
15136 break;
15137 case OPC_DPAQ_W_QH_DSP:
15138 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15139 switch (op2) {
15140 case OPC_DPAU_H_OBL:
15141 case OPC_DPAU_H_OBR:
15142 case OPC_DPSU_H_OBL:
15143 case OPC_DPSU_H_OBR:
15144 case OPC_DPA_W_QH:
15145 case OPC_DPAQ_S_W_QH:
15146 case OPC_DPS_W_QH:
15147 case OPC_DPSQ_S_W_QH:
15148 case OPC_MULSAQ_S_W_QH:
15149 case OPC_DPAQ_SA_L_PW:
15150 case OPC_DPSQ_SA_L_PW:
15151 case OPC_MULSAQ_S_L_PW:
15152 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15153 break;
15154 case OPC_MAQ_S_W_QHLL:
15155 case OPC_MAQ_S_W_QHLR:
15156 case OPC_MAQ_S_W_QHRL:
15157 case OPC_MAQ_S_W_QHRR:
15158 case OPC_MAQ_SA_W_QHLL:
15159 case OPC_MAQ_SA_W_QHLR:
15160 case OPC_MAQ_SA_W_QHRL:
15161 case OPC_MAQ_SA_W_QHRR:
15162 case OPC_MAQ_S_L_PWL:
15163 case OPC_MAQ_S_L_PWR:
15164 case OPC_DMADD:
15165 case OPC_DMADDU:
15166 case OPC_DMSUB:
15167 case OPC_DMSUBU:
15168 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15169 break;
15170 default: /* Invalid */
15171 MIPS_INVAL("MASK DPAQ.W.QH");
15172 generate_exception(ctx, EXCP_RI);
15173 break;
15174 }
15175 break;
15176 case OPC_DINSV_DSP:
15177 op2 = MASK_INSV(ctx->opcode);
15178 switch (op2) {
15179 case OPC_DINSV:
15180 {
15181 TCGv t0, t1;
15182
15183 if (rt == 0) {
15184 MIPS_DEBUG("NOP");
15185 break;
15186 }
15187 check_dsp(ctx);
15188
15189 t0 = tcg_temp_new();
15190 t1 = tcg_temp_new();
15191
15192 gen_load_gpr(t0, rt);
15193 gen_load_gpr(t1, rs);
15194
15195 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15196 break;
15197 }
15198 default: /* Invalid */
15199 MIPS_INVAL("MASK DINSV");
15200 generate_exception(ctx, EXCP_RI);
15201 break;
15202 }
15203 break;
15204 case OPC_SHLL_OB_DSP:
15205 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15206 break;
15207 #endif
15208 default: /* Invalid */
15209 MIPS_INVAL("special3");
15210 generate_exception(ctx, EXCP_RI);
15211 break;
15212 }
15213 break;
15214 case OPC_REGIMM:
15215 op1 = MASK_REGIMM(ctx->opcode);
15216 switch (op1) {
15217 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15218 case OPC_BLTZAL ... OPC_BGEZALL:
15219 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15220 *is_branch = 1;
15221 break;
15222 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15223 case OPC_TNEI:
15224 gen_trap(ctx, op1, rs, -1, imm);
15225 break;
15226 case OPC_SYNCI:
15227 check_insn(env, ctx, ISA_MIPS32R2);
15228 /* Treat as NOP. */
15229 break;
15230 case OPC_BPOSGE32: /* MIPS DSP branch */
15231 #if defined(TARGET_MIPS64)
15232 case OPC_BPOSGE64:
15233 #endif
15234 check_dsp(ctx);
15235 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15236 *is_branch = 1;
15237 break;
15238 default: /* Invalid */
15239 MIPS_INVAL("regimm");
15240 generate_exception(ctx, EXCP_RI);
15241 break;
15242 }
15243 break;
15244 case OPC_CP0:
15245 check_cp0_enabled(ctx);
15246 op1 = MASK_CP0(ctx->opcode);
15247 switch (op1) {
15248 case OPC_MFC0:
15249 case OPC_MTC0:
15250 case OPC_MFTR:
15251 case OPC_MTTR:
15252 #if defined(TARGET_MIPS64)
15253 case OPC_DMFC0:
15254 case OPC_DMTC0:
15255 #endif
15256 #ifndef CONFIG_USER_ONLY
15257 gen_cp0(env, ctx, op1, rt, rd);
15258 #endif /* !CONFIG_USER_ONLY */
15259 break;
15260 case OPC_C0_FIRST ... OPC_C0_LAST:
15261 #ifndef CONFIG_USER_ONLY
15262 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15263 #endif /* !CONFIG_USER_ONLY */
15264 break;
15265 case OPC_MFMC0:
15266 #ifndef CONFIG_USER_ONLY
15267 {
15268 TCGv t0 = tcg_temp_new();
15269
15270 op2 = MASK_MFMC0(ctx->opcode);
15271 switch (op2) {
15272 case OPC_DMT:
15273 check_insn(env, ctx, ASE_MT);
15274 gen_helper_dmt(t0);
15275 gen_store_gpr(t0, rt);
15276 break;
15277 case OPC_EMT:
15278 check_insn(env, ctx, ASE_MT);
15279 gen_helper_emt(t0);
15280 gen_store_gpr(t0, rt);
15281 break;
15282 case OPC_DVPE:
15283 check_insn(env, ctx, ASE_MT);
15284 gen_helper_dvpe(t0, cpu_env);
15285 gen_store_gpr(t0, rt);
15286 break;
15287 case OPC_EVPE:
15288 check_insn(env, ctx, ASE_MT);
15289 gen_helper_evpe(t0, cpu_env);
15290 gen_store_gpr(t0, rt);
15291 break;
15292 case OPC_DI:
15293 check_insn(env, ctx, ISA_MIPS32R2);
15294 save_cpu_state(ctx, 1);
15295 gen_helper_di(t0, cpu_env);
15296 gen_store_gpr(t0, rt);
15297 /* Stop translation as we may have switched the execution mode */
15298 ctx->bstate = BS_STOP;
15299 break;
15300 case OPC_EI:
15301 check_insn(env, ctx, ISA_MIPS32R2);
15302 save_cpu_state(ctx, 1);
15303 gen_helper_ei(t0, cpu_env);
15304 gen_store_gpr(t0, rt);
15305 /* Stop translation as we may have switched the execution mode */
15306 ctx->bstate = BS_STOP;
15307 break;
15308 default: /* Invalid */
15309 MIPS_INVAL("mfmc0");
15310 generate_exception(ctx, EXCP_RI);
15311 break;
15312 }
15313 tcg_temp_free(t0);
15314 }
15315 #endif /* !CONFIG_USER_ONLY */
15316 break;
15317 case OPC_RDPGPR:
15318 check_insn(env, ctx, ISA_MIPS32R2);
15319 gen_load_srsgpr(rt, rd);
15320 break;
15321 case OPC_WRPGPR:
15322 check_insn(env, ctx, ISA_MIPS32R2);
15323 gen_store_srsgpr(rt, rd);
15324 break;
15325 default:
15326 MIPS_INVAL("cp0");
15327 generate_exception(ctx, EXCP_RI);
15328 break;
15329 }
15330 break;
15331 case OPC_ADDI: /* Arithmetic with immediate opcode */
15332 case OPC_ADDIU:
15333 gen_arith_imm(env, ctx, op, rt, rs, imm);
15334 break;
15335 case OPC_SLTI: /* Set on less than with immediate opcode */
15336 case OPC_SLTIU:
15337 gen_slt_imm(env, ctx, op, rt, rs, imm);
15338 break;
15339 case OPC_ANDI: /* Arithmetic with immediate opcode */
15340 case OPC_LUI:
15341 case OPC_ORI:
15342 case OPC_XORI:
15343 gen_logic_imm(env, ctx, op, rt, rs, imm);
15344 break;
15345 case OPC_J ... OPC_JAL: /* Jump */
15346 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15347 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15348 *is_branch = 1;
15349 break;
15350 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15351 case OPC_BEQL ... OPC_BGTZL:
15352 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15353 *is_branch = 1;
15354 break;
15355 case OPC_LB ... OPC_LWR: /* Load and stores */
15356 case OPC_LL:
15357 gen_ld(env, ctx, op, rt, rs, imm);
15358 break;
15359 case OPC_SB ... OPC_SW:
15360 case OPC_SWR:
15361 gen_st(ctx, op, rt, rs, imm);
15362 break;
15363 case OPC_SC:
15364 gen_st_cond(ctx, op, rt, rs, imm);
15365 break;
15366 case OPC_CACHE:
15367 check_cp0_enabled(ctx);
15368 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15369 /* Treat as NOP. */
15370 break;
15371 case OPC_PREF:
15372 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15373 /* Treat as NOP. */
15374 break;
15375
15376 /* Floating point (COP1). */
15377 case OPC_LWC1:
15378 case OPC_LDC1:
15379 case OPC_SWC1:
15380 case OPC_SDC1:
15381 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15382 break;
15383
15384 case OPC_CP1:
15385 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15386 check_cp1_enabled(ctx);
15387 op1 = MASK_CP1(ctx->opcode);
15388 switch (op1) {
15389 case OPC_MFHC1:
15390 case OPC_MTHC1:
15391 check_insn(env, ctx, ISA_MIPS32R2);
15392 case OPC_MFC1:
15393 case OPC_CFC1:
15394 case OPC_MTC1:
15395 case OPC_CTC1:
15396 gen_cp1(ctx, op1, rt, rd);
15397 break;
15398 #if defined(TARGET_MIPS64)
15399 case OPC_DMFC1:
15400 case OPC_DMTC1:
15401 check_insn(env, ctx, ISA_MIPS3);
15402 gen_cp1(ctx, op1, rt, rd);
15403 break;
15404 #endif
15405 case OPC_BC1ANY2:
15406 case OPC_BC1ANY4:
15407 check_cop1x(ctx);
15408 check_insn(env, ctx, ASE_MIPS3D);
15409 /* fall through */
15410 case OPC_BC1:
15411 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15412 (rt >> 2) & 0x7, imm << 2);
15413 *is_branch = 1;
15414 break;
15415 case OPC_S_FMT:
15416 case OPC_D_FMT:
15417 case OPC_W_FMT:
15418 case OPC_L_FMT:
15419 case OPC_PS_FMT:
15420 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15421 (imm >> 8) & 0x7);
15422 break;
15423 default:
15424 MIPS_INVAL("cp1");
15425 generate_exception (ctx, EXCP_RI);
15426 break;
15427 }
15428 } else {
15429 generate_exception_err(ctx, EXCP_CpU, 1);
15430 }
15431 break;
15432
15433 /* COP2. */
15434 case OPC_LWC2:
15435 case OPC_LDC2:
15436 case OPC_SWC2:
15437 case OPC_SDC2:
15438 /* COP2: Not implemented. */
15439 generate_exception_err(ctx, EXCP_CpU, 2);
15440 break;
15441 case OPC_CP2:
15442 check_insn(env, ctx, INSN_LOONGSON2F);
15443 /* Note that these instructions use different fields. */
15444 gen_loongson_multimedia(ctx, sa, rd, rt);
15445 break;
15446
15447 case OPC_CP3:
15448 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15449 check_cp1_enabled(ctx);
15450 op1 = MASK_CP3(ctx->opcode);
15451 switch (op1) {
15452 case OPC_LWXC1:
15453 case OPC_LDXC1:
15454 case OPC_LUXC1:
15455 case OPC_SWXC1:
15456 case OPC_SDXC1:
15457 case OPC_SUXC1:
15458 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15459 break;
15460 case OPC_PREFX:
15461 /* Treat as NOP. */
15462 break;
15463 case OPC_ALNV_PS:
15464 case OPC_MADD_S:
15465 case OPC_MADD_D:
15466 case OPC_MADD_PS:
15467 case OPC_MSUB_S:
15468 case OPC_MSUB_D:
15469 case OPC_MSUB_PS:
15470 case OPC_NMADD_S:
15471 case OPC_NMADD_D:
15472 case OPC_NMADD_PS:
15473 case OPC_NMSUB_S:
15474 case OPC_NMSUB_D:
15475 case OPC_NMSUB_PS:
15476 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15477 break;
15478 default:
15479 MIPS_INVAL("cp3");
15480 generate_exception (ctx, EXCP_RI);
15481 break;
15482 }
15483 } else {
15484 generate_exception_err(ctx, EXCP_CpU, 1);
15485 }
15486 break;
15487
15488 #if defined(TARGET_MIPS64)
15489 /* MIPS64 opcodes */
15490 case OPC_LWU:
15491 case OPC_LDL ... OPC_LDR:
15492 case OPC_LLD:
15493 case OPC_LD:
15494 check_insn(env, ctx, ISA_MIPS3);
15495 check_mips_64(ctx);
15496 gen_ld(env, ctx, op, rt, rs, imm);
15497 break;
15498 case OPC_SDL ... OPC_SDR:
15499 case OPC_SD:
15500 check_insn(env, ctx, ISA_MIPS3);
15501 check_mips_64(ctx);
15502 gen_st(ctx, op, rt, rs, imm);
15503 break;
15504 case OPC_SCD:
15505 check_insn(env, ctx, ISA_MIPS3);
15506 check_mips_64(ctx);
15507 gen_st_cond(ctx, op, rt, rs, imm);
15508 break;
15509 case OPC_DADDI:
15510 case OPC_DADDIU:
15511 check_insn(env, ctx, ISA_MIPS3);
15512 check_mips_64(ctx);
15513 gen_arith_imm(env, ctx, op, rt, rs, imm);
15514 break;
15515 #endif
15516 case OPC_JALX:
15517 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15518 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15519 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15520 *is_branch = 1;
15521 break;
15522 case OPC_MDMX:
15523 check_insn(env, ctx, ASE_MDMX);
15524 /* MDMX: Not implemented. */
15525 default: /* Invalid */
15526 MIPS_INVAL("major opcode");
15527 generate_exception(ctx, EXCP_RI);
15528 break;
15529 }
15530 }
15531
15532 static inline void
15533 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15534 int search_pc)
15535 {
15536 DisasContext ctx;
15537 target_ulong pc_start;
15538 uint16_t *gen_opc_end;
15539 CPUBreakpoint *bp;
15540 int j, lj = -1;
15541 int num_insns;
15542 int max_insns;
15543 int insn_bytes;
15544 int is_branch;
15545
15546 if (search_pc)
15547 qemu_log("search pc %d\n", search_pc);
15548
15549 pc_start = tb->pc;
15550 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15551 ctx.pc = pc_start;
15552 ctx.saved_pc = -1;
15553 ctx.singlestep_enabled = env->singlestep_enabled;
15554 ctx.tb = tb;
15555 ctx.bstate = BS_NONE;
15556 /* Restore delay slot state from the tb context. */
15557 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15558 restore_cpu_state(env, &ctx);
15559 #ifdef CONFIG_USER_ONLY
15560 ctx.mem_idx = MIPS_HFLAG_UM;
15561 #else
15562 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15563 #endif
15564 num_insns = 0;
15565 max_insns = tb->cflags & CF_COUNT_MASK;
15566 if (max_insns == 0)
15567 max_insns = CF_COUNT_MASK;
15568 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15569 gen_icount_start();
15570 while (ctx.bstate == BS_NONE) {
15571 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15572 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15573 if (bp->pc == ctx.pc) {
15574 save_cpu_state(&ctx, 1);
15575 ctx.bstate = BS_BRANCH;
15576 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15577 /* Include the breakpoint location or the tb won't
15578 * be flushed when it must be. */
15579 ctx.pc += 4;
15580 goto done_generating;
15581 }
15582 }
15583 }
15584
15585 if (search_pc) {
15586 j = gen_opc_ptr - gen_opc_buf;
15587 if (lj < j) {
15588 lj++;
15589 while (lj < j)
15590 gen_opc_instr_start[lj++] = 0;
15591 }
15592 gen_opc_pc[lj] = ctx.pc;
15593 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15594 gen_opc_btarget[lj] = ctx.btarget;
15595 gen_opc_instr_start[lj] = 1;
15596 gen_opc_icount[lj] = num_insns;
15597 }
15598 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15599 gen_io_start();
15600
15601 is_branch = 0;
15602 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15603 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15604 insn_bytes = 4;
15605 decode_opc(env, &ctx, &is_branch);
15606 } else if (env->insn_flags & ASE_MICROMIPS) {
15607 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15608 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15609 } else if (env->insn_flags & ASE_MIPS16) {
15610 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15611 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15612 } else {
15613 generate_exception(&ctx, EXCP_RI);
15614 ctx.bstate = BS_STOP;
15615 break;
15616 }
15617 if (!is_branch) {
15618 handle_delay_slot(env, &ctx, insn_bytes);
15619 }
15620 ctx.pc += insn_bytes;
15621
15622 num_insns++;
15623
15624 /* Execute a branch and its delay slot as a single instruction.
15625 This is what GDB expects and is consistent with what the
15626 hardware does (e.g. if a delay slot instruction faults, the
15627 reported PC is the PC of the branch). */
15628 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15629 break;
15630
15631 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15632 break;
15633
15634 if (gen_opc_ptr >= gen_opc_end)
15635 break;
15636
15637 if (num_insns >= max_insns)
15638 break;
15639
15640 if (singlestep)
15641 break;
15642 }
15643 if (tb->cflags & CF_LAST_IO)
15644 gen_io_end();
15645 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15646 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15647 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15648 } else {
15649 switch (ctx.bstate) {
15650 case BS_STOP:
15651 gen_goto_tb(&ctx, 0, ctx.pc);
15652 break;
15653 case BS_NONE:
15654 save_cpu_state(&ctx, 0);
15655 gen_goto_tb(&ctx, 0, ctx.pc);
15656 break;
15657 case BS_EXCP:
15658 tcg_gen_exit_tb(0);
15659 break;
15660 case BS_BRANCH:
15661 default:
15662 break;
15663 }
15664 }
15665 done_generating:
15666 gen_icount_end(tb, num_insns);
15667 *gen_opc_ptr = INDEX_op_end;
15668 if (search_pc) {
15669 j = gen_opc_ptr - gen_opc_buf;
15670 lj++;
15671 while (lj <= j)
15672 gen_opc_instr_start[lj++] = 0;
15673 } else {
15674 tb->size = ctx.pc - pc_start;
15675 tb->icount = num_insns;
15676 }
15677 #ifdef DEBUG_DISAS
15678 LOG_DISAS("\n");
15679 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15680 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15681 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15682 qemu_log("\n");
15683 }
15684 #endif
15685 }
15686
15687 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15688 {
15689 gen_intermediate_code_internal(env, tb, 0);
15690 }
15691
15692 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15693 {
15694 gen_intermediate_code_internal(env, tb, 1);
15695 }
15696
15697 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15698 int flags)
15699 {
15700 int i;
15701 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15702
15703 #define printfpr(fp) \
15704 do { \
15705 if (is_fpu64) \
15706 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15707 " fd:%13g fs:%13g psu: %13g\n", \
15708 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15709 (double)(fp)->fd, \
15710 (double)(fp)->fs[FP_ENDIAN_IDX], \
15711 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15712 else { \
15713 fpr_t tmp; \
15714 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15715 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15716 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15717 " fd:%13g fs:%13g psu:%13g\n", \
15718 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15719 (double)tmp.fd, \
15720 (double)tmp.fs[FP_ENDIAN_IDX], \
15721 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15722 } \
15723 } while(0)
15724
15725
15726 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15727 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15728 get_float_exception_flags(&env->active_fpu.fp_status));
15729 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15730 fpu_fprintf(f, "%3s: ", fregnames[i]);
15731 printfpr(&env->active_fpu.fpr[i]);
15732 }
15733
15734 #undef printfpr
15735 }
15736
15737 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15738 /* Debug help: The architecture requires 32bit code to maintain proper
15739 sign-extended values on 64bit machines. */
15740
15741 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15742
15743 static void
15744 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15745 fprintf_function cpu_fprintf,
15746 int flags)
15747 {
15748 int i;
15749
15750 if (!SIGN_EXT_P(env->active_tc.PC))
15751 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15752 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15753 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15754 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15755 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15756 if (!SIGN_EXT_P(env->btarget))
15757 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15758
15759 for (i = 0; i < 32; i++) {
15760 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15761 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15762 }
15763
15764 if (!SIGN_EXT_P(env->CP0_EPC))
15765 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15766 if (!SIGN_EXT_P(env->lladdr))
15767 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15768 }
15769 #endif
15770
15771 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15772 int flags)
15773 {
15774 int i;
15775
15776 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15777 " LO=0x" TARGET_FMT_lx " ds %04x "
15778 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15779 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15780 env->hflags, env->btarget, env->bcond);
15781 for (i = 0; i < 32; i++) {
15782 if ((i & 3) == 0)
15783 cpu_fprintf(f, "GPR%02d:", i);
15784 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15785 if ((i & 3) == 3)
15786 cpu_fprintf(f, "\n");
15787 }
15788
15789 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15790 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15791 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15792 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15793 if (env->hflags & MIPS_HFLAG_FPU)
15794 fpu_dump_state(env, f, cpu_fprintf, flags);
15795 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15796 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15797 #endif
15798 }
15799
15800 static void mips_tcg_init(void)
15801 {
15802 int i;
15803 static int inited;
15804
15805 /* Initialize various static tables. */
15806 if (inited)
15807 return;
15808
15809 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15810 TCGV_UNUSED(cpu_gpr[0]);
15811 for (i = 1; i < 32; i++)
15812 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15813 offsetof(CPUMIPSState, active_tc.gpr[i]),
15814 regnames[i]);
15815
15816 for (i = 0; i < 32; i++) {
15817 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15818 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15819 }
15820
15821 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15822 offsetof(CPUMIPSState, active_tc.PC), "PC");
15823 for (i = 0; i < MIPS_DSP_ACC; i++) {
15824 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15825 offsetof(CPUMIPSState, active_tc.HI[i]),
15826 regnames_HI[i]);
15827 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15828 offsetof(CPUMIPSState, active_tc.LO[i]),
15829 regnames_LO[i]);
15830 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15831 offsetof(CPUMIPSState, active_tc.ACX[i]),
15832 regnames_ACX[i]);
15833 }
15834 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15835 offsetof(CPUMIPSState, active_tc.DSPControl),
15836 "DSPControl");
15837 bcond = tcg_global_mem_new(TCG_AREG0,
15838 offsetof(CPUMIPSState, bcond), "bcond");
15839 btarget = tcg_global_mem_new(TCG_AREG0,
15840 offsetof(CPUMIPSState, btarget), "btarget");
15841 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15842 offsetof(CPUMIPSState, hflags), "hflags");
15843
15844 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15845 offsetof(CPUMIPSState, active_fpu.fcr0),
15846 "fcr0");
15847 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15848 offsetof(CPUMIPSState, active_fpu.fcr31),
15849 "fcr31");
15850
15851 /* register helpers */
15852 #define GEN_HELPER 2
15853 #include "helper.h"
15854
15855 inited = 1;
15856 }
15857
15858 #include "translate_init.c"
15859
15860 MIPSCPU *cpu_mips_init(const char *cpu_model)
15861 {
15862 MIPSCPU *cpu;
15863 CPUMIPSState *env;
15864 const mips_def_t *def;
15865
15866 def = cpu_mips_find_by_name(cpu_model);
15867 if (!def)
15868 return NULL;
15869 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15870 env = &cpu->env;
15871 env->cpu_model = def;
15872 env->cpu_model_str = cpu_model;
15873
15874 #ifndef CONFIG_USER_ONLY
15875 mmu_init(env, def);
15876 #endif
15877 fpu_init(env, def);
15878 mvp_init(env, def);
15879 mips_tcg_init();
15880 cpu_reset(CPU(cpu));
15881 qemu_init_vcpu(env);
15882 return cpu;
15883 }
15884
15885 void cpu_state_reset(CPUMIPSState *env)
15886 {
15887 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15888 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15889 log_cpu_state(env, 0);
15890 }
15891
15892 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15893 tlb_flush(env, 1);
15894
15895 /* Reset registers to their default values */
15896 env->CP0_PRid = env->cpu_model->CP0_PRid;
15897 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15898 #ifdef TARGET_WORDS_BIGENDIAN
15899 env->CP0_Config0 |= (1 << CP0C0_BE);
15900 #endif
15901 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15902 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15903 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15904 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15905 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15906 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15907 << env->cpu_model->CP0_LLAddr_shift;
15908 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15909 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15910 env->CCRes = env->cpu_model->CCRes;
15911 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15912 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15913 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15914 env->current_tc = 0;
15915 env->SEGBITS = env->cpu_model->SEGBITS;
15916 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15917 #if defined(TARGET_MIPS64)
15918 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15919 env->SEGMask |= 3ULL << 62;
15920 }
15921 #endif
15922 env->PABITS = env->cpu_model->PABITS;
15923 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15924 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15925 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15926 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15927 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15928 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15929 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15930 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15931 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15932 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15933 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15934 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15935 env->insn_flags = env->cpu_model->insn_flags;
15936
15937 #if defined(CONFIG_USER_ONLY)
15938 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15939 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15940 hardware registers. */
15941 env->CP0_HWREna |= 0x0000000F;
15942 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15943 env->CP0_Status |= (1 << CP0St_CU1);
15944 }
15945 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15946 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15947 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15948 env->hflags |= MIPS_HFLAG_DSP;
15949 }
15950 #else
15951 if (env->hflags & MIPS_HFLAG_BMASK) {
15952 /* If the exception was raised from a delay slot,
15953 come back to the jump. */
15954 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15955 } else {
15956 env->CP0_ErrorEPC = env->active_tc.PC;
15957 }
15958 env->active_tc.PC = (int32_t)0xBFC00000;
15959 env->CP0_Random = env->tlb->nb_tlb - 1;
15960 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15961 env->CP0_Wired = 0;
15962 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15963 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15964 /* vectored interrupts not implemented, timer on int 7,
15965 no performance counters. */
15966 env->CP0_IntCtl = 0xe0000000;
15967 {
15968 int i;
15969
15970 for (i = 0; i < 7; i++) {
15971 env->CP0_WatchLo[i] = 0;
15972 env->CP0_WatchHi[i] = 0x80000000;
15973 }
15974 env->CP0_WatchLo[7] = 0;
15975 env->CP0_WatchHi[7] = 0;
15976 }
15977 /* Count register increments in debug mode, EJTAG version 1 */
15978 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15979
15980 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15981 int i;
15982
15983 /* Only TC0 on VPE 0 starts as active. */
15984 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15985 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15986 env->tcs[i].CP0_TCHalt = 1;
15987 }
15988 env->active_tc.CP0_TCHalt = 1;
15989 env->halted = 1;
15990
15991 if (!env->cpu_index) {
15992 /* VPE0 starts up enabled. */
15993 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15994 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15995
15996 /* TC0 starts up unhalted. */
15997 env->halted = 0;
15998 env->active_tc.CP0_TCHalt = 0;
15999 env->tcs[0].CP0_TCHalt = 0;
16000 /* With thread 0 active. */
16001 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16002 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16003 }
16004 }
16005 #endif
16006 compute_hflags(env);
16007 env->exception_index = EXCP_NONE;
16008 }
16009
16010 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16011 {
16012 env->active_tc.PC = gen_opc_pc[pc_pos];
16013 env->hflags &= ~MIPS_HFLAG_BMASK;
16014 env->hflags |= gen_opc_hflags[pc_pos];
16015 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16016 case MIPS_HFLAG_BR:
16017 break;
16018 case MIPS_HFLAG_BC:
16019 case MIPS_HFLAG_BL:
16020 case MIPS_HFLAG_B:
16021 env->btarget = gen_opc_btarget[pc_pos];
16022 break;
16023 }
16024 }