]> git.proxmox.com Git - mirror_qemu.git/blob - target-mips/translate.c
Merge remote-tracking branch 'afaerber/qom-cpu' into staging
[mirror_qemu.git] / target-mips / translate.c
1 /*
2 * MIPS32 emulation for qemu: main translation routines.
3 *
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "cpu.h"
25 #include "disas.h"
26 #include "tcg-op.h"
27
28 #include "helper.h"
29 #define GEN_HELPER 1
30 #include "helper.h"
31
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
34
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
37
38 enum {
39 /* indirect opcode tables */
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
61 /* Jump and branches */
62 OPC_J = (0x02 << 26),
63 OPC_JAL = (0x03 << 26),
64 OPC_JALS = OPC_JAL | 0x5,
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS = OPC_JALX | 0x5,
75 /* Load and stores */
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
82 OPC_LWPC = OPC_LW | 0x5,
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
97 OPC_LDPC = OPC_LD | 0x5,
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
117 };
118
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
121
122 enum {
123 /* Shifts */
124 OPC_SLL = 0x00 | OPC_SPECIAL,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
129 OPC_ROTR = OPC_SRL | (1 << 21),
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
133 OPC_ROTRV = OPC_SRLV | (1 << 6),
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
141 OPC_DROTR = OPC_DSRL | (1 << 21),
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
147 /* Multiplication / division */
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
171 /* Jumps */
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
174 OPC_JALRC = OPC_JALR | (0x5 << 6),
175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
176 /* Traps */
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
183 /* HI / LO registers load & stores */
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
188 /* Conditional moves */
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
191
192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
193
194 /* Special */
195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
200
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
208 };
209
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
212
213 enum {
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
228 };
229
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
232
233 enum {
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
251 };
252
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
255
256 enum {
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
263 /* Loongson 2F */
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
276 /* Misc */
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
281 /* Special */
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
283 };
284
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
287
288 enum {
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
302
303 /* Loongson 2E */
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
316
317 /* MIPS DSP Load */
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
339 /* MIPS DSP Compare-Pick Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
345 };
346
347 /* BSHFL opcodes */
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
349
350 enum {
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
354 };
355
356 /* DBSHFL opcodes */
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
358
359 enum {
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
362 };
363
364 /* MIPS DSP REGIMM opcodes */
365 enum {
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
368 };
369
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
371 /* MIPS DSP Load */
372 enum {
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
377 };
378
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
380 enum {
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
407 };
408
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
411 enum {
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
430 };
431
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
433 enum {
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
454 };
455
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457 enum {
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
482 };
483
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485 enum {
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
509 };
510
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
512 enum {
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
536 };
537
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539 enum {
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
542 };
543
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545 enum {
546 /* MIPS DSP Compare-Pick Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
550 };
551
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 enum {
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
572 };
573
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575 enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
601 };
602
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604 enum {
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
633 };
634
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636 enum {
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
666 };
667
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669 enum {
670 /* DSP Compare-Pick Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
675 };
676
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678 enum {
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
701 };
702
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704 enum {
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
707 };
708
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710 enum {
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
738 };
739
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741 enum {
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
769 };
770
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
773
774 enum {
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
787 };
788
789 /* MFMC0 opcodes */
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
791
792 enum {
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
799 };
800
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
803
804 enum {
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
813 };
814
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
817
818 /* Values for the fmt field in FP instructions */
819 enum {
820 /* 0 - 15 are reserved */
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
828 /* 23 - 31 are reserved */
829 };
830
831 enum {
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
850 };
851
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
854
855 enum {
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
860 };
861
862 enum {
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
865 };
866
867 enum {
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
870 };
871
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
873
874 enum {
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
884 };
885
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
887
888 enum {
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
897
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
906
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
915
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
924
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
931
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
938
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
945
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
952
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
959
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
966
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
973
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
980 };
981
982
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
984
985 enum {
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
1001 OPC_NMADD_D = 0x31 | OPC_CP3,
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1006 };
1007
1008 /* global register indices */
1009 static TCGv_ptr cpu_env;
1010 static TCGv cpu_gpr[32], cpu_PC;
1011 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012 static TCGv cpu_dspctrl, btarget, bcond;
1013 static TCGv_i32 hflags;
1014 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015 static TCGv_i64 fpu_f64[32];
1016
1017 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1019
1020 #include "gen-icount.h"
1021
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1026 } while(0)
1027
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1032 } while(0)
1033
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1038 } while(0)
1039
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1044 } while(0)
1045
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1050 } while(0)
1051
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1056 } while(0)
1057
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1062 } while(0)
1063
1064 typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1067 uint32_t opcode;
1068 int singlestep_enabled;
1069 /* Routine used to access memory */
1070 int mem_idx;
1071 uint32_t hflags, saved_hflags;
1072 int bstate;
1073 target_ulong btarget;
1074 } DisasContext;
1075
1076 enum {
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
1078 * exception condition */
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1082 };
1083
1084 static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1089 };
1090
1091 static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1093 };
1094
1095 static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1097 };
1098
1099 static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1101 };
1102
1103 static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1108 };
1109
1110 #define MIPS_DEBUG(fmt, ...) \
1111 do { \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1116 } \
1117 } while (0)
1118
1119 #define LOG_DISAS(...) \
1120 do { \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1123 } \
1124 } while (0)
1125
1126 #define MIPS_INVAL(op) \
1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1129
1130 /* General purpose registers moves. */
1131 static inline void gen_load_gpr (TCGv t, int reg)
1132 {
1133 if (reg == 0)
1134 tcg_gen_movi_tl(t, 0);
1135 else
1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
1137 }
1138
1139 static inline void gen_store_gpr (TCGv t, int reg)
1140 {
1141 if (reg != 0)
1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
1143 }
1144
1145 /* Moves to/from ACX register. */
1146 static inline void gen_load_ACX (TCGv t, int reg)
1147 {
1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
1149 }
1150
1151 static inline void gen_store_ACX (TCGv t, int reg)
1152 {
1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
1154 }
1155
1156 /* Moves to/from shadow registers. */
1157 static inline void gen_load_srsgpr (int from, int to)
1158 {
1159 TCGv t0 = tcg_temp_new();
1160
1161 if (from == 0)
1162 tcg_gen_movi_tl(t0, 0);
1163 else {
1164 TCGv_i32 t2 = tcg_temp_new_i32();
1165 TCGv_ptr addr = tcg_temp_new_ptr();
1166
1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
1172 tcg_gen_add_ptr(addr, cpu_env, addr);
1173
1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1175 tcg_temp_free_ptr(addr);
1176 tcg_temp_free_i32(t2);
1177 }
1178 gen_store_gpr(t0, to);
1179 tcg_temp_free(t0);
1180 }
1181
1182 static inline void gen_store_srsgpr (int from, int to)
1183 {
1184 if (to != 0) {
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
1187 TCGv_ptr addr = tcg_temp_new_ptr();
1188
1189 gen_load_gpr(t0, from);
1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
1195 tcg_gen_add_ptr(addr, cpu_env, addr);
1196
1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1198 tcg_temp_free_ptr(addr);
1199 tcg_temp_free_i32(t2);
1200 tcg_temp_free(t0);
1201 }
1202 }
1203
1204 /* Floating point register moves. */
1205 static void gen_load_fpr32(TCGv_i32 t, int reg)
1206 {
1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1208 }
1209
1210 static void gen_store_fpr32(TCGv_i32 t, int reg)
1211 {
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
1216 }
1217
1218 static void gen_load_fpr32h(TCGv_i32 t, int reg)
1219 {
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
1224 }
1225
1226 static void gen_store_fpr32h(TCGv_i32 t, int reg)
1227 {
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
1232 }
1233
1234 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1235 {
1236 if (ctx->hflags & MIPS_HFLAG_F64) {
1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
1238 } else {
1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1240 }
1241 }
1242
1243 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1244 {
1245 if (ctx->hflags & MIPS_HFLAG_F64) {
1246 tcg_gen_mov_i64(fpu_f64[reg], t);
1247 } else {
1248 TCGv_i64 t0;
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
1251 tcg_gen_shri_i64(t0, t, 32);
1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1253 tcg_temp_free_i64(t0);
1254 }
1255 }
1256
1257 static inline int get_fp_bit (int cc)
1258 {
1259 if (cc)
1260 return 24 + cc;
1261 else
1262 return 23;
1263 }
1264
1265 /* Tests */
1266 static inline void gen_save_pc(target_ulong pc)
1267 {
1268 tcg_gen_movi_tl(cpu_PC, pc);
1269 }
1270
1271 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1272 {
1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1275 gen_save_pc(ctx->pc);
1276 ctx->saved_pc = ctx->pc;
1277 }
1278 if (ctx->hflags != ctx->saved_hflags) {
1279 tcg_gen_movi_i32(hflags, ctx->hflags);
1280 ctx->saved_hflags = ctx->hflags;
1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1282 case MIPS_HFLAG_BR:
1283 break;
1284 case MIPS_HFLAG_BC:
1285 case MIPS_HFLAG_BL:
1286 case MIPS_HFLAG_B:
1287 tcg_gen_movi_tl(btarget, ctx->btarget);
1288 break;
1289 }
1290 }
1291 }
1292
1293 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1294 {
1295 ctx->saved_hflags = ctx->hflags;
1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1297 case MIPS_HFLAG_BR:
1298 break;
1299 case MIPS_HFLAG_BC:
1300 case MIPS_HFLAG_BL:
1301 case MIPS_HFLAG_B:
1302 ctx->btarget = env->btarget;
1303 break;
1304 }
1305 }
1306
1307 static inline void
1308 generate_exception_err (DisasContext *ctx, int excp, int err)
1309 {
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
1312 save_cpu_state(ctx, 1);
1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
1316 }
1317
1318 static inline void
1319 generate_exception (DisasContext *ctx, int excp)
1320 {
1321 save_cpu_state(ctx, 1);
1322 gen_helper_0e0i(raise_exception, excp);
1323 }
1324
1325 /* Addresses computation */
1326 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1327 {
1328 tcg_gen_add_tl(ret, arg0, arg1);
1329
1330 #if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
1336 tcg_gen_ext32s_i64(ret, ret);
1337 }
1338 #endif
1339 }
1340
1341 static inline void check_cp0_enabled(DisasContext *ctx)
1342 {
1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1344 generate_exception_err(ctx, EXCP_CpU, 0);
1345 }
1346
1347 static inline void check_cp1_enabled(DisasContext *ctx)
1348 {
1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1351 }
1352
1353 /* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1355 opcode tables. */
1356
1357 static inline void check_cop1x(DisasContext *ctx)
1358 {
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1361 }
1362
1363 /* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1365
1366 static inline void check_cp1_64bitmode(DisasContext *ctx)
1367 {
1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1369 generate_exception(ctx, EXCP_RI);
1370 }
1371
1372 /*
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1379 *
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1382 */
1383 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1384 {
1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1386 generate_exception(ctx, EXCP_RI);
1387 }
1388
1389 /* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1391 */
1392
1393 static inline void check_dsp(DisasContext *ctx)
1394 {
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1397 }
1398 }
1399
1400 static inline void check_dspr2(DisasContext *ctx)
1401 {
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1404 }
1405 }
1406
1407 /* This code generates a "reserved instruction" exception if the
1408 CPU does not support the instruction set corresponding to flags. */
1409 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1410 {
1411 if (unlikely(!(env->insn_flags & flags)))
1412 generate_exception(ctx, EXCP_RI);
1413 }
1414
1415 /* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
1417 static inline void check_mips_64(DisasContext *ctx)
1418 {
1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1420 generate_exception(ctx, EXCP_RI);
1421 }
1422
1423 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1426 this one use. */
1427 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1432 { \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1435 switch (ifmt) { \
1436 case FMT_PS: \
1437 check_cp1_64bitmode(ctx); \
1438 break; \
1439 case FMT_D: \
1440 if (abs) { \
1441 check_cop1x(ctx); \
1442 } \
1443 check_cp1_registers(ctx, fs | ft); \
1444 break; \
1445 case FMT_S: \
1446 if (abs) { \
1447 check_cop1x(ctx); \
1448 } \
1449 break; \
1450 } \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1453 switch (n) { \
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1470 default: abort(); \
1471 } \
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1474 }
1475
1476 FOP_CONDS(, 0, d, FMT_D, 64)
1477 FOP_CONDS(abs, 1, d, FMT_D, 64)
1478 FOP_CONDS(, 0, s, FMT_S, 32)
1479 FOP_CONDS(abs, 1, s, FMT_S, 32)
1480 FOP_CONDS(, 0, ps, FMT_PS, 64)
1481 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1482 #undef FOP_CONDS
1483 #undef gen_ldcmp_fpr32
1484 #undef gen_ldcmp_fpr64
1485
1486 /* load/store instructions. */
1487 #ifdef CONFIG_USER_ONLY
1488 #define OP_LD_ATOMIC(insn,fname) \
1489 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1490 { \
1491 TCGv t0 = tcg_temp_new(); \
1492 tcg_gen_mov_tl(t0, arg1); \
1493 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1494 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1495 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1496 tcg_temp_free(t0); \
1497 }
1498 #else
1499 #define OP_LD_ATOMIC(insn,fname) \
1500 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1501 { \
1502 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1503 }
1504 #endif
1505 OP_LD_ATOMIC(ll,ld32s);
1506 #if defined(TARGET_MIPS64)
1507 OP_LD_ATOMIC(lld,ld64);
1508 #endif
1509 #undef OP_LD_ATOMIC
1510
1511 #ifdef CONFIG_USER_ONLY
1512 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1513 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1514 { \
1515 TCGv t0 = tcg_temp_new(); \
1516 int l1 = gen_new_label(); \
1517 int l2 = gen_new_label(); \
1518 \
1519 tcg_gen_andi_tl(t0, arg2, almask); \
1520 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1521 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1522 generate_exception(ctx, EXCP_AdES); \
1523 gen_set_label(l1); \
1524 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1525 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1526 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1527 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1528 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1529 gen_helper_0e0i(raise_exception, EXCP_SC); \
1530 gen_set_label(l2); \
1531 tcg_gen_movi_tl(t0, 0); \
1532 gen_store_gpr(t0, rt); \
1533 tcg_temp_free(t0); \
1534 }
1535 #else
1536 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1537 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1538 { \
1539 TCGv t0 = tcg_temp_new(); \
1540 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1541 gen_store_gpr(t0, rt); \
1542 tcg_temp_free(t0); \
1543 }
1544 #endif
1545 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1546 #if defined(TARGET_MIPS64)
1547 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1548 #endif
1549 #undef OP_ST_ATOMIC
1550
1551 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1552 int base, int16_t offset)
1553 {
1554 if (base == 0) {
1555 tcg_gen_movi_tl(addr, offset);
1556 } else if (offset == 0) {
1557 gen_load_gpr(addr, base);
1558 } else {
1559 tcg_gen_movi_tl(addr, offset);
1560 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1561 }
1562 }
1563
1564 static target_ulong pc_relative_pc (DisasContext *ctx)
1565 {
1566 target_ulong pc = ctx->pc;
1567
1568 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1569 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1570
1571 pc -= branch_bytes;
1572 }
1573
1574 pc &= ~(target_ulong)3;
1575 return pc;
1576 }
1577
1578 /* Load */
1579 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1580 int rt, int base, int16_t offset)
1581 {
1582 const char *opn = "ld";
1583 TCGv t0, t1, t2;
1584
1585 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1586 /* Loongson CPU uses a load to zero register for prefetch.
1587 We emulate it as a NOP. On other CPU we must perform the
1588 actual memory access. */
1589 MIPS_DEBUG("NOP");
1590 return;
1591 }
1592
1593 t0 = tcg_temp_new();
1594 gen_base_offset_addr(ctx, t0, base, offset);
1595
1596 switch (opc) {
1597 #if defined(TARGET_MIPS64)
1598 case OPC_LWU:
1599 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1600 gen_store_gpr(t0, rt);
1601 opn = "lwu";
1602 break;
1603 case OPC_LD:
1604 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1605 gen_store_gpr(t0, rt);
1606 opn = "ld";
1607 break;
1608 case OPC_LLD:
1609 save_cpu_state(ctx, 1);
1610 op_ld_lld(t0, t0, ctx);
1611 gen_store_gpr(t0, rt);
1612 opn = "lld";
1613 break;
1614 case OPC_LDL:
1615 t1 = tcg_temp_new();
1616 tcg_gen_andi_tl(t1, t0, 7);
1617 #ifndef TARGET_WORDS_BIGENDIAN
1618 tcg_gen_xori_tl(t1, t1, 7);
1619 #endif
1620 tcg_gen_shli_tl(t1, t1, 3);
1621 tcg_gen_andi_tl(t0, t0, ~7);
1622 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1623 tcg_gen_shl_tl(t0, t0, t1);
1624 tcg_gen_xori_tl(t1, t1, 63);
1625 t2 = tcg_const_tl(0x7fffffffffffffffull);
1626 tcg_gen_shr_tl(t2, t2, t1);
1627 gen_load_gpr(t1, rt);
1628 tcg_gen_and_tl(t1, t1, t2);
1629 tcg_temp_free(t2);
1630 tcg_gen_or_tl(t0, t0, t1);
1631 tcg_temp_free(t1);
1632 gen_store_gpr(t0, rt);
1633 opn = "ldl";
1634 break;
1635 case OPC_LDR:
1636 t1 = tcg_temp_new();
1637 tcg_gen_andi_tl(t1, t0, 7);
1638 #ifdef TARGET_WORDS_BIGENDIAN
1639 tcg_gen_xori_tl(t1, t1, 7);
1640 #endif
1641 tcg_gen_shli_tl(t1, t1, 3);
1642 tcg_gen_andi_tl(t0, t0, ~7);
1643 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1644 tcg_gen_shr_tl(t0, t0, t1);
1645 tcg_gen_xori_tl(t1, t1, 63);
1646 t2 = tcg_const_tl(0xfffffffffffffffeull);
1647 tcg_gen_shl_tl(t2, t2, t1);
1648 gen_load_gpr(t1, rt);
1649 tcg_gen_and_tl(t1, t1, t2);
1650 tcg_temp_free(t2);
1651 tcg_gen_or_tl(t0, t0, t1);
1652 tcg_temp_free(t1);
1653 gen_store_gpr(t0, rt);
1654 opn = "ldr";
1655 break;
1656 case OPC_LDPC:
1657 t1 = tcg_const_tl(pc_relative_pc(ctx));
1658 gen_op_addr_add(ctx, t0, t0, t1);
1659 tcg_temp_free(t1);
1660 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1661 gen_store_gpr(t0, rt);
1662 opn = "ldpc";
1663 break;
1664 #endif
1665 case OPC_LWPC:
1666 t1 = tcg_const_tl(pc_relative_pc(ctx));
1667 gen_op_addr_add(ctx, t0, t0, t1);
1668 tcg_temp_free(t1);
1669 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1670 gen_store_gpr(t0, rt);
1671 opn = "lwpc";
1672 break;
1673 case OPC_LW:
1674 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1675 gen_store_gpr(t0, rt);
1676 opn = "lw";
1677 break;
1678 case OPC_LH:
1679 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1680 gen_store_gpr(t0, rt);
1681 opn = "lh";
1682 break;
1683 case OPC_LHU:
1684 tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1685 gen_store_gpr(t0, rt);
1686 opn = "lhu";
1687 break;
1688 case OPC_LB:
1689 tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1690 gen_store_gpr(t0, rt);
1691 opn = "lb";
1692 break;
1693 case OPC_LBU:
1694 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1695 gen_store_gpr(t0, rt);
1696 opn = "lbu";
1697 break;
1698 case OPC_LWL:
1699 t1 = tcg_temp_new();
1700 tcg_gen_andi_tl(t1, t0, 3);
1701 #ifndef TARGET_WORDS_BIGENDIAN
1702 tcg_gen_xori_tl(t1, t1, 3);
1703 #endif
1704 tcg_gen_shli_tl(t1, t1, 3);
1705 tcg_gen_andi_tl(t0, t0, ~3);
1706 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1707 tcg_gen_shl_tl(t0, t0, t1);
1708 tcg_gen_xori_tl(t1, t1, 31);
1709 t2 = tcg_const_tl(0x7fffffffull);
1710 tcg_gen_shr_tl(t2, t2, t1);
1711 gen_load_gpr(t1, rt);
1712 tcg_gen_and_tl(t1, t1, t2);
1713 tcg_temp_free(t2);
1714 tcg_gen_or_tl(t0, t0, t1);
1715 tcg_temp_free(t1);
1716 tcg_gen_ext32s_tl(t0, t0);
1717 gen_store_gpr(t0, rt);
1718 opn = "lwl";
1719 break;
1720 case OPC_LWR:
1721 t1 = tcg_temp_new();
1722 tcg_gen_andi_tl(t1, t0, 3);
1723 #ifdef TARGET_WORDS_BIGENDIAN
1724 tcg_gen_xori_tl(t1, t1, 3);
1725 #endif
1726 tcg_gen_shli_tl(t1, t1, 3);
1727 tcg_gen_andi_tl(t0, t0, ~3);
1728 tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1729 tcg_gen_shr_tl(t0, t0, t1);
1730 tcg_gen_xori_tl(t1, t1, 31);
1731 t2 = tcg_const_tl(0xfffffffeull);
1732 tcg_gen_shl_tl(t2, t2, t1);
1733 gen_load_gpr(t1, rt);
1734 tcg_gen_and_tl(t1, t1, t2);
1735 tcg_temp_free(t2);
1736 tcg_gen_or_tl(t0, t0, t1);
1737 tcg_temp_free(t1);
1738 gen_store_gpr(t0, rt);
1739 opn = "lwr";
1740 break;
1741 case OPC_LL:
1742 save_cpu_state(ctx, 1);
1743 op_ld_ll(t0, t0, ctx);
1744 gen_store_gpr(t0, rt);
1745 opn = "ll";
1746 break;
1747 }
1748 (void)opn; /* avoid a compiler warning */
1749 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1750 tcg_temp_free(t0);
1751 }
1752
1753 /* Store */
1754 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1755 int base, int16_t offset)
1756 {
1757 const char *opn = "st";
1758 TCGv t0 = tcg_temp_new();
1759 TCGv t1 = tcg_temp_new();
1760
1761 gen_base_offset_addr(ctx, t0, base, offset);
1762 gen_load_gpr(t1, rt);
1763 switch (opc) {
1764 #if defined(TARGET_MIPS64)
1765 case OPC_SD:
1766 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1767 opn = "sd";
1768 break;
1769 case OPC_SDL:
1770 save_cpu_state(ctx, 1);
1771 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1772 opn = "sdl";
1773 break;
1774 case OPC_SDR:
1775 save_cpu_state(ctx, 1);
1776 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1777 opn = "sdr";
1778 break;
1779 #endif
1780 case OPC_SW:
1781 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1782 opn = "sw";
1783 break;
1784 case OPC_SH:
1785 tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1786 opn = "sh";
1787 break;
1788 case OPC_SB:
1789 tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1790 opn = "sb";
1791 break;
1792 case OPC_SWL:
1793 save_cpu_state(ctx, 1);
1794 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1795 opn = "swl";
1796 break;
1797 case OPC_SWR:
1798 save_cpu_state(ctx, 1);
1799 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1800 opn = "swr";
1801 break;
1802 }
1803 (void)opn; /* avoid a compiler warning */
1804 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1805 tcg_temp_free(t0);
1806 tcg_temp_free(t1);
1807 }
1808
1809
1810 /* Store conditional */
1811 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1812 int base, int16_t offset)
1813 {
1814 const char *opn = "st_cond";
1815 TCGv t0, t1;
1816
1817 #ifdef CONFIG_USER_ONLY
1818 t0 = tcg_temp_local_new();
1819 t1 = tcg_temp_local_new();
1820 #else
1821 t0 = tcg_temp_new();
1822 t1 = tcg_temp_new();
1823 #endif
1824 gen_base_offset_addr(ctx, t0, base, offset);
1825 gen_load_gpr(t1, rt);
1826 switch (opc) {
1827 #if defined(TARGET_MIPS64)
1828 case OPC_SCD:
1829 save_cpu_state(ctx, 1);
1830 op_st_scd(t1, t0, rt, ctx);
1831 opn = "scd";
1832 break;
1833 #endif
1834 case OPC_SC:
1835 save_cpu_state(ctx, 1);
1836 op_st_sc(t1, t0, rt, ctx);
1837 opn = "sc";
1838 break;
1839 }
1840 (void)opn; /* avoid a compiler warning */
1841 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1842 tcg_temp_free(t1);
1843 tcg_temp_free(t0);
1844 }
1845
1846 /* Load and store */
1847 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1848 int base, int16_t offset)
1849 {
1850 const char *opn = "flt_ldst";
1851 TCGv t0 = tcg_temp_new();
1852
1853 gen_base_offset_addr(ctx, t0, base, offset);
1854 /* Don't do NOP if destination is zero: we must perform the actual
1855 memory access. */
1856 switch (opc) {
1857 case OPC_LWC1:
1858 {
1859 TCGv_i32 fp0 = tcg_temp_new_i32();
1860
1861 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1862 tcg_gen_trunc_tl_i32(fp0, t0);
1863 gen_store_fpr32(fp0, ft);
1864 tcg_temp_free_i32(fp0);
1865 }
1866 opn = "lwc1";
1867 break;
1868 case OPC_SWC1:
1869 {
1870 TCGv_i32 fp0 = tcg_temp_new_i32();
1871 TCGv t1 = tcg_temp_new();
1872
1873 gen_load_fpr32(fp0, ft);
1874 tcg_gen_extu_i32_tl(t1, fp0);
1875 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1876 tcg_temp_free(t1);
1877 tcg_temp_free_i32(fp0);
1878 }
1879 opn = "swc1";
1880 break;
1881 case OPC_LDC1:
1882 {
1883 TCGv_i64 fp0 = tcg_temp_new_i64();
1884
1885 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1886 gen_store_fpr64(ctx, fp0, ft);
1887 tcg_temp_free_i64(fp0);
1888 }
1889 opn = "ldc1";
1890 break;
1891 case OPC_SDC1:
1892 {
1893 TCGv_i64 fp0 = tcg_temp_new_i64();
1894
1895 gen_load_fpr64(ctx, fp0, ft);
1896 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1897 tcg_temp_free_i64(fp0);
1898 }
1899 opn = "sdc1";
1900 break;
1901 default:
1902 MIPS_INVAL(opn);
1903 generate_exception(ctx, EXCP_RI);
1904 goto out;
1905 }
1906 (void)opn; /* avoid a compiler warning */
1907 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1908 out:
1909 tcg_temp_free(t0);
1910 }
1911
1912 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1913 uint32_t op, int rt, int rs, int16_t imm)
1914 {
1915 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1916 check_cp1_enabled(ctx);
1917 gen_flt_ldst(ctx, op, rt, rs, imm);
1918 } else {
1919 generate_exception_err(ctx, EXCP_CpU, 1);
1920 }
1921 }
1922
1923 /* Arithmetic with immediate operand */
1924 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1925 int rt, int rs, int16_t imm)
1926 {
1927 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1928 const char *opn = "imm arith";
1929
1930 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1931 /* If no destination, treat it as a NOP.
1932 For addi, we must generate the overflow exception when needed. */
1933 MIPS_DEBUG("NOP");
1934 return;
1935 }
1936 switch (opc) {
1937 case OPC_ADDI:
1938 {
1939 TCGv t0 = tcg_temp_local_new();
1940 TCGv t1 = tcg_temp_new();
1941 TCGv t2 = tcg_temp_new();
1942 int l1 = gen_new_label();
1943
1944 gen_load_gpr(t1, rs);
1945 tcg_gen_addi_tl(t0, t1, uimm);
1946 tcg_gen_ext32s_tl(t0, t0);
1947
1948 tcg_gen_xori_tl(t1, t1, ~uimm);
1949 tcg_gen_xori_tl(t2, t0, uimm);
1950 tcg_gen_and_tl(t1, t1, t2);
1951 tcg_temp_free(t2);
1952 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1953 tcg_temp_free(t1);
1954 /* operands of same sign, result different sign */
1955 generate_exception(ctx, EXCP_OVERFLOW);
1956 gen_set_label(l1);
1957 tcg_gen_ext32s_tl(t0, t0);
1958 gen_store_gpr(t0, rt);
1959 tcg_temp_free(t0);
1960 }
1961 opn = "addi";
1962 break;
1963 case OPC_ADDIU:
1964 if (rs != 0) {
1965 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1966 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1967 } else {
1968 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1969 }
1970 opn = "addiu";
1971 break;
1972 #if defined(TARGET_MIPS64)
1973 case OPC_DADDI:
1974 {
1975 TCGv t0 = tcg_temp_local_new();
1976 TCGv t1 = tcg_temp_new();
1977 TCGv t2 = tcg_temp_new();
1978 int l1 = gen_new_label();
1979
1980 gen_load_gpr(t1, rs);
1981 tcg_gen_addi_tl(t0, t1, uimm);
1982
1983 tcg_gen_xori_tl(t1, t1, ~uimm);
1984 tcg_gen_xori_tl(t2, t0, uimm);
1985 tcg_gen_and_tl(t1, t1, t2);
1986 tcg_temp_free(t2);
1987 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1988 tcg_temp_free(t1);
1989 /* operands of same sign, result different sign */
1990 generate_exception(ctx, EXCP_OVERFLOW);
1991 gen_set_label(l1);
1992 gen_store_gpr(t0, rt);
1993 tcg_temp_free(t0);
1994 }
1995 opn = "daddi";
1996 break;
1997 case OPC_DADDIU:
1998 if (rs != 0) {
1999 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2000 } else {
2001 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2002 }
2003 opn = "daddiu";
2004 break;
2005 #endif
2006 }
2007 (void)opn; /* avoid a compiler warning */
2008 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2009 }
2010
2011 /* Logic with immediate operand */
2012 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2013 int rt, int rs, int16_t imm)
2014 {
2015 target_ulong uimm;
2016 const char *opn = "imm logic";
2017
2018 if (rt == 0) {
2019 /* If no destination, treat it as a NOP. */
2020 MIPS_DEBUG("NOP");
2021 return;
2022 }
2023 uimm = (uint16_t)imm;
2024 switch (opc) {
2025 case OPC_ANDI:
2026 if (likely(rs != 0))
2027 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2028 else
2029 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2030 opn = "andi";
2031 break;
2032 case OPC_ORI:
2033 if (rs != 0)
2034 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2035 else
2036 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2037 opn = "ori";
2038 break;
2039 case OPC_XORI:
2040 if (likely(rs != 0))
2041 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2042 else
2043 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2044 opn = "xori";
2045 break;
2046 case OPC_LUI:
2047 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2048 opn = "lui";
2049 break;
2050 }
2051 (void)opn; /* avoid a compiler warning */
2052 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2053 }
2054
2055 /* Set on less than with immediate operand */
2056 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2057 int rt, int rs, int16_t imm)
2058 {
2059 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2060 const char *opn = "imm arith";
2061 TCGv t0;
2062
2063 if (rt == 0) {
2064 /* If no destination, treat it as a NOP. */
2065 MIPS_DEBUG("NOP");
2066 return;
2067 }
2068 t0 = tcg_temp_new();
2069 gen_load_gpr(t0, rs);
2070 switch (opc) {
2071 case OPC_SLTI:
2072 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2073 opn = "slti";
2074 break;
2075 case OPC_SLTIU:
2076 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2077 opn = "sltiu";
2078 break;
2079 }
2080 (void)opn; /* avoid a compiler warning */
2081 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2082 tcg_temp_free(t0);
2083 }
2084
2085 /* Shifts with immediate operand */
2086 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2087 int rt, int rs, int16_t imm)
2088 {
2089 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2090 const char *opn = "imm shift";
2091 TCGv t0;
2092
2093 if (rt == 0) {
2094 /* If no destination, treat it as a NOP. */
2095 MIPS_DEBUG("NOP");
2096 return;
2097 }
2098
2099 t0 = tcg_temp_new();
2100 gen_load_gpr(t0, rs);
2101 switch (opc) {
2102 case OPC_SLL:
2103 tcg_gen_shli_tl(t0, t0, uimm);
2104 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2105 opn = "sll";
2106 break;
2107 case OPC_SRA:
2108 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2109 opn = "sra";
2110 break;
2111 case OPC_SRL:
2112 if (uimm != 0) {
2113 tcg_gen_ext32u_tl(t0, t0);
2114 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2115 } else {
2116 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2117 }
2118 opn = "srl";
2119 break;
2120 case OPC_ROTR:
2121 if (uimm != 0) {
2122 TCGv_i32 t1 = tcg_temp_new_i32();
2123
2124 tcg_gen_trunc_tl_i32(t1, t0);
2125 tcg_gen_rotri_i32(t1, t1, uimm);
2126 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2127 tcg_temp_free_i32(t1);
2128 } else {
2129 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2130 }
2131 opn = "rotr";
2132 break;
2133 #if defined(TARGET_MIPS64)
2134 case OPC_DSLL:
2135 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2136 opn = "dsll";
2137 break;
2138 case OPC_DSRA:
2139 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2140 opn = "dsra";
2141 break;
2142 case OPC_DSRL:
2143 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2144 opn = "dsrl";
2145 break;
2146 case OPC_DROTR:
2147 if (uimm != 0) {
2148 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2149 } else {
2150 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2151 }
2152 opn = "drotr";
2153 break;
2154 case OPC_DSLL32:
2155 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2156 opn = "dsll32";
2157 break;
2158 case OPC_DSRA32:
2159 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2160 opn = "dsra32";
2161 break;
2162 case OPC_DSRL32:
2163 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2164 opn = "dsrl32";
2165 break;
2166 case OPC_DROTR32:
2167 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2168 opn = "drotr32";
2169 break;
2170 #endif
2171 }
2172 (void)opn; /* avoid a compiler warning */
2173 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2174 tcg_temp_free(t0);
2175 }
2176
2177 /* Arithmetic */
2178 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2179 int rd, int rs, int rt)
2180 {
2181 const char *opn = "arith";
2182
2183 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2184 && opc != OPC_DADD && opc != OPC_DSUB) {
2185 /* If no destination, treat it as a NOP.
2186 For add & sub, we must generate the overflow exception when needed. */
2187 MIPS_DEBUG("NOP");
2188 return;
2189 }
2190
2191 switch (opc) {
2192 case OPC_ADD:
2193 {
2194 TCGv t0 = tcg_temp_local_new();
2195 TCGv t1 = tcg_temp_new();
2196 TCGv t2 = tcg_temp_new();
2197 int l1 = gen_new_label();
2198
2199 gen_load_gpr(t1, rs);
2200 gen_load_gpr(t2, rt);
2201 tcg_gen_add_tl(t0, t1, t2);
2202 tcg_gen_ext32s_tl(t0, t0);
2203 tcg_gen_xor_tl(t1, t1, t2);
2204 tcg_gen_xor_tl(t2, t0, t2);
2205 tcg_gen_andc_tl(t1, t2, t1);
2206 tcg_temp_free(t2);
2207 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2208 tcg_temp_free(t1);
2209 /* operands of same sign, result different sign */
2210 generate_exception(ctx, EXCP_OVERFLOW);
2211 gen_set_label(l1);
2212 gen_store_gpr(t0, rd);
2213 tcg_temp_free(t0);
2214 }
2215 opn = "add";
2216 break;
2217 case OPC_ADDU:
2218 if (rs != 0 && rt != 0) {
2219 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2220 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2221 } else if (rs == 0 && rt != 0) {
2222 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2223 } else if (rs != 0 && rt == 0) {
2224 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2225 } else {
2226 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2227 }
2228 opn = "addu";
2229 break;
2230 case OPC_SUB:
2231 {
2232 TCGv t0 = tcg_temp_local_new();
2233 TCGv t1 = tcg_temp_new();
2234 TCGv t2 = tcg_temp_new();
2235 int l1 = gen_new_label();
2236
2237 gen_load_gpr(t1, rs);
2238 gen_load_gpr(t2, rt);
2239 tcg_gen_sub_tl(t0, t1, t2);
2240 tcg_gen_ext32s_tl(t0, t0);
2241 tcg_gen_xor_tl(t2, t1, t2);
2242 tcg_gen_xor_tl(t1, t0, t1);
2243 tcg_gen_and_tl(t1, t1, t2);
2244 tcg_temp_free(t2);
2245 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2246 tcg_temp_free(t1);
2247 /* operands of different sign, first operand and result different sign */
2248 generate_exception(ctx, EXCP_OVERFLOW);
2249 gen_set_label(l1);
2250 gen_store_gpr(t0, rd);
2251 tcg_temp_free(t0);
2252 }
2253 opn = "sub";
2254 break;
2255 case OPC_SUBU:
2256 if (rs != 0 && rt != 0) {
2257 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2258 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2259 } else if (rs == 0 && rt != 0) {
2260 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2261 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2262 } else if (rs != 0 && rt == 0) {
2263 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2264 } else {
2265 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2266 }
2267 opn = "subu";
2268 break;
2269 #if defined(TARGET_MIPS64)
2270 case OPC_DADD:
2271 {
2272 TCGv t0 = tcg_temp_local_new();
2273 TCGv t1 = tcg_temp_new();
2274 TCGv t2 = tcg_temp_new();
2275 int l1 = gen_new_label();
2276
2277 gen_load_gpr(t1, rs);
2278 gen_load_gpr(t2, rt);
2279 tcg_gen_add_tl(t0, t1, t2);
2280 tcg_gen_xor_tl(t1, t1, t2);
2281 tcg_gen_xor_tl(t2, t0, t2);
2282 tcg_gen_andc_tl(t1, t2, t1);
2283 tcg_temp_free(t2);
2284 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2285 tcg_temp_free(t1);
2286 /* operands of same sign, result different sign */
2287 generate_exception(ctx, EXCP_OVERFLOW);
2288 gen_set_label(l1);
2289 gen_store_gpr(t0, rd);
2290 tcg_temp_free(t0);
2291 }
2292 opn = "dadd";
2293 break;
2294 case OPC_DADDU:
2295 if (rs != 0 && rt != 0) {
2296 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2297 } else if (rs == 0 && rt != 0) {
2298 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2299 } else if (rs != 0 && rt == 0) {
2300 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2301 } else {
2302 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2303 }
2304 opn = "daddu";
2305 break;
2306 case OPC_DSUB:
2307 {
2308 TCGv t0 = tcg_temp_local_new();
2309 TCGv t1 = tcg_temp_new();
2310 TCGv t2 = tcg_temp_new();
2311 int l1 = gen_new_label();
2312
2313 gen_load_gpr(t1, rs);
2314 gen_load_gpr(t2, rt);
2315 tcg_gen_sub_tl(t0, t1, t2);
2316 tcg_gen_xor_tl(t2, t1, t2);
2317 tcg_gen_xor_tl(t1, t0, t1);
2318 tcg_gen_and_tl(t1, t1, t2);
2319 tcg_temp_free(t2);
2320 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2321 tcg_temp_free(t1);
2322 /* operands of different sign, first operand and result different sign */
2323 generate_exception(ctx, EXCP_OVERFLOW);
2324 gen_set_label(l1);
2325 gen_store_gpr(t0, rd);
2326 tcg_temp_free(t0);
2327 }
2328 opn = "dsub";
2329 break;
2330 case OPC_DSUBU:
2331 if (rs != 0 && rt != 0) {
2332 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2333 } else if (rs == 0 && rt != 0) {
2334 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2335 } else if (rs != 0 && rt == 0) {
2336 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2337 } else {
2338 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2339 }
2340 opn = "dsubu";
2341 break;
2342 #endif
2343 case OPC_MUL:
2344 if (likely(rs != 0 && rt != 0)) {
2345 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2346 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2347 } else {
2348 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2349 }
2350 opn = "mul";
2351 break;
2352 }
2353 (void)opn; /* avoid a compiler warning */
2354 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2355 }
2356
2357 /* Conditional move */
2358 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2359 int rd, int rs, int rt)
2360 {
2361 const char *opn = "cond move";
2362 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 t0 = tcg_temp_new();
2657 t1 = tcg_temp_new();
2658
2659 gen_load_gpr(t0, rs);
2660 gen_load_gpr(t1, rt);
2661
2662 switch (opc) {
2663 case OPC_DIV:
2664 {
2665 TCGv t2 = tcg_temp_new();
2666 TCGv t3 = tcg_temp_new();
2667 tcg_gen_ext32s_tl(t0, t0);
2668 tcg_gen_ext32s_tl(t1, t1);
2669 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2670 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2671 tcg_gen_and_tl(t2, t2, t3);
2672 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2673 tcg_gen_or_tl(t2, t2, t3);
2674 tcg_gen_movi_tl(t3, 0);
2675 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2676 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2677 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2678 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2679 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2680 tcg_temp_free(t3);
2681 tcg_temp_free(t2);
2682 }
2683 opn = "div";
2684 break;
2685 case OPC_DIVU:
2686 {
2687 TCGv t2 = tcg_const_tl(0);
2688 TCGv t3 = tcg_const_tl(1);
2689 tcg_gen_ext32u_tl(t0, t0);
2690 tcg_gen_ext32u_tl(t1, t1);
2691 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2692 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2693 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2694 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2695 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2696 tcg_temp_free(t3);
2697 tcg_temp_free(t2);
2698 }
2699 opn = "divu";
2700 break;
2701 case OPC_MULT:
2702 {
2703 TCGv_i64 t2 = tcg_temp_new_i64();
2704 TCGv_i64 t3 = tcg_temp_new_i64();
2705 acc = ((ctx->opcode) >> 11) & 0x03;
2706 if (acc != 0) {
2707 check_dsp(ctx);
2708 }
2709
2710 tcg_gen_ext_tl_i64(t2, t0);
2711 tcg_gen_ext_tl_i64(t3, t1);
2712 tcg_gen_mul_i64(t2, t2, t3);
2713 tcg_temp_free_i64(t3);
2714 tcg_gen_trunc_i64_tl(t0, t2);
2715 tcg_gen_shri_i64(t2, t2, 32);
2716 tcg_gen_trunc_i64_tl(t1, t2);
2717 tcg_temp_free_i64(t2);
2718 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2719 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2720 }
2721 opn = "mult";
2722 break;
2723 case OPC_MULTU:
2724 {
2725 TCGv_i64 t2 = tcg_temp_new_i64();
2726 TCGv_i64 t3 = tcg_temp_new_i64();
2727 acc = ((ctx->opcode) >> 11) & 0x03;
2728 if (acc != 0) {
2729 check_dsp(ctx);
2730 }
2731
2732 tcg_gen_ext32u_tl(t0, t0);
2733 tcg_gen_ext32u_tl(t1, t1);
2734 tcg_gen_extu_tl_i64(t2, t0);
2735 tcg_gen_extu_tl_i64(t3, t1);
2736 tcg_gen_mul_i64(t2, t2, t3);
2737 tcg_temp_free_i64(t3);
2738 tcg_gen_trunc_i64_tl(t0, t2);
2739 tcg_gen_shri_i64(t2, t2, 32);
2740 tcg_gen_trunc_i64_tl(t1, t2);
2741 tcg_temp_free_i64(t2);
2742 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2743 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2744 }
2745 opn = "multu";
2746 break;
2747 #if defined(TARGET_MIPS64)
2748 case OPC_DDIV:
2749 {
2750 TCGv t2 = tcg_temp_new();
2751 TCGv t3 = tcg_temp_new();
2752 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2753 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2754 tcg_gen_and_tl(t2, t2, t3);
2755 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2756 tcg_gen_or_tl(t2, t2, t3);
2757 tcg_gen_movi_tl(t3, 0);
2758 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2759 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2760 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2761 tcg_temp_free(t3);
2762 tcg_temp_free(t2);
2763 }
2764 opn = "ddiv";
2765 break;
2766 case OPC_DDIVU:
2767 {
2768 TCGv t2 = tcg_const_tl(0);
2769 TCGv t3 = tcg_const_tl(1);
2770 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2771 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2772 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2773 tcg_temp_free(t3);
2774 tcg_temp_free(t2);
2775 }
2776 opn = "ddivu";
2777 break;
2778 case OPC_DMULT:
2779 gen_helper_dmult(cpu_env, t0, t1);
2780 opn = "dmult";
2781 break;
2782 case OPC_DMULTU:
2783 gen_helper_dmultu(cpu_env, t0, t1);
2784 opn = "dmultu";
2785 break;
2786 #endif
2787 case OPC_MADD:
2788 {
2789 TCGv_i64 t2 = tcg_temp_new_i64();
2790 TCGv_i64 t3 = tcg_temp_new_i64();
2791 acc = ((ctx->opcode) >> 11) & 0x03;
2792 if (acc != 0) {
2793 check_dsp(ctx);
2794 }
2795
2796 tcg_gen_ext_tl_i64(t2, t0);
2797 tcg_gen_ext_tl_i64(t3, t1);
2798 tcg_gen_mul_i64(t2, t2, t3);
2799 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2800 tcg_gen_add_i64(t2, t2, t3);
2801 tcg_temp_free_i64(t3);
2802 tcg_gen_trunc_i64_tl(t0, t2);
2803 tcg_gen_shri_i64(t2, t2, 32);
2804 tcg_gen_trunc_i64_tl(t1, t2);
2805 tcg_temp_free_i64(t2);
2806 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2807 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2808 }
2809 opn = "madd";
2810 break;
2811 case OPC_MADDU:
2812 {
2813 TCGv_i64 t2 = tcg_temp_new_i64();
2814 TCGv_i64 t3 = tcg_temp_new_i64();
2815 acc = ((ctx->opcode) >> 11) & 0x03;
2816 if (acc != 0) {
2817 check_dsp(ctx);
2818 }
2819
2820 tcg_gen_ext32u_tl(t0, t0);
2821 tcg_gen_ext32u_tl(t1, t1);
2822 tcg_gen_extu_tl_i64(t2, t0);
2823 tcg_gen_extu_tl_i64(t3, t1);
2824 tcg_gen_mul_i64(t2, t2, t3);
2825 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2826 tcg_gen_add_i64(t2, t2, t3);
2827 tcg_temp_free_i64(t3);
2828 tcg_gen_trunc_i64_tl(t0, t2);
2829 tcg_gen_shri_i64(t2, t2, 32);
2830 tcg_gen_trunc_i64_tl(t1, t2);
2831 tcg_temp_free_i64(t2);
2832 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2833 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2834 }
2835 opn = "maddu";
2836 break;
2837 case OPC_MSUB:
2838 {
2839 TCGv_i64 t2 = tcg_temp_new_i64();
2840 TCGv_i64 t3 = tcg_temp_new_i64();
2841 acc = ((ctx->opcode) >> 11) & 0x03;
2842 if (acc != 0) {
2843 check_dsp(ctx);
2844 }
2845
2846 tcg_gen_ext_tl_i64(t2, t0);
2847 tcg_gen_ext_tl_i64(t3, t1);
2848 tcg_gen_mul_i64(t2, t2, t3);
2849 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2850 tcg_gen_sub_i64(t2, t3, t2);
2851 tcg_temp_free_i64(t3);
2852 tcg_gen_trunc_i64_tl(t0, t2);
2853 tcg_gen_shri_i64(t2, t2, 32);
2854 tcg_gen_trunc_i64_tl(t1, t2);
2855 tcg_temp_free_i64(t2);
2856 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2857 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2858 }
2859 opn = "msub";
2860 break;
2861 case OPC_MSUBU:
2862 {
2863 TCGv_i64 t2 = tcg_temp_new_i64();
2864 TCGv_i64 t3 = tcg_temp_new_i64();
2865 acc = ((ctx->opcode) >> 11) & 0x03;
2866 if (acc != 0) {
2867 check_dsp(ctx);
2868 }
2869
2870 tcg_gen_ext32u_tl(t0, t0);
2871 tcg_gen_ext32u_tl(t1, t1);
2872 tcg_gen_extu_tl_i64(t2, t0);
2873 tcg_gen_extu_tl_i64(t3, t1);
2874 tcg_gen_mul_i64(t2, t2, t3);
2875 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2876 tcg_gen_sub_i64(t2, t3, t2);
2877 tcg_temp_free_i64(t3);
2878 tcg_gen_trunc_i64_tl(t0, t2);
2879 tcg_gen_shri_i64(t2, t2, 32);
2880 tcg_gen_trunc_i64_tl(t1, t2);
2881 tcg_temp_free_i64(t2);
2882 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2883 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2884 }
2885 opn = "msubu";
2886 break;
2887 default:
2888 MIPS_INVAL(opn);
2889 generate_exception(ctx, EXCP_RI);
2890 goto out;
2891 }
2892 (void)opn; /* avoid a compiler warning */
2893 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2894 out:
2895 tcg_temp_free(t0);
2896 tcg_temp_free(t1);
2897 }
2898
2899 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2900 int rd, int rs, int rt)
2901 {
2902 const char *opn = "mul vr54xx";
2903 TCGv t0 = tcg_temp_new();
2904 TCGv t1 = tcg_temp_new();
2905
2906 gen_load_gpr(t0, rs);
2907 gen_load_gpr(t1, rt);
2908
2909 switch (opc) {
2910 case OPC_VR54XX_MULS:
2911 gen_helper_muls(t0, cpu_env, t0, t1);
2912 opn = "muls";
2913 break;
2914 case OPC_VR54XX_MULSU:
2915 gen_helper_mulsu(t0, cpu_env, t0, t1);
2916 opn = "mulsu";
2917 break;
2918 case OPC_VR54XX_MACC:
2919 gen_helper_macc(t0, cpu_env, t0, t1);
2920 opn = "macc";
2921 break;
2922 case OPC_VR54XX_MACCU:
2923 gen_helper_maccu(t0, cpu_env, t0, t1);
2924 opn = "maccu";
2925 break;
2926 case OPC_VR54XX_MSAC:
2927 gen_helper_msac(t0, cpu_env, t0, t1);
2928 opn = "msac";
2929 break;
2930 case OPC_VR54XX_MSACU:
2931 gen_helper_msacu(t0, cpu_env, t0, t1);
2932 opn = "msacu";
2933 break;
2934 case OPC_VR54XX_MULHI:
2935 gen_helper_mulhi(t0, cpu_env, t0, t1);
2936 opn = "mulhi";
2937 break;
2938 case OPC_VR54XX_MULHIU:
2939 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2940 opn = "mulhiu";
2941 break;
2942 case OPC_VR54XX_MULSHI:
2943 gen_helper_mulshi(t0, cpu_env, t0, t1);
2944 opn = "mulshi";
2945 break;
2946 case OPC_VR54XX_MULSHIU:
2947 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2948 opn = "mulshiu";
2949 break;
2950 case OPC_VR54XX_MACCHI:
2951 gen_helper_macchi(t0, cpu_env, t0, t1);
2952 opn = "macchi";
2953 break;
2954 case OPC_VR54XX_MACCHIU:
2955 gen_helper_macchiu(t0, cpu_env, t0, t1);
2956 opn = "macchiu";
2957 break;
2958 case OPC_VR54XX_MSACHI:
2959 gen_helper_msachi(t0, cpu_env, t0, t1);
2960 opn = "msachi";
2961 break;
2962 case OPC_VR54XX_MSACHIU:
2963 gen_helper_msachiu(t0, cpu_env, t0, t1);
2964 opn = "msachiu";
2965 break;
2966 default:
2967 MIPS_INVAL("mul vr54xx");
2968 generate_exception(ctx, EXCP_RI);
2969 goto out;
2970 }
2971 gen_store_gpr(t0, rd);
2972 (void)opn; /* avoid a compiler warning */
2973 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2974
2975 out:
2976 tcg_temp_free(t0);
2977 tcg_temp_free(t1);
2978 }
2979
2980 static void gen_cl (DisasContext *ctx, uint32_t opc,
2981 int rd, int rs)
2982 {
2983 const char *opn = "CLx";
2984 TCGv t0;
2985
2986 if (rd == 0) {
2987 /* Treat as NOP. */
2988 MIPS_DEBUG("NOP");
2989 return;
2990 }
2991 t0 = tcg_temp_new();
2992 gen_load_gpr(t0, rs);
2993 switch (opc) {
2994 case OPC_CLO:
2995 gen_helper_clo(cpu_gpr[rd], t0);
2996 opn = "clo";
2997 break;
2998 case OPC_CLZ:
2999 gen_helper_clz(cpu_gpr[rd], t0);
3000 opn = "clz";
3001 break;
3002 #if defined(TARGET_MIPS64)
3003 case OPC_DCLO:
3004 gen_helper_dclo(cpu_gpr[rd], t0);
3005 opn = "dclo";
3006 break;
3007 case OPC_DCLZ:
3008 gen_helper_dclz(cpu_gpr[rd], t0);
3009 opn = "dclz";
3010 break;
3011 #endif
3012 }
3013 (void)opn; /* avoid a compiler warning */
3014 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3015 tcg_temp_free(t0);
3016 }
3017
3018 /* Godson integer instructions */
3019 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3020 int rd, int rs, int rt)
3021 {
3022 const char *opn = "loongson";
3023 TCGv t0, t1;
3024
3025 if (rd == 0) {
3026 /* Treat as NOP. */
3027 MIPS_DEBUG("NOP");
3028 return;
3029 }
3030
3031 switch (opc) {
3032 case OPC_MULT_G_2E:
3033 case OPC_MULT_G_2F:
3034 case OPC_MULTU_G_2E:
3035 case OPC_MULTU_G_2F:
3036 #if defined(TARGET_MIPS64)
3037 case OPC_DMULT_G_2E:
3038 case OPC_DMULT_G_2F:
3039 case OPC_DMULTU_G_2E:
3040 case OPC_DMULTU_G_2F:
3041 #endif
3042 t0 = tcg_temp_new();
3043 t1 = tcg_temp_new();
3044 break;
3045 default:
3046 t0 = tcg_temp_local_new();
3047 t1 = tcg_temp_local_new();
3048 break;
3049 }
3050
3051 gen_load_gpr(t0, rs);
3052 gen_load_gpr(t1, rt);
3053
3054 switch (opc) {
3055 case OPC_MULT_G_2E:
3056 case OPC_MULT_G_2F:
3057 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3058 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3059 opn = "mult.g";
3060 break;
3061 case OPC_MULTU_G_2E:
3062 case OPC_MULTU_G_2F:
3063 tcg_gen_ext32u_tl(t0, t0);
3064 tcg_gen_ext32u_tl(t1, t1);
3065 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3066 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3067 opn = "multu.g";
3068 break;
3069 case OPC_DIV_G_2E:
3070 case OPC_DIV_G_2F:
3071 {
3072 int l1 = gen_new_label();
3073 int l2 = gen_new_label();
3074 int l3 = gen_new_label();
3075 tcg_gen_ext32s_tl(t0, t0);
3076 tcg_gen_ext32s_tl(t1, t1);
3077 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3078 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3079 tcg_gen_br(l3);
3080 gen_set_label(l1);
3081 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3082 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3083 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3084 tcg_gen_br(l3);
3085 gen_set_label(l2);
3086 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3087 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3088 gen_set_label(l3);
3089 }
3090 opn = "div.g";
3091 break;
3092 case OPC_DIVU_G_2E:
3093 case OPC_DIVU_G_2F:
3094 {
3095 int l1 = gen_new_label();
3096 int l2 = gen_new_label();
3097 tcg_gen_ext32u_tl(t0, t0);
3098 tcg_gen_ext32u_tl(t1, t1);
3099 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3100 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3101 tcg_gen_br(l2);
3102 gen_set_label(l1);
3103 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3104 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3105 gen_set_label(l2);
3106 }
3107 opn = "divu.g";
3108 break;
3109 case OPC_MOD_G_2E:
3110 case OPC_MOD_G_2F:
3111 {
3112 int l1 = gen_new_label();
3113 int l2 = gen_new_label();
3114 int l3 = gen_new_label();
3115 tcg_gen_ext32u_tl(t0, t0);
3116 tcg_gen_ext32u_tl(t1, t1);
3117 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3118 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3119 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3120 gen_set_label(l1);
3121 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3122 tcg_gen_br(l3);
3123 gen_set_label(l2);
3124 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3125 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3126 gen_set_label(l3);
3127 }
3128 opn = "mod.g";
3129 break;
3130 case OPC_MODU_G_2E:
3131 case OPC_MODU_G_2F:
3132 {
3133 int l1 = gen_new_label();
3134 int l2 = gen_new_label();
3135 tcg_gen_ext32u_tl(t0, t0);
3136 tcg_gen_ext32u_tl(t1, t1);
3137 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3138 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3139 tcg_gen_br(l2);
3140 gen_set_label(l1);
3141 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3142 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3143 gen_set_label(l2);
3144 }
3145 opn = "modu.g";
3146 break;
3147 #if defined(TARGET_MIPS64)
3148 case OPC_DMULT_G_2E:
3149 case OPC_DMULT_G_2F:
3150 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3151 opn = "dmult.g";
3152 break;
3153 case OPC_DMULTU_G_2E:
3154 case OPC_DMULTU_G_2F:
3155 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3156 opn = "dmultu.g";
3157 break;
3158 case OPC_DDIV_G_2E:
3159 case OPC_DDIV_G_2F:
3160 {
3161 int l1 = gen_new_label();
3162 int l2 = gen_new_label();
3163 int l3 = gen_new_label();
3164 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3165 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3166 tcg_gen_br(l3);
3167 gen_set_label(l1);
3168 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3169 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3170 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3171 tcg_gen_br(l3);
3172 gen_set_label(l2);
3173 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3174 gen_set_label(l3);
3175 }
3176 opn = "ddiv.g";
3177 break;
3178 case OPC_DDIVU_G_2E:
3179 case OPC_DDIVU_G_2F:
3180 {
3181 int l1 = gen_new_label();
3182 int l2 = gen_new_label();
3183 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3184 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3185 tcg_gen_br(l2);
3186 gen_set_label(l1);
3187 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3188 gen_set_label(l2);
3189 }
3190 opn = "ddivu.g";
3191 break;
3192 case OPC_DMOD_G_2E:
3193 case OPC_DMOD_G_2F:
3194 {
3195 int l1 = gen_new_label();
3196 int l2 = gen_new_label();
3197 int l3 = gen_new_label();
3198 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3199 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3200 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3201 gen_set_label(l1);
3202 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3203 tcg_gen_br(l3);
3204 gen_set_label(l2);
3205 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3206 gen_set_label(l3);
3207 }
3208 opn = "dmod.g";
3209 break;
3210 case OPC_DMODU_G_2E:
3211 case OPC_DMODU_G_2F:
3212 {
3213 int l1 = gen_new_label();
3214 int l2 = gen_new_label();
3215 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3216 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3217 tcg_gen_br(l2);
3218 gen_set_label(l1);
3219 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3220 gen_set_label(l2);
3221 }
3222 opn = "dmodu.g";
3223 break;
3224 #endif
3225 }
3226
3227 (void)opn; /* avoid a compiler warning */
3228 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3229 tcg_temp_free(t0);
3230 tcg_temp_free(t1);
3231 }
3232
3233 /* Loongson multimedia instructions */
3234 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3235 {
3236 const char *opn = "loongson_cp2";
3237 uint32_t opc, shift_max;
3238 TCGv_i64 t0, t1;
3239
3240 opc = MASK_LMI(ctx->opcode);
3241 switch (opc) {
3242 case OPC_ADD_CP2:
3243 case OPC_SUB_CP2:
3244 case OPC_DADD_CP2:
3245 case OPC_DSUB_CP2:
3246 t0 = tcg_temp_local_new_i64();
3247 t1 = tcg_temp_local_new_i64();
3248 break;
3249 default:
3250 t0 = tcg_temp_new_i64();
3251 t1 = tcg_temp_new_i64();
3252 break;
3253 }
3254
3255 gen_load_fpr64(ctx, t0, rs);
3256 gen_load_fpr64(ctx, t1, rt);
3257
3258 #define LMI_HELPER(UP, LO) \
3259 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3260 #define LMI_HELPER_1(UP, LO) \
3261 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3262 #define LMI_DIRECT(UP, LO, OP) \
3263 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3264
3265 switch (opc) {
3266 LMI_HELPER(PADDSH, paddsh);
3267 LMI_HELPER(PADDUSH, paddush);
3268 LMI_HELPER(PADDH, paddh);
3269 LMI_HELPER(PADDW, paddw);
3270 LMI_HELPER(PADDSB, paddsb);
3271 LMI_HELPER(PADDUSB, paddusb);
3272 LMI_HELPER(PADDB, paddb);
3273
3274 LMI_HELPER(PSUBSH, psubsh);
3275 LMI_HELPER(PSUBUSH, psubush);
3276 LMI_HELPER(PSUBH, psubh);
3277 LMI_HELPER(PSUBW, psubw);
3278 LMI_HELPER(PSUBSB, psubsb);
3279 LMI_HELPER(PSUBUSB, psubusb);
3280 LMI_HELPER(PSUBB, psubb);
3281
3282 LMI_HELPER(PSHUFH, pshufh);
3283 LMI_HELPER(PACKSSWH, packsswh);
3284 LMI_HELPER(PACKSSHB, packsshb);
3285 LMI_HELPER(PACKUSHB, packushb);
3286
3287 LMI_HELPER(PUNPCKLHW, punpcklhw);
3288 LMI_HELPER(PUNPCKHHW, punpckhhw);
3289 LMI_HELPER(PUNPCKLBH, punpcklbh);
3290 LMI_HELPER(PUNPCKHBH, punpckhbh);
3291 LMI_HELPER(PUNPCKLWD, punpcklwd);
3292 LMI_HELPER(PUNPCKHWD, punpckhwd);
3293
3294 LMI_HELPER(PAVGH, pavgh);
3295 LMI_HELPER(PAVGB, pavgb);
3296 LMI_HELPER(PMAXSH, pmaxsh);
3297 LMI_HELPER(PMINSH, pminsh);
3298 LMI_HELPER(PMAXUB, pmaxub);
3299 LMI_HELPER(PMINUB, pminub);
3300
3301 LMI_HELPER(PCMPEQW, pcmpeqw);
3302 LMI_HELPER(PCMPGTW, pcmpgtw);
3303 LMI_HELPER(PCMPEQH, pcmpeqh);
3304 LMI_HELPER(PCMPGTH, pcmpgth);
3305 LMI_HELPER(PCMPEQB, pcmpeqb);
3306 LMI_HELPER(PCMPGTB, pcmpgtb);
3307
3308 LMI_HELPER(PSLLW, psllw);
3309 LMI_HELPER(PSLLH, psllh);
3310 LMI_HELPER(PSRLW, psrlw);
3311 LMI_HELPER(PSRLH, psrlh);
3312 LMI_HELPER(PSRAW, psraw);
3313 LMI_HELPER(PSRAH, psrah);
3314
3315 LMI_HELPER(PMULLH, pmullh);
3316 LMI_HELPER(PMULHH, pmulhh);
3317 LMI_HELPER(PMULHUH, pmulhuh);
3318 LMI_HELPER(PMADDHW, pmaddhw);
3319
3320 LMI_HELPER(PASUBUB, pasubub);
3321 LMI_HELPER_1(BIADD, biadd);
3322 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3323
3324 LMI_DIRECT(PADDD, paddd, add);
3325 LMI_DIRECT(PSUBD, psubd, sub);
3326 LMI_DIRECT(XOR_CP2, xor, xor);
3327 LMI_DIRECT(NOR_CP2, nor, nor);
3328 LMI_DIRECT(AND_CP2, and, and);
3329 LMI_DIRECT(PANDN, pandn, andc);
3330 LMI_DIRECT(OR, or, or);
3331
3332 case OPC_PINSRH_0:
3333 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3334 opn = "pinsrh_0";
3335 break;
3336 case OPC_PINSRH_1:
3337 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3338 opn = "pinsrh_1";
3339 break;
3340 case OPC_PINSRH_2:
3341 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3342 opn = "pinsrh_2";
3343 break;
3344 case OPC_PINSRH_3:
3345 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3346 opn = "pinsrh_3";
3347 break;
3348
3349 case OPC_PEXTRH:
3350 tcg_gen_andi_i64(t1, t1, 3);
3351 tcg_gen_shli_i64(t1, t1, 4);
3352 tcg_gen_shr_i64(t0, t0, t1);
3353 tcg_gen_ext16u_i64(t0, t0);
3354 opn = "pextrh";
3355 break;
3356
3357 case OPC_ADDU_CP2:
3358 tcg_gen_add_i64(t0, t0, t1);
3359 tcg_gen_ext32s_i64(t0, t0);
3360 opn = "addu";
3361 break;
3362 case OPC_SUBU_CP2:
3363 tcg_gen_sub_i64(t0, t0, t1);
3364 tcg_gen_ext32s_i64(t0, t0);
3365 opn = "addu";
3366 break;
3367
3368 case OPC_SLL_CP2:
3369 opn = "sll";
3370 shift_max = 32;
3371 goto do_shift;
3372 case OPC_SRL_CP2:
3373 opn = "srl";
3374 shift_max = 32;
3375 goto do_shift;
3376 case OPC_SRA_CP2:
3377 opn = "sra";
3378 shift_max = 32;
3379 goto do_shift;
3380 case OPC_DSLL_CP2:
3381 opn = "dsll";
3382 shift_max = 64;
3383 goto do_shift;
3384 case OPC_DSRL_CP2:
3385 opn = "dsrl";
3386 shift_max = 64;
3387 goto do_shift;
3388 case OPC_DSRA_CP2:
3389 opn = "dsra";
3390 shift_max = 64;
3391 goto do_shift;
3392 do_shift:
3393 /* Make sure shift count isn't TCG undefined behaviour. */
3394 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3395
3396 switch (opc) {
3397 case OPC_SLL_CP2:
3398 case OPC_DSLL_CP2:
3399 tcg_gen_shl_i64(t0, t0, t1);
3400 break;
3401 case OPC_SRA_CP2:
3402 case OPC_DSRA_CP2:
3403 /* Since SRA is UndefinedResult without sign-extended inputs,
3404 we can treat SRA and DSRA the same. */
3405 tcg_gen_sar_i64(t0, t0, t1);
3406 break;
3407 case OPC_SRL_CP2:
3408 /* We want to shift in zeros for SRL; zero-extend first. */
3409 tcg_gen_ext32u_i64(t0, t0);
3410 /* FALLTHRU */
3411 case OPC_DSRL_CP2:
3412 tcg_gen_shr_i64(t0, t0, t1);
3413 break;
3414 }
3415
3416 if (shift_max == 32) {
3417 tcg_gen_ext32s_i64(t0, t0);
3418 }
3419
3420 /* Shifts larger than MAX produce zero. */
3421 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3422 tcg_gen_neg_i64(t1, t1);
3423 tcg_gen_and_i64(t0, t0, t1);
3424 break;
3425
3426 case OPC_ADD_CP2:
3427 case OPC_DADD_CP2:
3428 {
3429 TCGv_i64 t2 = tcg_temp_new_i64();
3430 int lab = gen_new_label();
3431
3432 tcg_gen_mov_i64(t2, t0);
3433 tcg_gen_add_i64(t0, t1, t2);
3434 if (opc == OPC_ADD_CP2) {
3435 tcg_gen_ext32s_i64(t0, t0);
3436 }
3437 tcg_gen_xor_i64(t1, t1, t2);
3438 tcg_gen_xor_i64(t2, t2, t0);
3439 tcg_gen_andc_i64(t1, t2, t1);
3440 tcg_temp_free_i64(t2);
3441 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3442 generate_exception(ctx, EXCP_OVERFLOW);
3443 gen_set_label(lab);
3444
3445 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3446 break;
3447 }
3448
3449 case OPC_SUB_CP2:
3450 case OPC_DSUB_CP2:
3451 {
3452 TCGv_i64 t2 = tcg_temp_new_i64();
3453 int lab = gen_new_label();
3454
3455 tcg_gen_mov_i64(t2, t0);
3456 tcg_gen_sub_i64(t0, t1, t2);
3457 if (opc == OPC_SUB_CP2) {
3458 tcg_gen_ext32s_i64(t0, t0);
3459 }
3460 tcg_gen_xor_i64(t1, t1, t2);
3461 tcg_gen_xor_i64(t2, t2, t0);
3462 tcg_gen_and_i64(t1, t1, t2);
3463 tcg_temp_free_i64(t2);
3464 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3465 generate_exception(ctx, EXCP_OVERFLOW);
3466 gen_set_label(lab);
3467
3468 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3469 break;
3470 }
3471
3472 case OPC_PMULUW:
3473 tcg_gen_ext32u_i64(t0, t0);
3474 tcg_gen_ext32u_i64(t1, t1);
3475 tcg_gen_mul_i64(t0, t0, t1);
3476 opn = "pmuluw";
3477 break;
3478
3479 case OPC_SEQU_CP2:
3480 case OPC_SEQ_CP2:
3481 case OPC_SLTU_CP2:
3482 case OPC_SLT_CP2:
3483 case OPC_SLEU_CP2:
3484 case OPC_SLE_CP2:
3485 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3486 FD field is the CC field? */
3487 default:
3488 MIPS_INVAL(opn);
3489 generate_exception(ctx, EXCP_RI);
3490 return;
3491 }
3492
3493 #undef LMI_HELPER
3494 #undef LMI_DIRECT
3495
3496 gen_store_fpr64(ctx, t0, rd);
3497
3498 (void)opn; /* avoid a compiler warning */
3499 MIPS_DEBUG("%s %s, %s, %s", opn,
3500 fregnames[rd], fregnames[rs], fregnames[rt]);
3501 tcg_temp_free_i64(t0);
3502 tcg_temp_free_i64(t1);
3503 }
3504
3505 /* Traps */
3506 static void gen_trap (DisasContext *ctx, uint32_t opc,
3507 int rs, int rt, int16_t imm)
3508 {
3509 int cond;
3510 TCGv t0 = tcg_temp_new();
3511 TCGv t1 = tcg_temp_new();
3512
3513 cond = 0;
3514 /* Load needed operands */
3515 switch (opc) {
3516 case OPC_TEQ:
3517 case OPC_TGE:
3518 case OPC_TGEU:
3519 case OPC_TLT:
3520 case OPC_TLTU:
3521 case OPC_TNE:
3522 /* Compare two registers */
3523 if (rs != rt) {
3524 gen_load_gpr(t0, rs);
3525 gen_load_gpr(t1, rt);
3526 cond = 1;
3527 }
3528 break;
3529 case OPC_TEQI:
3530 case OPC_TGEI:
3531 case OPC_TGEIU:
3532 case OPC_TLTI:
3533 case OPC_TLTIU:
3534 case OPC_TNEI:
3535 /* Compare register to immediate */
3536 if (rs != 0 || imm != 0) {
3537 gen_load_gpr(t0, rs);
3538 tcg_gen_movi_tl(t1, (int32_t)imm);
3539 cond = 1;
3540 }
3541 break;
3542 }
3543 if (cond == 0) {
3544 switch (opc) {
3545 case OPC_TEQ: /* rs == rs */
3546 case OPC_TEQI: /* r0 == 0 */
3547 case OPC_TGE: /* rs >= rs */
3548 case OPC_TGEI: /* r0 >= 0 */
3549 case OPC_TGEU: /* rs >= rs unsigned */
3550 case OPC_TGEIU: /* r0 >= 0 unsigned */
3551 /* Always trap */
3552 generate_exception(ctx, EXCP_TRAP);
3553 break;
3554 case OPC_TLT: /* rs < rs */
3555 case OPC_TLTI: /* r0 < 0 */
3556 case OPC_TLTU: /* rs < rs unsigned */
3557 case OPC_TLTIU: /* r0 < 0 unsigned */
3558 case OPC_TNE: /* rs != rs */
3559 case OPC_TNEI: /* r0 != 0 */
3560 /* Never trap: treat as NOP. */
3561 break;
3562 }
3563 } else {
3564 int l1 = gen_new_label();
3565
3566 switch (opc) {
3567 case OPC_TEQ:
3568 case OPC_TEQI:
3569 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3570 break;
3571 case OPC_TGE:
3572 case OPC_TGEI:
3573 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3574 break;
3575 case OPC_TGEU:
3576 case OPC_TGEIU:
3577 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3578 break;
3579 case OPC_TLT:
3580 case OPC_TLTI:
3581 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3582 break;
3583 case OPC_TLTU:
3584 case OPC_TLTIU:
3585 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3586 break;
3587 case OPC_TNE:
3588 case OPC_TNEI:
3589 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3590 break;
3591 }
3592 generate_exception(ctx, EXCP_TRAP);
3593 gen_set_label(l1);
3594 }
3595 tcg_temp_free(t0);
3596 tcg_temp_free(t1);
3597 }
3598
3599 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3600 {
3601 TranslationBlock *tb;
3602 tb = ctx->tb;
3603 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3604 likely(!ctx->singlestep_enabled)) {
3605 tcg_gen_goto_tb(n);
3606 gen_save_pc(dest);
3607 tcg_gen_exit_tb((tcg_target_long)tb + n);
3608 } else {
3609 gen_save_pc(dest);
3610 if (ctx->singlestep_enabled) {
3611 save_cpu_state(ctx, 0);
3612 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3613 }
3614 tcg_gen_exit_tb(0);
3615 }
3616 }
3617
3618 /* Branches (before delay slot) */
3619 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3620 int insn_bytes,
3621 int rs, int rt, int32_t offset)
3622 {
3623 target_ulong btgt = -1;
3624 int blink = 0;
3625 int bcond_compute = 0;
3626 TCGv t0 = tcg_temp_new();
3627 TCGv t1 = tcg_temp_new();
3628
3629 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3630 #ifdef MIPS_DEBUG_DISAS
3631 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3632 #endif
3633 generate_exception(ctx, EXCP_RI);
3634 goto out;
3635 }
3636
3637 /* Load needed operands */
3638 switch (opc) {
3639 case OPC_BEQ:
3640 case OPC_BEQL:
3641 case OPC_BNE:
3642 case OPC_BNEL:
3643 /* Compare two registers */
3644 if (rs != rt) {
3645 gen_load_gpr(t0, rs);
3646 gen_load_gpr(t1, rt);
3647 bcond_compute = 1;
3648 }
3649 btgt = ctx->pc + insn_bytes + offset;
3650 break;
3651 case OPC_BGEZ:
3652 case OPC_BGEZAL:
3653 case OPC_BGEZALS:
3654 case OPC_BGEZALL:
3655 case OPC_BGEZL:
3656 case OPC_BGTZ:
3657 case OPC_BGTZL:
3658 case OPC_BLEZ:
3659 case OPC_BLEZL:
3660 case OPC_BLTZ:
3661 case OPC_BLTZAL:
3662 case OPC_BLTZALS:
3663 case OPC_BLTZALL:
3664 case OPC_BLTZL:
3665 /* Compare to zero */
3666 if (rs != 0) {
3667 gen_load_gpr(t0, rs);
3668 bcond_compute = 1;
3669 }
3670 btgt = ctx->pc + insn_bytes + offset;
3671 break;
3672 case OPC_BPOSGE32:
3673 #if defined(TARGET_MIPS64)
3674 case OPC_BPOSGE64:
3675 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3676 #else
3677 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3678 #endif
3679 bcond_compute = 1;
3680 btgt = ctx->pc + insn_bytes + offset;
3681 break;
3682 case OPC_J:
3683 case OPC_JAL:
3684 case OPC_JALX:
3685 case OPC_JALS:
3686 case OPC_JALXS:
3687 /* Jump to immediate */
3688 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3689 break;
3690 case OPC_JR:
3691 case OPC_JALR:
3692 case OPC_JALRC:
3693 case OPC_JALRS:
3694 /* Jump to register */
3695 if (offset != 0 && offset != 16) {
3696 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3697 others are reserved. */
3698 MIPS_INVAL("jump hint");
3699 generate_exception(ctx, EXCP_RI);
3700 goto out;
3701 }
3702 gen_load_gpr(btarget, rs);
3703 break;
3704 default:
3705 MIPS_INVAL("branch/jump");
3706 generate_exception(ctx, EXCP_RI);
3707 goto out;
3708 }
3709 if (bcond_compute == 0) {
3710 /* No condition to be computed */
3711 switch (opc) {
3712 case OPC_BEQ: /* rx == rx */
3713 case OPC_BEQL: /* rx == rx likely */
3714 case OPC_BGEZ: /* 0 >= 0 */
3715 case OPC_BGEZL: /* 0 >= 0 likely */
3716 case OPC_BLEZ: /* 0 <= 0 */
3717 case OPC_BLEZL: /* 0 <= 0 likely */
3718 /* Always take */
3719 ctx->hflags |= MIPS_HFLAG_B;
3720 MIPS_DEBUG("balways");
3721 break;
3722 case OPC_BGEZALS:
3723 case OPC_BGEZAL: /* 0 >= 0 */
3724 case OPC_BGEZALL: /* 0 >= 0 likely */
3725 ctx->hflags |= (opc == OPC_BGEZALS
3726 ? MIPS_HFLAG_BDS16
3727 : MIPS_HFLAG_BDS32);
3728 /* Always take and link */
3729 blink = 31;
3730 ctx->hflags |= MIPS_HFLAG_B;
3731 MIPS_DEBUG("balways and link");
3732 break;
3733 case OPC_BNE: /* rx != rx */
3734 case OPC_BGTZ: /* 0 > 0 */
3735 case OPC_BLTZ: /* 0 < 0 */
3736 /* Treat as NOP. */
3737 MIPS_DEBUG("bnever (NOP)");
3738 goto out;
3739 case OPC_BLTZALS:
3740 case OPC_BLTZAL: /* 0 < 0 */
3741 ctx->hflags |= (opc == OPC_BLTZALS
3742 ? MIPS_HFLAG_BDS16
3743 : MIPS_HFLAG_BDS32);
3744 /* Handle as an unconditional branch to get correct delay
3745 slot checking. */
3746 blink = 31;
3747 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3748 ctx->hflags |= MIPS_HFLAG_B;
3749 MIPS_DEBUG("bnever and link");
3750 break;
3751 case OPC_BLTZALL: /* 0 < 0 likely */
3752 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3753 /* Skip the instruction in the delay slot */
3754 MIPS_DEBUG("bnever, link and skip");
3755 ctx->pc += 4;
3756 goto out;
3757 case OPC_BNEL: /* rx != rx likely */
3758 case OPC_BGTZL: /* 0 > 0 likely */
3759 case OPC_BLTZL: /* 0 < 0 likely */
3760 /* Skip the instruction in the delay slot */
3761 MIPS_DEBUG("bnever and skip");
3762 ctx->pc += 4;
3763 goto out;
3764 case OPC_J:
3765 ctx->hflags |= MIPS_HFLAG_B;
3766 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3767 break;
3768 case OPC_JALXS:
3769 case OPC_JALX:
3770 ctx->hflags |= MIPS_HFLAG_BX;
3771 /* Fallthrough */
3772 case OPC_JALS:
3773 case OPC_JAL:
3774 blink = 31;
3775 ctx->hflags |= MIPS_HFLAG_B;
3776 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3777 ? MIPS_HFLAG_BDS16
3778 : MIPS_HFLAG_BDS32);
3779 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3780 break;
3781 case OPC_JR:
3782 ctx->hflags |= MIPS_HFLAG_BR;
3783 if (insn_bytes == 4)
3784 ctx->hflags |= MIPS_HFLAG_BDS32;
3785 MIPS_DEBUG("jr %s", regnames[rs]);
3786 break;
3787 case OPC_JALRS:
3788 case OPC_JALR:
3789 case OPC_JALRC:
3790 blink = rt;
3791 ctx->hflags |= MIPS_HFLAG_BR;
3792 ctx->hflags |= (opc == OPC_JALRS
3793 ? MIPS_HFLAG_BDS16
3794 : MIPS_HFLAG_BDS32);
3795 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3796 break;
3797 default:
3798 MIPS_INVAL("branch/jump");
3799 generate_exception(ctx, EXCP_RI);
3800 goto out;
3801 }
3802 } else {
3803 switch (opc) {
3804 case OPC_BEQ:
3805 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3806 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3807 regnames[rs], regnames[rt], btgt);
3808 goto not_likely;
3809 case OPC_BEQL:
3810 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3811 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3812 regnames[rs], regnames[rt], btgt);
3813 goto likely;
3814 case OPC_BNE:
3815 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3816 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3817 regnames[rs], regnames[rt], btgt);
3818 goto not_likely;
3819 case OPC_BNEL:
3820 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3821 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3822 regnames[rs], regnames[rt], btgt);
3823 goto likely;
3824 case OPC_BGEZ:
3825 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3826 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3827 goto not_likely;
3828 case OPC_BGEZL:
3829 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3830 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3831 goto likely;
3832 case OPC_BGEZALS:
3833 case OPC_BGEZAL:
3834 ctx->hflags |= (opc == OPC_BGEZALS
3835 ? MIPS_HFLAG_BDS16
3836 : MIPS_HFLAG_BDS32);
3837 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3838 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3839 blink = 31;
3840 goto not_likely;
3841 case OPC_BGEZALL:
3842 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3843 blink = 31;
3844 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3845 goto likely;
3846 case OPC_BGTZ:
3847 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3848 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3849 goto not_likely;
3850 case OPC_BGTZL:
3851 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3852 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3853 goto likely;
3854 case OPC_BLEZ:
3855 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3856 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3857 goto not_likely;
3858 case OPC_BLEZL:
3859 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3860 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3861 goto likely;
3862 case OPC_BLTZ:
3863 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3864 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3865 goto not_likely;
3866 case OPC_BLTZL:
3867 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3868 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3869 goto likely;
3870 case OPC_BPOSGE32:
3871 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3872 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3873 goto not_likely;
3874 #if defined(TARGET_MIPS64)
3875 case OPC_BPOSGE64:
3876 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3877 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3878 goto not_likely;
3879 #endif
3880 case OPC_BLTZALS:
3881 case OPC_BLTZAL:
3882 ctx->hflags |= (opc == OPC_BLTZALS
3883 ? MIPS_HFLAG_BDS16
3884 : MIPS_HFLAG_BDS32);
3885 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3886 blink = 31;
3887 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3888 not_likely:
3889 ctx->hflags |= MIPS_HFLAG_BC;
3890 break;
3891 case OPC_BLTZALL:
3892 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3893 blink = 31;
3894 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3895 likely:
3896 ctx->hflags |= MIPS_HFLAG_BL;
3897 break;
3898 default:
3899 MIPS_INVAL("conditional branch/jump");
3900 generate_exception(ctx, EXCP_RI);
3901 goto out;
3902 }
3903 }
3904 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3905 blink, ctx->hflags, btgt);
3906
3907 ctx->btarget = btgt;
3908 if (blink > 0) {
3909 int post_delay = insn_bytes;
3910 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3911
3912 if (opc != OPC_JALRC)
3913 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3914
3915 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3916 }
3917
3918 out:
3919 if (insn_bytes == 2)
3920 ctx->hflags |= MIPS_HFLAG_B16;
3921 tcg_temp_free(t0);
3922 tcg_temp_free(t1);
3923 }
3924
3925 /* special3 bitfield operations */
3926 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3927 int rs, int lsb, int msb)
3928 {
3929 TCGv t0 = tcg_temp_new();
3930 TCGv t1 = tcg_temp_new();
3931
3932 gen_load_gpr(t1, rs);
3933 switch (opc) {
3934 case OPC_EXT:
3935 if (lsb + msb > 31)
3936 goto fail;
3937 tcg_gen_shri_tl(t0, t1, lsb);
3938 if (msb != 31) {
3939 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3940 } else {
3941 tcg_gen_ext32s_tl(t0, t0);
3942 }
3943 break;
3944 #if defined(TARGET_MIPS64)
3945 case OPC_DEXTM:
3946 tcg_gen_shri_tl(t0, t1, lsb);
3947 if (msb != 31) {
3948 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3949 }
3950 break;
3951 case OPC_DEXTU:
3952 tcg_gen_shri_tl(t0, t1, lsb + 32);
3953 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3954 break;
3955 case OPC_DEXT:
3956 tcg_gen_shri_tl(t0, t1, lsb);
3957 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3958 break;
3959 #endif
3960 case OPC_INS:
3961 if (lsb > msb)
3962 goto fail;
3963 gen_load_gpr(t0, rt);
3964 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3965 tcg_gen_ext32s_tl(t0, t0);
3966 break;
3967 #if defined(TARGET_MIPS64)
3968 case OPC_DINSM:
3969 gen_load_gpr(t0, rt);
3970 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3971 break;
3972 case OPC_DINSU:
3973 gen_load_gpr(t0, rt);
3974 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3975 break;
3976 case OPC_DINS:
3977 gen_load_gpr(t0, rt);
3978 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3979 break;
3980 #endif
3981 default:
3982 fail:
3983 MIPS_INVAL("bitops");
3984 generate_exception(ctx, EXCP_RI);
3985 tcg_temp_free(t0);
3986 tcg_temp_free(t1);
3987 return;
3988 }
3989 gen_store_gpr(t0, rt);
3990 tcg_temp_free(t0);
3991 tcg_temp_free(t1);
3992 }
3993
3994 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3995 {
3996 TCGv t0;
3997
3998 if (rd == 0) {
3999 /* If no destination, treat it as a NOP. */
4000 MIPS_DEBUG("NOP");
4001 return;
4002 }
4003
4004 t0 = tcg_temp_new();
4005 gen_load_gpr(t0, rt);
4006 switch (op2) {
4007 case OPC_WSBH:
4008 {
4009 TCGv t1 = tcg_temp_new();
4010
4011 tcg_gen_shri_tl(t1, t0, 8);
4012 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4013 tcg_gen_shli_tl(t0, t0, 8);
4014 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4015 tcg_gen_or_tl(t0, t0, t1);
4016 tcg_temp_free(t1);
4017 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4018 }
4019 break;
4020 case OPC_SEB:
4021 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
4022 break;
4023 case OPC_SEH:
4024 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4025 break;
4026 #if defined(TARGET_MIPS64)
4027 case OPC_DSBH:
4028 {
4029 TCGv t1 = tcg_temp_new();
4030
4031 tcg_gen_shri_tl(t1, t0, 8);
4032 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4033 tcg_gen_shli_tl(t0, t0, 8);
4034 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4035 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4036 tcg_temp_free(t1);
4037 }
4038 break;
4039 case OPC_DSHD:
4040 {
4041 TCGv t1 = tcg_temp_new();
4042
4043 tcg_gen_shri_tl(t1, t0, 16);
4044 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4045 tcg_gen_shli_tl(t0, t0, 16);
4046 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4047 tcg_gen_or_tl(t0, t0, t1);
4048 tcg_gen_shri_tl(t1, t0, 32);
4049 tcg_gen_shli_tl(t0, t0, 32);
4050 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4051 tcg_temp_free(t1);
4052 }
4053 break;
4054 #endif
4055 default:
4056 MIPS_INVAL("bsfhl");
4057 generate_exception(ctx, EXCP_RI);
4058 tcg_temp_free(t0);
4059 return;
4060 }
4061 tcg_temp_free(t0);
4062 }
4063
4064 #ifndef CONFIG_USER_ONLY
4065 /* CP0 (MMU and control) */
4066 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4067 {
4068 TCGv_i32 t0 = tcg_temp_new_i32();
4069
4070 tcg_gen_ld_i32(t0, cpu_env, off);
4071 tcg_gen_ext_i32_tl(arg, t0);
4072 tcg_temp_free_i32(t0);
4073 }
4074
4075 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4076 {
4077 tcg_gen_ld_tl(arg, cpu_env, off);
4078 tcg_gen_ext32s_tl(arg, arg);
4079 }
4080
4081 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4082 {
4083 TCGv_i32 t0 = tcg_temp_new_i32();
4084
4085 tcg_gen_trunc_tl_i32(t0, arg);
4086 tcg_gen_st_i32(t0, cpu_env, off);
4087 tcg_temp_free_i32(t0);
4088 }
4089
4090 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4091 {
4092 tcg_gen_ext32s_tl(arg, arg);
4093 tcg_gen_st_tl(arg, cpu_env, off);
4094 }
4095
4096 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4097 {
4098 const char *rn = "invalid";
4099
4100 if (sel != 0)
4101 check_insn(env, ctx, ISA_MIPS32);
4102
4103 switch (reg) {
4104 case 0:
4105 switch (sel) {
4106 case 0:
4107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4108 rn = "Index";
4109 break;
4110 case 1:
4111 check_insn(env, ctx, ASE_MT);
4112 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4113 rn = "MVPControl";
4114 break;
4115 case 2:
4116 check_insn(env, ctx, ASE_MT);
4117 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4118 rn = "MVPConf0";
4119 break;
4120 case 3:
4121 check_insn(env, ctx, ASE_MT);
4122 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4123 rn = "MVPConf1";
4124 break;
4125 default:
4126 goto die;
4127 }
4128 break;
4129 case 1:
4130 switch (sel) {
4131 case 0:
4132 gen_helper_mfc0_random(arg, cpu_env);
4133 rn = "Random";
4134 break;
4135 case 1:
4136 check_insn(env, ctx, ASE_MT);
4137 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4138 rn = "VPEControl";
4139 break;
4140 case 2:
4141 check_insn(env, ctx, ASE_MT);
4142 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4143 rn = "VPEConf0";
4144 break;
4145 case 3:
4146 check_insn(env, ctx, ASE_MT);
4147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4148 rn = "VPEConf1";
4149 break;
4150 case 4:
4151 check_insn(env, ctx, ASE_MT);
4152 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4153 rn = "YQMask";
4154 break;
4155 case 5:
4156 check_insn(env, ctx, ASE_MT);
4157 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4158 rn = "VPESchedule";
4159 break;
4160 case 6:
4161 check_insn(env, ctx, ASE_MT);
4162 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4163 rn = "VPEScheFBack";
4164 break;
4165 case 7:
4166 check_insn(env, ctx, ASE_MT);
4167 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4168 rn = "VPEOpt";
4169 break;
4170 default:
4171 goto die;
4172 }
4173 break;
4174 case 2:
4175 switch (sel) {
4176 case 0:
4177 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4178 tcg_gen_ext32s_tl(arg, arg);
4179 rn = "EntryLo0";
4180 break;
4181 case 1:
4182 check_insn(env, ctx, ASE_MT);
4183 gen_helper_mfc0_tcstatus(arg, cpu_env);
4184 rn = "TCStatus";
4185 break;
4186 case 2:
4187 check_insn(env, ctx, ASE_MT);
4188 gen_helper_mfc0_tcbind(arg, cpu_env);
4189 rn = "TCBind";
4190 break;
4191 case 3:
4192 check_insn(env, ctx, ASE_MT);
4193 gen_helper_mfc0_tcrestart(arg, cpu_env);
4194 rn = "TCRestart";
4195 break;
4196 case 4:
4197 check_insn(env, ctx, ASE_MT);
4198 gen_helper_mfc0_tchalt(arg, cpu_env);
4199 rn = "TCHalt";
4200 break;
4201 case 5:
4202 check_insn(env, ctx, ASE_MT);
4203 gen_helper_mfc0_tccontext(arg, cpu_env);
4204 rn = "TCContext";
4205 break;
4206 case 6:
4207 check_insn(env, ctx, ASE_MT);
4208 gen_helper_mfc0_tcschedule(arg, cpu_env);
4209 rn = "TCSchedule";
4210 break;
4211 case 7:
4212 check_insn(env, ctx, ASE_MT);
4213 gen_helper_mfc0_tcschefback(arg, cpu_env);
4214 rn = "TCScheFBack";
4215 break;
4216 default:
4217 goto die;
4218 }
4219 break;
4220 case 3:
4221 switch (sel) {
4222 case 0:
4223 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4224 tcg_gen_ext32s_tl(arg, arg);
4225 rn = "EntryLo1";
4226 break;
4227 default:
4228 goto die;
4229 }
4230 break;
4231 case 4:
4232 switch (sel) {
4233 case 0:
4234 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4235 tcg_gen_ext32s_tl(arg, arg);
4236 rn = "Context";
4237 break;
4238 case 1:
4239 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4240 rn = "ContextConfig";
4241 // break;
4242 default:
4243 goto die;
4244 }
4245 break;
4246 case 5:
4247 switch (sel) {
4248 case 0:
4249 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4250 rn = "PageMask";
4251 break;
4252 case 1:
4253 check_insn(env, ctx, ISA_MIPS32R2);
4254 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4255 rn = "PageGrain";
4256 break;
4257 default:
4258 goto die;
4259 }
4260 break;
4261 case 6:
4262 switch (sel) {
4263 case 0:
4264 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4265 rn = "Wired";
4266 break;
4267 case 1:
4268 check_insn(env, ctx, ISA_MIPS32R2);
4269 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4270 rn = "SRSConf0";
4271 break;
4272 case 2:
4273 check_insn(env, ctx, ISA_MIPS32R2);
4274 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4275 rn = "SRSConf1";
4276 break;
4277 case 3:
4278 check_insn(env, ctx, ISA_MIPS32R2);
4279 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4280 rn = "SRSConf2";
4281 break;
4282 case 4:
4283 check_insn(env, ctx, ISA_MIPS32R2);
4284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4285 rn = "SRSConf3";
4286 break;
4287 case 5:
4288 check_insn(env, ctx, ISA_MIPS32R2);
4289 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4290 rn = "SRSConf4";
4291 break;
4292 default:
4293 goto die;
4294 }
4295 break;
4296 case 7:
4297 switch (sel) {
4298 case 0:
4299 check_insn(env, ctx, ISA_MIPS32R2);
4300 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4301 rn = "HWREna";
4302 break;
4303 default:
4304 goto die;
4305 }
4306 break;
4307 case 8:
4308 switch (sel) {
4309 case 0:
4310 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4311 tcg_gen_ext32s_tl(arg, arg);
4312 rn = "BadVAddr";
4313 break;
4314 default:
4315 goto die;
4316 }
4317 break;
4318 case 9:
4319 switch (sel) {
4320 case 0:
4321 /* Mark as an IO operation because we read the time. */
4322 if (use_icount)
4323 gen_io_start();
4324 gen_helper_mfc0_count(arg, cpu_env);
4325 if (use_icount) {
4326 gen_io_end();
4327 }
4328 /* Break the TB to be able to take timer interrupts immediately
4329 after reading count. */
4330 ctx->bstate = BS_STOP;
4331 rn = "Count";
4332 break;
4333 /* 6,7 are implementation dependent */
4334 default:
4335 goto die;
4336 }
4337 break;
4338 case 10:
4339 switch (sel) {
4340 case 0:
4341 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4342 tcg_gen_ext32s_tl(arg, arg);
4343 rn = "EntryHi";
4344 break;
4345 default:
4346 goto die;
4347 }
4348 break;
4349 case 11:
4350 switch (sel) {
4351 case 0:
4352 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4353 rn = "Compare";
4354 break;
4355 /* 6,7 are implementation dependent */
4356 default:
4357 goto die;
4358 }
4359 break;
4360 case 12:
4361 switch (sel) {
4362 case 0:
4363 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4364 rn = "Status";
4365 break;
4366 case 1:
4367 check_insn(env, ctx, ISA_MIPS32R2);
4368 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4369 rn = "IntCtl";
4370 break;
4371 case 2:
4372 check_insn(env, ctx, ISA_MIPS32R2);
4373 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4374 rn = "SRSCtl";
4375 break;
4376 case 3:
4377 check_insn(env, ctx, ISA_MIPS32R2);
4378 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4379 rn = "SRSMap";
4380 break;
4381 default:
4382 goto die;
4383 }
4384 break;
4385 case 13:
4386 switch (sel) {
4387 case 0:
4388 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4389 rn = "Cause";
4390 break;
4391 default:
4392 goto die;
4393 }
4394 break;
4395 case 14:
4396 switch (sel) {
4397 case 0:
4398 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4399 tcg_gen_ext32s_tl(arg, arg);
4400 rn = "EPC";
4401 break;
4402 default:
4403 goto die;
4404 }
4405 break;
4406 case 15:
4407 switch (sel) {
4408 case 0:
4409 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4410 rn = "PRid";
4411 break;
4412 case 1:
4413 check_insn(env, ctx, ISA_MIPS32R2);
4414 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4415 rn = "EBase";
4416 break;
4417 default:
4418 goto die;
4419 }
4420 break;
4421 case 16:
4422 switch (sel) {
4423 case 0:
4424 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4425 rn = "Config";
4426 break;
4427 case 1:
4428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4429 rn = "Config1";
4430 break;
4431 case 2:
4432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4433 rn = "Config2";
4434 break;
4435 case 3:
4436 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4437 rn = "Config3";
4438 break;
4439 /* 4,5 are reserved */
4440 /* 6,7 are implementation dependent */
4441 case 6:
4442 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4443 rn = "Config6";
4444 break;
4445 case 7:
4446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4447 rn = "Config7";
4448 break;
4449 default:
4450 goto die;
4451 }
4452 break;
4453 case 17:
4454 switch (sel) {
4455 case 0:
4456 gen_helper_mfc0_lladdr(arg, cpu_env);
4457 rn = "LLAddr";
4458 break;
4459 default:
4460 goto die;
4461 }
4462 break;
4463 case 18:
4464 switch (sel) {
4465 case 0 ... 7:
4466 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4467 rn = "WatchLo";
4468 break;
4469 default:
4470 goto die;
4471 }
4472 break;
4473 case 19:
4474 switch (sel) {
4475 case 0 ...7:
4476 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4477 rn = "WatchHi";
4478 break;
4479 default:
4480 goto die;
4481 }
4482 break;
4483 case 20:
4484 switch (sel) {
4485 case 0:
4486 #if defined(TARGET_MIPS64)
4487 check_insn(env, ctx, ISA_MIPS3);
4488 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4489 tcg_gen_ext32s_tl(arg, arg);
4490 rn = "XContext";
4491 break;
4492 #endif
4493 default:
4494 goto die;
4495 }
4496 break;
4497 case 21:
4498 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4499 switch (sel) {
4500 case 0:
4501 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4502 rn = "Framemask";
4503 break;
4504 default:
4505 goto die;
4506 }
4507 break;
4508 case 22:
4509 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4510 rn = "'Diagnostic"; /* implementation dependent */
4511 break;
4512 case 23:
4513 switch (sel) {
4514 case 0:
4515 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4516 rn = "Debug";
4517 break;
4518 case 1:
4519 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4520 rn = "TraceControl";
4521 // break;
4522 case 2:
4523 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4524 rn = "TraceControl2";
4525 // break;
4526 case 3:
4527 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4528 rn = "UserTraceData";
4529 // break;
4530 case 4:
4531 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4532 rn = "TraceBPC";
4533 // break;
4534 default:
4535 goto die;
4536 }
4537 break;
4538 case 24:
4539 switch (sel) {
4540 case 0:
4541 /* EJTAG support */
4542 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4543 tcg_gen_ext32s_tl(arg, arg);
4544 rn = "DEPC";
4545 break;
4546 default:
4547 goto die;
4548 }
4549 break;
4550 case 25:
4551 switch (sel) {
4552 case 0:
4553 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4554 rn = "Performance0";
4555 break;
4556 case 1:
4557 // gen_helper_mfc0_performance1(arg);
4558 rn = "Performance1";
4559 // break;
4560 case 2:
4561 // gen_helper_mfc0_performance2(arg);
4562 rn = "Performance2";
4563 // break;
4564 case 3:
4565 // gen_helper_mfc0_performance3(arg);
4566 rn = "Performance3";
4567 // break;
4568 case 4:
4569 // gen_helper_mfc0_performance4(arg);
4570 rn = "Performance4";
4571 // break;
4572 case 5:
4573 // gen_helper_mfc0_performance5(arg);
4574 rn = "Performance5";
4575 // break;
4576 case 6:
4577 // gen_helper_mfc0_performance6(arg);
4578 rn = "Performance6";
4579 // break;
4580 case 7:
4581 // gen_helper_mfc0_performance7(arg);
4582 rn = "Performance7";
4583 // break;
4584 default:
4585 goto die;
4586 }
4587 break;
4588 case 26:
4589 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4590 rn = "ECC";
4591 break;
4592 case 27:
4593 switch (sel) {
4594 case 0 ... 3:
4595 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4596 rn = "CacheErr";
4597 break;
4598 default:
4599 goto die;
4600 }
4601 break;
4602 case 28:
4603 switch (sel) {
4604 case 0:
4605 case 2:
4606 case 4:
4607 case 6:
4608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4609 rn = "TagLo";
4610 break;
4611 case 1:
4612 case 3:
4613 case 5:
4614 case 7:
4615 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4616 rn = "DataLo";
4617 break;
4618 default:
4619 goto die;
4620 }
4621 break;
4622 case 29:
4623 switch (sel) {
4624 case 0:
4625 case 2:
4626 case 4:
4627 case 6:
4628 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4629 rn = "TagHi";
4630 break;
4631 case 1:
4632 case 3:
4633 case 5:
4634 case 7:
4635 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4636 rn = "DataHi";
4637 break;
4638 default:
4639 goto die;
4640 }
4641 break;
4642 case 30:
4643 switch (sel) {
4644 case 0:
4645 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4646 tcg_gen_ext32s_tl(arg, arg);
4647 rn = "ErrorEPC";
4648 break;
4649 default:
4650 goto die;
4651 }
4652 break;
4653 case 31:
4654 switch (sel) {
4655 case 0:
4656 /* EJTAG support */
4657 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4658 rn = "DESAVE";
4659 break;
4660 default:
4661 goto die;
4662 }
4663 break;
4664 default:
4665 goto die;
4666 }
4667 (void)rn; /* avoid a compiler warning */
4668 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4669 return;
4670
4671 die:
4672 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4673 generate_exception(ctx, EXCP_RI);
4674 }
4675
4676 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4677 {
4678 const char *rn = "invalid";
4679
4680 if (sel != 0)
4681 check_insn(env, ctx, ISA_MIPS32);
4682
4683 if (use_icount)
4684 gen_io_start();
4685
4686 switch (reg) {
4687 case 0:
4688 switch (sel) {
4689 case 0:
4690 gen_helper_mtc0_index(cpu_env, arg);
4691 rn = "Index";
4692 break;
4693 case 1:
4694 check_insn(env, ctx, ASE_MT);
4695 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4696 rn = "MVPControl";
4697 break;
4698 case 2:
4699 check_insn(env, ctx, ASE_MT);
4700 /* ignored */
4701 rn = "MVPConf0";
4702 break;
4703 case 3:
4704 check_insn(env, ctx, ASE_MT);
4705 /* ignored */
4706 rn = "MVPConf1";
4707 break;
4708 default:
4709 goto die;
4710 }
4711 break;
4712 case 1:
4713 switch (sel) {
4714 case 0:
4715 /* ignored */
4716 rn = "Random";
4717 break;
4718 case 1:
4719 check_insn(env, ctx, ASE_MT);
4720 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4721 rn = "VPEControl";
4722 break;
4723 case 2:
4724 check_insn(env, ctx, ASE_MT);
4725 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4726 rn = "VPEConf0";
4727 break;
4728 case 3:
4729 check_insn(env, ctx, ASE_MT);
4730 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4731 rn = "VPEConf1";
4732 break;
4733 case 4:
4734 check_insn(env, ctx, ASE_MT);
4735 gen_helper_mtc0_yqmask(cpu_env, arg);
4736 rn = "YQMask";
4737 break;
4738 case 5:
4739 check_insn(env, ctx, ASE_MT);
4740 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4741 rn = "VPESchedule";
4742 break;
4743 case 6:
4744 check_insn(env, ctx, ASE_MT);
4745 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4746 rn = "VPEScheFBack";
4747 break;
4748 case 7:
4749 check_insn(env, ctx, ASE_MT);
4750 gen_helper_mtc0_vpeopt(cpu_env, arg);
4751 rn = "VPEOpt";
4752 break;
4753 default:
4754 goto die;
4755 }
4756 break;
4757 case 2:
4758 switch (sel) {
4759 case 0:
4760 gen_helper_mtc0_entrylo0(cpu_env, arg);
4761 rn = "EntryLo0";
4762 break;
4763 case 1:
4764 check_insn(env, ctx, ASE_MT);
4765 gen_helper_mtc0_tcstatus(cpu_env, arg);
4766 rn = "TCStatus";
4767 break;
4768 case 2:
4769 check_insn(env, ctx, ASE_MT);
4770 gen_helper_mtc0_tcbind(cpu_env, arg);
4771 rn = "TCBind";
4772 break;
4773 case 3:
4774 check_insn(env, ctx, ASE_MT);
4775 gen_helper_mtc0_tcrestart(cpu_env, arg);
4776 rn = "TCRestart";
4777 break;
4778 case 4:
4779 check_insn(env, ctx, ASE_MT);
4780 gen_helper_mtc0_tchalt(cpu_env, arg);
4781 rn = "TCHalt";
4782 break;
4783 case 5:
4784 check_insn(env, ctx, ASE_MT);
4785 gen_helper_mtc0_tccontext(cpu_env, arg);
4786 rn = "TCContext";
4787 break;
4788 case 6:
4789 check_insn(env, ctx, ASE_MT);
4790 gen_helper_mtc0_tcschedule(cpu_env, arg);
4791 rn = "TCSchedule";
4792 break;
4793 case 7:
4794 check_insn(env, ctx, ASE_MT);
4795 gen_helper_mtc0_tcschefback(cpu_env, arg);
4796 rn = "TCScheFBack";
4797 break;
4798 default:
4799 goto die;
4800 }
4801 break;
4802 case 3:
4803 switch (sel) {
4804 case 0:
4805 gen_helper_mtc0_entrylo1(cpu_env, arg);
4806 rn = "EntryLo1";
4807 break;
4808 default:
4809 goto die;
4810 }
4811 break;
4812 case 4:
4813 switch (sel) {
4814 case 0:
4815 gen_helper_mtc0_context(cpu_env, arg);
4816 rn = "Context";
4817 break;
4818 case 1:
4819 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4820 rn = "ContextConfig";
4821 // break;
4822 default:
4823 goto die;
4824 }
4825 break;
4826 case 5:
4827 switch (sel) {
4828 case 0:
4829 gen_helper_mtc0_pagemask(cpu_env, arg);
4830 rn = "PageMask";
4831 break;
4832 case 1:
4833 check_insn(env, ctx, ISA_MIPS32R2);
4834 gen_helper_mtc0_pagegrain(cpu_env, arg);
4835 rn = "PageGrain";
4836 break;
4837 default:
4838 goto die;
4839 }
4840 break;
4841 case 6:
4842 switch (sel) {
4843 case 0:
4844 gen_helper_mtc0_wired(cpu_env, arg);
4845 rn = "Wired";
4846 break;
4847 case 1:
4848 check_insn(env, ctx, ISA_MIPS32R2);
4849 gen_helper_mtc0_srsconf0(cpu_env, arg);
4850 rn = "SRSConf0";
4851 break;
4852 case 2:
4853 check_insn(env, ctx, ISA_MIPS32R2);
4854 gen_helper_mtc0_srsconf1(cpu_env, arg);
4855 rn = "SRSConf1";
4856 break;
4857 case 3:
4858 check_insn(env, ctx, ISA_MIPS32R2);
4859 gen_helper_mtc0_srsconf2(cpu_env, arg);
4860 rn = "SRSConf2";
4861 break;
4862 case 4:
4863 check_insn(env, ctx, ISA_MIPS32R2);
4864 gen_helper_mtc0_srsconf3(cpu_env, arg);
4865 rn = "SRSConf3";
4866 break;
4867 case 5:
4868 check_insn(env, ctx, ISA_MIPS32R2);
4869 gen_helper_mtc0_srsconf4(cpu_env, arg);
4870 rn = "SRSConf4";
4871 break;
4872 default:
4873 goto die;
4874 }
4875 break;
4876 case 7:
4877 switch (sel) {
4878 case 0:
4879 check_insn(env, ctx, ISA_MIPS32R2);
4880 gen_helper_mtc0_hwrena(cpu_env, arg);
4881 rn = "HWREna";
4882 break;
4883 default:
4884 goto die;
4885 }
4886 break;
4887 case 8:
4888 /* ignored */
4889 rn = "BadVAddr";
4890 break;
4891 case 9:
4892 switch (sel) {
4893 case 0:
4894 gen_helper_mtc0_count(cpu_env, arg);
4895 rn = "Count";
4896 break;
4897 /* 6,7 are implementation dependent */
4898 default:
4899 goto die;
4900 }
4901 break;
4902 case 10:
4903 switch (sel) {
4904 case 0:
4905 gen_helper_mtc0_entryhi(cpu_env, arg);
4906 rn = "EntryHi";
4907 break;
4908 default:
4909 goto die;
4910 }
4911 break;
4912 case 11:
4913 switch (sel) {
4914 case 0:
4915 gen_helper_mtc0_compare(cpu_env, arg);
4916 rn = "Compare";
4917 break;
4918 /* 6,7 are implementation dependent */
4919 default:
4920 goto die;
4921 }
4922 break;
4923 case 12:
4924 switch (sel) {
4925 case 0:
4926 save_cpu_state(ctx, 1);
4927 gen_helper_mtc0_status(cpu_env, arg);
4928 /* BS_STOP isn't good enough here, hflags may have changed. */
4929 gen_save_pc(ctx->pc + 4);
4930 ctx->bstate = BS_EXCP;
4931 rn = "Status";
4932 break;
4933 case 1:
4934 check_insn(env, ctx, ISA_MIPS32R2);
4935 gen_helper_mtc0_intctl(cpu_env, arg);
4936 /* Stop translation as we may have switched the execution mode */
4937 ctx->bstate = BS_STOP;
4938 rn = "IntCtl";
4939 break;
4940 case 2:
4941 check_insn(env, ctx, ISA_MIPS32R2);
4942 gen_helper_mtc0_srsctl(cpu_env, arg);
4943 /* Stop translation as we may have switched the execution mode */
4944 ctx->bstate = BS_STOP;
4945 rn = "SRSCtl";
4946 break;
4947 case 3:
4948 check_insn(env, ctx, ISA_MIPS32R2);
4949 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4950 /* Stop translation as we may have switched the execution mode */
4951 ctx->bstate = BS_STOP;
4952 rn = "SRSMap";
4953 break;
4954 default:
4955 goto die;
4956 }
4957 break;
4958 case 13:
4959 switch (sel) {
4960 case 0:
4961 save_cpu_state(ctx, 1);
4962 gen_helper_mtc0_cause(cpu_env, arg);
4963 rn = "Cause";
4964 break;
4965 default:
4966 goto die;
4967 }
4968 break;
4969 case 14:
4970 switch (sel) {
4971 case 0:
4972 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4973 rn = "EPC";
4974 break;
4975 default:
4976 goto die;
4977 }
4978 break;
4979 case 15:
4980 switch (sel) {
4981 case 0:
4982 /* ignored */
4983 rn = "PRid";
4984 break;
4985 case 1:
4986 check_insn(env, ctx, ISA_MIPS32R2);
4987 gen_helper_mtc0_ebase(cpu_env, arg);
4988 rn = "EBase";
4989 break;
4990 default:
4991 goto die;
4992 }
4993 break;
4994 case 16:
4995 switch (sel) {
4996 case 0:
4997 gen_helper_mtc0_config0(cpu_env, arg);
4998 rn = "Config";
4999 /* Stop translation as we may have switched the execution mode */
5000 ctx->bstate = BS_STOP;
5001 break;
5002 case 1:
5003 /* ignored, read only */
5004 rn = "Config1";
5005 break;
5006 case 2:
5007 gen_helper_mtc0_config2(cpu_env, arg);
5008 rn = "Config2";
5009 /* Stop translation as we may have switched the execution mode */
5010 ctx->bstate = BS_STOP;
5011 break;
5012 case 3:
5013 /* ignored, read only */
5014 rn = "Config3";
5015 break;
5016 /* 4,5 are reserved */
5017 /* 6,7 are implementation dependent */
5018 case 6:
5019 /* ignored */
5020 rn = "Config6";
5021 break;
5022 case 7:
5023 /* ignored */
5024 rn = "Config7";
5025 break;
5026 default:
5027 rn = "Invalid config selector";
5028 goto die;
5029 }
5030 break;
5031 case 17:
5032 switch (sel) {
5033 case 0:
5034 gen_helper_mtc0_lladdr(cpu_env, arg);
5035 rn = "LLAddr";
5036 break;
5037 default:
5038 goto die;
5039 }
5040 break;
5041 case 18:
5042 switch (sel) {
5043 case 0 ... 7:
5044 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5045 rn = "WatchLo";
5046 break;
5047 default:
5048 goto die;
5049 }
5050 break;
5051 case 19:
5052 switch (sel) {
5053 case 0 ... 7:
5054 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5055 rn = "WatchHi";
5056 break;
5057 default:
5058 goto die;
5059 }
5060 break;
5061 case 20:
5062 switch (sel) {
5063 case 0:
5064 #if defined(TARGET_MIPS64)
5065 check_insn(env, ctx, ISA_MIPS3);
5066 gen_helper_mtc0_xcontext(cpu_env, arg);
5067 rn = "XContext";
5068 break;
5069 #endif
5070 default:
5071 goto die;
5072 }
5073 break;
5074 case 21:
5075 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5076 switch (sel) {
5077 case 0:
5078 gen_helper_mtc0_framemask(cpu_env, arg);
5079 rn = "Framemask";
5080 break;
5081 default:
5082 goto die;
5083 }
5084 break;
5085 case 22:
5086 /* ignored */
5087 rn = "Diagnostic"; /* implementation dependent */
5088 break;
5089 case 23:
5090 switch (sel) {
5091 case 0:
5092 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5093 /* BS_STOP isn't good enough here, hflags may have changed. */
5094 gen_save_pc(ctx->pc + 4);
5095 ctx->bstate = BS_EXCP;
5096 rn = "Debug";
5097 break;
5098 case 1:
5099 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5100 rn = "TraceControl";
5101 /* Stop translation as we may have switched the execution mode */
5102 ctx->bstate = BS_STOP;
5103 // break;
5104 case 2:
5105 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5106 rn = "TraceControl2";
5107 /* Stop translation as we may have switched the execution mode */
5108 ctx->bstate = BS_STOP;
5109 // break;
5110 case 3:
5111 /* Stop translation as we may have switched the execution mode */
5112 ctx->bstate = BS_STOP;
5113 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5114 rn = "UserTraceData";
5115 /* Stop translation as we may have switched the execution mode */
5116 ctx->bstate = BS_STOP;
5117 // break;
5118 case 4:
5119 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5120 /* Stop translation as we may have switched the execution mode */
5121 ctx->bstate = BS_STOP;
5122 rn = "TraceBPC";
5123 // break;
5124 default:
5125 goto die;
5126 }
5127 break;
5128 case 24:
5129 switch (sel) {
5130 case 0:
5131 /* EJTAG support */
5132 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5133 rn = "DEPC";
5134 break;
5135 default:
5136 goto die;
5137 }
5138 break;
5139 case 25:
5140 switch (sel) {
5141 case 0:
5142 gen_helper_mtc0_performance0(cpu_env, arg);
5143 rn = "Performance0";
5144 break;
5145 case 1:
5146 // gen_helper_mtc0_performance1(arg);
5147 rn = "Performance1";
5148 // break;
5149 case 2:
5150 // gen_helper_mtc0_performance2(arg);
5151 rn = "Performance2";
5152 // break;
5153 case 3:
5154 // gen_helper_mtc0_performance3(arg);
5155 rn = "Performance3";
5156 // break;
5157 case 4:
5158 // gen_helper_mtc0_performance4(arg);
5159 rn = "Performance4";
5160 // break;
5161 case 5:
5162 // gen_helper_mtc0_performance5(arg);
5163 rn = "Performance5";
5164 // break;
5165 case 6:
5166 // gen_helper_mtc0_performance6(arg);
5167 rn = "Performance6";
5168 // break;
5169 case 7:
5170 // gen_helper_mtc0_performance7(arg);
5171 rn = "Performance7";
5172 // break;
5173 default:
5174 goto die;
5175 }
5176 break;
5177 case 26:
5178 /* ignored */
5179 rn = "ECC";
5180 break;
5181 case 27:
5182 switch (sel) {
5183 case 0 ... 3:
5184 /* ignored */
5185 rn = "CacheErr";
5186 break;
5187 default:
5188 goto die;
5189 }
5190 break;
5191 case 28:
5192 switch (sel) {
5193 case 0:
5194 case 2:
5195 case 4:
5196 case 6:
5197 gen_helper_mtc0_taglo(cpu_env, arg);
5198 rn = "TagLo";
5199 break;
5200 case 1:
5201 case 3:
5202 case 5:
5203 case 7:
5204 gen_helper_mtc0_datalo(cpu_env, arg);
5205 rn = "DataLo";
5206 break;
5207 default:
5208 goto die;
5209 }
5210 break;
5211 case 29:
5212 switch (sel) {
5213 case 0:
5214 case 2:
5215 case 4:
5216 case 6:
5217 gen_helper_mtc0_taghi(cpu_env, arg);
5218 rn = "TagHi";
5219 break;
5220 case 1:
5221 case 3:
5222 case 5:
5223 case 7:
5224 gen_helper_mtc0_datahi(cpu_env, arg);
5225 rn = "DataHi";
5226 break;
5227 default:
5228 rn = "invalid sel";
5229 goto die;
5230 }
5231 break;
5232 case 30:
5233 switch (sel) {
5234 case 0:
5235 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5236 rn = "ErrorEPC";
5237 break;
5238 default:
5239 goto die;
5240 }
5241 break;
5242 case 31:
5243 switch (sel) {
5244 case 0:
5245 /* EJTAG support */
5246 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5247 rn = "DESAVE";
5248 break;
5249 default:
5250 goto die;
5251 }
5252 /* Stop translation as we may have switched the execution mode */
5253 ctx->bstate = BS_STOP;
5254 break;
5255 default:
5256 goto die;
5257 }
5258 (void)rn; /* avoid a compiler warning */
5259 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5260 /* For simplicity assume that all writes can cause interrupts. */
5261 if (use_icount) {
5262 gen_io_end();
5263 ctx->bstate = BS_STOP;
5264 }
5265 return;
5266
5267 die:
5268 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5269 generate_exception(ctx, EXCP_RI);
5270 }
5271
5272 #if defined(TARGET_MIPS64)
5273 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5274 {
5275 const char *rn = "invalid";
5276
5277 if (sel != 0)
5278 check_insn(env, ctx, ISA_MIPS64);
5279
5280 switch (reg) {
5281 case 0:
5282 switch (sel) {
5283 case 0:
5284 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5285 rn = "Index";
5286 break;
5287 case 1:
5288 check_insn(env, ctx, ASE_MT);
5289 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5290 rn = "MVPControl";
5291 break;
5292 case 2:
5293 check_insn(env, ctx, ASE_MT);
5294 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5295 rn = "MVPConf0";
5296 break;
5297 case 3:
5298 check_insn(env, ctx, ASE_MT);
5299 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5300 rn = "MVPConf1";
5301 break;
5302 default:
5303 goto die;
5304 }
5305 break;
5306 case 1:
5307 switch (sel) {
5308 case 0:
5309 gen_helper_mfc0_random(arg, cpu_env);
5310 rn = "Random";
5311 break;
5312 case 1:
5313 check_insn(env, ctx, ASE_MT);
5314 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5315 rn = "VPEControl";
5316 break;
5317 case 2:
5318 check_insn(env, ctx, ASE_MT);
5319 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5320 rn = "VPEConf0";
5321 break;
5322 case 3:
5323 check_insn(env, ctx, ASE_MT);
5324 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5325 rn = "VPEConf1";
5326 break;
5327 case 4:
5328 check_insn(env, ctx, ASE_MT);
5329 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5330 rn = "YQMask";
5331 break;
5332 case 5:
5333 check_insn(env, ctx, ASE_MT);
5334 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5335 rn = "VPESchedule";
5336 break;
5337 case 6:
5338 check_insn(env, ctx, ASE_MT);
5339 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5340 rn = "VPEScheFBack";
5341 break;
5342 case 7:
5343 check_insn(env, ctx, ASE_MT);
5344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5345 rn = "VPEOpt";
5346 break;
5347 default:
5348 goto die;
5349 }
5350 break;
5351 case 2:
5352 switch (sel) {
5353 case 0:
5354 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5355 rn = "EntryLo0";
5356 break;
5357 case 1:
5358 check_insn(env, ctx, ASE_MT);
5359 gen_helper_mfc0_tcstatus(arg, cpu_env);
5360 rn = "TCStatus";
5361 break;
5362 case 2:
5363 check_insn(env, ctx, ASE_MT);
5364 gen_helper_mfc0_tcbind(arg, cpu_env);
5365 rn = "TCBind";
5366 break;
5367 case 3:
5368 check_insn(env, ctx, ASE_MT);
5369 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5370 rn = "TCRestart";
5371 break;
5372 case 4:
5373 check_insn(env, ctx, ASE_MT);
5374 gen_helper_dmfc0_tchalt(arg, cpu_env);
5375 rn = "TCHalt";
5376 break;
5377 case 5:
5378 check_insn(env, ctx, ASE_MT);
5379 gen_helper_dmfc0_tccontext(arg, cpu_env);
5380 rn = "TCContext";
5381 break;
5382 case 6:
5383 check_insn(env, ctx, ASE_MT);
5384 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5385 rn = "TCSchedule";
5386 break;
5387 case 7:
5388 check_insn(env, ctx, ASE_MT);
5389 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5390 rn = "TCScheFBack";
5391 break;
5392 default:
5393 goto die;
5394 }
5395 break;
5396 case 3:
5397 switch (sel) {
5398 case 0:
5399 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5400 rn = "EntryLo1";
5401 break;
5402 default:
5403 goto die;
5404 }
5405 break;
5406 case 4:
5407 switch (sel) {
5408 case 0:
5409 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5410 rn = "Context";
5411 break;
5412 case 1:
5413 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5414 rn = "ContextConfig";
5415 // break;
5416 default:
5417 goto die;
5418 }
5419 break;
5420 case 5:
5421 switch (sel) {
5422 case 0:
5423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5424 rn = "PageMask";
5425 break;
5426 case 1:
5427 check_insn(env, ctx, ISA_MIPS32R2);
5428 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5429 rn = "PageGrain";
5430 break;
5431 default:
5432 goto die;
5433 }
5434 break;
5435 case 6:
5436 switch (sel) {
5437 case 0:
5438 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5439 rn = "Wired";
5440 break;
5441 case 1:
5442 check_insn(env, ctx, ISA_MIPS32R2);
5443 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5444 rn = "SRSConf0";
5445 break;
5446 case 2:
5447 check_insn(env, ctx, ISA_MIPS32R2);
5448 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5449 rn = "SRSConf1";
5450 break;
5451 case 3:
5452 check_insn(env, ctx, ISA_MIPS32R2);
5453 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5454 rn = "SRSConf2";
5455 break;
5456 case 4:
5457 check_insn(env, ctx, ISA_MIPS32R2);
5458 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5459 rn = "SRSConf3";
5460 break;
5461 case 5:
5462 check_insn(env, ctx, ISA_MIPS32R2);
5463 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5464 rn = "SRSConf4";
5465 break;
5466 default:
5467 goto die;
5468 }
5469 break;
5470 case 7:
5471 switch (sel) {
5472 case 0:
5473 check_insn(env, ctx, ISA_MIPS32R2);
5474 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5475 rn = "HWREna";
5476 break;
5477 default:
5478 goto die;
5479 }
5480 break;
5481 case 8:
5482 switch (sel) {
5483 case 0:
5484 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5485 rn = "BadVAddr";
5486 break;
5487 default:
5488 goto die;
5489 }
5490 break;
5491 case 9:
5492 switch (sel) {
5493 case 0:
5494 /* Mark as an IO operation because we read the time. */
5495 if (use_icount)
5496 gen_io_start();
5497 gen_helper_mfc0_count(arg, cpu_env);
5498 if (use_icount) {
5499 gen_io_end();
5500 }
5501 /* Break the TB to be able to take timer interrupts immediately
5502 after reading count. */
5503 ctx->bstate = BS_STOP;
5504 rn = "Count";
5505 break;
5506 /* 6,7 are implementation dependent */
5507 default:
5508 goto die;
5509 }
5510 break;
5511 case 10:
5512 switch (sel) {
5513 case 0:
5514 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5515 rn = "EntryHi";
5516 break;
5517 default:
5518 goto die;
5519 }
5520 break;
5521 case 11:
5522 switch (sel) {
5523 case 0:
5524 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5525 rn = "Compare";
5526 break;
5527 /* 6,7 are implementation dependent */
5528 default:
5529 goto die;
5530 }
5531 break;
5532 case 12:
5533 switch (sel) {
5534 case 0:
5535 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5536 rn = "Status";
5537 break;
5538 case 1:
5539 check_insn(env, ctx, ISA_MIPS32R2);
5540 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5541 rn = "IntCtl";
5542 break;
5543 case 2:
5544 check_insn(env, ctx, ISA_MIPS32R2);
5545 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5546 rn = "SRSCtl";
5547 break;
5548 case 3:
5549 check_insn(env, ctx, ISA_MIPS32R2);
5550 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5551 rn = "SRSMap";
5552 break;
5553 default:
5554 goto die;
5555 }
5556 break;
5557 case 13:
5558 switch (sel) {
5559 case 0:
5560 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5561 rn = "Cause";
5562 break;
5563 default:
5564 goto die;
5565 }
5566 break;
5567 case 14:
5568 switch (sel) {
5569 case 0:
5570 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5571 rn = "EPC";
5572 break;
5573 default:
5574 goto die;
5575 }
5576 break;
5577 case 15:
5578 switch (sel) {
5579 case 0:
5580 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5581 rn = "PRid";
5582 break;
5583 case 1:
5584 check_insn(env, ctx, ISA_MIPS32R2);
5585 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5586 rn = "EBase";
5587 break;
5588 default:
5589 goto die;
5590 }
5591 break;
5592 case 16:
5593 switch (sel) {
5594 case 0:
5595 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5596 rn = "Config";
5597 break;
5598 case 1:
5599 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5600 rn = "Config1";
5601 break;
5602 case 2:
5603 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5604 rn = "Config2";
5605 break;
5606 case 3:
5607 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5608 rn = "Config3";
5609 break;
5610 /* 6,7 are implementation dependent */
5611 case 6:
5612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5613 rn = "Config6";
5614 break;
5615 case 7:
5616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5617 rn = "Config7";
5618 break;
5619 default:
5620 goto die;
5621 }
5622 break;
5623 case 17:
5624 switch (sel) {
5625 case 0:
5626 gen_helper_dmfc0_lladdr(arg, cpu_env);
5627 rn = "LLAddr";
5628 break;
5629 default:
5630 goto die;
5631 }
5632 break;
5633 case 18:
5634 switch (sel) {
5635 case 0 ... 7:
5636 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5637 rn = "WatchLo";
5638 break;
5639 default:
5640 goto die;
5641 }
5642 break;
5643 case 19:
5644 switch (sel) {
5645 case 0 ... 7:
5646 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5647 rn = "WatchHi";
5648 break;
5649 default:
5650 goto die;
5651 }
5652 break;
5653 case 20:
5654 switch (sel) {
5655 case 0:
5656 check_insn(env, ctx, ISA_MIPS3);
5657 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5658 rn = "XContext";
5659 break;
5660 default:
5661 goto die;
5662 }
5663 break;
5664 case 21:
5665 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5666 switch (sel) {
5667 case 0:
5668 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5669 rn = "Framemask";
5670 break;
5671 default:
5672 goto die;
5673 }
5674 break;
5675 case 22:
5676 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5677 rn = "'Diagnostic"; /* implementation dependent */
5678 break;
5679 case 23:
5680 switch (sel) {
5681 case 0:
5682 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5683 rn = "Debug";
5684 break;
5685 case 1:
5686 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5687 rn = "TraceControl";
5688 // break;
5689 case 2:
5690 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5691 rn = "TraceControl2";
5692 // break;
5693 case 3:
5694 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5695 rn = "UserTraceData";
5696 // break;
5697 case 4:
5698 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5699 rn = "TraceBPC";
5700 // break;
5701 default:
5702 goto die;
5703 }
5704 break;
5705 case 24:
5706 switch (sel) {
5707 case 0:
5708 /* EJTAG support */
5709 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5710 rn = "DEPC";
5711 break;
5712 default:
5713 goto die;
5714 }
5715 break;
5716 case 25:
5717 switch (sel) {
5718 case 0:
5719 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5720 rn = "Performance0";
5721 break;
5722 case 1:
5723 // gen_helper_dmfc0_performance1(arg);
5724 rn = "Performance1";
5725 // break;
5726 case 2:
5727 // gen_helper_dmfc0_performance2(arg);
5728 rn = "Performance2";
5729 // break;
5730 case 3:
5731 // gen_helper_dmfc0_performance3(arg);
5732 rn = "Performance3";
5733 // break;
5734 case 4:
5735 // gen_helper_dmfc0_performance4(arg);
5736 rn = "Performance4";
5737 // break;
5738 case 5:
5739 // gen_helper_dmfc0_performance5(arg);
5740 rn = "Performance5";
5741 // break;
5742 case 6:
5743 // gen_helper_dmfc0_performance6(arg);
5744 rn = "Performance6";
5745 // break;
5746 case 7:
5747 // gen_helper_dmfc0_performance7(arg);
5748 rn = "Performance7";
5749 // break;
5750 default:
5751 goto die;
5752 }
5753 break;
5754 case 26:
5755 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5756 rn = "ECC";
5757 break;
5758 case 27:
5759 switch (sel) {
5760 /* ignored */
5761 case 0 ... 3:
5762 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5763 rn = "CacheErr";
5764 break;
5765 default:
5766 goto die;
5767 }
5768 break;
5769 case 28:
5770 switch (sel) {
5771 case 0:
5772 case 2:
5773 case 4:
5774 case 6:
5775 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5776 rn = "TagLo";
5777 break;
5778 case 1:
5779 case 3:
5780 case 5:
5781 case 7:
5782 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5783 rn = "DataLo";
5784 break;
5785 default:
5786 goto die;
5787 }
5788 break;
5789 case 29:
5790 switch (sel) {
5791 case 0:
5792 case 2:
5793 case 4:
5794 case 6:
5795 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5796 rn = "TagHi";
5797 break;
5798 case 1:
5799 case 3:
5800 case 5:
5801 case 7:
5802 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5803 rn = "DataHi";
5804 break;
5805 default:
5806 goto die;
5807 }
5808 break;
5809 case 30:
5810 switch (sel) {
5811 case 0:
5812 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5813 rn = "ErrorEPC";
5814 break;
5815 default:
5816 goto die;
5817 }
5818 break;
5819 case 31:
5820 switch (sel) {
5821 case 0:
5822 /* EJTAG support */
5823 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5824 rn = "DESAVE";
5825 break;
5826 default:
5827 goto die;
5828 }
5829 break;
5830 default:
5831 goto die;
5832 }
5833 (void)rn; /* avoid a compiler warning */
5834 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5835 return;
5836
5837 die:
5838 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5839 generate_exception(ctx, EXCP_RI);
5840 }
5841
5842 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5843 {
5844 const char *rn = "invalid";
5845
5846 if (sel != 0)
5847 check_insn(env, ctx, ISA_MIPS64);
5848
5849 if (use_icount)
5850 gen_io_start();
5851
5852 switch (reg) {
5853 case 0:
5854 switch (sel) {
5855 case 0:
5856 gen_helper_mtc0_index(cpu_env, arg);
5857 rn = "Index";
5858 break;
5859 case 1:
5860 check_insn(env, ctx, ASE_MT);
5861 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5862 rn = "MVPControl";
5863 break;
5864 case 2:
5865 check_insn(env, ctx, ASE_MT);
5866 /* ignored */
5867 rn = "MVPConf0";
5868 break;
5869 case 3:
5870 check_insn(env, ctx, ASE_MT);
5871 /* ignored */
5872 rn = "MVPConf1";
5873 break;
5874 default:
5875 goto die;
5876 }
5877 break;
5878 case 1:
5879 switch (sel) {
5880 case 0:
5881 /* ignored */
5882 rn = "Random";
5883 break;
5884 case 1:
5885 check_insn(env, ctx, ASE_MT);
5886 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5887 rn = "VPEControl";
5888 break;
5889 case 2:
5890 check_insn(env, ctx, ASE_MT);
5891 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5892 rn = "VPEConf0";
5893 break;
5894 case 3:
5895 check_insn(env, ctx, ASE_MT);
5896 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5897 rn = "VPEConf1";
5898 break;
5899 case 4:
5900 check_insn(env, ctx, ASE_MT);
5901 gen_helper_mtc0_yqmask(cpu_env, arg);
5902 rn = "YQMask";
5903 break;
5904 case 5:
5905 check_insn(env, ctx, ASE_MT);
5906 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5907 rn = "VPESchedule";
5908 break;
5909 case 6:
5910 check_insn(env, ctx, ASE_MT);
5911 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5912 rn = "VPEScheFBack";
5913 break;
5914 case 7:
5915 check_insn(env, ctx, ASE_MT);
5916 gen_helper_mtc0_vpeopt(cpu_env, arg);
5917 rn = "VPEOpt";
5918 break;
5919 default:
5920 goto die;
5921 }
5922 break;
5923 case 2:
5924 switch (sel) {
5925 case 0:
5926 gen_helper_mtc0_entrylo0(cpu_env, arg);
5927 rn = "EntryLo0";
5928 break;
5929 case 1:
5930 check_insn(env, ctx, ASE_MT);
5931 gen_helper_mtc0_tcstatus(cpu_env, arg);
5932 rn = "TCStatus";
5933 break;
5934 case 2:
5935 check_insn(env, ctx, ASE_MT);
5936 gen_helper_mtc0_tcbind(cpu_env, arg);
5937 rn = "TCBind";
5938 break;
5939 case 3:
5940 check_insn(env, ctx, ASE_MT);
5941 gen_helper_mtc0_tcrestart(cpu_env, arg);
5942 rn = "TCRestart";
5943 break;
5944 case 4:
5945 check_insn(env, ctx, ASE_MT);
5946 gen_helper_mtc0_tchalt(cpu_env, arg);
5947 rn = "TCHalt";
5948 break;
5949 case 5:
5950 check_insn(env, ctx, ASE_MT);
5951 gen_helper_mtc0_tccontext(cpu_env, arg);
5952 rn = "TCContext";
5953 break;
5954 case 6:
5955 check_insn(env, ctx, ASE_MT);
5956 gen_helper_mtc0_tcschedule(cpu_env, arg);
5957 rn = "TCSchedule";
5958 break;
5959 case 7:
5960 check_insn(env, ctx, ASE_MT);
5961 gen_helper_mtc0_tcschefback(cpu_env, arg);
5962 rn = "TCScheFBack";
5963 break;
5964 default:
5965 goto die;
5966 }
5967 break;
5968 case 3:
5969 switch (sel) {
5970 case 0:
5971 gen_helper_mtc0_entrylo1(cpu_env, arg);
5972 rn = "EntryLo1";
5973 break;
5974 default:
5975 goto die;
5976 }
5977 break;
5978 case 4:
5979 switch (sel) {
5980 case 0:
5981 gen_helper_mtc0_context(cpu_env, arg);
5982 rn = "Context";
5983 break;
5984 case 1:
5985 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5986 rn = "ContextConfig";
5987 // break;
5988 default:
5989 goto die;
5990 }
5991 break;
5992 case 5:
5993 switch (sel) {
5994 case 0:
5995 gen_helper_mtc0_pagemask(cpu_env, arg);
5996 rn = "PageMask";
5997 break;
5998 case 1:
5999 check_insn(env, ctx, ISA_MIPS32R2);
6000 gen_helper_mtc0_pagegrain(cpu_env, arg);
6001 rn = "PageGrain";
6002 break;
6003 default:
6004 goto die;
6005 }
6006 break;
6007 case 6:
6008 switch (sel) {
6009 case 0:
6010 gen_helper_mtc0_wired(cpu_env, arg);
6011 rn = "Wired";
6012 break;
6013 case 1:
6014 check_insn(env, ctx, ISA_MIPS32R2);
6015 gen_helper_mtc0_srsconf0(cpu_env, arg);
6016 rn = "SRSConf0";
6017 break;
6018 case 2:
6019 check_insn(env, ctx, ISA_MIPS32R2);
6020 gen_helper_mtc0_srsconf1(cpu_env, arg);
6021 rn = "SRSConf1";
6022 break;
6023 case 3:
6024 check_insn(env, ctx, ISA_MIPS32R2);
6025 gen_helper_mtc0_srsconf2(cpu_env, arg);
6026 rn = "SRSConf2";
6027 break;
6028 case 4:
6029 check_insn(env, ctx, ISA_MIPS32R2);
6030 gen_helper_mtc0_srsconf3(cpu_env, arg);
6031 rn = "SRSConf3";
6032 break;
6033 case 5:
6034 check_insn(env, ctx, ISA_MIPS32R2);
6035 gen_helper_mtc0_srsconf4(cpu_env, arg);
6036 rn = "SRSConf4";
6037 break;
6038 default:
6039 goto die;
6040 }
6041 break;
6042 case 7:
6043 switch (sel) {
6044 case 0:
6045 check_insn(env, ctx, ISA_MIPS32R2);
6046 gen_helper_mtc0_hwrena(cpu_env, arg);
6047 rn = "HWREna";
6048 break;
6049 default:
6050 goto die;
6051 }
6052 break;
6053 case 8:
6054 /* ignored */
6055 rn = "BadVAddr";
6056 break;
6057 case 9:
6058 switch (sel) {
6059 case 0:
6060 gen_helper_mtc0_count(cpu_env, arg);
6061 rn = "Count";
6062 break;
6063 /* 6,7 are implementation dependent */
6064 default:
6065 goto die;
6066 }
6067 /* Stop translation as we may have switched the execution mode */
6068 ctx->bstate = BS_STOP;
6069 break;
6070 case 10:
6071 switch (sel) {
6072 case 0:
6073 gen_helper_mtc0_entryhi(cpu_env, arg);
6074 rn = "EntryHi";
6075 break;
6076 default:
6077 goto die;
6078 }
6079 break;
6080 case 11:
6081 switch (sel) {
6082 case 0:
6083 gen_helper_mtc0_compare(cpu_env, arg);
6084 rn = "Compare";
6085 break;
6086 /* 6,7 are implementation dependent */
6087 default:
6088 goto die;
6089 }
6090 /* Stop translation as we may have switched the execution mode */
6091 ctx->bstate = BS_STOP;
6092 break;
6093 case 12:
6094 switch (sel) {
6095 case 0:
6096 save_cpu_state(ctx, 1);
6097 gen_helper_mtc0_status(cpu_env, arg);
6098 /* BS_STOP isn't good enough here, hflags may have changed. */
6099 gen_save_pc(ctx->pc + 4);
6100 ctx->bstate = BS_EXCP;
6101 rn = "Status";
6102 break;
6103 case 1:
6104 check_insn(env, ctx, ISA_MIPS32R2);
6105 gen_helper_mtc0_intctl(cpu_env, arg);
6106 /* Stop translation as we may have switched the execution mode */
6107 ctx->bstate = BS_STOP;
6108 rn = "IntCtl";
6109 break;
6110 case 2:
6111 check_insn(env, ctx, ISA_MIPS32R2);
6112 gen_helper_mtc0_srsctl(cpu_env, arg);
6113 /* Stop translation as we may have switched the execution mode */
6114 ctx->bstate = BS_STOP;
6115 rn = "SRSCtl";
6116 break;
6117 case 3:
6118 check_insn(env, ctx, ISA_MIPS32R2);
6119 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6120 /* Stop translation as we may have switched the execution mode */
6121 ctx->bstate = BS_STOP;
6122 rn = "SRSMap";
6123 break;
6124 default:
6125 goto die;
6126 }
6127 break;
6128 case 13:
6129 switch (sel) {
6130 case 0:
6131 save_cpu_state(ctx, 1);
6132 /* Mark as an IO operation because we may trigger a software
6133 interrupt. */
6134 if (use_icount) {
6135 gen_io_start();
6136 }
6137 gen_helper_mtc0_cause(cpu_env, arg);
6138 if (use_icount) {
6139 gen_io_end();
6140 }
6141 /* Stop translation as we may have triggered an intetrupt */
6142 ctx->bstate = BS_STOP;
6143 rn = "Cause";
6144 break;
6145 default:
6146 goto die;
6147 }
6148 break;
6149 case 14:
6150 switch (sel) {
6151 case 0:
6152 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6153 rn = "EPC";
6154 break;
6155 default:
6156 goto die;
6157 }
6158 break;
6159 case 15:
6160 switch (sel) {
6161 case 0:
6162 /* ignored */
6163 rn = "PRid";
6164 break;
6165 case 1:
6166 check_insn(env, ctx, ISA_MIPS32R2);
6167 gen_helper_mtc0_ebase(cpu_env, arg);
6168 rn = "EBase";
6169 break;
6170 default:
6171 goto die;
6172 }
6173 break;
6174 case 16:
6175 switch (sel) {
6176 case 0:
6177 gen_helper_mtc0_config0(cpu_env, arg);
6178 rn = "Config";
6179 /* Stop translation as we may have switched the execution mode */
6180 ctx->bstate = BS_STOP;
6181 break;
6182 case 1:
6183 /* ignored, read only */
6184 rn = "Config1";
6185 break;
6186 case 2:
6187 gen_helper_mtc0_config2(cpu_env, arg);
6188 rn = "Config2";
6189 /* Stop translation as we may have switched the execution mode */
6190 ctx->bstate = BS_STOP;
6191 break;
6192 case 3:
6193 /* ignored */
6194 rn = "Config3";
6195 break;
6196 /* 6,7 are implementation dependent */
6197 default:
6198 rn = "Invalid config selector";
6199 goto die;
6200 }
6201 break;
6202 case 17:
6203 switch (sel) {
6204 case 0:
6205 gen_helper_mtc0_lladdr(cpu_env, arg);
6206 rn = "LLAddr";
6207 break;
6208 default:
6209 goto die;
6210 }
6211 break;
6212 case 18:
6213 switch (sel) {
6214 case 0 ... 7:
6215 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6216 rn = "WatchLo";
6217 break;
6218 default:
6219 goto die;
6220 }
6221 break;
6222 case 19:
6223 switch (sel) {
6224 case 0 ... 7:
6225 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6226 rn = "WatchHi";
6227 break;
6228 default:
6229 goto die;
6230 }
6231 break;
6232 case 20:
6233 switch (sel) {
6234 case 0:
6235 check_insn(env, ctx, ISA_MIPS3);
6236 gen_helper_mtc0_xcontext(cpu_env, arg);
6237 rn = "XContext";
6238 break;
6239 default:
6240 goto die;
6241 }
6242 break;
6243 case 21:
6244 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6245 switch (sel) {
6246 case 0:
6247 gen_helper_mtc0_framemask(cpu_env, arg);
6248 rn = "Framemask";
6249 break;
6250 default:
6251 goto die;
6252 }
6253 break;
6254 case 22:
6255 /* ignored */
6256 rn = "Diagnostic"; /* implementation dependent */
6257 break;
6258 case 23:
6259 switch (sel) {
6260 case 0:
6261 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6262 /* BS_STOP isn't good enough here, hflags may have changed. */
6263 gen_save_pc(ctx->pc + 4);
6264 ctx->bstate = BS_EXCP;
6265 rn = "Debug";
6266 break;
6267 case 1:
6268 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6269 /* Stop translation as we may have switched the execution mode */
6270 ctx->bstate = BS_STOP;
6271 rn = "TraceControl";
6272 // break;
6273 case 2:
6274 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6275 /* Stop translation as we may have switched the execution mode */
6276 ctx->bstate = BS_STOP;
6277 rn = "TraceControl2";
6278 // break;
6279 case 3:
6280 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6281 /* Stop translation as we may have switched the execution mode */
6282 ctx->bstate = BS_STOP;
6283 rn = "UserTraceData";
6284 // break;
6285 case 4:
6286 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6287 /* Stop translation as we may have switched the execution mode */
6288 ctx->bstate = BS_STOP;
6289 rn = "TraceBPC";
6290 // break;
6291 default:
6292 goto die;
6293 }
6294 break;
6295 case 24:
6296 switch (sel) {
6297 case 0:
6298 /* EJTAG support */
6299 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6300 rn = "DEPC";
6301 break;
6302 default:
6303 goto die;
6304 }
6305 break;
6306 case 25:
6307 switch (sel) {
6308 case 0:
6309 gen_helper_mtc0_performance0(cpu_env, arg);
6310 rn = "Performance0";
6311 break;
6312 case 1:
6313 // gen_helper_mtc0_performance1(cpu_env, arg);
6314 rn = "Performance1";
6315 // break;
6316 case 2:
6317 // gen_helper_mtc0_performance2(cpu_env, arg);
6318 rn = "Performance2";
6319 // break;
6320 case 3:
6321 // gen_helper_mtc0_performance3(cpu_env, arg);
6322 rn = "Performance3";
6323 // break;
6324 case 4:
6325 // gen_helper_mtc0_performance4(cpu_env, arg);
6326 rn = "Performance4";
6327 // break;
6328 case 5:
6329 // gen_helper_mtc0_performance5(cpu_env, arg);
6330 rn = "Performance5";
6331 // break;
6332 case 6:
6333 // gen_helper_mtc0_performance6(cpu_env, arg);
6334 rn = "Performance6";
6335 // break;
6336 case 7:
6337 // gen_helper_mtc0_performance7(cpu_env, arg);
6338 rn = "Performance7";
6339 // break;
6340 default:
6341 goto die;
6342 }
6343 break;
6344 case 26:
6345 /* ignored */
6346 rn = "ECC";
6347 break;
6348 case 27:
6349 switch (sel) {
6350 case 0 ... 3:
6351 /* ignored */
6352 rn = "CacheErr";
6353 break;
6354 default:
6355 goto die;
6356 }
6357 break;
6358 case 28:
6359 switch (sel) {
6360 case 0:
6361 case 2:
6362 case 4:
6363 case 6:
6364 gen_helper_mtc0_taglo(cpu_env, arg);
6365 rn = "TagLo";
6366 break;
6367 case 1:
6368 case 3:
6369 case 5:
6370 case 7:
6371 gen_helper_mtc0_datalo(cpu_env, arg);
6372 rn = "DataLo";
6373 break;
6374 default:
6375 goto die;
6376 }
6377 break;
6378 case 29:
6379 switch (sel) {
6380 case 0:
6381 case 2:
6382 case 4:
6383 case 6:
6384 gen_helper_mtc0_taghi(cpu_env, arg);
6385 rn = "TagHi";
6386 break;
6387 case 1:
6388 case 3:
6389 case 5:
6390 case 7:
6391 gen_helper_mtc0_datahi(cpu_env, arg);
6392 rn = "DataHi";
6393 break;
6394 default:
6395 rn = "invalid sel";
6396 goto die;
6397 }
6398 break;
6399 case 30:
6400 switch (sel) {
6401 case 0:
6402 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6403 rn = "ErrorEPC";
6404 break;
6405 default:
6406 goto die;
6407 }
6408 break;
6409 case 31:
6410 switch (sel) {
6411 case 0:
6412 /* EJTAG support */
6413 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6414 rn = "DESAVE";
6415 break;
6416 default:
6417 goto die;
6418 }
6419 /* Stop translation as we may have switched the execution mode */
6420 ctx->bstate = BS_STOP;
6421 break;
6422 default:
6423 goto die;
6424 }
6425 (void)rn; /* avoid a compiler warning */
6426 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6427 /* For simplicity assume that all writes can cause interrupts. */
6428 if (use_icount) {
6429 gen_io_end();
6430 ctx->bstate = BS_STOP;
6431 }
6432 return;
6433
6434 die:
6435 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6436 generate_exception(ctx, EXCP_RI);
6437 }
6438 #endif /* TARGET_MIPS64 */
6439
6440 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6441 int u, int sel, int h)
6442 {
6443 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6444 TCGv t0 = tcg_temp_local_new();
6445
6446 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6447 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6448 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6449 tcg_gen_movi_tl(t0, -1);
6450 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6451 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6452 tcg_gen_movi_tl(t0, -1);
6453 else if (u == 0) {
6454 switch (rt) {
6455 case 1:
6456 switch (sel) {
6457 case 1:
6458 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6459 break;
6460 case 2:
6461 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6462 break;
6463 default:
6464 goto die;
6465 break;
6466 }
6467 break;
6468 case 2:
6469 switch (sel) {
6470 case 1:
6471 gen_helper_mftc0_tcstatus(t0, cpu_env);
6472 break;
6473 case 2:
6474 gen_helper_mftc0_tcbind(t0, cpu_env);
6475 break;
6476 case 3:
6477 gen_helper_mftc0_tcrestart(t0, cpu_env);
6478 break;
6479 case 4:
6480 gen_helper_mftc0_tchalt(t0, cpu_env);
6481 break;
6482 case 5:
6483 gen_helper_mftc0_tccontext(t0, cpu_env);
6484 break;
6485 case 6:
6486 gen_helper_mftc0_tcschedule(t0, cpu_env);
6487 break;
6488 case 7:
6489 gen_helper_mftc0_tcschefback(t0, cpu_env);
6490 break;
6491 default:
6492 gen_mfc0(env, ctx, t0, rt, sel);
6493 break;
6494 }
6495 break;
6496 case 10:
6497 switch (sel) {
6498 case 0:
6499 gen_helper_mftc0_entryhi(t0, cpu_env);
6500 break;
6501 default:
6502 gen_mfc0(env, ctx, t0, rt, sel);
6503 break;
6504 }
6505 case 12:
6506 switch (sel) {
6507 case 0:
6508 gen_helper_mftc0_status(t0, cpu_env);
6509 break;
6510 default:
6511 gen_mfc0(env, ctx, t0, rt, sel);
6512 break;
6513 }
6514 case 13:
6515 switch (sel) {
6516 case 0:
6517 gen_helper_mftc0_cause(t0, cpu_env);
6518 break;
6519 default:
6520 goto die;
6521 break;
6522 }
6523 break;
6524 case 14:
6525 switch (sel) {
6526 case 0:
6527 gen_helper_mftc0_epc(t0, cpu_env);
6528 break;
6529 default:
6530 goto die;
6531 break;
6532 }
6533 break;
6534 case 15:
6535 switch (sel) {
6536 case 1:
6537 gen_helper_mftc0_ebase(t0, cpu_env);
6538 break;
6539 default:
6540 goto die;
6541 break;
6542 }
6543 break;
6544 case 16:
6545 switch (sel) {
6546 case 0 ... 7:
6547 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6548 break;
6549 default:
6550 goto die;
6551 break;
6552 }
6553 break;
6554 case 23:
6555 switch (sel) {
6556 case 0:
6557 gen_helper_mftc0_debug(t0, cpu_env);
6558 break;
6559 default:
6560 gen_mfc0(env, ctx, t0, rt, sel);
6561 break;
6562 }
6563 break;
6564 default:
6565 gen_mfc0(env, ctx, t0, rt, sel);
6566 }
6567 } else switch (sel) {
6568 /* GPR registers. */
6569 case 0:
6570 gen_helper_1e0i(mftgpr, t0, rt);
6571 break;
6572 /* Auxiliary CPU registers */
6573 case 1:
6574 switch (rt) {
6575 case 0:
6576 gen_helper_1e0i(mftlo, t0, 0);
6577 break;
6578 case 1:
6579 gen_helper_1e0i(mfthi, t0, 0);
6580 break;
6581 case 2:
6582 gen_helper_1e0i(mftacx, t0, 0);
6583 break;
6584 case 4:
6585 gen_helper_1e0i(mftlo, t0, 1);
6586 break;
6587 case 5:
6588 gen_helper_1e0i(mfthi, t0, 1);
6589 break;
6590 case 6:
6591 gen_helper_1e0i(mftacx, t0, 1);
6592 break;
6593 case 8:
6594 gen_helper_1e0i(mftlo, t0, 2);
6595 break;
6596 case 9:
6597 gen_helper_1e0i(mfthi, t0, 2);
6598 break;
6599 case 10:
6600 gen_helper_1e0i(mftacx, t0, 2);
6601 break;
6602 case 12:
6603 gen_helper_1e0i(mftlo, t0, 3);
6604 break;
6605 case 13:
6606 gen_helper_1e0i(mfthi, t0, 3);
6607 break;
6608 case 14:
6609 gen_helper_1e0i(mftacx, t0, 3);
6610 break;
6611 case 16:
6612 gen_helper_mftdsp(t0, cpu_env);
6613 break;
6614 default:
6615 goto die;
6616 }
6617 break;
6618 /* Floating point (COP1). */
6619 case 2:
6620 /* XXX: For now we support only a single FPU context. */
6621 if (h == 0) {
6622 TCGv_i32 fp0 = tcg_temp_new_i32();
6623
6624 gen_load_fpr32(fp0, rt);
6625 tcg_gen_ext_i32_tl(t0, fp0);
6626 tcg_temp_free_i32(fp0);
6627 } else {
6628 TCGv_i32 fp0 = tcg_temp_new_i32();
6629
6630 gen_load_fpr32h(fp0, rt);
6631 tcg_gen_ext_i32_tl(t0, fp0);
6632 tcg_temp_free_i32(fp0);
6633 }
6634 break;
6635 case 3:
6636 /* XXX: For now we support only a single FPU context. */
6637 gen_helper_1e0i(cfc1, t0, rt);
6638 break;
6639 /* COP2: Not implemented. */
6640 case 4:
6641 case 5:
6642 /* fall through */
6643 default:
6644 goto die;
6645 }
6646 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6647 gen_store_gpr(t0, rd);
6648 tcg_temp_free(t0);
6649 return;
6650
6651 die:
6652 tcg_temp_free(t0);
6653 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6654 generate_exception(ctx, EXCP_RI);
6655 }
6656
6657 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6658 int u, int sel, int h)
6659 {
6660 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6661 TCGv t0 = tcg_temp_local_new();
6662
6663 gen_load_gpr(t0, rt);
6664 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6665 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6666 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6667 /* NOP */ ;
6668 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6669 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6670 /* NOP */ ;
6671 else if (u == 0) {
6672 switch (rd) {
6673 case 1:
6674 switch (sel) {
6675 case 1:
6676 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6677 break;
6678 case 2:
6679 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6680 break;
6681 default:
6682 goto die;
6683 break;
6684 }
6685 break;
6686 case 2:
6687 switch (sel) {
6688 case 1:
6689 gen_helper_mttc0_tcstatus(cpu_env, t0);
6690 break;
6691 case 2:
6692 gen_helper_mttc0_tcbind(cpu_env, t0);
6693 break;
6694 case 3:
6695 gen_helper_mttc0_tcrestart(cpu_env, t0);
6696 break;
6697 case 4:
6698 gen_helper_mttc0_tchalt(cpu_env, t0);
6699 break;
6700 case 5:
6701 gen_helper_mttc0_tccontext(cpu_env, t0);
6702 break;
6703 case 6:
6704 gen_helper_mttc0_tcschedule(cpu_env, t0);
6705 break;
6706 case 7:
6707 gen_helper_mttc0_tcschefback(cpu_env, t0);
6708 break;
6709 default:
6710 gen_mtc0(env, ctx, t0, rd, sel);
6711 break;
6712 }
6713 break;
6714 case 10:
6715 switch (sel) {
6716 case 0:
6717 gen_helper_mttc0_entryhi(cpu_env, t0);
6718 break;
6719 default:
6720 gen_mtc0(env, ctx, t0, rd, sel);
6721 break;
6722 }
6723 case 12:
6724 switch (sel) {
6725 case 0:
6726 gen_helper_mttc0_status(cpu_env, t0);
6727 break;
6728 default:
6729 gen_mtc0(env, ctx, t0, rd, sel);
6730 break;
6731 }
6732 case 13:
6733 switch (sel) {
6734 case 0:
6735 gen_helper_mttc0_cause(cpu_env, t0);
6736 break;
6737 default:
6738 goto die;
6739 break;
6740 }
6741 break;
6742 case 15:
6743 switch (sel) {
6744 case 1:
6745 gen_helper_mttc0_ebase(cpu_env, t0);
6746 break;
6747 default:
6748 goto die;
6749 break;
6750 }
6751 break;
6752 case 23:
6753 switch (sel) {
6754 case 0:
6755 gen_helper_mttc0_debug(cpu_env, t0);
6756 break;
6757 default:
6758 gen_mtc0(env, ctx, t0, rd, sel);
6759 break;
6760 }
6761 break;
6762 default:
6763 gen_mtc0(env, ctx, t0, rd, sel);
6764 }
6765 } else switch (sel) {
6766 /* GPR registers. */
6767 case 0:
6768 gen_helper_0e1i(mttgpr, t0, rd);
6769 break;
6770 /* Auxiliary CPU registers */
6771 case 1:
6772 switch (rd) {
6773 case 0:
6774 gen_helper_0e1i(mttlo, t0, 0);
6775 break;
6776 case 1:
6777 gen_helper_0e1i(mtthi, t0, 0);
6778 break;
6779 case 2:
6780 gen_helper_0e1i(mttacx, t0, 0);
6781 break;
6782 case 4:
6783 gen_helper_0e1i(mttlo, t0, 1);
6784 break;
6785 case 5:
6786 gen_helper_0e1i(mtthi, t0, 1);
6787 break;
6788 case 6:
6789 gen_helper_0e1i(mttacx, t0, 1);
6790 break;
6791 case 8:
6792 gen_helper_0e1i(mttlo, t0, 2);
6793 break;
6794 case 9:
6795 gen_helper_0e1i(mtthi, t0, 2);
6796 break;
6797 case 10:
6798 gen_helper_0e1i(mttacx, t0, 2);
6799 break;
6800 case 12:
6801 gen_helper_0e1i(mttlo, t0, 3);
6802 break;
6803 case 13:
6804 gen_helper_0e1i(mtthi, t0, 3);
6805 break;
6806 case 14:
6807 gen_helper_0e1i(mttacx, t0, 3);
6808 break;
6809 case 16:
6810 gen_helper_mttdsp(cpu_env, t0);
6811 break;
6812 default:
6813 goto die;
6814 }
6815 break;
6816 /* Floating point (COP1). */
6817 case 2:
6818 /* XXX: For now we support only a single FPU context. */
6819 if (h == 0) {
6820 TCGv_i32 fp0 = tcg_temp_new_i32();
6821
6822 tcg_gen_trunc_tl_i32(fp0, t0);
6823 gen_store_fpr32(fp0, rd);
6824 tcg_temp_free_i32(fp0);
6825 } else {
6826 TCGv_i32 fp0 = tcg_temp_new_i32();
6827
6828 tcg_gen_trunc_tl_i32(fp0, t0);
6829 gen_store_fpr32h(fp0, rd);
6830 tcg_temp_free_i32(fp0);
6831 }
6832 break;
6833 case 3:
6834 /* XXX: For now we support only a single FPU context. */
6835 gen_helper_0e1i(ctc1, t0, rd);
6836 break;
6837 /* COP2: Not implemented. */
6838 case 4:
6839 case 5:
6840 /* fall through */
6841 default:
6842 goto die;
6843 }
6844 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6845 tcg_temp_free(t0);
6846 return;
6847
6848 die:
6849 tcg_temp_free(t0);
6850 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6851 generate_exception(ctx, EXCP_RI);
6852 }
6853
6854 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6855 {
6856 const char *opn = "ldst";
6857
6858 check_cp0_enabled(ctx);
6859 switch (opc) {
6860 case OPC_MFC0:
6861 if (rt == 0) {
6862 /* Treat as NOP. */
6863 return;
6864 }
6865 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6866 opn = "mfc0";
6867 break;
6868 case OPC_MTC0:
6869 {
6870 TCGv t0 = tcg_temp_new();
6871
6872 gen_load_gpr(t0, rt);
6873 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6874 tcg_temp_free(t0);
6875 }
6876 opn = "mtc0";
6877 break;
6878 #if defined(TARGET_MIPS64)
6879 case OPC_DMFC0:
6880 check_insn(env, ctx, ISA_MIPS3);
6881 if (rt == 0) {
6882 /* Treat as NOP. */
6883 return;
6884 }
6885 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6886 opn = "dmfc0";
6887 break;
6888 case OPC_DMTC0:
6889 check_insn(env, ctx, ISA_MIPS3);
6890 {
6891 TCGv t0 = tcg_temp_new();
6892
6893 gen_load_gpr(t0, rt);
6894 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6895 tcg_temp_free(t0);
6896 }
6897 opn = "dmtc0";
6898 break;
6899 #endif
6900 case OPC_MFTR:
6901 check_insn(env, ctx, ASE_MT);
6902 if (rd == 0) {
6903 /* Treat as NOP. */
6904 return;
6905 }
6906 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6907 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6908 opn = "mftr";
6909 break;
6910 case OPC_MTTR:
6911 check_insn(env, ctx, ASE_MT);
6912 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6913 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6914 opn = "mttr";
6915 break;
6916 case OPC_TLBWI:
6917 opn = "tlbwi";
6918 if (!env->tlb->helper_tlbwi)
6919 goto die;
6920 gen_helper_tlbwi(cpu_env);
6921 break;
6922 case OPC_TLBWR:
6923 opn = "tlbwr";
6924 if (!env->tlb->helper_tlbwr)
6925 goto die;
6926 gen_helper_tlbwr(cpu_env);
6927 break;
6928 case OPC_TLBP:
6929 opn = "tlbp";
6930 if (!env->tlb->helper_tlbp)
6931 goto die;
6932 gen_helper_tlbp(cpu_env);
6933 break;
6934 case OPC_TLBR:
6935 opn = "tlbr";
6936 if (!env->tlb->helper_tlbr)
6937 goto die;
6938 gen_helper_tlbr(cpu_env);
6939 break;
6940 case OPC_ERET:
6941 opn = "eret";
6942 check_insn(env, ctx, ISA_MIPS2);
6943 gen_helper_eret(cpu_env);
6944 ctx->bstate = BS_EXCP;
6945 break;
6946 case OPC_DERET:
6947 opn = "deret";
6948 check_insn(env, ctx, ISA_MIPS32);
6949 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6950 MIPS_INVAL(opn);
6951 generate_exception(ctx, EXCP_RI);
6952 } else {
6953 gen_helper_deret(cpu_env);
6954 ctx->bstate = BS_EXCP;
6955 }
6956 break;
6957 case OPC_WAIT:
6958 opn = "wait";
6959 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6960 /* If we get an exception, we want to restart at next instruction */
6961 ctx->pc += 4;
6962 save_cpu_state(ctx, 1);
6963 ctx->pc -= 4;
6964 gen_helper_wait(cpu_env);
6965 ctx->bstate = BS_EXCP;
6966 break;
6967 default:
6968 die:
6969 MIPS_INVAL(opn);
6970 generate_exception(ctx, EXCP_RI);
6971 return;
6972 }
6973 (void)opn; /* avoid a compiler warning */
6974 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6975 }
6976 #endif /* !CONFIG_USER_ONLY */
6977
6978 /* CP1 Branches (before delay slot) */
6979 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
6980 int32_t cc, int32_t offset)
6981 {
6982 target_ulong btarget;
6983 const char *opn = "cp1 cond branch";
6984 TCGv_i32 t0 = tcg_temp_new_i32();
6985
6986 if (cc != 0)
6987 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6988
6989 btarget = ctx->pc + 4 + offset;
6990
6991 switch (op) {
6992 case OPC_BC1F:
6993 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6994 tcg_gen_not_i32(t0, t0);
6995 tcg_gen_andi_i32(t0, t0, 1);
6996 tcg_gen_extu_i32_tl(bcond, t0);
6997 opn = "bc1f";
6998 goto not_likely;
6999 case OPC_BC1FL:
7000 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7001 tcg_gen_not_i32(t0, t0);
7002 tcg_gen_andi_i32(t0, t0, 1);
7003 tcg_gen_extu_i32_tl(bcond, t0);
7004 opn = "bc1fl";
7005 goto likely;
7006 case OPC_BC1T:
7007 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7008 tcg_gen_andi_i32(t0, t0, 1);
7009 tcg_gen_extu_i32_tl(bcond, t0);
7010 opn = "bc1t";
7011 goto not_likely;
7012 case OPC_BC1TL:
7013 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7014 tcg_gen_andi_i32(t0, t0, 1);
7015 tcg_gen_extu_i32_tl(bcond, t0);
7016 opn = "bc1tl";
7017 likely:
7018 ctx->hflags |= MIPS_HFLAG_BL;
7019 break;
7020 case OPC_BC1FANY2:
7021 {
7022 TCGv_i32 t1 = tcg_temp_new_i32();
7023 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7024 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7025 tcg_gen_nand_i32(t0, t0, t1);
7026 tcg_temp_free_i32(t1);
7027 tcg_gen_andi_i32(t0, t0, 1);
7028 tcg_gen_extu_i32_tl(bcond, t0);
7029 }
7030 opn = "bc1any2f";
7031 goto not_likely;
7032 case OPC_BC1TANY2:
7033 {
7034 TCGv_i32 t1 = tcg_temp_new_i32();
7035 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7036 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7037 tcg_gen_or_i32(t0, t0, t1);
7038 tcg_temp_free_i32(t1);
7039 tcg_gen_andi_i32(t0, t0, 1);
7040 tcg_gen_extu_i32_tl(bcond, t0);
7041 }
7042 opn = "bc1any2t";
7043 goto not_likely;
7044 case OPC_BC1FANY4:
7045 {
7046 TCGv_i32 t1 = tcg_temp_new_i32();
7047 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7048 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7049 tcg_gen_and_i32(t0, t0, t1);
7050 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7051 tcg_gen_and_i32(t0, t0, t1);
7052 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7053 tcg_gen_nand_i32(t0, t0, t1);
7054 tcg_temp_free_i32(t1);
7055 tcg_gen_andi_i32(t0, t0, 1);
7056 tcg_gen_extu_i32_tl(bcond, t0);
7057 }
7058 opn = "bc1any4f";
7059 goto not_likely;
7060 case OPC_BC1TANY4:
7061 {
7062 TCGv_i32 t1 = tcg_temp_new_i32();
7063 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7064 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7065 tcg_gen_or_i32(t0, t0, t1);
7066 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7067 tcg_gen_or_i32(t0, t0, t1);
7068 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7069 tcg_gen_or_i32(t0, t0, t1);
7070 tcg_temp_free_i32(t1);
7071 tcg_gen_andi_i32(t0, t0, 1);
7072 tcg_gen_extu_i32_tl(bcond, t0);
7073 }
7074 opn = "bc1any4t";
7075 not_likely:
7076 ctx->hflags |= MIPS_HFLAG_BC;
7077 break;
7078 default:
7079 MIPS_INVAL(opn);
7080 generate_exception (ctx, EXCP_RI);
7081 goto out;
7082 }
7083 (void)opn; /* avoid a compiler warning */
7084 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7085 ctx->hflags, btarget);
7086 ctx->btarget = btarget;
7087
7088 out:
7089 tcg_temp_free_i32(t0);
7090 }
7091
7092 /* Coprocessor 1 (FPU) */
7093
7094 #define FOP(func, fmt) (((fmt) << 21) | (func))
7095
7096 enum fopcode {
7097 OPC_ADD_S = FOP(0, FMT_S),
7098 OPC_SUB_S = FOP(1, FMT_S),
7099 OPC_MUL_S = FOP(2, FMT_S),
7100 OPC_DIV_S = FOP(3, FMT_S),
7101 OPC_SQRT_S = FOP(4, FMT_S),
7102 OPC_ABS_S = FOP(5, FMT_S),
7103 OPC_MOV_S = FOP(6, FMT_S),
7104 OPC_NEG_S = FOP(7, FMT_S),
7105 OPC_ROUND_L_S = FOP(8, FMT_S),
7106 OPC_TRUNC_L_S = FOP(9, FMT_S),
7107 OPC_CEIL_L_S = FOP(10, FMT_S),
7108 OPC_FLOOR_L_S = FOP(11, FMT_S),
7109 OPC_ROUND_W_S = FOP(12, FMT_S),
7110 OPC_TRUNC_W_S = FOP(13, FMT_S),
7111 OPC_CEIL_W_S = FOP(14, FMT_S),
7112 OPC_FLOOR_W_S = FOP(15, FMT_S),
7113 OPC_MOVCF_S = FOP(17, FMT_S),
7114 OPC_MOVZ_S = FOP(18, FMT_S),
7115 OPC_MOVN_S = FOP(19, FMT_S),
7116 OPC_RECIP_S = FOP(21, FMT_S),
7117 OPC_RSQRT_S = FOP(22, FMT_S),
7118 OPC_RECIP2_S = FOP(28, FMT_S),
7119 OPC_RECIP1_S = FOP(29, FMT_S),
7120 OPC_RSQRT1_S = FOP(30, FMT_S),
7121 OPC_RSQRT2_S = FOP(31, FMT_S),
7122 OPC_CVT_D_S = FOP(33, FMT_S),
7123 OPC_CVT_W_S = FOP(36, FMT_S),
7124 OPC_CVT_L_S = FOP(37, FMT_S),
7125 OPC_CVT_PS_S = FOP(38, FMT_S),
7126 OPC_CMP_F_S = FOP (48, FMT_S),
7127 OPC_CMP_UN_S = FOP (49, FMT_S),
7128 OPC_CMP_EQ_S = FOP (50, FMT_S),
7129 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7130 OPC_CMP_OLT_S = FOP (52, FMT_S),
7131 OPC_CMP_ULT_S = FOP (53, FMT_S),
7132 OPC_CMP_OLE_S = FOP (54, FMT_S),
7133 OPC_CMP_ULE_S = FOP (55, FMT_S),
7134 OPC_CMP_SF_S = FOP (56, FMT_S),
7135 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7136 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7137 OPC_CMP_NGL_S = FOP (59, FMT_S),
7138 OPC_CMP_LT_S = FOP (60, FMT_S),
7139 OPC_CMP_NGE_S = FOP (61, FMT_S),
7140 OPC_CMP_LE_S = FOP (62, FMT_S),
7141 OPC_CMP_NGT_S = FOP (63, FMT_S),
7142
7143 OPC_ADD_D = FOP(0, FMT_D),
7144 OPC_SUB_D = FOP(1, FMT_D),
7145 OPC_MUL_D = FOP(2, FMT_D),
7146 OPC_DIV_D = FOP(3, FMT_D),
7147 OPC_SQRT_D = FOP(4, FMT_D),
7148 OPC_ABS_D = FOP(5, FMT_D),
7149 OPC_MOV_D = FOP(6, FMT_D),
7150 OPC_NEG_D = FOP(7, FMT_D),
7151 OPC_ROUND_L_D = FOP(8, FMT_D),
7152 OPC_TRUNC_L_D = FOP(9, FMT_D),
7153 OPC_CEIL_L_D = FOP(10, FMT_D),
7154 OPC_FLOOR_L_D = FOP(11, FMT_D),
7155 OPC_ROUND_W_D = FOP(12, FMT_D),
7156 OPC_TRUNC_W_D = FOP(13, FMT_D),
7157 OPC_CEIL_W_D = FOP(14, FMT_D),
7158 OPC_FLOOR_W_D = FOP(15, FMT_D),
7159 OPC_MOVCF_D = FOP(17, FMT_D),
7160 OPC_MOVZ_D = FOP(18, FMT_D),
7161 OPC_MOVN_D = FOP(19, FMT_D),
7162 OPC_RECIP_D = FOP(21, FMT_D),
7163 OPC_RSQRT_D = FOP(22, FMT_D),
7164 OPC_RECIP2_D = FOP(28, FMT_D),
7165 OPC_RECIP1_D = FOP(29, FMT_D),
7166 OPC_RSQRT1_D = FOP(30, FMT_D),
7167 OPC_RSQRT2_D = FOP(31, FMT_D),
7168 OPC_CVT_S_D = FOP(32, FMT_D),
7169 OPC_CVT_W_D = FOP(36, FMT_D),
7170 OPC_CVT_L_D = FOP(37, FMT_D),
7171 OPC_CMP_F_D = FOP (48, FMT_D),
7172 OPC_CMP_UN_D = FOP (49, FMT_D),
7173 OPC_CMP_EQ_D = FOP (50, FMT_D),
7174 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7175 OPC_CMP_OLT_D = FOP (52, FMT_D),
7176 OPC_CMP_ULT_D = FOP (53, FMT_D),
7177 OPC_CMP_OLE_D = FOP (54, FMT_D),
7178 OPC_CMP_ULE_D = FOP (55, FMT_D),
7179 OPC_CMP_SF_D = FOP (56, FMT_D),
7180 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7181 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7182 OPC_CMP_NGL_D = FOP (59, FMT_D),
7183 OPC_CMP_LT_D = FOP (60, FMT_D),
7184 OPC_CMP_NGE_D = FOP (61, FMT_D),
7185 OPC_CMP_LE_D = FOP (62, FMT_D),
7186 OPC_CMP_NGT_D = FOP (63, FMT_D),
7187
7188 OPC_CVT_S_W = FOP(32, FMT_W),
7189 OPC_CVT_D_W = FOP(33, FMT_W),
7190 OPC_CVT_S_L = FOP(32, FMT_L),
7191 OPC_CVT_D_L = FOP(33, FMT_L),
7192 OPC_CVT_PS_PW = FOP(38, FMT_W),
7193
7194 OPC_ADD_PS = FOP(0, FMT_PS),
7195 OPC_SUB_PS = FOP(1, FMT_PS),
7196 OPC_MUL_PS = FOP(2, FMT_PS),
7197 OPC_DIV_PS = FOP(3, FMT_PS),
7198 OPC_ABS_PS = FOP(5, FMT_PS),
7199 OPC_MOV_PS = FOP(6, FMT_PS),
7200 OPC_NEG_PS = FOP(7, FMT_PS),
7201 OPC_MOVCF_PS = FOP(17, FMT_PS),
7202 OPC_MOVZ_PS = FOP(18, FMT_PS),
7203 OPC_MOVN_PS = FOP(19, FMT_PS),
7204 OPC_ADDR_PS = FOP(24, FMT_PS),
7205 OPC_MULR_PS = FOP(26, FMT_PS),
7206 OPC_RECIP2_PS = FOP(28, FMT_PS),
7207 OPC_RECIP1_PS = FOP(29, FMT_PS),
7208 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7209 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7210
7211 OPC_CVT_S_PU = FOP(32, FMT_PS),
7212 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7213 OPC_CVT_S_PL = FOP(40, FMT_PS),
7214 OPC_PLL_PS = FOP(44, FMT_PS),
7215 OPC_PLU_PS = FOP(45, FMT_PS),
7216 OPC_PUL_PS = FOP(46, FMT_PS),
7217 OPC_PUU_PS = FOP(47, FMT_PS),
7218 OPC_CMP_F_PS = FOP (48, FMT_PS),
7219 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7220 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7221 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7222 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7223 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7224 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7225 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7226 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7227 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7228 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7229 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7230 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7231 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7232 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7233 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7234 };
7235
7236 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7237 {
7238 const char *opn = "cp1 move";
7239 TCGv t0 = tcg_temp_new();
7240
7241 switch (opc) {
7242 case OPC_MFC1:
7243 {
7244 TCGv_i32 fp0 = tcg_temp_new_i32();
7245
7246 gen_load_fpr32(fp0, fs);
7247 tcg_gen_ext_i32_tl(t0, fp0);
7248 tcg_temp_free_i32(fp0);
7249 }
7250 gen_store_gpr(t0, rt);
7251 opn = "mfc1";
7252 break;
7253 case OPC_MTC1:
7254 gen_load_gpr(t0, rt);
7255 {
7256 TCGv_i32 fp0 = tcg_temp_new_i32();
7257
7258 tcg_gen_trunc_tl_i32(fp0, t0);
7259 gen_store_fpr32(fp0, fs);
7260 tcg_temp_free_i32(fp0);
7261 }
7262 opn = "mtc1";
7263 break;
7264 case OPC_CFC1:
7265 gen_helper_1e0i(cfc1, t0, fs);
7266 gen_store_gpr(t0, rt);
7267 opn = "cfc1";
7268 break;
7269 case OPC_CTC1:
7270 gen_load_gpr(t0, rt);
7271 gen_helper_0e1i(ctc1, t0, fs);
7272 opn = "ctc1";
7273 break;
7274 #if defined(TARGET_MIPS64)
7275 case OPC_DMFC1:
7276 gen_load_fpr64(ctx, t0, fs);
7277 gen_store_gpr(t0, rt);
7278 opn = "dmfc1";
7279 break;
7280 case OPC_DMTC1:
7281 gen_load_gpr(t0, rt);
7282 gen_store_fpr64(ctx, t0, fs);
7283 opn = "dmtc1";
7284 break;
7285 #endif
7286 case OPC_MFHC1:
7287 {
7288 TCGv_i32 fp0 = tcg_temp_new_i32();
7289
7290 gen_load_fpr32h(fp0, fs);
7291 tcg_gen_ext_i32_tl(t0, fp0);
7292 tcg_temp_free_i32(fp0);
7293 }
7294 gen_store_gpr(t0, rt);
7295 opn = "mfhc1";
7296 break;
7297 case OPC_MTHC1:
7298 gen_load_gpr(t0, rt);
7299 {
7300 TCGv_i32 fp0 = tcg_temp_new_i32();
7301
7302 tcg_gen_trunc_tl_i32(fp0, t0);
7303 gen_store_fpr32h(fp0, fs);
7304 tcg_temp_free_i32(fp0);
7305 }
7306 opn = "mthc1";
7307 break;
7308 default:
7309 MIPS_INVAL(opn);
7310 generate_exception (ctx, EXCP_RI);
7311 goto out;
7312 }
7313 (void)opn; /* avoid a compiler warning */
7314 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7315
7316 out:
7317 tcg_temp_free(t0);
7318 }
7319
7320 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7321 {
7322 int l1;
7323 TCGCond cond;
7324 TCGv_i32 t0;
7325
7326 if (rd == 0) {
7327 /* Treat as NOP. */
7328 return;
7329 }
7330
7331 if (tf)
7332 cond = TCG_COND_EQ;
7333 else
7334 cond = TCG_COND_NE;
7335
7336 l1 = gen_new_label();
7337 t0 = tcg_temp_new_i32();
7338 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7339 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7340 tcg_temp_free_i32(t0);
7341 if (rs == 0) {
7342 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7343 } else {
7344 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7345 }
7346 gen_set_label(l1);
7347 }
7348
7349 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7350 {
7351 int cond;
7352 TCGv_i32 t0 = tcg_temp_new_i32();
7353 int l1 = gen_new_label();
7354
7355 if (tf)
7356 cond = TCG_COND_EQ;
7357 else
7358 cond = TCG_COND_NE;
7359
7360 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7361 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7362 gen_load_fpr32(t0, fs);
7363 gen_store_fpr32(t0, fd);
7364 gen_set_label(l1);
7365 tcg_temp_free_i32(t0);
7366 }
7367
7368 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7369 {
7370 int cond;
7371 TCGv_i32 t0 = tcg_temp_new_i32();
7372 TCGv_i64 fp0;
7373 int l1 = gen_new_label();
7374
7375 if (tf)
7376 cond = TCG_COND_EQ;
7377 else
7378 cond = TCG_COND_NE;
7379
7380 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7381 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7382 tcg_temp_free_i32(t0);
7383 fp0 = tcg_temp_new_i64();
7384 gen_load_fpr64(ctx, fp0, fs);
7385 gen_store_fpr64(ctx, fp0, fd);
7386 tcg_temp_free_i64(fp0);
7387 gen_set_label(l1);
7388 }
7389
7390 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7391 {
7392 int cond;
7393 TCGv_i32 t0 = tcg_temp_new_i32();
7394 int l1 = gen_new_label();
7395 int l2 = gen_new_label();
7396
7397 if (tf)
7398 cond = TCG_COND_EQ;
7399 else
7400 cond = TCG_COND_NE;
7401
7402 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7403 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7404 gen_load_fpr32(t0, fs);
7405 gen_store_fpr32(t0, fd);
7406 gen_set_label(l1);
7407
7408 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7409 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7410 gen_load_fpr32h(t0, fs);
7411 gen_store_fpr32h(t0, fd);
7412 tcg_temp_free_i32(t0);
7413 gen_set_label(l2);
7414 }
7415
7416
7417 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7418 int ft, int fs, int fd, int cc)
7419 {
7420 const char *opn = "farith";
7421 const char *condnames[] = {
7422 "c.f",
7423 "c.un",
7424 "c.eq",
7425 "c.ueq",
7426 "c.olt",
7427 "c.ult",
7428 "c.ole",
7429 "c.ule",
7430 "c.sf",
7431 "c.ngle",
7432 "c.seq",
7433 "c.ngl",
7434 "c.lt",
7435 "c.nge",
7436 "c.le",
7437 "c.ngt",
7438 };
7439 const char *condnames_abs[] = {
7440 "cabs.f",
7441 "cabs.un",
7442 "cabs.eq",
7443 "cabs.ueq",
7444 "cabs.olt",
7445 "cabs.ult",
7446 "cabs.ole",
7447 "cabs.ule",
7448 "cabs.sf",
7449 "cabs.ngle",
7450 "cabs.seq",
7451 "cabs.ngl",
7452 "cabs.lt",
7453 "cabs.nge",
7454 "cabs.le",
7455 "cabs.ngt",
7456 };
7457 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7458 uint32_t func = ctx->opcode & 0x3f;
7459
7460 switch (op1) {
7461 case OPC_ADD_S:
7462 {
7463 TCGv_i32 fp0 = tcg_temp_new_i32();
7464 TCGv_i32 fp1 = tcg_temp_new_i32();
7465
7466 gen_load_fpr32(fp0, fs);
7467 gen_load_fpr32(fp1, ft);
7468 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7469 tcg_temp_free_i32(fp1);
7470 gen_store_fpr32(fp0, fd);
7471 tcg_temp_free_i32(fp0);
7472 }
7473 opn = "add.s";
7474 optype = BINOP;
7475 break;
7476 case OPC_SUB_S:
7477 {
7478 TCGv_i32 fp0 = tcg_temp_new_i32();
7479 TCGv_i32 fp1 = tcg_temp_new_i32();
7480
7481 gen_load_fpr32(fp0, fs);
7482 gen_load_fpr32(fp1, ft);
7483 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7484 tcg_temp_free_i32(fp1);
7485 gen_store_fpr32(fp0, fd);
7486 tcg_temp_free_i32(fp0);
7487 }
7488 opn = "sub.s";
7489 optype = BINOP;
7490 break;
7491 case OPC_MUL_S:
7492 {
7493 TCGv_i32 fp0 = tcg_temp_new_i32();
7494 TCGv_i32 fp1 = tcg_temp_new_i32();
7495
7496 gen_load_fpr32(fp0, fs);
7497 gen_load_fpr32(fp1, ft);
7498 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7499 tcg_temp_free_i32(fp1);
7500 gen_store_fpr32(fp0, fd);
7501 tcg_temp_free_i32(fp0);
7502 }
7503 opn = "mul.s";
7504 optype = BINOP;
7505 break;
7506 case OPC_DIV_S:
7507 {
7508 TCGv_i32 fp0 = tcg_temp_new_i32();
7509 TCGv_i32 fp1 = tcg_temp_new_i32();
7510
7511 gen_load_fpr32(fp0, fs);
7512 gen_load_fpr32(fp1, ft);
7513 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7514 tcg_temp_free_i32(fp1);
7515 gen_store_fpr32(fp0, fd);
7516 tcg_temp_free_i32(fp0);
7517 }
7518 opn = "div.s";
7519 optype = BINOP;
7520 break;
7521 case OPC_SQRT_S:
7522 {
7523 TCGv_i32 fp0 = tcg_temp_new_i32();
7524
7525 gen_load_fpr32(fp0, fs);
7526 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7527 gen_store_fpr32(fp0, fd);
7528 tcg_temp_free_i32(fp0);
7529 }
7530 opn = "sqrt.s";
7531 break;
7532 case OPC_ABS_S:
7533 {
7534 TCGv_i32 fp0 = tcg_temp_new_i32();
7535
7536 gen_load_fpr32(fp0, fs);
7537 gen_helper_float_abs_s(fp0, fp0);
7538 gen_store_fpr32(fp0, fd);
7539 tcg_temp_free_i32(fp0);
7540 }
7541 opn = "abs.s";
7542 break;
7543 case OPC_MOV_S:
7544 {
7545 TCGv_i32 fp0 = tcg_temp_new_i32();
7546
7547 gen_load_fpr32(fp0, fs);
7548 gen_store_fpr32(fp0, fd);
7549 tcg_temp_free_i32(fp0);
7550 }
7551 opn = "mov.s";
7552 break;
7553 case OPC_NEG_S:
7554 {
7555 TCGv_i32 fp0 = tcg_temp_new_i32();
7556
7557 gen_load_fpr32(fp0, fs);
7558 gen_helper_float_chs_s(fp0, fp0);
7559 gen_store_fpr32(fp0, fd);
7560 tcg_temp_free_i32(fp0);
7561 }
7562 opn = "neg.s";
7563 break;
7564 case OPC_ROUND_L_S:
7565 check_cp1_64bitmode(ctx);
7566 {
7567 TCGv_i32 fp32 = tcg_temp_new_i32();
7568 TCGv_i64 fp64 = tcg_temp_new_i64();
7569
7570 gen_load_fpr32(fp32, fs);
7571 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7572 tcg_temp_free_i32(fp32);
7573 gen_store_fpr64(ctx, fp64, fd);
7574 tcg_temp_free_i64(fp64);
7575 }
7576 opn = "round.l.s";
7577 break;
7578 case OPC_TRUNC_L_S:
7579 check_cp1_64bitmode(ctx);
7580 {
7581 TCGv_i32 fp32 = tcg_temp_new_i32();
7582 TCGv_i64 fp64 = tcg_temp_new_i64();
7583
7584 gen_load_fpr32(fp32, fs);
7585 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7586 tcg_temp_free_i32(fp32);
7587 gen_store_fpr64(ctx, fp64, fd);
7588 tcg_temp_free_i64(fp64);
7589 }
7590 opn = "trunc.l.s";
7591 break;
7592 case OPC_CEIL_L_S:
7593 check_cp1_64bitmode(ctx);
7594 {
7595 TCGv_i32 fp32 = tcg_temp_new_i32();
7596 TCGv_i64 fp64 = tcg_temp_new_i64();
7597
7598 gen_load_fpr32(fp32, fs);
7599 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7600 tcg_temp_free_i32(fp32);
7601 gen_store_fpr64(ctx, fp64, fd);
7602 tcg_temp_free_i64(fp64);
7603 }
7604 opn = "ceil.l.s";
7605 break;
7606 case OPC_FLOOR_L_S:
7607 check_cp1_64bitmode(ctx);
7608 {
7609 TCGv_i32 fp32 = tcg_temp_new_i32();
7610 TCGv_i64 fp64 = tcg_temp_new_i64();
7611
7612 gen_load_fpr32(fp32, fs);
7613 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7614 tcg_temp_free_i32(fp32);
7615 gen_store_fpr64(ctx, fp64, fd);
7616 tcg_temp_free_i64(fp64);
7617 }
7618 opn = "floor.l.s";
7619 break;
7620 case OPC_ROUND_W_S:
7621 {
7622 TCGv_i32 fp0 = tcg_temp_new_i32();
7623
7624 gen_load_fpr32(fp0, fs);
7625 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7626 gen_store_fpr32(fp0, fd);
7627 tcg_temp_free_i32(fp0);
7628 }
7629 opn = "round.w.s";
7630 break;
7631 case OPC_TRUNC_W_S:
7632 {
7633 TCGv_i32 fp0 = tcg_temp_new_i32();
7634
7635 gen_load_fpr32(fp0, fs);
7636 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7637 gen_store_fpr32(fp0, fd);
7638 tcg_temp_free_i32(fp0);
7639 }
7640 opn = "trunc.w.s";
7641 break;
7642 case OPC_CEIL_W_S:
7643 {
7644 TCGv_i32 fp0 = tcg_temp_new_i32();
7645
7646 gen_load_fpr32(fp0, fs);
7647 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7648 gen_store_fpr32(fp0, fd);
7649 tcg_temp_free_i32(fp0);
7650 }
7651 opn = "ceil.w.s";
7652 break;
7653 case OPC_FLOOR_W_S:
7654 {
7655 TCGv_i32 fp0 = tcg_temp_new_i32();
7656
7657 gen_load_fpr32(fp0, fs);
7658 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7659 gen_store_fpr32(fp0, fd);
7660 tcg_temp_free_i32(fp0);
7661 }
7662 opn = "floor.w.s";
7663 break;
7664 case OPC_MOVCF_S:
7665 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7666 opn = "movcf.s";
7667 break;
7668 case OPC_MOVZ_S:
7669 {
7670 int l1 = gen_new_label();
7671 TCGv_i32 fp0;
7672
7673 if (ft != 0) {
7674 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7675 }
7676 fp0 = tcg_temp_new_i32();
7677 gen_load_fpr32(fp0, fs);
7678 gen_store_fpr32(fp0, fd);
7679 tcg_temp_free_i32(fp0);
7680 gen_set_label(l1);
7681 }
7682 opn = "movz.s";
7683 break;
7684 case OPC_MOVN_S:
7685 {
7686 int l1 = gen_new_label();
7687 TCGv_i32 fp0;
7688
7689 if (ft != 0) {
7690 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7691 fp0 = tcg_temp_new_i32();
7692 gen_load_fpr32(fp0, fs);
7693 gen_store_fpr32(fp0, fd);
7694 tcg_temp_free_i32(fp0);
7695 gen_set_label(l1);
7696 }
7697 }
7698 opn = "movn.s";
7699 break;
7700 case OPC_RECIP_S:
7701 check_cop1x(ctx);
7702 {
7703 TCGv_i32 fp0 = tcg_temp_new_i32();
7704
7705 gen_load_fpr32(fp0, fs);
7706 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7707 gen_store_fpr32(fp0, fd);
7708 tcg_temp_free_i32(fp0);
7709 }
7710 opn = "recip.s";
7711 break;
7712 case OPC_RSQRT_S:
7713 check_cop1x(ctx);
7714 {
7715 TCGv_i32 fp0 = tcg_temp_new_i32();
7716
7717 gen_load_fpr32(fp0, fs);
7718 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7719 gen_store_fpr32(fp0, fd);
7720 tcg_temp_free_i32(fp0);
7721 }
7722 opn = "rsqrt.s";
7723 break;
7724 case OPC_RECIP2_S:
7725 check_cp1_64bitmode(ctx);
7726 {
7727 TCGv_i32 fp0 = tcg_temp_new_i32();
7728 TCGv_i32 fp1 = tcg_temp_new_i32();
7729
7730 gen_load_fpr32(fp0, fs);
7731 gen_load_fpr32(fp1, ft);
7732 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7733 tcg_temp_free_i32(fp1);
7734 gen_store_fpr32(fp0, fd);
7735 tcg_temp_free_i32(fp0);
7736 }
7737 opn = "recip2.s";
7738 break;
7739 case OPC_RECIP1_S:
7740 check_cp1_64bitmode(ctx);
7741 {
7742 TCGv_i32 fp0 = tcg_temp_new_i32();
7743
7744 gen_load_fpr32(fp0, fs);
7745 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7746 gen_store_fpr32(fp0, fd);
7747 tcg_temp_free_i32(fp0);
7748 }
7749 opn = "recip1.s";
7750 break;
7751 case OPC_RSQRT1_S:
7752 check_cp1_64bitmode(ctx);
7753 {
7754 TCGv_i32 fp0 = tcg_temp_new_i32();
7755
7756 gen_load_fpr32(fp0, fs);
7757 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7758 gen_store_fpr32(fp0, fd);
7759 tcg_temp_free_i32(fp0);
7760 }
7761 opn = "rsqrt1.s";
7762 break;
7763 case OPC_RSQRT2_S:
7764 check_cp1_64bitmode(ctx);
7765 {
7766 TCGv_i32 fp0 = tcg_temp_new_i32();
7767 TCGv_i32 fp1 = tcg_temp_new_i32();
7768
7769 gen_load_fpr32(fp0, fs);
7770 gen_load_fpr32(fp1, ft);
7771 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7772 tcg_temp_free_i32(fp1);
7773 gen_store_fpr32(fp0, fd);
7774 tcg_temp_free_i32(fp0);
7775 }
7776 opn = "rsqrt2.s";
7777 break;
7778 case OPC_CVT_D_S:
7779 check_cp1_registers(ctx, fd);
7780 {
7781 TCGv_i32 fp32 = tcg_temp_new_i32();
7782 TCGv_i64 fp64 = tcg_temp_new_i64();
7783
7784 gen_load_fpr32(fp32, fs);
7785 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7786 tcg_temp_free_i32(fp32);
7787 gen_store_fpr64(ctx, fp64, fd);
7788 tcg_temp_free_i64(fp64);
7789 }
7790 opn = "cvt.d.s";
7791 break;
7792 case OPC_CVT_W_S:
7793 {
7794 TCGv_i32 fp0 = tcg_temp_new_i32();
7795
7796 gen_load_fpr32(fp0, fs);
7797 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7798 gen_store_fpr32(fp0, fd);
7799 tcg_temp_free_i32(fp0);
7800 }
7801 opn = "cvt.w.s";
7802 break;
7803 case OPC_CVT_L_S:
7804 check_cp1_64bitmode(ctx);
7805 {
7806 TCGv_i32 fp32 = tcg_temp_new_i32();
7807 TCGv_i64 fp64 = tcg_temp_new_i64();
7808
7809 gen_load_fpr32(fp32, fs);
7810 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7811 tcg_temp_free_i32(fp32);
7812 gen_store_fpr64(ctx, fp64, fd);
7813 tcg_temp_free_i64(fp64);
7814 }
7815 opn = "cvt.l.s";
7816 break;
7817 case OPC_CVT_PS_S:
7818 check_cp1_64bitmode(ctx);
7819 {
7820 TCGv_i64 fp64 = tcg_temp_new_i64();
7821 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7822 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7823
7824 gen_load_fpr32(fp32_0, fs);
7825 gen_load_fpr32(fp32_1, ft);
7826 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7827 tcg_temp_free_i32(fp32_1);
7828 tcg_temp_free_i32(fp32_0);
7829 gen_store_fpr64(ctx, fp64, fd);
7830 tcg_temp_free_i64(fp64);
7831 }
7832 opn = "cvt.ps.s";
7833 break;
7834 case OPC_CMP_F_S:
7835 case OPC_CMP_UN_S:
7836 case OPC_CMP_EQ_S:
7837 case OPC_CMP_UEQ_S:
7838 case OPC_CMP_OLT_S:
7839 case OPC_CMP_ULT_S:
7840 case OPC_CMP_OLE_S:
7841 case OPC_CMP_ULE_S:
7842 case OPC_CMP_SF_S:
7843 case OPC_CMP_NGLE_S:
7844 case OPC_CMP_SEQ_S:
7845 case OPC_CMP_NGL_S:
7846 case OPC_CMP_LT_S:
7847 case OPC_CMP_NGE_S:
7848 case OPC_CMP_LE_S:
7849 case OPC_CMP_NGT_S:
7850 if (ctx->opcode & (1 << 6)) {
7851 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7852 opn = condnames_abs[func-48];
7853 } else {
7854 gen_cmp_s(ctx, func-48, ft, fs, cc);
7855 opn = condnames[func-48];
7856 }
7857 break;
7858 case OPC_ADD_D:
7859 check_cp1_registers(ctx, fs | ft | fd);
7860 {
7861 TCGv_i64 fp0 = tcg_temp_new_i64();
7862 TCGv_i64 fp1 = tcg_temp_new_i64();
7863
7864 gen_load_fpr64(ctx, fp0, fs);
7865 gen_load_fpr64(ctx, fp1, ft);
7866 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7867 tcg_temp_free_i64(fp1);
7868 gen_store_fpr64(ctx, fp0, fd);
7869 tcg_temp_free_i64(fp0);
7870 }
7871 opn = "add.d";
7872 optype = BINOP;
7873 break;
7874 case OPC_SUB_D:
7875 check_cp1_registers(ctx, fs | ft | fd);
7876 {
7877 TCGv_i64 fp0 = tcg_temp_new_i64();
7878 TCGv_i64 fp1 = tcg_temp_new_i64();
7879
7880 gen_load_fpr64(ctx, fp0, fs);
7881 gen_load_fpr64(ctx, fp1, ft);
7882 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7883 tcg_temp_free_i64(fp1);
7884 gen_store_fpr64(ctx, fp0, fd);
7885 tcg_temp_free_i64(fp0);
7886 }
7887 opn = "sub.d";
7888 optype = BINOP;
7889 break;
7890 case OPC_MUL_D:
7891 check_cp1_registers(ctx, fs | ft | fd);
7892 {
7893 TCGv_i64 fp0 = tcg_temp_new_i64();
7894 TCGv_i64 fp1 = tcg_temp_new_i64();
7895
7896 gen_load_fpr64(ctx, fp0, fs);
7897 gen_load_fpr64(ctx, fp1, ft);
7898 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7899 tcg_temp_free_i64(fp1);
7900 gen_store_fpr64(ctx, fp0, fd);
7901 tcg_temp_free_i64(fp0);
7902 }
7903 opn = "mul.d";
7904 optype = BINOP;
7905 break;
7906 case OPC_DIV_D:
7907 check_cp1_registers(ctx, fs | ft | fd);
7908 {
7909 TCGv_i64 fp0 = tcg_temp_new_i64();
7910 TCGv_i64 fp1 = tcg_temp_new_i64();
7911
7912 gen_load_fpr64(ctx, fp0, fs);
7913 gen_load_fpr64(ctx, fp1, ft);
7914 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7915 tcg_temp_free_i64(fp1);
7916 gen_store_fpr64(ctx, fp0, fd);
7917 tcg_temp_free_i64(fp0);
7918 }
7919 opn = "div.d";
7920 optype = BINOP;
7921 break;
7922 case OPC_SQRT_D:
7923 check_cp1_registers(ctx, fs | fd);
7924 {
7925 TCGv_i64 fp0 = tcg_temp_new_i64();
7926
7927 gen_load_fpr64(ctx, fp0, fs);
7928 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7929 gen_store_fpr64(ctx, fp0, fd);
7930 tcg_temp_free_i64(fp0);
7931 }
7932 opn = "sqrt.d";
7933 break;
7934 case OPC_ABS_D:
7935 check_cp1_registers(ctx, fs | fd);
7936 {
7937 TCGv_i64 fp0 = tcg_temp_new_i64();
7938
7939 gen_load_fpr64(ctx, fp0, fs);
7940 gen_helper_float_abs_d(fp0, fp0);
7941 gen_store_fpr64(ctx, fp0, fd);
7942 tcg_temp_free_i64(fp0);
7943 }
7944 opn = "abs.d";
7945 break;
7946 case OPC_MOV_D:
7947 check_cp1_registers(ctx, fs | fd);
7948 {
7949 TCGv_i64 fp0 = tcg_temp_new_i64();
7950
7951 gen_load_fpr64(ctx, fp0, fs);
7952 gen_store_fpr64(ctx, fp0, fd);
7953 tcg_temp_free_i64(fp0);
7954 }
7955 opn = "mov.d";
7956 break;
7957 case OPC_NEG_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_chs_d(fp0, fp0);
7964 gen_store_fpr64(ctx, fp0, fd);
7965 tcg_temp_free_i64(fp0);
7966 }
7967 opn = "neg.d";
7968 break;
7969 case OPC_ROUND_L_D:
7970 check_cp1_64bitmode(ctx);
7971 {
7972 TCGv_i64 fp0 = tcg_temp_new_i64();
7973
7974 gen_load_fpr64(ctx, fp0, fs);
7975 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7976 gen_store_fpr64(ctx, fp0, fd);
7977 tcg_temp_free_i64(fp0);
7978 }
7979 opn = "round.l.d";
7980 break;
7981 case OPC_TRUNC_L_D:
7982 check_cp1_64bitmode(ctx);
7983 {
7984 TCGv_i64 fp0 = tcg_temp_new_i64();
7985
7986 gen_load_fpr64(ctx, fp0, fs);
7987 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7988 gen_store_fpr64(ctx, fp0, fd);
7989 tcg_temp_free_i64(fp0);
7990 }
7991 opn = "trunc.l.d";
7992 break;
7993 case OPC_CEIL_L_D:
7994 check_cp1_64bitmode(ctx);
7995 {
7996 TCGv_i64 fp0 = tcg_temp_new_i64();
7997
7998 gen_load_fpr64(ctx, fp0, fs);
7999 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8000 gen_store_fpr64(ctx, fp0, fd);
8001 tcg_temp_free_i64(fp0);
8002 }
8003 opn = "ceil.l.d";
8004 break;
8005 case OPC_FLOOR_L_D:
8006 check_cp1_64bitmode(ctx);
8007 {
8008 TCGv_i64 fp0 = tcg_temp_new_i64();
8009
8010 gen_load_fpr64(ctx, fp0, fs);
8011 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8012 gen_store_fpr64(ctx, fp0, fd);
8013 tcg_temp_free_i64(fp0);
8014 }
8015 opn = "floor.l.d";
8016 break;
8017 case OPC_ROUND_W_D:
8018 check_cp1_registers(ctx, fs);
8019 {
8020 TCGv_i32 fp32 = tcg_temp_new_i32();
8021 TCGv_i64 fp64 = tcg_temp_new_i64();
8022
8023 gen_load_fpr64(ctx, fp64, fs);
8024 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8025 tcg_temp_free_i64(fp64);
8026 gen_store_fpr32(fp32, fd);
8027 tcg_temp_free_i32(fp32);
8028 }
8029 opn = "round.w.d";
8030 break;
8031 case OPC_TRUNC_W_D:
8032 check_cp1_registers(ctx, fs);
8033 {
8034 TCGv_i32 fp32 = tcg_temp_new_i32();
8035 TCGv_i64 fp64 = tcg_temp_new_i64();
8036
8037 gen_load_fpr64(ctx, fp64, fs);
8038 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8039 tcg_temp_free_i64(fp64);
8040 gen_store_fpr32(fp32, fd);
8041 tcg_temp_free_i32(fp32);
8042 }
8043 opn = "trunc.w.d";
8044 break;
8045 case OPC_CEIL_W_D:
8046 check_cp1_registers(ctx, fs);
8047 {
8048 TCGv_i32 fp32 = tcg_temp_new_i32();
8049 TCGv_i64 fp64 = tcg_temp_new_i64();
8050
8051 gen_load_fpr64(ctx, fp64, fs);
8052 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8053 tcg_temp_free_i64(fp64);
8054 gen_store_fpr32(fp32, fd);
8055 tcg_temp_free_i32(fp32);
8056 }
8057 opn = "ceil.w.d";
8058 break;
8059 case OPC_FLOOR_W_D:
8060 check_cp1_registers(ctx, fs);
8061 {
8062 TCGv_i32 fp32 = tcg_temp_new_i32();
8063 TCGv_i64 fp64 = tcg_temp_new_i64();
8064
8065 gen_load_fpr64(ctx, fp64, fs);
8066 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8067 tcg_temp_free_i64(fp64);
8068 gen_store_fpr32(fp32, fd);
8069 tcg_temp_free_i32(fp32);
8070 }
8071 opn = "floor.w.d";
8072 break;
8073 case OPC_MOVCF_D:
8074 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8075 opn = "movcf.d";
8076 break;
8077 case OPC_MOVZ_D:
8078 {
8079 int l1 = gen_new_label();
8080 TCGv_i64 fp0;
8081
8082 if (ft != 0) {
8083 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8084 }
8085 fp0 = tcg_temp_new_i64();
8086 gen_load_fpr64(ctx, fp0, fs);
8087 gen_store_fpr64(ctx, fp0, fd);
8088 tcg_temp_free_i64(fp0);
8089 gen_set_label(l1);
8090 }
8091 opn = "movz.d";
8092 break;
8093 case OPC_MOVN_D:
8094 {
8095 int l1 = gen_new_label();
8096 TCGv_i64 fp0;
8097
8098 if (ft != 0) {
8099 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8100 fp0 = tcg_temp_new_i64();
8101 gen_load_fpr64(ctx, fp0, fs);
8102 gen_store_fpr64(ctx, fp0, fd);
8103 tcg_temp_free_i64(fp0);
8104 gen_set_label(l1);
8105 }
8106 }
8107 opn = "movn.d";
8108 break;
8109 case OPC_RECIP_D:
8110 check_cp1_64bitmode(ctx);
8111 {
8112 TCGv_i64 fp0 = tcg_temp_new_i64();
8113
8114 gen_load_fpr64(ctx, fp0, fs);
8115 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8116 gen_store_fpr64(ctx, fp0, fd);
8117 tcg_temp_free_i64(fp0);
8118 }
8119 opn = "recip.d";
8120 break;
8121 case OPC_RSQRT_D:
8122 check_cp1_64bitmode(ctx);
8123 {
8124 TCGv_i64 fp0 = tcg_temp_new_i64();
8125
8126 gen_load_fpr64(ctx, fp0, fs);
8127 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8128 gen_store_fpr64(ctx, fp0, fd);
8129 tcg_temp_free_i64(fp0);
8130 }
8131 opn = "rsqrt.d";
8132 break;
8133 case OPC_RECIP2_D:
8134 check_cp1_64bitmode(ctx);
8135 {
8136 TCGv_i64 fp0 = tcg_temp_new_i64();
8137 TCGv_i64 fp1 = tcg_temp_new_i64();
8138
8139 gen_load_fpr64(ctx, fp0, fs);
8140 gen_load_fpr64(ctx, fp1, ft);
8141 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8142 tcg_temp_free_i64(fp1);
8143 gen_store_fpr64(ctx, fp0, fd);
8144 tcg_temp_free_i64(fp0);
8145 }
8146 opn = "recip2.d";
8147 break;
8148 case OPC_RECIP1_D:
8149 check_cp1_64bitmode(ctx);
8150 {
8151 TCGv_i64 fp0 = tcg_temp_new_i64();
8152
8153 gen_load_fpr64(ctx, fp0, fs);
8154 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8155 gen_store_fpr64(ctx, fp0, fd);
8156 tcg_temp_free_i64(fp0);
8157 }
8158 opn = "recip1.d";
8159 break;
8160 case OPC_RSQRT1_D:
8161 check_cp1_64bitmode(ctx);
8162 {
8163 TCGv_i64 fp0 = tcg_temp_new_i64();
8164
8165 gen_load_fpr64(ctx, fp0, fs);
8166 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8167 gen_store_fpr64(ctx, fp0, fd);
8168 tcg_temp_free_i64(fp0);
8169 }
8170 opn = "rsqrt1.d";
8171 break;
8172 case OPC_RSQRT2_D:
8173 check_cp1_64bitmode(ctx);
8174 {
8175 TCGv_i64 fp0 = tcg_temp_new_i64();
8176 TCGv_i64 fp1 = tcg_temp_new_i64();
8177
8178 gen_load_fpr64(ctx, fp0, fs);
8179 gen_load_fpr64(ctx, fp1, ft);
8180 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8181 tcg_temp_free_i64(fp1);
8182 gen_store_fpr64(ctx, fp0, fd);
8183 tcg_temp_free_i64(fp0);
8184 }
8185 opn = "rsqrt2.d";
8186 break;
8187 case OPC_CMP_F_D:
8188 case OPC_CMP_UN_D:
8189 case OPC_CMP_EQ_D:
8190 case OPC_CMP_UEQ_D:
8191 case OPC_CMP_OLT_D:
8192 case OPC_CMP_ULT_D:
8193 case OPC_CMP_OLE_D:
8194 case OPC_CMP_ULE_D:
8195 case OPC_CMP_SF_D:
8196 case OPC_CMP_NGLE_D:
8197 case OPC_CMP_SEQ_D:
8198 case OPC_CMP_NGL_D:
8199 case OPC_CMP_LT_D:
8200 case OPC_CMP_NGE_D:
8201 case OPC_CMP_LE_D:
8202 case OPC_CMP_NGT_D:
8203 if (ctx->opcode & (1 << 6)) {
8204 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8205 opn = condnames_abs[func-48];
8206 } else {
8207 gen_cmp_d(ctx, func-48, ft, fs, cc);
8208 opn = condnames[func-48];
8209 }
8210 break;
8211 case OPC_CVT_S_D:
8212 check_cp1_registers(ctx, fs);
8213 {
8214 TCGv_i32 fp32 = tcg_temp_new_i32();
8215 TCGv_i64 fp64 = tcg_temp_new_i64();
8216
8217 gen_load_fpr64(ctx, fp64, fs);
8218 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8219 tcg_temp_free_i64(fp64);
8220 gen_store_fpr32(fp32, fd);
8221 tcg_temp_free_i32(fp32);
8222 }
8223 opn = "cvt.s.d";
8224 break;
8225 case OPC_CVT_W_D:
8226 check_cp1_registers(ctx, fs);
8227 {
8228 TCGv_i32 fp32 = tcg_temp_new_i32();
8229 TCGv_i64 fp64 = tcg_temp_new_i64();
8230
8231 gen_load_fpr64(ctx, fp64, fs);
8232 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8233 tcg_temp_free_i64(fp64);
8234 gen_store_fpr32(fp32, fd);
8235 tcg_temp_free_i32(fp32);
8236 }
8237 opn = "cvt.w.d";
8238 break;
8239 case OPC_CVT_L_D:
8240 check_cp1_64bitmode(ctx);
8241 {
8242 TCGv_i64 fp0 = tcg_temp_new_i64();
8243
8244 gen_load_fpr64(ctx, fp0, fs);
8245 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8246 gen_store_fpr64(ctx, fp0, fd);
8247 tcg_temp_free_i64(fp0);
8248 }
8249 opn = "cvt.l.d";
8250 break;
8251 case OPC_CVT_S_W:
8252 {
8253 TCGv_i32 fp0 = tcg_temp_new_i32();
8254
8255 gen_load_fpr32(fp0, fs);
8256 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8257 gen_store_fpr32(fp0, fd);
8258 tcg_temp_free_i32(fp0);
8259 }
8260 opn = "cvt.s.w";
8261 break;
8262 case OPC_CVT_D_W:
8263 check_cp1_registers(ctx, fd);
8264 {
8265 TCGv_i32 fp32 = tcg_temp_new_i32();
8266 TCGv_i64 fp64 = tcg_temp_new_i64();
8267
8268 gen_load_fpr32(fp32, fs);
8269 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8270 tcg_temp_free_i32(fp32);
8271 gen_store_fpr64(ctx, fp64, fd);
8272 tcg_temp_free_i64(fp64);
8273 }
8274 opn = "cvt.d.w";
8275 break;
8276 case OPC_CVT_S_L:
8277 check_cp1_64bitmode(ctx);
8278 {
8279 TCGv_i32 fp32 = tcg_temp_new_i32();
8280 TCGv_i64 fp64 = tcg_temp_new_i64();
8281
8282 gen_load_fpr64(ctx, fp64, fs);
8283 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8284 tcg_temp_free_i64(fp64);
8285 gen_store_fpr32(fp32, fd);
8286 tcg_temp_free_i32(fp32);
8287 }
8288 opn = "cvt.s.l";
8289 break;
8290 case OPC_CVT_D_L:
8291 check_cp1_64bitmode(ctx);
8292 {
8293 TCGv_i64 fp0 = tcg_temp_new_i64();
8294
8295 gen_load_fpr64(ctx, fp0, fs);
8296 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8297 gen_store_fpr64(ctx, fp0, fd);
8298 tcg_temp_free_i64(fp0);
8299 }
8300 opn = "cvt.d.l";
8301 break;
8302 case OPC_CVT_PS_PW:
8303 check_cp1_64bitmode(ctx);
8304 {
8305 TCGv_i64 fp0 = tcg_temp_new_i64();
8306
8307 gen_load_fpr64(ctx, fp0, fs);
8308 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8309 gen_store_fpr64(ctx, fp0, fd);
8310 tcg_temp_free_i64(fp0);
8311 }
8312 opn = "cvt.ps.pw";
8313 break;
8314 case OPC_ADD_PS:
8315 check_cp1_64bitmode(ctx);
8316 {
8317 TCGv_i64 fp0 = tcg_temp_new_i64();
8318 TCGv_i64 fp1 = tcg_temp_new_i64();
8319
8320 gen_load_fpr64(ctx, fp0, fs);
8321 gen_load_fpr64(ctx, fp1, ft);
8322 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8323 tcg_temp_free_i64(fp1);
8324 gen_store_fpr64(ctx, fp0, fd);
8325 tcg_temp_free_i64(fp0);
8326 }
8327 opn = "add.ps";
8328 break;
8329 case OPC_SUB_PS:
8330 check_cp1_64bitmode(ctx);
8331 {
8332 TCGv_i64 fp0 = tcg_temp_new_i64();
8333 TCGv_i64 fp1 = tcg_temp_new_i64();
8334
8335 gen_load_fpr64(ctx, fp0, fs);
8336 gen_load_fpr64(ctx, fp1, ft);
8337 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8338 tcg_temp_free_i64(fp1);
8339 gen_store_fpr64(ctx, fp0, fd);
8340 tcg_temp_free_i64(fp0);
8341 }
8342 opn = "sub.ps";
8343 break;
8344 case OPC_MUL_PS:
8345 check_cp1_64bitmode(ctx);
8346 {
8347 TCGv_i64 fp0 = tcg_temp_new_i64();
8348 TCGv_i64 fp1 = tcg_temp_new_i64();
8349
8350 gen_load_fpr64(ctx, fp0, fs);
8351 gen_load_fpr64(ctx, fp1, ft);
8352 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8353 tcg_temp_free_i64(fp1);
8354 gen_store_fpr64(ctx, fp0, fd);
8355 tcg_temp_free_i64(fp0);
8356 }
8357 opn = "mul.ps";
8358 break;
8359 case OPC_ABS_PS:
8360 check_cp1_64bitmode(ctx);
8361 {
8362 TCGv_i64 fp0 = tcg_temp_new_i64();
8363
8364 gen_load_fpr64(ctx, fp0, fs);
8365 gen_helper_float_abs_ps(fp0, fp0);
8366 gen_store_fpr64(ctx, fp0, fd);
8367 tcg_temp_free_i64(fp0);
8368 }
8369 opn = "abs.ps";
8370 break;
8371 case OPC_MOV_PS:
8372 check_cp1_64bitmode(ctx);
8373 {
8374 TCGv_i64 fp0 = tcg_temp_new_i64();
8375
8376 gen_load_fpr64(ctx, fp0, fs);
8377 gen_store_fpr64(ctx, fp0, fd);
8378 tcg_temp_free_i64(fp0);
8379 }
8380 opn = "mov.ps";
8381 break;
8382 case OPC_NEG_PS:
8383 check_cp1_64bitmode(ctx);
8384 {
8385 TCGv_i64 fp0 = tcg_temp_new_i64();
8386
8387 gen_load_fpr64(ctx, fp0, fs);
8388 gen_helper_float_chs_ps(fp0, fp0);
8389 gen_store_fpr64(ctx, fp0, fd);
8390 tcg_temp_free_i64(fp0);
8391 }
8392 opn = "neg.ps";
8393 break;
8394 case OPC_MOVCF_PS:
8395 check_cp1_64bitmode(ctx);
8396 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8397 opn = "movcf.ps";
8398 break;
8399 case OPC_MOVZ_PS:
8400 check_cp1_64bitmode(ctx);
8401 {
8402 int l1 = gen_new_label();
8403 TCGv_i64 fp0;
8404
8405 if (ft != 0)
8406 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8407 fp0 = tcg_temp_new_i64();
8408 gen_load_fpr64(ctx, fp0, fs);
8409 gen_store_fpr64(ctx, fp0, fd);
8410 tcg_temp_free_i64(fp0);
8411 gen_set_label(l1);
8412 }
8413 opn = "movz.ps";
8414 break;
8415 case OPC_MOVN_PS:
8416 check_cp1_64bitmode(ctx);
8417 {
8418 int l1 = gen_new_label();
8419 TCGv_i64 fp0;
8420
8421 if (ft != 0) {
8422 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8423 fp0 = tcg_temp_new_i64();
8424 gen_load_fpr64(ctx, fp0, fs);
8425 gen_store_fpr64(ctx, fp0, fd);
8426 tcg_temp_free_i64(fp0);
8427 gen_set_label(l1);
8428 }
8429 }
8430 opn = "movn.ps";
8431 break;
8432 case OPC_ADDR_PS:
8433 check_cp1_64bitmode(ctx);
8434 {
8435 TCGv_i64 fp0 = tcg_temp_new_i64();
8436 TCGv_i64 fp1 = tcg_temp_new_i64();
8437
8438 gen_load_fpr64(ctx, fp0, ft);
8439 gen_load_fpr64(ctx, fp1, fs);
8440 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8441 tcg_temp_free_i64(fp1);
8442 gen_store_fpr64(ctx, fp0, fd);
8443 tcg_temp_free_i64(fp0);
8444 }
8445 opn = "addr.ps";
8446 break;
8447 case OPC_MULR_PS:
8448 check_cp1_64bitmode(ctx);
8449 {
8450 TCGv_i64 fp0 = tcg_temp_new_i64();
8451 TCGv_i64 fp1 = tcg_temp_new_i64();
8452
8453 gen_load_fpr64(ctx, fp0, ft);
8454 gen_load_fpr64(ctx, fp1, fs);
8455 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8456 tcg_temp_free_i64(fp1);
8457 gen_store_fpr64(ctx, fp0, fd);
8458 tcg_temp_free_i64(fp0);
8459 }
8460 opn = "mulr.ps";
8461 break;
8462 case OPC_RECIP2_PS:
8463 check_cp1_64bitmode(ctx);
8464 {
8465 TCGv_i64 fp0 = tcg_temp_new_i64();
8466 TCGv_i64 fp1 = tcg_temp_new_i64();
8467
8468 gen_load_fpr64(ctx, fp0, fs);
8469 gen_load_fpr64(ctx, fp1, ft);
8470 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8471 tcg_temp_free_i64(fp1);
8472 gen_store_fpr64(ctx, fp0, fd);
8473 tcg_temp_free_i64(fp0);
8474 }
8475 opn = "recip2.ps";
8476 break;
8477 case OPC_RECIP1_PS:
8478 check_cp1_64bitmode(ctx);
8479 {
8480 TCGv_i64 fp0 = tcg_temp_new_i64();
8481
8482 gen_load_fpr64(ctx, fp0, fs);
8483 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8484 gen_store_fpr64(ctx, fp0, fd);
8485 tcg_temp_free_i64(fp0);
8486 }
8487 opn = "recip1.ps";
8488 break;
8489 case OPC_RSQRT1_PS:
8490 check_cp1_64bitmode(ctx);
8491 {
8492 TCGv_i64 fp0 = tcg_temp_new_i64();
8493
8494 gen_load_fpr64(ctx, fp0, fs);
8495 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8496 gen_store_fpr64(ctx, fp0, fd);
8497 tcg_temp_free_i64(fp0);
8498 }
8499 opn = "rsqrt1.ps";
8500 break;
8501 case OPC_RSQRT2_PS:
8502 check_cp1_64bitmode(ctx);
8503 {
8504 TCGv_i64 fp0 = tcg_temp_new_i64();
8505 TCGv_i64 fp1 = tcg_temp_new_i64();
8506
8507 gen_load_fpr64(ctx, fp0, fs);
8508 gen_load_fpr64(ctx, fp1, ft);
8509 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8510 tcg_temp_free_i64(fp1);
8511 gen_store_fpr64(ctx, fp0, fd);
8512 tcg_temp_free_i64(fp0);
8513 }
8514 opn = "rsqrt2.ps";
8515 break;
8516 case OPC_CVT_S_PU:
8517 check_cp1_64bitmode(ctx);
8518 {
8519 TCGv_i32 fp0 = tcg_temp_new_i32();
8520
8521 gen_load_fpr32h(fp0, fs);
8522 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8523 gen_store_fpr32(fp0, fd);
8524 tcg_temp_free_i32(fp0);
8525 }
8526 opn = "cvt.s.pu";
8527 break;
8528 case OPC_CVT_PW_PS:
8529 check_cp1_64bitmode(ctx);
8530 {
8531 TCGv_i64 fp0 = tcg_temp_new_i64();
8532
8533 gen_load_fpr64(ctx, fp0, fs);
8534 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8535 gen_store_fpr64(ctx, fp0, fd);
8536 tcg_temp_free_i64(fp0);
8537 }
8538 opn = "cvt.pw.ps";
8539 break;
8540 case OPC_CVT_S_PL:
8541 check_cp1_64bitmode(ctx);
8542 {
8543 TCGv_i32 fp0 = tcg_temp_new_i32();
8544
8545 gen_load_fpr32(fp0, fs);
8546 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8547 gen_store_fpr32(fp0, fd);
8548 tcg_temp_free_i32(fp0);
8549 }
8550 opn = "cvt.s.pl";
8551 break;
8552 case OPC_PLL_PS:
8553 check_cp1_64bitmode(ctx);
8554 {
8555 TCGv_i32 fp0 = tcg_temp_new_i32();
8556 TCGv_i32 fp1 = tcg_temp_new_i32();
8557
8558 gen_load_fpr32(fp0, fs);
8559 gen_load_fpr32(fp1, ft);
8560 gen_store_fpr32h(fp0, fd);
8561 gen_store_fpr32(fp1, fd);
8562 tcg_temp_free_i32(fp0);
8563 tcg_temp_free_i32(fp1);
8564 }
8565 opn = "pll.ps";
8566 break;
8567 case OPC_PLU_PS:
8568 check_cp1_64bitmode(ctx);
8569 {
8570 TCGv_i32 fp0 = tcg_temp_new_i32();
8571 TCGv_i32 fp1 = tcg_temp_new_i32();
8572
8573 gen_load_fpr32(fp0, fs);
8574 gen_load_fpr32h(fp1, ft);
8575 gen_store_fpr32(fp1, fd);
8576 gen_store_fpr32h(fp0, fd);
8577 tcg_temp_free_i32(fp0);
8578 tcg_temp_free_i32(fp1);
8579 }
8580 opn = "plu.ps";
8581 break;
8582 case OPC_PUL_PS:
8583 check_cp1_64bitmode(ctx);
8584 {
8585 TCGv_i32 fp0 = tcg_temp_new_i32();
8586 TCGv_i32 fp1 = tcg_temp_new_i32();
8587
8588 gen_load_fpr32h(fp0, fs);
8589 gen_load_fpr32(fp1, ft);
8590 gen_store_fpr32(fp1, fd);
8591 gen_store_fpr32h(fp0, fd);
8592 tcg_temp_free_i32(fp0);
8593 tcg_temp_free_i32(fp1);
8594 }
8595 opn = "pul.ps";
8596 break;
8597 case OPC_PUU_PS:
8598 check_cp1_64bitmode(ctx);
8599 {
8600 TCGv_i32 fp0 = tcg_temp_new_i32();
8601 TCGv_i32 fp1 = tcg_temp_new_i32();
8602
8603 gen_load_fpr32h(fp0, fs);
8604 gen_load_fpr32h(fp1, ft);
8605 gen_store_fpr32(fp1, fd);
8606 gen_store_fpr32h(fp0, fd);
8607 tcg_temp_free_i32(fp0);
8608 tcg_temp_free_i32(fp1);
8609 }
8610 opn = "puu.ps";
8611 break;
8612 case OPC_CMP_F_PS:
8613 case OPC_CMP_UN_PS:
8614 case OPC_CMP_EQ_PS:
8615 case OPC_CMP_UEQ_PS:
8616 case OPC_CMP_OLT_PS:
8617 case OPC_CMP_ULT_PS:
8618 case OPC_CMP_OLE_PS:
8619 case OPC_CMP_ULE_PS:
8620 case OPC_CMP_SF_PS:
8621 case OPC_CMP_NGLE_PS:
8622 case OPC_CMP_SEQ_PS:
8623 case OPC_CMP_NGL_PS:
8624 case OPC_CMP_LT_PS:
8625 case OPC_CMP_NGE_PS:
8626 case OPC_CMP_LE_PS:
8627 case OPC_CMP_NGT_PS:
8628 if (ctx->opcode & (1 << 6)) {
8629 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8630 opn = condnames_abs[func-48];
8631 } else {
8632 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8633 opn = condnames[func-48];
8634 }
8635 break;
8636 default:
8637 MIPS_INVAL(opn);
8638 generate_exception (ctx, EXCP_RI);
8639 return;
8640 }
8641 (void)opn; /* avoid a compiler warning */
8642 switch (optype) {
8643 case BINOP:
8644 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8645 break;
8646 case CMPOP:
8647 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8648 break;
8649 default:
8650 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8651 break;
8652 }
8653 }
8654
8655 /* Coprocessor 3 (FPU) */
8656 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8657 int fd, int fs, int base, int index)
8658 {
8659 const char *opn = "extended float load/store";
8660 int store = 0;
8661 TCGv t0 = tcg_temp_new();
8662
8663 if (base == 0) {
8664 gen_load_gpr(t0, index);
8665 } else if (index == 0) {
8666 gen_load_gpr(t0, base);
8667 } else {
8668 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8669 }
8670 /* Don't do NOP if destination is zero: we must perform the actual
8671 memory access. */
8672 switch (opc) {
8673 case OPC_LWXC1:
8674 check_cop1x(ctx);
8675 {
8676 TCGv_i32 fp0 = tcg_temp_new_i32();
8677
8678 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8679 tcg_gen_trunc_tl_i32(fp0, t0);
8680 gen_store_fpr32(fp0, fd);
8681 tcg_temp_free_i32(fp0);
8682 }
8683 opn = "lwxc1";
8684 break;
8685 case OPC_LDXC1:
8686 check_cop1x(ctx);
8687 check_cp1_registers(ctx, fd);
8688 {
8689 TCGv_i64 fp0 = tcg_temp_new_i64();
8690
8691 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8692 gen_store_fpr64(ctx, fp0, fd);
8693 tcg_temp_free_i64(fp0);
8694 }
8695 opn = "ldxc1";
8696 break;
8697 case OPC_LUXC1:
8698 check_cp1_64bitmode(ctx);
8699 tcg_gen_andi_tl(t0, t0, ~0x7);
8700 {
8701 TCGv_i64 fp0 = tcg_temp_new_i64();
8702
8703 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8704 gen_store_fpr64(ctx, fp0, fd);
8705 tcg_temp_free_i64(fp0);
8706 }
8707 opn = "luxc1";
8708 break;
8709 case OPC_SWXC1:
8710 check_cop1x(ctx);
8711 {
8712 TCGv_i32 fp0 = tcg_temp_new_i32();
8713 TCGv t1 = tcg_temp_new();
8714
8715 gen_load_fpr32(fp0, fs);
8716 tcg_gen_extu_i32_tl(t1, fp0);
8717 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8718 tcg_temp_free_i32(fp0);
8719 tcg_temp_free(t1);
8720 }
8721 opn = "swxc1";
8722 store = 1;
8723 break;
8724 case OPC_SDXC1:
8725 check_cop1x(ctx);
8726 check_cp1_registers(ctx, fs);
8727 {
8728 TCGv_i64 fp0 = tcg_temp_new_i64();
8729
8730 gen_load_fpr64(ctx, fp0, fs);
8731 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8732 tcg_temp_free_i64(fp0);
8733 }
8734 opn = "sdxc1";
8735 store = 1;
8736 break;
8737 case OPC_SUXC1:
8738 check_cp1_64bitmode(ctx);
8739 tcg_gen_andi_tl(t0, t0, ~0x7);
8740 {
8741 TCGv_i64 fp0 = tcg_temp_new_i64();
8742
8743 gen_load_fpr64(ctx, fp0, fs);
8744 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8745 tcg_temp_free_i64(fp0);
8746 }
8747 opn = "suxc1";
8748 store = 1;
8749 break;
8750 }
8751 tcg_temp_free(t0);
8752 (void)opn; (void)store; /* avoid compiler warnings */
8753 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8754 regnames[index], regnames[base]);
8755 }
8756
8757 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8758 int fd, int fr, int fs, int ft)
8759 {
8760 const char *opn = "flt3_arith";
8761
8762 switch (opc) {
8763 case OPC_ALNV_PS:
8764 check_cp1_64bitmode(ctx);
8765 {
8766 TCGv t0 = tcg_temp_local_new();
8767 TCGv_i32 fp = tcg_temp_new_i32();
8768 TCGv_i32 fph = tcg_temp_new_i32();
8769 int l1 = gen_new_label();
8770 int l2 = gen_new_label();
8771
8772 gen_load_gpr(t0, fr);
8773 tcg_gen_andi_tl(t0, t0, 0x7);
8774
8775 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8776 gen_load_fpr32(fp, fs);
8777 gen_load_fpr32h(fph, fs);
8778 gen_store_fpr32(fp, fd);
8779 gen_store_fpr32h(fph, fd);
8780 tcg_gen_br(l2);
8781 gen_set_label(l1);
8782 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8783 tcg_temp_free(t0);
8784 #ifdef TARGET_WORDS_BIGENDIAN
8785 gen_load_fpr32(fp, fs);
8786 gen_load_fpr32h(fph, ft);
8787 gen_store_fpr32h(fp, fd);
8788 gen_store_fpr32(fph, fd);
8789 #else
8790 gen_load_fpr32h(fph, fs);
8791 gen_load_fpr32(fp, ft);
8792 gen_store_fpr32(fph, fd);
8793 gen_store_fpr32h(fp, fd);
8794 #endif
8795 gen_set_label(l2);
8796 tcg_temp_free_i32(fp);
8797 tcg_temp_free_i32(fph);
8798 }
8799 opn = "alnv.ps";
8800 break;
8801 case OPC_MADD_S:
8802 check_cop1x(ctx);
8803 {
8804 TCGv_i32 fp0 = tcg_temp_new_i32();
8805 TCGv_i32 fp1 = tcg_temp_new_i32();
8806 TCGv_i32 fp2 = tcg_temp_new_i32();
8807
8808 gen_load_fpr32(fp0, fs);
8809 gen_load_fpr32(fp1, ft);
8810 gen_load_fpr32(fp2, fr);
8811 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8812 tcg_temp_free_i32(fp0);
8813 tcg_temp_free_i32(fp1);
8814 gen_store_fpr32(fp2, fd);
8815 tcg_temp_free_i32(fp2);
8816 }
8817 opn = "madd.s";
8818 break;
8819 case OPC_MADD_D:
8820 check_cop1x(ctx);
8821 check_cp1_registers(ctx, fd | fs | ft | fr);
8822 {
8823 TCGv_i64 fp0 = tcg_temp_new_i64();
8824 TCGv_i64 fp1 = tcg_temp_new_i64();
8825 TCGv_i64 fp2 = tcg_temp_new_i64();
8826
8827 gen_load_fpr64(ctx, fp0, fs);
8828 gen_load_fpr64(ctx, fp1, ft);
8829 gen_load_fpr64(ctx, fp2, fr);
8830 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8831 tcg_temp_free_i64(fp0);
8832 tcg_temp_free_i64(fp1);
8833 gen_store_fpr64(ctx, fp2, fd);
8834 tcg_temp_free_i64(fp2);
8835 }
8836 opn = "madd.d";
8837 break;
8838 case OPC_MADD_PS:
8839 check_cp1_64bitmode(ctx);
8840 {
8841 TCGv_i64 fp0 = tcg_temp_new_i64();
8842 TCGv_i64 fp1 = tcg_temp_new_i64();
8843 TCGv_i64 fp2 = tcg_temp_new_i64();
8844
8845 gen_load_fpr64(ctx, fp0, fs);
8846 gen_load_fpr64(ctx, fp1, ft);
8847 gen_load_fpr64(ctx, fp2, fr);
8848 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8849 tcg_temp_free_i64(fp0);
8850 tcg_temp_free_i64(fp1);
8851 gen_store_fpr64(ctx, fp2, fd);
8852 tcg_temp_free_i64(fp2);
8853 }
8854 opn = "madd.ps";
8855 break;
8856 case OPC_MSUB_S:
8857 check_cop1x(ctx);
8858 {
8859 TCGv_i32 fp0 = tcg_temp_new_i32();
8860 TCGv_i32 fp1 = tcg_temp_new_i32();
8861 TCGv_i32 fp2 = tcg_temp_new_i32();
8862
8863 gen_load_fpr32(fp0, fs);
8864 gen_load_fpr32(fp1, ft);
8865 gen_load_fpr32(fp2, fr);
8866 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8867 tcg_temp_free_i32(fp0);
8868 tcg_temp_free_i32(fp1);
8869 gen_store_fpr32(fp2, fd);
8870 tcg_temp_free_i32(fp2);
8871 }
8872 opn = "msub.s";
8873 break;
8874 case OPC_MSUB_D:
8875 check_cop1x(ctx);
8876 check_cp1_registers(ctx, fd | fs | ft | fr);
8877 {
8878 TCGv_i64 fp0 = tcg_temp_new_i64();
8879 TCGv_i64 fp1 = tcg_temp_new_i64();
8880 TCGv_i64 fp2 = tcg_temp_new_i64();
8881
8882 gen_load_fpr64(ctx, fp0, fs);
8883 gen_load_fpr64(ctx, fp1, ft);
8884 gen_load_fpr64(ctx, fp2, fr);
8885 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8886 tcg_temp_free_i64(fp0);
8887 tcg_temp_free_i64(fp1);
8888 gen_store_fpr64(ctx, fp2, fd);
8889 tcg_temp_free_i64(fp2);
8890 }
8891 opn = "msub.d";
8892 break;
8893 case OPC_MSUB_PS:
8894 check_cp1_64bitmode(ctx);
8895 {
8896 TCGv_i64 fp0 = tcg_temp_new_i64();
8897 TCGv_i64 fp1 = tcg_temp_new_i64();
8898 TCGv_i64 fp2 = tcg_temp_new_i64();
8899
8900 gen_load_fpr64(ctx, fp0, fs);
8901 gen_load_fpr64(ctx, fp1, ft);
8902 gen_load_fpr64(ctx, fp2, fr);
8903 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8904 tcg_temp_free_i64(fp0);
8905 tcg_temp_free_i64(fp1);
8906 gen_store_fpr64(ctx, fp2, fd);
8907 tcg_temp_free_i64(fp2);
8908 }
8909 opn = "msub.ps";
8910 break;
8911 case OPC_NMADD_S:
8912 check_cop1x(ctx);
8913 {
8914 TCGv_i32 fp0 = tcg_temp_new_i32();
8915 TCGv_i32 fp1 = tcg_temp_new_i32();
8916 TCGv_i32 fp2 = tcg_temp_new_i32();
8917
8918 gen_load_fpr32(fp0, fs);
8919 gen_load_fpr32(fp1, ft);
8920 gen_load_fpr32(fp2, fr);
8921 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8922 tcg_temp_free_i32(fp0);
8923 tcg_temp_free_i32(fp1);
8924 gen_store_fpr32(fp2, fd);
8925 tcg_temp_free_i32(fp2);
8926 }
8927 opn = "nmadd.s";
8928 break;
8929 case OPC_NMADD_D:
8930 check_cop1x(ctx);
8931 check_cp1_registers(ctx, fd | fs | ft | fr);
8932 {
8933 TCGv_i64 fp0 = tcg_temp_new_i64();
8934 TCGv_i64 fp1 = tcg_temp_new_i64();
8935 TCGv_i64 fp2 = tcg_temp_new_i64();
8936
8937 gen_load_fpr64(ctx, fp0, fs);
8938 gen_load_fpr64(ctx, fp1, ft);
8939 gen_load_fpr64(ctx, fp2, fr);
8940 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8941 tcg_temp_free_i64(fp0);
8942 tcg_temp_free_i64(fp1);
8943 gen_store_fpr64(ctx, fp2, fd);
8944 tcg_temp_free_i64(fp2);
8945 }
8946 opn = "nmadd.d";
8947 break;
8948 case OPC_NMADD_PS:
8949 check_cp1_64bitmode(ctx);
8950 {
8951 TCGv_i64 fp0 = tcg_temp_new_i64();
8952 TCGv_i64 fp1 = tcg_temp_new_i64();
8953 TCGv_i64 fp2 = tcg_temp_new_i64();
8954
8955 gen_load_fpr64(ctx, fp0, fs);
8956 gen_load_fpr64(ctx, fp1, ft);
8957 gen_load_fpr64(ctx, fp2, fr);
8958 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8959 tcg_temp_free_i64(fp0);
8960 tcg_temp_free_i64(fp1);
8961 gen_store_fpr64(ctx, fp2, fd);
8962 tcg_temp_free_i64(fp2);
8963 }
8964 opn = "nmadd.ps";
8965 break;
8966 case OPC_NMSUB_S:
8967 check_cop1x(ctx);
8968 {
8969 TCGv_i32 fp0 = tcg_temp_new_i32();
8970 TCGv_i32 fp1 = tcg_temp_new_i32();
8971 TCGv_i32 fp2 = tcg_temp_new_i32();
8972
8973 gen_load_fpr32(fp0, fs);
8974 gen_load_fpr32(fp1, ft);
8975 gen_load_fpr32(fp2, fr);
8976 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8977 tcg_temp_free_i32(fp0);
8978 tcg_temp_free_i32(fp1);
8979 gen_store_fpr32(fp2, fd);
8980 tcg_temp_free_i32(fp2);
8981 }
8982 opn = "nmsub.s";
8983 break;
8984 case OPC_NMSUB_D:
8985 check_cop1x(ctx);
8986 check_cp1_registers(ctx, fd | fs | ft | fr);
8987 {
8988 TCGv_i64 fp0 = tcg_temp_new_i64();
8989 TCGv_i64 fp1 = tcg_temp_new_i64();
8990 TCGv_i64 fp2 = tcg_temp_new_i64();
8991
8992 gen_load_fpr64(ctx, fp0, fs);
8993 gen_load_fpr64(ctx, fp1, ft);
8994 gen_load_fpr64(ctx, fp2, fr);
8995 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
8996 tcg_temp_free_i64(fp0);
8997 tcg_temp_free_i64(fp1);
8998 gen_store_fpr64(ctx, fp2, fd);
8999 tcg_temp_free_i64(fp2);
9000 }
9001 opn = "nmsub.d";
9002 break;
9003 case OPC_NMSUB_PS:
9004 check_cp1_64bitmode(ctx);
9005 {
9006 TCGv_i64 fp0 = tcg_temp_new_i64();
9007 TCGv_i64 fp1 = tcg_temp_new_i64();
9008 TCGv_i64 fp2 = tcg_temp_new_i64();
9009
9010 gen_load_fpr64(ctx, fp0, fs);
9011 gen_load_fpr64(ctx, fp1, ft);
9012 gen_load_fpr64(ctx, fp2, fr);
9013 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9014 tcg_temp_free_i64(fp0);
9015 tcg_temp_free_i64(fp1);
9016 gen_store_fpr64(ctx, fp2, fd);
9017 tcg_temp_free_i64(fp2);
9018 }
9019 opn = "nmsub.ps";
9020 break;
9021 default:
9022 MIPS_INVAL(opn);
9023 generate_exception (ctx, EXCP_RI);
9024 return;
9025 }
9026 (void)opn; /* avoid a compiler warning */
9027 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9028 fregnames[fs], fregnames[ft]);
9029 }
9030
9031 static void
9032 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
9033 {
9034 TCGv t0;
9035
9036 #if !defined(CONFIG_USER_ONLY)
9037 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9038 Therefore only check the ISA in system mode. */
9039 check_insn(env, ctx, ISA_MIPS32R2);
9040 #endif
9041 t0 = tcg_temp_new();
9042
9043 switch (rd) {
9044 case 0:
9045 save_cpu_state(ctx, 1);
9046 gen_helper_rdhwr_cpunum(t0, cpu_env);
9047 gen_store_gpr(t0, rt);
9048 break;
9049 case 1:
9050 save_cpu_state(ctx, 1);
9051 gen_helper_rdhwr_synci_step(t0, cpu_env);
9052 gen_store_gpr(t0, rt);
9053 break;
9054 case 2:
9055 save_cpu_state(ctx, 1);
9056 gen_helper_rdhwr_cc(t0, cpu_env);
9057 gen_store_gpr(t0, rt);
9058 break;
9059 case 3:
9060 save_cpu_state(ctx, 1);
9061 gen_helper_rdhwr_ccres(t0, cpu_env);
9062 gen_store_gpr(t0, rt);
9063 break;
9064 case 29:
9065 #if defined(CONFIG_USER_ONLY)
9066 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9067 gen_store_gpr(t0, rt);
9068 break;
9069 #else
9070 /* XXX: Some CPUs implement this in hardware.
9071 Not supported yet. */
9072 #endif
9073 default: /* Invalid */
9074 MIPS_INVAL("rdhwr");
9075 generate_exception(ctx, EXCP_RI);
9076 break;
9077 }
9078 tcg_temp_free(t0);
9079 }
9080
9081 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
9082 int insn_bytes)
9083 {
9084 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9085 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9086 /* Branches completion */
9087 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9088 ctx->bstate = BS_BRANCH;
9089 save_cpu_state(ctx, 0);
9090 /* FIXME: Need to clear can_do_io. */
9091 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9092 case MIPS_HFLAG_B:
9093 /* unconditional branch */
9094 MIPS_DEBUG("unconditional branch");
9095 if (proc_hflags & MIPS_HFLAG_BX) {
9096 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9097 }
9098 gen_goto_tb(ctx, 0, ctx->btarget);
9099 break;
9100 case MIPS_HFLAG_BL:
9101 /* blikely taken case */
9102 MIPS_DEBUG("blikely branch taken");
9103 gen_goto_tb(ctx, 0, ctx->btarget);
9104 break;
9105 case MIPS_HFLAG_BC:
9106 /* Conditional branch */
9107 MIPS_DEBUG("conditional branch");
9108 {
9109 int l1 = gen_new_label();
9110
9111 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9112 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9113 gen_set_label(l1);
9114 gen_goto_tb(ctx, 0, ctx->btarget);
9115 }
9116 break;
9117 case MIPS_HFLAG_BR:
9118 /* unconditional branch to register */
9119 MIPS_DEBUG("branch to register");
9120 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9121 TCGv t0 = tcg_temp_new();
9122 TCGv_i32 t1 = tcg_temp_new_i32();
9123
9124 tcg_gen_andi_tl(t0, btarget, 0x1);
9125 tcg_gen_trunc_tl_i32(t1, t0);
9126 tcg_temp_free(t0);
9127 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9128 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9129 tcg_gen_or_i32(hflags, hflags, t1);
9130 tcg_temp_free_i32(t1);
9131
9132 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9133 } else {
9134 tcg_gen_mov_tl(cpu_PC, btarget);
9135 }
9136 if (ctx->singlestep_enabled) {
9137 save_cpu_state(ctx, 0);
9138 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9139 }
9140 tcg_gen_exit_tb(0);
9141 break;
9142 default:
9143 MIPS_DEBUG("unknown branch");
9144 break;
9145 }
9146 }
9147 }
9148
9149 /* ISA extensions (ASEs) */
9150 /* MIPS16 extension to MIPS32 */
9151
9152 /* MIPS16 major opcodes */
9153 enum {
9154 M16_OPC_ADDIUSP = 0x00,
9155 M16_OPC_ADDIUPC = 0x01,
9156 M16_OPC_B = 0x02,
9157 M16_OPC_JAL = 0x03,
9158 M16_OPC_BEQZ = 0x04,
9159 M16_OPC_BNEQZ = 0x05,
9160 M16_OPC_SHIFT = 0x06,
9161 M16_OPC_LD = 0x07,
9162 M16_OPC_RRIA = 0x08,
9163 M16_OPC_ADDIU8 = 0x09,
9164 M16_OPC_SLTI = 0x0a,
9165 M16_OPC_SLTIU = 0x0b,
9166 M16_OPC_I8 = 0x0c,
9167 M16_OPC_LI = 0x0d,
9168 M16_OPC_CMPI = 0x0e,
9169 M16_OPC_SD = 0x0f,
9170 M16_OPC_LB = 0x10,
9171 M16_OPC_LH = 0x11,
9172 M16_OPC_LWSP = 0x12,
9173 M16_OPC_LW = 0x13,
9174 M16_OPC_LBU = 0x14,
9175 M16_OPC_LHU = 0x15,
9176 M16_OPC_LWPC = 0x16,
9177 M16_OPC_LWU = 0x17,
9178 M16_OPC_SB = 0x18,
9179 M16_OPC_SH = 0x19,
9180 M16_OPC_SWSP = 0x1a,
9181 M16_OPC_SW = 0x1b,
9182 M16_OPC_RRR = 0x1c,
9183 M16_OPC_RR = 0x1d,
9184 M16_OPC_EXTEND = 0x1e,
9185 M16_OPC_I64 = 0x1f
9186 };
9187
9188 /* I8 funct field */
9189 enum {
9190 I8_BTEQZ = 0x0,
9191 I8_BTNEZ = 0x1,
9192 I8_SWRASP = 0x2,
9193 I8_ADJSP = 0x3,
9194 I8_SVRS = 0x4,
9195 I8_MOV32R = 0x5,
9196 I8_MOVR32 = 0x7
9197 };
9198
9199 /* RRR f field */
9200 enum {
9201 RRR_DADDU = 0x0,
9202 RRR_ADDU = 0x1,
9203 RRR_DSUBU = 0x2,
9204 RRR_SUBU = 0x3
9205 };
9206
9207 /* RR funct field */
9208 enum {
9209 RR_JR = 0x00,
9210 RR_SDBBP = 0x01,
9211 RR_SLT = 0x02,
9212 RR_SLTU = 0x03,
9213 RR_SLLV = 0x04,
9214 RR_BREAK = 0x05,
9215 RR_SRLV = 0x06,
9216 RR_SRAV = 0x07,
9217 RR_DSRL = 0x08,
9218 RR_CMP = 0x0a,
9219 RR_NEG = 0x0b,
9220 RR_AND = 0x0c,
9221 RR_OR = 0x0d,
9222 RR_XOR = 0x0e,
9223 RR_NOT = 0x0f,
9224 RR_MFHI = 0x10,
9225 RR_CNVT = 0x11,
9226 RR_MFLO = 0x12,
9227 RR_DSRA = 0x13,
9228 RR_DSLLV = 0x14,
9229 RR_DSRLV = 0x16,
9230 RR_DSRAV = 0x17,
9231 RR_MULT = 0x18,
9232 RR_MULTU = 0x19,
9233 RR_DIV = 0x1a,
9234 RR_DIVU = 0x1b,
9235 RR_DMULT = 0x1c,
9236 RR_DMULTU = 0x1d,
9237 RR_DDIV = 0x1e,
9238 RR_DDIVU = 0x1f
9239 };
9240
9241 /* I64 funct field */
9242 enum {
9243 I64_LDSP = 0x0,
9244 I64_SDSP = 0x1,
9245 I64_SDRASP = 0x2,
9246 I64_DADJSP = 0x3,
9247 I64_LDPC = 0x4,
9248 I64_DADDIU5 = 0x5,
9249 I64_DADDIUPC = 0x6,
9250 I64_DADDIUSP = 0x7
9251 };
9252
9253 /* RR ry field for CNVT */
9254 enum {
9255 RR_RY_CNVT_ZEB = 0x0,
9256 RR_RY_CNVT_ZEH = 0x1,
9257 RR_RY_CNVT_ZEW = 0x2,
9258 RR_RY_CNVT_SEB = 0x4,
9259 RR_RY_CNVT_SEH = 0x5,
9260 RR_RY_CNVT_SEW = 0x6,
9261 };
9262
9263 static int xlat (int r)
9264 {
9265 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9266
9267 return map[r];
9268 }
9269
9270 static void gen_mips16_save (DisasContext *ctx,
9271 int xsregs, int aregs,
9272 int do_ra, int do_s0, int do_s1,
9273 int framesize)
9274 {
9275 TCGv t0 = tcg_temp_new();
9276 TCGv t1 = tcg_temp_new();
9277 int args, astatic;
9278
9279 switch (aregs) {
9280 case 0:
9281 case 1:
9282 case 2:
9283 case 3:
9284 case 11:
9285 args = 0;
9286 break;
9287 case 4:
9288 case 5:
9289 case 6:
9290 case 7:
9291 args = 1;
9292 break;
9293 case 8:
9294 case 9:
9295 case 10:
9296 args = 2;
9297 break;
9298 case 12:
9299 case 13:
9300 args = 3;
9301 break;
9302 case 14:
9303 args = 4;
9304 break;
9305 default:
9306 generate_exception(ctx, EXCP_RI);
9307 return;
9308 }
9309
9310 switch (args) {
9311 case 4:
9312 gen_base_offset_addr(ctx, t0, 29, 12);
9313 gen_load_gpr(t1, 7);
9314 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9315 /* Fall through */
9316 case 3:
9317 gen_base_offset_addr(ctx, t0, 29, 8);
9318 gen_load_gpr(t1, 6);
9319 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9320 /* Fall through */
9321 case 2:
9322 gen_base_offset_addr(ctx, t0, 29, 4);
9323 gen_load_gpr(t1, 5);
9324 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9325 /* Fall through */
9326 case 1:
9327 gen_base_offset_addr(ctx, t0, 29, 0);
9328 gen_load_gpr(t1, 4);
9329 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9330 }
9331
9332 gen_load_gpr(t0, 29);
9333
9334 #define DECR_AND_STORE(reg) do { \
9335 tcg_gen_subi_tl(t0, t0, 4); \
9336 gen_load_gpr(t1, reg); \
9337 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9338 } while (0)
9339
9340 if (do_ra) {
9341 DECR_AND_STORE(31);
9342 }
9343
9344 switch (xsregs) {
9345 case 7:
9346 DECR_AND_STORE(30);
9347 /* Fall through */
9348 case 6:
9349 DECR_AND_STORE(23);
9350 /* Fall through */
9351 case 5:
9352 DECR_AND_STORE(22);
9353 /* Fall through */
9354 case 4:
9355 DECR_AND_STORE(21);
9356 /* Fall through */
9357 case 3:
9358 DECR_AND_STORE(20);
9359 /* Fall through */
9360 case 2:
9361 DECR_AND_STORE(19);
9362 /* Fall through */
9363 case 1:
9364 DECR_AND_STORE(18);
9365 }
9366
9367 if (do_s1) {
9368 DECR_AND_STORE(17);
9369 }
9370 if (do_s0) {
9371 DECR_AND_STORE(16);
9372 }
9373
9374 switch (aregs) {
9375 case 0:
9376 case 4:
9377 case 8:
9378 case 12:
9379 case 14:
9380 astatic = 0;
9381 break;
9382 case 1:
9383 case 5:
9384 case 9:
9385 case 13:
9386 astatic = 1;
9387 break;
9388 case 2:
9389 case 6:
9390 case 10:
9391 astatic = 2;
9392 break;
9393 case 3:
9394 case 7:
9395 astatic = 3;
9396 break;
9397 case 11:
9398 astatic = 4;
9399 break;
9400 default:
9401 generate_exception(ctx, EXCP_RI);
9402 return;
9403 }
9404
9405 if (astatic > 0) {
9406 DECR_AND_STORE(7);
9407 if (astatic > 1) {
9408 DECR_AND_STORE(6);
9409 if (astatic > 2) {
9410 DECR_AND_STORE(5);
9411 if (astatic > 3) {
9412 DECR_AND_STORE(4);
9413 }
9414 }
9415 }
9416 }
9417 #undef DECR_AND_STORE
9418
9419 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9420 tcg_temp_free(t0);
9421 tcg_temp_free(t1);
9422 }
9423
9424 static void gen_mips16_restore (DisasContext *ctx,
9425 int xsregs, int aregs,
9426 int do_ra, int do_s0, int do_s1,
9427 int framesize)
9428 {
9429 int astatic;
9430 TCGv t0 = tcg_temp_new();
9431 TCGv t1 = tcg_temp_new();
9432
9433 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9434
9435 #define DECR_AND_LOAD(reg) do { \
9436 tcg_gen_subi_tl(t0, t0, 4); \
9437 tcg_gen_qemu_ld32u(t1, t0, ctx->mem_idx); \
9438 gen_store_gpr(t1, reg); \
9439 } while (0)
9440
9441 if (do_ra) {
9442 DECR_AND_LOAD(31);
9443 }
9444
9445 switch (xsregs) {
9446 case 7:
9447 DECR_AND_LOAD(30);
9448 /* Fall through */
9449 case 6:
9450 DECR_AND_LOAD(23);
9451 /* Fall through */
9452 case 5:
9453 DECR_AND_LOAD(22);
9454 /* Fall through */
9455 case 4:
9456 DECR_AND_LOAD(21);
9457 /* Fall through */
9458 case 3:
9459 DECR_AND_LOAD(20);
9460 /* Fall through */
9461 case 2:
9462 DECR_AND_LOAD(19);
9463 /* Fall through */
9464 case 1:
9465 DECR_AND_LOAD(18);
9466 }
9467
9468 if (do_s1) {
9469 DECR_AND_LOAD(17);
9470 }
9471 if (do_s0) {
9472 DECR_AND_LOAD(16);
9473 }
9474
9475 switch (aregs) {
9476 case 0:
9477 case 4:
9478 case 8:
9479 case 12:
9480 case 14:
9481 astatic = 0;
9482 break;
9483 case 1:
9484 case 5:
9485 case 9:
9486 case 13:
9487 astatic = 1;
9488 break;
9489 case 2:
9490 case 6:
9491 case 10:
9492 astatic = 2;
9493 break;
9494 case 3:
9495 case 7:
9496 astatic = 3;
9497 break;
9498 case 11:
9499 astatic = 4;
9500 break;
9501 default:
9502 generate_exception(ctx, EXCP_RI);
9503 return;
9504 }
9505
9506 if (astatic > 0) {
9507 DECR_AND_LOAD(7);
9508 if (astatic > 1) {
9509 DECR_AND_LOAD(6);
9510 if (astatic > 2) {
9511 DECR_AND_LOAD(5);
9512 if (astatic > 3) {
9513 DECR_AND_LOAD(4);
9514 }
9515 }
9516 }
9517 }
9518 #undef DECR_AND_LOAD
9519
9520 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9521 tcg_temp_free(t0);
9522 tcg_temp_free(t1);
9523 }
9524
9525 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9526 int is_64_bit, int extended)
9527 {
9528 TCGv t0;
9529
9530 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9531 generate_exception(ctx, EXCP_RI);
9532 return;
9533 }
9534
9535 t0 = tcg_temp_new();
9536
9537 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9538 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9539 if (!is_64_bit) {
9540 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9541 }
9542
9543 tcg_temp_free(t0);
9544 }
9545
9546 #if defined(TARGET_MIPS64)
9547 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9548 int ry, int funct, int16_t offset,
9549 int extended)
9550 {
9551 switch (funct) {
9552 case I64_LDSP:
9553 check_mips_64(ctx);
9554 offset = extended ? offset : offset << 3;
9555 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9556 break;
9557 case I64_SDSP:
9558 check_mips_64(ctx);
9559 offset = extended ? offset : offset << 3;
9560 gen_st(ctx, OPC_SD, ry, 29, offset);
9561 break;
9562 case I64_SDRASP:
9563 check_mips_64(ctx);
9564 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9565 gen_st(ctx, OPC_SD, 31, 29, offset);
9566 break;
9567 case I64_DADJSP:
9568 check_mips_64(ctx);
9569 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9570 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9571 break;
9572 case I64_LDPC:
9573 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9574 generate_exception(ctx, EXCP_RI);
9575 } else {
9576 offset = extended ? offset : offset << 3;
9577 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9578 }
9579 break;
9580 case I64_DADDIU5:
9581 check_mips_64(ctx);
9582 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9583 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9584 break;
9585 case I64_DADDIUPC:
9586 check_mips_64(ctx);
9587 offset = extended ? offset : offset << 2;
9588 gen_addiupc(ctx, ry, offset, 1, extended);
9589 break;
9590 case I64_DADDIUSP:
9591 check_mips_64(ctx);
9592 offset = extended ? offset : offset << 2;
9593 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9594 break;
9595 }
9596 }
9597 #endif
9598
9599 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9600 int *is_branch)
9601 {
9602 int extend = cpu_lduw_code(env, ctx->pc + 2);
9603 int op, rx, ry, funct, sa;
9604 int16_t imm, offset;
9605
9606 ctx->opcode = (ctx->opcode << 16) | extend;
9607 op = (ctx->opcode >> 11) & 0x1f;
9608 sa = (ctx->opcode >> 22) & 0x1f;
9609 funct = (ctx->opcode >> 8) & 0x7;
9610 rx = xlat((ctx->opcode >> 8) & 0x7);
9611 ry = xlat((ctx->opcode >> 5) & 0x7);
9612 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9613 | ((ctx->opcode >> 21) & 0x3f) << 5
9614 | (ctx->opcode & 0x1f));
9615
9616 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9617 counterparts. */
9618 switch (op) {
9619 case M16_OPC_ADDIUSP:
9620 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9621 break;
9622 case M16_OPC_ADDIUPC:
9623 gen_addiupc(ctx, rx, imm, 0, 1);
9624 break;
9625 case M16_OPC_B:
9626 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9627 /* No delay slot, so just process as a normal instruction */
9628 break;
9629 case M16_OPC_BEQZ:
9630 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9631 /* No delay slot, so just process as a normal instruction */
9632 break;
9633 case M16_OPC_BNEQZ:
9634 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9635 /* No delay slot, so just process as a normal instruction */
9636 break;
9637 case M16_OPC_SHIFT:
9638 switch (ctx->opcode & 0x3) {
9639 case 0x0:
9640 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9641 break;
9642 case 0x1:
9643 #if defined(TARGET_MIPS64)
9644 check_mips_64(ctx);
9645 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9646 #else
9647 generate_exception(ctx, EXCP_RI);
9648 #endif
9649 break;
9650 case 0x2:
9651 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9652 break;
9653 case 0x3:
9654 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9655 break;
9656 }
9657 break;
9658 #if defined(TARGET_MIPS64)
9659 case M16_OPC_LD:
9660 check_mips_64(ctx);
9661 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9662 break;
9663 #endif
9664 case M16_OPC_RRIA:
9665 imm = ctx->opcode & 0xf;
9666 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9667 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9668 imm = (int16_t) (imm << 1) >> 1;
9669 if ((ctx->opcode >> 4) & 0x1) {
9670 #if defined(TARGET_MIPS64)
9671 check_mips_64(ctx);
9672 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9673 #else
9674 generate_exception(ctx, EXCP_RI);
9675 #endif
9676 } else {
9677 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9678 }
9679 break;
9680 case M16_OPC_ADDIU8:
9681 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9682 break;
9683 case M16_OPC_SLTI:
9684 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9685 break;
9686 case M16_OPC_SLTIU:
9687 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9688 break;
9689 case M16_OPC_I8:
9690 switch (funct) {
9691 case I8_BTEQZ:
9692 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9693 break;
9694 case I8_BTNEZ:
9695 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9696 break;
9697 case I8_SWRASP:
9698 gen_st(ctx, OPC_SW, 31, 29, imm);
9699 break;
9700 case I8_ADJSP:
9701 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9702 break;
9703 case I8_SVRS:
9704 {
9705 int xsregs = (ctx->opcode >> 24) & 0x7;
9706 int aregs = (ctx->opcode >> 16) & 0xf;
9707 int do_ra = (ctx->opcode >> 6) & 0x1;
9708 int do_s0 = (ctx->opcode >> 5) & 0x1;
9709 int do_s1 = (ctx->opcode >> 4) & 0x1;
9710 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9711 | (ctx->opcode & 0xf)) << 3;
9712
9713 if (ctx->opcode & (1 << 7)) {
9714 gen_mips16_save(ctx, xsregs, aregs,
9715 do_ra, do_s0, do_s1,
9716 framesize);
9717 } else {
9718 gen_mips16_restore(ctx, xsregs, aregs,
9719 do_ra, do_s0, do_s1,
9720 framesize);
9721 }
9722 }
9723 break;
9724 default:
9725 generate_exception(ctx, EXCP_RI);
9726 break;
9727 }
9728 break;
9729 case M16_OPC_LI:
9730 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9731 break;
9732 case M16_OPC_CMPI:
9733 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9734 break;
9735 #if defined(TARGET_MIPS64)
9736 case M16_OPC_SD:
9737 gen_st(ctx, OPC_SD, ry, rx, offset);
9738 break;
9739 #endif
9740 case M16_OPC_LB:
9741 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9742 break;
9743 case M16_OPC_LH:
9744 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9745 break;
9746 case M16_OPC_LWSP:
9747 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9748 break;
9749 case M16_OPC_LW:
9750 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9751 break;
9752 case M16_OPC_LBU:
9753 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9754 break;
9755 case M16_OPC_LHU:
9756 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9757 break;
9758 case M16_OPC_LWPC:
9759 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9760 break;
9761 #if defined(TARGET_MIPS64)
9762 case M16_OPC_LWU:
9763 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9764 break;
9765 #endif
9766 case M16_OPC_SB:
9767 gen_st(ctx, OPC_SB, ry, rx, offset);
9768 break;
9769 case M16_OPC_SH:
9770 gen_st(ctx, OPC_SH, ry, rx, offset);
9771 break;
9772 case M16_OPC_SWSP:
9773 gen_st(ctx, OPC_SW, rx, 29, offset);
9774 break;
9775 case M16_OPC_SW:
9776 gen_st(ctx, OPC_SW, ry, rx, offset);
9777 break;
9778 #if defined(TARGET_MIPS64)
9779 case M16_OPC_I64:
9780 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9781 break;
9782 #endif
9783 default:
9784 generate_exception(ctx, EXCP_RI);
9785 break;
9786 }
9787
9788 return 4;
9789 }
9790
9791 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9792 int *is_branch)
9793 {
9794 int rx, ry;
9795 int sa;
9796 int op, cnvt_op, op1, offset;
9797 int funct;
9798 int n_bytes;
9799
9800 op = (ctx->opcode >> 11) & 0x1f;
9801 sa = (ctx->opcode >> 2) & 0x7;
9802 sa = sa == 0 ? 8 : sa;
9803 rx = xlat((ctx->opcode >> 8) & 0x7);
9804 cnvt_op = (ctx->opcode >> 5) & 0x7;
9805 ry = xlat((ctx->opcode >> 5) & 0x7);
9806 op1 = offset = ctx->opcode & 0x1f;
9807
9808 n_bytes = 2;
9809
9810 switch (op) {
9811 case M16_OPC_ADDIUSP:
9812 {
9813 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9814
9815 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9816 }
9817 break;
9818 case M16_OPC_ADDIUPC:
9819 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9820 break;
9821 case M16_OPC_B:
9822 offset = (ctx->opcode & 0x7ff) << 1;
9823 offset = (int16_t)(offset << 4) >> 4;
9824 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9825 /* No delay slot, so just process as a normal instruction */
9826 break;
9827 case M16_OPC_JAL:
9828 offset = cpu_lduw_code(env, ctx->pc + 2);
9829 offset = (((ctx->opcode & 0x1f) << 21)
9830 | ((ctx->opcode >> 5) & 0x1f) << 16
9831 | offset) << 2;
9832 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9833 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9834 n_bytes = 4;
9835 *is_branch = 1;
9836 break;
9837 case M16_OPC_BEQZ:
9838 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9839 /* No delay slot, so just process as a normal instruction */
9840 break;
9841 case M16_OPC_BNEQZ:
9842 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9843 /* No delay slot, so just process as a normal instruction */
9844 break;
9845 case M16_OPC_SHIFT:
9846 switch (ctx->opcode & 0x3) {
9847 case 0x0:
9848 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9849 break;
9850 case 0x1:
9851 #if defined(TARGET_MIPS64)
9852 check_mips_64(ctx);
9853 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9854 #else
9855 generate_exception(ctx, EXCP_RI);
9856 #endif
9857 break;
9858 case 0x2:
9859 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9860 break;
9861 case 0x3:
9862 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9863 break;
9864 }
9865 break;
9866 #if defined(TARGET_MIPS64)
9867 case M16_OPC_LD:
9868 check_mips_64(ctx);
9869 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9870 break;
9871 #endif
9872 case M16_OPC_RRIA:
9873 {
9874 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9875
9876 if ((ctx->opcode >> 4) & 1) {
9877 #if defined(TARGET_MIPS64)
9878 check_mips_64(ctx);
9879 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9880 #else
9881 generate_exception(ctx, EXCP_RI);
9882 #endif
9883 } else {
9884 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9885 }
9886 }
9887 break;
9888 case M16_OPC_ADDIU8:
9889 {
9890 int16_t imm = (int8_t) ctx->opcode;
9891
9892 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9893 }
9894 break;
9895 case M16_OPC_SLTI:
9896 {
9897 int16_t imm = (uint8_t) ctx->opcode;
9898 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9899 }
9900 break;
9901 case M16_OPC_SLTIU:
9902 {
9903 int16_t imm = (uint8_t) ctx->opcode;
9904 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9905 }
9906 break;
9907 case M16_OPC_I8:
9908 {
9909 int reg32;
9910
9911 funct = (ctx->opcode >> 8) & 0x7;
9912 switch (funct) {
9913 case I8_BTEQZ:
9914 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9915 ((int8_t)ctx->opcode) << 1);
9916 break;
9917 case I8_BTNEZ:
9918 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9919 ((int8_t)ctx->opcode) << 1);
9920 break;
9921 case I8_SWRASP:
9922 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9923 break;
9924 case I8_ADJSP:
9925 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9926 ((int8_t)ctx->opcode) << 3);
9927 break;
9928 case I8_SVRS:
9929 {
9930 int do_ra = ctx->opcode & (1 << 6);
9931 int do_s0 = ctx->opcode & (1 << 5);
9932 int do_s1 = ctx->opcode & (1 << 4);
9933 int framesize = ctx->opcode & 0xf;
9934
9935 if (framesize == 0) {
9936 framesize = 128;
9937 } else {
9938 framesize = framesize << 3;
9939 }
9940
9941 if (ctx->opcode & (1 << 7)) {
9942 gen_mips16_save(ctx, 0, 0,
9943 do_ra, do_s0, do_s1, framesize);
9944 } else {
9945 gen_mips16_restore(ctx, 0, 0,
9946 do_ra, do_s0, do_s1, framesize);
9947 }
9948 }
9949 break;
9950 case I8_MOV32R:
9951 {
9952 int rz = xlat(ctx->opcode & 0x7);
9953
9954 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9955 ((ctx->opcode >> 5) & 0x7);
9956 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9957 }
9958 break;
9959 case I8_MOVR32:
9960 reg32 = ctx->opcode & 0x1f;
9961 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9962 break;
9963 default:
9964 generate_exception(ctx, EXCP_RI);
9965 break;
9966 }
9967 }
9968 break;
9969 case M16_OPC_LI:
9970 {
9971 int16_t imm = (uint8_t) ctx->opcode;
9972
9973 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9974 }
9975 break;
9976 case M16_OPC_CMPI:
9977 {
9978 int16_t imm = (uint8_t) ctx->opcode;
9979 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
9980 }
9981 break;
9982 #if defined(TARGET_MIPS64)
9983 case M16_OPC_SD:
9984 check_mips_64(ctx);
9985 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9986 break;
9987 #endif
9988 case M16_OPC_LB:
9989 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9990 break;
9991 case M16_OPC_LH:
9992 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9993 break;
9994 case M16_OPC_LWSP:
9995 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9996 break;
9997 case M16_OPC_LW:
9998 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
9999 break;
10000 case M16_OPC_LBU:
10001 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
10002 break;
10003 case M16_OPC_LHU:
10004 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
10005 break;
10006 case M16_OPC_LWPC:
10007 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10008 break;
10009 #if defined (TARGET_MIPS64)
10010 case M16_OPC_LWU:
10011 check_mips_64(ctx);
10012 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
10013 break;
10014 #endif
10015 case M16_OPC_SB:
10016 gen_st(ctx, OPC_SB, ry, rx, offset);
10017 break;
10018 case M16_OPC_SH:
10019 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10020 break;
10021 case M16_OPC_SWSP:
10022 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10023 break;
10024 case M16_OPC_SW:
10025 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10026 break;
10027 case M16_OPC_RRR:
10028 {
10029 int rz = xlat((ctx->opcode >> 2) & 0x7);
10030 int mips32_op;
10031
10032 switch (ctx->opcode & 0x3) {
10033 case RRR_ADDU:
10034 mips32_op = OPC_ADDU;
10035 break;
10036 case RRR_SUBU:
10037 mips32_op = OPC_SUBU;
10038 break;
10039 #if defined(TARGET_MIPS64)
10040 case RRR_DADDU:
10041 mips32_op = OPC_DADDU;
10042 check_mips_64(ctx);
10043 break;
10044 case RRR_DSUBU:
10045 mips32_op = OPC_DSUBU;
10046 check_mips_64(ctx);
10047 break;
10048 #endif
10049 default:
10050 generate_exception(ctx, EXCP_RI);
10051 goto done;
10052 }
10053
10054 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10055 done:
10056 ;
10057 }
10058 break;
10059 case M16_OPC_RR:
10060 switch (op1) {
10061 case RR_JR:
10062 {
10063 int nd = (ctx->opcode >> 7) & 0x1;
10064 int link = (ctx->opcode >> 6) & 0x1;
10065 int ra = (ctx->opcode >> 5) & 0x1;
10066
10067 if (link) {
10068 op = nd ? OPC_JALRC : OPC_JALRS;
10069 } else {
10070 op = OPC_JR;
10071 }
10072
10073 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10074 if (!nd) {
10075 *is_branch = 1;
10076 }
10077 }
10078 break;
10079 case RR_SDBBP:
10080 /* XXX: not clear which exception should be raised
10081 * when in debug mode...
10082 */
10083 check_insn(env, ctx, ISA_MIPS32);
10084 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10085 generate_exception(ctx, EXCP_DBp);
10086 } else {
10087 generate_exception(ctx, EXCP_DBp);
10088 }
10089 break;
10090 case RR_SLT:
10091 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
10092 break;
10093 case RR_SLTU:
10094 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
10095 break;
10096 case RR_BREAK:
10097 generate_exception(ctx, EXCP_BREAK);
10098 break;
10099 case RR_SLLV:
10100 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10101 break;
10102 case RR_SRLV:
10103 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10104 break;
10105 case RR_SRAV:
10106 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10107 break;
10108 #if defined (TARGET_MIPS64)
10109 case RR_DSRL:
10110 check_mips_64(ctx);
10111 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10112 break;
10113 #endif
10114 case RR_CMP:
10115 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
10116 break;
10117 case RR_NEG:
10118 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10119 break;
10120 case RR_AND:
10121 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
10122 break;
10123 case RR_OR:
10124 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
10125 break;
10126 case RR_XOR:
10127 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
10128 break;
10129 case RR_NOT:
10130 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
10131 break;
10132 case RR_MFHI:
10133 gen_HILO(ctx, OPC_MFHI, rx);
10134 break;
10135 case RR_CNVT:
10136 switch (cnvt_op) {
10137 case RR_RY_CNVT_ZEB:
10138 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10139 break;
10140 case RR_RY_CNVT_ZEH:
10141 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10142 break;
10143 case RR_RY_CNVT_SEB:
10144 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10145 break;
10146 case RR_RY_CNVT_SEH:
10147 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10148 break;
10149 #if defined (TARGET_MIPS64)
10150 case RR_RY_CNVT_ZEW:
10151 check_mips_64(ctx);
10152 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10153 break;
10154 case RR_RY_CNVT_SEW:
10155 check_mips_64(ctx);
10156 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10157 break;
10158 #endif
10159 default:
10160 generate_exception(ctx, EXCP_RI);
10161 break;
10162 }
10163 break;
10164 case RR_MFLO:
10165 gen_HILO(ctx, OPC_MFLO, rx);
10166 break;
10167 #if defined (TARGET_MIPS64)
10168 case RR_DSRA:
10169 check_mips_64(ctx);
10170 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10171 break;
10172 case RR_DSLLV:
10173 check_mips_64(ctx);
10174 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10175 break;
10176 case RR_DSRLV:
10177 check_mips_64(ctx);
10178 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10179 break;
10180 case RR_DSRAV:
10181 check_mips_64(ctx);
10182 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10183 break;
10184 #endif
10185 case RR_MULT:
10186 gen_muldiv(ctx, OPC_MULT, rx, ry);
10187 break;
10188 case RR_MULTU:
10189 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10190 break;
10191 case RR_DIV:
10192 gen_muldiv(ctx, OPC_DIV, rx, ry);
10193 break;
10194 case RR_DIVU:
10195 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10196 break;
10197 #if defined (TARGET_MIPS64)
10198 case RR_DMULT:
10199 check_mips_64(ctx);
10200 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10201 break;
10202 case RR_DMULTU:
10203 check_mips_64(ctx);
10204 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10205 break;
10206 case RR_DDIV:
10207 check_mips_64(ctx);
10208 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10209 break;
10210 case RR_DDIVU:
10211 check_mips_64(ctx);
10212 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10213 break;
10214 #endif
10215 default:
10216 generate_exception(ctx, EXCP_RI);
10217 break;
10218 }
10219 break;
10220 case M16_OPC_EXTEND:
10221 decode_extended_mips16_opc(env, ctx, is_branch);
10222 n_bytes = 4;
10223 break;
10224 #if defined(TARGET_MIPS64)
10225 case M16_OPC_I64:
10226 funct = (ctx->opcode >> 8) & 0x7;
10227 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10228 break;
10229 #endif
10230 default:
10231 generate_exception(ctx, EXCP_RI);
10232 break;
10233 }
10234
10235 return n_bytes;
10236 }
10237
10238 /* microMIPS extension to MIPS32 */
10239
10240 /* microMIPS32 major opcodes */
10241
10242 enum {
10243 POOL32A = 0x00,
10244 POOL16A = 0x01,
10245 LBU16 = 0x02,
10246 MOVE16 = 0x03,
10247 ADDI32 = 0x04,
10248 LBU32 = 0x05,
10249 SB32 = 0x06,
10250 LB32 = 0x07,
10251
10252 POOL32B = 0x08,
10253 POOL16B = 0x09,
10254 LHU16 = 0x0a,
10255 ANDI16 = 0x0b,
10256 ADDIU32 = 0x0c,
10257 LHU32 = 0x0d,
10258 SH32 = 0x0e,
10259 LH32 = 0x0f,
10260
10261 POOL32I = 0x10,
10262 POOL16C = 0x11,
10263 LWSP16 = 0x12,
10264 POOL16D = 0x13,
10265 ORI32 = 0x14,
10266 POOL32F = 0x15,
10267 POOL32S = 0x16,
10268 DADDIU32 = 0x17,
10269
10270 POOL32C = 0x18,
10271 LWGP16 = 0x19,
10272 LW16 = 0x1a,
10273 POOL16E = 0x1b,
10274 XORI32 = 0x1c,
10275 JALS32 = 0x1d,
10276 ADDIUPC = 0x1e,
10277 POOL48A = 0x1f,
10278
10279 /* 0x20 is reserved */
10280 RES_20 = 0x20,
10281 POOL16F = 0x21,
10282 SB16 = 0x22,
10283 BEQZ16 = 0x23,
10284 SLTI32 = 0x24,
10285 BEQ32 = 0x25,
10286 SWC132 = 0x26,
10287 LWC132 = 0x27,
10288
10289 /* 0x28 and 0x29 are reserved */
10290 RES_28 = 0x28,
10291 RES_29 = 0x29,
10292 SH16 = 0x2a,
10293 BNEZ16 = 0x2b,
10294 SLTIU32 = 0x2c,
10295 BNE32 = 0x2d,
10296 SDC132 = 0x2e,
10297 LDC132 = 0x2f,
10298
10299 /* 0x30 and 0x31 are reserved */
10300 RES_30 = 0x30,
10301 RES_31 = 0x31,
10302 SWSP16 = 0x32,
10303 B16 = 0x33,
10304 ANDI32 = 0x34,
10305 J32 = 0x35,
10306 SD32 = 0x36,
10307 LD32 = 0x37,
10308
10309 /* 0x38 and 0x39 are reserved */
10310 RES_38 = 0x38,
10311 RES_39 = 0x39,
10312 SW16 = 0x3a,
10313 LI16 = 0x3b,
10314 JALX32 = 0x3c,
10315 JAL32 = 0x3d,
10316 SW32 = 0x3e,
10317 LW32 = 0x3f
10318 };
10319
10320 /* POOL32A encoding of minor opcode field */
10321
10322 enum {
10323 /* These opcodes are distinguished only by bits 9..6; those bits are
10324 * what are recorded below. */
10325 SLL32 = 0x0,
10326 SRL32 = 0x1,
10327 SRA = 0x2,
10328 ROTR = 0x3,
10329
10330 SLLV = 0x0,
10331 SRLV = 0x1,
10332 SRAV = 0x2,
10333 ROTRV = 0x3,
10334 ADD = 0x4,
10335 ADDU32 = 0x5,
10336 SUB = 0x6,
10337 SUBU32 = 0x7,
10338 MUL = 0x8,
10339 AND = 0x9,
10340 OR32 = 0xa,
10341 NOR = 0xb,
10342 XOR32 = 0xc,
10343 SLT = 0xd,
10344 SLTU = 0xe,
10345
10346 MOVN = 0x0,
10347 MOVZ = 0x1,
10348 LWXS = 0x4,
10349
10350 /* The following can be distinguished by their lower 6 bits. */
10351 INS = 0x0c,
10352 EXT = 0x2c,
10353 POOL32AXF = 0x3c
10354 };
10355
10356 /* POOL32AXF encoding of minor opcode field extension */
10357
10358 enum {
10359 /* bits 11..6 */
10360 TEQ = 0x00,
10361 TGE = 0x08,
10362 TGEU = 0x10,
10363 TLT = 0x20,
10364 TLTU = 0x28,
10365 TNE = 0x30,
10366
10367 MFC0 = 0x03,
10368 MTC0 = 0x0b,
10369
10370 /* bits 13..12 for 0x01 */
10371 MFHI_ACC = 0x0,
10372 MFLO_ACC = 0x1,
10373 MTHI_ACC = 0x2,
10374 MTLO_ACC = 0x3,
10375
10376 /* bits 13..12 for 0x2a */
10377 MADD_ACC = 0x0,
10378 MADDU_ACC = 0x1,
10379 MSUB_ACC = 0x2,
10380 MSUBU_ACC = 0x3,
10381
10382 /* bits 13..12 for 0x32 */
10383 MULT_ACC = 0x0,
10384 MULTU_ACC = 0x0,
10385
10386 /* bits 15..12 for 0x2c */
10387 SEB = 0x2,
10388 SEH = 0x3,
10389 CLO = 0x4,
10390 CLZ = 0x5,
10391 RDHWR = 0x6,
10392 WSBH = 0x7,
10393 MULT = 0x8,
10394 MULTU = 0x9,
10395 DIV = 0xa,
10396 DIVU = 0xb,
10397 MADD = 0xc,
10398 MADDU = 0xd,
10399 MSUB = 0xe,
10400 MSUBU = 0xf,
10401
10402 /* bits 15..12 for 0x34 */
10403 MFC2 = 0x4,
10404 MTC2 = 0x5,
10405 MFHC2 = 0x8,
10406 MTHC2 = 0x9,
10407 CFC2 = 0xc,
10408 CTC2 = 0xd,
10409
10410 /* bits 15..12 for 0x3c */
10411 JALR = 0x0,
10412 JR = 0x0, /* alias */
10413 JALR_HB = 0x1,
10414 JALRS = 0x4,
10415 JALRS_HB = 0x5,
10416
10417 /* bits 15..12 for 0x05 */
10418 RDPGPR = 0xe,
10419 WRPGPR = 0xf,
10420
10421 /* bits 15..12 for 0x0d */
10422 TLBP = 0x0,
10423 TLBR = 0x1,
10424 TLBWI = 0x2,
10425 TLBWR = 0x3,
10426 WAIT = 0x9,
10427 IRET = 0xd,
10428 DERET = 0xe,
10429 ERET = 0xf,
10430
10431 /* bits 15..12 for 0x15 */
10432 DMT = 0x0,
10433 DVPE = 0x1,
10434 EMT = 0x2,
10435 EVPE = 0x3,
10436
10437 /* bits 15..12 for 0x1d */
10438 DI = 0x4,
10439 EI = 0x5,
10440
10441 /* bits 15..12 for 0x2d */
10442 SYNC = 0x6,
10443 SYSCALL = 0x8,
10444 SDBBP = 0xd,
10445
10446 /* bits 15..12 for 0x35 */
10447 MFHI32 = 0x0,
10448 MFLO32 = 0x1,
10449 MTHI32 = 0x2,
10450 MTLO32 = 0x3,
10451 };
10452
10453 /* POOL32B encoding of minor opcode field (bits 15..12) */
10454
10455 enum {
10456 LWC2 = 0x0,
10457 LWP = 0x1,
10458 LDP = 0x4,
10459 LWM32 = 0x5,
10460 CACHE = 0x6,
10461 LDM = 0x7,
10462 SWC2 = 0x8,
10463 SWP = 0x9,
10464 SDP = 0xc,
10465 SWM32 = 0xd,
10466 SDM = 0xf
10467 };
10468
10469 /* POOL32C encoding of minor opcode field (bits 15..12) */
10470
10471 enum {
10472 LWL = 0x0,
10473 SWL = 0x8,
10474 LWR = 0x1,
10475 SWR = 0x9,
10476 PREF = 0x2,
10477 /* 0xa is reserved */
10478 LL = 0x3,
10479 SC = 0xb,
10480 LDL = 0x4,
10481 SDL = 0xc,
10482 LDR = 0x5,
10483 SDR = 0xd,
10484 /* 0x6 is reserved */
10485 LWU = 0xe,
10486 LLD = 0x7,
10487 SCD = 0xf
10488 };
10489
10490 /* POOL32F encoding of minor opcode field (bits 5..0) */
10491
10492 enum {
10493 /* These are the bit 7..6 values */
10494 ADD_FMT = 0x0,
10495 MOVN_FMT = 0x0,
10496
10497 SUB_FMT = 0x1,
10498 MOVZ_FMT = 0x1,
10499
10500 MUL_FMT = 0x2,
10501
10502 DIV_FMT = 0x3,
10503
10504 /* These are the bit 8..6 values */
10505 RSQRT2_FMT = 0x0,
10506 MOVF_FMT = 0x0,
10507
10508 LWXC1 = 0x1,
10509 MOVT_FMT = 0x1,
10510
10511 PLL_PS = 0x2,
10512 SWXC1 = 0x2,
10513
10514 PLU_PS = 0x3,
10515 LDXC1 = 0x3,
10516
10517 PUL_PS = 0x4,
10518 SDXC1 = 0x4,
10519 RECIP2_FMT = 0x4,
10520
10521 PUU_PS = 0x5,
10522 LUXC1 = 0x5,
10523
10524 CVT_PS_S = 0x6,
10525 SUXC1 = 0x6,
10526 ADDR_PS = 0x6,
10527 PREFX = 0x6,
10528
10529 MULR_PS = 0x7,
10530
10531 MADD_S = 0x01,
10532 MADD_D = 0x09,
10533 MADD_PS = 0x11,
10534 ALNV_PS = 0x19,
10535 MSUB_S = 0x21,
10536 MSUB_D = 0x29,
10537 MSUB_PS = 0x31,
10538
10539 NMADD_S = 0x02,
10540 NMADD_D = 0x0a,
10541 NMADD_PS = 0x12,
10542 NMSUB_S = 0x22,
10543 NMSUB_D = 0x2a,
10544 NMSUB_PS = 0x32,
10545
10546 POOL32FXF = 0x3b,
10547
10548 CABS_COND_FMT = 0x1c, /* MIPS3D */
10549 C_COND_FMT = 0x3c
10550 };
10551
10552 /* POOL32Fxf encoding of minor opcode extension field */
10553
10554 enum {
10555 CVT_L = 0x04,
10556 RSQRT_FMT = 0x08,
10557 FLOOR_L = 0x0c,
10558 CVT_PW_PS = 0x1c,
10559 CVT_W = 0x24,
10560 SQRT_FMT = 0x28,
10561 FLOOR_W = 0x2c,
10562 CVT_PS_PW = 0x3c,
10563 CFC1 = 0x40,
10564 RECIP_FMT = 0x48,
10565 CEIL_L = 0x4c,
10566 CTC1 = 0x60,
10567 CEIL_W = 0x6c,
10568 MFC1 = 0x80,
10569 CVT_S_PL = 0x84,
10570 TRUNC_L = 0x8c,
10571 MTC1 = 0xa0,
10572 CVT_S_PU = 0xa4,
10573 TRUNC_W = 0xac,
10574 MFHC1 = 0xc0,
10575 ROUND_L = 0xcc,
10576 MTHC1 = 0xe0,
10577 ROUND_W = 0xec,
10578
10579 MOV_FMT = 0x01,
10580 MOVF = 0x05,
10581 ABS_FMT = 0x0d,
10582 RSQRT1_FMT = 0x1d,
10583 MOVT = 0x25,
10584 NEG_FMT = 0x2d,
10585 CVT_D = 0x4d,
10586 RECIP1_FMT = 0x5d,
10587 CVT_S = 0x6d
10588 };
10589
10590 /* POOL32I encoding of minor opcode field (bits 25..21) */
10591
10592 enum {
10593 BLTZ = 0x00,
10594 BLTZAL = 0x01,
10595 BGEZ = 0x02,
10596 BGEZAL = 0x03,
10597 BLEZ = 0x04,
10598 BNEZC = 0x05,
10599 BGTZ = 0x06,
10600 BEQZC = 0x07,
10601 TLTI = 0x08,
10602 TGEI = 0x09,
10603 TLTIU = 0x0a,
10604 TGEIU = 0x0b,
10605 TNEI = 0x0c,
10606 LUI = 0x0d,
10607 TEQI = 0x0e,
10608 SYNCI = 0x10,
10609 BLTZALS = 0x11,
10610 BGEZALS = 0x13,
10611 BC2F = 0x14,
10612 BC2T = 0x15,
10613 BPOSGE64 = 0x1a,
10614 BPOSGE32 = 0x1b,
10615 /* These overlap and are distinguished by bit16 of the instruction */
10616 BC1F = 0x1c,
10617 BC1T = 0x1d,
10618 BC1ANY2F = 0x1c,
10619 BC1ANY2T = 0x1d,
10620 BC1ANY4F = 0x1e,
10621 BC1ANY4T = 0x1f
10622 };
10623
10624 /* POOL16A encoding of minor opcode field */
10625
10626 enum {
10627 ADDU16 = 0x0,
10628 SUBU16 = 0x1
10629 };
10630
10631 /* POOL16B encoding of minor opcode field */
10632
10633 enum {
10634 SLL16 = 0x0,
10635 SRL16 = 0x1
10636 };
10637
10638 /* POOL16C encoding of minor opcode field */
10639
10640 enum {
10641 NOT16 = 0x00,
10642 XOR16 = 0x04,
10643 AND16 = 0x08,
10644 OR16 = 0x0c,
10645 LWM16 = 0x10,
10646 SWM16 = 0x14,
10647 JR16 = 0x18,
10648 JRC16 = 0x1a,
10649 JALR16 = 0x1c,
10650 JALR16S = 0x1e,
10651 MFHI16 = 0x20,
10652 MFLO16 = 0x24,
10653 BREAK16 = 0x28,
10654 SDBBP16 = 0x2c,
10655 JRADDIUSP = 0x30
10656 };
10657
10658 /* POOL16D encoding of minor opcode field */
10659
10660 enum {
10661 ADDIUS5 = 0x0,
10662 ADDIUSP = 0x1
10663 };
10664
10665 /* POOL16E encoding of minor opcode field */
10666
10667 enum {
10668 ADDIUR2 = 0x0,
10669 ADDIUR1SP = 0x1
10670 };
10671
10672 static int mmreg (int r)
10673 {
10674 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10675
10676 return map[r];
10677 }
10678
10679 /* Used for 16-bit store instructions. */
10680 static int mmreg2 (int r)
10681 {
10682 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10683
10684 return map[r];
10685 }
10686
10687 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10688 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10689 #define uMIPS_RS2(op) uMIPS_RS(op)
10690 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10691 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10692 #define uMIPS_RS5(op) (op & 0x1f)
10693
10694 /* Signed immediate */
10695 #define SIMM(op, start, width) \
10696 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10697 << (32-width)) \
10698 >> (32-width))
10699 /* Zero-extended immediate */
10700 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10701
10702 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10703 {
10704 int rd = mmreg(uMIPS_RD(ctx->opcode));
10705
10706 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10707 }
10708
10709 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10710 {
10711 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10712 int rd = mmreg(uMIPS_RD(ctx->opcode));
10713 int rs = mmreg(uMIPS_RS(ctx->opcode));
10714
10715 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10716 }
10717
10718 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10719 {
10720 int encoded = ZIMM(ctx->opcode, 1, 9);
10721 int decoded;
10722
10723 if (encoded <= 1) {
10724 decoded = 256 + encoded;
10725 } else if (encoded <= 255) {
10726 decoded = encoded;
10727 } else if (encoded <= 509) {
10728 decoded = encoded - 512;
10729 } else {
10730 decoded = encoded - 768;
10731 }
10732
10733 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10734 }
10735
10736 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10737 {
10738 int imm = SIMM(ctx->opcode, 1, 4);
10739 int rd = (ctx->opcode >> 5) & 0x1f;
10740
10741 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10742 }
10743
10744 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10745 {
10746 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10747 31, 32, 63, 64, 255, 32768, 65535 };
10748 int rd = mmreg(uMIPS_RD(ctx->opcode));
10749 int rs = mmreg(uMIPS_RS(ctx->opcode));
10750 int encoded = ZIMM(ctx->opcode, 0, 4);
10751
10752 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10753 }
10754
10755 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10756 int base, int16_t offset)
10757 {
10758 const char *opn = "ldst_multiple";
10759 TCGv t0, t1;
10760 TCGv_i32 t2;
10761
10762 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10763 generate_exception(ctx, EXCP_RI);
10764 return;
10765 }
10766
10767 t0 = tcg_temp_new();
10768
10769 gen_base_offset_addr(ctx, t0, base, offset);
10770
10771 t1 = tcg_const_tl(reglist);
10772 t2 = tcg_const_i32(ctx->mem_idx);
10773
10774 save_cpu_state(ctx, 1);
10775 switch (opc) {
10776 case LWM32:
10777 gen_helper_lwm(cpu_env, t0, t1, t2);
10778 opn = "lwm";
10779 break;
10780 case SWM32:
10781 gen_helper_swm(cpu_env, t0, t1, t2);
10782 opn = "swm";
10783 break;
10784 #ifdef TARGET_MIPS64
10785 case LDM:
10786 gen_helper_ldm(cpu_env, t0, t1, t2);
10787 opn = "ldm";
10788 break;
10789 case SDM:
10790 gen_helper_sdm(cpu_env, t0, t1, t2);
10791 opn = "sdm";
10792 break;
10793 #endif
10794 }
10795 (void)opn;
10796 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10797 tcg_temp_free(t0);
10798 tcg_temp_free(t1);
10799 tcg_temp_free_i32(t2);
10800 }
10801
10802
10803 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10804 {
10805 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10806 int rs = mmreg(ctx->opcode & 0x7);
10807 int opc;
10808
10809 switch (((ctx->opcode) >> 4) & 0x3f) {
10810 case NOT16 + 0:
10811 case NOT16 + 1:
10812 case NOT16 + 2:
10813 case NOT16 + 3:
10814 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10815 break;
10816 case XOR16 + 0:
10817 case XOR16 + 1:
10818 case XOR16 + 2:
10819 case XOR16 + 3:
10820 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10821 break;
10822 case AND16 + 0:
10823 case AND16 + 1:
10824 case AND16 + 2:
10825 case AND16 + 3:
10826 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10827 break;
10828 case OR16 + 0:
10829 case OR16 + 1:
10830 case OR16 + 2:
10831 case OR16 + 3:
10832 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10833 break;
10834 case LWM16 + 0:
10835 case LWM16 + 1:
10836 case LWM16 + 2:
10837 case LWM16 + 3:
10838 {
10839 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10840 int offset = ZIMM(ctx->opcode, 0, 4);
10841
10842 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10843 29, offset << 2);
10844 }
10845 break;
10846 case SWM16 + 0:
10847 case SWM16 + 1:
10848 case SWM16 + 2:
10849 case SWM16 + 3:
10850 {
10851 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10852 int offset = ZIMM(ctx->opcode, 0, 4);
10853
10854 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10855 29, offset << 2);
10856 }
10857 break;
10858 case JR16 + 0:
10859 case JR16 + 1:
10860 {
10861 int reg = ctx->opcode & 0x1f;
10862
10863 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10864 }
10865 *is_branch = 1;
10866 break;
10867 case JRC16 + 0:
10868 case JRC16 + 1:
10869 {
10870 int reg = ctx->opcode & 0x1f;
10871
10872 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10873 /* Let normal delay slot handling in our caller take us
10874 to the branch target. */
10875 }
10876 break;
10877 case JALR16 + 0:
10878 case JALR16 + 1:
10879 opc = OPC_JALR;
10880 goto do_jalr;
10881 case JALR16S + 0:
10882 case JALR16S + 1:
10883 opc = OPC_JALRS;
10884 do_jalr:
10885 {
10886 int reg = ctx->opcode & 0x1f;
10887
10888 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10889 }
10890 *is_branch = 1;
10891 break;
10892 case MFHI16 + 0:
10893 case MFHI16 + 1:
10894 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10895 break;
10896 case MFLO16 + 0:
10897 case MFLO16 + 1:
10898 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10899 break;
10900 case BREAK16:
10901 generate_exception(ctx, EXCP_BREAK);
10902 break;
10903 case SDBBP16:
10904 /* XXX: not clear which exception should be raised
10905 * when in debug mode...
10906 */
10907 check_insn(env, ctx, ISA_MIPS32);
10908 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10909 generate_exception(ctx, EXCP_DBp);
10910 } else {
10911 generate_exception(ctx, EXCP_DBp);
10912 }
10913 break;
10914 case JRADDIUSP + 0:
10915 case JRADDIUSP + 1:
10916 {
10917 int imm = ZIMM(ctx->opcode, 0, 5);
10918
10919 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10920 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10921 /* Let normal delay slot handling in our caller take us
10922 to the branch target. */
10923 }
10924 break;
10925 default:
10926 generate_exception(ctx, EXCP_RI);
10927 break;
10928 }
10929 }
10930
10931 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10932 {
10933 TCGv t0 = tcg_temp_new();
10934 TCGv t1 = tcg_temp_new();
10935
10936 gen_load_gpr(t0, base);
10937
10938 if (index != 0) {
10939 gen_load_gpr(t1, index);
10940 tcg_gen_shli_tl(t1, t1, 2);
10941 gen_op_addr_add(ctx, t0, t1, t0);
10942 }
10943
10944 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10945 gen_store_gpr(t1, rd);
10946
10947 tcg_temp_free(t0);
10948 tcg_temp_free(t1);
10949 }
10950
10951 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10952 int base, int16_t offset)
10953 {
10954 const char *opn = "ldst_pair";
10955 TCGv t0, t1;
10956
10957 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10958 generate_exception(ctx, EXCP_RI);
10959 return;
10960 }
10961
10962 t0 = tcg_temp_new();
10963 t1 = tcg_temp_new();
10964
10965 gen_base_offset_addr(ctx, t0, base, offset);
10966
10967 switch (opc) {
10968 case LWP:
10969 if (rd == base) {
10970 generate_exception(ctx, EXCP_RI);
10971 return;
10972 }
10973 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10974 gen_store_gpr(t1, rd);
10975 tcg_gen_movi_tl(t1, 4);
10976 gen_op_addr_add(ctx, t0, t0, t1);
10977 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10978 gen_store_gpr(t1, rd+1);
10979 opn = "lwp";
10980 break;
10981 case SWP:
10982 gen_load_gpr(t1, rd);
10983 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10984 tcg_gen_movi_tl(t1, 4);
10985 gen_op_addr_add(ctx, t0, t0, t1);
10986 gen_load_gpr(t1, rd+1);
10987 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10988 opn = "swp";
10989 break;
10990 #ifdef TARGET_MIPS64
10991 case LDP:
10992 if (rd == base) {
10993 generate_exception(ctx, EXCP_RI);
10994 return;
10995 }
10996 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
10997 gen_store_gpr(t1, rd);
10998 tcg_gen_movi_tl(t1, 8);
10999 gen_op_addr_add(ctx, t0, t0, t1);
11000 tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
11001 gen_store_gpr(t1, rd+1);
11002 opn = "ldp";
11003 break;
11004 case SDP:
11005 gen_load_gpr(t1, rd);
11006 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11007 tcg_gen_movi_tl(t1, 8);
11008 gen_op_addr_add(ctx, t0, t0, t1);
11009 gen_load_gpr(t1, rd+1);
11010 tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11011 opn = "sdp";
11012 break;
11013 #endif
11014 }
11015 (void)opn; /* avoid a compiler warning */
11016 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11017 tcg_temp_free(t0);
11018 tcg_temp_free(t1);
11019 }
11020
11021 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
11022 int *is_branch)
11023 {
11024 int extension = (ctx->opcode >> 6) & 0x3f;
11025 int minor = (ctx->opcode >> 12) & 0xf;
11026 uint32_t mips32_op;
11027
11028 switch (extension) {
11029 case TEQ:
11030 mips32_op = OPC_TEQ;
11031 goto do_trap;
11032 case TGE:
11033 mips32_op = OPC_TGE;
11034 goto do_trap;
11035 case TGEU:
11036 mips32_op = OPC_TGEU;
11037 goto do_trap;
11038 case TLT:
11039 mips32_op = OPC_TLT;
11040 goto do_trap;
11041 case TLTU:
11042 mips32_op = OPC_TLTU;
11043 goto do_trap;
11044 case TNE:
11045 mips32_op = OPC_TNE;
11046 do_trap:
11047 gen_trap(ctx, mips32_op, rs, rt, -1);
11048 break;
11049 #ifndef CONFIG_USER_ONLY
11050 case MFC0:
11051 case MFC0 + 32:
11052 check_cp0_enabled(ctx);
11053 if (rt == 0) {
11054 /* Treat as NOP. */
11055 break;
11056 }
11057 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11058 break;
11059 case MTC0:
11060 case MTC0 + 32:
11061 check_cp0_enabled(ctx);
11062 {
11063 TCGv t0 = tcg_temp_new();
11064
11065 gen_load_gpr(t0, rt);
11066 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11067 tcg_temp_free(t0);
11068 }
11069 break;
11070 #endif
11071 case 0x2c:
11072 switch (minor) {
11073 case SEB:
11074 gen_bshfl(ctx, OPC_SEB, rs, rt);
11075 break;
11076 case SEH:
11077 gen_bshfl(ctx, OPC_SEH, rs, rt);
11078 break;
11079 case CLO:
11080 mips32_op = OPC_CLO;
11081 goto do_cl;
11082 case CLZ:
11083 mips32_op = OPC_CLZ;
11084 do_cl:
11085 check_insn(env, ctx, ISA_MIPS32);
11086 gen_cl(ctx, mips32_op, rt, rs);
11087 break;
11088 case RDHWR:
11089 gen_rdhwr(env, ctx, rt, rs);
11090 break;
11091 case WSBH:
11092 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11093 break;
11094 case MULT:
11095 mips32_op = OPC_MULT;
11096 goto do_muldiv;
11097 case MULTU:
11098 mips32_op = OPC_MULTU;
11099 goto do_muldiv;
11100 case DIV:
11101 mips32_op = OPC_DIV;
11102 goto do_muldiv;
11103 case DIVU:
11104 mips32_op = OPC_DIVU;
11105 goto do_muldiv;
11106 case MADD:
11107 mips32_op = OPC_MADD;
11108 goto do_muldiv;
11109 case MADDU:
11110 mips32_op = OPC_MADDU;
11111 goto do_muldiv;
11112 case MSUB:
11113 mips32_op = OPC_MSUB;
11114 goto do_muldiv;
11115 case MSUBU:
11116 mips32_op = OPC_MSUBU;
11117 do_muldiv:
11118 check_insn(env, ctx, ISA_MIPS32);
11119 gen_muldiv(ctx, mips32_op, rs, rt);
11120 break;
11121 default:
11122 goto pool32axf_invalid;
11123 }
11124 break;
11125 case 0x34:
11126 switch (minor) {
11127 case MFC2:
11128 case MTC2:
11129 case MFHC2:
11130 case MTHC2:
11131 case CFC2:
11132 case CTC2:
11133 generate_exception_err(ctx, EXCP_CpU, 2);
11134 break;
11135 default:
11136 goto pool32axf_invalid;
11137 }
11138 break;
11139 case 0x3c:
11140 switch (minor) {
11141 case JALR:
11142 case JALR_HB:
11143 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11144 *is_branch = 1;
11145 break;
11146 case JALRS:
11147 case JALRS_HB:
11148 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11149 *is_branch = 1;
11150 break;
11151 default:
11152 goto pool32axf_invalid;
11153 }
11154 break;
11155 case 0x05:
11156 switch (minor) {
11157 case RDPGPR:
11158 check_cp0_enabled(ctx);
11159 check_insn(env, ctx, ISA_MIPS32R2);
11160 gen_load_srsgpr(rt, rs);
11161 break;
11162 case WRPGPR:
11163 check_cp0_enabled(ctx);
11164 check_insn(env, ctx, ISA_MIPS32R2);
11165 gen_store_srsgpr(rt, rs);
11166 break;
11167 default:
11168 goto pool32axf_invalid;
11169 }
11170 break;
11171 #ifndef CONFIG_USER_ONLY
11172 case 0x0d:
11173 switch (minor) {
11174 case TLBP:
11175 mips32_op = OPC_TLBP;
11176 goto do_cp0;
11177 case TLBR:
11178 mips32_op = OPC_TLBR;
11179 goto do_cp0;
11180 case TLBWI:
11181 mips32_op = OPC_TLBWI;
11182 goto do_cp0;
11183 case TLBWR:
11184 mips32_op = OPC_TLBWR;
11185 goto do_cp0;
11186 case WAIT:
11187 mips32_op = OPC_WAIT;
11188 goto do_cp0;
11189 case DERET:
11190 mips32_op = OPC_DERET;
11191 goto do_cp0;
11192 case ERET:
11193 mips32_op = OPC_ERET;
11194 do_cp0:
11195 gen_cp0(env, ctx, mips32_op, rt, rs);
11196 break;
11197 default:
11198 goto pool32axf_invalid;
11199 }
11200 break;
11201 case 0x1d:
11202 switch (minor) {
11203 case DI:
11204 check_cp0_enabled(ctx);
11205 {
11206 TCGv t0 = tcg_temp_new();
11207
11208 save_cpu_state(ctx, 1);
11209 gen_helper_di(t0, cpu_env);
11210 gen_store_gpr(t0, rs);
11211 /* Stop translation as we may have switched the execution mode */
11212 ctx->bstate = BS_STOP;
11213 tcg_temp_free(t0);
11214 }
11215 break;
11216 case EI:
11217 check_cp0_enabled(ctx);
11218 {
11219 TCGv t0 = tcg_temp_new();
11220
11221 save_cpu_state(ctx, 1);
11222 gen_helper_ei(t0, cpu_env);
11223 gen_store_gpr(t0, rs);
11224 /* Stop translation as we may have switched the execution mode */
11225 ctx->bstate = BS_STOP;
11226 tcg_temp_free(t0);
11227 }
11228 break;
11229 default:
11230 goto pool32axf_invalid;
11231 }
11232 break;
11233 #endif
11234 case 0x2d:
11235 switch (minor) {
11236 case SYNC:
11237 /* NOP */
11238 break;
11239 case SYSCALL:
11240 generate_exception(ctx, EXCP_SYSCALL);
11241 ctx->bstate = BS_STOP;
11242 break;
11243 case SDBBP:
11244 check_insn(env, ctx, ISA_MIPS32);
11245 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11246 generate_exception(ctx, EXCP_DBp);
11247 } else {
11248 generate_exception(ctx, EXCP_DBp);
11249 }
11250 break;
11251 default:
11252 goto pool32axf_invalid;
11253 }
11254 break;
11255 case 0x35:
11256 switch (minor) {
11257 case MFHI32:
11258 gen_HILO(ctx, OPC_MFHI, rs);
11259 break;
11260 case MFLO32:
11261 gen_HILO(ctx, OPC_MFLO, rs);
11262 break;
11263 case MTHI32:
11264 gen_HILO(ctx, OPC_MTHI, rs);
11265 break;
11266 case MTLO32:
11267 gen_HILO(ctx, OPC_MTLO, rs);
11268 break;
11269 default:
11270 goto pool32axf_invalid;
11271 }
11272 break;
11273 default:
11274 pool32axf_invalid:
11275 MIPS_INVAL("pool32axf");
11276 generate_exception(ctx, EXCP_RI);
11277 break;
11278 }
11279 }
11280
11281 /* Values for microMIPS fmt field. Variable-width, depending on which
11282 formats the instruction supports. */
11283
11284 enum {
11285 FMT_SD_S = 0,
11286 FMT_SD_D = 1,
11287
11288 FMT_SDPS_S = 0,
11289 FMT_SDPS_D = 1,
11290 FMT_SDPS_PS = 2,
11291
11292 FMT_SWL_S = 0,
11293 FMT_SWL_W = 1,
11294 FMT_SWL_L = 2,
11295
11296 FMT_DWL_D = 0,
11297 FMT_DWL_W = 1,
11298 FMT_DWL_L = 2
11299 };
11300
11301 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11302 {
11303 int extension = (ctx->opcode >> 6) & 0x3ff;
11304 uint32_t mips32_op;
11305
11306 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11307 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11308 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11309
11310 switch (extension) {
11311 case FLOAT_1BIT_FMT(CFC1, 0):
11312 mips32_op = OPC_CFC1;
11313 goto do_cp1;
11314 case FLOAT_1BIT_FMT(CTC1, 0):
11315 mips32_op = OPC_CTC1;
11316 goto do_cp1;
11317 case FLOAT_1BIT_FMT(MFC1, 0):
11318 mips32_op = OPC_MFC1;
11319 goto do_cp1;
11320 case FLOAT_1BIT_FMT(MTC1, 0):
11321 mips32_op = OPC_MTC1;
11322 goto do_cp1;
11323 case FLOAT_1BIT_FMT(MFHC1, 0):
11324 mips32_op = OPC_MFHC1;
11325 goto do_cp1;
11326 case FLOAT_1BIT_FMT(MTHC1, 0):
11327 mips32_op = OPC_MTHC1;
11328 do_cp1:
11329 gen_cp1(ctx, mips32_op, rt, rs);
11330 break;
11331
11332 /* Reciprocal square root */
11333 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11334 mips32_op = OPC_RSQRT_S;
11335 goto do_unaryfp;
11336 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11337 mips32_op = OPC_RSQRT_D;
11338 goto do_unaryfp;
11339
11340 /* Square root */
11341 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11342 mips32_op = OPC_SQRT_S;
11343 goto do_unaryfp;
11344 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11345 mips32_op = OPC_SQRT_D;
11346 goto do_unaryfp;
11347
11348 /* Reciprocal */
11349 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11350 mips32_op = OPC_RECIP_S;
11351 goto do_unaryfp;
11352 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11353 mips32_op = OPC_RECIP_D;
11354 goto do_unaryfp;
11355
11356 /* Floor */
11357 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11358 mips32_op = OPC_FLOOR_L_S;
11359 goto do_unaryfp;
11360 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11361 mips32_op = OPC_FLOOR_L_D;
11362 goto do_unaryfp;
11363 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11364 mips32_op = OPC_FLOOR_W_S;
11365 goto do_unaryfp;
11366 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11367 mips32_op = OPC_FLOOR_W_D;
11368 goto do_unaryfp;
11369
11370 /* Ceiling */
11371 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11372 mips32_op = OPC_CEIL_L_S;
11373 goto do_unaryfp;
11374 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11375 mips32_op = OPC_CEIL_L_D;
11376 goto do_unaryfp;
11377 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11378 mips32_op = OPC_CEIL_W_S;
11379 goto do_unaryfp;
11380 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11381 mips32_op = OPC_CEIL_W_D;
11382 goto do_unaryfp;
11383
11384 /* Truncation */
11385 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11386 mips32_op = OPC_TRUNC_L_S;
11387 goto do_unaryfp;
11388 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11389 mips32_op = OPC_TRUNC_L_D;
11390 goto do_unaryfp;
11391 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11392 mips32_op = OPC_TRUNC_W_S;
11393 goto do_unaryfp;
11394 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11395 mips32_op = OPC_TRUNC_W_D;
11396 goto do_unaryfp;
11397
11398 /* Round */
11399 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11400 mips32_op = OPC_ROUND_L_S;
11401 goto do_unaryfp;
11402 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11403 mips32_op = OPC_ROUND_L_D;
11404 goto do_unaryfp;
11405 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11406 mips32_op = OPC_ROUND_W_S;
11407 goto do_unaryfp;
11408 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11409 mips32_op = OPC_ROUND_W_D;
11410 goto do_unaryfp;
11411
11412 /* Integer to floating-point conversion */
11413 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11414 mips32_op = OPC_CVT_L_S;
11415 goto do_unaryfp;
11416 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11417 mips32_op = OPC_CVT_L_D;
11418 goto do_unaryfp;
11419 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11420 mips32_op = OPC_CVT_W_S;
11421 goto do_unaryfp;
11422 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11423 mips32_op = OPC_CVT_W_D;
11424 goto do_unaryfp;
11425
11426 /* Paired-foo conversions */
11427 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11428 mips32_op = OPC_CVT_S_PL;
11429 goto do_unaryfp;
11430 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11431 mips32_op = OPC_CVT_S_PU;
11432 goto do_unaryfp;
11433 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11434 mips32_op = OPC_CVT_PW_PS;
11435 goto do_unaryfp;
11436 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11437 mips32_op = OPC_CVT_PS_PW;
11438 goto do_unaryfp;
11439
11440 /* Floating-point moves */
11441 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11442 mips32_op = OPC_MOV_S;
11443 goto do_unaryfp;
11444 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11445 mips32_op = OPC_MOV_D;
11446 goto do_unaryfp;
11447 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11448 mips32_op = OPC_MOV_PS;
11449 goto do_unaryfp;
11450
11451 /* Absolute value */
11452 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11453 mips32_op = OPC_ABS_S;
11454 goto do_unaryfp;
11455 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11456 mips32_op = OPC_ABS_D;
11457 goto do_unaryfp;
11458 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11459 mips32_op = OPC_ABS_PS;
11460 goto do_unaryfp;
11461
11462 /* Negation */
11463 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11464 mips32_op = OPC_NEG_S;
11465 goto do_unaryfp;
11466 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11467 mips32_op = OPC_NEG_D;
11468 goto do_unaryfp;
11469 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11470 mips32_op = OPC_NEG_PS;
11471 goto do_unaryfp;
11472
11473 /* Reciprocal square root step */
11474 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11475 mips32_op = OPC_RSQRT1_S;
11476 goto do_unaryfp;
11477 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11478 mips32_op = OPC_RSQRT1_D;
11479 goto do_unaryfp;
11480 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11481 mips32_op = OPC_RSQRT1_PS;
11482 goto do_unaryfp;
11483
11484 /* Reciprocal step */
11485 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11486 mips32_op = OPC_RECIP1_S;
11487 goto do_unaryfp;
11488 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11489 mips32_op = OPC_RECIP1_S;
11490 goto do_unaryfp;
11491 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11492 mips32_op = OPC_RECIP1_PS;
11493 goto do_unaryfp;
11494
11495 /* Conversions from double */
11496 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11497 mips32_op = OPC_CVT_D_S;
11498 goto do_unaryfp;
11499 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11500 mips32_op = OPC_CVT_D_W;
11501 goto do_unaryfp;
11502 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11503 mips32_op = OPC_CVT_D_L;
11504 goto do_unaryfp;
11505
11506 /* Conversions from single */
11507 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11508 mips32_op = OPC_CVT_S_D;
11509 goto do_unaryfp;
11510 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11511 mips32_op = OPC_CVT_S_W;
11512 goto do_unaryfp;
11513 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11514 mips32_op = OPC_CVT_S_L;
11515 do_unaryfp:
11516 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11517 break;
11518
11519 /* Conditional moves on floating-point codes */
11520 case COND_FLOAT_MOV(MOVT, 0):
11521 case COND_FLOAT_MOV(MOVT, 1):
11522 case COND_FLOAT_MOV(MOVT, 2):
11523 case COND_FLOAT_MOV(MOVT, 3):
11524 case COND_FLOAT_MOV(MOVT, 4):
11525 case COND_FLOAT_MOV(MOVT, 5):
11526 case COND_FLOAT_MOV(MOVT, 6):
11527 case COND_FLOAT_MOV(MOVT, 7):
11528 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11529 break;
11530 case COND_FLOAT_MOV(MOVF, 0):
11531 case COND_FLOAT_MOV(MOVF, 1):
11532 case COND_FLOAT_MOV(MOVF, 2):
11533 case COND_FLOAT_MOV(MOVF, 3):
11534 case COND_FLOAT_MOV(MOVF, 4):
11535 case COND_FLOAT_MOV(MOVF, 5):
11536 case COND_FLOAT_MOV(MOVF, 6):
11537 case COND_FLOAT_MOV(MOVF, 7):
11538 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11539 break;
11540 default:
11541 MIPS_INVAL("pool32fxf");
11542 generate_exception(ctx, EXCP_RI);
11543 break;
11544 }
11545 }
11546
11547 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11548 uint16_t insn_hw1, int *is_branch)
11549 {
11550 int32_t offset;
11551 uint16_t insn;
11552 int rt, rs, rd, rr;
11553 int16_t imm;
11554 uint32_t op, minor, mips32_op;
11555 uint32_t cond, fmt, cc;
11556
11557 insn = cpu_lduw_code(env, ctx->pc + 2);
11558 ctx->opcode = (ctx->opcode << 16) | insn;
11559
11560 rt = (ctx->opcode >> 21) & 0x1f;
11561 rs = (ctx->opcode >> 16) & 0x1f;
11562 rd = (ctx->opcode >> 11) & 0x1f;
11563 rr = (ctx->opcode >> 6) & 0x1f;
11564 imm = (int16_t) ctx->opcode;
11565
11566 op = (ctx->opcode >> 26) & 0x3f;
11567 switch (op) {
11568 case POOL32A:
11569 minor = ctx->opcode & 0x3f;
11570 switch (minor) {
11571 case 0x00:
11572 minor = (ctx->opcode >> 6) & 0xf;
11573 switch (minor) {
11574 case SLL32:
11575 mips32_op = OPC_SLL;
11576 goto do_shifti;
11577 case SRA:
11578 mips32_op = OPC_SRA;
11579 goto do_shifti;
11580 case SRL32:
11581 mips32_op = OPC_SRL;
11582 goto do_shifti;
11583 case ROTR:
11584 mips32_op = OPC_ROTR;
11585 do_shifti:
11586 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11587 break;
11588 default:
11589 goto pool32a_invalid;
11590 }
11591 break;
11592 case 0x10:
11593 minor = (ctx->opcode >> 6) & 0xf;
11594 switch (minor) {
11595 /* Arithmetic */
11596 case ADD:
11597 mips32_op = OPC_ADD;
11598 goto do_arith;
11599 case ADDU32:
11600 mips32_op = OPC_ADDU;
11601 goto do_arith;
11602 case SUB:
11603 mips32_op = OPC_SUB;
11604 goto do_arith;
11605 case SUBU32:
11606 mips32_op = OPC_SUBU;
11607 goto do_arith;
11608 case MUL:
11609 mips32_op = OPC_MUL;
11610 do_arith:
11611 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11612 break;
11613 /* Shifts */
11614 case SLLV:
11615 mips32_op = OPC_SLLV;
11616 goto do_shift;
11617 case SRLV:
11618 mips32_op = OPC_SRLV;
11619 goto do_shift;
11620 case SRAV:
11621 mips32_op = OPC_SRAV;
11622 goto do_shift;
11623 case ROTRV:
11624 mips32_op = OPC_ROTRV;
11625 do_shift:
11626 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11627 break;
11628 /* Logical operations */
11629 case AND:
11630 mips32_op = OPC_AND;
11631 goto do_logic;
11632 case OR32:
11633 mips32_op = OPC_OR;
11634 goto do_logic;
11635 case NOR:
11636 mips32_op = OPC_NOR;
11637 goto do_logic;
11638 case XOR32:
11639 mips32_op = OPC_XOR;
11640 do_logic:
11641 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11642 break;
11643 /* Set less than */
11644 case SLT:
11645 mips32_op = OPC_SLT;
11646 goto do_slt;
11647 case SLTU:
11648 mips32_op = OPC_SLTU;
11649 do_slt:
11650 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11651 break;
11652 default:
11653 goto pool32a_invalid;
11654 }
11655 break;
11656 case 0x18:
11657 minor = (ctx->opcode >> 6) & 0xf;
11658 switch (minor) {
11659 /* Conditional moves */
11660 case MOVN:
11661 mips32_op = OPC_MOVN;
11662 goto do_cmov;
11663 case MOVZ:
11664 mips32_op = OPC_MOVZ;
11665 do_cmov:
11666 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11667 break;
11668 case LWXS:
11669 gen_ldxs(ctx, rs, rt, rd);
11670 break;
11671 default:
11672 goto pool32a_invalid;
11673 }
11674 break;
11675 case INS:
11676 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11677 return;
11678 case EXT:
11679 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11680 return;
11681 case POOL32AXF:
11682 gen_pool32axf(env, ctx, rt, rs, is_branch);
11683 break;
11684 case 0x07:
11685 generate_exception(ctx, EXCP_BREAK);
11686 break;
11687 default:
11688 pool32a_invalid:
11689 MIPS_INVAL("pool32a");
11690 generate_exception(ctx, EXCP_RI);
11691 break;
11692 }
11693 break;
11694 case POOL32B:
11695 minor = (ctx->opcode >> 12) & 0xf;
11696 switch (minor) {
11697 case CACHE:
11698 check_cp0_enabled(ctx);
11699 /* Treat as no-op. */
11700 break;
11701 case LWC2:
11702 case SWC2:
11703 /* COP2: Not implemented. */
11704 generate_exception_err(ctx, EXCP_CpU, 2);
11705 break;
11706 case LWP:
11707 case SWP:
11708 #ifdef TARGET_MIPS64
11709 case LDP:
11710 case SDP:
11711 #endif
11712 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11713 break;
11714 case LWM32:
11715 case SWM32:
11716 #ifdef TARGET_MIPS64
11717 case LDM:
11718 case SDM:
11719 #endif
11720 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11721 break;
11722 default:
11723 MIPS_INVAL("pool32b");
11724 generate_exception(ctx, EXCP_RI);
11725 break;
11726 }
11727 break;
11728 case POOL32F:
11729 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11730 minor = ctx->opcode & 0x3f;
11731 check_cp1_enabled(ctx);
11732 switch (minor) {
11733 case ALNV_PS:
11734 mips32_op = OPC_ALNV_PS;
11735 goto do_madd;
11736 case MADD_S:
11737 mips32_op = OPC_MADD_S;
11738 goto do_madd;
11739 case MADD_D:
11740 mips32_op = OPC_MADD_D;
11741 goto do_madd;
11742 case MADD_PS:
11743 mips32_op = OPC_MADD_PS;
11744 goto do_madd;
11745 case MSUB_S:
11746 mips32_op = OPC_MSUB_S;
11747 goto do_madd;
11748 case MSUB_D:
11749 mips32_op = OPC_MSUB_D;
11750 goto do_madd;
11751 case MSUB_PS:
11752 mips32_op = OPC_MSUB_PS;
11753 goto do_madd;
11754 case NMADD_S:
11755 mips32_op = OPC_NMADD_S;
11756 goto do_madd;
11757 case NMADD_D:
11758 mips32_op = OPC_NMADD_D;
11759 goto do_madd;
11760 case NMADD_PS:
11761 mips32_op = OPC_NMADD_PS;
11762 goto do_madd;
11763 case NMSUB_S:
11764 mips32_op = OPC_NMSUB_S;
11765 goto do_madd;
11766 case NMSUB_D:
11767 mips32_op = OPC_NMSUB_D;
11768 goto do_madd;
11769 case NMSUB_PS:
11770 mips32_op = OPC_NMSUB_PS;
11771 do_madd:
11772 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11773 break;
11774 case CABS_COND_FMT:
11775 cond = (ctx->opcode >> 6) & 0xf;
11776 cc = (ctx->opcode >> 13) & 0x7;
11777 fmt = (ctx->opcode >> 10) & 0x3;
11778 switch (fmt) {
11779 case 0x0:
11780 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11781 break;
11782 case 0x1:
11783 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11784 break;
11785 case 0x2:
11786 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11787 break;
11788 default:
11789 goto pool32f_invalid;
11790 }
11791 break;
11792 case C_COND_FMT:
11793 cond = (ctx->opcode >> 6) & 0xf;
11794 cc = (ctx->opcode >> 13) & 0x7;
11795 fmt = (ctx->opcode >> 10) & 0x3;
11796 switch (fmt) {
11797 case 0x0:
11798 gen_cmp_s(ctx, cond, rt, rs, cc);
11799 break;
11800 case 0x1:
11801 gen_cmp_d(ctx, cond, rt, rs, cc);
11802 break;
11803 case 0x2:
11804 gen_cmp_ps(ctx, cond, rt, rs, cc);
11805 break;
11806 default:
11807 goto pool32f_invalid;
11808 }
11809 break;
11810 case POOL32FXF:
11811 gen_pool32fxf(env, ctx, rt, rs);
11812 break;
11813 case 0x00:
11814 /* PLL foo */
11815 switch ((ctx->opcode >> 6) & 0x7) {
11816 case PLL_PS:
11817 mips32_op = OPC_PLL_PS;
11818 goto do_ps;
11819 case PLU_PS:
11820 mips32_op = OPC_PLU_PS;
11821 goto do_ps;
11822 case PUL_PS:
11823 mips32_op = OPC_PUL_PS;
11824 goto do_ps;
11825 case PUU_PS:
11826 mips32_op = OPC_PUU_PS;
11827 goto do_ps;
11828 case CVT_PS_S:
11829 mips32_op = OPC_CVT_PS_S;
11830 do_ps:
11831 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11832 break;
11833 default:
11834 goto pool32f_invalid;
11835 }
11836 break;
11837 case 0x08:
11838 /* [LS][WDU]XC1 */
11839 switch ((ctx->opcode >> 6) & 0x7) {
11840 case LWXC1:
11841 mips32_op = OPC_LWXC1;
11842 goto do_ldst_cp1;
11843 case SWXC1:
11844 mips32_op = OPC_SWXC1;
11845 goto do_ldst_cp1;
11846 case LDXC1:
11847 mips32_op = OPC_LDXC1;
11848 goto do_ldst_cp1;
11849 case SDXC1:
11850 mips32_op = OPC_SDXC1;
11851 goto do_ldst_cp1;
11852 case LUXC1:
11853 mips32_op = OPC_LUXC1;
11854 goto do_ldst_cp1;
11855 case SUXC1:
11856 mips32_op = OPC_SUXC1;
11857 do_ldst_cp1:
11858 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11859 break;
11860 default:
11861 goto pool32f_invalid;
11862 }
11863 break;
11864 case 0x18:
11865 /* 3D insns */
11866 fmt = (ctx->opcode >> 9) & 0x3;
11867 switch ((ctx->opcode >> 6) & 0x7) {
11868 case RSQRT2_FMT:
11869 switch (fmt) {
11870 case FMT_SDPS_S:
11871 mips32_op = OPC_RSQRT2_S;
11872 goto do_3d;
11873 case FMT_SDPS_D:
11874 mips32_op = OPC_RSQRT2_D;
11875 goto do_3d;
11876 case FMT_SDPS_PS:
11877 mips32_op = OPC_RSQRT2_PS;
11878 goto do_3d;
11879 default:
11880 goto pool32f_invalid;
11881 }
11882 break;
11883 case RECIP2_FMT:
11884 switch (fmt) {
11885 case FMT_SDPS_S:
11886 mips32_op = OPC_RECIP2_S;
11887 goto do_3d;
11888 case FMT_SDPS_D:
11889 mips32_op = OPC_RECIP2_D;
11890 goto do_3d;
11891 case FMT_SDPS_PS:
11892 mips32_op = OPC_RECIP2_PS;
11893 goto do_3d;
11894 default:
11895 goto pool32f_invalid;
11896 }
11897 break;
11898 case ADDR_PS:
11899 mips32_op = OPC_ADDR_PS;
11900 goto do_3d;
11901 case MULR_PS:
11902 mips32_op = OPC_MULR_PS;
11903 do_3d:
11904 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11905 break;
11906 default:
11907 goto pool32f_invalid;
11908 }
11909 break;
11910 case 0x20:
11911 /* MOV[FT].fmt and PREFX */
11912 cc = (ctx->opcode >> 13) & 0x7;
11913 fmt = (ctx->opcode >> 9) & 0x3;
11914 switch ((ctx->opcode >> 6) & 0x7) {
11915 case MOVF_FMT:
11916 switch (fmt) {
11917 case FMT_SDPS_S:
11918 gen_movcf_s(rs, rt, cc, 0);
11919 break;
11920 case FMT_SDPS_D:
11921 gen_movcf_d(ctx, rs, rt, cc, 0);
11922 break;
11923 case FMT_SDPS_PS:
11924 gen_movcf_ps(rs, rt, cc, 0);
11925 break;
11926 default:
11927 goto pool32f_invalid;
11928 }
11929 break;
11930 case MOVT_FMT:
11931 switch (fmt) {
11932 case FMT_SDPS_S:
11933 gen_movcf_s(rs, rt, cc, 1);
11934 break;
11935 case FMT_SDPS_D:
11936 gen_movcf_d(ctx, rs, rt, cc, 1);
11937 break;
11938 case FMT_SDPS_PS:
11939 gen_movcf_ps(rs, rt, cc, 1);
11940 break;
11941 default:
11942 goto pool32f_invalid;
11943 }
11944 break;
11945 case PREFX:
11946 break;
11947 default:
11948 goto pool32f_invalid;
11949 }
11950 break;
11951 #define FINSN_3ARG_SDPS(prfx) \
11952 switch ((ctx->opcode >> 8) & 0x3) { \
11953 case FMT_SDPS_S: \
11954 mips32_op = OPC_##prfx##_S; \
11955 goto do_fpop; \
11956 case FMT_SDPS_D: \
11957 mips32_op = OPC_##prfx##_D; \
11958 goto do_fpop; \
11959 case FMT_SDPS_PS: \
11960 mips32_op = OPC_##prfx##_PS; \
11961 goto do_fpop; \
11962 default: \
11963 goto pool32f_invalid; \
11964 }
11965 case 0x30:
11966 /* regular FP ops */
11967 switch ((ctx->opcode >> 6) & 0x3) {
11968 case ADD_FMT:
11969 FINSN_3ARG_SDPS(ADD);
11970 break;
11971 case SUB_FMT:
11972 FINSN_3ARG_SDPS(SUB);
11973 break;
11974 case MUL_FMT:
11975 FINSN_3ARG_SDPS(MUL);
11976 break;
11977 case DIV_FMT:
11978 fmt = (ctx->opcode >> 8) & 0x3;
11979 if (fmt == 1) {
11980 mips32_op = OPC_DIV_D;
11981 } else if (fmt == 0) {
11982 mips32_op = OPC_DIV_S;
11983 } else {
11984 goto pool32f_invalid;
11985 }
11986 goto do_fpop;
11987 default:
11988 goto pool32f_invalid;
11989 }
11990 break;
11991 case 0x38:
11992 /* cmovs */
11993 switch ((ctx->opcode >> 6) & 0x3) {
11994 case MOVN_FMT:
11995 FINSN_3ARG_SDPS(MOVN);
11996 break;
11997 case MOVZ_FMT:
11998 FINSN_3ARG_SDPS(MOVZ);
11999 break;
12000 default:
12001 goto pool32f_invalid;
12002 }
12003 break;
12004 do_fpop:
12005 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12006 break;
12007 default:
12008 pool32f_invalid:
12009 MIPS_INVAL("pool32f");
12010 generate_exception(ctx, EXCP_RI);
12011 break;
12012 }
12013 } else {
12014 generate_exception_err(ctx, EXCP_CpU, 1);
12015 }
12016 break;
12017 case POOL32I:
12018 minor = (ctx->opcode >> 21) & 0x1f;
12019 switch (minor) {
12020 case BLTZ:
12021 mips32_op = OPC_BLTZ;
12022 goto do_branch;
12023 case BLTZAL:
12024 mips32_op = OPC_BLTZAL;
12025 goto do_branch;
12026 case BLTZALS:
12027 mips32_op = OPC_BLTZALS;
12028 goto do_branch;
12029 case BGEZ:
12030 mips32_op = OPC_BGEZ;
12031 goto do_branch;
12032 case BGEZAL:
12033 mips32_op = OPC_BGEZAL;
12034 goto do_branch;
12035 case BGEZALS:
12036 mips32_op = OPC_BGEZALS;
12037 goto do_branch;
12038 case BLEZ:
12039 mips32_op = OPC_BLEZ;
12040 goto do_branch;
12041 case BGTZ:
12042 mips32_op = OPC_BGTZ;
12043 do_branch:
12044 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12045 *is_branch = 1;
12046 break;
12047
12048 /* Traps */
12049 case TLTI:
12050 mips32_op = OPC_TLTI;
12051 goto do_trapi;
12052 case TGEI:
12053 mips32_op = OPC_TGEI;
12054 goto do_trapi;
12055 case TLTIU:
12056 mips32_op = OPC_TLTIU;
12057 goto do_trapi;
12058 case TGEIU:
12059 mips32_op = OPC_TGEIU;
12060 goto do_trapi;
12061 case TNEI:
12062 mips32_op = OPC_TNEI;
12063 goto do_trapi;
12064 case TEQI:
12065 mips32_op = OPC_TEQI;
12066 do_trapi:
12067 gen_trap(ctx, mips32_op, rs, -1, imm);
12068 break;
12069
12070 case BNEZC:
12071 case BEQZC:
12072 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12073 4, rs, 0, imm << 1);
12074 /* Compact branches don't have a delay slot, so just let
12075 the normal delay slot handling take us to the branch
12076 target. */
12077 break;
12078 case LUI:
12079 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
12080 break;
12081 case SYNCI:
12082 break;
12083 case BC2F:
12084 case BC2T:
12085 /* COP2: Not implemented. */
12086 generate_exception_err(ctx, EXCP_CpU, 2);
12087 break;
12088 case BC1F:
12089 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12090 goto do_cp1branch;
12091 case BC1T:
12092 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12093 goto do_cp1branch;
12094 case BC1ANY4F:
12095 mips32_op = OPC_BC1FANY4;
12096 goto do_cp1mips3d;
12097 case BC1ANY4T:
12098 mips32_op = OPC_BC1TANY4;
12099 do_cp1mips3d:
12100 check_cop1x(ctx);
12101 check_insn(env, ctx, ASE_MIPS3D);
12102 /* Fall through */
12103 do_cp1branch:
12104 gen_compute_branch1(env, ctx, mips32_op,
12105 (ctx->opcode >> 18) & 0x7, imm << 1);
12106 *is_branch = 1;
12107 break;
12108 case BPOSGE64:
12109 case BPOSGE32:
12110 /* MIPS DSP: not implemented */
12111 /* Fall through */
12112 default:
12113 MIPS_INVAL("pool32i");
12114 generate_exception(ctx, EXCP_RI);
12115 break;
12116 }
12117 break;
12118 case POOL32C:
12119 minor = (ctx->opcode >> 12) & 0xf;
12120 switch (minor) {
12121 case LWL:
12122 mips32_op = OPC_LWL;
12123 goto do_ld_lr;
12124 case SWL:
12125 mips32_op = OPC_SWL;
12126 goto do_st_lr;
12127 case LWR:
12128 mips32_op = OPC_LWR;
12129 goto do_ld_lr;
12130 case SWR:
12131 mips32_op = OPC_SWR;
12132 goto do_st_lr;
12133 #if defined(TARGET_MIPS64)
12134 case LDL:
12135 mips32_op = OPC_LDL;
12136 goto do_ld_lr;
12137 case SDL:
12138 mips32_op = OPC_SDL;
12139 goto do_st_lr;
12140 case LDR:
12141 mips32_op = OPC_LDR;
12142 goto do_ld_lr;
12143 case SDR:
12144 mips32_op = OPC_SDR;
12145 goto do_st_lr;
12146 case LWU:
12147 mips32_op = OPC_LWU;
12148 goto do_ld_lr;
12149 case LLD:
12150 mips32_op = OPC_LLD;
12151 goto do_ld_lr;
12152 #endif
12153 case LL:
12154 mips32_op = OPC_LL;
12155 goto do_ld_lr;
12156 do_ld_lr:
12157 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12158 break;
12159 do_st_lr:
12160 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12161 break;
12162 case SC:
12163 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12164 break;
12165 #if defined(TARGET_MIPS64)
12166 case SCD:
12167 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12168 break;
12169 #endif
12170 case PREF:
12171 /* Treat as no-op */
12172 break;
12173 default:
12174 MIPS_INVAL("pool32c");
12175 generate_exception(ctx, EXCP_RI);
12176 break;
12177 }
12178 break;
12179 case ADDI32:
12180 mips32_op = OPC_ADDI;
12181 goto do_addi;
12182 case ADDIU32:
12183 mips32_op = OPC_ADDIU;
12184 do_addi:
12185 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12186 break;
12187
12188 /* Logical operations */
12189 case ORI32:
12190 mips32_op = OPC_ORI;
12191 goto do_logici;
12192 case XORI32:
12193 mips32_op = OPC_XORI;
12194 goto do_logici;
12195 case ANDI32:
12196 mips32_op = OPC_ANDI;
12197 do_logici:
12198 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
12199 break;
12200
12201 /* Set less than immediate */
12202 case SLTI32:
12203 mips32_op = OPC_SLTI;
12204 goto do_slti;
12205 case SLTIU32:
12206 mips32_op = OPC_SLTIU;
12207 do_slti:
12208 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
12209 break;
12210 case JALX32:
12211 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12212 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12213 *is_branch = 1;
12214 break;
12215 case JALS32:
12216 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12217 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12218 *is_branch = 1;
12219 break;
12220 case BEQ32:
12221 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12222 *is_branch = 1;
12223 break;
12224 case BNE32:
12225 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12226 *is_branch = 1;
12227 break;
12228 case J32:
12229 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12230 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12231 *is_branch = 1;
12232 break;
12233 case JAL32:
12234 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12235 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12236 *is_branch = 1;
12237 break;
12238 /* Floating point (COP1) */
12239 case LWC132:
12240 mips32_op = OPC_LWC1;
12241 goto do_cop1;
12242 case LDC132:
12243 mips32_op = OPC_LDC1;
12244 goto do_cop1;
12245 case SWC132:
12246 mips32_op = OPC_SWC1;
12247 goto do_cop1;
12248 case SDC132:
12249 mips32_op = OPC_SDC1;
12250 do_cop1:
12251 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12252 break;
12253 case ADDIUPC:
12254 {
12255 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12256 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12257
12258 gen_addiupc(ctx, reg, offset, 0, 0);
12259 }
12260 break;
12261 /* Loads and stores */
12262 case LB32:
12263 mips32_op = OPC_LB;
12264 goto do_ld;
12265 case LBU32:
12266 mips32_op = OPC_LBU;
12267 goto do_ld;
12268 case LH32:
12269 mips32_op = OPC_LH;
12270 goto do_ld;
12271 case LHU32:
12272 mips32_op = OPC_LHU;
12273 goto do_ld;
12274 case LW32:
12275 mips32_op = OPC_LW;
12276 goto do_ld;
12277 #ifdef TARGET_MIPS64
12278 case LD32:
12279 mips32_op = OPC_LD;
12280 goto do_ld;
12281 case SD32:
12282 mips32_op = OPC_SD;
12283 goto do_st;
12284 #endif
12285 case SB32:
12286 mips32_op = OPC_SB;
12287 goto do_st;
12288 case SH32:
12289 mips32_op = OPC_SH;
12290 goto do_st;
12291 case SW32:
12292 mips32_op = OPC_SW;
12293 goto do_st;
12294 do_ld:
12295 gen_ld(env, ctx, mips32_op, rt, rs, imm);
12296 break;
12297 do_st:
12298 gen_st(ctx, mips32_op, rt, rs, imm);
12299 break;
12300 default:
12301 generate_exception(ctx, EXCP_RI);
12302 break;
12303 }
12304 }
12305
12306 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12307 {
12308 uint32_t op;
12309
12310 /* make sure instructions are on a halfword boundary */
12311 if (ctx->pc & 0x1) {
12312 env->CP0_BadVAddr = ctx->pc;
12313 generate_exception(ctx, EXCP_AdEL);
12314 ctx->bstate = BS_STOP;
12315 return 2;
12316 }
12317
12318 op = (ctx->opcode >> 10) & 0x3f;
12319 /* Enforce properly-sized instructions in a delay slot */
12320 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12321 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12322
12323 switch (op) {
12324 case POOL32A:
12325 case POOL32B:
12326 case POOL32I:
12327 case POOL32C:
12328 case ADDI32:
12329 case ADDIU32:
12330 case ORI32:
12331 case XORI32:
12332 case SLTI32:
12333 case SLTIU32:
12334 case ANDI32:
12335 case JALX32:
12336 case LBU32:
12337 case LHU32:
12338 case POOL32F:
12339 case JALS32:
12340 case BEQ32:
12341 case BNE32:
12342 case J32:
12343 case JAL32:
12344 case SB32:
12345 case SH32:
12346 case POOL32S:
12347 case ADDIUPC:
12348 case SWC132:
12349 case SDC132:
12350 case SD32:
12351 case SW32:
12352 case LB32:
12353 case LH32:
12354 case DADDIU32:
12355 case POOL48A: /* ??? */
12356 case LWC132:
12357 case LDC132:
12358 case LD32:
12359 case LW32:
12360 if (bits & MIPS_HFLAG_BDS16) {
12361 generate_exception(ctx, EXCP_RI);
12362 /* Just stop translation; the user is confused. */
12363 ctx->bstate = BS_STOP;
12364 return 2;
12365 }
12366 break;
12367 case POOL16A:
12368 case POOL16B:
12369 case POOL16C:
12370 case LWGP16:
12371 case POOL16F:
12372 case LBU16:
12373 case LHU16:
12374 case LWSP16:
12375 case LW16:
12376 case SB16:
12377 case SH16:
12378 case SWSP16:
12379 case SW16:
12380 case MOVE16:
12381 case ANDI16:
12382 case POOL16D:
12383 case POOL16E:
12384 case BEQZ16:
12385 case BNEZ16:
12386 case B16:
12387 case LI16:
12388 if (bits & MIPS_HFLAG_BDS32) {
12389 generate_exception(ctx, EXCP_RI);
12390 /* Just stop translation; the user is confused. */
12391 ctx->bstate = BS_STOP;
12392 return 2;
12393 }
12394 break;
12395 default:
12396 break;
12397 }
12398 }
12399 switch (op) {
12400 case POOL16A:
12401 {
12402 int rd = mmreg(uMIPS_RD(ctx->opcode));
12403 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12404 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12405 uint32_t opc = 0;
12406
12407 switch (ctx->opcode & 0x1) {
12408 case ADDU16:
12409 opc = OPC_ADDU;
12410 break;
12411 case SUBU16:
12412 opc = OPC_SUBU;
12413 break;
12414 }
12415
12416 gen_arith(env, ctx, opc, rd, rs1, rs2);
12417 }
12418 break;
12419 case POOL16B:
12420 {
12421 int rd = mmreg(uMIPS_RD(ctx->opcode));
12422 int rs = mmreg(uMIPS_RS(ctx->opcode));
12423 int amount = (ctx->opcode >> 1) & 0x7;
12424 uint32_t opc = 0;
12425 amount = amount == 0 ? 8 : amount;
12426
12427 switch (ctx->opcode & 0x1) {
12428 case SLL16:
12429 opc = OPC_SLL;
12430 break;
12431 case SRL16:
12432 opc = OPC_SRL;
12433 break;
12434 }
12435
12436 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12437 }
12438 break;
12439 case POOL16C:
12440 gen_pool16c_insn(env, ctx, is_branch);
12441 break;
12442 case LWGP16:
12443 {
12444 int rd = mmreg(uMIPS_RD(ctx->opcode));
12445 int rb = 28; /* GP */
12446 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12447
12448 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12449 }
12450 break;
12451 case POOL16F:
12452 if (ctx->opcode & 1) {
12453 generate_exception(ctx, EXCP_RI);
12454 } else {
12455 /* MOVEP */
12456 int enc_dest = uMIPS_RD(ctx->opcode);
12457 int enc_rt = uMIPS_RS2(ctx->opcode);
12458 int enc_rs = uMIPS_RS1(ctx->opcode);
12459 int rd, rs, re, rt;
12460 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12461 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12462 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12463
12464 rd = rd_enc[enc_dest];
12465 re = re_enc[enc_dest];
12466 rs = rs_rt_enc[enc_rs];
12467 rt = rs_rt_enc[enc_rt];
12468
12469 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12470 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12471 }
12472 break;
12473 case LBU16:
12474 {
12475 int rd = mmreg(uMIPS_RD(ctx->opcode));
12476 int rb = mmreg(uMIPS_RS(ctx->opcode));
12477 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12478 offset = (offset == 0xf ? -1 : offset);
12479
12480 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
12481 }
12482 break;
12483 case LHU16:
12484 {
12485 int rd = mmreg(uMIPS_RD(ctx->opcode));
12486 int rb = mmreg(uMIPS_RS(ctx->opcode));
12487 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12488
12489 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
12490 }
12491 break;
12492 case LWSP16:
12493 {
12494 int rd = (ctx->opcode >> 5) & 0x1f;
12495 int rb = 29; /* SP */
12496 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12497
12498 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12499 }
12500 break;
12501 case LW16:
12502 {
12503 int rd = mmreg(uMIPS_RD(ctx->opcode));
12504 int rb = mmreg(uMIPS_RS(ctx->opcode));
12505 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12506
12507 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
12508 }
12509 break;
12510 case SB16:
12511 {
12512 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12513 int rb = mmreg(uMIPS_RS(ctx->opcode));
12514 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12515
12516 gen_st(ctx, OPC_SB, rd, rb, offset);
12517 }
12518 break;
12519 case SH16:
12520 {
12521 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12522 int rb = mmreg(uMIPS_RS(ctx->opcode));
12523 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12524
12525 gen_st(ctx, OPC_SH, rd, rb, offset);
12526 }
12527 break;
12528 case SWSP16:
12529 {
12530 int rd = (ctx->opcode >> 5) & 0x1f;
12531 int rb = 29; /* SP */
12532 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12533
12534 gen_st(ctx, OPC_SW, rd, rb, offset);
12535 }
12536 break;
12537 case SW16:
12538 {
12539 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12540 int rb = mmreg(uMIPS_RS(ctx->opcode));
12541 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12542
12543 gen_st(ctx, OPC_SW, rd, rb, offset);
12544 }
12545 break;
12546 case MOVE16:
12547 {
12548 int rd = uMIPS_RD5(ctx->opcode);
12549 int rs = uMIPS_RS5(ctx->opcode);
12550
12551 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12552 }
12553 break;
12554 case ANDI16:
12555 gen_andi16(env, ctx);
12556 break;
12557 case POOL16D:
12558 switch (ctx->opcode & 0x1) {
12559 case ADDIUS5:
12560 gen_addius5(env, ctx);
12561 break;
12562 case ADDIUSP:
12563 gen_addiusp(env, ctx);
12564 break;
12565 }
12566 break;
12567 case POOL16E:
12568 switch (ctx->opcode & 0x1) {
12569 case ADDIUR2:
12570 gen_addiur2(env, ctx);
12571 break;
12572 case ADDIUR1SP:
12573 gen_addiur1sp(env, ctx);
12574 break;
12575 }
12576 break;
12577 case B16:
12578 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12579 SIMM(ctx->opcode, 0, 10) << 1);
12580 *is_branch = 1;
12581 break;
12582 case BNEZ16:
12583 case BEQZ16:
12584 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12585 mmreg(uMIPS_RD(ctx->opcode)),
12586 0, SIMM(ctx->opcode, 0, 7) << 1);
12587 *is_branch = 1;
12588 break;
12589 case LI16:
12590 {
12591 int reg = mmreg(uMIPS_RD(ctx->opcode));
12592 int imm = ZIMM(ctx->opcode, 0, 7);
12593
12594 imm = (imm == 0x7f ? -1 : imm);
12595 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12596 }
12597 break;
12598 case RES_20:
12599 case RES_28:
12600 case RES_29:
12601 case RES_30:
12602 case RES_31:
12603 case RES_38:
12604 case RES_39:
12605 generate_exception(ctx, EXCP_RI);
12606 break;
12607 default:
12608 decode_micromips32_opc (env, ctx, op, is_branch);
12609 return 4;
12610 }
12611
12612 return 2;
12613 }
12614
12615 /* SmartMIPS extension to MIPS32 */
12616
12617 #if defined(TARGET_MIPS64)
12618
12619 /* MDMX extension to MIPS64 */
12620
12621 #endif
12622
12623 /* MIPSDSP functions. */
12624 static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12625 int rd, int base, int offset)
12626 {
12627 const char *opn = "ldx";
12628 TCGv t0;
12629
12630 if (rd == 0) {
12631 MIPS_DEBUG("NOP");
12632 return;
12633 }
12634
12635 check_dsp(ctx);
12636 t0 = tcg_temp_new();
12637
12638 if (base == 0) {
12639 gen_load_gpr(t0, offset);
12640 } else if (offset == 0) {
12641 gen_load_gpr(t0, base);
12642 } else {
12643 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12644 }
12645
12646 switch (opc) {
12647 case OPC_LBUX:
12648 tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12649 gen_store_gpr(t0, rd);
12650 opn = "lbux";
12651 break;
12652 case OPC_LHX:
12653 tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12654 gen_store_gpr(t0, rd);
12655 opn = "lhx";
12656 break;
12657 case OPC_LWX:
12658 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12659 gen_store_gpr(t0, rd);
12660 opn = "lwx";
12661 break;
12662 #if defined(TARGET_MIPS64)
12663 case OPC_LDX:
12664 tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12665 gen_store_gpr(t0, rd);
12666 opn = "ldx";
12667 break;
12668 #endif
12669 }
12670 (void)opn; /* avoid a compiler warning */
12671 MIPS_DEBUG("%s %s, %s(%s)", opn,
12672 regnames[rd], regnames[offset], regnames[base]);
12673 tcg_temp_free(t0);
12674 }
12675
12676 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12677 int ret, int v1, int v2)
12678 {
12679 const char *opn = "mipsdsp arith";
12680 TCGv v1_t;
12681 TCGv v2_t;
12682
12683 if (ret == 0) {
12684 /* Treat as NOP. */
12685 MIPS_DEBUG("NOP");
12686 return;
12687 }
12688
12689 v1_t = tcg_temp_new();
12690 v2_t = tcg_temp_new();
12691
12692 gen_load_gpr(v1_t, v1);
12693 gen_load_gpr(v2_t, v2);
12694
12695 switch (op1) {
12696 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12697 case OPC_MULT_G_2E:
12698 check_dspr2(ctx);
12699 switch (op2) {
12700 case OPC_ADDUH_QB:
12701 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12702 break;
12703 case OPC_ADDUH_R_QB:
12704 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12705 break;
12706 case OPC_ADDQH_PH:
12707 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12708 break;
12709 case OPC_ADDQH_R_PH:
12710 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12711 break;
12712 case OPC_ADDQH_W:
12713 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12714 break;
12715 case OPC_ADDQH_R_W:
12716 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12717 break;
12718 case OPC_SUBUH_QB:
12719 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12720 break;
12721 case OPC_SUBUH_R_QB:
12722 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12723 break;
12724 case OPC_SUBQH_PH:
12725 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12726 break;
12727 case OPC_SUBQH_R_PH:
12728 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12729 break;
12730 case OPC_SUBQH_W:
12731 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12732 break;
12733 case OPC_SUBQH_R_W:
12734 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12735 break;
12736 }
12737 break;
12738 case OPC_ABSQ_S_PH_DSP:
12739 switch (op2) {
12740 case OPC_ABSQ_S_QB:
12741 check_dspr2(ctx);
12742 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12743 break;
12744 case OPC_ABSQ_S_PH:
12745 check_dsp(ctx);
12746 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12747 break;
12748 case OPC_ABSQ_S_W:
12749 check_dsp(ctx);
12750 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12751 break;
12752 case OPC_PRECEQ_W_PHL:
12753 check_dsp(ctx);
12754 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12755 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12756 break;
12757 case OPC_PRECEQ_W_PHR:
12758 check_dsp(ctx);
12759 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12760 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12761 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12762 break;
12763 case OPC_PRECEQU_PH_QBL:
12764 check_dsp(ctx);
12765 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12766 break;
12767 case OPC_PRECEQU_PH_QBR:
12768 check_dsp(ctx);
12769 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12770 break;
12771 case OPC_PRECEQU_PH_QBLA:
12772 check_dsp(ctx);
12773 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12774 break;
12775 case OPC_PRECEQU_PH_QBRA:
12776 check_dsp(ctx);
12777 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12778 break;
12779 case OPC_PRECEU_PH_QBL:
12780 check_dsp(ctx);
12781 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12782 break;
12783 case OPC_PRECEU_PH_QBR:
12784 check_dsp(ctx);
12785 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12786 break;
12787 case OPC_PRECEU_PH_QBLA:
12788 check_dsp(ctx);
12789 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12790 break;
12791 case OPC_PRECEU_PH_QBRA:
12792 check_dsp(ctx);
12793 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12794 break;
12795 }
12796 break;
12797 case OPC_ADDU_QB_DSP:
12798 switch (op2) {
12799 case OPC_ADDQ_PH:
12800 check_dsp(ctx);
12801 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12802 break;
12803 case OPC_ADDQ_S_PH:
12804 check_dsp(ctx);
12805 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12806 break;
12807 case OPC_ADDQ_S_W:
12808 check_dsp(ctx);
12809 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12810 break;
12811 case OPC_ADDU_QB:
12812 check_dsp(ctx);
12813 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12814 break;
12815 case OPC_ADDU_S_QB:
12816 check_dsp(ctx);
12817 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12818 break;
12819 case OPC_ADDU_PH:
12820 check_dspr2(ctx);
12821 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12822 break;
12823 case OPC_ADDU_S_PH:
12824 check_dspr2(ctx);
12825 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12826 break;
12827 case OPC_SUBQ_PH:
12828 check_dsp(ctx);
12829 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12830 break;
12831 case OPC_SUBQ_S_PH:
12832 check_dsp(ctx);
12833 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12834 break;
12835 case OPC_SUBQ_S_W:
12836 check_dsp(ctx);
12837 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12838 break;
12839 case OPC_SUBU_QB:
12840 check_dsp(ctx);
12841 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12842 break;
12843 case OPC_SUBU_S_QB:
12844 check_dsp(ctx);
12845 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12846 break;
12847 case OPC_SUBU_PH:
12848 check_dspr2(ctx);
12849 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12850 break;
12851 case OPC_SUBU_S_PH:
12852 check_dspr2(ctx);
12853 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12854 break;
12855 case OPC_ADDSC:
12856 check_dsp(ctx);
12857 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12858 break;
12859 case OPC_ADDWC:
12860 check_dsp(ctx);
12861 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12862 break;
12863 case OPC_MODSUB:
12864 check_dsp(ctx);
12865 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12866 break;
12867 case OPC_RADDU_W_QB:
12868 check_dsp(ctx);
12869 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12870 break;
12871 }
12872 break;
12873 case OPC_CMPU_EQ_QB_DSP:
12874 switch (op2) {
12875 case OPC_PRECR_QB_PH:
12876 check_dspr2(ctx);
12877 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12878 break;
12879 case OPC_PRECRQ_QB_PH:
12880 check_dsp(ctx);
12881 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12882 break;
12883 case OPC_PRECR_SRA_PH_W:
12884 check_dspr2(ctx);
12885 {
12886 TCGv_i32 sa_t = tcg_const_i32(v2);
12887 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12888 cpu_gpr[ret]);
12889 tcg_temp_free_i32(sa_t);
12890 break;
12891 }
12892 case OPC_PRECR_SRA_R_PH_W:
12893 check_dspr2(ctx);
12894 {
12895 TCGv_i32 sa_t = tcg_const_i32(v2);
12896 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12897 cpu_gpr[ret]);
12898 tcg_temp_free_i32(sa_t);
12899 break;
12900 }
12901 case OPC_PRECRQ_PH_W:
12902 check_dsp(ctx);
12903 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12904 break;
12905 case OPC_PRECRQ_RS_PH_W:
12906 check_dsp(ctx);
12907 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12908 break;
12909 case OPC_PRECRQU_S_QB_PH:
12910 check_dsp(ctx);
12911 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12912 break;
12913 }
12914 break;
12915 #ifdef TARGET_MIPS64
12916 case OPC_ABSQ_S_QH_DSP:
12917 switch (op2) {
12918 case OPC_PRECEQ_L_PWL:
12919 check_dsp(ctx);
12920 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12921 break;
12922 case OPC_PRECEQ_L_PWR:
12923 check_dsp(ctx);
12924 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12925 break;
12926 case OPC_PRECEQ_PW_QHL:
12927 check_dsp(ctx);
12928 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12929 break;
12930 case OPC_PRECEQ_PW_QHR:
12931 check_dsp(ctx);
12932 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12933 break;
12934 case OPC_PRECEQ_PW_QHLA:
12935 check_dsp(ctx);
12936 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12937 break;
12938 case OPC_PRECEQ_PW_QHRA:
12939 check_dsp(ctx);
12940 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12941 break;
12942 case OPC_PRECEQU_QH_OBL:
12943 check_dsp(ctx);
12944 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12945 break;
12946 case OPC_PRECEQU_QH_OBR:
12947 check_dsp(ctx);
12948 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12949 break;
12950 case OPC_PRECEQU_QH_OBLA:
12951 check_dsp(ctx);
12952 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12953 break;
12954 case OPC_PRECEQU_QH_OBRA:
12955 check_dsp(ctx);
12956 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12957 break;
12958 case OPC_PRECEU_QH_OBL:
12959 check_dsp(ctx);
12960 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12961 break;
12962 case OPC_PRECEU_QH_OBR:
12963 check_dsp(ctx);
12964 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12965 break;
12966 case OPC_PRECEU_QH_OBLA:
12967 check_dsp(ctx);
12968 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12969 break;
12970 case OPC_PRECEU_QH_OBRA:
12971 check_dsp(ctx);
12972 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12973 break;
12974 case OPC_ABSQ_S_OB:
12975 check_dspr2(ctx);
12976 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12977 break;
12978 case OPC_ABSQ_S_PW:
12979 check_dsp(ctx);
12980 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12981 break;
12982 case OPC_ABSQ_S_QH:
12983 check_dsp(ctx);
12984 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12985 break;
12986 }
12987 break;
12988 case OPC_ADDU_OB_DSP:
12989 switch (op2) {
12990 case OPC_RADDU_L_OB:
12991 check_dsp(ctx);
12992 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12993 break;
12994 case OPC_SUBQ_PW:
12995 check_dsp(ctx);
12996 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12997 break;
12998 case OPC_SUBQ_S_PW:
12999 check_dsp(ctx);
13000 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13001 break;
13002 case OPC_SUBQ_QH:
13003 check_dsp(ctx);
13004 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13005 break;
13006 case OPC_SUBQ_S_QH:
13007 check_dsp(ctx);
13008 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13009 break;
13010 case OPC_SUBU_OB:
13011 check_dsp(ctx);
13012 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13013 break;
13014 case OPC_SUBU_S_OB:
13015 check_dsp(ctx);
13016 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13017 break;
13018 case OPC_SUBU_QH:
13019 check_dspr2(ctx);
13020 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13021 break;
13022 case OPC_SUBU_S_QH:
13023 check_dspr2(ctx);
13024 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13025 break;
13026 case OPC_SUBUH_OB:
13027 check_dspr2(ctx);
13028 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13029 break;
13030 case OPC_SUBUH_R_OB:
13031 check_dspr2(ctx);
13032 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13033 break;
13034 case OPC_ADDQ_PW:
13035 check_dsp(ctx);
13036 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13037 break;
13038 case OPC_ADDQ_S_PW:
13039 check_dsp(ctx);
13040 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13041 break;
13042 case OPC_ADDQ_QH:
13043 check_dsp(ctx);
13044 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13045 break;
13046 case OPC_ADDQ_S_QH:
13047 check_dsp(ctx);
13048 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13049 break;
13050 case OPC_ADDU_OB:
13051 check_dsp(ctx);
13052 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13053 break;
13054 case OPC_ADDU_S_OB:
13055 check_dsp(ctx);
13056 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13057 break;
13058 case OPC_ADDU_QH:
13059 check_dspr2(ctx);
13060 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13061 break;
13062 case OPC_ADDU_S_QH:
13063 check_dspr2(ctx);
13064 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13065 break;
13066 case OPC_ADDUH_OB:
13067 check_dspr2(ctx);
13068 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13069 break;
13070 case OPC_ADDUH_R_OB:
13071 check_dspr2(ctx);
13072 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13073 break;
13074 }
13075 break;
13076 case OPC_CMPU_EQ_OB_DSP:
13077 switch (op2) {
13078 case OPC_PRECR_OB_QH:
13079 check_dspr2(ctx);
13080 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13081 break;
13082 case OPC_PRECR_SRA_QH_PW:
13083 check_dspr2(ctx);
13084 {
13085 TCGv_i32 ret_t = tcg_const_i32(ret);
13086 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13087 tcg_temp_free_i32(ret_t);
13088 break;
13089 }
13090 case OPC_PRECR_SRA_R_QH_PW:
13091 check_dspr2(ctx);
13092 {
13093 TCGv_i32 sa_v = tcg_const_i32(ret);
13094 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13095 tcg_temp_free_i32(sa_v);
13096 break;
13097 }
13098 case OPC_PRECRQ_OB_QH:
13099 check_dsp(ctx);
13100 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13101 break;
13102 case OPC_PRECRQ_PW_L:
13103 check_dsp(ctx);
13104 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13105 break;
13106 case OPC_PRECRQ_QH_PW:
13107 check_dsp(ctx);
13108 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13109 break;
13110 case OPC_PRECRQ_RS_QH_PW:
13111 check_dsp(ctx);
13112 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13113 break;
13114 case OPC_PRECRQU_S_OB_QH:
13115 check_dsp(ctx);
13116 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13117 break;
13118 }
13119 break;
13120 #endif
13121 }
13122
13123 tcg_temp_free(v1_t);
13124 tcg_temp_free(v2_t);
13125
13126 (void)opn; /* avoid a compiler warning */
13127 MIPS_DEBUG("%s", opn);
13128 }
13129
13130 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13131 int ret, int v1, int v2)
13132 {
13133 uint32_t op2;
13134 const char *opn = "mipsdsp shift";
13135 TCGv t0;
13136 TCGv v1_t;
13137 TCGv v2_t;
13138
13139 if (ret == 0) {
13140 /* Treat as NOP. */
13141 MIPS_DEBUG("NOP");
13142 return;
13143 }
13144
13145 t0 = tcg_temp_new();
13146 v1_t = tcg_temp_new();
13147 v2_t = tcg_temp_new();
13148
13149 tcg_gen_movi_tl(t0, v1);
13150 gen_load_gpr(v1_t, v1);
13151 gen_load_gpr(v2_t, v2);
13152
13153 switch (opc) {
13154 case OPC_SHLL_QB_DSP:
13155 {
13156 op2 = MASK_SHLL_QB(ctx->opcode);
13157 switch (op2) {
13158 case OPC_SHLL_QB:
13159 check_dsp(ctx);
13160 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13161 break;
13162 case OPC_SHLLV_QB:
13163 check_dsp(ctx);
13164 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13165 break;
13166 case OPC_SHLL_PH:
13167 check_dsp(ctx);
13168 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13169 break;
13170 case OPC_SHLLV_PH:
13171 check_dsp(ctx);
13172 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13173 break;
13174 case OPC_SHLL_S_PH:
13175 check_dsp(ctx);
13176 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13177 break;
13178 case OPC_SHLLV_S_PH:
13179 check_dsp(ctx);
13180 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13181 break;
13182 case OPC_SHLL_S_W:
13183 check_dsp(ctx);
13184 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13185 break;
13186 case OPC_SHLLV_S_W:
13187 check_dsp(ctx);
13188 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13189 break;
13190 case OPC_SHRL_QB:
13191 check_dsp(ctx);
13192 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13193 break;
13194 case OPC_SHRLV_QB:
13195 check_dsp(ctx);
13196 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13197 break;
13198 case OPC_SHRL_PH:
13199 check_dspr2(ctx);
13200 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13201 break;
13202 case OPC_SHRLV_PH:
13203 check_dspr2(ctx);
13204 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13205 break;
13206 case OPC_SHRA_QB:
13207 check_dspr2(ctx);
13208 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13209 break;
13210 case OPC_SHRA_R_QB:
13211 check_dspr2(ctx);
13212 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13213 break;
13214 case OPC_SHRAV_QB:
13215 check_dspr2(ctx);
13216 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13217 break;
13218 case OPC_SHRAV_R_QB:
13219 check_dspr2(ctx);
13220 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13221 break;
13222 case OPC_SHRA_PH:
13223 check_dsp(ctx);
13224 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13225 break;
13226 case OPC_SHRA_R_PH:
13227 check_dsp(ctx);
13228 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13229 break;
13230 case OPC_SHRAV_PH:
13231 check_dsp(ctx);
13232 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13233 break;
13234 case OPC_SHRAV_R_PH:
13235 check_dsp(ctx);
13236 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13237 break;
13238 case OPC_SHRA_R_W:
13239 check_dsp(ctx);
13240 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13241 break;
13242 case OPC_SHRAV_R_W:
13243 check_dsp(ctx);
13244 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13245 break;
13246 default: /* Invalid */
13247 MIPS_INVAL("MASK SHLL.QB");
13248 generate_exception(ctx, EXCP_RI);
13249 break;
13250 }
13251 break;
13252 }
13253 #ifdef TARGET_MIPS64
13254 case OPC_SHLL_OB_DSP:
13255 op2 = MASK_SHLL_OB(ctx->opcode);
13256 switch (op2) {
13257 case OPC_SHLL_PW:
13258 check_dsp(ctx);
13259 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13260 break;
13261 case OPC_SHLLV_PW:
13262 check_dsp(ctx);
13263 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13264 break;
13265 case OPC_SHLL_S_PW:
13266 check_dsp(ctx);
13267 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13268 break;
13269 case OPC_SHLLV_S_PW:
13270 check_dsp(ctx);
13271 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13272 break;
13273 case OPC_SHLL_OB:
13274 check_dsp(ctx);
13275 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13276 break;
13277 case OPC_SHLLV_OB:
13278 check_dsp(ctx);
13279 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13280 break;
13281 case OPC_SHLL_QH:
13282 check_dsp(ctx);
13283 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13284 break;
13285 case OPC_SHLLV_QH:
13286 check_dsp(ctx);
13287 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13288 break;
13289 case OPC_SHLL_S_QH:
13290 check_dsp(ctx);
13291 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13292 break;
13293 case OPC_SHLLV_S_QH:
13294 check_dsp(ctx);
13295 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13296 break;
13297 case OPC_SHRA_OB:
13298 check_dspr2(ctx);
13299 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13300 break;
13301 case OPC_SHRAV_OB:
13302 check_dspr2(ctx);
13303 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13304 break;
13305 case OPC_SHRA_R_OB:
13306 check_dspr2(ctx);
13307 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13308 break;
13309 case OPC_SHRAV_R_OB:
13310 check_dspr2(ctx);
13311 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13312 break;
13313 case OPC_SHRA_PW:
13314 check_dsp(ctx);
13315 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13316 break;
13317 case OPC_SHRAV_PW:
13318 check_dsp(ctx);
13319 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13320 break;
13321 case OPC_SHRA_R_PW:
13322 check_dsp(ctx);
13323 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13324 break;
13325 case OPC_SHRAV_R_PW:
13326 check_dsp(ctx);
13327 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13328 break;
13329 case OPC_SHRA_QH:
13330 check_dsp(ctx);
13331 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13332 break;
13333 case OPC_SHRAV_QH:
13334 check_dsp(ctx);
13335 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13336 break;
13337 case OPC_SHRA_R_QH:
13338 check_dsp(ctx);
13339 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13340 break;
13341 case OPC_SHRAV_R_QH:
13342 check_dsp(ctx);
13343 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13344 break;
13345 case OPC_SHRL_OB:
13346 check_dsp(ctx);
13347 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13348 break;
13349 case OPC_SHRLV_OB:
13350 check_dsp(ctx);
13351 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13352 break;
13353 case OPC_SHRL_QH:
13354 check_dspr2(ctx);
13355 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13356 break;
13357 case OPC_SHRLV_QH:
13358 check_dspr2(ctx);
13359 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13360 break;
13361 default: /* Invalid */
13362 MIPS_INVAL("MASK SHLL.OB");
13363 generate_exception(ctx, EXCP_RI);
13364 break;
13365 }
13366 break;
13367 #endif
13368 }
13369
13370 tcg_temp_free(t0);
13371 tcg_temp_free(v1_t);
13372 tcg_temp_free(v2_t);
13373 (void)opn; /* avoid a compiler warning */
13374 MIPS_DEBUG("%s", opn);
13375 }
13376
13377 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13378 int ret, int v1, int v2, int check_ret)
13379 {
13380 const char *opn = "mipsdsp multiply";
13381 TCGv_i32 t0;
13382 TCGv v1_t;
13383 TCGv v2_t;
13384
13385 if ((ret == 0) && (check_ret == 1)) {
13386 /* Treat as NOP. */
13387 MIPS_DEBUG("NOP");
13388 return;
13389 }
13390
13391 t0 = tcg_temp_new_i32();
13392 v1_t = tcg_temp_new();
13393 v2_t = tcg_temp_new();
13394
13395 tcg_gen_movi_i32(t0, ret);
13396 gen_load_gpr(v1_t, v1);
13397 gen_load_gpr(v2_t, v2);
13398
13399 switch (op1) {
13400 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13401 * the same mask and op1. */
13402 case OPC_MULT_G_2E:
13403 switch (op2) {
13404 case OPC_MUL_PH:
13405 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13406 break;
13407 case OPC_MUL_S_PH:
13408 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13409 break;
13410 case OPC_MULQ_S_W:
13411 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13412 break;
13413 case OPC_MULQ_RS_W:
13414 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13415 break;
13416 }
13417 break;
13418 case OPC_DPA_W_PH_DSP:
13419 switch (op2) {
13420 case OPC_DPAU_H_QBL:
13421 check_dsp(ctx);
13422 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13423 break;
13424 case OPC_DPAU_H_QBR:
13425 check_dsp(ctx);
13426 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13427 break;
13428 case OPC_DPSU_H_QBL:
13429 check_dsp(ctx);
13430 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13431 break;
13432 case OPC_DPSU_H_QBR:
13433 check_dsp(ctx);
13434 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13435 break;
13436 case OPC_DPA_W_PH:
13437 check_dspr2(ctx);
13438 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13439 break;
13440 case OPC_DPAX_W_PH:
13441 check_dspr2(ctx);
13442 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13443 break;
13444 case OPC_DPAQ_S_W_PH:
13445 check_dsp(ctx);
13446 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13447 break;
13448 case OPC_DPAQX_S_W_PH:
13449 check_dspr2(ctx);
13450 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13451 break;
13452 case OPC_DPAQX_SA_W_PH:
13453 check_dspr2(ctx);
13454 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13455 break;
13456 case OPC_DPS_W_PH:
13457 check_dspr2(ctx);
13458 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13459 break;
13460 case OPC_DPSX_W_PH:
13461 check_dspr2(ctx);
13462 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13463 break;
13464 case OPC_DPSQ_S_W_PH:
13465 check_dsp(ctx);
13466 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13467 break;
13468 case OPC_DPSQX_S_W_PH:
13469 check_dspr2(ctx);
13470 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13471 break;
13472 case OPC_DPSQX_SA_W_PH:
13473 check_dspr2(ctx);
13474 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13475 break;
13476 case OPC_MULSAQ_S_W_PH:
13477 check_dsp(ctx);
13478 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13479 break;
13480 case OPC_DPAQ_SA_L_W:
13481 check_dsp(ctx);
13482 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13483 break;
13484 case OPC_DPSQ_SA_L_W:
13485 check_dsp(ctx);
13486 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13487 break;
13488 case OPC_MAQ_S_W_PHL:
13489 check_dsp(ctx);
13490 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13491 break;
13492 case OPC_MAQ_S_W_PHR:
13493 check_dsp(ctx);
13494 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13495 break;
13496 case OPC_MAQ_SA_W_PHL:
13497 check_dsp(ctx);
13498 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13499 break;
13500 case OPC_MAQ_SA_W_PHR:
13501 check_dsp(ctx);
13502 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13503 break;
13504 case OPC_MULSA_W_PH:
13505 check_dspr2(ctx);
13506 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13507 break;
13508 }
13509 break;
13510 #ifdef TARGET_MIPS64
13511 case OPC_DPAQ_W_QH_DSP:
13512 {
13513 int ac = ret & 0x03;
13514 tcg_gen_movi_i32(t0, ac);
13515
13516 switch (op2) {
13517 case OPC_DMADD:
13518 check_dsp(ctx);
13519 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13520 break;
13521 case OPC_DMADDU:
13522 check_dsp(ctx);
13523 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13524 break;
13525 case OPC_DMSUB:
13526 check_dsp(ctx);
13527 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13528 break;
13529 case OPC_DMSUBU:
13530 check_dsp(ctx);
13531 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13532 break;
13533 case OPC_DPA_W_QH:
13534 check_dspr2(ctx);
13535 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13536 break;
13537 case OPC_DPAQ_S_W_QH:
13538 check_dsp(ctx);
13539 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13540 break;
13541 case OPC_DPAQ_SA_L_PW:
13542 check_dsp(ctx);
13543 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13544 break;
13545 case OPC_DPAU_H_OBL:
13546 check_dsp(ctx);
13547 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13548 break;
13549 case OPC_DPAU_H_OBR:
13550 check_dsp(ctx);
13551 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13552 break;
13553 case OPC_DPS_W_QH:
13554 check_dspr2(ctx);
13555 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13556 break;
13557 case OPC_DPSQ_S_W_QH:
13558 check_dsp(ctx);
13559 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13560 break;
13561 case OPC_DPSQ_SA_L_PW:
13562 check_dsp(ctx);
13563 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13564 break;
13565 case OPC_DPSU_H_OBL:
13566 check_dsp(ctx);
13567 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13568 break;
13569 case OPC_DPSU_H_OBR:
13570 check_dsp(ctx);
13571 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13572 break;
13573 case OPC_MAQ_S_L_PWL:
13574 check_dsp(ctx);
13575 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13576 break;
13577 case OPC_MAQ_S_L_PWR:
13578 check_dsp(ctx);
13579 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13580 break;
13581 case OPC_MAQ_S_W_QHLL:
13582 check_dsp(ctx);
13583 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13584 break;
13585 case OPC_MAQ_SA_W_QHLL:
13586 check_dsp(ctx);
13587 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13588 break;
13589 case OPC_MAQ_S_W_QHLR:
13590 check_dsp(ctx);
13591 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13592 break;
13593 case OPC_MAQ_SA_W_QHLR:
13594 check_dsp(ctx);
13595 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13596 break;
13597 case OPC_MAQ_S_W_QHRL:
13598 check_dsp(ctx);
13599 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13600 break;
13601 case OPC_MAQ_SA_W_QHRL:
13602 check_dsp(ctx);
13603 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13604 break;
13605 case OPC_MAQ_S_W_QHRR:
13606 check_dsp(ctx);
13607 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13608 break;
13609 case OPC_MAQ_SA_W_QHRR:
13610 check_dsp(ctx);
13611 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13612 break;
13613 case OPC_MULSAQ_S_L_PW:
13614 check_dsp(ctx);
13615 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13616 break;
13617 case OPC_MULSAQ_S_W_QH:
13618 check_dsp(ctx);
13619 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13620 break;
13621 }
13622 }
13623 break;
13624 #endif
13625 case OPC_ADDU_QB_DSP:
13626 switch (op2) {
13627 case OPC_MULEU_S_PH_QBL:
13628 check_dsp(ctx);
13629 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13630 break;
13631 case OPC_MULEU_S_PH_QBR:
13632 check_dsp(ctx);
13633 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13634 break;
13635 case OPC_MULQ_RS_PH:
13636 check_dsp(ctx);
13637 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13638 break;
13639 case OPC_MULEQ_S_W_PHL:
13640 check_dsp(ctx);
13641 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13642 break;
13643 case OPC_MULEQ_S_W_PHR:
13644 check_dsp(ctx);
13645 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13646 break;
13647 case OPC_MULQ_S_PH:
13648 check_dspr2(ctx);
13649 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13650 break;
13651 }
13652 break;
13653 #ifdef TARGET_MIPS64
13654 case OPC_ADDU_OB_DSP:
13655 switch (op2) {
13656 case OPC_MULEQ_S_PW_QHL:
13657 check_dsp(ctx);
13658 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13659 break;
13660 case OPC_MULEQ_S_PW_QHR:
13661 check_dsp(ctx);
13662 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13663 break;
13664 case OPC_MULEU_S_QH_OBL:
13665 check_dsp(ctx);
13666 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13667 break;
13668 case OPC_MULEU_S_QH_OBR:
13669 check_dsp(ctx);
13670 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13671 break;
13672 case OPC_MULQ_RS_QH:
13673 check_dsp(ctx);
13674 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13675 break;
13676 }
13677 break;
13678 #endif
13679 }
13680
13681 tcg_temp_free_i32(t0);
13682 tcg_temp_free(v1_t);
13683 tcg_temp_free(v2_t);
13684
13685 (void)opn; /* avoid a compiler warning */
13686 MIPS_DEBUG("%s", opn);
13687
13688 }
13689
13690 static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13691 uint32_t op1, uint32_t op2,
13692 int ret, int val)
13693 {
13694 const char *opn = "mipsdsp Bit/ Manipulation";
13695 int16_t imm;
13696 TCGv t0;
13697 TCGv val_t;
13698
13699 if (ret == 0) {
13700 /* Treat as NOP. */
13701 MIPS_DEBUG("NOP");
13702 return;
13703 }
13704
13705 t0 = tcg_temp_new();
13706 val_t = tcg_temp_new();
13707 gen_load_gpr(val_t, val);
13708
13709 switch (op1) {
13710 case OPC_ABSQ_S_PH_DSP:
13711 switch (op2) {
13712 case OPC_BITREV:
13713 check_dsp(ctx);
13714 gen_helper_bitrev(cpu_gpr[ret], val_t);
13715 break;
13716 case OPC_REPL_QB:
13717 check_dsp(ctx);
13718 {
13719 target_long result;
13720 imm = (ctx->opcode >> 16) & 0xFF;
13721 result = (uint32_t)imm << 24 |
13722 (uint32_t)imm << 16 |
13723 (uint32_t)imm << 8 |
13724 (uint32_t)imm;
13725 result = (int32_t)result;
13726 tcg_gen_movi_tl(cpu_gpr[ret], result);
13727 }
13728 break;
13729 case OPC_REPLV_QB:
13730 check_dsp(ctx);
13731 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13732 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13733 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13734 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13735 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13736 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13737 break;
13738 case OPC_REPL_PH:
13739 check_dsp(ctx);
13740 {
13741 imm = (ctx->opcode >> 16) & 0x03FF;
13742 tcg_gen_movi_tl(cpu_gpr[ret], \
13743 (target_long)((int32_t)imm << 16 | \
13744 (uint32_t)(uint16_t)imm));
13745 }
13746 break;
13747 case OPC_REPLV_PH:
13748 check_dsp(ctx);
13749 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13750 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13751 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13752 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13753 break;
13754 }
13755 break;
13756 #ifdef TARGET_MIPS64
13757 case OPC_ABSQ_S_QH_DSP:
13758 switch (op2) {
13759 case OPC_REPL_OB:
13760 check_dsp(ctx);
13761 {
13762 target_long temp;
13763
13764 imm = (ctx->opcode >> 16) & 0xFF;
13765 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13766 temp = (temp << 16) | temp;
13767 temp = (temp << 32) | temp;
13768 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13769 break;
13770 }
13771 case OPC_REPL_PW:
13772 check_dsp(ctx);
13773 {
13774 target_long temp;
13775
13776 imm = (ctx->opcode >> 16) & 0x03FF;
13777 imm = (int16_t)(imm << 6) >> 6;
13778 temp = ((target_long)imm << 32) \
13779 | ((target_long)imm & 0xFFFFFFFF);
13780 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13781 break;
13782 }
13783 case OPC_REPL_QH:
13784 check_dsp(ctx);
13785 {
13786 target_long temp;
13787
13788 imm = (ctx->opcode >> 16) & 0x03FF;
13789 imm = (int16_t)(imm << 6) >> 6;
13790
13791 temp = ((uint64_t)(uint16_t)imm << 48) |
13792 ((uint64_t)(uint16_t)imm << 32) |
13793 ((uint64_t)(uint16_t)imm << 16) |
13794 (uint64_t)(uint16_t)imm;
13795 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13796 break;
13797 }
13798 case OPC_REPLV_OB:
13799 check_dsp(ctx);
13800 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13801 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13802 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13803 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13804 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13805 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13806 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13807 break;
13808 case OPC_REPLV_PW:
13809 check_dsp(ctx);
13810 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13811 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13812 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13813 break;
13814 case OPC_REPLV_QH:
13815 check_dsp(ctx);
13816 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13817 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13818 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13819 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13820 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13821 break;
13822 }
13823 break;
13824 #endif
13825 }
13826 tcg_temp_free(t0);
13827 tcg_temp_free(val_t);
13828
13829 (void)opn; /* avoid a compiler warning */
13830 MIPS_DEBUG("%s", opn);
13831 }
13832
13833 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13834 uint32_t op1, uint32_t op2,
13835 int ret, int v1, int v2, int check_ret)
13836 {
13837 const char *opn = "mipsdsp add compare pick";
13838 TCGv_i32 t0;
13839 TCGv t1;
13840 TCGv v1_t;
13841 TCGv v2_t;
13842
13843 if ((ret == 0) && (check_ret == 1)) {
13844 /* Treat as NOP. */
13845 MIPS_DEBUG("NOP");
13846 return;
13847 }
13848
13849 t0 = tcg_temp_new_i32();
13850 t1 = tcg_temp_new();
13851 v1_t = tcg_temp_new();
13852 v2_t = tcg_temp_new();
13853
13854 gen_load_gpr(v1_t, v1);
13855 gen_load_gpr(v2_t, v2);
13856
13857 switch (op1) {
13858 case OPC_APPEND_DSP:
13859 switch (op2) {
13860 case OPC_APPEND:
13861 tcg_gen_movi_i32(t0, v2);
13862 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13863 break;
13864 case OPC_PREPEND:
13865 tcg_gen_movi_i32(t0, v2);
13866 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13867 break;
13868 case OPC_BALIGN:
13869 tcg_gen_movi_i32(t0, v2);
13870 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13871 break;
13872 default: /* Invid */
13873 MIPS_INVAL("MASK APPEND");
13874 generate_exception(ctx, EXCP_RI);
13875 break;
13876 }
13877 break;
13878 case OPC_CMPU_EQ_QB_DSP:
13879 switch (op2) {
13880 case OPC_CMPU_EQ_QB:
13881 check_dsp(ctx);
13882 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13883 break;
13884 case OPC_CMPU_LT_QB:
13885 check_dsp(ctx);
13886 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13887 break;
13888 case OPC_CMPU_LE_QB:
13889 check_dsp(ctx);
13890 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13891 break;
13892 case OPC_CMPGU_EQ_QB:
13893 check_dsp(ctx);
13894 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13895 break;
13896 case OPC_CMPGU_LT_QB:
13897 check_dsp(ctx);
13898 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13899 break;
13900 case OPC_CMPGU_LE_QB:
13901 check_dsp(ctx);
13902 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13903 break;
13904 case OPC_CMPGDU_EQ_QB:
13905 check_dspr2(ctx);
13906 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13907 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13908 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13909 tcg_gen_shli_tl(t1, t1, 24);
13910 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13911 break;
13912 case OPC_CMPGDU_LT_QB:
13913 check_dspr2(ctx);
13914 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13915 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13916 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13917 tcg_gen_shli_tl(t1, t1, 24);
13918 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13919 break;
13920 case OPC_CMPGDU_LE_QB:
13921 check_dspr2(ctx);
13922 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13923 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13924 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13925 tcg_gen_shli_tl(t1, t1, 24);
13926 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13927 break;
13928 case OPC_CMP_EQ_PH:
13929 check_dsp(ctx);
13930 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13931 break;
13932 case OPC_CMP_LT_PH:
13933 check_dsp(ctx);
13934 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13935 break;
13936 case OPC_CMP_LE_PH:
13937 check_dsp(ctx);
13938 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13939 break;
13940 case OPC_PICK_QB:
13941 check_dsp(ctx);
13942 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13943 break;
13944 case OPC_PICK_PH:
13945 check_dsp(ctx);
13946 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13947 break;
13948 case OPC_PACKRL_PH:
13949 check_dsp(ctx);
13950 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13951 break;
13952 }
13953 break;
13954 #ifdef TARGET_MIPS64
13955 case OPC_CMPU_EQ_OB_DSP:
13956 switch (op2) {
13957 case OPC_CMP_EQ_PW:
13958 check_dsp(ctx);
13959 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13960 break;
13961 case OPC_CMP_LT_PW:
13962 check_dsp(ctx);
13963 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13964 break;
13965 case OPC_CMP_LE_PW:
13966 check_dsp(ctx);
13967 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13968 break;
13969 case OPC_CMP_EQ_QH:
13970 check_dsp(ctx);
13971 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13972 break;
13973 case OPC_CMP_LT_QH:
13974 check_dsp(ctx);
13975 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13976 break;
13977 case OPC_CMP_LE_QH:
13978 check_dsp(ctx);
13979 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13980 break;
13981 case OPC_CMPGDU_EQ_OB:
13982 check_dspr2(ctx);
13983 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13984 break;
13985 case OPC_CMPGDU_LT_OB:
13986 check_dspr2(ctx);
13987 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13988 break;
13989 case OPC_CMPGDU_LE_OB:
13990 check_dspr2(ctx);
13991 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13992 break;
13993 case OPC_CMPGU_EQ_OB:
13994 check_dsp(ctx);
13995 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13996 break;
13997 case OPC_CMPGU_LT_OB:
13998 check_dsp(ctx);
13999 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14000 break;
14001 case OPC_CMPGU_LE_OB:
14002 check_dsp(ctx);
14003 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14004 break;
14005 case OPC_CMPU_EQ_OB:
14006 check_dsp(ctx);
14007 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14008 break;
14009 case OPC_CMPU_LT_OB:
14010 check_dsp(ctx);
14011 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14012 break;
14013 case OPC_CMPU_LE_OB:
14014 check_dsp(ctx);
14015 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14016 break;
14017 case OPC_PACKRL_PW:
14018 check_dsp(ctx);
14019 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14020 break;
14021 case OPC_PICK_OB:
14022 check_dsp(ctx);
14023 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14024 break;
14025 case OPC_PICK_PW:
14026 check_dsp(ctx);
14027 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14028 break;
14029 case OPC_PICK_QH:
14030 check_dsp(ctx);
14031 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14032 break;
14033 }
14034 break;
14035 case OPC_DAPPEND_DSP:
14036 switch (op2) {
14037 case OPC_DAPPEND:
14038 tcg_gen_movi_i32(t0, v2);
14039 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14040 break;
14041 case OPC_PREPENDD:
14042 tcg_gen_movi_i32(t0, v2);
14043 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14044 break;
14045 case OPC_PREPENDW:
14046 tcg_gen_movi_i32(t0, v2);
14047 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14048 break;
14049 case OPC_DBALIGN:
14050 tcg_gen_movi_i32(t0, v2);
14051 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14052 break;
14053 default: /* Invalid */
14054 MIPS_INVAL("MASK DAPPEND");
14055 generate_exception(ctx, EXCP_RI);
14056 break;
14057 }
14058 break;
14059 #endif
14060 }
14061
14062 tcg_temp_free_i32(t0);
14063 tcg_temp_free(t1);
14064 tcg_temp_free(v1_t);
14065 tcg_temp_free(v2_t);
14066
14067 (void)opn; /* avoid a compiler warning */
14068 MIPS_DEBUG("%s", opn);
14069 }
14070
14071 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14072 int ret, int v1, int v2, int check_ret)
14073
14074 {
14075 const char *opn = "mipsdsp accumulator";
14076 TCGv t0;
14077 TCGv t1;
14078 TCGv v1_t;
14079 TCGv v2_t;
14080 int16_t imm;
14081
14082 if ((ret == 0) && (check_ret == 1)) {
14083 /* Treat as NOP. */
14084 MIPS_DEBUG("NOP");
14085 return;
14086 }
14087
14088 t0 = tcg_temp_new();
14089 t1 = tcg_temp_new();
14090 v1_t = tcg_temp_new();
14091 v2_t = tcg_temp_new();
14092
14093 gen_load_gpr(v1_t, v1);
14094 gen_load_gpr(v2_t, v2);
14095
14096 switch (op1) {
14097 case OPC_EXTR_W_DSP:
14098 check_dsp(ctx);
14099 switch (op2) {
14100 case OPC_EXTR_W:
14101 tcg_gen_movi_tl(t0, v2);
14102 tcg_gen_movi_tl(t1, v1);
14103 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14104 break;
14105 case OPC_EXTR_R_W:
14106 tcg_gen_movi_tl(t0, v2);
14107 tcg_gen_movi_tl(t1, v1);
14108 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14109 break;
14110 case OPC_EXTR_RS_W:
14111 tcg_gen_movi_tl(t0, v2);
14112 tcg_gen_movi_tl(t1, v1);
14113 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14114 break;
14115 case OPC_EXTR_S_H:
14116 tcg_gen_movi_tl(t0, v2);
14117 tcg_gen_movi_tl(t1, v1);
14118 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14119 break;
14120 case OPC_EXTRV_S_H:
14121 tcg_gen_movi_tl(t0, v2);
14122 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14123 break;
14124 case OPC_EXTRV_W:
14125 tcg_gen_movi_tl(t0, v2);
14126 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14127 break;
14128 case OPC_EXTRV_R_W:
14129 tcg_gen_movi_tl(t0, v2);
14130 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14131 break;
14132 case OPC_EXTRV_RS_W:
14133 tcg_gen_movi_tl(t0, v2);
14134 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14135 break;
14136 case OPC_EXTP:
14137 tcg_gen_movi_tl(t0, v2);
14138 tcg_gen_movi_tl(t1, v1);
14139 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14140 break;
14141 case OPC_EXTPV:
14142 tcg_gen_movi_tl(t0, v2);
14143 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14144 break;
14145 case OPC_EXTPDP:
14146 tcg_gen_movi_tl(t0, v2);
14147 tcg_gen_movi_tl(t1, v1);
14148 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14149 break;
14150 case OPC_EXTPDPV:
14151 tcg_gen_movi_tl(t0, v2);
14152 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14153 break;
14154 case OPC_SHILO:
14155 imm = (ctx->opcode >> 20) & 0x3F;
14156 tcg_gen_movi_tl(t0, ret);
14157 tcg_gen_movi_tl(t1, imm);
14158 gen_helper_shilo(t0, t1, cpu_env);
14159 break;
14160 case OPC_SHILOV:
14161 tcg_gen_movi_tl(t0, ret);
14162 gen_helper_shilo(t0, v1_t, cpu_env);
14163 break;
14164 case OPC_MTHLIP:
14165 tcg_gen_movi_tl(t0, ret);
14166 gen_helper_mthlip(t0, v1_t, cpu_env);
14167 break;
14168 case OPC_WRDSP:
14169 imm = (ctx->opcode >> 11) & 0x3FF;
14170 tcg_gen_movi_tl(t0, imm);
14171 gen_helper_wrdsp(v1_t, t0, cpu_env);
14172 break;
14173 case OPC_RDDSP:
14174 imm = (ctx->opcode >> 16) & 0x03FF;
14175 tcg_gen_movi_tl(t0, imm);
14176 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14177 break;
14178 }
14179 break;
14180 #ifdef TARGET_MIPS64
14181 case OPC_DEXTR_W_DSP:
14182 check_dsp(ctx);
14183 switch (op2) {
14184 case OPC_DMTHLIP:
14185 tcg_gen_movi_tl(t0, ret);
14186 gen_helper_dmthlip(v1_t, t0, cpu_env);
14187 break;
14188 case OPC_DSHILO:
14189 {
14190 int shift = (ctx->opcode >> 19) & 0x7F;
14191 int ac = (ctx->opcode >> 11) & 0x03;
14192 tcg_gen_movi_tl(t0, shift);
14193 tcg_gen_movi_tl(t1, ac);
14194 gen_helper_dshilo(t0, t1, cpu_env);
14195 break;
14196 }
14197 case OPC_DSHILOV:
14198 {
14199 int ac = (ctx->opcode >> 11) & 0x03;
14200 tcg_gen_movi_tl(t0, ac);
14201 gen_helper_dshilo(v1_t, t0, cpu_env);
14202 break;
14203 }
14204 case OPC_DEXTP:
14205 tcg_gen_movi_tl(t0, v2);
14206 tcg_gen_movi_tl(t1, v1);
14207
14208 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14209 break;
14210 case OPC_DEXTPV:
14211 tcg_gen_movi_tl(t0, v2);
14212 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14213 break;
14214 case OPC_DEXTPDP:
14215 tcg_gen_movi_tl(t0, v2);
14216 tcg_gen_movi_tl(t1, v1);
14217 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14218 break;
14219 case OPC_DEXTPDPV:
14220 tcg_gen_movi_tl(t0, v2);
14221 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14222 break;
14223 case OPC_DEXTR_L:
14224 tcg_gen_movi_tl(t0, v2);
14225 tcg_gen_movi_tl(t1, v1);
14226 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14227 break;
14228 case OPC_DEXTR_R_L:
14229 tcg_gen_movi_tl(t0, v2);
14230 tcg_gen_movi_tl(t1, v1);
14231 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14232 break;
14233 case OPC_DEXTR_RS_L:
14234 tcg_gen_movi_tl(t0, v2);
14235 tcg_gen_movi_tl(t1, v1);
14236 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14237 break;
14238 case OPC_DEXTR_W:
14239 tcg_gen_movi_tl(t0, v2);
14240 tcg_gen_movi_tl(t1, v1);
14241 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14242 break;
14243 case OPC_DEXTR_R_W:
14244 tcg_gen_movi_tl(t0, v2);
14245 tcg_gen_movi_tl(t1, v1);
14246 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14247 break;
14248 case OPC_DEXTR_RS_W:
14249 tcg_gen_movi_tl(t0, v2);
14250 tcg_gen_movi_tl(t1, v1);
14251 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14252 break;
14253 case OPC_DEXTR_S_H:
14254 tcg_gen_movi_tl(t0, v2);
14255 tcg_gen_movi_tl(t1, v1);
14256 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14257 break;
14258 case OPC_DEXTRV_S_H:
14259 tcg_gen_movi_tl(t0, v2);
14260 tcg_gen_movi_tl(t1, v1);
14261 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14262 break;
14263 case OPC_DEXTRV_L:
14264 tcg_gen_movi_tl(t0, v2);
14265 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14266 break;
14267 case OPC_DEXTRV_R_L:
14268 tcg_gen_movi_tl(t0, v2);
14269 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14270 break;
14271 case OPC_DEXTRV_RS_L:
14272 tcg_gen_movi_tl(t0, v2);
14273 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14274 break;
14275 case OPC_DEXTRV_W:
14276 tcg_gen_movi_tl(t0, v2);
14277 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14278 break;
14279 case OPC_DEXTRV_R_W:
14280 tcg_gen_movi_tl(t0, v2);
14281 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14282 break;
14283 case OPC_DEXTRV_RS_W:
14284 tcg_gen_movi_tl(t0, v2);
14285 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14286 break;
14287 }
14288 break;
14289 #endif
14290 }
14291
14292 tcg_temp_free(t0);
14293 tcg_temp_free(t1);
14294 tcg_temp_free(v1_t);
14295 tcg_temp_free(v2_t);
14296
14297 (void)opn; /* avoid a compiler warning */
14298 MIPS_DEBUG("%s", opn);
14299 }
14300
14301 /* End MIPSDSP functions. */
14302
14303 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
14304 {
14305 int32_t offset;
14306 int rs, rt, rd, sa;
14307 uint32_t op, op1, op2;
14308 int16_t imm;
14309
14310 /* make sure instructions are on a word boundary */
14311 if (ctx->pc & 0x3) {
14312 env->CP0_BadVAddr = ctx->pc;
14313 generate_exception(ctx, EXCP_AdEL);
14314 return;
14315 }
14316
14317 /* Handle blikely not taken case */
14318 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14319 int l1 = gen_new_label();
14320
14321 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14322 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14323 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14324 gen_goto_tb(ctx, 1, ctx->pc + 4);
14325 gen_set_label(l1);
14326 }
14327
14328 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14329 tcg_gen_debug_insn_start(ctx->pc);
14330 }
14331
14332 op = MASK_OP_MAJOR(ctx->opcode);
14333 rs = (ctx->opcode >> 21) & 0x1f;
14334 rt = (ctx->opcode >> 16) & 0x1f;
14335 rd = (ctx->opcode >> 11) & 0x1f;
14336 sa = (ctx->opcode >> 6) & 0x1f;
14337 imm = (int16_t)ctx->opcode;
14338 switch (op) {
14339 case OPC_SPECIAL:
14340 op1 = MASK_SPECIAL(ctx->opcode);
14341 switch (op1) {
14342 case OPC_SLL: /* Shift with immediate */
14343 case OPC_SRA:
14344 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14345 break;
14346 case OPC_SRL:
14347 switch ((ctx->opcode >> 21) & 0x1f) {
14348 case 1:
14349 /* rotr is decoded as srl on non-R2 CPUs */
14350 if (env->insn_flags & ISA_MIPS32R2) {
14351 op1 = OPC_ROTR;
14352 }
14353 /* Fallthrough */
14354 case 0:
14355 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14356 break;
14357 default:
14358 generate_exception(ctx, EXCP_RI);
14359 break;
14360 }
14361 break;
14362 case OPC_MOVN: /* Conditional move */
14363 case OPC_MOVZ:
14364 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14365 INSN_LOONGSON2E | INSN_LOONGSON2F);
14366 gen_cond_move(env, ctx, op1, rd, rs, rt);
14367 break;
14368 case OPC_ADD ... OPC_SUBU:
14369 gen_arith(env, ctx, op1, rd, rs, rt);
14370 break;
14371 case OPC_SLLV: /* Shifts */
14372 case OPC_SRAV:
14373 gen_shift(env, ctx, op1, rd, rs, rt);
14374 break;
14375 case OPC_SRLV:
14376 switch ((ctx->opcode >> 6) & 0x1f) {
14377 case 1:
14378 /* rotrv is decoded as srlv on non-R2 CPUs */
14379 if (env->insn_flags & ISA_MIPS32R2) {
14380 op1 = OPC_ROTRV;
14381 }
14382 /* Fallthrough */
14383 case 0:
14384 gen_shift(env, ctx, op1, rd, rs, rt);
14385 break;
14386 default:
14387 generate_exception(ctx, EXCP_RI);
14388 break;
14389 }
14390 break;
14391 case OPC_SLT: /* Set on less than */
14392 case OPC_SLTU:
14393 gen_slt(env, ctx, op1, rd, rs, rt);
14394 break;
14395 case OPC_AND: /* Logic*/
14396 case OPC_OR:
14397 case OPC_NOR:
14398 case OPC_XOR:
14399 gen_logic(env, ctx, op1, rd, rs, rt);
14400 break;
14401 case OPC_MULT ... OPC_DIVU:
14402 if (sa) {
14403 check_insn(env, ctx, INSN_VR54XX);
14404 op1 = MASK_MUL_VR54XX(ctx->opcode);
14405 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14406 } else
14407 gen_muldiv(ctx, op1, rs, rt);
14408 break;
14409 case OPC_JR ... OPC_JALR:
14410 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14411 *is_branch = 1;
14412 break;
14413 case OPC_TGE ... OPC_TEQ: /* Traps */
14414 case OPC_TNE:
14415 gen_trap(ctx, op1, rs, rt, -1);
14416 break;
14417 case OPC_MFHI: /* Move from HI/LO */
14418 case OPC_MFLO:
14419 gen_HILO(ctx, op1, rd);
14420 break;
14421 case OPC_MTHI:
14422 case OPC_MTLO: /* Move to HI/LO */
14423 gen_HILO(ctx, op1, rs);
14424 break;
14425 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14426 #ifdef MIPS_STRICT_STANDARD
14427 MIPS_INVAL("PMON / selsl");
14428 generate_exception(ctx, EXCP_RI);
14429 #else
14430 gen_helper_0e0i(pmon, sa);
14431 #endif
14432 break;
14433 case OPC_SYSCALL:
14434 generate_exception(ctx, EXCP_SYSCALL);
14435 ctx->bstate = BS_STOP;
14436 break;
14437 case OPC_BREAK:
14438 generate_exception(ctx, EXCP_BREAK);
14439 break;
14440 case OPC_SPIM:
14441 #ifdef MIPS_STRICT_STANDARD
14442 MIPS_INVAL("SPIM");
14443 generate_exception(ctx, EXCP_RI);
14444 #else
14445 /* Implemented as RI exception for now. */
14446 MIPS_INVAL("spim (unofficial)");
14447 generate_exception(ctx, EXCP_RI);
14448 #endif
14449 break;
14450 case OPC_SYNC:
14451 /* Treat as NOP. */
14452 break;
14453
14454 case OPC_MOVCI:
14455 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
14456 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14457 check_cp1_enabled(ctx);
14458 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14459 (ctx->opcode >> 16) & 1);
14460 } else {
14461 generate_exception_err(ctx, EXCP_CpU, 1);
14462 }
14463 break;
14464
14465 #if defined(TARGET_MIPS64)
14466 /* MIPS64 specific opcodes */
14467 case OPC_DSLL:
14468 case OPC_DSRA:
14469 case OPC_DSLL32:
14470 case OPC_DSRA32:
14471 check_insn(env, ctx, ISA_MIPS3);
14472 check_mips_64(ctx);
14473 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14474 break;
14475 case OPC_DSRL:
14476 switch ((ctx->opcode >> 21) & 0x1f) {
14477 case 1:
14478 /* drotr is decoded as dsrl on non-R2 CPUs */
14479 if (env->insn_flags & ISA_MIPS32R2) {
14480 op1 = OPC_DROTR;
14481 }
14482 /* Fallthrough */
14483 case 0:
14484 check_insn(env, ctx, ISA_MIPS3);
14485 check_mips_64(ctx);
14486 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14487 break;
14488 default:
14489 generate_exception(ctx, EXCP_RI);
14490 break;
14491 }
14492 break;
14493 case OPC_DSRL32:
14494 switch ((ctx->opcode >> 21) & 0x1f) {
14495 case 1:
14496 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14497 if (env->insn_flags & ISA_MIPS32R2) {
14498 op1 = OPC_DROTR32;
14499 }
14500 /* Fallthrough */
14501 case 0:
14502 check_insn(env, ctx, ISA_MIPS3);
14503 check_mips_64(ctx);
14504 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14505 break;
14506 default:
14507 generate_exception(ctx, EXCP_RI);
14508 break;
14509 }
14510 break;
14511 case OPC_DADD ... OPC_DSUBU:
14512 check_insn(env, ctx, ISA_MIPS3);
14513 check_mips_64(ctx);
14514 gen_arith(env, ctx, op1, rd, rs, rt);
14515 break;
14516 case OPC_DSLLV:
14517 case OPC_DSRAV:
14518 check_insn(env, ctx, ISA_MIPS3);
14519 check_mips_64(ctx);
14520 gen_shift(env, ctx, op1, rd, rs, rt);
14521 break;
14522 case OPC_DSRLV:
14523 switch ((ctx->opcode >> 6) & 0x1f) {
14524 case 1:
14525 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14526 if (env->insn_flags & ISA_MIPS32R2) {
14527 op1 = OPC_DROTRV;
14528 }
14529 /* Fallthrough */
14530 case 0:
14531 check_insn(env, ctx, ISA_MIPS3);
14532 check_mips_64(ctx);
14533 gen_shift(env, ctx, op1, rd, rs, rt);
14534 break;
14535 default:
14536 generate_exception(ctx, EXCP_RI);
14537 break;
14538 }
14539 break;
14540 case OPC_DMULT ... OPC_DDIVU:
14541 check_insn(env, ctx, ISA_MIPS3);
14542 check_mips_64(ctx);
14543 gen_muldiv(ctx, op1, rs, rt);
14544 break;
14545 #endif
14546 default: /* Invalid */
14547 MIPS_INVAL("special");
14548 generate_exception(ctx, EXCP_RI);
14549 break;
14550 }
14551 break;
14552 case OPC_SPECIAL2:
14553 op1 = MASK_SPECIAL2(ctx->opcode);
14554 switch (op1) {
14555 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14556 case OPC_MSUB ... OPC_MSUBU:
14557 check_insn(env, ctx, ISA_MIPS32);
14558 gen_muldiv(ctx, op1, rs, rt);
14559 break;
14560 case OPC_MUL:
14561 gen_arith(env, ctx, op1, rd, rs, rt);
14562 break;
14563 case OPC_CLO:
14564 case OPC_CLZ:
14565 check_insn(env, ctx, ISA_MIPS32);
14566 gen_cl(ctx, op1, rd, rs);
14567 break;
14568 case OPC_SDBBP:
14569 /* XXX: not clear which exception should be raised
14570 * when in debug mode...
14571 */
14572 check_insn(env, ctx, ISA_MIPS32);
14573 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14574 generate_exception(ctx, EXCP_DBp);
14575 } else {
14576 generate_exception(ctx, EXCP_DBp);
14577 }
14578 /* Treat as NOP. */
14579 break;
14580 case OPC_DIV_G_2F:
14581 case OPC_DIVU_G_2F:
14582 case OPC_MULT_G_2F:
14583 case OPC_MULTU_G_2F:
14584 case OPC_MOD_G_2F:
14585 case OPC_MODU_G_2F:
14586 check_insn(env, ctx, INSN_LOONGSON2F);
14587 gen_loongson_integer(ctx, op1, rd, rs, rt);
14588 break;
14589 #if defined(TARGET_MIPS64)
14590 case OPC_DCLO:
14591 case OPC_DCLZ:
14592 check_insn(env, ctx, ISA_MIPS64);
14593 check_mips_64(ctx);
14594 gen_cl(ctx, op1, rd, rs);
14595 break;
14596 case OPC_DMULT_G_2F:
14597 case OPC_DMULTU_G_2F:
14598 case OPC_DDIV_G_2F:
14599 case OPC_DDIVU_G_2F:
14600 case OPC_DMOD_G_2F:
14601 case OPC_DMODU_G_2F:
14602 check_insn(env, ctx, INSN_LOONGSON2F);
14603 gen_loongson_integer(ctx, op1, rd, rs, rt);
14604 break;
14605 #endif
14606 default: /* Invalid */
14607 MIPS_INVAL("special2");
14608 generate_exception(ctx, EXCP_RI);
14609 break;
14610 }
14611 break;
14612 case OPC_SPECIAL3:
14613 op1 = MASK_SPECIAL3(ctx->opcode);
14614 switch (op1) {
14615 case OPC_EXT:
14616 case OPC_INS:
14617 check_insn(env, ctx, ISA_MIPS32R2);
14618 gen_bitops(ctx, op1, rt, rs, sa, rd);
14619 break;
14620 case OPC_BSHFL:
14621 check_insn(env, ctx, ISA_MIPS32R2);
14622 op2 = MASK_BSHFL(ctx->opcode);
14623 gen_bshfl(ctx, op2, rt, rd);
14624 break;
14625 case OPC_RDHWR:
14626 gen_rdhwr(env, ctx, rt, rd);
14627 break;
14628 case OPC_FORK:
14629 check_insn(env, ctx, ASE_MT);
14630 {
14631 TCGv t0 = tcg_temp_new();
14632 TCGv t1 = tcg_temp_new();
14633
14634 gen_load_gpr(t0, rt);
14635 gen_load_gpr(t1, rs);
14636 gen_helper_fork(t0, t1);
14637 tcg_temp_free(t0);
14638 tcg_temp_free(t1);
14639 }
14640 break;
14641 case OPC_YIELD:
14642 check_insn(env, ctx, ASE_MT);
14643 {
14644 TCGv t0 = tcg_temp_new();
14645
14646 save_cpu_state(ctx, 1);
14647 gen_load_gpr(t0, rs);
14648 gen_helper_yield(t0, cpu_env, t0);
14649 gen_store_gpr(t0, rd);
14650 tcg_temp_free(t0);
14651 }
14652 break;
14653 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14654 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14655 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14656 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14657 * the same mask and op1. */
14658 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14659 op2 = MASK_ADDUH_QB(ctx->opcode);
14660 switch (op2) {
14661 case OPC_ADDUH_QB:
14662 case OPC_ADDUH_R_QB:
14663 case OPC_ADDQH_PH:
14664 case OPC_ADDQH_R_PH:
14665 case OPC_ADDQH_W:
14666 case OPC_ADDQH_R_W:
14667 case OPC_SUBUH_QB:
14668 case OPC_SUBUH_R_QB:
14669 case OPC_SUBQH_PH:
14670 case OPC_SUBQH_R_PH:
14671 case OPC_SUBQH_W:
14672 case OPC_SUBQH_R_W:
14673 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14674 break;
14675 case OPC_MUL_PH:
14676 case OPC_MUL_S_PH:
14677 case OPC_MULQ_S_W:
14678 case OPC_MULQ_RS_W:
14679 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14680 break;
14681 default:
14682 MIPS_INVAL("MASK ADDUH.QB");
14683 generate_exception(ctx, EXCP_RI);
14684 break;
14685 }
14686 } else if (env->insn_flags & INSN_LOONGSON2E) {
14687 gen_loongson_integer(ctx, op1, rd, rs, rt);
14688 } else {
14689 generate_exception(ctx, EXCP_RI);
14690 }
14691 break;
14692 case OPC_LX_DSP:
14693 op2 = MASK_LX(ctx->opcode);
14694 switch (op2) {
14695 #if defined(TARGET_MIPS64)
14696 case OPC_LDX:
14697 #endif
14698 case OPC_LBUX:
14699 case OPC_LHX:
14700 case OPC_LWX:
14701 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14702 break;
14703 default: /* Invalid */
14704 MIPS_INVAL("MASK LX");
14705 generate_exception(ctx, EXCP_RI);
14706 break;
14707 }
14708 break;
14709 case OPC_ABSQ_S_PH_DSP:
14710 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14711 switch (op2) {
14712 case OPC_ABSQ_S_QB:
14713 case OPC_ABSQ_S_PH:
14714 case OPC_ABSQ_S_W:
14715 case OPC_PRECEQ_W_PHL:
14716 case OPC_PRECEQ_W_PHR:
14717 case OPC_PRECEQU_PH_QBL:
14718 case OPC_PRECEQU_PH_QBR:
14719 case OPC_PRECEQU_PH_QBLA:
14720 case OPC_PRECEQU_PH_QBRA:
14721 case OPC_PRECEU_PH_QBL:
14722 case OPC_PRECEU_PH_QBR:
14723 case OPC_PRECEU_PH_QBLA:
14724 case OPC_PRECEU_PH_QBRA:
14725 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14726 break;
14727 case OPC_BITREV:
14728 case OPC_REPL_QB:
14729 case OPC_REPLV_QB:
14730 case OPC_REPL_PH:
14731 case OPC_REPLV_PH:
14732 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14733 break;
14734 default:
14735 MIPS_INVAL("MASK ABSQ_S.PH");
14736 generate_exception(ctx, EXCP_RI);
14737 break;
14738 }
14739 break;
14740 case OPC_ADDU_QB_DSP:
14741 op2 = MASK_ADDU_QB(ctx->opcode);
14742 switch (op2) {
14743 case OPC_ADDQ_PH:
14744 case OPC_ADDQ_S_PH:
14745 case OPC_ADDQ_S_W:
14746 case OPC_ADDU_QB:
14747 case OPC_ADDU_S_QB:
14748 case OPC_ADDU_PH:
14749 case OPC_ADDU_S_PH:
14750 case OPC_SUBQ_PH:
14751 case OPC_SUBQ_S_PH:
14752 case OPC_SUBQ_S_W:
14753 case OPC_SUBU_QB:
14754 case OPC_SUBU_S_QB:
14755 case OPC_SUBU_PH:
14756 case OPC_SUBU_S_PH:
14757 case OPC_ADDSC:
14758 case OPC_ADDWC:
14759 case OPC_MODSUB:
14760 case OPC_RADDU_W_QB:
14761 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14762 break;
14763 case OPC_MULEU_S_PH_QBL:
14764 case OPC_MULEU_S_PH_QBR:
14765 case OPC_MULQ_RS_PH:
14766 case OPC_MULEQ_S_W_PHL:
14767 case OPC_MULEQ_S_W_PHR:
14768 case OPC_MULQ_S_PH:
14769 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14770 break;
14771 default: /* Invalid */
14772 MIPS_INVAL("MASK ADDU.QB");
14773 generate_exception(ctx, EXCP_RI);
14774 break;
14775
14776 }
14777 break;
14778 case OPC_CMPU_EQ_QB_DSP:
14779 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14780 switch (op2) {
14781 case OPC_PRECR_SRA_PH_W:
14782 case OPC_PRECR_SRA_R_PH_W:
14783 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14784 break;
14785 case OPC_PRECR_QB_PH:
14786 case OPC_PRECRQ_QB_PH:
14787 case OPC_PRECRQ_PH_W:
14788 case OPC_PRECRQ_RS_PH_W:
14789 case OPC_PRECRQU_S_QB_PH:
14790 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14791 break;
14792 case OPC_CMPU_EQ_QB:
14793 case OPC_CMPU_LT_QB:
14794 case OPC_CMPU_LE_QB:
14795 case OPC_CMP_EQ_PH:
14796 case OPC_CMP_LT_PH:
14797 case OPC_CMP_LE_PH:
14798 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14799 break;
14800 case OPC_CMPGU_EQ_QB:
14801 case OPC_CMPGU_LT_QB:
14802 case OPC_CMPGU_LE_QB:
14803 case OPC_CMPGDU_EQ_QB:
14804 case OPC_CMPGDU_LT_QB:
14805 case OPC_CMPGDU_LE_QB:
14806 case OPC_PICK_QB:
14807 case OPC_PICK_PH:
14808 case OPC_PACKRL_PH:
14809 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14810 break;
14811 default: /* Invalid */
14812 MIPS_INVAL("MASK CMPU.EQ.QB");
14813 generate_exception(ctx, EXCP_RI);
14814 break;
14815 }
14816 break;
14817 case OPC_SHLL_QB_DSP:
14818 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14819 break;
14820 case OPC_DPA_W_PH_DSP:
14821 op2 = MASK_DPA_W_PH(ctx->opcode);
14822 switch (op2) {
14823 case OPC_DPAU_H_QBL:
14824 case OPC_DPAU_H_QBR:
14825 case OPC_DPSU_H_QBL:
14826 case OPC_DPSU_H_QBR:
14827 case OPC_DPA_W_PH:
14828 case OPC_DPAX_W_PH:
14829 case OPC_DPAQ_S_W_PH:
14830 case OPC_DPAQX_S_W_PH:
14831 case OPC_DPAQX_SA_W_PH:
14832 case OPC_DPS_W_PH:
14833 case OPC_DPSX_W_PH:
14834 case OPC_DPSQ_S_W_PH:
14835 case OPC_DPSQX_S_W_PH:
14836 case OPC_DPSQX_SA_W_PH:
14837 case OPC_MULSAQ_S_W_PH:
14838 case OPC_DPAQ_SA_L_W:
14839 case OPC_DPSQ_SA_L_W:
14840 case OPC_MAQ_S_W_PHL:
14841 case OPC_MAQ_S_W_PHR:
14842 case OPC_MAQ_SA_W_PHL:
14843 case OPC_MAQ_SA_W_PHR:
14844 case OPC_MULSA_W_PH:
14845 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14846 break;
14847 default: /* Invalid */
14848 MIPS_INVAL("MASK DPAW.PH");
14849 generate_exception(ctx, EXCP_RI);
14850 break;
14851 }
14852 break;
14853 case OPC_INSV_DSP:
14854 op2 = MASK_INSV(ctx->opcode);
14855 switch (op2) {
14856 case OPC_INSV:
14857 check_dsp(ctx);
14858 {
14859 TCGv t0, t1;
14860
14861 if (rt == 0) {
14862 MIPS_DEBUG("NOP");
14863 break;
14864 }
14865
14866 t0 = tcg_temp_new();
14867 t1 = tcg_temp_new();
14868
14869 gen_load_gpr(t0, rt);
14870 gen_load_gpr(t1, rs);
14871
14872 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14873
14874 tcg_temp_free(t0);
14875 tcg_temp_free(t1);
14876 break;
14877 }
14878 default: /* Invalid */
14879 MIPS_INVAL("MASK INSV");
14880 generate_exception(ctx, EXCP_RI);
14881 break;
14882 }
14883 break;
14884 case OPC_APPEND_DSP:
14885 check_dspr2(ctx);
14886 op2 = MASK_APPEND(ctx->opcode);
14887 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14888 break;
14889 case OPC_EXTR_W_DSP:
14890 op2 = MASK_EXTR_W(ctx->opcode);
14891 switch (op2) {
14892 case OPC_EXTR_W:
14893 case OPC_EXTR_R_W:
14894 case OPC_EXTR_RS_W:
14895 case OPC_EXTR_S_H:
14896 case OPC_EXTRV_S_H:
14897 case OPC_EXTRV_W:
14898 case OPC_EXTRV_R_W:
14899 case OPC_EXTRV_RS_W:
14900 case OPC_EXTP:
14901 case OPC_EXTPV:
14902 case OPC_EXTPDP:
14903 case OPC_EXTPDPV:
14904 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14905 break;
14906 case OPC_RDDSP:
14907 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14908 break;
14909 case OPC_SHILO:
14910 case OPC_SHILOV:
14911 case OPC_MTHLIP:
14912 case OPC_WRDSP:
14913 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14914 break;
14915 default: /* Invalid */
14916 MIPS_INVAL("MASK EXTR.W");
14917 generate_exception(ctx, EXCP_RI);
14918 break;
14919 }
14920 break;
14921 #if defined(TARGET_MIPS64)
14922 case OPC_DEXTM ... OPC_DEXT:
14923 case OPC_DINSM ... OPC_DINS:
14924 check_insn(env, ctx, ISA_MIPS64R2);
14925 check_mips_64(ctx);
14926 gen_bitops(ctx, op1, rt, rs, sa, rd);
14927 break;
14928 case OPC_DBSHFL:
14929 check_insn(env, ctx, ISA_MIPS64R2);
14930 check_mips_64(ctx);
14931 op2 = MASK_DBSHFL(ctx->opcode);
14932 gen_bshfl(ctx, op2, rt, rd);
14933 break;
14934 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14935 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14936 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14937 check_insn(env, ctx, INSN_LOONGSON2E);
14938 gen_loongson_integer(ctx, op1, rd, rs, rt);
14939 break;
14940 case OPC_ABSQ_S_QH_DSP:
14941 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14942 switch (op2) {
14943 case OPC_PRECEQ_L_PWL:
14944 case OPC_PRECEQ_L_PWR:
14945 case OPC_PRECEQ_PW_QHL:
14946 case OPC_PRECEQ_PW_QHR:
14947 case OPC_PRECEQ_PW_QHLA:
14948 case OPC_PRECEQ_PW_QHRA:
14949 case OPC_PRECEQU_QH_OBL:
14950 case OPC_PRECEQU_QH_OBR:
14951 case OPC_PRECEQU_QH_OBLA:
14952 case OPC_PRECEQU_QH_OBRA:
14953 case OPC_PRECEU_QH_OBL:
14954 case OPC_PRECEU_QH_OBR:
14955 case OPC_PRECEU_QH_OBLA:
14956 case OPC_PRECEU_QH_OBRA:
14957 case OPC_ABSQ_S_OB:
14958 case OPC_ABSQ_S_PW:
14959 case OPC_ABSQ_S_QH:
14960 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14961 break;
14962 case OPC_REPL_OB:
14963 case OPC_REPL_PW:
14964 case OPC_REPL_QH:
14965 case OPC_REPLV_OB:
14966 case OPC_REPLV_PW:
14967 case OPC_REPLV_QH:
14968 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14969 break;
14970 default: /* Invalid */
14971 MIPS_INVAL("MASK ABSQ_S.QH");
14972 generate_exception(ctx, EXCP_RI);
14973 break;
14974 }
14975 break;
14976 case OPC_ADDU_OB_DSP:
14977 op2 = MASK_ADDU_OB(ctx->opcode);
14978 switch (op2) {
14979 case OPC_RADDU_L_OB:
14980 case OPC_SUBQ_PW:
14981 case OPC_SUBQ_S_PW:
14982 case OPC_SUBQ_QH:
14983 case OPC_SUBQ_S_QH:
14984 case OPC_SUBU_OB:
14985 case OPC_SUBU_S_OB:
14986 case OPC_SUBU_QH:
14987 case OPC_SUBU_S_QH:
14988 case OPC_SUBUH_OB:
14989 case OPC_SUBUH_R_OB:
14990 case OPC_ADDQ_PW:
14991 case OPC_ADDQ_S_PW:
14992 case OPC_ADDQ_QH:
14993 case OPC_ADDQ_S_QH:
14994 case OPC_ADDU_OB:
14995 case OPC_ADDU_S_OB:
14996 case OPC_ADDU_QH:
14997 case OPC_ADDU_S_QH:
14998 case OPC_ADDUH_OB:
14999 case OPC_ADDUH_R_OB:
15000 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15001 break;
15002 case OPC_MULEQ_S_PW_QHL:
15003 case OPC_MULEQ_S_PW_QHR:
15004 case OPC_MULEU_S_QH_OBL:
15005 case OPC_MULEU_S_QH_OBR:
15006 case OPC_MULQ_RS_QH:
15007 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15008 break;
15009 default: /* Invalid */
15010 MIPS_INVAL("MASK ADDU.OB");
15011 generate_exception(ctx, EXCP_RI);
15012 break;
15013 }
15014 break;
15015 case OPC_CMPU_EQ_OB_DSP:
15016 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15017 switch (op2) {
15018 case OPC_PRECR_SRA_QH_PW:
15019 case OPC_PRECR_SRA_R_QH_PW:
15020 /* Return value is rt. */
15021 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15022 break;
15023 case OPC_PRECR_OB_QH:
15024 case OPC_PRECRQ_OB_QH:
15025 case OPC_PRECRQ_PW_L:
15026 case OPC_PRECRQ_QH_PW:
15027 case OPC_PRECRQ_RS_QH_PW:
15028 case OPC_PRECRQU_S_OB_QH:
15029 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15030 break;
15031 case OPC_CMPU_EQ_OB:
15032 case OPC_CMPU_LT_OB:
15033 case OPC_CMPU_LE_OB:
15034 case OPC_CMP_EQ_QH:
15035 case OPC_CMP_LT_QH:
15036 case OPC_CMP_LE_QH:
15037 case OPC_CMP_EQ_PW:
15038 case OPC_CMP_LT_PW:
15039 case OPC_CMP_LE_PW:
15040 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15041 break;
15042 case OPC_CMPGDU_EQ_OB:
15043 case OPC_CMPGDU_LT_OB:
15044 case OPC_CMPGDU_LE_OB:
15045 case OPC_CMPGU_EQ_OB:
15046 case OPC_CMPGU_LT_OB:
15047 case OPC_CMPGU_LE_OB:
15048 case OPC_PACKRL_PW:
15049 case OPC_PICK_OB:
15050 case OPC_PICK_PW:
15051 case OPC_PICK_QH:
15052 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15053 break;
15054 default: /* Invalid */
15055 MIPS_INVAL("MASK CMPU_EQ.OB");
15056 generate_exception(ctx, EXCP_RI);
15057 break;
15058 }
15059 break;
15060 case OPC_DAPPEND_DSP:
15061 check_dspr2(ctx);
15062 op2 = MASK_DAPPEND(ctx->opcode);
15063 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15064 break;
15065 case OPC_DEXTR_W_DSP:
15066 op2 = MASK_DEXTR_W(ctx->opcode);
15067 switch (op2) {
15068 case OPC_DEXTP:
15069 case OPC_DEXTPDP:
15070 case OPC_DEXTPDPV:
15071 case OPC_DEXTPV:
15072 case OPC_DEXTR_L:
15073 case OPC_DEXTR_R_L:
15074 case OPC_DEXTR_RS_L:
15075 case OPC_DEXTR_W:
15076 case OPC_DEXTR_R_W:
15077 case OPC_DEXTR_RS_W:
15078 case OPC_DEXTR_S_H:
15079 case OPC_DEXTRV_L:
15080 case OPC_DEXTRV_R_L:
15081 case OPC_DEXTRV_RS_L:
15082 case OPC_DEXTRV_S_H:
15083 case OPC_DEXTRV_W:
15084 case OPC_DEXTRV_R_W:
15085 case OPC_DEXTRV_RS_W:
15086 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15087 break;
15088 case OPC_DMTHLIP:
15089 case OPC_DSHILO:
15090 case OPC_DSHILOV:
15091 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15092 break;
15093 default: /* Invalid */
15094 MIPS_INVAL("MASK EXTR.W");
15095 generate_exception(ctx, EXCP_RI);
15096 break;
15097 }
15098 break;
15099 case OPC_DPAQ_W_QH_DSP:
15100 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15101 switch (op2) {
15102 case OPC_DPAU_H_OBL:
15103 case OPC_DPAU_H_OBR:
15104 case OPC_DPSU_H_OBL:
15105 case OPC_DPSU_H_OBR:
15106 case OPC_DPA_W_QH:
15107 case OPC_DPAQ_S_W_QH:
15108 case OPC_DPS_W_QH:
15109 case OPC_DPSQ_S_W_QH:
15110 case OPC_MULSAQ_S_W_QH:
15111 case OPC_DPAQ_SA_L_PW:
15112 case OPC_DPSQ_SA_L_PW:
15113 case OPC_MULSAQ_S_L_PW:
15114 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15115 break;
15116 case OPC_MAQ_S_W_QHLL:
15117 case OPC_MAQ_S_W_QHLR:
15118 case OPC_MAQ_S_W_QHRL:
15119 case OPC_MAQ_S_W_QHRR:
15120 case OPC_MAQ_SA_W_QHLL:
15121 case OPC_MAQ_SA_W_QHLR:
15122 case OPC_MAQ_SA_W_QHRL:
15123 case OPC_MAQ_SA_W_QHRR:
15124 case OPC_MAQ_S_L_PWL:
15125 case OPC_MAQ_S_L_PWR:
15126 case OPC_DMADD:
15127 case OPC_DMADDU:
15128 case OPC_DMSUB:
15129 case OPC_DMSUBU:
15130 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15131 break;
15132 default: /* Invalid */
15133 MIPS_INVAL("MASK DPAQ.W.QH");
15134 generate_exception(ctx, EXCP_RI);
15135 break;
15136 }
15137 break;
15138 case OPC_DINSV_DSP:
15139 op2 = MASK_INSV(ctx->opcode);
15140 switch (op2) {
15141 case OPC_DINSV:
15142 {
15143 TCGv t0, t1;
15144
15145 if (rt == 0) {
15146 MIPS_DEBUG("NOP");
15147 break;
15148 }
15149 check_dsp(ctx);
15150
15151 t0 = tcg_temp_new();
15152 t1 = tcg_temp_new();
15153
15154 gen_load_gpr(t0, rt);
15155 gen_load_gpr(t1, rs);
15156
15157 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15158 break;
15159 }
15160 default: /* Invalid */
15161 MIPS_INVAL("MASK DINSV");
15162 generate_exception(ctx, EXCP_RI);
15163 break;
15164 }
15165 break;
15166 case OPC_SHLL_OB_DSP:
15167 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15168 break;
15169 #endif
15170 default: /* Invalid */
15171 MIPS_INVAL("special3");
15172 generate_exception(ctx, EXCP_RI);
15173 break;
15174 }
15175 break;
15176 case OPC_REGIMM:
15177 op1 = MASK_REGIMM(ctx->opcode);
15178 switch (op1) {
15179 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15180 case OPC_BLTZAL ... OPC_BGEZALL:
15181 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15182 *is_branch = 1;
15183 break;
15184 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15185 case OPC_TNEI:
15186 gen_trap(ctx, op1, rs, -1, imm);
15187 break;
15188 case OPC_SYNCI:
15189 check_insn(env, ctx, ISA_MIPS32R2);
15190 /* Treat as NOP. */
15191 break;
15192 case OPC_BPOSGE32: /* MIPS DSP branch */
15193 #if defined(TARGET_MIPS64)
15194 case OPC_BPOSGE64:
15195 #endif
15196 check_dsp(ctx);
15197 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15198 *is_branch = 1;
15199 break;
15200 default: /* Invalid */
15201 MIPS_INVAL("regimm");
15202 generate_exception(ctx, EXCP_RI);
15203 break;
15204 }
15205 break;
15206 case OPC_CP0:
15207 check_cp0_enabled(ctx);
15208 op1 = MASK_CP0(ctx->opcode);
15209 switch (op1) {
15210 case OPC_MFC0:
15211 case OPC_MTC0:
15212 case OPC_MFTR:
15213 case OPC_MTTR:
15214 #if defined(TARGET_MIPS64)
15215 case OPC_DMFC0:
15216 case OPC_DMTC0:
15217 #endif
15218 #ifndef CONFIG_USER_ONLY
15219 gen_cp0(env, ctx, op1, rt, rd);
15220 #endif /* !CONFIG_USER_ONLY */
15221 break;
15222 case OPC_C0_FIRST ... OPC_C0_LAST:
15223 #ifndef CONFIG_USER_ONLY
15224 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15225 #endif /* !CONFIG_USER_ONLY */
15226 break;
15227 case OPC_MFMC0:
15228 #ifndef CONFIG_USER_ONLY
15229 {
15230 TCGv t0 = tcg_temp_new();
15231
15232 op2 = MASK_MFMC0(ctx->opcode);
15233 switch (op2) {
15234 case OPC_DMT:
15235 check_insn(env, ctx, ASE_MT);
15236 gen_helper_dmt(t0);
15237 gen_store_gpr(t0, rt);
15238 break;
15239 case OPC_EMT:
15240 check_insn(env, ctx, ASE_MT);
15241 gen_helper_emt(t0);
15242 gen_store_gpr(t0, rt);
15243 break;
15244 case OPC_DVPE:
15245 check_insn(env, ctx, ASE_MT);
15246 gen_helper_dvpe(t0, cpu_env);
15247 gen_store_gpr(t0, rt);
15248 break;
15249 case OPC_EVPE:
15250 check_insn(env, ctx, ASE_MT);
15251 gen_helper_evpe(t0, cpu_env);
15252 gen_store_gpr(t0, rt);
15253 break;
15254 case OPC_DI:
15255 check_insn(env, ctx, ISA_MIPS32R2);
15256 save_cpu_state(ctx, 1);
15257 gen_helper_di(t0, cpu_env);
15258 gen_store_gpr(t0, rt);
15259 /* Stop translation as we may have switched the execution mode */
15260 ctx->bstate = BS_STOP;
15261 break;
15262 case OPC_EI:
15263 check_insn(env, ctx, ISA_MIPS32R2);
15264 save_cpu_state(ctx, 1);
15265 gen_helper_ei(t0, cpu_env);
15266 gen_store_gpr(t0, rt);
15267 /* Stop translation as we may have switched the execution mode */
15268 ctx->bstate = BS_STOP;
15269 break;
15270 default: /* Invalid */
15271 MIPS_INVAL("mfmc0");
15272 generate_exception(ctx, EXCP_RI);
15273 break;
15274 }
15275 tcg_temp_free(t0);
15276 }
15277 #endif /* !CONFIG_USER_ONLY */
15278 break;
15279 case OPC_RDPGPR:
15280 check_insn(env, ctx, ISA_MIPS32R2);
15281 gen_load_srsgpr(rt, rd);
15282 break;
15283 case OPC_WRPGPR:
15284 check_insn(env, ctx, ISA_MIPS32R2);
15285 gen_store_srsgpr(rt, rd);
15286 break;
15287 default:
15288 MIPS_INVAL("cp0");
15289 generate_exception(ctx, EXCP_RI);
15290 break;
15291 }
15292 break;
15293 case OPC_ADDI: /* Arithmetic with immediate opcode */
15294 case OPC_ADDIU:
15295 gen_arith_imm(env, ctx, op, rt, rs, imm);
15296 break;
15297 case OPC_SLTI: /* Set on less than with immediate opcode */
15298 case OPC_SLTIU:
15299 gen_slt_imm(env, ctx, op, rt, rs, imm);
15300 break;
15301 case OPC_ANDI: /* Arithmetic with immediate opcode */
15302 case OPC_LUI:
15303 case OPC_ORI:
15304 case OPC_XORI:
15305 gen_logic_imm(env, ctx, op, rt, rs, imm);
15306 break;
15307 case OPC_J ... OPC_JAL: /* Jump */
15308 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15309 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15310 *is_branch = 1;
15311 break;
15312 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15313 case OPC_BEQL ... OPC_BGTZL:
15314 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15315 *is_branch = 1;
15316 break;
15317 case OPC_LB ... OPC_LWR: /* Load and stores */
15318 case OPC_LL:
15319 gen_ld(env, ctx, op, rt, rs, imm);
15320 break;
15321 case OPC_SB ... OPC_SW:
15322 case OPC_SWR:
15323 gen_st(ctx, op, rt, rs, imm);
15324 break;
15325 case OPC_SC:
15326 gen_st_cond(ctx, op, rt, rs, imm);
15327 break;
15328 case OPC_CACHE:
15329 check_cp0_enabled(ctx);
15330 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
15331 /* Treat as NOP. */
15332 break;
15333 case OPC_PREF:
15334 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
15335 /* Treat as NOP. */
15336 break;
15337
15338 /* Floating point (COP1). */
15339 case OPC_LWC1:
15340 case OPC_LDC1:
15341 case OPC_SWC1:
15342 case OPC_SDC1:
15343 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15344 break;
15345
15346 case OPC_CP1:
15347 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15348 check_cp1_enabled(ctx);
15349 op1 = MASK_CP1(ctx->opcode);
15350 switch (op1) {
15351 case OPC_MFHC1:
15352 case OPC_MTHC1:
15353 check_insn(env, ctx, ISA_MIPS32R2);
15354 case OPC_MFC1:
15355 case OPC_CFC1:
15356 case OPC_MTC1:
15357 case OPC_CTC1:
15358 gen_cp1(ctx, op1, rt, rd);
15359 break;
15360 #if defined(TARGET_MIPS64)
15361 case OPC_DMFC1:
15362 case OPC_DMTC1:
15363 check_insn(env, ctx, ISA_MIPS3);
15364 gen_cp1(ctx, op1, rt, rd);
15365 break;
15366 #endif
15367 case OPC_BC1ANY2:
15368 case OPC_BC1ANY4:
15369 check_cop1x(ctx);
15370 check_insn(env, ctx, ASE_MIPS3D);
15371 /* fall through */
15372 case OPC_BC1:
15373 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
15374 (rt >> 2) & 0x7, imm << 2);
15375 *is_branch = 1;
15376 break;
15377 case OPC_S_FMT:
15378 case OPC_D_FMT:
15379 case OPC_W_FMT:
15380 case OPC_L_FMT:
15381 case OPC_PS_FMT:
15382 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15383 (imm >> 8) & 0x7);
15384 break;
15385 default:
15386 MIPS_INVAL("cp1");
15387 generate_exception (ctx, EXCP_RI);
15388 break;
15389 }
15390 } else {
15391 generate_exception_err(ctx, EXCP_CpU, 1);
15392 }
15393 break;
15394
15395 /* COP2. */
15396 case OPC_LWC2:
15397 case OPC_LDC2:
15398 case OPC_SWC2:
15399 case OPC_SDC2:
15400 /* COP2: Not implemented. */
15401 generate_exception_err(ctx, EXCP_CpU, 2);
15402 break;
15403 case OPC_CP2:
15404 check_insn(env, ctx, INSN_LOONGSON2F);
15405 /* Note that these instructions use different fields. */
15406 gen_loongson_multimedia(ctx, sa, rd, rt);
15407 break;
15408
15409 case OPC_CP3:
15410 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15411 check_cp1_enabled(ctx);
15412 op1 = MASK_CP3(ctx->opcode);
15413 switch (op1) {
15414 case OPC_LWXC1:
15415 case OPC_LDXC1:
15416 case OPC_LUXC1:
15417 case OPC_SWXC1:
15418 case OPC_SDXC1:
15419 case OPC_SUXC1:
15420 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15421 break;
15422 case OPC_PREFX:
15423 /* Treat as NOP. */
15424 break;
15425 case OPC_ALNV_PS:
15426 case OPC_MADD_S:
15427 case OPC_MADD_D:
15428 case OPC_MADD_PS:
15429 case OPC_MSUB_S:
15430 case OPC_MSUB_D:
15431 case OPC_MSUB_PS:
15432 case OPC_NMADD_S:
15433 case OPC_NMADD_D:
15434 case OPC_NMADD_PS:
15435 case OPC_NMSUB_S:
15436 case OPC_NMSUB_D:
15437 case OPC_NMSUB_PS:
15438 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15439 break;
15440 default:
15441 MIPS_INVAL("cp3");
15442 generate_exception (ctx, EXCP_RI);
15443 break;
15444 }
15445 } else {
15446 generate_exception_err(ctx, EXCP_CpU, 1);
15447 }
15448 break;
15449
15450 #if defined(TARGET_MIPS64)
15451 /* MIPS64 opcodes */
15452 case OPC_LWU:
15453 case OPC_LDL ... OPC_LDR:
15454 case OPC_LLD:
15455 case OPC_LD:
15456 check_insn(env, ctx, ISA_MIPS3);
15457 check_mips_64(ctx);
15458 gen_ld(env, ctx, op, rt, rs, imm);
15459 break;
15460 case OPC_SDL ... OPC_SDR:
15461 case OPC_SD:
15462 check_insn(env, ctx, ISA_MIPS3);
15463 check_mips_64(ctx);
15464 gen_st(ctx, op, rt, rs, imm);
15465 break;
15466 case OPC_SCD:
15467 check_insn(env, ctx, ISA_MIPS3);
15468 check_mips_64(ctx);
15469 gen_st_cond(ctx, op, rt, rs, imm);
15470 break;
15471 case OPC_DADDI:
15472 case OPC_DADDIU:
15473 check_insn(env, ctx, ISA_MIPS3);
15474 check_mips_64(ctx);
15475 gen_arith_imm(env, ctx, op, rt, rs, imm);
15476 break;
15477 #endif
15478 case OPC_JALX:
15479 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
15480 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15481 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15482 *is_branch = 1;
15483 break;
15484 case OPC_MDMX:
15485 check_insn(env, ctx, ASE_MDMX);
15486 /* MDMX: Not implemented. */
15487 default: /* Invalid */
15488 MIPS_INVAL("major opcode");
15489 generate_exception(ctx, EXCP_RI);
15490 break;
15491 }
15492 }
15493
15494 static inline void
15495 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
15496 int search_pc)
15497 {
15498 DisasContext ctx;
15499 target_ulong pc_start;
15500 uint16_t *gen_opc_end;
15501 CPUBreakpoint *bp;
15502 int j, lj = -1;
15503 int num_insns;
15504 int max_insns;
15505 int insn_bytes;
15506 int is_branch;
15507
15508 if (search_pc)
15509 qemu_log("search pc %d\n", search_pc);
15510
15511 pc_start = tb->pc;
15512 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
15513 ctx.pc = pc_start;
15514 ctx.saved_pc = -1;
15515 ctx.singlestep_enabled = env->singlestep_enabled;
15516 ctx.tb = tb;
15517 ctx.bstate = BS_NONE;
15518 /* Restore delay slot state from the tb context. */
15519 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15520 restore_cpu_state(env, &ctx);
15521 #ifdef CONFIG_USER_ONLY
15522 ctx.mem_idx = MIPS_HFLAG_UM;
15523 #else
15524 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15525 #endif
15526 num_insns = 0;
15527 max_insns = tb->cflags & CF_COUNT_MASK;
15528 if (max_insns == 0)
15529 max_insns = CF_COUNT_MASK;
15530 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15531 gen_icount_start();
15532 while (ctx.bstate == BS_NONE) {
15533 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15534 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15535 if (bp->pc == ctx.pc) {
15536 save_cpu_state(&ctx, 1);
15537 ctx.bstate = BS_BRANCH;
15538 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15539 /* Include the breakpoint location or the tb won't
15540 * be flushed when it must be. */
15541 ctx.pc += 4;
15542 goto done_generating;
15543 }
15544 }
15545 }
15546
15547 if (search_pc) {
15548 j = gen_opc_ptr - gen_opc_buf;
15549 if (lj < j) {
15550 lj++;
15551 while (lj < j)
15552 gen_opc_instr_start[lj++] = 0;
15553 }
15554 gen_opc_pc[lj] = ctx.pc;
15555 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15556 gen_opc_btarget[lj] = ctx.btarget;
15557 gen_opc_instr_start[lj] = 1;
15558 gen_opc_icount[lj] = num_insns;
15559 }
15560 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15561 gen_io_start();
15562
15563 is_branch = 0;
15564 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15565 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15566 insn_bytes = 4;
15567 decode_opc(env, &ctx, &is_branch);
15568 } else if (env->insn_flags & ASE_MICROMIPS) {
15569 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15570 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
15571 } else if (env->insn_flags & ASE_MIPS16) {
15572 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15573 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
15574 } else {
15575 generate_exception(&ctx, EXCP_RI);
15576 ctx.bstate = BS_STOP;
15577 break;
15578 }
15579 if (!is_branch) {
15580 handle_delay_slot(env, &ctx, insn_bytes);
15581 }
15582 ctx.pc += insn_bytes;
15583
15584 num_insns++;
15585
15586 /* Execute a branch and its delay slot as a single instruction.
15587 This is what GDB expects and is consistent with what the
15588 hardware does (e.g. if a delay slot instruction faults, the
15589 reported PC is the PC of the branch). */
15590 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
15591 break;
15592
15593 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15594 break;
15595
15596 if (gen_opc_ptr >= gen_opc_end)
15597 break;
15598
15599 if (num_insns >= max_insns)
15600 break;
15601
15602 if (singlestep)
15603 break;
15604 }
15605 if (tb->cflags & CF_LAST_IO)
15606 gen_io_end();
15607 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15608 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15609 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15610 } else {
15611 switch (ctx.bstate) {
15612 case BS_STOP:
15613 gen_goto_tb(&ctx, 0, ctx.pc);
15614 break;
15615 case BS_NONE:
15616 save_cpu_state(&ctx, 0);
15617 gen_goto_tb(&ctx, 0, ctx.pc);
15618 break;
15619 case BS_EXCP:
15620 tcg_gen_exit_tb(0);
15621 break;
15622 case BS_BRANCH:
15623 default:
15624 break;
15625 }
15626 }
15627 done_generating:
15628 gen_icount_end(tb, num_insns);
15629 *gen_opc_ptr = INDEX_op_end;
15630 if (search_pc) {
15631 j = gen_opc_ptr - gen_opc_buf;
15632 lj++;
15633 while (lj <= j)
15634 gen_opc_instr_start[lj++] = 0;
15635 } else {
15636 tb->size = ctx.pc - pc_start;
15637 tb->icount = num_insns;
15638 }
15639 #ifdef DEBUG_DISAS
15640 LOG_DISAS("\n");
15641 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15642 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15643 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15644 qemu_log("\n");
15645 }
15646 #endif
15647 }
15648
15649 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15650 {
15651 gen_intermediate_code_internal(env, tb, 0);
15652 }
15653
15654 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15655 {
15656 gen_intermediate_code_internal(env, tb, 1);
15657 }
15658
15659 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15660 int flags)
15661 {
15662 int i;
15663 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15664
15665 #define printfpr(fp) \
15666 do { \
15667 if (is_fpu64) \
15668 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15669 " fd:%13g fs:%13g psu: %13g\n", \
15670 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15671 (double)(fp)->fd, \
15672 (double)(fp)->fs[FP_ENDIAN_IDX], \
15673 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15674 else { \
15675 fpr_t tmp; \
15676 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15677 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15678 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15679 " fd:%13g fs:%13g psu:%13g\n", \
15680 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15681 (double)tmp.fd, \
15682 (double)tmp.fs[FP_ENDIAN_IDX], \
15683 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15684 } \
15685 } while(0)
15686
15687
15688 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15689 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15690 get_float_exception_flags(&env->active_fpu.fp_status));
15691 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15692 fpu_fprintf(f, "%3s: ", fregnames[i]);
15693 printfpr(&env->active_fpu.fpr[i]);
15694 }
15695
15696 #undef printfpr
15697 }
15698
15699 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15700 /* Debug help: The architecture requires 32bit code to maintain proper
15701 sign-extended values on 64bit machines. */
15702
15703 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15704
15705 static void
15706 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15707 fprintf_function cpu_fprintf,
15708 int flags)
15709 {
15710 int i;
15711
15712 if (!SIGN_EXT_P(env->active_tc.PC))
15713 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15714 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15715 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15716 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15717 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15718 if (!SIGN_EXT_P(env->btarget))
15719 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15720
15721 for (i = 0; i < 32; i++) {
15722 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15723 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15724 }
15725
15726 if (!SIGN_EXT_P(env->CP0_EPC))
15727 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15728 if (!SIGN_EXT_P(env->lladdr))
15729 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15730 }
15731 #endif
15732
15733 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
15734 int flags)
15735 {
15736 int i;
15737
15738 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15739 " LO=0x" TARGET_FMT_lx " ds %04x "
15740 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15741 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15742 env->hflags, env->btarget, env->bcond);
15743 for (i = 0; i < 32; i++) {
15744 if ((i & 3) == 0)
15745 cpu_fprintf(f, "GPR%02d:", i);
15746 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15747 if ((i & 3) == 3)
15748 cpu_fprintf(f, "\n");
15749 }
15750
15751 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15752 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15753 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15754 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15755 if (env->hflags & MIPS_HFLAG_FPU)
15756 fpu_dump_state(env, f, cpu_fprintf, flags);
15757 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15758 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15759 #endif
15760 }
15761
15762 static void mips_tcg_init(void)
15763 {
15764 int i;
15765 static int inited;
15766
15767 /* Initialize various static tables. */
15768 if (inited)
15769 return;
15770
15771 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15772 TCGV_UNUSED(cpu_gpr[0]);
15773 for (i = 1; i < 32; i++)
15774 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15775 offsetof(CPUMIPSState, active_tc.gpr[i]),
15776 regnames[i]);
15777
15778 for (i = 0; i < 32; i++) {
15779 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15780 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15781 }
15782
15783 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15784 offsetof(CPUMIPSState, active_tc.PC), "PC");
15785 for (i = 0; i < MIPS_DSP_ACC; i++) {
15786 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15787 offsetof(CPUMIPSState, active_tc.HI[i]),
15788 regnames_HI[i]);
15789 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15790 offsetof(CPUMIPSState, active_tc.LO[i]),
15791 regnames_LO[i]);
15792 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15793 offsetof(CPUMIPSState, active_tc.ACX[i]),
15794 regnames_ACX[i]);
15795 }
15796 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15797 offsetof(CPUMIPSState, active_tc.DSPControl),
15798 "DSPControl");
15799 bcond = tcg_global_mem_new(TCG_AREG0,
15800 offsetof(CPUMIPSState, bcond), "bcond");
15801 btarget = tcg_global_mem_new(TCG_AREG0,
15802 offsetof(CPUMIPSState, btarget), "btarget");
15803 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15804 offsetof(CPUMIPSState, hflags), "hflags");
15805
15806 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15807 offsetof(CPUMIPSState, active_fpu.fcr0),
15808 "fcr0");
15809 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15810 offsetof(CPUMIPSState, active_fpu.fcr31),
15811 "fcr31");
15812
15813 /* register helpers */
15814 #define GEN_HELPER 2
15815 #include "helper.h"
15816
15817 inited = 1;
15818 }
15819
15820 #include "translate_init.c"
15821
15822 MIPSCPU *cpu_mips_init(const char *cpu_model)
15823 {
15824 MIPSCPU *cpu;
15825 CPUMIPSState *env;
15826 const mips_def_t *def;
15827
15828 def = cpu_mips_find_by_name(cpu_model);
15829 if (!def)
15830 return NULL;
15831 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15832 env = &cpu->env;
15833 env->cpu_model = def;
15834 env->cpu_model_str = cpu_model;
15835
15836 #ifndef CONFIG_USER_ONLY
15837 mmu_init(env, def);
15838 #endif
15839 fpu_init(env, def);
15840 mvp_init(env, def);
15841 mips_tcg_init();
15842 cpu_reset(CPU(cpu));
15843 qemu_init_vcpu(env);
15844 return cpu;
15845 }
15846
15847 void cpu_state_reset(CPUMIPSState *env)
15848 {
15849 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15850 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15851 log_cpu_state(env, 0);
15852 }
15853
15854 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
15855 tlb_flush(env, 1);
15856
15857 /* Reset registers to their default values */
15858 env->CP0_PRid = env->cpu_model->CP0_PRid;
15859 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15860 #ifdef TARGET_WORDS_BIGENDIAN
15861 env->CP0_Config0 |= (1 << CP0C0_BE);
15862 #endif
15863 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15864 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15865 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15866 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15867 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15868 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15869 << env->cpu_model->CP0_LLAddr_shift;
15870 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15871 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15872 env->CCRes = env->cpu_model->CCRes;
15873 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15874 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15875 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15876 env->current_tc = 0;
15877 env->SEGBITS = env->cpu_model->SEGBITS;
15878 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15879 #if defined(TARGET_MIPS64)
15880 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15881 env->SEGMask |= 3ULL << 62;
15882 }
15883 #endif
15884 env->PABITS = env->cpu_model->PABITS;
15885 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15886 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15887 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15888 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15889 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15890 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15891 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15892 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15893 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15894 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15895 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15896 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15897 env->insn_flags = env->cpu_model->insn_flags;
15898
15899 #if defined(CONFIG_USER_ONLY)
15900 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15901 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15902 hardware registers. */
15903 env->CP0_HWREna |= 0x0000000F;
15904 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15905 env->CP0_Status |= (1 << CP0St_CU1);
15906 }
15907 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15908 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15909 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15910 env->hflags |= MIPS_HFLAG_DSP;
15911 }
15912 #else
15913 if (env->hflags & MIPS_HFLAG_BMASK) {
15914 /* If the exception was raised from a delay slot,
15915 come back to the jump. */
15916 env->CP0_ErrorEPC = env->active_tc.PC - 4;
15917 } else {
15918 env->CP0_ErrorEPC = env->active_tc.PC;
15919 }
15920 env->active_tc.PC = (int32_t)0xBFC00000;
15921 env->CP0_Random = env->tlb->nb_tlb - 1;
15922 env->tlb->tlb_in_use = env->tlb->nb_tlb;
15923 env->CP0_Wired = 0;
15924 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
15925 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15926 /* vectored interrupts not implemented, timer on int 7,
15927 no performance counters. */
15928 env->CP0_IntCtl = 0xe0000000;
15929 {
15930 int i;
15931
15932 for (i = 0; i < 7; i++) {
15933 env->CP0_WatchLo[i] = 0;
15934 env->CP0_WatchHi[i] = 0x80000000;
15935 }
15936 env->CP0_WatchLo[7] = 0;
15937 env->CP0_WatchHi[7] = 0;
15938 }
15939 /* Count register increments in debug mode, EJTAG version 1 */
15940 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
15941
15942 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15943 int i;
15944
15945 /* Only TC0 on VPE 0 starts as active. */
15946 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15947 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15948 env->tcs[i].CP0_TCHalt = 1;
15949 }
15950 env->active_tc.CP0_TCHalt = 1;
15951 env->halted = 1;
15952
15953 if (!env->cpu_index) {
15954 /* VPE0 starts up enabled. */
15955 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15956 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15957
15958 /* TC0 starts up unhalted. */
15959 env->halted = 0;
15960 env->active_tc.CP0_TCHalt = 0;
15961 env->tcs[0].CP0_TCHalt = 0;
15962 /* With thread 0 active. */
15963 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15964 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15965 }
15966 }
15967 #endif
15968 compute_hflags(env);
15969 env->exception_index = EXCP_NONE;
15970 }
15971
15972 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
15973 {
15974 env->active_tc.PC = gen_opc_pc[pc_pos];
15975 env->hflags &= ~MIPS_HFLAG_BMASK;
15976 env->hflags |= gen_opc_hflags[pc_pos];
15977 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15978 case MIPS_HFLAG_BR:
15979 break;
15980 case MIPS_HFLAG_BC:
15981 case MIPS_HFLAG_BL:
15982 case MIPS_HFLAG_B:
15983 env->btarget = gen_opc_btarget[pc_pos];
15984 break;
15985 }
15986 }