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