]> git.proxmox.com Git - mirror_qemu.git/blob - target-mips/translate.c
tcg: Invert the inclusion of helper.h
[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/disas.h"
26 #include "tcg-op.h"
27
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
30
31 #define MIPS_DEBUG_DISAS 0
32 //#define MIPS_DEBUG_SIGN_EXTENSIONS
33
34 /* MIPS major opcodes */
35 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
36
37 enum {
38 /* indirect opcode tables */
39 OPC_SPECIAL = (0x00 << 26),
40 OPC_REGIMM = (0x01 << 26),
41 OPC_CP0 = (0x10 << 26),
42 OPC_CP1 = (0x11 << 26),
43 OPC_CP2 = (0x12 << 26),
44 OPC_CP3 = (0x13 << 26),
45 OPC_SPECIAL2 = (0x1C << 26),
46 OPC_SPECIAL3 = (0x1F << 26),
47 /* arithmetic with immediate */
48 OPC_ADDI = (0x08 << 26),
49 OPC_ADDIU = (0x09 << 26),
50 OPC_SLTI = (0x0A << 26),
51 OPC_SLTIU = (0x0B << 26),
52 /* logic with immediate */
53 OPC_ANDI = (0x0C << 26),
54 OPC_ORI = (0x0D << 26),
55 OPC_XORI = (0x0E << 26),
56 OPC_LUI = (0x0F << 26),
57 /* arithmetic with immediate */
58 OPC_DADDI = (0x18 << 26),
59 OPC_DADDIU = (0x19 << 26),
60 /* Jump and branches */
61 OPC_J = (0x02 << 26),
62 OPC_JAL = (0x03 << 26),
63 OPC_JALS = OPC_JAL | 0x5,
64 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
65 OPC_BEQL = (0x14 << 26),
66 OPC_BNE = (0x05 << 26),
67 OPC_BNEL = (0x15 << 26),
68 OPC_BLEZ = (0x06 << 26),
69 OPC_BLEZL = (0x16 << 26),
70 OPC_BGTZ = (0x07 << 26),
71 OPC_BGTZL = (0x17 << 26),
72 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
73 OPC_JALXS = OPC_JALX | 0x5,
74 /* Load and stores */
75 OPC_LDL = (0x1A << 26),
76 OPC_LDR = (0x1B << 26),
77 OPC_LB = (0x20 << 26),
78 OPC_LH = (0x21 << 26),
79 OPC_LWL = (0x22 << 26),
80 OPC_LW = (0x23 << 26),
81 OPC_LWPC = OPC_LW | 0x5,
82 OPC_LBU = (0x24 << 26),
83 OPC_LHU = (0x25 << 26),
84 OPC_LWR = (0x26 << 26),
85 OPC_LWU = (0x27 << 26),
86 OPC_SB = (0x28 << 26),
87 OPC_SH = (0x29 << 26),
88 OPC_SWL = (0x2A << 26),
89 OPC_SW = (0x2B << 26),
90 OPC_SDL = (0x2C << 26),
91 OPC_SDR = (0x2D << 26),
92 OPC_SWR = (0x2E << 26),
93 OPC_LL = (0x30 << 26),
94 OPC_LLD = (0x34 << 26),
95 OPC_LD = (0x37 << 26),
96 OPC_LDPC = OPC_LD | 0x5,
97 OPC_SC = (0x38 << 26),
98 OPC_SCD = (0x3C << 26),
99 OPC_SD = (0x3F << 26),
100 /* Floating point load/store */
101 OPC_LWC1 = (0x31 << 26),
102 OPC_LWC2 = (0x32 << 26),
103 OPC_LDC1 = (0x35 << 26),
104 OPC_LDC2 = (0x36 << 26),
105 OPC_SWC1 = (0x39 << 26),
106 OPC_SWC2 = (0x3A << 26),
107 OPC_SDC1 = (0x3D << 26),
108 OPC_SDC2 = (0x3E << 26),
109 /* MDMX ASE specific */
110 OPC_MDMX = (0x1E << 26),
111 /* Cache and prefetch */
112 OPC_CACHE = (0x2F << 26),
113 OPC_PREF = (0x33 << 26),
114 /* Reserved major opcode */
115 OPC_MAJOR3B_RESERVED = (0x3B << 26),
116 };
117
118 /* MIPS special opcodes */
119 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
120
121 enum {
122 /* Shifts */
123 OPC_SLL = 0x00 | OPC_SPECIAL,
124 /* NOP is SLL r0, r0, 0 */
125 /* SSNOP is SLL r0, r0, 1 */
126 /* EHB is SLL r0, r0, 3 */
127 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
128 OPC_ROTR = OPC_SRL | (1 << 21),
129 OPC_SRA = 0x03 | OPC_SPECIAL,
130 OPC_SLLV = 0x04 | OPC_SPECIAL,
131 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
132 OPC_ROTRV = OPC_SRLV | (1 << 6),
133 OPC_SRAV = 0x07 | OPC_SPECIAL,
134 OPC_DSLLV = 0x14 | OPC_SPECIAL,
135 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
136 OPC_DROTRV = OPC_DSRLV | (1 << 6),
137 OPC_DSRAV = 0x17 | OPC_SPECIAL,
138 OPC_DSLL = 0x38 | OPC_SPECIAL,
139 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
140 OPC_DROTR = OPC_DSRL | (1 << 21),
141 OPC_DSRA = 0x3B | OPC_SPECIAL,
142 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
143 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
144 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
145 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
146 /* Multiplication / division */
147 OPC_MULT = 0x18 | OPC_SPECIAL,
148 OPC_MULTU = 0x19 | OPC_SPECIAL,
149 OPC_DIV = 0x1A | OPC_SPECIAL,
150 OPC_DIVU = 0x1B | OPC_SPECIAL,
151 OPC_DMULT = 0x1C | OPC_SPECIAL,
152 OPC_DMULTU = 0x1D | OPC_SPECIAL,
153 OPC_DDIV = 0x1E | OPC_SPECIAL,
154 OPC_DDIVU = 0x1F | OPC_SPECIAL,
155 /* 2 registers arithmetic / logic */
156 OPC_ADD = 0x20 | OPC_SPECIAL,
157 OPC_ADDU = 0x21 | OPC_SPECIAL,
158 OPC_SUB = 0x22 | OPC_SPECIAL,
159 OPC_SUBU = 0x23 | OPC_SPECIAL,
160 OPC_AND = 0x24 | OPC_SPECIAL,
161 OPC_OR = 0x25 | OPC_SPECIAL,
162 OPC_XOR = 0x26 | OPC_SPECIAL,
163 OPC_NOR = 0x27 | OPC_SPECIAL,
164 OPC_SLT = 0x2A | OPC_SPECIAL,
165 OPC_SLTU = 0x2B | OPC_SPECIAL,
166 OPC_DADD = 0x2C | OPC_SPECIAL,
167 OPC_DADDU = 0x2D | OPC_SPECIAL,
168 OPC_DSUB = 0x2E | OPC_SPECIAL,
169 OPC_DSUBU = 0x2F | OPC_SPECIAL,
170 /* Jumps */
171 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
172 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
173 OPC_JALRC = OPC_JALR | (0x5 << 6),
174 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
175 /* Traps */
176 OPC_TGE = 0x30 | OPC_SPECIAL,
177 OPC_TGEU = 0x31 | OPC_SPECIAL,
178 OPC_TLT = 0x32 | OPC_SPECIAL,
179 OPC_TLTU = 0x33 | OPC_SPECIAL,
180 OPC_TEQ = 0x34 | OPC_SPECIAL,
181 OPC_TNE = 0x36 | OPC_SPECIAL,
182 /* HI / LO registers load & stores */
183 OPC_MFHI = 0x10 | OPC_SPECIAL,
184 OPC_MTHI = 0x11 | OPC_SPECIAL,
185 OPC_MFLO = 0x12 | OPC_SPECIAL,
186 OPC_MTLO = 0x13 | OPC_SPECIAL,
187 /* Conditional moves */
188 OPC_MOVZ = 0x0A | OPC_SPECIAL,
189 OPC_MOVN = 0x0B | OPC_SPECIAL,
190
191 OPC_MOVCI = 0x01 | OPC_SPECIAL,
192
193 /* Special */
194 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
195 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
196 OPC_BREAK = 0x0D | OPC_SPECIAL,
197 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
198 OPC_SYNC = 0x0F | OPC_SPECIAL,
199
200 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
201 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
202 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
203 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
204 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
205 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
206 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
207 };
208
209 /* Multiplication variants of the vr54xx. */
210 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
211
212 enum {
213 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
214 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
215 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
216 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
217 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
218 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
219 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
220 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
221 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
222 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
223 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
224 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
225 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
226 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
227 };
228
229 /* REGIMM (rt field) opcodes */
230 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
231
232 enum {
233 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
234 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
235 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
236 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
237 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
238 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
239 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
240 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
241 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
242 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
243 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
244 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
245 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
246 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
247 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
248 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
249 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
250 };
251
252 /* Special2 opcodes */
253 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
254
255 enum {
256 /* Multiply & xxx operations */
257 OPC_MADD = 0x00 | OPC_SPECIAL2,
258 OPC_MADDU = 0x01 | OPC_SPECIAL2,
259 OPC_MUL = 0x02 | OPC_SPECIAL2,
260 OPC_MSUB = 0x04 | OPC_SPECIAL2,
261 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
262 /* Loongson 2F */
263 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
264 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
265 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
266 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
267 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
268 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
269 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
270 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
271 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
272 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
273 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
274 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
275 /* Misc */
276 OPC_CLZ = 0x20 | OPC_SPECIAL2,
277 OPC_CLO = 0x21 | OPC_SPECIAL2,
278 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
279 OPC_DCLO = 0x25 | OPC_SPECIAL2,
280 /* Special */
281 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
282 };
283
284 /* Special3 opcodes */
285 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
286
287 enum {
288 OPC_EXT = 0x00 | OPC_SPECIAL3,
289 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
290 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
291 OPC_DEXT = 0x03 | OPC_SPECIAL3,
292 OPC_INS = 0x04 | OPC_SPECIAL3,
293 OPC_DINSM = 0x05 | OPC_SPECIAL3,
294 OPC_DINSU = 0x06 | OPC_SPECIAL3,
295 OPC_DINS = 0x07 | OPC_SPECIAL3,
296 OPC_FORK = 0x08 | OPC_SPECIAL3,
297 OPC_YIELD = 0x09 | OPC_SPECIAL3,
298 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
299 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
300 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
301
302 /* Loongson 2E */
303 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
304 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
305 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
306 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
307 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
308 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
309 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
310 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
311 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
312 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
313 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
314 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
315
316 /* MIPS DSP Load */
317 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
318 /* MIPS DSP Arithmetic */
319 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
320 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
321 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
322 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
323 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
324 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
325 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
326 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
327 /* MIPS DSP GPR-Based Shift Sub-class */
328 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
329 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
330 /* MIPS DSP Multiply Sub-class insns */
331 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
332 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
333 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
334 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
335 /* DSP Bit/Manipulation Sub-class */
336 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
337 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
338 /* MIPS DSP Append Sub-class */
339 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
340 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
341 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
342 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
343 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
344 };
345
346 /* BSHFL opcodes */
347 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
348
349 enum {
350 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
351 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
352 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
353 };
354
355 /* DBSHFL opcodes */
356 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
357
358 enum {
359 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
360 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
361 };
362
363 /* MIPS DSP REGIMM opcodes */
364 enum {
365 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
366 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
367 };
368
369 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
370 /* MIPS DSP Load */
371 enum {
372 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
373 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
374 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
375 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
376 };
377
378 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
379 enum {
380 /* MIPS DSP Arithmetic Sub-class */
381 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
382 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
388 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
395 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
397 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
398 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
399 /* MIPS DSP Multiply Sub-class insns */
400 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
401 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
406 };
407
408 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
409 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
410 enum {
411 /* MIPS DSP Arithmetic Sub-class */
412 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
413 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
424 /* MIPS DSP Multiply Sub-class insns */
425 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
426 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
429 };
430
431 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
432 enum {
433 /* MIPS DSP Arithmetic Sub-class */
434 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
435 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
447 /* DSP Bit/Manipulation Sub-class */
448 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
449 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
453 };
454
455 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
456 enum {
457 /* MIPS DSP Arithmetic Sub-class */
458 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
459 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
465 /* DSP Compare-Pick Sub-class */
466 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
467 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
481 };
482
483 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
484 enum {
485 /* MIPS DSP GPR-Based Shift Sub-class */
486 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
487 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
508 };
509
510 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
511 enum {
512 /* MIPS DSP Multiply Sub-class insns */
513 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
514 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
527 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
528 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
530 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
535 };
536
537 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
538 enum {
539 /* DSP Bit/Manipulation Sub-class */
540 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
541 };
542
543 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
544 enum {
545 /* MIPS DSP Append Sub-class */
546 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
547 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
548 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
549 };
550
551 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
552 enum {
553 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
554 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
555 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
566 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
568 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
569 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
570 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
571 };
572
573 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
574 enum {
575 /* MIPS DSP Arithmetic Sub-class */
576 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
577 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
593 /* DSP Bit/Manipulation Sub-class */
594 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
595 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
600 };
601
602 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
603 enum {
604 /* MIPS DSP Multiply Sub-class insns */
605 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
606 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
610 /* MIPS DSP Arithmetic Sub-class */
611 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
612 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
622 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
632 };
633
634 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
635 enum {
636 /* DSP Compare-Pick Sub-class */
637 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
638 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
656 /* MIPS DSP Arithmetic Sub-class */
657 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
658 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
665 };
666
667 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
668 enum {
669 /* DSP Append Sub-class */
670 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
671 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
673 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
674 };
675
676 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
677 enum {
678 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
679 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
680 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
681 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
700 };
701
702 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
703 enum {
704 /* DSP Bit/Manipulation Sub-class */
705 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
706 };
707
708 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
709 enum {
710 /* MIPS DSP Multiply Sub-class insns */
711 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
712 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
737 };
738
739 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
740 enum {
741 /* MIPS DSP GPR-Based Shift Sub-class */
742 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
743 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
768 };
769
770 /* Coprocessor 0 (rs field) */
771 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
772
773 enum {
774 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
775 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
776 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
777 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
778 OPC_MFTR = (0x08 << 21) | OPC_CP0,
779 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
780 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
781 OPC_MTTR = (0x0C << 21) | OPC_CP0,
782 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
783 OPC_C0 = (0x10 << 21) | OPC_CP0,
784 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
785 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
786 };
787
788 /* MFMC0 opcodes */
789 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
790
791 enum {
792 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
793 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
795 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
796 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
797 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
798 };
799
800 /* Coprocessor 0 (with rs == C0) */
801 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
802
803 enum {
804 OPC_TLBR = 0x01 | OPC_C0,
805 OPC_TLBWI = 0x02 | OPC_C0,
806 OPC_TLBWR = 0x06 | OPC_C0,
807 OPC_TLBP = 0x08 | OPC_C0,
808 OPC_RFE = 0x10 | OPC_C0,
809 OPC_ERET = 0x18 | OPC_C0,
810 OPC_DERET = 0x1F | OPC_C0,
811 OPC_WAIT = 0x20 | OPC_C0,
812 };
813
814 /* Coprocessor 1 (rs field) */
815 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
816
817 /* Values for the fmt field in FP instructions */
818 enum {
819 /* 0 - 15 are reserved */
820 FMT_S = 16, /* single fp */
821 FMT_D = 17, /* double fp */
822 FMT_E = 18, /* extended fp */
823 FMT_Q = 19, /* quad fp */
824 FMT_W = 20, /* 32-bit fixed */
825 FMT_L = 21, /* 64-bit fixed */
826 FMT_PS = 22, /* paired single fp */
827 /* 23 - 31 are reserved */
828 };
829
830 enum {
831 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
832 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
833 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
834 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
835 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
836 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
837 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
838 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
839 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
840 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
841 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
842 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
843 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
844 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
845 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
846 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
847 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
848 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
849 };
850
851 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
852 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
853
854 enum {
855 OPC_BC1F = (0x00 << 16) | OPC_BC1,
856 OPC_BC1T = (0x01 << 16) | OPC_BC1,
857 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
858 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
859 };
860
861 enum {
862 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
863 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
864 };
865
866 enum {
867 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
868 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
869 };
870
871 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
872
873 enum {
874 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
875 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
876 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
877 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
878 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
879 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
880 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
881 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
882 OPC_BC2 = (0x08 << 21) | OPC_CP2,
883 };
884
885 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
886
887 enum {
888 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
889 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
896
897 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
898 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
905
906 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
907 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
910 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
911 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
912 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
913 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
914
915 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
916 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
919 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
923
924 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
925 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
926 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
927 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
928 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
929 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
930
931 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
932 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
937
938 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
939 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
940 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
944
945 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
946 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
949 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
951
952 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
953 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
954 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
955 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
956 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
958
959 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
960 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
961 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
962 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
963 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
965
966 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
967 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
968 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
969 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
970 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
972
973 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
974 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
975 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
976 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
977 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
978 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
979 };
980
981
982 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
983
984 enum {
985 OPC_LWXC1 = 0x00 | OPC_CP3,
986 OPC_LDXC1 = 0x01 | OPC_CP3,
987 OPC_LUXC1 = 0x05 | OPC_CP3,
988 OPC_SWXC1 = 0x08 | OPC_CP3,
989 OPC_SDXC1 = 0x09 | OPC_CP3,
990 OPC_SUXC1 = 0x0D | OPC_CP3,
991 OPC_PREFX = 0x0F | OPC_CP3,
992 OPC_ALNV_PS = 0x1E | OPC_CP3,
993 OPC_MADD_S = 0x20 | OPC_CP3,
994 OPC_MADD_D = 0x21 | OPC_CP3,
995 OPC_MADD_PS = 0x26 | OPC_CP3,
996 OPC_MSUB_S = 0x28 | OPC_CP3,
997 OPC_MSUB_D = 0x29 | OPC_CP3,
998 OPC_MSUB_PS = 0x2E | OPC_CP3,
999 OPC_NMADD_S = 0x30 | OPC_CP3,
1000 OPC_NMADD_D = 0x31 | OPC_CP3,
1001 OPC_NMADD_PS= 0x36 | OPC_CP3,
1002 OPC_NMSUB_S = 0x38 | OPC_CP3,
1003 OPC_NMSUB_D = 0x39 | OPC_CP3,
1004 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1005 };
1006
1007 /* global register indices */
1008 static TCGv_ptr cpu_env;
1009 static TCGv cpu_gpr[32], cpu_PC;
1010 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1011 static TCGv cpu_dspctrl, btarget, bcond;
1012 static TCGv_i32 hflags;
1013 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1014 static TCGv_i64 fpu_f64[32];
1015
1016 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1017 static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1018
1019 #include "exec/gen-icount.h"
1020
1021 #define gen_helper_0e0i(name, arg) do { \
1022 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1023 gen_helper_##name(cpu_env, helper_tmp); \
1024 tcg_temp_free_i32(helper_tmp); \
1025 } while(0)
1026
1027 #define gen_helper_0e1i(name, arg1, arg2) do { \
1028 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1029 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1030 tcg_temp_free_i32(helper_tmp); \
1031 } while(0)
1032
1033 #define gen_helper_1e0i(name, ret, arg1) do { \
1034 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1035 gen_helper_##name(ret, cpu_env, helper_tmp); \
1036 tcg_temp_free_i32(helper_tmp); \
1037 } while(0)
1038
1039 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1040 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1041 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1042 tcg_temp_free_i32(helper_tmp); \
1043 } while(0)
1044
1045 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1046 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1047 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1048 tcg_temp_free_i32(helper_tmp); \
1049 } while(0)
1050
1051 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1052 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1053 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1054 tcg_temp_free_i32(helper_tmp); \
1055 } while(0)
1056
1057 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1058 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1059 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1060 tcg_temp_free_i32(helper_tmp); \
1061 } while(0)
1062
1063 typedef struct DisasContext {
1064 struct TranslationBlock *tb;
1065 target_ulong pc, saved_pc;
1066 uint32_t opcode;
1067 int singlestep_enabled;
1068 int insn_flags;
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(DisasContext *ctx, TCGv_i32 t, int reg)
1219 {
1220 if (ctx->hflags & MIPS_HFLAG_F64) {
1221 TCGv_i64 t64 = tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1223 tcg_gen_trunc_i64_i32(t, t64);
1224 tcg_temp_free_i64(t64);
1225 } else {
1226 gen_load_fpr32(t, reg | 1);
1227 }
1228 }
1229
1230 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1231 {
1232 if (ctx->hflags & MIPS_HFLAG_F64) {
1233 TCGv_i64 t64 = tcg_temp_new_i64();
1234 tcg_gen_extu_i32_i64(t64, t);
1235 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1236 tcg_temp_free_i64(t64);
1237 } else {
1238 gen_store_fpr32(t, reg | 1);
1239 }
1240 }
1241
1242 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1243 {
1244 if (ctx->hflags & MIPS_HFLAG_F64) {
1245 tcg_gen_mov_i64(t, fpu_f64[reg]);
1246 } else {
1247 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1248 }
1249 }
1250
1251 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1252 {
1253 if (ctx->hflags & MIPS_HFLAG_F64) {
1254 tcg_gen_mov_i64(fpu_f64[reg], t);
1255 } else {
1256 TCGv_i64 t0;
1257 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1258 t0 = tcg_temp_new_i64();
1259 tcg_gen_shri_i64(t0, t, 32);
1260 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1261 tcg_temp_free_i64(t0);
1262 }
1263 }
1264
1265 static inline int get_fp_bit (int cc)
1266 {
1267 if (cc)
1268 return 24 + cc;
1269 else
1270 return 23;
1271 }
1272
1273 /* Tests */
1274 static inline void gen_save_pc(target_ulong pc)
1275 {
1276 tcg_gen_movi_tl(cpu_PC, pc);
1277 }
1278
1279 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1280 {
1281 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1282 if (do_save_pc && ctx->pc != ctx->saved_pc) {
1283 gen_save_pc(ctx->pc);
1284 ctx->saved_pc = ctx->pc;
1285 }
1286 if (ctx->hflags != ctx->saved_hflags) {
1287 tcg_gen_movi_i32(hflags, ctx->hflags);
1288 ctx->saved_hflags = ctx->hflags;
1289 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1290 case MIPS_HFLAG_BR:
1291 break;
1292 case MIPS_HFLAG_BC:
1293 case MIPS_HFLAG_BL:
1294 case MIPS_HFLAG_B:
1295 tcg_gen_movi_tl(btarget, ctx->btarget);
1296 break;
1297 }
1298 }
1299 }
1300
1301 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1302 {
1303 ctx->saved_hflags = ctx->hflags;
1304 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1305 case MIPS_HFLAG_BR:
1306 break;
1307 case MIPS_HFLAG_BC:
1308 case MIPS_HFLAG_BL:
1309 case MIPS_HFLAG_B:
1310 ctx->btarget = env->btarget;
1311 break;
1312 }
1313 }
1314
1315 static inline void
1316 generate_exception_err (DisasContext *ctx, int excp, int err)
1317 {
1318 TCGv_i32 texcp = tcg_const_i32(excp);
1319 TCGv_i32 terr = tcg_const_i32(err);
1320 save_cpu_state(ctx, 1);
1321 gen_helper_raise_exception_err(cpu_env, texcp, terr);
1322 tcg_temp_free_i32(terr);
1323 tcg_temp_free_i32(texcp);
1324 }
1325
1326 static inline void
1327 generate_exception (DisasContext *ctx, int excp)
1328 {
1329 save_cpu_state(ctx, 1);
1330 gen_helper_0e0i(raise_exception, excp);
1331 }
1332
1333 /* Addresses computation */
1334 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1335 {
1336 tcg_gen_add_tl(ret, arg0, arg1);
1337
1338 #if defined(TARGET_MIPS64)
1339 /* For compatibility with 32-bit code, data reference in user mode
1340 with Status_UX = 0 should be casted to 32-bit and sign extended.
1341 See the MIPS64 PRA manual, section 4.10. */
1342 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1343 !(ctx->hflags & MIPS_HFLAG_UX)) {
1344 tcg_gen_ext32s_i64(ret, ret);
1345 }
1346 #endif
1347 }
1348
1349 static inline void check_cp0_enabled(DisasContext *ctx)
1350 {
1351 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1352 generate_exception_err(ctx, EXCP_CpU, 0);
1353 }
1354
1355 static inline void check_cp1_enabled(DisasContext *ctx)
1356 {
1357 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1358 generate_exception_err(ctx, EXCP_CpU, 1);
1359 }
1360
1361 /* Verify that the processor is running with COP1X instructions enabled.
1362 This is associated with the nabla symbol in the MIPS32 and MIPS64
1363 opcode tables. */
1364
1365 static inline void check_cop1x(DisasContext *ctx)
1366 {
1367 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1368 generate_exception(ctx, EXCP_RI);
1369 }
1370
1371 /* Verify that the processor is running with 64-bit floating-point
1372 operations enabled. */
1373
1374 static inline void check_cp1_64bitmode(DisasContext *ctx)
1375 {
1376 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1377 generate_exception(ctx, EXCP_RI);
1378 }
1379
1380 /*
1381 * Verify if floating point register is valid; an operation is not defined
1382 * if bit 0 of any register specification is set and the FR bit in the
1383 * Status register equals zero, since the register numbers specify an
1384 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1385 * in the Status register equals one, both even and odd register numbers
1386 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1387 *
1388 * Multiple 64 bit wide registers can be checked by calling
1389 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1390 */
1391 static inline void check_cp1_registers(DisasContext *ctx, int regs)
1392 {
1393 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1394 generate_exception(ctx, EXCP_RI);
1395 }
1396
1397 /* Verify that the processor is running with DSP instructions enabled.
1398 This is enabled by CP0 Status register MX(24) bit.
1399 */
1400
1401 static inline void check_dsp(DisasContext *ctx)
1402 {
1403 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1404 if (ctx->insn_flags & ASE_DSP) {
1405 generate_exception(ctx, EXCP_DSPDIS);
1406 } else {
1407 generate_exception(ctx, EXCP_RI);
1408 }
1409 }
1410 }
1411
1412 static inline void check_dspr2(DisasContext *ctx)
1413 {
1414 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1415 if (ctx->insn_flags & ASE_DSP) {
1416 generate_exception(ctx, EXCP_DSPDIS);
1417 } else {
1418 generate_exception(ctx, EXCP_RI);
1419 }
1420 }
1421 }
1422
1423 /* This code generates a "reserved instruction" exception if the
1424 CPU does not support the instruction set corresponding to flags. */
1425 static inline void check_insn(DisasContext *ctx, int flags)
1426 {
1427 if (unlikely(!(ctx->insn_flags & flags))) {
1428 generate_exception(ctx, EXCP_RI);
1429 }
1430 }
1431
1432 /* This code generates a "reserved instruction" exception if 64-bit
1433 instructions are not enabled. */
1434 static inline void check_mips_64(DisasContext *ctx)
1435 {
1436 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1437 generate_exception(ctx, EXCP_RI);
1438 }
1439
1440 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1441 calling interface for 32 and 64-bit FPRs. No sense in changing
1442 all callers for gen_load_fpr32 when we need the CTX parameter for
1443 this one use. */
1444 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1445 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1446 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1447 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1448 int ft, int fs, int cc) \
1449 { \
1450 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1451 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1452 switch (ifmt) { \
1453 case FMT_PS: \
1454 check_cp1_64bitmode(ctx); \
1455 break; \
1456 case FMT_D: \
1457 if (abs) { \
1458 check_cop1x(ctx); \
1459 } \
1460 check_cp1_registers(ctx, fs | ft); \
1461 break; \
1462 case FMT_S: \
1463 if (abs) { \
1464 check_cop1x(ctx); \
1465 } \
1466 break; \
1467 } \
1468 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1469 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1470 switch (n) { \
1471 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1472 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1473 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1474 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1475 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1476 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1477 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1478 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1479 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1480 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1481 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1482 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1483 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1484 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1485 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1486 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1487 default: abort(); \
1488 } \
1489 tcg_temp_free_i##bits (fp0); \
1490 tcg_temp_free_i##bits (fp1); \
1491 }
1492
1493 FOP_CONDS(, 0, d, FMT_D, 64)
1494 FOP_CONDS(abs, 1, d, FMT_D, 64)
1495 FOP_CONDS(, 0, s, FMT_S, 32)
1496 FOP_CONDS(abs, 1, s, FMT_S, 32)
1497 FOP_CONDS(, 0, ps, FMT_PS, 64)
1498 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1499 #undef FOP_CONDS
1500 #undef gen_ldcmp_fpr32
1501 #undef gen_ldcmp_fpr64
1502
1503 /* load/store instructions. */
1504 #ifdef CONFIG_USER_ONLY
1505 #define OP_LD_ATOMIC(insn,fname) \
1506 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1507 { \
1508 TCGv t0 = tcg_temp_new(); \
1509 tcg_gen_mov_tl(t0, arg1); \
1510 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1511 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1512 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1513 tcg_temp_free(t0); \
1514 }
1515 #else
1516 #define OP_LD_ATOMIC(insn,fname) \
1517 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1518 { \
1519 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1520 }
1521 #endif
1522 OP_LD_ATOMIC(ll,ld32s);
1523 #if defined(TARGET_MIPS64)
1524 OP_LD_ATOMIC(lld,ld64);
1525 #endif
1526 #undef OP_LD_ATOMIC
1527
1528 #ifdef CONFIG_USER_ONLY
1529 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1530 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1531 { \
1532 TCGv t0 = tcg_temp_new(); \
1533 int l1 = gen_new_label(); \
1534 int l2 = gen_new_label(); \
1535 \
1536 tcg_gen_andi_tl(t0, arg2, almask); \
1537 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1538 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1539 generate_exception(ctx, EXCP_AdES); \
1540 gen_set_label(l1); \
1541 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1542 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1543 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1544 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1545 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1546 gen_helper_0e0i(raise_exception, EXCP_SC); \
1547 gen_set_label(l2); \
1548 tcg_gen_movi_tl(t0, 0); \
1549 gen_store_gpr(t0, rt); \
1550 tcg_temp_free(t0); \
1551 }
1552 #else
1553 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1554 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1555 { \
1556 TCGv t0 = tcg_temp_new(); \
1557 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1558 gen_store_gpr(t0, rt); \
1559 tcg_temp_free(t0); \
1560 }
1561 #endif
1562 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1563 #if defined(TARGET_MIPS64)
1564 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1565 #endif
1566 #undef OP_ST_ATOMIC
1567
1568 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1569 int base, int16_t offset)
1570 {
1571 if (base == 0) {
1572 tcg_gen_movi_tl(addr, offset);
1573 } else if (offset == 0) {
1574 gen_load_gpr(addr, base);
1575 } else {
1576 tcg_gen_movi_tl(addr, offset);
1577 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1578 }
1579 }
1580
1581 static target_ulong pc_relative_pc (DisasContext *ctx)
1582 {
1583 target_ulong pc = ctx->pc;
1584
1585 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1586 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1587
1588 pc -= branch_bytes;
1589 }
1590
1591 pc &= ~(target_ulong)3;
1592 return pc;
1593 }
1594
1595 /* Load */
1596 static void gen_ld(DisasContext *ctx, uint32_t opc,
1597 int rt, int base, int16_t offset)
1598 {
1599 const char *opn = "ld";
1600 TCGv t0, t1, t2;
1601
1602 if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1603 /* Loongson CPU uses a load to zero register for prefetch.
1604 We emulate it as a NOP. On other CPU we must perform the
1605 actual memory access. */
1606 MIPS_DEBUG("NOP");
1607 return;
1608 }
1609
1610 t0 = tcg_temp_new();
1611 gen_base_offset_addr(ctx, t0, base, offset);
1612
1613 switch (opc) {
1614 #if defined(TARGET_MIPS64)
1615 case OPC_LWU:
1616 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1617 gen_store_gpr(t0, rt);
1618 opn = "lwu";
1619 break;
1620 case OPC_LD:
1621 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1622 gen_store_gpr(t0, rt);
1623 opn = "ld";
1624 break;
1625 case OPC_LLD:
1626 save_cpu_state(ctx, 1);
1627 op_ld_lld(t0, t0, ctx);
1628 gen_store_gpr(t0, rt);
1629 opn = "lld";
1630 break;
1631 case OPC_LDL:
1632 t1 = tcg_temp_new();
1633 tcg_gen_andi_tl(t1, t0, 7);
1634 #ifndef TARGET_WORDS_BIGENDIAN
1635 tcg_gen_xori_tl(t1, t1, 7);
1636 #endif
1637 tcg_gen_shli_tl(t1, t1, 3);
1638 tcg_gen_andi_tl(t0, t0, ~7);
1639 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1640 tcg_gen_shl_tl(t0, t0, t1);
1641 tcg_gen_xori_tl(t1, t1, 63);
1642 t2 = tcg_const_tl(0x7fffffffffffffffull);
1643 tcg_gen_shr_tl(t2, t2, t1);
1644 gen_load_gpr(t1, rt);
1645 tcg_gen_and_tl(t1, t1, t2);
1646 tcg_temp_free(t2);
1647 tcg_gen_or_tl(t0, t0, t1);
1648 tcg_temp_free(t1);
1649 gen_store_gpr(t0, rt);
1650 opn = "ldl";
1651 break;
1652 case OPC_LDR:
1653 t1 = tcg_temp_new();
1654 tcg_gen_andi_tl(t1, t0, 7);
1655 #ifdef TARGET_WORDS_BIGENDIAN
1656 tcg_gen_xori_tl(t1, t1, 7);
1657 #endif
1658 tcg_gen_shli_tl(t1, t1, 3);
1659 tcg_gen_andi_tl(t0, t0, ~7);
1660 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1661 tcg_gen_shr_tl(t0, t0, t1);
1662 tcg_gen_xori_tl(t1, t1, 63);
1663 t2 = tcg_const_tl(0xfffffffffffffffeull);
1664 tcg_gen_shl_tl(t2, t2, t1);
1665 gen_load_gpr(t1, rt);
1666 tcg_gen_and_tl(t1, t1, t2);
1667 tcg_temp_free(t2);
1668 tcg_gen_or_tl(t0, t0, t1);
1669 tcg_temp_free(t1);
1670 gen_store_gpr(t0, rt);
1671 opn = "ldr";
1672 break;
1673 case OPC_LDPC:
1674 t1 = tcg_const_tl(pc_relative_pc(ctx));
1675 gen_op_addr_add(ctx, t0, t0, t1);
1676 tcg_temp_free(t1);
1677 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
1678 gen_store_gpr(t0, rt);
1679 opn = "ldpc";
1680 break;
1681 #endif
1682 case OPC_LWPC:
1683 t1 = tcg_const_tl(pc_relative_pc(ctx));
1684 gen_op_addr_add(ctx, t0, t0, t1);
1685 tcg_temp_free(t1);
1686 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1687 gen_store_gpr(t0, rt);
1688 opn = "lwpc";
1689 break;
1690 case OPC_LW:
1691 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
1692 gen_store_gpr(t0, rt);
1693 opn = "lw";
1694 break;
1695 case OPC_LH:
1696 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
1697 gen_store_gpr(t0, rt);
1698 opn = "lh";
1699 break;
1700 case OPC_LHU:
1701 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW);
1702 gen_store_gpr(t0, rt);
1703 opn = "lhu";
1704 break;
1705 case OPC_LB:
1706 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
1707 gen_store_gpr(t0, rt);
1708 opn = "lb";
1709 break;
1710 case OPC_LBU:
1711 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
1712 gen_store_gpr(t0, rt);
1713 opn = "lbu";
1714 break;
1715 case OPC_LWL:
1716 t1 = tcg_temp_new();
1717 tcg_gen_andi_tl(t1, t0, 3);
1718 #ifndef TARGET_WORDS_BIGENDIAN
1719 tcg_gen_xori_tl(t1, t1, 3);
1720 #endif
1721 tcg_gen_shli_tl(t1, t1, 3);
1722 tcg_gen_andi_tl(t0, t0, ~3);
1723 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1724 tcg_gen_shl_tl(t0, t0, t1);
1725 tcg_gen_xori_tl(t1, t1, 31);
1726 t2 = tcg_const_tl(0x7fffffffull);
1727 tcg_gen_shr_tl(t2, t2, t1);
1728 gen_load_gpr(t1, rt);
1729 tcg_gen_and_tl(t1, t1, t2);
1730 tcg_temp_free(t2);
1731 tcg_gen_or_tl(t0, t0, t1);
1732 tcg_temp_free(t1);
1733 tcg_gen_ext32s_tl(t0, t0);
1734 gen_store_gpr(t0, rt);
1735 opn = "lwl";
1736 break;
1737 case OPC_LWR:
1738 t1 = tcg_temp_new();
1739 tcg_gen_andi_tl(t1, t0, 3);
1740 #ifdef TARGET_WORDS_BIGENDIAN
1741 tcg_gen_xori_tl(t1, t1, 3);
1742 #endif
1743 tcg_gen_shli_tl(t1, t1, 3);
1744 tcg_gen_andi_tl(t0, t0, ~3);
1745 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
1746 tcg_gen_shr_tl(t0, t0, t1);
1747 tcg_gen_xori_tl(t1, t1, 31);
1748 t2 = tcg_const_tl(0xfffffffeull);
1749 tcg_gen_shl_tl(t2, t2, t1);
1750 gen_load_gpr(t1, rt);
1751 tcg_gen_and_tl(t1, t1, t2);
1752 tcg_temp_free(t2);
1753 tcg_gen_or_tl(t0, t0, t1);
1754 tcg_temp_free(t1);
1755 tcg_gen_ext32s_tl(t0, t0);
1756 gen_store_gpr(t0, rt);
1757 opn = "lwr";
1758 break;
1759 case OPC_LL:
1760 save_cpu_state(ctx, 1);
1761 op_ld_ll(t0, t0, ctx);
1762 gen_store_gpr(t0, rt);
1763 opn = "ll";
1764 break;
1765 }
1766 (void)opn; /* avoid a compiler warning */
1767 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1768 tcg_temp_free(t0);
1769 }
1770
1771 /* Store */
1772 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1773 int base, int16_t offset)
1774 {
1775 const char *opn = "st";
1776 TCGv t0 = tcg_temp_new();
1777 TCGv t1 = tcg_temp_new();
1778
1779 gen_base_offset_addr(ctx, t0, base, offset);
1780 gen_load_gpr(t1, rt);
1781 switch (opc) {
1782 #if defined(TARGET_MIPS64)
1783 case OPC_SD:
1784 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
1785 opn = "sd";
1786 break;
1787 case OPC_SDL:
1788 save_cpu_state(ctx, 1);
1789 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1790 opn = "sdl";
1791 break;
1792 case OPC_SDR:
1793 save_cpu_state(ctx, 1);
1794 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1795 opn = "sdr";
1796 break;
1797 #endif
1798 case OPC_SW:
1799 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
1800 opn = "sw";
1801 break;
1802 case OPC_SH:
1803 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW);
1804 opn = "sh";
1805 break;
1806 case OPC_SB:
1807 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
1808 opn = "sb";
1809 break;
1810 case OPC_SWL:
1811 save_cpu_state(ctx, 1);
1812 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1813 opn = "swl";
1814 break;
1815 case OPC_SWR:
1816 save_cpu_state(ctx, 1);
1817 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1818 opn = "swr";
1819 break;
1820 }
1821 (void)opn; /* avoid a compiler warning */
1822 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1823 tcg_temp_free(t0);
1824 tcg_temp_free(t1);
1825 }
1826
1827
1828 /* Store conditional */
1829 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1830 int base, int16_t offset)
1831 {
1832 const char *opn = "st_cond";
1833 TCGv t0, t1;
1834
1835 #ifdef CONFIG_USER_ONLY
1836 t0 = tcg_temp_local_new();
1837 t1 = tcg_temp_local_new();
1838 #else
1839 t0 = tcg_temp_new();
1840 t1 = tcg_temp_new();
1841 #endif
1842 gen_base_offset_addr(ctx, t0, base, offset);
1843 gen_load_gpr(t1, rt);
1844 switch (opc) {
1845 #if defined(TARGET_MIPS64)
1846 case OPC_SCD:
1847 save_cpu_state(ctx, 1);
1848 op_st_scd(t1, t0, rt, ctx);
1849 opn = "scd";
1850 break;
1851 #endif
1852 case OPC_SC:
1853 save_cpu_state(ctx, 1);
1854 op_st_sc(t1, t0, rt, ctx);
1855 opn = "sc";
1856 break;
1857 }
1858 (void)opn; /* avoid a compiler warning */
1859 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1860 tcg_temp_free(t1);
1861 tcg_temp_free(t0);
1862 }
1863
1864 /* Load and store */
1865 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1866 int base, int16_t offset)
1867 {
1868 const char *opn = "flt_ldst";
1869 TCGv t0 = tcg_temp_new();
1870
1871 gen_base_offset_addr(ctx, t0, base, offset);
1872 /* Don't do NOP if destination is zero: we must perform the actual
1873 memory access. */
1874 switch (opc) {
1875 case OPC_LWC1:
1876 {
1877 TCGv_i32 fp0 = tcg_temp_new_i32();
1878 tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL);
1879 gen_store_fpr32(fp0, ft);
1880 tcg_temp_free_i32(fp0);
1881 }
1882 opn = "lwc1";
1883 break;
1884 case OPC_SWC1:
1885 {
1886 TCGv_i32 fp0 = tcg_temp_new_i32();
1887 gen_load_fpr32(fp0, ft);
1888 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
1889 tcg_temp_free_i32(fp0);
1890 }
1891 opn = "swc1";
1892 break;
1893 case OPC_LDC1:
1894 {
1895 TCGv_i64 fp0 = tcg_temp_new_i64();
1896 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
1897 gen_store_fpr64(ctx, fp0, ft);
1898 tcg_temp_free_i64(fp0);
1899 }
1900 opn = "ldc1";
1901 break;
1902 case OPC_SDC1:
1903 {
1904 TCGv_i64 fp0 = tcg_temp_new_i64();
1905 gen_load_fpr64(ctx, fp0, ft);
1906 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
1907 tcg_temp_free_i64(fp0);
1908 }
1909 opn = "sdc1";
1910 break;
1911 default:
1912 MIPS_INVAL(opn);
1913 generate_exception(ctx, EXCP_RI);
1914 goto out;
1915 }
1916 (void)opn; /* avoid a compiler warning */
1917 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1918 out:
1919 tcg_temp_free(t0);
1920 }
1921
1922 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1923 uint32_t op, int rt, int rs, int16_t imm)
1924 {
1925 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1926 check_cp1_enabled(ctx);
1927 gen_flt_ldst(ctx, op, rt, rs, imm);
1928 } else {
1929 generate_exception_err(ctx, EXCP_CpU, 1);
1930 }
1931 }
1932
1933 /* Arithmetic with immediate operand */
1934 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1935 int rt, int rs, int16_t imm)
1936 {
1937 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1938 const char *opn = "imm arith";
1939
1940 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1941 /* If no destination, treat it as a NOP.
1942 For addi, we must generate the overflow exception when needed. */
1943 MIPS_DEBUG("NOP");
1944 return;
1945 }
1946 switch (opc) {
1947 case OPC_ADDI:
1948 {
1949 TCGv t0 = tcg_temp_local_new();
1950 TCGv t1 = tcg_temp_new();
1951 TCGv t2 = tcg_temp_new();
1952 int l1 = gen_new_label();
1953
1954 gen_load_gpr(t1, rs);
1955 tcg_gen_addi_tl(t0, t1, uimm);
1956 tcg_gen_ext32s_tl(t0, t0);
1957
1958 tcg_gen_xori_tl(t1, t1, ~uimm);
1959 tcg_gen_xori_tl(t2, t0, uimm);
1960 tcg_gen_and_tl(t1, t1, t2);
1961 tcg_temp_free(t2);
1962 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1963 tcg_temp_free(t1);
1964 /* operands of same sign, result different sign */
1965 generate_exception(ctx, EXCP_OVERFLOW);
1966 gen_set_label(l1);
1967 tcg_gen_ext32s_tl(t0, t0);
1968 gen_store_gpr(t0, rt);
1969 tcg_temp_free(t0);
1970 }
1971 opn = "addi";
1972 break;
1973 case OPC_ADDIU:
1974 if (rs != 0) {
1975 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1976 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1977 } else {
1978 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1979 }
1980 opn = "addiu";
1981 break;
1982 #if defined(TARGET_MIPS64)
1983 case OPC_DADDI:
1984 {
1985 TCGv t0 = tcg_temp_local_new();
1986 TCGv t1 = tcg_temp_new();
1987 TCGv t2 = tcg_temp_new();
1988 int l1 = gen_new_label();
1989
1990 gen_load_gpr(t1, rs);
1991 tcg_gen_addi_tl(t0, t1, uimm);
1992
1993 tcg_gen_xori_tl(t1, t1, ~uimm);
1994 tcg_gen_xori_tl(t2, t0, uimm);
1995 tcg_gen_and_tl(t1, t1, t2);
1996 tcg_temp_free(t2);
1997 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1998 tcg_temp_free(t1);
1999 /* operands of same sign, result different sign */
2000 generate_exception(ctx, EXCP_OVERFLOW);
2001 gen_set_label(l1);
2002 gen_store_gpr(t0, rt);
2003 tcg_temp_free(t0);
2004 }
2005 opn = "daddi";
2006 break;
2007 case OPC_DADDIU:
2008 if (rs != 0) {
2009 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2010 } else {
2011 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2012 }
2013 opn = "daddiu";
2014 break;
2015 #endif
2016 }
2017 (void)opn; /* avoid a compiler warning */
2018 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2019 }
2020
2021 /* Logic with immediate operand */
2022 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2023 int rt, int rs, int16_t imm)
2024 {
2025 target_ulong uimm;
2026
2027 if (rt == 0) {
2028 /* If no destination, treat it as a NOP. */
2029 MIPS_DEBUG("NOP");
2030 return;
2031 }
2032 uimm = (uint16_t)imm;
2033 switch (opc) {
2034 case OPC_ANDI:
2035 if (likely(rs != 0))
2036 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2037 else
2038 tcg_gen_movi_tl(cpu_gpr[rt], 0);
2039 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2040 regnames[rs], uimm);
2041 break;
2042 case OPC_ORI:
2043 if (rs != 0)
2044 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2045 else
2046 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2047 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2048 regnames[rs], uimm);
2049 break;
2050 case OPC_XORI:
2051 if (likely(rs != 0))
2052 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2053 else
2054 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2055 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2056 regnames[rs], uimm);
2057 break;
2058 case OPC_LUI:
2059 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2060 MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2061 break;
2062
2063 default:
2064 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2065 break;
2066 }
2067 }
2068
2069 /* Set on less than with immediate operand */
2070 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2071 int rt, int rs, int16_t imm)
2072 {
2073 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2074 const char *opn = "imm arith";
2075 TCGv t0;
2076
2077 if (rt == 0) {
2078 /* If no destination, treat it as a NOP. */
2079 MIPS_DEBUG("NOP");
2080 return;
2081 }
2082 t0 = tcg_temp_new();
2083 gen_load_gpr(t0, rs);
2084 switch (opc) {
2085 case OPC_SLTI:
2086 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2087 opn = "slti";
2088 break;
2089 case OPC_SLTIU:
2090 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2091 opn = "sltiu";
2092 break;
2093 }
2094 (void)opn; /* avoid a compiler warning */
2095 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2096 tcg_temp_free(t0);
2097 }
2098
2099 /* Shifts with immediate operand */
2100 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2101 int rt, int rs, int16_t imm)
2102 {
2103 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2104 const char *opn = "imm shift";
2105 TCGv t0;
2106
2107 if (rt == 0) {
2108 /* If no destination, treat it as a NOP. */
2109 MIPS_DEBUG("NOP");
2110 return;
2111 }
2112
2113 t0 = tcg_temp_new();
2114 gen_load_gpr(t0, rs);
2115 switch (opc) {
2116 case OPC_SLL:
2117 tcg_gen_shli_tl(t0, t0, uimm);
2118 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2119 opn = "sll";
2120 break;
2121 case OPC_SRA:
2122 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2123 opn = "sra";
2124 break;
2125 case OPC_SRL:
2126 if (uimm != 0) {
2127 tcg_gen_ext32u_tl(t0, t0);
2128 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2129 } else {
2130 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2131 }
2132 opn = "srl";
2133 break;
2134 case OPC_ROTR:
2135 if (uimm != 0) {
2136 TCGv_i32 t1 = tcg_temp_new_i32();
2137
2138 tcg_gen_trunc_tl_i32(t1, t0);
2139 tcg_gen_rotri_i32(t1, t1, uimm);
2140 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2141 tcg_temp_free_i32(t1);
2142 } else {
2143 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2144 }
2145 opn = "rotr";
2146 break;
2147 #if defined(TARGET_MIPS64)
2148 case OPC_DSLL:
2149 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2150 opn = "dsll";
2151 break;
2152 case OPC_DSRA:
2153 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2154 opn = "dsra";
2155 break;
2156 case OPC_DSRL:
2157 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2158 opn = "dsrl";
2159 break;
2160 case OPC_DROTR:
2161 if (uimm != 0) {
2162 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2163 } else {
2164 tcg_gen_mov_tl(cpu_gpr[rt], t0);
2165 }
2166 opn = "drotr";
2167 break;
2168 case OPC_DSLL32:
2169 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2170 opn = "dsll32";
2171 break;
2172 case OPC_DSRA32:
2173 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2174 opn = "dsra32";
2175 break;
2176 case OPC_DSRL32:
2177 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2178 opn = "dsrl32";
2179 break;
2180 case OPC_DROTR32:
2181 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2182 opn = "drotr32";
2183 break;
2184 #endif
2185 }
2186 (void)opn; /* avoid a compiler warning */
2187 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2188 tcg_temp_free(t0);
2189 }
2190
2191 /* Arithmetic */
2192 static void gen_arith(DisasContext *ctx, uint32_t opc,
2193 int rd, int rs, int rt)
2194 {
2195 const char *opn = "arith";
2196
2197 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2198 && opc != OPC_DADD && opc != OPC_DSUB) {
2199 /* If no destination, treat it as a NOP.
2200 For add & sub, we must generate the overflow exception when needed. */
2201 MIPS_DEBUG("NOP");
2202 return;
2203 }
2204
2205 switch (opc) {
2206 case OPC_ADD:
2207 {
2208 TCGv t0 = tcg_temp_local_new();
2209 TCGv t1 = tcg_temp_new();
2210 TCGv t2 = tcg_temp_new();
2211 int l1 = gen_new_label();
2212
2213 gen_load_gpr(t1, rs);
2214 gen_load_gpr(t2, rt);
2215 tcg_gen_add_tl(t0, t1, t2);
2216 tcg_gen_ext32s_tl(t0, t0);
2217 tcg_gen_xor_tl(t1, t1, t2);
2218 tcg_gen_xor_tl(t2, t0, t2);
2219 tcg_gen_andc_tl(t1, t2, t1);
2220 tcg_temp_free(t2);
2221 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2222 tcg_temp_free(t1);
2223 /* operands of same sign, result different sign */
2224 generate_exception(ctx, EXCP_OVERFLOW);
2225 gen_set_label(l1);
2226 gen_store_gpr(t0, rd);
2227 tcg_temp_free(t0);
2228 }
2229 opn = "add";
2230 break;
2231 case OPC_ADDU:
2232 if (rs != 0 && rt != 0) {
2233 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2234 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2235 } else if (rs == 0 && rt != 0) {
2236 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2237 } else if (rs != 0 && rt == 0) {
2238 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2239 } else {
2240 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2241 }
2242 opn = "addu";
2243 break;
2244 case OPC_SUB:
2245 {
2246 TCGv t0 = tcg_temp_local_new();
2247 TCGv t1 = tcg_temp_new();
2248 TCGv t2 = tcg_temp_new();
2249 int l1 = gen_new_label();
2250
2251 gen_load_gpr(t1, rs);
2252 gen_load_gpr(t2, rt);
2253 tcg_gen_sub_tl(t0, t1, t2);
2254 tcg_gen_ext32s_tl(t0, t0);
2255 tcg_gen_xor_tl(t2, t1, t2);
2256 tcg_gen_xor_tl(t1, t0, t1);
2257 tcg_gen_and_tl(t1, t1, t2);
2258 tcg_temp_free(t2);
2259 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2260 tcg_temp_free(t1);
2261 /* operands of different sign, first operand and result different sign */
2262 generate_exception(ctx, EXCP_OVERFLOW);
2263 gen_set_label(l1);
2264 gen_store_gpr(t0, rd);
2265 tcg_temp_free(t0);
2266 }
2267 opn = "sub";
2268 break;
2269 case OPC_SUBU:
2270 if (rs != 0 && rt != 0) {
2271 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2272 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2273 } else if (rs == 0 && rt != 0) {
2274 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2275 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2276 } else if (rs != 0 && rt == 0) {
2277 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2278 } else {
2279 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2280 }
2281 opn = "subu";
2282 break;
2283 #if defined(TARGET_MIPS64)
2284 case OPC_DADD:
2285 {
2286 TCGv t0 = tcg_temp_local_new();
2287 TCGv t1 = tcg_temp_new();
2288 TCGv t2 = tcg_temp_new();
2289 int l1 = gen_new_label();
2290
2291 gen_load_gpr(t1, rs);
2292 gen_load_gpr(t2, rt);
2293 tcg_gen_add_tl(t0, t1, t2);
2294 tcg_gen_xor_tl(t1, t1, t2);
2295 tcg_gen_xor_tl(t2, t0, t2);
2296 tcg_gen_andc_tl(t1, t2, t1);
2297 tcg_temp_free(t2);
2298 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2299 tcg_temp_free(t1);
2300 /* operands of same sign, result different sign */
2301 generate_exception(ctx, EXCP_OVERFLOW);
2302 gen_set_label(l1);
2303 gen_store_gpr(t0, rd);
2304 tcg_temp_free(t0);
2305 }
2306 opn = "dadd";
2307 break;
2308 case OPC_DADDU:
2309 if (rs != 0 && rt != 0) {
2310 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2311 } else if (rs == 0 && rt != 0) {
2312 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2313 } else if (rs != 0 && rt == 0) {
2314 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2315 } else {
2316 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2317 }
2318 opn = "daddu";
2319 break;
2320 case OPC_DSUB:
2321 {
2322 TCGv t0 = tcg_temp_local_new();
2323 TCGv t1 = tcg_temp_new();
2324 TCGv t2 = tcg_temp_new();
2325 int l1 = gen_new_label();
2326
2327 gen_load_gpr(t1, rs);
2328 gen_load_gpr(t2, rt);
2329 tcg_gen_sub_tl(t0, t1, t2);
2330 tcg_gen_xor_tl(t2, t1, t2);
2331 tcg_gen_xor_tl(t1, t0, t1);
2332 tcg_gen_and_tl(t1, t1, t2);
2333 tcg_temp_free(t2);
2334 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2335 tcg_temp_free(t1);
2336 /* operands of different sign, first operand and result different sign */
2337 generate_exception(ctx, EXCP_OVERFLOW);
2338 gen_set_label(l1);
2339 gen_store_gpr(t0, rd);
2340 tcg_temp_free(t0);
2341 }
2342 opn = "dsub";
2343 break;
2344 case OPC_DSUBU:
2345 if (rs != 0 && rt != 0) {
2346 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2347 } else if (rs == 0 && rt != 0) {
2348 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2349 } else if (rs != 0 && rt == 0) {
2350 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2351 } else {
2352 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2353 }
2354 opn = "dsubu";
2355 break;
2356 #endif
2357 case OPC_MUL:
2358 if (likely(rs != 0 && rt != 0)) {
2359 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2360 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2361 } else {
2362 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2363 }
2364 opn = "mul";
2365 break;
2366 }
2367 (void)opn; /* avoid a compiler warning */
2368 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2369 }
2370
2371 /* Conditional move */
2372 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2373 int rd, int rs, int rt)
2374 {
2375 const char *opn = "cond move";
2376 TCGv t0, t1, t2;
2377
2378 if (rd == 0) {
2379 /* If no destination, treat it as a NOP. */
2380 MIPS_DEBUG("NOP");
2381 return;
2382 }
2383
2384 t0 = tcg_temp_new();
2385 gen_load_gpr(t0, rt);
2386 t1 = tcg_const_tl(0);
2387 t2 = tcg_temp_new();
2388 gen_load_gpr(t2, rs);
2389 switch (opc) {
2390 case OPC_MOVN:
2391 tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2392 opn = "movn";
2393 break;
2394 case OPC_MOVZ:
2395 tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2396 opn = "movz";
2397 break;
2398 }
2399 tcg_temp_free(t2);
2400 tcg_temp_free(t1);
2401 tcg_temp_free(t0);
2402
2403 (void)opn; /* avoid a compiler warning */
2404 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2405 }
2406
2407 /* Logic */
2408 static void gen_logic(DisasContext *ctx, uint32_t opc,
2409 int rd, int rs, int rt)
2410 {
2411 const char *opn = "logic";
2412
2413 if (rd == 0) {
2414 /* If no destination, treat it as a NOP. */
2415 MIPS_DEBUG("NOP");
2416 return;
2417 }
2418
2419 switch (opc) {
2420 case OPC_AND:
2421 if (likely(rs != 0 && rt != 0)) {
2422 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2423 } else {
2424 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2425 }
2426 opn = "and";
2427 break;
2428 case OPC_NOR:
2429 if (rs != 0 && rt != 0) {
2430 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2431 } else if (rs == 0 && rt != 0) {
2432 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2433 } else if (rs != 0 && rt == 0) {
2434 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2435 } else {
2436 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2437 }
2438 opn = "nor";
2439 break;
2440 case OPC_OR:
2441 if (likely(rs != 0 && rt != 0)) {
2442 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2443 } else if (rs == 0 && rt != 0) {
2444 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2445 } else if (rs != 0 && rt == 0) {
2446 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2447 } else {
2448 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2449 }
2450 opn = "or";
2451 break;
2452 case OPC_XOR:
2453 if (likely(rs != 0 && rt != 0)) {
2454 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2455 } else if (rs == 0 && rt != 0) {
2456 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2457 } else if (rs != 0 && rt == 0) {
2458 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2459 } else {
2460 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2461 }
2462 opn = "xor";
2463 break;
2464 }
2465 (void)opn; /* avoid a compiler warning */
2466 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2467 }
2468
2469 /* Set on lower than */
2470 static void gen_slt(DisasContext *ctx, uint32_t opc,
2471 int rd, int rs, int rt)
2472 {
2473 const char *opn = "slt";
2474 TCGv t0, t1;
2475
2476 if (rd == 0) {
2477 /* If no destination, treat it as a NOP. */
2478 MIPS_DEBUG("NOP");
2479 return;
2480 }
2481
2482 t0 = tcg_temp_new();
2483 t1 = tcg_temp_new();
2484 gen_load_gpr(t0, rs);
2485 gen_load_gpr(t1, rt);
2486 switch (opc) {
2487 case OPC_SLT:
2488 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2489 opn = "slt";
2490 break;
2491 case OPC_SLTU:
2492 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2493 opn = "sltu";
2494 break;
2495 }
2496 (void)opn; /* avoid a compiler warning */
2497 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2498 tcg_temp_free(t0);
2499 tcg_temp_free(t1);
2500 }
2501
2502 /* Shifts */
2503 static void gen_shift(DisasContext *ctx, uint32_t opc,
2504 int rd, int rs, int rt)
2505 {
2506 const char *opn = "shifts";
2507 TCGv t0, t1;
2508
2509 if (rd == 0) {
2510 /* If no destination, treat it as a NOP.
2511 For add & sub, we must generate the overflow exception when needed. */
2512 MIPS_DEBUG("NOP");
2513 return;
2514 }
2515
2516 t0 = tcg_temp_new();
2517 t1 = tcg_temp_new();
2518 gen_load_gpr(t0, rs);
2519 gen_load_gpr(t1, rt);
2520 switch (opc) {
2521 case OPC_SLLV:
2522 tcg_gen_andi_tl(t0, t0, 0x1f);
2523 tcg_gen_shl_tl(t0, t1, t0);
2524 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2525 opn = "sllv";
2526 break;
2527 case OPC_SRAV:
2528 tcg_gen_andi_tl(t0, t0, 0x1f);
2529 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2530 opn = "srav";
2531 break;
2532 case OPC_SRLV:
2533 tcg_gen_ext32u_tl(t1, t1);
2534 tcg_gen_andi_tl(t0, t0, 0x1f);
2535 tcg_gen_shr_tl(t0, t1, t0);
2536 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2537 opn = "srlv";
2538 break;
2539 case OPC_ROTRV:
2540 {
2541 TCGv_i32 t2 = tcg_temp_new_i32();
2542 TCGv_i32 t3 = tcg_temp_new_i32();
2543
2544 tcg_gen_trunc_tl_i32(t2, t0);
2545 tcg_gen_trunc_tl_i32(t3, t1);
2546 tcg_gen_andi_i32(t2, t2, 0x1f);
2547 tcg_gen_rotr_i32(t2, t3, t2);
2548 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2549 tcg_temp_free_i32(t2);
2550 tcg_temp_free_i32(t3);
2551 opn = "rotrv";
2552 }
2553 break;
2554 #if defined(TARGET_MIPS64)
2555 case OPC_DSLLV:
2556 tcg_gen_andi_tl(t0, t0, 0x3f);
2557 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2558 opn = "dsllv";
2559 break;
2560 case OPC_DSRAV:
2561 tcg_gen_andi_tl(t0, t0, 0x3f);
2562 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2563 opn = "dsrav";
2564 break;
2565 case OPC_DSRLV:
2566 tcg_gen_andi_tl(t0, t0, 0x3f);
2567 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2568 opn = "dsrlv";
2569 break;
2570 case OPC_DROTRV:
2571 tcg_gen_andi_tl(t0, t0, 0x3f);
2572 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2573 opn = "drotrv";
2574 break;
2575 #endif
2576 }
2577 (void)opn; /* avoid a compiler warning */
2578 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2579 tcg_temp_free(t0);
2580 tcg_temp_free(t1);
2581 }
2582
2583 /* Arithmetic on HI/LO registers */
2584 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2585 {
2586 const char *opn = "hilo";
2587
2588 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2589 /* Treat as NOP. */
2590 MIPS_DEBUG("NOP");
2591 return;
2592 }
2593
2594 if (acc != 0) {
2595 check_dsp(ctx);
2596 }
2597
2598 switch (opc) {
2599 case OPC_MFHI:
2600 #if defined(TARGET_MIPS64)
2601 if (acc != 0) {
2602 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2603 } else
2604 #endif
2605 {
2606 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2607 }
2608 opn = "mfhi";
2609 break;
2610 case OPC_MFLO:
2611 #if defined(TARGET_MIPS64)
2612 if (acc != 0) {
2613 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2614 } else
2615 #endif
2616 {
2617 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2618 }
2619 opn = "mflo";
2620 break;
2621 case OPC_MTHI:
2622 if (reg != 0) {
2623 #if defined(TARGET_MIPS64)
2624 if (acc != 0) {
2625 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2626 } else
2627 #endif
2628 {
2629 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2630 }
2631 } else {
2632 tcg_gen_movi_tl(cpu_HI[acc], 0);
2633 }
2634 opn = "mthi";
2635 break;
2636 case OPC_MTLO:
2637 if (reg != 0) {
2638 #if defined(TARGET_MIPS64)
2639 if (acc != 0) {
2640 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2641 } else
2642 #endif
2643 {
2644 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2645 }
2646 } else {
2647 tcg_gen_movi_tl(cpu_LO[acc], 0);
2648 }
2649 opn = "mtlo";
2650 break;
2651 }
2652 (void)opn; /* avoid a compiler warning */
2653 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2654 }
2655
2656 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2657 int acc, int rs, int rt)
2658 {
2659 const char *opn = "mul/div";
2660 TCGv t0, t1;
2661
2662 t0 = tcg_temp_new();
2663 t1 = tcg_temp_new();
2664
2665 gen_load_gpr(t0, rs);
2666 gen_load_gpr(t1, rt);
2667
2668 if (acc != 0) {
2669 check_dsp(ctx);
2670 }
2671
2672 switch (opc) {
2673 case OPC_DIV:
2674 {
2675 TCGv t2 = tcg_temp_new();
2676 TCGv t3 = tcg_temp_new();
2677 tcg_gen_ext32s_tl(t0, t0);
2678 tcg_gen_ext32s_tl(t1, t1);
2679 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2680 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2681 tcg_gen_and_tl(t2, t2, t3);
2682 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2683 tcg_gen_or_tl(t2, t2, t3);
2684 tcg_gen_movi_tl(t3, 0);
2685 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2686 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2687 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2688 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2689 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2690 tcg_temp_free(t3);
2691 tcg_temp_free(t2);
2692 }
2693 opn = "div";
2694 break;
2695 case OPC_DIVU:
2696 {
2697 TCGv t2 = tcg_const_tl(0);
2698 TCGv t3 = tcg_const_tl(1);
2699 tcg_gen_ext32u_tl(t0, t0);
2700 tcg_gen_ext32u_tl(t1, t1);
2701 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2702 tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2703 tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2704 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2705 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2706 tcg_temp_free(t3);
2707 tcg_temp_free(t2);
2708 }
2709 opn = "divu";
2710 break;
2711 case OPC_MULT:
2712 {
2713 TCGv_i32 t2 = tcg_temp_new_i32();
2714 TCGv_i32 t3 = tcg_temp_new_i32();
2715 tcg_gen_trunc_tl_i32(t2, t0);
2716 tcg_gen_trunc_tl_i32(t3, t1);
2717 tcg_gen_muls2_i32(t2, t3, t2, t3);
2718 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2719 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2720 tcg_temp_free_i32(t2);
2721 tcg_temp_free_i32(t3);
2722 }
2723 opn = "mult";
2724 break;
2725 case OPC_MULTU:
2726 {
2727 TCGv_i32 t2 = tcg_temp_new_i32();
2728 TCGv_i32 t3 = tcg_temp_new_i32();
2729 tcg_gen_trunc_tl_i32(t2, t0);
2730 tcg_gen_trunc_tl_i32(t3, t1);
2731 tcg_gen_mulu2_i32(t2, t3, t2, t3);
2732 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2733 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2734 tcg_temp_free_i32(t2);
2735 tcg_temp_free_i32(t3);
2736 }
2737 opn = "multu";
2738 break;
2739 #if defined(TARGET_MIPS64)
2740 case OPC_DDIV:
2741 {
2742 TCGv t2 = tcg_temp_new();
2743 TCGv t3 = tcg_temp_new();
2744 tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2745 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2746 tcg_gen_and_tl(t2, t2, t3);
2747 tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2748 tcg_gen_or_tl(t2, t2, t3);
2749 tcg_gen_movi_tl(t3, 0);
2750 tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2751 tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2752 tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2753 tcg_temp_free(t3);
2754 tcg_temp_free(t2);
2755 }
2756 opn = "ddiv";
2757 break;
2758 case OPC_DDIVU:
2759 {
2760 TCGv t2 = tcg_const_tl(0);
2761 TCGv t3 = tcg_const_tl(1);
2762 tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2763 tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2764 tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
2765 tcg_temp_free(t3);
2766 tcg_temp_free(t2);
2767 }
2768 opn = "ddivu";
2769 break;
2770 case OPC_DMULT:
2771 tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2772 opn = "dmult";
2773 break;
2774 case OPC_DMULTU:
2775 tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2776 opn = "dmultu";
2777 break;
2778 #endif
2779 case OPC_MADD:
2780 {
2781 TCGv_i64 t2 = tcg_temp_new_i64();
2782 TCGv_i64 t3 = tcg_temp_new_i64();
2783
2784 tcg_gen_ext_tl_i64(t2, t0);
2785 tcg_gen_ext_tl_i64(t3, t1);
2786 tcg_gen_mul_i64(t2, t2, t3);
2787 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2788 tcg_gen_add_i64(t2, t2, t3);
2789 tcg_temp_free_i64(t3);
2790 tcg_gen_trunc_i64_tl(t0, t2);
2791 tcg_gen_shri_i64(t2, t2, 32);
2792 tcg_gen_trunc_i64_tl(t1, t2);
2793 tcg_temp_free_i64(t2);
2794 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2795 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2796 }
2797 opn = "madd";
2798 break;
2799 case OPC_MADDU:
2800 {
2801 TCGv_i64 t2 = tcg_temp_new_i64();
2802 TCGv_i64 t3 = tcg_temp_new_i64();
2803
2804 tcg_gen_ext32u_tl(t0, t0);
2805 tcg_gen_ext32u_tl(t1, t1);
2806 tcg_gen_extu_tl_i64(t2, t0);
2807 tcg_gen_extu_tl_i64(t3, t1);
2808 tcg_gen_mul_i64(t2, t2, t3);
2809 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2810 tcg_gen_add_i64(t2, t2, t3);
2811 tcg_temp_free_i64(t3);
2812 tcg_gen_trunc_i64_tl(t0, t2);
2813 tcg_gen_shri_i64(t2, t2, 32);
2814 tcg_gen_trunc_i64_tl(t1, t2);
2815 tcg_temp_free_i64(t2);
2816 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2817 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2818 }
2819 opn = "maddu";
2820 break;
2821 case OPC_MSUB:
2822 {
2823 TCGv_i64 t2 = tcg_temp_new_i64();
2824 TCGv_i64 t3 = tcg_temp_new_i64();
2825
2826 tcg_gen_ext_tl_i64(t2, t0);
2827 tcg_gen_ext_tl_i64(t3, t1);
2828 tcg_gen_mul_i64(t2, t2, t3);
2829 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2830 tcg_gen_sub_i64(t2, t3, t2);
2831 tcg_temp_free_i64(t3);
2832 tcg_gen_trunc_i64_tl(t0, t2);
2833 tcg_gen_shri_i64(t2, t2, 32);
2834 tcg_gen_trunc_i64_tl(t1, t2);
2835 tcg_temp_free_i64(t2);
2836 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2837 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2838 }
2839 opn = "msub";
2840 break;
2841 case OPC_MSUBU:
2842 {
2843 TCGv_i64 t2 = tcg_temp_new_i64();
2844 TCGv_i64 t3 = tcg_temp_new_i64();
2845
2846 tcg_gen_ext32u_tl(t0, t0);
2847 tcg_gen_ext32u_tl(t1, t1);
2848 tcg_gen_extu_tl_i64(t2, t0);
2849 tcg_gen_extu_tl_i64(t3, t1);
2850 tcg_gen_mul_i64(t2, t2, t3);
2851 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2852 tcg_gen_sub_i64(t2, t3, t2);
2853 tcg_temp_free_i64(t3);
2854 tcg_gen_trunc_i64_tl(t0, t2);
2855 tcg_gen_shri_i64(t2, t2, 32);
2856 tcg_gen_trunc_i64_tl(t1, t2);
2857 tcg_temp_free_i64(t2);
2858 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2859 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2860 }
2861 opn = "msubu";
2862 break;
2863 default:
2864 MIPS_INVAL(opn);
2865 generate_exception(ctx, EXCP_RI);
2866 goto out;
2867 }
2868 (void)opn; /* avoid a compiler warning */
2869 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2870 out:
2871 tcg_temp_free(t0);
2872 tcg_temp_free(t1);
2873 }
2874
2875 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2876 int rd, int rs, int rt)
2877 {
2878 const char *opn = "mul vr54xx";
2879 TCGv t0 = tcg_temp_new();
2880 TCGv t1 = tcg_temp_new();
2881
2882 gen_load_gpr(t0, rs);
2883 gen_load_gpr(t1, rt);
2884
2885 switch (opc) {
2886 case OPC_VR54XX_MULS:
2887 gen_helper_muls(t0, cpu_env, t0, t1);
2888 opn = "muls";
2889 break;
2890 case OPC_VR54XX_MULSU:
2891 gen_helper_mulsu(t0, cpu_env, t0, t1);
2892 opn = "mulsu";
2893 break;
2894 case OPC_VR54XX_MACC:
2895 gen_helper_macc(t0, cpu_env, t0, t1);
2896 opn = "macc";
2897 break;
2898 case OPC_VR54XX_MACCU:
2899 gen_helper_maccu(t0, cpu_env, t0, t1);
2900 opn = "maccu";
2901 break;
2902 case OPC_VR54XX_MSAC:
2903 gen_helper_msac(t0, cpu_env, t0, t1);
2904 opn = "msac";
2905 break;
2906 case OPC_VR54XX_MSACU:
2907 gen_helper_msacu(t0, cpu_env, t0, t1);
2908 opn = "msacu";
2909 break;
2910 case OPC_VR54XX_MULHI:
2911 gen_helper_mulhi(t0, cpu_env, t0, t1);
2912 opn = "mulhi";
2913 break;
2914 case OPC_VR54XX_MULHIU:
2915 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2916 opn = "mulhiu";
2917 break;
2918 case OPC_VR54XX_MULSHI:
2919 gen_helper_mulshi(t0, cpu_env, t0, t1);
2920 opn = "mulshi";
2921 break;
2922 case OPC_VR54XX_MULSHIU:
2923 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2924 opn = "mulshiu";
2925 break;
2926 case OPC_VR54XX_MACCHI:
2927 gen_helper_macchi(t0, cpu_env, t0, t1);
2928 opn = "macchi";
2929 break;
2930 case OPC_VR54XX_MACCHIU:
2931 gen_helper_macchiu(t0, cpu_env, t0, t1);
2932 opn = "macchiu";
2933 break;
2934 case OPC_VR54XX_MSACHI:
2935 gen_helper_msachi(t0, cpu_env, t0, t1);
2936 opn = "msachi";
2937 break;
2938 case OPC_VR54XX_MSACHIU:
2939 gen_helper_msachiu(t0, cpu_env, t0, t1);
2940 opn = "msachiu";
2941 break;
2942 default:
2943 MIPS_INVAL("mul vr54xx");
2944 generate_exception(ctx, EXCP_RI);
2945 goto out;
2946 }
2947 gen_store_gpr(t0, rd);
2948 (void)opn; /* avoid a compiler warning */
2949 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2950
2951 out:
2952 tcg_temp_free(t0);
2953 tcg_temp_free(t1);
2954 }
2955
2956 static void gen_cl (DisasContext *ctx, uint32_t opc,
2957 int rd, int rs)
2958 {
2959 const char *opn = "CLx";
2960 TCGv t0;
2961
2962 if (rd == 0) {
2963 /* Treat as NOP. */
2964 MIPS_DEBUG("NOP");
2965 return;
2966 }
2967 t0 = tcg_temp_new();
2968 gen_load_gpr(t0, rs);
2969 switch (opc) {
2970 case OPC_CLO:
2971 gen_helper_clo(cpu_gpr[rd], t0);
2972 opn = "clo";
2973 break;
2974 case OPC_CLZ:
2975 gen_helper_clz(cpu_gpr[rd], t0);
2976 opn = "clz";
2977 break;
2978 #if defined(TARGET_MIPS64)
2979 case OPC_DCLO:
2980 gen_helper_dclo(cpu_gpr[rd], t0);
2981 opn = "dclo";
2982 break;
2983 case OPC_DCLZ:
2984 gen_helper_dclz(cpu_gpr[rd], t0);
2985 opn = "dclz";
2986 break;
2987 #endif
2988 }
2989 (void)opn; /* avoid a compiler warning */
2990 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2991 tcg_temp_free(t0);
2992 }
2993
2994 /* Godson integer instructions */
2995 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2996 int rd, int rs, int rt)
2997 {
2998 const char *opn = "loongson";
2999 TCGv t0, t1;
3000
3001 if (rd == 0) {
3002 /* Treat as NOP. */
3003 MIPS_DEBUG("NOP");
3004 return;
3005 }
3006
3007 switch (opc) {
3008 case OPC_MULT_G_2E:
3009 case OPC_MULT_G_2F:
3010 case OPC_MULTU_G_2E:
3011 case OPC_MULTU_G_2F:
3012 #if defined(TARGET_MIPS64)
3013 case OPC_DMULT_G_2E:
3014 case OPC_DMULT_G_2F:
3015 case OPC_DMULTU_G_2E:
3016 case OPC_DMULTU_G_2F:
3017 #endif
3018 t0 = tcg_temp_new();
3019 t1 = tcg_temp_new();
3020 break;
3021 default:
3022 t0 = tcg_temp_local_new();
3023 t1 = tcg_temp_local_new();
3024 break;
3025 }
3026
3027 gen_load_gpr(t0, rs);
3028 gen_load_gpr(t1, rt);
3029
3030 switch (opc) {
3031 case OPC_MULT_G_2E:
3032 case OPC_MULT_G_2F:
3033 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3034 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3035 opn = "mult.g";
3036 break;
3037 case OPC_MULTU_G_2E:
3038 case OPC_MULTU_G_2F:
3039 tcg_gen_ext32u_tl(t0, t0);
3040 tcg_gen_ext32u_tl(t1, t1);
3041 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3042 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3043 opn = "multu.g";
3044 break;
3045 case OPC_DIV_G_2E:
3046 case OPC_DIV_G_2F:
3047 {
3048 int l1 = gen_new_label();
3049 int l2 = gen_new_label();
3050 int l3 = gen_new_label();
3051 tcg_gen_ext32s_tl(t0, t0);
3052 tcg_gen_ext32s_tl(t1, t1);
3053 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3054 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3055 tcg_gen_br(l3);
3056 gen_set_label(l1);
3057 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3058 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3059 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3060 tcg_gen_br(l3);
3061 gen_set_label(l2);
3062 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3063 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3064 gen_set_label(l3);
3065 }
3066 opn = "div.g";
3067 break;
3068 case OPC_DIVU_G_2E:
3069 case OPC_DIVU_G_2F:
3070 {
3071 int l1 = gen_new_label();
3072 int l2 = gen_new_label();
3073 tcg_gen_ext32u_tl(t0, t0);
3074 tcg_gen_ext32u_tl(t1, t1);
3075 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3076 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3077 tcg_gen_br(l2);
3078 gen_set_label(l1);
3079 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3080 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3081 gen_set_label(l2);
3082 }
3083 opn = "divu.g";
3084 break;
3085 case OPC_MOD_G_2E:
3086 case OPC_MOD_G_2F:
3087 {
3088 int l1 = gen_new_label();
3089 int l2 = gen_new_label();
3090 int l3 = gen_new_label();
3091 tcg_gen_ext32u_tl(t0, t0);
3092 tcg_gen_ext32u_tl(t1, t1);
3093 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3094 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3095 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3096 gen_set_label(l1);
3097 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3098 tcg_gen_br(l3);
3099 gen_set_label(l2);
3100 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3101 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3102 gen_set_label(l3);
3103 }
3104 opn = "mod.g";
3105 break;
3106 case OPC_MODU_G_2E:
3107 case OPC_MODU_G_2F:
3108 {
3109 int l1 = gen_new_label();
3110 int l2 = gen_new_label();
3111 tcg_gen_ext32u_tl(t0, t0);
3112 tcg_gen_ext32u_tl(t1, t1);
3113 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3114 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3115 tcg_gen_br(l2);
3116 gen_set_label(l1);
3117 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3118 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3119 gen_set_label(l2);
3120 }
3121 opn = "modu.g";
3122 break;
3123 #if defined(TARGET_MIPS64)
3124 case OPC_DMULT_G_2E:
3125 case OPC_DMULT_G_2F:
3126 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3127 opn = "dmult.g";
3128 break;
3129 case OPC_DMULTU_G_2E:
3130 case OPC_DMULTU_G_2F:
3131 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3132 opn = "dmultu.g";
3133 break;
3134 case OPC_DDIV_G_2E:
3135 case OPC_DDIV_G_2F:
3136 {
3137 int l1 = gen_new_label();
3138 int l2 = gen_new_label();
3139 int l3 = gen_new_label();
3140 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3141 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3142 tcg_gen_br(l3);
3143 gen_set_label(l1);
3144 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3145 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3146 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3147 tcg_gen_br(l3);
3148 gen_set_label(l2);
3149 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3150 gen_set_label(l3);
3151 }
3152 opn = "ddiv.g";
3153 break;
3154 case OPC_DDIVU_G_2E:
3155 case OPC_DDIVU_G_2F:
3156 {
3157 int l1 = gen_new_label();
3158 int l2 = gen_new_label();
3159 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3160 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3161 tcg_gen_br(l2);
3162 gen_set_label(l1);
3163 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3164 gen_set_label(l2);
3165 }
3166 opn = "ddivu.g";
3167 break;
3168 case OPC_DMOD_G_2E:
3169 case OPC_DMOD_G_2F:
3170 {
3171 int l1 = gen_new_label();
3172 int l2 = gen_new_label();
3173 int l3 = gen_new_label();
3174 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3175 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3176 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3177 gen_set_label(l1);
3178 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3179 tcg_gen_br(l3);
3180 gen_set_label(l2);
3181 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3182 gen_set_label(l3);
3183 }
3184 opn = "dmod.g";
3185 break;
3186 case OPC_DMODU_G_2E:
3187 case OPC_DMODU_G_2F:
3188 {
3189 int l1 = gen_new_label();
3190 int l2 = gen_new_label();
3191 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3192 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3193 tcg_gen_br(l2);
3194 gen_set_label(l1);
3195 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3196 gen_set_label(l2);
3197 }
3198 opn = "dmodu.g";
3199 break;
3200 #endif
3201 }
3202
3203 (void)opn; /* avoid a compiler warning */
3204 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3205 tcg_temp_free(t0);
3206 tcg_temp_free(t1);
3207 }
3208
3209 /* Loongson multimedia instructions */
3210 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3211 {
3212 const char *opn = "loongson_cp2";
3213 uint32_t opc, shift_max;
3214 TCGv_i64 t0, t1;
3215
3216 opc = MASK_LMI(ctx->opcode);
3217 switch (opc) {
3218 case OPC_ADD_CP2:
3219 case OPC_SUB_CP2:
3220 case OPC_DADD_CP2:
3221 case OPC_DSUB_CP2:
3222 t0 = tcg_temp_local_new_i64();
3223 t1 = tcg_temp_local_new_i64();
3224 break;
3225 default:
3226 t0 = tcg_temp_new_i64();
3227 t1 = tcg_temp_new_i64();
3228 break;
3229 }
3230
3231 gen_load_fpr64(ctx, t0, rs);
3232 gen_load_fpr64(ctx, t1, rt);
3233
3234 #define LMI_HELPER(UP, LO) \
3235 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3236 #define LMI_HELPER_1(UP, LO) \
3237 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3238 #define LMI_DIRECT(UP, LO, OP) \
3239 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3240
3241 switch (opc) {
3242 LMI_HELPER(PADDSH, paddsh);
3243 LMI_HELPER(PADDUSH, paddush);
3244 LMI_HELPER(PADDH, paddh);
3245 LMI_HELPER(PADDW, paddw);
3246 LMI_HELPER(PADDSB, paddsb);
3247 LMI_HELPER(PADDUSB, paddusb);
3248 LMI_HELPER(PADDB, paddb);
3249
3250 LMI_HELPER(PSUBSH, psubsh);
3251 LMI_HELPER(PSUBUSH, psubush);
3252 LMI_HELPER(PSUBH, psubh);
3253 LMI_HELPER(PSUBW, psubw);
3254 LMI_HELPER(PSUBSB, psubsb);
3255 LMI_HELPER(PSUBUSB, psubusb);
3256 LMI_HELPER(PSUBB, psubb);
3257
3258 LMI_HELPER(PSHUFH, pshufh);
3259 LMI_HELPER(PACKSSWH, packsswh);
3260 LMI_HELPER(PACKSSHB, packsshb);
3261 LMI_HELPER(PACKUSHB, packushb);
3262
3263 LMI_HELPER(PUNPCKLHW, punpcklhw);
3264 LMI_HELPER(PUNPCKHHW, punpckhhw);
3265 LMI_HELPER(PUNPCKLBH, punpcklbh);
3266 LMI_HELPER(PUNPCKHBH, punpckhbh);
3267 LMI_HELPER(PUNPCKLWD, punpcklwd);
3268 LMI_HELPER(PUNPCKHWD, punpckhwd);
3269
3270 LMI_HELPER(PAVGH, pavgh);
3271 LMI_HELPER(PAVGB, pavgb);
3272 LMI_HELPER(PMAXSH, pmaxsh);
3273 LMI_HELPER(PMINSH, pminsh);
3274 LMI_HELPER(PMAXUB, pmaxub);
3275 LMI_HELPER(PMINUB, pminub);
3276
3277 LMI_HELPER(PCMPEQW, pcmpeqw);
3278 LMI_HELPER(PCMPGTW, pcmpgtw);
3279 LMI_HELPER(PCMPEQH, pcmpeqh);
3280 LMI_HELPER(PCMPGTH, pcmpgth);
3281 LMI_HELPER(PCMPEQB, pcmpeqb);
3282 LMI_HELPER(PCMPGTB, pcmpgtb);
3283
3284 LMI_HELPER(PSLLW, psllw);
3285 LMI_HELPER(PSLLH, psllh);
3286 LMI_HELPER(PSRLW, psrlw);
3287 LMI_HELPER(PSRLH, psrlh);
3288 LMI_HELPER(PSRAW, psraw);
3289 LMI_HELPER(PSRAH, psrah);
3290
3291 LMI_HELPER(PMULLH, pmullh);
3292 LMI_HELPER(PMULHH, pmulhh);
3293 LMI_HELPER(PMULHUH, pmulhuh);
3294 LMI_HELPER(PMADDHW, pmaddhw);
3295
3296 LMI_HELPER(PASUBUB, pasubub);
3297 LMI_HELPER_1(BIADD, biadd);
3298 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3299
3300 LMI_DIRECT(PADDD, paddd, add);
3301 LMI_DIRECT(PSUBD, psubd, sub);
3302 LMI_DIRECT(XOR_CP2, xor, xor);
3303 LMI_DIRECT(NOR_CP2, nor, nor);
3304 LMI_DIRECT(AND_CP2, and, and);
3305 LMI_DIRECT(PANDN, pandn, andc);
3306 LMI_DIRECT(OR, or, or);
3307
3308 case OPC_PINSRH_0:
3309 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3310 opn = "pinsrh_0";
3311 break;
3312 case OPC_PINSRH_1:
3313 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3314 opn = "pinsrh_1";
3315 break;
3316 case OPC_PINSRH_2:
3317 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3318 opn = "pinsrh_2";
3319 break;
3320 case OPC_PINSRH_3:
3321 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3322 opn = "pinsrh_3";
3323 break;
3324
3325 case OPC_PEXTRH:
3326 tcg_gen_andi_i64(t1, t1, 3);
3327 tcg_gen_shli_i64(t1, t1, 4);
3328 tcg_gen_shr_i64(t0, t0, t1);
3329 tcg_gen_ext16u_i64(t0, t0);
3330 opn = "pextrh";
3331 break;
3332
3333 case OPC_ADDU_CP2:
3334 tcg_gen_add_i64(t0, t0, t1);
3335 tcg_gen_ext32s_i64(t0, t0);
3336 opn = "addu";
3337 break;
3338 case OPC_SUBU_CP2:
3339 tcg_gen_sub_i64(t0, t0, t1);
3340 tcg_gen_ext32s_i64(t0, t0);
3341 opn = "addu";
3342 break;
3343
3344 case OPC_SLL_CP2:
3345 opn = "sll";
3346 shift_max = 32;
3347 goto do_shift;
3348 case OPC_SRL_CP2:
3349 opn = "srl";
3350 shift_max = 32;
3351 goto do_shift;
3352 case OPC_SRA_CP2:
3353 opn = "sra";
3354 shift_max = 32;
3355 goto do_shift;
3356 case OPC_DSLL_CP2:
3357 opn = "dsll";
3358 shift_max = 64;
3359 goto do_shift;
3360 case OPC_DSRL_CP2:
3361 opn = "dsrl";
3362 shift_max = 64;
3363 goto do_shift;
3364 case OPC_DSRA_CP2:
3365 opn = "dsra";
3366 shift_max = 64;
3367 goto do_shift;
3368 do_shift:
3369 /* Make sure shift count isn't TCG undefined behaviour. */
3370 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3371
3372 switch (opc) {
3373 case OPC_SLL_CP2:
3374 case OPC_DSLL_CP2:
3375 tcg_gen_shl_i64(t0, t0, t1);
3376 break;
3377 case OPC_SRA_CP2:
3378 case OPC_DSRA_CP2:
3379 /* Since SRA is UndefinedResult without sign-extended inputs,
3380 we can treat SRA and DSRA the same. */
3381 tcg_gen_sar_i64(t0, t0, t1);
3382 break;
3383 case OPC_SRL_CP2:
3384 /* We want to shift in zeros for SRL; zero-extend first. */
3385 tcg_gen_ext32u_i64(t0, t0);
3386 /* FALLTHRU */
3387 case OPC_DSRL_CP2:
3388 tcg_gen_shr_i64(t0, t0, t1);
3389 break;
3390 }
3391
3392 if (shift_max == 32) {
3393 tcg_gen_ext32s_i64(t0, t0);
3394 }
3395
3396 /* Shifts larger than MAX produce zero. */
3397 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3398 tcg_gen_neg_i64(t1, t1);
3399 tcg_gen_and_i64(t0, t0, t1);
3400 break;
3401
3402 case OPC_ADD_CP2:
3403 case OPC_DADD_CP2:
3404 {
3405 TCGv_i64 t2 = tcg_temp_new_i64();
3406 int lab = gen_new_label();
3407
3408 tcg_gen_mov_i64(t2, t0);
3409 tcg_gen_add_i64(t0, t1, t2);
3410 if (opc == OPC_ADD_CP2) {
3411 tcg_gen_ext32s_i64(t0, t0);
3412 }
3413 tcg_gen_xor_i64(t1, t1, t2);
3414 tcg_gen_xor_i64(t2, t2, t0);
3415 tcg_gen_andc_i64(t1, t2, t1);
3416 tcg_temp_free_i64(t2);
3417 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3418 generate_exception(ctx, EXCP_OVERFLOW);
3419 gen_set_label(lab);
3420
3421 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3422 break;
3423 }
3424
3425 case OPC_SUB_CP2:
3426 case OPC_DSUB_CP2:
3427 {
3428 TCGv_i64 t2 = tcg_temp_new_i64();
3429 int lab = gen_new_label();
3430
3431 tcg_gen_mov_i64(t2, t0);
3432 tcg_gen_sub_i64(t0, t1, t2);
3433 if (opc == OPC_SUB_CP2) {
3434 tcg_gen_ext32s_i64(t0, t0);
3435 }
3436 tcg_gen_xor_i64(t1, t1, t2);
3437 tcg_gen_xor_i64(t2, t2, t0);
3438 tcg_gen_and_i64(t1, t1, t2);
3439 tcg_temp_free_i64(t2);
3440 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3441 generate_exception(ctx, EXCP_OVERFLOW);
3442 gen_set_label(lab);
3443
3444 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3445 break;
3446 }
3447
3448 case OPC_PMULUW:
3449 tcg_gen_ext32u_i64(t0, t0);
3450 tcg_gen_ext32u_i64(t1, t1);
3451 tcg_gen_mul_i64(t0, t0, t1);
3452 opn = "pmuluw";
3453 break;
3454
3455 case OPC_SEQU_CP2:
3456 case OPC_SEQ_CP2:
3457 case OPC_SLTU_CP2:
3458 case OPC_SLT_CP2:
3459 case OPC_SLEU_CP2:
3460 case OPC_SLE_CP2:
3461 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3462 FD field is the CC field? */
3463 default:
3464 MIPS_INVAL(opn);
3465 generate_exception(ctx, EXCP_RI);
3466 return;
3467 }
3468
3469 #undef LMI_HELPER
3470 #undef LMI_DIRECT
3471
3472 gen_store_fpr64(ctx, t0, rd);
3473
3474 (void)opn; /* avoid a compiler warning */
3475 MIPS_DEBUG("%s %s, %s, %s", opn,
3476 fregnames[rd], fregnames[rs], fregnames[rt]);
3477 tcg_temp_free_i64(t0);
3478 tcg_temp_free_i64(t1);
3479 }
3480
3481 /* Traps */
3482 static void gen_trap (DisasContext *ctx, uint32_t opc,
3483 int rs, int rt, int16_t imm)
3484 {
3485 int cond;
3486 TCGv t0 = tcg_temp_new();
3487 TCGv t1 = tcg_temp_new();
3488
3489 cond = 0;
3490 /* Load needed operands */
3491 switch (opc) {
3492 case OPC_TEQ:
3493 case OPC_TGE:
3494 case OPC_TGEU:
3495 case OPC_TLT:
3496 case OPC_TLTU:
3497 case OPC_TNE:
3498 /* Compare two registers */
3499 if (rs != rt) {
3500 gen_load_gpr(t0, rs);
3501 gen_load_gpr(t1, rt);
3502 cond = 1;
3503 }
3504 break;
3505 case OPC_TEQI:
3506 case OPC_TGEI:
3507 case OPC_TGEIU:
3508 case OPC_TLTI:
3509 case OPC_TLTIU:
3510 case OPC_TNEI:
3511 /* Compare register to immediate */
3512 if (rs != 0 || imm != 0) {
3513 gen_load_gpr(t0, rs);
3514 tcg_gen_movi_tl(t1, (int32_t)imm);
3515 cond = 1;
3516 }
3517 break;
3518 }
3519 if (cond == 0) {
3520 switch (opc) {
3521 case OPC_TEQ: /* rs == rs */
3522 case OPC_TEQI: /* r0 == 0 */
3523 case OPC_TGE: /* rs >= rs */
3524 case OPC_TGEI: /* r0 >= 0 */
3525 case OPC_TGEU: /* rs >= rs unsigned */
3526 case OPC_TGEIU: /* r0 >= 0 unsigned */
3527 /* Always trap */
3528 generate_exception(ctx, EXCP_TRAP);
3529 break;
3530 case OPC_TLT: /* rs < rs */
3531 case OPC_TLTI: /* r0 < 0 */
3532 case OPC_TLTU: /* rs < rs unsigned */
3533 case OPC_TLTIU: /* r0 < 0 unsigned */
3534 case OPC_TNE: /* rs != rs */
3535 case OPC_TNEI: /* r0 != 0 */
3536 /* Never trap: treat as NOP. */
3537 break;
3538 }
3539 } else {
3540 int l1 = gen_new_label();
3541
3542 switch (opc) {
3543 case OPC_TEQ:
3544 case OPC_TEQI:
3545 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3546 break;
3547 case OPC_TGE:
3548 case OPC_TGEI:
3549 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3550 break;
3551 case OPC_TGEU:
3552 case OPC_TGEIU:
3553 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3554 break;
3555 case OPC_TLT:
3556 case OPC_TLTI:
3557 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3558 break;
3559 case OPC_TLTU:
3560 case OPC_TLTIU:
3561 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3562 break;
3563 case OPC_TNE:
3564 case OPC_TNEI:
3565 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3566 break;
3567 }
3568 generate_exception(ctx, EXCP_TRAP);
3569 gen_set_label(l1);
3570 }
3571 tcg_temp_free(t0);
3572 tcg_temp_free(t1);
3573 }
3574
3575 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3576 {
3577 TranslationBlock *tb;
3578 tb = ctx->tb;
3579 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3580 likely(!ctx->singlestep_enabled)) {
3581 tcg_gen_goto_tb(n);
3582 gen_save_pc(dest);
3583 tcg_gen_exit_tb((uintptr_t)tb + n);
3584 } else {
3585 gen_save_pc(dest);
3586 if (ctx->singlestep_enabled) {
3587 save_cpu_state(ctx, 0);
3588 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3589 }
3590 tcg_gen_exit_tb(0);
3591 }
3592 }
3593
3594 /* Branches (before delay slot) */
3595 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3596 int insn_bytes,
3597 int rs, int rt, int32_t offset)
3598 {
3599 target_ulong btgt = -1;
3600 int blink = 0;
3601 int bcond_compute = 0;
3602 TCGv t0 = tcg_temp_new();
3603 TCGv t1 = tcg_temp_new();
3604
3605 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3606 #ifdef MIPS_DEBUG_DISAS
3607 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3608 #endif
3609 generate_exception(ctx, EXCP_RI);
3610 goto out;
3611 }
3612
3613 /* Load needed operands */
3614 switch (opc) {
3615 case OPC_BEQ:
3616 case OPC_BEQL:
3617 case OPC_BNE:
3618 case OPC_BNEL:
3619 /* Compare two registers */
3620 if (rs != rt) {
3621 gen_load_gpr(t0, rs);
3622 gen_load_gpr(t1, rt);
3623 bcond_compute = 1;
3624 }
3625 btgt = ctx->pc + insn_bytes + offset;
3626 break;
3627 case OPC_BGEZ:
3628 case OPC_BGEZAL:
3629 case OPC_BGEZALS:
3630 case OPC_BGEZALL:
3631 case OPC_BGEZL:
3632 case OPC_BGTZ:
3633 case OPC_BGTZL:
3634 case OPC_BLEZ:
3635 case OPC_BLEZL:
3636 case OPC_BLTZ:
3637 case OPC_BLTZAL:
3638 case OPC_BLTZALS:
3639 case OPC_BLTZALL:
3640 case OPC_BLTZL:
3641 /* Compare to zero */
3642 if (rs != 0) {
3643 gen_load_gpr(t0, rs);
3644 bcond_compute = 1;
3645 }
3646 btgt = ctx->pc + insn_bytes + offset;
3647 break;
3648 case OPC_BPOSGE32:
3649 #if defined(TARGET_MIPS64)
3650 case OPC_BPOSGE64:
3651 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3652 #else
3653 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3654 #endif
3655 bcond_compute = 1;
3656 btgt = ctx->pc + insn_bytes + offset;
3657 break;
3658 case OPC_J:
3659 case OPC_JAL:
3660 case OPC_JALX:
3661 case OPC_JALS:
3662 case OPC_JALXS:
3663 /* Jump to immediate */
3664 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3665 break;
3666 case OPC_JR:
3667 case OPC_JALR:
3668 case OPC_JALRC:
3669 case OPC_JALRS:
3670 /* Jump to register */
3671 if (offset != 0 && offset != 16) {
3672 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3673 others are reserved. */
3674 MIPS_INVAL("jump hint");
3675 generate_exception(ctx, EXCP_RI);
3676 goto out;
3677 }
3678 gen_load_gpr(btarget, rs);
3679 break;
3680 default:
3681 MIPS_INVAL("branch/jump");
3682 generate_exception(ctx, EXCP_RI);
3683 goto out;
3684 }
3685 if (bcond_compute == 0) {
3686 /* No condition to be computed */
3687 switch (opc) {
3688 case OPC_BEQ: /* rx == rx */
3689 case OPC_BEQL: /* rx == rx likely */
3690 case OPC_BGEZ: /* 0 >= 0 */
3691 case OPC_BGEZL: /* 0 >= 0 likely */
3692 case OPC_BLEZ: /* 0 <= 0 */
3693 case OPC_BLEZL: /* 0 <= 0 likely */
3694 /* Always take */
3695 ctx->hflags |= MIPS_HFLAG_B;
3696 MIPS_DEBUG("balways");
3697 break;
3698 case OPC_BGEZALS:
3699 case OPC_BGEZAL: /* 0 >= 0 */
3700 case OPC_BGEZALL: /* 0 >= 0 likely */
3701 ctx->hflags |= (opc == OPC_BGEZALS
3702 ? MIPS_HFLAG_BDS16
3703 : MIPS_HFLAG_BDS32);
3704 /* Always take and link */
3705 blink = 31;
3706 ctx->hflags |= MIPS_HFLAG_B;
3707 MIPS_DEBUG("balways and link");
3708 break;
3709 case OPC_BNE: /* rx != rx */
3710 case OPC_BGTZ: /* 0 > 0 */
3711 case OPC_BLTZ: /* 0 < 0 */
3712 /* Treat as NOP. */
3713 MIPS_DEBUG("bnever (NOP)");
3714 goto out;
3715 case OPC_BLTZALS:
3716 case OPC_BLTZAL: /* 0 < 0 */
3717 ctx->hflags |= (opc == OPC_BLTZALS
3718 ? MIPS_HFLAG_BDS16
3719 : MIPS_HFLAG_BDS32);
3720 /* Handle as an unconditional branch to get correct delay
3721 slot checking. */
3722 blink = 31;
3723 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3724 ctx->hflags |= MIPS_HFLAG_B;
3725 MIPS_DEBUG("bnever and link");
3726 break;
3727 case OPC_BLTZALL: /* 0 < 0 likely */
3728 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3729 /* Skip the instruction in the delay slot */
3730 MIPS_DEBUG("bnever, link and skip");
3731 ctx->pc += 4;
3732 goto out;
3733 case OPC_BNEL: /* rx != rx likely */
3734 case OPC_BGTZL: /* 0 > 0 likely */
3735 case OPC_BLTZL: /* 0 < 0 likely */
3736 /* Skip the instruction in the delay slot */
3737 MIPS_DEBUG("bnever and skip");
3738 ctx->pc += 4;
3739 goto out;
3740 case OPC_J:
3741 ctx->hflags |= MIPS_HFLAG_B;
3742 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3743 break;
3744 case OPC_JALXS:
3745 case OPC_JALX:
3746 ctx->hflags |= MIPS_HFLAG_BX;
3747 /* Fallthrough */
3748 case OPC_JALS:
3749 case OPC_JAL:
3750 blink = 31;
3751 ctx->hflags |= MIPS_HFLAG_B;
3752 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3753 ? MIPS_HFLAG_BDS16
3754 : MIPS_HFLAG_BDS32);
3755 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3756 break;
3757 case OPC_JR:
3758 ctx->hflags |= MIPS_HFLAG_BR;
3759 if (insn_bytes == 4)
3760 ctx->hflags |= MIPS_HFLAG_BDS32;
3761 MIPS_DEBUG("jr %s", regnames[rs]);
3762 break;
3763 case OPC_JALRS:
3764 case OPC_JALR:
3765 case OPC_JALRC:
3766 blink = rt;
3767 ctx->hflags |= MIPS_HFLAG_BR;
3768 ctx->hflags |= (opc == OPC_JALRS
3769 ? MIPS_HFLAG_BDS16
3770 : MIPS_HFLAG_BDS32);
3771 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3772 break;
3773 default:
3774 MIPS_INVAL("branch/jump");
3775 generate_exception(ctx, EXCP_RI);
3776 goto out;
3777 }
3778 } else {
3779 switch (opc) {
3780 case OPC_BEQ:
3781 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3782 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3783 regnames[rs], regnames[rt], btgt);
3784 goto not_likely;
3785 case OPC_BEQL:
3786 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3787 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3788 regnames[rs], regnames[rt], btgt);
3789 goto likely;
3790 case OPC_BNE:
3791 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3792 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3793 regnames[rs], regnames[rt], btgt);
3794 goto not_likely;
3795 case OPC_BNEL:
3796 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3797 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3798 regnames[rs], regnames[rt], btgt);
3799 goto likely;
3800 case OPC_BGEZ:
3801 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3802 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3803 goto not_likely;
3804 case OPC_BGEZL:
3805 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3806 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3807 goto likely;
3808 case OPC_BGEZALS:
3809 case OPC_BGEZAL:
3810 ctx->hflags |= (opc == OPC_BGEZALS
3811 ? MIPS_HFLAG_BDS16
3812 : MIPS_HFLAG_BDS32);
3813 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3814 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3815 blink = 31;
3816 goto not_likely;
3817 case OPC_BGEZALL:
3818 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3819 blink = 31;
3820 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3821 goto likely;
3822 case OPC_BGTZ:
3823 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3824 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3825 goto not_likely;
3826 case OPC_BGTZL:
3827 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3828 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3829 goto likely;
3830 case OPC_BLEZ:
3831 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3832 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3833 goto not_likely;
3834 case OPC_BLEZL:
3835 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3836 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3837 goto likely;
3838 case OPC_BLTZ:
3839 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3840 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3841 goto not_likely;
3842 case OPC_BLTZL:
3843 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3844 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3845 goto likely;
3846 case OPC_BPOSGE32:
3847 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3848 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3849 goto not_likely;
3850 #if defined(TARGET_MIPS64)
3851 case OPC_BPOSGE64:
3852 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3853 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3854 goto not_likely;
3855 #endif
3856 case OPC_BLTZALS:
3857 case OPC_BLTZAL:
3858 ctx->hflags |= (opc == OPC_BLTZALS
3859 ? MIPS_HFLAG_BDS16
3860 : MIPS_HFLAG_BDS32);
3861 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3862 blink = 31;
3863 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3864 not_likely:
3865 ctx->hflags |= MIPS_HFLAG_BC;
3866 break;
3867 case OPC_BLTZALL:
3868 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3869 blink = 31;
3870 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3871 likely:
3872 ctx->hflags |= MIPS_HFLAG_BL;
3873 break;
3874 default:
3875 MIPS_INVAL("conditional branch/jump");
3876 generate_exception(ctx, EXCP_RI);
3877 goto out;
3878 }
3879 }
3880 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3881 blink, ctx->hflags, btgt);
3882
3883 ctx->btarget = btgt;
3884 if (blink > 0) {
3885 int post_delay = insn_bytes;
3886 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3887
3888 if (opc != OPC_JALRC)
3889 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3890
3891 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3892 }
3893
3894 out:
3895 if (insn_bytes == 2)
3896 ctx->hflags |= MIPS_HFLAG_B16;
3897 tcg_temp_free(t0);
3898 tcg_temp_free(t1);
3899 }
3900
3901 /* special3 bitfield operations */
3902 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3903 int rs, int lsb, int msb)
3904 {
3905 TCGv t0 = tcg_temp_new();
3906 TCGv t1 = tcg_temp_new();
3907
3908 gen_load_gpr(t1, rs);
3909 switch (opc) {
3910 case OPC_EXT:
3911 if (lsb + msb > 31)
3912 goto fail;
3913 tcg_gen_shri_tl(t0, t1, lsb);
3914 if (msb != 31) {
3915 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3916 } else {
3917 tcg_gen_ext32s_tl(t0, t0);
3918 }
3919 break;
3920 #if defined(TARGET_MIPS64)
3921 case OPC_DEXTM:
3922 tcg_gen_shri_tl(t0, t1, lsb);
3923 if (msb != 31) {
3924 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3925 }
3926 break;
3927 case OPC_DEXTU:
3928 tcg_gen_shri_tl(t0, t1, lsb + 32);
3929 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3930 break;
3931 case OPC_DEXT:
3932 tcg_gen_shri_tl(t0, t1, lsb);
3933 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3934 break;
3935 #endif
3936 case OPC_INS:
3937 if (lsb > msb)
3938 goto fail;
3939 gen_load_gpr(t0, rt);
3940 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3941 tcg_gen_ext32s_tl(t0, t0);
3942 break;
3943 #if defined(TARGET_MIPS64)
3944 case OPC_DINSM:
3945 gen_load_gpr(t0, rt);
3946 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3947 break;
3948 case OPC_DINSU:
3949 gen_load_gpr(t0, rt);
3950 tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3951 break;
3952 case OPC_DINS:
3953 gen_load_gpr(t0, rt);
3954 tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3955 break;
3956 #endif
3957 default:
3958 fail:
3959 MIPS_INVAL("bitops");
3960 generate_exception(ctx, EXCP_RI);
3961 tcg_temp_free(t0);
3962 tcg_temp_free(t1);
3963 return;
3964 }
3965 gen_store_gpr(t0, rt);
3966 tcg_temp_free(t0);
3967 tcg_temp_free(t1);
3968 }
3969
3970 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3971 {
3972 TCGv t0;
3973
3974 if (rd == 0) {
3975 /* If no destination, treat it as a NOP. */
3976 MIPS_DEBUG("NOP");
3977 return;
3978 }
3979
3980 t0 = tcg_temp_new();
3981 gen_load_gpr(t0, rt);
3982 switch (op2) {
3983 case OPC_WSBH:
3984 {
3985 TCGv t1 = tcg_temp_new();
3986
3987 tcg_gen_shri_tl(t1, t0, 8);
3988 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3989 tcg_gen_shli_tl(t0, t0, 8);
3990 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3991 tcg_gen_or_tl(t0, t0, t1);
3992 tcg_temp_free(t1);
3993 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3994 }
3995 break;
3996 case OPC_SEB:
3997 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3998 break;
3999 case OPC_SEH:
4000 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4001 break;
4002 #if defined(TARGET_MIPS64)
4003 case OPC_DSBH:
4004 {
4005 TCGv t1 = tcg_temp_new();
4006
4007 tcg_gen_shri_tl(t1, t0, 8);
4008 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4009 tcg_gen_shli_tl(t0, t0, 8);
4010 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4011 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4012 tcg_temp_free(t1);
4013 }
4014 break;
4015 case OPC_DSHD:
4016 {
4017 TCGv t1 = tcg_temp_new();
4018
4019 tcg_gen_shri_tl(t1, t0, 16);
4020 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4021 tcg_gen_shli_tl(t0, t0, 16);
4022 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4023 tcg_gen_or_tl(t0, t0, t1);
4024 tcg_gen_shri_tl(t1, t0, 32);
4025 tcg_gen_shli_tl(t0, t0, 32);
4026 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4027 tcg_temp_free(t1);
4028 }
4029 break;
4030 #endif
4031 default:
4032 MIPS_INVAL("bsfhl");
4033 generate_exception(ctx, EXCP_RI);
4034 tcg_temp_free(t0);
4035 return;
4036 }
4037 tcg_temp_free(t0);
4038 }
4039
4040 #ifndef CONFIG_USER_ONLY
4041 /* CP0 (MMU and control) */
4042 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4043 {
4044 TCGv_i32 t0 = tcg_temp_new_i32();
4045
4046 tcg_gen_ld_i32(t0, cpu_env, off);
4047 tcg_gen_ext_i32_tl(arg, t0);
4048 tcg_temp_free_i32(t0);
4049 }
4050
4051 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4052 {
4053 tcg_gen_ld_tl(arg, cpu_env, off);
4054 tcg_gen_ext32s_tl(arg, arg);
4055 }
4056
4057 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4058 {
4059 TCGv_i32 t0 = tcg_temp_new_i32();
4060
4061 tcg_gen_trunc_tl_i32(t0, arg);
4062 tcg_gen_st_i32(t0, cpu_env, off);
4063 tcg_temp_free_i32(t0);
4064 }
4065
4066 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4067 {
4068 tcg_gen_ext32s_tl(arg, arg);
4069 tcg_gen_st_tl(arg, cpu_env, off);
4070 }
4071
4072 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4073 {
4074 const char *rn = "invalid";
4075
4076 if (sel != 0)
4077 check_insn(ctx, ISA_MIPS32);
4078
4079 switch (reg) {
4080 case 0:
4081 switch (sel) {
4082 case 0:
4083 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4084 rn = "Index";
4085 break;
4086 case 1:
4087 check_insn(ctx, ASE_MT);
4088 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4089 rn = "MVPControl";
4090 break;
4091 case 2:
4092 check_insn(ctx, ASE_MT);
4093 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4094 rn = "MVPConf0";
4095 break;
4096 case 3:
4097 check_insn(ctx, ASE_MT);
4098 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4099 rn = "MVPConf1";
4100 break;
4101 default:
4102 goto die;
4103 }
4104 break;
4105 case 1:
4106 switch (sel) {
4107 case 0:
4108 gen_helper_mfc0_random(arg, cpu_env);
4109 rn = "Random";
4110 break;
4111 case 1:
4112 check_insn(ctx, ASE_MT);
4113 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4114 rn = "VPEControl";
4115 break;
4116 case 2:
4117 check_insn(ctx, ASE_MT);
4118 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4119 rn = "VPEConf0";
4120 break;
4121 case 3:
4122 check_insn(ctx, ASE_MT);
4123 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4124 rn = "VPEConf1";
4125 break;
4126 case 4:
4127 check_insn(ctx, ASE_MT);
4128 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4129 rn = "YQMask";
4130 break;
4131 case 5:
4132 check_insn(ctx, ASE_MT);
4133 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4134 rn = "VPESchedule";
4135 break;
4136 case 6:
4137 check_insn(ctx, ASE_MT);
4138 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4139 rn = "VPEScheFBack";
4140 break;
4141 case 7:
4142 check_insn(ctx, ASE_MT);
4143 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4144 rn = "VPEOpt";
4145 break;
4146 default:
4147 goto die;
4148 }
4149 break;
4150 case 2:
4151 switch (sel) {
4152 case 0:
4153 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4154 tcg_gen_ext32s_tl(arg, arg);
4155 rn = "EntryLo0";
4156 break;
4157 case 1:
4158 check_insn(ctx, ASE_MT);
4159 gen_helper_mfc0_tcstatus(arg, cpu_env);
4160 rn = "TCStatus";
4161 break;
4162 case 2:
4163 check_insn(ctx, ASE_MT);
4164 gen_helper_mfc0_tcbind(arg, cpu_env);
4165 rn = "TCBind";
4166 break;
4167 case 3:
4168 check_insn(ctx, ASE_MT);
4169 gen_helper_mfc0_tcrestart(arg, cpu_env);
4170 rn = "TCRestart";
4171 break;
4172 case 4:
4173 check_insn(ctx, ASE_MT);
4174 gen_helper_mfc0_tchalt(arg, cpu_env);
4175 rn = "TCHalt";
4176 break;
4177 case 5:
4178 check_insn(ctx, ASE_MT);
4179 gen_helper_mfc0_tccontext(arg, cpu_env);
4180 rn = "TCContext";
4181 break;
4182 case 6:
4183 check_insn(ctx, ASE_MT);
4184 gen_helper_mfc0_tcschedule(arg, cpu_env);
4185 rn = "TCSchedule";
4186 break;
4187 case 7:
4188 check_insn(ctx, ASE_MT);
4189 gen_helper_mfc0_tcschefback(arg, cpu_env);
4190 rn = "TCScheFBack";
4191 break;
4192 default:
4193 goto die;
4194 }
4195 break;
4196 case 3:
4197 switch (sel) {
4198 case 0:
4199 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4200 tcg_gen_ext32s_tl(arg, arg);
4201 rn = "EntryLo1";
4202 break;
4203 default:
4204 goto die;
4205 }
4206 break;
4207 case 4:
4208 switch (sel) {
4209 case 0:
4210 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4211 tcg_gen_ext32s_tl(arg, arg);
4212 rn = "Context";
4213 break;
4214 case 1:
4215 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4216 rn = "ContextConfig";
4217 // break;
4218 default:
4219 goto die;
4220 }
4221 break;
4222 case 5:
4223 switch (sel) {
4224 case 0:
4225 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4226 rn = "PageMask";
4227 break;
4228 case 1:
4229 check_insn(ctx, ISA_MIPS32R2);
4230 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4231 rn = "PageGrain";
4232 break;
4233 default:
4234 goto die;
4235 }
4236 break;
4237 case 6:
4238 switch (sel) {
4239 case 0:
4240 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4241 rn = "Wired";
4242 break;
4243 case 1:
4244 check_insn(ctx, ISA_MIPS32R2);
4245 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4246 rn = "SRSConf0";
4247 break;
4248 case 2:
4249 check_insn(ctx, ISA_MIPS32R2);
4250 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4251 rn = "SRSConf1";
4252 break;
4253 case 3:
4254 check_insn(ctx, ISA_MIPS32R2);
4255 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4256 rn = "SRSConf2";
4257 break;
4258 case 4:
4259 check_insn(ctx, ISA_MIPS32R2);
4260 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4261 rn = "SRSConf3";
4262 break;
4263 case 5:
4264 check_insn(ctx, ISA_MIPS32R2);
4265 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4266 rn = "SRSConf4";
4267 break;
4268 default:
4269 goto die;
4270 }
4271 break;
4272 case 7:
4273 switch (sel) {
4274 case 0:
4275 check_insn(ctx, ISA_MIPS32R2);
4276 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4277 rn = "HWREna";
4278 break;
4279 default:
4280 goto die;
4281 }
4282 break;
4283 case 8:
4284 switch (sel) {
4285 case 0:
4286 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4287 tcg_gen_ext32s_tl(arg, arg);
4288 rn = "BadVAddr";
4289 break;
4290 default:
4291 goto die;
4292 }
4293 break;
4294 case 9:
4295 switch (sel) {
4296 case 0:
4297 /* Mark as an IO operation because we read the time. */
4298 if (use_icount)
4299 gen_io_start();
4300 gen_helper_mfc0_count(arg, cpu_env);
4301 if (use_icount) {
4302 gen_io_end();
4303 }
4304 /* Break the TB to be able to take timer interrupts immediately
4305 after reading count. */
4306 ctx->bstate = BS_STOP;
4307 rn = "Count";
4308 break;
4309 /* 6,7 are implementation dependent */
4310 default:
4311 goto die;
4312 }
4313 break;
4314 case 10:
4315 switch (sel) {
4316 case 0:
4317 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4318 tcg_gen_ext32s_tl(arg, arg);
4319 rn = "EntryHi";
4320 break;
4321 default:
4322 goto die;
4323 }
4324 break;
4325 case 11:
4326 switch (sel) {
4327 case 0:
4328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4329 rn = "Compare";
4330 break;
4331 /* 6,7 are implementation dependent */
4332 default:
4333 goto die;
4334 }
4335 break;
4336 case 12:
4337 switch (sel) {
4338 case 0:
4339 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4340 rn = "Status";
4341 break;
4342 case 1:
4343 check_insn(ctx, ISA_MIPS32R2);
4344 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4345 rn = "IntCtl";
4346 break;
4347 case 2:
4348 check_insn(ctx, ISA_MIPS32R2);
4349 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4350 rn = "SRSCtl";
4351 break;
4352 case 3:
4353 check_insn(ctx, ISA_MIPS32R2);
4354 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4355 rn = "SRSMap";
4356 break;
4357 default:
4358 goto die;
4359 }
4360 break;
4361 case 13:
4362 switch (sel) {
4363 case 0:
4364 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4365 rn = "Cause";
4366 break;
4367 default:
4368 goto die;
4369 }
4370 break;
4371 case 14:
4372 switch (sel) {
4373 case 0:
4374 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4375 tcg_gen_ext32s_tl(arg, arg);
4376 rn = "EPC";
4377 break;
4378 default:
4379 goto die;
4380 }
4381 break;
4382 case 15:
4383 switch (sel) {
4384 case 0:
4385 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4386 rn = "PRid";
4387 break;
4388 case 1:
4389 check_insn(ctx, ISA_MIPS32R2);
4390 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4391 rn = "EBase";
4392 break;
4393 default:
4394 goto die;
4395 }
4396 break;
4397 case 16:
4398 switch (sel) {
4399 case 0:
4400 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4401 rn = "Config";
4402 break;
4403 case 1:
4404 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4405 rn = "Config1";
4406 break;
4407 case 2:
4408 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4409 rn = "Config2";
4410 break;
4411 case 3:
4412 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4413 rn = "Config3";
4414 break;
4415 case 4:
4416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
4417 rn = "Config4";
4418 break;
4419 case 5:
4420 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
4421 rn = "Config5";
4422 break;
4423 /* 6,7 are implementation dependent */
4424 case 6:
4425 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4426 rn = "Config6";
4427 break;
4428 case 7:
4429 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4430 rn = "Config7";
4431 break;
4432 default:
4433 goto die;
4434 }
4435 break;
4436 case 17:
4437 switch (sel) {
4438 case 0:
4439 gen_helper_mfc0_lladdr(arg, cpu_env);
4440 rn = "LLAddr";
4441 break;
4442 default:
4443 goto die;
4444 }
4445 break;
4446 case 18:
4447 switch (sel) {
4448 case 0 ... 7:
4449 gen_helper_1e0i(mfc0_watchlo, arg, sel);
4450 rn = "WatchLo";
4451 break;
4452 default:
4453 goto die;
4454 }
4455 break;
4456 case 19:
4457 switch (sel) {
4458 case 0 ...7:
4459 gen_helper_1e0i(mfc0_watchhi, arg, sel);
4460 rn = "WatchHi";
4461 break;
4462 default:
4463 goto die;
4464 }
4465 break;
4466 case 20:
4467 switch (sel) {
4468 case 0:
4469 #if defined(TARGET_MIPS64)
4470 check_insn(ctx, ISA_MIPS3);
4471 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4472 tcg_gen_ext32s_tl(arg, arg);
4473 rn = "XContext";
4474 break;
4475 #endif
4476 default:
4477 goto die;
4478 }
4479 break;
4480 case 21:
4481 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4482 switch (sel) {
4483 case 0:
4484 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4485 rn = "Framemask";
4486 break;
4487 default:
4488 goto die;
4489 }
4490 break;
4491 case 22:
4492 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4493 rn = "'Diagnostic"; /* implementation dependent */
4494 break;
4495 case 23:
4496 switch (sel) {
4497 case 0:
4498 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4499 rn = "Debug";
4500 break;
4501 case 1:
4502 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4503 rn = "TraceControl";
4504 // break;
4505 case 2:
4506 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4507 rn = "TraceControl2";
4508 // break;
4509 case 3:
4510 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4511 rn = "UserTraceData";
4512 // break;
4513 case 4:
4514 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4515 rn = "TraceBPC";
4516 // break;
4517 default:
4518 goto die;
4519 }
4520 break;
4521 case 24:
4522 switch (sel) {
4523 case 0:
4524 /* EJTAG support */
4525 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4526 tcg_gen_ext32s_tl(arg, arg);
4527 rn = "DEPC";
4528 break;
4529 default:
4530 goto die;
4531 }
4532 break;
4533 case 25:
4534 switch (sel) {
4535 case 0:
4536 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4537 rn = "Performance0";
4538 break;
4539 case 1:
4540 // gen_helper_mfc0_performance1(arg);
4541 rn = "Performance1";
4542 // break;
4543 case 2:
4544 // gen_helper_mfc0_performance2(arg);
4545 rn = "Performance2";
4546 // break;
4547 case 3:
4548 // gen_helper_mfc0_performance3(arg);
4549 rn = "Performance3";
4550 // break;
4551 case 4:
4552 // gen_helper_mfc0_performance4(arg);
4553 rn = "Performance4";
4554 // break;
4555 case 5:
4556 // gen_helper_mfc0_performance5(arg);
4557 rn = "Performance5";
4558 // break;
4559 case 6:
4560 // gen_helper_mfc0_performance6(arg);
4561 rn = "Performance6";
4562 // break;
4563 case 7:
4564 // gen_helper_mfc0_performance7(arg);
4565 rn = "Performance7";
4566 // break;
4567 default:
4568 goto die;
4569 }
4570 break;
4571 case 26:
4572 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4573 rn = "ECC";
4574 break;
4575 case 27:
4576 switch (sel) {
4577 case 0 ... 3:
4578 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4579 rn = "CacheErr";
4580 break;
4581 default:
4582 goto die;
4583 }
4584 break;
4585 case 28:
4586 switch (sel) {
4587 case 0:
4588 case 2:
4589 case 4:
4590 case 6:
4591 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4592 rn = "TagLo";
4593 break;
4594 case 1:
4595 case 3:
4596 case 5:
4597 case 7:
4598 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4599 rn = "DataLo";
4600 break;
4601 default:
4602 goto die;
4603 }
4604 break;
4605 case 29:
4606 switch (sel) {
4607 case 0:
4608 case 2:
4609 case 4:
4610 case 6:
4611 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4612 rn = "TagHi";
4613 break;
4614 case 1:
4615 case 3:
4616 case 5:
4617 case 7:
4618 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4619 rn = "DataHi";
4620 break;
4621 default:
4622 goto die;
4623 }
4624 break;
4625 case 30:
4626 switch (sel) {
4627 case 0:
4628 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4629 tcg_gen_ext32s_tl(arg, arg);
4630 rn = "ErrorEPC";
4631 break;
4632 default:
4633 goto die;
4634 }
4635 break;
4636 case 31:
4637 switch (sel) {
4638 case 0:
4639 /* EJTAG support */
4640 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4641 rn = "DESAVE";
4642 break;
4643 default:
4644 goto die;
4645 }
4646 break;
4647 default:
4648 goto die;
4649 }
4650 (void)rn; /* avoid a compiler warning */
4651 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4652 return;
4653
4654 die:
4655 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4656 generate_exception(ctx, EXCP_RI);
4657 }
4658
4659 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4660 {
4661 const char *rn = "invalid";
4662
4663 if (sel != 0)
4664 check_insn(ctx, ISA_MIPS32);
4665
4666 if (use_icount)
4667 gen_io_start();
4668
4669 switch (reg) {
4670 case 0:
4671 switch (sel) {
4672 case 0:
4673 gen_helper_mtc0_index(cpu_env, arg);
4674 rn = "Index";
4675 break;
4676 case 1:
4677 check_insn(ctx, ASE_MT);
4678 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4679 rn = "MVPControl";
4680 break;
4681 case 2:
4682 check_insn(ctx, ASE_MT);
4683 /* ignored */
4684 rn = "MVPConf0";
4685 break;
4686 case 3:
4687 check_insn(ctx, ASE_MT);
4688 /* ignored */
4689 rn = "MVPConf1";
4690 break;
4691 default:
4692 goto die;
4693 }
4694 break;
4695 case 1:
4696 switch (sel) {
4697 case 0:
4698 /* ignored */
4699 rn = "Random";
4700 break;
4701 case 1:
4702 check_insn(ctx, ASE_MT);
4703 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4704 rn = "VPEControl";
4705 break;
4706 case 2:
4707 check_insn(ctx, ASE_MT);
4708 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4709 rn = "VPEConf0";
4710 break;
4711 case 3:
4712 check_insn(ctx, ASE_MT);
4713 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4714 rn = "VPEConf1";
4715 break;
4716 case 4:
4717 check_insn(ctx, ASE_MT);
4718 gen_helper_mtc0_yqmask(cpu_env, arg);
4719 rn = "YQMask";
4720 break;
4721 case 5:
4722 check_insn(ctx, ASE_MT);
4723 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4724 rn = "VPESchedule";
4725 break;
4726 case 6:
4727 check_insn(ctx, ASE_MT);
4728 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4729 rn = "VPEScheFBack";
4730 break;
4731 case 7:
4732 check_insn(ctx, ASE_MT);
4733 gen_helper_mtc0_vpeopt(cpu_env, arg);
4734 rn = "VPEOpt";
4735 break;
4736 default:
4737 goto die;
4738 }
4739 break;
4740 case 2:
4741 switch (sel) {
4742 case 0:
4743 gen_helper_mtc0_entrylo0(cpu_env, arg);
4744 rn = "EntryLo0";
4745 break;
4746 case 1:
4747 check_insn(ctx, ASE_MT);
4748 gen_helper_mtc0_tcstatus(cpu_env, arg);
4749 rn = "TCStatus";
4750 break;
4751 case 2:
4752 check_insn(ctx, ASE_MT);
4753 gen_helper_mtc0_tcbind(cpu_env, arg);
4754 rn = "TCBind";
4755 break;
4756 case 3:
4757 check_insn(ctx, ASE_MT);
4758 gen_helper_mtc0_tcrestart(cpu_env, arg);
4759 rn = "TCRestart";
4760 break;
4761 case 4:
4762 check_insn(ctx, ASE_MT);
4763 gen_helper_mtc0_tchalt(cpu_env, arg);
4764 rn = "TCHalt";
4765 break;
4766 case 5:
4767 check_insn(ctx, ASE_MT);
4768 gen_helper_mtc0_tccontext(cpu_env, arg);
4769 rn = "TCContext";
4770 break;
4771 case 6:
4772 check_insn(ctx, ASE_MT);
4773 gen_helper_mtc0_tcschedule(cpu_env, arg);
4774 rn = "TCSchedule";
4775 break;
4776 case 7:
4777 check_insn(ctx, ASE_MT);
4778 gen_helper_mtc0_tcschefback(cpu_env, arg);
4779 rn = "TCScheFBack";
4780 break;
4781 default:
4782 goto die;
4783 }
4784 break;
4785 case 3:
4786 switch (sel) {
4787 case 0:
4788 gen_helper_mtc0_entrylo1(cpu_env, arg);
4789 rn = "EntryLo1";
4790 break;
4791 default:
4792 goto die;
4793 }
4794 break;
4795 case 4:
4796 switch (sel) {
4797 case 0:
4798 gen_helper_mtc0_context(cpu_env, arg);
4799 rn = "Context";
4800 break;
4801 case 1:
4802 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4803 rn = "ContextConfig";
4804 // break;
4805 default:
4806 goto die;
4807 }
4808 break;
4809 case 5:
4810 switch (sel) {
4811 case 0:
4812 gen_helper_mtc0_pagemask(cpu_env, arg);
4813 rn = "PageMask";
4814 break;
4815 case 1:
4816 check_insn(ctx, ISA_MIPS32R2);
4817 gen_helper_mtc0_pagegrain(cpu_env, arg);
4818 rn = "PageGrain";
4819 break;
4820 default:
4821 goto die;
4822 }
4823 break;
4824 case 6:
4825 switch (sel) {
4826 case 0:
4827 gen_helper_mtc0_wired(cpu_env, arg);
4828 rn = "Wired";
4829 break;
4830 case 1:
4831 check_insn(ctx, ISA_MIPS32R2);
4832 gen_helper_mtc0_srsconf0(cpu_env, arg);
4833 rn = "SRSConf0";
4834 break;
4835 case 2:
4836 check_insn(ctx, ISA_MIPS32R2);
4837 gen_helper_mtc0_srsconf1(cpu_env, arg);
4838 rn = "SRSConf1";
4839 break;
4840 case 3:
4841 check_insn(ctx, ISA_MIPS32R2);
4842 gen_helper_mtc0_srsconf2(cpu_env, arg);
4843 rn = "SRSConf2";
4844 break;
4845 case 4:
4846 check_insn(ctx, ISA_MIPS32R2);
4847 gen_helper_mtc0_srsconf3(cpu_env, arg);
4848 rn = "SRSConf3";
4849 break;
4850 case 5:
4851 check_insn(ctx, ISA_MIPS32R2);
4852 gen_helper_mtc0_srsconf4(cpu_env, arg);
4853 rn = "SRSConf4";
4854 break;
4855 default:
4856 goto die;
4857 }
4858 break;
4859 case 7:
4860 switch (sel) {
4861 case 0:
4862 check_insn(ctx, ISA_MIPS32R2);
4863 gen_helper_mtc0_hwrena(cpu_env, arg);
4864 rn = "HWREna";
4865 break;
4866 default:
4867 goto die;
4868 }
4869 break;
4870 case 8:
4871 /* ignored */
4872 rn = "BadVAddr";
4873 break;
4874 case 9:
4875 switch (sel) {
4876 case 0:
4877 gen_helper_mtc0_count(cpu_env, arg);
4878 rn = "Count";
4879 break;
4880 /* 6,7 are implementation dependent */
4881 default:
4882 goto die;
4883 }
4884 break;
4885 case 10:
4886 switch (sel) {
4887 case 0:
4888 gen_helper_mtc0_entryhi(cpu_env, arg);
4889 rn = "EntryHi";
4890 break;
4891 default:
4892 goto die;
4893 }
4894 break;
4895 case 11:
4896 switch (sel) {
4897 case 0:
4898 gen_helper_mtc0_compare(cpu_env, arg);
4899 rn = "Compare";
4900 break;
4901 /* 6,7 are implementation dependent */
4902 default:
4903 goto die;
4904 }
4905 break;
4906 case 12:
4907 switch (sel) {
4908 case 0:
4909 save_cpu_state(ctx, 1);
4910 gen_helper_mtc0_status(cpu_env, arg);
4911 /* BS_STOP isn't good enough here, hflags may have changed. */
4912 gen_save_pc(ctx->pc + 4);
4913 ctx->bstate = BS_EXCP;
4914 rn = "Status";
4915 break;
4916 case 1:
4917 check_insn(ctx, ISA_MIPS32R2);
4918 gen_helper_mtc0_intctl(cpu_env, arg);
4919 /* Stop translation as we may have switched the execution mode */
4920 ctx->bstate = BS_STOP;
4921 rn = "IntCtl";
4922 break;
4923 case 2:
4924 check_insn(ctx, ISA_MIPS32R2);
4925 gen_helper_mtc0_srsctl(cpu_env, arg);
4926 /* Stop translation as we may have switched the execution mode */
4927 ctx->bstate = BS_STOP;
4928 rn = "SRSCtl";
4929 break;
4930 case 3:
4931 check_insn(ctx, ISA_MIPS32R2);
4932 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4933 /* Stop translation as we may have switched the execution mode */
4934 ctx->bstate = BS_STOP;
4935 rn = "SRSMap";
4936 break;
4937 default:
4938 goto die;
4939 }
4940 break;
4941 case 13:
4942 switch (sel) {
4943 case 0:
4944 save_cpu_state(ctx, 1);
4945 gen_helper_mtc0_cause(cpu_env, arg);
4946 rn = "Cause";
4947 break;
4948 default:
4949 goto die;
4950 }
4951 break;
4952 case 14:
4953 switch (sel) {
4954 case 0:
4955 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4956 rn = "EPC";
4957 break;
4958 default:
4959 goto die;
4960 }
4961 break;
4962 case 15:
4963 switch (sel) {
4964 case 0:
4965 /* ignored */
4966 rn = "PRid";
4967 break;
4968 case 1:
4969 check_insn(ctx, ISA_MIPS32R2);
4970 gen_helper_mtc0_ebase(cpu_env, arg);
4971 rn = "EBase";
4972 break;
4973 default:
4974 goto die;
4975 }
4976 break;
4977 case 16:
4978 switch (sel) {
4979 case 0:
4980 gen_helper_mtc0_config0(cpu_env, arg);
4981 rn = "Config";
4982 /* Stop translation as we may have switched the execution mode */
4983 ctx->bstate = BS_STOP;
4984 break;
4985 case 1:
4986 /* ignored, read only */
4987 rn = "Config1";
4988 break;
4989 case 2:
4990 gen_helper_mtc0_config2(cpu_env, arg);
4991 rn = "Config2";
4992 /* Stop translation as we may have switched the execution mode */
4993 ctx->bstate = BS_STOP;
4994 break;
4995 case 3:
4996 /* ignored, read only */
4997 rn = "Config3";
4998 break;
4999 case 4:
5000 gen_helper_mtc0_config4(cpu_env, arg);
5001 rn = "Config4";
5002 ctx->bstate = BS_STOP;
5003 break;
5004 case 5:
5005 gen_helper_mtc0_config5(cpu_env, arg);
5006 rn = "Config5";
5007 /* Stop translation as we may have switched the execution mode */
5008 ctx->bstate = BS_STOP;
5009 break;
5010 /* 6,7 are implementation dependent */
5011 case 6:
5012 /* ignored */
5013 rn = "Config6";
5014 break;
5015 case 7:
5016 /* ignored */
5017 rn = "Config7";
5018 break;
5019 default:
5020 rn = "Invalid config selector";
5021 goto die;
5022 }
5023 break;
5024 case 17:
5025 switch (sel) {
5026 case 0:
5027 gen_helper_mtc0_lladdr(cpu_env, arg);
5028 rn = "LLAddr";
5029 break;
5030 default:
5031 goto die;
5032 }
5033 break;
5034 case 18:
5035 switch (sel) {
5036 case 0 ... 7:
5037 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5038 rn = "WatchLo";
5039 break;
5040 default:
5041 goto die;
5042 }
5043 break;
5044 case 19:
5045 switch (sel) {
5046 case 0 ... 7:
5047 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5048 rn = "WatchHi";
5049 break;
5050 default:
5051 goto die;
5052 }
5053 break;
5054 case 20:
5055 switch (sel) {
5056 case 0:
5057 #if defined(TARGET_MIPS64)
5058 check_insn(ctx, ISA_MIPS3);
5059 gen_helper_mtc0_xcontext(cpu_env, arg);
5060 rn = "XContext";
5061 break;
5062 #endif
5063 default:
5064 goto die;
5065 }
5066 break;
5067 case 21:
5068 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5069 switch (sel) {
5070 case 0:
5071 gen_helper_mtc0_framemask(cpu_env, arg);
5072 rn = "Framemask";
5073 break;
5074 default:
5075 goto die;
5076 }
5077 break;
5078 case 22:
5079 /* ignored */
5080 rn = "Diagnostic"; /* implementation dependent */
5081 break;
5082 case 23:
5083 switch (sel) {
5084 case 0:
5085 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5086 /* BS_STOP isn't good enough here, hflags may have changed. */
5087 gen_save_pc(ctx->pc + 4);
5088 ctx->bstate = BS_EXCP;
5089 rn = "Debug";
5090 break;
5091 case 1:
5092 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5093 rn = "TraceControl";
5094 /* Stop translation as we may have switched the execution mode */
5095 ctx->bstate = BS_STOP;
5096 // break;
5097 case 2:
5098 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5099 rn = "TraceControl2";
5100 /* Stop translation as we may have switched the execution mode */
5101 ctx->bstate = BS_STOP;
5102 // break;
5103 case 3:
5104 /* Stop translation as we may have switched the execution mode */
5105 ctx->bstate = BS_STOP;
5106 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5107 rn = "UserTraceData";
5108 /* Stop translation as we may have switched the execution mode */
5109 ctx->bstate = BS_STOP;
5110 // break;
5111 case 4:
5112 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5113 /* Stop translation as we may have switched the execution mode */
5114 ctx->bstate = BS_STOP;
5115 rn = "TraceBPC";
5116 // break;
5117 default:
5118 goto die;
5119 }
5120 break;
5121 case 24:
5122 switch (sel) {
5123 case 0:
5124 /* EJTAG support */
5125 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5126 rn = "DEPC";
5127 break;
5128 default:
5129 goto die;
5130 }
5131 break;
5132 case 25:
5133 switch (sel) {
5134 case 0:
5135 gen_helper_mtc0_performance0(cpu_env, arg);
5136 rn = "Performance0";
5137 break;
5138 case 1:
5139 // gen_helper_mtc0_performance1(arg);
5140 rn = "Performance1";
5141 // break;
5142 case 2:
5143 // gen_helper_mtc0_performance2(arg);
5144 rn = "Performance2";
5145 // break;
5146 case 3:
5147 // gen_helper_mtc0_performance3(arg);
5148 rn = "Performance3";
5149 // break;
5150 case 4:
5151 // gen_helper_mtc0_performance4(arg);
5152 rn = "Performance4";
5153 // break;
5154 case 5:
5155 // gen_helper_mtc0_performance5(arg);
5156 rn = "Performance5";
5157 // break;
5158 case 6:
5159 // gen_helper_mtc0_performance6(arg);
5160 rn = "Performance6";
5161 // break;
5162 case 7:
5163 // gen_helper_mtc0_performance7(arg);
5164 rn = "Performance7";
5165 // break;
5166 default:
5167 goto die;
5168 }
5169 break;
5170 case 26:
5171 /* ignored */
5172 rn = "ECC";
5173 break;
5174 case 27:
5175 switch (sel) {
5176 case 0 ... 3:
5177 /* ignored */
5178 rn = "CacheErr";
5179 break;
5180 default:
5181 goto die;
5182 }
5183 break;
5184 case 28:
5185 switch (sel) {
5186 case 0:
5187 case 2:
5188 case 4:
5189 case 6:
5190 gen_helper_mtc0_taglo(cpu_env, arg);
5191 rn = "TagLo";
5192 break;
5193 case 1:
5194 case 3:
5195 case 5:
5196 case 7:
5197 gen_helper_mtc0_datalo(cpu_env, arg);
5198 rn = "DataLo";
5199 break;
5200 default:
5201 goto die;
5202 }
5203 break;
5204 case 29:
5205 switch (sel) {
5206 case 0:
5207 case 2:
5208 case 4:
5209 case 6:
5210 gen_helper_mtc0_taghi(cpu_env, arg);
5211 rn = "TagHi";
5212 break;
5213 case 1:
5214 case 3:
5215 case 5:
5216 case 7:
5217 gen_helper_mtc0_datahi(cpu_env, arg);
5218 rn = "DataHi";
5219 break;
5220 default:
5221 rn = "invalid sel";
5222 goto die;
5223 }
5224 break;
5225 case 30:
5226 switch (sel) {
5227 case 0:
5228 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5229 rn = "ErrorEPC";
5230 break;
5231 default:
5232 goto die;
5233 }
5234 break;
5235 case 31:
5236 switch (sel) {
5237 case 0:
5238 /* EJTAG support */
5239 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5240 rn = "DESAVE";
5241 break;
5242 default:
5243 goto die;
5244 }
5245 /* Stop translation as we may have switched the execution mode */
5246 ctx->bstate = BS_STOP;
5247 break;
5248 default:
5249 goto die;
5250 }
5251 (void)rn; /* avoid a compiler warning */
5252 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5253 /* For simplicity assume that all writes can cause interrupts. */
5254 if (use_icount) {
5255 gen_io_end();
5256 ctx->bstate = BS_STOP;
5257 }
5258 return;
5259
5260 die:
5261 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5262 generate_exception(ctx, EXCP_RI);
5263 }
5264
5265 #if defined(TARGET_MIPS64)
5266 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5267 {
5268 const char *rn = "invalid";
5269
5270 if (sel != 0)
5271 check_insn(ctx, ISA_MIPS64);
5272
5273 switch (reg) {
5274 case 0:
5275 switch (sel) {
5276 case 0:
5277 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5278 rn = "Index";
5279 break;
5280 case 1:
5281 check_insn(ctx, ASE_MT);
5282 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5283 rn = "MVPControl";
5284 break;
5285 case 2:
5286 check_insn(ctx, ASE_MT);
5287 gen_helper_mfc0_mvpconf0(arg, cpu_env);
5288 rn = "MVPConf0";
5289 break;
5290 case 3:
5291 check_insn(ctx, ASE_MT);
5292 gen_helper_mfc0_mvpconf1(arg, cpu_env);
5293 rn = "MVPConf1";
5294 break;
5295 default:
5296 goto die;
5297 }
5298 break;
5299 case 1:
5300 switch (sel) {
5301 case 0:
5302 gen_helper_mfc0_random(arg, cpu_env);
5303 rn = "Random";
5304 break;
5305 case 1:
5306 check_insn(ctx, ASE_MT);
5307 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5308 rn = "VPEControl";
5309 break;
5310 case 2:
5311 check_insn(ctx, ASE_MT);
5312 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5313 rn = "VPEConf0";
5314 break;
5315 case 3:
5316 check_insn(ctx, ASE_MT);
5317 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5318 rn = "VPEConf1";
5319 break;
5320 case 4:
5321 check_insn(ctx, ASE_MT);
5322 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5323 rn = "YQMask";
5324 break;
5325 case 5:
5326 check_insn(ctx, ASE_MT);
5327 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5328 rn = "VPESchedule";
5329 break;
5330 case 6:
5331 check_insn(ctx, ASE_MT);
5332 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5333 rn = "VPEScheFBack";
5334 break;
5335 case 7:
5336 check_insn(ctx, ASE_MT);
5337 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5338 rn = "VPEOpt";
5339 break;
5340 default:
5341 goto die;
5342 }
5343 break;
5344 case 2:
5345 switch (sel) {
5346 case 0:
5347 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5348 rn = "EntryLo0";
5349 break;
5350 case 1:
5351 check_insn(ctx, ASE_MT);
5352 gen_helper_mfc0_tcstatus(arg, cpu_env);
5353 rn = "TCStatus";
5354 break;
5355 case 2:
5356 check_insn(ctx, ASE_MT);
5357 gen_helper_mfc0_tcbind(arg, cpu_env);
5358 rn = "TCBind";
5359 break;
5360 case 3:
5361 check_insn(ctx, ASE_MT);
5362 gen_helper_dmfc0_tcrestart(arg, cpu_env);
5363 rn = "TCRestart";
5364 break;
5365 case 4:
5366 check_insn(ctx, ASE_MT);
5367 gen_helper_dmfc0_tchalt(arg, cpu_env);
5368 rn = "TCHalt";
5369 break;
5370 case 5:
5371 check_insn(ctx, ASE_MT);
5372 gen_helper_dmfc0_tccontext(arg, cpu_env);
5373 rn = "TCContext";
5374 break;
5375 case 6:
5376 check_insn(ctx, ASE_MT);
5377 gen_helper_dmfc0_tcschedule(arg, cpu_env);
5378 rn = "TCSchedule";
5379 break;
5380 case 7:
5381 check_insn(ctx, ASE_MT);
5382 gen_helper_dmfc0_tcschefback(arg, cpu_env);
5383 rn = "TCScheFBack";
5384 break;
5385 default:
5386 goto die;
5387 }
5388 break;
5389 case 3:
5390 switch (sel) {
5391 case 0:
5392 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5393 rn = "EntryLo1";
5394 break;
5395 default:
5396 goto die;
5397 }
5398 break;
5399 case 4:
5400 switch (sel) {
5401 case 0:
5402 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5403 rn = "Context";
5404 break;
5405 case 1:
5406 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5407 rn = "ContextConfig";
5408 // break;
5409 default:
5410 goto die;
5411 }
5412 break;
5413 case 5:
5414 switch (sel) {
5415 case 0:
5416 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5417 rn = "PageMask";
5418 break;
5419 case 1:
5420 check_insn(ctx, ISA_MIPS32R2);
5421 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5422 rn = "PageGrain";
5423 break;
5424 default:
5425 goto die;
5426 }
5427 break;
5428 case 6:
5429 switch (sel) {
5430 case 0:
5431 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5432 rn = "Wired";
5433 break;
5434 case 1:
5435 check_insn(ctx, ISA_MIPS32R2);
5436 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5437 rn = "SRSConf0";
5438 break;
5439 case 2:
5440 check_insn(ctx, ISA_MIPS32R2);
5441 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5442 rn = "SRSConf1";
5443 break;
5444 case 3:
5445 check_insn(ctx, ISA_MIPS32R2);
5446 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5447 rn = "SRSConf2";
5448 break;
5449 case 4:
5450 check_insn(ctx, ISA_MIPS32R2);
5451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5452 rn = "SRSConf3";
5453 break;
5454 case 5:
5455 check_insn(ctx, ISA_MIPS32R2);
5456 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5457 rn = "SRSConf4";
5458 break;
5459 default:
5460 goto die;
5461 }
5462 break;
5463 case 7:
5464 switch (sel) {
5465 case 0:
5466 check_insn(ctx, ISA_MIPS32R2);
5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5468 rn = "HWREna";
5469 break;
5470 default:
5471 goto die;
5472 }
5473 break;
5474 case 8:
5475 switch (sel) {
5476 case 0:
5477 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5478 rn = "BadVAddr";
5479 break;
5480 default:
5481 goto die;
5482 }
5483 break;
5484 case 9:
5485 switch (sel) {
5486 case 0:
5487 /* Mark as an IO operation because we read the time. */
5488 if (use_icount)
5489 gen_io_start();
5490 gen_helper_mfc0_count(arg, cpu_env);
5491 if (use_icount) {
5492 gen_io_end();
5493 }
5494 /* Break the TB to be able to take timer interrupts immediately
5495 after reading count. */
5496 ctx->bstate = BS_STOP;
5497 rn = "Count";
5498 break;
5499 /* 6,7 are implementation dependent */
5500 default:
5501 goto die;
5502 }
5503 break;
5504 case 10:
5505 switch (sel) {
5506 case 0:
5507 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5508 rn = "EntryHi";
5509 break;
5510 default:
5511 goto die;
5512 }
5513 break;
5514 case 11:
5515 switch (sel) {
5516 case 0:
5517 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5518 rn = "Compare";
5519 break;
5520 /* 6,7 are implementation dependent */
5521 default:
5522 goto die;
5523 }
5524 break;
5525 case 12:
5526 switch (sel) {
5527 case 0:
5528 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5529 rn = "Status";
5530 break;
5531 case 1:
5532 check_insn(ctx, ISA_MIPS32R2);
5533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5534 rn = "IntCtl";
5535 break;
5536 case 2:
5537 check_insn(ctx, ISA_MIPS32R2);
5538 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5539 rn = "SRSCtl";
5540 break;
5541 case 3:
5542 check_insn(ctx, ISA_MIPS32R2);
5543 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5544 rn = "SRSMap";
5545 break;
5546 default:
5547 goto die;
5548 }
5549 break;
5550 case 13:
5551 switch (sel) {
5552 case 0:
5553 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5554 rn = "Cause";
5555 break;
5556 default:
5557 goto die;
5558 }
5559 break;
5560 case 14:
5561 switch (sel) {
5562 case 0:
5563 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5564 rn = "EPC";
5565 break;
5566 default:
5567 goto die;
5568 }
5569 break;
5570 case 15:
5571 switch (sel) {
5572 case 0:
5573 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5574 rn = "PRid";
5575 break;
5576 case 1:
5577 check_insn(ctx, ISA_MIPS32R2);
5578 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5579 rn = "EBase";
5580 break;
5581 default:
5582 goto die;
5583 }
5584 break;
5585 case 16:
5586 switch (sel) {
5587 case 0:
5588 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5589 rn = "Config";
5590 break;
5591 case 1:
5592 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5593 rn = "Config1";
5594 break;
5595 case 2:
5596 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5597 rn = "Config2";
5598 break;
5599 case 3:
5600 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5601 rn = "Config3";
5602 break;
5603 /* 6,7 are implementation dependent */
5604 case 6:
5605 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5606 rn = "Config6";
5607 break;
5608 case 7:
5609 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5610 rn = "Config7";
5611 break;
5612 default:
5613 goto die;
5614 }
5615 break;
5616 case 17:
5617 switch (sel) {
5618 case 0:
5619 gen_helper_dmfc0_lladdr(arg, cpu_env);
5620 rn = "LLAddr";
5621 break;
5622 default:
5623 goto die;
5624 }
5625 break;
5626 case 18:
5627 switch (sel) {
5628 case 0 ... 7:
5629 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5630 rn = "WatchLo";
5631 break;
5632 default:
5633 goto die;
5634 }
5635 break;
5636 case 19:
5637 switch (sel) {
5638 case 0 ... 7:
5639 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5640 rn = "WatchHi";
5641 break;
5642 default:
5643 goto die;
5644 }
5645 break;
5646 case 20:
5647 switch (sel) {
5648 case 0:
5649 check_insn(ctx, ISA_MIPS3);
5650 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5651 rn = "XContext";
5652 break;
5653 default:
5654 goto die;
5655 }
5656 break;
5657 case 21:
5658 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5659 switch (sel) {
5660 case 0:
5661 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5662 rn = "Framemask";
5663 break;
5664 default:
5665 goto die;
5666 }
5667 break;
5668 case 22:
5669 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5670 rn = "'Diagnostic"; /* implementation dependent */
5671 break;
5672 case 23:
5673 switch (sel) {
5674 case 0:
5675 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5676 rn = "Debug";
5677 break;
5678 case 1:
5679 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5680 rn = "TraceControl";
5681 // break;
5682 case 2:
5683 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5684 rn = "TraceControl2";
5685 // break;
5686 case 3:
5687 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5688 rn = "UserTraceData";
5689 // break;
5690 case 4:
5691 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5692 rn = "TraceBPC";
5693 // break;
5694 default:
5695 goto die;
5696 }
5697 break;
5698 case 24:
5699 switch (sel) {
5700 case 0:
5701 /* EJTAG support */
5702 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5703 rn = "DEPC";
5704 break;
5705 default:
5706 goto die;
5707 }
5708 break;
5709 case 25:
5710 switch (sel) {
5711 case 0:
5712 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5713 rn = "Performance0";
5714 break;
5715 case 1:
5716 // gen_helper_dmfc0_performance1(arg);
5717 rn = "Performance1";
5718 // break;
5719 case 2:
5720 // gen_helper_dmfc0_performance2(arg);
5721 rn = "Performance2";
5722 // break;
5723 case 3:
5724 // gen_helper_dmfc0_performance3(arg);
5725 rn = "Performance3";
5726 // break;
5727 case 4:
5728 // gen_helper_dmfc0_performance4(arg);
5729 rn = "Performance4";
5730 // break;
5731 case 5:
5732 // gen_helper_dmfc0_performance5(arg);
5733 rn = "Performance5";
5734 // break;
5735 case 6:
5736 // gen_helper_dmfc0_performance6(arg);
5737 rn = "Performance6";
5738 // break;
5739 case 7:
5740 // gen_helper_dmfc0_performance7(arg);
5741 rn = "Performance7";
5742 // break;
5743 default:
5744 goto die;
5745 }
5746 break;
5747 case 26:
5748 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5749 rn = "ECC";
5750 break;
5751 case 27:
5752 switch (sel) {
5753 /* ignored */
5754 case 0 ... 3:
5755 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5756 rn = "CacheErr";
5757 break;
5758 default:
5759 goto die;
5760 }
5761 break;
5762 case 28:
5763 switch (sel) {
5764 case 0:
5765 case 2:
5766 case 4:
5767 case 6:
5768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5769 rn = "TagLo";
5770 break;
5771 case 1:
5772 case 3:
5773 case 5:
5774 case 7:
5775 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5776 rn = "DataLo";
5777 break;
5778 default:
5779 goto die;
5780 }
5781 break;
5782 case 29:
5783 switch (sel) {
5784 case 0:
5785 case 2:
5786 case 4:
5787 case 6:
5788 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5789 rn = "TagHi";
5790 break;
5791 case 1:
5792 case 3:
5793 case 5:
5794 case 7:
5795 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5796 rn = "DataHi";
5797 break;
5798 default:
5799 goto die;
5800 }
5801 break;
5802 case 30:
5803 switch (sel) {
5804 case 0:
5805 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5806 rn = "ErrorEPC";
5807 break;
5808 default:
5809 goto die;
5810 }
5811 break;
5812 case 31:
5813 switch (sel) {
5814 case 0:
5815 /* EJTAG support */
5816 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5817 rn = "DESAVE";
5818 break;
5819 default:
5820 goto die;
5821 }
5822 break;
5823 default:
5824 goto die;
5825 }
5826 (void)rn; /* avoid a compiler warning */
5827 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5828 return;
5829
5830 die:
5831 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5832 generate_exception(ctx, EXCP_RI);
5833 }
5834
5835 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5836 {
5837 const char *rn = "invalid";
5838
5839 if (sel != 0)
5840 check_insn(ctx, ISA_MIPS64);
5841
5842 if (use_icount)
5843 gen_io_start();
5844
5845 switch (reg) {
5846 case 0:
5847 switch (sel) {
5848 case 0:
5849 gen_helper_mtc0_index(cpu_env, arg);
5850 rn = "Index";
5851 break;
5852 case 1:
5853 check_insn(ctx, ASE_MT);
5854 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5855 rn = "MVPControl";
5856 break;
5857 case 2:
5858 check_insn(ctx, ASE_MT);
5859 /* ignored */
5860 rn = "MVPConf0";
5861 break;
5862 case 3:
5863 check_insn(ctx, ASE_MT);
5864 /* ignored */
5865 rn = "MVPConf1";
5866 break;
5867 default:
5868 goto die;
5869 }
5870 break;
5871 case 1:
5872 switch (sel) {
5873 case 0:
5874 /* ignored */
5875 rn = "Random";
5876 break;
5877 case 1:
5878 check_insn(ctx, ASE_MT);
5879 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5880 rn = "VPEControl";
5881 break;
5882 case 2:
5883 check_insn(ctx, ASE_MT);
5884 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5885 rn = "VPEConf0";
5886 break;
5887 case 3:
5888 check_insn(ctx, ASE_MT);
5889 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5890 rn = "VPEConf1";
5891 break;
5892 case 4:
5893 check_insn(ctx, ASE_MT);
5894 gen_helper_mtc0_yqmask(cpu_env, arg);
5895 rn = "YQMask";
5896 break;
5897 case 5:
5898 check_insn(ctx, ASE_MT);
5899 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5900 rn = "VPESchedule";
5901 break;
5902 case 6:
5903 check_insn(ctx, ASE_MT);
5904 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5905 rn = "VPEScheFBack";
5906 break;
5907 case 7:
5908 check_insn(ctx, ASE_MT);
5909 gen_helper_mtc0_vpeopt(cpu_env, arg);
5910 rn = "VPEOpt";
5911 break;
5912 default:
5913 goto die;
5914 }
5915 break;
5916 case 2:
5917 switch (sel) {
5918 case 0:
5919 gen_helper_mtc0_entrylo0(cpu_env, arg);
5920 rn = "EntryLo0";
5921 break;
5922 case 1:
5923 check_insn(ctx, ASE_MT);
5924 gen_helper_mtc0_tcstatus(cpu_env, arg);
5925 rn = "TCStatus";
5926 break;
5927 case 2:
5928 check_insn(ctx, ASE_MT);
5929 gen_helper_mtc0_tcbind(cpu_env, arg);
5930 rn = "TCBind";
5931 break;
5932 case 3:
5933 check_insn(ctx, ASE_MT);
5934 gen_helper_mtc0_tcrestart(cpu_env, arg);
5935 rn = "TCRestart";
5936 break;
5937 case 4:
5938 check_insn(ctx, ASE_MT);
5939 gen_helper_mtc0_tchalt(cpu_env, arg);
5940 rn = "TCHalt";
5941 break;
5942 case 5:
5943 check_insn(ctx, ASE_MT);
5944 gen_helper_mtc0_tccontext(cpu_env, arg);
5945 rn = "TCContext";
5946 break;
5947 case 6:
5948 check_insn(ctx, ASE_MT);
5949 gen_helper_mtc0_tcschedule(cpu_env, arg);
5950 rn = "TCSchedule";
5951 break;
5952 case 7:
5953 check_insn(ctx, ASE_MT);
5954 gen_helper_mtc0_tcschefback(cpu_env, arg);
5955 rn = "TCScheFBack";
5956 break;
5957 default:
5958 goto die;
5959 }
5960 break;
5961 case 3:
5962 switch (sel) {
5963 case 0:
5964 gen_helper_mtc0_entrylo1(cpu_env, arg);
5965 rn = "EntryLo1";
5966 break;
5967 default:
5968 goto die;
5969 }
5970 break;
5971 case 4:
5972 switch (sel) {
5973 case 0:
5974 gen_helper_mtc0_context(cpu_env, arg);
5975 rn = "Context";
5976 break;
5977 case 1:
5978 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5979 rn = "ContextConfig";
5980 // break;
5981 default:
5982 goto die;
5983 }
5984 break;
5985 case 5:
5986 switch (sel) {
5987 case 0:
5988 gen_helper_mtc0_pagemask(cpu_env, arg);
5989 rn = "PageMask";
5990 break;
5991 case 1:
5992 check_insn(ctx, ISA_MIPS32R2);
5993 gen_helper_mtc0_pagegrain(cpu_env, arg);
5994 rn = "PageGrain";
5995 break;
5996 default:
5997 goto die;
5998 }
5999 break;
6000 case 6:
6001 switch (sel) {
6002 case 0:
6003 gen_helper_mtc0_wired(cpu_env, arg);
6004 rn = "Wired";
6005 break;
6006 case 1:
6007 check_insn(ctx, ISA_MIPS32R2);
6008 gen_helper_mtc0_srsconf0(cpu_env, arg);
6009 rn = "SRSConf0";
6010 break;
6011 case 2:
6012 check_insn(ctx, ISA_MIPS32R2);
6013 gen_helper_mtc0_srsconf1(cpu_env, arg);
6014 rn = "SRSConf1";
6015 break;
6016 case 3:
6017 check_insn(ctx, ISA_MIPS32R2);
6018 gen_helper_mtc0_srsconf2(cpu_env, arg);
6019 rn = "SRSConf2";
6020 break;
6021 case 4:
6022 check_insn(ctx, ISA_MIPS32R2);
6023 gen_helper_mtc0_srsconf3(cpu_env, arg);
6024 rn = "SRSConf3";
6025 break;
6026 case 5:
6027 check_insn(ctx, ISA_MIPS32R2);
6028 gen_helper_mtc0_srsconf4(cpu_env, arg);
6029 rn = "SRSConf4";
6030 break;
6031 default:
6032 goto die;
6033 }
6034 break;
6035 case 7:
6036 switch (sel) {
6037 case 0:
6038 check_insn(ctx, ISA_MIPS32R2);
6039 gen_helper_mtc0_hwrena(cpu_env, arg);
6040 rn = "HWREna";
6041 break;
6042 default:
6043 goto die;
6044 }
6045 break;
6046 case 8:
6047 /* ignored */
6048 rn = "BadVAddr";
6049 break;
6050 case 9:
6051 switch (sel) {
6052 case 0:
6053 gen_helper_mtc0_count(cpu_env, arg);
6054 rn = "Count";
6055 break;
6056 /* 6,7 are implementation dependent */
6057 default:
6058 goto die;
6059 }
6060 /* Stop translation as we may have switched the execution mode */
6061 ctx->bstate = BS_STOP;
6062 break;
6063 case 10:
6064 switch (sel) {
6065 case 0:
6066 gen_helper_mtc0_entryhi(cpu_env, arg);
6067 rn = "EntryHi";
6068 break;
6069 default:
6070 goto die;
6071 }
6072 break;
6073 case 11:
6074 switch (sel) {
6075 case 0:
6076 gen_helper_mtc0_compare(cpu_env, arg);
6077 rn = "Compare";
6078 break;
6079 /* 6,7 are implementation dependent */
6080 default:
6081 goto die;
6082 }
6083 /* Stop translation as we may have switched the execution mode */
6084 ctx->bstate = BS_STOP;
6085 break;
6086 case 12:
6087 switch (sel) {
6088 case 0:
6089 save_cpu_state(ctx, 1);
6090 gen_helper_mtc0_status(cpu_env, arg);
6091 /* BS_STOP isn't good enough here, hflags may have changed. */
6092 gen_save_pc(ctx->pc + 4);
6093 ctx->bstate = BS_EXCP;
6094 rn = "Status";
6095 break;
6096 case 1:
6097 check_insn(ctx, ISA_MIPS32R2);
6098 gen_helper_mtc0_intctl(cpu_env, arg);
6099 /* Stop translation as we may have switched the execution mode */
6100 ctx->bstate = BS_STOP;
6101 rn = "IntCtl";
6102 break;
6103 case 2:
6104 check_insn(ctx, ISA_MIPS32R2);
6105 gen_helper_mtc0_srsctl(cpu_env, arg);
6106 /* Stop translation as we may have switched the execution mode */
6107 ctx->bstate = BS_STOP;
6108 rn = "SRSCtl";
6109 break;
6110 case 3:
6111 check_insn(ctx, ISA_MIPS32R2);
6112 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6113 /* Stop translation as we may have switched the execution mode */
6114 ctx->bstate = BS_STOP;
6115 rn = "SRSMap";
6116 break;
6117 default:
6118 goto die;
6119 }
6120 break;
6121 case 13:
6122 switch (sel) {
6123 case 0:
6124 save_cpu_state(ctx, 1);
6125 /* Mark as an IO operation because we may trigger a software
6126 interrupt. */
6127 if (use_icount) {
6128 gen_io_start();
6129 }
6130 gen_helper_mtc0_cause(cpu_env, arg);
6131 if (use_icount) {
6132 gen_io_end();
6133 }
6134 /* Stop translation as we may have triggered an intetrupt */
6135 ctx->bstate = BS_STOP;
6136 rn = "Cause";
6137 break;
6138 default:
6139 goto die;
6140 }
6141 break;
6142 case 14:
6143 switch (sel) {
6144 case 0:
6145 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6146 rn = "EPC";
6147 break;
6148 default:
6149 goto die;
6150 }
6151 break;
6152 case 15:
6153 switch (sel) {
6154 case 0:
6155 /* ignored */
6156 rn = "PRid";
6157 break;
6158 case 1:
6159 check_insn(ctx, ISA_MIPS32R2);
6160 gen_helper_mtc0_ebase(cpu_env, arg);
6161 rn = "EBase";
6162 break;
6163 default:
6164 goto die;
6165 }
6166 break;
6167 case 16:
6168 switch (sel) {
6169 case 0:
6170 gen_helper_mtc0_config0(cpu_env, arg);
6171 rn = "Config";
6172 /* Stop translation as we may have switched the execution mode */
6173 ctx->bstate = BS_STOP;
6174 break;
6175 case 1:
6176 /* ignored, read only */
6177 rn = "Config1";
6178 break;
6179 case 2:
6180 gen_helper_mtc0_config2(cpu_env, arg);
6181 rn = "Config2";
6182 /* Stop translation as we may have switched the execution mode */
6183 ctx->bstate = BS_STOP;
6184 break;
6185 case 3:
6186 /* ignored */
6187 rn = "Config3";
6188 break;
6189 /* 6,7 are implementation dependent */
6190 default:
6191 rn = "Invalid config selector";
6192 goto die;
6193 }
6194 break;
6195 case 17:
6196 switch (sel) {
6197 case 0:
6198 gen_helper_mtc0_lladdr(cpu_env, arg);
6199 rn = "LLAddr";
6200 break;
6201 default:
6202 goto die;
6203 }
6204 break;
6205 case 18:
6206 switch (sel) {
6207 case 0 ... 7:
6208 gen_helper_0e1i(mtc0_watchlo, arg, sel);
6209 rn = "WatchLo";
6210 break;
6211 default:
6212 goto die;
6213 }
6214 break;
6215 case 19:
6216 switch (sel) {
6217 case 0 ... 7:
6218 gen_helper_0e1i(mtc0_watchhi, arg, sel);
6219 rn = "WatchHi";
6220 break;
6221 default:
6222 goto die;
6223 }
6224 break;
6225 case 20:
6226 switch (sel) {
6227 case 0:
6228 check_insn(ctx, ISA_MIPS3);
6229 gen_helper_mtc0_xcontext(cpu_env, arg);
6230 rn = "XContext";
6231 break;
6232 default:
6233 goto die;
6234 }
6235 break;
6236 case 21:
6237 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6238 switch (sel) {
6239 case 0:
6240 gen_helper_mtc0_framemask(cpu_env, arg);
6241 rn = "Framemask";
6242 break;
6243 default:
6244 goto die;
6245 }
6246 break;
6247 case 22:
6248 /* ignored */
6249 rn = "Diagnostic"; /* implementation dependent */
6250 break;
6251 case 23:
6252 switch (sel) {
6253 case 0:
6254 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6255 /* BS_STOP isn't good enough here, hflags may have changed. */
6256 gen_save_pc(ctx->pc + 4);
6257 ctx->bstate = BS_EXCP;
6258 rn = "Debug";
6259 break;
6260 case 1:
6261 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6262 /* Stop translation as we may have switched the execution mode */
6263 ctx->bstate = BS_STOP;
6264 rn = "TraceControl";
6265 // break;
6266 case 2:
6267 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6268 /* Stop translation as we may have switched the execution mode */
6269 ctx->bstate = BS_STOP;
6270 rn = "TraceControl2";
6271 // break;
6272 case 3:
6273 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6274 /* Stop translation as we may have switched the execution mode */
6275 ctx->bstate = BS_STOP;
6276 rn = "UserTraceData";
6277 // break;
6278 case 4:
6279 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6280 /* Stop translation as we may have switched the execution mode */
6281 ctx->bstate = BS_STOP;
6282 rn = "TraceBPC";
6283 // break;
6284 default:
6285 goto die;
6286 }
6287 break;
6288 case 24:
6289 switch (sel) {
6290 case 0:
6291 /* EJTAG support */
6292 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6293 rn = "DEPC";
6294 break;
6295 default:
6296 goto die;
6297 }
6298 break;
6299 case 25:
6300 switch (sel) {
6301 case 0:
6302 gen_helper_mtc0_performance0(cpu_env, arg);
6303 rn = "Performance0";
6304 break;
6305 case 1:
6306 // gen_helper_mtc0_performance1(cpu_env, arg);
6307 rn = "Performance1";
6308 // break;
6309 case 2:
6310 // gen_helper_mtc0_performance2(cpu_env, arg);
6311 rn = "Performance2";
6312 // break;
6313 case 3:
6314 // gen_helper_mtc0_performance3(cpu_env, arg);
6315 rn = "Performance3";
6316 // break;
6317 case 4:
6318 // gen_helper_mtc0_performance4(cpu_env, arg);
6319 rn = "Performance4";
6320 // break;
6321 case 5:
6322 // gen_helper_mtc0_performance5(cpu_env, arg);
6323 rn = "Performance5";
6324 // break;
6325 case 6:
6326 // gen_helper_mtc0_performance6(cpu_env, arg);
6327 rn = "Performance6";
6328 // break;
6329 case 7:
6330 // gen_helper_mtc0_performance7(cpu_env, arg);
6331 rn = "Performance7";
6332 // break;
6333 default:
6334 goto die;
6335 }
6336 break;
6337 case 26:
6338 /* ignored */
6339 rn = "ECC";
6340 break;
6341 case 27:
6342 switch (sel) {
6343 case 0 ... 3:
6344 /* ignored */
6345 rn = "CacheErr";
6346 break;
6347 default:
6348 goto die;
6349 }
6350 break;
6351 case 28:
6352 switch (sel) {
6353 case 0:
6354 case 2:
6355 case 4:
6356 case 6:
6357 gen_helper_mtc0_taglo(cpu_env, arg);
6358 rn = "TagLo";
6359 break;
6360 case 1:
6361 case 3:
6362 case 5:
6363 case 7:
6364 gen_helper_mtc0_datalo(cpu_env, arg);
6365 rn = "DataLo";
6366 break;
6367 default:
6368 goto die;
6369 }
6370 break;
6371 case 29:
6372 switch (sel) {
6373 case 0:
6374 case 2:
6375 case 4:
6376 case 6:
6377 gen_helper_mtc0_taghi(cpu_env, arg);
6378 rn = "TagHi";
6379 break;
6380 case 1:
6381 case 3:
6382 case 5:
6383 case 7:
6384 gen_helper_mtc0_datahi(cpu_env, arg);
6385 rn = "DataHi";
6386 break;
6387 default:
6388 rn = "invalid sel";
6389 goto die;
6390 }
6391 break;
6392 case 30:
6393 switch (sel) {
6394 case 0:
6395 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6396 rn = "ErrorEPC";
6397 break;
6398 default:
6399 goto die;
6400 }
6401 break;
6402 case 31:
6403 switch (sel) {
6404 case 0:
6405 /* EJTAG support */
6406 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6407 rn = "DESAVE";
6408 break;
6409 default:
6410 goto die;
6411 }
6412 /* Stop translation as we may have switched the execution mode */
6413 ctx->bstate = BS_STOP;
6414 break;
6415 default:
6416 goto die;
6417 }
6418 (void)rn; /* avoid a compiler warning */
6419 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6420 /* For simplicity assume that all writes can cause interrupts. */
6421 if (use_icount) {
6422 gen_io_end();
6423 ctx->bstate = BS_STOP;
6424 }
6425 return;
6426
6427 die:
6428 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6429 generate_exception(ctx, EXCP_RI);
6430 }
6431 #endif /* TARGET_MIPS64 */
6432
6433 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6434 int u, int sel, int h)
6435 {
6436 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6437 TCGv t0 = tcg_temp_local_new();
6438
6439 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6440 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6441 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6442 tcg_gen_movi_tl(t0, -1);
6443 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6444 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6445 tcg_gen_movi_tl(t0, -1);
6446 else if (u == 0) {
6447 switch (rt) {
6448 case 1:
6449 switch (sel) {
6450 case 1:
6451 gen_helper_mftc0_vpecontrol(t0, cpu_env);
6452 break;
6453 case 2:
6454 gen_helper_mftc0_vpeconf0(t0, cpu_env);
6455 break;
6456 default:
6457 goto die;
6458 break;
6459 }
6460 break;
6461 case 2:
6462 switch (sel) {
6463 case 1:
6464 gen_helper_mftc0_tcstatus(t0, cpu_env);
6465 break;
6466 case 2:
6467 gen_helper_mftc0_tcbind(t0, cpu_env);
6468 break;
6469 case 3:
6470 gen_helper_mftc0_tcrestart(t0, cpu_env);
6471 break;
6472 case 4:
6473 gen_helper_mftc0_tchalt(t0, cpu_env);
6474 break;
6475 case 5:
6476 gen_helper_mftc0_tccontext(t0, cpu_env);
6477 break;
6478 case 6:
6479 gen_helper_mftc0_tcschedule(t0, cpu_env);
6480 break;
6481 case 7:
6482 gen_helper_mftc0_tcschefback(t0, cpu_env);
6483 break;
6484 default:
6485 gen_mfc0(ctx, t0, rt, sel);
6486 break;
6487 }
6488 break;
6489 case 10:
6490 switch (sel) {
6491 case 0:
6492 gen_helper_mftc0_entryhi(t0, cpu_env);
6493 break;
6494 default:
6495 gen_mfc0(ctx, t0, rt, sel);
6496 break;
6497 }
6498 case 12:
6499 switch (sel) {
6500 case 0:
6501 gen_helper_mftc0_status(t0, cpu_env);
6502 break;
6503 default:
6504 gen_mfc0(ctx, t0, rt, sel);
6505 break;
6506 }
6507 case 13:
6508 switch (sel) {
6509 case 0:
6510 gen_helper_mftc0_cause(t0, cpu_env);
6511 break;
6512 default:
6513 goto die;
6514 break;
6515 }
6516 break;
6517 case 14:
6518 switch (sel) {
6519 case 0:
6520 gen_helper_mftc0_epc(t0, cpu_env);
6521 break;
6522 default:
6523 goto die;
6524 break;
6525 }
6526 break;
6527 case 15:
6528 switch (sel) {
6529 case 1:
6530 gen_helper_mftc0_ebase(t0, cpu_env);
6531 break;
6532 default:
6533 goto die;
6534 break;
6535 }
6536 break;
6537 case 16:
6538 switch (sel) {
6539 case 0 ... 7:
6540 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6541 break;
6542 default:
6543 goto die;
6544 break;
6545 }
6546 break;
6547 case 23:
6548 switch (sel) {
6549 case 0:
6550 gen_helper_mftc0_debug(t0, cpu_env);
6551 break;
6552 default:
6553 gen_mfc0(ctx, t0, rt, sel);
6554 break;
6555 }
6556 break;
6557 default:
6558 gen_mfc0(ctx, t0, rt, sel);
6559 }
6560 } else switch (sel) {
6561 /* GPR registers. */
6562 case 0:
6563 gen_helper_1e0i(mftgpr, t0, rt);
6564 break;
6565 /* Auxiliary CPU registers */
6566 case 1:
6567 switch (rt) {
6568 case 0:
6569 gen_helper_1e0i(mftlo, t0, 0);
6570 break;
6571 case 1:
6572 gen_helper_1e0i(mfthi, t0, 0);
6573 break;
6574 case 2:
6575 gen_helper_1e0i(mftacx, t0, 0);
6576 break;
6577 case 4:
6578 gen_helper_1e0i(mftlo, t0, 1);
6579 break;
6580 case 5:
6581 gen_helper_1e0i(mfthi, t0, 1);
6582 break;
6583 case 6:
6584 gen_helper_1e0i(mftacx, t0, 1);
6585 break;
6586 case 8:
6587 gen_helper_1e0i(mftlo, t0, 2);
6588 break;
6589 case 9:
6590 gen_helper_1e0i(mfthi, t0, 2);
6591 break;
6592 case 10:
6593 gen_helper_1e0i(mftacx, t0, 2);
6594 break;
6595 case 12:
6596 gen_helper_1e0i(mftlo, t0, 3);
6597 break;
6598 case 13:
6599 gen_helper_1e0i(mfthi, t0, 3);
6600 break;
6601 case 14:
6602 gen_helper_1e0i(mftacx, t0, 3);
6603 break;
6604 case 16:
6605 gen_helper_mftdsp(t0, cpu_env);
6606 break;
6607 default:
6608 goto die;
6609 }
6610 break;
6611 /* Floating point (COP1). */
6612 case 2:
6613 /* XXX: For now we support only a single FPU context. */
6614 if (h == 0) {
6615 TCGv_i32 fp0 = tcg_temp_new_i32();
6616
6617 gen_load_fpr32(fp0, rt);
6618 tcg_gen_ext_i32_tl(t0, fp0);
6619 tcg_temp_free_i32(fp0);
6620 } else {
6621 TCGv_i32 fp0 = tcg_temp_new_i32();
6622
6623 gen_load_fpr32h(ctx, fp0, rt);
6624 tcg_gen_ext_i32_tl(t0, fp0);
6625 tcg_temp_free_i32(fp0);
6626 }
6627 break;
6628 case 3:
6629 /* XXX: For now we support only a single FPU context. */
6630 gen_helper_1e0i(cfc1, t0, rt);
6631 break;
6632 /* COP2: Not implemented. */
6633 case 4:
6634 case 5:
6635 /* fall through */
6636 default:
6637 goto die;
6638 }
6639 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6640 gen_store_gpr(t0, rd);
6641 tcg_temp_free(t0);
6642 return;
6643
6644 die:
6645 tcg_temp_free(t0);
6646 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6647 generate_exception(ctx, EXCP_RI);
6648 }
6649
6650 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6651 int u, int sel, int h)
6652 {
6653 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6654 TCGv t0 = tcg_temp_local_new();
6655
6656 gen_load_gpr(t0, rt);
6657 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6658 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6659 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6660 /* NOP */ ;
6661 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6662 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6663 /* NOP */ ;
6664 else if (u == 0) {
6665 switch (rd) {
6666 case 1:
6667 switch (sel) {
6668 case 1:
6669 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6670 break;
6671 case 2:
6672 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6673 break;
6674 default:
6675 goto die;
6676 break;
6677 }
6678 break;
6679 case 2:
6680 switch (sel) {
6681 case 1:
6682 gen_helper_mttc0_tcstatus(cpu_env, t0);
6683 break;
6684 case 2:
6685 gen_helper_mttc0_tcbind(cpu_env, t0);
6686 break;
6687 case 3:
6688 gen_helper_mttc0_tcrestart(cpu_env, t0);
6689 break;
6690 case 4:
6691 gen_helper_mttc0_tchalt(cpu_env, t0);
6692 break;
6693 case 5:
6694 gen_helper_mttc0_tccontext(cpu_env, t0);
6695 break;
6696 case 6:
6697 gen_helper_mttc0_tcschedule(cpu_env, t0);
6698 break;
6699 case 7:
6700 gen_helper_mttc0_tcschefback(cpu_env, t0);
6701 break;
6702 default:
6703 gen_mtc0(ctx, t0, rd, sel);
6704 break;
6705 }
6706 break;
6707 case 10:
6708 switch (sel) {
6709 case 0:
6710 gen_helper_mttc0_entryhi(cpu_env, t0);
6711 break;
6712 default:
6713 gen_mtc0(ctx, t0, rd, sel);
6714 break;
6715 }
6716 case 12:
6717 switch (sel) {
6718 case 0:
6719 gen_helper_mttc0_status(cpu_env, t0);
6720 break;
6721 default:
6722 gen_mtc0(ctx, t0, rd, sel);
6723 break;
6724 }
6725 case 13:
6726 switch (sel) {
6727 case 0:
6728 gen_helper_mttc0_cause(cpu_env, t0);
6729 break;
6730 default:
6731 goto die;
6732 break;
6733 }
6734 break;
6735 case 15:
6736 switch (sel) {
6737 case 1:
6738 gen_helper_mttc0_ebase(cpu_env, t0);
6739 break;
6740 default:
6741 goto die;
6742 break;
6743 }
6744 break;
6745 case 23:
6746 switch (sel) {
6747 case 0:
6748 gen_helper_mttc0_debug(cpu_env, t0);
6749 break;
6750 default:
6751 gen_mtc0(ctx, t0, rd, sel);
6752 break;
6753 }
6754 break;
6755 default:
6756 gen_mtc0(ctx, t0, rd, sel);
6757 }
6758 } else switch (sel) {
6759 /* GPR registers. */
6760 case 0:
6761 gen_helper_0e1i(mttgpr, t0, rd);
6762 break;
6763 /* Auxiliary CPU registers */
6764 case 1:
6765 switch (rd) {
6766 case 0:
6767 gen_helper_0e1i(mttlo, t0, 0);
6768 break;
6769 case 1:
6770 gen_helper_0e1i(mtthi, t0, 0);
6771 break;
6772 case 2:
6773 gen_helper_0e1i(mttacx, t0, 0);
6774 break;
6775 case 4:
6776 gen_helper_0e1i(mttlo, t0, 1);
6777 break;
6778 case 5:
6779 gen_helper_0e1i(mtthi, t0, 1);
6780 break;
6781 case 6:
6782 gen_helper_0e1i(mttacx, t0, 1);
6783 break;
6784 case 8:
6785 gen_helper_0e1i(mttlo, t0, 2);
6786 break;
6787 case 9:
6788 gen_helper_0e1i(mtthi, t0, 2);
6789 break;
6790 case 10:
6791 gen_helper_0e1i(mttacx, t0, 2);
6792 break;
6793 case 12:
6794 gen_helper_0e1i(mttlo, t0, 3);
6795 break;
6796 case 13:
6797 gen_helper_0e1i(mtthi, t0, 3);
6798 break;
6799 case 14:
6800 gen_helper_0e1i(mttacx, t0, 3);
6801 break;
6802 case 16:
6803 gen_helper_mttdsp(cpu_env, t0);
6804 break;
6805 default:
6806 goto die;
6807 }
6808 break;
6809 /* Floating point (COP1). */
6810 case 2:
6811 /* XXX: For now we support only a single FPU context. */
6812 if (h == 0) {
6813 TCGv_i32 fp0 = tcg_temp_new_i32();
6814
6815 tcg_gen_trunc_tl_i32(fp0, t0);
6816 gen_store_fpr32(fp0, rd);
6817 tcg_temp_free_i32(fp0);
6818 } else {
6819 TCGv_i32 fp0 = tcg_temp_new_i32();
6820
6821 tcg_gen_trunc_tl_i32(fp0, t0);
6822 gen_store_fpr32h(ctx, fp0, rd);
6823 tcg_temp_free_i32(fp0);
6824 }
6825 break;
6826 case 3:
6827 /* XXX: For now we support only a single FPU context. */
6828 {
6829 TCGv_i32 fs_tmp = tcg_const_i32(rd);
6830
6831 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
6832 tcg_temp_free_i32(fs_tmp);
6833 }
6834 break;
6835 /* COP2: Not implemented. */
6836 case 4:
6837 case 5:
6838 /* fall through */
6839 default:
6840 goto die;
6841 }
6842 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6843 tcg_temp_free(t0);
6844 return;
6845
6846 die:
6847 tcg_temp_free(t0);
6848 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6849 generate_exception(ctx, EXCP_RI);
6850 }
6851
6852 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6853 {
6854 const char *opn = "ldst";
6855
6856 check_cp0_enabled(ctx);
6857 switch (opc) {
6858 case OPC_MFC0:
6859 if (rt == 0) {
6860 /* Treat as NOP. */
6861 return;
6862 }
6863 gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6864 opn = "mfc0";
6865 break;
6866 case OPC_MTC0:
6867 {
6868 TCGv t0 = tcg_temp_new();
6869
6870 gen_load_gpr(t0, rt);
6871 gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
6872 tcg_temp_free(t0);
6873 }
6874 opn = "mtc0";
6875 break;
6876 #if defined(TARGET_MIPS64)
6877 case OPC_DMFC0:
6878 check_insn(ctx, ISA_MIPS3);
6879 if (rt == 0) {
6880 /* Treat as NOP. */
6881 return;
6882 }
6883 gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6884 opn = "dmfc0";
6885 break;
6886 case OPC_DMTC0:
6887 check_insn(ctx, ISA_MIPS3);
6888 {
6889 TCGv t0 = tcg_temp_new();
6890
6891 gen_load_gpr(t0, rt);
6892 gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
6893 tcg_temp_free(t0);
6894 }
6895 opn = "dmtc0";
6896 break;
6897 #endif
6898 case OPC_MFTR:
6899 check_insn(ctx, ASE_MT);
6900 if (rd == 0) {
6901 /* Treat as NOP. */
6902 return;
6903 }
6904 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6905 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6906 opn = "mftr";
6907 break;
6908 case OPC_MTTR:
6909 check_insn(ctx, ASE_MT);
6910 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6911 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6912 opn = "mttr";
6913 break;
6914 case OPC_TLBWI:
6915 opn = "tlbwi";
6916 if (!env->tlb->helper_tlbwi)
6917 goto die;
6918 gen_helper_tlbwi(cpu_env);
6919 break;
6920 case OPC_TLBWR:
6921 opn = "tlbwr";
6922 if (!env->tlb->helper_tlbwr)
6923 goto die;
6924 gen_helper_tlbwr(cpu_env);
6925 break;
6926 case OPC_TLBP:
6927 opn = "tlbp";
6928 if (!env->tlb->helper_tlbp)
6929 goto die;
6930 gen_helper_tlbp(cpu_env);
6931 break;
6932 case OPC_TLBR:
6933 opn = "tlbr";
6934 if (!env->tlb->helper_tlbr)
6935 goto die;
6936 gen_helper_tlbr(cpu_env);
6937 break;
6938 case OPC_ERET:
6939 opn = "eret";
6940 check_insn(ctx, ISA_MIPS2);
6941 gen_helper_eret(cpu_env);
6942 ctx->bstate = BS_EXCP;
6943 break;
6944 case OPC_DERET:
6945 opn = "deret";
6946 check_insn(ctx, ISA_MIPS32);
6947 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6948 MIPS_INVAL(opn);
6949 generate_exception(ctx, EXCP_RI);
6950 } else {
6951 gen_helper_deret(cpu_env);
6952 ctx->bstate = BS_EXCP;
6953 }
6954 break;
6955 case OPC_WAIT:
6956 opn = "wait";
6957 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
6958 /* If we get an exception, we want to restart at next instruction */
6959 ctx->pc += 4;
6960 save_cpu_state(ctx, 1);
6961 ctx->pc -= 4;
6962 gen_helper_wait(cpu_env);
6963 ctx->bstate = BS_EXCP;
6964 break;
6965 default:
6966 die:
6967 MIPS_INVAL(opn);
6968 generate_exception(ctx, EXCP_RI);
6969 return;
6970 }
6971 (void)opn; /* avoid a compiler warning */
6972 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6973 }
6974 #endif /* !CONFIG_USER_ONLY */
6975
6976 /* CP1 Branches (before delay slot) */
6977 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6978 int32_t cc, int32_t offset)
6979 {
6980 target_ulong btarget;
6981 const char *opn = "cp1 cond branch";
6982 TCGv_i32 t0 = tcg_temp_new_i32();
6983
6984 if (cc != 0)
6985 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
6986
6987 btarget = ctx->pc + 4 + offset;
6988
6989 switch (op) {
6990 case OPC_BC1F:
6991 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6992 tcg_gen_not_i32(t0, t0);
6993 tcg_gen_andi_i32(t0, t0, 1);
6994 tcg_gen_extu_i32_tl(bcond, t0);
6995 opn = "bc1f";
6996 goto not_likely;
6997 case OPC_BC1FL:
6998 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6999 tcg_gen_not_i32(t0, t0);
7000 tcg_gen_andi_i32(t0, t0, 1);
7001 tcg_gen_extu_i32_tl(bcond, t0);
7002 opn = "bc1fl";
7003 goto likely;
7004 case OPC_BC1T:
7005 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7006 tcg_gen_andi_i32(t0, t0, 1);
7007 tcg_gen_extu_i32_tl(bcond, t0);
7008 opn = "bc1t";
7009 goto not_likely;
7010 case OPC_BC1TL:
7011 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7012 tcg_gen_andi_i32(t0, t0, 1);
7013 tcg_gen_extu_i32_tl(bcond, t0);
7014 opn = "bc1tl";
7015 likely:
7016 ctx->hflags |= MIPS_HFLAG_BL;
7017 break;
7018 case OPC_BC1FANY2:
7019 {
7020 TCGv_i32 t1 = tcg_temp_new_i32();
7021 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7022 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7023 tcg_gen_nand_i32(t0, t0, t1);
7024 tcg_temp_free_i32(t1);
7025 tcg_gen_andi_i32(t0, t0, 1);
7026 tcg_gen_extu_i32_tl(bcond, t0);
7027 }
7028 opn = "bc1any2f";
7029 goto not_likely;
7030 case OPC_BC1TANY2:
7031 {
7032 TCGv_i32 t1 = tcg_temp_new_i32();
7033 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7034 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7035 tcg_gen_or_i32(t0, t0, t1);
7036 tcg_temp_free_i32(t1);
7037 tcg_gen_andi_i32(t0, t0, 1);
7038 tcg_gen_extu_i32_tl(bcond, t0);
7039 }
7040 opn = "bc1any2t";
7041 goto not_likely;
7042 case OPC_BC1FANY4:
7043 {
7044 TCGv_i32 t1 = tcg_temp_new_i32();
7045 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7046 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7047 tcg_gen_and_i32(t0, t0, t1);
7048 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7049 tcg_gen_and_i32(t0, t0, t1);
7050 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7051 tcg_gen_nand_i32(t0, t0, t1);
7052 tcg_temp_free_i32(t1);
7053 tcg_gen_andi_i32(t0, t0, 1);
7054 tcg_gen_extu_i32_tl(bcond, t0);
7055 }
7056 opn = "bc1any4f";
7057 goto not_likely;
7058 case OPC_BC1TANY4:
7059 {
7060 TCGv_i32 t1 = tcg_temp_new_i32();
7061 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7062 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7063 tcg_gen_or_i32(t0, t0, t1);
7064 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7065 tcg_gen_or_i32(t0, t0, t1);
7066 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7067 tcg_gen_or_i32(t0, t0, t1);
7068 tcg_temp_free_i32(t1);
7069 tcg_gen_andi_i32(t0, t0, 1);
7070 tcg_gen_extu_i32_tl(bcond, t0);
7071 }
7072 opn = "bc1any4t";
7073 not_likely:
7074 ctx->hflags |= MIPS_HFLAG_BC;
7075 break;
7076 default:
7077 MIPS_INVAL(opn);
7078 generate_exception (ctx, EXCP_RI);
7079 goto out;
7080 }
7081 (void)opn; /* avoid a compiler warning */
7082 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7083 ctx->hflags, btarget);
7084 ctx->btarget = btarget;
7085
7086 out:
7087 tcg_temp_free_i32(t0);
7088 }
7089
7090 /* Coprocessor 1 (FPU) */
7091
7092 #define FOP(func, fmt) (((fmt) << 21) | (func))
7093
7094 enum fopcode {
7095 OPC_ADD_S = FOP(0, FMT_S),
7096 OPC_SUB_S = FOP(1, FMT_S),
7097 OPC_MUL_S = FOP(2, FMT_S),
7098 OPC_DIV_S = FOP(3, FMT_S),
7099 OPC_SQRT_S = FOP(4, FMT_S),
7100 OPC_ABS_S = FOP(5, FMT_S),
7101 OPC_MOV_S = FOP(6, FMT_S),
7102 OPC_NEG_S = FOP(7, FMT_S),
7103 OPC_ROUND_L_S = FOP(8, FMT_S),
7104 OPC_TRUNC_L_S = FOP(9, FMT_S),
7105 OPC_CEIL_L_S = FOP(10, FMT_S),
7106 OPC_FLOOR_L_S = FOP(11, FMT_S),
7107 OPC_ROUND_W_S = FOP(12, FMT_S),
7108 OPC_TRUNC_W_S = FOP(13, FMT_S),
7109 OPC_CEIL_W_S = FOP(14, FMT_S),
7110 OPC_FLOOR_W_S = FOP(15, FMT_S),
7111 OPC_MOVCF_S = FOP(17, FMT_S),
7112 OPC_MOVZ_S = FOP(18, FMT_S),
7113 OPC_MOVN_S = FOP(19, FMT_S),
7114 OPC_RECIP_S = FOP(21, FMT_S),
7115 OPC_RSQRT_S = FOP(22, FMT_S),
7116 OPC_RECIP2_S = FOP(28, FMT_S),
7117 OPC_RECIP1_S = FOP(29, FMT_S),
7118 OPC_RSQRT1_S = FOP(30, FMT_S),
7119 OPC_RSQRT2_S = FOP(31, FMT_S),
7120 OPC_CVT_D_S = FOP(33, FMT_S),
7121 OPC_CVT_W_S = FOP(36, FMT_S),
7122 OPC_CVT_L_S = FOP(37, FMT_S),
7123 OPC_CVT_PS_S = FOP(38, FMT_S),
7124 OPC_CMP_F_S = FOP (48, FMT_S),
7125 OPC_CMP_UN_S = FOP (49, FMT_S),
7126 OPC_CMP_EQ_S = FOP (50, FMT_S),
7127 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7128 OPC_CMP_OLT_S = FOP (52, FMT_S),
7129 OPC_CMP_ULT_S = FOP (53, FMT_S),
7130 OPC_CMP_OLE_S = FOP (54, FMT_S),
7131 OPC_CMP_ULE_S = FOP (55, FMT_S),
7132 OPC_CMP_SF_S = FOP (56, FMT_S),
7133 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7134 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7135 OPC_CMP_NGL_S = FOP (59, FMT_S),
7136 OPC_CMP_LT_S = FOP (60, FMT_S),
7137 OPC_CMP_NGE_S = FOP (61, FMT_S),
7138 OPC_CMP_LE_S = FOP (62, FMT_S),
7139 OPC_CMP_NGT_S = FOP (63, FMT_S),
7140
7141 OPC_ADD_D = FOP(0, FMT_D),
7142 OPC_SUB_D = FOP(1, FMT_D),
7143 OPC_MUL_D = FOP(2, FMT_D),
7144 OPC_DIV_D = FOP(3, FMT_D),
7145 OPC_SQRT_D = FOP(4, FMT_D),
7146 OPC_ABS_D = FOP(5, FMT_D),
7147 OPC_MOV_D = FOP(6, FMT_D),
7148 OPC_NEG_D = FOP(7, FMT_D),
7149 OPC_ROUND_L_D = FOP(8, FMT_D),
7150 OPC_TRUNC_L_D = FOP(9, FMT_D),
7151 OPC_CEIL_L_D = FOP(10, FMT_D),
7152 OPC_FLOOR_L_D = FOP(11, FMT_D),
7153 OPC_ROUND_W_D = FOP(12, FMT_D),
7154 OPC_TRUNC_W_D = FOP(13, FMT_D),
7155 OPC_CEIL_W_D = FOP(14, FMT_D),
7156 OPC_FLOOR_W_D = FOP(15, FMT_D),
7157 OPC_MOVCF_D = FOP(17, FMT_D),
7158 OPC_MOVZ_D = FOP(18, FMT_D),
7159 OPC_MOVN_D = FOP(19, FMT_D),
7160 OPC_RECIP_D = FOP(21, FMT_D),
7161 OPC_RSQRT_D = FOP(22, FMT_D),
7162 OPC_RECIP2_D = FOP(28, FMT_D),
7163 OPC_RECIP1_D = FOP(29, FMT_D),
7164 OPC_RSQRT1_D = FOP(30, FMT_D),
7165 OPC_RSQRT2_D = FOP(31, FMT_D),
7166 OPC_CVT_S_D = FOP(32, FMT_D),
7167 OPC_CVT_W_D = FOP(36, FMT_D),
7168 OPC_CVT_L_D = FOP(37, FMT_D),
7169 OPC_CMP_F_D = FOP (48, FMT_D),
7170 OPC_CMP_UN_D = FOP (49, FMT_D),
7171 OPC_CMP_EQ_D = FOP (50, FMT_D),
7172 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7173 OPC_CMP_OLT_D = FOP (52, FMT_D),
7174 OPC_CMP_ULT_D = FOP (53, FMT_D),
7175 OPC_CMP_OLE_D = FOP (54, FMT_D),
7176 OPC_CMP_ULE_D = FOP (55, FMT_D),
7177 OPC_CMP_SF_D = FOP (56, FMT_D),
7178 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7179 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7180 OPC_CMP_NGL_D = FOP (59, FMT_D),
7181 OPC_CMP_LT_D = FOP (60, FMT_D),
7182 OPC_CMP_NGE_D = FOP (61, FMT_D),
7183 OPC_CMP_LE_D = FOP (62, FMT_D),
7184 OPC_CMP_NGT_D = FOP (63, FMT_D),
7185
7186 OPC_CVT_S_W = FOP(32, FMT_W),
7187 OPC_CVT_D_W = FOP(33, FMT_W),
7188 OPC_CVT_S_L = FOP(32, FMT_L),
7189 OPC_CVT_D_L = FOP(33, FMT_L),
7190 OPC_CVT_PS_PW = FOP(38, FMT_W),
7191
7192 OPC_ADD_PS = FOP(0, FMT_PS),
7193 OPC_SUB_PS = FOP(1, FMT_PS),
7194 OPC_MUL_PS = FOP(2, FMT_PS),
7195 OPC_DIV_PS = FOP(3, FMT_PS),
7196 OPC_ABS_PS = FOP(5, FMT_PS),
7197 OPC_MOV_PS = FOP(6, FMT_PS),
7198 OPC_NEG_PS = FOP(7, FMT_PS),
7199 OPC_MOVCF_PS = FOP(17, FMT_PS),
7200 OPC_MOVZ_PS = FOP(18, FMT_PS),
7201 OPC_MOVN_PS = FOP(19, FMT_PS),
7202 OPC_ADDR_PS = FOP(24, FMT_PS),
7203 OPC_MULR_PS = FOP(26, FMT_PS),
7204 OPC_RECIP2_PS = FOP(28, FMT_PS),
7205 OPC_RECIP1_PS = FOP(29, FMT_PS),
7206 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7207 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7208
7209 OPC_CVT_S_PU = FOP(32, FMT_PS),
7210 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7211 OPC_CVT_S_PL = FOP(40, FMT_PS),
7212 OPC_PLL_PS = FOP(44, FMT_PS),
7213 OPC_PLU_PS = FOP(45, FMT_PS),
7214 OPC_PUL_PS = FOP(46, FMT_PS),
7215 OPC_PUU_PS = FOP(47, FMT_PS),
7216 OPC_CMP_F_PS = FOP (48, FMT_PS),
7217 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7218 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7219 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7220 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7221 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7222 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7223 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7224 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7225 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7226 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7227 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7228 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7229 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7230 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7231 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7232 };
7233
7234 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7235 {
7236 const char *opn = "cp1 move";
7237 TCGv t0 = tcg_temp_new();
7238
7239 switch (opc) {
7240 case OPC_MFC1:
7241 {
7242 TCGv_i32 fp0 = tcg_temp_new_i32();
7243
7244 gen_load_fpr32(fp0, fs);
7245 tcg_gen_ext_i32_tl(t0, fp0);
7246 tcg_temp_free_i32(fp0);
7247 }
7248 gen_store_gpr(t0, rt);
7249 opn = "mfc1";
7250 break;
7251 case OPC_MTC1:
7252 gen_load_gpr(t0, rt);
7253 {
7254 TCGv_i32 fp0 = tcg_temp_new_i32();
7255
7256 tcg_gen_trunc_tl_i32(fp0, t0);
7257 gen_store_fpr32(fp0, fs);
7258 tcg_temp_free_i32(fp0);
7259 }
7260 opn = "mtc1";
7261 break;
7262 case OPC_CFC1:
7263 gen_helper_1e0i(cfc1, t0, fs);
7264 gen_store_gpr(t0, rt);
7265 opn = "cfc1";
7266 break;
7267 case OPC_CTC1:
7268 gen_load_gpr(t0, rt);
7269 {
7270 TCGv_i32 fs_tmp = tcg_const_i32(fs);
7271
7272 gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
7273 tcg_temp_free_i32(fs_tmp);
7274 }
7275 opn = "ctc1";
7276 break;
7277 #if defined(TARGET_MIPS64)
7278 case OPC_DMFC1:
7279 gen_load_fpr64(ctx, t0, fs);
7280 gen_store_gpr(t0, rt);
7281 opn = "dmfc1";
7282 break;
7283 case OPC_DMTC1:
7284 gen_load_gpr(t0, rt);
7285 gen_store_fpr64(ctx, t0, fs);
7286 opn = "dmtc1";
7287 break;
7288 #endif
7289 case OPC_MFHC1:
7290 {
7291 TCGv_i32 fp0 = tcg_temp_new_i32();
7292
7293 gen_load_fpr32h(ctx, fp0, fs);
7294 tcg_gen_ext_i32_tl(t0, fp0);
7295 tcg_temp_free_i32(fp0);
7296 }
7297 gen_store_gpr(t0, rt);
7298 opn = "mfhc1";
7299 break;
7300 case OPC_MTHC1:
7301 gen_load_gpr(t0, rt);
7302 {
7303 TCGv_i32 fp0 = tcg_temp_new_i32();
7304
7305 tcg_gen_trunc_tl_i32(fp0, t0);
7306 gen_store_fpr32h(ctx, fp0, fs);
7307 tcg_temp_free_i32(fp0);
7308 }
7309 opn = "mthc1";
7310 break;
7311 default:
7312 MIPS_INVAL(opn);
7313 generate_exception (ctx, EXCP_RI);
7314 goto out;
7315 }
7316 (void)opn; /* avoid a compiler warning */
7317 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7318
7319 out:
7320 tcg_temp_free(t0);
7321 }
7322
7323 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7324 {
7325 int l1;
7326 TCGCond cond;
7327 TCGv_i32 t0;
7328
7329 if (rd == 0) {
7330 /* Treat as NOP. */
7331 return;
7332 }
7333
7334 if (tf)
7335 cond = TCG_COND_EQ;
7336 else
7337 cond = TCG_COND_NE;
7338
7339 l1 = gen_new_label();
7340 t0 = tcg_temp_new_i32();
7341 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7342 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7343 tcg_temp_free_i32(t0);
7344 if (rs == 0) {
7345 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7346 } else {
7347 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7348 }
7349 gen_set_label(l1);
7350 }
7351
7352 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7353 {
7354 int cond;
7355 TCGv_i32 t0 = tcg_temp_new_i32();
7356 int l1 = gen_new_label();
7357
7358 if (tf)
7359 cond = TCG_COND_EQ;
7360 else
7361 cond = TCG_COND_NE;
7362
7363 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7364 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7365 gen_load_fpr32(t0, fs);
7366 gen_store_fpr32(t0, fd);
7367 gen_set_label(l1);
7368 tcg_temp_free_i32(t0);
7369 }
7370
7371 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7372 {
7373 int cond;
7374 TCGv_i32 t0 = tcg_temp_new_i32();
7375 TCGv_i64 fp0;
7376 int l1 = gen_new_label();
7377
7378 if (tf)
7379 cond = TCG_COND_EQ;
7380 else
7381 cond = TCG_COND_NE;
7382
7383 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7384 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7385 tcg_temp_free_i32(t0);
7386 fp0 = tcg_temp_new_i64();
7387 gen_load_fpr64(ctx, fp0, fs);
7388 gen_store_fpr64(ctx, fp0, fd);
7389 tcg_temp_free_i64(fp0);
7390 gen_set_label(l1);
7391 }
7392
7393 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
7394 int cc, int tf)
7395 {
7396 int cond;
7397 TCGv_i32 t0 = tcg_temp_new_i32();
7398 int l1 = gen_new_label();
7399 int l2 = gen_new_label();
7400
7401 if (tf)
7402 cond = TCG_COND_EQ;
7403 else
7404 cond = TCG_COND_NE;
7405
7406 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7407 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7408 gen_load_fpr32(t0, fs);
7409 gen_store_fpr32(t0, fd);
7410 gen_set_label(l1);
7411
7412 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7413 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7414 gen_load_fpr32h(ctx, t0, fs);
7415 gen_store_fpr32h(ctx, t0, fd);
7416 tcg_temp_free_i32(t0);
7417 gen_set_label(l2);
7418 }
7419
7420
7421 static void gen_farith (DisasContext *ctx, enum fopcode op1,
7422 int ft, int fs, int fd, int cc)
7423 {
7424 const char *opn = "farith";
7425 const char *condnames[] = {
7426 "c.f",
7427 "c.un",
7428 "c.eq",
7429 "c.ueq",
7430 "c.olt",
7431 "c.ult",
7432 "c.ole",
7433 "c.ule",
7434 "c.sf",
7435 "c.ngle",
7436 "c.seq",
7437 "c.ngl",
7438 "c.lt",
7439 "c.nge",
7440 "c.le",
7441 "c.ngt",
7442 };
7443 const char *condnames_abs[] = {
7444 "cabs.f",
7445 "cabs.un",
7446 "cabs.eq",
7447 "cabs.ueq",
7448 "cabs.olt",
7449 "cabs.ult",
7450 "cabs.ole",
7451 "cabs.ule",
7452 "cabs.sf",
7453 "cabs.ngle",
7454 "cabs.seq",
7455 "cabs.ngl",
7456 "cabs.lt",
7457 "cabs.nge",
7458 "cabs.le",
7459 "cabs.ngt",
7460 };
7461 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7462 uint32_t func = ctx->opcode & 0x3f;
7463
7464 switch (op1) {
7465 case OPC_ADD_S:
7466 {
7467 TCGv_i32 fp0 = tcg_temp_new_i32();
7468 TCGv_i32 fp1 = tcg_temp_new_i32();
7469
7470 gen_load_fpr32(fp0, fs);
7471 gen_load_fpr32(fp1, ft);
7472 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7473 tcg_temp_free_i32(fp1);
7474 gen_store_fpr32(fp0, fd);
7475 tcg_temp_free_i32(fp0);
7476 }
7477 opn = "add.s";
7478 optype = BINOP;
7479 break;
7480 case OPC_SUB_S:
7481 {
7482 TCGv_i32 fp0 = tcg_temp_new_i32();
7483 TCGv_i32 fp1 = tcg_temp_new_i32();
7484
7485 gen_load_fpr32(fp0, fs);
7486 gen_load_fpr32(fp1, ft);
7487 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7488 tcg_temp_free_i32(fp1);
7489 gen_store_fpr32(fp0, fd);
7490 tcg_temp_free_i32(fp0);
7491 }
7492 opn = "sub.s";
7493 optype = BINOP;
7494 break;
7495 case OPC_MUL_S:
7496 {
7497 TCGv_i32 fp0 = tcg_temp_new_i32();
7498 TCGv_i32 fp1 = tcg_temp_new_i32();
7499
7500 gen_load_fpr32(fp0, fs);
7501 gen_load_fpr32(fp1, ft);
7502 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7503 tcg_temp_free_i32(fp1);
7504 gen_store_fpr32(fp0, fd);
7505 tcg_temp_free_i32(fp0);
7506 }
7507 opn = "mul.s";
7508 optype = BINOP;
7509 break;
7510 case OPC_DIV_S:
7511 {
7512 TCGv_i32 fp0 = tcg_temp_new_i32();
7513 TCGv_i32 fp1 = tcg_temp_new_i32();
7514
7515 gen_load_fpr32(fp0, fs);
7516 gen_load_fpr32(fp1, ft);
7517 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7518 tcg_temp_free_i32(fp1);
7519 gen_store_fpr32(fp0, fd);
7520 tcg_temp_free_i32(fp0);
7521 }
7522 opn = "div.s";
7523 optype = BINOP;
7524 break;
7525 case OPC_SQRT_S:
7526 {
7527 TCGv_i32 fp0 = tcg_temp_new_i32();
7528
7529 gen_load_fpr32(fp0, fs);
7530 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7531 gen_store_fpr32(fp0, fd);
7532 tcg_temp_free_i32(fp0);
7533 }
7534 opn = "sqrt.s";
7535 break;
7536 case OPC_ABS_S:
7537 {
7538 TCGv_i32 fp0 = tcg_temp_new_i32();
7539
7540 gen_load_fpr32(fp0, fs);
7541 gen_helper_float_abs_s(fp0, fp0);
7542 gen_store_fpr32(fp0, fd);
7543 tcg_temp_free_i32(fp0);
7544 }
7545 opn = "abs.s";
7546 break;
7547 case OPC_MOV_S:
7548 {
7549 TCGv_i32 fp0 = tcg_temp_new_i32();
7550
7551 gen_load_fpr32(fp0, fs);
7552 gen_store_fpr32(fp0, fd);
7553 tcg_temp_free_i32(fp0);
7554 }
7555 opn = "mov.s";
7556 break;
7557 case OPC_NEG_S:
7558 {
7559 TCGv_i32 fp0 = tcg_temp_new_i32();
7560
7561 gen_load_fpr32(fp0, fs);
7562 gen_helper_float_chs_s(fp0, fp0);
7563 gen_store_fpr32(fp0, fd);
7564 tcg_temp_free_i32(fp0);
7565 }
7566 opn = "neg.s";
7567 break;
7568 case OPC_ROUND_L_S:
7569 check_cp1_64bitmode(ctx);
7570 {
7571 TCGv_i32 fp32 = tcg_temp_new_i32();
7572 TCGv_i64 fp64 = tcg_temp_new_i64();
7573
7574 gen_load_fpr32(fp32, fs);
7575 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7576 tcg_temp_free_i32(fp32);
7577 gen_store_fpr64(ctx, fp64, fd);
7578 tcg_temp_free_i64(fp64);
7579 }
7580 opn = "round.l.s";
7581 break;
7582 case OPC_TRUNC_L_S:
7583 check_cp1_64bitmode(ctx);
7584 {
7585 TCGv_i32 fp32 = tcg_temp_new_i32();
7586 TCGv_i64 fp64 = tcg_temp_new_i64();
7587
7588 gen_load_fpr32(fp32, fs);
7589 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7590 tcg_temp_free_i32(fp32);
7591 gen_store_fpr64(ctx, fp64, fd);
7592 tcg_temp_free_i64(fp64);
7593 }
7594 opn = "trunc.l.s";
7595 break;
7596 case OPC_CEIL_L_S:
7597 check_cp1_64bitmode(ctx);
7598 {
7599 TCGv_i32 fp32 = tcg_temp_new_i32();
7600 TCGv_i64 fp64 = tcg_temp_new_i64();
7601
7602 gen_load_fpr32(fp32, fs);
7603 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7604 tcg_temp_free_i32(fp32);
7605 gen_store_fpr64(ctx, fp64, fd);
7606 tcg_temp_free_i64(fp64);
7607 }
7608 opn = "ceil.l.s";
7609 break;
7610 case OPC_FLOOR_L_S:
7611 check_cp1_64bitmode(ctx);
7612 {
7613 TCGv_i32 fp32 = tcg_temp_new_i32();
7614 TCGv_i64 fp64 = tcg_temp_new_i64();
7615
7616 gen_load_fpr32(fp32, fs);
7617 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7618 tcg_temp_free_i32(fp32);
7619 gen_store_fpr64(ctx, fp64, fd);
7620 tcg_temp_free_i64(fp64);
7621 }
7622 opn = "floor.l.s";
7623 break;
7624 case OPC_ROUND_W_S:
7625 {
7626 TCGv_i32 fp0 = tcg_temp_new_i32();
7627
7628 gen_load_fpr32(fp0, fs);
7629 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7630 gen_store_fpr32(fp0, fd);
7631 tcg_temp_free_i32(fp0);
7632 }
7633 opn = "round.w.s";
7634 break;
7635 case OPC_TRUNC_W_S:
7636 {
7637 TCGv_i32 fp0 = tcg_temp_new_i32();
7638
7639 gen_load_fpr32(fp0, fs);
7640 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7641 gen_store_fpr32(fp0, fd);
7642 tcg_temp_free_i32(fp0);
7643 }
7644 opn = "trunc.w.s";
7645 break;
7646 case OPC_CEIL_W_S:
7647 {
7648 TCGv_i32 fp0 = tcg_temp_new_i32();
7649
7650 gen_load_fpr32(fp0, fs);
7651 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7652 gen_store_fpr32(fp0, fd);
7653 tcg_temp_free_i32(fp0);
7654 }
7655 opn = "ceil.w.s";
7656 break;
7657 case OPC_FLOOR_W_S:
7658 {
7659 TCGv_i32 fp0 = tcg_temp_new_i32();
7660
7661 gen_load_fpr32(fp0, fs);
7662 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7663 gen_store_fpr32(fp0, fd);
7664 tcg_temp_free_i32(fp0);
7665 }
7666 opn = "floor.w.s";
7667 break;
7668 case OPC_MOVCF_S:
7669 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7670 opn = "movcf.s";
7671 break;
7672 case OPC_MOVZ_S:
7673 {
7674 int l1 = gen_new_label();
7675 TCGv_i32 fp0;
7676
7677 if (ft != 0) {
7678 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7679 }
7680 fp0 = tcg_temp_new_i32();
7681 gen_load_fpr32(fp0, fs);
7682 gen_store_fpr32(fp0, fd);
7683 tcg_temp_free_i32(fp0);
7684 gen_set_label(l1);
7685 }
7686 opn = "movz.s";
7687 break;
7688 case OPC_MOVN_S:
7689 {
7690 int l1 = gen_new_label();
7691 TCGv_i32 fp0;
7692
7693 if (ft != 0) {
7694 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7695 fp0 = tcg_temp_new_i32();
7696 gen_load_fpr32(fp0, fs);
7697 gen_store_fpr32(fp0, fd);
7698 tcg_temp_free_i32(fp0);
7699 gen_set_label(l1);
7700 }
7701 }
7702 opn = "movn.s";
7703 break;
7704 case OPC_RECIP_S:
7705 check_cop1x(ctx);
7706 {
7707 TCGv_i32 fp0 = tcg_temp_new_i32();
7708
7709 gen_load_fpr32(fp0, fs);
7710 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7711 gen_store_fpr32(fp0, fd);
7712 tcg_temp_free_i32(fp0);
7713 }
7714 opn = "recip.s";
7715 break;
7716 case OPC_RSQRT_S:
7717 check_cop1x(ctx);
7718 {
7719 TCGv_i32 fp0 = tcg_temp_new_i32();
7720
7721 gen_load_fpr32(fp0, fs);
7722 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7723 gen_store_fpr32(fp0, fd);
7724 tcg_temp_free_i32(fp0);
7725 }
7726 opn = "rsqrt.s";
7727 break;
7728 case OPC_RECIP2_S:
7729 check_cp1_64bitmode(ctx);
7730 {
7731 TCGv_i32 fp0 = tcg_temp_new_i32();
7732 TCGv_i32 fp1 = tcg_temp_new_i32();
7733
7734 gen_load_fpr32(fp0, fs);
7735 gen_load_fpr32(fp1, ft);
7736 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7737 tcg_temp_free_i32(fp1);
7738 gen_store_fpr32(fp0, fd);
7739 tcg_temp_free_i32(fp0);
7740 }
7741 opn = "recip2.s";
7742 break;
7743 case OPC_RECIP1_S:
7744 check_cp1_64bitmode(ctx);
7745 {
7746 TCGv_i32 fp0 = tcg_temp_new_i32();
7747
7748 gen_load_fpr32(fp0, fs);
7749 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7750 gen_store_fpr32(fp0, fd);
7751 tcg_temp_free_i32(fp0);
7752 }
7753 opn = "recip1.s";
7754 break;
7755 case OPC_RSQRT1_S:
7756 check_cp1_64bitmode(ctx);
7757 {
7758 TCGv_i32 fp0 = tcg_temp_new_i32();
7759
7760 gen_load_fpr32(fp0, fs);
7761 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7762 gen_store_fpr32(fp0, fd);
7763 tcg_temp_free_i32(fp0);
7764 }
7765 opn = "rsqrt1.s";
7766 break;
7767 case OPC_RSQRT2_S:
7768 check_cp1_64bitmode(ctx);
7769 {
7770 TCGv_i32 fp0 = tcg_temp_new_i32();
7771 TCGv_i32 fp1 = tcg_temp_new_i32();
7772
7773 gen_load_fpr32(fp0, fs);
7774 gen_load_fpr32(fp1, ft);
7775 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7776 tcg_temp_free_i32(fp1);
7777 gen_store_fpr32(fp0, fd);
7778 tcg_temp_free_i32(fp0);
7779 }
7780 opn = "rsqrt2.s";
7781 break;
7782 case OPC_CVT_D_S:
7783 check_cp1_registers(ctx, fd);
7784 {
7785 TCGv_i32 fp32 = tcg_temp_new_i32();
7786 TCGv_i64 fp64 = tcg_temp_new_i64();
7787
7788 gen_load_fpr32(fp32, fs);
7789 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7790 tcg_temp_free_i32(fp32);
7791 gen_store_fpr64(ctx, fp64, fd);
7792 tcg_temp_free_i64(fp64);
7793 }
7794 opn = "cvt.d.s";
7795 break;
7796 case OPC_CVT_W_S:
7797 {
7798 TCGv_i32 fp0 = tcg_temp_new_i32();
7799
7800 gen_load_fpr32(fp0, fs);
7801 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7802 gen_store_fpr32(fp0, fd);
7803 tcg_temp_free_i32(fp0);
7804 }
7805 opn = "cvt.w.s";
7806 break;
7807 case OPC_CVT_L_S:
7808 check_cp1_64bitmode(ctx);
7809 {
7810 TCGv_i32 fp32 = tcg_temp_new_i32();
7811 TCGv_i64 fp64 = tcg_temp_new_i64();
7812
7813 gen_load_fpr32(fp32, fs);
7814 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7815 tcg_temp_free_i32(fp32);
7816 gen_store_fpr64(ctx, fp64, fd);
7817 tcg_temp_free_i64(fp64);
7818 }
7819 opn = "cvt.l.s";
7820 break;
7821 case OPC_CVT_PS_S:
7822 check_cp1_64bitmode(ctx);
7823 {
7824 TCGv_i64 fp64 = tcg_temp_new_i64();
7825 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7826 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7827
7828 gen_load_fpr32(fp32_0, fs);
7829 gen_load_fpr32(fp32_1, ft);
7830 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7831 tcg_temp_free_i32(fp32_1);
7832 tcg_temp_free_i32(fp32_0);
7833 gen_store_fpr64(ctx, fp64, fd);
7834 tcg_temp_free_i64(fp64);
7835 }
7836 opn = "cvt.ps.s";
7837 break;
7838 case OPC_CMP_F_S:
7839 case OPC_CMP_UN_S:
7840 case OPC_CMP_EQ_S:
7841 case OPC_CMP_UEQ_S:
7842 case OPC_CMP_OLT_S:
7843 case OPC_CMP_ULT_S:
7844 case OPC_CMP_OLE_S:
7845 case OPC_CMP_ULE_S:
7846 case OPC_CMP_SF_S:
7847 case OPC_CMP_NGLE_S:
7848 case OPC_CMP_SEQ_S:
7849 case OPC_CMP_NGL_S:
7850 case OPC_CMP_LT_S:
7851 case OPC_CMP_NGE_S:
7852 case OPC_CMP_LE_S:
7853 case OPC_CMP_NGT_S:
7854 if (ctx->opcode & (1 << 6)) {
7855 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7856 opn = condnames_abs[func-48];
7857 } else {
7858 gen_cmp_s(ctx, func-48, ft, fs, cc);
7859 opn = condnames[func-48];
7860 }
7861 break;
7862 case OPC_ADD_D:
7863 check_cp1_registers(ctx, fs | ft | fd);
7864 {
7865 TCGv_i64 fp0 = tcg_temp_new_i64();
7866 TCGv_i64 fp1 = tcg_temp_new_i64();
7867
7868 gen_load_fpr64(ctx, fp0, fs);
7869 gen_load_fpr64(ctx, fp1, ft);
7870 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7871 tcg_temp_free_i64(fp1);
7872 gen_store_fpr64(ctx, fp0, fd);
7873 tcg_temp_free_i64(fp0);
7874 }
7875 opn = "add.d";
7876 optype = BINOP;
7877 break;
7878 case OPC_SUB_D:
7879 check_cp1_registers(ctx, fs | ft | fd);
7880 {
7881 TCGv_i64 fp0 = tcg_temp_new_i64();
7882 TCGv_i64 fp1 = tcg_temp_new_i64();
7883
7884 gen_load_fpr64(ctx, fp0, fs);
7885 gen_load_fpr64(ctx, fp1, ft);
7886 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7887 tcg_temp_free_i64(fp1);
7888 gen_store_fpr64(ctx, fp0, fd);
7889 tcg_temp_free_i64(fp0);
7890 }
7891 opn = "sub.d";
7892 optype = BINOP;
7893 break;
7894 case OPC_MUL_D:
7895 check_cp1_registers(ctx, fs | ft | fd);
7896 {
7897 TCGv_i64 fp0 = tcg_temp_new_i64();
7898 TCGv_i64 fp1 = tcg_temp_new_i64();
7899
7900 gen_load_fpr64(ctx, fp0, fs);
7901 gen_load_fpr64(ctx, fp1, ft);
7902 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7903 tcg_temp_free_i64(fp1);
7904 gen_store_fpr64(ctx, fp0, fd);
7905 tcg_temp_free_i64(fp0);
7906 }
7907 opn = "mul.d";
7908 optype = BINOP;
7909 break;
7910 case OPC_DIV_D:
7911 check_cp1_registers(ctx, fs | ft | fd);
7912 {
7913 TCGv_i64 fp0 = tcg_temp_new_i64();
7914 TCGv_i64 fp1 = tcg_temp_new_i64();
7915
7916 gen_load_fpr64(ctx, fp0, fs);
7917 gen_load_fpr64(ctx, fp1, ft);
7918 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7919 tcg_temp_free_i64(fp1);
7920 gen_store_fpr64(ctx, fp0, fd);
7921 tcg_temp_free_i64(fp0);
7922 }
7923 opn = "div.d";
7924 optype = BINOP;
7925 break;
7926 case OPC_SQRT_D:
7927 check_cp1_registers(ctx, fs | fd);
7928 {
7929 TCGv_i64 fp0 = tcg_temp_new_i64();
7930
7931 gen_load_fpr64(ctx, fp0, fs);
7932 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7933 gen_store_fpr64(ctx, fp0, fd);
7934 tcg_temp_free_i64(fp0);
7935 }
7936 opn = "sqrt.d";
7937 break;
7938 case OPC_ABS_D:
7939 check_cp1_registers(ctx, fs | fd);
7940 {
7941 TCGv_i64 fp0 = tcg_temp_new_i64();
7942
7943 gen_load_fpr64(ctx, fp0, fs);
7944 gen_helper_float_abs_d(fp0, fp0);
7945 gen_store_fpr64(ctx, fp0, fd);
7946 tcg_temp_free_i64(fp0);
7947 }
7948 opn = "abs.d";
7949 break;
7950 case OPC_MOV_D:
7951 check_cp1_registers(ctx, fs | fd);
7952 {
7953 TCGv_i64 fp0 = tcg_temp_new_i64();
7954
7955 gen_load_fpr64(ctx, fp0, fs);
7956 gen_store_fpr64(ctx, fp0, fd);
7957 tcg_temp_free_i64(fp0);
7958 }
7959 opn = "mov.d";
7960 break;
7961 case OPC_NEG_D:
7962 check_cp1_registers(ctx, fs | fd);
7963 {
7964 TCGv_i64 fp0 = tcg_temp_new_i64();
7965
7966 gen_load_fpr64(ctx, fp0, fs);
7967 gen_helper_float_chs_d(fp0, fp0);
7968 gen_store_fpr64(ctx, fp0, fd);
7969 tcg_temp_free_i64(fp0);
7970 }
7971 opn = "neg.d";
7972 break;
7973 case OPC_ROUND_L_D:
7974 check_cp1_64bitmode(ctx);
7975 {
7976 TCGv_i64 fp0 = tcg_temp_new_i64();
7977
7978 gen_load_fpr64(ctx, fp0, fs);
7979 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7980 gen_store_fpr64(ctx, fp0, fd);
7981 tcg_temp_free_i64(fp0);
7982 }
7983 opn = "round.l.d";
7984 break;
7985 case OPC_TRUNC_L_D:
7986 check_cp1_64bitmode(ctx);
7987 {
7988 TCGv_i64 fp0 = tcg_temp_new_i64();
7989
7990 gen_load_fpr64(ctx, fp0, fs);
7991 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7992 gen_store_fpr64(ctx, fp0, fd);
7993 tcg_temp_free_i64(fp0);
7994 }
7995 opn = "trunc.l.d";
7996 break;
7997 case OPC_CEIL_L_D:
7998 check_cp1_64bitmode(ctx);
7999 {
8000 TCGv_i64 fp0 = tcg_temp_new_i64();
8001
8002 gen_load_fpr64(ctx, fp0, fs);
8003 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
8004 gen_store_fpr64(ctx, fp0, fd);
8005 tcg_temp_free_i64(fp0);
8006 }
8007 opn = "ceil.l.d";
8008 break;
8009 case OPC_FLOOR_L_D:
8010 check_cp1_64bitmode(ctx);
8011 {
8012 TCGv_i64 fp0 = tcg_temp_new_i64();
8013
8014 gen_load_fpr64(ctx, fp0, fs);
8015 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
8016 gen_store_fpr64(ctx, fp0, fd);
8017 tcg_temp_free_i64(fp0);
8018 }
8019 opn = "floor.l.d";
8020 break;
8021 case OPC_ROUND_W_D:
8022 check_cp1_registers(ctx, fs);
8023 {
8024 TCGv_i32 fp32 = tcg_temp_new_i32();
8025 TCGv_i64 fp64 = tcg_temp_new_i64();
8026
8027 gen_load_fpr64(ctx, fp64, fs);
8028 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8029 tcg_temp_free_i64(fp64);
8030 gen_store_fpr32(fp32, fd);
8031 tcg_temp_free_i32(fp32);
8032 }
8033 opn = "round.w.d";
8034 break;
8035 case OPC_TRUNC_W_D:
8036 check_cp1_registers(ctx, fs);
8037 {
8038 TCGv_i32 fp32 = tcg_temp_new_i32();
8039 TCGv_i64 fp64 = tcg_temp_new_i64();
8040
8041 gen_load_fpr64(ctx, fp64, fs);
8042 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8043 tcg_temp_free_i64(fp64);
8044 gen_store_fpr32(fp32, fd);
8045 tcg_temp_free_i32(fp32);
8046 }
8047 opn = "trunc.w.d";
8048 break;
8049 case OPC_CEIL_W_D:
8050 check_cp1_registers(ctx, fs);
8051 {
8052 TCGv_i32 fp32 = tcg_temp_new_i32();
8053 TCGv_i64 fp64 = tcg_temp_new_i64();
8054
8055 gen_load_fpr64(ctx, fp64, fs);
8056 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8057 tcg_temp_free_i64(fp64);
8058 gen_store_fpr32(fp32, fd);
8059 tcg_temp_free_i32(fp32);
8060 }
8061 opn = "ceil.w.d";
8062 break;
8063 case OPC_FLOOR_W_D:
8064 check_cp1_registers(ctx, fs);
8065 {
8066 TCGv_i32 fp32 = tcg_temp_new_i32();
8067 TCGv_i64 fp64 = tcg_temp_new_i64();
8068
8069 gen_load_fpr64(ctx, fp64, fs);
8070 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8071 tcg_temp_free_i64(fp64);
8072 gen_store_fpr32(fp32, fd);
8073 tcg_temp_free_i32(fp32);
8074 }
8075 opn = "floor.w.d";
8076 break;
8077 case OPC_MOVCF_D:
8078 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8079 opn = "movcf.d";
8080 break;
8081 case OPC_MOVZ_D:
8082 {
8083 int l1 = gen_new_label();
8084 TCGv_i64 fp0;
8085
8086 if (ft != 0) {
8087 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8088 }
8089 fp0 = tcg_temp_new_i64();
8090 gen_load_fpr64(ctx, fp0, fs);
8091 gen_store_fpr64(ctx, fp0, fd);
8092 tcg_temp_free_i64(fp0);
8093 gen_set_label(l1);
8094 }
8095 opn = "movz.d";
8096 break;
8097 case OPC_MOVN_D:
8098 {
8099 int l1 = gen_new_label();
8100 TCGv_i64 fp0;
8101
8102 if (ft != 0) {
8103 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8104 fp0 = tcg_temp_new_i64();
8105 gen_load_fpr64(ctx, fp0, fs);
8106 gen_store_fpr64(ctx, fp0, fd);
8107 tcg_temp_free_i64(fp0);
8108 gen_set_label(l1);
8109 }
8110 }
8111 opn = "movn.d";
8112 break;
8113 case OPC_RECIP_D:
8114 check_cp1_64bitmode(ctx);
8115 {
8116 TCGv_i64 fp0 = tcg_temp_new_i64();
8117
8118 gen_load_fpr64(ctx, fp0, fs);
8119 gen_helper_float_recip_d(fp0, cpu_env, fp0);
8120 gen_store_fpr64(ctx, fp0, fd);
8121 tcg_temp_free_i64(fp0);
8122 }
8123 opn = "recip.d";
8124 break;
8125 case OPC_RSQRT_D:
8126 check_cp1_64bitmode(ctx);
8127 {
8128 TCGv_i64 fp0 = tcg_temp_new_i64();
8129
8130 gen_load_fpr64(ctx, fp0, fs);
8131 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8132 gen_store_fpr64(ctx, fp0, fd);
8133 tcg_temp_free_i64(fp0);
8134 }
8135 opn = "rsqrt.d";
8136 break;
8137 case OPC_RECIP2_D:
8138 check_cp1_64bitmode(ctx);
8139 {
8140 TCGv_i64 fp0 = tcg_temp_new_i64();
8141 TCGv_i64 fp1 = tcg_temp_new_i64();
8142
8143 gen_load_fpr64(ctx, fp0, fs);
8144 gen_load_fpr64(ctx, fp1, ft);
8145 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8146 tcg_temp_free_i64(fp1);
8147 gen_store_fpr64(ctx, fp0, fd);
8148 tcg_temp_free_i64(fp0);
8149 }
8150 opn = "recip2.d";
8151 break;
8152 case OPC_RECIP1_D:
8153 check_cp1_64bitmode(ctx);
8154 {
8155 TCGv_i64 fp0 = tcg_temp_new_i64();
8156
8157 gen_load_fpr64(ctx, fp0, fs);
8158 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8159 gen_store_fpr64(ctx, fp0, fd);
8160 tcg_temp_free_i64(fp0);
8161 }
8162 opn = "recip1.d";
8163 break;
8164 case OPC_RSQRT1_D:
8165 check_cp1_64bitmode(ctx);
8166 {
8167 TCGv_i64 fp0 = tcg_temp_new_i64();
8168
8169 gen_load_fpr64(ctx, fp0, fs);
8170 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8171 gen_store_fpr64(ctx, fp0, fd);
8172 tcg_temp_free_i64(fp0);
8173 }
8174 opn = "rsqrt1.d";
8175 break;
8176 case OPC_RSQRT2_D:
8177 check_cp1_64bitmode(ctx);
8178 {
8179 TCGv_i64 fp0 = tcg_temp_new_i64();
8180 TCGv_i64 fp1 = tcg_temp_new_i64();
8181
8182 gen_load_fpr64(ctx, fp0, fs);
8183 gen_load_fpr64(ctx, fp1, ft);
8184 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8185 tcg_temp_free_i64(fp1);
8186 gen_store_fpr64(ctx, fp0, fd);
8187 tcg_temp_free_i64(fp0);
8188 }
8189 opn = "rsqrt2.d";
8190 break;
8191 case OPC_CMP_F_D:
8192 case OPC_CMP_UN_D:
8193 case OPC_CMP_EQ_D:
8194 case OPC_CMP_UEQ_D:
8195 case OPC_CMP_OLT_D:
8196 case OPC_CMP_ULT_D:
8197 case OPC_CMP_OLE_D:
8198 case OPC_CMP_ULE_D:
8199 case OPC_CMP_SF_D:
8200 case OPC_CMP_NGLE_D:
8201 case OPC_CMP_SEQ_D:
8202 case OPC_CMP_NGL_D:
8203 case OPC_CMP_LT_D:
8204 case OPC_CMP_NGE_D:
8205 case OPC_CMP_LE_D:
8206 case OPC_CMP_NGT_D:
8207 if (ctx->opcode & (1 << 6)) {
8208 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8209 opn = condnames_abs[func-48];
8210 } else {
8211 gen_cmp_d(ctx, func-48, ft, fs, cc);
8212 opn = condnames[func-48];
8213 }
8214 break;
8215 case OPC_CVT_S_D:
8216 check_cp1_registers(ctx, fs);
8217 {
8218 TCGv_i32 fp32 = tcg_temp_new_i32();
8219 TCGv_i64 fp64 = tcg_temp_new_i64();
8220
8221 gen_load_fpr64(ctx, fp64, fs);
8222 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8223 tcg_temp_free_i64(fp64);
8224 gen_store_fpr32(fp32, fd);
8225 tcg_temp_free_i32(fp32);
8226 }
8227 opn = "cvt.s.d";
8228 break;
8229 case OPC_CVT_W_D:
8230 check_cp1_registers(ctx, fs);
8231 {
8232 TCGv_i32 fp32 = tcg_temp_new_i32();
8233 TCGv_i64 fp64 = tcg_temp_new_i64();
8234
8235 gen_load_fpr64(ctx, fp64, fs);
8236 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8237 tcg_temp_free_i64(fp64);
8238 gen_store_fpr32(fp32, fd);
8239 tcg_temp_free_i32(fp32);
8240 }
8241 opn = "cvt.w.d";
8242 break;
8243 case OPC_CVT_L_D:
8244 check_cp1_64bitmode(ctx);
8245 {
8246 TCGv_i64 fp0 = tcg_temp_new_i64();
8247
8248 gen_load_fpr64(ctx, fp0, fs);
8249 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8250 gen_store_fpr64(ctx, fp0, fd);
8251 tcg_temp_free_i64(fp0);
8252 }
8253 opn = "cvt.l.d";
8254 break;
8255 case OPC_CVT_S_W:
8256 {
8257 TCGv_i32 fp0 = tcg_temp_new_i32();
8258
8259 gen_load_fpr32(fp0, fs);
8260 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8261 gen_store_fpr32(fp0, fd);
8262 tcg_temp_free_i32(fp0);
8263 }
8264 opn = "cvt.s.w";
8265 break;
8266 case OPC_CVT_D_W:
8267 check_cp1_registers(ctx, fd);
8268 {
8269 TCGv_i32 fp32 = tcg_temp_new_i32();
8270 TCGv_i64 fp64 = tcg_temp_new_i64();
8271
8272 gen_load_fpr32(fp32, fs);
8273 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8274 tcg_temp_free_i32(fp32);
8275 gen_store_fpr64(ctx, fp64, fd);
8276 tcg_temp_free_i64(fp64);
8277 }
8278 opn = "cvt.d.w";
8279 break;
8280 case OPC_CVT_S_L:
8281 check_cp1_64bitmode(ctx);
8282 {
8283 TCGv_i32 fp32 = tcg_temp_new_i32();
8284 TCGv_i64 fp64 = tcg_temp_new_i64();
8285
8286 gen_load_fpr64(ctx, fp64, fs);
8287 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8288 tcg_temp_free_i64(fp64);
8289 gen_store_fpr32(fp32, fd);
8290 tcg_temp_free_i32(fp32);
8291 }
8292 opn = "cvt.s.l";
8293 break;
8294 case OPC_CVT_D_L:
8295 check_cp1_64bitmode(ctx);
8296 {
8297 TCGv_i64 fp0 = tcg_temp_new_i64();
8298
8299 gen_load_fpr64(ctx, fp0, fs);
8300 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8301 gen_store_fpr64(ctx, fp0, fd);
8302 tcg_temp_free_i64(fp0);
8303 }
8304 opn = "cvt.d.l";
8305 break;
8306 case OPC_CVT_PS_PW:
8307 check_cp1_64bitmode(ctx);
8308 {
8309 TCGv_i64 fp0 = tcg_temp_new_i64();
8310
8311 gen_load_fpr64(ctx, fp0, fs);
8312 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8313 gen_store_fpr64(ctx, fp0, fd);
8314 tcg_temp_free_i64(fp0);
8315 }
8316 opn = "cvt.ps.pw";
8317 break;
8318 case OPC_ADD_PS:
8319 check_cp1_64bitmode(ctx);
8320 {
8321 TCGv_i64 fp0 = tcg_temp_new_i64();
8322 TCGv_i64 fp1 = tcg_temp_new_i64();
8323
8324 gen_load_fpr64(ctx, fp0, fs);
8325 gen_load_fpr64(ctx, fp1, ft);
8326 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8327 tcg_temp_free_i64(fp1);
8328 gen_store_fpr64(ctx, fp0, fd);
8329 tcg_temp_free_i64(fp0);
8330 }
8331 opn = "add.ps";
8332 break;
8333 case OPC_SUB_PS:
8334 check_cp1_64bitmode(ctx);
8335 {
8336 TCGv_i64 fp0 = tcg_temp_new_i64();
8337 TCGv_i64 fp1 = tcg_temp_new_i64();
8338
8339 gen_load_fpr64(ctx, fp0, fs);
8340 gen_load_fpr64(ctx, fp1, ft);
8341 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8342 tcg_temp_free_i64(fp1);
8343 gen_store_fpr64(ctx, fp0, fd);
8344 tcg_temp_free_i64(fp0);
8345 }
8346 opn = "sub.ps";
8347 break;
8348 case OPC_MUL_PS:
8349 check_cp1_64bitmode(ctx);
8350 {
8351 TCGv_i64 fp0 = tcg_temp_new_i64();
8352 TCGv_i64 fp1 = tcg_temp_new_i64();
8353
8354 gen_load_fpr64(ctx, fp0, fs);
8355 gen_load_fpr64(ctx, fp1, ft);
8356 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8357 tcg_temp_free_i64(fp1);
8358 gen_store_fpr64(ctx, fp0, fd);
8359 tcg_temp_free_i64(fp0);
8360 }
8361 opn = "mul.ps";
8362 break;
8363 case OPC_ABS_PS:
8364 check_cp1_64bitmode(ctx);
8365 {
8366 TCGv_i64 fp0 = tcg_temp_new_i64();
8367
8368 gen_load_fpr64(ctx, fp0, fs);
8369 gen_helper_float_abs_ps(fp0, fp0);
8370 gen_store_fpr64(ctx, fp0, fd);
8371 tcg_temp_free_i64(fp0);
8372 }
8373 opn = "abs.ps";
8374 break;
8375 case OPC_MOV_PS:
8376 check_cp1_64bitmode(ctx);
8377 {
8378 TCGv_i64 fp0 = tcg_temp_new_i64();
8379
8380 gen_load_fpr64(ctx, fp0, fs);
8381 gen_store_fpr64(ctx, fp0, fd);
8382 tcg_temp_free_i64(fp0);
8383 }
8384 opn = "mov.ps";
8385 break;
8386 case OPC_NEG_PS:
8387 check_cp1_64bitmode(ctx);
8388 {
8389 TCGv_i64 fp0 = tcg_temp_new_i64();
8390
8391 gen_load_fpr64(ctx, fp0, fs);
8392 gen_helper_float_chs_ps(fp0, fp0);
8393 gen_store_fpr64(ctx, fp0, fd);
8394 tcg_temp_free_i64(fp0);
8395 }
8396 opn = "neg.ps";
8397 break;
8398 case OPC_MOVCF_PS:
8399 check_cp1_64bitmode(ctx);
8400 gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8401 opn = "movcf.ps";
8402 break;
8403 case OPC_MOVZ_PS:
8404 check_cp1_64bitmode(ctx);
8405 {
8406 int l1 = gen_new_label();
8407 TCGv_i64 fp0;
8408
8409 if (ft != 0)
8410 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8411 fp0 = tcg_temp_new_i64();
8412 gen_load_fpr64(ctx, fp0, fs);
8413 gen_store_fpr64(ctx, fp0, fd);
8414 tcg_temp_free_i64(fp0);
8415 gen_set_label(l1);
8416 }
8417 opn = "movz.ps";
8418 break;
8419 case OPC_MOVN_PS:
8420 check_cp1_64bitmode(ctx);
8421 {
8422 int l1 = gen_new_label();
8423 TCGv_i64 fp0;
8424
8425 if (ft != 0) {
8426 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8427 fp0 = tcg_temp_new_i64();
8428 gen_load_fpr64(ctx, fp0, fs);
8429 gen_store_fpr64(ctx, fp0, fd);
8430 tcg_temp_free_i64(fp0);
8431 gen_set_label(l1);
8432 }
8433 }
8434 opn = "movn.ps";
8435 break;
8436 case OPC_ADDR_PS:
8437 check_cp1_64bitmode(ctx);
8438 {
8439 TCGv_i64 fp0 = tcg_temp_new_i64();
8440 TCGv_i64 fp1 = tcg_temp_new_i64();
8441
8442 gen_load_fpr64(ctx, fp0, ft);
8443 gen_load_fpr64(ctx, fp1, fs);
8444 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8445 tcg_temp_free_i64(fp1);
8446 gen_store_fpr64(ctx, fp0, fd);
8447 tcg_temp_free_i64(fp0);
8448 }
8449 opn = "addr.ps";
8450 break;
8451 case OPC_MULR_PS:
8452 check_cp1_64bitmode(ctx);
8453 {
8454 TCGv_i64 fp0 = tcg_temp_new_i64();
8455 TCGv_i64 fp1 = tcg_temp_new_i64();
8456
8457 gen_load_fpr64(ctx, fp0, ft);
8458 gen_load_fpr64(ctx, fp1, fs);
8459 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8460 tcg_temp_free_i64(fp1);
8461 gen_store_fpr64(ctx, fp0, fd);
8462 tcg_temp_free_i64(fp0);
8463 }
8464 opn = "mulr.ps";
8465 break;
8466 case OPC_RECIP2_PS:
8467 check_cp1_64bitmode(ctx);
8468 {
8469 TCGv_i64 fp0 = tcg_temp_new_i64();
8470 TCGv_i64 fp1 = tcg_temp_new_i64();
8471
8472 gen_load_fpr64(ctx, fp0, fs);
8473 gen_load_fpr64(ctx, fp1, ft);
8474 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8475 tcg_temp_free_i64(fp1);
8476 gen_store_fpr64(ctx, fp0, fd);
8477 tcg_temp_free_i64(fp0);
8478 }
8479 opn = "recip2.ps";
8480 break;
8481 case OPC_RECIP1_PS:
8482 check_cp1_64bitmode(ctx);
8483 {
8484 TCGv_i64 fp0 = tcg_temp_new_i64();
8485
8486 gen_load_fpr64(ctx, fp0, fs);
8487 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8488 gen_store_fpr64(ctx, fp0, fd);
8489 tcg_temp_free_i64(fp0);
8490 }
8491 opn = "recip1.ps";
8492 break;
8493 case OPC_RSQRT1_PS:
8494 check_cp1_64bitmode(ctx);
8495 {
8496 TCGv_i64 fp0 = tcg_temp_new_i64();
8497
8498 gen_load_fpr64(ctx, fp0, fs);
8499 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8500 gen_store_fpr64(ctx, fp0, fd);
8501 tcg_temp_free_i64(fp0);
8502 }
8503 opn = "rsqrt1.ps";
8504 break;
8505 case OPC_RSQRT2_PS:
8506 check_cp1_64bitmode(ctx);
8507 {
8508 TCGv_i64 fp0 = tcg_temp_new_i64();
8509 TCGv_i64 fp1 = tcg_temp_new_i64();
8510
8511 gen_load_fpr64(ctx, fp0, fs);
8512 gen_load_fpr64(ctx, fp1, ft);
8513 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8514 tcg_temp_free_i64(fp1);
8515 gen_store_fpr64(ctx, fp0, fd);
8516 tcg_temp_free_i64(fp0);
8517 }
8518 opn = "rsqrt2.ps";
8519 break;
8520 case OPC_CVT_S_PU:
8521 check_cp1_64bitmode(ctx);
8522 {
8523 TCGv_i32 fp0 = tcg_temp_new_i32();
8524
8525 gen_load_fpr32h(ctx, fp0, fs);
8526 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8527 gen_store_fpr32(fp0, fd);
8528 tcg_temp_free_i32(fp0);
8529 }
8530 opn = "cvt.s.pu";
8531 break;
8532 case OPC_CVT_PW_PS:
8533 check_cp1_64bitmode(ctx);
8534 {
8535 TCGv_i64 fp0 = tcg_temp_new_i64();
8536
8537 gen_load_fpr64(ctx, fp0, fs);
8538 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8539 gen_store_fpr64(ctx, fp0, fd);
8540 tcg_temp_free_i64(fp0);
8541 }
8542 opn = "cvt.pw.ps";
8543 break;
8544 case OPC_CVT_S_PL:
8545 check_cp1_64bitmode(ctx);
8546 {
8547 TCGv_i32 fp0 = tcg_temp_new_i32();
8548
8549 gen_load_fpr32(fp0, fs);
8550 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8551 gen_store_fpr32(fp0, fd);
8552 tcg_temp_free_i32(fp0);
8553 }
8554 opn = "cvt.s.pl";
8555 break;
8556 case OPC_PLL_PS:
8557 check_cp1_64bitmode(ctx);
8558 {
8559 TCGv_i32 fp0 = tcg_temp_new_i32();
8560 TCGv_i32 fp1 = tcg_temp_new_i32();
8561
8562 gen_load_fpr32(fp0, fs);
8563 gen_load_fpr32(fp1, ft);
8564 gen_store_fpr32h(ctx, fp0, fd);
8565 gen_store_fpr32(fp1, fd);
8566 tcg_temp_free_i32(fp0);
8567 tcg_temp_free_i32(fp1);
8568 }
8569 opn = "pll.ps";
8570 break;
8571 case OPC_PLU_PS:
8572 check_cp1_64bitmode(ctx);
8573 {
8574 TCGv_i32 fp0 = tcg_temp_new_i32();
8575 TCGv_i32 fp1 = tcg_temp_new_i32();
8576
8577 gen_load_fpr32(fp0, fs);
8578 gen_load_fpr32h(ctx, fp1, ft);
8579 gen_store_fpr32(fp1, fd);
8580 gen_store_fpr32h(ctx, fp0, fd);
8581 tcg_temp_free_i32(fp0);
8582 tcg_temp_free_i32(fp1);
8583 }
8584 opn = "plu.ps";
8585 break;
8586 case OPC_PUL_PS:
8587 check_cp1_64bitmode(ctx);
8588 {
8589 TCGv_i32 fp0 = tcg_temp_new_i32();
8590 TCGv_i32 fp1 = tcg_temp_new_i32();
8591
8592 gen_load_fpr32h(ctx, fp0, fs);
8593 gen_load_fpr32(fp1, ft);
8594 gen_store_fpr32(fp1, fd);
8595 gen_store_fpr32h(ctx, fp0, fd);
8596 tcg_temp_free_i32(fp0);
8597 tcg_temp_free_i32(fp1);
8598 }
8599 opn = "pul.ps";
8600 break;
8601 case OPC_PUU_PS:
8602 check_cp1_64bitmode(ctx);
8603 {
8604 TCGv_i32 fp0 = tcg_temp_new_i32();
8605 TCGv_i32 fp1 = tcg_temp_new_i32();
8606
8607 gen_load_fpr32h(ctx, fp0, fs);
8608 gen_load_fpr32h(ctx, fp1, ft);
8609 gen_store_fpr32(fp1, fd);
8610 gen_store_fpr32h(ctx, fp0, fd);
8611 tcg_temp_free_i32(fp0);
8612 tcg_temp_free_i32(fp1);
8613 }
8614 opn = "puu.ps";
8615 break;
8616 case OPC_CMP_F_PS:
8617 case OPC_CMP_UN_PS:
8618 case OPC_CMP_EQ_PS:
8619 case OPC_CMP_UEQ_PS:
8620 case OPC_CMP_OLT_PS:
8621 case OPC_CMP_ULT_PS:
8622 case OPC_CMP_OLE_PS:
8623 case OPC_CMP_ULE_PS:
8624 case OPC_CMP_SF_PS:
8625 case OPC_CMP_NGLE_PS:
8626 case OPC_CMP_SEQ_PS:
8627 case OPC_CMP_NGL_PS:
8628 case OPC_CMP_LT_PS:
8629 case OPC_CMP_NGE_PS:
8630 case OPC_CMP_LE_PS:
8631 case OPC_CMP_NGT_PS:
8632 if (ctx->opcode & (1 << 6)) {
8633 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8634 opn = condnames_abs[func-48];
8635 } else {
8636 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8637 opn = condnames[func-48];
8638 }
8639 break;
8640 default:
8641 MIPS_INVAL(opn);
8642 generate_exception (ctx, EXCP_RI);
8643 return;
8644 }
8645 (void)opn; /* avoid a compiler warning */
8646 switch (optype) {
8647 case BINOP:
8648 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8649 break;
8650 case CMPOP:
8651 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8652 break;
8653 default:
8654 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8655 break;
8656 }
8657 }
8658
8659 /* Coprocessor 3 (FPU) */
8660 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8661 int fd, int fs, int base, int index)
8662 {
8663 const char *opn = "extended float load/store";
8664 int store = 0;
8665 TCGv t0 = tcg_temp_new();
8666
8667 if (base == 0) {
8668 gen_load_gpr(t0, index);
8669 } else if (index == 0) {
8670 gen_load_gpr(t0, base);
8671 } else {
8672 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8673 }
8674 /* Don't do NOP if destination is zero: we must perform the actual
8675 memory access. */
8676 switch (opc) {
8677 case OPC_LWXC1:
8678 check_cop1x(ctx);
8679 {
8680 TCGv_i32 fp0 = tcg_temp_new_i32();
8681
8682 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
8683 tcg_gen_trunc_tl_i32(fp0, t0);
8684 gen_store_fpr32(fp0, fd);
8685 tcg_temp_free_i32(fp0);
8686 }
8687 opn = "lwxc1";
8688 break;
8689 case OPC_LDXC1:
8690 check_cop1x(ctx);
8691 check_cp1_registers(ctx, fd);
8692 {
8693 TCGv_i64 fp0 = tcg_temp_new_i64();
8694 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8695 gen_store_fpr64(ctx, fp0, fd);
8696 tcg_temp_free_i64(fp0);
8697 }
8698 opn = "ldxc1";
8699 break;
8700 case OPC_LUXC1:
8701 check_cp1_64bitmode(ctx);
8702 tcg_gen_andi_tl(t0, t0, ~0x7);
8703 {
8704 TCGv_i64 fp0 = tcg_temp_new_i64();
8705
8706 tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8707 gen_store_fpr64(ctx, fp0, fd);
8708 tcg_temp_free_i64(fp0);
8709 }
8710 opn = "luxc1";
8711 break;
8712 case OPC_SWXC1:
8713 check_cop1x(ctx);
8714 {
8715 TCGv_i32 fp0 = tcg_temp_new_i32();
8716 gen_load_fpr32(fp0, fs);
8717 tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
8718 tcg_temp_free_i32(fp0);
8719 }
8720 opn = "swxc1";
8721 store = 1;
8722 break;
8723 case OPC_SDXC1:
8724 check_cop1x(ctx);
8725 check_cp1_registers(ctx, fs);
8726 {
8727 TCGv_i64 fp0 = tcg_temp_new_i64();
8728 gen_load_fpr64(ctx, fp0, fs);
8729 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8730 tcg_temp_free_i64(fp0);
8731 }
8732 opn = "sdxc1";
8733 store = 1;
8734 break;
8735 case OPC_SUXC1:
8736 check_cp1_64bitmode(ctx);
8737 tcg_gen_andi_tl(t0, t0, ~0x7);
8738 {
8739 TCGv_i64 fp0 = tcg_temp_new_i64();
8740 gen_load_fpr64(ctx, fp0, fs);
8741 tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
8742 tcg_temp_free_i64(fp0);
8743 }
8744 opn = "suxc1";
8745 store = 1;
8746 break;
8747 }
8748 tcg_temp_free(t0);
8749 (void)opn; (void)store; /* avoid compiler warnings */
8750 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8751 regnames[index], regnames[base]);
8752 }
8753
8754 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8755 int fd, int fr, int fs, int ft)
8756 {
8757 const char *opn = "flt3_arith";
8758
8759 switch (opc) {
8760 case OPC_ALNV_PS:
8761 check_cp1_64bitmode(ctx);
8762 {
8763 TCGv t0 = tcg_temp_local_new();
8764 TCGv_i32 fp = tcg_temp_new_i32();
8765 TCGv_i32 fph = tcg_temp_new_i32();
8766 int l1 = gen_new_label();
8767 int l2 = gen_new_label();
8768
8769 gen_load_gpr(t0, fr);
8770 tcg_gen_andi_tl(t0, t0, 0x7);
8771
8772 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8773 gen_load_fpr32(fp, fs);
8774 gen_load_fpr32h(ctx, fph, fs);
8775 gen_store_fpr32(fp, fd);
8776 gen_store_fpr32h(ctx, fph, fd);
8777 tcg_gen_br(l2);
8778 gen_set_label(l1);
8779 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8780 tcg_temp_free(t0);
8781 #ifdef TARGET_WORDS_BIGENDIAN
8782 gen_load_fpr32(fp, fs);
8783 gen_load_fpr32h(ctx, fph, ft);
8784 gen_store_fpr32h(ctx, fp, fd);
8785 gen_store_fpr32(fph, fd);
8786 #else
8787 gen_load_fpr32h(ctx, fph, fs);
8788 gen_load_fpr32(fp, ft);
8789 gen_store_fpr32(fph, fd);
8790 gen_store_fpr32h(ctx, fp, fd);
8791 #endif
8792 gen_set_label(l2);
8793 tcg_temp_free_i32(fp);
8794 tcg_temp_free_i32(fph);
8795 }
8796 opn = "alnv.ps";
8797 break;
8798 case OPC_MADD_S:
8799 check_cop1x(ctx);
8800 {
8801 TCGv_i32 fp0 = tcg_temp_new_i32();
8802 TCGv_i32 fp1 = tcg_temp_new_i32();
8803 TCGv_i32 fp2 = tcg_temp_new_i32();
8804
8805 gen_load_fpr32(fp0, fs);
8806 gen_load_fpr32(fp1, ft);
8807 gen_load_fpr32(fp2, fr);
8808 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8809 tcg_temp_free_i32(fp0);
8810 tcg_temp_free_i32(fp1);
8811 gen_store_fpr32(fp2, fd);
8812 tcg_temp_free_i32(fp2);
8813 }
8814 opn = "madd.s";
8815 break;
8816 case OPC_MADD_D:
8817 check_cop1x(ctx);
8818 check_cp1_registers(ctx, fd | fs | ft | fr);
8819 {
8820 TCGv_i64 fp0 = tcg_temp_new_i64();
8821 TCGv_i64 fp1 = tcg_temp_new_i64();
8822 TCGv_i64 fp2 = tcg_temp_new_i64();
8823
8824 gen_load_fpr64(ctx, fp0, fs);
8825 gen_load_fpr64(ctx, fp1, ft);
8826 gen_load_fpr64(ctx, fp2, fr);
8827 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8828 tcg_temp_free_i64(fp0);
8829 tcg_temp_free_i64(fp1);
8830 gen_store_fpr64(ctx, fp2, fd);
8831 tcg_temp_free_i64(fp2);
8832 }
8833 opn = "madd.d";
8834 break;
8835 case OPC_MADD_PS:
8836 check_cp1_64bitmode(ctx);
8837 {
8838 TCGv_i64 fp0 = tcg_temp_new_i64();
8839 TCGv_i64 fp1 = tcg_temp_new_i64();
8840 TCGv_i64 fp2 = tcg_temp_new_i64();
8841
8842 gen_load_fpr64(ctx, fp0, fs);
8843 gen_load_fpr64(ctx, fp1, ft);
8844 gen_load_fpr64(ctx, fp2, fr);
8845 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8846 tcg_temp_free_i64(fp0);
8847 tcg_temp_free_i64(fp1);
8848 gen_store_fpr64(ctx, fp2, fd);
8849 tcg_temp_free_i64(fp2);
8850 }
8851 opn = "madd.ps";
8852 break;
8853 case OPC_MSUB_S:
8854 check_cop1x(ctx);
8855 {
8856 TCGv_i32 fp0 = tcg_temp_new_i32();
8857 TCGv_i32 fp1 = tcg_temp_new_i32();
8858 TCGv_i32 fp2 = tcg_temp_new_i32();
8859
8860 gen_load_fpr32(fp0, fs);
8861 gen_load_fpr32(fp1, ft);
8862 gen_load_fpr32(fp2, fr);
8863 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8864 tcg_temp_free_i32(fp0);
8865 tcg_temp_free_i32(fp1);
8866 gen_store_fpr32(fp2, fd);
8867 tcg_temp_free_i32(fp2);
8868 }
8869 opn = "msub.s";
8870 break;
8871 case OPC_MSUB_D:
8872 check_cop1x(ctx);
8873 check_cp1_registers(ctx, fd | fs | ft | fr);
8874 {
8875 TCGv_i64 fp0 = tcg_temp_new_i64();
8876 TCGv_i64 fp1 = tcg_temp_new_i64();
8877 TCGv_i64 fp2 = tcg_temp_new_i64();
8878
8879 gen_load_fpr64(ctx, fp0, fs);
8880 gen_load_fpr64(ctx, fp1, ft);
8881 gen_load_fpr64(ctx, fp2, fr);
8882 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8883 tcg_temp_free_i64(fp0);
8884 tcg_temp_free_i64(fp1);
8885 gen_store_fpr64(ctx, fp2, fd);
8886 tcg_temp_free_i64(fp2);
8887 }
8888 opn = "msub.d";
8889 break;
8890 case OPC_MSUB_PS:
8891 check_cp1_64bitmode(ctx);
8892 {
8893 TCGv_i64 fp0 = tcg_temp_new_i64();
8894 TCGv_i64 fp1 = tcg_temp_new_i64();
8895 TCGv_i64 fp2 = tcg_temp_new_i64();
8896
8897 gen_load_fpr64(ctx, fp0, fs);
8898 gen_load_fpr64(ctx, fp1, ft);
8899 gen_load_fpr64(ctx, fp2, fr);
8900 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8901 tcg_temp_free_i64(fp0);
8902 tcg_temp_free_i64(fp1);
8903 gen_store_fpr64(ctx, fp2, fd);
8904 tcg_temp_free_i64(fp2);
8905 }
8906 opn = "msub.ps";
8907 break;
8908 case OPC_NMADD_S:
8909 check_cop1x(ctx);
8910 {
8911 TCGv_i32 fp0 = tcg_temp_new_i32();
8912 TCGv_i32 fp1 = tcg_temp_new_i32();
8913 TCGv_i32 fp2 = tcg_temp_new_i32();
8914
8915 gen_load_fpr32(fp0, fs);
8916 gen_load_fpr32(fp1, ft);
8917 gen_load_fpr32(fp2, fr);
8918 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8919 tcg_temp_free_i32(fp0);
8920 tcg_temp_free_i32(fp1);
8921 gen_store_fpr32(fp2, fd);
8922 tcg_temp_free_i32(fp2);
8923 }
8924 opn = "nmadd.s";
8925 break;
8926 case OPC_NMADD_D:
8927 check_cop1x(ctx);
8928 check_cp1_registers(ctx, fd | fs | ft | fr);
8929 {
8930 TCGv_i64 fp0 = tcg_temp_new_i64();
8931 TCGv_i64 fp1 = tcg_temp_new_i64();
8932 TCGv_i64 fp2 = tcg_temp_new_i64();
8933
8934 gen_load_fpr64(ctx, fp0, fs);
8935 gen_load_fpr64(ctx, fp1, ft);
8936 gen_load_fpr64(ctx, fp2, fr);
8937 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8938 tcg_temp_free_i64(fp0);
8939 tcg_temp_free_i64(fp1);
8940 gen_store_fpr64(ctx, fp2, fd);
8941 tcg_temp_free_i64(fp2);
8942 }
8943 opn = "nmadd.d";
8944 break;
8945 case OPC_NMADD_PS:
8946 check_cp1_64bitmode(ctx);
8947 {
8948 TCGv_i64 fp0 = tcg_temp_new_i64();
8949 TCGv_i64 fp1 = tcg_temp_new_i64();
8950 TCGv_i64 fp2 = tcg_temp_new_i64();
8951
8952 gen_load_fpr64(ctx, fp0, fs);
8953 gen_load_fpr64(ctx, fp1, ft);
8954 gen_load_fpr64(ctx, fp2, fr);
8955 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8956 tcg_temp_free_i64(fp0);
8957 tcg_temp_free_i64(fp1);
8958 gen_store_fpr64(ctx, fp2, fd);
8959 tcg_temp_free_i64(fp2);
8960 }
8961 opn = "nmadd.ps";
8962 break;
8963 case OPC_NMSUB_S:
8964 check_cop1x(ctx);
8965 {
8966 TCGv_i32 fp0 = tcg_temp_new_i32();
8967 TCGv_i32 fp1 = tcg_temp_new_i32();
8968 TCGv_i32 fp2 = tcg_temp_new_i32();
8969
8970 gen_load_fpr32(fp0, fs);
8971 gen_load_fpr32(fp1, ft);
8972 gen_load_fpr32(fp2, fr);
8973 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8974 tcg_temp_free_i32(fp0);
8975 tcg_temp_free_i32(fp1);
8976 gen_store_fpr32(fp2, fd);
8977 tcg_temp_free_i32(fp2);
8978 }
8979 opn = "nmsub.s";
8980 break;
8981 case OPC_NMSUB_D:
8982 check_cop1x(ctx);
8983 check_cp1_registers(ctx, fd | fs | ft | fr);
8984 {
8985 TCGv_i64 fp0 = tcg_temp_new_i64();
8986 TCGv_i64 fp1 = tcg_temp_new_i64();
8987 TCGv_i64 fp2 = tcg_temp_new_i64();
8988
8989 gen_load_fpr64(ctx, fp0, fs);
8990 gen_load_fpr64(ctx, fp1, ft);
8991 gen_load_fpr64(ctx, fp2, fr);
8992 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
8993 tcg_temp_free_i64(fp0);
8994 tcg_temp_free_i64(fp1);
8995 gen_store_fpr64(ctx, fp2, fd);
8996 tcg_temp_free_i64(fp2);
8997 }
8998 opn = "nmsub.d";
8999 break;
9000 case OPC_NMSUB_PS:
9001 check_cp1_64bitmode(ctx);
9002 {
9003 TCGv_i64 fp0 = tcg_temp_new_i64();
9004 TCGv_i64 fp1 = tcg_temp_new_i64();
9005 TCGv_i64 fp2 = tcg_temp_new_i64();
9006
9007 gen_load_fpr64(ctx, fp0, fs);
9008 gen_load_fpr64(ctx, fp1, ft);
9009 gen_load_fpr64(ctx, fp2, fr);
9010 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
9011 tcg_temp_free_i64(fp0);
9012 tcg_temp_free_i64(fp1);
9013 gen_store_fpr64(ctx, fp2, fd);
9014 tcg_temp_free_i64(fp2);
9015 }
9016 opn = "nmsub.ps";
9017 break;
9018 default:
9019 MIPS_INVAL(opn);
9020 generate_exception (ctx, EXCP_RI);
9021 return;
9022 }
9023 (void)opn; /* avoid a compiler warning */
9024 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9025 fregnames[fs], fregnames[ft]);
9026 }
9027
9028 static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
9029 {
9030 TCGv t0;
9031
9032 #if !defined(CONFIG_USER_ONLY)
9033 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9034 Therefore only check the ISA in system mode. */
9035 check_insn(ctx, ISA_MIPS32R2);
9036 #endif
9037 t0 = tcg_temp_new();
9038
9039 switch (rd) {
9040 case 0:
9041 save_cpu_state(ctx, 1);
9042 gen_helper_rdhwr_cpunum(t0, cpu_env);
9043 gen_store_gpr(t0, rt);
9044 break;
9045 case 1:
9046 save_cpu_state(ctx, 1);
9047 gen_helper_rdhwr_synci_step(t0, cpu_env);
9048 gen_store_gpr(t0, rt);
9049 break;
9050 case 2:
9051 save_cpu_state(ctx, 1);
9052 gen_helper_rdhwr_cc(t0, cpu_env);
9053 gen_store_gpr(t0, rt);
9054 break;
9055 case 3:
9056 save_cpu_state(ctx, 1);
9057 gen_helper_rdhwr_ccres(t0, cpu_env);
9058 gen_store_gpr(t0, rt);
9059 break;
9060 case 29:
9061 #if defined(CONFIG_USER_ONLY)
9062 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9063 gen_store_gpr(t0, rt);
9064 break;
9065 #else
9066 /* XXX: Some CPUs implement this in hardware.
9067 Not supported yet. */
9068 #endif
9069 default: /* Invalid */
9070 MIPS_INVAL("rdhwr");
9071 generate_exception(ctx, EXCP_RI);
9072 break;
9073 }
9074 tcg_temp_free(t0);
9075 }
9076
9077 static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
9078 {
9079 if (ctx->hflags & MIPS_HFLAG_BMASK) {
9080 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9081 /* Branches completion */
9082 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9083 ctx->bstate = BS_BRANCH;
9084 save_cpu_state(ctx, 0);
9085 /* FIXME: Need to clear can_do_io. */
9086 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9087 case MIPS_HFLAG_B:
9088 /* unconditional branch */
9089 MIPS_DEBUG("unconditional branch");
9090 if (proc_hflags & MIPS_HFLAG_BX) {
9091 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9092 }
9093 gen_goto_tb(ctx, 0, ctx->btarget);
9094 break;
9095 case MIPS_HFLAG_BL:
9096 /* blikely taken case */
9097 MIPS_DEBUG("blikely branch taken");
9098 gen_goto_tb(ctx, 0, ctx->btarget);
9099 break;
9100 case MIPS_HFLAG_BC:
9101 /* Conditional branch */
9102 MIPS_DEBUG("conditional branch");
9103 {
9104 int l1 = gen_new_label();
9105
9106 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9107 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9108 gen_set_label(l1);
9109 gen_goto_tb(ctx, 0, ctx->btarget);
9110 }
9111 break;
9112 case MIPS_HFLAG_BR:
9113 /* unconditional branch to register */
9114 MIPS_DEBUG("branch to register");
9115 if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9116 TCGv t0 = tcg_temp_new();
9117 TCGv_i32 t1 = tcg_temp_new_i32();
9118
9119 tcg_gen_andi_tl(t0, btarget, 0x1);
9120 tcg_gen_trunc_tl_i32(t1, t0);
9121 tcg_temp_free(t0);
9122 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9123 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9124 tcg_gen_or_i32(hflags, hflags, t1);
9125 tcg_temp_free_i32(t1);
9126
9127 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9128 } else {
9129 tcg_gen_mov_tl(cpu_PC, btarget);
9130 }
9131 if (ctx->singlestep_enabled) {
9132 save_cpu_state(ctx, 0);
9133 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9134 }
9135 tcg_gen_exit_tb(0);
9136 break;
9137 default:
9138 MIPS_DEBUG("unknown branch");
9139 break;
9140 }
9141 }
9142 }
9143
9144 /* ISA extensions (ASEs) */
9145 /* MIPS16 extension to MIPS32 */
9146
9147 /* MIPS16 major opcodes */
9148 enum {
9149 M16_OPC_ADDIUSP = 0x00,
9150 M16_OPC_ADDIUPC = 0x01,
9151 M16_OPC_B = 0x02,
9152 M16_OPC_JAL = 0x03,
9153 M16_OPC_BEQZ = 0x04,
9154 M16_OPC_BNEQZ = 0x05,
9155 M16_OPC_SHIFT = 0x06,
9156 M16_OPC_LD = 0x07,
9157 M16_OPC_RRIA = 0x08,
9158 M16_OPC_ADDIU8 = 0x09,
9159 M16_OPC_SLTI = 0x0a,
9160 M16_OPC_SLTIU = 0x0b,
9161 M16_OPC_I8 = 0x0c,
9162 M16_OPC_LI = 0x0d,
9163 M16_OPC_CMPI = 0x0e,
9164 M16_OPC_SD = 0x0f,
9165 M16_OPC_LB = 0x10,
9166 M16_OPC_LH = 0x11,
9167 M16_OPC_LWSP = 0x12,
9168 M16_OPC_LW = 0x13,
9169 M16_OPC_LBU = 0x14,
9170 M16_OPC_LHU = 0x15,
9171 M16_OPC_LWPC = 0x16,
9172 M16_OPC_LWU = 0x17,
9173 M16_OPC_SB = 0x18,
9174 M16_OPC_SH = 0x19,
9175 M16_OPC_SWSP = 0x1a,
9176 M16_OPC_SW = 0x1b,
9177 M16_OPC_RRR = 0x1c,
9178 M16_OPC_RR = 0x1d,
9179 M16_OPC_EXTEND = 0x1e,
9180 M16_OPC_I64 = 0x1f
9181 };
9182
9183 /* I8 funct field */
9184 enum {
9185 I8_BTEQZ = 0x0,
9186 I8_BTNEZ = 0x1,
9187 I8_SWRASP = 0x2,
9188 I8_ADJSP = 0x3,
9189 I8_SVRS = 0x4,
9190 I8_MOV32R = 0x5,
9191 I8_MOVR32 = 0x7
9192 };
9193
9194 /* RRR f field */
9195 enum {
9196 RRR_DADDU = 0x0,
9197 RRR_ADDU = 0x1,
9198 RRR_DSUBU = 0x2,
9199 RRR_SUBU = 0x3
9200 };
9201
9202 /* RR funct field */
9203 enum {
9204 RR_JR = 0x00,
9205 RR_SDBBP = 0x01,
9206 RR_SLT = 0x02,
9207 RR_SLTU = 0x03,
9208 RR_SLLV = 0x04,
9209 RR_BREAK = 0x05,
9210 RR_SRLV = 0x06,
9211 RR_SRAV = 0x07,
9212 RR_DSRL = 0x08,
9213 RR_CMP = 0x0a,
9214 RR_NEG = 0x0b,
9215 RR_AND = 0x0c,
9216 RR_OR = 0x0d,
9217 RR_XOR = 0x0e,
9218 RR_NOT = 0x0f,
9219 RR_MFHI = 0x10,
9220 RR_CNVT = 0x11,
9221 RR_MFLO = 0x12,
9222 RR_DSRA = 0x13,
9223 RR_DSLLV = 0x14,
9224 RR_DSRLV = 0x16,
9225 RR_DSRAV = 0x17,
9226 RR_MULT = 0x18,
9227 RR_MULTU = 0x19,
9228 RR_DIV = 0x1a,
9229 RR_DIVU = 0x1b,
9230 RR_DMULT = 0x1c,
9231 RR_DMULTU = 0x1d,
9232 RR_DDIV = 0x1e,
9233 RR_DDIVU = 0x1f
9234 };
9235
9236 /* I64 funct field */
9237 enum {
9238 I64_LDSP = 0x0,
9239 I64_SDSP = 0x1,
9240 I64_SDRASP = 0x2,
9241 I64_DADJSP = 0x3,
9242 I64_LDPC = 0x4,
9243 I64_DADDIU5 = 0x5,
9244 I64_DADDIUPC = 0x6,
9245 I64_DADDIUSP = 0x7
9246 };
9247
9248 /* RR ry field for CNVT */
9249 enum {
9250 RR_RY_CNVT_ZEB = 0x0,
9251 RR_RY_CNVT_ZEH = 0x1,
9252 RR_RY_CNVT_ZEW = 0x2,
9253 RR_RY_CNVT_SEB = 0x4,
9254 RR_RY_CNVT_SEH = 0x5,
9255 RR_RY_CNVT_SEW = 0x6,
9256 };
9257
9258 static int xlat (int r)
9259 {
9260 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9261
9262 return map[r];
9263 }
9264
9265 static void gen_mips16_save (DisasContext *ctx,
9266 int xsregs, int aregs,
9267 int do_ra, int do_s0, int do_s1,
9268 int framesize)
9269 {
9270 TCGv t0 = tcg_temp_new();
9271 TCGv t1 = tcg_temp_new();
9272 int args, astatic;
9273
9274 switch (aregs) {
9275 case 0:
9276 case 1:
9277 case 2:
9278 case 3:
9279 case 11:
9280 args = 0;
9281 break;
9282 case 4:
9283 case 5:
9284 case 6:
9285 case 7:
9286 args = 1;
9287 break;
9288 case 8:
9289 case 9:
9290 case 10:
9291 args = 2;
9292 break;
9293 case 12:
9294 case 13:
9295 args = 3;
9296 break;
9297 case 14:
9298 args = 4;
9299 break;
9300 default:
9301 generate_exception(ctx, EXCP_RI);
9302 return;
9303 }
9304
9305 switch (args) {
9306 case 4:
9307 gen_base_offset_addr(ctx, t0, 29, 12);
9308 gen_load_gpr(t1, 7);
9309 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9310 /* Fall through */
9311 case 3:
9312 gen_base_offset_addr(ctx, t0, 29, 8);
9313 gen_load_gpr(t1, 6);
9314 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9315 /* Fall through */
9316 case 2:
9317 gen_base_offset_addr(ctx, t0, 29, 4);
9318 gen_load_gpr(t1, 5);
9319 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9320 /* Fall through */
9321 case 1:
9322 gen_base_offset_addr(ctx, t0, 29, 0);
9323 gen_load_gpr(t1, 4);
9324 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
9325 }
9326
9327 gen_load_gpr(t0, 29);
9328
9329 #define DECR_AND_STORE(reg) do { \
9330 tcg_gen_subi_tl(t0, t0, 4); \
9331 gen_load_gpr(t1, reg); \
9332 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9333 } while (0)
9334
9335 if (do_ra) {
9336 DECR_AND_STORE(31);
9337 }
9338
9339 switch (xsregs) {
9340 case 7:
9341 DECR_AND_STORE(30);
9342 /* Fall through */
9343 case 6:
9344 DECR_AND_STORE(23);
9345 /* Fall through */
9346 case 5:
9347 DECR_AND_STORE(22);
9348 /* Fall through */
9349 case 4:
9350 DECR_AND_STORE(21);
9351 /* Fall through */
9352 case 3:
9353 DECR_AND_STORE(20);
9354 /* Fall through */
9355 case 2:
9356 DECR_AND_STORE(19);
9357 /* Fall through */
9358 case 1:
9359 DECR_AND_STORE(18);
9360 }
9361
9362 if (do_s1) {
9363 DECR_AND_STORE(17);
9364 }
9365 if (do_s0) {
9366 DECR_AND_STORE(16);
9367 }
9368
9369 switch (aregs) {
9370 case 0:
9371 case 4:
9372 case 8:
9373 case 12:
9374 case 14:
9375 astatic = 0;
9376 break;
9377 case 1:
9378 case 5:
9379 case 9:
9380 case 13:
9381 astatic = 1;
9382 break;
9383 case 2:
9384 case 6:
9385 case 10:
9386 astatic = 2;
9387 break;
9388 case 3:
9389 case 7:
9390 astatic = 3;
9391 break;
9392 case 11:
9393 astatic = 4;
9394 break;
9395 default:
9396 generate_exception(ctx, EXCP_RI);
9397 return;
9398 }
9399
9400 if (astatic > 0) {
9401 DECR_AND_STORE(7);
9402 if (astatic > 1) {
9403 DECR_AND_STORE(6);
9404 if (astatic > 2) {
9405 DECR_AND_STORE(5);
9406 if (astatic > 3) {
9407 DECR_AND_STORE(4);
9408 }
9409 }
9410 }
9411 }
9412 #undef DECR_AND_STORE
9413
9414 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9415 tcg_temp_free(t0);
9416 tcg_temp_free(t1);
9417 }
9418
9419 static void gen_mips16_restore (DisasContext *ctx,
9420 int xsregs, int aregs,
9421 int do_ra, int do_s0, int do_s1,
9422 int framesize)
9423 {
9424 int astatic;
9425 TCGv t0 = tcg_temp_new();
9426 TCGv t1 = tcg_temp_new();
9427
9428 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9429
9430 #define DECR_AND_LOAD(reg) do { \
9431 tcg_gen_subi_tl(t0, t0, 4); \
9432 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9433 gen_store_gpr(t1, reg); \
9434 } while (0)
9435
9436 if (do_ra) {
9437 DECR_AND_LOAD(31);
9438 }
9439
9440 switch (xsregs) {
9441 case 7:
9442 DECR_AND_LOAD(30);
9443 /* Fall through */
9444 case 6:
9445 DECR_AND_LOAD(23);
9446 /* Fall through */
9447 case 5:
9448 DECR_AND_LOAD(22);
9449 /* Fall through */
9450 case 4:
9451 DECR_AND_LOAD(21);
9452 /* Fall through */
9453 case 3:
9454 DECR_AND_LOAD(20);
9455 /* Fall through */
9456 case 2:
9457 DECR_AND_LOAD(19);
9458 /* Fall through */
9459 case 1:
9460 DECR_AND_LOAD(18);
9461 }
9462
9463 if (do_s1) {
9464 DECR_AND_LOAD(17);
9465 }
9466 if (do_s0) {
9467 DECR_AND_LOAD(16);
9468 }
9469
9470 switch (aregs) {
9471 case 0:
9472 case 4:
9473 case 8:
9474 case 12:
9475 case 14:
9476 astatic = 0;
9477 break;
9478 case 1:
9479 case 5:
9480 case 9:
9481 case 13:
9482 astatic = 1;
9483 break;
9484 case 2:
9485 case 6:
9486 case 10:
9487 astatic = 2;
9488 break;
9489 case 3:
9490 case 7:
9491 astatic = 3;
9492 break;
9493 case 11:
9494 astatic = 4;
9495 break;
9496 default:
9497 generate_exception(ctx, EXCP_RI);
9498 return;
9499 }
9500
9501 if (astatic > 0) {
9502 DECR_AND_LOAD(7);
9503 if (astatic > 1) {
9504 DECR_AND_LOAD(6);
9505 if (astatic > 2) {
9506 DECR_AND_LOAD(5);
9507 if (astatic > 3) {
9508 DECR_AND_LOAD(4);
9509 }
9510 }
9511 }
9512 }
9513 #undef DECR_AND_LOAD
9514
9515 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9516 tcg_temp_free(t0);
9517 tcg_temp_free(t1);
9518 }
9519
9520 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9521 int is_64_bit, int extended)
9522 {
9523 TCGv t0;
9524
9525 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9526 generate_exception(ctx, EXCP_RI);
9527 return;
9528 }
9529
9530 t0 = tcg_temp_new();
9531
9532 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9533 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9534 if (!is_64_bit) {
9535 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9536 }
9537
9538 tcg_temp_free(t0);
9539 }
9540
9541 #if defined(TARGET_MIPS64)
9542 static void decode_i64_mips16 (DisasContext *ctx,
9543 int ry, int funct, int16_t offset,
9544 int extended)
9545 {
9546 switch (funct) {
9547 case I64_LDSP:
9548 check_mips_64(ctx);
9549 offset = extended ? offset : offset << 3;
9550 gen_ld(ctx, OPC_LD, ry, 29, offset);
9551 break;
9552 case I64_SDSP:
9553 check_mips_64(ctx);
9554 offset = extended ? offset : offset << 3;
9555 gen_st(ctx, OPC_SD, ry, 29, offset);
9556 break;
9557 case I64_SDRASP:
9558 check_mips_64(ctx);
9559 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9560 gen_st(ctx, OPC_SD, 31, 29, offset);
9561 break;
9562 case I64_DADJSP:
9563 check_mips_64(ctx);
9564 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9565 gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
9566 break;
9567 case I64_LDPC:
9568 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9569 generate_exception(ctx, EXCP_RI);
9570 } else {
9571 offset = extended ? offset : offset << 3;
9572 gen_ld(ctx, OPC_LDPC, ry, 0, offset);
9573 }
9574 break;
9575 case I64_DADDIU5:
9576 check_mips_64(ctx);
9577 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9578 gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
9579 break;
9580 case I64_DADDIUPC:
9581 check_mips_64(ctx);
9582 offset = extended ? offset : offset << 2;
9583 gen_addiupc(ctx, ry, offset, 1, extended);
9584 break;
9585 case I64_DADDIUSP:
9586 check_mips_64(ctx);
9587 offset = extended ? offset : offset << 2;
9588 gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
9589 break;
9590 }
9591 }
9592 #endif
9593
9594 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9595 {
9596 int extend = cpu_lduw_code(env, ctx->pc + 2);
9597 int op, rx, ry, funct, sa;
9598 int16_t imm, offset;
9599
9600 ctx->opcode = (ctx->opcode << 16) | extend;
9601 op = (ctx->opcode >> 11) & 0x1f;
9602 sa = (ctx->opcode >> 22) & 0x1f;
9603 funct = (ctx->opcode >> 8) & 0x7;
9604 rx = xlat((ctx->opcode >> 8) & 0x7);
9605 ry = xlat((ctx->opcode >> 5) & 0x7);
9606 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9607 | ((ctx->opcode >> 21) & 0x3f) << 5
9608 | (ctx->opcode & 0x1f));
9609
9610 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9611 counterparts. */
9612 switch (op) {
9613 case M16_OPC_ADDIUSP:
9614 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9615 break;
9616 case M16_OPC_ADDIUPC:
9617 gen_addiupc(ctx, rx, imm, 0, 1);
9618 break;
9619 case M16_OPC_B:
9620 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9621 /* No delay slot, so just process as a normal instruction */
9622 break;
9623 case M16_OPC_BEQZ:
9624 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9625 /* No delay slot, so just process as a normal instruction */
9626 break;
9627 case M16_OPC_BNEQZ:
9628 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9629 /* No delay slot, so just process as a normal instruction */
9630 break;
9631 case M16_OPC_SHIFT:
9632 switch (ctx->opcode & 0x3) {
9633 case 0x0:
9634 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9635 break;
9636 case 0x1:
9637 #if defined(TARGET_MIPS64)
9638 check_mips_64(ctx);
9639 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9640 #else
9641 generate_exception(ctx, EXCP_RI);
9642 #endif
9643 break;
9644 case 0x2:
9645 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9646 break;
9647 case 0x3:
9648 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9649 break;
9650 }
9651 break;
9652 #if defined(TARGET_MIPS64)
9653 case M16_OPC_LD:
9654 check_mips_64(ctx);
9655 gen_ld(ctx, OPC_LD, ry, rx, offset);
9656 break;
9657 #endif
9658 case M16_OPC_RRIA:
9659 imm = ctx->opcode & 0xf;
9660 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9661 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9662 imm = (int16_t) (imm << 1) >> 1;
9663 if ((ctx->opcode >> 4) & 0x1) {
9664 #if defined(TARGET_MIPS64)
9665 check_mips_64(ctx);
9666 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9667 #else
9668 generate_exception(ctx, EXCP_RI);
9669 #endif
9670 } else {
9671 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9672 }
9673 break;
9674 case M16_OPC_ADDIU8:
9675 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9676 break;
9677 case M16_OPC_SLTI:
9678 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9679 break;
9680 case M16_OPC_SLTIU:
9681 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9682 break;
9683 case M16_OPC_I8:
9684 switch (funct) {
9685 case I8_BTEQZ:
9686 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9687 break;
9688 case I8_BTNEZ:
9689 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9690 break;
9691 case I8_SWRASP:
9692 gen_st(ctx, OPC_SW, 31, 29, imm);
9693 break;
9694 case I8_ADJSP:
9695 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
9696 break;
9697 case I8_SVRS:
9698 {
9699 int xsregs = (ctx->opcode >> 24) & 0x7;
9700 int aregs = (ctx->opcode >> 16) & 0xf;
9701 int do_ra = (ctx->opcode >> 6) & 0x1;
9702 int do_s0 = (ctx->opcode >> 5) & 0x1;
9703 int do_s1 = (ctx->opcode >> 4) & 0x1;
9704 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9705 | (ctx->opcode & 0xf)) << 3;
9706
9707 if (ctx->opcode & (1 << 7)) {
9708 gen_mips16_save(ctx, xsregs, aregs,
9709 do_ra, do_s0, do_s1,
9710 framesize);
9711 } else {
9712 gen_mips16_restore(ctx, xsregs, aregs,
9713 do_ra, do_s0, do_s1,
9714 framesize);
9715 }
9716 }
9717 break;
9718 default:
9719 generate_exception(ctx, EXCP_RI);
9720 break;
9721 }
9722 break;
9723 case M16_OPC_LI:
9724 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9725 break;
9726 case M16_OPC_CMPI:
9727 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9728 break;
9729 #if defined(TARGET_MIPS64)
9730 case M16_OPC_SD:
9731 gen_st(ctx, OPC_SD, ry, rx, offset);
9732 break;
9733 #endif
9734 case M16_OPC_LB:
9735 gen_ld(ctx, OPC_LB, ry, rx, offset);
9736 break;
9737 case M16_OPC_LH:
9738 gen_ld(ctx, OPC_LH, ry, rx, offset);
9739 break;
9740 case M16_OPC_LWSP:
9741 gen_ld(ctx, OPC_LW, rx, 29, offset);
9742 break;
9743 case M16_OPC_LW:
9744 gen_ld(ctx, OPC_LW, ry, rx, offset);
9745 break;
9746 case M16_OPC_LBU:
9747 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9748 break;
9749 case M16_OPC_LHU:
9750 gen_ld(ctx, OPC_LHU, ry, rx, offset);
9751 break;
9752 case M16_OPC_LWPC:
9753 gen_ld(ctx, OPC_LWPC, rx, 0, offset);
9754 break;
9755 #if defined(TARGET_MIPS64)
9756 case M16_OPC_LWU:
9757 gen_ld(ctx, OPC_LWU, ry, rx, offset);
9758 break;
9759 #endif
9760 case M16_OPC_SB:
9761 gen_st(ctx, OPC_SB, ry, rx, offset);
9762 break;
9763 case M16_OPC_SH:
9764 gen_st(ctx, OPC_SH, ry, rx, offset);
9765 break;
9766 case M16_OPC_SWSP:
9767 gen_st(ctx, OPC_SW, rx, 29, offset);
9768 break;
9769 case M16_OPC_SW:
9770 gen_st(ctx, OPC_SW, ry, rx, offset);
9771 break;
9772 #if defined(TARGET_MIPS64)
9773 case M16_OPC_I64:
9774 decode_i64_mips16(ctx, ry, funct, offset, 1);
9775 break;
9776 #endif
9777 default:
9778 generate_exception(ctx, EXCP_RI);
9779 break;
9780 }
9781
9782 return 4;
9783 }
9784
9785 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9786 {
9787 int rx, ry;
9788 int sa;
9789 int op, cnvt_op, op1, offset;
9790 int funct;
9791 int n_bytes;
9792
9793 op = (ctx->opcode >> 11) & 0x1f;
9794 sa = (ctx->opcode >> 2) & 0x7;
9795 sa = sa == 0 ? 8 : sa;
9796 rx = xlat((ctx->opcode >> 8) & 0x7);
9797 cnvt_op = (ctx->opcode >> 5) & 0x7;
9798 ry = xlat((ctx->opcode >> 5) & 0x7);
9799 op1 = offset = ctx->opcode & 0x1f;
9800
9801 n_bytes = 2;
9802
9803 switch (op) {
9804 case M16_OPC_ADDIUSP:
9805 {
9806 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9807
9808 gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9809 }
9810 break;
9811 case M16_OPC_ADDIUPC:
9812 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9813 break;
9814 case M16_OPC_B:
9815 offset = (ctx->opcode & 0x7ff) << 1;
9816 offset = (int16_t)(offset << 4) >> 4;
9817 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9818 /* No delay slot, so just process as a normal instruction */
9819 break;
9820 case M16_OPC_JAL:
9821 offset = cpu_lduw_code(env, ctx->pc + 2);
9822 offset = (((ctx->opcode & 0x1f) << 21)
9823 | ((ctx->opcode >> 5) & 0x1f) << 16
9824 | offset) << 2;
9825 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9826 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9827 n_bytes = 4;
9828 break;
9829 case M16_OPC_BEQZ:
9830 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9831 /* No delay slot, so just process as a normal instruction */
9832 break;
9833 case M16_OPC_BNEQZ:
9834 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9835 /* No delay slot, so just process as a normal instruction */
9836 break;
9837 case M16_OPC_SHIFT:
9838 switch (ctx->opcode & 0x3) {
9839 case 0x0:
9840 gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9841 break;
9842 case 0x1:
9843 #if defined(TARGET_MIPS64)
9844 check_mips_64(ctx);
9845 gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9846 #else
9847 generate_exception(ctx, EXCP_RI);
9848 #endif
9849 break;
9850 case 0x2:
9851 gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9852 break;
9853 case 0x3:
9854 gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9855 break;
9856 }
9857 break;
9858 #if defined(TARGET_MIPS64)
9859 case M16_OPC_LD:
9860 check_mips_64(ctx);
9861 gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
9862 break;
9863 #endif
9864 case M16_OPC_RRIA:
9865 {
9866 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9867
9868 if ((ctx->opcode >> 4) & 1) {
9869 #if defined(TARGET_MIPS64)
9870 check_mips_64(ctx);
9871 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9872 #else
9873 generate_exception(ctx, EXCP_RI);
9874 #endif
9875 } else {
9876 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9877 }
9878 }
9879 break;
9880 case M16_OPC_ADDIU8:
9881 {
9882 int16_t imm = (int8_t) ctx->opcode;
9883
9884 gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9885 }
9886 break;
9887 case M16_OPC_SLTI:
9888 {
9889 int16_t imm = (uint8_t) ctx->opcode;
9890 gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9891 }
9892 break;
9893 case M16_OPC_SLTIU:
9894 {
9895 int16_t imm = (uint8_t) ctx->opcode;
9896 gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9897 }
9898 break;
9899 case M16_OPC_I8:
9900 {
9901 int reg32;
9902
9903 funct = (ctx->opcode >> 8) & 0x7;
9904 switch (funct) {
9905 case I8_BTEQZ:
9906 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9907 ((int8_t)ctx->opcode) << 1);
9908 break;
9909 case I8_BTNEZ:
9910 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9911 ((int8_t)ctx->opcode) << 1);
9912 break;
9913 case I8_SWRASP:
9914 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9915 break;
9916 case I8_ADJSP:
9917 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
9918 ((int8_t)ctx->opcode) << 3);
9919 break;
9920 case I8_SVRS:
9921 {
9922 int do_ra = ctx->opcode & (1 << 6);
9923 int do_s0 = ctx->opcode & (1 << 5);
9924 int do_s1 = ctx->opcode & (1 << 4);
9925 int framesize = ctx->opcode & 0xf;
9926
9927 if (framesize == 0) {
9928 framesize = 128;
9929 } else {
9930 framesize = framesize << 3;
9931 }
9932
9933 if (ctx->opcode & (1 << 7)) {
9934 gen_mips16_save(ctx, 0, 0,
9935 do_ra, do_s0, do_s1, framesize);
9936 } else {
9937 gen_mips16_restore(ctx, 0, 0,
9938 do_ra, do_s0, do_s1, framesize);
9939 }
9940 }
9941 break;
9942 case I8_MOV32R:
9943 {
9944 int rz = xlat(ctx->opcode & 0x7);
9945
9946 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9947 ((ctx->opcode >> 5) & 0x7);
9948 gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
9949 }
9950 break;
9951 case I8_MOVR32:
9952 reg32 = ctx->opcode & 0x1f;
9953 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
9954 break;
9955 default:
9956 generate_exception(ctx, EXCP_RI);
9957 break;
9958 }
9959 }
9960 break;
9961 case M16_OPC_LI:
9962 {
9963 int16_t imm = (uint8_t) ctx->opcode;
9964
9965 gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
9966 }
9967 break;
9968 case M16_OPC_CMPI:
9969 {
9970 int16_t imm = (uint8_t) ctx->opcode;
9971 gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
9972 }
9973 break;
9974 #if defined(TARGET_MIPS64)
9975 case M16_OPC_SD:
9976 check_mips_64(ctx);
9977 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9978 break;
9979 #endif
9980 case M16_OPC_LB:
9981 gen_ld(ctx, OPC_LB, ry, rx, offset);
9982 break;
9983 case M16_OPC_LH:
9984 gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
9985 break;
9986 case M16_OPC_LWSP:
9987 gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9988 break;
9989 case M16_OPC_LW:
9990 gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
9991 break;
9992 case M16_OPC_LBU:
9993 gen_ld(ctx, OPC_LBU, ry, rx, offset);
9994 break;
9995 case M16_OPC_LHU:
9996 gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
9997 break;
9998 case M16_OPC_LWPC:
9999 gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
10000 break;
10001 #if defined (TARGET_MIPS64)
10002 case M16_OPC_LWU:
10003 check_mips_64(ctx);
10004 gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
10005 break;
10006 #endif
10007 case M16_OPC_SB:
10008 gen_st(ctx, OPC_SB, ry, rx, offset);
10009 break;
10010 case M16_OPC_SH:
10011 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
10012 break;
10013 case M16_OPC_SWSP:
10014 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
10015 break;
10016 case M16_OPC_SW:
10017 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
10018 break;
10019 case M16_OPC_RRR:
10020 {
10021 int rz = xlat((ctx->opcode >> 2) & 0x7);
10022 int mips32_op;
10023
10024 switch (ctx->opcode & 0x3) {
10025 case RRR_ADDU:
10026 mips32_op = OPC_ADDU;
10027 break;
10028 case RRR_SUBU:
10029 mips32_op = OPC_SUBU;
10030 break;
10031 #if defined(TARGET_MIPS64)
10032 case RRR_DADDU:
10033 mips32_op = OPC_DADDU;
10034 check_mips_64(ctx);
10035 break;
10036 case RRR_DSUBU:
10037 mips32_op = OPC_DSUBU;
10038 check_mips_64(ctx);
10039 break;
10040 #endif
10041 default:
10042 generate_exception(ctx, EXCP_RI);
10043 goto done;
10044 }
10045
10046 gen_arith(ctx, mips32_op, rz, rx, ry);
10047 done:
10048 ;
10049 }
10050 break;
10051 case M16_OPC_RR:
10052 switch (op1) {
10053 case RR_JR:
10054 {
10055 int nd = (ctx->opcode >> 7) & 0x1;
10056 int link = (ctx->opcode >> 6) & 0x1;
10057 int ra = (ctx->opcode >> 5) & 0x1;
10058
10059 if (link) {
10060 op = nd ? OPC_JALRC : OPC_JALRS;
10061 } else {
10062 op = OPC_JR;
10063 }
10064
10065 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10066 }
10067 break;
10068 case RR_SDBBP:
10069 /* XXX: not clear which exception should be raised
10070 * when in debug mode...
10071 */
10072 check_insn(ctx, ISA_MIPS32);
10073 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10074 generate_exception(ctx, EXCP_DBp);
10075 } else {
10076 generate_exception(ctx, EXCP_DBp);
10077 }
10078 break;
10079 case RR_SLT:
10080 gen_slt(ctx, OPC_SLT, 24, rx, ry);
10081 break;
10082 case RR_SLTU:
10083 gen_slt(ctx, OPC_SLTU, 24, rx, ry);
10084 break;
10085 case RR_BREAK:
10086 generate_exception(ctx, EXCP_BREAK);
10087 break;
10088 case RR_SLLV:
10089 gen_shift(ctx, OPC_SLLV, ry, rx, ry);
10090 break;
10091 case RR_SRLV:
10092 gen_shift(ctx, OPC_SRLV, ry, rx, ry);
10093 break;
10094 case RR_SRAV:
10095 gen_shift(ctx, OPC_SRAV, ry, rx, ry);
10096 break;
10097 #if defined (TARGET_MIPS64)
10098 case RR_DSRL:
10099 check_mips_64(ctx);
10100 gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
10101 break;
10102 #endif
10103 case RR_CMP:
10104 gen_logic(ctx, OPC_XOR, 24, rx, ry);
10105 break;
10106 case RR_NEG:
10107 gen_arith(ctx, OPC_SUBU, rx, 0, ry);
10108 break;
10109 case RR_AND:
10110 gen_logic(ctx, OPC_AND, rx, rx, ry);
10111 break;
10112 case RR_OR:
10113 gen_logic(ctx, OPC_OR, rx, rx, ry);
10114 break;
10115 case RR_XOR:
10116 gen_logic(ctx, OPC_XOR, rx, rx, ry);
10117 break;
10118 case RR_NOT:
10119 gen_logic(ctx, OPC_NOR, rx, ry, 0);
10120 break;
10121 case RR_MFHI:
10122 gen_HILO(ctx, OPC_MFHI, 0, rx);
10123 break;
10124 case RR_CNVT:
10125 switch (cnvt_op) {
10126 case RR_RY_CNVT_ZEB:
10127 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10128 break;
10129 case RR_RY_CNVT_ZEH:
10130 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10131 break;
10132 case RR_RY_CNVT_SEB:
10133 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10134 break;
10135 case RR_RY_CNVT_SEH:
10136 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10137 break;
10138 #if defined (TARGET_MIPS64)
10139 case RR_RY_CNVT_ZEW:
10140 check_mips_64(ctx);
10141 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10142 break;
10143 case RR_RY_CNVT_SEW:
10144 check_mips_64(ctx);
10145 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10146 break;
10147 #endif
10148 default:
10149 generate_exception(ctx, EXCP_RI);
10150 break;
10151 }
10152 break;
10153 case RR_MFLO:
10154 gen_HILO(ctx, OPC_MFLO, 0, rx);
10155 break;
10156 #if defined (TARGET_MIPS64)
10157 case RR_DSRA:
10158 check_mips_64(ctx);
10159 gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
10160 break;
10161 case RR_DSLLV:
10162 check_mips_64(ctx);
10163 gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
10164 break;
10165 case RR_DSRLV:
10166 check_mips_64(ctx);
10167 gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
10168 break;
10169 case RR_DSRAV:
10170 check_mips_64(ctx);
10171 gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
10172 break;
10173 #endif
10174 case RR_MULT:
10175 gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
10176 break;
10177 case RR_MULTU:
10178 gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
10179 break;
10180 case RR_DIV:
10181 gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
10182 break;
10183 case RR_DIVU:
10184 gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
10185 break;
10186 #if defined (TARGET_MIPS64)
10187 case RR_DMULT:
10188 check_mips_64(ctx);
10189 gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
10190 break;
10191 case RR_DMULTU:
10192 check_mips_64(ctx);
10193 gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
10194 break;
10195 case RR_DDIV:
10196 check_mips_64(ctx);
10197 gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
10198 break;
10199 case RR_DDIVU:
10200 check_mips_64(ctx);
10201 gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
10202 break;
10203 #endif
10204 default:
10205 generate_exception(ctx, EXCP_RI);
10206 break;
10207 }
10208 break;
10209 case M16_OPC_EXTEND:
10210 decode_extended_mips16_opc(env, ctx);
10211 n_bytes = 4;
10212 break;
10213 #if defined(TARGET_MIPS64)
10214 case M16_OPC_I64:
10215 funct = (ctx->opcode >> 8) & 0x7;
10216 decode_i64_mips16(ctx, ry, funct, offset, 0);
10217 break;
10218 #endif
10219 default:
10220 generate_exception(ctx, EXCP_RI);
10221 break;
10222 }
10223
10224 return n_bytes;
10225 }
10226
10227 /* microMIPS extension to MIPS32/MIPS64 */
10228
10229 /*
10230 * microMIPS32/microMIPS64 major opcodes
10231 *
10232 * 1. MIPS Architecture for Programmers Volume II-B:
10233 * The microMIPS32 Instruction Set (Revision 3.05)
10234 *
10235 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10236 *
10237 * 2. MIPS Architecture For Programmers Volume II-A:
10238 * The MIPS64 Instruction Set (Revision 3.51)
10239 */
10240
10241 enum {
10242 POOL32A = 0x00,
10243 POOL16A = 0x01,
10244 LBU16 = 0x02,
10245 MOVE16 = 0x03,
10246 ADDI32 = 0x04,
10247 LBU32 = 0x05,
10248 SB32 = 0x06,
10249 LB32 = 0x07,
10250
10251 POOL32B = 0x08,
10252 POOL16B = 0x09,
10253 LHU16 = 0x0a,
10254 ANDI16 = 0x0b,
10255 ADDIU32 = 0x0c,
10256 LHU32 = 0x0d,
10257 SH32 = 0x0e,
10258 LH32 = 0x0f,
10259
10260 POOL32I = 0x10,
10261 POOL16C = 0x11,
10262 LWSP16 = 0x12,
10263 POOL16D = 0x13,
10264 ORI32 = 0x14,
10265 POOL32F = 0x15,
10266 POOL32S = 0x16, /* MIPS64 */
10267 DADDIU32 = 0x17, /* MIPS64 */
10268
10269 /* 0x1f is reserved */
10270 POOL32C = 0x18,
10271 LWGP16 = 0x19,
10272 LW16 = 0x1a,
10273 POOL16E = 0x1b,
10274 XORI32 = 0x1c,
10275 JALS32 = 0x1d,
10276 ADDIUPC = 0x1e,
10277
10278 /* 0x20 is reserved */
10279 RES_20 = 0x20,
10280 POOL16F = 0x21,
10281 SB16 = 0x22,
10282 BEQZ16 = 0x23,
10283 SLTI32 = 0x24,
10284 BEQ32 = 0x25,
10285 SWC132 = 0x26,
10286 LWC132 = 0x27,
10287
10288 /* 0x28 and 0x29 are reserved */
10289 RES_28 = 0x28,
10290 RES_29 = 0x29,
10291 SH16 = 0x2a,
10292 BNEZ16 = 0x2b,
10293 SLTIU32 = 0x2c,
10294 BNE32 = 0x2d,
10295 SDC132 = 0x2e,
10296 LDC132 = 0x2f,
10297
10298 /* 0x30 and 0x31 are reserved */
10299 RES_30 = 0x30,
10300 RES_31 = 0x31,
10301 SWSP16 = 0x32,
10302 B16 = 0x33,
10303 ANDI32 = 0x34,
10304 J32 = 0x35,
10305 SD32 = 0x36, /* MIPS64 */
10306 LD32 = 0x37, /* MIPS64 */
10307
10308 /* 0x38 and 0x39 are reserved */
10309 RES_38 = 0x38,
10310 RES_39 = 0x39,
10311 SW16 = 0x3a,
10312 LI16 = 0x3b,
10313 JALX32 = 0x3c,
10314 JAL32 = 0x3d,
10315 SW32 = 0x3e,
10316 LW32 = 0x3f
10317 };
10318
10319 /* POOL32A encoding of minor opcode field */
10320
10321 enum {
10322 /* These opcodes are distinguished only by bits 9..6; those bits are
10323 * what are recorded below. */
10324 SLL32 = 0x0,
10325 SRL32 = 0x1,
10326 SRA = 0x2,
10327 ROTR = 0x3,
10328
10329 SLLV = 0x0,
10330 SRLV = 0x1,
10331 SRAV = 0x2,
10332 ROTRV = 0x3,
10333 ADD = 0x4,
10334 ADDU32 = 0x5,
10335 SUB = 0x6,
10336 SUBU32 = 0x7,
10337 MUL = 0x8,
10338 AND = 0x9,
10339 OR32 = 0xa,
10340 NOR = 0xb,
10341 XOR32 = 0xc,
10342 SLT = 0xd,
10343 SLTU = 0xe,
10344
10345 MOVN = 0x0,
10346 MOVZ = 0x1,
10347 LWXS = 0x4,
10348
10349 /* The following can be distinguished by their lower 6 bits. */
10350 INS = 0x0c,
10351 EXT = 0x2c,
10352 POOL32AXF = 0x3c
10353 };
10354
10355 /* POOL32AXF encoding of minor opcode field extension */
10356
10357 /*
10358 * 1. MIPS Architecture for Programmers Volume II-B:
10359 * The microMIPS32 Instruction Set (Revision 3.05)
10360 *
10361 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10362 *
10363 * 2. MIPS Architecture for Programmers VolumeIV-e:
10364 * The MIPS DSP Application-Specific Extension
10365 * to the microMIPS32 Architecture (Revision 2.34)
10366 *
10367 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10368 */
10369
10370 enum {
10371 /* bits 11..6 */
10372 TEQ = 0x00,
10373 TGE = 0x08,
10374 TGEU = 0x10,
10375 TLT = 0x20,
10376 TLTU = 0x28,
10377 TNE = 0x30,
10378
10379 MFC0 = 0x03,
10380 MTC0 = 0x0b,
10381
10382 /* begin of microMIPS32 DSP */
10383
10384 /* bits 13..12 for 0x01 */
10385 MFHI_ACC = 0x0,
10386 MFLO_ACC = 0x1,
10387 MTHI_ACC = 0x2,
10388 MTLO_ACC = 0x3,
10389
10390 /* bits 13..12 for 0x2a */
10391 MADD_ACC = 0x0,
10392 MADDU_ACC = 0x1,
10393 MSUB_ACC = 0x2,
10394 MSUBU_ACC = 0x3,
10395
10396 /* bits 13..12 for 0x32 */
10397 MULT_ACC = 0x0,
10398 MULTU_ACC = 0x1,
10399
10400 /* end of microMIPS32 DSP */
10401
10402 /* bits 15..12 for 0x2c */
10403 SEB = 0x2,
10404 SEH = 0x3,
10405 CLO = 0x4,
10406 CLZ = 0x5,
10407 RDHWR = 0x6,
10408 WSBH = 0x7,
10409 MULT = 0x8,
10410 MULTU = 0x9,
10411 DIV = 0xa,
10412 DIVU = 0xb,
10413 MADD = 0xc,
10414 MADDU = 0xd,
10415 MSUB = 0xe,
10416 MSUBU = 0xf,
10417
10418 /* bits 15..12 for 0x34 */
10419 MFC2 = 0x4,
10420 MTC2 = 0x5,
10421 MFHC2 = 0x8,
10422 MTHC2 = 0x9,
10423 CFC2 = 0xc,
10424 CTC2 = 0xd,
10425
10426 /* bits 15..12 for 0x3c */
10427 JALR = 0x0,
10428 JR = 0x0, /* alias */
10429 JALR_HB = 0x1,
10430 JALRS = 0x4,
10431 JALRS_HB = 0x5,
10432
10433 /* bits 15..12 for 0x05 */
10434 RDPGPR = 0xe,
10435 WRPGPR = 0xf,
10436
10437 /* bits 15..12 for 0x0d */
10438 TLBP = 0x0,
10439 TLBR = 0x1,
10440 TLBWI = 0x2,
10441 TLBWR = 0x3,
10442 WAIT = 0x9,
10443 IRET = 0xd,
10444 DERET = 0xe,
10445 ERET = 0xf,
10446
10447 /* bits 15..12 for 0x15 */
10448 DMT = 0x0,
10449 DVPE = 0x1,
10450 EMT = 0x2,
10451 EVPE = 0x3,
10452
10453 /* bits 15..12 for 0x1d */
10454 DI = 0x4,
10455 EI = 0x5,
10456
10457 /* bits 15..12 for 0x2d */
10458 SYNC = 0x6,
10459 SYSCALL = 0x8,
10460 SDBBP = 0xd,
10461
10462 /* bits 15..12 for 0x35 */
10463 MFHI32 = 0x0,
10464 MFLO32 = 0x1,
10465 MTHI32 = 0x2,
10466 MTLO32 = 0x3,
10467 };
10468
10469 /* POOL32B encoding of minor opcode field (bits 15..12) */
10470
10471 enum {
10472 LWC2 = 0x0,
10473 LWP = 0x1,
10474 LDP = 0x4,
10475 LWM32 = 0x5,
10476 CACHE = 0x6,
10477 LDM = 0x7,
10478 SWC2 = 0x8,
10479 SWP = 0x9,
10480 SDP = 0xc,
10481 SWM32 = 0xd,
10482 SDM = 0xf
10483 };
10484
10485 /* POOL32C encoding of minor opcode field (bits 15..12) */
10486
10487 enum {
10488 LWL = 0x0,
10489 SWL = 0x8,
10490 LWR = 0x1,
10491 SWR = 0x9,
10492 PREF = 0x2,
10493 /* 0xa is reserved */
10494 LL = 0x3,
10495 SC = 0xb,
10496 LDL = 0x4,
10497 SDL = 0xc,
10498 LDR = 0x5,
10499 SDR = 0xd,
10500 /* 0x6 is reserved */
10501 LWU = 0xe,
10502 LLD = 0x7,
10503 SCD = 0xf
10504 };
10505
10506 /* POOL32F encoding of minor opcode field (bits 5..0) */
10507
10508 enum {
10509 /* These are the bit 7..6 values */
10510 ADD_FMT = 0x0,
10511 MOVN_FMT = 0x0,
10512
10513 SUB_FMT = 0x1,
10514 MOVZ_FMT = 0x1,
10515
10516 MUL_FMT = 0x2,
10517
10518 DIV_FMT = 0x3,
10519
10520 /* These are the bit 8..6 values */
10521 RSQRT2_FMT = 0x0,
10522 MOVF_FMT = 0x0,
10523
10524 LWXC1 = 0x1,
10525 MOVT_FMT = 0x1,
10526
10527 PLL_PS = 0x2,
10528 SWXC1 = 0x2,
10529
10530 PLU_PS = 0x3,
10531 LDXC1 = 0x3,
10532
10533 PUL_PS = 0x4,
10534 SDXC1 = 0x4,
10535 RECIP2_FMT = 0x4,
10536
10537 PUU_PS = 0x5,
10538 LUXC1 = 0x5,
10539
10540 CVT_PS_S = 0x6,
10541 SUXC1 = 0x6,
10542 ADDR_PS = 0x6,
10543 PREFX = 0x6,
10544
10545 MULR_PS = 0x7,
10546
10547 MADD_S = 0x01,
10548 MADD_D = 0x09,
10549 MADD_PS = 0x11,
10550 ALNV_PS = 0x19,
10551 MSUB_S = 0x21,
10552 MSUB_D = 0x29,
10553 MSUB_PS = 0x31,
10554
10555 NMADD_S = 0x02,
10556 NMADD_D = 0x0a,
10557 NMADD_PS = 0x12,
10558 NMSUB_S = 0x22,
10559 NMSUB_D = 0x2a,
10560 NMSUB_PS = 0x32,
10561
10562 POOL32FXF = 0x3b,
10563
10564 CABS_COND_FMT = 0x1c, /* MIPS3D */
10565 C_COND_FMT = 0x3c
10566 };
10567
10568 /* POOL32Fxf encoding of minor opcode extension field */
10569
10570 enum {
10571 CVT_L = 0x04,
10572 RSQRT_FMT = 0x08,
10573 FLOOR_L = 0x0c,
10574 CVT_PW_PS = 0x1c,
10575 CVT_W = 0x24,
10576 SQRT_FMT = 0x28,
10577 FLOOR_W = 0x2c,
10578 CVT_PS_PW = 0x3c,
10579 CFC1 = 0x40,
10580 RECIP_FMT = 0x48,
10581 CEIL_L = 0x4c,
10582 CTC1 = 0x60,
10583 CEIL_W = 0x6c,
10584 MFC1 = 0x80,
10585 CVT_S_PL = 0x84,
10586 TRUNC_L = 0x8c,
10587 MTC1 = 0xa0,
10588 CVT_S_PU = 0xa4,
10589 TRUNC_W = 0xac,
10590 MFHC1 = 0xc0,
10591 ROUND_L = 0xcc,
10592 MTHC1 = 0xe0,
10593 ROUND_W = 0xec,
10594
10595 MOV_FMT = 0x01,
10596 MOVF = 0x05,
10597 ABS_FMT = 0x0d,
10598 RSQRT1_FMT = 0x1d,
10599 MOVT = 0x25,
10600 NEG_FMT = 0x2d,
10601 CVT_D = 0x4d,
10602 RECIP1_FMT = 0x5d,
10603 CVT_S = 0x6d
10604 };
10605
10606 /* POOL32I encoding of minor opcode field (bits 25..21) */
10607
10608 enum {
10609 BLTZ = 0x00,
10610 BLTZAL = 0x01,
10611 BGEZ = 0x02,
10612 BGEZAL = 0x03,
10613 BLEZ = 0x04,
10614 BNEZC = 0x05,
10615 BGTZ = 0x06,
10616 BEQZC = 0x07,
10617 TLTI = 0x08,
10618 TGEI = 0x09,
10619 TLTIU = 0x0a,
10620 TGEIU = 0x0b,
10621 TNEI = 0x0c,
10622 LUI = 0x0d,
10623 TEQI = 0x0e,
10624 SYNCI = 0x10,
10625 BLTZALS = 0x11,
10626 BGEZALS = 0x13,
10627 BC2F = 0x14,
10628 BC2T = 0x15,
10629 BPOSGE64 = 0x1a,
10630 BPOSGE32 = 0x1b,
10631 /* These overlap and are distinguished by bit16 of the instruction */
10632 BC1F = 0x1c,
10633 BC1T = 0x1d,
10634 BC1ANY2F = 0x1c,
10635 BC1ANY2T = 0x1d,
10636 BC1ANY4F = 0x1e,
10637 BC1ANY4T = 0x1f
10638 };
10639
10640 /* POOL16A encoding of minor opcode field */
10641
10642 enum {
10643 ADDU16 = 0x0,
10644 SUBU16 = 0x1
10645 };
10646
10647 /* POOL16B encoding of minor opcode field */
10648
10649 enum {
10650 SLL16 = 0x0,
10651 SRL16 = 0x1
10652 };
10653
10654 /* POOL16C encoding of minor opcode field */
10655
10656 enum {
10657 NOT16 = 0x00,
10658 XOR16 = 0x04,
10659 AND16 = 0x08,
10660 OR16 = 0x0c,
10661 LWM16 = 0x10,
10662 SWM16 = 0x14,
10663 JR16 = 0x18,
10664 JRC16 = 0x1a,
10665 JALR16 = 0x1c,
10666 JALR16S = 0x1e,
10667 MFHI16 = 0x20,
10668 MFLO16 = 0x24,
10669 BREAK16 = 0x28,
10670 SDBBP16 = 0x2c,
10671 JRADDIUSP = 0x30
10672 };
10673
10674 /* POOL16D encoding of minor opcode field */
10675
10676 enum {
10677 ADDIUS5 = 0x0,
10678 ADDIUSP = 0x1
10679 };
10680
10681 /* POOL16E encoding of minor opcode field */
10682
10683 enum {
10684 ADDIUR2 = 0x0,
10685 ADDIUR1SP = 0x1
10686 };
10687
10688 static int mmreg (int r)
10689 {
10690 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10691
10692 return map[r];
10693 }
10694
10695 /* Used for 16-bit store instructions. */
10696 static int mmreg2 (int r)
10697 {
10698 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10699
10700 return map[r];
10701 }
10702
10703 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10704 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10705 #define uMIPS_RS2(op) uMIPS_RS(op)
10706 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10707 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10708 #define uMIPS_RS5(op) (op & 0x1f)
10709
10710 /* Signed immediate */
10711 #define SIMM(op, start, width) \
10712 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10713 << (32-width)) \
10714 >> (32-width))
10715 /* Zero-extended immediate */
10716 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10717
10718 static void gen_addiur1sp(DisasContext *ctx)
10719 {
10720 int rd = mmreg(uMIPS_RD(ctx->opcode));
10721
10722 gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10723 }
10724
10725 static void gen_addiur2(DisasContext *ctx)
10726 {
10727 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10728 int rd = mmreg(uMIPS_RD(ctx->opcode));
10729 int rs = mmreg(uMIPS_RS(ctx->opcode));
10730
10731 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10732 }
10733
10734 static void gen_addiusp(DisasContext *ctx)
10735 {
10736 int encoded = ZIMM(ctx->opcode, 1, 9);
10737 int decoded;
10738
10739 if (encoded <= 1) {
10740 decoded = 256 + encoded;
10741 } else if (encoded <= 255) {
10742 decoded = encoded;
10743 } else if (encoded <= 509) {
10744 decoded = encoded - 512;
10745 } else {
10746 decoded = encoded - 768;
10747 }
10748
10749 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
10750 }
10751
10752 static void gen_addius5(DisasContext *ctx)
10753 {
10754 int imm = SIMM(ctx->opcode, 1, 4);
10755 int rd = (ctx->opcode >> 5) & 0x1f;
10756
10757 gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
10758 }
10759
10760 static void gen_andi16(DisasContext *ctx)
10761 {
10762 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10763 31, 32, 63, 64, 255, 32768, 65535 };
10764 int rd = mmreg(uMIPS_RD(ctx->opcode));
10765 int rs = mmreg(uMIPS_RS(ctx->opcode));
10766 int encoded = ZIMM(ctx->opcode, 0, 4);
10767
10768 gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10769 }
10770
10771 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10772 int base, int16_t offset)
10773 {
10774 const char *opn = "ldst_multiple";
10775 TCGv t0, t1;
10776 TCGv_i32 t2;
10777
10778 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10779 generate_exception(ctx, EXCP_RI);
10780 return;
10781 }
10782
10783 t0 = tcg_temp_new();
10784
10785 gen_base_offset_addr(ctx, t0, base, offset);
10786
10787 t1 = tcg_const_tl(reglist);
10788 t2 = tcg_const_i32(ctx->mem_idx);
10789
10790 save_cpu_state(ctx, 1);
10791 switch (opc) {
10792 case LWM32:
10793 gen_helper_lwm(cpu_env, t0, t1, t2);
10794 opn = "lwm";
10795 break;
10796 case SWM32:
10797 gen_helper_swm(cpu_env, t0, t1, t2);
10798 opn = "swm";
10799 break;
10800 #ifdef TARGET_MIPS64
10801 case LDM:
10802 gen_helper_ldm(cpu_env, t0, t1, t2);
10803 opn = "ldm";
10804 break;
10805 case SDM:
10806 gen_helper_sdm(cpu_env, t0, t1, t2);
10807 opn = "sdm";
10808 break;
10809 #endif
10810 }
10811 (void)opn;
10812 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10813 tcg_temp_free(t0);
10814 tcg_temp_free(t1);
10815 tcg_temp_free_i32(t2);
10816 }
10817
10818
10819 static void gen_pool16c_insn(DisasContext *ctx)
10820 {
10821 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10822 int rs = mmreg(ctx->opcode & 0x7);
10823 int opc;
10824
10825 switch (((ctx->opcode) >> 4) & 0x3f) {
10826 case NOT16 + 0:
10827 case NOT16 + 1:
10828 case NOT16 + 2:
10829 case NOT16 + 3:
10830 gen_logic(ctx, OPC_NOR, rd, rs, 0);
10831 break;
10832 case XOR16 + 0:
10833 case XOR16 + 1:
10834 case XOR16 + 2:
10835 case XOR16 + 3:
10836 gen_logic(ctx, OPC_XOR, rd, rd, rs);
10837 break;
10838 case AND16 + 0:
10839 case AND16 + 1:
10840 case AND16 + 2:
10841 case AND16 + 3:
10842 gen_logic(ctx, OPC_AND, rd, rd, rs);
10843 break;
10844 case OR16 + 0:
10845 case OR16 + 1:
10846 case OR16 + 2:
10847 case OR16 + 3:
10848 gen_logic(ctx, OPC_OR, rd, rd, rs);
10849 break;
10850 case LWM16 + 0:
10851 case LWM16 + 1:
10852 case LWM16 + 2:
10853 case LWM16 + 3:
10854 {
10855 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10856 int offset = ZIMM(ctx->opcode, 0, 4);
10857
10858 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10859 29, offset << 2);
10860 }
10861 break;
10862 case SWM16 + 0:
10863 case SWM16 + 1:
10864 case SWM16 + 2:
10865 case SWM16 + 3:
10866 {
10867 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10868 int offset = ZIMM(ctx->opcode, 0, 4);
10869
10870 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10871 29, offset << 2);
10872 }
10873 break;
10874 case JR16 + 0:
10875 case JR16 + 1:
10876 {
10877 int reg = ctx->opcode & 0x1f;
10878
10879 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10880 }
10881 break;
10882 case JRC16 + 0:
10883 case JRC16 + 1:
10884 {
10885 int reg = ctx->opcode & 0x1f;
10886
10887 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10888 /* Let normal delay slot handling in our caller take us
10889 to the branch target. */
10890 }
10891 break;
10892 case JALR16 + 0:
10893 case JALR16 + 1:
10894 opc = OPC_JALR;
10895 goto do_jalr;
10896 case JALR16S + 0:
10897 case JALR16S + 1:
10898 opc = OPC_JALRS;
10899 do_jalr:
10900 {
10901 int reg = ctx->opcode & 0x1f;
10902
10903 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10904 }
10905 break;
10906 case MFHI16 + 0:
10907 case MFHI16 + 1:
10908 gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
10909 break;
10910 case MFLO16 + 0:
10911 case MFLO16 + 1:
10912 gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
10913 break;
10914 case BREAK16:
10915 generate_exception(ctx, EXCP_BREAK);
10916 break;
10917 case SDBBP16:
10918 /* XXX: not clear which exception should be raised
10919 * when in debug mode...
10920 */
10921 check_insn(ctx, ISA_MIPS32);
10922 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10923 generate_exception(ctx, EXCP_DBp);
10924 } else {
10925 generate_exception(ctx, EXCP_DBp);
10926 }
10927 break;
10928 case JRADDIUSP + 0:
10929 case JRADDIUSP + 1:
10930 {
10931 int imm = ZIMM(ctx->opcode, 0, 5);
10932
10933 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10934 gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
10935 /* Let normal delay slot handling in our caller take us
10936 to the branch target. */
10937 }
10938 break;
10939 default:
10940 generate_exception(ctx, EXCP_RI);
10941 break;
10942 }
10943 }
10944
10945 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10946 {
10947 TCGv t0 = tcg_temp_new();
10948 TCGv t1 = tcg_temp_new();
10949
10950 gen_load_gpr(t0, base);
10951
10952 if (index != 0) {
10953 gen_load_gpr(t1, index);
10954 tcg_gen_shli_tl(t1, t1, 2);
10955 gen_op_addr_add(ctx, t0, t1, t0);
10956 }
10957
10958 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10959 gen_store_gpr(t1, rd);
10960
10961 tcg_temp_free(t0);
10962 tcg_temp_free(t1);
10963 }
10964
10965 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10966 int base, int16_t offset)
10967 {
10968 const char *opn = "ldst_pair";
10969 TCGv t0, t1;
10970
10971 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10972 generate_exception(ctx, EXCP_RI);
10973 return;
10974 }
10975
10976 t0 = tcg_temp_new();
10977 t1 = tcg_temp_new();
10978
10979 gen_base_offset_addr(ctx, t0, base, offset);
10980
10981 switch (opc) {
10982 case LWP:
10983 if (rd == base) {
10984 generate_exception(ctx, EXCP_RI);
10985 return;
10986 }
10987 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10988 gen_store_gpr(t1, rd);
10989 tcg_gen_movi_tl(t1, 4);
10990 gen_op_addr_add(ctx, t0, t0, t1);
10991 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
10992 gen_store_gpr(t1, rd+1);
10993 opn = "lwp";
10994 break;
10995 case SWP:
10996 gen_load_gpr(t1, rd);
10997 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
10998 tcg_gen_movi_tl(t1, 4);
10999 gen_op_addr_add(ctx, t0, t0, t1);
11000 gen_load_gpr(t1, rd+1);
11001 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
11002 opn = "swp";
11003 break;
11004 #ifdef TARGET_MIPS64
11005 case LDP:
11006 if (rd == base) {
11007 generate_exception(ctx, EXCP_RI);
11008 return;
11009 }
11010 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11011 gen_store_gpr(t1, rd);
11012 tcg_gen_movi_tl(t1, 8);
11013 gen_op_addr_add(ctx, t0, t0, t1);
11014 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11015 gen_store_gpr(t1, rd+1);
11016 opn = "ldp";
11017 break;
11018 case SDP:
11019 gen_load_gpr(t1, rd);
11020 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11021 tcg_gen_movi_tl(t1, 8);
11022 gen_op_addr_add(ctx, t0, t0, t1);
11023 gen_load_gpr(t1, rd+1);
11024 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
11025 opn = "sdp";
11026 break;
11027 #endif
11028 }
11029 (void)opn; /* avoid a compiler warning */
11030 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11031 tcg_temp_free(t0);
11032 tcg_temp_free(t1);
11033 }
11034
11035 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11036 {
11037 int extension = (ctx->opcode >> 6) & 0x3f;
11038 int minor = (ctx->opcode >> 12) & 0xf;
11039 uint32_t mips32_op;
11040
11041 switch (extension) {
11042 case TEQ:
11043 mips32_op = OPC_TEQ;
11044 goto do_trap;
11045 case TGE:
11046 mips32_op = OPC_TGE;
11047 goto do_trap;
11048 case TGEU:
11049 mips32_op = OPC_TGEU;
11050 goto do_trap;
11051 case TLT:
11052 mips32_op = OPC_TLT;
11053 goto do_trap;
11054 case TLTU:
11055 mips32_op = OPC_TLTU;
11056 goto do_trap;
11057 case TNE:
11058 mips32_op = OPC_TNE;
11059 do_trap:
11060 gen_trap(ctx, mips32_op, rs, rt, -1);
11061 break;
11062 #ifndef CONFIG_USER_ONLY
11063 case MFC0:
11064 case MFC0 + 32:
11065 check_cp0_enabled(ctx);
11066 if (rt == 0) {
11067 /* Treat as NOP. */
11068 break;
11069 }
11070 gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11071 break;
11072 case MTC0:
11073 case MTC0 + 32:
11074 check_cp0_enabled(ctx);
11075 {
11076 TCGv t0 = tcg_temp_new();
11077
11078 gen_load_gpr(t0, rt);
11079 gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11080 tcg_temp_free(t0);
11081 }
11082 break;
11083 #endif
11084 case 0x2a:
11085 switch (minor & 3) {
11086 case MADD_ACC:
11087 gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11088 break;
11089 case MADDU_ACC:
11090 gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11091 break;
11092 case MSUB_ACC:
11093 gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11094 break;
11095 case MSUBU_ACC:
11096 gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11097 break;
11098 default:
11099 goto pool32axf_invalid;
11100 }
11101 break;
11102 case 0x32:
11103 switch (minor & 3) {
11104 case MULT_ACC:
11105 gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11106 break;
11107 case MULTU_ACC:
11108 gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11109 break;
11110 default:
11111 goto pool32axf_invalid;
11112 }
11113 break;
11114 case 0x2c:
11115 switch (minor) {
11116 case SEB:
11117 gen_bshfl(ctx, OPC_SEB, rs, rt);
11118 break;
11119 case SEH:
11120 gen_bshfl(ctx, OPC_SEH, rs, rt);
11121 break;
11122 case CLO:
11123 mips32_op = OPC_CLO;
11124 goto do_cl;
11125 case CLZ:
11126 mips32_op = OPC_CLZ;
11127 do_cl:
11128 check_insn(ctx, ISA_MIPS32);
11129 gen_cl(ctx, mips32_op, rt, rs);
11130 break;
11131 case RDHWR:
11132 gen_rdhwr(ctx, rt, rs);
11133 break;
11134 case WSBH:
11135 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11136 break;
11137 case MULT:
11138 mips32_op = OPC_MULT;
11139 goto do_mul;
11140 case MULTU:
11141 mips32_op = OPC_MULTU;
11142 goto do_mul;
11143 case DIV:
11144 mips32_op = OPC_DIV;
11145 goto do_div;
11146 case DIVU:
11147 mips32_op = OPC_DIVU;
11148 goto do_div;
11149 do_div:
11150 check_insn(ctx, ISA_MIPS32);
11151 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11152 break;
11153 case MADD:
11154 mips32_op = OPC_MADD;
11155 goto do_mul;
11156 case MADDU:
11157 mips32_op = OPC_MADDU;
11158 goto do_mul;
11159 case MSUB:
11160 mips32_op = OPC_MSUB;
11161 goto do_mul;
11162 case MSUBU:
11163 mips32_op = OPC_MSUBU;
11164 do_mul:
11165 check_insn(ctx, ISA_MIPS32);
11166 gen_muldiv(ctx, mips32_op, 0, rs, rt);
11167 break;
11168 default:
11169 goto pool32axf_invalid;
11170 }
11171 break;
11172 case 0x34:
11173 switch (minor) {
11174 case MFC2:
11175 case MTC2:
11176 case MFHC2:
11177 case MTHC2:
11178 case CFC2:
11179 case CTC2:
11180 generate_exception_err(ctx, EXCP_CpU, 2);
11181 break;
11182 default:
11183 goto pool32axf_invalid;
11184 }
11185 break;
11186 case 0x3c:
11187 switch (minor) {
11188 case JALR:
11189 case JALR_HB:
11190 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11191 break;
11192 case JALRS:
11193 case JALRS_HB:
11194 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11195 break;
11196 default:
11197 goto pool32axf_invalid;
11198 }
11199 break;
11200 case 0x05:
11201 switch (minor) {
11202 case RDPGPR:
11203 check_cp0_enabled(ctx);
11204 check_insn(ctx, ISA_MIPS32R2);
11205 gen_load_srsgpr(rt, rs);
11206 break;
11207 case WRPGPR:
11208 check_cp0_enabled(ctx);
11209 check_insn(ctx, ISA_MIPS32R2);
11210 gen_store_srsgpr(rt, rs);
11211 break;
11212 default:
11213 goto pool32axf_invalid;
11214 }
11215 break;
11216 #ifndef CONFIG_USER_ONLY
11217 case 0x0d:
11218 switch (minor) {
11219 case TLBP:
11220 mips32_op = OPC_TLBP;
11221 goto do_cp0;
11222 case TLBR:
11223 mips32_op = OPC_TLBR;
11224 goto do_cp0;
11225 case TLBWI:
11226 mips32_op = OPC_TLBWI;
11227 goto do_cp0;
11228 case TLBWR:
11229 mips32_op = OPC_TLBWR;
11230 goto do_cp0;
11231 case WAIT:
11232 mips32_op = OPC_WAIT;
11233 goto do_cp0;
11234 case DERET:
11235 mips32_op = OPC_DERET;
11236 goto do_cp0;
11237 case ERET:
11238 mips32_op = OPC_ERET;
11239 do_cp0:
11240 gen_cp0(env, ctx, mips32_op, rt, rs);
11241 break;
11242 default:
11243 goto pool32axf_invalid;
11244 }
11245 break;
11246 case 0x1d:
11247 switch (minor) {
11248 case DI:
11249 check_cp0_enabled(ctx);
11250 {
11251 TCGv t0 = tcg_temp_new();
11252
11253 save_cpu_state(ctx, 1);
11254 gen_helper_di(t0, cpu_env);
11255 gen_store_gpr(t0, rs);
11256 /* Stop translation as we may have switched the execution mode */
11257 ctx->bstate = BS_STOP;
11258 tcg_temp_free(t0);
11259 }
11260 break;
11261 case EI:
11262 check_cp0_enabled(ctx);
11263 {
11264 TCGv t0 = tcg_temp_new();
11265
11266 save_cpu_state(ctx, 1);
11267 gen_helper_ei(t0, cpu_env);
11268 gen_store_gpr(t0, rs);
11269 /* Stop translation as we may have switched the execution mode */
11270 ctx->bstate = BS_STOP;
11271 tcg_temp_free(t0);
11272 }
11273 break;
11274 default:
11275 goto pool32axf_invalid;
11276 }
11277 break;
11278 #endif
11279 case 0x2d:
11280 switch (minor) {
11281 case SYNC:
11282 /* NOP */
11283 break;
11284 case SYSCALL:
11285 generate_exception(ctx, EXCP_SYSCALL);
11286 ctx->bstate = BS_STOP;
11287 break;
11288 case SDBBP:
11289 check_insn(ctx, ISA_MIPS32);
11290 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11291 generate_exception(ctx, EXCP_DBp);
11292 } else {
11293 generate_exception(ctx, EXCP_DBp);
11294 }
11295 break;
11296 default:
11297 goto pool32axf_invalid;
11298 }
11299 break;
11300 case 0x01:
11301 switch (minor & 3) {
11302 case MFHI_ACC:
11303 gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
11304 break;
11305 case MFLO_ACC:
11306 gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
11307 break;
11308 case MTHI_ACC:
11309 gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
11310 break;
11311 case MTLO_ACC:
11312 gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
11313 break;
11314 default:
11315 goto pool32axf_invalid;
11316 }
11317 break;
11318 case 0x35:
11319 switch (minor) {
11320 case MFHI32:
11321 gen_HILO(ctx, OPC_MFHI, 0, rs);
11322 break;
11323 case MFLO32:
11324 gen_HILO(ctx, OPC_MFLO, 0, rs);
11325 break;
11326 case MTHI32:
11327 gen_HILO(ctx, OPC_MTHI, 0, rs);
11328 break;
11329 case MTLO32:
11330 gen_HILO(ctx, OPC_MTLO, 0, rs);
11331 break;
11332 default:
11333 goto pool32axf_invalid;
11334 }
11335 break;
11336 default:
11337 pool32axf_invalid:
11338 MIPS_INVAL("pool32axf");
11339 generate_exception(ctx, EXCP_RI);
11340 break;
11341 }
11342 }
11343
11344 /* Values for microMIPS fmt field. Variable-width, depending on which
11345 formats the instruction supports. */
11346
11347 enum {
11348 FMT_SD_S = 0,
11349 FMT_SD_D = 1,
11350
11351 FMT_SDPS_S = 0,
11352 FMT_SDPS_D = 1,
11353 FMT_SDPS_PS = 2,
11354
11355 FMT_SWL_S = 0,
11356 FMT_SWL_W = 1,
11357 FMT_SWL_L = 2,
11358
11359 FMT_DWL_D = 0,
11360 FMT_DWL_W = 1,
11361 FMT_DWL_L = 2
11362 };
11363
11364 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
11365 {
11366 int extension = (ctx->opcode >> 6) & 0x3ff;
11367 uint32_t mips32_op;
11368
11369 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11370 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11371 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11372
11373 switch (extension) {
11374 case FLOAT_1BIT_FMT(CFC1, 0):
11375 mips32_op = OPC_CFC1;
11376 goto do_cp1;
11377 case FLOAT_1BIT_FMT(CTC1, 0):
11378 mips32_op = OPC_CTC1;
11379 goto do_cp1;
11380 case FLOAT_1BIT_FMT(MFC1, 0):
11381 mips32_op = OPC_MFC1;
11382 goto do_cp1;
11383 case FLOAT_1BIT_FMT(MTC1, 0):
11384 mips32_op = OPC_MTC1;
11385 goto do_cp1;
11386 case FLOAT_1BIT_FMT(MFHC1, 0):
11387 mips32_op = OPC_MFHC1;
11388 goto do_cp1;
11389 case FLOAT_1BIT_FMT(MTHC1, 0):
11390 mips32_op = OPC_MTHC1;
11391 do_cp1:
11392 gen_cp1(ctx, mips32_op, rt, rs);
11393 break;
11394
11395 /* Reciprocal square root */
11396 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11397 mips32_op = OPC_RSQRT_S;
11398 goto do_unaryfp;
11399 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11400 mips32_op = OPC_RSQRT_D;
11401 goto do_unaryfp;
11402
11403 /* Square root */
11404 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11405 mips32_op = OPC_SQRT_S;
11406 goto do_unaryfp;
11407 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11408 mips32_op = OPC_SQRT_D;
11409 goto do_unaryfp;
11410
11411 /* Reciprocal */
11412 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11413 mips32_op = OPC_RECIP_S;
11414 goto do_unaryfp;
11415 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11416 mips32_op = OPC_RECIP_D;
11417 goto do_unaryfp;
11418
11419 /* Floor */
11420 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11421 mips32_op = OPC_FLOOR_L_S;
11422 goto do_unaryfp;
11423 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11424 mips32_op = OPC_FLOOR_L_D;
11425 goto do_unaryfp;
11426 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11427 mips32_op = OPC_FLOOR_W_S;
11428 goto do_unaryfp;
11429 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11430 mips32_op = OPC_FLOOR_W_D;
11431 goto do_unaryfp;
11432
11433 /* Ceiling */
11434 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11435 mips32_op = OPC_CEIL_L_S;
11436 goto do_unaryfp;
11437 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11438 mips32_op = OPC_CEIL_L_D;
11439 goto do_unaryfp;
11440 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11441 mips32_op = OPC_CEIL_W_S;
11442 goto do_unaryfp;
11443 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11444 mips32_op = OPC_CEIL_W_D;
11445 goto do_unaryfp;
11446
11447 /* Truncation */
11448 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11449 mips32_op = OPC_TRUNC_L_S;
11450 goto do_unaryfp;
11451 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11452 mips32_op = OPC_TRUNC_L_D;
11453 goto do_unaryfp;
11454 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11455 mips32_op = OPC_TRUNC_W_S;
11456 goto do_unaryfp;
11457 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11458 mips32_op = OPC_TRUNC_W_D;
11459 goto do_unaryfp;
11460
11461 /* Round */
11462 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11463 mips32_op = OPC_ROUND_L_S;
11464 goto do_unaryfp;
11465 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11466 mips32_op = OPC_ROUND_L_D;
11467 goto do_unaryfp;
11468 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11469 mips32_op = OPC_ROUND_W_S;
11470 goto do_unaryfp;
11471 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11472 mips32_op = OPC_ROUND_W_D;
11473 goto do_unaryfp;
11474
11475 /* Integer to floating-point conversion */
11476 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11477 mips32_op = OPC_CVT_L_S;
11478 goto do_unaryfp;
11479 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11480 mips32_op = OPC_CVT_L_D;
11481 goto do_unaryfp;
11482 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11483 mips32_op = OPC_CVT_W_S;
11484 goto do_unaryfp;
11485 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11486 mips32_op = OPC_CVT_W_D;
11487 goto do_unaryfp;
11488
11489 /* Paired-foo conversions */
11490 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11491 mips32_op = OPC_CVT_S_PL;
11492 goto do_unaryfp;
11493 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11494 mips32_op = OPC_CVT_S_PU;
11495 goto do_unaryfp;
11496 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11497 mips32_op = OPC_CVT_PW_PS;
11498 goto do_unaryfp;
11499 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11500 mips32_op = OPC_CVT_PS_PW;
11501 goto do_unaryfp;
11502
11503 /* Floating-point moves */
11504 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11505 mips32_op = OPC_MOV_S;
11506 goto do_unaryfp;
11507 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11508 mips32_op = OPC_MOV_D;
11509 goto do_unaryfp;
11510 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11511 mips32_op = OPC_MOV_PS;
11512 goto do_unaryfp;
11513
11514 /* Absolute value */
11515 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11516 mips32_op = OPC_ABS_S;
11517 goto do_unaryfp;
11518 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11519 mips32_op = OPC_ABS_D;
11520 goto do_unaryfp;
11521 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11522 mips32_op = OPC_ABS_PS;
11523 goto do_unaryfp;
11524
11525 /* Negation */
11526 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11527 mips32_op = OPC_NEG_S;
11528 goto do_unaryfp;
11529 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11530 mips32_op = OPC_NEG_D;
11531 goto do_unaryfp;
11532 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11533 mips32_op = OPC_NEG_PS;
11534 goto do_unaryfp;
11535
11536 /* Reciprocal square root step */
11537 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11538 mips32_op = OPC_RSQRT1_S;
11539 goto do_unaryfp;
11540 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11541 mips32_op = OPC_RSQRT1_D;
11542 goto do_unaryfp;
11543 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11544 mips32_op = OPC_RSQRT1_PS;
11545 goto do_unaryfp;
11546
11547 /* Reciprocal step */
11548 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11549 mips32_op = OPC_RECIP1_S;
11550 goto do_unaryfp;
11551 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11552 mips32_op = OPC_RECIP1_S;
11553 goto do_unaryfp;
11554 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11555 mips32_op = OPC_RECIP1_PS;
11556 goto do_unaryfp;
11557
11558 /* Conversions from double */
11559 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11560 mips32_op = OPC_CVT_D_S;
11561 goto do_unaryfp;
11562 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11563 mips32_op = OPC_CVT_D_W;
11564 goto do_unaryfp;
11565 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11566 mips32_op = OPC_CVT_D_L;
11567 goto do_unaryfp;
11568
11569 /* Conversions from single */
11570 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11571 mips32_op = OPC_CVT_S_D;
11572 goto do_unaryfp;
11573 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11574 mips32_op = OPC_CVT_S_W;
11575 goto do_unaryfp;
11576 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11577 mips32_op = OPC_CVT_S_L;
11578 do_unaryfp:
11579 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11580 break;
11581
11582 /* Conditional moves on floating-point codes */
11583 case COND_FLOAT_MOV(MOVT, 0):
11584 case COND_FLOAT_MOV(MOVT, 1):
11585 case COND_FLOAT_MOV(MOVT, 2):
11586 case COND_FLOAT_MOV(MOVT, 3):
11587 case COND_FLOAT_MOV(MOVT, 4):
11588 case COND_FLOAT_MOV(MOVT, 5):
11589 case COND_FLOAT_MOV(MOVT, 6):
11590 case COND_FLOAT_MOV(MOVT, 7):
11591 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11592 break;
11593 case COND_FLOAT_MOV(MOVF, 0):
11594 case COND_FLOAT_MOV(MOVF, 1):
11595 case COND_FLOAT_MOV(MOVF, 2):
11596 case COND_FLOAT_MOV(MOVF, 3):
11597 case COND_FLOAT_MOV(MOVF, 4):
11598 case COND_FLOAT_MOV(MOVF, 5):
11599 case COND_FLOAT_MOV(MOVF, 6):
11600 case COND_FLOAT_MOV(MOVF, 7):
11601 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11602 break;
11603 default:
11604 MIPS_INVAL("pool32fxf");
11605 generate_exception(ctx, EXCP_RI);
11606 break;
11607 }
11608 }
11609
11610 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11611 uint16_t insn_hw1)
11612 {
11613 int32_t offset;
11614 uint16_t insn;
11615 int rt, rs, rd, rr;
11616 int16_t imm;
11617 uint32_t op, minor, mips32_op;
11618 uint32_t cond, fmt, cc;
11619
11620 insn = cpu_lduw_code(env, ctx->pc + 2);
11621 ctx->opcode = (ctx->opcode << 16) | insn;
11622
11623 rt = (ctx->opcode >> 21) & 0x1f;
11624 rs = (ctx->opcode >> 16) & 0x1f;
11625 rd = (ctx->opcode >> 11) & 0x1f;
11626 rr = (ctx->opcode >> 6) & 0x1f;
11627 imm = (int16_t) ctx->opcode;
11628
11629 op = (ctx->opcode >> 26) & 0x3f;
11630 switch (op) {
11631 case POOL32A:
11632 minor = ctx->opcode & 0x3f;
11633 switch (minor) {
11634 case 0x00:
11635 minor = (ctx->opcode >> 6) & 0xf;
11636 switch (minor) {
11637 case SLL32:
11638 mips32_op = OPC_SLL;
11639 goto do_shifti;
11640 case SRA:
11641 mips32_op = OPC_SRA;
11642 goto do_shifti;
11643 case SRL32:
11644 mips32_op = OPC_SRL;
11645 goto do_shifti;
11646 case ROTR:
11647 mips32_op = OPC_ROTR;
11648 do_shifti:
11649 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
11650 break;
11651 default:
11652 goto pool32a_invalid;
11653 }
11654 break;
11655 case 0x10:
11656 minor = (ctx->opcode >> 6) & 0xf;
11657 switch (minor) {
11658 /* Arithmetic */
11659 case ADD:
11660 mips32_op = OPC_ADD;
11661 goto do_arith;
11662 case ADDU32:
11663 mips32_op = OPC_ADDU;
11664 goto do_arith;
11665 case SUB:
11666 mips32_op = OPC_SUB;
11667 goto do_arith;
11668 case SUBU32:
11669 mips32_op = OPC_SUBU;
11670 goto do_arith;
11671 case MUL:
11672 mips32_op = OPC_MUL;
11673 do_arith:
11674 gen_arith(ctx, mips32_op, rd, rs, rt);
11675 break;
11676 /* Shifts */
11677 case SLLV:
11678 mips32_op = OPC_SLLV;
11679 goto do_shift;
11680 case SRLV:
11681 mips32_op = OPC_SRLV;
11682 goto do_shift;
11683 case SRAV:
11684 mips32_op = OPC_SRAV;
11685 goto do_shift;
11686 case ROTRV:
11687 mips32_op = OPC_ROTRV;
11688 do_shift:
11689 gen_shift(ctx, mips32_op, rd, rs, rt);
11690 break;
11691 /* Logical operations */
11692 case AND:
11693 mips32_op = OPC_AND;
11694 goto do_logic;
11695 case OR32:
11696 mips32_op = OPC_OR;
11697 goto do_logic;
11698 case NOR:
11699 mips32_op = OPC_NOR;
11700 goto do_logic;
11701 case XOR32:
11702 mips32_op = OPC_XOR;
11703 do_logic:
11704 gen_logic(ctx, mips32_op, rd, rs, rt);
11705 break;
11706 /* Set less than */
11707 case SLT:
11708 mips32_op = OPC_SLT;
11709 goto do_slt;
11710 case SLTU:
11711 mips32_op = OPC_SLTU;
11712 do_slt:
11713 gen_slt(ctx, mips32_op, rd, rs, rt);
11714 break;
11715 default:
11716 goto pool32a_invalid;
11717 }
11718 break;
11719 case 0x18:
11720 minor = (ctx->opcode >> 6) & 0xf;
11721 switch (minor) {
11722 /* Conditional moves */
11723 case MOVN:
11724 mips32_op = OPC_MOVN;
11725 goto do_cmov;
11726 case MOVZ:
11727 mips32_op = OPC_MOVZ;
11728 do_cmov:
11729 gen_cond_move(ctx, mips32_op, rd, rs, rt);
11730 break;
11731 case LWXS:
11732 gen_ldxs(ctx, rs, rt, rd);
11733 break;
11734 default:
11735 goto pool32a_invalid;
11736 }
11737 break;
11738 case INS:
11739 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11740 return;
11741 case EXT:
11742 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11743 return;
11744 case POOL32AXF:
11745 gen_pool32axf(env, ctx, rt, rs);
11746 break;
11747 case 0x07:
11748 generate_exception(ctx, EXCP_BREAK);
11749 break;
11750 default:
11751 pool32a_invalid:
11752 MIPS_INVAL("pool32a");
11753 generate_exception(ctx, EXCP_RI);
11754 break;
11755 }
11756 break;
11757 case POOL32B:
11758 minor = (ctx->opcode >> 12) & 0xf;
11759 switch (minor) {
11760 case CACHE:
11761 check_cp0_enabled(ctx);
11762 /* Treat as no-op. */
11763 break;
11764 case LWC2:
11765 case SWC2:
11766 /* COP2: Not implemented. */
11767 generate_exception_err(ctx, EXCP_CpU, 2);
11768 break;
11769 case LWP:
11770 case SWP:
11771 #ifdef TARGET_MIPS64
11772 case LDP:
11773 case SDP:
11774 #endif
11775 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11776 break;
11777 case LWM32:
11778 case SWM32:
11779 #ifdef TARGET_MIPS64
11780 case LDM:
11781 case SDM:
11782 #endif
11783 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11784 break;
11785 default:
11786 MIPS_INVAL("pool32b");
11787 generate_exception(ctx, EXCP_RI);
11788 break;
11789 }
11790 break;
11791 case POOL32F:
11792 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11793 minor = ctx->opcode & 0x3f;
11794 check_cp1_enabled(ctx);
11795 switch (minor) {
11796 case ALNV_PS:
11797 mips32_op = OPC_ALNV_PS;
11798 goto do_madd;
11799 case MADD_S:
11800 mips32_op = OPC_MADD_S;
11801 goto do_madd;
11802 case MADD_D:
11803 mips32_op = OPC_MADD_D;
11804 goto do_madd;
11805 case MADD_PS:
11806 mips32_op = OPC_MADD_PS;
11807 goto do_madd;
11808 case MSUB_S:
11809 mips32_op = OPC_MSUB_S;
11810 goto do_madd;
11811 case MSUB_D:
11812 mips32_op = OPC_MSUB_D;
11813 goto do_madd;
11814 case MSUB_PS:
11815 mips32_op = OPC_MSUB_PS;
11816 goto do_madd;
11817 case NMADD_S:
11818 mips32_op = OPC_NMADD_S;
11819 goto do_madd;
11820 case NMADD_D:
11821 mips32_op = OPC_NMADD_D;
11822 goto do_madd;
11823 case NMADD_PS:
11824 mips32_op = OPC_NMADD_PS;
11825 goto do_madd;
11826 case NMSUB_S:
11827 mips32_op = OPC_NMSUB_S;
11828 goto do_madd;
11829 case NMSUB_D:
11830 mips32_op = OPC_NMSUB_D;
11831 goto do_madd;
11832 case NMSUB_PS:
11833 mips32_op = OPC_NMSUB_PS;
11834 do_madd:
11835 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11836 break;
11837 case CABS_COND_FMT:
11838 cond = (ctx->opcode >> 6) & 0xf;
11839 cc = (ctx->opcode >> 13) & 0x7;
11840 fmt = (ctx->opcode >> 10) & 0x3;
11841 switch (fmt) {
11842 case 0x0:
11843 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11844 break;
11845 case 0x1:
11846 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11847 break;
11848 case 0x2:
11849 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11850 break;
11851 default:
11852 goto pool32f_invalid;
11853 }
11854 break;
11855 case C_COND_FMT:
11856 cond = (ctx->opcode >> 6) & 0xf;
11857 cc = (ctx->opcode >> 13) & 0x7;
11858 fmt = (ctx->opcode >> 10) & 0x3;
11859 switch (fmt) {
11860 case 0x0:
11861 gen_cmp_s(ctx, cond, rt, rs, cc);
11862 break;
11863 case 0x1:
11864 gen_cmp_d(ctx, cond, rt, rs, cc);
11865 break;
11866 case 0x2:
11867 gen_cmp_ps(ctx, cond, rt, rs, cc);
11868 break;
11869 default:
11870 goto pool32f_invalid;
11871 }
11872 break;
11873 case POOL32FXF:
11874 gen_pool32fxf(ctx, rt, rs);
11875 break;
11876 case 0x00:
11877 /* PLL foo */
11878 switch ((ctx->opcode >> 6) & 0x7) {
11879 case PLL_PS:
11880 mips32_op = OPC_PLL_PS;
11881 goto do_ps;
11882 case PLU_PS:
11883 mips32_op = OPC_PLU_PS;
11884 goto do_ps;
11885 case PUL_PS:
11886 mips32_op = OPC_PUL_PS;
11887 goto do_ps;
11888 case PUU_PS:
11889 mips32_op = OPC_PUU_PS;
11890 goto do_ps;
11891 case CVT_PS_S:
11892 mips32_op = OPC_CVT_PS_S;
11893 do_ps:
11894 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11895 break;
11896 default:
11897 goto pool32f_invalid;
11898 }
11899 break;
11900 case 0x08:
11901 /* [LS][WDU]XC1 */
11902 switch ((ctx->opcode >> 6) & 0x7) {
11903 case LWXC1:
11904 mips32_op = OPC_LWXC1;
11905 goto do_ldst_cp1;
11906 case SWXC1:
11907 mips32_op = OPC_SWXC1;
11908 goto do_ldst_cp1;
11909 case LDXC1:
11910 mips32_op = OPC_LDXC1;
11911 goto do_ldst_cp1;
11912 case SDXC1:
11913 mips32_op = OPC_SDXC1;
11914 goto do_ldst_cp1;
11915 case LUXC1:
11916 mips32_op = OPC_LUXC1;
11917 goto do_ldst_cp1;
11918 case SUXC1:
11919 mips32_op = OPC_SUXC1;
11920 do_ldst_cp1:
11921 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11922 break;
11923 default:
11924 goto pool32f_invalid;
11925 }
11926 break;
11927 case 0x18:
11928 /* 3D insns */
11929 fmt = (ctx->opcode >> 9) & 0x3;
11930 switch ((ctx->opcode >> 6) & 0x7) {
11931 case RSQRT2_FMT:
11932 switch (fmt) {
11933 case FMT_SDPS_S:
11934 mips32_op = OPC_RSQRT2_S;
11935 goto do_3d;
11936 case FMT_SDPS_D:
11937 mips32_op = OPC_RSQRT2_D;
11938 goto do_3d;
11939 case FMT_SDPS_PS:
11940 mips32_op = OPC_RSQRT2_PS;
11941 goto do_3d;
11942 default:
11943 goto pool32f_invalid;
11944 }
11945 break;
11946 case RECIP2_FMT:
11947 switch (fmt) {
11948 case FMT_SDPS_S:
11949 mips32_op = OPC_RECIP2_S;
11950 goto do_3d;
11951 case FMT_SDPS_D:
11952 mips32_op = OPC_RECIP2_D;
11953 goto do_3d;
11954 case FMT_SDPS_PS:
11955 mips32_op = OPC_RECIP2_PS;
11956 goto do_3d;
11957 default:
11958 goto pool32f_invalid;
11959 }
11960 break;
11961 case ADDR_PS:
11962 mips32_op = OPC_ADDR_PS;
11963 goto do_3d;
11964 case MULR_PS:
11965 mips32_op = OPC_MULR_PS;
11966 do_3d:
11967 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11968 break;
11969 default:
11970 goto pool32f_invalid;
11971 }
11972 break;
11973 case 0x20:
11974 /* MOV[FT].fmt and PREFX */
11975 cc = (ctx->opcode >> 13) & 0x7;
11976 fmt = (ctx->opcode >> 9) & 0x3;
11977 switch ((ctx->opcode >> 6) & 0x7) {
11978 case MOVF_FMT:
11979 switch (fmt) {
11980 case FMT_SDPS_S:
11981 gen_movcf_s(rs, rt, cc, 0);
11982 break;
11983 case FMT_SDPS_D:
11984 gen_movcf_d(ctx, rs, rt, cc, 0);
11985 break;
11986 case FMT_SDPS_PS:
11987 gen_movcf_ps(ctx, rs, rt, cc, 0);
11988 break;
11989 default:
11990 goto pool32f_invalid;
11991 }
11992 break;
11993 case MOVT_FMT:
11994 switch (fmt) {
11995 case FMT_SDPS_S:
11996 gen_movcf_s(rs, rt, cc, 1);
11997 break;
11998 case FMT_SDPS_D:
11999 gen_movcf_d(ctx, rs, rt, cc, 1);
12000 break;
12001 case FMT_SDPS_PS:
12002 gen_movcf_ps(ctx, rs, rt, cc, 1);
12003 break;
12004 default:
12005 goto pool32f_invalid;
12006 }
12007 break;
12008 case PREFX:
12009 break;
12010 default:
12011 goto pool32f_invalid;
12012 }
12013 break;
12014 #define FINSN_3ARG_SDPS(prfx) \
12015 switch ((ctx->opcode >> 8) & 0x3) { \
12016 case FMT_SDPS_S: \
12017 mips32_op = OPC_##prfx##_S; \
12018 goto do_fpop; \
12019 case FMT_SDPS_D: \
12020 mips32_op = OPC_##prfx##_D; \
12021 goto do_fpop; \
12022 case FMT_SDPS_PS: \
12023 mips32_op = OPC_##prfx##_PS; \
12024 goto do_fpop; \
12025 default: \
12026 goto pool32f_invalid; \
12027 }
12028 case 0x30:
12029 /* regular FP ops */
12030 switch ((ctx->opcode >> 6) & 0x3) {
12031 case ADD_FMT:
12032 FINSN_3ARG_SDPS(ADD);
12033 break;
12034 case SUB_FMT:
12035 FINSN_3ARG_SDPS(SUB);
12036 break;
12037 case MUL_FMT:
12038 FINSN_3ARG_SDPS(MUL);
12039 break;
12040 case DIV_FMT:
12041 fmt = (ctx->opcode >> 8) & 0x3;
12042 if (fmt == 1) {
12043 mips32_op = OPC_DIV_D;
12044 } else if (fmt == 0) {
12045 mips32_op = OPC_DIV_S;
12046 } else {
12047 goto pool32f_invalid;
12048 }
12049 goto do_fpop;
12050 default:
12051 goto pool32f_invalid;
12052 }
12053 break;
12054 case 0x38:
12055 /* cmovs */
12056 switch ((ctx->opcode >> 6) & 0x3) {
12057 case MOVN_FMT:
12058 FINSN_3ARG_SDPS(MOVN);
12059 break;
12060 case MOVZ_FMT:
12061 FINSN_3ARG_SDPS(MOVZ);
12062 break;
12063 default:
12064 goto pool32f_invalid;
12065 }
12066 break;
12067 do_fpop:
12068 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12069 break;
12070 default:
12071 pool32f_invalid:
12072 MIPS_INVAL("pool32f");
12073 generate_exception(ctx, EXCP_RI);
12074 break;
12075 }
12076 } else {
12077 generate_exception_err(ctx, EXCP_CpU, 1);
12078 }
12079 break;
12080 case POOL32I:
12081 minor = (ctx->opcode >> 21) & 0x1f;
12082 switch (minor) {
12083 case BLTZ:
12084 mips32_op = OPC_BLTZ;
12085 goto do_branch;
12086 case BLTZAL:
12087 mips32_op = OPC_BLTZAL;
12088 goto do_branch;
12089 case BLTZALS:
12090 mips32_op = OPC_BLTZALS;
12091 goto do_branch;
12092 case BGEZ:
12093 mips32_op = OPC_BGEZ;
12094 goto do_branch;
12095 case BGEZAL:
12096 mips32_op = OPC_BGEZAL;
12097 goto do_branch;
12098 case BGEZALS:
12099 mips32_op = OPC_BGEZALS;
12100 goto do_branch;
12101 case BLEZ:
12102 mips32_op = OPC_BLEZ;
12103 goto do_branch;
12104 case BGTZ:
12105 mips32_op = OPC_BGTZ;
12106 do_branch:
12107 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12108 break;
12109
12110 /* Traps */
12111 case TLTI:
12112 mips32_op = OPC_TLTI;
12113 goto do_trapi;
12114 case TGEI:
12115 mips32_op = OPC_TGEI;
12116 goto do_trapi;
12117 case TLTIU:
12118 mips32_op = OPC_TLTIU;
12119 goto do_trapi;
12120 case TGEIU:
12121 mips32_op = OPC_TGEIU;
12122 goto do_trapi;
12123 case TNEI:
12124 mips32_op = OPC_TNEI;
12125 goto do_trapi;
12126 case TEQI:
12127 mips32_op = OPC_TEQI;
12128 do_trapi:
12129 gen_trap(ctx, mips32_op, rs, -1, imm);
12130 break;
12131
12132 case BNEZC:
12133 case BEQZC:
12134 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12135 4, rs, 0, imm << 1);
12136 /* Compact branches don't have a delay slot, so just let
12137 the normal delay slot handling take us to the branch
12138 target. */
12139 break;
12140 case LUI:
12141 gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
12142 break;
12143 case SYNCI:
12144 break;
12145 case BC2F:
12146 case BC2T:
12147 /* COP2: Not implemented. */
12148 generate_exception_err(ctx, EXCP_CpU, 2);
12149 break;
12150 case BC1F:
12151 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12152 goto do_cp1branch;
12153 case BC1T:
12154 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12155 goto do_cp1branch;
12156 case BC1ANY4F:
12157 mips32_op = OPC_BC1FANY4;
12158 goto do_cp1mips3d;
12159 case BC1ANY4T:
12160 mips32_op = OPC_BC1TANY4;
12161 do_cp1mips3d:
12162 check_cop1x(ctx);
12163 check_insn(ctx, ASE_MIPS3D);
12164 /* Fall through */
12165 do_cp1branch:
12166 gen_compute_branch1(ctx, mips32_op,
12167 (ctx->opcode >> 18) & 0x7, imm << 1);
12168 break;
12169 case BPOSGE64:
12170 case BPOSGE32:
12171 /* MIPS DSP: not implemented */
12172 /* Fall through */
12173 default:
12174 MIPS_INVAL("pool32i");
12175 generate_exception(ctx, EXCP_RI);
12176 break;
12177 }
12178 break;
12179 case POOL32C:
12180 minor = (ctx->opcode >> 12) & 0xf;
12181 switch (minor) {
12182 case LWL:
12183 mips32_op = OPC_LWL;
12184 goto do_ld_lr;
12185 case SWL:
12186 mips32_op = OPC_SWL;
12187 goto do_st_lr;
12188 case LWR:
12189 mips32_op = OPC_LWR;
12190 goto do_ld_lr;
12191 case SWR:
12192 mips32_op = OPC_SWR;
12193 goto do_st_lr;
12194 #if defined(TARGET_MIPS64)
12195 case LDL:
12196 mips32_op = OPC_LDL;
12197 goto do_ld_lr;
12198 case SDL:
12199 mips32_op = OPC_SDL;
12200 goto do_st_lr;
12201 case LDR:
12202 mips32_op = OPC_LDR;
12203 goto do_ld_lr;
12204 case SDR:
12205 mips32_op = OPC_SDR;
12206 goto do_st_lr;
12207 case LWU:
12208 mips32_op = OPC_LWU;
12209 goto do_ld_lr;
12210 case LLD:
12211 mips32_op = OPC_LLD;
12212 goto do_ld_lr;
12213 #endif
12214 case LL:
12215 mips32_op = OPC_LL;
12216 goto do_ld_lr;
12217 do_ld_lr:
12218 gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12219 break;
12220 do_st_lr:
12221 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12222 break;
12223 case SC:
12224 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12225 break;
12226 #if defined(TARGET_MIPS64)
12227 case SCD:
12228 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12229 break;
12230 #endif
12231 case PREF:
12232 /* Treat as no-op */
12233 break;
12234 default:
12235 MIPS_INVAL("pool32c");
12236 generate_exception(ctx, EXCP_RI);
12237 break;
12238 }
12239 break;
12240 case ADDI32:
12241 mips32_op = OPC_ADDI;
12242 goto do_addi;
12243 case ADDIU32:
12244 mips32_op = OPC_ADDIU;
12245 do_addi:
12246 gen_arith_imm(ctx, mips32_op, rt, rs, imm);
12247 break;
12248
12249 /* Logical operations */
12250 case ORI32:
12251 mips32_op = OPC_ORI;
12252 goto do_logici;
12253 case XORI32:
12254 mips32_op = OPC_XORI;
12255 goto do_logici;
12256 case ANDI32:
12257 mips32_op = OPC_ANDI;
12258 do_logici:
12259 gen_logic_imm(ctx, mips32_op, rt, rs, imm);
12260 break;
12261
12262 /* Set less than immediate */
12263 case SLTI32:
12264 mips32_op = OPC_SLTI;
12265 goto do_slti;
12266 case SLTIU32:
12267 mips32_op = OPC_SLTIU;
12268 do_slti:
12269 gen_slt_imm(ctx, mips32_op, rt, rs, imm);
12270 break;
12271 case JALX32:
12272 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12273 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12274 break;
12275 case JALS32:
12276 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12277 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12278 break;
12279 case BEQ32:
12280 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12281 break;
12282 case BNE32:
12283 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12284 break;
12285 case J32:
12286 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12287 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12288 break;
12289 case JAL32:
12290 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12291 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12292 break;
12293 /* Floating point (COP1) */
12294 case LWC132:
12295 mips32_op = OPC_LWC1;
12296 goto do_cop1;
12297 case LDC132:
12298 mips32_op = OPC_LDC1;
12299 goto do_cop1;
12300 case SWC132:
12301 mips32_op = OPC_SWC1;
12302 goto do_cop1;
12303 case SDC132:
12304 mips32_op = OPC_SDC1;
12305 do_cop1:
12306 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12307 break;
12308 case ADDIUPC:
12309 {
12310 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12311 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12312
12313 gen_addiupc(ctx, reg, offset, 0, 0);
12314 }
12315 break;
12316 /* Loads and stores */
12317 case LB32:
12318 mips32_op = OPC_LB;
12319 goto do_ld;
12320 case LBU32:
12321 mips32_op = OPC_LBU;
12322 goto do_ld;
12323 case LH32:
12324 mips32_op = OPC_LH;
12325 goto do_ld;
12326 case LHU32:
12327 mips32_op = OPC_LHU;
12328 goto do_ld;
12329 case LW32:
12330 mips32_op = OPC_LW;
12331 goto do_ld;
12332 #ifdef TARGET_MIPS64
12333 case LD32:
12334 mips32_op = OPC_LD;
12335 goto do_ld;
12336 case SD32:
12337 mips32_op = OPC_SD;
12338 goto do_st;
12339 #endif
12340 case SB32:
12341 mips32_op = OPC_SB;
12342 goto do_st;
12343 case SH32:
12344 mips32_op = OPC_SH;
12345 goto do_st;
12346 case SW32:
12347 mips32_op = OPC_SW;
12348 goto do_st;
12349 do_ld:
12350 gen_ld(ctx, mips32_op, rt, rs, imm);
12351 break;
12352 do_st:
12353 gen_st(ctx, mips32_op, rt, rs, imm);
12354 break;
12355 default:
12356 generate_exception(ctx, EXCP_RI);
12357 break;
12358 }
12359 }
12360
12361 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
12362 {
12363 uint32_t op;
12364
12365 /* make sure instructions are on a halfword boundary */
12366 if (ctx->pc & 0x1) {
12367 env->CP0_BadVAddr = ctx->pc;
12368 generate_exception(ctx, EXCP_AdEL);
12369 ctx->bstate = BS_STOP;
12370 return 2;
12371 }
12372
12373 op = (ctx->opcode >> 10) & 0x3f;
12374 /* Enforce properly-sized instructions in a delay slot */
12375 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12376 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12377
12378 switch (op) {
12379 case POOL32A:
12380 case POOL32B:
12381 case POOL32I:
12382 case POOL32C:
12383 case ADDI32:
12384 case ADDIU32:
12385 case ORI32:
12386 case XORI32:
12387 case SLTI32:
12388 case SLTIU32:
12389 case ANDI32:
12390 case JALX32:
12391 case LBU32:
12392 case LHU32:
12393 case POOL32F:
12394 case JALS32:
12395 case BEQ32:
12396 case BNE32:
12397 case J32:
12398 case JAL32:
12399 case SB32:
12400 case SH32:
12401 case POOL32S:
12402 case ADDIUPC:
12403 case SWC132:
12404 case SDC132:
12405 case SD32:
12406 case SW32:
12407 case LB32:
12408 case LH32:
12409 case DADDIU32:
12410 case LWC132:
12411 case LDC132:
12412 case LD32:
12413 case LW32:
12414 if (bits & MIPS_HFLAG_BDS16) {
12415 generate_exception(ctx, EXCP_RI);
12416 /* Just stop translation; the user is confused. */
12417 ctx->bstate = BS_STOP;
12418 return 2;
12419 }
12420 break;
12421 case POOL16A:
12422 case POOL16B:
12423 case POOL16C:
12424 case LWGP16:
12425 case POOL16F:
12426 case LBU16:
12427 case LHU16:
12428 case LWSP16:
12429 case LW16:
12430 case SB16:
12431 case SH16:
12432 case SWSP16:
12433 case SW16:
12434 case MOVE16:
12435 case ANDI16:
12436 case POOL16D:
12437 case POOL16E:
12438 case BEQZ16:
12439 case BNEZ16:
12440 case B16:
12441 case LI16:
12442 if (bits & MIPS_HFLAG_BDS32) {
12443 generate_exception(ctx, EXCP_RI);
12444 /* Just stop translation; the user is confused. */
12445 ctx->bstate = BS_STOP;
12446 return 2;
12447 }
12448 break;
12449 default:
12450 break;
12451 }
12452 }
12453 switch (op) {
12454 case POOL16A:
12455 {
12456 int rd = mmreg(uMIPS_RD(ctx->opcode));
12457 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12458 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12459 uint32_t opc = 0;
12460
12461 switch (ctx->opcode & 0x1) {
12462 case ADDU16:
12463 opc = OPC_ADDU;
12464 break;
12465 case SUBU16:
12466 opc = OPC_SUBU;
12467 break;
12468 }
12469
12470 gen_arith(ctx, opc, rd, rs1, rs2);
12471 }
12472 break;
12473 case POOL16B:
12474 {
12475 int rd = mmreg(uMIPS_RD(ctx->opcode));
12476 int rs = mmreg(uMIPS_RS(ctx->opcode));
12477 int amount = (ctx->opcode >> 1) & 0x7;
12478 uint32_t opc = 0;
12479 amount = amount == 0 ? 8 : amount;
12480
12481 switch (ctx->opcode & 0x1) {
12482 case SLL16:
12483 opc = OPC_SLL;
12484 break;
12485 case SRL16:
12486 opc = OPC_SRL;
12487 break;
12488 }
12489
12490 gen_shift_imm(ctx, opc, rd, rs, amount);
12491 }
12492 break;
12493 case POOL16C:
12494 gen_pool16c_insn(ctx);
12495 break;
12496 case LWGP16:
12497 {
12498 int rd = mmreg(uMIPS_RD(ctx->opcode));
12499 int rb = 28; /* GP */
12500 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12501
12502 gen_ld(ctx, OPC_LW, rd, rb, offset);
12503 }
12504 break;
12505 case POOL16F:
12506 if (ctx->opcode & 1) {
12507 generate_exception(ctx, EXCP_RI);
12508 } else {
12509 /* MOVEP */
12510 int enc_dest = uMIPS_RD(ctx->opcode);
12511 int enc_rt = uMIPS_RS2(ctx->opcode);
12512 int enc_rs = uMIPS_RS1(ctx->opcode);
12513 int rd, rs, re, rt;
12514 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12515 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12516 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12517
12518 rd = rd_enc[enc_dest];
12519 re = re_enc[enc_dest];
12520 rs = rs_rt_enc[enc_rs];
12521 rt = rs_rt_enc[enc_rt];
12522
12523 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12524 gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
12525 }
12526 break;
12527 case LBU16:
12528 {
12529 int rd = mmreg(uMIPS_RD(ctx->opcode));
12530 int rb = mmreg(uMIPS_RS(ctx->opcode));
12531 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12532 offset = (offset == 0xf ? -1 : offset);
12533
12534 gen_ld(ctx, OPC_LBU, rd, rb, offset);
12535 }
12536 break;
12537 case LHU16:
12538 {
12539 int rd = mmreg(uMIPS_RD(ctx->opcode));
12540 int rb = mmreg(uMIPS_RS(ctx->opcode));
12541 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12542
12543 gen_ld(ctx, OPC_LHU, rd, rb, offset);
12544 }
12545 break;
12546 case LWSP16:
12547 {
12548 int rd = (ctx->opcode >> 5) & 0x1f;
12549 int rb = 29; /* SP */
12550 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12551
12552 gen_ld(ctx, OPC_LW, rd, rb, offset);
12553 }
12554 break;
12555 case LW16:
12556 {
12557 int rd = mmreg(uMIPS_RD(ctx->opcode));
12558 int rb = mmreg(uMIPS_RS(ctx->opcode));
12559 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12560
12561 gen_ld(ctx, OPC_LW, rd, rb, offset);
12562 }
12563 break;
12564 case SB16:
12565 {
12566 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12567 int rb = mmreg(uMIPS_RS(ctx->opcode));
12568 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12569
12570 gen_st(ctx, OPC_SB, rd, rb, offset);
12571 }
12572 break;
12573 case SH16:
12574 {
12575 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12576 int rb = mmreg(uMIPS_RS(ctx->opcode));
12577 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12578
12579 gen_st(ctx, OPC_SH, rd, rb, offset);
12580 }
12581 break;
12582 case SWSP16:
12583 {
12584 int rd = (ctx->opcode >> 5) & 0x1f;
12585 int rb = 29; /* SP */
12586 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12587
12588 gen_st(ctx, OPC_SW, rd, rb, offset);
12589 }
12590 break;
12591 case SW16:
12592 {
12593 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12594 int rb = mmreg(uMIPS_RS(ctx->opcode));
12595 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12596
12597 gen_st(ctx, OPC_SW, rd, rb, offset);
12598 }
12599 break;
12600 case MOVE16:
12601 {
12602 int rd = uMIPS_RD5(ctx->opcode);
12603 int rs = uMIPS_RS5(ctx->opcode);
12604
12605 gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12606 }
12607 break;
12608 case ANDI16:
12609 gen_andi16(ctx);
12610 break;
12611 case POOL16D:
12612 switch (ctx->opcode & 0x1) {
12613 case ADDIUS5:
12614 gen_addius5(ctx);
12615 break;
12616 case ADDIUSP:
12617 gen_addiusp(ctx);
12618 break;
12619 }
12620 break;
12621 case POOL16E:
12622 switch (ctx->opcode & 0x1) {
12623 case ADDIUR2:
12624 gen_addiur2(ctx);
12625 break;
12626 case ADDIUR1SP:
12627 gen_addiur1sp(ctx);
12628 break;
12629 }
12630 break;
12631 case B16:
12632 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12633 SIMM(ctx->opcode, 0, 10) << 1);
12634 break;
12635 case BNEZ16:
12636 case BEQZ16:
12637 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12638 mmreg(uMIPS_RD(ctx->opcode)),
12639 0, SIMM(ctx->opcode, 0, 7) << 1);
12640 break;
12641 case LI16:
12642 {
12643 int reg = mmreg(uMIPS_RD(ctx->opcode));
12644 int imm = ZIMM(ctx->opcode, 0, 7);
12645
12646 imm = (imm == 0x7f ? -1 : imm);
12647 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12648 }
12649 break;
12650 case RES_20:
12651 case RES_28:
12652 case RES_29:
12653 case RES_30:
12654 case RES_31:
12655 case RES_38:
12656 case RES_39:
12657 generate_exception(ctx, EXCP_RI);
12658 break;
12659 default:
12660 decode_micromips32_opc (env, ctx, op);
12661 return 4;
12662 }
12663
12664 return 2;
12665 }
12666
12667 /* SmartMIPS extension to MIPS32 */
12668
12669 #if defined(TARGET_MIPS64)
12670
12671 /* MDMX extension to MIPS64 */
12672
12673 #endif
12674
12675 /* MIPSDSP functions. */
12676 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12677 int rd, int base, int offset)
12678 {
12679 const char *opn = "ldx";
12680 TCGv t0;
12681
12682 check_dsp(ctx);
12683 t0 = tcg_temp_new();
12684
12685 if (base == 0) {
12686 gen_load_gpr(t0, offset);
12687 } else if (offset == 0) {
12688 gen_load_gpr(t0, base);
12689 } else {
12690 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12691 }
12692
12693 switch (opc) {
12694 case OPC_LBUX:
12695 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12696 gen_store_gpr(t0, rd);
12697 opn = "lbux";
12698 break;
12699 case OPC_LHX:
12700 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12701 gen_store_gpr(t0, rd);
12702 opn = "lhx";
12703 break;
12704 case OPC_LWX:
12705 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12706 gen_store_gpr(t0, rd);
12707 opn = "lwx";
12708 break;
12709 #if defined(TARGET_MIPS64)
12710 case OPC_LDX:
12711 tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
12712 gen_store_gpr(t0, rd);
12713 opn = "ldx";
12714 break;
12715 #endif
12716 }
12717 (void)opn; /* avoid a compiler warning */
12718 MIPS_DEBUG("%s %s, %s(%s)", opn,
12719 regnames[rd], regnames[offset], regnames[base]);
12720 tcg_temp_free(t0);
12721 }
12722
12723 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12724 int ret, int v1, int v2)
12725 {
12726 const char *opn = "mipsdsp arith";
12727 TCGv v1_t;
12728 TCGv v2_t;
12729
12730 if (ret == 0) {
12731 /* Treat as NOP. */
12732 MIPS_DEBUG("NOP");
12733 return;
12734 }
12735
12736 v1_t = tcg_temp_new();
12737 v2_t = tcg_temp_new();
12738
12739 gen_load_gpr(v1_t, v1);
12740 gen_load_gpr(v2_t, v2);
12741
12742 switch (op1) {
12743 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12744 case OPC_MULT_G_2E:
12745 check_dspr2(ctx);
12746 switch (op2) {
12747 case OPC_ADDUH_QB:
12748 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12749 break;
12750 case OPC_ADDUH_R_QB:
12751 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12752 break;
12753 case OPC_ADDQH_PH:
12754 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12755 break;
12756 case OPC_ADDQH_R_PH:
12757 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12758 break;
12759 case OPC_ADDQH_W:
12760 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12761 break;
12762 case OPC_ADDQH_R_W:
12763 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12764 break;
12765 case OPC_SUBUH_QB:
12766 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12767 break;
12768 case OPC_SUBUH_R_QB:
12769 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12770 break;
12771 case OPC_SUBQH_PH:
12772 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12773 break;
12774 case OPC_SUBQH_R_PH:
12775 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12776 break;
12777 case OPC_SUBQH_W:
12778 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12779 break;
12780 case OPC_SUBQH_R_W:
12781 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12782 break;
12783 }
12784 break;
12785 case OPC_ABSQ_S_PH_DSP:
12786 switch (op2) {
12787 case OPC_ABSQ_S_QB:
12788 check_dspr2(ctx);
12789 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12790 break;
12791 case OPC_ABSQ_S_PH:
12792 check_dsp(ctx);
12793 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12794 break;
12795 case OPC_ABSQ_S_W:
12796 check_dsp(ctx);
12797 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12798 break;
12799 case OPC_PRECEQ_W_PHL:
12800 check_dsp(ctx);
12801 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12802 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12803 break;
12804 case OPC_PRECEQ_W_PHR:
12805 check_dsp(ctx);
12806 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12807 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12808 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12809 break;
12810 case OPC_PRECEQU_PH_QBL:
12811 check_dsp(ctx);
12812 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12813 break;
12814 case OPC_PRECEQU_PH_QBR:
12815 check_dsp(ctx);
12816 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12817 break;
12818 case OPC_PRECEQU_PH_QBLA:
12819 check_dsp(ctx);
12820 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12821 break;
12822 case OPC_PRECEQU_PH_QBRA:
12823 check_dsp(ctx);
12824 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12825 break;
12826 case OPC_PRECEU_PH_QBL:
12827 check_dsp(ctx);
12828 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12829 break;
12830 case OPC_PRECEU_PH_QBR:
12831 check_dsp(ctx);
12832 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12833 break;
12834 case OPC_PRECEU_PH_QBLA:
12835 check_dsp(ctx);
12836 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12837 break;
12838 case OPC_PRECEU_PH_QBRA:
12839 check_dsp(ctx);
12840 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12841 break;
12842 }
12843 break;
12844 case OPC_ADDU_QB_DSP:
12845 switch (op2) {
12846 case OPC_ADDQ_PH:
12847 check_dsp(ctx);
12848 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849 break;
12850 case OPC_ADDQ_S_PH:
12851 check_dsp(ctx);
12852 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853 break;
12854 case OPC_ADDQ_S_W:
12855 check_dsp(ctx);
12856 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12857 break;
12858 case OPC_ADDU_QB:
12859 check_dsp(ctx);
12860 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861 break;
12862 case OPC_ADDU_S_QB:
12863 check_dsp(ctx);
12864 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865 break;
12866 case OPC_ADDU_PH:
12867 check_dspr2(ctx);
12868 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12869 break;
12870 case OPC_ADDU_S_PH:
12871 check_dspr2(ctx);
12872 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12873 break;
12874 case OPC_SUBQ_PH:
12875 check_dsp(ctx);
12876 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12877 break;
12878 case OPC_SUBQ_S_PH:
12879 check_dsp(ctx);
12880 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12881 break;
12882 case OPC_SUBQ_S_W:
12883 check_dsp(ctx);
12884 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885 break;
12886 case OPC_SUBU_QB:
12887 check_dsp(ctx);
12888 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889 break;
12890 case OPC_SUBU_S_QB:
12891 check_dsp(ctx);
12892 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12893 break;
12894 case OPC_SUBU_PH:
12895 check_dspr2(ctx);
12896 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12897 break;
12898 case OPC_SUBU_S_PH:
12899 check_dspr2(ctx);
12900 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12901 break;
12902 case OPC_ADDSC:
12903 check_dsp(ctx);
12904 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12905 break;
12906 case OPC_ADDWC:
12907 check_dsp(ctx);
12908 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12909 break;
12910 case OPC_MODSUB:
12911 check_dsp(ctx);
12912 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12913 break;
12914 case OPC_RADDU_W_QB:
12915 check_dsp(ctx);
12916 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12917 break;
12918 }
12919 break;
12920 case OPC_CMPU_EQ_QB_DSP:
12921 switch (op2) {
12922 case OPC_PRECR_QB_PH:
12923 check_dspr2(ctx);
12924 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12925 break;
12926 case OPC_PRECRQ_QB_PH:
12927 check_dsp(ctx);
12928 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12929 break;
12930 case OPC_PRECR_SRA_PH_W:
12931 check_dspr2(ctx);
12932 {
12933 TCGv_i32 sa_t = tcg_const_i32(v2);
12934 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12935 cpu_gpr[ret]);
12936 tcg_temp_free_i32(sa_t);
12937 break;
12938 }
12939 case OPC_PRECR_SRA_R_PH_W:
12940 check_dspr2(ctx);
12941 {
12942 TCGv_i32 sa_t = tcg_const_i32(v2);
12943 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12944 cpu_gpr[ret]);
12945 tcg_temp_free_i32(sa_t);
12946 break;
12947 }
12948 case OPC_PRECRQ_PH_W:
12949 check_dsp(ctx);
12950 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12951 break;
12952 case OPC_PRECRQ_RS_PH_W:
12953 check_dsp(ctx);
12954 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12955 break;
12956 case OPC_PRECRQU_S_QB_PH:
12957 check_dsp(ctx);
12958 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12959 break;
12960 }
12961 break;
12962 #ifdef TARGET_MIPS64
12963 case OPC_ABSQ_S_QH_DSP:
12964 switch (op2) {
12965 case OPC_PRECEQ_L_PWL:
12966 check_dsp(ctx);
12967 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12968 break;
12969 case OPC_PRECEQ_L_PWR:
12970 check_dsp(ctx);
12971 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12972 break;
12973 case OPC_PRECEQ_PW_QHL:
12974 check_dsp(ctx);
12975 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12976 break;
12977 case OPC_PRECEQ_PW_QHR:
12978 check_dsp(ctx);
12979 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12980 break;
12981 case OPC_PRECEQ_PW_QHLA:
12982 check_dsp(ctx);
12983 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12984 break;
12985 case OPC_PRECEQ_PW_QHRA:
12986 check_dsp(ctx);
12987 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12988 break;
12989 case OPC_PRECEQU_QH_OBL:
12990 check_dsp(ctx);
12991 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12992 break;
12993 case OPC_PRECEQU_QH_OBR:
12994 check_dsp(ctx);
12995 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12996 break;
12997 case OPC_PRECEQU_QH_OBLA:
12998 check_dsp(ctx);
12999 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
13000 break;
13001 case OPC_PRECEQU_QH_OBRA:
13002 check_dsp(ctx);
13003 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
13004 break;
13005 case OPC_PRECEU_QH_OBL:
13006 check_dsp(ctx);
13007 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
13008 break;
13009 case OPC_PRECEU_QH_OBR:
13010 check_dsp(ctx);
13011 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
13012 break;
13013 case OPC_PRECEU_QH_OBLA:
13014 check_dsp(ctx);
13015 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
13016 break;
13017 case OPC_PRECEU_QH_OBRA:
13018 check_dsp(ctx);
13019 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13020 break;
13021 case OPC_ABSQ_S_OB:
13022 check_dspr2(ctx);
13023 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13024 break;
13025 case OPC_ABSQ_S_PW:
13026 check_dsp(ctx);
13027 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13028 break;
13029 case OPC_ABSQ_S_QH:
13030 check_dsp(ctx);
13031 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13032 break;
13033 }
13034 break;
13035 case OPC_ADDU_OB_DSP:
13036 switch (op2) {
13037 case OPC_RADDU_L_OB:
13038 check_dsp(ctx);
13039 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13040 break;
13041 case OPC_SUBQ_PW:
13042 check_dsp(ctx);
13043 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044 break;
13045 case OPC_SUBQ_S_PW:
13046 check_dsp(ctx);
13047 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048 break;
13049 case OPC_SUBQ_QH:
13050 check_dsp(ctx);
13051 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052 break;
13053 case OPC_SUBQ_S_QH:
13054 check_dsp(ctx);
13055 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13056 break;
13057 case OPC_SUBU_OB:
13058 check_dsp(ctx);
13059 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13060 break;
13061 case OPC_SUBU_S_OB:
13062 check_dsp(ctx);
13063 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13064 break;
13065 case OPC_SUBU_QH:
13066 check_dspr2(ctx);
13067 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13068 break;
13069 case OPC_SUBU_S_QH:
13070 check_dspr2(ctx);
13071 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13072 break;
13073 case OPC_SUBUH_OB:
13074 check_dspr2(ctx);
13075 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13076 break;
13077 case OPC_SUBUH_R_OB:
13078 check_dspr2(ctx);
13079 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13080 break;
13081 case OPC_ADDQ_PW:
13082 check_dsp(ctx);
13083 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084 break;
13085 case OPC_ADDQ_S_PW:
13086 check_dsp(ctx);
13087 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13088 break;
13089 case OPC_ADDQ_QH:
13090 check_dsp(ctx);
13091 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092 break;
13093 case OPC_ADDQ_S_QH:
13094 check_dsp(ctx);
13095 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13096 break;
13097 case OPC_ADDU_OB:
13098 check_dsp(ctx);
13099 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13100 break;
13101 case OPC_ADDU_S_OB:
13102 check_dsp(ctx);
13103 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13104 break;
13105 case OPC_ADDU_QH:
13106 check_dspr2(ctx);
13107 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13108 break;
13109 case OPC_ADDU_S_QH:
13110 check_dspr2(ctx);
13111 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13112 break;
13113 case OPC_ADDUH_OB:
13114 check_dspr2(ctx);
13115 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13116 break;
13117 case OPC_ADDUH_R_OB:
13118 check_dspr2(ctx);
13119 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13120 break;
13121 }
13122 break;
13123 case OPC_CMPU_EQ_OB_DSP:
13124 switch (op2) {
13125 case OPC_PRECR_OB_QH:
13126 check_dspr2(ctx);
13127 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13128 break;
13129 case OPC_PRECR_SRA_QH_PW:
13130 check_dspr2(ctx);
13131 {
13132 TCGv_i32 ret_t = tcg_const_i32(ret);
13133 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13134 tcg_temp_free_i32(ret_t);
13135 break;
13136 }
13137 case OPC_PRECR_SRA_R_QH_PW:
13138 check_dspr2(ctx);
13139 {
13140 TCGv_i32 sa_v = tcg_const_i32(ret);
13141 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13142 tcg_temp_free_i32(sa_v);
13143 break;
13144 }
13145 case OPC_PRECRQ_OB_QH:
13146 check_dsp(ctx);
13147 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13148 break;
13149 case OPC_PRECRQ_PW_L:
13150 check_dsp(ctx);
13151 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13152 break;
13153 case OPC_PRECRQ_QH_PW:
13154 check_dsp(ctx);
13155 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13156 break;
13157 case OPC_PRECRQ_RS_QH_PW:
13158 check_dsp(ctx);
13159 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13160 break;
13161 case OPC_PRECRQU_S_OB_QH:
13162 check_dsp(ctx);
13163 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13164 break;
13165 }
13166 break;
13167 #endif
13168 }
13169
13170 tcg_temp_free(v1_t);
13171 tcg_temp_free(v2_t);
13172
13173 (void)opn; /* avoid a compiler warning */
13174 MIPS_DEBUG("%s", opn);
13175 }
13176
13177 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13178 int ret, int v1, int v2)
13179 {
13180 uint32_t op2;
13181 const char *opn = "mipsdsp shift";
13182 TCGv t0;
13183 TCGv v1_t;
13184 TCGv v2_t;
13185
13186 if (ret == 0) {
13187 /* Treat as NOP. */
13188 MIPS_DEBUG("NOP");
13189 return;
13190 }
13191
13192 t0 = tcg_temp_new();
13193 v1_t = tcg_temp_new();
13194 v2_t = tcg_temp_new();
13195
13196 tcg_gen_movi_tl(t0, v1);
13197 gen_load_gpr(v1_t, v1);
13198 gen_load_gpr(v2_t, v2);
13199
13200 switch (opc) {
13201 case OPC_SHLL_QB_DSP:
13202 {
13203 op2 = MASK_SHLL_QB(ctx->opcode);
13204 switch (op2) {
13205 case OPC_SHLL_QB:
13206 check_dsp(ctx);
13207 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13208 break;
13209 case OPC_SHLLV_QB:
13210 check_dsp(ctx);
13211 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13212 break;
13213 case OPC_SHLL_PH:
13214 check_dsp(ctx);
13215 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13216 break;
13217 case OPC_SHLLV_PH:
13218 check_dsp(ctx);
13219 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13220 break;
13221 case OPC_SHLL_S_PH:
13222 check_dsp(ctx);
13223 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13224 break;
13225 case OPC_SHLLV_S_PH:
13226 check_dsp(ctx);
13227 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13228 break;
13229 case OPC_SHLL_S_W:
13230 check_dsp(ctx);
13231 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13232 break;
13233 case OPC_SHLLV_S_W:
13234 check_dsp(ctx);
13235 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13236 break;
13237 case OPC_SHRL_QB:
13238 check_dsp(ctx);
13239 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13240 break;
13241 case OPC_SHRLV_QB:
13242 check_dsp(ctx);
13243 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13244 break;
13245 case OPC_SHRL_PH:
13246 check_dspr2(ctx);
13247 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13248 break;
13249 case OPC_SHRLV_PH:
13250 check_dspr2(ctx);
13251 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13252 break;
13253 case OPC_SHRA_QB:
13254 check_dspr2(ctx);
13255 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13256 break;
13257 case OPC_SHRA_R_QB:
13258 check_dspr2(ctx);
13259 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13260 break;
13261 case OPC_SHRAV_QB:
13262 check_dspr2(ctx);
13263 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13264 break;
13265 case OPC_SHRAV_R_QB:
13266 check_dspr2(ctx);
13267 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13268 break;
13269 case OPC_SHRA_PH:
13270 check_dsp(ctx);
13271 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13272 break;
13273 case OPC_SHRA_R_PH:
13274 check_dsp(ctx);
13275 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13276 break;
13277 case OPC_SHRAV_PH:
13278 check_dsp(ctx);
13279 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13280 break;
13281 case OPC_SHRAV_R_PH:
13282 check_dsp(ctx);
13283 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13284 break;
13285 case OPC_SHRA_R_W:
13286 check_dsp(ctx);
13287 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13288 break;
13289 case OPC_SHRAV_R_W:
13290 check_dsp(ctx);
13291 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13292 break;
13293 default: /* Invalid */
13294 MIPS_INVAL("MASK SHLL.QB");
13295 generate_exception(ctx, EXCP_RI);
13296 break;
13297 }
13298 break;
13299 }
13300 #ifdef TARGET_MIPS64
13301 case OPC_SHLL_OB_DSP:
13302 op2 = MASK_SHLL_OB(ctx->opcode);
13303 switch (op2) {
13304 case OPC_SHLL_PW:
13305 check_dsp(ctx);
13306 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13307 break;
13308 case OPC_SHLLV_PW:
13309 check_dsp(ctx);
13310 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13311 break;
13312 case OPC_SHLL_S_PW:
13313 check_dsp(ctx);
13314 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13315 break;
13316 case OPC_SHLLV_S_PW:
13317 check_dsp(ctx);
13318 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13319 break;
13320 case OPC_SHLL_OB:
13321 check_dsp(ctx);
13322 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13323 break;
13324 case OPC_SHLLV_OB:
13325 check_dsp(ctx);
13326 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13327 break;
13328 case OPC_SHLL_QH:
13329 check_dsp(ctx);
13330 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13331 break;
13332 case OPC_SHLLV_QH:
13333 check_dsp(ctx);
13334 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13335 break;
13336 case OPC_SHLL_S_QH:
13337 check_dsp(ctx);
13338 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13339 break;
13340 case OPC_SHLLV_S_QH:
13341 check_dsp(ctx);
13342 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13343 break;
13344 case OPC_SHRA_OB:
13345 check_dspr2(ctx);
13346 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13347 break;
13348 case OPC_SHRAV_OB:
13349 check_dspr2(ctx);
13350 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13351 break;
13352 case OPC_SHRA_R_OB:
13353 check_dspr2(ctx);
13354 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13355 break;
13356 case OPC_SHRAV_R_OB:
13357 check_dspr2(ctx);
13358 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13359 break;
13360 case OPC_SHRA_PW:
13361 check_dsp(ctx);
13362 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13363 break;
13364 case OPC_SHRAV_PW:
13365 check_dsp(ctx);
13366 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13367 break;
13368 case OPC_SHRA_R_PW:
13369 check_dsp(ctx);
13370 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13371 break;
13372 case OPC_SHRAV_R_PW:
13373 check_dsp(ctx);
13374 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13375 break;
13376 case OPC_SHRA_QH:
13377 check_dsp(ctx);
13378 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13379 break;
13380 case OPC_SHRAV_QH:
13381 check_dsp(ctx);
13382 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13383 break;
13384 case OPC_SHRA_R_QH:
13385 check_dsp(ctx);
13386 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13387 break;
13388 case OPC_SHRAV_R_QH:
13389 check_dsp(ctx);
13390 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13391 break;
13392 case OPC_SHRL_OB:
13393 check_dsp(ctx);
13394 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13395 break;
13396 case OPC_SHRLV_OB:
13397 check_dsp(ctx);
13398 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13399 break;
13400 case OPC_SHRL_QH:
13401 check_dspr2(ctx);
13402 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13403 break;
13404 case OPC_SHRLV_QH:
13405 check_dspr2(ctx);
13406 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13407 break;
13408 default: /* Invalid */
13409 MIPS_INVAL("MASK SHLL.OB");
13410 generate_exception(ctx, EXCP_RI);
13411 break;
13412 }
13413 break;
13414 #endif
13415 }
13416
13417 tcg_temp_free(t0);
13418 tcg_temp_free(v1_t);
13419 tcg_temp_free(v2_t);
13420 (void)opn; /* avoid a compiler warning */
13421 MIPS_DEBUG("%s", opn);
13422 }
13423
13424 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13425 int ret, int v1, int v2, int check_ret)
13426 {
13427 const char *opn = "mipsdsp multiply";
13428 TCGv_i32 t0;
13429 TCGv v1_t;
13430 TCGv v2_t;
13431
13432 if ((ret == 0) && (check_ret == 1)) {
13433 /* Treat as NOP. */
13434 MIPS_DEBUG("NOP");
13435 return;
13436 }
13437
13438 t0 = tcg_temp_new_i32();
13439 v1_t = tcg_temp_new();
13440 v2_t = tcg_temp_new();
13441
13442 tcg_gen_movi_i32(t0, ret);
13443 gen_load_gpr(v1_t, v1);
13444 gen_load_gpr(v2_t, v2);
13445
13446 switch (op1) {
13447 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13448 * the same mask and op1. */
13449 case OPC_MULT_G_2E:
13450 check_dspr2(ctx);
13451 switch (op2) {
13452 case OPC_MUL_PH:
13453 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13454 break;
13455 case OPC_MUL_S_PH:
13456 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13457 break;
13458 case OPC_MULQ_S_W:
13459 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13460 break;
13461 case OPC_MULQ_RS_W:
13462 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13463 break;
13464 }
13465 break;
13466 case OPC_DPA_W_PH_DSP:
13467 switch (op2) {
13468 case OPC_DPAU_H_QBL:
13469 check_dsp(ctx);
13470 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13471 break;
13472 case OPC_DPAU_H_QBR:
13473 check_dsp(ctx);
13474 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13475 break;
13476 case OPC_DPSU_H_QBL:
13477 check_dsp(ctx);
13478 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13479 break;
13480 case OPC_DPSU_H_QBR:
13481 check_dsp(ctx);
13482 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13483 break;
13484 case OPC_DPA_W_PH:
13485 check_dspr2(ctx);
13486 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13487 break;
13488 case OPC_DPAX_W_PH:
13489 check_dspr2(ctx);
13490 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13491 break;
13492 case OPC_DPAQ_S_W_PH:
13493 check_dsp(ctx);
13494 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13495 break;
13496 case OPC_DPAQX_S_W_PH:
13497 check_dspr2(ctx);
13498 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13499 break;
13500 case OPC_DPAQX_SA_W_PH:
13501 check_dspr2(ctx);
13502 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13503 break;
13504 case OPC_DPS_W_PH:
13505 check_dspr2(ctx);
13506 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13507 break;
13508 case OPC_DPSX_W_PH:
13509 check_dspr2(ctx);
13510 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13511 break;
13512 case OPC_DPSQ_S_W_PH:
13513 check_dsp(ctx);
13514 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13515 break;
13516 case OPC_DPSQX_S_W_PH:
13517 check_dspr2(ctx);
13518 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13519 break;
13520 case OPC_DPSQX_SA_W_PH:
13521 check_dspr2(ctx);
13522 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13523 break;
13524 case OPC_MULSAQ_S_W_PH:
13525 check_dsp(ctx);
13526 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13527 break;
13528 case OPC_DPAQ_SA_L_W:
13529 check_dsp(ctx);
13530 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13531 break;
13532 case OPC_DPSQ_SA_L_W:
13533 check_dsp(ctx);
13534 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13535 break;
13536 case OPC_MAQ_S_W_PHL:
13537 check_dsp(ctx);
13538 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13539 break;
13540 case OPC_MAQ_S_W_PHR:
13541 check_dsp(ctx);
13542 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13543 break;
13544 case OPC_MAQ_SA_W_PHL:
13545 check_dsp(ctx);
13546 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13547 break;
13548 case OPC_MAQ_SA_W_PHR:
13549 check_dsp(ctx);
13550 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13551 break;
13552 case OPC_MULSA_W_PH:
13553 check_dspr2(ctx);
13554 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13555 break;
13556 }
13557 break;
13558 #ifdef TARGET_MIPS64
13559 case OPC_DPAQ_W_QH_DSP:
13560 {
13561 int ac = ret & 0x03;
13562 tcg_gen_movi_i32(t0, ac);
13563
13564 switch (op2) {
13565 case OPC_DMADD:
13566 check_dsp(ctx);
13567 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13568 break;
13569 case OPC_DMADDU:
13570 check_dsp(ctx);
13571 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13572 break;
13573 case OPC_DMSUB:
13574 check_dsp(ctx);
13575 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13576 break;
13577 case OPC_DMSUBU:
13578 check_dsp(ctx);
13579 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13580 break;
13581 case OPC_DPA_W_QH:
13582 check_dspr2(ctx);
13583 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13584 break;
13585 case OPC_DPAQ_S_W_QH:
13586 check_dsp(ctx);
13587 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13588 break;
13589 case OPC_DPAQ_SA_L_PW:
13590 check_dsp(ctx);
13591 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13592 break;
13593 case OPC_DPAU_H_OBL:
13594 check_dsp(ctx);
13595 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13596 break;
13597 case OPC_DPAU_H_OBR:
13598 check_dsp(ctx);
13599 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13600 break;
13601 case OPC_DPS_W_QH:
13602 check_dspr2(ctx);
13603 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13604 break;
13605 case OPC_DPSQ_S_W_QH:
13606 check_dsp(ctx);
13607 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13608 break;
13609 case OPC_DPSQ_SA_L_PW:
13610 check_dsp(ctx);
13611 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13612 break;
13613 case OPC_DPSU_H_OBL:
13614 check_dsp(ctx);
13615 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13616 break;
13617 case OPC_DPSU_H_OBR:
13618 check_dsp(ctx);
13619 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13620 break;
13621 case OPC_MAQ_S_L_PWL:
13622 check_dsp(ctx);
13623 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13624 break;
13625 case OPC_MAQ_S_L_PWR:
13626 check_dsp(ctx);
13627 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13628 break;
13629 case OPC_MAQ_S_W_QHLL:
13630 check_dsp(ctx);
13631 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13632 break;
13633 case OPC_MAQ_SA_W_QHLL:
13634 check_dsp(ctx);
13635 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13636 break;
13637 case OPC_MAQ_S_W_QHLR:
13638 check_dsp(ctx);
13639 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13640 break;
13641 case OPC_MAQ_SA_W_QHLR:
13642 check_dsp(ctx);
13643 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13644 break;
13645 case OPC_MAQ_S_W_QHRL:
13646 check_dsp(ctx);
13647 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13648 break;
13649 case OPC_MAQ_SA_W_QHRL:
13650 check_dsp(ctx);
13651 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13652 break;
13653 case OPC_MAQ_S_W_QHRR:
13654 check_dsp(ctx);
13655 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13656 break;
13657 case OPC_MAQ_SA_W_QHRR:
13658 check_dsp(ctx);
13659 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13660 break;
13661 case OPC_MULSAQ_S_L_PW:
13662 check_dsp(ctx);
13663 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13664 break;
13665 case OPC_MULSAQ_S_W_QH:
13666 check_dsp(ctx);
13667 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13668 break;
13669 }
13670 }
13671 break;
13672 #endif
13673 case OPC_ADDU_QB_DSP:
13674 switch (op2) {
13675 case OPC_MULEU_S_PH_QBL:
13676 check_dsp(ctx);
13677 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13678 break;
13679 case OPC_MULEU_S_PH_QBR:
13680 check_dsp(ctx);
13681 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13682 break;
13683 case OPC_MULQ_RS_PH:
13684 check_dsp(ctx);
13685 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13686 break;
13687 case OPC_MULEQ_S_W_PHL:
13688 check_dsp(ctx);
13689 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13690 break;
13691 case OPC_MULEQ_S_W_PHR:
13692 check_dsp(ctx);
13693 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13694 break;
13695 case OPC_MULQ_S_PH:
13696 check_dspr2(ctx);
13697 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13698 break;
13699 }
13700 break;
13701 #ifdef TARGET_MIPS64
13702 case OPC_ADDU_OB_DSP:
13703 switch (op2) {
13704 case OPC_MULEQ_S_PW_QHL:
13705 check_dsp(ctx);
13706 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13707 break;
13708 case OPC_MULEQ_S_PW_QHR:
13709 check_dsp(ctx);
13710 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13711 break;
13712 case OPC_MULEU_S_QH_OBL:
13713 check_dsp(ctx);
13714 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13715 break;
13716 case OPC_MULEU_S_QH_OBR:
13717 check_dsp(ctx);
13718 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13719 break;
13720 case OPC_MULQ_RS_QH:
13721 check_dsp(ctx);
13722 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13723 break;
13724 }
13725 break;
13726 #endif
13727 }
13728
13729 tcg_temp_free_i32(t0);
13730 tcg_temp_free(v1_t);
13731 tcg_temp_free(v2_t);
13732
13733 (void)opn; /* avoid a compiler warning */
13734 MIPS_DEBUG("%s", opn);
13735
13736 }
13737
13738 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13739 int ret, int val)
13740 {
13741 const char *opn = "mipsdsp Bit/ Manipulation";
13742 int16_t imm;
13743 TCGv t0;
13744 TCGv val_t;
13745
13746 if (ret == 0) {
13747 /* Treat as NOP. */
13748 MIPS_DEBUG("NOP");
13749 return;
13750 }
13751
13752 t0 = tcg_temp_new();
13753 val_t = tcg_temp_new();
13754 gen_load_gpr(val_t, val);
13755
13756 switch (op1) {
13757 case OPC_ABSQ_S_PH_DSP:
13758 switch (op2) {
13759 case OPC_BITREV:
13760 check_dsp(ctx);
13761 gen_helper_bitrev(cpu_gpr[ret], val_t);
13762 break;
13763 case OPC_REPL_QB:
13764 check_dsp(ctx);
13765 {
13766 target_long result;
13767 imm = (ctx->opcode >> 16) & 0xFF;
13768 result = (uint32_t)imm << 24 |
13769 (uint32_t)imm << 16 |
13770 (uint32_t)imm << 8 |
13771 (uint32_t)imm;
13772 result = (int32_t)result;
13773 tcg_gen_movi_tl(cpu_gpr[ret], result);
13774 }
13775 break;
13776 case OPC_REPLV_QB:
13777 check_dsp(ctx);
13778 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13779 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13780 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13781 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13782 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13783 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13784 break;
13785 case OPC_REPL_PH:
13786 check_dsp(ctx);
13787 {
13788 imm = (ctx->opcode >> 16) & 0x03FF;
13789 imm = (int16_t)(imm << 6) >> 6;
13790 tcg_gen_movi_tl(cpu_gpr[ret], \
13791 (target_long)((int32_t)imm << 16 | \
13792 (uint16_t)imm));
13793 }
13794 break;
13795 case OPC_REPLV_PH:
13796 check_dsp(ctx);
13797 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13798 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13799 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13800 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13801 break;
13802 }
13803 break;
13804 #ifdef TARGET_MIPS64
13805 case OPC_ABSQ_S_QH_DSP:
13806 switch (op2) {
13807 case OPC_REPL_OB:
13808 check_dsp(ctx);
13809 {
13810 target_long temp;
13811
13812 imm = (ctx->opcode >> 16) & 0xFF;
13813 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13814 temp = (temp << 16) | temp;
13815 temp = (temp << 32) | temp;
13816 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13817 break;
13818 }
13819 case OPC_REPL_PW:
13820 check_dsp(ctx);
13821 {
13822 target_long temp;
13823
13824 imm = (ctx->opcode >> 16) & 0x03FF;
13825 imm = (int16_t)(imm << 6) >> 6;
13826 temp = ((target_long)imm << 32) \
13827 | ((target_long)imm & 0xFFFFFFFF);
13828 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13829 break;
13830 }
13831 case OPC_REPL_QH:
13832 check_dsp(ctx);
13833 {
13834 target_long temp;
13835
13836 imm = (ctx->opcode >> 16) & 0x03FF;
13837 imm = (int16_t)(imm << 6) >> 6;
13838
13839 temp = ((uint64_t)(uint16_t)imm << 48) |
13840 ((uint64_t)(uint16_t)imm << 32) |
13841 ((uint64_t)(uint16_t)imm << 16) |
13842 (uint64_t)(uint16_t)imm;
13843 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13844 break;
13845 }
13846 case OPC_REPLV_OB:
13847 check_dsp(ctx);
13848 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13849 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13850 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13851 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13852 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13853 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13854 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13855 break;
13856 case OPC_REPLV_PW:
13857 check_dsp(ctx);
13858 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13859 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13860 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13861 break;
13862 case OPC_REPLV_QH:
13863 check_dsp(ctx);
13864 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13865 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13866 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13867 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13868 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13869 break;
13870 }
13871 break;
13872 #endif
13873 }
13874 tcg_temp_free(t0);
13875 tcg_temp_free(val_t);
13876
13877 (void)opn; /* avoid a compiler warning */
13878 MIPS_DEBUG("%s", opn);
13879 }
13880
13881 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13882 uint32_t op1, uint32_t op2,
13883 int ret, int v1, int v2, int check_ret)
13884 {
13885 const char *opn = "mipsdsp add compare pick";
13886 TCGv t1;
13887 TCGv v1_t;
13888 TCGv v2_t;
13889
13890 if ((ret == 0) && (check_ret == 1)) {
13891 /* Treat as NOP. */
13892 MIPS_DEBUG("NOP");
13893 return;
13894 }
13895
13896 t1 = tcg_temp_new();
13897 v1_t = tcg_temp_new();
13898 v2_t = tcg_temp_new();
13899
13900 gen_load_gpr(v1_t, v1);
13901 gen_load_gpr(v2_t, v2);
13902
13903 switch (op1) {
13904 case OPC_CMPU_EQ_QB_DSP:
13905 switch (op2) {
13906 case OPC_CMPU_EQ_QB:
13907 check_dsp(ctx);
13908 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13909 break;
13910 case OPC_CMPU_LT_QB:
13911 check_dsp(ctx);
13912 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13913 break;
13914 case OPC_CMPU_LE_QB:
13915 check_dsp(ctx);
13916 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13917 break;
13918 case OPC_CMPGU_EQ_QB:
13919 check_dsp(ctx);
13920 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13921 break;
13922 case OPC_CMPGU_LT_QB:
13923 check_dsp(ctx);
13924 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13925 break;
13926 case OPC_CMPGU_LE_QB:
13927 check_dsp(ctx);
13928 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13929 break;
13930 case OPC_CMPGDU_EQ_QB:
13931 check_dspr2(ctx);
13932 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13933 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13934 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13935 tcg_gen_shli_tl(t1, t1, 24);
13936 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13937 break;
13938 case OPC_CMPGDU_LT_QB:
13939 check_dspr2(ctx);
13940 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13941 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13942 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13943 tcg_gen_shli_tl(t1, t1, 24);
13944 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13945 break;
13946 case OPC_CMPGDU_LE_QB:
13947 check_dspr2(ctx);
13948 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13949 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13950 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13951 tcg_gen_shli_tl(t1, t1, 24);
13952 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13953 break;
13954 case OPC_CMP_EQ_PH:
13955 check_dsp(ctx);
13956 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13957 break;
13958 case OPC_CMP_LT_PH:
13959 check_dsp(ctx);
13960 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13961 break;
13962 case OPC_CMP_LE_PH:
13963 check_dsp(ctx);
13964 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13965 break;
13966 case OPC_PICK_QB:
13967 check_dsp(ctx);
13968 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13969 break;
13970 case OPC_PICK_PH:
13971 check_dsp(ctx);
13972 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13973 break;
13974 case OPC_PACKRL_PH:
13975 check_dsp(ctx);
13976 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13977 break;
13978 }
13979 break;
13980 #ifdef TARGET_MIPS64
13981 case OPC_CMPU_EQ_OB_DSP:
13982 switch (op2) {
13983 case OPC_CMP_EQ_PW:
13984 check_dsp(ctx);
13985 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13986 break;
13987 case OPC_CMP_LT_PW:
13988 check_dsp(ctx);
13989 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13990 break;
13991 case OPC_CMP_LE_PW:
13992 check_dsp(ctx);
13993 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13994 break;
13995 case OPC_CMP_EQ_QH:
13996 check_dsp(ctx);
13997 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13998 break;
13999 case OPC_CMP_LT_QH:
14000 check_dsp(ctx);
14001 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
14002 break;
14003 case OPC_CMP_LE_QH:
14004 check_dsp(ctx);
14005 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
14006 break;
14007 case OPC_CMPGDU_EQ_OB:
14008 check_dspr2(ctx);
14009 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14010 break;
14011 case OPC_CMPGDU_LT_OB:
14012 check_dspr2(ctx);
14013 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14014 break;
14015 case OPC_CMPGDU_LE_OB:
14016 check_dspr2(ctx);
14017 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14018 break;
14019 case OPC_CMPGU_EQ_OB:
14020 check_dsp(ctx);
14021 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14022 break;
14023 case OPC_CMPGU_LT_OB:
14024 check_dsp(ctx);
14025 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14026 break;
14027 case OPC_CMPGU_LE_OB:
14028 check_dsp(ctx);
14029 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14030 break;
14031 case OPC_CMPU_EQ_OB:
14032 check_dsp(ctx);
14033 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14034 break;
14035 case OPC_CMPU_LT_OB:
14036 check_dsp(ctx);
14037 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14038 break;
14039 case OPC_CMPU_LE_OB:
14040 check_dsp(ctx);
14041 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14042 break;
14043 case OPC_PACKRL_PW:
14044 check_dsp(ctx);
14045 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14046 break;
14047 case OPC_PICK_OB:
14048 check_dsp(ctx);
14049 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14050 break;
14051 case OPC_PICK_PW:
14052 check_dsp(ctx);
14053 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14054 break;
14055 case OPC_PICK_QH:
14056 check_dsp(ctx);
14057 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14058 break;
14059 }
14060 break;
14061 #endif
14062 }
14063
14064 tcg_temp_free(t1);
14065 tcg_temp_free(v1_t);
14066 tcg_temp_free(v2_t);
14067
14068 (void)opn; /* avoid a compiler warning */
14069 MIPS_DEBUG("%s", opn);
14070 }
14071
14072 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14073 uint32_t op1, int rt, int rs, int sa)
14074 {
14075 const char *opn = "mipsdsp append/dappend";
14076 TCGv t0;
14077
14078 check_dspr2(ctx);
14079
14080 if (rt == 0) {
14081 /* Treat as NOP. */
14082 MIPS_DEBUG("NOP");
14083 return;
14084 }
14085
14086 t0 = tcg_temp_new();
14087 gen_load_gpr(t0, rs);
14088
14089 switch (op1) {
14090 case OPC_APPEND_DSP:
14091 switch (MASK_APPEND(ctx->opcode)) {
14092 case OPC_APPEND:
14093 if (sa != 0) {
14094 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14095 }
14096 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14097 break;
14098 case OPC_PREPEND:
14099 if (sa != 0) {
14100 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14101 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14102 tcg_gen_shli_tl(t0, t0, 32 - sa);
14103 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14104 }
14105 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14106 break;
14107 case OPC_BALIGN:
14108 sa &= 3;
14109 if (sa != 0 && sa != 2) {
14110 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14111 tcg_gen_ext32u_tl(t0, t0);
14112 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14113 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14114 }
14115 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14116 break;
14117 default: /* Invalid */
14118 MIPS_INVAL("MASK APPEND");
14119 generate_exception(ctx, EXCP_RI);
14120 break;
14121 }
14122 break;
14123 #ifdef TARGET_MIPS64
14124 case OPC_DAPPEND_DSP:
14125 switch (MASK_DAPPEND(ctx->opcode)) {
14126 case OPC_DAPPEND:
14127 if (sa != 0) {
14128 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14129 }
14130 break;
14131 case OPC_PREPENDD:
14132 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14133 tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14134 tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
14135 break;
14136 case OPC_PREPENDW:
14137 if (sa != 0) {
14138 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14139 tcg_gen_shli_tl(t0, t0, 64 - sa);
14140 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14141 }
14142 break;
14143 case OPC_DBALIGN:
14144 sa &= 7;
14145 if (sa != 0 && sa != 2 && sa != 4) {
14146 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14147 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14148 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14149 }
14150 break;
14151 default: /* Invalid */
14152 MIPS_INVAL("MASK DAPPEND");
14153 generate_exception(ctx, EXCP_RI);
14154 break;
14155 }
14156 break;
14157 #endif
14158 }
14159 tcg_temp_free(t0);
14160 (void)opn; /* avoid a compiler warning */
14161 MIPS_DEBUG("%s", opn);
14162 }
14163
14164 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14165 int ret, int v1, int v2, int check_ret)
14166
14167 {
14168 const char *opn = "mipsdsp accumulator";
14169 TCGv t0;
14170 TCGv t1;
14171 TCGv v1_t;
14172 TCGv v2_t;
14173 int16_t imm;
14174
14175 if ((ret == 0) && (check_ret == 1)) {
14176 /* Treat as NOP. */
14177 MIPS_DEBUG("NOP");
14178 return;
14179 }
14180
14181 t0 = tcg_temp_new();
14182 t1 = tcg_temp_new();
14183 v1_t = tcg_temp_new();
14184 v2_t = tcg_temp_new();
14185
14186 gen_load_gpr(v1_t, v1);
14187 gen_load_gpr(v2_t, v2);
14188
14189 switch (op1) {
14190 case OPC_EXTR_W_DSP:
14191 check_dsp(ctx);
14192 switch (op2) {
14193 case OPC_EXTR_W:
14194 tcg_gen_movi_tl(t0, v2);
14195 tcg_gen_movi_tl(t1, v1);
14196 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14197 break;
14198 case OPC_EXTR_R_W:
14199 tcg_gen_movi_tl(t0, v2);
14200 tcg_gen_movi_tl(t1, v1);
14201 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14202 break;
14203 case OPC_EXTR_RS_W:
14204 tcg_gen_movi_tl(t0, v2);
14205 tcg_gen_movi_tl(t1, v1);
14206 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14207 break;
14208 case OPC_EXTR_S_H:
14209 tcg_gen_movi_tl(t0, v2);
14210 tcg_gen_movi_tl(t1, v1);
14211 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14212 break;
14213 case OPC_EXTRV_S_H:
14214 tcg_gen_movi_tl(t0, v2);
14215 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14216 break;
14217 case OPC_EXTRV_W:
14218 tcg_gen_movi_tl(t0, v2);
14219 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14220 break;
14221 case OPC_EXTRV_R_W:
14222 tcg_gen_movi_tl(t0, v2);
14223 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14224 break;
14225 case OPC_EXTRV_RS_W:
14226 tcg_gen_movi_tl(t0, v2);
14227 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14228 break;
14229 case OPC_EXTP:
14230 tcg_gen_movi_tl(t0, v2);
14231 tcg_gen_movi_tl(t1, v1);
14232 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14233 break;
14234 case OPC_EXTPV:
14235 tcg_gen_movi_tl(t0, v2);
14236 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14237 break;
14238 case OPC_EXTPDP:
14239 tcg_gen_movi_tl(t0, v2);
14240 tcg_gen_movi_tl(t1, v1);
14241 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14242 break;
14243 case OPC_EXTPDPV:
14244 tcg_gen_movi_tl(t0, v2);
14245 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14246 break;
14247 case OPC_SHILO:
14248 imm = (ctx->opcode >> 20) & 0x3F;
14249 tcg_gen_movi_tl(t0, ret);
14250 tcg_gen_movi_tl(t1, imm);
14251 gen_helper_shilo(t0, t1, cpu_env);
14252 break;
14253 case OPC_SHILOV:
14254 tcg_gen_movi_tl(t0, ret);
14255 gen_helper_shilo(t0, v1_t, cpu_env);
14256 break;
14257 case OPC_MTHLIP:
14258 tcg_gen_movi_tl(t0, ret);
14259 gen_helper_mthlip(t0, v1_t, cpu_env);
14260 break;
14261 case OPC_WRDSP:
14262 imm = (ctx->opcode >> 11) & 0x3FF;
14263 tcg_gen_movi_tl(t0, imm);
14264 gen_helper_wrdsp(v1_t, t0, cpu_env);
14265 break;
14266 case OPC_RDDSP:
14267 imm = (ctx->opcode >> 16) & 0x03FF;
14268 tcg_gen_movi_tl(t0, imm);
14269 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14270 break;
14271 }
14272 break;
14273 #ifdef TARGET_MIPS64
14274 case OPC_DEXTR_W_DSP:
14275 check_dsp(ctx);
14276 switch (op2) {
14277 case OPC_DMTHLIP:
14278 tcg_gen_movi_tl(t0, ret);
14279 gen_helper_dmthlip(v1_t, t0, cpu_env);
14280 break;
14281 case OPC_DSHILO:
14282 {
14283 int shift = (ctx->opcode >> 19) & 0x7F;
14284 int ac = (ctx->opcode >> 11) & 0x03;
14285 tcg_gen_movi_tl(t0, shift);
14286 tcg_gen_movi_tl(t1, ac);
14287 gen_helper_dshilo(t0, t1, cpu_env);
14288 break;
14289 }
14290 case OPC_DSHILOV:
14291 {
14292 int ac = (ctx->opcode >> 11) & 0x03;
14293 tcg_gen_movi_tl(t0, ac);
14294 gen_helper_dshilo(v1_t, t0, cpu_env);
14295 break;
14296 }
14297 case OPC_DEXTP:
14298 tcg_gen_movi_tl(t0, v2);
14299 tcg_gen_movi_tl(t1, v1);
14300
14301 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14302 break;
14303 case OPC_DEXTPV:
14304 tcg_gen_movi_tl(t0, v2);
14305 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14306 break;
14307 case OPC_DEXTPDP:
14308 tcg_gen_movi_tl(t0, v2);
14309 tcg_gen_movi_tl(t1, v1);
14310 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14311 break;
14312 case OPC_DEXTPDPV:
14313 tcg_gen_movi_tl(t0, v2);
14314 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14315 break;
14316 case OPC_DEXTR_L:
14317 tcg_gen_movi_tl(t0, v2);
14318 tcg_gen_movi_tl(t1, v1);
14319 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14320 break;
14321 case OPC_DEXTR_R_L:
14322 tcg_gen_movi_tl(t0, v2);
14323 tcg_gen_movi_tl(t1, v1);
14324 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14325 break;
14326 case OPC_DEXTR_RS_L:
14327 tcg_gen_movi_tl(t0, v2);
14328 tcg_gen_movi_tl(t1, v1);
14329 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14330 break;
14331 case OPC_DEXTR_W:
14332 tcg_gen_movi_tl(t0, v2);
14333 tcg_gen_movi_tl(t1, v1);
14334 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14335 break;
14336 case OPC_DEXTR_R_W:
14337 tcg_gen_movi_tl(t0, v2);
14338 tcg_gen_movi_tl(t1, v1);
14339 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14340 break;
14341 case OPC_DEXTR_RS_W:
14342 tcg_gen_movi_tl(t0, v2);
14343 tcg_gen_movi_tl(t1, v1);
14344 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14345 break;
14346 case OPC_DEXTR_S_H:
14347 tcg_gen_movi_tl(t0, v2);
14348 tcg_gen_movi_tl(t1, v1);
14349 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14350 break;
14351 case OPC_DEXTRV_S_H:
14352 tcg_gen_movi_tl(t0, v2);
14353 tcg_gen_movi_tl(t1, v1);
14354 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14355 break;
14356 case OPC_DEXTRV_L:
14357 tcg_gen_movi_tl(t0, v2);
14358 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14359 break;
14360 case OPC_DEXTRV_R_L:
14361 tcg_gen_movi_tl(t0, v2);
14362 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14363 break;
14364 case OPC_DEXTRV_RS_L:
14365 tcg_gen_movi_tl(t0, v2);
14366 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14367 break;
14368 case OPC_DEXTRV_W:
14369 tcg_gen_movi_tl(t0, v2);
14370 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14371 break;
14372 case OPC_DEXTRV_R_W:
14373 tcg_gen_movi_tl(t0, v2);
14374 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14375 break;
14376 case OPC_DEXTRV_RS_W:
14377 tcg_gen_movi_tl(t0, v2);
14378 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14379 break;
14380 }
14381 break;
14382 #endif
14383 }
14384
14385 tcg_temp_free(t0);
14386 tcg_temp_free(t1);
14387 tcg_temp_free(v1_t);
14388 tcg_temp_free(v2_t);
14389
14390 (void)opn; /* avoid a compiler warning */
14391 MIPS_DEBUG("%s", opn);
14392 }
14393
14394 /* End MIPSDSP functions. */
14395
14396 static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
14397 {
14398 int32_t offset;
14399 int rs, rt, rd, sa;
14400 uint32_t op, op1, op2;
14401 int16_t imm;
14402
14403 /* make sure instructions are on a word boundary */
14404 if (ctx->pc & 0x3) {
14405 env->CP0_BadVAddr = ctx->pc;
14406 generate_exception(ctx, EXCP_AdEL);
14407 return;
14408 }
14409
14410 /* Handle blikely not taken case */
14411 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14412 int l1 = gen_new_label();
14413
14414 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14415 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14416 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14417 gen_goto_tb(ctx, 1, ctx->pc + 4);
14418 gen_set_label(l1);
14419 }
14420
14421 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14422 tcg_gen_debug_insn_start(ctx->pc);
14423 }
14424
14425 op = MASK_OP_MAJOR(ctx->opcode);
14426 rs = (ctx->opcode >> 21) & 0x1f;
14427 rt = (ctx->opcode >> 16) & 0x1f;
14428 rd = (ctx->opcode >> 11) & 0x1f;
14429 sa = (ctx->opcode >> 6) & 0x1f;
14430 imm = (int16_t)ctx->opcode;
14431 switch (op) {
14432 case OPC_SPECIAL:
14433 op1 = MASK_SPECIAL(ctx->opcode);
14434 switch (op1) {
14435 case OPC_SLL: /* Shift with immediate */
14436 case OPC_SRA:
14437 gen_shift_imm(ctx, op1, rd, rt, sa);
14438 break;
14439 case OPC_SRL:
14440 switch ((ctx->opcode >> 21) & 0x1f) {
14441 case 1:
14442 /* rotr is decoded as srl on non-R2 CPUs */
14443 if (ctx->insn_flags & ISA_MIPS32R2) {
14444 op1 = OPC_ROTR;
14445 }
14446 /* Fallthrough */
14447 case 0:
14448 gen_shift_imm(ctx, op1, rd, rt, sa);
14449 break;
14450 default:
14451 generate_exception(ctx, EXCP_RI);
14452 break;
14453 }
14454 break;
14455 case OPC_MOVN: /* Conditional move */
14456 case OPC_MOVZ:
14457 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14458 INSN_LOONGSON2E | INSN_LOONGSON2F);
14459 gen_cond_move(ctx, op1, rd, rs, rt);
14460 break;
14461 case OPC_ADD ... OPC_SUBU:
14462 gen_arith(ctx, op1, rd, rs, rt);
14463 break;
14464 case OPC_SLLV: /* Shifts */
14465 case OPC_SRAV:
14466 gen_shift(ctx, op1, rd, rs, rt);
14467 break;
14468 case OPC_SRLV:
14469 switch ((ctx->opcode >> 6) & 0x1f) {
14470 case 1:
14471 /* rotrv is decoded as srlv on non-R2 CPUs */
14472 if (ctx->insn_flags & ISA_MIPS32R2) {
14473 op1 = OPC_ROTRV;
14474 }
14475 /* Fallthrough */
14476 case 0:
14477 gen_shift(ctx, op1, rd, rs, rt);
14478 break;
14479 default:
14480 generate_exception(ctx, EXCP_RI);
14481 break;
14482 }
14483 break;
14484 case OPC_SLT: /* Set on less than */
14485 case OPC_SLTU:
14486 gen_slt(ctx, op1, rd, rs, rt);
14487 break;
14488 case OPC_AND: /* Logic*/
14489 case OPC_OR:
14490 case OPC_NOR:
14491 case OPC_XOR:
14492 gen_logic(ctx, op1, rd, rs, rt);
14493 break;
14494 case OPC_MULT:
14495 case OPC_MULTU:
14496 if (sa) {
14497 check_insn(ctx, INSN_VR54XX);
14498 op1 = MASK_MUL_VR54XX(ctx->opcode);
14499 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14500 } else {
14501 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14502 }
14503 break;
14504 case OPC_DIV:
14505 case OPC_DIVU:
14506 gen_muldiv(ctx, op1, 0, rs, rt);
14507 break;
14508 case OPC_JR ... OPC_JALR:
14509 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14510 break;
14511 case OPC_TGE ... OPC_TEQ: /* Traps */
14512 case OPC_TNE:
14513 gen_trap(ctx, op1, rs, rt, -1);
14514 break;
14515 case OPC_MFHI: /* Move from HI/LO */
14516 case OPC_MFLO:
14517 gen_HILO(ctx, op1, rs & 3, rd);
14518 break;
14519 case OPC_MTHI:
14520 case OPC_MTLO: /* Move to HI/LO */
14521 gen_HILO(ctx, op1, rd & 3, rs);
14522 break;
14523 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14524 #ifdef MIPS_STRICT_STANDARD
14525 MIPS_INVAL("PMON / selsl");
14526 generate_exception(ctx, EXCP_RI);
14527 #else
14528 gen_helper_0e0i(pmon, sa);
14529 #endif
14530 break;
14531 case OPC_SYSCALL:
14532 generate_exception(ctx, EXCP_SYSCALL);
14533 ctx->bstate = BS_STOP;
14534 break;
14535 case OPC_BREAK:
14536 generate_exception(ctx, EXCP_BREAK);
14537 break;
14538 case OPC_SPIM:
14539 #ifdef MIPS_STRICT_STANDARD
14540 MIPS_INVAL("SPIM");
14541 generate_exception(ctx, EXCP_RI);
14542 #else
14543 /* Implemented as RI exception for now. */
14544 MIPS_INVAL("spim (unofficial)");
14545 generate_exception(ctx, EXCP_RI);
14546 #endif
14547 break;
14548 case OPC_SYNC:
14549 /* Treat as NOP. */
14550 break;
14551
14552 case OPC_MOVCI:
14553 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14554 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14555 check_cp1_enabled(ctx);
14556 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14557 (ctx->opcode >> 16) & 1);
14558 } else {
14559 generate_exception_err(ctx, EXCP_CpU, 1);
14560 }
14561 break;
14562
14563 #if defined(TARGET_MIPS64)
14564 /* MIPS64 specific opcodes */
14565 case OPC_DSLL:
14566 case OPC_DSRA:
14567 case OPC_DSLL32:
14568 case OPC_DSRA32:
14569 check_insn(ctx, ISA_MIPS3);
14570 check_mips_64(ctx);
14571 gen_shift_imm(ctx, op1, rd, rt, sa);
14572 break;
14573 case OPC_DSRL:
14574 switch ((ctx->opcode >> 21) & 0x1f) {
14575 case 1:
14576 /* drotr is decoded as dsrl on non-R2 CPUs */
14577 if (ctx->insn_flags & ISA_MIPS32R2) {
14578 op1 = OPC_DROTR;
14579 }
14580 /* Fallthrough */
14581 case 0:
14582 check_insn(ctx, ISA_MIPS3);
14583 check_mips_64(ctx);
14584 gen_shift_imm(ctx, op1, rd, rt, sa);
14585 break;
14586 default:
14587 generate_exception(ctx, EXCP_RI);
14588 break;
14589 }
14590 break;
14591 case OPC_DSRL32:
14592 switch ((ctx->opcode >> 21) & 0x1f) {
14593 case 1:
14594 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14595 if (ctx->insn_flags & ISA_MIPS32R2) {
14596 op1 = OPC_DROTR32;
14597 }
14598 /* Fallthrough */
14599 case 0:
14600 check_insn(ctx, ISA_MIPS3);
14601 check_mips_64(ctx);
14602 gen_shift_imm(ctx, op1, rd, rt, sa);
14603 break;
14604 default:
14605 generate_exception(ctx, EXCP_RI);
14606 break;
14607 }
14608 break;
14609 case OPC_DADD ... OPC_DSUBU:
14610 check_insn(ctx, ISA_MIPS3);
14611 check_mips_64(ctx);
14612 gen_arith(ctx, op1, rd, rs, rt);
14613 break;
14614 case OPC_DSLLV:
14615 case OPC_DSRAV:
14616 check_insn(ctx, ISA_MIPS3);
14617 check_mips_64(ctx);
14618 gen_shift(ctx, op1, rd, rs, rt);
14619 break;
14620 case OPC_DSRLV:
14621 switch ((ctx->opcode >> 6) & 0x1f) {
14622 case 1:
14623 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14624 if (ctx->insn_flags & ISA_MIPS32R2) {
14625 op1 = OPC_DROTRV;
14626 }
14627 /* Fallthrough */
14628 case 0:
14629 check_insn(ctx, ISA_MIPS3);
14630 check_mips_64(ctx);
14631 gen_shift(ctx, op1, rd, rs, rt);
14632 break;
14633 default:
14634 generate_exception(ctx, EXCP_RI);
14635 break;
14636 }
14637 break;
14638 case OPC_DMULT ... OPC_DDIVU:
14639 check_insn(ctx, ISA_MIPS3);
14640 check_mips_64(ctx);
14641 gen_muldiv(ctx, op1, 0, rs, rt);
14642 break;
14643 #endif
14644 default: /* Invalid */
14645 MIPS_INVAL("special");
14646 generate_exception(ctx, EXCP_RI);
14647 break;
14648 }
14649 break;
14650 case OPC_SPECIAL2:
14651 op1 = MASK_SPECIAL2(ctx->opcode);
14652 switch (op1) {
14653 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14654 case OPC_MSUB ... OPC_MSUBU:
14655 check_insn(ctx, ISA_MIPS32);
14656 gen_muldiv(ctx, op1, rd & 3, rs, rt);
14657 break;
14658 case OPC_MUL:
14659 gen_arith(ctx, op1, rd, rs, rt);
14660 break;
14661 case OPC_CLO:
14662 case OPC_CLZ:
14663 check_insn(ctx, ISA_MIPS32);
14664 gen_cl(ctx, op1, rd, rs);
14665 break;
14666 case OPC_SDBBP:
14667 /* XXX: not clear which exception should be raised
14668 * when in debug mode...
14669 */
14670 check_insn(ctx, ISA_MIPS32);
14671 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14672 generate_exception(ctx, EXCP_DBp);
14673 } else {
14674 generate_exception(ctx, EXCP_DBp);
14675 }
14676 /* Treat as NOP. */
14677 break;
14678 case OPC_DIV_G_2F:
14679 case OPC_DIVU_G_2F:
14680 case OPC_MULT_G_2F:
14681 case OPC_MULTU_G_2F:
14682 case OPC_MOD_G_2F:
14683 case OPC_MODU_G_2F:
14684 check_insn(ctx, INSN_LOONGSON2F);
14685 gen_loongson_integer(ctx, op1, rd, rs, rt);
14686 break;
14687 #if defined(TARGET_MIPS64)
14688 case OPC_DCLO:
14689 case OPC_DCLZ:
14690 check_insn(ctx, ISA_MIPS64);
14691 check_mips_64(ctx);
14692 gen_cl(ctx, op1, rd, rs);
14693 break;
14694 case OPC_DMULT_G_2F:
14695 case OPC_DMULTU_G_2F:
14696 case OPC_DDIV_G_2F:
14697 case OPC_DDIVU_G_2F:
14698 case OPC_DMOD_G_2F:
14699 case OPC_DMODU_G_2F:
14700 check_insn(ctx, INSN_LOONGSON2F);
14701 gen_loongson_integer(ctx, op1, rd, rs, rt);
14702 break;
14703 #endif
14704 default: /* Invalid */
14705 MIPS_INVAL("special2");
14706 generate_exception(ctx, EXCP_RI);
14707 break;
14708 }
14709 break;
14710 case OPC_SPECIAL3:
14711 op1 = MASK_SPECIAL3(ctx->opcode);
14712 switch (op1) {
14713 case OPC_EXT:
14714 case OPC_INS:
14715 check_insn(ctx, ISA_MIPS32R2);
14716 gen_bitops(ctx, op1, rt, rs, sa, rd);
14717 break;
14718 case OPC_BSHFL:
14719 check_insn(ctx, ISA_MIPS32R2);
14720 op2 = MASK_BSHFL(ctx->opcode);
14721 gen_bshfl(ctx, op2, rt, rd);
14722 break;
14723 case OPC_RDHWR:
14724 gen_rdhwr(ctx, rt, rd);
14725 break;
14726 case OPC_FORK:
14727 check_insn(ctx, ASE_MT);
14728 {
14729 TCGv t0 = tcg_temp_new();
14730 TCGv t1 = tcg_temp_new();
14731
14732 gen_load_gpr(t0, rt);
14733 gen_load_gpr(t1, rs);
14734 gen_helper_fork(t0, t1);
14735 tcg_temp_free(t0);
14736 tcg_temp_free(t1);
14737 }
14738 break;
14739 case OPC_YIELD:
14740 check_insn(ctx, ASE_MT);
14741 {
14742 TCGv t0 = tcg_temp_new();
14743
14744 save_cpu_state(ctx, 1);
14745 gen_load_gpr(t0, rs);
14746 gen_helper_yield(t0, cpu_env, t0);
14747 gen_store_gpr(t0, rd);
14748 tcg_temp_free(t0);
14749 }
14750 break;
14751 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14752 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14753 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14754 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14755 * the same mask and op1. */
14756 if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14757 op2 = MASK_ADDUH_QB(ctx->opcode);
14758 switch (op2) {
14759 case OPC_ADDUH_QB:
14760 case OPC_ADDUH_R_QB:
14761 case OPC_ADDQH_PH:
14762 case OPC_ADDQH_R_PH:
14763 case OPC_ADDQH_W:
14764 case OPC_ADDQH_R_W:
14765 case OPC_SUBUH_QB:
14766 case OPC_SUBUH_R_QB:
14767 case OPC_SUBQH_PH:
14768 case OPC_SUBQH_R_PH:
14769 case OPC_SUBQH_W:
14770 case OPC_SUBQH_R_W:
14771 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14772 break;
14773 case OPC_MUL_PH:
14774 case OPC_MUL_S_PH:
14775 case OPC_MULQ_S_W:
14776 case OPC_MULQ_RS_W:
14777 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14778 break;
14779 default:
14780 MIPS_INVAL("MASK ADDUH.QB");
14781 generate_exception(ctx, EXCP_RI);
14782 break;
14783 }
14784 } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14785 gen_loongson_integer(ctx, op1, rd, rs, rt);
14786 } else {
14787 generate_exception(ctx, EXCP_RI);
14788 }
14789 break;
14790 case OPC_LX_DSP:
14791 op2 = MASK_LX(ctx->opcode);
14792 switch (op2) {
14793 #if defined(TARGET_MIPS64)
14794 case OPC_LDX:
14795 #endif
14796 case OPC_LBUX:
14797 case OPC_LHX:
14798 case OPC_LWX:
14799 gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14800 break;
14801 default: /* Invalid */
14802 MIPS_INVAL("MASK LX");
14803 generate_exception(ctx, EXCP_RI);
14804 break;
14805 }
14806 break;
14807 case OPC_ABSQ_S_PH_DSP:
14808 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14809 switch (op2) {
14810 case OPC_ABSQ_S_QB:
14811 case OPC_ABSQ_S_PH:
14812 case OPC_ABSQ_S_W:
14813 case OPC_PRECEQ_W_PHL:
14814 case OPC_PRECEQ_W_PHR:
14815 case OPC_PRECEQU_PH_QBL:
14816 case OPC_PRECEQU_PH_QBR:
14817 case OPC_PRECEQU_PH_QBLA:
14818 case OPC_PRECEQU_PH_QBRA:
14819 case OPC_PRECEU_PH_QBL:
14820 case OPC_PRECEU_PH_QBR:
14821 case OPC_PRECEU_PH_QBLA:
14822 case OPC_PRECEU_PH_QBRA:
14823 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14824 break;
14825 case OPC_BITREV:
14826 case OPC_REPL_QB:
14827 case OPC_REPLV_QB:
14828 case OPC_REPL_PH:
14829 case OPC_REPLV_PH:
14830 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14831 break;
14832 default:
14833 MIPS_INVAL("MASK ABSQ_S.PH");
14834 generate_exception(ctx, EXCP_RI);
14835 break;
14836 }
14837 break;
14838 case OPC_ADDU_QB_DSP:
14839 op2 = MASK_ADDU_QB(ctx->opcode);
14840 switch (op2) {
14841 case OPC_ADDQ_PH:
14842 case OPC_ADDQ_S_PH:
14843 case OPC_ADDQ_S_W:
14844 case OPC_ADDU_QB:
14845 case OPC_ADDU_S_QB:
14846 case OPC_ADDU_PH:
14847 case OPC_ADDU_S_PH:
14848 case OPC_SUBQ_PH:
14849 case OPC_SUBQ_S_PH:
14850 case OPC_SUBQ_S_W:
14851 case OPC_SUBU_QB:
14852 case OPC_SUBU_S_QB:
14853 case OPC_SUBU_PH:
14854 case OPC_SUBU_S_PH:
14855 case OPC_ADDSC:
14856 case OPC_ADDWC:
14857 case OPC_MODSUB:
14858 case OPC_RADDU_W_QB:
14859 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14860 break;
14861 case OPC_MULEU_S_PH_QBL:
14862 case OPC_MULEU_S_PH_QBR:
14863 case OPC_MULQ_RS_PH:
14864 case OPC_MULEQ_S_W_PHL:
14865 case OPC_MULEQ_S_W_PHR:
14866 case OPC_MULQ_S_PH:
14867 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14868 break;
14869 default: /* Invalid */
14870 MIPS_INVAL("MASK ADDU.QB");
14871 generate_exception(ctx, EXCP_RI);
14872 break;
14873
14874 }
14875 break;
14876 case OPC_CMPU_EQ_QB_DSP:
14877 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14878 switch (op2) {
14879 case OPC_PRECR_SRA_PH_W:
14880 case OPC_PRECR_SRA_R_PH_W:
14881 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14882 break;
14883 case OPC_PRECR_QB_PH:
14884 case OPC_PRECRQ_QB_PH:
14885 case OPC_PRECRQ_PH_W:
14886 case OPC_PRECRQ_RS_PH_W:
14887 case OPC_PRECRQU_S_QB_PH:
14888 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14889 break;
14890 case OPC_CMPU_EQ_QB:
14891 case OPC_CMPU_LT_QB:
14892 case OPC_CMPU_LE_QB:
14893 case OPC_CMP_EQ_PH:
14894 case OPC_CMP_LT_PH:
14895 case OPC_CMP_LE_PH:
14896 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14897 break;
14898 case OPC_CMPGU_EQ_QB:
14899 case OPC_CMPGU_LT_QB:
14900 case OPC_CMPGU_LE_QB:
14901 case OPC_CMPGDU_EQ_QB:
14902 case OPC_CMPGDU_LT_QB:
14903 case OPC_CMPGDU_LE_QB:
14904 case OPC_PICK_QB:
14905 case OPC_PICK_PH:
14906 case OPC_PACKRL_PH:
14907 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14908 break;
14909 default: /* Invalid */
14910 MIPS_INVAL("MASK CMPU.EQ.QB");
14911 generate_exception(ctx, EXCP_RI);
14912 break;
14913 }
14914 break;
14915 case OPC_SHLL_QB_DSP:
14916 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14917 break;
14918 case OPC_DPA_W_PH_DSP:
14919 op2 = MASK_DPA_W_PH(ctx->opcode);
14920 switch (op2) {
14921 case OPC_DPAU_H_QBL:
14922 case OPC_DPAU_H_QBR:
14923 case OPC_DPSU_H_QBL:
14924 case OPC_DPSU_H_QBR:
14925 case OPC_DPA_W_PH:
14926 case OPC_DPAX_W_PH:
14927 case OPC_DPAQ_S_W_PH:
14928 case OPC_DPAQX_S_W_PH:
14929 case OPC_DPAQX_SA_W_PH:
14930 case OPC_DPS_W_PH:
14931 case OPC_DPSX_W_PH:
14932 case OPC_DPSQ_S_W_PH:
14933 case OPC_DPSQX_S_W_PH:
14934 case OPC_DPSQX_SA_W_PH:
14935 case OPC_MULSAQ_S_W_PH:
14936 case OPC_DPAQ_SA_L_W:
14937 case OPC_DPSQ_SA_L_W:
14938 case OPC_MAQ_S_W_PHL:
14939 case OPC_MAQ_S_W_PHR:
14940 case OPC_MAQ_SA_W_PHL:
14941 case OPC_MAQ_SA_W_PHR:
14942 case OPC_MULSA_W_PH:
14943 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14944 break;
14945 default: /* Invalid */
14946 MIPS_INVAL("MASK DPAW.PH");
14947 generate_exception(ctx, EXCP_RI);
14948 break;
14949 }
14950 break;
14951 case OPC_INSV_DSP:
14952 op2 = MASK_INSV(ctx->opcode);
14953 switch (op2) {
14954 case OPC_INSV:
14955 check_dsp(ctx);
14956 {
14957 TCGv t0, t1;
14958
14959 if (rt == 0) {
14960 MIPS_DEBUG("NOP");
14961 break;
14962 }
14963
14964 t0 = tcg_temp_new();
14965 t1 = tcg_temp_new();
14966
14967 gen_load_gpr(t0, rt);
14968 gen_load_gpr(t1, rs);
14969
14970 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14971
14972 tcg_temp_free(t0);
14973 tcg_temp_free(t1);
14974 break;
14975 }
14976 default: /* Invalid */
14977 MIPS_INVAL("MASK INSV");
14978 generate_exception(ctx, EXCP_RI);
14979 break;
14980 }
14981 break;
14982 case OPC_APPEND_DSP:
14983 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14984 break;
14985 case OPC_EXTR_W_DSP:
14986 op2 = MASK_EXTR_W(ctx->opcode);
14987 switch (op2) {
14988 case OPC_EXTR_W:
14989 case OPC_EXTR_R_W:
14990 case OPC_EXTR_RS_W:
14991 case OPC_EXTR_S_H:
14992 case OPC_EXTRV_S_H:
14993 case OPC_EXTRV_W:
14994 case OPC_EXTRV_R_W:
14995 case OPC_EXTRV_RS_W:
14996 case OPC_EXTP:
14997 case OPC_EXTPV:
14998 case OPC_EXTPDP:
14999 case OPC_EXTPDPV:
15000 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15001 break;
15002 case OPC_RDDSP:
15003 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
15004 break;
15005 case OPC_SHILO:
15006 case OPC_SHILOV:
15007 case OPC_MTHLIP:
15008 case OPC_WRDSP:
15009 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15010 break;
15011 default: /* Invalid */
15012 MIPS_INVAL("MASK EXTR.W");
15013 generate_exception(ctx, EXCP_RI);
15014 break;
15015 }
15016 break;
15017 #if defined(TARGET_MIPS64)
15018 case OPC_DEXTM ... OPC_DEXT:
15019 case OPC_DINSM ... OPC_DINS:
15020 check_insn(ctx, ISA_MIPS64R2);
15021 check_mips_64(ctx);
15022 gen_bitops(ctx, op1, rt, rs, sa, rd);
15023 break;
15024 case OPC_DBSHFL:
15025 check_insn(ctx, ISA_MIPS64R2);
15026 check_mips_64(ctx);
15027 op2 = MASK_DBSHFL(ctx->opcode);
15028 gen_bshfl(ctx, op2, rt, rd);
15029 break;
15030 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15031 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15032 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15033 check_insn(ctx, INSN_LOONGSON2E);
15034 gen_loongson_integer(ctx, op1, rd, rs, rt);
15035 break;
15036 case OPC_ABSQ_S_QH_DSP:
15037 op2 = MASK_ABSQ_S_QH(ctx->opcode);
15038 switch (op2) {
15039 case OPC_PRECEQ_L_PWL:
15040 case OPC_PRECEQ_L_PWR:
15041 case OPC_PRECEQ_PW_QHL:
15042 case OPC_PRECEQ_PW_QHR:
15043 case OPC_PRECEQ_PW_QHLA:
15044 case OPC_PRECEQ_PW_QHRA:
15045 case OPC_PRECEQU_QH_OBL:
15046 case OPC_PRECEQU_QH_OBR:
15047 case OPC_PRECEQU_QH_OBLA:
15048 case OPC_PRECEQU_QH_OBRA:
15049 case OPC_PRECEU_QH_OBL:
15050 case OPC_PRECEU_QH_OBR:
15051 case OPC_PRECEU_QH_OBLA:
15052 case OPC_PRECEU_QH_OBRA:
15053 case OPC_ABSQ_S_OB:
15054 case OPC_ABSQ_S_PW:
15055 case OPC_ABSQ_S_QH:
15056 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15057 break;
15058 case OPC_REPL_OB:
15059 case OPC_REPL_PW:
15060 case OPC_REPL_QH:
15061 case OPC_REPLV_OB:
15062 case OPC_REPLV_PW:
15063 case OPC_REPLV_QH:
15064 gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15065 break;
15066 default: /* Invalid */
15067 MIPS_INVAL("MASK ABSQ_S.QH");
15068 generate_exception(ctx, EXCP_RI);
15069 break;
15070 }
15071 break;
15072 case OPC_ADDU_OB_DSP:
15073 op2 = MASK_ADDU_OB(ctx->opcode);
15074 switch (op2) {
15075 case OPC_RADDU_L_OB:
15076 case OPC_SUBQ_PW:
15077 case OPC_SUBQ_S_PW:
15078 case OPC_SUBQ_QH:
15079 case OPC_SUBQ_S_QH:
15080 case OPC_SUBU_OB:
15081 case OPC_SUBU_S_OB:
15082 case OPC_SUBU_QH:
15083 case OPC_SUBU_S_QH:
15084 case OPC_SUBUH_OB:
15085 case OPC_SUBUH_R_OB:
15086 case OPC_ADDQ_PW:
15087 case OPC_ADDQ_S_PW:
15088 case OPC_ADDQ_QH:
15089 case OPC_ADDQ_S_QH:
15090 case OPC_ADDU_OB:
15091 case OPC_ADDU_S_OB:
15092 case OPC_ADDU_QH:
15093 case OPC_ADDU_S_QH:
15094 case OPC_ADDUH_OB:
15095 case OPC_ADDUH_R_OB:
15096 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15097 break;
15098 case OPC_MULEQ_S_PW_QHL:
15099 case OPC_MULEQ_S_PW_QHR:
15100 case OPC_MULEU_S_QH_OBL:
15101 case OPC_MULEU_S_QH_OBR:
15102 case OPC_MULQ_RS_QH:
15103 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15104 break;
15105 default: /* Invalid */
15106 MIPS_INVAL("MASK ADDU.OB");
15107 generate_exception(ctx, EXCP_RI);
15108 break;
15109 }
15110 break;
15111 case OPC_CMPU_EQ_OB_DSP:
15112 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15113 switch (op2) {
15114 case OPC_PRECR_SRA_QH_PW:
15115 case OPC_PRECR_SRA_R_QH_PW:
15116 /* Return value is rt. */
15117 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15118 break;
15119 case OPC_PRECR_OB_QH:
15120 case OPC_PRECRQ_OB_QH:
15121 case OPC_PRECRQ_PW_L:
15122 case OPC_PRECRQ_QH_PW:
15123 case OPC_PRECRQ_RS_QH_PW:
15124 case OPC_PRECRQU_S_OB_QH:
15125 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15126 break;
15127 case OPC_CMPU_EQ_OB:
15128 case OPC_CMPU_LT_OB:
15129 case OPC_CMPU_LE_OB:
15130 case OPC_CMP_EQ_QH:
15131 case OPC_CMP_LT_QH:
15132 case OPC_CMP_LE_QH:
15133 case OPC_CMP_EQ_PW:
15134 case OPC_CMP_LT_PW:
15135 case OPC_CMP_LE_PW:
15136 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15137 break;
15138 case OPC_CMPGDU_EQ_OB:
15139 case OPC_CMPGDU_LT_OB:
15140 case OPC_CMPGDU_LE_OB:
15141 case OPC_CMPGU_EQ_OB:
15142 case OPC_CMPGU_LT_OB:
15143 case OPC_CMPGU_LE_OB:
15144 case OPC_PACKRL_PW:
15145 case OPC_PICK_OB:
15146 case OPC_PICK_PW:
15147 case OPC_PICK_QH:
15148 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15149 break;
15150 default: /* Invalid */
15151 MIPS_INVAL("MASK CMPU_EQ.OB");
15152 generate_exception(ctx, EXCP_RI);
15153 break;
15154 }
15155 break;
15156 case OPC_DAPPEND_DSP:
15157 gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15158 break;
15159 case OPC_DEXTR_W_DSP:
15160 op2 = MASK_DEXTR_W(ctx->opcode);
15161 switch (op2) {
15162 case OPC_DEXTP:
15163 case OPC_DEXTPDP:
15164 case OPC_DEXTPDPV:
15165 case OPC_DEXTPV:
15166 case OPC_DEXTR_L:
15167 case OPC_DEXTR_R_L:
15168 case OPC_DEXTR_RS_L:
15169 case OPC_DEXTR_W:
15170 case OPC_DEXTR_R_W:
15171 case OPC_DEXTR_RS_W:
15172 case OPC_DEXTR_S_H:
15173 case OPC_DEXTRV_L:
15174 case OPC_DEXTRV_R_L:
15175 case OPC_DEXTRV_RS_L:
15176 case OPC_DEXTRV_S_H:
15177 case OPC_DEXTRV_W:
15178 case OPC_DEXTRV_R_W:
15179 case OPC_DEXTRV_RS_W:
15180 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15181 break;
15182 case OPC_DMTHLIP:
15183 case OPC_DSHILO:
15184 case OPC_DSHILOV:
15185 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15186 break;
15187 default: /* Invalid */
15188 MIPS_INVAL("MASK EXTR.W");
15189 generate_exception(ctx, EXCP_RI);
15190 break;
15191 }
15192 break;
15193 case OPC_DPAQ_W_QH_DSP:
15194 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15195 switch (op2) {
15196 case OPC_DPAU_H_OBL:
15197 case OPC_DPAU_H_OBR:
15198 case OPC_DPSU_H_OBL:
15199 case OPC_DPSU_H_OBR:
15200 case OPC_DPA_W_QH:
15201 case OPC_DPAQ_S_W_QH:
15202 case OPC_DPS_W_QH:
15203 case OPC_DPSQ_S_W_QH:
15204 case OPC_MULSAQ_S_W_QH:
15205 case OPC_DPAQ_SA_L_PW:
15206 case OPC_DPSQ_SA_L_PW:
15207 case OPC_MULSAQ_S_L_PW:
15208 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15209 break;
15210 case OPC_MAQ_S_W_QHLL:
15211 case OPC_MAQ_S_W_QHLR:
15212 case OPC_MAQ_S_W_QHRL:
15213 case OPC_MAQ_S_W_QHRR:
15214 case OPC_MAQ_SA_W_QHLL:
15215 case OPC_MAQ_SA_W_QHLR:
15216 case OPC_MAQ_SA_W_QHRL:
15217 case OPC_MAQ_SA_W_QHRR:
15218 case OPC_MAQ_S_L_PWL:
15219 case OPC_MAQ_S_L_PWR:
15220 case OPC_DMADD:
15221 case OPC_DMADDU:
15222 case OPC_DMSUB:
15223 case OPC_DMSUBU:
15224 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15225 break;
15226 default: /* Invalid */
15227 MIPS_INVAL("MASK DPAQ.W.QH");
15228 generate_exception(ctx, EXCP_RI);
15229 break;
15230 }
15231 break;
15232 case OPC_DINSV_DSP:
15233 op2 = MASK_INSV(ctx->opcode);
15234 switch (op2) {
15235 case OPC_DINSV:
15236 {
15237 TCGv t0, t1;
15238
15239 if (rt == 0) {
15240 MIPS_DEBUG("NOP");
15241 break;
15242 }
15243 check_dsp(ctx);
15244
15245 t0 = tcg_temp_new();
15246 t1 = tcg_temp_new();
15247
15248 gen_load_gpr(t0, rt);
15249 gen_load_gpr(t1, rs);
15250
15251 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15252 break;
15253 }
15254 default: /* Invalid */
15255 MIPS_INVAL("MASK DINSV");
15256 generate_exception(ctx, EXCP_RI);
15257 break;
15258 }
15259 break;
15260 case OPC_SHLL_OB_DSP:
15261 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15262 break;
15263 #endif
15264 default: /* Invalid */
15265 MIPS_INVAL("special3");
15266 generate_exception(ctx, EXCP_RI);
15267 break;
15268 }
15269 break;
15270 case OPC_REGIMM:
15271 op1 = MASK_REGIMM(ctx->opcode);
15272 switch (op1) {
15273 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15274 case OPC_BLTZAL ... OPC_BGEZALL:
15275 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15276 break;
15277 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15278 case OPC_TNEI:
15279 gen_trap(ctx, op1, rs, -1, imm);
15280 break;
15281 case OPC_SYNCI:
15282 check_insn(ctx, ISA_MIPS32R2);
15283 /* Treat as NOP. */
15284 break;
15285 case OPC_BPOSGE32: /* MIPS DSP branch */
15286 #if defined(TARGET_MIPS64)
15287 case OPC_BPOSGE64:
15288 #endif
15289 check_dsp(ctx);
15290 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15291 break;
15292 default: /* Invalid */
15293 MIPS_INVAL("regimm");
15294 generate_exception(ctx, EXCP_RI);
15295 break;
15296 }
15297 break;
15298 case OPC_CP0:
15299 check_cp0_enabled(ctx);
15300 op1 = MASK_CP0(ctx->opcode);
15301 switch (op1) {
15302 case OPC_MFC0:
15303 case OPC_MTC0:
15304 case OPC_MFTR:
15305 case OPC_MTTR:
15306 #if defined(TARGET_MIPS64)
15307 case OPC_DMFC0:
15308 case OPC_DMTC0:
15309 #endif
15310 #ifndef CONFIG_USER_ONLY
15311 gen_cp0(env, ctx, op1, rt, rd);
15312 #endif /* !CONFIG_USER_ONLY */
15313 break;
15314 case OPC_C0_FIRST ... OPC_C0_LAST:
15315 #ifndef CONFIG_USER_ONLY
15316 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15317 #endif /* !CONFIG_USER_ONLY */
15318 break;
15319 case OPC_MFMC0:
15320 #ifndef CONFIG_USER_ONLY
15321 {
15322 TCGv t0 = tcg_temp_new();
15323
15324 op2 = MASK_MFMC0(ctx->opcode);
15325 switch (op2) {
15326 case OPC_DMT:
15327 check_insn(ctx, ASE_MT);
15328 gen_helper_dmt(t0);
15329 gen_store_gpr(t0, rt);
15330 break;
15331 case OPC_EMT:
15332 check_insn(ctx, ASE_MT);
15333 gen_helper_emt(t0);
15334 gen_store_gpr(t0, rt);
15335 break;
15336 case OPC_DVPE:
15337 check_insn(ctx, ASE_MT);
15338 gen_helper_dvpe(t0, cpu_env);
15339 gen_store_gpr(t0, rt);
15340 break;
15341 case OPC_EVPE:
15342 check_insn(ctx, ASE_MT);
15343 gen_helper_evpe(t0, cpu_env);
15344 gen_store_gpr(t0, rt);
15345 break;
15346 case OPC_DI:
15347 check_insn(ctx, ISA_MIPS32R2);
15348 save_cpu_state(ctx, 1);
15349 gen_helper_di(t0, cpu_env);
15350 gen_store_gpr(t0, rt);
15351 /* Stop translation as we may have switched the execution mode */
15352 ctx->bstate = BS_STOP;
15353 break;
15354 case OPC_EI:
15355 check_insn(ctx, ISA_MIPS32R2);
15356 save_cpu_state(ctx, 1);
15357 gen_helper_ei(t0, cpu_env);
15358 gen_store_gpr(t0, rt);
15359 /* Stop translation as we may have switched the execution mode */
15360 ctx->bstate = BS_STOP;
15361 break;
15362 default: /* Invalid */
15363 MIPS_INVAL("mfmc0");
15364 generate_exception(ctx, EXCP_RI);
15365 break;
15366 }
15367 tcg_temp_free(t0);
15368 }
15369 #endif /* !CONFIG_USER_ONLY */
15370 break;
15371 case OPC_RDPGPR:
15372 check_insn(ctx, ISA_MIPS32R2);
15373 gen_load_srsgpr(rt, rd);
15374 break;
15375 case OPC_WRPGPR:
15376 check_insn(ctx, ISA_MIPS32R2);
15377 gen_store_srsgpr(rt, rd);
15378 break;
15379 default:
15380 MIPS_INVAL("cp0");
15381 generate_exception(ctx, EXCP_RI);
15382 break;
15383 }
15384 break;
15385 case OPC_ADDI: /* Arithmetic with immediate opcode */
15386 case OPC_ADDIU:
15387 gen_arith_imm(ctx, op, rt, rs, imm);
15388 break;
15389 case OPC_SLTI: /* Set on less than with immediate opcode */
15390 case OPC_SLTIU:
15391 gen_slt_imm(ctx, op, rt, rs, imm);
15392 break;
15393 case OPC_ANDI: /* Arithmetic with immediate opcode */
15394 case OPC_LUI:
15395 case OPC_ORI:
15396 case OPC_XORI:
15397 gen_logic_imm(ctx, op, rt, rs, imm);
15398 break;
15399 case OPC_J ... OPC_JAL: /* Jump */
15400 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15401 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15402 break;
15403 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15404 case OPC_BEQL ... OPC_BGTZL:
15405 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15406 break;
15407 case OPC_LB ... OPC_LWR: /* Load and stores */
15408 case OPC_LL:
15409 gen_ld(ctx, op, rt, rs, imm);
15410 break;
15411 case OPC_SB ... OPC_SW:
15412 case OPC_SWR:
15413 gen_st(ctx, op, rt, rs, imm);
15414 break;
15415 case OPC_SC:
15416 gen_st_cond(ctx, op, rt, rs, imm);
15417 break;
15418 case OPC_CACHE:
15419 check_cp0_enabled(ctx);
15420 check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
15421 /* Treat as NOP. */
15422 break;
15423 case OPC_PREF:
15424 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15425 /* Treat as NOP. */
15426 break;
15427
15428 /* Floating point (COP1). */
15429 case OPC_LWC1:
15430 case OPC_LDC1:
15431 case OPC_SWC1:
15432 case OPC_SDC1:
15433 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15434 break;
15435
15436 case OPC_CP1:
15437 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15438 check_cp1_enabled(ctx);
15439 op1 = MASK_CP1(ctx->opcode);
15440 switch (op1) {
15441 case OPC_MFHC1:
15442 case OPC_MTHC1:
15443 check_insn(ctx, ISA_MIPS32R2);
15444 case OPC_MFC1:
15445 case OPC_CFC1:
15446 case OPC_MTC1:
15447 case OPC_CTC1:
15448 gen_cp1(ctx, op1, rt, rd);
15449 break;
15450 #if defined(TARGET_MIPS64)
15451 case OPC_DMFC1:
15452 case OPC_DMTC1:
15453 check_insn(ctx, ISA_MIPS3);
15454 gen_cp1(ctx, op1, rt, rd);
15455 break;
15456 #endif
15457 case OPC_BC1ANY2:
15458 case OPC_BC1ANY4:
15459 check_cop1x(ctx);
15460 check_insn(ctx, ASE_MIPS3D);
15461 /* fall through */
15462 case OPC_BC1:
15463 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15464 (rt >> 2) & 0x7, imm << 2);
15465 break;
15466 case OPC_S_FMT:
15467 case OPC_D_FMT:
15468 case OPC_W_FMT:
15469 case OPC_L_FMT:
15470 case OPC_PS_FMT:
15471 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15472 (imm >> 8) & 0x7);
15473 break;
15474 default:
15475 MIPS_INVAL("cp1");
15476 generate_exception (ctx, EXCP_RI);
15477 break;
15478 }
15479 } else {
15480 generate_exception_err(ctx, EXCP_CpU, 1);
15481 }
15482 break;
15483
15484 /* COP2. */
15485 case OPC_LWC2:
15486 case OPC_LDC2:
15487 case OPC_SWC2:
15488 case OPC_SDC2:
15489 /* COP2: Not implemented. */
15490 generate_exception_err(ctx, EXCP_CpU, 2);
15491 break;
15492 case OPC_CP2:
15493 check_insn(ctx, INSN_LOONGSON2F);
15494 /* Note that these instructions use different fields. */
15495 gen_loongson_multimedia(ctx, sa, rd, rt);
15496 break;
15497
15498 case OPC_CP3:
15499 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15500 check_cp1_enabled(ctx);
15501 op1 = MASK_CP3(ctx->opcode);
15502 switch (op1) {
15503 case OPC_LWXC1:
15504 case OPC_LDXC1:
15505 case OPC_LUXC1:
15506 case OPC_SWXC1:
15507 case OPC_SDXC1:
15508 case OPC_SUXC1:
15509 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15510 break;
15511 case OPC_PREFX:
15512 /* Treat as NOP. */
15513 break;
15514 case OPC_ALNV_PS:
15515 case OPC_MADD_S:
15516 case OPC_MADD_D:
15517 case OPC_MADD_PS:
15518 case OPC_MSUB_S:
15519 case OPC_MSUB_D:
15520 case OPC_MSUB_PS:
15521 case OPC_NMADD_S:
15522 case OPC_NMADD_D:
15523 case OPC_NMADD_PS:
15524 case OPC_NMSUB_S:
15525 case OPC_NMSUB_D:
15526 case OPC_NMSUB_PS:
15527 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15528 break;
15529 default:
15530 MIPS_INVAL("cp3");
15531 generate_exception (ctx, EXCP_RI);
15532 break;
15533 }
15534 } else {
15535 generate_exception_err(ctx, EXCP_CpU, 1);
15536 }
15537 break;
15538
15539 #if defined(TARGET_MIPS64)
15540 /* MIPS64 opcodes */
15541 case OPC_LWU:
15542 case OPC_LDL ... OPC_LDR:
15543 case OPC_LLD:
15544 case OPC_LD:
15545 check_insn(ctx, ISA_MIPS3);
15546 check_mips_64(ctx);
15547 gen_ld(ctx, op, rt, rs, imm);
15548 break;
15549 case OPC_SDL ... OPC_SDR:
15550 case OPC_SD:
15551 check_insn(ctx, ISA_MIPS3);
15552 check_mips_64(ctx);
15553 gen_st(ctx, op, rt, rs, imm);
15554 break;
15555 case OPC_SCD:
15556 check_insn(ctx, ISA_MIPS3);
15557 check_mips_64(ctx);
15558 gen_st_cond(ctx, op, rt, rs, imm);
15559 break;
15560 case OPC_DADDI:
15561 case OPC_DADDIU:
15562 check_insn(ctx, ISA_MIPS3);
15563 check_mips_64(ctx);
15564 gen_arith_imm(ctx, op, rt, rs, imm);
15565 break;
15566 #endif
15567 case OPC_JALX:
15568 check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15569 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15570 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15571 break;
15572 case OPC_MDMX:
15573 check_insn(ctx, ASE_MDMX);
15574 /* MDMX: Not implemented. */
15575 default: /* Invalid */
15576 MIPS_INVAL("major opcode");
15577 generate_exception(ctx, EXCP_RI);
15578 break;
15579 }
15580 }
15581
15582 static inline void
15583 gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15584 bool search_pc)
15585 {
15586 CPUState *cs = CPU(cpu);
15587 CPUMIPSState *env = &cpu->env;
15588 DisasContext ctx;
15589 target_ulong pc_start;
15590 uint16_t *gen_opc_end;
15591 CPUBreakpoint *bp;
15592 int j, lj = -1;
15593 int num_insns;
15594 int max_insns;
15595 int insn_bytes;
15596 int is_delay;
15597
15598 if (search_pc)
15599 qemu_log("search pc %d\n", search_pc);
15600
15601 pc_start = tb->pc;
15602 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15603 ctx.pc = pc_start;
15604 ctx.saved_pc = -1;
15605 ctx.singlestep_enabled = cs->singlestep_enabled;
15606 ctx.insn_flags = env->insn_flags;
15607 ctx.tb = tb;
15608 ctx.bstate = BS_NONE;
15609 /* Restore delay slot state from the tb context. */
15610 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15611 restore_cpu_state(env, &ctx);
15612 #ifdef CONFIG_USER_ONLY
15613 ctx.mem_idx = MIPS_HFLAG_UM;
15614 #else
15615 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15616 #endif
15617 num_insns = 0;
15618 max_insns = tb->cflags & CF_COUNT_MASK;
15619 if (max_insns == 0)
15620 max_insns = CF_COUNT_MASK;
15621 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15622 gen_tb_start();
15623 while (ctx.bstate == BS_NONE) {
15624 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
15625 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
15626 if (bp->pc == ctx.pc) {
15627 save_cpu_state(&ctx, 1);
15628 ctx.bstate = BS_BRANCH;
15629 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15630 /* Include the breakpoint location or the tb won't
15631 * be flushed when it must be. */
15632 ctx.pc += 4;
15633 goto done_generating;
15634 }
15635 }
15636 }
15637
15638 if (search_pc) {
15639 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15640 if (lj < j) {
15641 lj++;
15642 while (lj < j)
15643 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15644 }
15645 tcg_ctx.gen_opc_pc[lj] = ctx.pc;
15646 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15647 gen_opc_btarget[lj] = ctx.btarget;
15648 tcg_ctx.gen_opc_instr_start[lj] = 1;
15649 tcg_ctx.gen_opc_icount[lj] = num_insns;
15650 }
15651 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15652 gen_io_start();
15653
15654 is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
15655 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15656 ctx.opcode = cpu_ldl_code(env, ctx.pc);
15657 insn_bytes = 4;
15658 decode_opc(env, &ctx);
15659 } else if (ctx.insn_flags & ASE_MICROMIPS) {
15660 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15661 insn_bytes = decode_micromips_opc(env, &ctx);
15662 } else if (ctx.insn_flags & ASE_MIPS16) {
15663 ctx.opcode = cpu_lduw_code(env, ctx.pc);
15664 insn_bytes = decode_mips16_opc(env, &ctx);
15665 } else {
15666 generate_exception(&ctx, EXCP_RI);
15667 ctx.bstate = BS_STOP;
15668 break;
15669 }
15670 if (is_delay) {
15671 handle_delay_slot(&ctx, insn_bytes);
15672 }
15673 ctx.pc += insn_bytes;
15674
15675 num_insns++;
15676
15677 /* Execute a branch and its delay slot as a single instruction.
15678 This is what GDB expects and is consistent with what the
15679 hardware does (e.g. if a delay slot instruction faults, the
15680 reported PC is the PC of the branch). */
15681 if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
15682 break;
15683 }
15684
15685 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15686 break;
15687
15688 if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15689 break;
15690 }
15691
15692 if (num_insns >= max_insns)
15693 break;
15694
15695 if (singlestep)
15696 break;
15697 }
15698 if (tb->cflags & CF_LAST_IO) {
15699 gen_io_end();
15700 }
15701 if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15702 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15703 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15704 } else {
15705 switch (ctx.bstate) {
15706 case BS_STOP:
15707 gen_goto_tb(&ctx, 0, ctx.pc);
15708 break;
15709 case BS_NONE:
15710 save_cpu_state(&ctx, 0);
15711 gen_goto_tb(&ctx, 0, ctx.pc);
15712 break;
15713 case BS_EXCP:
15714 tcg_gen_exit_tb(0);
15715 break;
15716 case BS_BRANCH:
15717 default:
15718 break;
15719 }
15720 }
15721 done_generating:
15722 gen_tb_end(tb, num_insns);
15723 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15724 if (search_pc) {
15725 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15726 lj++;
15727 while (lj <= j)
15728 tcg_ctx.gen_opc_instr_start[lj++] = 0;
15729 } else {
15730 tb->size = ctx.pc - pc_start;
15731 tb->icount = num_insns;
15732 }
15733 #ifdef DEBUG_DISAS
15734 LOG_DISAS("\n");
15735 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15736 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15737 log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15738 qemu_log("\n");
15739 }
15740 #endif
15741 }
15742
15743 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15744 {
15745 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
15746 }
15747
15748 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15749 {
15750 gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
15751 }
15752
15753 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15754 int flags)
15755 {
15756 int i;
15757 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15758
15759 #define printfpr(fp) \
15760 do { \
15761 if (is_fpu64) \
15762 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15763 " fd:%13g fs:%13g psu: %13g\n", \
15764 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15765 (double)(fp)->fd, \
15766 (double)(fp)->fs[FP_ENDIAN_IDX], \
15767 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15768 else { \
15769 fpr_t tmp; \
15770 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15771 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15772 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15773 " fd:%13g fs:%13g psu:%13g\n", \
15774 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15775 (double)tmp.fd, \
15776 (double)tmp.fs[FP_ENDIAN_IDX], \
15777 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15778 } \
15779 } while(0)
15780
15781
15782 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15783 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15784 get_float_exception_flags(&env->active_fpu.fp_status));
15785 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15786 fpu_fprintf(f, "%3s: ", fregnames[i]);
15787 printfpr(&env->active_fpu.fpr[i]);
15788 }
15789
15790 #undef printfpr
15791 }
15792
15793 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15794 /* Debug help: The architecture requires 32bit code to maintain proper
15795 sign-extended values on 64bit machines. */
15796
15797 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15798
15799 static void
15800 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15801 fprintf_function cpu_fprintf,
15802 int flags)
15803 {
15804 int i;
15805
15806 if (!SIGN_EXT_P(env->active_tc.PC))
15807 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15808 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15809 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15810 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15811 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15812 if (!SIGN_EXT_P(env->btarget))
15813 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15814
15815 for (i = 0; i < 32; i++) {
15816 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15817 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15818 }
15819
15820 if (!SIGN_EXT_P(env->CP0_EPC))
15821 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15822 if (!SIGN_EXT_P(env->lladdr))
15823 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15824 }
15825 #endif
15826
15827 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15828 int flags)
15829 {
15830 MIPSCPU *cpu = MIPS_CPU(cs);
15831 CPUMIPSState *env = &cpu->env;
15832 int i;
15833
15834 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15835 " LO=0x" TARGET_FMT_lx " ds %04x "
15836 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15837 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15838 env->hflags, env->btarget, env->bcond);
15839 for (i = 0; i < 32; i++) {
15840 if ((i & 3) == 0)
15841 cpu_fprintf(f, "GPR%02d:", i);
15842 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15843 if ((i & 3) == 3)
15844 cpu_fprintf(f, "\n");
15845 }
15846
15847 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
15848 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15849 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15850 env->CP0_Config0, env->CP0_Config1, env->lladdr);
15851 if (env->hflags & MIPS_HFLAG_FPU)
15852 fpu_dump_state(env, f, cpu_fprintf, flags);
15853 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15854 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15855 #endif
15856 }
15857
15858 void mips_tcg_init(void)
15859 {
15860 int i;
15861 static int inited;
15862
15863 /* Initialize various static tables. */
15864 if (inited)
15865 return;
15866
15867 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15868 TCGV_UNUSED(cpu_gpr[0]);
15869 for (i = 1; i < 32; i++)
15870 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15871 offsetof(CPUMIPSState, active_tc.gpr[i]),
15872 regnames[i]);
15873
15874 for (i = 0; i < 32; i++) {
15875 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15876 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15877 }
15878
15879 cpu_PC = tcg_global_mem_new(TCG_AREG0,
15880 offsetof(CPUMIPSState, active_tc.PC), "PC");
15881 for (i = 0; i < MIPS_DSP_ACC; i++) {
15882 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15883 offsetof(CPUMIPSState, active_tc.HI[i]),
15884 regnames_HI[i]);
15885 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15886 offsetof(CPUMIPSState, active_tc.LO[i]),
15887 regnames_LO[i]);
15888 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15889 offsetof(CPUMIPSState, active_tc.ACX[i]),
15890 regnames_ACX[i]);
15891 }
15892 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15893 offsetof(CPUMIPSState, active_tc.DSPControl),
15894 "DSPControl");
15895 bcond = tcg_global_mem_new(TCG_AREG0,
15896 offsetof(CPUMIPSState, bcond), "bcond");
15897 btarget = tcg_global_mem_new(TCG_AREG0,
15898 offsetof(CPUMIPSState, btarget), "btarget");
15899 hflags = tcg_global_mem_new_i32(TCG_AREG0,
15900 offsetof(CPUMIPSState, hflags), "hflags");
15901
15902 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15903 offsetof(CPUMIPSState, active_fpu.fcr0),
15904 "fcr0");
15905 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15906 offsetof(CPUMIPSState, active_fpu.fcr31),
15907 "fcr31");
15908
15909 inited = 1;
15910 }
15911
15912 #include "translate_init.c"
15913
15914 MIPSCPU *cpu_mips_init(const char *cpu_model)
15915 {
15916 MIPSCPU *cpu;
15917 CPUMIPSState *env;
15918 const mips_def_t *def;
15919
15920 def = cpu_mips_find_by_name(cpu_model);
15921 if (!def)
15922 return NULL;
15923 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15924 env = &cpu->env;
15925 env->cpu_model = def;
15926
15927 #ifndef CONFIG_USER_ONLY
15928 mmu_init(env, def);
15929 #endif
15930 fpu_init(env, def);
15931 mvp_init(env, def);
15932
15933 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15934
15935 return cpu;
15936 }
15937
15938 void cpu_state_reset(CPUMIPSState *env)
15939 {
15940 MIPSCPU *cpu = mips_env_get_cpu(env);
15941 CPUState *cs = CPU(cpu);
15942
15943 /* Reset registers to their default values */
15944 env->CP0_PRid = env->cpu_model->CP0_PRid;
15945 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15946 #ifdef TARGET_WORDS_BIGENDIAN
15947 env->CP0_Config0 |= (1 << CP0C0_BE);
15948 #endif
15949 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15950 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15951 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15952 env->CP0_Config4 = env->cpu_model->CP0_Config4;
15953 env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
15954 env->CP0_Config5 = env->cpu_model->CP0_Config5;
15955 env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
15956 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15957 env->CP0_Config7 = env->cpu_model->CP0_Config7;
15958 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15959 << env->cpu_model->CP0_LLAddr_shift;
15960 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15961 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15962 env->CCRes = env->cpu_model->CCRes;
15963 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15964 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15965 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15966 env->current_tc = 0;
15967 env->SEGBITS = env->cpu_model->SEGBITS;
15968 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15969 #if defined(TARGET_MIPS64)
15970 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15971 env->SEGMask |= 3ULL << 62;
15972 }
15973 #endif
15974 env->PABITS = env->cpu_model->PABITS;
15975 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15976 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15977 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15978 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15979 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15980 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15981 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15982 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15983 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15984 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15985 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15986 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15987 env->insn_flags = env->cpu_model->insn_flags;
15988
15989 #if defined(CONFIG_USER_ONLY)
15990 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15991 # ifdef TARGET_MIPS64
15992 /* Enable 64-bit register mode. */
15993 env->CP0_Status |= (1 << CP0St_PX);
15994 # endif
15995 # ifdef TARGET_ABI_MIPSN64
15996 /* Enable 64-bit address mode. */
15997 env->CP0_Status |= (1 << CP0St_UX);
15998 # endif
15999 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16000 hardware registers. */
16001 env->CP0_HWREna |= 0x0000000F;
16002 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16003 env->CP0_Status |= (1 << CP0St_CU1);
16004 }
16005 if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
16006 env->CP0_Status |= (1 << CP0St_MX);
16007 }
16008 # if defined(TARGET_MIPS64)
16009 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16010 if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
16011 (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
16012 env->CP0_Status |= (1 << CP0St_FR);
16013 }
16014 # endif
16015 #else
16016 if (env->hflags & MIPS_HFLAG_BMASK) {
16017 /* If the exception was raised from a delay slot,
16018 come back to the jump. */
16019 env->CP0_ErrorEPC = env->active_tc.PC - 4;
16020 } else {
16021 env->CP0_ErrorEPC = env->active_tc.PC;
16022 }
16023 env->active_tc.PC = (int32_t)0xBFC00000;
16024 env->CP0_Random = env->tlb->nb_tlb - 1;
16025 env->tlb->tlb_in_use = env->tlb->nb_tlb;
16026 env->CP0_Wired = 0;
16027 env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
16028 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16029 /* vectored interrupts not implemented, timer on int 7,
16030 no performance counters. */
16031 env->CP0_IntCtl = 0xe0000000;
16032 {
16033 int i;
16034
16035 for (i = 0; i < 7; i++) {
16036 env->CP0_WatchLo[i] = 0;
16037 env->CP0_WatchHi[i] = 0x80000000;
16038 }
16039 env->CP0_WatchLo[7] = 0;
16040 env->CP0_WatchHi[7] = 0;
16041 }
16042 /* Count register increments in debug mode, EJTAG version 1 */
16043 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16044
16045 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16046 int i;
16047
16048 /* Only TC0 on VPE 0 starts as active. */
16049 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16050 env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
16051 env->tcs[i].CP0_TCHalt = 1;
16052 }
16053 env->active_tc.CP0_TCHalt = 1;
16054 cs->halted = 1;
16055
16056 if (cs->cpu_index == 0) {
16057 /* VPE0 starts up enabled. */
16058 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16059 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16060
16061 /* TC0 starts up unhalted. */
16062 cs->halted = 0;
16063 env->active_tc.CP0_TCHalt = 0;
16064 env->tcs[0].CP0_TCHalt = 0;
16065 /* With thread 0 active. */
16066 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16067 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16068 }
16069 }
16070 #endif
16071 compute_hflags(env);
16072 cs->exception_index = EXCP_NONE;
16073 }
16074
16075 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16076 {
16077 env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
16078 env->hflags &= ~MIPS_HFLAG_BMASK;
16079 env->hflags |= gen_opc_hflags[pc_pos];
16080 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16081 case MIPS_HFLAG_BR:
16082 break;
16083 case MIPS_HFLAG_BC:
16084 case MIPS_HFLAG_BL:
16085 case MIPS_HFLAG_B:
16086 env->btarget = gen_opc_btarget[pc_pos];
16087 break;
16088 }
16089 }