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