]> git.proxmox.com Git - qemu.git/blob - target-mips/translate.c
target-mips: implement movn/movz using movcond
[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 TCGv t0, t1, t2;
2363
2364 if (rd == 0) {
2365 /* If no destination, treat it as a NOP. */
2366 MIPS_DEBUG("NOP");
2367 return;
2368 }
2369
2370 t0 = tcg_temp_new();
2371 gen_load_gpr(t0, rt);
2372 t1 = tcg_const_tl(0);
2373 t2 = tcg_temp_new();
2374 gen_load_gpr(t2, rs);
2375 switch (opc) {
2376 case OPC_MOVN:
2377 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2378 opn = "movn";
2379 break;
2380 case OPC_MOVZ:
2381 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2382 opn = "movz";
2383 break;
2384 }
2385 tcg_temp_free(t2);
2386 tcg_temp_free(t1);
2387 tcg_temp_free(t0);
2388
2389 (void)opn; /* avoid a compiler warning */
2390 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2391 }
2392
2393 /* Logic */
2394 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2395 int rd, int rs, int rt)
2396 {
2397 const char *opn = "logic";
2398
2399 if (rd == 0) {
2400 /* If no destination, treat it as a NOP. */
2401 MIPS_DEBUG("NOP");
2402 return;
2403 }
2404
2405 switch (opc) {
2406 case OPC_AND:
2407 if (likely(rs != 0 && rt != 0)) {
2408 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2409 } else {
2410 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2411 }
2412 opn = "and";
2413 break;
2414 case OPC_NOR:
2415 if (rs != 0 && rt != 0) {
2416 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2417 } else if (rs == 0 && rt != 0) {
2418 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2419 } else if (rs != 0 && rt == 0) {
2420 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2421 } else {
2422 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2423 }
2424 opn = "nor";
2425 break;
2426 case OPC_OR:
2427 if (likely(rs != 0 && rt != 0)) {
2428 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2429 } else if (rs == 0 && rt != 0) {
2430 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2431 } else if (rs != 0 && rt == 0) {
2432 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2433 } else {
2434 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2435 }
2436 opn = "or";
2437 break;
2438 case OPC_XOR:
2439 if (likely(rs != 0 && rt != 0)) {
2440 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2441 } else if (rs == 0 && rt != 0) {
2442 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2443 } else if (rs != 0 && rt == 0) {
2444 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2445 } else {
2446 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2447 }
2448 opn = "xor";
2449 break;
2450 }
2451 (void)opn; /* avoid a compiler warning */
2452 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2453 }
2454
2455 /* Set on lower than */
2456 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2457 int rd, int rs, int rt)
2458 {
2459 const char *opn = "slt";
2460 TCGv t0, t1;
2461
2462 if (rd == 0) {
2463 /* If no destination, treat it as a NOP. */
2464 MIPS_DEBUG("NOP");
2465 return;
2466 }
2467
2468 t0 = tcg_temp_new();
2469 t1 = tcg_temp_new();
2470 gen_load_gpr(t0, rs);
2471 gen_load_gpr(t1, rt);
2472 switch (opc) {
2473 case OPC_SLT:
2474 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2475 opn = "slt";
2476 break;
2477 case OPC_SLTU:
2478 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2479 opn = "sltu";
2480 break;
2481 }
2482 (void)opn; /* avoid a compiler warning */
2483 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2484 tcg_temp_free(t0);
2485 tcg_temp_free(t1);
2486 }
2487
2488 /* Shifts */
2489 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2490 int rd, int rs, int rt)
2491 {
2492 const char *opn = "shifts";
2493 TCGv t0, t1;
2494
2495 if (rd == 0) {
2496 /* If no destination, treat it as a NOP.
2497 For add & sub, we must generate the overflow exception when needed. */
2498 MIPS_DEBUG("NOP");
2499 return;
2500 }
2501
2502 t0 = tcg_temp_new();
2503 t1 = tcg_temp_new();
2504 gen_load_gpr(t0, rs);
2505 gen_load_gpr(t1, rt);
2506 switch (opc) {
2507 case OPC_SLLV:
2508 tcg_gen_andi_tl(t0, t0, 0x1f);
2509 tcg_gen_shl_tl(t0, t1, t0);
2510 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2511 opn = "sllv";
2512 break;
2513 case OPC_SRAV:
2514 tcg_gen_andi_tl(t0, t0, 0x1f);
2515 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2516 opn = "srav";
2517 break;
2518 case OPC_SRLV:
2519 tcg_gen_ext32u_tl(t1, t1);
2520 tcg_gen_andi_tl(t0, t0, 0x1f);
2521 tcg_gen_shr_tl(t0, t1, t0);
2522 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2523 opn = "srlv";
2524 break;
2525 case OPC_ROTRV:
2526 {
2527 TCGv_i32 t2 = tcg_temp_new_i32();
2528 TCGv_i32 t3 = tcg_temp_new_i32();
2529
2530 tcg_gen_trunc_tl_i32(t2, t0);
2531 tcg_gen_trunc_tl_i32(t3, t1);
2532 tcg_gen_andi_i32(t2, t2, 0x1f);
2533 tcg_gen_rotr_i32(t2, t3, t2);
2534 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2535 tcg_temp_free_i32(t2);
2536 tcg_temp_free_i32(t3);
2537 opn = "rotrv";
2538 }
2539 break;
2540 #if defined(TARGET_MIPS64)
2541 case OPC_DSLLV:
2542 tcg_gen_andi_tl(t0, t0, 0x3f);
2543 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2544 opn = "dsllv";
2545 break;
2546 case OPC_DSRAV:
2547 tcg_gen_andi_tl(t0, t0, 0x3f);
2548 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2549 opn = "dsrav";
2550 break;
2551 case OPC_DSRLV:
2552 tcg_gen_andi_tl(t0, t0, 0x3f);
2553 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2554 opn = "dsrlv";
2555 break;
2556 case OPC_DROTRV:
2557 tcg_gen_andi_tl(t0, t0, 0x3f);
2558 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2559 opn = "drotrv";
2560 break;
2561 #endif
2562 }
2563 (void)opn; /* avoid a compiler warning */
2564 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2565 tcg_temp_free(t0);
2566 tcg_temp_free(t1);
2567 }
2568
2569 /* Arithmetic on HI/LO registers */
2570 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2571 {
2572 const char *opn = "hilo";
2573 unsigned int acc;
2574
2575 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2576 /* Treat as NOP. */
2577 MIPS_DEBUG("NOP");
2578 return;
2579 }
2580
2581 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2582 acc = ((ctx->opcode) >> 21) & 0x03;
2583 } else {
2584 acc = ((ctx->opcode) >> 11) & 0x03;
2585 }
2586
2587 if (acc != 0) {
2588 check_dsp(ctx);
2589 }
2590
2591 switch (opc) {
2592 case OPC_MFHI:
2593 #if defined(TARGET_MIPS64)
2594 if (acc != 0) {
2595 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2596 } else
2597 #endif
2598 {
2599 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2600 }
2601 opn = "mfhi";
2602 break;
2603 case OPC_MFLO:
2604 #if defined(TARGET_MIPS64)
2605 if (acc != 0) {
2606 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2607 } else
2608 #endif
2609 {
2610 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2611 }
2612 opn = "mflo";
2613 break;
2614 case OPC_MTHI:
2615 if (reg != 0) {
2616 #if defined(TARGET_MIPS64)
2617 if (acc != 0) {
2618 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2619 } else
2620 #endif
2621 {
2622 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2623 }
2624 } else {
2625 tcg_gen_movi_tl(cpu_HI[acc], 0);
2626 }
2627 opn = "mthi";
2628 break;
2629 case OPC_MTLO:
2630 if (reg != 0) {
2631 #if defined(TARGET_MIPS64)
2632 if (acc != 0) {
2633 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2634 } else
2635 #endif
2636 {
2637 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2638 }
2639 } else {
2640 tcg_gen_movi_tl(cpu_LO[acc], 0);
2641 }
2642 opn = "mtlo";
2643 break;
2644 }
2645 (void)opn; /* avoid a compiler warning */
2646 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2647 }
2648
2649 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2650 int rs, int rt)
2651 {
2652 const char *opn = "mul/div";
2653 TCGv t0, t1;
2654 unsigned int acc;
2655
2656 switch (opc) {
2657 case OPC_DIV:
2658 case OPC_DIVU:
2659 #if defined(TARGET_MIPS64)
2660 case OPC_DDIV:
2661 case OPC_DDIVU:
2662 #endif
2663 t0 = tcg_temp_local_new();
2664 t1 = tcg_temp_local_new();
2665 break;
2666 default:
2667 t0 = tcg_temp_new();
2668 t1 = tcg_temp_new();
2669 break;
2670 }
2671
2672 gen_load_gpr(t0, rs);
2673 gen_load_gpr(t1, rt);
2674 switch (opc) {
2675 case OPC_DIV:
2676 {
2677 int l1 = gen_new_label();
2678 int l2 = gen_new_label();
2679
2680 tcg_gen_ext32s_tl(t0, t0);
2681 tcg_gen_ext32s_tl(t1, t1);
2682 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2683 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2684 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2685
2686 tcg_gen_mov_tl(cpu_LO[0], t0);
2687 tcg_gen_movi_tl(cpu_HI[0], 0);
2688 tcg_gen_br(l1);
2689 gen_set_label(l2);
2690 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2691 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2692 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2693 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2694 gen_set_label(l1);
2695 }
2696 opn = "div";
2697 break;
2698 case OPC_DIVU:
2699 {
2700 int l1 = gen_new_label();
2701
2702 tcg_gen_ext32u_tl(t0, t0);
2703 tcg_gen_ext32u_tl(t1, t1);
2704 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2705 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2706 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2707 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2708 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2709 gen_set_label(l1);
2710 }
2711 opn = "divu";
2712 break;
2713 case OPC_MULT:
2714 {
2715 TCGv_i64 t2 = tcg_temp_new_i64();
2716 TCGv_i64 t3 = tcg_temp_new_i64();
2717 acc = ((ctx->opcode) >> 11) & 0x03;
2718 if (acc != 0) {
2719 check_dsp(ctx);
2720 }
2721
2722 tcg_gen_ext_tl_i64(t2, t0);
2723 tcg_gen_ext_tl_i64(t3, t1);
2724 tcg_gen_mul_i64(t2, t2, t3);
2725 tcg_temp_free_i64(t3);
2726 tcg_gen_trunc_i64_tl(t0, t2);
2727 tcg_gen_shri_i64(t2, t2, 32);
2728 tcg_gen_trunc_i64_tl(t1, t2);
2729 tcg_temp_free_i64(t2);
2730 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2731 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2732 }
2733 opn = "mult";
2734 break;
2735 case OPC_MULTU:
2736 {
2737 TCGv_i64 t2 = tcg_temp_new_i64();
2738 TCGv_i64 t3 = tcg_temp_new_i64();
2739 acc = ((ctx->opcode) >> 11) & 0x03;
2740 if (acc != 0) {
2741 check_dsp(ctx);
2742 }
2743
2744 tcg_gen_ext32u_tl(t0, t0);
2745 tcg_gen_ext32u_tl(t1, t1);
2746 tcg_gen_extu_tl_i64(t2, t0);
2747 tcg_gen_extu_tl_i64(t3, t1);
2748 tcg_gen_mul_i64(t2, t2, t3);
2749 tcg_temp_free_i64(t3);
2750 tcg_gen_trunc_i64_tl(t0, t2);
2751 tcg_gen_shri_i64(t2, t2, 32);
2752 tcg_gen_trunc_i64_tl(t1, t2);
2753 tcg_temp_free_i64(t2);
2754 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2755 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2756 }
2757 opn = "multu";
2758 break;
2759 #if defined(TARGET_MIPS64)
2760 case OPC_DDIV:
2761 {
2762 int l1 = gen_new_label();
2763 int l2 = gen_new_label();
2764
2765 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2766 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2767 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2768 tcg_gen_mov_tl(cpu_LO[0], t0);
2769 tcg_gen_movi_tl(cpu_HI[0], 0);
2770 tcg_gen_br(l1);
2771 gen_set_label(l2);
2772 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2773 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2774 gen_set_label(l1);
2775 }
2776 opn = "ddiv";
2777 break;
2778 case OPC_DDIVU:
2779 {
2780 int l1 = gen_new_label();
2781
2782 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2783 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2784 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2785 gen_set_label(l1);
2786 }
2787 opn = "ddivu";
2788 break;
2789 case OPC_DMULT:
2790 gen_helper_dmult(cpu_env, t0, t1);
2791 opn = "dmult";
2792 break;
2793 case OPC_DMULTU:
2794 gen_helper_dmultu(cpu_env, t0, t1);
2795 opn = "dmultu";
2796 break;
2797 #endif
2798 case OPC_MADD:
2799 {
2800 TCGv_i64 t2 = tcg_temp_new_i64();
2801 TCGv_i64 t3 = tcg_temp_new_i64();
2802 acc = ((ctx->opcode) >> 11) & 0x03;
2803 if (acc != 0) {
2804 check_dsp(ctx);
2805 }
2806
2807 tcg_gen_ext_tl_i64(t2, t0);
2808 tcg_gen_ext_tl_i64(t3, t1);
2809 tcg_gen_mul_i64(t2, t2, t3);
2810 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2811 tcg_gen_add_i64(t2, t2, t3);
2812 tcg_temp_free_i64(t3);
2813 tcg_gen_trunc_i64_tl(t0, t2);
2814 tcg_gen_shri_i64(t2, t2, 32);
2815 tcg_gen_trunc_i64_tl(t1, t2);
2816 tcg_temp_free_i64(t2);
2817 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2818 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2819 }
2820 opn = "madd";
2821 break;
2822 case OPC_MADDU:
2823 {
2824 TCGv_i64 t2 = tcg_temp_new_i64();
2825 TCGv_i64 t3 = tcg_temp_new_i64();
2826 acc = ((ctx->opcode) >> 11) & 0x03;
2827 if (acc != 0) {
2828 check_dsp(ctx);
2829 }
2830
2831 tcg_gen_ext32u_tl(t0, t0);
2832 tcg_gen_ext32u_tl(t1, t1);
2833 tcg_gen_extu_tl_i64(t2, t0);
2834 tcg_gen_extu_tl_i64(t3, t1);
2835 tcg_gen_mul_i64(t2, t2, t3);
2836 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2837 tcg_gen_add_i64(t2, t2, t3);
2838 tcg_temp_free_i64(t3);
2839 tcg_gen_trunc_i64_tl(t0, t2);
2840 tcg_gen_shri_i64(t2, t2, 32);
2841 tcg_gen_trunc_i64_tl(t1, t2);
2842 tcg_temp_free_i64(t2);
2843 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2844 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2845 }
2846 opn = "maddu";
2847 break;
2848 case OPC_MSUB:
2849 {
2850 TCGv_i64 t2 = tcg_temp_new_i64();
2851 TCGv_i64 t3 = tcg_temp_new_i64();
2852 acc = ((ctx->opcode) >> 11) & 0x03;
2853 if (acc != 0) {
2854 check_dsp(ctx);
2855 }
2856
2857 tcg_gen_ext_tl_i64(t2, t0);
2858 tcg_gen_ext_tl_i64(t3, t1);
2859 tcg_gen_mul_i64(t2, t2, t3);
2860 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2861 tcg_gen_sub_i64(t2, t3, t2);
2862 tcg_temp_free_i64(t3);
2863 tcg_gen_trunc_i64_tl(t0, t2);
2864 tcg_gen_shri_i64(t2, t2, 32);
2865 tcg_gen_trunc_i64_tl(t1, t2);
2866 tcg_temp_free_i64(t2);
2867 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2868 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2869 }
2870 opn = "msub";
2871 break;
2872 case OPC_MSUBU:
2873 {
2874 TCGv_i64 t2 = tcg_temp_new_i64();
2875 TCGv_i64 t3 = tcg_temp_new_i64();
2876 acc = ((ctx->opcode) >> 11) & 0x03;
2877 if (acc != 0) {
2878 check_dsp(ctx);
2879 }
2880
2881 tcg_gen_ext32u_tl(t0, t0);
2882 tcg_gen_ext32u_tl(t1, t1);
2883 tcg_gen_extu_tl_i64(t2, t0);
2884 tcg_gen_extu_tl_i64(t3, t1);
2885 tcg_gen_mul_i64(t2, t2, t3);
2886 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2887 tcg_gen_sub_i64(t2, t3, t2);
2888 tcg_temp_free_i64(t3);
2889 tcg_gen_trunc_i64_tl(t0, t2);
2890 tcg_gen_shri_i64(t2, t2, 32);
2891 tcg_gen_trunc_i64_tl(t1, t2);
2892 tcg_temp_free_i64(t2);
2893 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2894 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2895 }
2896 opn = "msubu";
2897 break;
2898 default:
2899 MIPS_INVAL(opn);
2900 generate_exception(ctx, EXCP_RI);
2901 goto out;
2902 }
2903 (void)opn; /* avoid a compiler warning */
2904 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2905 out:
2906 tcg_temp_free(t0);
2907 tcg_temp_free(t1);
2908 }
2909
2910 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2911 int rd, int rs, int rt)
2912 {
2913 const char *opn = "mul vr54xx";
2914 TCGv t0 = tcg_temp_new();
2915 TCGv t1 = tcg_temp_new();
2916
2917 gen_load_gpr(t0, rs);
2918 gen_load_gpr(t1, rt);
2919
2920 switch (opc) {
2921 case OPC_VR54XX_MULS:
2922 gen_helper_muls(t0, cpu_env, t0, t1);
2923 opn = "muls";
2924 break;
2925 case OPC_VR54XX_MULSU:
2926 gen_helper_mulsu(t0, cpu_env, t0, t1);
2927 opn = "mulsu";
2928 break;
2929 case OPC_VR54XX_MACC:
2930 gen_helper_macc(t0, cpu_env, t0, t1);
2931 opn = "macc";
2932 break;
2933 case OPC_VR54XX_MACCU:
2934 gen_helper_maccu(t0, cpu_env, t0, t1);
2935 opn = "maccu";
2936 break;
2937 case OPC_VR54XX_MSAC:
2938 gen_helper_msac(t0, cpu_env, t0, t1);
2939 opn = "msac";
2940 break;
2941 case OPC_VR54XX_MSACU:
2942 gen_helper_msacu(t0, cpu_env, t0, t1);
2943 opn = "msacu";
2944 break;
2945 case OPC_VR54XX_MULHI:
2946 gen_helper_mulhi(t0, cpu_env, t0, t1);
2947 opn = "mulhi";
2948 break;
2949 case OPC_VR54XX_MULHIU:
2950 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2951 opn = "mulhiu";
2952 break;
2953 case OPC_VR54XX_MULSHI:
2954 gen_helper_mulshi(t0, cpu_env, t0, t1);
2955 opn = "mulshi";
2956 break;
2957 case OPC_VR54XX_MULSHIU:
2958 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2959 opn = "mulshiu";
2960 break;
2961 case OPC_VR54XX_MACCHI:
2962 gen_helper_macchi(t0, cpu_env, t0, t1);
2963 opn = "macchi";
2964 break;
2965 case OPC_VR54XX_MACCHIU:
2966 gen_helper_macchiu(t0, cpu_env, t0, t1);
2967 opn = "macchiu";
2968 break;
2969 case OPC_VR54XX_MSACHI:
2970 gen_helper_msachi(t0, cpu_env, t0, t1);
2971 opn = "msachi";
2972 break;
2973 case OPC_VR54XX_MSACHIU:
2974 gen_helper_msachiu(t0, cpu_env, t0, t1);
2975 opn = "msachiu";
2976 break;
2977 default:
2978 MIPS_INVAL("mul vr54xx");
2979 generate_exception(ctx, EXCP_RI);
2980 goto out;
2981 }
2982 gen_store_gpr(t0, rd);
2983 (void)opn; /* avoid a compiler warning */
2984 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2985
2986 out:
2987 tcg_temp_free(t0);
2988 tcg_temp_free(t1);
2989 }
2990
2991 static void gen_cl (DisasContext *ctx, uint32_t opc,
2992 int rd, int rs)
2993 {
2994 const char *opn = "CLx";
2995 TCGv t0;
2996
2997 if (rd == 0) {
2998 /* Treat as NOP. */
2999 MIPS_DEBUG("NOP");
3000 return;
3001 }
3002 t0 = tcg_temp_new();
3003 gen_load_gpr(t0, rs);
3004 switch (opc) {
3005 case OPC_CLO:
3006 gen_helper_clo(cpu_gpr[rd], t0);
3007 opn = "clo";
3008 break;
3009 case OPC_CLZ:
3010 gen_helper_clz(cpu_gpr[rd], t0);
3011 opn = "clz";
3012 break;
3013 #if defined(TARGET_MIPS64)
3014 case OPC_DCLO:
3015 gen_helper_dclo(cpu_gpr[rd], t0);
3016 opn = "dclo";
3017 break;
3018 case OPC_DCLZ:
3019 gen_helper_dclz(cpu_gpr[rd], t0);
3020 opn = "dclz";
3021 break;
3022 #endif
3023 }
3024 (void)opn; /* avoid a compiler warning */
3025 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3026 tcg_temp_free(t0);
3027 }
3028
3029 /* Godson integer instructions */
3030 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3031 int rd, int rs, int rt)
3032 {
3033 const char *opn = "loongson";
3034 TCGv t0, t1;
3035
3036 if (rd == 0) {
3037 /* Treat as NOP. */
3038 MIPS_DEBUG("NOP");
3039 return;
3040 }
3041
3042 switch (opc) {
3043 case OPC_MULT_G_2E:
3044 case OPC_MULT_G_2F:
3045 case OPC_MULTU_G_2E:
3046 case OPC_MULTU_G_2F:
3047 #if defined(TARGET_MIPS64)
3048 case OPC_DMULT_G_2E:
3049 case OPC_DMULT_G_2F:
3050 case OPC_DMULTU_G_2E:
3051 case OPC_DMULTU_G_2F:
3052 #endif
3053 t0 = tcg_temp_new();
3054 t1 = tcg_temp_new();
3055 break;
3056 default:
3057 t0 = tcg_temp_local_new();
3058 t1 = tcg_temp_local_new();
3059 break;
3060 }
3061
3062 gen_load_gpr(t0, rs);
3063 gen_load_gpr(t1, rt);
3064
3065 switch (opc) {
3066 case OPC_MULT_G_2E:
3067 case OPC_MULT_G_2F:
3068 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3069 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3070 opn = "mult.g";
3071 break;
3072 case OPC_MULTU_G_2E:
3073 case OPC_MULTU_G_2F:
3074 tcg_gen_ext32u_tl(t0, t0);
3075 tcg_gen_ext32u_tl(t1, t1);
3076 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3077 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3078 opn = "multu.g";
3079 break;
3080 case OPC_DIV_G_2E:
3081 case OPC_DIV_G_2F:
3082 {
3083 int l1 = gen_new_label();
3084 int l2 = gen_new_label();
3085 int l3 = gen_new_label();
3086 tcg_gen_ext32s_tl(t0, t0);
3087 tcg_gen_ext32s_tl(t1, t1);
3088 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3089 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3090 tcg_gen_br(l3);
3091 gen_set_label(l1);
3092 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3093 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3094 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3095 tcg_gen_br(l3);
3096 gen_set_label(l2);
3097 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3098 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3099 gen_set_label(l3);
3100 }
3101 opn = "div.g";
3102 break;
3103 case OPC_DIVU_G_2E:
3104 case OPC_DIVU_G_2F:
3105 {
3106 int l1 = gen_new_label();
3107 int l2 = gen_new_label();
3108 tcg_gen_ext32u_tl(t0, t0);
3109 tcg_gen_ext32u_tl(t1, t1);
3110 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3111 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3112 tcg_gen_br(l2);
3113 gen_set_label(l1);
3114 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3115 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3116 gen_set_label(l2);
3117 }
3118 opn = "divu.g";
3119 break;
3120 case OPC_MOD_G_2E:
3121 case OPC_MOD_G_2F:
3122 {
3123 int l1 = gen_new_label();
3124 int l2 = gen_new_label();
3125 int l3 = gen_new_label();
3126 tcg_gen_ext32u_tl(t0, t0);
3127 tcg_gen_ext32u_tl(t1, t1);
3128 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3129 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3130 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3131 gen_set_label(l1);
3132 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3133 tcg_gen_br(l3);
3134 gen_set_label(l2);
3135 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3136 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3137 gen_set_label(l3);
3138 }
3139 opn = "mod.g";
3140 break;
3141 case OPC_MODU_G_2E:
3142 case OPC_MODU_G_2F:
3143 {
3144 int l1 = gen_new_label();
3145 int l2 = gen_new_label();
3146 tcg_gen_ext32u_tl(t0, t0);
3147 tcg_gen_ext32u_tl(t1, t1);
3148 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3149 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3150 tcg_gen_br(l2);
3151 gen_set_label(l1);
3152 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3153 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3154 gen_set_label(l2);
3155 }
3156 opn = "modu.g";
3157 break;
3158 #if defined(TARGET_MIPS64)
3159 case OPC_DMULT_G_2E:
3160 case OPC_DMULT_G_2F:
3161 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3162 opn = "dmult.g";
3163 break;
3164 case OPC_DMULTU_G_2E:
3165 case OPC_DMULTU_G_2F:
3166 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3167 opn = "dmultu.g";
3168 break;
3169 case OPC_DDIV_G_2E:
3170 case OPC_DDIV_G_2F:
3171 {
3172 int l1 = gen_new_label();
3173 int l2 = gen_new_label();
3174 int l3 = gen_new_label();
3175 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3176 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3177 tcg_gen_br(l3);
3178 gen_set_label(l1);
3179 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3180 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3181 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3182 tcg_gen_br(l3);
3183 gen_set_label(l2);
3184 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3185 gen_set_label(l3);
3186 }
3187 opn = "ddiv.g";
3188 break;
3189 case OPC_DDIVU_G_2E:
3190 case OPC_DDIVU_G_2F:
3191 {
3192 int l1 = gen_new_label();
3193 int l2 = gen_new_label();
3194 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3195 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3196 tcg_gen_br(l2);
3197 gen_set_label(l1);
3198 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3199 gen_set_label(l2);
3200 }
3201 opn = "ddivu.g";
3202 break;
3203 case OPC_DMOD_G_2E:
3204 case OPC_DMOD_G_2F:
3205 {
3206 int l1 = gen_new_label();
3207 int l2 = gen_new_label();
3208 int l3 = gen_new_label();
3209 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3210 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3211 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3212 gen_set_label(l1);
3213 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3214 tcg_gen_br(l3);
3215 gen_set_label(l2);
3216 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3217 gen_set_label(l3);
3218 }
3219 opn = "dmod.g";
3220 break;
3221 case OPC_DMODU_G_2E:
3222 case OPC_DMODU_G_2F:
3223 {
3224 int l1 = gen_new_label();
3225 int l2 = gen_new_label();
3226 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3227 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3228 tcg_gen_br(l2);
3229 gen_set_label(l1);
3230 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3231 gen_set_label(l2);
3232 }
3233 opn = "dmodu.g";
3234 break;
3235 #endif
3236 }
3237
3238 (void)opn; /* avoid a compiler warning */
3239 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3240 tcg_temp_free(t0);
3241 tcg_temp_free(t1);
3242 }
3243
3244 /* Loongson multimedia instructions */
3245 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3246 {
3247 const char *opn = "loongson_cp2";
3248 uint32_t opc, shift_max;
3249 TCGv_i64 t0, t1;
3250
3251 opc = MASK_LMI(ctx->opcode);
3252 switch (opc) {
3253 case OPC_ADD_CP2:
3254 case OPC_SUB_CP2:
3255 case OPC_DADD_CP2:
3256 case OPC_DSUB_CP2:
3257 t0 = tcg_temp_local_new_i64();
3258 t1 = tcg_temp_local_new_i64();
3259 break;
3260 default:
3261 t0 = tcg_temp_new_i64();
3262 t1 = tcg_temp_new_i64();
3263 break;
3264 }
3265
3266 gen_load_fpr64(ctx, t0, rs);
3267 gen_load_fpr64(ctx, t1, rt);
3268
3269 #define LMI_HELPER(UP, LO) \
3270 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3271 #define LMI_HELPER_1(UP, LO) \
3272 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3273 #define LMI_DIRECT(UP, LO, OP) \
3274 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3275
3276 switch (opc) {
3277 LMI_HELPER(PADDSH, paddsh);
3278 LMI_HELPER(PADDUSH, paddush);
3279 LMI_HELPER(PADDH, paddh);
3280 LMI_HELPER(PADDW, paddw);
3281 LMI_HELPER(PADDSB, paddsb);
3282 LMI_HELPER(PADDUSB, paddusb);
3283 LMI_HELPER(PADDB, paddb);
3284
3285 LMI_HELPER(PSUBSH, psubsh);
3286 LMI_HELPER(PSUBUSH, psubush);
3287 LMI_HELPER(PSUBH, psubh);
3288 LMI_HELPER(PSUBW, psubw);
3289 LMI_HELPER(PSUBSB, psubsb);
3290 LMI_HELPER(PSUBUSB, psubusb);
3291 LMI_HELPER(PSUBB, psubb);
3292
3293 LMI_HELPER(PSHUFH, pshufh);
3294 LMI_HELPER(PACKSSWH, packsswh);
3295 LMI_HELPER(PACKSSHB, packsshb);
3296 LMI_HELPER(PACKUSHB, packushb);
3297
3298 LMI_HELPER(PUNPCKLHW, punpcklhw);
3299 LMI_HELPER(PUNPCKHHW, punpckhhw);
3300 LMI_HELPER(PUNPCKLBH, punpcklbh);
3301 LMI_HELPER(PUNPCKHBH, punpckhbh);
3302 LMI_HELPER(PUNPCKLWD, punpcklwd);
3303 LMI_HELPER(PUNPCKHWD, punpckhwd);
3304
3305 LMI_HELPER(PAVGH, pavgh);
3306 LMI_HELPER(PAVGB, pavgb);
3307 LMI_HELPER(PMAXSH, pmaxsh);
3308 LMI_HELPER(PMINSH, pminsh);
3309 LMI_HELPER(PMAXUB, pmaxub);
3310 LMI_HELPER(PMINUB, pminub);
3311
3312 LMI_HELPER(PCMPEQW, pcmpeqw);
3313 LMI_HELPER(PCMPGTW, pcmpgtw);
3314 LMI_HELPER(PCMPEQH, pcmpeqh);
3315 LMI_HELPER(PCMPGTH, pcmpgth);
3316 LMI_HELPER(PCMPEQB, pcmpeqb);
3317 LMI_HELPER(PCMPGTB, pcmpgtb);
3318
3319 LMI_HELPER(PSLLW, psllw);
3320 LMI_HELPER(PSLLH, psllh);
3321 LMI_HELPER(PSRLW, psrlw);
3322 LMI_HELPER(PSRLH, psrlh);
3323 LMI_HELPER(PSRAW, psraw);
3324 LMI_HELPER(PSRAH, psrah);
3325
3326 LMI_HELPER(PMULLH, pmullh);
3327 LMI_HELPER(PMULHH, pmulhh);
3328 LMI_HELPER(PMULHUH, pmulhuh);
3329 LMI_HELPER(PMADDHW, pmaddhw);
3330
3331 LMI_HELPER(PASUBUB, pasubub);
3332 LMI_HELPER_1(BIADD, biadd);
3333 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3334
3335 LMI_DIRECT(PADDD, paddd, add);
3336 LMI_DIRECT(PSUBD, psubd, sub);
3337 LMI_DIRECT(XOR_CP2, xor, xor);
3338 LMI_DIRECT(NOR_CP2, nor, nor);
3339 LMI_DIRECT(AND_CP2, and, and);
3340 LMI_DIRECT(PANDN, pandn, andc);
3341 LMI_DIRECT(OR, or, or);
3342
3343 case OPC_PINSRH_0:
3344 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3345 opn = "pinsrh_0";
3346 break;
3347 case OPC_PINSRH_1:
3348 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3349 opn = "pinsrh_1";
3350 break;
3351 case OPC_PINSRH_2:
3352 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3353 opn = "pinsrh_2";
3354 break;
3355 case OPC_PINSRH_3:
3356 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3357 opn = "pinsrh_3";
3358 break;
3359
3360 case OPC_PEXTRH:
3361 tcg_gen_andi_i64(t1, t1, 3);
3362 tcg_gen_shli_i64(t1, t1, 4);
3363 tcg_gen_shr_i64(t0, t0, t1);
3364 tcg_gen_ext16u_i64(t0, t0);
3365 opn = "pextrh";
3366 break;
3367
3368 case OPC_ADDU_CP2:
3369 tcg_gen_add_i64(t0, t0, t1);
3370 tcg_gen_ext32s_i64(t0, t0);
3371 opn = "addu";
3372 break;
3373 case OPC_SUBU_CP2:
3374 tcg_gen_sub_i64(t0, t0, t1);
3375 tcg_gen_ext32s_i64(t0, t0);
3376 opn = "addu";
3377 break;
3378
3379 case OPC_SLL_CP2:
3380 opn = "sll";
3381 shift_max = 32;
3382 goto do_shift;
3383 case OPC_SRL_CP2:
3384 opn = "srl";
3385 shift_max = 32;
3386 goto do_shift;
3387 case OPC_SRA_CP2:
3388 opn = "sra";
3389 shift_max = 32;
3390 goto do_shift;
3391 case OPC_DSLL_CP2:
3392 opn = "dsll";
3393 shift_max = 64;
3394 goto do_shift;
3395 case OPC_DSRL_CP2:
3396 opn = "dsrl";
3397 shift_max = 64;
3398 goto do_shift;
3399 case OPC_DSRA_CP2:
3400 opn = "dsra";
3401 shift_max = 64;
3402 goto do_shift;
3403 do_shift:
3404 /* Make sure shift count isn't TCG undefined behaviour. */
3405 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3406
3407 switch (opc) {
3408 case OPC_SLL_CP2:
3409 case OPC_DSLL_CP2:
3410 tcg_gen_shl_i64(t0, t0, t1);
3411 break;
3412 case OPC_SRA_CP2:
3413 case OPC_DSRA_CP2:
3414 /* Since SRA is UndefinedResult without sign-extended inputs,
3415 we can treat SRA and DSRA the same. */
3416 tcg_gen_sar_i64(t0, t0, t1);
3417 break;
3418 case OPC_SRL_CP2:
3419 /* We want to shift in zeros for SRL; zero-extend first. */
3420 tcg_gen_ext32u_i64(t0, t0);
3421 /* FALLTHRU */
3422 case OPC_DSRL_CP2:
3423 tcg_gen_shr_i64(t0, t0, t1);
3424 break;
3425 }
3426
3427 if (shift_max == 32) {
3428 tcg_gen_ext32s_i64(t0, t0);
3429 }
3430
3431 /* Shifts larger than MAX produce zero. */
3432 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3433 tcg_gen_neg_i64(t1, t1);
3434 tcg_gen_and_i64(t0, t0, t1);
3435 break;
3436
3437 case OPC_ADD_CP2:
3438 case OPC_DADD_CP2:
3439 {
3440 TCGv_i64 t2 = tcg_temp_new_i64();
3441 int lab = gen_new_label();
3442
3443 tcg_gen_mov_i64(t2, t0);
3444 tcg_gen_add_i64(t0, t1, t2);
3445 if (opc == OPC_ADD_CP2) {
3446 tcg_gen_ext32s_i64(t0, t0);
3447 }
3448 tcg_gen_xor_i64(t1, t1, t2);
3449 tcg_gen_xor_i64(t2, t2, t0);
3450 tcg_gen_andc_i64(t1, t2, t1);
3451 tcg_temp_free_i64(t2);
3452 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3453 generate_exception(ctx, EXCP_OVERFLOW);
3454 gen_set_label(lab);
3455
3456 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3457 break;
3458 }
3459
3460 case OPC_SUB_CP2:
3461 case OPC_DSUB_CP2:
3462 {
3463 TCGv_i64 t2 = tcg_temp_new_i64();
3464 int lab = gen_new_label();
3465
3466 tcg_gen_mov_i64(t2, t0);
3467 tcg_gen_sub_i64(t0, t1, t2);
3468 if (opc == OPC_SUB_CP2) {
3469 tcg_gen_ext32s_i64(t0, t0);
3470 }
3471 tcg_gen_xor_i64(t1, t1, t2);
3472 tcg_gen_xor_i64(t2, t2, t0);
3473 tcg_gen_and_i64(t1, t1, t2);
3474 tcg_temp_free_i64(t2);
3475 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3476 generate_exception(ctx, EXCP_OVERFLOW);
3477 gen_set_label(lab);
3478
3479 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3480 break;
3481 }
3482
3483 case OPC_PMULUW:
3484 tcg_gen_ext32u_i64(t0, t0);
3485 tcg_gen_ext32u_i64(t1, t1);
3486 tcg_gen_mul_i64(t0, t0, t1);
3487 opn = "pmuluw";
3488 break;
3489
3490 case OPC_SEQU_CP2:
3491 case OPC_SEQ_CP2:
3492 case OPC_SLTU_CP2:
3493 case OPC_SLT_CP2:
3494 case OPC_SLEU_CP2:
3495 case OPC_SLE_CP2:
3496 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3497 FD field is the CC field? */
3498 default:
3499 MIPS_INVAL(opn);
3500 generate_exception(ctx, EXCP_RI);
3501 return;
3502 }
3503
3504 #undef LMI_HELPER
3505 #undef LMI_DIRECT
3506
3507 gen_store_fpr64(ctx, t0, rd);
3508
3509 (void)opn; /* avoid a compiler warning */
3510 MIPS_DEBUG("%s %s, %s, %s", opn,
3511 fregnames[rd], fregnames[rs], fregnames[rt]);
3512 tcg_temp_free_i64(t0);
3513 tcg_temp_free_i64(t1);
3514 }
3515
3516 /* Traps */
3517 static void gen_trap (DisasContext *ctx, uint32_t opc,
3518 int rs, int rt, int16_t imm)
3519 {
3520 int cond;
3521 TCGv t0 = tcg_temp_new();
3522 TCGv t1 = tcg_temp_new();
3523
3524 cond = 0;
3525 /* Load needed operands */
3526 switch (opc) {
3527 case OPC_TEQ:
3528 case OPC_TGE:
3529 case OPC_TGEU:
3530 case OPC_TLT:
3531 case OPC_TLTU:
3532 case OPC_TNE:
3533 /* Compare two registers */
3534 if (rs != rt) {
3535 gen_load_gpr(t0, rs);
3536 gen_load_gpr(t1, rt);
3537 cond = 1;
3538 }
3539 break;
3540 case OPC_TEQI:
3541 case OPC_TGEI:
3542 case OPC_TGEIU:
3543 case OPC_TLTI:
3544 case OPC_TLTIU:
3545 case OPC_TNEI:
3546 /* Compare register to immediate */
3547 if (rs != 0 || imm != 0) {
3548 gen_load_gpr(t0, rs);
3549 tcg_gen_movi_tl(t1, (int32_t)imm);
3550 cond = 1;
3551 }
3552 break;
3553 }
3554 if (cond == 0) {
3555 switch (opc) {
3556 case OPC_TEQ: /* rs == rs */
3557 case OPC_TEQI: /* r0 == 0 */
3558 case OPC_TGE: /* rs >= rs */
3559 case OPC_TGEI: /* r0 >= 0 */
3560 case OPC_TGEU: /* rs >= rs unsigned */
3561 case OPC_TGEIU: /* r0 >= 0 unsigned */
3562 /* Always trap */
3563 generate_exception(ctx, EXCP_TRAP);
3564 break;
3565 case OPC_TLT: /* rs < rs */
3566 case OPC_TLTI: /* r0 < 0 */
3567 case OPC_TLTU: /* rs < rs unsigned */
3568 case OPC_TLTIU: /* r0 < 0 unsigned */
3569 case OPC_TNE: /* rs != rs */
3570 case OPC_TNEI: /* r0 != 0 */
3571 /* Never trap: treat as NOP. */
3572 break;
3573 }
3574 } else {
3575 int l1 = gen_new_label();
3576
3577 switch (opc) {
3578 case OPC_TEQ:
3579 case OPC_TEQI:
3580 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3581 break;
3582 case OPC_TGE:
3583 case OPC_TGEI:
3584 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3585 break;
3586 case OPC_TGEU:
3587 case OPC_TGEIU:
3588 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3589 break;
3590 case OPC_TLT:
3591 case OPC_TLTI:
3592 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3593 break;
3594 case OPC_TLTU:
3595 case OPC_TLTIU:
3596 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3597 break;
3598 case OPC_TNE:
3599 case OPC_TNEI:
3600 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3601 break;
3602 }
3603 generate_exception(ctx, EXCP_TRAP);
3604 gen_set_label(l1);
3605 }
3606 tcg_temp_free(t0);
3607 tcg_temp_free(t1);
3608 }
3609
3610 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3611 {
3612 TranslationBlock *tb;
3613 tb = ctx->tb;
3614 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3615 likely(!ctx->singlestep_enabled)) {
3616 tcg_gen_goto_tb(n);
3617 gen_save_pc(dest);
3618 tcg_gen_exit_tb((tcg_target_long)tb + n);
3619 } else {
3620 gen_save_pc(dest);
3621 if (ctx->singlestep_enabled) {
3622 save_cpu_state(ctx, 0);
3623 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3624 }
3625 tcg_gen_exit_tb(0);
3626 }
3627 }
3628
3629 /* Branches (before delay slot) */
3630 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3631 int insn_bytes,
3632 int rs, int rt, int32_t offset)
3633 {
3634 target_ulong btgt = -1;
3635 int blink = 0;
3636 int bcond_compute = 0;
3637 TCGv t0 = tcg_temp_new();
3638 TCGv t1 = tcg_temp_new();
3639
3640 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3641 #ifdef MIPS_DEBUG_DISAS
3642 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3643 #endif
3644 generate_exception(ctx, EXCP_RI);
3645 goto out;
3646 }
3647
3648 /* Load needed operands */
3649 switch (opc) {
3650 case OPC_BEQ:
3651 case OPC_BEQL:
3652 case OPC_BNE:
3653 case OPC_BNEL:
3654 /* Compare two registers */
3655 if (rs != rt) {
3656 gen_load_gpr(t0, rs);
3657 gen_load_gpr(t1, rt);
3658 bcond_compute = 1;
3659 }
3660 btgt = ctx->pc + insn_bytes + offset;
3661 break;
3662 case OPC_BGEZ:
3663 case OPC_BGEZAL:
3664 case OPC_BGEZALS:
3665 case OPC_BGEZALL:
3666 case OPC_BGEZL:
3667 case OPC_BGTZ:
3668 case OPC_BGTZL:
3669 case OPC_BLEZ:
3670 case OPC_BLEZL:
3671 case OPC_BLTZ:
3672 case OPC_BLTZAL:
3673 case OPC_BLTZALS:
3674 case OPC_BLTZALL:
3675 case OPC_BLTZL:
3676 /* Compare to zero */
3677 if (rs != 0) {
3678 gen_load_gpr(t0, rs);
3679 bcond_compute = 1;
3680 }
3681 btgt = ctx->pc + insn_bytes + offset;
3682 break;
3683 case OPC_BPOSGE32:
3684 #if defined(TARGET_MIPS64)
3685 case OPC_BPOSGE64:
3686 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3687 #else
3688 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3689 #endif
3690 bcond_compute = 1;
3691 btgt = ctx->pc + insn_bytes + offset;
3692 break;
3693 case OPC_J:
3694 case OPC_JAL:
3695 case OPC_JALX:
3696 case OPC_JALS:
3697 case OPC_JALXS:
3698 /* Jump to immediate */
3699 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3700 break;
3701 case OPC_JR:
3702 case OPC_JALR:
3703 case OPC_JALRC:
3704 case OPC_JALRS:
3705 /* Jump to register */
3706 if (offset != 0 && offset != 16) {
3707 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3708 others are reserved. */
3709 MIPS_INVAL("jump hint");
3710 generate_exception(ctx, EXCP_RI);
3711 goto out;
3712 }
3713 gen_load_gpr(btarget, rs);
3714 break;
3715 default:
3716 MIPS_INVAL("branch/jump");
3717 generate_exception(ctx, EXCP_RI);
3718 goto out;
3719 }
3720 if (bcond_compute == 0) {
3721 /* No condition to be computed */
3722 switch (opc) {
3723 case OPC_BEQ: /* rx == rx */
3724 case OPC_BEQL: /* rx == rx likely */
3725 case OPC_BGEZ: /* 0 >= 0 */
3726 case OPC_BGEZL: /* 0 >= 0 likely */
3727 case OPC_BLEZ: /* 0 <= 0 */
3728 case OPC_BLEZL: /* 0 <= 0 likely */
3729 /* Always take */
3730 ctx->hflags |= MIPS_HFLAG_B;
3731 MIPS_DEBUG("balways");
3732 break;
3733 case OPC_BGEZALS:
3734 case OPC_BGEZAL: /* 0 >= 0 */
3735 case OPC_BGEZALL: /* 0 >= 0 likely */
3736 ctx->hflags |= (opc == OPC_BGEZALS
3737 ? MIPS_HFLAG_BDS16
3738 : MIPS_HFLAG_BDS32);
3739 /* Always take and link */
3740 blink = 31;
3741 ctx->hflags |= MIPS_HFLAG_B;
3742 MIPS_DEBUG("balways and link");
3743 break;
3744 case OPC_BNE: /* rx != rx */
3745 case OPC_BGTZ: /* 0 > 0 */
3746 case OPC_BLTZ: /* 0 < 0 */
3747 /* Treat as NOP. */
3748 MIPS_DEBUG("bnever (NOP)");
3749 goto out;
3750 case OPC_BLTZALS:
3751 case OPC_BLTZAL: /* 0 < 0 */
3752 ctx->hflags |= (opc == OPC_BLTZALS
3753 ? MIPS_HFLAG_BDS16
3754 : MIPS_HFLAG_BDS32);
3755 /* Handle as an unconditional branch to get correct delay
3756 slot checking. */
3757 blink = 31;
3758 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3759 ctx->hflags |= MIPS_HFLAG_B;
3760 MIPS_DEBUG("bnever and link");
3761 break;
3762 case OPC_BLTZALL: /* 0 < 0 likely */
3763 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3764 /* Skip the instruction in the delay slot */
3765 MIPS_DEBUG("bnever, link and skip");
3766 ctx->pc += 4;
3767 goto out;
3768 case OPC_BNEL: /* rx != rx likely */
3769 case OPC_BGTZL: /* 0 > 0 likely */
3770 case OPC_BLTZL: /* 0 < 0 likely */
3771 /* Skip the instruction in the delay slot */
3772 MIPS_DEBUG("bnever and skip");
3773 ctx->pc += 4;
3774 goto out;
3775 case OPC_J:
3776 ctx->hflags |= MIPS_HFLAG_B;
3777 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3778 break;
3779 case OPC_JALXS:
3780 case OPC_JALX:
3781 ctx->hflags |= MIPS_HFLAG_BX;
3782 /* Fallthrough */
3783 case OPC_JALS:
3784 case OPC_JAL:
3785 blink = 31;
3786 ctx->hflags |= MIPS_HFLAG_B;
3787 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3788 ? MIPS_HFLAG_BDS16
3789 : MIPS_HFLAG_BDS32);
3790 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3791 break;
3792 case OPC_JR:
3793 ctx->hflags |= MIPS_HFLAG_BR;
3794 if (insn_bytes == 4)
3795 ctx->hflags |= MIPS_HFLAG_BDS32;
3796 MIPS_DEBUG("jr %s", regnames[rs]);
3797 break;
3798 case OPC_JALRS:
3799 case OPC_JALR:
3800 case OPC_JALRC:
3801 blink = rt;
3802 ctx->hflags |= MIPS_HFLAG_BR;
3803 ctx->hflags |= (opc == OPC_JALRS
3804 ? MIPS_HFLAG_BDS16
3805 : MIPS_HFLAG_BDS32);
3806 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3807 break;
3808 default:
3809 MIPS_INVAL("branch/jump");
3810 generate_exception(ctx, EXCP_RI);
3811 goto out;
3812 }
3813 } else {
3814 switch (opc) {
3815 case OPC_BEQ:
3816 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3817 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3818 regnames[rs], regnames[rt], btgt);
3819 goto not_likely;
3820 case OPC_BEQL:
3821 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3822 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3823 regnames[rs], regnames[rt], btgt);
3824 goto likely;
3825 case OPC_BNE:
3826 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3827 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3828 regnames[rs], regnames[rt], btgt);
3829 goto not_likely;
3830 case OPC_BNEL:
3831 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3832 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3833 regnames[rs], regnames[rt], btgt);
3834 goto likely;
3835 case OPC_BGEZ:
3836 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3837 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3838 goto not_likely;
3839 case OPC_BGEZL:
3840 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3841 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3842 goto likely;
3843 case OPC_BGEZALS:
3844 case OPC_BGEZAL:
3845 ctx->hflags |= (opc == OPC_BGEZALS
3846 ? MIPS_HFLAG_BDS16
3847 : MIPS_HFLAG_BDS32);
3848 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3849 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3850 blink = 31;
3851 goto not_likely;
3852 case OPC_BGEZALL:
3853 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3854 blink = 31;
3855 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3856 goto likely;
3857 case OPC_BGTZ:
3858 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3859 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3860 goto not_likely;
3861 case OPC_BGTZL:
3862 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3863 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3864 goto likely;
3865 case OPC_BLEZ:
3866 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3867 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3868 goto not_likely;
3869 case OPC_BLEZL:
3870 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3871 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3872 goto likely;
3873 case OPC_BLTZ:
3874 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3875 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3876 goto not_likely;
3877 case OPC_BLTZL:
3878 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3879 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3880 goto likely;
3881 case OPC_BPOSGE32:
3882 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3883 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3884 goto not_likely;
3885 #if defined(TARGET_MIPS64)
3886 case OPC_BPOSGE64:
3887 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3888 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3889 goto not_likely;
3890 #endif
3891 case OPC_BLTZALS:
3892 case OPC_BLTZAL:
3893 ctx->hflags |= (opc == OPC_BLTZALS
3894 ? MIPS_HFLAG_BDS16
3895 : MIPS_HFLAG_BDS32);
3896 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3897 blink = 31;
3898 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3899 not_likely:
3900 ctx->hflags |= MIPS_HFLAG_BC;
3901 break;
3902 case OPC_BLTZALL:
3903 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3904 blink = 31;
3905 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3906 likely:
3907 ctx->hflags |= MIPS_HFLAG_BL;
3908 break;
3909 default:
3910 MIPS_INVAL("conditional branch/jump");
3911 generate_exception(ctx, EXCP_RI);
3912 goto out;
3913 }
3914 }
3915 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3916 blink, ctx->hflags, btgt);
3917
3918 ctx->btarget = btgt;
3919 if (blink > 0) {
3920 int post_delay = insn_bytes;
3921 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3922
3923 if (opc != OPC_JALRC)
3924 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3925
3926 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3927 }
3928
3929 out:
3930 if (insn_bytes == 2)
3931 ctx->hflags |= MIPS_HFLAG_B16;
3932 tcg_temp_free(t0);
3933 tcg_temp_free(t1);
3934 }
3935
3936 /* special3 bitfield operations */
3937 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3938 int rs, int lsb, int msb)
3939 {
3940 TCGv t0 = tcg_temp_new();
3941 TCGv t1 = tcg_temp_new();
3942 target_ulong mask;
3943
3944 gen_load_gpr(t1, rs);
3945 switch (opc) {
3946 case OPC_EXT:
3947 if (lsb + msb > 31)
3948 goto fail;
3949 tcg_gen_shri_tl(t0, t1, lsb);
3950 if (msb != 31) {
3951 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3952 } else {
3953 tcg_gen_ext32s_tl(t0, t0);
3954 }
3955 break;
3956 #if defined(TARGET_MIPS64)
3957 case OPC_DEXTM:
3958 tcg_gen_shri_tl(t0, t1, lsb);
3959 if (msb != 31) {
3960 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3961 }
3962 break;
3963 case OPC_DEXTU:
3964 tcg_gen_shri_tl(t0, t1, lsb + 32);
3965 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3966 break;
3967 case OPC_DEXT:
3968 tcg_gen_shri_tl(t0, t1, lsb);
3969 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3970 break;
3971 #endif
3972 case OPC_INS:
3973 if (lsb > msb)
3974 goto fail;
3975 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3976 gen_load_gpr(t0, rt);
3977 tcg_gen_andi_tl(t0, t0, ~mask);
3978 tcg_gen_shli_tl(t1, t1, lsb);
3979 tcg_gen_andi_tl(t1, t1, mask);
3980 tcg_gen_or_tl(t0, t0, t1);
3981 tcg_gen_ext32s_tl(t0, t0);
3982 break;
3983 #if defined(TARGET_MIPS64)
3984 case OPC_DINSM:
3985 if (lsb > msb)
3986 goto fail;
3987 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3988 gen_load_gpr(t0, rt);
3989 tcg_gen_andi_tl(t0, t0, ~mask);
3990 tcg_gen_shli_tl(t1, t1, lsb);
3991 tcg_gen_andi_tl(t1, t1, mask);
3992 tcg_gen_or_tl(t0, t0, t1);
3993 break;
3994 case OPC_DINSU:
3995 if (lsb > msb)
3996 goto fail;
3997 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3998 gen_load_gpr(t0, rt);
3999 tcg_gen_andi_tl(t0, t0, ~mask);
4000 tcg_gen_shli_tl(t1, t1, lsb + 32);
4001 tcg_gen_andi_tl(t1, t1, mask);
4002 tcg_gen_or_tl(t0, t0, t1);
4003 break;
4004 case OPC_DINS:
4005 if (lsb > msb)
4006 goto fail;
4007 gen_load_gpr(t0, rt);
4008 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
4009 gen_load_gpr(t0, rt);
4010 tcg_gen_andi_tl(t0, t0, ~mask);
4011 tcg_gen_shli_tl(t1, t1, lsb);
4012 tcg_gen_andi_tl(t1, t1, mask);
4013 tcg_gen_or_tl(t0, t0, t1);
4014 break;
4015 #endif
4016 default:
4017 fail:
4018 MIPS_INVAL("bitops");
4019 generate_exception(ctx, EXCP_RI);
4020 tcg_temp_free(t0);
4021 tcg_temp_free(t1);
4022 return;
4023 }
4024 gen_store_gpr(t0, rt);
4025 tcg_temp_free(t0);
4026 tcg_temp_free(t1);
4027 }
4028
4029 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4030 {
4031 TCGv t0;
4032
4033 if (rd == 0) {
4034 /* If no destination, treat it as a NOP. */
4035 MIPS_DEBUG("NOP");
4036 return;
4037 }
4038
4039 t0 = tcg_temp_new();
4040 gen_load_gpr(t0, rt);
4041 switch (op2) {
4042 case OPC_WSBH:
4043 {
4044 TCGv t1 = tcg_temp_new();
4045
4046 tcg_gen_shri_tl(t1, t0, 8);
4047 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4048 tcg_gen_shli_tl(t0, t0, 8);
4049 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4050 tcg_gen_or_tl(t0, t0, t1);
4051 tcg_temp_free(t1);
4052 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4053 }
4054 break;
4055 case OPC_SEB:
4056 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4057 break;
4058 case OPC_SEH:
4059 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4060 break;
4061 #if defined(TARGET_MIPS64)
4062 case OPC_DSBH:
4063 {
4064 TCGv t1 = tcg_temp_new();
4065
4066 tcg_gen_shri_tl(t1, t0, 8);
4067 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4068 tcg_gen_shli_tl(t0, t0, 8);
4069 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4070 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4071 tcg_temp_free(t1);
4072 }
4073 break;
4074 case OPC_DSHD:
4075 {
4076 TCGv t1 = tcg_temp_new();
4077
4078 tcg_gen_shri_tl(t1, t0, 16);
4079 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4080 tcg_gen_shli_tl(t0, t0, 16);
4081 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4082 tcg_gen_or_tl(t0, t0, t1);
4083 tcg_gen_shri_tl(t1, t0, 32);
4084 tcg_gen_shli_tl(t0, t0, 32);
4085 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4086 tcg_temp_free(t1);
4087 }
4088 break;
4089 #endif
4090 default:
4091 MIPS_INVAL("bsfhl");
4092 generate_exception(ctx, EXCP_RI);
4093 tcg_temp_free(t0);
4094 return;
4095 }
4096 tcg_temp_free(t0);
4097 }
4098
4099 #ifndef CONFIG_USER_ONLY
4100 /* CP0 (MMU and control) */
4101 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4102 {
4103 TCGv_i32 t0 = tcg_temp_new_i32();
4104
4105 tcg_gen_ld_i32(t0, cpu_env, off);
4106 tcg_gen_ext_i32_tl(arg, t0);
4107 tcg_temp_free_i32(t0);
4108 }
4109
4110 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4111 {
4112 tcg_gen_ld_tl(arg, cpu_env, off);
4113 tcg_gen_ext32s_tl(arg, arg);
4114 }
4115
4116 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4117 {
4118 TCGv_i32 t0 = tcg_temp_new_i32();
4119
4120 tcg_gen_trunc_tl_i32(t0, arg);
4121 tcg_gen_st_i32(t0, cpu_env, off);
4122 tcg_temp_free_i32(t0);
4123 }
4124
4125 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4126 {
4127 tcg_gen_ext32s_tl(arg, arg);
4128 tcg_gen_st_tl(arg, cpu_env, off);
4129 }
4130
4131 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4132 {
4133 const char *rn = "invalid";
4134
4135 if (sel != 0)
4136 check_insn(env, ctx, ISA_MIPS32);
4137
4138 switch (reg) {
4139 case 0:
4140 switch (sel) {
4141 case 0:
4142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4143 rn = "Index";
4144 break;
4145 case 1:
4146 check_insn(env, ctx, ASE_MT);
4147 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4148 rn = "MVPControl";
4149 break;
4150 case 2:
4151 check_insn(env, ctx, ASE_MT);
4152 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4153 rn = "MVPConf0";
4154 break;
4155 case 3:
4156 check_insn(env, ctx, ASE_MT);
4157 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4158 rn = "MVPConf1";
4159 break;
4160 default:
4161 goto die;
4162 }
4163 break;
4164 case 1:
4165 switch (sel) {
4166 case 0:
4167 gen_helper_mfc0_random(arg, cpu_env);
4168 rn = "Random";
4169 break;
4170 case 1:
4171 check_insn(env, ctx, ASE_MT);
4172 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4173 rn = "VPEControl";
4174 break;
4175 case 2:
4176 check_insn(env, ctx, ASE_MT);
4177 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4178 rn = "VPEConf0";
4179 break;
4180 case 3:
4181 check_insn(env, ctx, ASE_MT);
4182 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4183 rn = "VPEConf1";
4184 break;
4185 case 4:
4186 check_insn(env, ctx, ASE_MT);
4187 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4188 rn = "YQMask";
4189 break;
4190 case 5:
4191 check_insn(env, ctx, ASE_MT);
4192 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4193 rn = "VPESchedule";
4194 break;
4195 case 6:
4196 check_insn(env, ctx, ASE_MT);
4197 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4198 rn = "VPEScheFBack";
4199 break;
4200 case 7:
4201 check_insn(env, ctx, ASE_MT);
4202 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4203 rn = "VPEOpt";
4204 break;
4205 default:
4206 goto die;
4207 }
4208 break;
4209 case 2:
4210 switch (sel) {
4211 case 0:
4212 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4213 tcg_gen_ext32s_tl(arg, arg);
4214 rn = "EntryLo0";
4215 break;
4216 case 1:
4217 check_insn(env, ctx, ASE_MT);
4218 gen_helper_mfc0_tcstatus(arg, cpu_env);
4219 rn = "TCStatus";
4220 break;
4221 case 2:
4222 check_insn(env, ctx, ASE_MT);
4223 gen_helper_mfc0_tcbind(arg, cpu_env);
4224 rn = "TCBind";
4225 break;
4226 case 3:
4227 check_insn(env, ctx, ASE_MT);
4228 gen_helper_mfc0_tcrestart(arg, cpu_env);
4229 rn = "TCRestart";
4230 break;
4231 case 4:
4232 check_insn(env, ctx, ASE_MT);
4233 gen_helper_mfc0_tchalt(arg, cpu_env);
4234 rn = "TCHalt";
4235 break;
4236 case 5:
4237 check_insn(env, ctx, ASE_MT);
4238 gen_helper_mfc0_tccontext(arg, cpu_env);
4239 rn = "TCContext";
4240 break;
4241 case 6:
4242 check_insn(env, ctx, ASE_MT);
4243 gen_helper_mfc0_tcschedule(arg, cpu_env);
4244 rn = "TCSchedule";
4245 break;
4246 case 7:
4247 check_insn(env, ctx, ASE_MT);
4248 gen_helper_mfc0_tcschefback(arg, cpu_env);
4249 rn = "TCScheFBack";
4250 break;
4251 default:
4252 goto die;
4253 }
4254 break;
4255 case 3:
4256 switch (sel) {
4257 case 0:
4258 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4259 tcg_gen_ext32s_tl(arg, arg);
4260 rn = "EntryLo1";
4261 break;
4262 default:
4263 goto die;
4264 }
4265 break;
4266 case 4:
4267 switch (sel) {
4268 case 0:
4269 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4270 tcg_gen_ext32s_tl(arg, arg);
4271 rn = "Context";
4272 break;
4273 case 1:
4274 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4275 rn = "ContextConfig";
4276 // break;
4277 default:
4278 goto die;
4279 }
4280 break;
4281 case 5:
4282 switch (sel) {
4283 case 0:
4284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4285 rn = "PageMask";
4286 break;
4287 case 1:
4288 check_insn(env, ctx, ISA_MIPS32R2);
4289 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4290 rn = "PageGrain";
4291 break;
4292 default:
4293 goto die;
4294 }
4295 break;
4296 case 6:
4297 switch (sel) {
4298 case 0:
4299 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4300 rn = "Wired";
4301 break;
4302 case 1:
4303 check_insn(env, ctx, ISA_MIPS32R2);
4304 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4305 rn = "SRSConf0";
4306 break;
4307 case 2:
4308 check_insn(env, ctx, ISA_MIPS32R2);
4309 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4310 rn = "SRSConf1";
4311 break;
4312 case 3:
4313 check_insn(env, ctx, ISA_MIPS32R2);
4314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4315 rn = "SRSConf2";
4316 break;
4317 case 4:
4318 check_insn(env, ctx, ISA_MIPS32R2);
4319 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4320 rn = "SRSConf3";
4321 break;
4322 case 5:
4323 check_insn(env, ctx, ISA_MIPS32R2);
4324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4325 rn = "SRSConf4";
4326 break;
4327 default:
4328 goto die;
4329 }
4330 break;
4331 case 7:
4332 switch (sel) {
4333 case 0:
4334 check_insn(env, ctx, ISA_MIPS32R2);
4335 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4336 rn = "HWREna";
4337 break;
4338 default:
4339 goto die;
4340 }
4341 break;
4342 case 8:
4343 switch (sel) {
4344 case 0:
4345 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4346 tcg_gen_ext32s_tl(arg, arg);
4347 rn = "BadVAddr";
4348 break;
4349 default:
4350 goto die;
4351 }
4352 break;
4353 case 9:
4354 switch (sel) {
4355 case 0:
4356 /* Mark as an IO operation because we read the time. */
4357 if (use_icount)
4358 gen_io_start();
4359 gen_helper_mfc0_count(arg, cpu_env);
4360 if (use_icount) {
4361 gen_io_end();
4362 }
4363 /* Break the TB to be able to take timer interrupts immediately
4364 after reading count. */
4365 ctx->bstate = BS_STOP;
4366 rn = "Count";
4367 break;
4368 /* 6,7 are implementation dependent */
4369 default:
4370 goto die;
4371 }
4372 break;
4373 case 10:
4374 switch (sel) {
4375 case 0:
4376 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4377 tcg_gen_ext32s_tl(arg, arg);
4378 rn = "EntryHi";
4379 break;
4380 default:
4381 goto die;
4382 }
4383 break;
4384 case 11:
4385 switch (sel) {
4386 case 0:
4387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4388 rn = "Compare";
4389 break;
4390 /* 6,7 are implementation dependent */
4391 default:
4392 goto die;
4393 }
4394 break;
4395 case 12:
4396 switch (sel) {
4397 case 0:
4398 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4399 rn = "Status";
4400 break;
4401 case 1:
4402 check_insn(env, ctx, ISA_MIPS32R2);
4403 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4404 rn = "IntCtl";
4405 break;
4406 case 2:
4407 check_insn(env, ctx, ISA_MIPS32R2);
4408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4409 rn = "SRSCtl";
4410 break;
4411 case 3:
4412 check_insn(env, ctx, ISA_MIPS32R2);
4413 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4414 rn = "SRSMap";
4415 break;
4416 default:
4417 goto die;
4418 }
4419 break;
4420 case 13:
4421 switch (sel) {
4422 case 0:
4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4424 rn = "Cause";
4425 break;
4426 default:
4427 goto die;
4428 }
4429 break;
4430 case 14:
4431 switch (sel) {
4432 case 0:
4433 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4434 tcg_gen_ext32s_tl(arg, arg);
4435 rn = "EPC";
4436 break;
4437 default:
4438 goto die;
4439 }
4440 break;
4441 case 15:
4442 switch (sel) {
4443 case 0:
4444 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4445 rn = "PRid";
4446 break;
4447 case 1:
4448 check_insn(env, ctx, ISA_MIPS32R2);
4449 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4450 rn = "EBase";
4451 break;
4452 default:
4453 goto die;
4454 }
4455 break;
4456 case 16:
4457 switch (sel) {
4458 case 0:
4459 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4460 rn = "Config";
4461 break;
4462 case 1:
4463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4464 rn = "Config1";
4465 break;
4466 case 2:
4467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4468 rn = "Config2";
4469 break;
4470 case 3:
4471 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4472 rn = "Config3";
4473 break;
4474 /* 4,5 are reserved */
4475 /* 6,7 are implementation dependent */
4476 case 6:
4477 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4478 rn = "Config6";
4479 break;
4480 case 7:
4481 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4482 rn = "Config7";
4483 break;
4484 default:
4485 goto die;
4486 }
4487 break;
4488 case 17:
4489 switch (sel) {
4490 case 0:
4491 gen_helper_mfc0_lladdr(arg, cpu_env);
4492 rn = "LLAddr";
4493 break;
4494 default:
4495 goto die;
4496 }
4497 break;
4498 case 18:
4499 switch (sel) {
4500 case 0 ... 7:
4501 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4502 rn = "WatchLo";
4503 break;
4504 default:
4505 goto die;
4506 }
4507 break;
4508 case 19:
4509 switch (sel) {
4510 case 0 ...7:
4511 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4512 rn = "WatchHi";
4513 break;
4514 default:
4515 goto die;
4516 }
4517 break;
4518 case 20:
4519 switch (sel) {
4520 case 0:
4521 #if defined(TARGET_MIPS64)
4522 check_insn(env, ctx, ISA_MIPS3);
4523 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4524 tcg_gen_ext32s_tl(arg, arg);
4525 rn = "XContext";
4526 break;
4527 #endif
4528 default:
4529 goto die;
4530 }
4531 break;
4532 case 21:
4533 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4534 switch (sel) {
4535 case 0:
4536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4537 rn = "Framemask";
4538 break;
4539 default:
4540 goto die;
4541 }
4542 break;
4543 case 22:
4544 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4545 rn = "'Diagnostic"; /* implementation dependent */
4546 break;
4547 case 23:
4548 switch (sel) {
4549 case 0:
4550 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4551 rn = "Debug";
4552 break;
4553 case 1:
4554 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4555 rn = "TraceControl";
4556 // break;
4557 case 2:
4558 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4559 rn = "TraceControl2";
4560 // break;
4561 case 3:
4562 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4563 rn = "UserTraceData";
4564 // break;
4565 case 4:
4566 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4567 rn = "TraceBPC";
4568 // break;
4569 default:
4570 goto die;
4571 }
4572 break;
4573 case 24:
4574 switch (sel) {
4575 case 0:
4576 /* EJTAG support */
4577 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4578 tcg_gen_ext32s_tl(arg, arg);
4579 rn = "DEPC";
4580 break;
4581 default:
4582 goto die;
4583 }
4584 break;
4585 case 25:
4586 switch (sel) {
4587 case 0:
4588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4589 rn = "Performance0";
4590 break;
4591 case 1:
4592 // gen_helper_mfc0_performance1(arg);
4593 rn = "Performance1";
4594 // break;
4595 case 2:
4596 // gen_helper_mfc0_performance2(arg);
4597 rn = "Performance2";
4598 // break;
4599 case 3:
4600 // gen_helper_mfc0_performance3(arg);
4601 rn = "Performance3";
4602 // break;
4603 case 4:
4604 // gen_helper_mfc0_performance4(arg);
4605 rn = "Performance4";
4606 // break;
4607 case 5:
4608 // gen_helper_mfc0_performance5(arg);
4609 rn = "Performance5";
4610 // break;
4611 case 6:
4612 // gen_helper_mfc0_performance6(arg);
4613 rn = "Performance6";
4614 // break;
4615 case 7:
4616 // gen_helper_mfc0_performance7(arg);
4617 rn = "Performance7";
4618 // break;
4619 default:
4620 goto die;
4621 }
4622 break;
4623 case 26:
4624 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4625 rn = "ECC";
4626 break;
4627 case 27:
4628 switch (sel) {
4629 case 0 ... 3:
4630 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4631 rn = "CacheErr";
4632 break;
4633 default:
4634 goto die;
4635 }
4636 break;
4637 case 28:
4638 switch (sel) {
4639 case 0:
4640 case 2:
4641 case 4:
4642 case 6:
4643 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4644 rn = "TagLo";
4645 break;
4646 case 1:
4647 case 3:
4648 case 5:
4649 case 7:
4650 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4651 rn = "DataLo";
4652 break;
4653 default:
4654 goto die;
4655 }
4656 break;
4657 case 29:
4658 switch (sel) {
4659 case 0:
4660 case 2:
4661 case 4:
4662 case 6:
4663 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4664 rn = "TagHi";
4665 break;
4666 case 1:
4667 case 3:
4668 case 5:
4669 case 7:
4670 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4671 rn = "DataHi";
4672 break;
4673 default:
4674 goto die;
4675 }
4676 break;
4677 case 30:
4678 switch (sel) {
4679 case 0:
4680 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4681 tcg_gen_ext32s_tl(arg, arg);
4682 rn = "ErrorEPC";
4683 break;
4684 default:
4685 goto die;
4686 }
4687 break;
4688 case 31:
4689 switch (sel) {
4690 case 0:
4691 /* EJTAG support */
4692 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4693 rn = "DESAVE";
4694 break;
4695 default:
4696 goto die;
4697 }
4698 break;
4699 default:
4700 goto die;
4701 }
4702 (void)rn; /* avoid a compiler warning */
4703 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4704 return;
4705
4706 die:
4707 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4708 generate_exception(ctx, EXCP_RI);
4709 }
4710
4711 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4712 {
4713 const char *rn = "invalid";
4714
4715 if (sel != 0)
4716 check_insn(env, ctx, ISA_MIPS32);
4717
4718 if (use_icount)
4719 gen_io_start();
4720
4721 switch (reg) {
4722 case 0:
4723 switch (sel) {
4724 case 0:
4725 gen_helper_mtc0_index(cpu_env, arg);
4726 rn = "Index";
4727 break;
4728 case 1:
4729 check_insn(env, ctx, ASE_MT);
4730 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4731 rn = "MVPControl";
4732 break;
4733 case 2:
4734 check_insn(env, ctx, ASE_MT);
4735 /* ignored */
4736 rn = "MVPConf0";
4737 break;
4738 case 3:
4739 check_insn(env, ctx, ASE_MT);
4740 /* ignored */
4741 rn = "MVPConf1";
4742 break;
4743 default:
4744 goto die;
4745 }
4746 break;
4747 case 1:
4748 switch (sel) {
4749 case 0:
4750 /* ignored */
4751 rn = "Random";
4752 break;
4753 case 1:
4754 check_insn(env, ctx, ASE_MT);
4755 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4756 rn = "VPEControl";
4757 break;
4758 case 2:
4759 check_insn(env, ctx, ASE_MT);
4760 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4761 rn = "VPEConf0";
4762 break;
4763 case 3:
4764 check_insn(env, ctx, ASE_MT);
4765 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4766 rn = "VPEConf1";
4767 break;
4768 case 4:
4769 check_insn(env, ctx, ASE_MT);
4770 gen_helper_mtc0_yqmask(cpu_env, arg);
4771 rn = "YQMask";
4772 break;
4773 case 5:
4774 check_insn(env, ctx, ASE_MT);
4775 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4776 rn = "VPESchedule";
4777 break;
4778 case 6:
4779 check_insn(env, ctx, ASE_MT);
4780 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4781 rn = "VPEScheFBack";
4782 break;
4783 case 7:
4784 check_insn(env, ctx, ASE_MT);
4785 gen_helper_mtc0_vpeopt(cpu_env, arg);
4786 rn = "VPEOpt";
4787 break;
4788 default:
4789 goto die;
4790 }
4791 break;
4792 case 2:
4793 switch (sel) {
4794 case 0:
4795 gen_helper_mtc0_entrylo0(cpu_env, arg);
4796 rn = "EntryLo0";
4797 break;
4798 case 1:
4799 check_insn(env, ctx, ASE_MT);
4800 gen_helper_mtc0_tcstatus(cpu_env, arg);
4801 rn = "TCStatus";
4802 break;
4803 case 2:
4804 check_insn(env, ctx, ASE_MT);
4805 gen_helper_mtc0_tcbind(cpu_env, arg);
4806 rn = "TCBind";
4807 break;
4808 case 3:
4809 check_insn(env, ctx, ASE_MT);
4810 gen_helper_mtc0_tcrestart(cpu_env, arg);
4811 rn = "TCRestart";
4812 break;
4813 case 4:
4814 check_insn(env, ctx, ASE_MT);
4815 gen_helper_mtc0_tchalt(cpu_env, arg);
4816 rn = "TCHalt";
4817 break;
4818 case 5:
4819 check_insn(env, ctx, ASE_MT);
4820 gen_helper_mtc0_tccontext(cpu_env, arg);
4821 rn = "TCContext";
4822 break;
4823 case 6:
4824 check_insn(env, ctx, ASE_MT);
4825 gen_helper_mtc0_tcschedule(cpu_env, arg);
4826 rn = "TCSchedule";
4827 break;
4828 case 7:
4829 check_insn(env, ctx, ASE_MT);
4830 gen_helper_mtc0_tcschefback(cpu_env, arg);
4831 rn = "TCScheFBack";
4832 break;
4833 default:
4834 goto die;
4835 }
4836 break;
4837 case 3:
4838 switch (sel) {
4839 case 0:
4840 gen_helper_mtc0_entrylo1(cpu_env, arg);
4841 rn = "EntryLo1";
4842 break;
4843 default:
4844 goto die;
4845 }
4846 break;
4847 case 4:
4848 switch (sel) {
4849 case 0:
4850 gen_helper_mtc0_context(cpu_env, arg);
4851 rn = "Context";
4852 break;
4853 case 1:
4854 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4855 rn = "ContextConfig";
4856 // break;
4857 default:
4858 goto die;
4859 }
4860 break;
4861 case 5:
4862 switch (sel) {
4863 case 0:
4864 gen_helper_mtc0_pagemask(cpu_env, arg);
4865 rn = "PageMask";
4866 break;
4867 case 1:
4868 check_insn(env, ctx, ISA_MIPS32R2);
4869 gen_helper_mtc0_pagegrain(cpu_env, arg);
4870 rn = "PageGrain";
4871 break;
4872 default:
4873 goto die;
4874 }
4875 break;
4876 case 6:
4877 switch (sel) {
4878 case 0:
4879 gen_helper_mtc0_wired(cpu_env, arg);
4880 rn = "Wired";
4881 break;
4882 case 1:
4883 check_insn(env, ctx, ISA_MIPS32R2);
4884 gen_helper_mtc0_srsconf0(cpu_env, arg);
4885 rn = "SRSConf0";
4886 break;
4887 case 2:
4888 check_insn(env, ctx, ISA_MIPS32R2);
4889 gen_helper_mtc0_srsconf1(cpu_env, arg);
4890 rn = "SRSConf1";
4891 break;
4892 case 3:
4893 check_insn(env, ctx, ISA_MIPS32R2);
4894 gen_helper_mtc0_srsconf2(cpu_env, arg);
4895 rn = "SRSConf2";
4896 break;
4897 case 4:
4898 check_insn(env, ctx, ISA_MIPS32R2);
4899 gen_helper_mtc0_srsconf3(cpu_env, arg);
4900 rn = "SRSConf3";
4901 break;
4902 case 5:
4903 check_insn(env, ctx, ISA_MIPS32R2);
4904 gen_helper_mtc0_srsconf4(cpu_env, arg);
4905 rn = "SRSConf4";
4906 break;
4907 default:
4908 goto die;
4909 }
4910 break;
4911 case 7:
4912 switch (sel) {
4913 case 0:
4914 check_insn(env, ctx, ISA_MIPS32R2);
4915 gen_helper_mtc0_hwrena(cpu_env, arg);
4916 rn = "HWREna";
4917 break;
4918 default:
4919 goto die;
4920 }
4921 break;
4922 case 8:
4923 /* ignored */
4924 rn = "BadVAddr";
4925 break;
4926 case 9:
4927 switch (sel) {
4928 case 0:
4929 gen_helper_mtc0_count(cpu_env, arg);
4930 rn = "Count";
4931 break;
4932 /* 6,7 are implementation dependent */
4933 default:
4934 goto die;
4935 }
4936 break;
4937 case 10:
4938 switch (sel) {
4939 case 0:
4940 gen_helper_mtc0_entryhi(cpu_env, arg);
4941 rn = "EntryHi";
4942 break;
4943 default:
4944 goto die;
4945 }
4946 break;
4947 case 11:
4948 switch (sel) {
4949 case 0:
4950 gen_helper_mtc0_compare(cpu_env, arg);
4951 rn = "Compare";
4952 break;
4953 /* 6,7 are implementation dependent */
4954 default:
4955 goto die;
4956 }
4957 break;
4958 case 12:
4959 switch (sel) {
4960 case 0:
4961 save_cpu_state(ctx, 1);
4962 gen_helper_mtc0_status(cpu_env, arg);
4963 /* BS_STOP isn't good enough here, hflags may have changed. */
4964 gen_save_pc(ctx->pc + 4);
4965 ctx->bstate = BS_EXCP;
4966 rn = "Status";
4967 break;
4968 case 1:
4969 check_insn(env, ctx, ISA_MIPS32R2);
4970 gen_helper_mtc0_intctl(cpu_env, arg);
4971 /* Stop translation as we may have switched the execution mode */
4972 ctx->bstate = BS_STOP;
4973 rn = "IntCtl";
4974 break;
4975 case 2:
4976 check_insn(env, ctx, ISA_MIPS32R2);
4977 gen_helper_mtc0_srsctl(cpu_env, arg);
4978 /* Stop translation as we may have switched the execution mode */
4979 ctx->bstate = BS_STOP;
4980 rn = "SRSCtl";
4981 break;
4982 case 3:
4983 check_insn(env, ctx, ISA_MIPS32R2);
4984 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4985 /* Stop translation as we may have switched the execution mode */
4986 ctx->bstate = BS_STOP;
4987 rn = "SRSMap";
4988 break;
4989 default:
4990 goto die;
4991 }
4992 break;
4993 case 13:
4994 switch (sel) {
4995 case 0:
4996 save_cpu_state(ctx, 1);
4997 gen_helper_mtc0_cause(cpu_env, arg);
4998 rn = "Cause";
4999 break;
5000 default:
5001 goto die;
5002 }
5003 break;
5004 case 14:
5005 switch (sel) {
5006 case 0:
5007 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
5008 rn = "EPC";
5009 break;
5010 default:
5011 goto die;
5012 }
5013 break;
5014 case 15:
5015 switch (sel) {
5016 case 0:
5017 /* ignored */
5018 rn = "PRid";
5019 break;
5020 case 1:
5021 check_insn(env, ctx, ISA_MIPS32R2);
5022 gen_helper_mtc0_ebase(cpu_env, arg);
5023 rn = "EBase";
5024 break;
5025 default:
5026 goto die;
5027 }
5028 break;
5029 case 16:
5030 switch (sel) {
5031 case 0:
5032 gen_helper_mtc0_config0(cpu_env, arg);
5033 rn = "Config";
5034 /* Stop translation as we may have switched the execution mode */
5035 ctx->bstate = BS_STOP;
5036 break;
5037 case 1:
5038 /* ignored, read only */
5039 rn = "Config1";
5040 break;
5041 case 2:
5042 gen_helper_mtc0_config2(cpu_env, arg);
5043 rn = "Config2";
5044 /* Stop translation as we may have switched the execution mode */
5045 ctx->bstate = BS_STOP;
5046 break;
5047 case 3:
5048 /* ignored, read only */
5049 rn = "Config3";
5050 break;
5051 /* 4,5 are reserved */
5052 /* 6,7 are implementation dependent */
5053 case 6:
5054 /* ignored */
5055 rn = "Config6";
5056 break;
5057 case 7:
5058 /* ignored */
5059 rn = "Config7";
5060 break;
5061 default:
5062 rn = "Invalid config selector";
5063 goto die;
5064 }
5065 break;
5066 case 17:
5067 switch (sel) {
5068 case 0:
5069 gen_helper_mtc0_lladdr(cpu_env, arg);
5070 rn = "LLAddr";
5071 break;
5072 default:
5073 goto die;
5074 }
5075 break;
5076 case 18:
5077 switch (sel) {
5078 case 0 ... 7:
5079 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5080 rn = "WatchLo";
5081 break;
5082 default:
5083 goto die;
5084 }
5085 break;
5086 case 19:
5087 switch (sel) {
5088 case 0 ... 7:
5089 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5090 rn = "WatchHi";
5091 break;
5092 default:
5093 goto die;
5094 }
5095 break;
5096 case 20:
5097 switch (sel) {
5098 case 0:
5099 #if defined(TARGET_MIPS64)
5100 check_insn(env, ctx, ISA_MIPS3);
5101 gen_helper_mtc0_xcontext(cpu_env, arg);
5102 rn = "XContext";
5103 break;
5104 #endif
5105 default:
5106 goto die;
5107 }
5108 break;
5109 case 21:
5110 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5111 switch (sel) {
5112 case 0:
5113 gen_helper_mtc0_framemask(cpu_env, arg);
5114 rn = "Framemask";
5115 break;
5116 default:
5117 goto die;
5118 }
5119 break;
5120 case 22:
5121 /* ignored */
5122 rn = "Diagnostic"; /* implementation dependent */
5123 break;
5124 case 23:
5125 switch (sel) {
5126 case 0:
5127 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5128 /* BS_STOP isn't good enough here, hflags may have changed. */
5129 gen_save_pc(ctx->pc + 4);
5130 ctx->bstate = BS_EXCP;
5131 rn = "Debug";
5132 break;
5133 case 1:
5134 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5135 rn = "TraceControl";
5136 /* Stop translation as we may have switched the execution mode */
5137 ctx->bstate = BS_STOP;
5138 // break;
5139 case 2:
5140 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5141 rn = "TraceControl2";
5142 /* Stop translation as we may have switched the execution mode */
5143 ctx->bstate = BS_STOP;
5144 // break;
5145 case 3:
5146 /* Stop translation as we may have switched the execution mode */
5147 ctx->bstate = BS_STOP;
5148 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5149 rn = "UserTraceData";
5150 /* Stop translation as we may have switched the execution mode */
5151 ctx->bstate = BS_STOP;
5152 // break;
5153 case 4:
5154 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5155 /* Stop translation as we may have switched the execution mode */
5156 ctx->bstate = BS_STOP;
5157 rn = "TraceBPC";
5158 // break;
5159 default:
5160 goto die;
5161 }
5162 break;
5163 case 24:
5164 switch (sel) {
5165 case 0:
5166 /* EJTAG support */
5167 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5168 rn = "DEPC";
5169 break;
5170 default:
5171 goto die;
5172 }
5173 break;
5174 case 25:
5175 switch (sel) {
5176 case 0:
5177 gen_helper_mtc0_performance0(cpu_env, arg);
5178 rn = "Performance0";
5179 break;
5180 case 1:
5181 // gen_helper_mtc0_performance1(arg);
5182 rn = "Performance1";
5183 // break;
5184 case 2:
5185 // gen_helper_mtc0_performance2(arg);
5186 rn = "Performance2";
5187 // break;
5188 case 3:
5189 // gen_helper_mtc0_performance3(arg);
5190 rn = "Performance3";
5191 // break;
5192 case 4:
5193 // gen_helper_mtc0_performance4(arg);
5194 rn = "Performance4";
5195 // break;
5196 case 5:
5197 // gen_helper_mtc0_performance5(arg);
5198 rn = "Performance5";
5199 // break;
5200 case 6:
5201 // gen_helper_mtc0_performance6(arg);
5202 rn = "Performance6";
5203 // break;
5204 case 7:
5205 // gen_helper_mtc0_performance7(arg);
5206 rn = "Performance7";
5207 // break;
5208 default:
5209 goto die;
5210 }
5211 break;
5212 case 26:
5213 /* ignored */
5214 rn = "ECC";
5215 break;
5216 case 27:
5217 switch (sel) {
5218 case 0 ... 3:
5219 /* ignored */
5220 rn = "CacheErr";
5221 break;
5222 default:
5223 goto die;
5224 }
5225 break;
5226 case 28:
5227 switch (sel) {
5228 case 0:
5229 case 2:
5230 case 4:
5231 case 6:
5232 gen_helper_mtc0_taglo(cpu_env, arg);
5233 rn = "TagLo";
5234 break;
5235 case 1:
5236 case 3:
5237 case 5:
5238 case 7:
5239 gen_helper_mtc0_datalo(cpu_env, arg);
5240 rn = "DataLo";
5241 break;
5242 default:
5243 goto die;
5244 }
5245 break;
5246 case 29:
5247 switch (sel) {
5248 case 0:
5249 case 2:
5250 case 4:
5251 case 6:
5252 gen_helper_mtc0_taghi(cpu_env, arg);
5253 rn = "TagHi";
5254 break;
5255 case 1:
5256 case 3:
5257 case 5:
5258 case 7:
5259 gen_helper_mtc0_datahi(cpu_env, arg);
5260 rn = "DataHi";
5261 break;
5262 default:
5263 rn = "invalid sel";
5264 goto die;
5265 }
5266 break;
5267 case 30:
5268 switch (sel) {
5269 case 0:
5270 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5271 rn = "ErrorEPC";
5272 break;
5273 default:
5274 goto die;
5275 }
5276 break;
5277 case 31:
5278 switch (sel) {
5279 case 0:
5280 /* EJTAG support */
5281 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5282 rn = "DESAVE";
5283 break;
5284 default:
5285 goto die;
5286 }
5287 /* Stop translation as we may have switched the execution mode */
5288 ctx->bstate = BS_STOP;
5289 break;
5290 default:
5291 goto die;
5292 }
5293 (void)rn; /* avoid a compiler warning */
5294 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5295 /* For simplicity assume that all writes can cause interrupts. */
5296 if (use_icount) {
5297 gen_io_end();
5298 ctx->bstate = BS_STOP;
5299 }
5300 return;
5301
5302 die:
5303 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5304 generate_exception(ctx, EXCP_RI);
5305 }
5306
5307 #if defined(TARGET_MIPS64)
5308 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5309 {
5310 const char *rn = "invalid";
5311
5312 if (sel != 0)
5313 check_insn(env, ctx, ISA_MIPS64);
5314
5315 switch (reg) {
5316 case 0:
5317 switch (sel) {
5318 case 0:
5319 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5320 rn = "Index";
5321 break;
5322 case 1:
5323 check_insn(env, ctx, ASE_MT);
5324 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5325 rn = "MVPControl";
5326 break;
5327 case 2:
5328 check_insn(env, ctx, ASE_MT);
5329 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5330 rn = "MVPConf0";
5331 break;
5332 case 3:
5333 check_insn(env, ctx, ASE_MT);
5334 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5335 rn = "MVPConf1";
5336 break;
5337 default:
5338 goto die;
5339 }
5340 break;
5341 case 1:
5342 switch (sel) {
5343 case 0:
5344 gen_helper_mfc0_random(arg, cpu_env);
5345 rn = "Random";
5346 break;
5347 case 1:
5348 check_insn(env, ctx, ASE_MT);
5349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5350 rn = "VPEControl";
5351 break;
5352 case 2:
5353 check_insn(env, ctx, ASE_MT);
5354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5355 rn = "VPEConf0";
5356 break;
5357 case 3:
5358 check_insn(env, ctx, ASE_MT);
5359 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5360 rn = "VPEConf1";
5361 break;
5362 case 4:
5363 check_insn(env, ctx, ASE_MT);
5364 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5365 rn = "YQMask";
5366 break;
5367 case 5:
5368 check_insn(env, ctx, ASE_MT);
5369 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5370 rn = "VPESchedule";
5371 break;
5372 case 6:
5373 check_insn(env, ctx, ASE_MT);
5374 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5375 rn = "VPEScheFBack";
5376 break;
5377 case 7:
5378 check_insn(env, ctx, ASE_MT);
5379 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5380 rn = "VPEOpt";
5381 break;
5382 default:
5383 goto die;
5384 }
5385 break;
5386 case 2:
5387 switch (sel) {
5388 case 0:
5389 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5390 rn = "EntryLo0";
5391 break;
5392 case 1:
5393 check_insn(env, ctx, ASE_MT);
5394 gen_helper_mfc0_tcstatus(arg, cpu_env);
5395 rn = "TCStatus";
5396 break;
5397 case 2:
5398 check_insn(env, ctx, ASE_MT);
5399 gen_helper_mfc0_tcbind(arg, cpu_env);
5400 rn = "TCBind";
5401 break;
5402 case 3:
5403 check_insn(env, ctx, ASE_MT);
5404 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5405 rn = "TCRestart";
5406 break;
5407 case 4:
5408 check_insn(env, ctx, ASE_MT);
5409 gen_helper_dmfc0_tchalt(arg, cpu_env);
5410 rn = "TCHalt";
5411 break;
5412 case 5:
5413 check_insn(env, ctx, ASE_MT);
5414 gen_helper_dmfc0_tccontext(arg, cpu_env);
5415 rn = "TCContext";
5416 break;
5417 case 6:
5418 check_insn(env, ctx, ASE_MT);
5419 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5420 rn = "TCSchedule";
5421 break;
5422 case 7:
5423 check_insn(env, ctx, ASE_MT);
5424 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5425 rn = "TCScheFBack";
5426 break;
5427 default:
5428 goto die;
5429 }
5430 break;
5431 case 3:
5432 switch (sel) {
5433 case 0:
5434 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5435 rn = "EntryLo1";
5436 break;
5437 default:
5438 goto die;
5439 }
5440 break;
5441 case 4:
5442 switch (sel) {
5443 case 0:
5444 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5445 rn = "Context";
5446 break;
5447 case 1:
5448 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5449 rn = "ContextConfig";
5450 // break;
5451 default:
5452 goto die;
5453 }
5454 break;
5455 case 5:
5456 switch (sel) {
5457 case 0:
5458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5459 rn = "PageMask";
5460 break;
5461 case 1:
5462 check_insn(env, ctx, ISA_MIPS32R2);
5463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5464 rn = "PageGrain";
5465 break;
5466 default:
5467 goto die;
5468 }
5469 break;
5470 case 6:
5471 switch (sel) {
5472 case 0:
5473 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5474 rn = "Wired";
5475 break;
5476 case 1:
5477 check_insn(env, ctx, ISA_MIPS32R2);
5478 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5479 rn = "SRSConf0";
5480 break;
5481 case 2:
5482 check_insn(env, ctx, ISA_MIPS32R2);
5483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5484 rn = "SRSConf1";
5485 break;
5486 case 3:
5487 check_insn(env, ctx, ISA_MIPS32R2);
5488 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5489 rn = "SRSConf2";
5490 break;
5491 case 4:
5492 check_insn(env, ctx, ISA_MIPS32R2);
5493 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5494 rn = "SRSConf3";
5495 break;
5496 case 5:
5497 check_insn(env, ctx, ISA_MIPS32R2);
5498 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5499 rn = "SRSConf4";
5500 break;
5501 default:
5502 goto die;
5503 }
5504 break;
5505 case 7:
5506 switch (sel) {
5507 case 0:
5508 check_insn(env, ctx, ISA_MIPS32R2);
5509 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5510 rn = "HWREna";
5511 break;
5512 default:
5513 goto die;
5514 }
5515 break;
5516 case 8:
5517 switch (sel) {
5518 case 0:
5519 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5520 rn = "BadVAddr";
5521 break;
5522 default:
5523 goto die;
5524 }
5525 break;
5526 case 9:
5527 switch (sel) {
5528 case 0:
5529 /* Mark as an IO operation because we read the time. */
5530 if (use_icount)
5531 gen_io_start();
5532 gen_helper_mfc0_count(arg, cpu_env);
5533 if (use_icount) {
5534 gen_io_end();
5535 }
5536 /* Break the TB to be able to take timer interrupts immediately
5537 after reading count. */
5538 ctx->bstate = BS_STOP;
5539 rn = "Count";
5540 break;
5541 /* 6,7 are implementation dependent */
5542 default:
5543 goto die;
5544 }
5545 break;
5546 case 10:
5547 switch (sel) {
5548 case 0:
5549 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5550 rn = "EntryHi";
5551 break;
5552 default:
5553 goto die;
5554 }
5555 break;
5556 case 11:
5557 switch (sel) {
5558 case 0:
5559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5560 rn = "Compare";
5561 break;
5562 /* 6,7 are implementation dependent */
5563 default:
5564 goto die;
5565 }
5566 break;
5567 case 12:
5568 switch (sel) {
5569 case 0:
5570 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5571 rn = "Status";
5572 break;
5573 case 1:
5574 check_insn(env, ctx, ISA_MIPS32R2);
5575 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5576 rn = "IntCtl";
5577 break;
5578 case 2:
5579 check_insn(env, ctx, ISA_MIPS32R2);
5580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5581 rn = "SRSCtl";
5582 break;
5583 case 3:
5584 check_insn(env, ctx, ISA_MIPS32R2);
5585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5586 rn = "SRSMap";
5587 break;
5588 default:
5589 goto die;
5590 }
5591 break;
5592 case 13:
5593 switch (sel) {
5594 case 0:
5595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5596 rn = "Cause";
5597 break;
5598 default:
5599 goto die;
5600 }
5601 break;
5602 case 14:
5603 switch (sel) {
5604 case 0:
5605 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5606 rn = "EPC";
5607 break;
5608 default:
5609 goto die;
5610 }
5611 break;
5612 case 15:
5613 switch (sel) {
5614 case 0:
5615 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5616 rn = "PRid";
5617 break;
5618 case 1:
5619 check_insn(env, ctx, ISA_MIPS32R2);
5620 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5621 rn = "EBase";
5622 break;
5623 default:
5624 goto die;
5625 }
5626 break;
5627 case 16:
5628 switch (sel) {
5629 case 0:
5630 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5631 rn = "Config";
5632 break;
5633 case 1:
5634 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5635 rn = "Config1";
5636 break;
5637 case 2:
5638 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5639 rn = "Config2";
5640 break;
5641 case 3:
5642 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5643 rn = "Config3";
5644 break;
5645 /* 6,7 are implementation dependent */
5646 case 6:
5647 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5648 rn = "Config6";
5649 break;
5650 case 7:
5651 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5652 rn = "Config7";
5653 break;
5654 default:
5655 goto die;
5656 }
5657 break;
5658 case 17:
5659 switch (sel) {
5660 case 0:
5661 gen_helper_dmfc0_lladdr(arg, cpu_env);
5662 rn = "LLAddr";
5663 break;
5664 default:
5665 goto die;
5666 }
5667 break;
5668 case 18:
5669 switch (sel) {
5670 case 0 ... 7:
5671 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5672 rn = "WatchLo";
5673 break;
5674 default:
5675 goto die;
5676 }
5677 break;
5678 case 19:
5679 switch (sel) {
5680 case 0 ... 7:
5681 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5682 rn = "WatchHi";
5683 break;
5684 default:
5685 goto die;
5686 }
5687 break;
5688 case 20:
5689 switch (sel) {
5690 case 0:
5691 check_insn(env, ctx, ISA_MIPS3);
5692 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5693 rn = "XContext";
5694 break;
5695 default:
5696 goto die;
5697 }
5698 break;
5699 case 21:
5700 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5701 switch (sel) {
5702 case 0:
5703 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5704 rn = "Framemask";
5705 break;
5706 default:
5707 goto die;
5708 }
5709 break;
5710 case 22:
5711 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5712 rn = "'Diagnostic"; /* implementation dependent */
5713 break;
5714 case 23:
5715 switch (sel) {
5716 case 0:
5717 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5718 rn = "Debug";
5719 break;
5720 case 1:
5721 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5722 rn = "TraceControl";
5723 // break;
5724 case 2:
5725 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5726 rn = "TraceControl2";
5727 // break;
5728 case 3:
5729 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5730 rn = "UserTraceData";
5731 // break;
5732 case 4:
5733 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5734 rn = "TraceBPC";
5735 // break;
5736 default:
5737 goto die;
5738 }
5739 break;
5740 case 24:
5741 switch (sel) {
5742 case 0:
5743 /* EJTAG support */
5744 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5745 rn = "DEPC";
5746 break;
5747 default:
5748 goto die;
5749 }
5750 break;
5751 case 25:
5752 switch (sel) {
5753 case 0:
5754 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5755 rn = "Performance0";
5756 break;
5757 case 1:
5758 // gen_helper_dmfc0_performance1(arg);
5759 rn = "Performance1";
5760 // break;
5761 case 2:
5762 // gen_helper_dmfc0_performance2(arg);
5763 rn = "Performance2";
5764 // break;
5765 case 3:
5766 // gen_helper_dmfc0_performance3(arg);
5767 rn = "Performance3";
5768 // break;
5769 case 4:
5770 // gen_helper_dmfc0_performance4(arg);
5771 rn = "Performance4";
5772 // break;
5773 case 5:
5774 // gen_helper_dmfc0_performance5(arg);
5775 rn = "Performance5";
5776 // break;
5777 case 6:
5778 // gen_helper_dmfc0_performance6(arg);
5779 rn = "Performance6";
5780 // break;
5781 case 7:
5782 // gen_helper_dmfc0_performance7(arg);
5783 rn = "Performance7";
5784 // break;
5785 default:
5786 goto die;
5787 }
5788 break;
5789 case 26:
5790 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5791 rn = "ECC";
5792 break;
5793 case 27:
5794 switch (sel) {
5795 /* ignored */
5796 case 0 ... 3:
5797 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5798 rn = "CacheErr";
5799 break;
5800 default:
5801 goto die;
5802 }
5803 break;
5804 case 28:
5805 switch (sel) {
5806 case 0:
5807 case 2:
5808 case 4:
5809 case 6:
5810 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5811 rn = "TagLo";
5812 break;
5813 case 1:
5814 case 3:
5815 case 5:
5816 case 7:
5817 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5818 rn = "DataLo";
5819 break;
5820 default:
5821 goto die;
5822 }
5823 break;
5824 case 29:
5825 switch (sel) {
5826 case 0:
5827 case 2:
5828 case 4:
5829 case 6:
5830 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5831 rn = "TagHi";
5832 break;
5833 case 1:
5834 case 3:
5835 case 5:
5836 case 7:
5837 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5838 rn = "DataHi";
5839 break;
5840 default:
5841 goto die;
5842 }
5843 break;
5844 case 30:
5845 switch (sel) {
5846 case 0:
5847 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5848 rn = "ErrorEPC";
5849 break;
5850 default:
5851 goto die;
5852 }
5853 break;
5854 case 31:
5855 switch (sel) {
5856 case 0:
5857 /* EJTAG support */
5858 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5859 rn = "DESAVE";
5860 break;
5861 default:
5862 goto die;
5863 }
5864 break;
5865 default:
5866 goto die;
5867 }
5868 (void)rn; /* avoid a compiler warning */
5869 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5870 return;
5871
5872 die:
5873 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5874 generate_exception(ctx, EXCP_RI);
5875 }
5876
5877 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5878 {
5879 const char *rn = "invalid";
5880
5881 if (sel != 0)
5882 check_insn(env, ctx, ISA_MIPS64);
5883
5884 if (use_icount)
5885 gen_io_start();
5886
5887 switch (reg) {
5888 case 0:
5889 switch (sel) {
5890 case 0:
5891 gen_helper_mtc0_index(cpu_env, arg);
5892 rn = "Index";
5893 break;
5894 case 1:
5895 check_insn(env, ctx, ASE_MT);
5896 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5897 rn = "MVPControl";
5898 break;
5899 case 2:
5900 check_insn(env, ctx, ASE_MT);
5901 /* ignored */
5902 rn = "MVPConf0";
5903 break;
5904 case 3:
5905 check_insn(env, ctx, ASE_MT);
5906 /* ignored */
5907 rn = "MVPConf1";
5908 break;
5909 default:
5910 goto die;
5911 }
5912 break;
5913 case 1:
5914 switch (sel) {
5915 case 0:
5916 /* ignored */
5917 rn = "Random";
5918 break;
5919 case 1:
5920 check_insn(env, ctx, ASE_MT);
5921 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5922 rn = "VPEControl";
5923 break;
5924 case 2:
5925 check_insn(env, ctx, ASE_MT);
5926 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5927 rn = "VPEConf0";
5928 break;
5929 case 3:
5930 check_insn(env, ctx, ASE_MT);
5931 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5932 rn = "VPEConf1";
5933 break;
5934 case 4:
5935 check_insn(env, ctx, ASE_MT);
5936 gen_helper_mtc0_yqmask(cpu_env, arg);
5937 rn = "YQMask";
5938 break;
5939 case 5:
5940 check_insn(env, ctx, ASE_MT);
5941 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5942 rn = "VPESchedule";
5943 break;
5944 case 6:
5945 check_insn(env, ctx, ASE_MT);
5946 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5947 rn = "VPEScheFBack";
5948 break;
5949 case 7:
5950 check_insn(env, ctx, ASE_MT);
5951 gen_helper_mtc0_vpeopt(cpu_env, arg);
5952 rn = "VPEOpt";
5953 break;
5954 default:
5955 goto die;
5956 }
5957 break;
5958 case 2:
5959 switch (sel) {
5960 case 0:
5961 gen_helper_mtc0_entrylo0(cpu_env, arg);
5962 rn = "EntryLo0";
5963 break;
5964 case 1:
5965 check_insn(env, ctx, ASE_MT);
5966 gen_helper_mtc0_tcstatus(cpu_env, arg);
5967 rn = "TCStatus";
5968 break;
5969 case 2:
5970 check_insn(env, ctx, ASE_MT);
5971 gen_helper_mtc0_tcbind(cpu_env, arg);
5972 rn = "TCBind";
5973 break;
5974 case 3:
5975 check_insn(env, ctx, ASE_MT);
5976 gen_helper_mtc0_tcrestart(cpu_env, arg);
5977 rn = "TCRestart";
5978 break;
5979 case 4:
5980 check_insn(env, ctx, ASE_MT);
5981 gen_helper_mtc0_tchalt(cpu_env, arg);
5982 rn = "TCHalt";
5983 break;
5984 case 5:
5985 check_insn(env, ctx, ASE_MT);
5986 gen_helper_mtc0_tccontext(cpu_env, arg);
5987 rn = "TCContext";
5988 break;
5989 case 6:
5990 check_insn(env, ctx, ASE_MT);
5991 gen_helper_mtc0_tcschedule(cpu_env, arg);
5992 rn = "TCSchedule";
5993 break;
5994 case 7:
5995 check_insn(env, ctx, ASE_MT);
5996 gen_helper_mtc0_tcschefback(cpu_env, arg);
5997 rn = "TCScheFBack";
5998 break;
5999 default:
6000 goto die;
6001 }
6002 break;
6003 case 3:
6004 switch (sel) {
6005 case 0:
6006 gen_helper_mtc0_entrylo1(cpu_env, arg);
6007 rn = "EntryLo1";
6008 break;
6009 default:
6010 goto die;
6011 }
6012 break;
6013 case 4:
6014 switch (sel) {
6015 case 0:
6016 gen_helper_mtc0_context(cpu_env, arg);
6017 rn = "Context";
6018 break;
6019 case 1:
6020 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6021 rn = "ContextConfig";
6022 // break;
6023 default:
6024 goto die;
6025 }
6026 break;
6027 case 5:
6028 switch (sel) {
6029 case 0:
6030 gen_helper_mtc0_pagemask(cpu_env, arg);
6031 rn = "PageMask";
6032 break;
6033 case 1:
6034 check_insn(env, ctx, ISA_MIPS32R2);
6035 gen_helper_mtc0_pagegrain(cpu_env, arg);
6036 rn = "PageGrain";
6037 break;
6038 default:
6039 goto die;
6040 }
6041 break;
6042 case 6:
6043 switch (sel) {
6044 case 0:
6045 gen_helper_mtc0_wired(cpu_env, arg);
6046 rn = "Wired";
6047 break;
6048 case 1:
6049 check_insn(env, ctx, ISA_MIPS32R2);
6050 gen_helper_mtc0_srsconf0(cpu_env, arg);
6051 rn = "SRSConf0";
6052 break;
6053 case 2:
6054 check_insn(env, ctx, ISA_MIPS32R2);
6055 gen_helper_mtc0_srsconf1(cpu_env, arg);
6056 rn = "SRSConf1";
6057 break;
6058 case 3:
6059 check_insn(env, ctx, ISA_MIPS32R2);
6060 gen_helper_mtc0_srsconf2(cpu_env, arg);
6061 rn = "SRSConf2";
6062 break;
6063 case 4:
6064 check_insn(env, ctx, ISA_MIPS32R2);
6065 gen_helper_mtc0_srsconf3(cpu_env, arg);
6066 rn = "SRSConf3";
6067 break;
6068 case 5:
6069 check_insn(env, ctx, ISA_MIPS32R2);
6070 gen_helper_mtc0_srsconf4(cpu_env, arg);
6071 rn = "SRSConf4";
6072 break;
6073 default:
6074 goto die;
6075 }
6076 break;
6077 case 7:
6078 switch (sel) {
6079 case 0:
6080 check_insn(env, ctx, ISA_MIPS32R2);
6081 gen_helper_mtc0_hwrena(cpu_env, arg);
6082 rn = "HWREna";
6083 break;
6084 default:
6085 goto die;
6086 }
6087 break;
6088 case 8:
6089 /* ignored */
6090 rn = "BadVAddr";
6091 break;
6092 case 9:
6093 switch (sel) {
6094 case 0:
6095 gen_helper_mtc0_count(cpu_env, arg);
6096 rn = "Count";
6097 break;
6098 /* 6,7 are implementation dependent */
6099 default:
6100 goto die;
6101 }
6102 /* Stop translation as we may have switched the execution mode */
6103 ctx->bstate = BS_STOP;
6104 break;
6105 case 10:
6106 switch (sel) {
6107 case 0:
6108 gen_helper_mtc0_entryhi(cpu_env, arg);
6109 rn = "EntryHi";
6110 break;
6111 default:
6112 goto die;
6113 }
6114 break;
6115 case 11:
6116 switch (sel) {
6117 case 0:
6118 gen_helper_mtc0_compare(cpu_env, arg);
6119 rn = "Compare";
6120 break;
6121 /* 6,7 are implementation dependent */
6122 default:
6123 goto die;
6124 }
6125 /* Stop translation as we may have switched the execution mode */
6126 ctx->bstate = BS_STOP;
6127 break;
6128 case 12:
6129 switch (sel) {
6130 case 0:
6131 save_cpu_state(ctx, 1);
6132 gen_helper_mtc0_status(cpu_env, arg);
6133 /* BS_STOP isn't good enough here, hflags may have changed. */
6134 gen_save_pc(ctx->pc + 4);
6135 ctx->bstate = BS_EXCP;
6136 rn = "Status";
6137 break;
6138 case 1:
6139 check_insn(env, ctx, ISA_MIPS32R2);
6140 gen_helper_mtc0_intctl(cpu_env, arg);
6141 /* Stop translation as we may have switched the execution mode */
6142 ctx->bstate = BS_STOP;
6143 rn = "IntCtl";
6144 break;
6145 case 2:
6146 check_insn(env, ctx, ISA_MIPS32R2);
6147 gen_helper_mtc0_srsctl(cpu_env, arg);
6148 /* Stop translation as we may have switched the execution mode */
6149 ctx->bstate = BS_STOP;
6150 rn = "SRSCtl";
6151 break;
6152 case 3:
6153 check_insn(env, ctx, ISA_MIPS32R2);
6154 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6155 /* Stop translation as we may have switched the execution mode */
6156 ctx->bstate = BS_STOP;
6157 rn = "SRSMap";
6158 break;
6159 default:
6160 goto die;
6161 }
6162 break;
6163 case 13:
6164 switch (sel) {
6165 case 0:
6166 save_cpu_state(ctx, 1);
6167 /* Mark as an IO operation because we may trigger a software
6168 interrupt. */
6169 if (use_icount) {
6170 gen_io_start();
6171 }
6172 gen_helper_mtc0_cause(cpu_env, arg);
6173 if (use_icount) {
6174 gen_io_end();
6175 }
6176 /* Stop translation as we may have triggered an intetrupt */
6177 ctx->bstate = BS_STOP;
6178 rn = "Cause";
6179 break;
6180 default:
6181 goto die;
6182 }
6183 break;
6184 case 14:
6185 switch (sel) {
6186 case 0:
6187 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6188 rn = "EPC";
6189 break;
6190 default:
6191 goto die;
6192 }
6193 break;
6194 case 15:
6195 switch (sel) {
6196 case 0:
6197 /* ignored */
6198 rn = "PRid";
6199 break;
6200 case 1:
6201 check_insn(env, ctx, ISA_MIPS32R2);
6202 gen_helper_mtc0_ebase(cpu_env, arg);
6203 rn = "EBase";
6204 break;
6205 default:
6206 goto die;
6207 }
6208 break;
6209 case 16:
6210 switch (sel) {
6211 case 0:
6212 gen_helper_mtc0_config0(cpu_env, arg);
6213 rn = "Config";
6214 /* Stop translation as we may have switched the execution mode */
6215 ctx->bstate = BS_STOP;
6216 break;
6217 case 1:
6218 /* ignored, read only */
6219 rn = "Config1";
6220 break;
6221 case 2:
6222 gen_helper_mtc0_config2(cpu_env, arg);
6223 rn = "Config2";
6224 /* Stop translation as we may have switched the execution mode */
6225 ctx->bstate = BS_STOP;
6226 break;
6227 case 3:
6228 /* ignored */
6229 rn = "Config3";
6230 break;
6231 /* 6,7 are implementation dependent */
6232 default:
6233 rn = "Invalid config selector";
6234 goto die;
6235 }
6236 break;
6237 case 17:
6238 switch (sel) {
6239 case 0:
6240 gen_helper_mtc0_lladdr(cpu_env, arg);
6241 rn = "LLAddr";
6242 break;
6243 default:
6244 goto die;
6245 }
6246 break;
6247 case 18:
6248 switch (sel) {
6249 case 0 ... 7:
6250 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6251 rn = "WatchLo";
6252 break;
6253 default:
6254 goto die;
6255 }
6256 break;
6257 case 19:
6258 switch (sel) {
6259 case 0 ... 7:
6260 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6261 rn = "WatchHi";
6262 break;
6263 default:
6264 goto die;
6265 }
6266 break;
6267 case 20:
6268 switch (sel) {
6269 case 0:
6270 check_insn(env, ctx, ISA_MIPS3);
6271 gen_helper_mtc0_xcontext(cpu_env, arg);
6272 rn = "XContext";
6273 break;
6274 default:
6275 goto die;
6276 }
6277 break;
6278 case 21:
6279 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6280 switch (sel) {
6281 case 0:
6282 gen_helper_mtc0_framemask(cpu_env, arg);
6283 rn = "Framemask";
6284 break;
6285 default:
6286 goto die;
6287 }
6288 break;
6289 case 22:
6290 /* ignored */
6291 rn = "Diagnostic"; /* implementation dependent */
6292 break;
6293 case 23:
6294 switch (sel) {
6295 case 0:
6296 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6297 /* BS_STOP isn't good enough here, hflags may have changed. */
6298 gen_save_pc(ctx->pc + 4);
6299 ctx->bstate = BS_EXCP;
6300 rn = "Debug";
6301 break;
6302 case 1:
6303 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6304 /* Stop translation as we may have switched the execution mode */
6305 ctx->bstate = BS_STOP;
6306 rn = "TraceControl";
6307 // break;
6308 case 2:
6309 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6310 /* Stop translation as we may have switched the execution mode */
6311 ctx->bstate = BS_STOP;
6312 rn = "TraceControl2";
6313 // break;
6314 case 3:
6315 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6316 /* Stop translation as we may have switched the execution mode */
6317 ctx->bstate = BS_STOP;
6318 rn = "UserTraceData";
6319 // break;
6320 case 4:
6321 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6322 /* Stop translation as we may have switched the execution mode */
6323 ctx->bstate = BS_STOP;
6324 rn = "TraceBPC";
6325 // break;
6326 default:
6327 goto die;
6328 }
6329 break;
6330 case 24:
6331 switch (sel) {
6332 case 0:
6333 /* EJTAG support */
6334 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6335 rn = "DEPC";
6336 break;
6337 default:
6338 goto die;
6339 }
6340 break;
6341 case 25:
6342 switch (sel) {
6343 case 0:
6344 gen_helper_mtc0_performance0(cpu_env, arg);
6345 rn = "Performance0";
6346 break;
6347 case 1:
6348 // gen_helper_mtc0_performance1(cpu_env, arg);
6349 rn = "Performance1";
6350 // break;
6351 case 2:
6352 // gen_helper_mtc0_performance2(cpu_env, arg);
6353 rn = "Performance2";
6354 // break;
6355 case 3:
6356 // gen_helper_mtc0_performance3(cpu_env, arg);
6357 rn = "Performance3";
6358 // break;
6359 case 4:
6360 // gen_helper_mtc0_performance4(cpu_env, arg);
6361 rn = "Performance4";
6362 // break;
6363 case 5:
6364 // gen_helper_mtc0_performance5(cpu_env, arg);
6365 rn = "Performance5";
6366 // break;
6367 case 6:
6368 // gen_helper_mtc0_performance6(cpu_env, arg);
6369 rn = "Performance6";
6370 // break;
6371 case 7:
6372 // gen_helper_mtc0_performance7(cpu_env, arg);
6373 rn = "Performance7";
6374 // break;
6375 default:
6376 goto die;
6377 }
6378 break;
6379 case 26:
6380 /* ignored */
6381 rn = "ECC";
6382 break;
6383 case 27:
6384 switch (sel) {
6385 case 0 ... 3:
6386 /* ignored */
6387 rn = "CacheErr";
6388 break;
6389 default:
6390 goto die;
6391 }
6392 break;
6393 case 28:
6394 switch (sel) {
6395 case 0:
6396 case 2:
6397 case 4:
6398 case 6:
6399 gen_helper_mtc0_taglo(cpu_env, arg);
6400 rn = "TagLo";
6401 break;
6402 case 1:
6403 case 3:
6404 case 5:
6405 case 7:
6406 gen_helper_mtc0_datalo(cpu_env, arg);
6407 rn = "DataLo";
6408 break;
6409 default:
6410 goto die;
6411 }
6412 break;
6413 case 29:
6414 switch (sel) {
6415 case 0:
6416 case 2:
6417 case 4:
6418 case 6:
6419 gen_helper_mtc0_taghi(cpu_env, arg);
6420 rn = "TagHi";
6421 break;
6422 case 1:
6423 case 3:
6424 case 5:
6425 case 7:
6426 gen_helper_mtc0_datahi(cpu_env, arg);
6427 rn = "DataHi";
6428 break;
6429 default:
6430 rn = "invalid sel";
6431 goto die;
6432 }
6433 break;
6434 case 30:
6435 switch (sel) {
6436 case 0:
6437 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6438 rn = "ErrorEPC";
6439 break;
6440 default:
6441 goto die;
6442 }
6443 break;
6444 case 31:
6445 switch (sel) {
6446 case 0:
6447 /* EJTAG support */
6448 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6449 rn = "DESAVE";
6450 break;
6451 default:
6452 goto die;
6453 }
6454 /* Stop translation as we may have switched the execution mode */
6455 ctx->bstate = BS_STOP;
6456 break;
6457 default:
6458 goto die;
6459 }
6460 (void)rn; /* avoid a compiler warning */
6461 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6462 /* For simplicity assume that all writes can cause interrupts. */
6463 if (use_icount) {
6464 gen_io_end();
6465 ctx->bstate = BS_STOP;
6466 }
6467 return;
6468
6469 die:
6470 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6471 generate_exception(ctx, EXCP_RI);
6472 }
6473 #endif /* TARGET_MIPS64 */
6474
6475 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6476 int u, int sel, int h)
6477 {
6478 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6479 TCGv t0 = tcg_temp_local_new();
6480
6481 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6482 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6483 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6484 tcg_gen_movi_tl(t0, -1);
6485 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6486 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6487 tcg_gen_movi_tl(t0, -1);
6488 else if (u == 0) {
6489 switch (rt) {
6490 case 1:
6491 switch (sel) {
6492 case 1:
6493 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6494 break;
6495 case 2:
6496 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6497 break;
6498 default:
6499 goto die;
6500 break;
6501 }
6502 break;
6503 case 2:
6504 switch (sel) {
6505 case 1:
6506 gen_helper_mftc0_tcstatus(t0, cpu_env);
6507 break;
6508 case 2:
6509 gen_helper_mftc0_tcbind(t0, cpu_env);
6510 break;
6511 case 3:
6512 gen_helper_mftc0_tcrestart(t0, cpu_env);
6513 break;
6514 case 4:
6515 gen_helper_mftc0_tchalt(t0, cpu_env);
6516 break;
6517 case 5:
6518 gen_helper_mftc0_tccontext(t0, cpu_env);
6519 break;
6520 case 6:
6521 gen_helper_mftc0_tcschedule(t0, cpu_env);
6522 break;
6523 case 7:
6524 gen_helper_mftc0_tcschefback(t0, cpu_env);
6525 break;
6526 default:
6527 gen_mfc0(env, ctx, t0, rt, sel);
6528 break;
6529 }
6530 break;
6531 case 10:
6532 switch (sel) {
6533 case 0:
6534 gen_helper_mftc0_entryhi(t0, cpu_env);
6535 break;
6536 default:
6537 gen_mfc0(env, ctx, t0, rt, sel);
6538 break;
6539 }
6540 case 12:
6541 switch (sel) {
6542 case 0:
6543 gen_helper_mftc0_status(t0, cpu_env);
6544 break;
6545 default:
6546 gen_mfc0(env, ctx, t0, rt, sel);
6547 break;
6548 }
6549 case 13:
6550 switch (sel) {
6551 case 0:
6552 gen_helper_mftc0_cause(t0, cpu_env);
6553 break;
6554 default:
6555 goto die;
6556 break;
6557 }
6558 break;
6559 case 14:
6560 switch (sel) {
6561 case 0:
6562 gen_helper_mftc0_epc(t0, cpu_env);
6563 break;
6564 default:
6565 goto die;
6566 break;
6567 }
6568 break;
6569 case 15:
6570 switch (sel) {
6571 case 1:
6572 gen_helper_mftc0_ebase(t0, cpu_env);
6573 break;
6574 default:
6575 goto die;
6576 break;
6577 }
6578 break;
6579 case 16:
6580 switch (sel) {
6581 case 0 ... 7:
6582 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6583 break;
6584 default:
6585 goto die;
6586 break;
6587 }
6588 break;
6589 case 23:
6590 switch (sel) {
6591 case 0:
6592 gen_helper_mftc0_debug(t0, cpu_env);
6593 break;
6594 default:
6595 gen_mfc0(env, ctx, t0, rt, sel);
6596 break;
6597 }
6598 break;
6599 default:
6600 gen_mfc0(env, ctx, t0, rt, sel);
6601 }
6602 } else switch (sel) {
6603 /* GPR registers. */
6604 case 0:
6605 gen_helper_1e0i(mftgpr, t0, rt);
6606 break;
6607 /* Auxiliary CPU registers */
6608 case 1:
6609 switch (rt) {
6610 case 0:
6611 gen_helper_1e0i(mftlo, t0, 0);
6612 break;
6613 case 1:
6614 gen_helper_1e0i(mfthi, t0, 0);
6615 break;
6616 case 2:
6617 gen_helper_1e0i(mftacx, t0, 0);
6618 break;
6619 case 4:
6620 gen_helper_1e0i(mftlo, t0, 1);
6621 break;
6622 case 5:
6623 gen_helper_1e0i(mfthi, t0, 1);
6624 break;
6625 case 6:
6626 gen_helper_1e0i(mftacx, t0, 1);
6627 break;
6628 case 8:
6629 gen_helper_1e0i(mftlo, t0, 2);
6630 break;
6631 case 9:
6632 gen_helper_1e0i(mfthi, t0, 2);
6633 break;
6634 case 10:
6635 gen_helper_1e0i(mftacx, t0, 2);
6636 break;
6637 case 12:
6638 gen_helper_1e0i(mftlo, t0, 3);
6639 break;
6640 case 13:
6641 gen_helper_1e0i(mfthi, t0, 3);
6642 break;
6643 case 14:
6644 gen_helper_1e0i(mftacx, t0, 3);
6645 break;
6646 case 16:
6647 gen_helper_mftdsp(t0, cpu_env);
6648 break;
6649 default:
6650 goto die;
6651 }
6652 break;
6653 /* Floating point (COP1). */
6654 case 2:
6655 /* XXX: For now we support only a single FPU context. */
6656 if (h == 0) {
6657 TCGv_i32 fp0 = tcg_temp_new_i32();
6658
6659 gen_load_fpr32(fp0, rt);
6660 tcg_gen_ext_i32_tl(t0, fp0);
6661 tcg_temp_free_i32(fp0);
6662 } else {
6663 TCGv_i32 fp0 = tcg_temp_new_i32();
6664
6665 gen_load_fpr32h(fp0, rt);
6666 tcg_gen_ext_i32_tl(t0, fp0);
6667 tcg_temp_free_i32(fp0);
6668 }
6669 break;
6670 case 3:
6671 /* XXX: For now we support only a single FPU context. */
6672 gen_helper_1e0i(cfc1, t0, rt);
6673 break;
6674 /* COP2: Not implemented. */
6675 case 4:
6676 case 5:
6677 /* fall through */
6678 default:
6679 goto die;
6680 }
6681 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6682 gen_store_gpr(t0, rd);
6683 tcg_temp_free(t0);
6684 return;
6685
6686 die:
6687 tcg_temp_free(t0);
6688 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6689 generate_exception(ctx, EXCP_RI);
6690 }
6691
6692 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6693 int u, int sel, int h)
6694 {
6695 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6696 TCGv t0 = tcg_temp_local_new();
6697
6698 gen_load_gpr(t0, rt);
6699 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6700 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6701 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6702 /* NOP */ ;
6703 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6704 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6705 /* NOP */ ;
6706 else if (u == 0) {
6707 switch (rd) {
6708 case 1:
6709 switch (sel) {
6710 case 1:
6711 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6712 break;
6713 case 2:
6714 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6715 break;
6716 default:
6717 goto die;
6718 break;
6719 }
6720 break;
6721 case 2:
6722 switch (sel) {
6723 case 1:
6724 gen_helper_mttc0_tcstatus(cpu_env, t0);
6725 break;
6726 case 2:
6727 gen_helper_mttc0_tcbind(cpu_env, t0);
6728 break;
6729 case 3:
6730 gen_helper_mttc0_tcrestart(cpu_env, t0);
6731 break;
6732 case 4:
6733 gen_helper_mttc0_tchalt(cpu_env, t0);
6734 break;
6735 case 5:
6736 gen_helper_mttc0_tccontext(cpu_env, t0);
6737 break;
6738 case 6:
6739 gen_helper_mttc0_tcschedule(cpu_env, t0);
6740 break;
6741 case 7:
6742 gen_helper_mttc0_tcschefback(cpu_env, t0);
6743 break;
6744 default:
6745 gen_mtc0(env, ctx, t0, rd, sel);
6746 break;
6747 }
6748 break;
6749 case 10:
6750 switch (sel) {
6751 case 0:
6752 gen_helper_mttc0_entryhi(cpu_env, t0);
6753 break;
6754 default:
6755 gen_mtc0(env, ctx, t0, rd, sel);
6756 break;
6757 }
6758 case 12:
6759 switch (sel) {
6760 case 0:
6761 gen_helper_mttc0_status(cpu_env, t0);
6762 break;
6763 default:
6764 gen_mtc0(env, ctx, t0, rd, sel);
6765 break;
6766 }
6767 case 13:
6768 switch (sel) {
6769 case 0:
6770 gen_helper_mttc0_cause(cpu_env, t0);
6771 break;
6772 default:
6773 goto die;
6774 break;
6775 }
6776 break;
6777 case 15:
6778 switch (sel) {
6779 case 1:
6780 gen_helper_mttc0_ebase(cpu_env, t0);
6781 break;
6782 default:
6783 goto die;
6784 break;
6785 }
6786 break;
6787 case 23:
6788 switch (sel) {
6789 case 0:
6790 gen_helper_mttc0_debug(cpu_env, t0);
6791 break;
6792 default:
6793 gen_mtc0(env, ctx, t0, rd, sel);
6794 break;
6795 }
6796 break;
6797 default:
6798 gen_mtc0(env, ctx, t0, rd, sel);
6799 }
6800 } else switch (sel) {
6801 /* GPR registers. */
6802 case 0:
6803 gen_helper_0e1i(mttgpr, t0, rd);
6804 break;
6805 /* Auxiliary CPU registers */
6806 case 1:
6807 switch (rd) {
6808 case 0:
6809 gen_helper_0e1i(mttlo, t0, 0);
6810 break;
6811 case 1:
6812 gen_helper_0e1i(mtthi, t0, 0);
6813 break;
6814 case 2:
6815 gen_helper_0e1i(mttacx, t0, 0);
6816 break;
6817 case 4:
6818 gen_helper_0e1i(mttlo, t0, 1);
6819 break;
6820 case 5:
6821 gen_helper_0e1i(mtthi, t0, 1);
6822 break;
6823 case 6:
6824 gen_helper_0e1i(mttacx, t0, 1);
6825 break;
6826 case 8:
6827 gen_helper_0e1i(mttlo, t0, 2);
6828 break;
6829 case 9:
6830 gen_helper_0e1i(mtthi, t0, 2);
6831 break;
6832 case 10:
6833 gen_helper_0e1i(mttacx, t0, 2);
6834 break;
6835 case 12:
6836 gen_helper_0e1i(mttlo, t0, 3);
6837 break;
6838 case 13:
6839 gen_helper_0e1i(mtthi, t0, 3);
6840 break;
6841 case 14:
6842 gen_helper_0e1i(mttacx, t0, 3);
6843 break;
6844 case 16:
6845 gen_helper_mttdsp(cpu_env, t0);
6846 break;
6847 default:
6848 goto die;
6849 }
6850 break;
6851 /* Floating point (COP1). */
6852 case 2:
6853 /* XXX: For now we support only a single FPU context. */
6854 if (h == 0) {
6855 TCGv_i32 fp0 = tcg_temp_new_i32();
6856
6857 tcg_gen_trunc_tl_i32(fp0, t0);
6858 gen_store_fpr32(fp0, rd);
6859 tcg_temp_free_i32(fp0);
6860 } else {
6861 TCGv_i32 fp0 = tcg_temp_new_i32();
6862
6863 tcg_gen_trunc_tl_i32(fp0, t0);
6864 gen_store_fpr32h(fp0, rd);
6865 tcg_temp_free_i32(fp0);
6866 }
6867 break;
6868 case 3:
6869 /* XXX: For now we support only a single FPU context. */
6870 gen_helper_0e1i(ctc1, t0, rd);
6871 break;
6872 /* COP2: Not implemented. */
6873 case 4:
6874 case 5:
6875 /* fall through */
6876 default:
6877 goto die;
6878 }
6879 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6880 tcg_temp_free(t0);
6881 return;
6882
6883 die:
6884 tcg_temp_free(t0);
6885 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6886 generate_exception(ctx, EXCP_RI);
6887 }
6888
6889 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6890 {
6891 const char *opn = "ldst";
6892
6893 check_cp0_enabled(ctx);
6894 switch (opc) {
6895 case OPC_MFC0:
6896 if (rt == 0) {
6897 /* Treat as NOP. */
6898 return;
6899 }
6900 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6901 opn = "mfc0";
6902 break;
6903 case OPC_MTC0:
6904 {
6905 TCGv t0 = tcg_temp_new();
6906
6907 gen_load_gpr(t0, rt);
6908 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6909 tcg_temp_free(t0);
6910 }
6911 opn = "mtc0";
6912 break;
6913 #if defined(TARGET_MIPS64)
6914 case OPC_DMFC0:
6915 check_insn(env, ctx, ISA_MIPS3);
6916 if (rt == 0) {
6917 /* Treat as NOP. */
6918 return;
6919 }
6920 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6921 opn = "dmfc0";
6922 break;
6923 case OPC_DMTC0:
6924 check_insn(env, ctx, ISA_MIPS3);
6925 {
6926 TCGv t0 = tcg_temp_new();
6927
6928 gen_load_gpr(t0, rt);
6929 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6930 tcg_temp_free(t0);
6931 }
6932 opn = "dmtc0";
6933 break;
6934 #endif
6935 case OPC_MFTR:
6936 check_insn(env, ctx, ASE_MT);
6937 if (rd == 0) {
6938 /* Treat as NOP. */
6939 return;
6940 }
6941 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6942 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6943 opn = "mftr";
6944 break;
6945 case OPC_MTTR:
6946 check_insn(env, ctx, ASE_MT);
6947 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6948 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6949 opn = "mttr";
6950 break;
6951 case OPC_TLBWI:
6952 opn = "tlbwi";
6953 if (!env->tlb->helper_tlbwi)
6954 goto die;
6955 gen_helper_tlbwi(cpu_env);
6956 break;
6957 case OPC_TLBWR:
6958 opn = "tlbwr";
6959 if (!env->tlb->helper_tlbwr)
6960 goto die;
6961 gen_helper_tlbwr(cpu_env);
6962 break;
6963 case OPC_TLBP:
6964 opn = "tlbp";
6965 if (!env->tlb->helper_tlbp)
6966 goto die;
6967 gen_helper_tlbp(cpu_env);
6968 break;
6969 case OPC_TLBR:
6970 opn = "tlbr";
6971 if (!env->tlb->helper_tlbr)
6972 goto die;
6973 gen_helper_tlbr(cpu_env);
6974 break;
6975 case OPC_ERET:
6976 opn = "eret";
6977 check_insn(env, ctx, ISA_MIPS2);
6978 gen_helper_eret(cpu_env);
6979 ctx->bstate = BS_EXCP;
6980 break;
6981 case OPC_DERET:
6982 opn = "deret";
6983 check_insn(env, ctx, ISA_MIPS32);
6984 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6985 MIPS_INVAL(opn);
6986 generate_exception(ctx, EXCP_RI);
6987 } else {
6988 gen_helper_deret(cpu_env);
6989 ctx->bstate = BS_EXCP;
6990 }
6991 break;
6992 case OPC_WAIT:
6993 opn = "wait";
6994 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6995 /* If we get an exception, we want to restart at next instruction */
6996 ctx->pc += 4;
6997 save_cpu_state(ctx, 1);
6998 ctx->pc -= 4;
6999 gen_helper_wait(cpu_env);
7000 ctx->bstate = BS_EXCP;
7001 break;
7002 default:
7003 die:
7004 MIPS_INVAL(opn);
7005 generate_exception(ctx, EXCP_RI);
7006 return;
7007 }
7008 (void)opn; /* avoid a compiler warning */
7009 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
7010 }
7011 #endif /* !CONFIG_USER_ONLY */
7012
7013 /* CP1 Branches (before delay slot) */
7014 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
7015 int32_t cc, int32_t offset)
7016 {
7017 target_ulong btarget;
7018 const char *opn = "cp1 cond branch";
7019 TCGv_i32 t0 = tcg_temp_new_i32();
7020
7021 if (cc != 0)
7022 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7023
7024 btarget = ctx->pc + 4 + offset;
7025
7026 switch (op) {
7027 case OPC_BC1F:
7028 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7029 tcg_gen_not_i32(t0, t0);
7030 tcg_gen_andi_i32(t0, t0, 1);
7031 tcg_gen_extu_i32_tl(bcond, t0);
7032 opn = "bc1f";
7033 goto not_likely;
7034 case OPC_BC1FL:
7035 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7036 tcg_gen_not_i32(t0, t0);
7037 tcg_gen_andi_i32(t0, t0, 1);
7038 tcg_gen_extu_i32_tl(bcond, t0);
7039 opn = "bc1fl";
7040 goto likely;
7041 case OPC_BC1T:
7042 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7043 tcg_gen_andi_i32(t0, t0, 1);
7044 tcg_gen_extu_i32_tl(bcond, t0);
7045 opn = "bc1t";
7046 goto not_likely;
7047 case OPC_BC1TL:
7048 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7049 tcg_gen_andi_i32(t0, t0, 1);
7050 tcg_gen_extu_i32_tl(bcond, t0);
7051 opn = "bc1tl";
7052 likely:
7053 ctx->hflags |= MIPS_HFLAG_BL;
7054 break;
7055 case OPC_BC1FANY2:
7056 {
7057 TCGv_i32 t1 = tcg_temp_new_i32();
7058 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7060 tcg_gen_nand_i32(t0, t0, t1);
7061 tcg_temp_free_i32(t1);
7062 tcg_gen_andi_i32(t0, t0, 1);
7063 tcg_gen_extu_i32_tl(bcond, t0);
7064 }
7065 opn = "bc1any2f";
7066 goto not_likely;
7067 case OPC_BC1TANY2:
7068 {
7069 TCGv_i32 t1 = tcg_temp_new_i32();
7070 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7071 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7072 tcg_gen_or_i32(t0, t0, t1);
7073 tcg_temp_free_i32(t1);
7074 tcg_gen_andi_i32(t0, t0, 1);
7075 tcg_gen_extu_i32_tl(bcond, t0);
7076 }
7077 opn = "bc1any2t";
7078 goto not_likely;
7079 case OPC_BC1FANY4:
7080 {
7081 TCGv_i32 t1 = tcg_temp_new_i32();
7082 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7083 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7084 tcg_gen_and_i32(t0, t0, t1);
7085 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7086 tcg_gen_and_i32(t0, t0, t1);
7087 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7088 tcg_gen_nand_i32(t0, t0, t1);
7089 tcg_temp_free_i32(t1);
7090 tcg_gen_andi_i32(t0, t0, 1);
7091 tcg_gen_extu_i32_tl(bcond, t0);
7092 }
7093 opn = "bc1any4f";
7094 goto not_likely;
7095 case OPC_BC1TANY4:
7096 {
7097 TCGv_i32 t1 = tcg_temp_new_i32();
7098 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7099 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7100 tcg_gen_or_i32(t0, t0, t1);
7101 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7102 tcg_gen_or_i32(t0, t0, t1);
7103 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7104 tcg_gen_or_i32(t0, t0, t1);
7105 tcg_temp_free_i32(t1);
7106 tcg_gen_andi_i32(t0, t0, 1);
7107 tcg_gen_extu_i32_tl(bcond, t0);
7108 }
7109 opn = "bc1any4t";
7110 not_likely:
7111 ctx->hflags |= MIPS_HFLAG_BC;
7112 break;
7113 default:
7114 MIPS_INVAL(opn);
7115 generate_exception (ctx, EXCP_RI);
7116 goto out;
7117 }
7118 (void)opn; /* avoid a compiler warning */
7119 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7120 ctx->hflags, btarget);
7121 ctx->btarget = btarget;
7122
7123 out:
7124 tcg_temp_free_i32(t0);
7125 }
7126
7127 /* Coprocessor 1 (FPU) */
7128
7129 #define FOP(func, fmt) (((fmt) << 21) | (func))
7130
7131 enum fopcode {
7132 OPC_ADD_S = FOP(0, FMT_S),
7133 OPC_SUB_S = FOP(1, FMT_S),
7134 OPC_MUL_S = FOP(2, FMT_S),
7135 OPC_DIV_S = FOP(3, FMT_S),
7136 OPC_SQRT_S = FOP(4, FMT_S),
7137 OPC_ABS_S = FOP(5, FMT_S),
7138 OPC_MOV_S = FOP(6, FMT_S),
7139 OPC_NEG_S = FOP(7, FMT_S),
7140 OPC_ROUND_L_S = FOP(8, FMT_S),
7141 OPC_TRUNC_L_S = FOP(9, FMT_S),
7142 OPC_CEIL_L_S = FOP(10, FMT_S),
7143 OPC_FLOOR_L_S = FOP(11, FMT_S),
7144 OPC_ROUND_W_S = FOP(12, FMT_S),
7145 OPC_TRUNC_W_S = FOP(13, FMT_S),
7146 OPC_CEIL_W_S = FOP(14, FMT_S),
7147 OPC_FLOOR_W_S = FOP(15, FMT_S),
7148 OPC_MOVCF_S = FOP(17, FMT_S),
7149 OPC_MOVZ_S = FOP(18, FMT_S),
7150 OPC_MOVN_S = FOP(19, FMT_S),
7151 OPC_RECIP_S = FOP(21, FMT_S),
7152 OPC_RSQRT_S = FOP(22, FMT_S),
7153 OPC_RECIP2_S = FOP(28, FMT_S),
7154 OPC_RECIP1_S = FOP(29, FMT_S),
7155 OPC_RSQRT1_S = FOP(30, FMT_S),
7156 OPC_RSQRT2_S = FOP(31, FMT_S),
7157 OPC_CVT_D_S = FOP(33, FMT_S),
7158 OPC_CVT_W_S = FOP(36, FMT_S),
7159 OPC_CVT_L_S = FOP(37, FMT_S),
7160 OPC_CVT_PS_S = FOP(38, FMT_S),
7161 OPC_CMP_F_S = FOP (48, FMT_S),
7162 OPC_CMP_UN_S = FOP (49, FMT_S),
7163 OPC_CMP_EQ_S = FOP (50, FMT_S),
7164 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7165 OPC_CMP_OLT_S = FOP (52, FMT_S),
7166 OPC_CMP_ULT_S = FOP (53, FMT_S),
7167 OPC_CMP_OLE_S = FOP (54, FMT_S),
7168 OPC_CMP_ULE_S = FOP (55, FMT_S),
7169 OPC_CMP_SF_S = FOP (56, FMT_S),
7170 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7171 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7172 OPC_CMP_NGL_S = FOP (59, FMT_S),
7173 OPC_CMP_LT_S = FOP (60, FMT_S),
7174 OPC_CMP_NGE_S = FOP (61, FMT_S),
7175 OPC_CMP_LE_S = FOP (62, FMT_S),
7176 OPC_CMP_NGT_S = FOP (63, FMT_S),
7177
7178 OPC_ADD_D = FOP(0, FMT_D),
7179 OPC_SUB_D = FOP(1, FMT_D),
7180 OPC_MUL_D = FOP(2, FMT_D),
7181 OPC_DIV_D = FOP(3, FMT_D),
7182 OPC_SQRT_D = FOP(4, FMT_D),
7183 OPC_ABS_D = FOP(5, FMT_D),
7184 OPC_MOV_D = FOP(6, FMT_D),
7185 OPC_NEG_D = FOP(7, FMT_D),
7186 OPC_ROUND_L_D = FOP(8, FMT_D),
7187 OPC_TRUNC_L_D = FOP(9, FMT_D),
7188 OPC_CEIL_L_D = FOP(10, FMT_D),
7189 OPC_FLOOR_L_D = FOP(11, FMT_D),
7190 OPC_ROUND_W_D = FOP(12, FMT_D),
7191 OPC_TRUNC_W_D = FOP(13, FMT_D),
7192 OPC_CEIL_W_D = FOP(14, FMT_D),
7193 OPC_FLOOR_W_D = FOP(15, FMT_D),
7194 OPC_MOVCF_D = FOP(17, FMT_D),
7195 OPC_MOVZ_D = FOP(18, FMT_D),
7196 OPC_MOVN_D = FOP(19, FMT_D),
7197 OPC_RECIP_D = FOP(21, FMT_D),
7198 OPC_RSQRT_D = FOP(22, FMT_D),
7199 OPC_RECIP2_D = FOP(28, FMT_D),
7200 OPC_RECIP1_D = FOP(29, FMT_D),
7201 OPC_RSQRT1_D = FOP(30, FMT_D),
7202 OPC_RSQRT2_D = FOP(31, FMT_D),
7203 OPC_CVT_S_D = FOP(32, FMT_D),
7204 OPC_CVT_W_D = FOP(36, FMT_D),
7205 OPC_CVT_L_D = FOP(37, FMT_D),
7206 OPC_CMP_F_D = FOP (48, FMT_D),
7207 OPC_CMP_UN_D = FOP (49, FMT_D),
7208 OPC_CMP_EQ_D = FOP (50, FMT_D),
7209 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7210 OPC_CMP_OLT_D = FOP (52, FMT_D),
7211 OPC_CMP_ULT_D = FOP (53, FMT_D),
7212 OPC_CMP_OLE_D = FOP (54, FMT_D),
7213 OPC_CMP_ULE_D = FOP (55, FMT_D),
7214 OPC_CMP_SF_D = FOP (56, FMT_D),
7215 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7216 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7217 OPC_CMP_NGL_D = FOP (59, FMT_D),
7218 OPC_CMP_LT_D = FOP (60, FMT_D),
7219 OPC_CMP_NGE_D = FOP (61, FMT_D),
7220 OPC_CMP_LE_D = FOP (62, FMT_D),
7221 OPC_CMP_NGT_D = FOP (63, FMT_D),
7222
7223 OPC_CVT_S_W = FOP(32, FMT_W),
7224 OPC_CVT_D_W = FOP(33, FMT_W),
7225 OPC_CVT_S_L = FOP(32, FMT_L),
7226 OPC_CVT_D_L = FOP(33, FMT_L),
7227 OPC_CVT_PS_PW = FOP(38, FMT_W),
7228
7229 OPC_ADD_PS = FOP(0, FMT_PS),
7230 OPC_SUB_PS = FOP(1, FMT_PS),
7231 OPC_MUL_PS = FOP(2, FMT_PS),
7232 OPC_DIV_PS = FOP(3, FMT_PS),
7233 OPC_ABS_PS = FOP(5, FMT_PS),
7234 OPC_MOV_PS = FOP(6, FMT_PS),
7235 OPC_NEG_PS = FOP(7, FMT_PS),
7236 OPC_MOVCF_PS = FOP(17, FMT_PS),
7237 OPC_MOVZ_PS = FOP(18, FMT_PS),
7238 OPC_MOVN_PS = FOP(19, FMT_PS),
7239 OPC_ADDR_PS = FOP(24, FMT_PS),
7240 OPC_MULR_PS = FOP(26, FMT_PS),
7241 OPC_RECIP2_PS = FOP(28, FMT_PS),
7242 OPC_RECIP1_PS = FOP(29, FMT_PS),
7243 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7244 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7245
7246 OPC_CVT_S_PU = FOP(32, FMT_PS),
7247 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7248 OPC_CVT_S_PL = FOP(40, FMT_PS),
7249 OPC_PLL_PS = FOP(44, FMT_PS),
7250 OPC_PLU_PS = FOP(45, FMT_PS),
7251 OPC_PUL_PS = FOP(46, FMT_PS),
7252 OPC_PUU_PS = FOP(47, FMT_PS),
7253 OPC_CMP_F_PS = FOP (48, FMT_PS),
7254 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7255 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7256 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7257 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7258 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7259 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7260 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7261 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7262 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7263 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7264 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7265 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7266 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7267 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7268 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7269 };
7270
7271 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7272 {
7273 const char *opn = "cp1 move";
7274 TCGv t0 = tcg_temp_new();
7275
7276 switch (opc) {
7277 case OPC_MFC1:
7278 {
7279 TCGv_i32 fp0 = tcg_temp_new_i32();
7280
7281 gen_load_fpr32(fp0, fs);
7282 tcg_gen_ext_i32_tl(t0, fp0);
7283 tcg_temp_free_i32(fp0);
7284 }
7285 gen_store_gpr(t0, rt);
7286 opn = "mfc1";
7287 break;
7288 case OPC_MTC1:
7289 gen_load_gpr(t0, rt);
7290 {
7291 TCGv_i32 fp0 = tcg_temp_new_i32();
7292
7293 tcg_gen_trunc_tl_i32(fp0, t0);
7294 gen_store_fpr32(fp0, fs);
7295 tcg_temp_free_i32(fp0);
7296 }
7297 opn = "mtc1";
7298 break;
7299 case OPC_CFC1:
7300 gen_helper_1e0i(cfc1, t0, fs);
7301 gen_store_gpr(t0, rt);
7302 opn = "cfc1";
7303 break;
7304 case OPC_CTC1:
7305 gen_load_gpr(t0, rt);
7306 gen_helper_0e1i(ctc1, t0, fs);
7307 opn = "ctc1";
7308 break;
7309 #if defined(TARGET_MIPS64)
7310 case OPC_DMFC1:
7311 gen_load_fpr64(ctx, t0, fs);
7312 gen_store_gpr(t0, rt);
7313 opn = "dmfc1";
7314 break;
7315 case OPC_DMTC1:
7316 gen_load_gpr(t0, rt);
7317 gen_store_fpr64(ctx, t0, fs);
7318 opn = "dmtc1";
7319 break;
7320 #endif
7321 case OPC_MFHC1:
7322 {
7323 TCGv_i32 fp0 = tcg_temp_new_i32();
7324
7325 gen_load_fpr32h(fp0, fs);
7326 tcg_gen_ext_i32_tl(t0, fp0);
7327 tcg_temp_free_i32(fp0);
7328 }
7329 gen_store_gpr(t0, rt);
7330 opn = "mfhc1";
7331 break;
7332 case OPC_MTHC1:
7333 gen_load_gpr(t0, rt);
7334 {
7335 TCGv_i32 fp0 = tcg_temp_new_i32();
7336
7337 tcg_gen_trunc_tl_i32(fp0, t0);
7338 gen_store_fpr32h(fp0, fs);
7339 tcg_temp_free_i32(fp0);
7340 }
7341 opn = "mthc1";
7342 break;
7343 default:
7344 MIPS_INVAL(opn);
7345 generate_exception (ctx, EXCP_RI);
7346 goto out;
7347 }
7348 (void)opn; /* avoid a compiler warning */
7349 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7350
7351 out:
7352 tcg_temp_free(t0);
7353 }
7354
7355 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7356 {
7357 int l1;
7358 TCGCond cond;
7359 TCGv_i32 t0;
7360
7361 if (rd == 0) {
7362 /* Treat as NOP. */
7363 return;
7364 }
7365
7366 if (tf)
7367 cond = TCG_COND_EQ;
7368 else
7369 cond = TCG_COND_NE;
7370
7371 l1 = gen_new_label();
7372 t0 = tcg_temp_new_i32();
7373 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7374 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7375 tcg_temp_free_i32(t0);
7376 if (rs == 0) {
7377 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7378 } else {
7379 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7380 }
7381 gen_set_label(l1);
7382 }
7383
7384 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7385 {
7386 int cond;
7387 TCGv_i32 t0 = tcg_temp_new_i32();
7388 int l1 = gen_new_label();
7389
7390 if (tf)
7391 cond = TCG_COND_EQ;
7392 else
7393 cond = TCG_COND_NE;
7394
7395 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7396 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7397 gen_load_fpr32(t0, fs);
7398 gen_store_fpr32(t0, fd);
7399 gen_set_label(l1);
7400 tcg_temp_free_i32(t0);
7401 }
7402
7403 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7404 {
7405 int cond;
7406 TCGv_i32 t0 = tcg_temp_new_i32();
7407 TCGv_i64 fp0;
7408 int l1 = gen_new_label();
7409
7410 if (tf)
7411 cond = TCG_COND_EQ;
7412 else
7413 cond = TCG_COND_NE;
7414
7415 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7416 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7417 tcg_temp_free_i32(t0);
7418 fp0 = tcg_temp_new_i64();
7419 gen_load_fpr64(ctx, fp0, fs);
7420 gen_store_fpr64(ctx, fp0, fd);
7421 tcg_temp_free_i64(fp0);
7422 gen_set_label(l1);
7423 }
7424
7425 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7426 {
7427 int cond;
7428 TCGv_i32 t0 = tcg_temp_new_i32();
7429 int l1 = gen_new_label();
7430 int l2 = gen_new_label();
7431
7432 if (tf)
7433 cond = TCG_COND_EQ;
7434 else
7435 cond = TCG_COND_NE;
7436
7437 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7438 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7439 gen_load_fpr32(t0, fs);
7440 gen_store_fpr32(t0, fd);
7441 gen_set_label(l1);
7442
7443 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7444 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7445 gen_load_fpr32h(t0, fs);
7446 gen_store_fpr32h(t0, fd);
7447 tcg_temp_free_i32(t0);
7448 gen_set_label(l2);
7449 }
7450
7451
7452 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7453 int ft, int fs, int fd, int cc)
7454 {
7455 const char *opn = "farith";
7456 const char *condnames[] = {
7457 "c.f",
7458 "c.un",
7459 "c.eq",
7460 "c.ueq",
7461 "c.olt",
7462 "c.ult",
7463 "c.ole",
7464 "c.ule",
7465 "c.sf",
7466 "c.ngle",
7467 "c.seq",
7468 "c.ngl",
7469 "c.lt",
7470 "c.nge",
7471 "c.le",
7472 "c.ngt",
7473 };
7474 const char *condnames_abs[] = {
7475 "cabs.f",
7476 "cabs.un",
7477 "cabs.eq",
7478 "cabs.ueq",
7479 "cabs.olt",
7480 "cabs.ult",
7481 "cabs.ole",
7482 "cabs.ule",
7483 "cabs.sf",
7484 "cabs.ngle",
7485 "cabs.seq",
7486 "cabs.ngl",
7487 "cabs.lt",
7488 "cabs.nge",
7489 "cabs.le",
7490 "cabs.ngt",
7491 };
7492 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7493 uint32_t func = ctx->opcode & 0x3f;
7494
7495 switch (op1) {
7496 case OPC_ADD_S:
7497 {
7498 TCGv_i32 fp0 = tcg_temp_new_i32();
7499 TCGv_i32 fp1 = tcg_temp_new_i32();
7500
7501 gen_load_fpr32(fp0, fs);
7502 gen_load_fpr32(fp1, ft);
7503 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7504 tcg_temp_free_i32(fp1);
7505 gen_store_fpr32(fp0, fd);
7506 tcg_temp_free_i32(fp0);
7507 }
7508 opn = "add.s";
7509 optype = BINOP;
7510 break;
7511 case OPC_SUB_S:
7512 {
7513 TCGv_i32 fp0 = tcg_temp_new_i32();
7514 TCGv_i32 fp1 = tcg_temp_new_i32();
7515
7516 gen_load_fpr32(fp0, fs);
7517 gen_load_fpr32(fp1, ft);
7518 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7519 tcg_temp_free_i32(fp1);
7520 gen_store_fpr32(fp0, fd);
7521 tcg_temp_free_i32(fp0);
7522 }
7523 opn = "sub.s";
7524 optype = BINOP;
7525 break;
7526 case OPC_MUL_S:
7527 {
7528 TCGv_i32 fp0 = tcg_temp_new_i32();
7529 TCGv_i32 fp1 = tcg_temp_new_i32();
7530
7531 gen_load_fpr32(fp0, fs);
7532 gen_load_fpr32(fp1, ft);
7533 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7534 tcg_temp_free_i32(fp1);
7535 gen_store_fpr32(fp0, fd);
7536 tcg_temp_free_i32(fp0);
7537 }
7538 opn = "mul.s";
7539 optype = BINOP;
7540 break;
7541 case OPC_DIV_S:
7542 {
7543 TCGv_i32 fp0 = tcg_temp_new_i32();
7544 TCGv_i32 fp1 = tcg_temp_new_i32();
7545
7546 gen_load_fpr32(fp0, fs);
7547 gen_load_fpr32(fp1, ft);
7548 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7549 tcg_temp_free_i32(fp1);
7550 gen_store_fpr32(fp0, fd);
7551 tcg_temp_free_i32(fp0);
7552 }
7553 opn = "div.s";
7554 optype = BINOP;
7555 break;
7556 case OPC_SQRT_S:
7557 {
7558 TCGv_i32 fp0 = tcg_temp_new_i32();
7559
7560 gen_load_fpr32(fp0, fs);
7561 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7562 gen_store_fpr32(fp0, fd);
7563 tcg_temp_free_i32(fp0);
7564 }
7565 opn = "sqrt.s";
7566 break;
7567 case OPC_ABS_S:
7568 {
7569 TCGv_i32 fp0 = tcg_temp_new_i32();
7570
7571 gen_load_fpr32(fp0, fs);
7572 gen_helper_float_abs_s(fp0, fp0);
7573 gen_store_fpr32(fp0, fd);
7574 tcg_temp_free_i32(fp0);
7575 }
7576 opn = "abs.s";
7577 break;
7578 case OPC_MOV_S:
7579 {
7580 TCGv_i32 fp0 = tcg_temp_new_i32();
7581
7582 gen_load_fpr32(fp0, fs);
7583 gen_store_fpr32(fp0, fd);
7584 tcg_temp_free_i32(fp0);
7585 }
7586 opn = "mov.s";
7587 break;
7588 case OPC_NEG_S:
7589 {
7590 TCGv_i32 fp0 = tcg_temp_new_i32();
7591
7592 gen_load_fpr32(fp0, fs);
7593 gen_helper_float_chs_s(fp0, fp0);
7594 gen_store_fpr32(fp0, fd);
7595 tcg_temp_free_i32(fp0);
7596 }
7597 opn = "neg.s";
7598 break;
7599 case OPC_ROUND_L_S:
7600 check_cp1_64bitmode(ctx);
7601 {
7602 TCGv_i32 fp32 = tcg_temp_new_i32();
7603 TCGv_i64 fp64 = tcg_temp_new_i64();
7604
7605 gen_load_fpr32(fp32, fs);
7606 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7607 tcg_temp_free_i32(fp32);
7608 gen_store_fpr64(ctx, fp64, fd);
7609 tcg_temp_free_i64(fp64);
7610 }
7611 opn = "round.l.s";
7612 break;
7613 case OPC_TRUNC_L_S:
7614 check_cp1_64bitmode(ctx);
7615 {
7616 TCGv_i32 fp32 = tcg_temp_new_i32();
7617 TCGv_i64 fp64 = tcg_temp_new_i64();
7618
7619 gen_load_fpr32(fp32, fs);
7620 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7621 tcg_temp_free_i32(fp32);
7622 gen_store_fpr64(ctx, fp64, fd);
7623 tcg_temp_free_i64(fp64);
7624 }
7625 opn = "trunc.l.s";
7626 break;
7627 case OPC_CEIL_L_S:
7628 check_cp1_64bitmode(ctx);
7629 {
7630 TCGv_i32 fp32 = tcg_temp_new_i32();
7631 TCGv_i64 fp64 = tcg_temp_new_i64();
7632
7633 gen_load_fpr32(fp32, fs);
7634 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7635 tcg_temp_free_i32(fp32);
7636 gen_store_fpr64(ctx, fp64, fd);
7637 tcg_temp_free_i64(fp64);
7638 }
7639 opn = "ceil.l.s";
7640 break;
7641 case OPC_FLOOR_L_S:
7642 check_cp1_64bitmode(ctx);
7643 {
7644 TCGv_i32 fp32 = tcg_temp_new_i32();
7645 TCGv_i64 fp64 = tcg_temp_new_i64();
7646
7647 gen_load_fpr32(fp32, fs);
7648 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7649 tcg_temp_free_i32(fp32);
7650 gen_store_fpr64(ctx, fp64, fd);
7651 tcg_temp_free_i64(fp64);
7652 }
7653 opn = "floor.l.s";
7654 break;
7655 case OPC_ROUND_W_S:
7656 {
7657 TCGv_i32 fp0 = tcg_temp_new_i32();
7658
7659 gen_load_fpr32(fp0, fs);
7660 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7661 gen_store_fpr32(fp0, fd);
7662 tcg_temp_free_i32(fp0);
7663 }
7664 opn = "round.w.s";
7665 break;
7666 case OPC_TRUNC_W_S:
7667 {
7668 TCGv_i32 fp0 = tcg_temp_new_i32();
7669
7670 gen_load_fpr32(fp0, fs);
7671 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7672 gen_store_fpr32(fp0, fd);
7673 tcg_temp_free_i32(fp0);
7674 }
7675 opn = "trunc.w.s";
7676 break;
7677 case OPC_CEIL_W_S:
7678 {
7679 TCGv_i32 fp0 = tcg_temp_new_i32();
7680
7681 gen_load_fpr32(fp0, fs);
7682 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7683 gen_store_fpr32(fp0, fd);
7684 tcg_temp_free_i32(fp0);
7685 }
7686 opn = "ceil.w.s";
7687 break;
7688 case OPC_FLOOR_W_S:
7689 {
7690 TCGv_i32 fp0 = tcg_temp_new_i32();
7691
7692 gen_load_fpr32(fp0, fs);
7693 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7694 gen_store_fpr32(fp0, fd);
7695 tcg_temp_free_i32(fp0);
7696 }
7697 opn = "floor.w.s";
7698 break;
7699 case OPC_MOVCF_S:
7700 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7701 opn = "movcf.s";
7702 break;
7703 case OPC_MOVZ_S:
7704 {
7705 int l1 = gen_new_label();
7706 TCGv_i32 fp0;
7707
7708 if (ft != 0) {
7709 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7710 }
7711 fp0 = tcg_temp_new_i32();
7712 gen_load_fpr32(fp0, fs);
7713 gen_store_fpr32(fp0, fd);
7714 tcg_temp_free_i32(fp0);
7715 gen_set_label(l1);
7716 }
7717 opn = "movz.s";
7718 break;
7719 case OPC_MOVN_S:
7720 {
7721 int l1 = gen_new_label();
7722 TCGv_i32 fp0;
7723
7724 if (ft != 0) {
7725 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7726 fp0 = tcg_temp_new_i32();
7727 gen_load_fpr32(fp0, fs);
7728 gen_store_fpr32(fp0, fd);
7729 tcg_temp_free_i32(fp0);
7730 gen_set_label(l1);
7731 }
7732 }
7733 opn = "movn.s";
7734 break;
7735 case OPC_RECIP_S:
7736 check_cop1x(ctx);
7737 {
7738 TCGv_i32 fp0 = tcg_temp_new_i32();
7739
7740 gen_load_fpr32(fp0, fs);
7741 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7742 gen_store_fpr32(fp0, fd);
7743 tcg_temp_free_i32(fp0);
7744 }
7745 opn = "recip.s";
7746 break;
7747 case OPC_RSQRT_S:
7748 check_cop1x(ctx);
7749 {
7750 TCGv_i32 fp0 = tcg_temp_new_i32();
7751
7752 gen_load_fpr32(fp0, fs);
7753 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7754 gen_store_fpr32(fp0, fd);
7755 tcg_temp_free_i32(fp0);
7756 }
7757 opn = "rsqrt.s";
7758 break;
7759 case OPC_RECIP2_S:
7760 check_cp1_64bitmode(ctx);
7761 {
7762 TCGv_i32 fp0 = tcg_temp_new_i32();
7763 TCGv_i32 fp1 = tcg_temp_new_i32();
7764
7765 gen_load_fpr32(fp0, fs);
7766 gen_load_fpr32(fp1, ft);
7767 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7768 tcg_temp_free_i32(fp1);
7769 gen_store_fpr32(fp0, fd);
7770 tcg_temp_free_i32(fp0);
7771 }
7772 opn = "recip2.s";
7773 break;
7774 case OPC_RECIP1_S:
7775 check_cp1_64bitmode(ctx);
7776 {
7777 TCGv_i32 fp0 = tcg_temp_new_i32();
7778
7779 gen_load_fpr32(fp0, fs);
7780 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7781 gen_store_fpr32(fp0, fd);
7782 tcg_temp_free_i32(fp0);
7783 }
7784 opn = "recip1.s";
7785 break;
7786 case OPC_RSQRT1_S:
7787 check_cp1_64bitmode(ctx);
7788 {
7789 TCGv_i32 fp0 = tcg_temp_new_i32();
7790
7791 gen_load_fpr32(fp0, fs);
7792 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7793 gen_store_fpr32(fp0, fd);
7794 tcg_temp_free_i32(fp0);
7795 }
7796 opn = "rsqrt1.s";
7797 break;
7798 case OPC_RSQRT2_S:
7799 check_cp1_64bitmode(ctx);
7800 {
7801 TCGv_i32 fp0 = tcg_temp_new_i32();
7802 TCGv_i32 fp1 = tcg_temp_new_i32();
7803
7804 gen_load_fpr32(fp0, fs);
7805 gen_load_fpr32(fp1, ft);
7806 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7807 tcg_temp_free_i32(fp1);
7808 gen_store_fpr32(fp0, fd);
7809 tcg_temp_free_i32(fp0);
7810 }
7811 opn = "rsqrt2.s";
7812 break;
7813 case OPC_CVT_D_S:
7814 check_cp1_registers(ctx, fd);
7815 {
7816 TCGv_i32 fp32 = tcg_temp_new_i32();
7817 TCGv_i64 fp64 = tcg_temp_new_i64();
7818
7819 gen_load_fpr32(fp32, fs);
7820 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7821 tcg_temp_free_i32(fp32);
7822 gen_store_fpr64(ctx, fp64, fd);
7823 tcg_temp_free_i64(fp64);
7824 }
7825 opn = "cvt.d.s";
7826 break;
7827 case OPC_CVT_W_S:
7828 {
7829 TCGv_i32 fp0 = tcg_temp_new_i32();
7830
7831 gen_load_fpr32(fp0, fs);
7832 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7833 gen_store_fpr32(fp0, fd);
7834 tcg_temp_free_i32(fp0);
7835 }
7836 opn = "cvt.w.s";
7837 break;
7838 case OPC_CVT_L_S:
7839 check_cp1_64bitmode(ctx);
7840 {
7841 TCGv_i32 fp32 = tcg_temp_new_i32();
7842 TCGv_i64 fp64 = tcg_temp_new_i64();
7843
7844 gen_load_fpr32(fp32, fs);
7845 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7846 tcg_temp_free_i32(fp32);
7847 gen_store_fpr64(ctx, fp64, fd);
7848 tcg_temp_free_i64(fp64);
7849 }
7850 opn = "cvt.l.s";
7851 break;
7852 case OPC_CVT_PS_S:
7853 check_cp1_64bitmode(ctx);
7854 {
7855 TCGv_i64 fp64 = tcg_temp_new_i64();
7856 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7857 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7858
7859 gen_load_fpr32(fp32_0, fs);
7860 gen_load_fpr32(fp32_1, ft);
7861 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7862 tcg_temp_free_i32(fp32_1);
7863 tcg_temp_free_i32(fp32_0);
7864 gen_store_fpr64(ctx, fp64, fd);
7865 tcg_temp_free_i64(fp64);
7866 }
7867 opn = "cvt.ps.s";
7868 break;
7869 case OPC_CMP_F_S:
7870 case OPC_CMP_UN_S:
7871 case OPC_CMP_EQ_S:
7872 case OPC_CMP_UEQ_S:
7873 case OPC_CMP_OLT_S:
7874 case OPC_CMP_ULT_S:
7875 case OPC_CMP_OLE_S:
7876 case OPC_CMP_ULE_S:
7877 case OPC_CMP_SF_S:
7878 case OPC_CMP_NGLE_S:
7879 case OPC_CMP_SEQ_S:
7880 case OPC_CMP_NGL_S:
7881 case OPC_CMP_LT_S:
7882 case OPC_CMP_NGE_S:
7883 case OPC_CMP_LE_S:
7884 case OPC_CMP_NGT_S:
7885 if (ctx->opcode & (1 << 6)) {
7886 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7887 opn = condnames_abs[func-48];
7888 } else {
7889 gen_cmp_s(ctx, func-48, ft, fs, cc);
7890 opn = condnames[func-48];
7891 }
7892 break;
7893 case OPC_ADD_D:
7894 check_cp1_registers(ctx, fs | ft | fd);
7895 {
7896 TCGv_i64 fp0 = tcg_temp_new_i64();
7897 TCGv_i64 fp1 = tcg_temp_new_i64();
7898
7899 gen_load_fpr64(ctx, fp0, fs);
7900 gen_load_fpr64(ctx, fp1, ft);
7901 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7902 tcg_temp_free_i64(fp1);
7903 gen_store_fpr64(ctx, fp0, fd);
7904 tcg_temp_free_i64(fp0);
7905 }
7906 opn = "add.d";
7907 optype = BINOP;
7908 break;
7909 case OPC_SUB_D:
7910 check_cp1_registers(ctx, fs | ft | fd);
7911 {
7912 TCGv_i64 fp0 = tcg_temp_new_i64();
7913 TCGv_i64 fp1 = tcg_temp_new_i64();
7914
7915 gen_load_fpr64(ctx, fp0, fs);
7916 gen_load_fpr64(ctx, fp1, ft);
7917 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7918 tcg_temp_free_i64(fp1);
7919 gen_store_fpr64(ctx, fp0, fd);
7920 tcg_temp_free_i64(fp0);
7921 }
7922 opn = "sub.d";
7923 optype = BINOP;
7924 break;
7925 case OPC_MUL_D:
7926 check_cp1_registers(ctx, fs | ft | fd);
7927 {
7928 TCGv_i64 fp0 = tcg_temp_new_i64();
7929 TCGv_i64 fp1 = tcg_temp_new_i64();
7930
7931 gen_load_fpr64(ctx, fp0, fs);
7932 gen_load_fpr64(ctx, fp1, ft);
7933 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7934 tcg_temp_free_i64(fp1);
7935 gen_store_fpr64(ctx, fp0, fd);
7936 tcg_temp_free_i64(fp0);
7937 }
7938 opn = "mul.d";
7939 optype = BINOP;
7940 break;
7941 case OPC_DIV_D:
7942 check_cp1_registers(ctx, fs | ft | fd);
7943 {
7944 TCGv_i64 fp0 = tcg_temp_new_i64();
7945 TCGv_i64 fp1 = tcg_temp_new_i64();
7946
7947 gen_load_fpr64(ctx, fp0, fs);
7948 gen_load_fpr64(ctx, fp1, ft);
7949 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7950 tcg_temp_free_i64(fp1);
7951 gen_store_fpr64(ctx, fp0, fd);
7952 tcg_temp_free_i64(fp0);
7953 }
7954 opn = "div.d";
7955 optype = BINOP;
7956 break;
7957 case OPC_SQRT_D:
7958 check_cp1_registers(ctx, fs | fd);
7959 {
7960 TCGv_i64 fp0 = tcg_temp_new_i64();
7961
7962 gen_load_fpr64(ctx, fp0, fs);
7963 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7964 gen_store_fpr64(ctx, fp0, fd);
7965 tcg_temp_free_i64(fp0);
7966 }
7967 opn = "sqrt.d";
7968 break;
7969 case OPC_ABS_D:
7970 check_cp1_registers(ctx, fs | fd);
7971 {
7972 TCGv_i64 fp0 = tcg_temp_new_i64();
7973
7974 gen_load_fpr64(ctx, fp0, fs);
7975 gen_helper_float_abs_d(fp0, fp0);
7976 gen_store_fpr64(ctx, fp0, fd);
7977 tcg_temp_free_i64(fp0);
7978 }
7979 opn = "abs.d";
7980 break;
7981 case OPC_MOV_D:
7982 check_cp1_registers(ctx, fs | fd);
7983 {
7984 TCGv_i64 fp0 = tcg_temp_new_i64();
7985
7986 gen_load_fpr64(ctx, fp0, fs);
7987 gen_store_fpr64(ctx, fp0, fd);
7988 tcg_temp_free_i64(fp0);
7989 }
7990 opn = "mov.d";
7991 break;
7992 case OPC_NEG_D:
7993 check_cp1_registers(ctx, fs | fd);
7994 {
7995 TCGv_i64 fp0 = tcg_temp_new_i64();
7996
7997 gen_load_fpr64(ctx, fp0, fs);
7998 gen_helper_float_chs_d(fp0, fp0);
7999 gen_store_fpr64(ctx, fp0, fd);
8000 tcg_temp_free_i64(fp0);
8001 }
8002 opn = "neg.d";
8003 break;
8004 case OPC_ROUND_L_D:
8005 check_cp1_64bitmode(ctx);
8006 {
8007 TCGv_i64 fp0 = tcg_temp_new_i64();
8008
8009 gen_load_fpr64(ctx, fp0, fs);
8010 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
8011 gen_store_fpr64(ctx, fp0, fd);
8012 tcg_temp_free_i64(fp0);
8013 }
8014 opn = "round.l.d";
8015 break;
8016 case OPC_TRUNC_L_D:
8017 check_cp1_64bitmode(ctx);
8018 {
8019 TCGv_i64 fp0 = tcg_temp_new_i64();
8020
8021 gen_load_fpr64(ctx, fp0, fs);
8022 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
8023 gen_store_fpr64(ctx, fp0, fd);
8024 tcg_temp_free_i64(fp0);
8025 }
8026 opn = "trunc.l.d";
8027 break;
8028 case OPC_CEIL_L_D:
8029 check_cp1_64bitmode(ctx);
8030 {
8031 TCGv_i64 fp0 = tcg_temp_new_i64();
8032
8033 gen_load_fpr64(ctx, fp0, fs);
8034 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8035 gen_store_fpr64(ctx, fp0, fd);
8036 tcg_temp_free_i64(fp0);
8037 }
8038 opn = "ceil.l.d";
8039 break;
8040 case OPC_FLOOR_L_D:
8041 check_cp1_64bitmode(ctx);
8042 {
8043 TCGv_i64 fp0 = tcg_temp_new_i64();
8044
8045 gen_load_fpr64(ctx, fp0, fs);
8046 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8047 gen_store_fpr64(ctx, fp0, fd);
8048 tcg_temp_free_i64(fp0);
8049 }
8050 opn = "floor.l.d";
8051 break;
8052 case OPC_ROUND_W_D:
8053 check_cp1_registers(ctx, fs);
8054 {
8055 TCGv_i32 fp32 = tcg_temp_new_i32();
8056 TCGv_i64 fp64 = tcg_temp_new_i64();
8057
8058 gen_load_fpr64(ctx, fp64, fs);
8059 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8060 tcg_temp_free_i64(fp64);
8061 gen_store_fpr32(fp32, fd);
8062 tcg_temp_free_i32(fp32);
8063 }
8064 opn = "round.w.d";
8065 break;
8066 case OPC_TRUNC_W_D:
8067 check_cp1_registers(ctx, fs);
8068 {
8069 TCGv_i32 fp32 = tcg_temp_new_i32();
8070 TCGv_i64 fp64 = tcg_temp_new_i64();
8071
8072 gen_load_fpr64(ctx, fp64, fs);
8073 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8074 tcg_temp_free_i64(fp64);
8075 gen_store_fpr32(fp32, fd);
8076 tcg_temp_free_i32(fp32);
8077 }
8078 opn = "trunc.w.d";
8079 break;
8080 case OPC_CEIL_W_D:
8081 check_cp1_registers(ctx, fs);
8082 {
8083 TCGv_i32 fp32 = tcg_temp_new_i32();
8084 TCGv_i64 fp64 = tcg_temp_new_i64();
8085
8086 gen_load_fpr64(ctx, fp64, fs);
8087 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8088 tcg_temp_free_i64(fp64);
8089 gen_store_fpr32(fp32, fd);
8090 tcg_temp_free_i32(fp32);
8091 }
8092 opn = "ceil.w.d";
8093 break;
8094 case OPC_FLOOR_W_D:
8095 check_cp1_registers(ctx, fs);
8096 {
8097 TCGv_i32 fp32 = tcg_temp_new_i32();
8098 TCGv_i64 fp64 = tcg_temp_new_i64();
8099
8100 gen_load_fpr64(ctx, fp64, fs);
8101 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8102 tcg_temp_free_i64(fp64);
8103 gen_store_fpr32(fp32, fd);
8104 tcg_temp_free_i32(fp32);
8105 }
8106 opn = "floor.w.d";
8107 break;
8108 case OPC_MOVCF_D:
8109 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8110 opn = "movcf.d";
8111 break;
8112 case OPC_MOVZ_D:
8113 {
8114 int l1 = gen_new_label();
8115 TCGv_i64 fp0;
8116
8117 if (ft != 0) {
8118 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8119 }
8120 fp0 = tcg_temp_new_i64();
8121 gen_load_fpr64(ctx, fp0, fs);
8122 gen_store_fpr64(ctx, fp0, fd);
8123 tcg_temp_free_i64(fp0);
8124 gen_set_label(l1);
8125 }
8126 opn = "movz.d";
8127 break;
8128 case OPC_MOVN_D:
8129 {
8130 int l1 = gen_new_label();
8131 TCGv_i64 fp0;
8132
8133 if (ft != 0) {
8134 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8135 fp0 = tcg_temp_new_i64();
8136 gen_load_fpr64(ctx, fp0, fs);
8137 gen_store_fpr64(ctx, fp0, fd);
8138 tcg_temp_free_i64(fp0);
8139 gen_set_label(l1);
8140 }
8141 }
8142 opn = "movn.d";
8143 break;
8144 case OPC_RECIP_D:
8145 check_cp1_64bitmode(ctx);
8146 {
8147 TCGv_i64 fp0 = tcg_temp_new_i64();
8148
8149 gen_load_fpr64(ctx, fp0, fs);
8150 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8151 gen_store_fpr64(ctx, fp0, fd);
8152 tcg_temp_free_i64(fp0);
8153 }
8154 opn = "recip.d";
8155 break;
8156 case OPC_RSQRT_D:
8157 check_cp1_64bitmode(ctx);
8158 {
8159 TCGv_i64 fp0 = tcg_temp_new_i64();
8160
8161 gen_load_fpr64(ctx, fp0, fs);
8162 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8163 gen_store_fpr64(ctx, fp0, fd);
8164 tcg_temp_free_i64(fp0);
8165 }
8166 opn = "rsqrt.d";
8167 break;
8168 case OPC_RECIP2_D:
8169 check_cp1_64bitmode(ctx);
8170 {
8171 TCGv_i64 fp0 = tcg_temp_new_i64();
8172 TCGv_i64 fp1 = tcg_temp_new_i64();
8173
8174 gen_load_fpr64(ctx, fp0, fs);
8175 gen_load_fpr64(ctx, fp1, ft);
8176 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8177 tcg_temp_free_i64(fp1);
8178 gen_store_fpr64(ctx, fp0, fd);
8179 tcg_temp_free_i64(fp0);
8180 }
8181 opn = "recip2.d";
8182 break;
8183 case OPC_RECIP1_D:
8184 check_cp1_64bitmode(ctx);
8185 {
8186 TCGv_i64 fp0 = tcg_temp_new_i64();
8187
8188 gen_load_fpr64(ctx, fp0, fs);
8189 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8190 gen_store_fpr64(ctx, fp0, fd);
8191 tcg_temp_free_i64(fp0);
8192 }
8193 opn = "recip1.d";
8194 break;
8195 case OPC_RSQRT1_D:
8196 check_cp1_64bitmode(ctx);
8197 {
8198 TCGv_i64 fp0 = tcg_temp_new_i64();
8199
8200 gen_load_fpr64(ctx, fp0, fs);
8201 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8202 gen_store_fpr64(ctx, fp0, fd);
8203 tcg_temp_free_i64(fp0);
8204 }
8205 opn = "rsqrt1.d";
8206 break;
8207 case OPC_RSQRT2_D:
8208 check_cp1_64bitmode(ctx);
8209 {
8210 TCGv_i64 fp0 = tcg_temp_new_i64();
8211 TCGv_i64 fp1 = tcg_temp_new_i64();
8212
8213 gen_load_fpr64(ctx, fp0, fs);
8214 gen_load_fpr64(ctx, fp1, ft);
8215 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8216 tcg_temp_free_i64(fp1);
8217 gen_store_fpr64(ctx, fp0, fd);
8218 tcg_temp_free_i64(fp0);
8219 }
8220 opn = "rsqrt2.d";
8221 break;
8222 case OPC_CMP_F_D:
8223 case OPC_CMP_UN_D:
8224 case OPC_CMP_EQ_D:
8225 case OPC_CMP_UEQ_D:
8226 case OPC_CMP_OLT_D:
8227 case OPC_CMP_ULT_D:
8228 case OPC_CMP_OLE_D:
8229 case OPC_CMP_ULE_D:
8230 case OPC_CMP_SF_D:
8231 case OPC_CMP_NGLE_D:
8232 case OPC_CMP_SEQ_D:
8233 case OPC_CMP_NGL_D:
8234 case OPC_CMP_LT_D:
8235 case OPC_CMP_NGE_D:
8236 case OPC_CMP_LE_D:
8237 case OPC_CMP_NGT_D:
8238 if (ctx->opcode & (1 << 6)) {
8239 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8240 opn = condnames_abs[func-48];
8241 } else {
8242 gen_cmp_d(ctx, func-48, ft, fs, cc);
8243 opn = condnames[func-48];
8244 }
8245 break;
8246 case OPC_CVT_S_D:
8247 check_cp1_registers(ctx, fs);
8248 {
8249 TCGv_i32 fp32 = tcg_temp_new_i32();
8250 TCGv_i64 fp64 = tcg_temp_new_i64();
8251
8252 gen_load_fpr64(ctx, fp64, fs);
8253 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8254 tcg_temp_free_i64(fp64);
8255 gen_store_fpr32(fp32, fd);
8256 tcg_temp_free_i32(fp32);
8257 }
8258 opn = "cvt.s.d";
8259 break;
8260 case OPC_CVT_W_D:
8261 check_cp1_registers(ctx, fs);
8262 {
8263 TCGv_i32 fp32 = tcg_temp_new_i32();
8264 TCGv_i64 fp64 = tcg_temp_new_i64();
8265
8266 gen_load_fpr64(ctx, fp64, fs);
8267 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8268 tcg_temp_free_i64(fp64);
8269 gen_store_fpr32(fp32, fd);
8270 tcg_temp_free_i32(fp32);
8271 }
8272 opn = "cvt.w.d";
8273 break;
8274 case OPC_CVT_L_D:
8275 check_cp1_64bitmode(ctx);
8276 {
8277 TCGv_i64 fp0 = tcg_temp_new_i64();
8278
8279 gen_load_fpr64(ctx, fp0, fs);
8280 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8281 gen_store_fpr64(ctx, fp0, fd);
8282 tcg_temp_free_i64(fp0);
8283 }
8284 opn = "cvt.l.d";
8285 break;
8286 case OPC_CVT_S_W:
8287 {
8288 TCGv_i32 fp0 = tcg_temp_new_i32();
8289
8290 gen_load_fpr32(fp0, fs);
8291 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8292 gen_store_fpr32(fp0, fd);
8293 tcg_temp_free_i32(fp0);
8294 }
8295 opn = "cvt.s.w";
8296 break;
8297 case OPC_CVT_D_W:
8298 check_cp1_registers(ctx, fd);
8299 {
8300 TCGv_i32 fp32 = tcg_temp_new_i32();
8301 TCGv_i64 fp64 = tcg_temp_new_i64();
8302
8303 gen_load_fpr32(fp32, fs);
8304 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8305 tcg_temp_free_i32(fp32);
8306 gen_store_fpr64(ctx, fp64, fd);
8307 tcg_temp_free_i64(fp64);
8308 }
8309 opn = "cvt.d.w";
8310 break;
8311 case OPC_CVT_S_L:
8312 check_cp1_64bitmode(ctx);
8313 {
8314 TCGv_i32 fp32 = tcg_temp_new_i32();
8315 TCGv_i64 fp64 = tcg_temp_new_i64();
8316
8317 gen_load_fpr64(ctx, fp64, fs);
8318 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8319 tcg_temp_free_i64(fp64);
8320 gen_store_fpr32(fp32, fd);
8321 tcg_temp_free_i32(fp32);
8322 }
8323 opn = "cvt.s.l";
8324 break;
8325 case OPC_CVT_D_L:
8326 check_cp1_64bitmode(ctx);
8327 {
8328 TCGv_i64 fp0 = tcg_temp_new_i64();
8329
8330 gen_load_fpr64(ctx, fp0, fs);
8331 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8332 gen_store_fpr64(ctx, fp0, fd);
8333 tcg_temp_free_i64(fp0);
8334 }
8335 opn = "cvt.d.l";
8336 break;
8337 case OPC_CVT_PS_PW:
8338 check_cp1_64bitmode(ctx);
8339 {
8340 TCGv_i64 fp0 = tcg_temp_new_i64();
8341
8342 gen_load_fpr64(ctx, fp0, fs);
8343 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8344 gen_store_fpr64(ctx, fp0, fd);
8345 tcg_temp_free_i64(fp0);
8346 }
8347 opn = "cvt.ps.pw";
8348 break;
8349 case OPC_ADD_PS:
8350 check_cp1_64bitmode(ctx);
8351 {
8352 TCGv_i64 fp0 = tcg_temp_new_i64();
8353 TCGv_i64 fp1 = tcg_temp_new_i64();
8354
8355 gen_load_fpr64(ctx, fp0, fs);
8356 gen_load_fpr64(ctx, fp1, ft);
8357 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8358 tcg_temp_free_i64(fp1);
8359 gen_store_fpr64(ctx, fp0, fd);
8360 tcg_temp_free_i64(fp0);
8361 }
8362 opn = "add.ps";
8363 break;
8364 case OPC_SUB_PS:
8365 check_cp1_64bitmode(ctx);
8366 {
8367 TCGv_i64 fp0 = tcg_temp_new_i64();
8368 TCGv_i64 fp1 = tcg_temp_new_i64();
8369
8370 gen_load_fpr64(ctx, fp0, fs);
8371 gen_load_fpr64(ctx, fp1, ft);
8372 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8373 tcg_temp_free_i64(fp1);
8374 gen_store_fpr64(ctx, fp0, fd);
8375 tcg_temp_free_i64(fp0);
8376 }
8377 opn = "sub.ps";
8378 break;
8379 case OPC_MUL_PS:
8380 check_cp1_64bitmode(ctx);
8381 {
8382 TCGv_i64 fp0 = tcg_temp_new_i64();
8383 TCGv_i64 fp1 = tcg_temp_new_i64();
8384
8385 gen_load_fpr64(ctx, fp0, fs);
8386 gen_load_fpr64(ctx, fp1, ft);
8387 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8388 tcg_temp_free_i64(fp1);
8389 gen_store_fpr64(ctx, fp0, fd);
8390 tcg_temp_free_i64(fp0);
8391 }
8392 opn = "mul.ps";
8393 break;
8394 case OPC_ABS_PS:
8395 check_cp1_64bitmode(ctx);
8396 {
8397 TCGv_i64 fp0 = tcg_temp_new_i64();
8398
8399 gen_load_fpr64(ctx, fp0, fs);
8400 gen_helper_float_abs_ps(fp0, fp0);
8401 gen_store_fpr64(ctx, fp0, fd);
8402 tcg_temp_free_i64(fp0);
8403 }
8404 opn = "abs.ps";
8405 break;
8406 case OPC_MOV_PS:
8407 check_cp1_64bitmode(ctx);
8408 {
8409 TCGv_i64 fp0 = tcg_temp_new_i64();
8410
8411 gen_load_fpr64(ctx, fp0, fs);
8412 gen_store_fpr64(ctx, fp0, fd);
8413 tcg_temp_free_i64(fp0);
8414 }
8415 opn = "mov.ps";
8416 break;
8417 case OPC_NEG_PS:
8418 check_cp1_64bitmode(ctx);
8419 {
8420 TCGv_i64 fp0 = tcg_temp_new_i64();
8421
8422 gen_load_fpr64(ctx, fp0, fs);
8423 gen_helper_float_chs_ps(fp0, fp0);
8424 gen_store_fpr64(ctx, fp0, fd);
8425 tcg_temp_free_i64(fp0);
8426 }
8427 opn = "neg.ps";
8428 break;
8429 case OPC_MOVCF_PS:
8430 check_cp1_64bitmode(ctx);
8431 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8432 opn = "movcf.ps";
8433 break;
8434 case OPC_MOVZ_PS:
8435 check_cp1_64bitmode(ctx);
8436 {
8437 int l1 = gen_new_label();
8438 TCGv_i64 fp0;
8439
8440 if (ft != 0)
8441 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8442 fp0 = tcg_temp_new_i64();
8443 gen_load_fpr64(ctx, fp0, fs);
8444 gen_store_fpr64(ctx, fp0, fd);
8445 tcg_temp_free_i64(fp0);
8446 gen_set_label(l1);
8447 }
8448 opn = "movz.ps";
8449 break;
8450 case OPC_MOVN_PS:
8451 check_cp1_64bitmode(ctx);
8452 {
8453 int l1 = gen_new_label();
8454 TCGv_i64 fp0;
8455
8456 if (ft != 0) {
8457 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8458 fp0 = tcg_temp_new_i64();
8459 gen_load_fpr64(ctx, fp0, fs);
8460 gen_store_fpr64(ctx, fp0, fd);
8461 tcg_temp_free_i64(fp0);
8462 gen_set_label(l1);
8463 }
8464 }
8465 opn = "movn.ps";
8466 break;
8467 case OPC_ADDR_PS:
8468 check_cp1_64bitmode(ctx);
8469 {
8470 TCGv_i64 fp0 = tcg_temp_new_i64();
8471 TCGv_i64 fp1 = tcg_temp_new_i64();
8472
8473 gen_load_fpr64(ctx, fp0, ft);
8474 gen_load_fpr64(ctx, fp1, fs);
8475 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8476 tcg_temp_free_i64(fp1);
8477 gen_store_fpr64(ctx, fp0, fd);
8478 tcg_temp_free_i64(fp0);
8479 }
8480 opn = "addr.ps";
8481 break;
8482 case OPC_MULR_PS:
8483 check_cp1_64bitmode(ctx);
8484 {
8485 TCGv_i64 fp0 = tcg_temp_new_i64();
8486 TCGv_i64 fp1 = tcg_temp_new_i64();
8487
8488 gen_load_fpr64(ctx, fp0, ft);
8489 gen_load_fpr64(ctx, fp1, fs);
8490 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8491 tcg_temp_free_i64(fp1);
8492 gen_store_fpr64(ctx, fp0, fd);
8493 tcg_temp_free_i64(fp0);
8494 }
8495 opn = "mulr.ps";
8496 break;
8497 case OPC_RECIP2_PS:
8498 check_cp1_64bitmode(ctx);
8499 {
8500 TCGv_i64 fp0 = tcg_temp_new_i64();
8501 TCGv_i64 fp1 = tcg_temp_new_i64();
8502
8503 gen_load_fpr64(ctx, fp0, fs);
8504 gen_load_fpr64(ctx, fp1, ft);
8505 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8506 tcg_temp_free_i64(fp1);
8507 gen_store_fpr64(ctx, fp0, fd);
8508 tcg_temp_free_i64(fp0);
8509 }
8510 opn = "recip2.ps";
8511 break;
8512 case OPC_RECIP1_PS:
8513 check_cp1_64bitmode(ctx);
8514 {
8515 TCGv_i64 fp0 = tcg_temp_new_i64();
8516
8517 gen_load_fpr64(ctx, fp0, fs);
8518 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8519 gen_store_fpr64(ctx, fp0, fd);
8520 tcg_temp_free_i64(fp0);
8521 }
8522 opn = "recip1.ps";
8523 break;
8524 case OPC_RSQRT1_PS:
8525 check_cp1_64bitmode(ctx);
8526 {
8527 TCGv_i64 fp0 = tcg_temp_new_i64();
8528
8529 gen_load_fpr64(ctx, fp0, fs);
8530 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8531 gen_store_fpr64(ctx, fp0, fd);
8532 tcg_temp_free_i64(fp0);
8533 }
8534 opn = "rsqrt1.ps";
8535 break;
8536 case OPC_RSQRT2_PS:
8537 check_cp1_64bitmode(ctx);
8538 {
8539 TCGv_i64 fp0 = tcg_temp_new_i64();
8540 TCGv_i64 fp1 = tcg_temp_new_i64();
8541
8542 gen_load_fpr64(ctx, fp0, fs);
8543 gen_load_fpr64(ctx, fp1, ft);
8544 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8545 tcg_temp_free_i64(fp1);
8546 gen_store_fpr64(ctx, fp0, fd);
8547 tcg_temp_free_i64(fp0);
8548 }
8549 opn = "rsqrt2.ps";
8550 break;
8551 case OPC_CVT_S_PU:
8552 check_cp1_64bitmode(ctx);
8553 {
8554 TCGv_i32 fp0 = tcg_temp_new_i32();
8555
8556 gen_load_fpr32h(fp0, fs);
8557 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8558 gen_store_fpr32(fp0, fd);
8559 tcg_temp_free_i32(fp0);
8560 }
8561 opn = "cvt.s.pu";
8562 break;
8563 case OPC_CVT_PW_PS:
8564 check_cp1_64bitmode(ctx);
8565 {
8566 TCGv_i64 fp0 = tcg_temp_new_i64();
8567
8568 gen_load_fpr64(ctx, fp0, fs);
8569 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8570 gen_store_fpr64(ctx, fp0, fd);
8571 tcg_temp_free_i64(fp0);
8572 }
8573 opn = "cvt.pw.ps";
8574 break;
8575 case OPC_CVT_S_PL:
8576 check_cp1_64bitmode(ctx);
8577 {
8578 TCGv_i32 fp0 = tcg_temp_new_i32();
8579
8580 gen_load_fpr32(fp0, fs);
8581 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8582 gen_store_fpr32(fp0, fd);
8583 tcg_temp_free_i32(fp0);
8584 }
8585 opn = "cvt.s.pl";
8586 break;
8587 case OPC_PLL_PS:
8588 check_cp1_64bitmode(ctx);
8589 {
8590 TCGv_i32 fp0 = tcg_temp_new_i32();
8591 TCGv_i32 fp1 = tcg_temp_new_i32();
8592
8593 gen_load_fpr32(fp0, fs);
8594 gen_load_fpr32(fp1, ft);
8595 gen_store_fpr32h(fp0, fd);
8596 gen_store_fpr32(fp1, fd);
8597 tcg_temp_free_i32(fp0);
8598 tcg_temp_free_i32(fp1);
8599 }
8600 opn = "pll.ps";
8601 break;
8602 case OPC_PLU_PS:
8603 check_cp1_64bitmode(ctx);
8604 {
8605 TCGv_i32 fp0 = tcg_temp_new_i32();
8606 TCGv_i32 fp1 = tcg_temp_new_i32();
8607
8608 gen_load_fpr32(fp0, fs);
8609 gen_load_fpr32h(fp1, ft);
8610 gen_store_fpr32(fp1, fd);
8611 gen_store_fpr32h(fp0, fd);
8612 tcg_temp_free_i32(fp0);
8613 tcg_temp_free_i32(fp1);
8614 }
8615 opn = "plu.ps";
8616 break;
8617 case OPC_PUL_PS:
8618 check_cp1_64bitmode(ctx);
8619 {
8620 TCGv_i32 fp0 = tcg_temp_new_i32();
8621 TCGv_i32 fp1 = tcg_temp_new_i32();
8622
8623 gen_load_fpr32h(fp0, fs);
8624 gen_load_fpr32(fp1, ft);
8625 gen_store_fpr32(fp1, fd);
8626 gen_store_fpr32h(fp0, fd);
8627 tcg_temp_free_i32(fp0);
8628 tcg_temp_free_i32(fp1);
8629 }
8630 opn = "pul.ps";
8631 break;
8632 case OPC_PUU_PS:
8633 check_cp1_64bitmode(ctx);
8634 {
8635 TCGv_i32 fp0 = tcg_temp_new_i32();
8636 TCGv_i32 fp1 = tcg_temp_new_i32();
8637
8638 gen_load_fpr32h(fp0, fs);
8639 gen_load_fpr32h(fp1, ft);
8640 gen_store_fpr32(fp1, fd);
8641 gen_store_fpr32h(fp0, fd);
8642 tcg_temp_free_i32(fp0);
8643 tcg_temp_free_i32(fp1);
8644 }
8645 opn = "puu.ps";
8646 break;
8647 case OPC_CMP_F_PS:
8648 case OPC_CMP_UN_PS:
8649 case OPC_CMP_EQ_PS:
8650 case OPC_CMP_UEQ_PS:
8651 case OPC_CMP_OLT_PS:
8652 case OPC_CMP_ULT_PS:
8653 case OPC_CMP_OLE_PS:
8654 case OPC_CMP_ULE_PS:
8655 case OPC_CMP_SF_PS:
8656 case OPC_CMP_NGLE_PS:
8657 case OPC_CMP_SEQ_PS:
8658 case OPC_CMP_NGL_PS:
8659 case OPC_CMP_LT_PS:
8660 case OPC_CMP_NGE_PS:
8661 case OPC_CMP_LE_PS:
8662 case OPC_CMP_NGT_PS:
8663 if (ctx->opcode & (1 << 6)) {
8664 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8665 opn = condnames_abs[func-48];
8666 } else {
8667 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8668 opn = condnames[func-48];
8669 }
8670 break;
8671 default:
8672 MIPS_INVAL(opn);
8673 generate_exception (ctx, EXCP_RI);
8674 return;
8675 }
8676 (void)opn; /* avoid a compiler warning */
8677 switch (optype) {
8678 case BINOP:
8679 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8680 break;
8681 case CMPOP:
8682 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8683 break;
8684 default:
8685 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8686 break;
8687 }
8688 }
8689
8690 /* Coprocessor 3 (FPU) */
8691 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8692 int fd, int fs, int base, int index)
8693 {
8694 const char *opn = "extended float load/store";
8695 int store = 0;
8696 TCGv t0 = tcg_temp_new();
8697
8698 if (base == 0) {
8699 gen_load_gpr(t0, index);
8700 } else if (index == 0) {
8701 gen_load_gpr(t0, base);
8702 } else {
8703 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8704 }
8705 /* Don't do NOP if destination is zero: we must perform the actual
8706 memory access. */
8707 switch (opc) {
8708 case OPC_LWXC1:
8709 check_cop1x(ctx);
8710 {
8711 TCGv_i32 fp0 = tcg_temp_new_i32();
8712
8713 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8714 tcg_gen_trunc_tl_i32(fp0, t0);
8715 gen_store_fpr32(fp0, fd);
8716 tcg_temp_free_i32(fp0);
8717 }
8718 opn = "lwxc1";
8719 break;
8720 case OPC_LDXC1:
8721 check_cop1x(ctx);
8722 check_cp1_registers(ctx, fd);
8723 {
8724 TCGv_i64 fp0 = tcg_temp_new_i64();
8725
8726 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8727 gen_store_fpr64(ctx, fp0, fd);
8728 tcg_temp_free_i64(fp0);
8729 }
8730 opn = "ldxc1";
8731 break;
8732 case OPC_LUXC1:
8733 check_cp1_64bitmode(ctx);
8734 tcg_gen_andi_tl(t0, t0, ~0x7);
8735 {
8736 TCGv_i64 fp0 = tcg_temp_new_i64();
8737
8738 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8739 gen_store_fpr64(ctx, fp0, fd);
8740 tcg_temp_free_i64(fp0);
8741 }
8742 opn = "luxc1";
8743 break;
8744 case OPC_SWXC1:
8745 check_cop1x(ctx);
8746 {
8747 TCGv_i32 fp0 = tcg_temp_new_i32();
8748 TCGv t1 = tcg_temp_new();
8749
8750 gen_load_fpr32(fp0, fs);
8751 tcg_gen_extu_i32_tl(t1, fp0);
8752 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8753 tcg_temp_free_i32(fp0);
8754 tcg_temp_free(t1);
8755 }
8756 opn = "swxc1";
8757 store = 1;
8758 break;
8759 case OPC_SDXC1:
8760 check_cop1x(ctx);
8761 check_cp1_registers(ctx, fs);
8762 {
8763 TCGv_i64 fp0 = tcg_temp_new_i64();
8764
8765 gen_load_fpr64(ctx, fp0, fs);
8766 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8767 tcg_temp_free_i64(fp0);
8768 }
8769 opn = "sdxc1";
8770 store = 1;
8771 break;
8772 case OPC_SUXC1:
8773 check_cp1_64bitmode(ctx);
8774 tcg_gen_andi_tl(t0, t0, ~0x7);
8775 {
8776 TCGv_i64 fp0 = tcg_temp_new_i64();
8777
8778 gen_load_fpr64(ctx, fp0, fs);
8779 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8780 tcg_temp_free_i64(fp0);
8781 }
8782 opn = "suxc1";
8783 store = 1;
8784 break;
8785 }
8786 tcg_temp_free(t0);
8787 (void)opn; (void)store; /* avoid compiler warnings */
8788 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8789 regnames[index], regnames[base]);
8790 }
8791
8792 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8793 int fd, int fr, int fs, int ft)
8794 {
8795 const char *opn = "flt3_arith";
8796
8797 switch (opc) {
8798 case OPC_ALNV_PS:
8799 check_cp1_64bitmode(ctx);
8800 {
8801 TCGv t0 = tcg_temp_local_new();
8802 TCGv_i32 fp = tcg_temp_new_i32();
8803 TCGv_i32 fph = tcg_temp_new_i32();
8804 int l1 = gen_new_label();
8805 int l2 = gen_new_label();
8806
8807 gen_load_gpr(t0, fr);
8808 tcg_gen_andi_tl(t0, t0, 0x7);
8809
8810 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8811 gen_load_fpr32(fp, fs);
8812 gen_load_fpr32h(fph, fs);
8813 gen_store_fpr32(fp, fd);
8814 gen_store_fpr32h(fph, fd);
8815 tcg_gen_br(l2);
8816 gen_set_label(l1);
8817 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8818 tcg_temp_free(t0);
8819 #ifdef TARGET_WORDS_BIGENDIAN
8820 gen_load_fpr32(fp, fs);
8821 gen_load_fpr32h(fph, ft);
8822 gen_store_fpr32h(fp, fd);
8823 gen_store_fpr32(fph, fd);
8824 #else
8825 gen_load_fpr32h(fph, fs);
8826 gen_load_fpr32(fp, ft);
8827 gen_store_fpr32(fph, fd);
8828 gen_store_fpr32h(fp, fd);
8829 #endif
8830 gen_set_label(l2);
8831 tcg_temp_free_i32(fp);
8832 tcg_temp_free_i32(fph);
8833 }
8834 opn = "alnv.ps";
8835 break;
8836 case OPC_MADD_S:
8837 check_cop1x(ctx);
8838 {
8839 TCGv_i32 fp0 = tcg_temp_new_i32();
8840 TCGv_i32 fp1 = tcg_temp_new_i32();
8841 TCGv_i32 fp2 = tcg_temp_new_i32();
8842
8843 gen_load_fpr32(fp0, fs);
8844 gen_load_fpr32(fp1, ft);
8845 gen_load_fpr32(fp2, fr);
8846 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8847 tcg_temp_free_i32(fp0);
8848 tcg_temp_free_i32(fp1);
8849 gen_store_fpr32(fp2, fd);
8850 tcg_temp_free_i32(fp2);
8851 }
8852 opn = "madd.s";
8853 break;
8854 case OPC_MADD_D:
8855 check_cop1x(ctx);
8856 check_cp1_registers(ctx, fd | fs | ft | fr);
8857 {
8858 TCGv_i64 fp0 = tcg_temp_new_i64();
8859 TCGv_i64 fp1 = tcg_temp_new_i64();
8860 TCGv_i64 fp2 = tcg_temp_new_i64();
8861
8862 gen_load_fpr64(ctx, fp0, fs);
8863 gen_load_fpr64(ctx, fp1, ft);
8864 gen_load_fpr64(ctx, fp2, fr);
8865 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8866 tcg_temp_free_i64(fp0);
8867 tcg_temp_free_i64(fp1);
8868 gen_store_fpr64(ctx, fp2, fd);
8869 tcg_temp_free_i64(fp2);
8870 }
8871 opn = "madd.d";
8872 break;
8873 case OPC_MADD_PS:
8874 check_cp1_64bitmode(ctx);
8875 {
8876 TCGv_i64 fp0 = tcg_temp_new_i64();
8877 TCGv_i64 fp1 = tcg_temp_new_i64();
8878 TCGv_i64 fp2 = tcg_temp_new_i64();
8879
8880 gen_load_fpr64(ctx, fp0, fs);
8881 gen_load_fpr64(ctx, fp1, ft);
8882 gen_load_fpr64(ctx, fp2, fr);
8883 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8884 tcg_temp_free_i64(fp0);
8885 tcg_temp_free_i64(fp1);
8886 gen_store_fpr64(ctx, fp2, fd);
8887 tcg_temp_free_i64(fp2);
8888 }
8889 opn = "madd.ps";
8890 break;
8891 case OPC_MSUB_S:
8892 check_cop1x(ctx);
8893 {
8894 TCGv_i32 fp0 = tcg_temp_new_i32();
8895 TCGv_i32 fp1 = tcg_temp_new_i32();
8896 TCGv_i32 fp2 = tcg_temp_new_i32();
8897
8898 gen_load_fpr32(fp0, fs);
8899 gen_load_fpr32(fp1, ft);
8900 gen_load_fpr32(fp2, fr);
8901 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8902 tcg_temp_free_i32(fp0);
8903 tcg_temp_free_i32(fp1);
8904 gen_store_fpr32(fp2, fd);
8905 tcg_temp_free_i32(fp2);
8906 }
8907 opn = "msub.s";
8908 break;
8909 case OPC_MSUB_D:
8910 check_cop1x(ctx);
8911 check_cp1_registers(ctx, fd | fs | ft | fr);
8912 {
8913 TCGv_i64 fp0 = tcg_temp_new_i64();
8914 TCGv_i64 fp1 = tcg_temp_new_i64();
8915 TCGv_i64 fp2 = tcg_temp_new_i64();
8916
8917 gen_load_fpr64(ctx, fp0, fs);
8918 gen_load_fpr64(ctx, fp1, ft);
8919 gen_load_fpr64(ctx, fp2, fr);
8920 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8921 tcg_temp_free_i64(fp0);
8922 tcg_temp_free_i64(fp1);
8923 gen_store_fpr64(ctx, fp2, fd);
8924 tcg_temp_free_i64(fp2);
8925 }
8926 opn = "msub.d";
8927 break;
8928 case OPC_MSUB_PS:
8929 check_cp1_64bitmode(ctx);
8930 {
8931 TCGv_i64 fp0 = tcg_temp_new_i64();
8932 TCGv_i64 fp1 = tcg_temp_new_i64();
8933 TCGv_i64 fp2 = tcg_temp_new_i64();
8934
8935 gen_load_fpr64(ctx, fp0, fs);
8936 gen_load_fpr64(ctx, fp1, ft);
8937 gen_load_fpr64(ctx, fp2, fr);
8938 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8939 tcg_temp_free_i64(fp0);
8940 tcg_temp_free_i64(fp1);
8941 gen_store_fpr64(ctx, fp2, fd);
8942 tcg_temp_free_i64(fp2);
8943 }
8944 opn = "msub.ps";
8945 break;
8946 case OPC_NMADD_S:
8947 check_cop1x(ctx);
8948 {
8949 TCGv_i32 fp0 = tcg_temp_new_i32();
8950 TCGv_i32 fp1 = tcg_temp_new_i32();
8951 TCGv_i32 fp2 = tcg_temp_new_i32();
8952
8953 gen_load_fpr32(fp0, fs);
8954 gen_load_fpr32(fp1, ft);
8955 gen_load_fpr32(fp2, fr);
8956 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8957 tcg_temp_free_i32(fp0);
8958 tcg_temp_free_i32(fp1);
8959 gen_store_fpr32(fp2, fd);
8960 tcg_temp_free_i32(fp2);
8961 }
8962 opn = "nmadd.s";
8963 break;
8964 case OPC_NMADD_D:
8965 check_cop1x(ctx);
8966 check_cp1_registers(ctx, fd | fs | ft | fr);
8967 {
8968 TCGv_i64 fp0 = tcg_temp_new_i64();
8969 TCGv_i64 fp1 = tcg_temp_new_i64();
8970 TCGv_i64 fp2 = tcg_temp_new_i64();
8971
8972 gen_load_fpr64(ctx, fp0, fs);
8973 gen_load_fpr64(ctx, fp1, ft);
8974 gen_load_fpr64(ctx, fp2, fr);
8975 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8976 tcg_temp_free_i64(fp0);
8977 tcg_temp_free_i64(fp1);
8978 gen_store_fpr64(ctx, fp2, fd);
8979 tcg_temp_free_i64(fp2);
8980 }
8981 opn = "nmadd.d";
8982 break;
8983 case OPC_NMADD_PS:
8984 check_cp1_64bitmode(ctx);
8985 {
8986 TCGv_i64 fp0 = tcg_temp_new_i64();
8987 TCGv_i64 fp1 = tcg_temp_new_i64();
8988 TCGv_i64 fp2 = tcg_temp_new_i64();
8989
8990 gen_load_fpr64(ctx, fp0, fs);
8991 gen_load_fpr64(ctx, fp1, ft);
8992 gen_load_fpr64(ctx, fp2, fr);
8993 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8994 tcg_temp_free_i64(fp0);
8995 tcg_temp_free_i64(fp1);
8996 gen_store_fpr64(ctx, fp2, fd);
8997 tcg_temp_free_i64(fp2);
8998 }
8999 opn = "nmadd.ps";
9000 break;
9001 case OPC_NMSUB_S:
9002 check_cop1x(ctx);
9003 {
9004 TCGv_i32 fp0 = tcg_temp_new_i32();
9005 TCGv_i32 fp1 = tcg_temp_new_i32();
9006 TCGv_i32 fp2 = tcg_temp_new_i32();
9007
9008 gen_load_fpr32(fp0, fs);
9009 gen_load_fpr32(fp1, ft);
9010 gen_load_fpr32(fp2, fr);
9011 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
9012 tcg_temp_free_i32(fp0);
9013 tcg_temp_free_i32(fp1);
9014 gen_store_fpr32(fp2, fd);
9015 tcg_temp_free_i32(fp2);
9016 }
9017 opn = "nmsub.s";
9018 break;
9019 case OPC_NMSUB_D:
9020 check_cop1x(ctx);
9021 check_cp1_registers(ctx, fd | fs | ft | fr);
9022 {
9023 TCGv_i64 fp0 = tcg_temp_new_i64();
9024 TCGv_i64 fp1 = tcg_temp_new_i64();
9025 TCGv_i64 fp2 = tcg_temp_new_i64();
9026
9027 gen_load_fpr64(ctx, fp0, fs);
9028 gen_load_fpr64(ctx, fp1, ft);
9029 gen_load_fpr64(ctx, fp2, fr);
9030 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
9031 tcg_temp_free_i64(fp0);
9032 tcg_temp_free_i64(fp1);
9033 gen_store_fpr64(ctx, fp2, fd);
9034 tcg_temp_free_i64(fp2);
9035 }
9036 opn = "nmsub.d";
9037 break;
9038 case OPC_NMSUB_PS:
9039 check_cp1_64bitmode(ctx);
9040 {
9041 TCGv_i64 fp0 = tcg_temp_new_i64();
9042 TCGv_i64 fp1 = tcg_temp_new_i64();
9043 TCGv_i64 fp2 = tcg_temp_new_i64();
9044
9045 gen_load_fpr64(ctx, fp0, fs);
9046 gen_load_fpr64(ctx, fp1, ft);
9047 gen_load_fpr64(ctx, fp2, fr);
9048 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9049 tcg_temp_free_i64(fp0);
9050 tcg_temp_free_i64(fp1);
9051 gen_store_fpr64(ctx, fp2, fd);
9052 tcg_temp_free_i64(fp2);
9053 }
9054 opn = "nmsub.ps";
9055 break;
9056 default:
9057 MIPS_INVAL(opn);
9058 generate_exception (ctx, EXCP_RI);
9059 return;
9060 }
9061 (void)opn; /* avoid a compiler warning */
9062 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9063 fregnames[fs], fregnames[ft]);
9064 }
9065
9066 static void
9067 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9068 {
9069 TCGv t0;
9070
9071 #if !defined(CONFIG_USER_ONLY)
9072 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9073 Therefore only check the ISA in system mode. */
9074 check_insn(env, ctx, ISA_MIPS32R2);
9075 #endif
9076 t0 = tcg_temp_new();
9077
9078 switch (rd) {
9079 case 0:
9080 save_cpu_state(ctx, 1);
9081 gen_helper_rdhwr_cpunum(t0, cpu_env);
9082 gen_store_gpr(t0, rt);
9083 break;
9084 case 1:
9085 save_cpu_state(ctx, 1);
9086 gen_helper_rdhwr_synci_step(t0, cpu_env);
9087 gen_store_gpr(t0, rt);
9088 break;
9089 case 2:
9090 save_cpu_state(ctx, 1);
9091 gen_helper_rdhwr_cc(t0, cpu_env);
9092 gen_store_gpr(t0, rt);
9093 break;
9094 case 3:
9095 save_cpu_state(ctx, 1);
9096 gen_helper_rdhwr_ccres(t0, cpu_env);
9097 gen_store_gpr(t0, rt);
9098 break;
9099 case 29:
9100 #if defined(CONFIG_USER_ONLY)
9101 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9102 gen_store_gpr(t0, rt);
9103 break;
9104 #else
9105 /* XXX: Some CPUs implement this in hardware.
9106 Not supported yet. */
9107 #endif
9108 default: /* Invalid */
9109 MIPS_INVAL("rdhwr");
9110 generate_exception(ctx, EXCP_RI);
9111 break;
9112 }
9113 tcg_temp_free(t0);
9114 }
9115
9116 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9117 int insn_bytes)
9118 {
9119 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9120 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9121 /* Branches completion */
9122 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9123 ctx->bstate = BS_BRANCH;
9124 save_cpu_state(ctx, 0);
9125 /* FIXME: Need to clear can_do_io. */
9126 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9127 case MIPS_HFLAG_B:
9128 /* unconditional branch */
9129 MIPS_DEBUG("unconditional branch");
9130 if (proc_hflags & MIPS_HFLAG_BX) {
9131 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9132 }
9133 gen_goto_tb(ctx, 0, ctx->btarget);
9134 break;
9135 case MIPS_HFLAG_BL:
9136 /* blikely taken case */
9137 MIPS_DEBUG("blikely branch taken");
9138 gen_goto_tb(ctx, 0, ctx->btarget);
9139 break;
9140 case MIPS_HFLAG_BC:
9141 /* Conditional branch */
9142 MIPS_DEBUG("conditional branch");
9143 {
9144 int l1 = gen_new_label();
9145
9146 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9147 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9148 gen_set_label(l1);
9149 gen_goto_tb(ctx, 0, ctx->btarget);
9150 }
9151 break;
9152 case MIPS_HFLAG_BR:
9153 /* unconditional branch to register */
9154 MIPS_DEBUG("branch to register");
9155 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9156 TCGv t0 = tcg_temp_new();
9157 TCGv_i32 t1 = tcg_temp_new_i32();
9158
9159 tcg_gen_andi_tl(t0, btarget, 0x1);
9160 tcg_gen_trunc_tl_i32(t1, t0);
9161 tcg_temp_free(t0);
9162 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9163 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9164 tcg_gen_or_i32(hflags, hflags, t1);
9165 tcg_temp_free_i32(t1);
9166
9167 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9168 } else {
9169 tcg_gen_mov_tl(cpu_PC, btarget);
9170 }
9171 if (ctx->singlestep_enabled) {
9172 save_cpu_state(ctx, 0);
9173 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9174 }
9175 tcg_gen_exit_tb(0);
9176 break;
9177 default:
9178 MIPS_DEBUG("unknown branch");
9179 break;
9180 }
9181 }
9182 }
9183
9184 /* ISA extensions (ASEs) */
9185 /* MIPS16 extension to MIPS32 */
9186
9187 /* MIPS16 major opcodes */
9188 enum {
9189 M16_OPC_ADDIUSP = 0x00,
9190 M16_OPC_ADDIUPC = 0x01,
9191 M16_OPC_B = 0x02,
9192 M16_OPC_JAL = 0x03,
9193 M16_OPC_BEQZ = 0x04,
9194 M16_OPC_BNEQZ = 0x05,
9195 M16_OPC_SHIFT = 0x06,
9196 M16_OPC_LD = 0x07,
9197 M16_OPC_RRIA = 0x08,
9198 M16_OPC_ADDIU8 = 0x09,
9199 M16_OPC_SLTI = 0x0a,
9200 M16_OPC_SLTIU = 0x0b,
9201 M16_OPC_I8 = 0x0c,
9202 M16_OPC_LI = 0x0d,
9203 M16_OPC_CMPI = 0x0e,
9204 M16_OPC_SD = 0x0f,
9205 M16_OPC_LB = 0x10,
9206 M16_OPC_LH = 0x11,
9207 M16_OPC_LWSP = 0x12,
9208 M16_OPC_LW = 0x13,
9209 M16_OPC_LBU = 0x14,
9210 M16_OPC_LHU = 0x15,
9211 M16_OPC_LWPC = 0x16,
9212 M16_OPC_LWU = 0x17,
9213 M16_OPC_SB = 0x18,
9214 M16_OPC_SH = 0x19,
9215 M16_OPC_SWSP = 0x1a,
9216 M16_OPC_SW = 0x1b,
9217 M16_OPC_RRR = 0x1c,
9218 M16_OPC_RR = 0x1d,
9219 M16_OPC_EXTEND = 0x1e,
9220 M16_OPC_I64 = 0x1f
9221 };
9222
9223 /* I8 funct field */
9224 enum {
9225 I8_BTEQZ = 0x0,
9226 I8_BTNEZ = 0x1,
9227 I8_SWRASP = 0x2,
9228 I8_ADJSP = 0x3,
9229 I8_SVRS = 0x4,
9230 I8_MOV32R = 0x5,
9231 I8_MOVR32 = 0x7
9232 };
9233
9234 /* RRR f field */
9235 enum {
9236 RRR_DADDU = 0x0,
9237 RRR_ADDU = 0x1,
9238 RRR_DSUBU = 0x2,
9239 RRR_SUBU = 0x3
9240 };
9241
9242 /* RR funct field */
9243 enum {
9244 RR_JR = 0x00,
9245 RR_SDBBP = 0x01,
9246 RR_SLT = 0x02,
9247 RR_SLTU = 0x03,
9248 RR_SLLV = 0x04,
9249 RR_BREAK = 0x05,
9250 RR_SRLV = 0x06,
9251 RR_SRAV = 0x07,
9252 RR_DSRL = 0x08,
9253 RR_CMP = 0x0a,
9254 RR_NEG = 0x0b,
9255 RR_AND = 0x0c,
9256 RR_OR = 0x0d,
9257 RR_XOR = 0x0e,
9258 RR_NOT = 0x0f,
9259 RR_MFHI = 0x10,
9260 RR_CNVT = 0x11,
9261 RR_MFLO = 0x12,
9262 RR_DSRA = 0x13,
9263 RR_DSLLV = 0x14,
9264 RR_DSRLV = 0x16,
9265 RR_DSRAV = 0x17,
9266 RR_MULT = 0x18,
9267 RR_MULTU = 0x19,
9268 RR_DIV = 0x1a,
9269 RR_DIVU = 0x1b,
9270 RR_DMULT = 0x1c,
9271 RR_DMULTU = 0x1d,
9272 RR_DDIV = 0x1e,
9273 RR_DDIVU = 0x1f
9274 };
9275
9276 /* I64 funct field */
9277 enum {
9278 I64_LDSP = 0x0,
9279 I64_SDSP = 0x1,
9280 I64_SDRASP = 0x2,
9281 I64_DADJSP = 0x3,
9282 I64_LDPC = 0x4,
9283 I64_DADDIU5 = 0x5,
9284 I64_DADDIUPC = 0x6,
9285 I64_DADDIUSP = 0x7
9286 };
9287
9288 /* RR ry field for CNVT */
9289 enum {
9290 RR_RY_CNVT_ZEB = 0x0,
9291 RR_RY_CNVT_ZEH = 0x1,
9292 RR_RY_CNVT_ZEW = 0x2,
9293 RR_RY_CNVT_SEB = 0x4,
9294 RR_RY_CNVT_SEH = 0x5,
9295 RR_RY_CNVT_SEW = 0x6,
9296 };
9297
9298 static int xlat (int r)
9299 {
9300 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9301
9302 return map[r];
9303 }
9304
9305 static void gen_mips16_save (DisasContext *ctx,
9306 int xsregs, int aregs,
9307 int do_ra, int do_s0, int do_s1,
9308 int framesize)
9309 {
9310 TCGv t0 = tcg_temp_new();
9311 TCGv t1 = tcg_temp_new();
9312 int args, astatic;
9313
9314 switch (aregs) {
9315 case 0:
9316 case 1:
9317 case 2:
9318 case 3:
9319 case 11:
9320 args = 0;
9321 break;
9322 case 4:
9323 case 5:
9324 case 6:
9325 case 7:
9326 args = 1;
9327 break;
9328 case 8:
9329 case 9:
9330 case 10:
9331 args = 2;
9332 break;
9333 case 12:
9334 case 13:
9335 args = 3;
9336 break;
9337 case 14:
9338 args = 4;
9339 break;
9340 default:
9341 generate_exception(ctx, EXCP_RI);
9342 return;
9343 }
9344
9345 switch (args) {
9346 case 4:
9347 gen_base_offset_addr(ctx, t0, 29, 12);
9348 gen_load_gpr(t1, 7);
9349 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9350 /* Fall through */
9351 case 3:
9352 gen_base_offset_addr(ctx, t0, 29, 8);
9353 gen_load_gpr(t1, 6);
9354 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9355 /* Fall through */
9356 case 2:
9357 gen_base_offset_addr(ctx, t0, 29, 4);
9358 gen_load_gpr(t1, 5);
9359 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9360 /* Fall through */
9361 case 1:
9362 gen_base_offset_addr(ctx, t0, 29, 0);
9363 gen_load_gpr(t1, 4);
9364 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9365 }
9366
9367 gen_load_gpr(t0, 29);
9368
9369 #define DECR_AND_STORE(reg) do { \
9370 tcg_gen_subi_tl(t0, t0, 4); \
9371 gen_load_gpr(t1, reg); \
9372 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9373 } while (0)
9374
9375 if (do_ra) {
9376 DECR_AND_STORE(31);
9377 }
9378
9379 switch (xsregs) {
9380 case 7:
9381 DECR_AND_STORE(30);
9382 /* Fall through */
9383 case 6:
9384 DECR_AND_STORE(23);
9385 /* Fall through */
9386 case 5:
9387 DECR_AND_STORE(22);
9388 /* Fall through */
9389 case 4:
9390 DECR_AND_STORE(21);
9391 /* Fall through */
9392 case 3:
9393 DECR_AND_STORE(20);
9394 /* Fall through */
9395 case 2:
9396 DECR_AND_STORE(19);
9397 /* Fall through */
9398 case 1:
9399 DECR_AND_STORE(18);
9400 }
9401
9402 if (do_s1) {
9403 DECR_AND_STORE(17);
9404 }
9405 if (do_s0) {
9406 DECR_AND_STORE(16);
9407 }
9408
9409 switch (aregs) {
9410 case 0:
9411 case 4:
9412 case 8:
9413 case 12:
9414 case 14:
9415 astatic = 0;
9416 break;
9417 case 1:
9418 case 5:
9419 case 9:
9420 case 13:
9421 astatic = 1;
9422 break;
9423 case 2:
9424 case 6:
9425 case 10:
9426 astatic = 2;
9427 break;
9428 case 3:
9429 case 7:
9430 astatic = 3;
9431 break;
9432 case 11:
9433 astatic = 4;
9434 break;
9435 default:
9436 generate_exception(ctx, EXCP_RI);
9437 return;
9438 }
9439
9440 if (astatic > 0) {
9441 DECR_AND_STORE(7);
9442 if (astatic > 1) {
9443 DECR_AND_STORE(6);
9444 if (astatic > 2) {
9445 DECR_AND_STORE(5);
9446 if (astatic > 3) {
9447 DECR_AND_STORE(4);
9448 }
9449 }
9450 }
9451 }
9452 #undef DECR_AND_STORE
9453
9454 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9455 tcg_temp_free(t0);
9456 tcg_temp_free(t1);
9457 }
9458
9459 static void gen_mips16_restore (DisasContext *ctx,
9460 int xsregs, int aregs,
9461 int do_ra, int do_s0, int do_s1,
9462 int framesize)
9463 {
9464 int astatic;
9465 TCGv t0 = tcg_temp_new();
9466 TCGv t1 = tcg_temp_new();
9467
9468 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9469
9470 #define DECR_AND_LOAD(reg) do { \
9471 tcg_gen_subi_tl(t0, t0, 4); \
9472 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9473 gen_store_gpr(t1, reg); \
9474 } while (0)
9475
9476 if (do_ra) {
9477 DECR_AND_LOAD(31);
9478 }
9479
9480 switch (xsregs) {
9481 case 7:
9482 DECR_AND_LOAD(30);
9483 /* Fall through */
9484 case 6:
9485 DECR_AND_LOAD(23);
9486 /* Fall through */
9487 case 5:
9488 DECR_AND_LOAD(22);
9489 /* Fall through */
9490 case 4:
9491 DECR_AND_LOAD(21);
9492 /* Fall through */
9493 case 3:
9494 DECR_AND_LOAD(20);
9495 /* Fall through */
9496 case 2:
9497 DECR_AND_LOAD(19);
9498 /* Fall through */
9499 case 1:
9500 DECR_AND_LOAD(18);
9501 }
9502
9503 if (do_s1) {
9504 DECR_AND_LOAD(17);
9505 }
9506 if (do_s0) {
9507 DECR_AND_LOAD(16);
9508 }
9509
9510 switch (aregs) {
9511 case 0:
9512 case 4:
9513 case 8:
9514 case 12:
9515 case 14:
9516 astatic = 0;
9517 break;
9518 case 1:
9519 case 5:
9520 case 9:
9521 case 13:
9522 astatic = 1;
9523 break;
9524 case 2:
9525 case 6:
9526 case 10:
9527 astatic = 2;
9528 break;
9529 case 3:
9530 case 7:
9531 astatic = 3;
9532 break;
9533 case 11:
9534 astatic = 4;
9535 break;
9536 default:
9537 generate_exception(ctx, EXCP_RI);
9538 return;
9539 }
9540
9541 if (astatic > 0) {
9542 DECR_AND_LOAD(7);
9543 if (astatic > 1) {
9544 DECR_AND_LOAD(6);
9545 if (astatic > 2) {
9546 DECR_AND_LOAD(5);
9547 if (astatic > 3) {
9548 DECR_AND_LOAD(4);
9549 }
9550 }
9551 }
9552 }
9553 #undef DECR_AND_LOAD
9554
9555 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9556 tcg_temp_free(t0);
9557 tcg_temp_free(t1);
9558 }
9559
9560 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9561 int is_64_bit, int extended)
9562 {
9563 TCGv t0;
9564
9565 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9566 generate_exception(ctx, EXCP_RI);
9567 return;
9568 }
9569
9570 t0 = tcg_temp_new();
9571
9572 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9573 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9574 if (!is_64_bit) {
9575 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9576 }
9577
9578 tcg_temp_free(t0);
9579 }
9580
9581 #if defined(TARGET_MIPS64)
9582 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9583 int ry, int funct, int16_t offset,
9584 int extended)
9585 {
9586 switch (funct) {
9587 case I64_LDSP:
9588 check_mips_64(ctx);
9589 offset = extended ? offset : offset << 3;
9590 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9591 break;
9592 case I64_SDSP:
9593 check_mips_64(ctx);
9594 offset = extended ? offset : offset << 3;
9595 gen_st(ctx, OPC_SD, ry, 29, offset);
9596 break;
9597 case I64_SDRASP:
9598 check_mips_64(ctx);
9599 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9600 gen_st(ctx, OPC_SD, 31, 29, offset);
9601 break;
9602 case I64_DADJSP:
9603 check_mips_64(ctx);
9604 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9605 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9606 break;
9607 case I64_LDPC:
9608 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9609 generate_exception(ctx, EXCP_RI);
9610 } else {
9611 offset = extended ? offset : offset << 3;
9612 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9613 }
9614 break;
9615 case I64_DADDIU5:
9616 check_mips_64(ctx);
9617 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9618 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9619 break;
9620 case I64_DADDIUPC:
9621 check_mips_64(ctx);
9622 offset = extended ? offset : offset << 2;
9623 gen_addiupc(ctx, ry, offset, 1, extended);
9624 break;
9625 case I64_DADDIUSP:
9626 check_mips_64(ctx);
9627 offset = extended ? offset : offset << 2;
9628 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9629 break;
9630 }
9631 }
9632 #endif
9633
9634 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9635 int *is_branch)
9636 {
9637 int extend = cpu_lduw_code(env, ctx->pc + 2);
9638 int op, rx, ry, funct, sa;
9639 int16_t imm, offset;
9640
9641 ctx->opcode = (ctx->opcode << 16) | extend;
9642 op = (ctx->opcode >> 11) & 0x1f;
9643 sa = (ctx->opcode >> 22) & 0x1f;
9644 funct = (ctx->opcode >> 8) & 0x7;
9645 rx = xlat((ctx->opcode >> 8) & 0x7);
9646 ry = xlat((ctx->opcode >> 5) & 0x7);
9647 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9648 | ((ctx->opcode >> 21) & 0x3f) << 5
9649 | (ctx->opcode & 0x1f));
9650
9651 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9652 counterparts. */
9653 switch (op) {
9654 case M16_OPC_ADDIUSP:
9655 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9656 break;
9657 case M16_OPC_ADDIUPC:
9658 gen_addiupc(ctx, rx, imm, 0, 1);
9659 break;
9660 case M16_OPC_B:
9661 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9662 /* No delay slot, so just process as a normal instruction */
9663 break;
9664 case M16_OPC_BEQZ:
9665 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9666 /* No delay slot, so just process as a normal instruction */
9667 break;
9668 case M16_OPC_BNEQZ:
9669 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9670 /* No delay slot, so just process as a normal instruction */
9671 break;
9672 case M16_OPC_SHIFT:
9673 switch (ctx->opcode & 0x3) {
9674 case 0x0:
9675 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9676 break;
9677 case 0x1:
9678 #if defined(TARGET_MIPS64)
9679 check_mips_64(ctx);
9680 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9681 #else
9682 generate_exception(ctx, EXCP_RI);
9683 #endif
9684 break;
9685 case 0x2:
9686 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9687 break;
9688 case 0x3:
9689 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9690 break;
9691 }
9692 break;
9693 #if defined(TARGET_MIPS64)
9694 case M16_OPC_LD:
9695 check_mips_64(ctx);
9696 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9697 break;
9698 #endif
9699 case M16_OPC_RRIA:
9700 imm = ctx->opcode & 0xf;
9701 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9702 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9703 imm = (int16_t) (imm << 1) >> 1;
9704 if ((ctx->opcode >> 4) & 0x1) {
9705 #if defined(TARGET_MIPS64)
9706 check_mips_64(ctx);
9707 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9708 #else
9709 generate_exception(ctx, EXCP_RI);
9710 #endif
9711 } else {
9712 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9713 }
9714 break;
9715 case M16_OPC_ADDIU8:
9716 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9717 break;
9718 case M16_OPC_SLTI:
9719 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9720 break;
9721 case M16_OPC_SLTIU:
9722 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9723 break;
9724 case M16_OPC_I8:
9725 switch (funct) {
9726 case I8_BTEQZ:
9727 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9728 break;
9729 case I8_BTNEZ:
9730 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9731 break;
9732 case I8_SWRASP:
9733 gen_st(ctx, OPC_SW, 31, 29, imm);
9734 break;
9735 case I8_ADJSP:
9736 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9737 break;
9738 case I8_SVRS:
9739 {
9740 int xsregs = (ctx->opcode >> 24) & 0x7;
9741 int aregs = (ctx->opcode >> 16) & 0xf;
9742 int do_ra = (ctx->opcode >> 6) & 0x1;
9743 int do_s0 = (ctx->opcode >> 5) & 0x1;
9744 int do_s1 = (ctx->opcode >> 4) & 0x1;
9745 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9746 | (ctx->opcode & 0xf)) << 3;
9747
9748 if (ctx->opcode & (1 << 7)) {
9749 gen_mips16_save(ctx, xsregs, aregs,
9750 do_ra, do_s0, do_s1,
9751 framesize);
9752 } else {
9753 gen_mips16_restore(ctx, xsregs, aregs,
9754 do_ra, do_s0, do_s1,
9755 framesize);
9756 }
9757 }
9758 break;
9759 default:
9760 generate_exception(ctx, EXCP_RI);
9761 break;
9762 }
9763 break;
9764 case M16_OPC_LI:
9765 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9766 break;
9767 case M16_OPC_CMPI:
9768 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9769 break;
9770 #if defined(TARGET_MIPS64)
9771 case M16_OPC_SD:
9772 gen_st(ctx, OPC_SD, ry, rx, offset);
9773 break;
9774 #endif
9775 case M16_OPC_LB:
9776 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9777 break;
9778 case M16_OPC_LH:
9779 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9780 break;
9781 case M16_OPC_LWSP:
9782 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9783 break;
9784 case M16_OPC_LW:
9785 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9786 break;
9787 case M16_OPC_LBU:
9788 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9789 break;
9790 case M16_OPC_LHU:
9791 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9792 break;
9793 case M16_OPC_LWPC:
9794 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9795 break;
9796 #if defined(TARGET_MIPS64)
9797 case M16_OPC_LWU:
9798 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9799 break;
9800 #endif
9801 case M16_OPC_SB:
9802 gen_st(ctx, OPC_SB, ry, rx, offset);
9803 break;
9804 case M16_OPC_SH:
9805 gen_st(ctx, OPC_SH, ry, rx, offset);
9806 break;
9807 case M16_OPC_SWSP:
9808 gen_st(ctx, OPC_SW, rx, 29, offset);
9809 break;
9810 case M16_OPC_SW:
9811 gen_st(ctx, OPC_SW, ry, rx, offset);
9812 break;
9813 #if defined(TARGET_MIPS64)
9814 case M16_OPC_I64:
9815 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9816 break;
9817 #endif
9818 default:
9819 generate_exception(ctx, EXCP_RI);
9820 break;
9821 }
9822
9823 return 4;
9824 }
9825
9826 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9827 int *is_branch)
9828 {
9829 int rx, ry;
9830 int sa;
9831 int op, cnvt_op, op1, offset;
9832 int funct;
9833 int n_bytes;
9834
9835 op = (ctx->opcode >> 11) & 0x1f;
9836 sa = (ctx->opcode >> 2) & 0x7;
9837 sa = sa == 0 ? 8 : sa;
9838 rx = xlat((ctx->opcode >> 8) & 0x7);
9839 cnvt_op = (ctx->opcode >> 5) & 0x7;
9840 ry = xlat((ctx->opcode >> 5) & 0x7);
9841 op1 = offset = ctx->opcode & 0x1f;
9842
9843 n_bytes = 2;
9844
9845 switch (op) {
9846 case M16_OPC_ADDIUSP:
9847 {
9848 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9849
9850 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9851 }
9852 break;
9853 case M16_OPC_ADDIUPC:
9854 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9855 break;
9856 case M16_OPC_B:
9857 offset = (ctx->opcode & 0x7ff) << 1;
9858 offset = (int16_t)(offset << 4) >> 4;
9859 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9860 /* No delay slot, so just process as a normal instruction */
9861 break;
9862 case M16_OPC_JAL:
9863 offset = cpu_lduw_code(env, ctx->pc + 2);
9864 offset = (((ctx->opcode & 0x1f) << 21)
9865 | ((ctx->opcode >> 5) & 0x1f) << 16
9866 | offset) << 2;
9867 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9868 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9869 n_bytes = 4;
9870 *is_branch = 1;
9871 break;
9872 case M16_OPC_BEQZ:
9873 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9874 /* No delay slot, so just process as a normal instruction */
9875 break;
9876 case M16_OPC_BNEQZ:
9877 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9878 /* No delay slot, so just process as a normal instruction */
9879 break;
9880 case M16_OPC_SHIFT:
9881 switch (ctx->opcode & 0x3) {
9882 case 0x0:
9883 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9884 break;
9885 case 0x1:
9886 #if defined(TARGET_MIPS64)
9887 check_mips_64(ctx);
9888 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9889 #else
9890 generate_exception(ctx, EXCP_RI);
9891 #endif
9892 break;
9893 case 0x2:
9894 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9895 break;
9896 case 0x3:
9897 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9898 break;
9899 }
9900 break;
9901 #if defined(TARGET_MIPS64)
9902 case M16_OPC_LD:
9903 check_mips_64(ctx);
9904 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9905 break;
9906 #endif
9907 case M16_OPC_RRIA:
9908 {
9909 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9910
9911 if ((ctx->opcode >> 4) & 1) {
9912 #if defined(TARGET_MIPS64)
9913 check_mips_64(ctx);
9914 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9915 #else
9916 generate_exception(ctx, EXCP_RI);
9917 #endif
9918 } else {
9919 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9920 }
9921 }
9922 break;
9923 case M16_OPC_ADDIU8:
9924 {
9925 int16_t imm = (int8_t) ctx->opcode;
9926
9927 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9928 }
9929 break;
9930 case M16_OPC_SLTI:
9931 {
9932 int16_t imm = (uint8_t) ctx->opcode;
9933 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9934 }
9935 break;
9936 case M16_OPC_SLTIU:
9937 {
9938 int16_t imm = (uint8_t) ctx->opcode;
9939 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9940 }
9941 break;
9942 case M16_OPC_I8:
9943 {
9944 int reg32;
9945
9946 funct = (ctx->opcode >> 8) & 0x7;
9947 switch (funct) {
9948 case I8_BTEQZ:
9949 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9950 ((int8_t)ctx->opcode) << 1);
9951 break;
9952 case I8_BTNEZ:
9953 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9954 ((int8_t)ctx->opcode) << 1);
9955 break;
9956 case I8_SWRASP:
9957 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9958 break;
9959 case I8_ADJSP:
9960 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9961 ((int8_t)ctx->opcode) << 3);
9962 break;
9963 case I8_SVRS:
9964 {
9965 int do_ra = ctx->opcode & (1 << 6);
9966 int do_s0 = ctx->opcode & (1 << 5);
9967 int do_s1 = ctx->opcode & (1 << 4);
9968 int framesize = ctx->opcode & 0xf;
9969
9970 if (framesize == 0) {
9971 framesize = 128;
9972 } else {
9973 framesize = framesize << 3;
9974 }
9975
9976 if (ctx->opcode & (1 << 7)) {
9977 gen_mips16_save(ctx, 0, 0,
9978 do_ra, do_s0, do_s1, framesize);
9979 } else {
9980 gen_mips16_restore(ctx, 0, 0,
9981 do_ra, do_s0, do_s1, framesize);
9982 }
9983 }
9984 break;
9985 case I8_MOV32R:
9986 {
9987 int rz = xlat(ctx->opcode & 0x7);
9988
9989 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9990 ((ctx->opcode >> 5) & 0x7);
9991 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9992 }
9993 break;
9994 case I8_MOVR32:
9995 reg32 = ctx->opcode & 0x1f;
9996 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9997 break;
9998 default:
9999 generate_exception(ctx, EXCP_RI);
10000 break;
10001 }
10002 }
10003 break;
10004 case M16_OPC_LI:
10005 {
10006 int16_t imm = (uint8_t) ctx->opcode;
10007
10008 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
10009 }
10010 break;
10011 case M16_OPC_CMPI:
10012 {
10013 int16_t imm = (uint8_t) ctx->opcode;
10014 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
10015 }
10016 break;
10017 #if defined(TARGET_MIPS64)
10018 case M16_OPC_SD:
10019 check_mips_64(ctx);
10020 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
10021 break;
10022 #endif
10023 case M16_OPC_LB:
10024 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
10025 break;
10026 case M16_OPC_LH:
10027 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
10028 break;
10029 case M16_OPC_LWSP:
10030 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10031 break;
10032 case M16_OPC_LW:
10033 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
10034 break;
10035 case M16_OPC_LBU:
10036 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10037 break;
10038 case M16_OPC_LHU:
10039 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10040 break;
10041 case M16_OPC_LWPC:
10042 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10043 break;
10044 #if defined (TARGET_MIPS64)
10045 case M16_OPC_LWU:
10046 check_mips_64(ctx);
10047 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10048 break;
10049 #endif
10050 case M16_OPC_SB:
10051 gen_st(ctx, OPC_SB, ry, rx, offset);
10052 break;
10053 case M16_OPC_SH:
10054 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10055 break;
10056 case M16_OPC_SWSP:
10057 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10058 break;
10059 case M16_OPC_SW:
10060 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10061 break;
10062 case M16_OPC_RRR:
10063 {
10064 int rz = xlat((ctx->opcode >> 2) & 0x7);
10065 int mips32_op;
10066
10067 switch (ctx->opcode & 0x3) {
10068 case RRR_ADDU:
10069 mips32_op = OPC_ADDU;
10070 break;
10071 case RRR_SUBU:
10072 mips32_op = OPC_SUBU;
10073 break;
10074 #if defined(TARGET_MIPS64)
10075 case RRR_DADDU:
10076 mips32_op = OPC_DADDU;
10077 check_mips_64(ctx);
10078 break;
10079 case RRR_DSUBU:
10080 mips32_op = OPC_DSUBU;
10081 check_mips_64(ctx);
10082 break;
10083 #endif
10084 default:
10085 generate_exception(ctx, EXCP_RI);
10086 goto done;
10087 }
10088
10089 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10090 done:
10091 ;
10092 }
10093 break;
10094 case M16_OPC_RR:
10095 switch (op1) {
10096 case RR_JR:
10097 {
10098 int nd = (ctx->opcode >> 7) & 0x1;
10099 int link = (ctx->opcode >> 6) & 0x1;
10100 int ra = (ctx->opcode >> 5) & 0x1;
10101
10102 if (link) {
10103 op = nd ? OPC_JALRC : OPC_JALRS;
10104 } else {
10105 op = OPC_JR;
10106 }
10107
10108 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10109 if (!nd) {
10110 *is_branch = 1;
10111 }
10112 }
10113 break;
10114 case RR_SDBBP:
10115 /* XXX: not clear which exception should be raised
10116 * when in debug mode...
10117 */
10118 check_insn(env, ctx, ISA_MIPS32);
10119 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10120 generate_exception(ctx, EXCP_DBp);
10121 } else {
10122 generate_exception(ctx, EXCP_DBp);
10123 }
10124 break;
10125 case RR_SLT:
10126 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10127 break;
10128 case RR_SLTU:
10129 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10130 break;
10131 case RR_BREAK:
10132 generate_exception(ctx, EXCP_BREAK);
10133 break;
10134 case RR_SLLV:
10135 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10136 break;
10137 case RR_SRLV:
10138 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10139 break;
10140 case RR_SRAV:
10141 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10142 break;
10143 #if defined (TARGET_MIPS64)
10144 case RR_DSRL:
10145 check_mips_64(ctx);
10146 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10147 break;
10148 #endif
10149 case RR_CMP:
10150 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10151 break;
10152 case RR_NEG:
10153 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10154 break;
10155 case RR_AND:
10156 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10157 break;
10158 case RR_OR:
10159 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10160 break;
10161 case RR_XOR:
10162 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10163 break;
10164 case RR_NOT:
10165 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10166 break;
10167 case RR_MFHI:
10168 gen_HILO(ctx, OPC_MFHI, rx);
10169 break;
10170 case RR_CNVT:
10171 switch (cnvt_op) {
10172 case RR_RY_CNVT_ZEB:
10173 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10174 break;
10175 case RR_RY_CNVT_ZEH:
10176 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10177 break;
10178 case RR_RY_CNVT_SEB:
10179 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10180 break;
10181 case RR_RY_CNVT_SEH:
10182 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10183 break;
10184 #if defined (TARGET_MIPS64)
10185 case RR_RY_CNVT_ZEW:
10186 check_mips_64(ctx);
10187 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10188 break;
10189 case RR_RY_CNVT_SEW:
10190 check_mips_64(ctx);
10191 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10192 break;
10193 #endif
10194 default:
10195 generate_exception(ctx, EXCP_RI);
10196 break;
10197 }
10198 break;
10199 case RR_MFLO:
10200 gen_HILO(ctx, OPC_MFLO, rx);
10201 break;
10202 #if defined (TARGET_MIPS64)
10203 case RR_DSRA:
10204 check_mips_64(ctx);
10205 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10206 break;
10207 case RR_DSLLV:
10208 check_mips_64(ctx);
10209 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10210 break;
10211 case RR_DSRLV:
10212 check_mips_64(ctx);
10213 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10214 break;
10215 case RR_DSRAV:
10216 check_mips_64(ctx);
10217 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10218 break;
10219 #endif
10220 case RR_MULT:
10221 gen_muldiv(ctx, OPC_MULT, rx, ry);
10222 break;
10223 case RR_MULTU:
10224 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10225 break;
10226 case RR_DIV:
10227 gen_muldiv(ctx, OPC_DIV, rx, ry);
10228 break;
10229 case RR_DIVU:
10230 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10231 break;
10232 #if defined (TARGET_MIPS64)
10233 case RR_DMULT:
10234 check_mips_64(ctx);
10235 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10236 break;
10237 case RR_DMULTU:
10238 check_mips_64(ctx);
10239 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10240 break;
10241 case RR_DDIV:
10242 check_mips_64(ctx);
10243 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10244 break;
10245 case RR_DDIVU:
10246 check_mips_64(ctx);
10247 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10248 break;
10249 #endif
10250 default:
10251 generate_exception(ctx, EXCP_RI);
10252 break;
10253 }
10254 break;
10255 case M16_OPC_EXTEND:
10256 decode_extended_mips16_opc(env, ctx, is_branch);
10257 n_bytes = 4;
10258 break;
10259 #if defined(TARGET_MIPS64)
10260 case M16_OPC_I64:
10261 funct = (ctx->opcode >> 8) & 0x7;
10262 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10263 break;
10264 #endif
10265 default:
10266 generate_exception(ctx, EXCP_RI);
10267 break;
10268 }
10269
10270 return n_bytes;
10271 }
10272
10273 /* microMIPS extension to MIPS32 */
10274
10275 /* microMIPS32 major opcodes */
10276
10277 enum {
10278 POOL32A = 0x00,
10279 POOL16A = 0x01,
10280 LBU16 = 0x02,
10281 MOVE16 = 0x03,
10282 ADDI32 = 0x04,
10283 LBU32 = 0x05,
10284 SB32 = 0x06,
10285 LB32 = 0x07,
10286
10287 POOL32B = 0x08,
10288 POOL16B = 0x09,
10289 LHU16 = 0x0a,
10290 ANDI16 = 0x0b,
10291 ADDIU32 = 0x0c,
10292 LHU32 = 0x0d,
10293 SH32 = 0x0e,
10294 LH32 = 0x0f,
10295
10296 POOL32I = 0x10,
10297 POOL16C = 0x11,
10298 LWSP16 = 0x12,
10299 POOL16D = 0x13,
10300 ORI32 = 0x14,
10301 POOL32F = 0x15,
10302 POOL32S = 0x16,
10303 DADDIU32 = 0x17,
10304
10305 POOL32C = 0x18,
10306 LWGP16 = 0x19,
10307 LW16 = 0x1a,
10308 POOL16E = 0x1b,
10309 XORI32 = 0x1c,
10310 JALS32 = 0x1d,
10311 ADDIUPC = 0x1e,
10312 POOL48A = 0x1f,
10313
10314 /* 0x20 is reserved */
10315 RES_20 = 0x20,
10316 POOL16F = 0x21,
10317 SB16 = 0x22,
10318 BEQZ16 = 0x23,
10319 SLTI32 = 0x24,
10320 BEQ32 = 0x25,
10321 SWC132 = 0x26,
10322 LWC132 = 0x27,
10323
10324 /* 0x28 and 0x29 are reserved */
10325 RES_28 = 0x28,
10326 RES_29 = 0x29,
10327 SH16 = 0x2a,
10328 BNEZ16 = 0x2b,
10329 SLTIU32 = 0x2c,
10330 BNE32 = 0x2d,
10331 SDC132 = 0x2e,
10332 LDC132 = 0x2f,
10333
10334 /* 0x30 and 0x31 are reserved */
10335 RES_30 = 0x30,
10336 RES_31 = 0x31,
10337 SWSP16 = 0x32,
10338 B16 = 0x33,
10339 ANDI32 = 0x34,
10340 J32 = 0x35,
10341 SD32 = 0x36,
10342 LD32 = 0x37,
10343
10344 /* 0x38 and 0x39 are reserved */
10345 RES_38 = 0x38,
10346 RES_39 = 0x39,
10347 SW16 = 0x3a,
10348 LI16 = 0x3b,
10349 JALX32 = 0x3c,
10350 JAL32 = 0x3d,
10351 SW32 = 0x3e,
10352 LW32 = 0x3f
10353 };
10354
10355 /* POOL32A encoding of minor opcode field */
10356
10357 enum {
10358 /* These opcodes are distinguished only by bits 9..6; those bits are
10359 * what are recorded below. */
10360 SLL32 = 0x0,
10361 SRL32 = 0x1,
10362 SRA = 0x2,
10363 ROTR = 0x3,
10364
10365 SLLV = 0x0,
10366 SRLV = 0x1,
10367 SRAV = 0x2,
10368 ROTRV = 0x3,
10369 ADD = 0x4,
10370 ADDU32 = 0x5,
10371 SUB = 0x6,
10372 SUBU32 = 0x7,
10373 MUL = 0x8,
10374 AND = 0x9,
10375 OR32 = 0xa,
10376 NOR = 0xb,
10377 XOR32 = 0xc,
10378 SLT = 0xd,
10379 SLTU = 0xe,
10380
10381 MOVN = 0x0,
10382 MOVZ = 0x1,
10383 LWXS = 0x4,
10384
10385 /* The following can be distinguished by their lower 6 bits. */
10386 INS = 0x0c,
10387 EXT = 0x2c,
10388 POOL32AXF = 0x3c
10389 };
10390
10391 /* POOL32AXF encoding of minor opcode field extension */
10392
10393 enum {
10394 /* bits 11..6 */
10395 TEQ = 0x00,
10396 TGE = 0x08,
10397 TGEU = 0x10,
10398 TLT = 0x20,
10399 TLTU = 0x28,
10400 TNE = 0x30,
10401
10402 MFC0 = 0x03,
10403 MTC0 = 0x0b,
10404
10405 /* bits 13..12 for 0x01 */
10406 MFHI_ACC = 0x0,
10407 MFLO_ACC = 0x1,
10408 MTHI_ACC = 0x2,
10409 MTLO_ACC = 0x3,
10410
10411 /* bits 13..12 for 0x2a */
10412 MADD_ACC = 0x0,
10413 MADDU_ACC = 0x1,
10414 MSUB_ACC = 0x2,
10415 MSUBU_ACC = 0x3,
10416
10417 /* bits 13..12 for 0x32 */
10418 MULT_ACC = 0x0,
10419 MULTU_ACC = 0x0,
10420
10421 /* bits 15..12 for 0x2c */
10422 SEB = 0x2,
10423 SEH = 0x3,
10424 CLO = 0x4,
10425 CLZ = 0x5,
10426 RDHWR = 0x6,
10427 WSBH = 0x7,
10428 MULT = 0x8,
10429 MULTU = 0x9,
10430 DIV = 0xa,
10431 DIVU = 0xb,
10432 MADD = 0xc,
10433 MADDU = 0xd,
10434 MSUB = 0xe,
10435 MSUBU = 0xf,
10436
10437 /* bits 15..12 for 0x34 */
10438 MFC2 = 0x4,
10439 MTC2 = 0x5,
10440 MFHC2 = 0x8,
10441 MTHC2 = 0x9,
10442 CFC2 = 0xc,
10443 CTC2 = 0xd,
10444
10445 /* bits 15..12 for 0x3c */
10446 JALR = 0x0,
10447 JR = 0x0, /* alias */
10448 JALR_HB = 0x1,
10449 JALRS = 0x4,
10450 JALRS_HB = 0x5,
10451
10452 /* bits 15..12 for 0x05 */
10453 RDPGPR = 0xe,
10454 WRPGPR = 0xf,
10455
10456 /* bits 15..12 for 0x0d */
10457 TLBP = 0x0,
10458 TLBR = 0x1,
10459 TLBWI = 0x2,
10460 TLBWR = 0x3,
10461 WAIT = 0x9,
10462 IRET = 0xd,
10463 DERET = 0xe,
10464 ERET = 0xf,
10465
10466 /* bits 15..12 for 0x15 */
10467 DMT = 0x0,
10468 DVPE = 0x1,
10469 EMT = 0x2,
10470 EVPE = 0x3,
10471
10472 /* bits 15..12 for 0x1d */
10473 DI = 0x4,
10474 EI = 0x5,
10475
10476 /* bits 15..12 for 0x2d */
10477 SYNC = 0x6,
10478 SYSCALL = 0x8,
10479 SDBBP = 0xd,
10480
10481 /* bits 15..12 for 0x35 */
10482 MFHI32 = 0x0,
10483 MFLO32 = 0x1,
10484 MTHI32 = 0x2,
10485 MTLO32 = 0x3,
10486 };
10487
10488 /* POOL32B encoding of minor opcode field (bits 15..12) */
10489
10490 enum {
10491 LWC2 = 0x0,
10492 LWP = 0x1,
10493 LDP = 0x4,
10494 LWM32 = 0x5,
10495 CACHE = 0x6,
10496 LDM = 0x7,
10497 SWC2 = 0x8,
10498 SWP = 0x9,
10499 SDP = 0xc,
10500 SWM32 = 0xd,
10501 SDM = 0xf
10502 };
10503
10504 /* POOL32C encoding of minor opcode field (bits 15..12) */
10505
10506 enum {
10507 LWL = 0x0,
10508 SWL = 0x8,
10509 LWR = 0x1,
10510 SWR = 0x9,
10511 PREF = 0x2,
10512 /* 0xa is reserved */
10513 LL = 0x3,
10514 SC = 0xb,
10515 LDL = 0x4,
10516 SDL = 0xc,
10517 LDR = 0x5,
10518 SDR = 0xd,
10519 /* 0x6 is reserved */
10520 LWU = 0xe,
10521 LLD = 0x7,
10522 SCD = 0xf
10523 };
10524
10525 /* POOL32F encoding of minor opcode field (bits 5..0) */
10526
10527 enum {
10528 /* These are the bit 7..6 values */
10529 ADD_FMT = 0x0,
10530 MOVN_FMT = 0x0,
10531
10532 SUB_FMT = 0x1,
10533 MOVZ_FMT = 0x1,
10534
10535 MUL_FMT = 0x2,
10536
10537 DIV_FMT = 0x3,
10538
10539 /* These are the bit 8..6 values */
10540 RSQRT2_FMT = 0x0,
10541 MOVF_FMT = 0x0,
10542
10543 LWXC1 = 0x1,
10544 MOVT_FMT = 0x1,
10545
10546 PLL_PS = 0x2,
10547 SWXC1 = 0x2,
10548
10549 PLU_PS = 0x3,
10550 LDXC1 = 0x3,
10551
10552 PUL_PS = 0x4,
10553 SDXC1 = 0x4,
10554 RECIP2_FMT = 0x4,
10555
10556 PUU_PS = 0x5,
10557 LUXC1 = 0x5,
10558
10559 CVT_PS_S = 0x6,
10560 SUXC1 = 0x6,
10561 ADDR_PS = 0x6,
10562 PREFX = 0x6,
10563
10564 MULR_PS = 0x7,
10565
10566 MADD_S = 0x01,
10567 MADD_D = 0x09,
10568 MADD_PS = 0x11,
10569 ALNV_PS = 0x19,
10570 MSUB_S = 0x21,
10571 MSUB_D = 0x29,
10572 MSUB_PS = 0x31,
10573
10574 NMADD_S = 0x02,
10575 NMADD_D = 0x0a,
10576 NMADD_PS = 0x12,
10577 NMSUB_S = 0x22,
10578 NMSUB_D = 0x2a,
10579 NMSUB_PS = 0x32,
10580
10581 POOL32FXF = 0x3b,
10582
10583 CABS_COND_FMT = 0x1c, /* MIPS3D */
10584 C_COND_FMT = 0x3c
10585 };
10586
10587 /* POOL32Fxf encoding of minor opcode extension field */
10588
10589 enum {
10590 CVT_L = 0x04,
10591 RSQRT_FMT = 0x08,
10592 FLOOR_L = 0x0c,
10593 CVT_PW_PS = 0x1c,
10594 CVT_W = 0x24,
10595 SQRT_FMT = 0x28,
10596 FLOOR_W = 0x2c,
10597 CVT_PS_PW = 0x3c,
10598 CFC1 = 0x40,
10599 RECIP_FMT = 0x48,
10600 CEIL_L = 0x4c,
10601 CTC1 = 0x60,
10602 CEIL_W = 0x6c,
10603 MFC1 = 0x80,
10604 CVT_S_PL = 0x84,
10605 TRUNC_L = 0x8c,
10606 MTC1 = 0xa0,
10607 CVT_S_PU = 0xa4,
10608 TRUNC_W = 0xac,
10609 MFHC1 = 0xc0,
10610 ROUND_L = 0xcc,
10611 MTHC1 = 0xe0,
10612 ROUND_W = 0xec,
10613
10614 MOV_FMT = 0x01,
10615 MOVF = 0x05,
10616 ABS_FMT = 0x0d,
10617 RSQRT1_FMT = 0x1d,
10618 MOVT = 0x25,
10619 NEG_FMT = 0x2d,
10620 CVT_D = 0x4d,
10621 RECIP1_FMT = 0x5d,
10622 CVT_S = 0x6d
10623 };
10624
10625 /* POOL32I encoding of minor opcode field (bits 25..21) */
10626
10627 enum {
10628 BLTZ = 0x00,
10629 BLTZAL = 0x01,
10630 BGEZ = 0x02,
10631 BGEZAL = 0x03,
10632 BLEZ = 0x04,
10633 BNEZC = 0x05,
10634 BGTZ = 0x06,
10635 BEQZC = 0x07,
10636 TLTI = 0x08,
10637 TGEI = 0x09,
10638 TLTIU = 0x0a,
10639 TGEIU = 0x0b,
10640 TNEI = 0x0c,
10641 LUI = 0x0d,
10642 TEQI = 0x0e,
10643 SYNCI = 0x10,
10644 BLTZALS = 0x11,
10645 BGEZALS = 0x13,
10646 BC2F = 0x14,
10647 BC2T = 0x15,
10648 BPOSGE64 = 0x1a,
10649 BPOSGE32 = 0x1b,
10650 /* These overlap and are distinguished by bit16 of the instruction */
10651 BC1F = 0x1c,
10652 BC1T = 0x1d,
10653 BC1ANY2F = 0x1c,
10654 BC1ANY2T = 0x1d,
10655 BC1ANY4F = 0x1e,
10656 BC1ANY4T = 0x1f
10657 };
10658
10659 /* POOL16A encoding of minor opcode field */
10660
10661 enum {
10662 ADDU16 = 0x0,
10663 SUBU16 = 0x1
10664 };
10665
10666 /* POOL16B encoding of minor opcode field */
10667
10668 enum {
10669 SLL16 = 0x0,
10670 SRL16 = 0x1
10671 };
10672
10673 /* POOL16C encoding of minor opcode field */
10674
10675 enum {
10676 NOT16 = 0x00,
10677 XOR16 = 0x04,
10678 AND16 = 0x08,
10679 OR16 = 0x0c,
10680 LWM16 = 0x10,
10681 SWM16 = 0x14,
10682 JR16 = 0x18,
10683 JRC16 = 0x1a,
10684 JALR16 = 0x1c,
10685 JALR16S = 0x1e,
10686 MFHI16 = 0x20,
10687 MFLO16 = 0x24,
10688 BREAK16 = 0x28,
10689 SDBBP16 = 0x2c,
10690 JRADDIUSP = 0x30
10691 };
10692
10693 /* POOL16D encoding of minor opcode field */
10694
10695 enum {
10696 ADDIUS5 = 0x0,
10697 ADDIUSP = 0x1
10698 };
10699
10700 /* POOL16E encoding of minor opcode field */
10701
10702 enum {
10703 ADDIUR2 = 0x0,
10704 ADDIUR1SP = 0x1
10705 };
10706
10707 static int mmreg (int r)
10708 {
10709 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10710
10711 return map[r];
10712 }
10713
10714 /* Used for 16-bit store instructions. */
10715 static int mmreg2 (int r)
10716 {
10717 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10718
10719 return map[r];
10720 }
10721
10722 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10723 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10724 #define uMIPS_RS2(op) uMIPS_RS(op)
10725 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10726 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10727 #define uMIPS_RS5(op) (op & 0x1f)
10728
10729 /* Signed immediate */
10730 #define SIMM(op, start, width) \
10731 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10732 << (32-width)) \
10733 >> (32-width))
10734 /* Zero-extended immediate */
10735 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10736
10737 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10738 {
10739 int rd = mmreg(uMIPS_RD(ctx->opcode));
10740
10741 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10742 }
10743
10744 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10745 {
10746 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10747 int rd = mmreg(uMIPS_RD(ctx->opcode));
10748 int rs = mmreg(uMIPS_RS(ctx->opcode));
10749
10750 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10751 }
10752
10753 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10754 {
10755 int encoded = ZIMM(ctx->opcode, 1, 9);
10756 int decoded;
10757
10758 if (encoded <= 1) {
10759 decoded = 256 + encoded;
10760 } else if (encoded <= 255) {
10761 decoded = encoded;
10762 } else if (encoded <= 509) {
10763 decoded = encoded - 512;
10764 } else {
10765 decoded = encoded - 768;
10766 }
10767
10768 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10769 }
10770
10771 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10772 {
10773 int imm = SIMM(ctx->opcode, 1, 4);
10774 int rd = (ctx->opcode >> 5) & 0x1f;
10775
10776 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10777 }
10778
10779 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10780 {
10781 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10782 31, 32, 63, 64, 255, 32768, 65535 };
10783 int rd = mmreg(uMIPS_RD(ctx->opcode));
10784 int rs = mmreg(uMIPS_RS(ctx->opcode));
10785 int encoded = ZIMM(ctx->opcode, 0, 4);
10786
10787 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10788 }
10789
10790 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10791 int base, int16_t offset)
10792 {
10793 const char *opn = "ldst_multiple";
10794 TCGv t0, t1;
10795 TCGv_i32 t2;
10796
10797 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10798 generate_exception(ctx, EXCP_RI);
10799 return;
10800 }
10801
10802 t0 = tcg_temp_new();
10803
10804 gen_base_offset_addr(ctx, t0, base, offset);
10805
10806 t1 = tcg_const_tl(reglist);
10807 t2 = tcg_const_i32(ctx->mem_idx);
10808
10809 save_cpu_state(ctx, 1);
10810 switch (opc) {
10811 case LWM32:
10812 gen_helper_lwm(cpu_env, t0, t1, t2);
10813 opn = "lwm";
10814 break;
10815 case SWM32:
10816 gen_helper_swm(cpu_env, t0, t1, t2);
10817 opn = "swm";
10818 break;
10819 #ifdef TARGET_MIPS64
10820 case LDM:
10821 gen_helper_ldm(cpu_env, t0, t1, t2);
10822 opn = "ldm";
10823 break;
10824 case SDM:
10825 gen_helper_sdm(cpu_env, t0, t1, t2);
10826 opn = "sdm";
10827 break;
10828 #endif
10829 }
10830 (void)opn;
10831 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10832 tcg_temp_free(t0);
10833 tcg_temp_free(t1);
10834 tcg_temp_free_i32(t2);
10835 }
10836
10837
10838 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10839 {
10840 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10841 int rs = mmreg(ctx->opcode & 0x7);
10842 int opc;
10843
10844 switch (((ctx->opcode) >> 4) & 0x3f) {
10845 case NOT16 + 0:
10846 case NOT16 + 1:
10847 case NOT16 + 2:
10848 case NOT16 + 3:
10849 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10850 break;
10851 case XOR16 + 0:
10852 case XOR16 + 1:
10853 case XOR16 + 2:
10854 case XOR16 + 3:
10855 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10856 break;
10857 case AND16 + 0:
10858 case AND16 + 1:
10859 case AND16 + 2:
10860 case AND16 + 3:
10861 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10862 break;
10863 case OR16 + 0:
10864 case OR16 + 1:
10865 case OR16 + 2:
10866 case OR16 + 3:
10867 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10868 break;
10869 case LWM16 + 0:
10870 case LWM16 + 1:
10871 case LWM16 + 2:
10872 case LWM16 + 3:
10873 {
10874 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10875 int offset = ZIMM(ctx->opcode, 0, 4);
10876
10877 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10878 29, offset << 2);
10879 }
10880 break;
10881 case SWM16 + 0:
10882 case SWM16 + 1:
10883 case SWM16 + 2:
10884 case SWM16 + 3:
10885 {
10886 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10887 int offset = ZIMM(ctx->opcode, 0, 4);
10888
10889 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10890 29, offset << 2);
10891 }
10892 break;
10893 case JR16 + 0:
10894 case JR16 + 1:
10895 {
10896 int reg = ctx->opcode & 0x1f;
10897
10898 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10899 }
10900 *is_branch = 1;
10901 break;
10902 case JRC16 + 0:
10903 case JRC16 + 1:
10904 {
10905 int reg = ctx->opcode & 0x1f;
10906
10907 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10908 /* Let normal delay slot handling in our caller take us
10909 to the branch target. */
10910 }
10911 break;
10912 case JALR16 + 0:
10913 case JALR16 + 1:
10914 opc = OPC_JALR;
10915 goto do_jalr;
10916 case JALR16S + 0:
10917 case JALR16S + 1:
10918 opc = OPC_JALRS;
10919 do_jalr:
10920 {
10921 int reg = ctx->opcode & 0x1f;
10922
10923 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10924 }
10925 *is_branch = 1;
10926 break;
10927 case MFHI16 + 0:
10928 case MFHI16 + 1:
10929 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10930 break;
10931 case MFLO16 + 0:
10932 case MFLO16 + 1:
10933 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10934 break;
10935 case BREAK16:
10936 generate_exception(ctx, EXCP_BREAK);
10937 break;
10938 case SDBBP16:
10939 /* XXX: not clear which exception should be raised
10940 * when in debug mode...
10941 */
10942 check_insn(env, ctx, ISA_MIPS32);
10943 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10944 generate_exception(ctx, EXCP_DBp);
10945 } else {
10946 generate_exception(ctx, EXCP_DBp);
10947 }
10948 break;
10949 case JRADDIUSP + 0:
10950 case JRADDIUSP + 1:
10951 {
10952 int imm = ZIMM(ctx->opcode, 0, 5);
10953
10954 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10955 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10956 /* Let normal delay slot handling in our caller take us
10957 to the branch target. */
10958 }
10959 break;
10960 default:
10961 generate_exception(ctx, EXCP_RI);
10962 break;
10963 }
10964 }
10965
10966 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10967 {
10968 TCGv t0 = tcg_temp_new();
10969 TCGv t1 = tcg_temp_new();
10970
10971 gen_load_gpr(t0, base);
10972
10973 if (index != 0) {
10974 gen_load_gpr(t1, index);
10975 tcg_gen_shli_tl(t1, t1, 2);
10976 gen_op_addr_add(ctx, t0, t1, t0);
10977 }
10978
10979 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10980 gen_store_gpr(t1, rd);
10981
10982 tcg_temp_free(t0);
10983 tcg_temp_free(t1);
10984 }
10985
10986 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10987 int base, int16_t offset)
10988 {
10989 const char *opn = "ldst_pair";
10990 TCGv t0, t1;
10991
10992 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10993 generate_exception(ctx, EXCP_RI);
10994 return;
10995 }
10996
10997 t0 = tcg_temp_new();
10998 t1 = tcg_temp_new();
10999
11000 gen_base_offset_addr(ctx, t0, base, offset);
11001
11002 switch (opc) {
11003 case LWP:
11004 if (rd == base) {
11005 generate_exception(ctx, EXCP_RI);
11006 return;
11007 }
11008 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11009 gen_store_gpr(t1, rd);
11010 tcg_gen_movi_tl(t1, 4);
11011 gen_op_addr_add(ctx, t0, t0, t1);
11012 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
11013 gen_store_gpr(t1, rd+1);
11014 opn = "lwp";
11015 break;
11016 case SWP:
11017 gen_load_gpr(t1, rd);
11018 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11019 tcg_gen_movi_tl(t1, 4);
11020 gen_op_addr_add(ctx, t0, t0, t1);
11021 gen_load_gpr(t1, rd+1);
11022 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
11023 opn = "swp";
11024 break;
11025 #ifdef TARGET_MIPS64
11026 case LDP:
11027 if (rd == base) {
11028 generate_exception(ctx, EXCP_RI);
11029 return;
11030 }
11031 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11032 gen_store_gpr(t1, rd);
11033 tcg_gen_movi_tl(t1, 8);
11034 gen_op_addr_add(ctx, t0, t0, t1);
11035 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11036 gen_store_gpr(t1, rd+1);
11037 opn = "ldp";
11038 break;
11039 case SDP:
11040 gen_load_gpr(t1, rd);
11041 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11042 tcg_gen_movi_tl(t1, 8);
11043 gen_op_addr_add(ctx, t0, t0, t1);
11044 gen_load_gpr(t1, rd+1);
11045 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11046 opn = "sdp";
11047 break;
11048 #endif
11049 }
11050 (void)opn; /* avoid a compiler warning */
11051 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11052 tcg_temp_free(t0);
11053 tcg_temp_free(t1);
11054 }
11055
11056 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11057 int *is_branch)
11058 {
11059 int extension = (ctx->opcode >> 6) & 0x3f;
11060 int minor = (ctx->opcode >> 12) & 0xf;
11061 uint32_t mips32_op;
11062
11063 switch (extension) {
11064 case TEQ:
11065 mips32_op = OPC_TEQ;
11066 goto do_trap;
11067 case TGE:
11068 mips32_op = OPC_TGE;
11069 goto do_trap;
11070 case TGEU:
11071 mips32_op = OPC_TGEU;
11072 goto do_trap;
11073 case TLT:
11074 mips32_op = OPC_TLT;
11075 goto do_trap;
11076 case TLTU:
11077 mips32_op = OPC_TLTU;
11078 goto do_trap;
11079 case TNE:
11080 mips32_op = OPC_TNE;
11081 do_trap:
11082 gen_trap(ctx, mips32_op, rs, rt, -1);
11083 break;
11084 #ifndef CONFIG_USER_ONLY
11085 case MFC0:
11086 case MFC0 + 32:
11087 check_cp0_enabled(ctx);
11088 if (rt == 0) {
11089 /* Treat as NOP. */
11090 break;
11091 }
11092 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11093 break;
11094 case MTC0:
11095 case MTC0 + 32:
11096 check_cp0_enabled(ctx);
11097 {
11098 TCGv t0 = tcg_temp_new();
11099
11100 gen_load_gpr(t0, rt);
11101 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11102 tcg_temp_free(t0);
11103 }
11104 break;
11105 #endif
11106 case 0x2c:
11107 switch (minor) {
11108 case SEB:
11109 gen_bshfl(ctx, OPC_SEB, rs, rt);
11110 break;
11111 case SEH:
11112 gen_bshfl(ctx, OPC_SEH, rs, rt);
11113 break;
11114 case CLO:
11115 mips32_op = OPC_CLO;
11116 goto do_cl;
11117 case CLZ:
11118 mips32_op = OPC_CLZ;
11119 do_cl:
11120 check_insn(env, ctx, ISA_MIPS32);
11121 gen_cl(ctx, mips32_op, rt, rs);
11122 break;
11123 case RDHWR:
11124 gen_rdhwr(env, ctx, rt, rs);
11125 break;
11126 case WSBH:
11127 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11128 break;
11129 case MULT:
11130 mips32_op = OPC_MULT;
11131 goto do_muldiv;
11132 case MULTU:
11133 mips32_op = OPC_MULTU;
11134 goto do_muldiv;
11135 case DIV:
11136 mips32_op = OPC_DIV;
11137 goto do_muldiv;
11138 case DIVU:
11139 mips32_op = OPC_DIVU;
11140 goto do_muldiv;
11141 case MADD:
11142 mips32_op = OPC_MADD;
11143 goto do_muldiv;
11144 case MADDU:
11145 mips32_op = OPC_MADDU;
11146 goto do_muldiv;
11147 case MSUB:
11148 mips32_op = OPC_MSUB;
11149 goto do_muldiv;
11150 case MSUBU:
11151 mips32_op = OPC_MSUBU;
11152 do_muldiv:
11153 check_insn(env, ctx, ISA_MIPS32);
11154 gen_muldiv(ctx, mips32_op, rs, rt);
11155 break;
11156 default:
11157 goto pool32axf_invalid;
11158 }
11159 break;
11160 case 0x34:
11161 switch (minor) {
11162 case MFC2:
11163 case MTC2:
11164 case MFHC2:
11165 case MTHC2:
11166 case CFC2:
11167 case CTC2:
11168 generate_exception_err(ctx, EXCP_CpU, 2);
11169 break;
11170 default:
11171 goto pool32axf_invalid;
11172 }
11173 break;
11174 case 0x3c:
11175 switch (minor) {
11176 case JALR:
11177 case JALR_HB:
11178 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11179 *is_branch = 1;
11180 break;
11181 case JALRS:
11182 case JALRS_HB:
11183 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11184 *is_branch = 1;
11185 break;
11186 default:
11187 goto pool32axf_invalid;
11188 }
11189 break;
11190 case 0x05:
11191 switch (minor) {
11192 case RDPGPR:
11193 check_cp0_enabled(ctx);
11194 check_insn(env, ctx, ISA_MIPS32R2);
11195 gen_load_srsgpr(rt, rs);
11196 break;
11197 case WRPGPR:
11198 check_cp0_enabled(ctx);
11199 check_insn(env, ctx, ISA_MIPS32R2);
11200 gen_store_srsgpr(rt, rs);
11201 break;
11202 default:
11203 goto pool32axf_invalid;
11204 }
11205 break;
11206 #ifndef CONFIG_USER_ONLY
11207 case 0x0d:
11208 switch (minor) {
11209 case TLBP:
11210 mips32_op = OPC_TLBP;
11211 goto do_cp0;
11212 case TLBR:
11213 mips32_op = OPC_TLBR;
11214 goto do_cp0;
11215 case TLBWI:
11216 mips32_op = OPC_TLBWI;
11217 goto do_cp0;
11218 case TLBWR:
11219 mips32_op = OPC_TLBWR;
11220 goto do_cp0;
11221 case WAIT:
11222 mips32_op = OPC_WAIT;
11223 goto do_cp0;
11224 case DERET:
11225 mips32_op = OPC_DERET;
11226 goto do_cp0;
11227 case ERET:
11228 mips32_op = OPC_ERET;
11229 do_cp0:
11230 gen_cp0(env, ctx, mips32_op, rt, rs);
11231 break;
11232 default:
11233 goto pool32axf_invalid;
11234 }
11235 break;
11236 case 0x1d:
11237 switch (minor) {
11238 case DI:
11239 check_cp0_enabled(ctx);
11240 {
11241 TCGv t0 = tcg_temp_new();
11242
11243 save_cpu_state(ctx, 1);
11244 gen_helper_di(t0, cpu_env);
11245 gen_store_gpr(t0, rs);
11246 /* Stop translation as we may have switched the execution mode */
11247 ctx->bstate = BS_STOP;
11248 tcg_temp_free(t0);
11249 }
11250 break;
11251 case EI:
11252 check_cp0_enabled(ctx);
11253 {
11254 TCGv t0 = tcg_temp_new();
11255
11256 save_cpu_state(ctx, 1);
11257 gen_helper_ei(t0, cpu_env);
11258 gen_store_gpr(t0, rs);
11259 /* Stop translation as we may have switched the execution mode */
11260 ctx->bstate = BS_STOP;
11261 tcg_temp_free(t0);
11262 }
11263 break;
11264 default:
11265 goto pool32axf_invalid;
11266 }
11267 break;
11268 #endif
11269 case 0x2d:
11270 switch (minor) {
11271 case SYNC:
11272 /* NOP */
11273 break;
11274 case SYSCALL:
11275 generate_exception(ctx, EXCP_SYSCALL);
11276 ctx->bstate = BS_STOP;
11277 break;
11278 case SDBBP:
11279 check_insn(env, ctx, ISA_MIPS32);
11280 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11281 generate_exception(ctx, EXCP_DBp);
11282 } else {
11283 generate_exception(ctx, EXCP_DBp);
11284 }
11285 break;
11286 default:
11287 goto pool32axf_invalid;
11288 }
11289 break;
11290 case 0x35:
11291 switch (minor) {
11292 case MFHI32:
11293 gen_HILO(ctx, OPC_MFHI, rs);
11294 break;
11295 case MFLO32:
11296 gen_HILO(ctx, OPC_MFLO, rs);
11297 break;
11298 case MTHI32:
11299 gen_HILO(ctx, OPC_MTHI, rs);
11300 break;
11301 case MTLO32:
11302 gen_HILO(ctx, OPC_MTLO, rs);
11303 break;
11304 default:
11305 goto pool32axf_invalid;
11306 }
11307 break;
11308 default:
11309 pool32axf_invalid:
11310 MIPS_INVAL("pool32axf");
11311 generate_exception(ctx, EXCP_RI);
11312 break;
11313 }
11314 }
11315
11316 /* Values for microMIPS fmt field. Variable-width, depending on which
11317 formats the instruction supports. */
11318
11319 enum {
11320 FMT_SD_S = 0,
11321 FMT_SD_D = 1,
11322
11323 FMT_SDPS_S = 0,
11324 FMT_SDPS_D = 1,
11325 FMT_SDPS_PS = 2,
11326
11327 FMT_SWL_S = 0,
11328 FMT_SWL_W = 1,
11329 FMT_SWL_L = 2,
11330
11331 FMT_DWL_D = 0,
11332 FMT_DWL_W = 1,
11333 FMT_DWL_L = 2
11334 };
11335
11336 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11337 {
11338 int extension = (ctx->opcode >> 6) & 0x3ff;
11339 uint32_t mips32_op;
11340
11341 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11342 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11343 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11344
11345 switch (extension) {
11346 case FLOAT_1BIT_FMT(CFC1, 0):
11347 mips32_op = OPC_CFC1;
11348 goto do_cp1;
11349 case FLOAT_1BIT_FMT(CTC1, 0):
11350 mips32_op = OPC_CTC1;
11351 goto do_cp1;
11352 case FLOAT_1BIT_FMT(MFC1, 0):
11353 mips32_op = OPC_MFC1;
11354 goto do_cp1;
11355 case FLOAT_1BIT_FMT(MTC1, 0):
11356 mips32_op = OPC_MTC1;
11357 goto do_cp1;
11358 case FLOAT_1BIT_FMT(MFHC1, 0):
11359 mips32_op = OPC_MFHC1;
11360 goto do_cp1;
11361 case FLOAT_1BIT_FMT(MTHC1, 0):
11362 mips32_op = OPC_MTHC1;
11363 do_cp1:
11364 gen_cp1(ctx, mips32_op, rt, rs);
11365 break;
11366
11367 /* Reciprocal square root */
11368 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11369 mips32_op = OPC_RSQRT_S;
11370 goto do_unaryfp;
11371 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11372 mips32_op = OPC_RSQRT_D;
11373 goto do_unaryfp;
11374
11375 /* Square root */
11376 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11377 mips32_op = OPC_SQRT_S;
11378 goto do_unaryfp;
11379 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11380 mips32_op = OPC_SQRT_D;
11381 goto do_unaryfp;
11382
11383 /* Reciprocal */
11384 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11385 mips32_op = OPC_RECIP_S;
11386 goto do_unaryfp;
11387 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11388 mips32_op = OPC_RECIP_D;
11389 goto do_unaryfp;
11390
11391 /* Floor */
11392 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11393 mips32_op = OPC_FLOOR_L_S;
11394 goto do_unaryfp;
11395 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11396 mips32_op = OPC_FLOOR_L_D;
11397 goto do_unaryfp;
11398 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11399 mips32_op = OPC_FLOOR_W_S;
11400 goto do_unaryfp;
11401 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11402 mips32_op = OPC_FLOOR_W_D;
11403 goto do_unaryfp;
11404
11405 /* Ceiling */
11406 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11407 mips32_op = OPC_CEIL_L_S;
11408 goto do_unaryfp;
11409 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11410 mips32_op = OPC_CEIL_L_D;
11411 goto do_unaryfp;
11412 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11413 mips32_op = OPC_CEIL_W_S;
11414 goto do_unaryfp;
11415 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11416 mips32_op = OPC_CEIL_W_D;
11417 goto do_unaryfp;
11418
11419 /* Truncation */
11420 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11421 mips32_op = OPC_TRUNC_L_S;
11422 goto do_unaryfp;
11423 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11424 mips32_op = OPC_TRUNC_L_D;
11425 goto do_unaryfp;
11426 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11427 mips32_op = OPC_TRUNC_W_S;
11428 goto do_unaryfp;
11429 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11430 mips32_op = OPC_TRUNC_W_D;
11431 goto do_unaryfp;
11432
11433 /* Round */
11434 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11435 mips32_op = OPC_ROUND_L_S;
11436 goto do_unaryfp;
11437 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11438 mips32_op = OPC_ROUND_L_D;
11439 goto do_unaryfp;
11440 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11441 mips32_op = OPC_ROUND_W_S;
11442 goto do_unaryfp;
11443 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11444 mips32_op = OPC_ROUND_W_D;
11445 goto do_unaryfp;
11446
11447 /* Integer to floating-point conversion */
11448 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11449 mips32_op = OPC_CVT_L_S;
11450 goto do_unaryfp;
11451 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11452 mips32_op = OPC_CVT_L_D;
11453 goto do_unaryfp;
11454 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11455 mips32_op = OPC_CVT_W_S;
11456 goto do_unaryfp;
11457 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11458 mips32_op = OPC_CVT_W_D;
11459 goto do_unaryfp;
11460
11461 /* Paired-foo conversions */
11462 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11463 mips32_op = OPC_CVT_S_PL;
11464 goto do_unaryfp;
11465 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11466 mips32_op = OPC_CVT_S_PU;
11467 goto do_unaryfp;
11468 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11469 mips32_op = OPC_CVT_PW_PS;
11470 goto do_unaryfp;
11471 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11472 mips32_op = OPC_CVT_PS_PW;
11473 goto do_unaryfp;
11474
11475 /* Floating-point moves */
11476 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11477 mips32_op = OPC_MOV_S;
11478 goto do_unaryfp;
11479 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11480 mips32_op = OPC_MOV_D;
11481 goto do_unaryfp;
11482 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11483 mips32_op = OPC_MOV_PS;
11484 goto do_unaryfp;
11485
11486 /* Absolute value */
11487 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11488 mips32_op = OPC_ABS_S;
11489 goto do_unaryfp;
11490 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11491 mips32_op = OPC_ABS_D;
11492 goto do_unaryfp;
11493 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11494 mips32_op = OPC_ABS_PS;
11495 goto do_unaryfp;
11496
11497 /* Negation */
11498 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11499 mips32_op = OPC_NEG_S;
11500 goto do_unaryfp;
11501 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11502 mips32_op = OPC_NEG_D;
11503 goto do_unaryfp;
11504 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11505 mips32_op = OPC_NEG_PS;
11506 goto do_unaryfp;
11507
11508 /* Reciprocal square root step */
11509 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11510 mips32_op = OPC_RSQRT1_S;
11511 goto do_unaryfp;
11512 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11513 mips32_op = OPC_RSQRT1_D;
11514 goto do_unaryfp;
11515 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11516 mips32_op = OPC_RSQRT1_PS;
11517 goto do_unaryfp;
11518
11519 /* Reciprocal step */
11520 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11521 mips32_op = OPC_RECIP1_S;
11522 goto do_unaryfp;
11523 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11524 mips32_op = OPC_RECIP1_S;
11525 goto do_unaryfp;
11526 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11527 mips32_op = OPC_RECIP1_PS;
11528 goto do_unaryfp;
11529
11530 /* Conversions from double */
11531 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11532 mips32_op = OPC_CVT_D_S;
11533 goto do_unaryfp;
11534 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11535 mips32_op = OPC_CVT_D_W;
11536 goto do_unaryfp;
11537 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11538 mips32_op = OPC_CVT_D_L;
11539 goto do_unaryfp;
11540
11541 /* Conversions from single */
11542 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11543 mips32_op = OPC_CVT_S_D;
11544 goto do_unaryfp;
11545 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11546 mips32_op = OPC_CVT_S_W;
11547 goto do_unaryfp;
11548 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11549 mips32_op = OPC_CVT_S_L;
11550 do_unaryfp:
11551 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11552 break;
11553
11554 /* Conditional moves on floating-point codes */
11555 case COND_FLOAT_MOV(MOVT, 0):
11556 case COND_FLOAT_MOV(MOVT, 1):
11557 case COND_FLOAT_MOV(MOVT, 2):
11558 case COND_FLOAT_MOV(MOVT, 3):
11559 case COND_FLOAT_MOV(MOVT, 4):
11560 case COND_FLOAT_MOV(MOVT, 5):
11561 case COND_FLOAT_MOV(MOVT, 6):
11562 case COND_FLOAT_MOV(MOVT, 7):
11563 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11564 break;
11565 case COND_FLOAT_MOV(MOVF, 0):
11566 case COND_FLOAT_MOV(MOVF, 1):
11567 case COND_FLOAT_MOV(MOVF, 2):
11568 case COND_FLOAT_MOV(MOVF, 3):
11569 case COND_FLOAT_MOV(MOVF, 4):
11570 case COND_FLOAT_MOV(MOVF, 5):
11571 case COND_FLOAT_MOV(MOVF, 6):
11572 case COND_FLOAT_MOV(MOVF, 7):
11573 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11574 break;
11575 default:
11576 MIPS_INVAL("pool32fxf");
11577 generate_exception(ctx, EXCP_RI);
11578 break;
11579 }
11580 }
11581
11582 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11583 uint16_t insn_hw1, int *is_branch)
11584 {
11585 int32_t offset;
11586 uint16_t insn;
11587 int rt, rs, rd, rr;
11588 int16_t imm;
11589 uint32_t op, minor, mips32_op;
11590 uint32_t cond, fmt, cc;
11591
11592 insn = cpu_lduw_code(env, ctx->pc + 2);
11593 ctx->opcode = (ctx->opcode << 16) | insn;
11594
11595 rt = (ctx->opcode >> 21) & 0x1f;
11596 rs = (ctx->opcode >> 16) & 0x1f;
11597 rd = (ctx->opcode >> 11) & 0x1f;
11598 rr = (ctx->opcode >> 6) & 0x1f;
11599 imm = (int16_t) ctx->opcode;
11600
11601 op = (ctx->opcode >> 26) & 0x3f;
11602 switch (op) {
11603 case POOL32A:
11604 minor = ctx->opcode & 0x3f;
11605 switch (minor) {
11606 case 0x00:
11607 minor = (ctx->opcode >> 6) & 0xf;
11608 switch (minor) {
11609 case SLL32:
11610 mips32_op = OPC_SLL;
11611 goto do_shifti;
11612 case SRA:
11613 mips32_op = OPC_SRA;
11614 goto do_shifti;
11615 case SRL32:
11616 mips32_op = OPC_SRL;
11617 goto do_shifti;
11618 case ROTR:
11619 mips32_op = OPC_ROTR;
11620 do_shifti:
11621 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11622 break;
11623 default:
11624 goto pool32a_invalid;
11625 }
11626 break;
11627 case 0x10:
11628 minor = (ctx->opcode >> 6) & 0xf;
11629 switch (minor) {
11630 /* Arithmetic */
11631 case ADD:
11632 mips32_op = OPC_ADD;
11633 goto do_arith;
11634 case ADDU32:
11635 mips32_op = OPC_ADDU;
11636 goto do_arith;
11637 case SUB:
11638 mips32_op = OPC_SUB;
11639 goto do_arith;
11640 case SUBU32:
11641 mips32_op = OPC_SUBU;
11642 goto do_arith;
11643 case MUL:
11644 mips32_op = OPC_MUL;
11645 do_arith:
11646 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11647 break;
11648 /* Shifts */
11649 case SLLV:
11650 mips32_op = OPC_SLLV;
11651 goto do_shift;
11652 case SRLV:
11653 mips32_op = OPC_SRLV;
11654 goto do_shift;
11655 case SRAV:
11656 mips32_op = OPC_SRAV;
11657 goto do_shift;
11658 case ROTRV:
11659 mips32_op = OPC_ROTRV;
11660 do_shift:
11661 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11662 break;
11663 /* Logical operations */
11664 case AND:
11665 mips32_op = OPC_AND;
11666 goto do_logic;
11667 case OR32:
11668 mips32_op = OPC_OR;
11669 goto do_logic;
11670 case NOR:
11671 mips32_op = OPC_NOR;
11672 goto do_logic;
11673 case XOR32:
11674 mips32_op = OPC_XOR;
11675 do_logic:
11676 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11677 break;
11678 /* Set less than */
11679 case SLT:
11680 mips32_op = OPC_SLT;
11681 goto do_slt;
11682 case SLTU:
11683 mips32_op = OPC_SLTU;
11684 do_slt:
11685 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11686 break;
11687 default:
11688 goto pool32a_invalid;
11689 }
11690 break;
11691 case 0x18:
11692 minor = (ctx->opcode >> 6) & 0xf;
11693 switch (minor) {
11694 /* Conditional moves */
11695 case MOVN:
11696 mips32_op = OPC_MOVN;
11697 goto do_cmov;
11698 case MOVZ:
11699 mips32_op = OPC_MOVZ;
11700 do_cmov:
11701 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11702 break;
11703 case LWXS:
11704 gen_ldxs(ctx, rs, rt, rd);
11705 break;
11706 default:
11707 goto pool32a_invalid;
11708 }
11709 break;
11710 case INS:
11711 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11712 return;
11713 case EXT:
11714 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11715 return;
11716 case POOL32AXF:
11717 gen_pool32axf(env, ctx, rt, rs, is_branch);
11718 break;
11719 case 0x07:
11720 generate_exception(ctx, EXCP_BREAK);
11721 break;
11722 default:
11723 pool32a_invalid:
11724 MIPS_INVAL("pool32a");
11725 generate_exception(ctx, EXCP_RI);
11726 break;
11727 }
11728 break;
11729 case POOL32B:
11730 minor = (ctx->opcode >> 12) & 0xf;
11731 switch (minor) {
11732 case CACHE:
11733 check_cp0_enabled(ctx);
11734 /* Treat as no-op. */
11735 break;
11736 case LWC2:
11737 case SWC2:
11738 /* COP2: Not implemented. */
11739 generate_exception_err(ctx, EXCP_CpU, 2);
11740 break;
11741 case LWP:
11742 case SWP:
11743 #ifdef TARGET_MIPS64
11744 case LDP:
11745 case SDP:
11746 #endif
11747 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11748 break;
11749 case LWM32:
11750 case SWM32:
11751 #ifdef TARGET_MIPS64
11752 case LDM:
11753 case SDM:
11754 #endif
11755 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11756 break;
11757 default:
11758 MIPS_INVAL("pool32b");
11759 generate_exception(ctx, EXCP_RI);
11760 break;
11761 }
11762 break;
11763 case POOL32F:
11764 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11765 minor = ctx->opcode & 0x3f;
11766 check_cp1_enabled(ctx);
11767 switch (minor) {
11768 case ALNV_PS:
11769 mips32_op = OPC_ALNV_PS;
11770 goto do_madd;
11771 case MADD_S:
11772 mips32_op = OPC_MADD_S;
11773 goto do_madd;
11774 case MADD_D:
11775 mips32_op = OPC_MADD_D;
11776 goto do_madd;
11777 case MADD_PS:
11778 mips32_op = OPC_MADD_PS;
11779 goto do_madd;
11780 case MSUB_S:
11781 mips32_op = OPC_MSUB_S;
11782 goto do_madd;
11783 case MSUB_D:
11784 mips32_op = OPC_MSUB_D;
11785 goto do_madd;
11786 case MSUB_PS:
11787 mips32_op = OPC_MSUB_PS;
11788 goto do_madd;
11789 case NMADD_S:
11790 mips32_op = OPC_NMADD_S;
11791 goto do_madd;
11792 case NMADD_D:
11793 mips32_op = OPC_NMADD_D;
11794 goto do_madd;
11795 case NMADD_PS:
11796 mips32_op = OPC_NMADD_PS;
11797 goto do_madd;
11798 case NMSUB_S:
11799 mips32_op = OPC_NMSUB_S;
11800 goto do_madd;
11801 case NMSUB_D:
11802 mips32_op = OPC_NMSUB_D;
11803 goto do_madd;
11804 case NMSUB_PS:
11805 mips32_op = OPC_NMSUB_PS;
11806 do_madd:
11807 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11808 break;
11809 case CABS_COND_FMT:
11810 cond = (ctx->opcode >> 6) & 0xf;
11811 cc = (ctx->opcode >> 13) & 0x7;
11812 fmt = (ctx->opcode >> 10) & 0x3;
11813 switch (fmt) {
11814 case 0x0:
11815 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11816 break;
11817 case 0x1:
11818 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11819 break;
11820 case 0x2:
11821 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11822 break;
11823 default:
11824 goto pool32f_invalid;
11825 }
11826 break;
11827 case C_COND_FMT:
11828 cond = (ctx->opcode >> 6) & 0xf;
11829 cc = (ctx->opcode >> 13) & 0x7;
11830 fmt = (ctx->opcode >> 10) & 0x3;
11831 switch (fmt) {
11832 case 0x0:
11833 gen_cmp_s(ctx, cond, rt, rs, cc);
11834 break;
11835 case 0x1:
11836 gen_cmp_d(ctx, cond, rt, rs, cc);
11837 break;
11838 case 0x2:
11839 gen_cmp_ps(ctx, cond, rt, rs, cc);
11840 break;
11841 default:
11842 goto pool32f_invalid;
11843 }
11844 break;
11845 case POOL32FXF:
11846 gen_pool32fxf(env, ctx, rt, rs);
11847 break;
11848 case 0x00:
11849 /* PLL foo */
11850 switch ((ctx->opcode >> 6) & 0x7) {
11851 case PLL_PS:
11852 mips32_op = OPC_PLL_PS;
11853 goto do_ps;
11854 case PLU_PS:
11855 mips32_op = OPC_PLU_PS;
11856 goto do_ps;
11857 case PUL_PS:
11858 mips32_op = OPC_PUL_PS;
11859 goto do_ps;
11860 case PUU_PS:
11861 mips32_op = OPC_PUU_PS;
11862 goto do_ps;
11863 case CVT_PS_S:
11864 mips32_op = OPC_CVT_PS_S;
11865 do_ps:
11866 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11867 break;
11868 default:
11869 goto pool32f_invalid;
11870 }
11871 break;
11872 case 0x08:
11873 /* [LS][WDU]XC1 */
11874 switch ((ctx->opcode >> 6) & 0x7) {
11875 case LWXC1:
11876 mips32_op = OPC_LWXC1;
11877 goto do_ldst_cp1;
11878 case SWXC1:
11879 mips32_op = OPC_SWXC1;
11880 goto do_ldst_cp1;
11881 case LDXC1:
11882 mips32_op = OPC_LDXC1;
11883 goto do_ldst_cp1;
11884 case SDXC1:
11885 mips32_op = OPC_SDXC1;
11886 goto do_ldst_cp1;
11887 case LUXC1:
11888 mips32_op = OPC_LUXC1;
11889 goto do_ldst_cp1;
11890 case SUXC1:
11891 mips32_op = OPC_SUXC1;
11892 do_ldst_cp1:
11893 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11894 break;
11895 default:
11896 goto pool32f_invalid;
11897 }
11898 break;
11899 case 0x18:
11900 /* 3D insns */
11901 fmt = (ctx->opcode >> 9) & 0x3;
11902 switch ((ctx->opcode >> 6) & 0x7) {
11903 case RSQRT2_FMT:
11904 switch (fmt) {
11905 case FMT_SDPS_S:
11906 mips32_op = OPC_RSQRT2_S;
11907 goto do_3d;
11908 case FMT_SDPS_D:
11909 mips32_op = OPC_RSQRT2_D;
11910 goto do_3d;
11911 case FMT_SDPS_PS:
11912 mips32_op = OPC_RSQRT2_PS;
11913 goto do_3d;
11914 default:
11915 goto pool32f_invalid;
11916 }
11917 break;
11918 case RECIP2_FMT:
11919 switch (fmt) {
11920 case FMT_SDPS_S:
11921 mips32_op = OPC_RECIP2_S;
11922 goto do_3d;
11923 case FMT_SDPS_D:
11924 mips32_op = OPC_RECIP2_D;
11925 goto do_3d;
11926 case FMT_SDPS_PS:
11927 mips32_op = OPC_RECIP2_PS;
11928 goto do_3d;
11929 default:
11930 goto pool32f_invalid;
11931 }
11932 break;
11933 case ADDR_PS:
11934 mips32_op = OPC_ADDR_PS;
11935 goto do_3d;
11936 case MULR_PS:
11937 mips32_op = OPC_MULR_PS;
11938 do_3d:
11939 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11940 break;
11941 default:
11942 goto pool32f_invalid;
11943 }
11944 break;
11945 case 0x20:
11946 /* MOV[FT].fmt and PREFX */
11947 cc = (ctx->opcode >> 13) & 0x7;
11948 fmt = (ctx->opcode >> 9) & 0x3;
11949 switch ((ctx->opcode >> 6) & 0x7) {
11950 case MOVF_FMT:
11951 switch (fmt) {
11952 case FMT_SDPS_S:
11953 gen_movcf_s(rs, rt, cc, 0);
11954 break;
11955 case FMT_SDPS_D:
11956 gen_movcf_d(ctx, rs, rt, cc, 0);
11957 break;
11958 case FMT_SDPS_PS:
11959 gen_movcf_ps(rs, rt, cc, 0);
11960 break;
11961 default:
11962 goto pool32f_invalid;
11963 }
11964 break;
11965 case MOVT_FMT:
11966 switch (fmt) {
11967 case FMT_SDPS_S:
11968 gen_movcf_s(rs, rt, cc, 1);
11969 break;
11970 case FMT_SDPS_D:
11971 gen_movcf_d(ctx, rs, rt, cc, 1);
11972 break;
11973 case FMT_SDPS_PS:
11974 gen_movcf_ps(rs, rt, cc, 1);
11975 break;
11976 default:
11977 goto pool32f_invalid;
11978 }
11979 break;
11980 case PREFX:
11981 break;
11982 default:
11983 goto pool32f_invalid;
11984 }
11985 break;
11986 #define FINSN_3ARG_SDPS(prfx) \
11987 switch ((ctx->opcode >> 8) & 0x3) { \
11988 case FMT_SDPS_S: \
11989 mips32_op = OPC_##prfx##_S; \
11990 goto do_fpop; \
11991 case FMT_SDPS_D: \
11992 mips32_op = OPC_##prfx##_D; \
11993 goto do_fpop; \
11994 case FMT_SDPS_PS: \
11995 mips32_op = OPC_##prfx##_PS; \
11996 goto do_fpop; \
11997 default: \
11998 goto pool32f_invalid; \
11999 }
12000 case 0x30:
12001 /* regular FP ops */
12002 switch ((ctx->opcode >> 6) & 0x3) {
12003 case ADD_FMT:
12004 FINSN_3ARG_SDPS(ADD);
12005 break;
12006 case SUB_FMT:
12007 FINSN_3ARG_SDPS(SUB);
12008 break;
12009 case MUL_FMT:
12010 FINSN_3ARG_SDPS(MUL);
12011 break;
12012 case DIV_FMT:
12013 fmt = (ctx->opcode >> 8) & 0x3;
12014 if (fmt == 1) {
12015 mips32_op = OPC_DIV_D;
12016 } else if (fmt == 0) {
12017 mips32_op = OPC_DIV_S;
12018 } else {
12019 goto pool32f_invalid;
12020 }
12021 goto do_fpop;
12022 default:
12023 goto pool32f_invalid;
12024 }
12025 break;
12026 case 0x38:
12027 /* cmovs */
12028 switch ((ctx->opcode >> 6) & 0x3) {
12029 case MOVN_FMT:
12030 FINSN_3ARG_SDPS(MOVN);
12031 break;
12032 case MOVZ_FMT:
12033 FINSN_3ARG_SDPS(MOVZ);
12034 break;
12035 default:
12036 goto pool32f_invalid;
12037 }
12038 break;
12039 do_fpop:
12040 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12041 break;
12042 default:
12043 pool32f_invalid:
12044 MIPS_INVAL("pool32f");
12045 generate_exception(ctx, EXCP_RI);
12046 break;
12047 }
12048 } else {
12049 generate_exception_err(ctx, EXCP_CpU, 1);
12050 }
12051 break;
12052 case POOL32I:
12053 minor = (ctx->opcode >> 21) & 0x1f;
12054 switch (minor) {
12055 case BLTZ:
12056 mips32_op = OPC_BLTZ;
12057 goto do_branch;
12058 case BLTZAL:
12059 mips32_op = OPC_BLTZAL;
12060 goto do_branch;
12061 case BLTZALS:
12062 mips32_op = OPC_BLTZALS;
12063 goto do_branch;
12064 case BGEZ:
12065 mips32_op = OPC_BGEZ;
12066 goto do_branch;
12067 case BGEZAL:
12068 mips32_op = OPC_BGEZAL;
12069 goto do_branch;
12070 case BGEZALS:
12071 mips32_op = OPC_BGEZALS;
12072 goto do_branch;
12073 case BLEZ:
12074 mips32_op = OPC_BLEZ;
12075 goto do_branch;
12076 case BGTZ:
12077 mips32_op = OPC_BGTZ;
12078 do_branch:
12079 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12080 *is_branch = 1;
12081 break;
12082
12083 /* Traps */
12084 case TLTI:
12085 mips32_op = OPC_TLTI;
12086 goto do_trapi;
12087 case TGEI:
12088 mips32_op = OPC_TGEI;
12089 goto do_trapi;
12090 case TLTIU:
12091 mips32_op = OPC_TLTIU;
12092 goto do_trapi;
12093 case TGEIU:
12094 mips32_op = OPC_TGEIU;
12095 goto do_trapi;
12096 case TNEI:
12097 mips32_op = OPC_TNEI;
12098 goto do_trapi;
12099 case TEQI:
12100 mips32_op = OPC_TEQI;
12101 do_trapi:
12102 gen_trap(ctx, mips32_op, rs, -1, imm);
12103 break;
12104
12105 case BNEZC:
12106 case BEQZC:
12107 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12108 4, rs, 0, imm << 1);
12109 /* Compact branches don't have a delay slot, so just let
12110 the normal delay slot handling take us to the branch
12111 target. */
12112 break;
12113 case LUI:
12114 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12115 break;
12116 case SYNCI:
12117 break;
12118 case BC2F:
12119 case BC2T:
12120 /* COP2: Not implemented. */
12121 generate_exception_err(ctx, EXCP_CpU, 2);
12122 break;
12123 case BC1F:
12124 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12125 goto do_cp1branch;
12126 case BC1T:
12127 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12128 goto do_cp1branch;
12129 case BC1ANY4F:
12130 mips32_op = OPC_BC1FANY4;
12131 goto do_cp1mips3d;
12132 case BC1ANY4T:
12133 mips32_op = OPC_BC1TANY4;
12134 do_cp1mips3d:
12135 check_cop1x(ctx);
12136 check_insn(env, ctx, ASE_MIPS3D);
12137 /* Fall through */
12138 do_cp1branch:
12139 gen_compute_branch1(env, ctx, mips32_op,
12140 (ctx->opcode >> 18) & 0x7, imm << 1);
12141 *is_branch = 1;
12142 break;
12143 case BPOSGE64:
12144 case BPOSGE32:
12145 /* MIPS DSP: not implemented */
12146 /* Fall through */
12147 default:
12148 MIPS_INVAL("pool32i");
12149 generate_exception(ctx, EXCP_RI);
12150 break;
12151 }
12152 break;
12153 case POOL32C:
12154 minor = (ctx->opcode >> 12) & 0xf;
12155 switch (minor) {
12156 case LWL:
12157 mips32_op = OPC_LWL;
12158 goto do_ld_lr;
12159 case SWL:
12160 mips32_op = OPC_SWL;
12161 goto do_st_lr;
12162 case LWR:
12163 mips32_op = OPC_LWR;
12164 goto do_ld_lr;
12165 case SWR:
12166 mips32_op = OPC_SWR;
12167 goto do_st_lr;
12168 #if defined(TARGET_MIPS64)
12169 case LDL:
12170 mips32_op = OPC_LDL;
12171 goto do_ld_lr;
12172 case SDL:
12173 mips32_op = OPC_SDL;
12174 goto do_st_lr;
12175 case LDR:
12176 mips32_op = OPC_LDR;
12177 goto do_ld_lr;
12178 case SDR:
12179 mips32_op = OPC_SDR;
12180 goto do_st_lr;
12181 case LWU:
12182 mips32_op = OPC_LWU;
12183 goto do_ld_lr;
12184 case LLD:
12185 mips32_op = OPC_LLD;
12186 goto do_ld_lr;
12187 #endif
12188 case LL:
12189 mips32_op = OPC_LL;
12190 goto do_ld_lr;
12191 do_ld_lr:
12192 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12193 break;
12194 do_st_lr:
12195 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12196 break;
12197 case SC:
12198 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12199 break;
12200 #if defined(TARGET_MIPS64)
12201 case SCD:
12202 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12203 break;
12204 #endif
12205 case PREF:
12206 /* Treat as no-op */
12207 break;
12208 default:
12209 MIPS_INVAL("pool32c");
12210 generate_exception(ctx, EXCP_RI);
12211 break;
12212 }
12213 break;
12214 case ADDI32:
12215 mips32_op = OPC_ADDI;
12216 goto do_addi;
12217 case ADDIU32:
12218 mips32_op = OPC_ADDIU;
12219 do_addi:
12220 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12221 break;
12222
12223 /* Logical operations */
12224 case ORI32:
12225 mips32_op = OPC_ORI;
12226 goto do_logici;
12227 case XORI32:
12228 mips32_op = OPC_XORI;
12229 goto do_logici;
12230 case ANDI32:
12231 mips32_op = OPC_ANDI;
12232 do_logici:
12233 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12234 break;
12235
12236 /* Set less than immediate */
12237 case SLTI32:
12238 mips32_op = OPC_SLTI;
12239 goto do_slti;
12240 case SLTIU32:
12241 mips32_op = OPC_SLTIU;
12242 do_slti:
12243 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12244 break;
12245 case JALX32:
12246 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12247 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12248 *is_branch = 1;
12249 break;
12250 case JALS32:
12251 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12252 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12253 *is_branch = 1;
12254 break;
12255 case BEQ32:
12256 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12257 *is_branch = 1;
12258 break;
12259 case BNE32:
12260 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12261 *is_branch = 1;
12262 break;
12263 case J32:
12264 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12265 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12266 *is_branch = 1;
12267 break;
12268 case JAL32:
12269 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12270 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12271 *is_branch = 1;
12272 break;
12273 /* Floating point (COP1) */
12274 case LWC132:
12275 mips32_op = OPC_LWC1;
12276 goto do_cop1;
12277 case LDC132:
12278 mips32_op = OPC_LDC1;
12279 goto do_cop1;
12280 case SWC132:
12281 mips32_op = OPC_SWC1;
12282 goto do_cop1;
12283 case SDC132:
12284 mips32_op = OPC_SDC1;
12285 do_cop1:
12286 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12287 break;
12288 case ADDIUPC:
12289 {
12290 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12291 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12292
12293 gen_addiupc(ctx, reg, offset, 0, 0);
12294 }
12295 break;
12296 /* Loads and stores */
12297 case LB32:
12298 mips32_op = OPC_LB;
12299 goto do_ld;
12300 case LBU32:
12301 mips32_op = OPC_LBU;
12302 goto do_ld;
12303 case LH32:
12304 mips32_op = OPC_LH;
12305 goto do_ld;
12306 case LHU32:
12307 mips32_op = OPC_LHU;
12308 goto do_ld;
12309 case LW32:
12310 mips32_op = OPC_LW;
12311 goto do_ld;
12312 #ifdef TARGET_MIPS64
12313 case LD32:
12314 mips32_op = OPC_LD;
12315 goto do_ld;
12316 case SD32:
12317 mips32_op = OPC_SD;
12318 goto do_st;
12319 #endif
12320 case SB32:
12321 mips32_op = OPC_SB;
12322 goto do_st;
12323 case SH32:
12324 mips32_op = OPC_SH;
12325 goto do_st;
12326 case SW32:
12327 mips32_op = OPC_SW;
12328 goto do_st;
12329 do_ld:
12330 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12331 break;
12332 do_st:
12333 gen_st(ctx, mips32_op, rt, rs, imm);
12334 break;
12335 default:
12336 generate_exception(ctx, EXCP_RI);
12337 break;
12338 }
12339 }
12340
12341 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12342 {
12343 uint32_t op;
12344
12345 /* make sure instructions are on a halfword boundary */
12346 if (ctx->pc & 0x1) {
12347 env->CP0_BadVAddr = ctx->pc;
12348 generate_exception(ctx, EXCP_AdEL);
12349 ctx->bstate = BS_STOP;
12350 return 2;
12351 }
12352
12353 op = (ctx->opcode >> 10) & 0x3f;
12354 /* Enforce properly-sized instructions in a delay slot */
12355 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12356 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12357
12358 switch (op) {
12359 case POOL32A:
12360 case POOL32B:
12361 case POOL32I:
12362 case POOL32C:
12363 case ADDI32:
12364 case ADDIU32:
12365 case ORI32:
12366 case XORI32:
12367 case SLTI32:
12368 case SLTIU32:
12369 case ANDI32:
12370 case JALX32:
12371 case LBU32:
12372 case LHU32:
12373 case POOL32F:
12374 case JALS32:
12375 case BEQ32:
12376 case BNE32:
12377 case J32:
12378 case JAL32:
12379 case SB32:
12380 case SH32:
12381 case POOL32S:
12382 case ADDIUPC:
12383 case SWC132:
12384 case SDC132:
12385 case SD32:
12386 case SW32:
12387 case LB32:
12388 case LH32:
12389 case DADDIU32:
12390 case POOL48A: /* ??? */
12391 case LWC132:
12392 case LDC132:
12393 case LD32:
12394 case LW32:
12395 if (bits & MIPS_HFLAG_BDS16) {
12396 generate_exception(ctx, EXCP_RI);
12397 /* Just stop translation; the user is confused. */
12398 ctx->bstate = BS_STOP;
12399 return 2;
12400 }
12401 break;
12402 case POOL16A:
12403 case POOL16B:
12404 case POOL16C:
12405 case LWGP16:
12406 case POOL16F:
12407 case LBU16:
12408 case LHU16:
12409 case LWSP16:
12410 case LW16:
12411 case SB16:
12412 case SH16:
12413 case SWSP16:
12414 case SW16:
12415 case MOVE16:
12416 case ANDI16:
12417 case POOL16D:
12418 case POOL16E:
12419 case BEQZ16:
12420 case BNEZ16:
12421 case B16:
12422 case LI16:
12423 if (bits & MIPS_HFLAG_BDS32) {
12424 generate_exception(ctx, EXCP_RI);
12425 /* Just stop translation; the user is confused. */
12426 ctx->bstate = BS_STOP;
12427 return 2;
12428 }
12429 break;
12430 default:
12431 break;
12432 }
12433 }
12434 switch (op) {
12435 case POOL16A:
12436 {
12437 int rd = mmreg(uMIPS_RD(ctx->opcode));
12438 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12439 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12440 uint32_t opc = 0;
12441
12442 switch (ctx->opcode & 0x1) {
12443 case ADDU16:
12444 opc = OPC_ADDU;
12445 break;
12446 case SUBU16:
12447 opc = OPC_SUBU;
12448 break;
12449 }
12450
12451 gen_arith(env, ctx, opc, rd, rs1, rs2);
12452 }
12453 break;
12454 case POOL16B:
12455 {
12456 int rd = mmreg(uMIPS_RD(ctx->opcode));
12457 int rs = mmreg(uMIPS_RS(ctx->opcode));
12458 int amount = (ctx->opcode >> 1) & 0x7;
12459 uint32_t opc = 0;
12460 amount = amount == 0 ? 8 : amount;
12461
12462 switch (ctx->opcode & 0x1) {
12463 case SLL16:
12464 opc = OPC_SLL;
12465 break;
12466 case SRL16:
12467 opc = OPC_SRL;
12468 break;
12469 }
12470
12471 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12472 }
12473 break;
12474 case POOL16C:
12475 gen_pool16c_insn(env, ctx, is_branch);
12476 break;
12477 case LWGP16:
12478 {
12479 int rd = mmreg(uMIPS_RD(ctx->opcode));
12480 int rb = 28; /* GP */
12481 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12482
12483 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12484 }
12485 break;
12486 case POOL16F:
12487 if (ctx->opcode & 1) {
12488 generate_exception(ctx, EXCP_RI);
12489 } else {
12490 /* MOVEP */
12491 int enc_dest = uMIPS_RD(ctx->opcode);
12492 int enc_rt = uMIPS_RS2(ctx->opcode);
12493 int enc_rs = uMIPS_RS1(ctx->opcode);
12494 int rd, rs, re, rt;
12495 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12496 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12497 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12498
12499 rd = rd_enc[enc_dest];
12500 re = re_enc[enc_dest];
12501 rs = rs_rt_enc[enc_rs];
12502 rt = rs_rt_enc[enc_rt];
12503
12504 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12505 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12506 }
12507 break;
12508 case LBU16:
12509 {
12510 int rd = mmreg(uMIPS_RD(ctx->opcode));
12511 int rb = mmreg(uMIPS_RS(ctx->opcode));
12512 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12513 offset = (offset == 0xf ? -1 : offset);
12514
12515 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12516 }
12517 break;
12518 case LHU16:
12519 {
12520 int rd = mmreg(uMIPS_RD(ctx->opcode));
12521 int rb = mmreg(uMIPS_RS(ctx->opcode));
12522 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12523
12524 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12525 }
12526 break;
12527 case LWSP16:
12528 {
12529 int rd = (ctx->opcode >> 5) & 0x1f;
12530 int rb = 29; /* SP */
12531 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12532
12533 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12534 }
12535 break;
12536 case LW16:
12537 {
12538 int rd = mmreg(uMIPS_RD(ctx->opcode));
12539 int rb = mmreg(uMIPS_RS(ctx->opcode));
12540 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12541
12542 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12543 }
12544 break;
12545 case SB16:
12546 {
12547 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12548 int rb = mmreg(uMIPS_RS(ctx->opcode));
12549 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12550
12551 gen_st(ctx, OPC_SB, rd, rb, offset);
12552 }
12553 break;
12554 case SH16:
12555 {
12556 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12557 int rb = mmreg(uMIPS_RS(ctx->opcode));
12558 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12559
12560 gen_st(ctx, OPC_SH, rd, rb, offset);
12561 }
12562 break;
12563 case SWSP16:
12564 {
12565 int rd = (ctx->opcode >> 5) & 0x1f;
12566 int rb = 29; /* SP */
12567 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12568
12569 gen_st(ctx, OPC_SW, rd, rb, offset);
12570 }
12571 break;
12572 case SW16:
12573 {
12574 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12575 int rb = mmreg(uMIPS_RS(ctx->opcode));
12576 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12577
12578 gen_st(ctx, OPC_SW, rd, rb, offset);
12579 }
12580 break;
12581 case MOVE16:
12582 {
12583 int rd = uMIPS_RD5(ctx->opcode);
12584 int rs = uMIPS_RS5(ctx->opcode);
12585
12586 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12587 }
12588 break;
12589 case ANDI16:
12590 gen_andi16(env, ctx);
12591 break;
12592 case POOL16D:
12593 switch (ctx->opcode & 0x1) {
12594 case ADDIUS5:
12595 gen_addius5(env, ctx);
12596 break;
12597 case ADDIUSP:
12598 gen_addiusp(env, ctx);
12599 break;
12600 }
12601 break;
12602 case POOL16E:
12603 switch (ctx->opcode & 0x1) {
12604 case ADDIUR2:
12605 gen_addiur2(env, ctx);
12606 break;
12607 case ADDIUR1SP:
12608 gen_addiur1sp(env, ctx);
12609 break;
12610 }
12611 break;
12612 case B16:
12613 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12614 SIMM(ctx->opcode, 0, 10) << 1);
12615 *is_branch = 1;
12616 break;
12617 case BNEZ16:
12618 case BEQZ16:
12619 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12620 mmreg(uMIPS_RD(ctx->opcode)),
12621 0, SIMM(ctx->opcode, 0, 7) << 1);
12622 *is_branch = 1;
12623 break;
12624 case LI16:
12625 {
12626 int reg = mmreg(uMIPS_RD(ctx->opcode));
12627 int imm = ZIMM(ctx->opcode, 0, 7);
12628
12629 imm = (imm == 0x7f ? -1 : imm);
12630 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12631 }
12632 break;
12633 case RES_20:
12634 case RES_28:
12635 case RES_29:
12636 case RES_30:
12637 case RES_31:
12638 case RES_38:
12639 case RES_39:
12640 generate_exception(ctx, EXCP_RI);
12641 break;
12642 default:
12643 decode_micromips32_opc (env, ctx, op, is_branch);
12644 return 4;
12645 }
12646
12647 return 2;
12648 }
12649
12650 /* SmartMIPS extension to MIPS32 */
12651
12652 #if defined(TARGET_MIPS64)
12653
12654 /* MDMX extension to MIPS64 */
12655
12656 #endif
12657
12658 /* MIPSDSP functions. */
12659 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12660 int rd, int base, int offset)
12661 {
12662 const char *opn = "ldx";
12663 TCGv t0;
12664
12665 if (rd == 0) {
12666 MIPS_DEBUG("NOP");
12667 return;
12668 }
12669
12670 check_dsp(ctx);
12671 t0 = tcg_temp_new();
12672
12673 if (base == 0) {
12674 gen_load_gpr(t0, offset);
12675 } else if (offset == 0) {
12676 gen_load_gpr(t0, base);
12677 } else {
12678 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12679 }
12680
12681 switch (opc) {
12682 case OPC_LBUX:
12683 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12684 gen_store_gpr(t0, rd);
12685 opn = "lbux";
12686 break;
12687 case OPC_LHX:
12688 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12689 gen_store_gpr(t0, rd);
12690 opn = "lhx";
12691 break;
12692 case OPC_LWX:
12693 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12694 gen_store_gpr(t0, rd);
12695 opn = "lwx";
12696 break;
12697 #if defined(TARGET_MIPS64)
12698 case OPC_LDX:
12699 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12700 gen_store_gpr(t0, rd);
12701 opn = "ldx";
12702 break;
12703 #endif
12704 }
12705 (void)opn; /* avoid a compiler warning */
12706 MIPS_DEBUG("%s %s, %s(%s)", opn,
12707 regnames[rd], regnames[offset], regnames[base]);
12708 tcg_temp_free(t0);
12709 }
12710
12711 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12712 int ret, int v1, int v2)
12713 {
12714 const char *opn = "mipsdsp arith";
12715 TCGv v1_t;
12716 TCGv v2_t;
12717
12718 if (ret == 0) {
12719 /* Treat as NOP. */
12720 MIPS_DEBUG("NOP");
12721 return;
12722 }
12723
12724 v1_t = tcg_temp_new();
12725 v2_t = tcg_temp_new();
12726
12727 gen_load_gpr(v1_t, v1);
12728 gen_load_gpr(v2_t, v2);
12729
12730 switch (op1) {
12731 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12732 case OPC_MULT_G_2E:
12733 check_dspr2(ctx);
12734 switch (op2) {
12735 case OPC_ADDUH_QB:
12736 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12737 break;
12738 case OPC_ADDUH_R_QB:
12739 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12740 break;
12741 case OPC_ADDQH_PH:
12742 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12743 break;
12744 case OPC_ADDQH_R_PH:
12745 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12746 break;
12747 case OPC_ADDQH_W:
12748 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12749 break;
12750 case OPC_ADDQH_R_W:
12751 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12752 break;
12753 case OPC_SUBUH_QB:
12754 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12755 break;
12756 case OPC_SUBUH_R_QB:
12757 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12758 break;
12759 case OPC_SUBQH_PH:
12760 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12761 break;
12762 case OPC_SUBQH_R_PH:
12763 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12764 break;
12765 case OPC_SUBQH_W:
12766 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12767 break;
12768 case OPC_SUBQH_R_W:
12769 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12770 break;
12771 }
12772 break;
12773 case OPC_ABSQ_S_PH_DSP:
12774 switch (op2) {
12775 case OPC_ABSQ_S_QB:
12776 check_dspr2(ctx);
12777 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12778 break;
12779 case OPC_ABSQ_S_PH:
12780 check_dsp(ctx);
12781 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12782 break;
12783 case OPC_ABSQ_S_W:
12784 check_dsp(ctx);
12785 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12786 break;
12787 case OPC_PRECEQ_W_PHL:
12788 check_dsp(ctx);
12789 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12790 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12791 break;
12792 case OPC_PRECEQ_W_PHR:
12793 check_dsp(ctx);
12794 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12795 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12796 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12797 break;
12798 case OPC_PRECEQU_PH_QBL:
12799 check_dsp(ctx);
12800 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12801 break;
12802 case OPC_PRECEQU_PH_QBR:
12803 check_dsp(ctx);
12804 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12805 break;
12806 case OPC_PRECEQU_PH_QBLA:
12807 check_dsp(ctx);
12808 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12809 break;
12810 case OPC_PRECEQU_PH_QBRA:
12811 check_dsp(ctx);
12812 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12813 break;
12814 case OPC_PRECEU_PH_QBL:
12815 check_dsp(ctx);
12816 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12817 break;
12818 case OPC_PRECEU_PH_QBR:
12819 check_dsp(ctx);
12820 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12821 break;
12822 case OPC_PRECEU_PH_QBLA:
12823 check_dsp(ctx);
12824 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12825 break;
12826 case OPC_PRECEU_PH_QBRA:
12827 check_dsp(ctx);
12828 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12829 break;
12830 }
12831 break;
12832 case OPC_ADDU_QB_DSP:
12833 switch (op2) {
12834 case OPC_ADDQ_PH:
12835 check_dsp(ctx);
12836 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12837 break;
12838 case OPC_ADDQ_S_PH:
12839 check_dsp(ctx);
12840 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12841 break;
12842 case OPC_ADDQ_S_W:
12843 check_dsp(ctx);
12844 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12845 break;
12846 case OPC_ADDU_QB:
12847 check_dsp(ctx);
12848 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849 break;
12850 case OPC_ADDU_S_QB:
12851 check_dsp(ctx);
12852 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853 break;
12854 case OPC_ADDU_PH:
12855 check_dspr2(ctx);
12856 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12857 break;
12858 case OPC_ADDU_S_PH:
12859 check_dspr2(ctx);
12860 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861 break;
12862 case OPC_SUBQ_PH:
12863 check_dsp(ctx);
12864 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865 break;
12866 case OPC_SUBQ_S_PH:
12867 check_dsp(ctx);
12868 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12869 break;
12870 case OPC_SUBQ_S_W:
12871 check_dsp(ctx);
12872 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12873 break;
12874 case OPC_SUBU_QB:
12875 check_dsp(ctx);
12876 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12877 break;
12878 case OPC_SUBU_S_QB:
12879 check_dsp(ctx);
12880 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12881 break;
12882 case OPC_SUBU_PH:
12883 check_dspr2(ctx);
12884 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885 break;
12886 case OPC_SUBU_S_PH:
12887 check_dspr2(ctx);
12888 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 break;
12890 case OPC_ADDSC:
12891 check_dsp(ctx);
12892 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12893 break;
12894 case OPC_ADDWC:
12895 check_dsp(ctx);
12896 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12897 break;
12898 case OPC_MODSUB:
12899 check_dsp(ctx);
12900 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12901 break;
12902 case OPC_RADDU_W_QB:
12903 check_dsp(ctx);
12904 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12905 break;
12906 }
12907 break;
12908 case OPC_CMPU_EQ_QB_DSP:
12909 switch (op2) {
12910 case OPC_PRECR_QB_PH:
12911 check_dspr2(ctx);
12912 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12913 break;
12914 case OPC_PRECRQ_QB_PH:
12915 check_dsp(ctx);
12916 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12917 break;
12918 case OPC_PRECR_SRA_PH_W:
12919 check_dspr2(ctx);
12920 {
12921 TCGv_i32 sa_t = tcg_const_i32(v2);
12922 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12923 cpu_gpr[ret]);
12924 tcg_temp_free_i32(sa_t);
12925 break;
12926 }
12927 case OPC_PRECR_SRA_R_PH_W:
12928 check_dspr2(ctx);
12929 {
12930 TCGv_i32 sa_t = tcg_const_i32(v2);
12931 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12932 cpu_gpr[ret]);
12933 tcg_temp_free_i32(sa_t);
12934 break;
12935 }
12936 case OPC_PRECRQ_PH_W:
12937 check_dsp(ctx);
12938 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12939 break;
12940 case OPC_PRECRQ_RS_PH_W:
12941 check_dsp(ctx);
12942 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12943 break;
12944 case OPC_PRECRQU_S_QB_PH:
12945 check_dsp(ctx);
12946 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12947 break;
12948 }
12949 break;
12950 #ifdef TARGET_MIPS64
12951 case OPC_ABSQ_S_QH_DSP:
12952 switch (op2) {
12953 case OPC_PRECEQ_L_PWL:
12954 check_dsp(ctx);
12955 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12956 break;
12957 case OPC_PRECEQ_L_PWR:
12958 check_dsp(ctx);
12959 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12960 break;
12961 case OPC_PRECEQ_PW_QHL:
12962 check_dsp(ctx);
12963 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12964 break;
12965 case OPC_PRECEQ_PW_QHR:
12966 check_dsp(ctx);
12967 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12968 break;
12969 case OPC_PRECEQ_PW_QHLA:
12970 check_dsp(ctx);
12971 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12972 break;
12973 case OPC_PRECEQ_PW_QHRA:
12974 check_dsp(ctx);
12975 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12976 break;
12977 case OPC_PRECEQU_QH_OBL:
12978 check_dsp(ctx);
12979 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12980 break;
12981 case OPC_PRECEQU_QH_OBR:
12982 check_dsp(ctx);
12983 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12984 break;
12985 case OPC_PRECEQU_QH_OBLA:
12986 check_dsp(ctx);
12987 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12988 break;
12989 case OPC_PRECEQU_QH_OBRA:
12990 check_dsp(ctx);
12991 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12992 break;
12993 case OPC_PRECEU_QH_OBL:
12994 check_dsp(ctx);
12995 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12996 break;
12997 case OPC_PRECEU_QH_OBR:
12998 check_dsp(ctx);
12999 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13000 break;
13001 case OPC_PRECEU_QH_OBLA:
13002 check_dsp(ctx);
13003 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13004 break;
13005 case OPC_PRECEU_QH_OBRA:
13006 check_dsp(ctx);
13007 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13008 break;
13009 case OPC_ABSQ_S_OB:
13010 check_dspr2(ctx);
13011 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13012 break;
13013 case OPC_ABSQ_S_PW:
13014 check_dsp(ctx);
13015 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13016 break;
13017 case OPC_ABSQ_S_QH:
13018 check_dsp(ctx);
13019 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13020 break;
13021 }
13022 break;
13023 case OPC_ADDU_OB_DSP:
13024 switch (op2) {
13025 case OPC_RADDU_L_OB:
13026 check_dsp(ctx);
13027 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13028 break;
13029 case OPC_SUBQ_PW:
13030 check_dsp(ctx);
13031 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13032 break;
13033 case OPC_SUBQ_S_PW:
13034 check_dsp(ctx);
13035 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13036 break;
13037 case OPC_SUBQ_QH:
13038 check_dsp(ctx);
13039 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13040 break;
13041 case OPC_SUBQ_S_QH:
13042 check_dsp(ctx);
13043 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044 break;
13045 case OPC_SUBU_OB:
13046 check_dsp(ctx);
13047 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048 break;
13049 case OPC_SUBU_S_OB:
13050 check_dsp(ctx);
13051 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052 break;
13053 case OPC_SUBU_QH:
13054 check_dspr2(ctx);
13055 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13056 break;
13057 case OPC_SUBU_S_QH:
13058 check_dspr2(ctx);
13059 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13060 break;
13061 case OPC_SUBUH_OB:
13062 check_dspr2(ctx);
13063 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13064 break;
13065 case OPC_SUBUH_R_OB:
13066 check_dspr2(ctx);
13067 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13068 break;
13069 case OPC_ADDQ_PW:
13070 check_dsp(ctx);
13071 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13072 break;
13073 case OPC_ADDQ_S_PW:
13074 check_dsp(ctx);
13075 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13076 break;
13077 case OPC_ADDQ_QH:
13078 check_dsp(ctx);
13079 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13080 break;
13081 case OPC_ADDQ_S_QH:
13082 check_dsp(ctx);
13083 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084 break;
13085 case OPC_ADDU_OB:
13086 check_dsp(ctx);
13087 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13088 break;
13089 case OPC_ADDU_S_OB:
13090 check_dsp(ctx);
13091 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092 break;
13093 case OPC_ADDU_QH:
13094 check_dspr2(ctx);
13095 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13096 break;
13097 case OPC_ADDU_S_QH:
13098 check_dspr2(ctx);
13099 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13100 break;
13101 case OPC_ADDUH_OB:
13102 check_dspr2(ctx);
13103 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13104 break;
13105 case OPC_ADDUH_R_OB:
13106 check_dspr2(ctx);
13107 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13108 break;
13109 }
13110 break;
13111 case OPC_CMPU_EQ_OB_DSP:
13112 switch (op2) {
13113 case OPC_PRECR_OB_QH:
13114 check_dspr2(ctx);
13115 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13116 break;
13117 case OPC_PRECR_SRA_QH_PW:
13118 check_dspr2(ctx);
13119 {
13120 TCGv_i32 ret_t = tcg_const_i32(ret);
13121 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13122 tcg_temp_free_i32(ret_t);
13123 break;
13124 }
13125 case OPC_PRECR_SRA_R_QH_PW:
13126 check_dspr2(ctx);
13127 {
13128 TCGv_i32 sa_v = tcg_const_i32(ret);
13129 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13130 tcg_temp_free_i32(sa_v);
13131 break;
13132 }
13133 case OPC_PRECRQ_OB_QH:
13134 check_dsp(ctx);
13135 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13136 break;
13137 case OPC_PRECRQ_PW_L:
13138 check_dsp(ctx);
13139 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13140 break;
13141 case OPC_PRECRQ_QH_PW:
13142 check_dsp(ctx);
13143 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13144 break;
13145 case OPC_PRECRQ_RS_QH_PW:
13146 check_dsp(ctx);
13147 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13148 break;
13149 case OPC_PRECRQU_S_OB_QH:
13150 check_dsp(ctx);
13151 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13152 break;
13153 }
13154 break;
13155 #endif
13156 }
13157
13158 tcg_temp_free(v1_t);
13159 tcg_temp_free(v2_t);
13160
13161 (void)opn; /* avoid a compiler warning */
13162 MIPS_DEBUG("%s", opn);
13163 }
13164
13165 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13166 int ret, int v1, int v2)
13167 {
13168 uint32_t op2;
13169 const char *opn = "mipsdsp shift";
13170 TCGv t0;
13171 TCGv v1_t;
13172 TCGv v2_t;
13173
13174 if (ret == 0) {
13175 /* Treat as NOP. */
13176 MIPS_DEBUG("NOP");
13177 return;
13178 }
13179
13180 t0 = tcg_temp_new();
13181 v1_t = tcg_temp_new();
13182 v2_t = tcg_temp_new();
13183
13184 tcg_gen_movi_tl(t0, v1);
13185 gen_load_gpr(v1_t, v1);
13186 gen_load_gpr(v2_t, v2);
13187
13188 switch (opc) {
13189 case OPC_SHLL_QB_DSP:
13190 {
13191 op2 = MASK_SHLL_QB(ctx->opcode);
13192 switch (op2) {
13193 case OPC_SHLL_QB:
13194 check_dsp(ctx);
13195 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13196 break;
13197 case OPC_SHLLV_QB:
13198 check_dsp(ctx);
13199 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13200 break;
13201 case OPC_SHLL_PH:
13202 check_dsp(ctx);
13203 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13204 break;
13205 case OPC_SHLLV_PH:
13206 check_dsp(ctx);
13207 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13208 break;
13209 case OPC_SHLL_S_PH:
13210 check_dsp(ctx);
13211 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13212 break;
13213 case OPC_SHLLV_S_PH:
13214 check_dsp(ctx);
13215 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13216 break;
13217 case OPC_SHLL_S_W:
13218 check_dsp(ctx);
13219 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13220 break;
13221 case OPC_SHLLV_S_W:
13222 check_dsp(ctx);
13223 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13224 break;
13225 case OPC_SHRL_QB:
13226 check_dsp(ctx);
13227 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13228 break;
13229 case OPC_SHRLV_QB:
13230 check_dsp(ctx);
13231 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13232 break;
13233 case OPC_SHRL_PH:
13234 check_dspr2(ctx);
13235 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13236 break;
13237 case OPC_SHRLV_PH:
13238 check_dspr2(ctx);
13239 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13240 break;
13241 case OPC_SHRA_QB:
13242 check_dspr2(ctx);
13243 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13244 break;
13245 case OPC_SHRA_R_QB:
13246 check_dspr2(ctx);
13247 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13248 break;
13249 case OPC_SHRAV_QB:
13250 check_dspr2(ctx);
13251 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13252 break;
13253 case OPC_SHRAV_R_QB:
13254 check_dspr2(ctx);
13255 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13256 break;
13257 case OPC_SHRA_PH:
13258 check_dsp(ctx);
13259 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13260 break;
13261 case OPC_SHRA_R_PH:
13262 check_dsp(ctx);
13263 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13264 break;
13265 case OPC_SHRAV_PH:
13266 check_dsp(ctx);
13267 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13268 break;
13269 case OPC_SHRAV_R_PH:
13270 check_dsp(ctx);
13271 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13272 break;
13273 case OPC_SHRA_R_W:
13274 check_dsp(ctx);
13275 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13276 break;
13277 case OPC_SHRAV_R_W:
13278 check_dsp(ctx);
13279 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13280 break;
13281 default: /* Invalid */
13282 MIPS_INVAL("MASK SHLL.QB");
13283 generate_exception(ctx, EXCP_RI);
13284 break;
13285 }
13286 break;
13287 }
13288 #ifdef TARGET_MIPS64
13289 case OPC_SHLL_OB_DSP:
13290 op2 = MASK_SHLL_OB(ctx->opcode);
13291 switch (op2) {
13292 case OPC_SHLL_PW:
13293 check_dsp(ctx);
13294 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13295 break;
13296 case OPC_SHLLV_PW:
13297 check_dsp(ctx);
13298 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13299 break;
13300 case OPC_SHLL_S_PW:
13301 check_dsp(ctx);
13302 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13303 break;
13304 case OPC_SHLLV_S_PW:
13305 check_dsp(ctx);
13306 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13307 break;
13308 case OPC_SHLL_OB:
13309 check_dsp(ctx);
13310 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13311 break;
13312 case OPC_SHLLV_OB:
13313 check_dsp(ctx);
13314 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13315 break;
13316 case OPC_SHLL_QH:
13317 check_dsp(ctx);
13318 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13319 break;
13320 case OPC_SHLLV_QH:
13321 check_dsp(ctx);
13322 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13323 break;
13324 case OPC_SHLL_S_QH:
13325 check_dsp(ctx);
13326 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13327 break;
13328 case OPC_SHLLV_S_QH:
13329 check_dsp(ctx);
13330 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13331 break;
13332 case OPC_SHRA_OB:
13333 check_dspr2(ctx);
13334 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13335 break;
13336 case OPC_SHRAV_OB:
13337 check_dspr2(ctx);
13338 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13339 break;
13340 case OPC_SHRA_R_OB:
13341 check_dspr2(ctx);
13342 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13343 break;
13344 case OPC_SHRAV_R_OB:
13345 check_dspr2(ctx);
13346 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13347 break;
13348 case OPC_SHRA_PW:
13349 check_dsp(ctx);
13350 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13351 break;
13352 case OPC_SHRAV_PW:
13353 check_dsp(ctx);
13354 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13355 break;
13356 case OPC_SHRA_R_PW:
13357 check_dsp(ctx);
13358 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13359 break;
13360 case OPC_SHRAV_R_PW:
13361 check_dsp(ctx);
13362 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13363 break;
13364 case OPC_SHRA_QH:
13365 check_dsp(ctx);
13366 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13367 break;
13368 case OPC_SHRAV_QH:
13369 check_dsp(ctx);
13370 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13371 break;
13372 case OPC_SHRA_R_QH:
13373 check_dsp(ctx);
13374 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13375 break;
13376 case OPC_SHRAV_R_QH:
13377 check_dsp(ctx);
13378 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13379 break;
13380 case OPC_SHRL_OB:
13381 check_dsp(ctx);
13382 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13383 break;
13384 case OPC_SHRLV_OB:
13385 check_dsp(ctx);
13386 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13387 break;
13388 case OPC_SHRL_QH:
13389 check_dspr2(ctx);
13390 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13391 break;
13392 case OPC_SHRLV_QH:
13393 check_dspr2(ctx);
13394 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13395 break;
13396 default: /* Invalid */
13397 MIPS_INVAL("MASK SHLL.OB");
13398 generate_exception(ctx, EXCP_RI);
13399 break;
13400 }
13401 break;
13402 #endif
13403 }
13404
13405 tcg_temp_free(t0);
13406 tcg_temp_free(v1_t);
13407 tcg_temp_free(v2_t);
13408 (void)opn; /* avoid a compiler warning */
13409 MIPS_DEBUG("%s", opn);
13410 }
13411
13412 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13413 int ret, int v1, int v2, int check_ret)
13414 {
13415 const char *opn = "mipsdsp multiply";
13416 TCGv_i32 t0;
13417 TCGv v1_t;
13418 TCGv v2_t;
13419
13420 if ((ret == 0) && (check_ret == 1)) {
13421 /* Treat as NOP. */
13422 MIPS_DEBUG("NOP");
13423 return;
13424 }
13425
13426 t0 = tcg_temp_new_i32();
13427 v1_t = tcg_temp_new();
13428 v2_t = tcg_temp_new();
13429
13430 tcg_gen_movi_i32(t0, ret);
13431 gen_load_gpr(v1_t, v1);
13432 gen_load_gpr(v2_t, v2);
13433
13434 switch (op1) {
13435 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13436 * the same mask and op1. */
13437 case OPC_MULT_G_2E:
13438 switch (op2) {
13439 case OPC_MUL_PH:
13440 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13441 break;
13442 case OPC_MUL_S_PH:
13443 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13444 break;
13445 case OPC_MULQ_S_W:
13446 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13447 break;
13448 case OPC_MULQ_RS_W:
13449 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13450 break;
13451 }
13452 break;
13453 case OPC_DPA_W_PH_DSP:
13454 switch (op2) {
13455 case OPC_DPAU_H_QBL:
13456 check_dsp(ctx);
13457 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13458 break;
13459 case OPC_DPAU_H_QBR:
13460 check_dsp(ctx);
13461 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13462 break;
13463 case OPC_DPSU_H_QBL:
13464 check_dsp(ctx);
13465 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13466 break;
13467 case OPC_DPSU_H_QBR:
13468 check_dsp(ctx);
13469 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13470 break;
13471 case OPC_DPA_W_PH:
13472 check_dspr2(ctx);
13473 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13474 break;
13475 case OPC_DPAX_W_PH:
13476 check_dspr2(ctx);
13477 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13478 break;
13479 case OPC_DPAQ_S_W_PH:
13480 check_dsp(ctx);
13481 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13482 break;
13483 case OPC_DPAQX_S_W_PH:
13484 check_dspr2(ctx);
13485 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13486 break;
13487 case OPC_DPAQX_SA_W_PH:
13488 check_dspr2(ctx);
13489 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13490 break;
13491 case OPC_DPS_W_PH:
13492 check_dspr2(ctx);
13493 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13494 break;
13495 case OPC_DPSX_W_PH:
13496 check_dspr2(ctx);
13497 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13498 break;
13499 case OPC_DPSQ_S_W_PH:
13500 check_dsp(ctx);
13501 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13502 break;
13503 case OPC_DPSQX_S_W_PH:
13504 check_dspr2(ctx);
13505 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13506 break;
13507 case OPC_DPSQX_SA_W_PH:
13508 check_dspr2(ctx);
13509 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13510 break;
13511 case OPC_MULSAQ_S_W_PH:
13512 check_dsp(ctx);
13513 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13514 break;
13515 case OPC_DPAQ_SA_L_W:
13516 check_dsp(ctx);
13517 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13518 break;
13519 case OPC_DPSQ_SA_L_W:
13520 check_dsp(ctx);
13521 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13522 break;
13523 case OPC_MAQ_S_W_PHL:
13524 check_dsp(ctx);
13525 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13526 break;
13527 case OPC_MAQ_S_W_PHR:
13528 check_dsp(ctx);
13529 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13530 break;
13531 case OPC_MAQ_SA_W_PHL:
13532 check_dsp(ctx);
13533 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13534 break;
13535 case OPC_MAQ_SA_W_PHR:
13536 check_dsp(ctx);
13537 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13538 break;
13539 case OPC_MULSA_W_PH:
13540 check_dspr2(ctx);
13541 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13542 break;
13543 }
13544 break;
13545 #ifdef TARGET_MIPS64
13546 case OPC_DPAQ_W_QH_DSP:
13547 {
13548 int ac = ret & 0x03;
13549 tcg_gen_movi_i32(t0, ac);
13550
13551 switch (op2) {
13552 case OPC_DMADD:
13553 check_dsp(ctx);
13554 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13555 break;
13556 case OPC_DMADDU:
13557 check_dsp(ctx);
13558 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13559 break;
13560 case OPC_DMSUB:
13561 check_dsp(ctx);
13562 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13563 break;
13564 case OPC_DMSUBU:
13565 check_dsp(ctx);
13566 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13567 break;
13568 case OPC_DPA_W_QH:
13569 check_dspr2(ctx);
13570 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13571 break;
13572 case OPC_DPAQ_S_W_QH:
13573 check_dsp(ctx);
13574 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13575 break;
13576 case OPC_DPAQ_SA_L_PW:
13577 check_dsp(ctx);
13578 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13579 break;
13580 case OPC_DPAU_H_OBL:
13581 check_dsp(ctx);
13582 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13583 break;
13584 case OPC_DPAU_H_OBR:
13585 check_dsp(ctx);
13586 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13587 break;
13588 case OPC_DPS_W_QH:
13589 check_dspr2(ctx);
13590 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13591 break;
13592 case OPC_DPSQ_S_W_QH:
13593 check_dsp(ctx);
13594 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13595 break;
13596 case OPC_DPSQ_SA_L_PW:
13597 check_dsp(ctx);
13598 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13599 break;
13600 case OPC_DPSU_H_OBL:
13601 check_dsp(ctx);
13602 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13603 break;
13604 case OPC_DPSU_H_OBR:
13605 check_dsp(ctx);
13606 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13607 break;
13608 case OPC_MAQ_S_L_PWL:
13609 check_dsp(ctx);
13610 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13611 break;
13612 case OPC_MAQ_S_L_PWR:
13613 check_dsp(ctx);
13614 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13615 break;
13616 case OPC_MAQ_S_W_QHLL:
13617 check_dsp(ctx);
13618 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13619 break;
13620 case OPC_MAQ_SA_W_QHLL:
13621 check_dsp(ctx);
13622 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13623 break;
13624 case OPC_MAQ_S_W_QHLR:
13625 check_dsp(ctx);
13626 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13627 break;
13628 case OPC_MAQ_SA_W_QHLR:
13629 check_dsp(ctx);
13630 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13631 break;
13632 case OPC_MAQ_S_W_QHRL:
13633 check_dsp(ctx);
13634 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13635 break;
13636 case OPC_MAQ_SA_W_QHRL:
13637 check_dsp(ctx);
13638 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13639 break;
13640 case OPC_MAQ_S_W_QHRR:
13641 check_dsp(ctx);
13642 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13643 break;
13644 case OPC_MAQ_SA_W_QHRR:
13645 check_dsp(ctx);
13646 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13647 break;
13648 case OPC_MULSAQ_S_L_PW:
13649 check_dsp(ctx);
13650 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13651 break;
13652 case OPC_MULSAQ_S_W_QH:
13653 check_dsp(ctx);
13654 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13655 break;
13656 }
13657 }
13658 break;
13659 #endif
13660 case OPC_ADDU_QB_DSP:
13661 switch (op2) {
13662 case OPC_MULEU_S_PH_QBL:
13663 check_dsp(ctx);
13664 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13665 break;
13666 case OPC_MULEU_S_PH_QBR:
13667 check_dsp(ctx);
13668 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13669 break;
13670 case OPC_MULQ_RS_PH:
13671 check_dsp(ctx);
13672 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13673 break;
13674 case OPC_MULEQ_S_W_PHL:
13675 check_dsp(ctx);
13676 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13677 break;
13678 case OPC_MULEQ_S_W_PHR:
13679 check_dsp(ctx);
13680 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13681 break;
13682 case OPC_MULQ_S_PH:
13683 check_dspr2(ctx);
13684 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13685 break;
13686 }
13687 break;
13688 #ifdef TARGET_MIPS64
13689 case OPC_ADDU_OB_DSP:
13690 switch (op2) {
13691 case OPC_MULEQ_S_PW_QHL:
13692 check_dsp(ctx);
13693 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13694 break;
13695 case OPC_MULEQ_S_PW_QHR:
13696 check_dsp(ctx);
13697 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13698 break;
13699 case OPC_MULEU_S_QH_OBL:
13700 check_dsp(ctx);
13701 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13702 break;
13703 case OPC_MULEU_S_QH_OBR:
13704 check_dsp(ctx);
13705 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13706 break;
13707 case OPC_MULQ_RS_QH:
13708 check_dsp(ctx);
13709 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13710 break;
13711 }
13712 break;
13713 #endif
13714 }
13715
13716 tcg_temp_free_i32(t0);
13717 tcg_temp_free(v1_t);
13718 tcg_temp_free(v2_t);
13719
13720 (void)opn; /* avoid a compiler warning */
13721 MIPS_DEBUG("%s", opn);
13722
13723 }
13724
13725 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13726 uint32_t op1, uint32_t op2,
13727 int ret, int val)
13728 {
13729 const char *opn = "mipsdsp Bit/ Manipulation";
13730 int16_t imm;
13731 TCGv t0;
13732 TCGv val_t;
13733
13734 if (ret == 0) {
13735 /* Treat as NOP. */
13736 MIPS_DEBUG("NOP");
13737 return;
13738 }
13739
13740 t0 = tcg_temp_new();
13741 val_t = tcg_temp_new();
13742 gen_load_gpr(val_t, val);
13743
13744 switch (op1) {
13745 case OPC_ABSQ_S_PH_DSP:
13746 switch (op2) {
13747 case OPC_BITREV:
13748 check_dsp(ctx);
13749 gen_helper_bitrev(cpu_gpr[ret], val_t);
13750 break;
13751 case OPC_REPL_QB:
13752 check_dsp(ctx);
13753 {
13754 target_long result;
13755 imm = (ctx->opcode >> 16) & 0xFF;
13756 result = (uint32_t)imm << 24 |
13757 (uint32_t)imm << 16 |
13758 (uint32_t)imm << 8 |
13759 (uint32_t)imm;
13760 result = (int32_t)result;
13761 tcg_gen_movi_tl(cpu_gpr[ret], result);
13762 }
13763 break;
13764 case OPC_REPLV_QB:
13765 check_dsp(ctx);
13766 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13767 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13768 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13769 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13770 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13771 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13772 break;
13773 case OPC_REPL_PH:
13774 check_dsp(ctx);
13775 {
13776 imm = (ctx->opcode >> 16) & 0x03FF;
13777 tcg_gen_movi_tl(cpu_gpr[ret], \
13778 (target_long)((int32_t)imm << 16 | \
13779 (uint32_t)(uint16_t)imm));
13780 }
13781 break;
13782 case OPC_REPLV_PH:
13783 check_dsp(ctx);
13784 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13785 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13786 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13787 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13788 break;
13789 }
13790 break;
13791 #ifdef TARGET_MIPS64
13792 case OPC_ABSQ_S_QH_DSP:
13793 switch (op2) {
13794 case OPC_REPL_OB:
13795 check_dsp(ctx);
13796 {
13797 target_long temp;
13798
13799 imm = (ctx->opcode >> 16) & 0xFF;
13800 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13801 temp = (temp << 16) | temp;
13802 temp = (temp << 32) | temp;
13803 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13804 break;
13805 }
13806 case OPC_REPL_PW:
13807 check_dsp(ctx);
13808 {
13809 target_long temp;
13810
13811 imm = (ctx->opcode >> 16) & 0x03FF;
13812 imm = (int16_t)(imm << 6) >> 6;
13813 temp = ((target_long)imm << 32) \
13814 | ((target_long)imm & 0xFFFFFFFF);
13815 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13816 break;
13817 }
13818 case OPC_REPL_QH:
13819 check_dsp(ctx);
13820 {
13821 target_long temp;
13822
13823 imm = (ctx->opcode >> 16) & 0x03FF;
13824 imm = (int16_t)(imm << 6) >> 6;
13825
13826 temp = ((uint64_t)(uint16_t)imm << 48) |
13827 ((uint64_t)(uint16_t)imm << 32) |
13828 ((uint64_t)(uint16_t)imm << 16) |
13829 (uint64_t)(uint16_t)imm;
13830 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13831 break;
13832 }
13833 case OPC_REPLV_OB:
13834 check_dsp(ctx);
13835 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13836 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13837 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13838 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13839 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13840 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13841 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13842 break;
13843 case OPC_REPLV_PW:
13844 check_dsp(ctx);
13845 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13846 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13847 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13848 break;
13849 case OPC_REPLV_QH:
13850 check_dsp(ctx);
13851 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13852 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13853 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13854 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13855 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13856 break;
13857 }
13858 break;
13859 #endif
13860 }
13861 tcg_temp_free(t0);
13862 tcg_temp_free(val_t);
13863
13864 (void)opn; /* avoid a compiler warning */
13865 MIPS_DEBUG("%s", opn);
13866 }
13867
13868 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13869 uint32_t op1, uint32_t op2,
13870 int ret, int v1, int v2, int check_ret)
13871 {
13872 const char *opn = "mipsdsp add compare pick";
13873 TCGv_i32 t0;
13874 TCGv t1;
13875 TCGv v1_t;
13876 TCGv v2_t;
13877
13878 if ((ret == 0) && (check_ret == 1)) {
13879 /* Treat as NOP. */
13880 MIPS_DEBUG("NOP");
13881 return;
13882 }
13883
13884 t0 = tcg_temp_new_i32();
13885 t1 = tcg_temp_new();
13886 v1_t = tcg_temp_new();
13887 v2_t = tcg_temp_new();
13888
13889 gen_load_gpr(v1_t, v1);
13890 gen_load_gpr(v2_t, v2);
13891
13892 switch (op1) {
13893 case OPC_APPEND_DSP:
13894 switch (op2) {
13895 case OPC_APPEND:
13896 tcg_gen_movi_i32(t0, v2);
13897 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13898 break;
13899 case OPC_PREPEND:
13900 tcg_gen_movi_i32(t0, v2);
13901 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13902 break;
13903 case OPC_BALIGN:
13904 tcg_gen_movi_i32(t0, v2);
13905 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13906 break;
13907 default: /* Invid */
13908 MIPS_INVAL("MASK APPEND");
13909 generate_exception(ctx, EXCP_RI);
13910 break;
13911 }
13912 break;
13913 case OPC_CMPU_EQ_QB_DSP:
13914 switch (op2) {
13915 case OPC_CMPU_EQ_QB:
13916 check_dsp(ctx);
13917 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13918 break;
13919 case OPC_CMPU_LT_QB:
13920 check_dsp(ctx);
13921 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13922 break;
13923 case OPC_CMPU_LE_QB:
13924 check_dsp(ctx);
13925 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13926 break;
13927 case OPC_CMPGU_EQ_QB:
13928 check_dsp(ctx);
13929 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13930 break;
13931 case OPC_CMPGU_LT_QB:
13932 check_dsp(ctx);
13933 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13934 break;
13935 case OPC_CMPGU_LE_QB:
13936 check_dsp(ctx);
13937 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13938 break;
13939 case OPC_CMPGDU_EQ_QB:
13940 check_dspr2(ctx);
13941 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13942 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13943 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13944 tcg_gen_shli_tl(t1, t1, 24);
13945 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13946 break;
13947 case OPC_CMPGDU_LT_QB:
13948 check_dspr2(ctx);
13949 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13950 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13951 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13952 tcg_gen_shli_tl(t1, t1, 24);
13953 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13954 break;
13955 case OPC_CMPGDU_LE_QB:
13956 check_dspr2(ctx);
13957 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13958 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13959 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13960 tcg_gen_shli_tl(t1, t1, 24);
13961 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13962 break;
13963 case OPC_CMP_EQ_PH:
13964 check_dsp(ctx);
13965 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13966 break;
13967 case OPC_CMP_LT_PH:
13968 check_dsp(ctx);
13969 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13970 break;
13971 case OPC_CMP_LE_PH:
13972 check_dsp(ctx);
13973 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13974 break;
13975 case OPC_PICK_QB:
13976 check_dsp(ctx);
13977 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13978 break;
13979 case OPC_PICK_PH:
13980 check_dsp(ctx);
13981 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13982 break;
13983 case OPC_PACKRL_PH:
13984 check_dsp(ctx);
13985 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13986 break;
13987 }
13988 break;
13989 #ifdef TARGET_MIPS64
13990 case OPC_CMPU_EQ_OB_DSP:
13991 switch (op2) {
13992 case OPC_CMP_EQ_PW:
13993 check_dsp(ctx);
13994 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13995 break;
13996 case OPC_CMP_LT_PW:
13997 check_dsp(ctx);
13998 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13999 break;
14000 case OPC_CMP_LE_PW:
14001 check_dsp(ctx);
14002 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
14003 break;
14004 case OPC_CMP_EQ_QH:
14005 check_dsp(ctx);
14006 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
14007 break;
14008 case OPC_CMP_LT_QH:
14009 check_dsp(ctx);
14010 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14011 break;
14012 case OPC_CMP_LE_QH:
14013 check_dsp(ctx);
14014 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14015 break;
14016 case OPC_CMPGDU_EQ_OB:
14017 check_dspr2(ctx);
14018 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14019 break;
14020 case OPC_CMPGDU_LT_OB:
14021 check_dspr2(ctx);
14022 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14023 break;
14024 case OPC_CMPGDU_LE_OB:
14025 check_dspr2(ctx);
14026 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14027 break;
14028 case OPC_CMPGU_EQ_OB:
14029 check_dsp(ctx);
14030 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14031 break;
14032 case OPC_CMPGU_LT_OB:
14033 check_dsp(ctx);
14034 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14035 break;
14036 case OPC_CMPGU_LE_OB:
14037 check_dsp(ctx);
14038 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14039 break;
14040 case OPC_CMPU_EQ_OB:
14041 check_dsp(ctx);
14042 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14043 break;
14044 case OPC_CMPU_LT_OB:
14045 check_dsp(ctx);
14046 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14047 break;
14048 case OPC_CMPU_LE_OB:
14049 check_dsp(ctx);
14050 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14051 break;
14052 case OPC_PACKRL_PW:
14053 check_dsp(ctx);
14054 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14055 break;
14056 case OPC_PICK_OB:
14057 check_dsp(ctx);
14058 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14059 break;
14060 case OPC_PICK_PW:
14061 check_dsp(ctx);
14062 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14063 break;
14064 case OPC_PICK_QH:
14065 check_dsp(ctx);
14066 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14067 break;
14068 }
14069 break;
14070 case OPC_DAPPEND_DSP:
14071 switch (op2) {
14072 case OPC_DAPPEND:
14073 tcg_gen_movi_i32(t0, v2);
14074 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14075 break;
14076 case OPC_PREPENDD:
14077 tcg_gen_movi_i32(t0, v2);
14078 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14079 break;
14080 case OPC_PREPENDW:
14081 tcg_gen_movi_i32(t0, v2);
14082 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14083 break;
14084 case OPC_DBALIGN:
14085 tcg_gen_movi_i32(t0, v2);
14086 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14087 break;
14088 default: /* Invalid */
14089 MIPS_INVAL("MASK DAPPEND");
14090 generate_exception(ctx, EXCP_RI);
14091 break;
14092 }
14093 break;
14094 #endif
14095 }
14096
14097 tcg_temp_free_i32(t0);
14098 tcg_temp_free(t1);
14099 tcg_temp_free(v1_t);
14100 tcg_temp_free(v2_t);
14101
14102 (void)opn; /* avoid a compiler warning */
14103 MIPS_DEBUG("%s", opn);
14104 }
14105
14106 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14107 int ret, int v1, int v2, int check_ret)
14108
14109 {
14110 const char *opn = "mipsdsp accumulator";
14111 TCGv t0;
14112 TCGv t1;
14113 TCGv v1_t;
14114 TCGv v2_t;
14115 int16_t imm;
14116
14117 if ((ret == 0) && (check_ret == 1)) {
14118 /* Treat as NOP. */
14119 MIPS_DEBUG("NOP");
14120 return;
14121 }
14122
14123 t0 = tcg_temp_new();
14124 t1 = tcg_temp_new();
14125 v1_t = tcg_temp_new();
14126 v2_t = tcg_temp_new();
14127
14128 gen_load_gpr(v1_t, v1);
14129 gen_load_gpr(v2_t, v2);
14130
14131 switch (op1) {
14132 case OPC_EXTR_W_DSP:
14133 check_dsp(ctx);
14134 switch (op2) {
14135 case OPC_EXTR_W:
14136 tcg_gen_movi_tl(t0, v2);
14137 tcg_gen_movi_tl(t1, v1);
14138 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14139 break;
14140 case OPC_EXTR_R_W:
14141 tcg_gen_movi_tl(t0, v2);
14142 tcg_gen_movi_tl(t1, v1);
14143 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14144 break;
14145 case OPC_EXTR_RS_W:
14146 tcg_gen_movi_tl(t0, v2);
14147 tcg_gen_movi_tl(t1, v1);
14148 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14149 break;
14150 case OPC_EXTR_S_H:
14151 tcg_gen_movi_tl(t0, v2);
14152 tcg_gen_movi_tl(t1, v1);
14153 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14154 break;
14155 case OPC_EXTRV_S_H:
14156 tcg_gen_movi_tl(t0, v2);
14157 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14158 break;
14159 case OPC_EXTRV_W:
14160 tcg_gen_movi_tl(t0, v2);
14161 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14162 break;
14163 case OPC_EXTRV_R_W:
14164 tcg_gen_movi_tl(t0, v2);
14165 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14166 break;
14167 case OPC_EXTRV_RS_W:
14168 tcg_gen_movi_tl(t0, v2);
14169 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14170 break;
14171 case OPC_EXTP:
14172 tcg_gen_movi_tl(t0, v2);
14173 tcg_gen_movi_tl(t1, v1);
14174 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14175 break;
14176 case OPC_EXTPV:
14177 tcg_gen_movi_tl(t0, v2);
14178 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14179 break;
14180 case OPC_EXTPDP:
14181 tcg_gen_movi_tl(t0, v2);
14182 tcg_gen_movi_tl(t1, v1);
14183 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14184 break;
14185 case OPC_EXTPDPV:
14186 tcg_gen_movi_tl(t0, v2);
14187 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14188 break;
14189 case OPC_SHILO:
14190 imm = (ctx->opcode >> 20) & 0x3F;
14191 tcg_gen_movi_tl(t0, ret);
14192 tcg_gen_movi_tl(t1, imm);
14193 gen_helper_shilo(t0, t1, cpu_env);
14194 break;
14195 case OPC_SHILOV:
14196 tcg_gen_movi_tl(t0, ret);
14197 gen_helper_shilo(t0, v1_t, cpu_env);
14198 break;
14199 case OPC_MTHLIP:
14200 tcg_gen_movi_tl(t0, ret);
14201 gen_helper_mthlip(t0, v1_t, cpu_env);
14202 break;
14203 case OPC_WRDSP:
14204 imm = (ctx->opcode >> 11) & 0x3FF;
14205 tcg_gen_movi_tl(t0, imm);
14206 gen_helper_wrdsp(v1_t, t0, cpu_env);
14207 break;
14208 case OPC_RDDSP:
14209 imm = (ctx->opcode >> 16) & 0x03FF;
14210 tcg_gen_movi_tl(t0, imm);
14211 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14212 break;
14213 }
14214 break;
14215 #ifdef TARGET_MIPS64
14216 case OPC_DEXTR_W_DSP:
14217 check_dsp(ctx);
14218 switch (op2) {
14219 case OPC_DMTHLIP:
14220 tcg_gen_movi_tl(t0, ret);
14221 gen_helper_dmthlip(v1_t, t0, cpu_env);
14222 break;
14223 case OPC_DSHILO:
14224 {
14225 int shift = (ctx->opcode >> 19) & 0x7F;
14226 int ac = (ctx->opcode >> 11) & 0x03;
14227 tcg_gen_movi_tl(t0, shift);
14228 tcg_gen_movi_tl(t1, ac);
14229 gen_helper_dshilo(t0, t1, cpu_env);
14230 break;
14231 }
14232 case OPC_DSHILOV:
14233 {
14234 int ac = (ctx->opcode >> 11) & 0x03;
14235 tcg_gen_movi_tl(t0, ac);
14236 gen_helper_dshilo(v1_t, t0, cpu_env);
14237 break;
14238 }
14239 case OPC_DEXTP:
14240 tcg_gen_movi_tl(t0, v2);
14241 tcg_gen_movi_tl(t1, v1);
14242
14243 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14244 break;
14245 case OPC_DEXTPV:
14246 tcg_gen_movi_tl(t0, v2);
14247 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14248 break;
14249 case OPC_DEXTPDP:
14250 tcg_gen_movi_tl(t0, v2);
14251 tcg_gen_movi_tl(t1, v1);
14252 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14253 break;
14254 case OPC_DEXTPDPV:
14255 tcg_gen_movi_tl(t0, v2);
14256 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14257 break;
14258 case OPC_DEXTR_L:
14259 tcg_gen_movi_tl(t0, v2);
14260 tcg_gen_movi_tl(t1, v1);
14261 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14262 break;
14263 case OPC_DEXTR_R_L:
14264 tcg_gen_movi_tl(t0, v2);
14265 tcg_gen_movi_tl(t1, v1);
14266 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14267 break;
14268 case OPC_DEXTR_RS_L:
14269 tcg_gen_movi_tl(t0, v2);
14270 tcg_gen_movi_tl(t1, v1);
14271 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14272 break;
14273 case OPC_DEXTR_W:
14274 tcg_gen_movi_tl(t0, v2);
14275 tcg_gen_movi_tl(t1, v1);
14276 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14277 break;
14278 case OPC_DEXTR_R_W:
14279 tcg_gen_movi_tl(t0, v2);
14280 tcg_gen_movi_tl(t1, v1);
14281 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14282 break;
14283 case OPC_DEXTR_RS_W:
14284 tcg_gen_movi_tl(t0, v2);
14285 tcg_gen_movi_tl(t1, v1);
14286 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14287 break;
14288 case OPC_DEXTR_S_H:
14289 tcg_gen_movi_tl(t0, v2);
14290 tcg_gen_movi_tl(t1, v1);
14291 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14292 break;
14293 case OPC_DEXTRV_S_H:
14294 tcg_gen_movi_tl(t0, v2);
14295 tcg_gen_movi_tl(t1, v1);
14296 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14297 break;
14298 case OPC_DEXTRV_L:
14299 tcg_gen_movi_tl(t0, v2);
14300 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14301 break;
14302 case OPC_DEXTRV_R_L:
14303 tcg_gen_movi_tl(t0, v2);
14304 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14305 break;
14306 case OPC_DEXTRV_RS_L:
14307 tcg_gen_movi_tl(t0, v2);
14308 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14309 break;
14310 case OPC_DEXTRV_W:
14311 tcg_gen_movi_tl(t0, v2);
14312 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14313 break;
14314 case OPC_DEXTRV_R_W:
14315 tcg_gen_movi_tl(t0, v2);
14316 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14317 break;
14318 case OPC_DEXTRV_RS_W:
14319 tcg_gen_movi_tl(t0, v2);
14320 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14321 break;
14322 }
14323 break;
14324 #endif
14325 }
14326
14327 tcg_temp_free(t0);
14328 tcg_temp_free(t1);
14329 tcg_temp_free(v1_t);
14330 tcg_temp_free(v2_t);
14331
14332 (void)opn; /* avoid a compiler warning */
14333 MIPS_DEBUG("%s", opn);
14334 }
14335
14336 /* End MIPSDSP functions. */
14337
14338 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14339 {
14340 int32_t offset;
14341 int rs, rt, rd, sa;
14342 uint32_t op, op1, op2;
14343 int16_t imm;
14344
14345 /* make sure instructions are on a word boundary */
14346 if (ctx->pc & 0x3) {
14347 env->CP0_BadVAddr = ctx->pc;
14348 generate_exception(ctx, EXCP_AdEL);
14349 return;
14350 }
14351
14352 /* Handle blikely not taken case */
14353 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14354 int l1 = gen_new_label();
14355
14356 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14357 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14358 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14359 gen_goto_tb(ctx, 1, ctx->pc + 4);
14360 gen_set_label(l1);
14361 }
14362
14363 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14364 tcg_gen_debug_insn_start(ctx->pc);
14365 }
14366
14367 op = MASK_OP_MAJOR(ctx->opcode);
14368 rs = (ctx->opcode >> 21) & 0x1f;
14369 rt = (ctx->opcode >> 16) & 0x1f;
14370 rd = (ctx->opcode >> 11) & 0x1f;
14371 sa = (ctx->opcode >> 6) & 0x1f;
14372 imm = (int16_t)ctx->opcode;
14373 switch (op) {
14374 case OPC_SPECIAL:
14375 op1 = MASK_SPECIAL(ctx->opcode);
14376 switch (op1) {
14377 case OPC_SLL: /* Shift with immediate */
14378 case OPC_SRA:
14379 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14380 break;
14381 case OPC_SRL:
14382 switch ((ctx->opcode >> 21) & 0x1f) {
14383 case 1:
14384 /* rotr is decoded as srl on non-R2 CPUs */
14385 if (env->insn_flags & ISA_MIPS32R2) {
14386 op1 = OPC_ROTR;
14387 }
14388 /* Fallthrough */
14389 case 0:
14390 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14391 break;
14392 default:
14393 generate_exception(ctx, EXCP_RI);
14394 break;
14395 }
14396 break;
14397 case OPC_MOVN: /* Conditional move */
14398 case OPC_MOVZ:
14399 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14400 INSN_LOONGSON2E | INSN_LOONGSON2F);
14401 gen_cond_move(env, ctx, op1, rd, rs, rt);
14402 break;
14403 case OPC_ADD ... OPC_SUBU:
14404 gen_arith(env, ctx, op1, rd, rs, rt);
14405 break;
14406 case OPC_SLLV: /* Shifts */
14407 case OPC_SRAV:
14408 gen_shift(env, ctx, op1, rd, rs, rt);
14409 break;
14410 case OPC_SRLV:
14411 switch ((ctx->opcode >> 6) & 0x1f) {
14412 case 1:
14413 /* rotrv is decoded as srlv on non-R2 CPUs */
14414 if (env->insn_flags & ISA_MIPS32R2) {
14415 op1 = OPC_ROTRV;
14416 }
14417 /* Fallthrough */
14418 case 0:
14419 gen_shift(env, ctx, op1, rd, rs, rt);
14420 break;
14421 default:
14422 generate_exception(ctx, EXCP_RI);
14423 break;
14424 }
14425 break;
14426 case OPC_SLT: /* Set on less than */
14427 case OPC_SLTU:
14428 gen_slt(env, ctx, op1, rd, rs, rt);
14429 break;
14430 case OPC_AND: /* Logic*/
14431 case OPC_OR:
14432 case OPC_NOR:
14433 case OPC_XOR:
14434 gen_logic(env, ctx, op1, rd, rs, rt);
14435 break;
14436 case OPC_MULT ... OPC_DIVU:
14437 if (sa) {
14438 check_insn(env, ctx, INSN_VR54XX);
14439 op1 = MASK_MUL_VR54XX(ctx->opcode);
14440 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14441 } else
14442 gen_muldiv(ctx, op1, rs, rt);
14443 break;
14444 case OPC_JR ... OPC_JALR:
14445 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14446 *is_branch = 1;
14447 break;
14448 case OPC_TGE ... OPC_TEQ: /* Traps */
14449 case OPC_TNE:
14450 gen_trap(ctx, op1, rs, rt, -1);
14451 break;
14452 case OPC_MFHI: /* Move from HI/LO */
14453 case OPC_MFLO:
14454 gen_HILO(ctx, op1, rd);
14455 break;
14456 case OPC_MTHI:
14457 case OPC_MTLO: /* Move to HI/LO */
14458 gen_HILO(ctx, op1, rs);
14459 break;
14460 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14461 #ifdef MIPS_STRICT_STANDARD
14462 MIPS_INVAL("PMON / selsl");
14463 generate_exception(ctx, EXCP_RI);
14464 #else
14465 gen_helper_0e0i(pmon, sa);
14466 #endif
14467 break;
14468 case OPC_SYSCALL:
14469 generate_exception(ctx, EXCP_SYSCALL);
14470 ctx->bstate = BS_STOP;
14471 break;
14472 case OPC_BREAK:
14473 generate_exception(ctx, EXCP_BREAK);
14474 break;
14475 case OPC_SPIM:
14476 #ifdef MIPS_STRICT_STANDARD
14477 MIPS_INVAL("SPIM");
14478 generate_exception(ctx, EXCP_RI);
14479 #else
14480 /* Implemented as RI exception for now. */
14481 MIPS_INVAL("spim (unofficial)");
14482 generate_exception(ctx, EXCP_RI);
14483 #endif
14484 break;
14485 case OPC_SYNC:
14486 /* Treat as NOP. */
14487 break;
14488
14489 case OPC_MOVCI:
14490 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14491 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14492 check_cp1_enabled(ctx);
14493 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14494 (ctx->opcode >> 16) & 1);
14495 } else {
14496 generate_exception_err(ctx, EXCP_CpU, 1);
14497 }
14498 break;
14499
14500 #if defined(TARGET_MIPS64)
14501 /* MIPS64 specific opcodes */
14502 case OPC_DSLL:
14503 case OPC_DSRA:
14504 case OPC_DSLL32:
14505 case OPC_DSRA32:
14506 check_insn(env, ctx, ISA_MIPS3);
14507 check_mips_64(ctx);
14508 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14509 break;
14510 case OPC_DSRL:
14511 switch ((ctx->opcode >> 21) & 0x1f) {
14512 case 1:
14513 /* drotr is decoded as dsrl on non-R2 CPUs */
14514 if (env->insn_flags & ISA_MIPS32R2) {
14515 op1 = OPC_DROTR;
14516 }
14517 /* Fallthrough */
14518 case 0:
14519 check_insn(env, ctx, ISA_MIPS3);
14520 check_mips_64(ctx);
14521 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14522 break;
14523 default:
14524 generate_exception(ctx, EXCP_RI);
14525 break;
14526 }
14527 break;
14528 case OPC_DSRL32:
14529 switch ((ctx->opcode >> 21) & 0x1f) {
14530 case 1:
14531 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14532 if (env->insn_flags & ISA_MIPS32R2) {
14533 op1 = OPC_DROTR32;
14534 }
14535 /* Fallthrough */
14536 case 0:
14537 check_insn(env, ctx, ISA_MIPS3);
14538 check_mips_64(ctx);
14539 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14540 break;
14541 default:
14542 generate_exception(ctx, EXCP_RI);
14543 break;
14544 }
14545 break;
14546 case OPC_DADD ... OPC_DSUBU:
14547 check_insn(env, ctx, ISA_MIPS3);
14548 check_mips_64(ctx);
14549 gen_arith(env, ctx, op1, rd, rs, rt);
14550 break;
14551 case OPC_DSLLV:
14552 case OPC_DSRAV:
14553 check_insn(env, ctx, ISA_MIPS3);
14554 check_mips_64(ctx);
14555 gen_shift(env, ctx, op1, rd, rs, rt);
14556 break;
14557 case OPC_DSRLV:
14558 switch ((ctx->opcode >> 6) & 0x1f) {
14559 case 1:
14560 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14561 if (env->insn_flags & ISA_MIPS32R2) {
14562 op1 = OPC_DROTRV;
14563 }
14564 /* Fallthrough */
14565 case 0:
14566 check_insn(env, ctx, ISA_MIPS3);
14567 check_mips_64(ctx);
14568 gen_shift(env, ctx, op1, rd, rs, rt);
14569 break;
14570 default:
14571 generate_exception(ctx, EXCP_RI);
14572 break;
14573 }
14574 break;
14575 case OPC_DMULT ... OPC_DDIVU:
14576 check_insn(env, ctx, ISA_MIPS3);
14577 check_mips_64(ctx);
14578 gen_muldiv(ctx, op1, rs, rt);
14579 break;
14580 #endif
14581 default: /* Invalid */
14582 MIPS_INVAL("special");
14583 generate_exception(ctx, EXCP_RI);
14584 break;
14585 }
14586 break;
14587 case OPC_SPECIAL2:
14588 op1 = MASK_SPECIAL2(ctx->opcode);
14589 switch (op1) {
14590 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14591 case OPC_MSUB ... OPC_MSUBU:
14592 check_insn(env, ctx, ISA_MIPS32);
14593 gen_muldiv(ctx, op1, rs, rt);
14594 break;
14595 case OPC_MUL:
14596 gen_arith(env, ctx, op1, rd, rs, rt);
14597 break;
14598 case OPC_CLO:
14599 case OPC_CLZ:
14600 check_insn(env, ctx, ISA_MIPS32);
14601 gen_cl(ctx, op1, rd, rs);
14602 break;
14603 case OPC_SDBBP:
14604 /* XXX: not clear which exception should be raised
14605 * when in debug mode...
14606 */
14607 check_insn(env, ctx, ISA_MIPS32);
14608 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14609 generate_exception(ctx, EXCP_DBp);
14610 } else {
14611 generate_exception(ctx, EXCP_DBp);
14612 }
14613 /* Treat as NOP. */
14614 break;
14615 case OPC_DIV_G_2F:
14616 case OPC_DIVU_G_2F:
14617 case OPC_MULT_G_2F:
14618 case OPC_MULTU_G_2F:
14619 case OPC_MOD_G_2F:
14620 case OPC_MODU_G_2F:
14621 check_insn(env, ctx, INSN_LOONGSON2F);
14622 gen_loongson_integer(ctx, op1, rd, rs, rt);
14623 break;
14624 #if defined(TARGET_MIPS64)
14625 case OPC_DCLO:
14626 case OPC_DCLZ:
14627 check_insn(env, ctx, ISA_MIPS64);
14628 check_mips_64(ctx);
14629 gen_cl(ctx, op1, rd, rs);
14630 break;
14631 case OPC_DMULT_G_2F:
14632 case OPC_DMULTU_G_2F:
14633 case OPC_DDIV_G_2F:
14634 case OPC_DDIVU_G_2F:
14635 case OPC_DMOD_G_2F:
14636 case OPC_DMODU_G_2F:
14637 check_insn(env, ctx, INSN_LOONGSON2F);
14638 gen_loongson_integer(ctx, op1, rd, rs, rt);
14639 break;
14640 #endif
14641 default: /* Invalid */
14642 MIPS_INVAL("special2");
14643 generate_exception(ctx, EXCP_RI);
14644 break;
14645 }
14646 break;
14647 case OPC_SPECIAL3:
14648 op1 = MASK_SPECIAL3(ctx->opcode);
14649 switch (op1) {
14650 case OPC_EXT:
14651 case OPC_INS:
14652 check_insn(env, ctx, ISA_MIPS32R2);
14653 gen_bitops(ctx, op1, rt, rs, sa, rd);
14654 break;
14655 case OPC_BSHFL:
14656 check_insn(env, ctx, ISA_MIPS32R2);
14657 op2 = MASK_BSHFL(ctx->opcode);
14658 gen_bshfl(ctx, op2, rt, rd);
14659 break;
14660 case OPC_RDHWR:
14661 gen_rdhwr(env, ctx, rt, rd);
14662 break;
14663 case OPC_FORK:
14664 check_insn(env, ctx, ASE_MT);
14665 {
14666 TCGv t0 = tcg_temp_new();
14667 TCGv t1 = tcg_temp_new();
14668
14669 gen_load_gpr(t0, rt);
14670 gen_load_gpr(t1, rs);
14671 gen_helper_fork(t0, t1);
14672 tcg_temp_free(t0);
14673 tcg_temp_free(t1);
14674 }
14675 break;
14676 case OPC_YIELD:
14677 check_insn(env, ctx, ASE_MT);
14678 {
14679 TCGv t0 = tcg_temp_new();
14680
14681 save_cpu_state(ctx, 1);
14682 gen_load_gpr(t0, rs);
14683 gen_helper_yield(t0, cpu_env, t0);
14684 gen_store_gpr(t0, rd);
14685 tcg_temp_free(t0);
14686 }
14687 break;
14688 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14689 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14690 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14691 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14692 * the same mask and op1. */
14693 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14694 op2 = MASK_ADDUH_QB(ctx->opcode);
14695 switch (op2) {
14696 case OPC_ADDUH_QB:
14697 case OPC_ADDUH_R_QB:
14698 case OPC_ADDQH_PH:
14699 case OPC_ADDQH_R_PH:
14700 case OPC_ADDQH_W:
14701 case OPC_ADDQH_R_W:
14702 case OPC_SUBUH_QB:
14703 case OPC_SUBUH_R_QB:
14704 case OPC_SUBQH_PH:
14705 case OPC_SUBQH_R_PH:
14706 case OPC_SUBQH_W:
14707 case OPC_SUBQH_R_W:
14708 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14709 break;
14710 case OPC_MUL_PH:
14711 case OPC_MUL_S_PH:
14712 case OPC_MULQ_S_W:
14713 case OPC_MULQ_RS_W:
14714 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14715 break;
14716 default:
14717 MIPS_INVAL("MASK ADDUH.QB");
14718 generate_exception(ctx, EXCP_RI);
14719 break;
14720 }
14721 } else if (env->insn_flags & INSN_LOONGSON2E) {
14722 gen_loongson_integer(ctx, op1, rd, rs, rt);
14723 } else {
14724 generate_exception(ctx, EXCP_RI);
14725 }
14726 break;
14727 case OPC_LX_DSP:
14728 op2 = MASK_LX(ctx->opcode);
14729 switch (op2) {
14730 #if defined(TARGET_MIPS64)
14731 case OPC_LDX:
14732 #endif
14733 case OPC_LBUX:
14734 case OPC_LHX:
14735 case OPC_LWX:
14736 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14737 break;
14738 default: /* Invalid */
14739 MIPS_INVAL("MASK LX");
14740 generate_exception(ctx, EXCP_RI);
14741 break;
14742 }
14743 break;
14744 case OPC_ABSQ_S_PH_DSP:
14745 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14746 switch (op2) {
14747 case OPC_ABSQ_S_QB:
14748 case OPC_ABSQ_S_PH:
14749 case OPC_ABSQ_S_W:
14750 case OPC_PRECEQ_W_PHL:
14751 case OPC_PRECEQ_W_PHR:
14752 case OPC_PRECEQU_PH_QBL:
14753 case OPC_PRECEQU_PH_QBR:
14754 case OPC_PRECEQU_PH_QBLA:
14755 case OPC_PRECEQU_PH_QBRA:
14756 case OPC_PRECEU_PH_QBL:
14757 case OPC_PRECEU_PH_QBR:
14758 case OPC_PRECEU_PH_QBLA:
14759 case OPC_PRECEU_PH_QBRA:
14760 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14761 break;
14762 case OPC_BITREV:
14763 case OPC_REPL_QB:
14764 case OPC_REPLV_QB:
14765 case OPC_REPL_PH:
14766 case OPC_REPLV_PH:
14767 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14768 break;
14769 default:
14770 MIPS_INVAL("MASK ABSQ_S.PH");
14771 generate_exception(ctx, EXCP_RI);
14772 break;
14773 }
14774 break;
14775 case OPC_ADDU_QB_DSP:
14776 op2 = MASK_ADDU_QB(ctx->opcode);
14777 switch (op2) {
14778 case OPC_ADDQ_PH:
14779 case OPC_ADDQ_S_PH:
14780 case OPC_ADDQ_S_W:
14781 case OPC_ADDU_QB:
14782 case OPC_ADDU_S_QB:
14783 case OPC_ADDU_PH:
14784 case OPC_ADDU_S_PH:
14785 case OPC_SUBQ_PH:
14786 case OPC_SUBQ_S_PH:
14787 case OPC_SUBQ_S_W:
14788 case OPC_SUBU_QB:
14789 case OPC_SUBU_S_QB:
14790 case OPC_SUBU_PH:
14791 case OPC_SUBU_S_PH:
14792 case OPC_ADDSC:
14793 case OPC_ADDWC:
14794 case OPC_MODSUB:
14795 case OPC_RADDU_W_QB:
14796 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14797 break;
14798 case OPC_MULEU_S_PH_QBL:
14799 case OPC_MULEU_S_PH_QBR:
14800 case OPC_MULQ_RS_PH:
14801 case OPC_MULEQ_S_W_PHL:
14802 case OPC_MULEQ_S_W_PHR:
14803 case OPC_MULQ_S_PH:
14804 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14805 break;
14806 default: /* Invalid */
14807 MIPS_INVAL("MASK ADDU.QB");
14808 generate_exception(ctx, EXCP_RI);
14809 break;
14810
14811 }
14812 break;
14813 case OPC_CMPU_EQ_QB_DSP:
14814 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14815 switch (op2) {
14816 case OPC_PRECR_SRA_PH_W:
14817 case OPC_PRECR_SRA_R_PH_W:
14818 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14819 break;
14820 case OPC_PRECR_QB_PH:
14821 case OPC_PRECRQ_QB_PH:
14822 case OPC_PRECRQ_PH_W:
14823 case OPC_PRECRQ_RS_PH_W:
14824 case OPC_PRECRQU_S_QB_PH:
14825 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14826 break;
14827 case OPC_CMPU_EQ_QB:
14828 case OPC_CMPU_LT_QB:
14829 case OPC_CMPU_LE_QB:
14830 case OPC_CMP_EQ_PH:
14831 case OPC_CMP_LT_PH:
14832 case OPC_CMP_LE_PH:
14833 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14834 break;
14835 case OPC_CMPGU_EQ_QB:
14836 case OPC_CMPGU_LT_QB:
14837 case OPC_CMPGU_LE_QB:
14838 case OPC_CMPGDU_EQ_QB:
14839 case OPC_CMPGDU_LT_QB:
14840 case OPC_CMPGDU_LE_QB:
14841 case OPC_PICK_QB:
14842 case OPC_PICK_PH:
14843 case OPC_PACKRL_PH:
14844 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14845 break;
14846 default: /* Invalid */
14847 MIPS_INVAL("MASK CMPU.EQ.QB");
14848 generate_exception(ctx, EXCP_RI);
14849 break;
14850 }
14851 break;
14852 case OPC_SHLL_QB_DSP:
14853 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14854 break;
14855 case OPC_DPA_W_PH_DSP:
14856 op2 = MASK_DPA_W_PH(ctx->opcode);
14857 switch (op2) {
14858 case OPC_DPAU_H_QBL:
14859 case OPC_DPAU_H_QBR:
14860 case OPC_DPSU_H_QBL:
14861 case OPC_DPSU_H_QBR:
14862 case OPC_DPA_W_PH:
14863 case OPC_DPAX_W_PH:
14864 case OPC_DPAQ_S_W_PH:
14865 case OPC_DPAQX_S_W_PH:
14866 case OPC_DPAQX_SA_W_PH:
14867 case OPC_DPS_W_PH:
14868 case OPC_DPSX_W_PH:
14869 case OPC_DPSQ_S_W_PH:
14870 case OPC_DPSQX_S_W_PH:
14871 case OPC_DPSQX_SA_W_PH:
14872 case OPC_MULSAQ_S_W_PH:
14873 case OPC_DPAQ_SA_L_W:
14874 case OPC_DPSQ_SA_L_W:
14875 case OPC_MAQ_S_W_PHL:
14876 case OPC_MAQ_S_W_PHR:
14877 case OPC_MAQ_SA_W_PHL:
14878 case OPC_MAQ_SA_W_PHR:
14879 case OPC_MULSA_W_PH:
14880 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14881 break;
14882 default: /* Invalid */
14883 MIPS_INVAL("MASK DPAW.PH");
14884 generate_exception(ctx, EXCP_RI);
14885 break;
14886 }
14887 break;
14888 case OPC_INSV_DSP:
14889 op2 = MASK_INSV(ctx->opcode);
14890 switch (op2) {
14891 case OPC_INSV:
14892 check_dsp(ctx);
14893 {
14894 TCGv t0, t1;
14895
14896 if (rt == 0) {
14897 MIPS_DEBUG("NOP");
14898 break;
14899 }
14900
14901 t0 = tcg_temp_new();
14902 t1 = tcg_temp_new();
14903
14904 gen_load_gpr(t0, rt);
14905 gen_load_gpr(t1, rs);
14906
14907 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14908
14909 tcg_temp_free(t0);
14910 tcg_temp_free(t1);
14911 break;
14912 }
14913 default: /* Invalid */
14914 MIPS_INVAL("MASK INSV");
14915 generate_exception(ctx, EXCP_RI);
14916 break;
14917 }
14918 break;
14919 case OPC_APPEND_DSP:
14920 check_dspr2(ctx);
14921 op2 = MASK_APPEND(ctx->opcode);
14922 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14923 break;
14924 case OPC_EXTR_W_DSP:
14925 op2 = MASK_EXTR_W(ctx->opcode);
14926 switch (op2) {
14927 case OPC_EXTR_W:
14928 case OPC_EXTR_R_W:
14929 case OPC_EXTR_RS_W:
14930 case OPC_EXTR_S_H:
14931 case OPC_EXTRV_S_H:
14932 case OPC_EXTRV_W:
14933 case OPC_EXTRV_R_W:
14934 case OPC_EXTRV_RS_W:
14935 case OPC_EXTP:
14936 case OPC_EXTPV:
14937 case OPC_EXTPDP:
14938 case OPC_EXTPDPV:
14939 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14940 break;
14941 case OPC_RDDSP:
14942 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14943 break;
14944 case OPC_SHILO:
14945 case OPC_SHILOV:
14946 case OPC_MTHLIP:
14947 case OPC_WRDSP:
14948 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14949 break;
14950 default: /* Invalid */
14951 MIPS_INVAL("MASK EXTR.W");
14952 generate_exception(ctx, EXCP_RI);
14953 break;
14954 }
14955 break;
14956 #if defined(TARGET_MIPS64)
14957 case OPC_DEXTM ... OPC_DEXT:
14958 case OPC_DINSM ... OPC_DINS:
14959 check_insn(env, ctx, ISA_MIPS64R2);
14960 check_mips_64(ctx);
14961 gen_bitops(ctx, op1, rt, rs, sa, rd);
14962 break;
14963 case OPC_DBSHFL:
14964 check_insn(env, ctx, ISA_MIPS64R2);
14965 check_mips_64(ctx);
14966 op2 = MASK_DBSHFL(ctx->opcode);
14967 gen_bshfl(ctx, op2, rt, rd);
14968 break;
14969 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14970 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14971 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14972 check_insn(env, ctx, INSN_LOONGSON2E);
14973 gen_loongson_integer(ctx, op1, rd, rs, rt);
14974 break;
14975 case OPC_ABSQ_S_QH_DSP:
14976 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14977 switch (op2) {
14978 case OPC_PRECEQ_L_PWL:
14979 case OPC_PRECEQ_L_PWR:
14980 case OPC_PRECEQ_PW_QHL:
14981 case OPC_PRECEQ_PW_QHR:
14982 case OPC_PRECEQ_PW_QHLA:
14983 case OPC_PRECEQ_PW_QHRA:
14984 case OPC_PRECEQU_QH_OBL:
14985 case OPC_PRECEQU_QH_OBR:
14986 case OPC_PRECEQU_QH_OBLA:
14987 case OPC_PRECEQU_QH_OBRA:
14988 case OPC_PRECEU_QH_OBL:
14989 case OPC_PRECEU_QH_OBR:
14990 case OPC_PRECEU_QH_OBLA:
14991 case OPC_PRECEU_QH_OBRA:
14992 case OPC_ABSQ_S_OB:
14993 case OPC_ABSQ_S_PW:
14994 case OPC_ABSQ_S_QH:
14995 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14996 break;
14997 case OPC_REPL_OB:
14998 case OPC_REPL_PW:
14999 case OPC_REPL_QH:
15000 case OPC_REPLV_OB:
15001 case OPC_REPLV_PW:
15002 case OPC_REPLV_QH:
15003 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
15004 break;
15005 default: /* Invalid */
15006 MIPS_INVAL("MASK ABSQ_S.QH");
15007 generate_exception(ctx, EXCP_RI);
15008 break;
15009 }
15010 break;
15011 case OPC_ADDU_OB_DSP:
15012 op2 = MASK_ADDU_OB(ctx->opcode);
15013 switch (op2) {
15014 case OPC_RADDU_L_OB:
15015 case OPC_SUBQ_PW:
15016 case OPC_SUBQ_S_PW:
15017 case OPC_SUBQ_QH:
15018 case OPC_SUBQ_S_QH:
15019 case OPC_SUBU_OB:
15020 case OPC_SUBU_S_OB:
15021 case OPC_SUBU_QH:
15022 case OPC_SUBU_S_QH:
15023 case OPC_SUBUH_OB:
15024 case OPC_SUBUH_R_OB:
15025 case OPC_ADDQ_PW:
15026 case OPC_ADDQ_S_PW:
15027 case OPC_ADDQ_QH:
15028 case OPC_ADDQ_S_QH:
15029 case OPC_ADDU_OB:
15030 case OPC_ADDU_S_OB:
15031 case OPC_ADDU_QH:
15032 case OPC_ADDU_S_QH:
15033 case OPC_ADDUH_OB:
15034 case OPC_ADDUH_R_OB:
15035 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15036 break;
15037 case OPC_MULEQ_S_PW_QHL:
15038 case OPC_MULEQ_S_PW_QHR:
15039 case OPC_MULEU_S_QH_OBL:
15040 case OPC_MULEU_S_QH_OBR:
15041 case OPC_MULQ_RS_QH:
15042 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15043 break;
15044 default: /* Invalid */
15045 MIPS_INVAL("MASK ADDU.OB");
15046 generate_exception(ctx, EXCP_RI);
15047 break;
15048 }
15049 break;
15050 case OPC_CMPU_EQ_OB_DSP:
15051 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15052 switch (op2) {
15053 case OPC_PRECR_SRA_QH_PW:
15054 case OPC_PRECR_SRA_R_QH_PW:
15055 /* Return value is rt. */
15056 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15057 break;
15058 case OPC_PRECR_OB_QH:
15059 case OPC_PRECRQ_OB_QH:
15060 case OPC_PRECRQ_PW_L:
15061 case OPC_PRECRQ_QH_PW:
15062 case OPC_PRECRQ_RS_QH_PW:
15063 case OPC_PRECRQU_S_OB_QH:
15064 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15065 break;
15066 case OPC_CMPU_EQ_OB:
15067 case OPC_CMPU_LT_OB:
15068 case OPC_CMPU_LE_OB:
15069 case OPC_CMP_EQ_QH:
15070 case OPC_CMP_LT_QH:
15071 case OPC_CMP_LE_QH:
15072 case OPC_CMP_EQ_PW:
15073 case OPC_CMP_LT_PW:
15074 case OPC_CMP_LE_PW:
15075 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15076 break;
15077 case OPC_CMPGDU_EQ_OB:
15078 case OPC_CMPGDU_LT_OB:
15079 case OPC_CMPGDU_LE_OB:
15080 case OPC_CMPGU_EQ_OB:
15081 case OPC_CMPGU_LT_OB:
15082 case OPC_CMPGU_LE_OB:
15083 case OPC_PACKRL_PW:
15084 case OPC_PICK_OB:
15085 case OPC_PICK_PW:
15086 case OPC_PICK_QH:
15087 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15088 break;
15089 default: /* Invalid */
15090 MIPS_INVAL("MASK CMPU_EQ.OB");
15091 generate_exception(ctx, EXCP_RI);
15092 break;
15093 }
15094 break;
15095 case OPC_DAPPEND_DSP:
15096 check_dspr2(ctx);
15097 op2 = MASK_DAPPEND(ctx->opcode);
15098 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15099 break;
15100 case OPC_DEXTR_W_DSP:
15101 op2 = MASK_DEXTR_W(ctx->opcode);
15102 switch (op2) {
15103 case OPC_DEXTP:
15104 case OPC_DEXTPDP:
15105 case OPC_DEXTPDPV:
15106 case OPC_DEXTPV:
15107 case OPC_DEXTR_L:
15108 case OPC_DEXTR_R_L:
15109 case OPC_DEXTR_RS_L:
15110 case OPC_DEXTR_W:
15111 case OPC_DEXTR_R_W:
15112 case OPC_DEXTR_RS_W:
15113 case OPC_DEXTR_S_H:
15114 case OPC_DEXTRV_L:
15115 case OPC_DEXTRV_R_L:
15116 case OPC_DEXTRV_RS_L:
15117 case OPC_DEXTRV_S_H:
15118 case OPC_DEXTRV_W:
15119 case OPC_DEXTRV_R_W:
15120 case OPC_DEXTRV_RS_W:
15121 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15122 break;
15123 case OPC_DMTHLIP:
15124 case OPC_DSHILO:
15125 case OPC_DSHILOV:
15126 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15127 break;
15128 default: /* Invalid */
15129 MIPS_INVAL("MASK EXTR.W");
15130 generate_exception(ctx, EXCP_RI);
15131 break;
15132 }
15133 break;
15134 case OPC_DPAQ_W_QH_DSP:
15135 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15136 switch (op2) {
15137 case OPC_DPAU_H_OBL:
15138 case OPC_DPAU_H_OBR:
15139 case OPC_DPSU_H_OBL:
15140 case OPC_DPSU_H_OBR:
15141 case OPC_DPA_W_QH:
15142 case OPC_DPAQ_S_W_QH:
15143 case OPC_DPS_W_QH:
15144 case OPC_DPSQ_S_W_QH:
15145 case OPC_MULSAQ_S_W_QH:
15146 case OPC_DPAQ_SA_L_PW:
15147 case OPC_DPSQ_SA_L_PW:
15148 case OPC_MULSAQ_S_L_PW:
15149 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15150 break;
15151 case OPC_MAQ_S_W_QHLL:
15152 case OPC_MAQ_S_W_QHLR:
15153 case OPC_MAQ_S_W_QHRL:
15154 case OPC_MAQ_S_W_QHRR:
15155 case OPC_MAQ_SA_W_QHLL:
15156 case OPC_MAQ_SA_W_QHLR:
15157 case OPC_MAQ_SA_W_QHRL:
15158 case OPC_MAQ_SA_W_QHRR:
15159 case OPC_MAQ_S_L_PWL:
15160 case OPC_MAQ_S_L_PWR:
15161 case OPC_DMADD:
15162 case OPC_DMADDU:
15163 case OPC_DMSUB:
15164 case OPC_DMSUBU:
15165 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15166 break;
15167 default: /* Invalid */
15168 MIPS_INVAL("MASK DPAQ.W.QH");
15169 generate_exception(ctx, EXCP_RI);
15170 break;
15171 }
15172 break;
15173 case OPC_DINSV_DSP:
15174 op2 = MASK_INSV(ctx->opcode);
15175 switch (op2) {
15176 case OPC_DINSV:
15177 {
15178 TCGv t0, t1;
15179
15180 if (rt == 0) {
15181 MIPS_DEBUG("NOP");
15182 break;
15183 }
15184 check_dsp(ctx);
15185
15186 t0 = tcg_temp_new();
15187 t1 = tcg_temp_new();
15188
15189 gen_load_gpr(t0, rt);
15190 gen_load_gpr(t1, rs);
15191
15192 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15193 break;
15194 }
15195 default: /* Invalid */
15196 MIPS_INVAL("MASK DINSV");
15197 generate_exception(ctx, EXCP_RI);
15198 break;
15199 }
15200 break;
15201 case OPC_SHLL_OB_DSP:
15202 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15203 break;
15204 #endif
15205 default: /* Invalid */
15206 MIPS_INVAL("special3");
15207 generate_exception(ctx, EXCP_RI);
15208 break;
15209 }
15210 break;
15211 case OPC_REGIMM:
15212 op1 = MASK_REGIMM(ctx->opcode);
15213 switch (op1) {
15214 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15215 case OPC_BLTZAL ... OPC_BGEZALL:
15216 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15217 *is_branch = 1;
15218 break;
15219 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15220 case OPC_TNEI:
15221 gen_trap(ctx, op1, rs, -1, imm);
15222 break;
15223 case OPC_SYNCI:
15224 check_insn(env, ctx, ISA_MIPS32R2);
15225 /* Treat as NOP. */
15226 break;
15227 case OPC_BPOSGE32: /* MIPS DSP branch */
15228 #if defined(TARGET_MIPS64)
15229 case OPC_BPOSGE64:
15230 #endif
15231 check_dsp(ctx);
15232 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15233 *is_branch = 1;
15234 break;
15235 default: /* Invalid */
15236 MIPS_INVAL("regimm");
15237 generate_exception(ctx, EXCP_RI);
15238 break;
15239 }
15240 break;
15241 case OPC_CP0:
15242 check_cp0_enabled(ctx);
15243 op1 = MASK_CP0(ctx->opcode);
15244 switch (op1) {
15245 case OPC_MFC0:
15246 case OPC_MTC0:
15247 case OPC_MFTR:
15248 case OPC_MTTR:
15249 #if defined(TARGET_MIPS64)
15250 case OPC_DMFC0:
15251 case OPC_DMTC0:
15252 #endif
15253 #ifndef CONFIG_USER_ONLY
15254 gen_cp0(env, ctx, op1, rt, rd);
15255 #endif /* !CONFIG_USER_ONLY */
15256 break;
15257 case OPC_C0_FIRST ... OPC_C0_LAST:
15258 #ifndef CONFIG_USER_ONLY
15259 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15260 #endif /* !CONFIG_USER_ONLY */
15261 break;
15262 case OPC_MFMC0:
15263 #ifndef CONFIG_USER_ONLY
15264 {
15265 TCGv t0 = tcg_temp_new();
15266
15267 op2 = MASK_MFMC0(ctx->opcode);
15268 switch (op2) {
15269 case OPC_DMT:
15270 check_insn(env, ctx, ASE_MT);
15271 gen_helper_dmt(t0);
15272 gen_store_gpr(t0, rt);
15273 break;
15274 case OPC_EMT:
15275 check_insn(env, ctx, ASE_MT);
15276 gen_helper_emt(t0);
15277 gen_store_gpr(t0, rt);
15278 break;
15279 case OPC_DVPE:
15280 check_insn(env, ctx, ASE_MT);
15281 gen_helper_dvpe(t0, cpu_env);
15282 gen_store_gpr(t0, rt);
15283 break;
15284 case OPC_EVPE:
15285 check_insn(env, ctx, ASE_MT);
15286 gen_helper_evpe(t0, cpu_env);
15287 gen_store_gpr(t0, rt);
15288 break;
15289 case OPC_DI:
15290 check_insn(env, ctx, ISA_MIPS32R2);
15291 save_cpu_state(ctx, 1);
15292 gen_helper_di(t0, cpu_env);
15293 gen_store_gpr(t0, rt);
15294 /* Stop translation as we may have switched the execution mode */
15295 ctx->bstate = BS_STOP;
15296 break;
15297 case OPC_EI:
15298 check_insn(env, ctx, ISA_MIPS32R2);
15299 save_cpu_state(ctx, 1);
15300 gen_helper_ei(t0, cpu_env);
15301 gen_store_gpr(t0, rt);
15302 /* Stop translation as we may have switched the execution mode */
15303 ctx->bstate = BS_STOP;
15304 break;
15305 default: /* Invalid */
15306 MIPS_INVAL("mfmc0");
15307 generate_exception(ctx, EXCP_RI);
15308 break;
15309 }
15310 tcg_temp_free(t0);
15311 }
15312 #endif /* !CONFIG_USER_ONLY */
15313 break;
15314 case OPC_RDPGPR:
15315 check_insn(env, ctx, ISA_MIPS32R2);
15316 gen_load_srsgpr(rt, rd);
15317 break;
15318 case OPC_WRPGPR:
15319 check_insn(env, ctx, ISA_MIPS32R2);
15320 gen_store_srsgpr(rt, rd);
15321 break;
15322 default:
15323 MIPS_INVAL("cp0");
15324 generate_exception(ctx, EXCP_RI);
15325 break;
15326 }
15327 break;
15328 case OPC_ADDI: /* Arithmetic with immediate opcode */
15329 case OPC_ADDIU:
15330 gen_arith_imm(env, ctx, op, rt, rs, imm);
15331 break;
15332 case OPC_SLTI: /* Set on less than with immediate opcode */
15333 case OPC_SLTIU:
15334 gen_slt_imm(env, ctx, op, rt, rs, imm);
15335 break;
15336 case OPC_ANDI: /* Arithmetic with immediate opcode */
15337 case OPC_LUI:
15338 case OPC_ORI:
15339 case OPC_XORI:
15340 gen_logic_imm(env, ctx, op, rt, rs, imm);
15341 break;
15342 case OPC_J ... OPC_JAL: /* Jump */
15343 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15344 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15345 *is_branch = 1;
15346 break;
15347 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15348 case OPC_BEQL ... OPC_BGTZL:
15349 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15350 *is_branch = 1;
15351 break;
15352 case OPC_LB ... OPC_LWR: /* Load and stores */
15353 case OPC_LL:
15354 gen_ld(env, ctx, op, rt, rs, imm);
15355 break;
15356 case OPC_SB ... OPC_SW:
15357 case OPC_SWR:
15358 gen_st(ctx, op, rt, rs, imm);
15359 break;
15360 case OPC_SC:
15361 gen_st_cond(ctx, op, rt, rs, imm);
15362 break;
15363 case OPC_CACHE:
15364 check_cp0_enabled(ctx);
15365 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15366 /* Treat as NOP. */
15367 break;
15368 case OPC_PREF:
15369 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15370 /* Treat as NOP. */
15371 break;
15372
15373 /* Floating point (COP1). */
15374 case OPC_LWC1:
15375 case OPC_LDC1:
15376 case OPC_SWC1:
15377 case OPC_SDC1:
15378 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15379 break;
15380
15381 case OPC_CP1:
15382 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15383 check_cp1_enabled(ctx);
15384 op1 = MASK_CP1(ctx->opcode);
15385 switch (op1) {
15386 case OPC_MFHC1:
15387 case OPC_MTHC1:
15388 check_insn(env, ctx, ISA_MIPS32R2);
15389 case OPC_MFC1:
15390 case OPC_CFC1:
15391 case OPC_MTC1:
15392 case OPC_CTC1:
15393 gen_cp1(ctx, op1, rt, rd);
15394 break;
15395 #if defined(TARGET_MIPS64)
15396 case OPC_DMFC1:
15397 case OPC_DMTC1:
15398 check_insn(env, ctx, ISA_MIPS3);
15399 gen_cp1(ctx, op1, rt, rd);
15400 break;
15401 #endif
15402 case OPC_BC1ANY2:
15403 case OPC_BC1ANY4:
15404 check_cop1x(ctx);
15405 check_insn(env, ctx, ASE_MIPS3D);
15406 /* fall through */
15407 case OPC_BC1:
15408 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15409 (rt >> 2) & 0x7, imm << 2);
15410 *is_branch = 1;
15411 break;
15412 case OPC_S_FMT:
15413 case OPC_D_FMT:
15414 case OPC_W_FMT:
15415 case OPC_L_FMT:
15416 case OPC_PS_FMT:
15417 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15418 (imm >> 8) & 0x7);
15419 break;
15420 default:
15421 MIPS_INVAL("cp1");
15422 generate_exception (ctx, EXCP_RI);
15423 break;
15424 }
15425 } else {
15426 generate_exception_err(ctx, EXCP_CpU, 1);
15427 }
15428 break;
15429
15430 /* COP2. */
15431 case OPC_LWC2:
15432 case OPC_LDC2:
15433 case OPC_SWC2:
15434 case OPC_SDC2:
15435 /* COP2: Not implemented. */
15436 generate_exception_err(ctx, EXCP_CpU, 2);
15437 break;
15438 case OPC_CP2:
15439 check_insn(env, ctx, INSN_LOONGSON2F);
15440 /* Note that these instructions use different fields. */
15441 gen_loongson_multimedia(ctx, sa, rd, rt);
15442 break;
15443
15444 case OPC_CP3:
15445 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15446 check_cp1_enabled(ctx);
15447 op1 = MASK_CP3(ctx->opcode);
15448 switch (op1) {
15449 case OPC_LWXC1:
15450 case OPC_LDXC1:
15451 case OPC_LUXC1:
15452 case OPC_SWXC1:
15453 case OPC_SDXC1:
15454 case OPC_SUXC1:
15455 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15456 break;
15457 case OPC_PREFX:
15458 /* Treat as NOP. */
15459 break;
15460 case OPC_ALNV_PS:
15461 case OPC_MADD_S:
15462 case OPC_MADD_D:
15463 case OPC_MADD_PS:
15464 case OPC_MSUB_S:
15465 case OPC_MSUB_D:
15466 case OPC_MSUB_PS:
15467 case OPC_NMADD_S:
15468 case OPC_NMADD_D:
15469 case OPC_NMADD_PS:
15470 case OPC_NMSUB_S:
15471 case OPC_NMSUB_D:
15472 case OPC_NMSUB_PS:
15473 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15474 break;
15475 default:
15476 MIPS_INVAL("cp3");
15477 generate_exception (ctx, EXCP_RI);
15478 break;
15479 }
15480 } else {
15481 generate_exception_err(ctx, EXCP_CpU, 1);
15482 }
15483 break;
15484
15485 #if defined(TARGET_MIPS64)
15486 /* MIPS64 opcodes */
15487 case OPC_LWU:
15488 case OPC_LDL ... OPC_LDR:
15489 case OPC_LLD:
15490 case OPC_LD:
15491 check_insn(env, ctx, ISA_MIPS3);
15492 check_mips_64(ctx);
15493 gen_ld(env, ctx, op, rt, rs, imm);
15494 break;
15495 case OPC_SDL ... OPC_SDR:
15496 case OPC_SD:
15497 check_insn(env, ctx, ISA_MIPS3);
15498 check_mips_64(ctx);
15499 gen_st(ctx, op, rt, rs, imm);
15500 break;
15501 case OPC_SCD:
15502 check_insn(env, ctx, ISA_MIPS3);
15503 check_mips_64(ctx);
15504 gen_st_cond(ctx, op, rt, rs, imm);
15505 break;
15506 case OPC_DADDI:
15507 case OPC_DADDIU:
15508 check_insn(env, ctx, ISA_MIPS3);
15509 check_mips_64(ctx);
15510 gen_arith_imm(env, ctx, op, rt, rs, imm);
15511 break;
15512 #endif
15513 case OPC_JALX:
15514 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15515 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15516 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15517 *is_branch = 1;
15518 break;
15519 case OPC_MDMX:
15520 check_insn(env, ctx, ASE_MDMX);
15521 /* MDMX: Not implemented. */
15522 default: /* Invalid */
15523 MIPS_INVAL("major opcode");
15524 generate_exception(ctx, EXCP_RI);
15525 break;
15526 }
15527 }
15528
15529 static inline void
15530 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15531 int search_pc)
15532 {
15533 DisasContext ctx;
15534 target_ulong pc_start;
15535 uint16_t *gen_opc_end;
15536 CPUBreakpoint *bp;
15537 int j, lj = -1;
15538 int num_insns;
15539 int max_insns;
15540 int insn_bytes;
15541 int is_branch;
15542
15543 if (search_pc)
15544 qemu_log("search pc %d\n", search_pc);
15545
15546 pc_start = tb->pc;
15547 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15548 ctx.pc = pc_start;
15549 ctx.saved_pc = -1;
15550 ctx.singlestep_enabled = env->singlestep_enabled;
15551 ctx.tb = tb;
15552 ctx.bstate = BS_NONE;
15553 /* Restore delay slot state from the tb context. */
15554 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15555 restore_cpu_state(env, &ctx);
15556 #ifdef CONFIG_USER_ONLY
15557 ctx.mem_idx = MIPS_HFLAG_UM;
15558 #else
15559 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15560 #endif
15561 num_insns = 0;
15562 max_insns = tb->cflags & CF_COUNT_MASK;
15563 if (max_insns == 0)
15564 max_insns = CF_COUNT_MASK;
15565 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15566 gen_icount_start();
15567 while (ctx.bstate == BS_NONE) {
15568 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15569 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15570 if (bp->pc == ctx.pc) {
15571 save_cpu_state(&ctx, 1);
15572 ctx.bstate = BS_BRANCH;
15573 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15574 /* Include the breakpoint location or the tb won't
15575 * be flushed when it must be. */
15576 ctx.pc += 4;
15577 goto done_generating;
15578 }
15579 }
15580 }
15581
15582 if (search_pc) {
15583 j = gen_opc_ptr - gen_opc_buf;
15584 if (lj < j) {
15585 lj++;
15586 while (lj < j)
15587 gen_opc_instr_start[lj++] = 0;
15588 }
15589 gen_opc_pc[lj] = ctx.pc;
15590 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15591 gen_opc_btarget[lj] = ctx.btarget;
15592 gen_opc_instr_start[lj] = 1;
15593 gen_opc_icount[lj] = num_insns;
15594 }
15595 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15596 gen_io_start();
15597
15598 is_branch = 0;
15599 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15600 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15601 insn_bytes = 4;
15602 decode_opc(env, &ctx, &is_branch);
15603 } else if (env->insn_flags & ASE_MICROMIPS) {
15604 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15605 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15606 } else if (env->insn_flags & ASE_MIPS16) {
15607 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15608 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15609 } else {
15610 generate_exception(&ctx, EXCP_RI);
15611 ctx.bstate = BS_STOP;
15612 break;
15613 }
15614 if (!is_branch) {
15615 handle_delay_slot(env, &ctx, insn_bytes);
15616 }
15617 ctx.pc += insn_bytes;
15618
15619 num_insns++;
15620
15621 /* Execute a branch and its delay slot as a single instruction.
15622 This is what GDB expects and is consistent with what the
15623 hardware does (e.g. if a delay slot instruction faults, the
15624 reported PC is the PC of the branch). */
15625 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15626 break;
15627
15628 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15629 break;
15630
15631 if (gen_opc_ptr >= gen_opc_end)
15632 break;
15633
15634 if (num_insns >= max_insns)
15635 break;
15636
15637 if (singlestep)
15638 break;
15639 }
15640 if (tb->cflags & CF_LAST_IO)
15641 gen_io_end();
15642 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15643 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15644 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15645 } else {
15646 switch (ctx.bstate) {
15647 case BS_STOP:
15648 gen_goto_tb(&ctx, 0, ctx.pc);
15649 break;
15650 case BS_NONE:
15651 save_cpu_state(&ctx, 0);
15652 gen_goto_tb(&ctx, 0, ctx.pc);
15653 break;
15654 case BS_EXCP:
15655 tcg_gen_exit_tb(0);
15656 break;
15657 case BS_BRANCH:
15658 default:
15659 break;
15660 }
15661 }
15662 done_generating:
15663 gen_icount_end(tb, num_insns);
15664 *gen_opc_ptr = INDEX_op_end;
15665 if (search_pc) {
15666 j = gen_opc_ptr - gen_opc_buf;
15667 lj++;
15668 while (lj <= j)
15669 gen_opc_instr_start[lj++] = 0;
15670 } else {
15671 tb->size = ctx.pc - pc_start;
15672 tb->icount = num_insns;
15673 }
15674 #ifdef DEBUG_DISAS
15675 LOG_DISAS("\n");
15676 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15677 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15678 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15679 qemu_log("\n");
15680 }
15681 #endif
15682 }
15683
15684 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15685 {
15686 gen_intermediate_code_internal(env, tb, 0);
15687 }
15688
15689 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15690 {
15691 gen_intermediate_code_internal(env, tb, 1);
15692 }
15693
15694 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15695 int flags)
15696 {
15697 int i;
15698 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15699
15700 #define printfpr(fp) \
15701 do { \
15702 if (is_fpu64) \
15703 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15704 " fd:%13g fs:%13g psu: %13g\n", \
15705 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15706 (double)(fp)->fd, \
15707 (double)(fp)->fs[FP_ENDIAN_IDX], \
15708 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15709 else { \
15710 fpr_t tmp; \
15711 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15712 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15713 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15714 " fd:%13g fs:%13g psu:%13g\n", \
15715 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15716 (double)tmp.fd, \
15717 (double)tmp.fs[FP_ENDIAN_IDX], \
15718 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15719 } \
15720 } while(0)
15721
15722
15723 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15724 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15725 get_float_exception_flags(&env->active_fpu.fp_status));
15726 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15727 fpu_fprintf(f, "%3s: ", fregnames[i]);
15728 printfpr(&env->active_fpu.fpr[i]);
15729 }
15730
15731 #undef printfpr
15732 }
15733
15734 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15735 /* Debug help: The architecture requires 32bit code to maintain proper
15736 sign-extended values on 64bit machines. */
15737
15738 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15739
15740 static void
15741 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15742 fprintf_function cpu_fprintf,
15743 int flags)
15744 {
15745 int i;
15746
15747 if (!SIGN_EXT_P(env->active_tc.PC))
15748 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15749 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15750 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15751 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15752 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15753 if (!SIGN_EXT_P(env->btarget))
15754 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15755
15756 for (i = 0; i < 32; i++) {
15757 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15758 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15759 }
15760
15761 if (!SIGN_EXT_P(env->CP0_EPC))
15762 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15763 if (!SIGN_EXT_P(env->lladdr))
15764 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15765 }
15766 #endif
15767
15768 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15769 int flags)
15770 {
15771 int i;
15772
15773 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15774 " LO=0x" TARGET_FMT_lx " ds %04x "
15775 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15776 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15777 env->hflags, env->btarget, env->bcond);
15778 for (i = 0; i < 32; i++) {
15779 if ((i & 3) == 0)
15780 cpu_fprintf(f, "GPR%02d:", i);
15781 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15782 if ((i & 3) == 3)
15783 cpu_fprintf(f, "\n");
15784 }
15785
15786 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15787 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15788 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15789 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15790 if (env->hflags & MIPS_HFLAG_FPU)
15791 fpu_dump_state(env, f, cpu_fprintf, flags);
15792 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15793 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15794 #endif
15795 }
15796
15797 static void mips_tcg_init(void)
15798 {
15799 int i;
15800 static int inited;
15801
15802 /* Initialize various static tables. */
15803 if (inited)
15804 return;
15805
15806 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15807 TCGV_UNUSED(cpu_gpr[0]);
15808 for (i = 1; i < 32; i++)
15809 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15810 offsetof(CPUMIPSState, active_tc.gpr[i]),
15811 regnames[i]);
15812
15813 for (i = 0; i < 32; i++) {
15814 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15815 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15816 }
15817
15818 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15819 offsetof(CPUMIPSState, active_tc.PC), "PC");
15820 for (i = 0; i < MIPS_DSP_ACC; i++) {
15821 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15822 offsetof(CPUMIPSState, active_tc.HI[i]),
15823 regnames_HI[i]);
15824 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15825 offsetof(CPUMIPSState, active_tc.LO[i]),
15826 regnames_LO[i]);
15827 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15828 offsetof(CPUMIPSState, active_tc.ACX[i]),
15829 regnames_ACX[i]);
15830 }
15831 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15832 offsetof(CPUMIPSState, active_tc.DSPControl),
15833 "DSPControl");
15834 bcond = tcg_global_mem_new(TCG_AREG0,
15835 offsetof(CPUMIPSState, bcond), "bcond");
15836 btarget = tcg_global_mem_new(TCG_AREG0,
15837 offsetof(CPUMIPSState, btarget), "btarget");
15838 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15839 offsetof(CPUMIPSState, hflags), "hflags");
15840
15841 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15842 offsetof(CPUMIPSState, active_fpu.fcr0),
15843 "fcr0");
15844 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15845 offsetof(CPUMIPSState, active_fpu.fcr31),
15846 "fcr31");
15847
15848 /* register helpers */
15849 #define GEN_HELPER 2
15850 #include "helper.h"
15851
15852 inited = 1;
15853 }
15854
15855 #include "translate_init.c"
15856
15857 MIPSCPU *cpu_mips_init(const char *cpu_model)
15858 {
15859 MIPSCPU *cpu;
15860 CPUMIPSState *env;
15861 const mips_def_t *def;
15862
15863 def = cpu_mips_find_by_name(cpu_model);
15864 if (!def)
15865 return NULL;
15866 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15867 env = &cpu->env;
15868 env->cpu_model = def;
15869 env->cpu_model_str = cpu_model;
15870
15871 #ifndef CONFIG_USER_ONLY
15872 mmu_init(env, def);
15873 #endif
15874 fpu_init(env, def);
15875 mvp_init(env, def);
15876 mips_tcg_init();
15877 cpu_reset(CPU(cpu));
15878 qemu_init_vcpu(env);
15879 return cpu;
15880 }
15881
15882 void cpu_state_reset(CPUMIPSState *env)
15883 {
15884 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15885 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15886 log_cpu_state(env, 0);
15887 }
15888
15889 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15890 tlb_flush(env, 1);
15891
15892 /* Reset registers to their default values */
15893 env->CP0_PRid = env->cpu_model->CP0_PRid;
15894 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15895 #ifdef TARGET_WORDS_BIGENDIAN
15896 env->CP0_Config0 |= (1 << CP0C0_BE);
15897 #endif
15898 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15899 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15900 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15901 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15902 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15903 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15904 << env->cpu_model->CP0_LLAddr_shift;
15905 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15906 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15907 env->CCRes = env->cpu_model->CCRes;
15908 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15909 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15910 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15911 env->current_tc = 0;
15912 env->SEGBITS = env->cpu_model->SEGBITS;
15913 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15914 #if defined(TARGET_MIPS64)
15915 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15916 env->SEGMask |= 3ULL << 62;
15917 }
15918 #endif
15919 env->PABITS = env->cpu_model->PABITS;
15920 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15921 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15922 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15923 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15924 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15925 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15926 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15927 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15928 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15929 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15930 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15931 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15932 env->insn_flags = env->cpu_model->insn_flags;
15933
15934 #if defined(CONFIG_USER_ONLY)
15935 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15936 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15937 hardware registers. */
15938 env->CP0_HWREna |= 0x0000000F;
15939 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15940 env->CP0_Status |= (1 << CP0St_CU1);
15941 }
15942 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15943 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15944 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15945 env->hflags |= MIPS_HFLAG_DSP;
15946 }
15947 #else
15948 if (env->hflags & MIPS_HFLAG_BMASK) {
15949 /* If the exception was raised from a delay slot,
15950 come back to the jump. */
15951 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15952 } else {
15953 env->CP0_ErrorEPC = env->active_tc.PC;
15954 }
15955 env->active_tc.PC = (int32_t)0xBFC00000;
15956 env->CP0_Random = env->tlb->nb_tlb - 1;
15957 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15958 env->CP0_Wired = 0;
15959 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15960 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15961 /* vectored interrupts not implemented, timer on int 7,
15962 no performance counters. */
15963 env->CP0_IntCtl = 0xe0000000;
15964 {
15965 int i;
15966
15967 for (i = 0; i < 7; i++) {
15968 env->CP0_WatchLo[i] = 0;
15969 env->CP0_WatchHi[i] = 0x80000000;
15970 }
15971 env->CP0_WatchLo[7] = 0;
15972 env->CP0_WatchHi[7] = 0;
15973 }
15974 /* Count register increments in debug mode, EJTAG version 1 */
15975 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15976
15977 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15978 int i;
15979
15980 /* Only TC0 on VPE 0 starts as active. */
15981 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15982 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15983 env->tcs[i].CP0_TCHalt = 1;
15984 }
15985 env->active_tc.CP0_TCHalt = 1;
15986 env->halted = 1;
15987
15988 if (!env->cpu_index) {
15989 /* VPE0 starts up enabled. */
15990 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15991 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15992
15993 /* TC0 starts up unhalted. */
15994 env->halted = 0;
15995 env->active_tc.CP0_TCHalt = 0;
15996 env->tcs[0].CP0_TCHalt = 0;
15997 /* With thread 0 active. */
15998 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15999 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16000 }
16001 }
16002 #endif
16003 compute_hflags(env);
16004 env->exception_index = EXCP_NONE;
16005 }
16006
16007 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16008 {
16009 env->active_tc.PC = gen_opc_pc[pc_pos];
16010 env->hflags &= ~MIPS_HFLAG_BMASK;
16011 env->hflags |= gen_opc_hflags[pc_pos];
16012 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16013 case MIPS_HFLAG_BR:
16014 break;
16015 case MIPS_HFLAG_BC:
16016 case MIPS_HFLAG_BL:
16017 case MIPS_HFLAG_B:
16018 env->btarget = gen_opc_btarget[pc_pos];
16019 break;
16020 }
16021 }