]> git.proxmox.com Git - mirror_qemu.git/blob - target-mips/translate.c
target-mips: Use TCG registers for the FPU.
[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 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "cpu.h"
24 #include "disas.h"
25 #include "tcg-op.h"
26
27 #include "helper.h"
28 #define GEN_HELPER 1
29 #include "helper.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
317 /* BSHFL opcodes */
318 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
319
320 enum {
321 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
322 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
323 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
324 };
325
326 /* DBSHFL opcodes */
327 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
328
329 enum {
330 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
331 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
332 };
333
334 /* Coprocessor 0 (rs field) */
335 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
336
337 enum {
338 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
339 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
340 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
341 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
342 OPC_MFTR = (0x08 << 21) | OPC_CP0,
343 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
344 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
345 OPC_MTTR = (0x0C << 21) | OPC_CP0,
346 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
347 OPC_C0 = (0x10 << 21) | OPC_CP0,
348 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
349 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
350 };
351
352 /* MFMC0 opcodes */
353 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
354
355 enum {
356 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
357 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
358 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
359 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
360 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
361 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
362 };
363
364 /* Coprocessor 0 (with rs == C0) */
365 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
366
367 enum {
368 OPC_TLBR = 0x01 | OPC_C0,
369 OPC_TLBWI = 0x02 | OPC_C0,
370 OPC_TLBWR = 0x06 | OPC_C0,
371 OPC_TLBP = 0x08 | OPC_C0,
372 OPC_RFE = 0x10 | OPC_C0,
373 OPC_ERET = 0x18 | OPC_C0,
374 OPC_DERET = 0x1F | OPC_C0,
375 OPC_WAIT = 0x20 | OPC_C0,
376 };
377
378 /* Coprocessor 1 (rs field) */
379 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
380
381 /* Values for the fmt field in FP instructions */
382 enum {
383 /* 0 - 15 are reserved */
384 FMT_S = 16, /* single fp */
385 FMT_D = 17, /* double fp */
386 FMT_E = 18, /* extended fp */
387 FMT_Q = 19, /* quad fp */
388 FMT_W = 20, /* 32-bit fixed */
389 FMT_L = 21, /* 64-bit fixed */
390 FMT_PS = 22, /* paired single fp */
391 /* 23 - 31 are reserved */
392 };
393
394 enum {
395 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
396 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
397 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
398 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
399 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
400 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
401 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
402 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
403 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
404 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
405 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
406 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
407 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
408 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
409 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
410 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
411 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
412 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
413 };
414
415 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
416 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
417
418 enum {
419 OPC_BC1F = (0x00 << 16) | OPC_BC1,
420 OPC_BC1T = (0x01 << 16) | OPC_BC1,
421 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
422 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
423 };
424
425 enum {
426 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
427 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
428 };
429
430 enum {
431 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
432 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
433 };
434
435 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
436
437 enum {
438 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
439 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
440 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
441 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
442 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
443 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
444 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
445 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
446 OPC_BC2 = (0x08 << 21) | OPC_CP2,
447 };
448
449 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
450
451 enum {
452 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
453 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
454 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
455 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
456 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
457 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
458 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
459 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
460
461 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
462 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
463 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
464 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
465 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
466 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
467 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
468 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
469
470 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
471 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
472 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
473 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
474 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
475 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
476 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
477 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
478
479 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
480 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
481 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
482 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
483 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
484 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
485 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
486 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
487
488 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
489 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
490 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
491 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
492 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
493 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
494
495 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
496 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
497 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
498 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
499 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
500 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
501
502 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
503 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
504 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
505 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
506 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
507 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
508
509 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
510 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
511 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
512 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
513 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
514 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
515
516 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
517 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
518 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
519 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
520 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
521 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
522
523 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
524 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
525 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
526 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
527 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
528 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
529
530 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
531 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
532 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
533 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
534 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
535 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
536
537 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
538 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
539 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
540 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
541 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
542 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
543 };
544
545
546 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
547
548 enum {
549 OPC_LWXC1 = 0x00 | OPC_CP3,
550 OPC_LDXC1 = 0x01 | OPC_CP3,
551 OPC_LUXC1 = 0x05 | OPC_CP3,
552 OPC_SWXC1 = 0x08 | OPC_CP3,
553 OPC_SDXC1 = 0x09 | OPC_CP3,
554 OPC_SUXC1 = 0x0D | OPC_CP3,
555 OPC_PREFX = 0x0F | OPC_CP3,
556 OPC_ALNV_PS = 0x1E | OPC_CP3,
557 OPC_MADD_S = 0x20 | OPC_CP3,
558 OPC_MADD_D = 0x21 | OPC_CP3,
559 OPC_MADD_PS = 0x26 | OPC_CP3,
560 OPC_MSUB_S = 0x28 | OPC_CP3,
561 OPC_MSUB_D = 0x29 | OPC_CP3,
562 OPC_MSUB_PS = 0x2E | OPC_CP3,
563 OPC_NMADD_S = 0x30 | OPC_CP3,
564 OPC_NMADD_D = 0x31 | OPC_CP3,
565 OPC_NMADD_PS= 0x36 | OPC_CP3,
566 OPC_NMSUB_S = 0x38 | OPC_CP3,
567 OPC_NMSUB_D = 0x39 | OPC_CP3,
568 OPC_NMSUB_PS= 0x3E | OPC_CP3,
569 };
570
571 /* global register indices */
572 static TCGv_ptr cpu_env;
573 static TCGv cpu_gpr[32], cpu_PC;
574 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
575 static TCGv cpu_dspctrl, btarget, bcond;
576 static TCGv_i32 hflags;
577 static TCGv_i32 fpu_fcr0, fpu_fcr31;
578 static TCGv_i64 fpu_f64[32];
579
580 static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
581
582 #include "gen-icount.h"
583
584 #define gen_helper_0e0i(name, arg) do { \
585 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
586 gen_helper_##name(cpu_env, helper_tmp); \
587 tcg_temp_free_i32(helper_tmp); \
588 } while(0)
589
590 #define gen_helper_0e1i(name, arg1, arg2) do { \
591 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
592 gen_helper_##name(cpu_env, arg1, helper_tmp); \
593 tcg_temp_free_i32(helper_tmp); \
594 } while(0)
595
596 #define gen_helper_1e0i(name, ret, arg1) do { \
597 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
598 gen_helper_##name(ret, cpu_env, helper_tmp); \
599 tcg_temp_free_i32(helper_tmp); \
600 } while(0)
601
602 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
603 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
604 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
605 tcg_temp_free_i32(helper_tmp); \
606 } while(0)
607
608 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
609 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
610 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
611 tcg_temp_free_i32(helper_tmp); \
612 } while(0)
613
614 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
615 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
616 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
617 tcg_temp_free_i32(helper_tmp); \
618 } while(0)
619
620 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
621 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
622 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
623 tcg_temp_free_i32(helper_tmp); \
624 } while(0)
625
626 typedef struct DisasContext {
627 struct TranslationBlock *tb;
628 target_ulong pc, saved_pc;
629 uint32_t opcode;
630 int singlestep_enabled;
631 /* Routine used to access memory */
632 int mem_idx;
633 uint32_t hflags, saved_hflags;
634 int bstate;
635 target_ulong btarget;
636 } DisasContext;
637
638 enum {
639 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
640 * exception condition */
641 BS_STOP = 1, /* We want to stop translation for any reason */
642 BS_BRANCH = 2, /* We reached a branch condition */
643 BS_EXCP = 3, /* We reached an exception condition */
644 };
645
646 static const char * const regnames[] = {
647 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
648 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
649 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
650 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
651 };
652
653 static const char * const regnames_HI[] = {
654 "HI0", "HI1", "HI2", "HI3",
655 };
656
657 static const char * const regnames_LO[] = {
658 "LO0", "LO1", "LO2", "LO3",
659 };
660
661 static const char * const regnames_ACX[] = {
662 "ACX0", "ACX1", "ACX2", "ACX3",
663 };
664
665 static const char * const fregnames[] = {
666 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
667 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
668 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
669 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
670 };
671
672 #define MIPS_DEBUG(fmt, ...) \
673 do { \
674 if (MIPS_DEBUG_DISAS) { \
675 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
676 TARGET_FMT_lx ": %08x " fmt "\n", \
677 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
678 } \
679 } while (0)
680
681 #define LOG_DISAS(...) \
682 do { \
683 if (MIPS_DEBUG_DISAS) { \
684 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
685 } \
686 } while (0)
687
688 #define MIPS_INVAL(op) \
689 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
690 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
691
692 /* General purpose registers moves. */
693 static inline void gen_load_gpr (TCGv t, int reg)
694 {
695 if (reg == 0)
696 tcg_gen_movi_tl(t, 0);
697 else
698 tcg_gen_mov_tl(t, cpu_gpr[reg]);
699 }
700
701 static inline void gen_store_gpr (TCGv t, int reg)
702 {
703 if (reg != 0)
704 tcg_gen_mov_tl(cpu_gpr[reg], t);
705 }
706
707 /* Moves to/from ACX register. */
708 static inline void gen_load_ACX (TCGv t, int reg)
709 {
710 tcg_gen_mov_tl(t, cpu_ACX[reg]);
711 }
712
713 static inline void gen_store_ACX (TCGv t, int reg)
714 {
715 tcg_gen_mov_tl(cpu_ACX[reg], t);
716 }
717
718 /* Moves to/from shadow registers. */
719 static inline void gen_load_srsgpr (int from, int to)
720 {
721 TCGv t0 = tcg_temp_new();
722
723 if (from == 0)
724 tcg_gen_movi_tl(t0, 0);
725 else {
726 TCGv_i32 t2 = tcg_temp_new_i32();
727 TCGv_ptr addr = tcg_temp_new_ptr();
728
729 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
730 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
731 tcg_gen_andi_i32(t2, t2, 0xf);
732 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
733 tcg_gen_ext_i32_ptr(addr, t2);
734 tcg_gen_add_ptr(addr, cpu_env, addr);
735
736 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
737 tcg_temp_free_ptr(addr);
738 tcg_temp_free_i32(t2);
739 }
740 gen_store_gpr(t0, to);
741 tcg_temp_free(t0);
742 }
743
744 static inline void gen_store_srsgpr (int from, int to)
745 {
746 if (to != 0) {
747 TCGv t0 = tcg_temp_new();
748 TCGv_i32 t2 = tcg_temp_new_i32();
749 TCGv_ptr addr = tcg_temp_new_ptr();
750
751 gen_load_gpr(t0, from);
752 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
753 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
754 tcg_gen_andi_i32(t2, t2, 0xf);
755 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
756 tcg_gen_ext_i32_ptr(addr, t2);
757 tcg_gen_add_ptr(addr, cpu_env, addr);
758
759 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
760 tcg_temp_free_ptr(addr);
761 tcg_temp_free_i32(t2);
762 tcg_temp_free(t0);
763 }
764 }
765
766 /* Floating point register moves. */
767 static void gen_load_fpr32(TCGv_i32 t, int reg)
768 {
769 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
770 }
771
772 static void gen_store_fpr32(TCGv_i32 t, int reg)
773 {
774 TCGv_i64 t64 = tcg_temp_new_i64();
775 tcg_gen_extu_i32_i64(t64, t);
776 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
777 tcg_temp_free_i64(t64);
778 }
779
780 static void gen_load_fpr32h(TCGv_i32 t, int reg)
781 {
782 TCGv_i64 t64 = tcg_temp_new_i64();
783 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
784 tcg_gen_trunc_i64_i32(t, t64);
785 tcg_temp_free_i64(t64);
786 }
787
788 static void gen_store_fpr32h(TCGv_i32 t, int reg)
789 {
790 TCGv_i64 t64 = tcg_temp_new_i64();
791 tcg_gen_extu_i32_i64(t64, t);
792 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
793 tcg_temp_free_i64(t64);
794 }
795
796 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
797 {
798 if (ctx->hflags & MIPS_HFLAG_F64) {
799 tcg_gen_mov_i64(t, fpu_f64[reg]);
800 } else {
801 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
802 }
803 }
804
805 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
806 {
807 if (ctx->hflags & MIPS_HFLAG_F64) {
808 tcg_gen_mov_i64(fpu_f64[reg], t);
809 } else {
810 TCGv_i64 t0;
811 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
812 t0 = tcg_temp_new_i64();
813 tcg_gen_shri_i64(t0, t, 32);
814 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
815 tcg_temp_free_i64(t0);
816 }
817 }
818
819 static inline int get_fp_bit (int cc)
820 {
821 if (cc)
822 return 24 + cc;
823 else
824 return 23;
825 }
826
827 /* Tests */
828 static inline void gen_save_pc(target_ulong pc)
829 {
830 tcg_gen_movi_tl(cpu_PC, pc);
831 }
832
833 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
834 {
835 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
836 if (do_save_pc && ctx->pc != ctx->saved_pc) {
837 gen_save_pc(ctx->pc);
838 ctx->saved_pc = ctx->pc;
839 }
840 if (ctx->hflags != ctx->saved_hflags) {
841 tcg_gen_movi_i32(hflags, ctx->hflags);
842 ctx->saved_hflags = ctx->hflags;
843 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
844 case MIPS_HFLAG_BR:
845 break;
846 case MIPS_HFLAG_BC:
847 case MIPS_HFLAG_BL:
848 case MIPS_HFLAG_B:
849 tcg_gen_movi_tl(btarget, ctx->btarget);
850 break;
851 }
852 }
853 }
854
855 static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
856 {
857 ctx->saved_hflags = ctx->hflags;
858 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
859 case MIPS_HFLAG_BR:
860 break;
861 case MIPS_HFLAG_BC:
862 case MIPS_HFLAG_BL:
863 case MIPS_HFLAG_B:
864 ctx->btarget = env->btarget;
865 break;
866 }
867 }
868
869 static inline void
870 generate_exception_err (DisasContext *ctx, int excp, int err)
871 {
872 TCGv_i32 texcp = tcg_const_i32(excp);
873 TCGv_i32 terr = tcg_const_i32(err);
874 save_cpu_state(ctx, 1);
875 gen_helper_raise_exception_err(cpu_env, texcp, terr);
876 tcg_temp_free_i32(terr);
877 tcg_temp_free_i32(texcp);
878 }
879
880 static inline void
881 generate_exception (DisasContext *ctx, int excp)
882 {
883 save_cpu_state(ctx, 1);
884 gen_helper_0e0i(raise_exception, excp);
885 }
886
887 /* Addresses computation */
888 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
889 {
890 tcg_gen_add_tl(ret, arg0, arg1);
891
892 #if defined(TARGET_MIPS64)
893 /* For compatibility with 32-bit code, data reference in user mode
894 with Status_UX = 0 should be casted to 32-bit and sign extended.
895 See the MIPS64 PRA manual, section 4.10. */
896 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
897 !(ctx->hflags & MIPS_HFLAG_UX)) {
898 tcg_gen_ext32s_i64(ret, ret);
899 }
900 #endif
901 }
902
903 static inline void check_cp0_enabled(DisasContext *ctx)
904 {
905 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
906 generate_exception_err(ctx, EXCP_CpU, 0);
907 }
908
909 static inline void check_cp1_enabled(DisasContext *ctx)
910 {
911 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
912 generate_exception_err(ctx, EXCP_CpU, 1);
913 }
914
915 /* Verify that the processor is running with COP1X instructions enabled.
916 This is associated with the nabla symbol in the MIPS32 and MIPS64
917 opcode tables. */
918
919 static inline void check_cop1x(DisasContext *ctx)
920 {
921 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
922 generate_exception(ctx, EXCP_RI);
923 }
924
925 /* Verify that the processor is running with 64-bit floating-point
926 operations enabled. */
927
928 static inline void check_cp1_64bitmode(DisasContext *ctx)
929 {
930 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
931 generate_exception(ctx, EXCP_RI);
932 }
933
934 /*
935 * Verify if floating point register is valid; an operation is not defined
936 * if bit 0 of any register specification is set and the FR bit in the
937 * Status register equals zero, since the register numbers specify an
938 * even-odd pair of adjacent coprocessor general registers. When the FR bit
939 * in the Status register equals one, both even and odd register numbers
940 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
941 *
942 * Multiple 64 bit wide registers can be checked by calling
943 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
944 */
945 static inline void check_cp1_registers(DisasContext *ctx, int regs)
946 {
947 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
948 generate_exception(ctx, EXCP_RI);
949 }
950
951 /* This code generates a "reserved instruction" exception if the
952 CPU does not support the instruction set corresponding to flags. */
953 static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
954 {
955 if (unlikely(!(env->insn_flags & flags)))
956 generate_exception(ctx, EXCP_RI);
957 }
958
959 /* This code generates a "reserved instruction" exception if 64-bit
960 instructions are not enabled. */
961 static inline void check_mips_64(DisasContext *ctx)
962 {
963 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
964 generate_exception(ctx, EXCP_RI);
965 }
966
967 /* Define small wrappers for gen_load_fpr* so that we have a uniform
968 calling interface for 32 and 64-bit FPRs. No sense in changing
969 all callers for gen_load_fpr32 when we need the CTX parameter for
970 this one use. */
971 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
972 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
973 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
974 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
975 int ft, int fs, int cc) \
976 { \
977 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
978 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
979 switch (ifmt) { \
980 case FMT_PS: \
981 check_cp1_64bitmode(ctx); \
982 break; \
983 case FMT_D: \
984 if (abs) { \
985 check_cop1x(ctx); \
986 } \
987 check_cp1_registers(ctx, fs | ft); \
988 break; \
989 case FMT_S: \
990 if (abs) { \
991 check_cop1x(ctx); \
992 } \
993 break; \
994 } \
995 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
996 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
997 switch (n) { \
998 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
999 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1000 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1001 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1002 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1003 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1004 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1005 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1006 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1007 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1008 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1009 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1010 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1011 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1012 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1013 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1014 default: abort(); \
1015 } \
1016 tcg_temp_free_i##bits (fp0); \
1017 tcg_temp_free_i##bits (fp1); \
1018 }
1019
1020 FOP_CONDS(, 0, d, FMT_D, 64)
1021 FOP_CONDS(abs, 1, d, FMT_D, 64)
1022 FOP_CONDS(, 0, s, FMT_S, 32)
1023 FOP_CONDS(abs, 1, s, FMT_S, 32)
1024 FOP_CONDS(, 0, ps, FMT_PS, 64)
1025 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1026 #undef FOP_CONDS
1027 #undef gen_ldcmp_fpr32
1028 #undef gen_ldcmp_fpr64
1029
1030 /* load/store instructions. */
1031 #define OP_LD(insn,fname) \
1032 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1033 { \
1034 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1035 }
1036 OP_LD(lb,ld8s);
1037 OP_LD(lbu,ld8u);
1038 OP_LD(lh,ld16s);
1039 OP_LD(lhu,ld16u);
1040 OP_LD(lw,ld32s);
1041 #if defined(TARGET_MIPS64)
1042 OP_LD(lwu,ld32u);
1043 OP_LD(ld,ld64);
1044 #endif
1045 #undef OP_LD
1046
1047 #define OP_ST(insn,fname) \
1048 static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
1049 { \
1050 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
1051 }
1052 OP_ST(sb,st8);
1053 OP_ST(sh,st16);
1054 OP_ST(sw,st32);
1055 #if defined(TARGET_MIPS64)
1056 OP_ST(sd,st64);
1057 #endif
1058 #undef OP_ST
1059
1060 #ifdef CONFIG_USER_ONLY
1061 #define OP_LD_ATOMIC(insn,fname) \
1062 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1063 { \
1064 TCGv t0 = tcg_temp_new(); \
1065 tcg_gen_mov_tl(t0, arg1); \
1066 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1067 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1068 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1069 tcg_temp_free(t0); \
1070 }
1071 #else
1072 #define OP_LD_ATOMIC(insn,fname) \
1073 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1074 { \
1075 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1076 }
1077 #endif
1078 OP_LD_ATOMIC(ll,ld32s);
1079 #if defined(TARGET_MIPS64)
1080 OP_LD_ATOMIC(lld,ld64);
1081 #endif
1082 #undef OP_LD_ATOMIC
1083
1084 #ifdef CONFIG_USER_ONLY
1085 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1086 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1087 { \
1088 TCGv t0 = tcg_temp_new(); \
1089 int l1 = gen_new_label(); \
1090 int l2 = gen_new_label(); \
1091 \
1092 tcg_gen_andi_tl(t0, arg2, almask); \
1093 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1094 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1095 generate_exception(ctx, EXCP_AdES); \
1096 gen_set_label(l1); \
1097 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1098 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1099 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1100 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1101 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1102 gen_helper_0e0i(raise_exception, EXCP_SC); \
1103 gen_set_label(l2); \
1104 tcg_gen_movi_tl(t0, 0); \
1105 gen_store_gpr(t0, rt); \
1106 tcg_temp_free(t0); \
1107 }
1108 #else
1109 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1110 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1111 { \
1112 TCGv t0 = tcg_temp_new(); \
1113 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1114 gen_store_gpr(t0, rt); \
1115 tcg_temp_free(t0); \
1116 }
1117 #endif
1118 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1119 #if defined(TARGET_MIPS64)
1120 OP_ST_ATOMIC(scd,st64,ld64,0x7);
1121 #endif
1122 #undef OP_ST_ATOMIC
1123
1124 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1125 int base, int16_t offset)
1126 {
1127 if (base == 0) {
1128 tcg_gen_movi_tl(addr, offset);
1129 } else if (offset == 0) {
1130 gen_load_gpr(addr, base);
1131 } else {
1132 tcg_gen_movi_tl(addr, offset);
1133 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1134 }
1135 }
1136
1137 static target_ulong pc_relative_pc (DisasContext *ctx)
1138 {
1139 target_ulong pc = ctx->pc;
1140
1141 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1142 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1143
1144 pc -= branch_bytes;
1145 }
1146
1147 pc &= ~(target_ulong)3;
1148 return pc;
1149 }
1150
1151 /* Load */
1152 static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1153 int rt, int base, int16_t offset)
1154 {
1155 const char *opn = "ld";
1156 TCGv t0, t1;
1157
1158 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1159 /* Loongson CPU uses a load to zero register for prefetch.
1160 We emulate it as a NOP. On other CPU we must perform the
1161 actual memory access. */
1162 MIPS_DEBUG("NOP");
1163 return;
1164 }
1165
1166 t0 = tcg_temp_new();
1167 t1 = tcg_temp_new();
1168 gen_base_offset_addr(ctx, t0, base, offset);
1169
1170 switch (opc) {
1171 #if defined(TARGET_MIPS64)
1172 case OPC_LWU:
1173 save_cpu_state(ctx, 0);
1174 op_ld_lwu(t0, t0, ctx);
1175 gen_store_gpr(t0, rt);
1176 opn = "lwu";
1177 break;
1178 case OPC_LD:
1179 save_cpu_state(ctx, 0);
1180 op_ld_ld(t0, t0, ctx);
1181 gen_store_gpr(t0, rt);
1182 opn = "ld";
1183 break;
1184 case OPC_LLD:
1185 save_cpu_state(ctx, 1);
1186 op_ld_lld(t0, t0, ctx);
1187 gen_store_gpr(t0, rt);
1188 opn = "lld";
1189 break;
1190 case OPC_LDL:
1191 save_cpu_state(ctx, 1);
1192 gen_load_gpr(t1, rt);
1193 gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
1194 gen_store_gpr(t1, rt);
1195 opn = "ldl";
1196 break;
1197 case OPC_LDR:
1198 save_cpu_state(ctx, 1);
1199 gen_load_gpr(t1, rt);
1200 gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
1201 gen_store_gpr(t1, rt);
1202 opn = "ldr";
1203 break;
1204 case OPC_LDPC:
1205 save_cpu_state(ctx, 0);
1206 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1207 gen_op_addr_add(ctx, t0, t0, t1);
1208 op_ld_ld(t0, t0, ctx);
1209 gen_store_gpr(t0, rt);
1210 opn = "ldpc";
1211 break;
1212 #endif
1213 case OPC_LWPC:
1214 save_cpu_state(ctx, 0);
1215 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1216 gen_op_addr_add(ctx, t0, t0, t1);
1217 op_ld_lw(t0, t0, ctx);
1218 gen_store_gpr(t0, rt);
1219 opn = "lwpc";
1220 break;
1221 case OPC_LW:
1222 save_cpu_state(ctx, 0);
1223 op_ld_lw(t0, t0, ctx);
1224 gen_store_gpr(t0, rt);
1225 opn = "lw";
1226 break;
1227 case OPC_LH:
1228 save_cpu_state(ctx, 0);
1229 op_ld_lh(t0, t0, ctx);
1230 gen_store_gpr(t0, rt);
1231 opn = "lh";
1232 break;
1233 case OPC_LHU:
1234 save_cpu_state(ctx, 0);
1235 op_ld_lhu(t0, t0, ctx);
1236 gen_store_gpr(t0, rt);
1237 opn = "lhu";
1238 break;
1239 case OPC_LB:
1240 save_cpu_state(ctx, 0);
1241 op_ld_lb(t0, t0, ctx);
1242 gen_store_gpr(t0, rt);
1243 opn = "lb";
1244 break;
1245 case OPC_LBU:
1246 save_cpu_state(ctx, 0);
1247 op_ld_lbu(t0, t0, ctx);
1248 gen_store_gpr(t0, rt);
1249 opn = "lbu";
1250 break;
1251 case OPC_LWL:
1252 save_cpu_state(ctx, 1);
1253 gen_load_gpr(t1, rt);
1254 gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
1255 gen_store_gpr(t1, rt);
1256 opn = "lwl";
1257 break;
1258 case OPC_LWR:
1259 save_cpu_state(ctx, 1);
1260 gen_load_gpr(t1, rt);
1261 gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
1262 gen_store_gpr(t1, rt);
1263 opn = "lwr";
1264 break;
1265 case OPC_LL:
1266 save_cpu_state(ctx, 1);
1267 op_ld_ll(t0, t0, ctx);
1268 gen_store_gpr(t0, rt);
1269 opn = "ll";
1270 break;
1271 }
1272 (void)opn; /* avoid a compiler warning */
1273 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1274 tcg_temp_free(t0);
1275 tcg_temp_free(t1);
1276 }
1277
1278 /* Store */
1279 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1280 int base, int16_t offset)
1281 {
1282 const char *opn = "st";
1283 TCGv t0 = tcg_temp_new();
1284 TCGv t1 = tcg_temp_new();
1285
1286 gen_base_offset_addr(ctx, t0, base, offset);
1287 gen_load_gpr(t1, rt);
1288 switch (opc) {
1289 #if defined(TARGET_MIPS64)
1290 case OPC_SD:
1291 save_cpu_state(ctx, 0);
1292 op_st_sd(t1, t0, ctx);
1293 opn = "sd";
1294 break;
1295 case OPC_SDL:
1296 save_cpu_state(ctx, 1);
1297 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1298 opn = "sdl";
1299 break;
1300 case OPC_SDR:
1301 save_cpu_state(ctx, 1);
1302 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1303 opn = "sdr";
1304 break;
1305 #endif
1306 case OPC_SW:
1307 save_cpu_state(ctx, 0);
1308 op_st_sw(t1, t0, ctx);
1309 opn = "sw";
1310 break;
1311 case OPC_SH:
1312 save_cpu_state(ctx, 0);
1313 op_st_sh(t1, t0, ctx);
1314 opn = "sh";
1315 break;
1316 case OPC_SB:
1317 save_cpu_state(ctx, 0);
1318 op_st_sb(t1, t0, ctx);
1319 opn = "sb";
1320 break;
1321 case OPC_SWL:
1322 save_cpu_state(ctx, 1);
1323 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1324 opn = "swl";
1325 break;
1326 case OPC_SWR:
1327 save_cpu_state(ctx, 1);
1328 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1329 opn = "swr";
1330 break;
1331 }
1332 (void)opn; /* avoid a compiler warning */
1333 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1334 tcg_temp_free(t0);
1335 tcg_temp_free(t1);
1336 }
1337
1338
1339 /* Store conditional */
1340 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1341 int base, int16_t offset)
1342 {
1343 const char *opn = "st_cond";
1344 TCGv t0, t1;
1345
1346 t0 = tcg_temp_local_new();
1347
1348 gen_base_offset_addr(ctx, t0, base, offset);
1349 /* Don't do NOP if destination is zero: we must perform the actual
1350 memory access. */
1351
1352 t1 = tcg_temp_local_new();
1353 gen_load_gpr(t1, rt);
1354 switch (opc) {
1355 #if defined(TARGET_MIPS64)
1356 case OPC_SCD:
1357 save_cpu_state(ctx, 1);
1358 op_st_scd(t1, t0, rt, ctx);
1359 opn = "scd";
1360 break;
1361 #endif
1362 case OPC_SC:
1363 save_cpu_state(ctx, 1);
1364 op_st_sc(t1, t0, rt, ctx);
1365 opn = "sc";
1366 break;
1367 }
1368 (void)opn; /* avoid a compiler warning */
1369 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1370 tcg_temp_free(t1);
1371 tcg_temp_free(t0);
1372 }
1373
1374 /* Load and store */
1375 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1376 int base, int16_t offset)
1377 {
1378 const char *opn = "flt_ldst";
1379 TCGv t0 = tcg_temp_new();
1380
1381 gen_base_offset_addr(ctx, t0, base, offset);
1382 /* Don't do NOP if destination is zero: we must perform the actual
1383 memory access. */
1384 switch (opc) {
1385 case OPC_LWC1:
1386 {
1387 TCGv_i32 fp0 = tcg_temp_new_i32();
1388
1389 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1390 tcg_gen_trunc_tl_i32(fp0, t0);
1391 gen_store_fpr32(fp0, ft);
1392 tcg_temp_free_i32(fp0);
1393 }
1394 opn = "lwc1";
1395 break;
1396 case OPC_SWC1:
1397 {
1398 TCGv_i32 fp0 = tcg_temp_new_i32();
1399 TCGv t1 = tcg_temp_new();
1400
1401 gen_load_fpr32(fp0, ft);
1402 tcg_gen_extu_i32_tl(t1, fp0);
1403 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1404 tcg_temp_free(t1);
1405 tcg_temp_free_i32(fp0);
1406 }
1407 opn = "swc1";
1408 break;
1409 case OPC_LDC1:
1410 {
1411 TCGv_i64 fp0 = tcg_temp_new_i64();
1412
1413 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1414 gen_store_fpr64(ctx, fp0, ft);
1415 tcg_temp_free_i64(fp0);
1416 }
1417 opn = "ldc1";
1418 break;
1419 case OPC_SDC1:
1420 {
1421 TCGv_i64 fp0 = tcg_temp_new_i64();
1422
1423 gen_load_fpr64(ctx, fp0, ft);
1424 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1425 tcg_temp_free_i64(fp0);
1426 }
1427 opn = "sdc1";
1428 break;
1429 default:
1430 MIPS_INVAL(opn);
1431 generate_exception(ctx, EXCP_RI);
1432 goto out;
1433 }
1434 (void)opn; /* avoid a compiler warning */
1435 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1436 out:
1437 tcg_temp_free(t0);
1438 }
1439
1440 static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1441 uint32_t op, int rt, int rs, int16_t imm)
1442 {
1443 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1444 check_cp1_enabled(ctx);
1445 gen_flt_ldst(ctx, op, rt, rs, imm);
1446 } else {
1447 generate_exception_err(ctx, EXCP_CpU, 1);
1448 }
1449 }
1450
1451 /* Arithmetic with immediate operand */
1452 static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1453 int rt, int rs, int16_t imm)
1454 {
1455 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1456 const char *opn = "imm arith";
1457
1458 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1459 /* If no destination, treat it as a NOP.
1460 For addi, we must generate the overflow exception when needed. */
1461 MIPS_DEBUG("NOP");
1462 return;
1463 }
1464 switch (opc) {
1465 case OPC_ADDI:
1466 {
1467 TCGv t0 = tcg_temp_local_new();
1468 TCGv t1 = tcg_temp_new();
1469 TCGv t2 = tcg_temp_new();
1470 int l1 = gen_new_label();
1471
1472 gen_load_gpr(t1, rs);
1473 tcg_gen_addi_tl(t0, t1, uimm);
1474 tcg_gen_ext32s_tl(t0, t0);
1475
1476 tcg_gen_xori_tl(t1, t1, ~uimm);
1477 tcg_gen_xori_tl(t2, t0, uimm);
1478 tcg_gen_and_tl(t1, t1, t2);
1479 tcg_temp_free(t2);
1480 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1481 tcg_temp_free(t1);
1482 /* operands of same sign, result different sign */
1483 generate_exception(ctx, EXCP_OVERFLOW);
1484 gen_set_label(l1);
1485 tcg_gen_ext32s_tl(t0, t0);
1486 gen_store_gpr(t0, rt);
1487 tcg_temp_free(t0);
1488 }
1489 opn = "addi";
1490 break;
1491 case OPC_ADDIU:
1492 if (rs != 0) {
1493 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1494 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1495 } else {
1496 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1497 }
1498 opn = "addiu";
1499 break;
1500 #if defined(TARGET_MIPS64)
1501 case OPC_DADDI:
1502 {
1503 TCGv t0 = tcg_temp_local_new();
1504 TCGv t1 = tcg_temp_new();
1505 TCGv t2 = tcg_temp_new();
1506 int l1 = gen_new_label();
1507
1508 gen_load_gpr(t1, rs);
1509 tcg_gen_addi_tl(t0, t1, uimm);
1510
1511 tcg_gen_xori_tl(t1, t1, ~uimm);
1512 tcg_gen_xori_tl(t2, t0, uimm);
1513 tcg_gen_and_tl(t1, t1, t2);
1514 tcg_temp_free(t2);
1515 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1516 tcg_temp_free(t1);
1517 /* operands of same sign, result different sign */
1518 generate_exception(ctx, EXCP_OVERFLOW);
1519 gen_set_label(l1);
1520 gen_store_gpr(t0, rt);
1521 tcg_temp_free(t0);
1522 }
1523 opn = "daddi";
1524 break;
1525 case OPC_DADDIU:
1526 if (rs != 0) {
1527 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1528 } else {
1529 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1530 }
1531 opn = "daddiu";
1532 break;
1533 #endif
1534 }
1535 (void)opn; /* avoid a compiler warning */
1536 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1537 }
1538
1539 /* Logic with immediate operand */
1540 static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1541 int rt, int rs, int16_t imm)
1542 {
1543 target_ulong uimm;
1544 const char *opn = "imm logic";
1545
1546 if (rt == 0) {
1547 /* If no destination, treat it as a NOP. */
1548 MIPS_DEBUG("NOP");
1549 return;
1550 }
1551 uimm = (uint16_t)imm;
1552 switch (opc) {
1553 case OPC_ANDI:
1554 if (likely(rs != 0))
1555 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1556 else
1557 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1558 opn = "andi";
1559 break;
1560 case OPC_ORI:
1561 if (rs != 0)
1562 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1563 else
1564 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1565 opn = "ori";
1566 break;
1567 case OPC_XORI:
1568 if (likely(rs != 0))
1569 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1570 else
1571 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1572 opn = "xori";
1573 break;
1574 case OPC_LUI:
1575 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1576 opn = "lui";
1577 break;
1578 }
1579 (void)opn; /* avoid a compiler warning */
1580 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1581 }
1582
1583 /* Set on less than with immediate operand */
1584 static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1585 int rt, int rs, int16_t imm)
1586 {
1587 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1588 const char *opn = "imm arith";
1589 TCGv t0;
1590
1591 if (rt == 0) {
1592 /* If no destination, treat it as a NOP. */
1593 MIPS_DEBUG("NOP");
1594 return;
1595 }
1596 t0 = tcg_temp_new();
1597 gen_load_gpr(t0, rs);
1598 switch (opc) {
1599 case OPC_SLTI:
1600 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1601 opn = "slti";
1602 break;
1603 case OPC_SLTIU:
1604 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1605 opn = "sltiu";
1606 break;
1607 }
1608 (void)opn; /* avoid a compiler warning */
1609 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1610 tcg_temp_free(t0);
1611 }
1612
1613 /* Shifts with immediate operand */
1614 static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1615 int rt, int rs, int16_t imm)
1616 {
1617 target_ulong uimm = ((uint16_t)imm) & 0x1f;
1618 const char *opn = "imm shift";
1619 TCGv t0;
1620
1621 if (rt == 0) {
1622 /* If no destination, treat it as a NOP. */
1623 MIPS_DEBUG("NOP");
1624 return;
1625 }
1626
1627 t0 = tcg_temp_new();
1628 gen_load_gpr(t0, rs);
1629 switch (opc) {
1630 case OPC_SLL:
1631 tcg_gen_shli_tl(t0, t0, uimm);
1632 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1633 opn = "sll";
1634 break;
1635 case OPC_SRA:
1636 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1637 opn = "sra";
1638 break;
1639 case OPC_SRL:
1640 if (uimm != 0) {
1641 tcg_gen_ext32u_tl(t0, t0);
1642 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1643 } else {
1644 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1645 }
1646 opn = "srl";
1647 break;
1648 case OPC_ROTR:
1649 if (uimm != 0) {
1650 TCGv_i32 t1 = tcg_temp_new_i32();
1651
1652 tcg_gen_trunc_tl_i32(t1, t0);
1653 tcg_gen_rotri_i32(t1, t1, uimm);
1654 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1655 tcg_temp_free_i32(t1);
1656 } else {
1657 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1658 }
1659 opn = "rotr";
1660 break;
1661 #if defined(TARGET_MIPS64)
1662 case OPC_DSLL:
1663 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1664 opn = "dsll";
1665 break;
1666 case OPC_DSRA:
1667 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1668 opn = "dsra";
1669 break;
1670 case OPC_DSRL:
1671 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1672 opn = "dsrl";
1673 break;
1674 case OPC_DROTR:
1675 if (uimm != 0) {
1676 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1677 } else {
1678 tcg_gen_mov_tl(cpu_gpr[rt], t0);
1679 }
1680 opn = "drotr";
1681 break;
1682 case OPC_DSLL32:
1683 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1684 opn = "dsll32";
1685 break;
1686 case OPC_DSRA32:
1687 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1688 opn = "dsra32";
1689 break;
1690 case OPC_DSRL32:
1691 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1692 opn = "dsrl32";
1693 break;
1694 case OPC_DROTR32:
1695 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1696 opn = "drotr32";
1697 break;
1698 #endif
1699 }
1700 (void)opn; /* avoid a compiler warning */
1701 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1702 tcg_temp_free(t0);
1703 }
1704
1705 /* Arithmetic */
1706 static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1707 int rd, int rs, int rt)
1708 {
1709 const char *opn = "arith";
1710
1711 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1712 && opc != OPC_DADD && opc != OPC_DSUB) {
1713 /* If no destination, treat it as a NOP.
1714 For add & sub, we must generate the overflow exception when needed. */
1715 MIPS_DEBUG("NOP");
1716 return;
1717 }
1718
1719 switch (opc) {
1720 case OPC_ADD:
1721 {
1722 TCGv t0 = tcg_temp_local_new();
1723 TCGv t1 = tcg_temp_new();
1724 TCGv t2 = tcg_temp_new();
1725 int l1 = gen_new_label();
1726
1727 gen_load_gpr(t1, rs);
1728 gen_load_gpr(t2, rt);
1729 tcg_gen_add_tl(t0, t1, t2);
1730 tcg_gen_ext32s_tl(t0, t0);
1731 tcg_gen_xor_tl(t1, t1, t2);
1732 tcg_gen_xor_tl(t2, t0, t2);
1733 tcg_gen_andc_tl(t1, t2, t1);
1734 tcg_temp_free(t2);
1735 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1736 tcg_temp_free(t1);
1737 /* operands of same sign, result different sign */
1738 generate_exception(ctx, EXCP_OVERFLOW);
1739 gen_set_label(l1);
1740 gen_store_gpr(t0, rd);
1741 tcg_temp_free(t0);
1742 }
1743 opn = "add";
1744 break;
1745 case OPC_ADDU:
1746 if (rs != 0 && rt != 0) {
1747 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1748 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1749 } else if (rs == 0 && rt != 0) {
1750 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1751 } else if (rs != 0 && rt == 0) {
1752 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1753 } else {
1754 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1755 }
1756 opn = "addu";
1757 break;
1758 case OPC_SUB:
1759 {
1760 TCGv t0 = tcg_temp_local_new();
1761 TCGv t1 = tcg_temp_new();
1762 TCGv t2 = tcg_temp_new();
1763 int l1 = gen_new_label();
1764
1765 gen_load_gpr(t1, rs);
1766 gen_load_gpr(t2, rt);
1767 tcg_gen_sub_tl(t0, t1, t2);
1768 tcg_gen_ext32s_tl(t0, t0);
1769 tcg_gen_xor_tl(t2, t1, t2);
1770 tcg_gen_xor_tl(t1, t0, t1);
1771 tcg_gen_and_tl(t1, t1, t2);
1772 tcg_temp_free(t2);
1773 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1774 tcg_temp_free(t1);
1775 /* operands of different sign, first operand and result different sign */
1776 generate_exception(ctx, EXCP_OVERFLOW);
1777 gen_set_label(l1);
1778 gen_store_gpr(t0, rd);
1779 tcg_temp_free(t0);
1780 }
1781 opn = "sub";
1782 break;
1783 case OPC_SUBU:
1784 if (rs != 0 && rt != 0) {
1785 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1786 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1787 } else if (rs == 0 && rt != 0) {
1788 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1789 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1790 } else if (rs != 0 && rt == 0) {
1791 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1792 } else {
1793 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1794 }
1795 opn = "subu";
1796 break;
1797 #if defined(TARGET_MIPS64)
1798 case OPC_DADD:
1799 {
1800 TCGv t0 = tcg_temp_local_new();
1801 TCGv t1 = tcg_temp_new();
1802 TCGv t2 = tcg_temp_new();
1803 int l1 = gen_new_label();
1804
1805 gen_load_gpr(t1, rs);
1806 gen_load_gpr(t2, rt);
1807 tcg_gen_add_tl(t0, t1, t2);
1808 tcg_gen_xor_tl(t1, t1, t2);
1809 tcg_gen_xor_tl(t2, t0, t2);
1810 tcg_gen_andc_tl(t1, t2, t1);
1811 tcg_temp_free(t2);
1812 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1813 tcg_temp_free(t1);
1814 /* operands of same sign, result different sign */
1815 generate_exception(ctx, EXCP_OVERFLOW);
1816 gen_set_label(l1);
1817 gen_store_gpr(t0, rd);
1818 tcg_temp_free(t0);
1819 }
1820 opn = "dadd";
1821 break;
1822 case OPC_DADDU:
1823 if (rs != 0 && rt != 0) {
1824 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1825 } else if (rs == 0 && rt != 0) {
1826 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1827 } else if (rs != 0 && rt == 0) {
1828 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1829 } else {
1830 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1831 }
1832 opn = "daddu";
1833 break;
1834 case OPC_DSUB:
1835 {
1836 TCGv t0 = tcg_temp_local_new();
1837 TCGv t1 = tcg_temp_new();
1838 TCGv t2 = tcg_temp_new();
1839 int l1 = gen_new_label();
1840
1841 gen_load_gpr(t1, rs);
1842 gen_load_gpr(t2, rt);
1843 tcg_gen_sub_tl(t0, t1, t2);
1844 tcg_gen_xor_tl(t2, t1, t2);
1845 tcg_gen_xor_tl(t1, t0, t1);
1846 tcg_gen_and_tl(t1, t1, t2);
1847 tcg_temp_free(t2);
1848 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1849 tcg_temp_free(t1);
1850 /* operands of different sign, first operand and result different sign */
1851 generate_exception(ctx, EXCP_OVERFLOW);
1852 gen_set_label(l1);
1853 gen_store_gpr(t0, rd);
1854 tcg_temp_free(t0);
1855 }
1856 opn = "dsub";
1857 break;
1858 case OPC_DSUBU:
1859 if (rs != 0 && rt != 0) {
1860 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1861 } else if (rs == 0 && rt != 0) {
1862 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1863 } else if (rs != 0 && rt == 0) {
1864 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1865 } else {
1866 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1867 }
1868 opn = "dsubu";
1869 break;
1870 #endif
1871 case OPC_MUL:
1872 if (likely(rs != 0 && rt != 0)) {
1873 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1874 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1875 } else {
1876 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1877 }
1878 opn = "mul";
1879 break;
1880 }
1881 (void)opn; /* avoid a compiler warning */
1882 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1883 }
1884
1885 /* Conditional move */
1886 static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1887 int rd, int rs, int rt)
1888 {
1889 const char *opn = "cond move";
1890 int l1;
1891
1892 if (rd == 0) {
1893 /* If no destination, treat it as a NOP.
1894 For add & sub, we must generate the overflow exception when needed. */
1895 MIPS_DEBUG("NOP");
1896 return;
1897 }
1898
1899 l1 = gen_new_label();
1900 switch (opc) {
1901 case OPC_MOVN:
1902 if (likely(rt != 0))
1903 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1904 else
1905 tcg_gen_br(l1);
1906 opn = "movn";
1907 break;
1908 case OPC_MOVZ:
1909 if (likely(rt != 0))
1910 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1911 opn = "movz";
1912 break;
1913 }
1914 if (rs != 0)
1915 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1916 else
1917 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1918 gen_set_label(l1);
1919
1920 (void)opn; /* avoid a compiler warning */
1921 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1922 }
1923
1924 /* Logic */
1925 static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1926 int rd, int rs, int rt)
1927 {
1928 const char *opn = "logic";
1929
1930 if (rd == 0) {
1931 /* If no destination, treat it as a NOP. */
1932 MIPS_DEBUG("NOP");
1933 return;
1934 }
1935
1936 switch (opc) {
1937 case OPC_AND:
1938 if (likely(rs != 0 && rt != 0)) {
1939 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1940 } else {
1941 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1942 }
1943 opn = "and";
1944 break;
1945 case OPC_NOR:
1946 if (rs != 0 && rt != 0) {
1947 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1948 } else if (rs == 0 && rt != 0) {
1949 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1950 } else if (rs != 0 && rt == 0) {
1951 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1952 } else {
1953 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1954 }
1955 opn = "nor";
1956 break;
1957 case OPC_OR:
1958 if (likely(rs != 0 && rt != 0)) {
1959 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1960 } else if (rs == 0 && rt != 0) {
1961 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1962 } else if (rs != 0 && rt == 0) {
1963 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1964 } else {
1965 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1966 }
1967 opn = "or";
1968 break;
1969 case OPC_XOR:
1970 if (likely(rs != 0 && rt != 0)) {
1971 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1972 } else if (rs == 0 && rt != 0) {
1973 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1974 } else if (rs != 0 && rt == 0) {
1975 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1976 } else {
1977 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1978 }
1979 opn = "xor";
1980 break;
1981 }
1982 (void)opn; /* avoid a compiler warning */
1983 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1984 }
1985
1986 /* Set on lower than */
1987 static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1988 int rd, int rs, int rt)
1989 {
1990 const char *opn = "slt";
1991 TCGv t0, t1;
1992
1993 if (rd == 0) {
1994 /* If no destination, treat it as a NOP. */
1995 MIPS_DEBUG("NOP");
1996 return;
1997 }
1998
1999 t0 = tcg_temp_new();
2000 t1 = tcg_temp_new();
2001 gen_load_gpr(t0, rs);
2002 gen_load_gpr(t1, rt);
2003 switch (opc) {
2004 case OPC_SLT:
2005 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2006 opn = "slt";
2007 break;
2008 case OPC_SLTU:
2009 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2010 opn = "sltu";
2011 break;
2012 }
2013 (void)opn; /* avoid a compiler warning */
2014 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2015 tcg_temp_free(t0);
2016 tcg_temp_free(t1);
2017 }
2018
2019 /* Shifts */
2020 static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2021 int rd, int rs, int rt)
2022 {
2023 const char *opn = "shifts";
2024 TCGv t0, t1;
2025
2026 if (rd == 0) {
2027 /* If no destination, treat it as a NOP.
2028 For add & sub, we must generate the overflow exception when needed. */
2029 MIPS_DEBUG("NOP");
2030 return;
2031 }
2032
2033 t0 = tcg_temp_new();
2034 t1 = tcg_temp_new();
2035 gen_load_gpr(t0, rs);
2036 gen_load_gpr(t1, rt);
2037 switch (opc) {
2038 case OPC_SLLV:
2039 tcg_gen_andi_tl(t0, t0, 0x1f);
2040 tcg_gen_shl_tl(t0, t1, t0);
2041 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2042 opn = "sllv";
2043 break;
2044 case OPC_SRAV:
2045 tcg_gen_andi_tl(t0, t0, 0x1f);
2046 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2047 opn = "srav";
2048 break;
2049 case OPC_SRLV:
2050 tcg_gen_ext32u_tl(t1, t1);
2051 tcg_gen_andi_tl(t0, t0, 0x1f);
2052 tcg_gen_shr_tl(t0, t1, t0);
2053 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2054 opn = "srlv";
2055 break;
2056 case OPC_ROTRV:
2057 {
2058 TCGv_i32 t2 = tcg_temp_new_i32();
2059 TCGv_i32 t3 = tcg_temp_new_i32();
2060
2061 tcg_gen_trunc_tl_i32(t2, t0);
2062 tcg_gen_trunc_tl_i32(t3, t1);
2063 tcg_gen_andi_i32(t2, t2, 0x1f);
2064 tcg_gen_rotr_i32(t2, t3, t2);
2065 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2066 tcg_temp_free_i32(t2);
2067 tcg_temp_free_i32(t3);
2068 opn = "rotrv";
2069 }
2070 break;
2071 #if defined(TARGET_MIPS64)
2072 case OPC_DSLLV:
2073 tcg_gen_andi_tl(t0, t0, 0x3f);
2074 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2075 opn = "dsllv";
2076 break;
2077 case OPC_DSRAV:
2078 tcg_gen_andi_tl(t0, t0, 0x3f);
2079 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2080 opn = "dsrav";
2081 break;
2082 case OPC_DSRLV:
2083 tcg_gen_andi_tl(t0, t0, 0x3f);
2084 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2085 opn = "dsrlv";
2086 break;
2087 case OPC_DROTRV:
2088 tcg_gen_andi_tl(t0, t0, 0x3f);
2089 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2090 opn = "drotrv";
2091 break;
2092 #endif
2093 }
2094 (void)opn; /* avoid a compiler warning */
2095 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2096 tcg_temp_free(t0);
2097 tcg_temp_free(t1);
2098 }
2099
2100 /* Arithmetic on HI/LO registers */
2101 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
2102 {
2103 const char *opn = "hilo";
2104
2105 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2106 /* Treat as NOP. */
2107 MIPS_DEBUG("NOP");
2108 return;
2109 }
2110 switch (opc) {
2111 case OPC_MFHI:
2112 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
2113 opn = "mfhi";
2114 break;
2115 case OPC_MFLO:
2116 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
2117 opn = "mflo";
2118 break;
2119 case OPC_MTHI:
2120 if (reg != 0)
2121 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
2122 else
2123 tcg_gen_movi_tl(cpu_HI[0], 0);
2124 opn = "mthi";
2125 break;
2126 case OPC_MTLO:
2127 if (reg != 0)
2128 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2129 else
2130 tcg_gen_movi_tl(cpu_LO[0], 0);
2131 opn = "mtlo";
2132 break;
2133 }
2134 (void)opn; /* avoid a compiler warning */
2135 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2136 }
2137
2138 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2139 int rs, int rt)
2140 {
2141 const char *opn = "mul/div";
2142 TCGv t0, t1;
2143
2144 switch (opc) {
2145 case OPC_DIV:
2146 case OPC_DIVU:
2147 #if defined(TARGET_MIPS64)
2148 case OPC_DDIV:
2149 case OPC_DDIVU:
2150 #endif
2151 t0 = tcg_temp_local_new();
2152 t1 = tcg_temp_local_new();
2153 break;
2154 default:
2155 t0 = tcg_temp_new();
2156 t1 = tcg_temp_new();
2157 break;
2158 }
2159
2160 gen_load_gpr(t0, rs);
2161 gen_load_gpr(t1, rt);
2162 switch (opc) {
2163 case OPC_DIV:
2164 {
2165 int l1 = gen_new_label();
2166 int l2 = gen_new_label();
2167
2168 tcg_gen_ext32s_tl(t0, t0);
2169 tcg_gen_ext32s_tl(t1, t1);
2170 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2171 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2172 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2173
2174 tcg_gen_mov_tl(cpu_LO[0], t0);
2175 tcg_gen_movi_tl(cpu_HI[0], 0);
2176 tcg_gen_br(l1);
2177 gen_set_label(l2);
2178 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2179 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2180 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2181 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2182 gen_set_label(l1);
2183 }
2184 opn = "div";
2185 break;
2186 case OPC_DIVU:
2187 {
2188 int l1 = gen_new_label();
2189
2190 tcg_gen_ext32u_tl(t0, t0);
2191 tcg_gen_ext32u_tl(t1, t1);
2192 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2193 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2194 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2195 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2196 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2197 gen_set_label(l1);
2198 }
2199 opn = "divu";
2200 break;
2201 case OPC_MULT:
2202 {
2203 TCGv_i64 t2 = tcg_temp_new_i64();
2204 TCGv_i64 t3 = tcg_temp_new_i64();
2205
2206 tcg_gen_ext_tl_i64(t2, t0);
2207 tcg_gen_ext_tl_i64(t3, t1);
2208 tcg_gen_mul_i64(t2, t2, t3);
2209 tcg_temp_free_i64(t3);
2210 tcg_gen_trunc_i64_tl(t0, t2);
2211 tcg_gen_shri_i64(t2, t2, 32);
2212 tcg_gen_trunc_i64_tl(t1, t2);
2213 tcg_temp_free_i64(t2);
2214 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2215 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2216 }
2217 opn = "mult";
2218 break;
2219 case OPC_MULTU:
2220 {
2221 TCGv_i64 t2 = tcg_temp_new_i64();
2222 TCGv_i64 t3 = tcg_temp_new_i64();
2223
2224 tcg_gen_ext32u_tl(t0, t0);
2225 tcg_gen_ext32u_tl(t1, t1);
2226 tcg_gen_extu_tl_i64(t2, t0);
2227 tcg_gen_extu_tl_i64(t3, t1);
2228 tcg_gen_mul_i64(t2, t2, t3);
2229 tcg_temp_free_i64(t3);
2230 tcg_gen_trunc_i64_tl(t0, t2);
2231 tcg_gen_shri_i64(t2, t2, 32);
2232 tcg_gen_trunc_i64_tl(t1, t2);
2233 tcg_temp_free_i64(t2);
2234 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2235 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2236 }
2237 opn = "multu";
2238 break;
2239 #if defined(TARGET_MIPS64)
2240 case OPC_DDIV:
2241 {
2242 int l1 = gen_new_label();
2243 int l2 = gen_new_label();
2244
2245 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2246 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2247 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2248 tcg_gen_mov_tl(cpu_LO[0], t0);
2249 tcg_gen_movi_tl(cpu_HI[0], 0);
2250 tcg_gen_br(l1);
2251 gen_set_label(l2);
2252 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2253 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2254 gen_set_label(l1);
2255 }
2256 opn = "ddiv";
2257 break;
2258 case OPC_DDIVU:
2259 {
2260 int l1 = gen_new_label();
2261
2262 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2263 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2264 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2265 gen_set_label(l1);
2266 }
2267 opn = "ddivu";
2268 break;
2269 case OPC_DMULT:
2270 gen_helper_dmult(cpu_env, t0, t1);
2271 opn = "dmult";
2272 break;
2273 case OPC_DMULTU:
2274 gen_helper_dmultu(cpu_env, t0, t1);
2275 opn = "dmultu";
2276 break;
2277 #endif
2278 case OPC_MADD:
2279 {
2280 TCGv_i64 t2 = tcg_temp_new_i64();
2281 TCGv_i64 t3 = tcg_temp_new_i64();
2282
2283 tcg_gen_ext_tl_i64(t2, t0);
2284 tcg_gen_ext_tl_i64(t3, t1);
2285 tcg_gen_mul_i64(t2, t2, t3);
2286 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2287 tcg_gen_add_i64(t2, t2, t3);
2288 tcg_temp_free_i64(t3);
2289 tcg_gen_trunc_i64_tl(t0, t2);
2290 tcg_gen_shri_i64(t2, t2, 32);
2291 tcg_gen_trunc_i64_tl(t1, t2);
2292 tcg_temp_free_i64(t2);
2293 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2294 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2295 }
2296 opn = "madd";
2297 break;
2298 case OPC_MADDU:
2299 {
2300 TCGv_i64 t2 = tcg_temp_new_i64();
2301 TCGv_i64 t3 = tcg_temp_new_i64();
2302
2303 tcg_gen_ext32u_tl(t0, t0);
2304 tcg_gen_ext32u_tl(t1, t1);
2305 tcg_gen_extu_tl_i64(t2, t0);
2306 tcg_gen_extu_tl_i64(t3, t1);
2307 tcg_gen_mul_i64(t2, t2, t3);
2308 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2309 tcg_gen_add_i64(t2, t2, t3);
2310 tcg_temp_free_i64(t3);
2311 tcg_gen_trunc_i64_tl(t0, t2);
2312 tcg_gen_shri_i64(t2, t2, 32);
2313 tcg_gen_trunc_i64_tl(t1, t2);
2314 tcg_temp_free_i64(t2);
2315 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2316 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2317 }
2318 opn = "maddu";
2319 break;
2320 case OPC_MSUB:
2321 {
2322 TCGv_i64 t2 = tcg_temp_new_i64();
2323 TCGv_i64 t3 = tcg_temp_new_i64();
2324
2325 tcg_gen_ext_tl_i64(t2, t0);
2326 tcg_gen_ext_tl_i64(t3, t1);
2327 tcg_gen_mul_i64(t2, t2, t3);
2328 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2329 tcg_gen_sub_i64(t2, t3, t2);
2330 tcg_temp_free_i64(t3);
2331 tcg_gen_trunc_i64_tl(t0, t2);
2332 tcg_gen_shri_i64(t2, t2, 32);
2333 tcg_gen_trunc_i64_tl(t1, t2);
2334 tcg_temp_free_i64(t2);
2335 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2336 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2337 }
2338 opn = "msub";
2339 break;
2340 case OPC_MSUBU:
2341 {
2342 TCGv_i64 t2 = tcg_temp_new_i64();
2343 TCGv_i64 t3 = tcg_temp_new_i64();
2344
2345 tcg_gen_ext32u_tl(t0, t0);
2346 tcg_gen_ext32u_tl(t1, t1);
2347 tcg_gen_extu_tl_i64(t2, t0);
2348 tcg_gen_extu_tl_i64(t3, t1);
2349 tcg_gen_mul_i64(t2, t2, t3);
2350 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2351 tcg_gen_sub_i64(t2, t3, t2);
2352 tcg_temp_free_i64(t3);
2353 tcg_gen_trunc_i64_tl(t0, t2);
2354 tcg_gen_shri_i64(t2, t2, 32);
2355 tcg_gen_trunc_i64_tl(t1, t2);
2356 tcg_temp_free_i64(t2);
2357 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2358 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2359 }
2360 opn = "msubu";
2361 break;
2362 default:
2363 MIPS_INVAL(opn);
2364 generate_exception(ctx, EXCP_RI);
2365 goto out;
2366 }
2367 (void)opn; /* avoid a compiler warning */
2368 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2369 out:
2370 tcg_temp_free(t0);
2371 tcg_temp_free(t1);
2372 }
2373
2374 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2375 int rd, int rs, int rt)
2376 {
2377 const char *opn = "mul vr54xx";
2378 TCGv t0 = tcg_temp_new();
2379 TCGv t1 = tcg_temp_new();
2380
2381 gen_load_gpr(t0, rs);
2382 gen_load_gpr(t1, rt);
2383
2384 switch (opc) {
2385 case OPC_VR54XX_MULS:
2386 gen_helper_muls(t0, cpu_env, t0, t1);
2387 opn = "muls";
2388 break;
2389 case OPC_VR54XX_MULSU:
2390 gen_helper_mulsu(t0, cpu_env, t0, t1);
2391 opn = "mulsu";
2392 break;
2393 case OPC_VR54XX_MACC:
2394 gen_helper_macc(t0, cpu_env, t0, t1);
2395 opn = "macc";
2396 break;
2397 case OPC_VR54XX_MACCU:
2398 gen_helper_maccu(t0, cpu_env, t0, t1);
2399 opn = "maccu";
2400 break;
2401 case OPC_VR54XX_MSAC:
2402 gen_helper_msac(t0, cpu_env, t0, t1);
2403 opn = "msac";
2404 break;
2405 case OPC_VR54XX_MSACU:
2406 gen_helper_msacu(t0, cpu_env, t0, t1);
2407 opn = "msacu";
2408 break;
2409 case OPC_VR54XX_MULHI:
2410 gen_helper_mulhi(t0, cpu_env, t0, t1);
2411 opn = "mulhi";
2412 break;
2413 case OPC_VR54XX_MULHIU:
2414 gen_helper_mulhiu(t0, cpu_env, t0, t1);
2415 opn = "mulhiu";
2416 break;
2417 case OPC_VR54XX_MULSHI:
2418 gen_helper_mulshi(t0, cpu_env, t0, t1);
2419 opn = "mulshi";
2420 break;
2421 case OPC_VR54XX_MULSHIU:
2422 gen_helper_mulshiu(t0, cpu_env, t0, t1);
2423 opn = "mulshiu";
2424 break;
2425 case OPC_VR54XX_MACCHI:
2426 gen_helper_macchi(t0, cpu_env, t0, t1);
2427 opn = "macchi";
2428 break;
2429 case OPC_VR54XX_MACCHIU:
2430 gen_helper_macchiu(t0, cpu_env, t0, t1);
2431 opn = "macchiu";
2432 break;
2433 case OPC_VR54XX_MSACHI:
2434 gen_helper_msachi(t0, cpu_env, t0, t1);
2435 opn = "msachi";
2436 break;
2437 case OPC_VR54XX_MSACHIU:
2438 gen_helper_msachiu(t0, cpu_env, t0, t1);
2439 opn = "msachiu";
2440 break;
2441 default:
2442 MIPS_INVAL("mul vr54xx");
2443 generate_exception(ctx, EXCP_RI);
2444 goto out;
2445 }
2446 gen_store_gpr(t0, rd);
2447 (void)opn; /* avoid a compiler warning */
2448 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2449
2450 out:
2451 tcg_temp_free(t0);
2452 tcg_temp_free(t1);
2453 }
2454
2455 static void gen_cl (DisasContext *ctx, uint32_t opc,
2456 int rd, int rs)
2457 {
2458 const char *opn = "CLx";
2459 TCGv t0;
2460
2461 if (rd == 0) {
2462 /* Treat as NOP. */
2463 MIPS_DEBUG("NOP");
2464 return;
2465 }
2466 t0 = tcg_temp_new();
2467 gen_load_gpr(t0, rs);
2468 switch (opc) {
2469 case OPC_CLO:
2470 gen_helper_clo(cpu_gpr[rd], t0);
2471 opn = "clo";
2472 break;
2473 case OPC_CLZ:
2474 gen_helper_clz(cpu_gpr[rd], t0);
2475 opn = "clz";
2476 break;
2477 #if defined(TARGET_MIPS64)
2478 case OPC_DCLO:
2479 gen_helper_dclo(cpu_gpr[rd], t0);
2480 opn = "dclo";
2481 break;
2482 case OPC_DCLZ:
2483 gen_helper_dclz(cpu_gpr[rd], t0);
2484 opn = "dclz";
2485 break;
2486 #endif
2487 }
2488 (void)opn; /* avoid a compiler warning */
2489 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2490 tcg_temp_free(t0);
2491 }
2492
2493 /* Godson integer instructions */
2494 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2495 int rd, int rs, int rt)
2496 {
2497 const char *opn = "loongson";
2498 TCGv t0, t1;
2499
2500 if (rd == 0) {
2501 /* Treat as NOP. */
2502 MIPS_DEBUG("NOP");
2503 return;
2504 }
2505
2506 switch (opc) {
2507 case OPC_MULT_G_2E:
2508 case OPC_MULT_G_2F:
2509 case OPC_MULTU_G_2E:
2510 case OPC_MULTU_G_2F:
2511 #if defined(TARGET_MIPS64)
2512 case OPC_DMULT_G_2E:
2513 case OPC_DMULT_G_2F:
2514 case OPC_DMULTU_G_2E:
2515 case OPC_DMULTU_G_2F:
2516 #endif
2517 t0 = tcg_temp_new();
2518 t1 = tcg_temp_new();
2519 break;
2520 default:
2521 t0 = tcg_temp_local_new();
2522 t1 = tcg_temp_local_new();
2523 break;
2524 }
2525
2526 gen_load_gpr(t0, rs);
2527 gen_load_gpr(t1, rt);
2528
2529 switch (opc) {
2530 case OPC_MULT_G_2E:
2531 case OPC_MULT_G_2F:
2532 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2533 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2534 opn = "mult.g";
2535 break;
2536 case OPC_MULTU_G_2E:
2537 case OPC_MULTU_G_2F:
2538 tcg_gen_ext32u_tl(t0, t0);
2539 tcg_gen_ext32u_tl(t1, t1);
2540 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2541 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2542 opn = "multu.g";
2543 break;
2544 case OPC_DIV_G_2E:
2545 case OPC_DIV_G_2F:
2546 {
2547 int l1 = gen_new_label();
2548 int l2 = gen_new_label();
2549 int l3 = gen_new_label();
2550 tcg_gen_ext32s_tl(t0, t0);
2551 tcg_gen_ext32s_tl(t1, t1);
2552 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2553 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2554 tcg_gen_br(l3);
2555 gen_set_label(l1);
2556 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2557 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2558 tcg_gen_mov_tl(cpu_gpr[rd], t0);
2559 tcg_gen_br(l3);
2560 gen_set_label(l2);
2561 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2562 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2563 gen_set_label(l3);
2564 }
2565 opn = "div.g";
2566 break;
2567 case OPC_DIVU_G_2E:
2568 case OPC_DIVU_G_2F:
2569 {
2570 int l1 = gen_new_label();
2571 int l2 = gen_new_label();
2572 tcg_gen_ext32u_tl(t0, t0);
2573 tcg_gen_ext32u_tl(t1, t1);
2574 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2575 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2576 tcg_gen_br(l2);
2577 gen_set_label(l1);
2578 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2579 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2580 gen_set_label(l2);
2581 }
2582 opn = "divu.g";
2583 break;
2584 case OPC_MOD_G_2E:
2585 case OPC_MOD_G_2F:
2586 {
2587 int l1 = gen_new_label();
2588 int l2 = gen_new_label();
2589 int l3 = gen_new_label();
2590 tcg_gen_ext32u_tl(t0, t0);
2591 tcg_gen_ext32u_tl(t1, t1);
2592 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2593 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2594 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2595 gen_set_label(l1);
2596 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2597 tcg_gen_br(l3);
2598 gen_set_label(l2);
2599 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2600 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2601 gen_set_label(l3);
2602 }
2603 opn = "mod.g";
2604 break;
2605 case OPC_MODU_G_2E:
2606 case OPC_MODU_G_2F:
2607 {
2608 int l1 = gen_new_label();
2609 int l2 = gen_new_label();
2610 tcg_gen_ext32u_tl(t0, t0);
2611 tcg_gen_ext32u_tl(t1, t1);
2612 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2613 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2614 tcg_gen_br(l2);
2615 gen_set_label(l1);
2616 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2617 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2618 gen_set_label(l2);
2619 }
2620 opn = "modu.g";
2621 break;
2622 #if defined(TARGET_MIPS64)
2623 case OPC_DMULT_G_2E:
2624 case OPC_DMULT_G_2F:
2625 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2626 opn = "dmult.g";
2627 break;
2628 case OPC_DMULTU_G_2E:
2629 case OPC_DMULTU_G_2F:
2630 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
2631 opn = "dmultu.g";
2632 break;
2633 case OPC_DDIV_G_2E:
2634 case OPC_DDIV_G_2F:
2635 {
2636 int l1 = gen_new_label();
2637 int l2 = gen_new_label();
2638 int l3 = gen_new_label();
2639 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2640 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2641 tcg_gen_br(l3);
2642 gen_set_label(l1);
2643 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2644 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2645 tcg_gen_mov_tl(cpu_gpr[rd], t0);
2646 tcg_gen_br(l3);
2647 gen_set_label(l2);
2648 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
2649 gen_set_label(l3);
2650 }
2651 opn = "ddiv.g";
2652 break;
2653 case OPC_DDIVU_G_2E:
2654 case OPC_DDIVU_G_2F:
2655 {
2656 int l1 = gen_new_label();
2657 int l2 = gen_new_label();
2658 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2659 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2660 tcg_gen_br(l2);
2661 gen_set_label(l1);
2662 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
2663 gen_set_label(l2);
2664 }
2665 opn = "ddivu.g";
2666 break;
2667 case OPC_DMOD_G_2E:
2668 case OPC_DMOD_G_2F:
2669 {
2670 int l1 = gen_new_label();
2671 int l2 = gen_new_label();
2672 int l3 = gen_new_label();
2673 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2674 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2675 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2676 gen_set_label(l1);
2677 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2678 tcg_gen_br(l3);
2679 gen_set_label(l2);
2680 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
2681 gen_set_label(l3);
2682 }
2683 opn = "dmod.g";
2684 break;
2685 case OPC_DMODU_G_2E:
2686 case OPC_DMODU_G_2F:
2687 {
2688 int l1 = gen_new_label();
2689 int l2 = gen_new_label();
2690 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
2691 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2692 tcg_gen_br(l2);
2693 gen_set_label(l1);
2694 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
2695 gen_set_label(l2);
2696 }
2697 opn = "dmodu.g";
2698 break;
2699 #endif
2700 }
2701
2702 (void)opn; /* avoid a compiler warning */
2703 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2704 tcg_temp_free(t0);
2705 tcg_temp_free(t1);
2706 }
2707
2708 /* Loongson multimedia instructions */
2709 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
2710 {
2711 const char *opn = "loongson_cp2";
2712 uint32_t opc, shift_max;
2713 TCGv_i64 t0, t1;
2714
2715 opc = MASK_LMI(ctx->opcode);
2716 switch (opc) {
2717 case OPC_ADD_CP2:
2718 case OPC_SUB_CP2:
2719 case OPC_DADD_CP2:
2720 case OPC_DSUB_CP2:
2721 t0 = tcg_temp_local_new_i64();
2722 t1 = tcg_temp_local_new_i64();
2723 break;
2724 default:
2725 t0 = tcg_temp_new_i64();
2726 t1 = tcg_temp_new_i64();
2727 break;
2728 }
2729
2730 gen_load_fpr64(ctx, t0, rs);
2731 gen_load_fpr64(ctx, t1, rt);
2732
2733 #define LMI_HELPER(UP, LO) \
2734 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
2735 #define LMI_HELPER_1(UP, LO) \
2736 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
2737 #define LMI_DIRECT(UP, LO, OP) \
2738 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
2739
2740 switch (opc) {
2741 LMI_HELPER(PADDSH, paddsh);
2742 LMI_HELPER(PADDUSH, paddush);
2743 LMI_HELPER(PADDH, paddh);
2744 LMI_HELPER(PADDW, paddw);
2745 LMI_HELPER(PADDSB, paddsb);
2746 LMI_HELPER(PADDUSB, paddusb);
2747 LMI_HELPER(PADDB, paddb);
2748
2749 LMI_HELPER(PSUBSH, psubsh);
2750 LMI_HELPER(PSUBUSH, psubush);
2751 LMI_HELPER(PSUBH, psubh);
2752 LMI_HELPER(PSUBW, psubw);
2753 LMI_HELPER(PSUBSB, psubsb);
2754 LMI_HELPER(PSUBUSB, psubusb);
2755 LMI_HELPER(PSUBB, psubb);
2756
2757 LMI_HELPER(PSHUFH, pshufh);
2758 LMI_HELPER(PACKSSWH, packsswh);
2759 LMI_HELPER(PACKSSHB, packsshb);
2760 LMI_HELPER(PACKUSHB, packushb);
2761
2762 LMI_HELPER(PUNPCKLHW, punpcklhw);
2763 LMI_HELPER(PUNPCKHHW, punpckhhw);
2764 LMI_HELPER(PUNPCKLBH, punpcklbh);
2765 LMI_HELPER(PUNPCKHBH, punpckhbh);
2766 LMI_HELPER(PUNPCKLWD, punpcklwd);
2767 LMI_HELPER(PUNPCKHWD, punpckhwd);
2768
2769 LMI_HELPER(PAVGH, pavgh);
2770 LMI_HELPER(PAVGB, pavgb);
2771 LMI_HELPER(PMAXSH, pmaxsh);
2772 LMI_HELPER(PMINSH, pminsh);
2773 LMI_HELPER(PMAXUB, pmaxub);
2774 LMI_HELPER(PMINUB, pminub);
2775
2776 LMI_HELPER(PCMPEQW, pcmpeqw);
2777 LMI_HELPER(PCMPGTW, pcmpgtw);
2778 LMI_HELPER(PCMPEQH, pcmpeqh);
2779 LMI_HELPER(PCMPGTH, pcmpgth);
2780 LMI_HELPER(PCMPEQB, pcmpeqb);
2781 LMI_HELPER(PCMPGTB, pcmpgtb);
2782
2783 LMI_HELPER(PSLLW, psllw);
2784 LMI_HELPER(PSLLH, psllh);
2785 LMI_HELPER(PSRLW, psrlw);
2786 LMI_HELPER(PSRLH, psrlh);
2787 LMI_HELPER(PSRAW, psraw);
2788 LMI_HELPER(PSRAH, psrah);
2789
2790 LMI_HELPER(PMULLH, pmullh);
2791 LMI_HELPER(PMULHH, pmulhh);
2792 LMI_HELPER(PMULHUH, pmulhuh);
2793 LMI_HELPER(PMADDHW, pmaddhw);
2794
2795 LMI_HELPER(PASUBUB, pasubub);
2796 LMI_HELPER_1(BIADD, biadd);
2797 LMI_HELPER_1(PMOVMSKB, pmovmskb);
2798
2799 LMI_DIRECT(PADDD, paddd, add);
2800 LMI_DIRECT(PSUBD, psubd, sub);
2801 LMI_DIRECT(XOR_CP2, xor, xor);
2802 LMI_DIRECT(NOR_CP2, nor, nor);
2803 LMI_DIRECT(AND_CP2, and, and);
2804 LMI_DIRECT(PANDN, pandn, andc);
2805 LMI_DIRECT(OR, or, or);
2806
2807 case OPC_PINSRH_0:
2808 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
2809 opn = "pinsrh_0";
2810 break;
2811 case OPC_PINSRH_1:
2812 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
2813 opn = "pinsrh_1";
2814 break;
2815 case OPC_PINSRH_2:
2816 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
2817 opn = "pinsrh_2";
2818 break;
2819 case OPC_PINSRH_3:
2820 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
2821 opn = "pinsrh_3";
2822 break;
2823
2824 case OPC_PEXTRH:
2825 tcg_gen_andi_i64(t1, t1, 3);
2826 tcg_gen_shli_i64(t1, t1, 4);
2827 tcg_gen_shr_i64(t0, t0, t1);
2828 tcg_gen_ext16u_i64(t0, t0);
2829 opn = "pextrh";
2830 break;
2831
2832 case OPC_ADDU_CP2:
2833 tcg_gen_add_i64(t0, t0, t1);
2834 tcg_gen_ext32s_i64(t0, t0);
2835 opn = "addu";
2836 break;
2837 case OPC_SUBU_CP2:
2838 tcg_gen_sub_i64(t0, t0, t1);
2839 tcg_gen_ext32s_i64(t0, t0);
2840 opn = "addu";
2841 break;
2842
2843 case OPC_SLL_CP2:
2844 opn = "sll";
2845 shift_max = 32;
2846 goto do_shift;
2847 case OPC_SRL_CP2:
2848 opn = "srl";
2849 shift_max = 32;
2850 goto do_shift;
2851 case OPC_SRA_CP2:
2852 opn = "sra";
2853 shift_max = 32;
2854 goto do_shift;
2855 case OPC_DSLL_CP2:
2856 opn = "dsll";
2857 shift_max = 64;
2858 goto do_shift;
2859 case OPC_DSRL_CP2:
2860 opn = "dsrl";
2861 shift_max = 64;
2862 goto do_shift;
2863 case OPC_DSRA_CP2:
2864 opn = "dsra";
2865 shift_max = 64;
2866 goto do_shift;
2867 do_shift:
2868 /* Make sure shift count isn't TCG undefined behaviour. */
2869 tcg_gen_andi_i64(t1, t1, shift_max - 1);
2870
2871 switch (opc) {
2872 case OPC_SLL_CP2:
2873 case OPC_DSLL_CP2:
2874 tcg_gen_shl_i64(t0, t0, t1);
2875 break;
2876 case OPC_SRA_CP2:
2877 case OPC_DSRA_CP2:
2878 /* Since SRA is UndefinedResult without sign-extended inputs,
2879 we can treat SRA and DSRA the same. */
2880 tcg_gen_sar_i64(t0, t0, t1);
2881 break;
2882 case OPC_SRL_CP2:
2883 /* We want to shift in zeros for SRL; zero-extend first. */
2884 tcg_gen_ext32u_i64(t0, t0);
2885 /* FALLTHRU */
2886 case OPC_DSRL_CP2:
2887 tcg_gen_shr_i64(t0, t0, t1);
2888 break;
2889 }
2890
2891 if (shift_max == 32) {
2892 tcg_gen_ext32s_i64(t0, t0);
2893 }
2894
2895 /* Shifts larger than MAX produce zero. */
2896 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
2897 tcg_gen_neg_i64(t1, t1);
2898 tcg_gen_and_i64(t0, t0, t1);
2899 break;
2900
2901 case OPC_ADD_CP2:
2902 case OPC_DADD_CP2:
2903 {
2904 TCGv_i64 t2 = tcg_temp_new_i64();
2905 int lab = gen_new_label();
2906
2907 tcg_gen_mov_i64(t2, t0);
2908 tcg_gen_add_i64(t0, t1, t2);
2909 if (opc == OPC_ADD_CP2) {
2910 tcg_gen_ext32s_i64(t0, t0);
2911 }
2912 tcg_gen_xor_i64(t1, t1, t2);
2913 tcg_gen_xor_i64(t2, t2, t0);
2914 tcg_gen_andc_i64(t1, t2, t1);
2915 tcg_temp_free_i64(t2);
2916 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
2917 generate_exception(ctx, EXCP_OVERFLOW);
2918 gen_set_label(lab);
2919
2920 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
2921 break;
2922 }
2923
2924 case OPC_SUB_CP2:
2925 case OPC_DSUB_CP2:
2926 {
2927 TCGv_i64 t2 = tcg_temp_new_i64();
2928 int lab = gen_new_label();
2929
2930 tcg_gen_mov_i64(t2, t0);
2931 tcg_gen_sub_i64(t0, t1, t2);
2932 if (opc == OPC_SUB_CP2) {
2933 tcg_gen_ext32s_i64(t0, t0);
2934 }
2935 tcg_gen_xor_i64(t1, t1, t2);
2936 tcg_gen_xor_i64(t2, t2, t0);
2937 tcg_gen_and_i64(t1, t1, t2);
2938 tcg_temp_free_i64(t2);
2939 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
2940 generate_exception(ctx, EXCP_OVERFLOW);
2941 gen_set_label(lab);
2942
2943 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
2944 break;
2945 }
2946
2947 case OPC_PMULUW:
2948 tcg_gen_ext32u_i64(t0, t0);
2949 tcg_gen_ext32u_i64(t1, t1);
2950 tcg_gen_mul_i64(t0, t0, t1);
2951 opn = "pmuluw";
2952 break;
2953
2954 case OPC_SEQU_CP2:
2955 case OPC_SEQ_CP2:
2956 case OPC_SLTU_CP2:
2957 case OPC_SLT_CP2:
2958 case OPC_SLEU_CP2:
2959 case OPC_SLE_CP2:
2960 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
2961 FD field is the CC field? */
2962 default:
2963 MIPS_INVAL(opn);
2964 generate_exception(ctx, EXCP_RI);
2965 return;
2966 }
2967
2968 #undef LMI_HELPER
2969 #undef LMI_DIRECT
2970
2971 gen_store_fpr64(ctx, t0, rd);
2972
2973 (void)opn; /* avoid a compiler warning */
2974 MIPS_DEBUG("%s %s, %s, %s", opn,
2975 fregnames[rd], fregnames[rs], fregnames[rt]);
2976 tcg_temp_free_i64(t0);
2977 tcg_temp_free_i64(t1);
2978 }
2979
2980 /* Traps */
2981 static void gen_trap (DisasContext *ctx, uint32_t opc,
2982 int rs, int rt, int16_t imm)
2983 {
2984 int cond;
2985 TCGv t0 = tcg_temp_new();
2986 TCGv t1 = tcg_temp_new();
2987
2988 cond = 0;
2989 /* Load needed operands */
2990 switch (opc) {
2991 case OPC_TEQ:
2992 case OPC_TGE:
2993 case OPC_TGEU:
2994 case OPC_TLT:
2995 case OPC_TLTU:
2996 case OPC_TNE:
2997 /* Compare two registers */
2998 if (rs != rt) {
2999 gen_load_gpr(t0, rs);
3000 gen_load_gpr(t1, rt);
3001 cond = 1;
3002 }
3003 break;
3004 case OPC_TEQI:
3005 case OPC_TGEI:
3006 case OPC_TGEIU:
3007 case OPC_TLTI:
3008 case OPC_TLTIU:
3009 case OPC_TNEI:
3010 /* Compare register to immediate */
3011 if (rs != 0 || imm != 0) {
3012 gen_load_gpr(t0, rs);
3013 tcg_gen_movi_tl(t1, (int32_t)imm);
3014 cond = 1;
3015 }
3016 break;
3017 }
3018 if (cond == 0) {
3019 switch (opc) {
3020 case OPC_TEQ: /* rs == rs */
3021 case OPC_TEQI: /* r0 == 0 */
3022 case OPC_TGE: /* rs >= rs */
3023 case OPC_TGEI: /* r0 >= 0 */
3024 case OPC_TGEU: /* rs >= rs unsigned */
3025 case OPC_TGEIU: /* r0 >= 0 unsigned */
3026 /* Always trap */
3027 generate_exception(ctx, EXCP_TRAP);
3028 break;
3029 case OPC_TLT: /* rs < rs */
3030 case OPC_TLTI: /* r0 < 0 */
3031 case OPC_TLTU: /* rs < rs unsigned */
3032 case OPC_TLTIU: /* r0 < 0 unsigned */
3033 case OPC_TNE: /* rs != rs */
3034 case OPC_TNEI: /* r0 != 0 */
3035 /* Never trap: treat as NOP. */
3036 break;
3037 }
3038 } else {
3039 int l1 = gen_new_label();
3040
3041 switch (opc) {
3042 case OPC_TEQ:
3043 case OPC_TEQI:
3044 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3045 break;
3046 case OPC_TGE:
3047 case OPC_TGEI:
3048 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3049 break;
3050 case OPC_TGEU:
3051 case OPC_TGEIU:
3052 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3053 break;
3054 case OPC_TLT:
3055 case OPC_TLTI:
3056 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3057 break;
3058 case OPC_TLTU:
3059 case OPC_TLTIU:
3060 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3061 break;
3062 case OPC_TNE:
3063 case OPC_TNEI:
3064 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3065 break;
3066 }
3067 generate_exception(ctx, EXCP_TRAP);
3068 gen_set_label(l1);
3069 }
3070 tcg_temp_free(t0);
3071 tcg_temp_free(t1);
3072 }
3073
3074 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3075 {
3076 TranslationBlock *tb;
3077 tb = ctx->tb;
3078 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3079 likely(!ctx->singlestep_enabled)) {
3080 tcg_gen_goto_tb(n);
3081 gen_save_pc(dest);
3082 tcg_gen_exit_tb((tcg_target_long)tb + n);
3083 } else {
3084 gen_save_pc(dest);
3085 if (ctx->singlestep_enabled) {
3086 save_cpu_state(ctx, 0);
3087 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3088 }
3089 tcg_gen_exit_tb(0);
3090 }
3091 }
3092
3093 /* Branches (before delay slot) */
3094 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3095 int insn_bytes,
3096 int rs, int rt, int32_t offset)
3097 {
3098 target_ulong btgt = -1;
3099 int blink = 0;
3100 int bcond_compute = 0;
3101 TCGv t0 = tcg_temp_new();
3102 TCGv t1 = tcg_temp_new();
3103
3104 if (ctx->hflags & MIPS_HFLAG_BMASK) {
3105 #ifdef MIPS_DEBUG_DISAS
3106 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3107 #endif
3108 generate_exception(ctx, EXCP_RI);
3109 goto out;
3110 }
3111
3112 /* Load needed operands */
3113 switch (opc) {
3114 case OPC_BEQ:
3115 case OPC_BEQL:
3116 case OPC_BNE:
3117 case OPC_BNEL:
3118 /* Compare two registers */
3119 if (rs != rt) {
3120 gen_load_gpr(t0, rs);
3121 gen_load_gpr(t1, rt);
3122 bcond_compute = 1;
3123 }
3124 btgt = ctx->pc + insn_bytes + offset;
3125 break;
3126 case OPC_BGEZ:
3127 case OPC_BGEZAL:
3128 case OPC_BGEZALS:
3129 case OPC_BGEZALL:
3130 case OPC_BGEZL:
3131 case OPC_BGTZ:
3132 case OPC_BGTZL:
3133 case OPC_BLEZ:
3134 case OPC_BLEZL:
3135 case OPC_BLTZ:
3136 case OPC_BLTZAL:
3137 case OPC_BLTZALS:
3138 case OPC_BLTZALL:
3139 case OPC_BLTZL:
3140 /* Compare to zero */
3141 if (rs != 0) {
3142 gen_load_gpr(t0, rs);
3143 bcond_compute = 1;
3144 }
3145 btgt = ctx->pc + insn_bytes + offset;
3146 break;
3147 case OPC_J:
3148 case OPC_JAL:
3149 case OPC_JALX:
3150 case OPC_JALS:
3151 case OPC_JALXS:
3152 /* Jump to immediate */
3153 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3154 break;
3155 case OPC_JR:
3156 case OPC_JALR:
3157 case OPC_JALRC:
3158 case OPC_JALRS:
3159 /* Jump to register */
3160 if (offset != 0 && offset != 16) {
3161 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3162 others are reserved. */
3163 MIPS_INVAL("jump hint");
3164 generate_exception(ctx, EXCP_RI);
3165 goto out;
3166 }
3167 gen_load_gpr(btarget, rs);
3168 break;
3169 default:
3170 MIPS_INVAL("branch/jump");
3171 generate_exception(ctx, EXCP_RI);
3172 goto out;
3173 }
3174 if (bcond_compute == 0) {
3175 /* No condition to be computed */
3176 switch (opc) {
3177 case OPC_BEQ: /* rx == rx */
3178 case OPC_BEQL: /* rx == rx likely */
3179 case OPC_BGEZ: /* 0 >= 0 */
3180 case OPC_BGEZL: /* 0 >= 0 likely */
3181 case OPC_BLEZ: /* 0 <= 0 */
3182 case OPC_BLEZL: /* 0 <= 0 likely */
3183 /* Always take */
3184 ctx->hflags |= MIPS_HFLAG_B;
3185 MIPS_DEBUG("balways");
3186 break;
3187 case OPC_BGEZALS:
3188 case OPC_BGEZAL: /* 0 >= 0 */
3189 case OPC_BGEZALL: /* 0 >= 0 likely */
3190 ctx->hflags |= (opc == OPC_BGEZALS
3191 ? MIPS_HFLAG_BDS16
3192 : MIPS_HFLAG_BDS32);
3193 /* Always take and link */
3194 blink = 31;
3195 ctx->hflags |= MIPS_HFLAG_B;
3196 MIPS_DEBUG("balways and link");
3197 break;
3198 case OPC_BNE: /* rx != rx */
3199 case OPC_BGTZ: /* 0 > 0 */
3200 case OPC_BLTZ: /* 0 < 0 */
3201 /* Treat as NOP. */
3202 MIPS_DEBUG("bnever (NOP)");
3203 goto out;
3204 case OPC_BLTZALS:
3205 case OPC_BLTZAL: /* 0 < 0 */
3206 ctx->hflags |= (opc == OPC_BLTZALS
3207 ? MIPS_HFLAG_BDS16
3208 : MIPS_HFLAG_BDS32);
3209 /* Handle as an unconditional branch to get correct delay
3210 slot checking. */
3211 blink = 31;
3212 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3213 ctx->hflags |= MIPS_HFLAG_B;
3214 MIPS_DEBUG("bnever and link");
3215 break;
3216 case OPC_BLTZALL: /* 0 < 0 likely */
3217 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3218 /* Skip the instruction in the delay slot */
3219 MIPS_DEBUG("bnever, link and skip");
3220 ctx->pc += 4;
3221 goto out;
3222 case OPC_BNEL: /* rx != rx likely */
3223 case OPC_BGTZL: /* 0 > 0 likely */
3224 case OPC_BLTZL: /* 0 < 0 likely */
3225 /* Skip the instruction in the delay slot */
3226 MIPS_DEBUG("bnever and skip");
3227 ctx->pc += 4;
3228 goto out;
3229 case OPC_J:
3230 ctx->hflags |= MIPS_HFLAG_B;
3231 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3232 break;
3233 case OPC_JALXS:
3234 case OPC_JALX:
3235 ctx->hflags |= MIPS_HFLAG_BX;
3236 /* Fallthrough */
3237 case OPC_JALS:
3238 case OPC_JAL:
3239 blink = 31;
3240 ctx->hflags |= MIPS_HFLAG_B;
3241 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3242 ? MIPS_HFLAG_BDS16
3243 : MIPS_HFLAG_BDS32);
3244 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3245 break;
3246 case OPC_JR:
3247 ctx->hflags |= MIPS_HFLAG_BR;
3248 if (insn_bytes == 4)
3249 ctx->hflags |= MIPS_HFLAG_BDS32;
3250 MIPS_DEBUG("jr %s", regnames[rs]);
3251 break;
3252 case OPC_JALRS:
3253 case OPC_JALR:
3254 case OPC_JALRC:
3255 blink = rt;
3256 ctx->hflags |= MIPS_HFLAG_BR;
3257 ctx->hflags |= (opc == OPC_JALRS
3258 ? MIPS_HFLAG_BDS16
3259 : MIPS_HFLAG_BDS32);
3260 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3261 break;
3262 default:
3263 MIPS_INVAL("branch/jump");
3264 generate_exception(ctx, EXCP_RI);
3265 goto out;
3266 }
3267 } else {
3268 switch (opc) {
3269 case OPC_BEQ:
3270 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3271 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3272 regnames[rs], regnames[rt], btgt);
3273 goto not_likely;
3274 case OPC_BEQL:
3275 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3276 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3277 regnames[rs], regnames[rt], btgt);
3278 goto likely;
3279 case OPC_BNE:
3280 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3281 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3282 regnames[rs], regnames[rt], btgt);
3283 goto not_likely;
3284 case OPC_BNEL:
3285 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3286 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3287 regnames[rs], regnames[rt], btgt);
3288 goto likely;
3289 case OPC_BGEZ:
3290 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3291 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3292 goto not_likely;
3293 case OPC_BGEZL:
3294 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3295 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3296 goto likely;
3297 case OPC_BGEZALS:
3298 case OPC_BGEZAL:
3299 ctx->hflags |= (opc == OPC_BGEZALS
3300 ? MIPS_HFLAG_BDS16
3301 : MIPS_HFLAG_BDS32);
3302 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3303 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3304 blink = 31;
3305 goto not_likely;
3306 case OPC_BGEZALL:
3307 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3308 blink = 31;
3309 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3310 goto likely;
3311 case OPC_BGTZ:
3312 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3313 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3314 goto not_likely;
3315 case OPC_BGTZL:
3316 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3317 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3318 goto likely;
3319 case OPC_BLEZ:
3320 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3321 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3322 goto not_likely;
3323 case OPC_BLEZL:
3324 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3325 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3326 goto likely;
3327 case OPC_BLTZ:
3328 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3329 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3330 goto not_likely;
3331 case OPC_BLTZL:
3332 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3333 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3334 goto likely;
3335 case OPC_BLTZALS:
3336 case OPC_BLTZAL:
3337 ctx->hflags |= (opc == OPC_BLTZALS
3338 ? MIPS_HFLAG_BDS16
3339 : MIPS_HFLAG_BDS32);
3340 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3341 blink = 31;
3342 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3343 not_likely:
3344 ctx->hflags |= MIPS_HFLAG_BC;
3345 break;
3346 case OPC_BLTZALL:
3347 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3348 blink = 31;
3349 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3350 likely:
3351 ctx->hflags |= MIPS_HFLAG_BL;
3352 break;
3353 default:
3354 MIPS_INVAL("conditional branch/jump");
3355 generate_exception(ctx, EXCP_RI);
3356 goto out;
3357 }
3358 }
3359 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3360 blink, ctx->hflags, btgt);
3361
3362 ctx->btarget = btgt;
3363 if (blink > 0) {
3364 int post_delay = insn_bytes;
3365 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3366
3367 if (opc != OPC_JALRC)
3368 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3369
3370 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3371 }
3372
3373 out:
3374 if (insn_bytes == 2)
3375 ctx->hflags |= MIPS_HFLAG_B16;
3376 tcg_temp_free(t0);
3377 tcg_temp_free(t1);
3378 }
3379
3380 /* special3 bitfield operations */
3381 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3382 int rs, int lsb, int msb)
3383 {
3384 TCGv t0 = tcg_temp_new();
3385 TCGv t1 = tcg_temp_new();
3386 target_ulong mask;
3387
3388 gen_load_gpr(t1, rs);
3389 switch (opc) {
3390 case OPC_EXT:
3391 if (lsb + msb > 31)
3392 goto fail;
3393 tcg_gen_shri_tl(t0, t1, lsb);
3394 if (msb != 31) {
3395 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3396 } else {
3397 tcg_gen_ext32s_tl(t0, t0);
3398 }
3399 break;
3400 #if defined(TARGET_MIPS64)
3401 case OPC_DEXTM:
3402 tcg_gen_shri_tl(t0, t1, lsb);
3403 if (msb != 31) {
3404 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3405 }
3406 break;
3407 case OPC_DEXTU:
3408 tcg_gen_shri_tl(t0, t1, lsb + 32);
3409 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3410 break;
3411 case OPC_DEXT:
3412 tcg_gen_shri_tl(t0, t1, lsb);
3413 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3414 break;
3415 #endif
3416 case OPC_INS:
3417 if (lsb > msb)
3418 goto fail;
3419 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
3420 gen_load_gpr(t0, rt);
3421 tcg_gen_andi_tl(t0, t0, ~mask);
3422 tcg_gen_shli_tl(t1, t1, lsb);
3423 tcg_gen_andi_tl(t1, t1, mask);
3424 tcg_gen_or_tl(t0, t0, t1);
3425 tcg_gen_ext32s_tl(t0, t0);
3426 break;
3427 #if defined(TARGET_MIPS64)
3428 case OPC_DINSM:
3429 if (lsb > msb)
3430 goto fail;
3431 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
3432 gen_load_gpr(t0, rt);
3433 tcg_gen_andi_tl(t0, t0, ~mask);
3434 tcg_gen_shli_tl(t1, t1, lsb);
3435 tcg_gen_andi_tl(t1, t1, mask);
3436 tcg_gen_or_tl(t0, t0, t1);
3437 break;
3438 case OPC_DINSU:
3439 if (lsb > msb)
3440 goto fail;
3441 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
3442 gen_load_gpr(t0, rt);
3443 tcg_gen_andi_tl(t0, t0, ~mask);
3444 tcg_gen_shli_tl(t1, t1, lsb + 32);
3445 tcg_gen_andi_tl(t1, t1, mask);
3446 tcg_gen_or_tl(t0, t0, t1);
3447 break;
3448 case OPC_DINS:
3449 if (lsb > msb)
3450 goto fail;
3451 gen_load_gpr(t0, rt);
3452 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3453 gen_load_gpr(t0, rt);
3454 tcg_gen_andi_tl(t0, t0, ~mask);
3455 tcg_gen_shli_tl(t1, t1, lsb);
3456 tcg_gen_andi_tl(t1, t1, mask);
3457 tcg_gen_or_tl(t0, t0, t1);
3458 break;
3459 #endif
3460 default:
3461 fail:
3462 MIPS_INVAL("bitops");
3463 generate_exception(ctx, EXCP_RI);
3464 tcg_temp_free(t0);
3465 tcg_temp_free(t1);
3466 return;
3467 }
3468 gen_store_gpr(t0, rt);
3469 tcg_temp_free(t0);
3470 tcg_temp_free(t1);
3471 }
3472
3473 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3474 {
3475 TCGv t0;
3476
3477 if (rd == 0) {
3478 /* If no destination, treat it as a NOP. */
3479 MIPS_DEBUG("NOP");
3480 return;
3481 }
3482
3483 t0 = tcg_temp_new();
3484 gen_load_gpr(t0, rt);
3485 switch (op2) {
3486 case OPC_WSBH:
3487 {
3488 TCGv t1 = tcg_temp_new();
3489
3490 tcg_gen_shri_tl(t1, t0, 8);
3491 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3492 tcg_gen_shli_tl(t0, t0, 8);
3493 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3494 tcg_gen_or_tl(t0, t0, t1);
3495 tcg_temp_free(t1);
3496 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3497 }
3498 break;
3499 case OPC_SEB:
3500 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3501 break;
3502 case OPC_SEH:
3503 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
3504 break;
3505 #if defined(TARGET_MIPS64)
3506 case OPC_DSBH:
3507 {
3508 TCGv t1 = tcg_temp_new();
3509
3510 tcg_gen_shri_tl(t1, t0, 8);
3511 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
3512 tcg_gen_shli_tl(t0, t0, 8);
3513 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
3514 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3515 tcg_temp_free(t1);
3516 }
3517 break;
3518 case OPC_DSHD:
3519 {
3520 TCGv t1 = tcg_temp_new();
3521
3522 tcg_gen_shri_tl(t1, t0, 16);
3523 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
3524 tcg_gen_shli_tl(t0, t0, 16);
3525 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
3526 tcg_gen_or_tl(t0, t0, t1);
3527 tcg_gen_shri_tl(t1, t0, 32);
3528 tcg_gen_shli_tl(t0, t0, 32);
3529 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
3530 tcg_temp_free(t1);
3531 }
3532 break;
3533 #endif
3534 default:
3535 MIPS_INVAL("bsfhl");
3536 generate_exception(ctx, EXCP_RI);
3537 tcg_temp_free(t0);
3538 return;
3539 }
3540 tcg_temp_free(t0);
3541 }
3542
3543 #ifndef CONFIG_USER_ONLY
3544 /* CP0 (MMU and control) */
3545 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
3546 {
3547 TCGv_i32 t0 = tcg_temp_new_i32();
3548
3549 tcg_gen_ld_i32(t0, cpu_env, off);
3550 tcg_gen_ext_i32_tl(arg, t0);
3551 tcg_temp_free_i32(t0);
3552 }
3553
3554 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
3555 {
3556 tcg_gen_ld_tl(arg, cpu_env, off);
3557 tcg_gen_ext32s_tl(arg, arg);
3558 }
3559
3560 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
3561 {
3562 TCGv_i32 t0 = tcg_temp_new_i32();
3563
3564 tcg_gen_trunc_tl_i32(t0, arg);
3565 tcg_gen_st_i32(t0, cpu_env, off);
3566 tcg_temp_free_i32(t0);
3567 }
3568
3569 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
3570 {
3571 tcg_gen_ext32s_tl(arg, arg);
3572 tcg_gen_st_tl(arg, cpu_env, off);
3573 }
3574
3575 static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3576 {
3577 const char *rn = "invalid";
3578
3579 if (sel != 0)
3580 check_insn(env, ctx, ISA_MIPS32);
3581
3582 switch (reg) {
3583 case 0:
3584 switch (sel) {
3585 case 0:
3586 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
3587 rn = "Index";
3588 break;
3589 case 1:
3590 check_insn(env, ctx, ASE_MT);
3591 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
3592 rn = "MVPControl";
3593 break;
3594 case 2:
3595 check_insn(env, ctx, ASE_MT);
3596 gen_helper_mfc0_mvpconf0(arg, cpu_env);
3597 rn = "MVPConf0";
3598 break;
3599 case 3:
3600 check_insn(env, ctx, ASE_MT);
3601 gen_helper_mfc0_mvpconf1(arg, cpu_env);
3602 rn = "MVPConf1";
3603 break;
3604 default:
3605 goto die;
3606 }
3607 break;
3608 case 1:
3609 switch (sel) {
3610 case 0:
3611 gen_helper_mfc0_random(arg, cpu_env);
3612 rn = "Random";
3613 break;
3614 case 1:
3615 check_insn(env, ctx, ASE_MT);
3616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
3617 rn = "VPEControl";
3618 break;
3619 case 2:
3620 check_insn(env, ctx, ASE_MT);
3621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
3622 rn = "VPEConf0";
3623 break;
3624 case 3:
3625 check_insn(env, ctx, ASE_MT);
3626 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
3627 rn = "VPEConf1";
3628 break;
3629 case 4:
3630 check_insn(env, ctx, ASE_MT);
3631 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
3632 rn = "YQMask";
3633 break;
3634 case 5:
3635 check_insn(env, ctx, ASE_MT);
3636 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
3637 rn = "VPESchedule";
3638 break;
3639 case 6:
3640 check_insn(env, ctx, ASE_MT);
3641 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
3642 rn = "VPEScheFBack";
3643 break;
3644 case 7:
3645 check_insn(env, ctx, ASE_MT);
3646 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
3647 rn = "VPEOpt";
3648 break;
3649 default:
3650 goto die;
3651 }
3652 break;
3653 case 2:
3654 switch (sel) {
3655 case 0:
3656 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
3657 tcg_gen_ext32s_tl(arg, arg);
3658 rn = "EntryLo0";
3659 break;
3660 case 1:
3661 check_insn(env, ctx, ASE_MT);
3662 gen_helper_mfc0_tcstatus(arg, cpu_env);
3663 rn = "TCStatus";
3664 break;
3665 case 2:
3666 check_insn(env, ctx, ASE_MT);
3667 gen_helper_mfc0_tcbind(arg, cpu_env);
3668 rn = "TCBind";
3669 break;
3670 case 3:
3671 check_insn(env, ctx, ASE_MT);
3672 gen_helper_mfc0_tcrestart(arg, cpu_env);
3673 rn = "TCRestart";
3674 break;
3675 case 4:
3676 check_insn(env, ctx, ASE_MT);
3677 gen_helper_mfc0_tchalt(arg, cpu_env);
3678 rn = "TCHalt";
3679 break;
3680 case 5:
3681 check_insn(env, ctx, ASE_MT);
3682 gen_helper_mfc0_tccontext(arg, cpu_env);
3683 rn = "TCContext";
3684 break;
3685 case 6:
3686 check_insn(env, ctx, ASE_MT);
3687 gen_helper_mfc0_tcschedule(arg, cpu_env);
3688 rn = "TCSchedule";
3689 break;
3690 case 7:
3691 check_insn(env, ctx, ASE_MT);
3692 gen_helper_mfc0_tcschefback(arg, cpu_env);
3693 rn = "TCScheFBack";
3694 break;
3695 default:
3696 goto die;
3697 }
3698 break;
3699 case 3:
3700 switch (sel) {
3701 case 0:
3702 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
3703 tcg_gen_ext32s_tl(arg, arg);
3704 rn = "EntryLo1";
3705 break;
3706 default:
3707 goto die;
3708 }
3709 break;
3710 case 4:
3711 switch (sel) {
3712 case 0:
3713 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
3714 tcg_gen_ext32s_tl(arg, arg);
3715 rn = "Context";
3716 break;
3717 case 1:
3718 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3719 rn = "ContextConfig";
3720 // break;
3721 default:
3722 goto die;
3723 }
3724 break;
3725 case 5:
3726 switch (sel) {
3727 case 0:
3728 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
3729 rn = "PageMask";
3730 break;
3731 case 1:
3732 check_insn(env, ctx, ISA_MIPS32R2);
3733 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
3734 rn = "PageGrain";
3735 break;
3736 default:
3737 goto die;
3738 }
3739 break;
3740 case 6:
3741 switch (sel) {
3742 case 0:
3743 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
3744 rn = "Wired";
3745 break;
3746 case 1:
3747 check_insn(env, ctx, ISA_MIPS32R2);
3748 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
3749 rn = "SRSConf0";
3750 break;
3751 case 2:
3752 check_insn(env, ctx, ISA_MIPS32R2);
3753 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
3754 rn = "SRSConf1";
3755 break;
3756 case 3:
3757 check_insn(env, ctx, ISA_MIPS32R2);
3758 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
3759 rn = "SRSConf2";
3760 break;
3761 case 4:
3762 check_insn(env, ctx, ISA_MIPS32R2);
3763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
3764 rn = "SRSConf3";
3765 break;
3766 case 5:
3767 check_insn(env, ctx, ISA_MIPS32R2);
3768 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
3769 rn = "SRSConf4";
3770 break;
3771 default:
3772 goto die;
3773 }
3774 break;
3775 case 7:
3776 switch (sel) {
3777 case 0:
3778 check_insn(env, ctx, ISA_MIPS32R2);
3779 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
3780 rn = "HWREna";
3781 break;
3782 default:
3783 goto die;
3784 }
3785 break;
3786 case 8:
3787 switch (sel) {
3788 case 0:
3789 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
3790 tcg_gen_ext32s_tl(arg, arg);
3791 rn = "BadVAddr";
3792 break;
3793 default:
3794 goto die;
3795 }
3796 break;
3797 case 9:
3798 switch (sel) {
3799 case 0:
3800 /* Mark as an IO operation because we read the time. */
3801 if (use_icount)
3802 gen_io_start();
3803 gen_helper_mfc0_count(arg, cpu_env);
3804 if (use_icount) {
3805 gen_io_end();
3806 }
3807 /* Break the TB to be able to take timer interrupts immediately
3808 after reading count. */
3809 ctx->bstate = BS_STOP;
3810 rn = "Count";
3811 break;
3812 /* 6,7 are implementation dependent */
3813 default:
3814 goto die;
3815 }
3816 break;
3817 case 10:
3818 switch (sel) {
3819 case 0:
3820 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
3821 tcg_gen_ext32s_tl(arg, arg);
3822 rn = "EntryHi";
3823 break;
3824 default:
3825 goto die;
3826 }
3827 break;
3828 case 11:
3829 switch (sel) {
3830 case 0:
3831 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
3832 rn = "Compare";
3833 break;
3834 /* 6,7 are implementation dependent */
3835 default:
3836 goto die;
3837 }
3838 break;
3839 case 12:
3840 switch (sel) {
3841 case 0:
3842 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
3843 rn = "Status";
3844 break;
3845 case 1:
3846 check_insn(env, ctx, ISA_MIPS32R2);
3847 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
3848 rn = "IntCtl";
3849 break;
3850 case 2:
3851 check_insn(env, ctx, ISA_MIPS32R2);
3852 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
3853 rn = "SRSCtl";
3854 break;
3855 case 3:
3856 check_insn(env, ctx, ISA_MIPS32R2);
3857 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
3858 rn = "SRSMap";
3859 break;
3860 default:
3861 goto die;
3862 }
3863 break;
3864 case 13:
3865 switch (sel) {
3866 case 0:
3867 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
3868 rn = "Cause";
3869 break;
3870 default:
3871 goto die;
3872 }
3873 break;
3874 case 14:
3875 switch (sel) {
3876 case 0:
3877 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
3878 tcg_gen_ext32s_tl(arg, arg);
3879 rn = "EPC";
3880 break;
3881 default:
3882 goto die;
3883 }
3884 break;
3885 case 15:
3886 switch (sel) {
3887 case 0:
3888 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
3889 rn = "PRid";
3890 break;
3891 case 1:
3892 check_insn(env, ctx, ISA_MIPS32R2);
3893 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
3894 rn = "EBase";
3895 break;
3896 default:
3897 goto die;
3898 }
3899 break;
3900 case 16:
3901 switch (sel) {
3902 case 0:
3903 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
3904 rn = "Config";
3905 break;
3906 case 1:
3907 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
3908 rn = "Config1";
3909 break;
3910 case 2:
3911 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
3912 rn = "Config2";
3913 break;
3914 case 3:
3915 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
3916 rn = "Config3";
3917 break;
3918 /* 4,5 are reserved */
3919 /* 6,7 are implementation dependent */
3920 case 6:
3921 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
3922 rn = "Config6";
3923 break;
3924 case 7:
3925 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
3926 rn = "Config7";
3927 break;
3928 default:
3929 goto die;
3930 }
3931 break;
3932 case 17:
3933 switch (sel) {
3934 case 0:
3935 gen_helper_mfc0_lladdr(arg, cpu_env);
3936 rn = "LLAddr";
3937 break;
3938 default:
3939 goto die;
3940 }
3941 break;
3942 case 18:
3943 switch (sel) {
3944 case 0 ... 7:
3945 gen_helper_1e0i(mfc0_watchlo, arg, sel);
3946 rn = "WatchLo";
3947 break;
3948 default:
3949 goto die;
3950 }
3951 break;
3952 case 19:
3953 switch (sel) {
3954 case 0 ...7:
3955 gen_helper_1e0i(mfc0_watchhi, arg, sel);
3956 rn = "WatchHi";
3957 break;
3958 default:
3959 goto die;
3960 }
3961 break;
3962 case 20:
3963 switch (sel) {
3964 case 0:
3965 #if defined(TARGET_MIPS64)
3966 check_insn(env, ctx, ISA_MIPS3);
3967 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
3968 tcg_gen_ext32s_tl(arg, arg);
3969 rn = "XContext";
3970 break;
3971 #endif
3972 default:
3973 goto die;
3974 }
3975 break;
3976 case 21:
3977 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3978 switch (sel) {
3979 case 0:
3980 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
3981 rn = "Framemask";
3982 break;
3983 default:
3984 goto die;
3985 }
3986 break;
3987 case 22:
3988 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3989 rn = "'Diagnostic"; /* implementation dependent */
3990 break;
3991 case 23:
3992 switch (sel) {
3993 case 0:
3994 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
3995 rn = "Debug";
3996 break;
3997 case 1:
3998 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3999 rn = "TraceControl";
4000 // break;
4001 case 2:
4002 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4003 rn = "TraceControl2";
4004 // break;
4005 case 3:
4006 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4007 rn = "UserTraceData";
4008 // break;
4009 case 4:
4010 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4011 rn = "TraceBPC";
4012 // break;
4013 default:
4014 goto die;
4015 }
4016 break;
4017 case 24:
4018 switch (sel) {
4019 case 0:
4020 /* EJTAG support */
4021 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4022 tcg_gen_ext32s_tl(arg, arg);
4023 rn = "DEPC";
4024 break;
4025 default:
4026 goto die;
4027 }
4028 break;
4029 case 25:
4030 switch (sel) {
4031 case 0:
4032 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4033 rn = "Performance0";
4034 break;
4035 case 1:
4036 // gen_helper_mfc0_performance1(arg);
4037 rn = "Performance1";
4038 // break;
4039 case 2:
4040 // gen_helper_mfc0_performance2(arg);
4041 rn = "Performance2";
4042 // break;
4043 case 3:
4044 // gen_helper_mfc0_performance3(arg);
4045 rn = "Performance3";
4046 // break;
4047 case 4:
4048 // gen_helper_mfc0_performance4(arg);
4049 rn = "Performance4";
4050 // break;
4051 case 5:
4052 // gen_helper_mfc0_performance5(arg);
4053 rn = "Performance5";
4054 // break;
4055 case 6:
4056 // gen_helper_mfc0_performance6(arg);
4057 rn = "Performance6";
4058 // break;
4059 case 7:
4060 // gen_helper_mfc0_performance7(arg);
4061 rn = "Performance7";
4062 // break;
4063 default:
4064 goto die;
4065 }
4066 break;
4067 case 26:
4068 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4069 rn = "ECC";
4070 break;
4071 case 27:
4072 switch (sel) {
4073 case 0 ... 3:
4074 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4075 rn = "CacheErr";
4076 break;
4077 default:
4078 goto die;
4079 }
4080 break;
4081 case 28:
4082 switch (sel) {
4083 case 0:
4084 case 2:
4085 case 4:
4086 case 6:
4087 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4088 rn = "TagLo";
4089 break;
4090 case 1:
4091 case 3:
4092 case 5:
4093 case 7:
4094 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4095 rn = "DataLo";
4096 break;
4097 default:
4098 goto die;
4099 }
4100 break;
4101 case 29:
4102 switch (sel) {
4103 case 0:
4104 case 2:
4105 case 4:
4106 case 6:
4107 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4108 rn = "TagHi";
4109 break;
4110 case 1:
4111 case 3:
4112 case 5:
4113 case 7:
4114 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4115 rn = "DataHi";
4116 break;
4117 default:
4118 goto die;
4119 }
4120 break;
4121 case 30:
4122 switch (sel) {
4123 case 0:
4124 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4125 tcg_gen_ext32s_tl(arg, arg);
4126 rn = "ErrorEPC";
4127 break;
4128 default:
4129 goto die;
4130 }
4131 break;
4132 case 31:
4133 switch (sel) {
4134 case 0:
4135 /* EJTAG support */
4136 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4137 rn = "DESAVE";
4138 break;
4139 default:
4140 goto die;
4141 }
4142 break;
4143 default:
4144 goto die;
4145 }
4146 (void)rn; /* avoid a compiler warning */
4147 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4148 return;
4149
4150 die:
4151 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4152 generate_exception(ctx, EXCP_RI);
4153 }
4154
4155 static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4156 {
4157 const char *rn = "invalid";
4158
4159 if (sel != 0)
4160 check_insn(env, ctx, ISA_MIPS32);
4161
4162 if (use_icount)
4163 gen_io_start();
4164
4165 switch (reg) {
4166 case 0:
4167 switch (sel) {
4168 case 0:
4169 gen_helper_mtc0_index(cpu_env, arg);
4170 rn = "Index";
4171 break;
4172 case 1:
4173 check_insn(env, ctx, ASE_MT);
4174 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4175 rn = "MVPControl";
4176 break;
4177 case 2:
4178 check_insn(env, ctx, ASE_MT);
4179 /* ignored */
4180 rn = "MVPConf0";
4181 break;
4182 case 3:
4183 check_insn(env, ctx, ASE_MT);
4184 /* ignored */
4185 rn = "MVPConf1";
4186 break;
4187 default:
4188 goto die;
4189 }
4190 break;
4191 case 1:
4192 switch (sel) {
4193 case 0:
4194 /* ignored */
4195 rn = "Random";
4196 break;
4197 case 1:
4198 check_insn(env, ctx, ASE_MT);
4199 gen_helper_mtc0_vpecontrol(cpu_env, arg);
4200 rn = "VPEControl";
4201 break;
4202 case 2:
4203 check_insn(env, ctx, ASE_MT);
4204 gen_helper_mtc0_vpeconf0(cpu_env, arg);
4205 rn = "VPEConf0";
4206 break;
4207 case 3:
4208 check_insn(env, ctx, ASE_MT);
4209 gen_helper_mtc0_vpeconf1(cpu_env, arg);
4210 rn = "VPEConf1";
4211 break;
4212 case 4:
4213 check_insn(env, ctx, ASE_MT);
4214 gen_helper_mtc0_yqmask(cpu_env, arg);
4215 rn = "YQMask";
4216 break;
4217 case 5:
4218 check_insn(env, ctx, ASE_MT);
4219 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4220 rn = "VPESchedule";
4221 break;
4222 case 6:
4223 check_insn(env, ctx, ASE_MT);
4224 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4225 rn = "VPEScheFBack";
4226 break;
4227 case 7:
4228 check_insn(env, ctx, ASE_MT);
4229 gen_helper_mtc0_vpeopt(cpu_env, arg);
4230 rn = "VPEOpt";
4231 break;
4232 default:
4233 goto die;
4234 }
4235 break;
4236 case 2:
4237 switch (sel) {
4238 case 0:
4239 gen_helper_mtc0_entrylo0(cpu_env, arg);
4240 rn = "EntryLo0";
4241 break;
4242 case 1:
4243 check_insn(env, ctx, ASE_MT);
4244 gen_helper_mtc0_tcstatus(cpu_env, arg);
4245 rn = "TCStatus";
4246 break;
4247 case 2:
4248 check_insn(env, ctx, ASE_MT);
4249 gen_helper_mtc0_tcbind(cpu_env, arg);
4250 rn = "TCBind";
4251 break;
4252 case 3:
4253 check_insn(env, ctx, ASE_MT);
4254 gen_helper_mtc0_tcrestart(cpu_env, arg);
4255 rn = "TCRestart";
4256 break;
4257 case 4:
4258 check_insn(env, ctx, ASE_MT);
4259 gen_helper_mtc0_tchalt(cpu_env, arg);
4260 rn = "TCHalt";
4261 break;
4262 case 5:
4263 check_insn(env, ctx, ASE_MT);
4264 gen_helper_mtc0_tccontext(cpu_env, arg);
4265 rn = "TCContext";
4266 break;
4267 case 6:
4268 check_insn(env, ctx, ASE_MT);
4269 gen_helper_mtc0_tcschedule(cpu_env, arg);
4270 rn = "TCSchedule";
4271 break;
4272 case 7:
4273 check_insn(env, ctx, ASE_MT);
4274 gen_helper_mtc0_tcschefback(cpu_env, arg);
4275 rn = "TCScheFBack";
4276 break;
4277 default:
4278 goto die;
4279 }
4280 break;
4281 case 3:
4282 switch (sel) {
4283 case 0:
4284 gen_helper_mtc0_entrylo1(cpu_env, arg);
4285 rn = "EntryLo1";
4286 break;
4287 default:
4288 goto die;
4289 }
4290 break;
4291 case 4:
4292 switch (sel) {
4293 case 0:
4294 gen_helper_mtc0_context(cpu_env, arg);
4295 rn = "Context";
4296 break;
4297 case 1:
4298 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4299 rn = "ContextConfig";
4300 // break;
4301 default:
4302 goto die;
4303 }
4304 break;
4305 case 5:
4306 switch (sel) {
4307 case 0:
4308 gen_helper_mtc0_pagemask(cpu_env, arg);
4309 rn = "PageMask";
4310 break;
4311 case 1:
4312 check_insn(env, ctx, ISA_MIPS32R2);
4313 gen_helper_mtc0_pagegrain(cpu_env, arg);
4314 rn = "PageGrain";
4315 break;
4316 default:
4317 goto die;
4318 }
4319 break;
4320 case 6:
4321 switch (sel) {
4322 case 0:
4323 gen_helper_mtc0_wired(cpu_env, arg);
4324 rn = "Wired";
4325 break;
4326 case 1:
4327 check_insn(env, ctx, ISA_MIPS32R2);
4328 gen_helper_mtc0_srsconf0(cpu_env, arg);
4329 rn = "SRSConf0";
4330 break;
4331 case 2:
4332 check_insn(env, ctx, ISA_MIPS32R2);
4333 gen_helper_mtc0_srsconf1(cpu_env, arg);
4334 rn = "SRSConf1";
4335 break;
4336 case 3:
4337 check_insn(env, ctx, ISA_MIPS32R2);
4338 gen_helper_mtc0_srsconf2(cpu_env, arg);
4339 rn = "SRSConf2";
4340 break;
4341 case 4:
4342 check_insn(env, ctx, ISA_MIPS32R2);
4343 gen_helper_mtc0_srsconf3(cpu_env, arg);
4344 rn = "SRSConf3";
4345 break;
4346 case 5:
4347 check_insn(env, ctx, ISA_MIPS32R2);
4348 gen_helper_mtc0_srsconf4(cpu_env, arg);
4349 rn = "SRSConf4";
4350 break;
4351 default:
4352 goto die;
4353 }
4354 break;
4355 case 7:
4356 switch (sel) {
4357 case 0:
4358 check_insn(env, ctx, ISA_MIPS32R2);
4359 gen_helper_mtc0_hwrena(cpu_env, arg);
4360 rn = "HWREna";
4361 break;
4362 default:
4363 goto die;
4364 }
4365 break;
4366 case 8:
4367 /* ignored */
4368 rn = "BadVAddr";
4369 break;
4370 case 9:
4371 switch (sel) {
4372 case 0:
4373 gen_helper_mtc0_count(cpu_env, arg);
4374 rn = "Count";
4375 break;
4376 /* 6,7 are implementation dependent */
4377 default:
4378 goto die;
4379 }
4380 break;
4381 case 10:
4382 switch (sel) {
4383 case 0:
4384 gen_helper_mtc0_entryhi(cpu_env, arg);
4385 rn = "EntryHi";
4386 break;
4387 default:
4388 goto die;
4389 }
4390 break;
4391 case 11:
4392 switch (sel) {
4393 case 0:
4394 gen_helper_mtc0_compare(cpu_env, arg);
4395 rn = "Compare";
4396 break;
4397 /* 6,7 are implementation dependent */
4398 default:
4399 goto die;
4400 }
4401 break;
4402 case 12:
4403 switch (sel) {
4404 case 0:
4405 save_cpu_state(ctx, 1);
4406 gen_helper_mtc0_status(cpu_env, arg);
4407 /* BS_STOP isn't good enough here, hflags may have changed. */
4408 gen_save_pc(ctx->pc + 4);
4409 ctx->bstate = BS_EXCP;
4410 rn = "Status";
4411 break;
4412 case 1:
4413 check_insn(env, ctx, ISA_MIPS32R2);
4414 gen_helper_mtc0_intctl(cpu_env, arg);
4415 /* Stop translation as we may have switched the execution mode */
4416 ctx->bstate = BS_STOP;
4417 rn = "IntCtl";
4418 break;
4419 case 2:
4420 check_insn(env, ctx, ISA_MIPS32R2);
4421 gen_helper_mtc0_srsctl(cpu_env, arg);
4422 /* Stop translation as we may have switched the execution mode */
4423 ctx->bstate = BS_STOP;
4424 rn = "SRSCtl";
4425 break;
4426 case 3:
4427 check_insn(env, ctx, ISA_MIPS32R2);
4428 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4429 /* Stop translation as we may have switched the execution mode */
4430 ctx->bstate = BS_STOP;
4431 rn = "SRSMap";
4432 break;
4433 default:
4434 goto die;
4435 }
4436 break;
4437 case 13:
4438 switch (sel) {
4439 case 0:
4440 save_cpu_state(ctx, 1);
4441 gen_helper_mtc0_cause(cpu_env, arg);
4442 rn = "Cause";
4443 break;
4444 default:
4445 goto die;
4446 }
4447 break;
4448 case 14:
4449 switch (sel) {
4450 case 0:
4451 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4452 rn = "EPC";
4453 break;
4454 default:
4455 goto die;
4456 }
4457 break;
4458 case 15:
4459 switch (sel) {
4460 case 0:
4461 /* ignored */
4462 rn = "PRid";
4463 break;
4464 case 1:
4465 check_insn(env, ctx, ISA_MIPS32R2);
4466 gen_helper_mtc0_ebase(cpu_env, arg);
4467 rn = "EBase";
4468 break;
4469 default:
4470 goto die;
4471 }
4472 break;
4473 case 16:
4474 switch (sel) {
4475 case 0:
4476 gen_helper_mtc0_config0(cpu_env, arg);
4477 rn = "Config";
4478 /* Stop translation as we may have switched the execution mode */
4479 ctx->bstate = BS_STOP;
4480 break;
4481 case 1:
4482 /* ignored, read only */
4483 rn = "Config1";
4484 break;
4485 case 2:
4486 gen_helper_mtc0_config2(cpu_env, arg);
4487 rn = "Config2";
4488 /* Stop translation as we may have switched the execution mode */
4489 ctx->bstate = BS_STOP;
4490 break;
4491 case 3:
4492 /* ignored, read only */
4493 rn = "Config3";
4494 break;
4495 /* 4,5 are reserved */
4496 /* 6,7 are implementation dependent */
4497 case 6:
4498 /* ignored */
4499 rn = "Config6";
4500 break;
4501 case 7:
4502 /* ignored */
4503 rn = "Config7";
4504 break;
4505 default:
4506 rn = "Invalid config selector";
4507 goto die;
4508 }
4509 break;
4510 case 17:
4511 switch (sel) {
4512 case 0:
4513 gen_helper_mtc0_lladdr(cpu_env, arg);
4514 rn = "LLAddr";
4515 break;
4516 default:
4517 goto die;
4518 }
4519 break;
4520 case 18:
4521 switch (sel) {
4522 case 0 ... 7:
4523 gen_helper_0e1i(mtc0_watchlo, arg, sel);
4524 rn = "WatchLo";
4525 break;
4526 default:
4527 goto die;
4528 }
4529 break;
4530 case 19:
4531 switch (sel) {
4532 case 0 ... 7:
4533 gen_helper_0e1i(mtc0_watchhi, arg, sel);
4534 rn = "WatchHi";
4535 break;
4536 default:
4537 goto die;
4538 }
4539 break;
4540 case 20:
4541 switch (sel) {
4542 case 0:
4543 #if defined(TARGET_MIPS64)
4544 check_insn(env, ctx, ISA_MIPS3);
4545 gen_helper_mtc0_xcontext(cpu_env, arg);
4546 rn = "XContext";
4547 break;
4548 #endif
4549 default:
4550 goto die;
4551 }
4552 break;
4553 case 21:
4554 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4555 switch (sel) {
4556 case 0:
4557 gen_helper_mtc0_framemask(cpu_env, arg);
4558 rn = "Framemask";
4559 break;
4560 default:
4561 goto die;
4562 }
4563 break;
4564 case 22:
4565 /* ignored */
4566 rn = "Diagnostic"; /* implementation dependent */
4567 break;
4568 case 23:
4569 switch (sel) {
4570 case 0:
4571 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
4572 /* BS_STOP isn't good enough here, hflags may have changed. */
4573 gen_save_pc(ctx->pc + 4);
4574 ctx->bstate = BS_EXCP;
4575 rn = "Debug";
4576 break;
4577 case 1:
4578 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
4579 rn = "TraceControl";
4580 /* Stop translation as we may have switched the execution mode */
4581 ctx->bstate = BS_STOP;
4582 // break;
4583 case 2:
4584 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
4585 rn = "TraceControl2";
4586 /* Stop translation as we may have switched the execution mode */
4587 ctx->bstate = BS_STOP;
4588 // break;
4589 case 3:
4590 /* Stop translation as we may have switched the execution mode */
4591 ctx->bstate = BS_STOP;
4592 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
4593 rn = "UserTraceData";
4594 /* Stop translation as we may have switched the execution mode */
4595 ctx->bstate = BS_STOP;
4596 // break;
4597 case 4:
4598 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
4599 /* Stop translation as we may have switched the execution mode */
4600 ctx->bstate = BS_STOP;
4601 rn = "TraceBPC";
4602 // break;
4603 default:
4604 goto die;
4605 }
4606 break;
4607 case 24:
4608 switch (sel) {
4609 case 0:
4610 /* EJTAG support */
4611 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
4612 rn = "DEPC";
4613 break;
4614 default:
4615 goto die;
4616 }
4617 break;
4618 case 25:
4619 switch (sel) {
4620 case 0:
4621 gen_helper_mtc0_performance0(cpu_env, arg);
4622 rn = "Performance0";
4623 break;
4624 case 1:
4625 // gen_helper_mtc0_performance1(arg);
4626 rn = "Performance1";
4627 // break;
4628 case 2:
4629 // gen_helper_mtc0_performance2(arg);
4630 rn = "Performance2";
4631 // break;
4632 case 3:
4633 // gen_helper_mtc0_performance3(arg);
4634 rn = "Performance3";
4635 // break;
4636 case 4:
4637 // gen_helper_mtc0_performance4(arg);
4638 rn = "Performance4";
4639 // break;
4640 case 5:
4641 // gen_helper_mtc0_performance5(arg);
4642 rn = "Performance5";
4643 // break;
4644 case 6:
4645 // gen_helper_mtc0_performance6(arg);
4646 rn = "Performance6";
4647 // break;
4648 case 7:
4649 // gen_helper_mtc0_performance7(arg);
4650 rn = "Performance7";
4651 // break;
4652 default:
4653 goto die;
4654 }
4655 break;
4656 case 26:
4657 /* ignored */
4658 rn = "ECC";
4659 break;
4660 case 27:
4661 switch (sel) {
4662 case 0 ... 3:
4663 /* ignored */
4664 rn = "CacheErr";
4665 break;
4666 default:
4667 goto die;
4668 }
4669 break;
4670 case 28:
4671 switch (sel) {
4672 case 0:
4673 case 2:
4674 case 4:
4675 case 6:
4676 gen_helper_mtc0_taglo(cpu_env, arg);
4677 rn = "TagLo";
4678 break;
4679 case 1:
4680 case 3:
4681 case 5:
4682 case 7:
4683 gen_helper_mtc0_datalo(cpu_env, arg);
4684 rn = "DataLo";
4685 break;
4686 default:
4687 goto die;
4688 }
4689 break;
4690 case 29:
4691 switch (sel) {
4692 case 0:
4693 case 2:
4694 case 4:
4695 case 6:
4696 gen_helper_mtc0_taghi(cpu_env, arg);
4697 rn = "TagHi";
4698 break;
4699 case 1:
4700 case 3:
4701 case 5:
4702 case 7:
4703 gen_helper_mtc0_datahi(cpu_env, arg);
4704 rn = "DataHi";
4705 break;
4706 default:
4707 rn = "invalid sel";
4708 goto die;
4709 }
4710 break;
4711 case 30:
4712 switch (sel) {
4713 case 0:
4714 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
4715 rn = "ErrorEPC";
4716 break;
4717 default:
4718 goto die;
4719 }
4720 break;
4721 case 31:
4722 switch (sel) {
4723 case 0:
4724 /* EJTAG support */
4725 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4726 rn = "DESAVE";
4727 break;
4728 default:
4729 goto die;
4730 }
4731 /* Stop translation as we may have switched the execution mode */
4732 ctx->bstate = BS_STOP;
4733 break;
4734 default:
4735 goto die;
4736 }
4737 (void)rn; /* avoid a compiler warning */
4738 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4739 /* For simplicity assume that all writes can cause interrupts. */
4740 if (use_icount) {
4741 gen_io_end();
4742 ctx->bstate = BS_STOP;
4743 }
4744 return;
4745
4746 die:
4747 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4748 generate_exception(ctx, EXCP_RI);
4749 }
4750
4751 #if defined(TARGET_MIPS64)
4752 static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4753 {
4754 const char *rn = "invalid";
4755
4756 if (sel != 0)
4757 check_insn(env, ctx, ISA_MIPS64);
4758
4759 switch (reg) {
4760 case 0:
4761 switch (sel) {
4762 case 0:
4763 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4764 rn = "Index";
4765 break;
4766 case 1:
4767 check_insn(env, ctx, ASE_MT);
4768 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4769 rn = "MVPControl";
4770 break;
4771 case 2:
4772 check_insn(env, ctx, ASE_MT);
4773 gen_helper_mfc0_mvpconf0(arg, cpu_env);
4774 rn = "MVPConf0";
4775 break;
4776 case 3:
4777 check_insn(env, ctx, ASE_MT);
4778 gen_helper_mfc0_mvpconf1(arg, cpu_env);
4779 rn = "MVPConf1";
4780 break;
4781 default:
4782 goto die;
4783 }
4784 break;
4785 case 1:
4786 switch (sel) {
4787 case 0:
4788 gen_helper_mfc0_random(arg, cpu_env);
4789 rn = "Random";
4790 break;
4791 case 1:
4792 check_insn(env, ctx, ASE_MT);
4793 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4794 rn = "VPEControl";
4795 break;
4796 case 2:
4797 check_insn(env, ctx, ASE_MT);
4798 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4799 rn = "VPEConf0";
4800 break;
4801 case 3:
4802 check_insn(env, ctx, ASE_MT);
4803 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4804 rn = "VPEConf1";
4805 break;
4806 case 4:
4807 check_insn(env, ctx, ASE_MT);
4808 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
4809 rn = "YQMask";
4810 break;
4811 case 5:
4812 check_insn(env, ctx, ASE_MT);
4813 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
4814 rn = "VPESchedule";
4815 break;
4816 case 6:
4817 check_insn(env, ctx, ASE_MT);
4818 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4819 rn = "VPEScheFBack";
4820 break;
4821 case 7:
4822 check_insn(env, ctx, ASE_MT);
4823 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4824 rn = "VPEOpt";
4825 break;
4826 default:
4827 goto die;
4828 }
4829 break;
4830 case 2:
4831 switch (sel) {
4832 case 0:
4833 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4834 rn = "EntryLo0";
4835 break;
4836 case 1:
4837 check_insn(env, ctx, ASE_MT);
4838 gen_helper_mfc0_tcstatus(arg, cpu_env);
4839 rn = "TCStatus";
4840 break;
4841 case 2:
4842 check_insn(env, ctx, ASE_MT);
4843 gen_helper_mfc0_tcbind(arg, cpu_env);
4844 rn = "TCBind";
4845 break;
4846 case 3:
4847 check_insn(env, ctx, ASE_MT);
4848 gen_helper_dmfc0_tcrestart(arg, cpu_env);
4849 rn = "TCRestart";
4850 break;
4851 case 4:
4852 check_insn(env, ctx, ASE_MT);
4853 gen_helper_dmfc0_tchalt(arg, cpu_env);
4854 rn = "TCHalt";
4855 break;
4856 case 5:
4857 check_insn(env, ctx, ASE_MT);
4858 gen_helper_dmfc0_tccontext(arg, cpu_env);
4859 rn = "TCContext";
4860 break;
4861 case 6:
4862 check_insn(env, ctx, ASE_MT);
4863 gen_helper_dmfc0_tcschedule(arg, cpu_env);
4864 rn = "TCSchedule";
4865 break;
4866 case 7:
4867 check_insn(env, ctx, ASE_MT);
4868 gen_helper_dmfc0_tcschefback(arg, cpu_env);
4869 rn = "TCScheFBack";
4870 break;
4871 default:
4872 goto die;
4873 }
4874 break;
4875 case 3:
4876 switch (sel) {
4877 case 0:
4878 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4879 rn = "EntryLo1";
4880 break;
4881 default:
4882 goto die;
4883 }
4884 break;
4885 case 4:
4886 switch (sel) {
4887 case 0:
4888 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4889 rn = "Context";
4890 break;
4891 case 1:
4892 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4893 rn = "ContextConfig";
4894 // break;
4895 default:
4896 goto die;
4897 }
4898 break;
4899 case 5:
4900 switch (sel) {
4901 case 0:
4902 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4903 rn = "PageMask";
4904 break;
4905 case 1:
4906 check_insn(env, ctx, ISA_MIPS32R2);
4907 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4908 rn = "PageGrain";
4909 break;
4910 default:
4911 goto die;
4912 }
4913 break;
4914 case 6:
4915 switch (sel) {
4916 case 0:
4917 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4918 rn = "Wired";
4919 break;
4920 case 1:
4921 check_insn(env, ctx, ISA_MIPS32R2);
4922 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4923 rn = "SRSConf0";
4924 break;
4925 case 2:
4926 check_insn(env, ctx, ISA_MIPS32R2);
4927 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4928 rn = "SRSConf1";
4929 break;
4930 case 3:
4931 check_insn(env, ctx, ISA_MIPS32R2);
4932 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4933 rn = "SRSConf2";
4934 break;
4935 case 4:
4936 check_insn(env, ctx, ISA_MIPS32R2);
4937 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4938 rn = "SRSConf3";
4939 break;
4940 case 5:
4941 check_insn(env, ctx, ISA_MIPS32R2);
4942 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4943 rn = "SRSConf4";
4944 break;
4945 default:
4946 goto die;
4947 }
4948 break;
4949 case 7:
4950 switch (sel) {
4951 case 0:
4952 check_insn(env, ctx, ISA_MIPS32R2);
4953 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4954 rn = "HWREna";
4955 break;
4956 default:
4957 goto die;
4958 }
4959 break;
4960 case 8:
4961 switch (sel) {
4962 case 0:
4963 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4964 rn = "BadVAddr";
4965 break;
4966 default:
4967 goto die;
4968 }
4969 break;
4970 case 9:
4971 switch (sel) {
4972 case 0:
4973 /* Mark as an IO operation because we read the time. */
4974 if (use_icount)
4975 gen_io_start();
4976 gen_helper_mfc0_count(arg, cpu_env);
4977 if (use_icount) {
4978 gen_io_end();
4979 }
4980 /* Break the TB to be able to take timer interrupts immediately
4981 after reading count. */
4982 ctx->bstate = BS_STOP;
4983 rn = "Count";
4984 break;
4985 /* 6,7 are implementation dependent */
4986 default:
4987 goto die;
4988 }
4989 break;
4990 case 10:
4991 switch (sel) {
4992 case 0:
4993 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4994 rn = "EntryHi";
4995 break;
4996 default:
4997 goto die;
4998 }
4999 break;
5000 case 11:
5001 switch (sel) {
5002 case 0:
5003 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5004 rn = "Compare";
5005 break;
5006 /* 6,7 are implementation dependent */
5007 default:
5008 goto die;
5009 }
5010 break;
5011 case 12:
5012 switch (sel) {
5013 case 0:
5014 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5015 rn = "Status";
5016 break;
5017 case 1:
5018 check_insn(env, ctx, ISA_MIPS32R2);
5019 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5020 rn = "IntCtl";
5021 break;
5022 case 2:
5023 check_insn(env, ctx, ISA_MIPS32R2);
5024 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5025 rn = "SRSCtl";
5026 break;
5027 case 3:
5028 check_insn(env, ctx, ISA_MIPS32R2);
5029 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5030 rn = "SRSMap";
5031 break;
5032 default:
5033 goto die;
5034 }
5035 break;
5036 case 13:
5037 switch (sel) {
5038 case 0:
5039 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5040 rn = "Cause";
5041 break;
5042 default:
5043 goto die;
5044 }
5045 break;
5046 case 14:
5047 switch (sel) {
5048 case 0:
5049 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5050 rn = "EPC";
5051 break;
5052 default:
5053 goto die;
5054 }
5055 break;
5056 case 15:
5057 switch (sel) {
5058 case 0:
5059 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5060 rn = "PRid";
5061 break;
5062 case 1:
5063 check_insn(env, ctx, ISA_MIPS32R2);
5064 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5065 rn = "EBase";
5066 break;
5067 default:
5068 goto die;
5069 }
5070 break;
5071 case 16:
5072 switch (sel) {
5073 case 0:
5074 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5075 rn = "Config";
5076 break;
5077 case 1:
5078 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5079 rn = "Config1";
5080 break;
5081 case 2:
5082 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5083 rn = "Config2";
5084 break;
5085 case 3:
5086 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5087 rn = "Config3";
5088 break;
5089 /* 6,7 are implementation dependent */
5090 case 6:
5091 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5092 rn = "Config6";
5093 break;
5094 case 7:
5095 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5096 rn = "Config7";
5097 break;
5098 default:
5099 goto die;
5100 }
5101 break;
5102 case 17:
5103 switch (sel) {
5104 case 0:
5105 gen_helper_dmfc0_lladdr(arg, cpu_env);
5106 rn = "LLAddr";
5107 break;
5108 default:
5109 goto die;
5110 }
5111 break;
5112 case 18:
5113 switch (sel) {
5114 case 0 ... 7:
5115 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5116 rn = "WatchLo";
5117 break;
5118 default:
5119 goto die;
5120 }
5121 break;
5122 case 19:
5123 switch (sel) {
5124 case 0 ... 7:
5125 gen_helper_1e0i(mfc0_watchhi, arg, sel);
5126 rn = "WatchHi";
5127 break;
5128 default:
5129 goto die;
5130 }
5131 break;
5132 case 20:
5133 switch (sel) {
5134 case 0:
5135 check_insn(env, ctx, ISA_MIPS3);
5136 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5137 rn = "XContext";
5138 break;
5139 default:
5140 goto die;
5141 }
5142 break;
5143 case 21:
5144 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5145 switch (sel) {
5146 case 0:
5147 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5148 rn = "Framemask";
5149 break;
5150 default:
5151 goto die;
5152 }
5153 break;
5154 case 22:
5155 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5156 rn = "'Diagnostic"; /* implementation dependent */
5157 break;
5158 case 23:
5159 switch (sel) {
5160 case 0:
5161 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5162 rn = "Debug";
5163 break;
5164 case 1:
5165 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5166 rn = "TraceControl";
5167 // break;
5168 case 2:
5169 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5170 rn = "TraceControl2";
5171 // break;
5172 case 3:
5173 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5174 rn = "UserTraceData";
5175 // break;
5176 case 4:
5177 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5178 rn = "TraceBPC";
5179 // break;
5180 default:
5181 goto die;
5182 }
5183 break;
5184 case 24:
5185 switch (sel) {
5186 case 0:
5187 /* EJTAG support */
5188 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5189 rn = "DEPC";
5190 break;
5191 default:
5192 goto die;
5193 }
5194 break;
5195 case 25:
5196 switch (sel) {
5197 case 0:
5198 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5199 rn = "Performance0";
5200 break;
5201 case 1:
5202 // gen_helper_dmfc0_performance1(arg);
5203 rn = "Performance1";
5204 // break;
5205 case 2:
5206 // gen_helper_dmfc0_performance2(arg);
5207 rn = "Performance2";
5208 // break;
5209 case 3:
5210 // gen_helper_dmfc0_performance3(arg);
5211 rn = "Performance3";
5212 // break;
5213 case 4:
5214 // gen_helper_dmfc0_performance4(arg);
5215 rn = "Performance4";
5216 // break;
5217 case 5:
5218 // gen_helper_dmfc0_performance5(arg);
5219 rn = "Performance5";
5220 // break;
5221 case 6:
5222 // gen_helper_dmfc0_performance6(arg);
5223 rn = "Performance6";
5224 // break;
5225 case 7:
5226 // gen_helper_dmfc0_performance7(arg);
5227 rn = "Performance7";
5228 // break;
5229 default:
5230 goto die;
5231 }
5232 break;
5233 case 26:
5234 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5235 rn = "ECC";
5236 break;
5237 case 27:
5238 switch (sel) {
5239 /* ignored */
5240 case 0 ... 3:
5241 tcg_gen_movi_tl(arg, 0); /* unimplemented */
5242 rn = "CacheErr";
5243 break;
5244 default:
5245 goto die;
5246 }
5247 break;
5248 case 28:
5249 switch (sel) {
5250 case 0:
5251 case 2:
5252 case 4:
5253 case 6:
5254 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5255 rn = "TagLo";
5256 break;
5257 case 1:
5258 case 3:
5259 case 5:
5260 case 7:
5261 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5262 rn = "DataLo";
5263 break;
5264 default:
5265 goto die;
5266 }
5267 break;
5268 case 29:
5269 switch (sel) {
5270 case 0:
5271 case 2:
5272 case 4:
5273 case 6:
5274 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5275 rn = "TagHi";
5276 break;
5277 case 1:
5278 case 3:
5279 case 5:
5280 case 7:
5281 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5282 rn = "DataHi";
5283 break;
5284 default:
5285 goto die;
5286 }
5287 break;
5288 case 30:
5289 switch (sel) {
5290 case 0:
5291 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5292 rn = "ErrorEPC";
5293 break;
5294 default:
5295 goto die;
5296 }
5297 break;
5298 case 31:
5299 switch (sel) {
5300 case 0:
5301 /* EJTAG support */
5302 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5303 rn = "DESAVE";
5304 break;
5305 default:
5306 goto die;
5307 }
5308 break;
5309 default:
5310 goto die;
5311 }
5312 (void)rn; /* avoid a compiler warning */
5313 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5314 return;
5315
5316 die:
5317 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5318 generate_exception(ctx, EXCP_RI);
5319 }
5320
5321 static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
5322 {
5323 const char *rn = "invalid";
5324
5325 if (sel != 0)
5326 check_insn(env, ctx, ISA_MIPS64);
5327
5328 if (use_icount)
5329 gen_io_start();
5330
5331 switch (reg) {
5332 case 0:
5333 switch (sel) {
5334 case 0:
5335 gen_helper_mtc0_index(cpu_env, arg);
5336 rn = "Index";
5337 break;
5338 case 1:
5339 check_insn(env, ctx, ASE_MT);
5340 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5341 rn = "MVPControl";
5342 break;
5343 case 2:
5344 check_insn(env, ctx, ASE_MT);
5345 /* ignored */
5346 rn = "MVPConf0";
5347 break;
5348 case 3:
5349 check_insn(env, ctx, ASE_MT);
5350 /* ignored */
5351 rn = "MVPConf1";
5352 break;
5353 default:
5354 goto die;
5355 }
5356 break;
5357 case 1:
5358 switch (sel) {
5359 case 0:
5360 /* ignored */
5361 rn = "Random";
5362 break;
5363 case 1:
5364 check_insn(env, ctx, ASE_MT);
5365 gen_helper_mtc0_vpecontrol(cpu_env, arg);
5366 rn = "VPEControl";
5367 break;
5368 case 2:
5369 check_insn(env, ctx, ASE_MT);
5370 gen_helper_mtc0_vpeconf0(cpu_env, arg);
5371 rn = "VPEConf0";
5372 break;
5373 case 3:
5374 check_insn(env, ctx, ASE_MT);
5375 gen_helper_mtc0_vpeconf1(cpu_env, arg);
5376 rn = "VPEConf1";
5377 break;
5378 case 4:
5379 check_insn(env, ctx, ASE_MT);
5380 gen_helper_mtc0_yqmask(cpu_env, arg);
5381 rn = "YQMask";
5382 break;
5383 case 5:
5384 check_insn(env, ctx, ASE_MT);
5385 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5386 rn = "VPESchedule";
5387 break;
5388 case 6:
5389 check_insn(env, ctx, ASE_MT);
5390 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5391 rn = "VPEScheFBack";
5392 break;
5393 case 7:
5394 check_insn(env, ctx, ASE_MT);
5395 gen_helper_mtc0_vpeopt(cpu_env, arg);
5396 rn = "VPEOpt";
5397 break;
5398 default:
5399 goto die;
5400 }
5401 break;
5402 case 2:
5403 switch (sel) {
5404 case 0:
5405 gen_helper_mtc0_entrylo0(cpu_env, arg);
5406 rn = "EntryLo0";
5407 break;
5408 case 1:
5409 check_insn(env, ctx, ASE_MT);
5410 gen_helper_mtc0_tcstatus(cpu_env, arg);
5411 rn = "TCStatus";
5412 break;
5413 case 2:
5414 check_insn(env, ctx, ASE_MT);
5415 gen_helper_mtc0_tcbind(cpu_env, arg);
5416 rn = "TCBind";
5417 break;
5418 case 3:
5419 check_insn(env, ctx, ASE_MT);
5420 gen_helper_mtc0_tcrestart(cpu_env, arg);
5421 rn = "TCRestart";
5422 break;
5423 case 4:
5424 check_insn(env, ctx, ASE_MT);
5425 gen_helper_mtc0_tchalt(cpu_env, arg);
5426 rn = "TCHalt";
5427 break;
5428 case 5:
5429 check_insn(env, ctx, ASE_MT);
5430 gen_helper_mtc0_tccontext(cpu_env, arg);
5431 rn = "TCContext";
5432 break;
5433 case 6:
5434 check_insn(env, ctx, ASE_MT);
5435 gen_helper_mtc0_tcschedule(cpu_env, arg);
5436 rn = "TCSchedule";
5437 break;
5438 case 7:
5439 check_insn(env, ctx, ASE_MT);
5440 gen_helper_mtc0_tcschefback(cpu_env, arg);
5441 rn = "TCScheFBack";
5442 break;
5443 default:
5444 goto die;
5445 }
5446 break;
5447 case 3:
5448 switch (sel) {
5449 case 0:
5450 gen_helper_mtc0_entrylo1(cpu_env, arg);
5451 rn = "EntryLo1";
5452 break;
5453 default:
5454 goto die;
5455 }
5456 break;
5457 case 4:
5458 switch (sel) {
5459 case 0:
5460 gen_helper_mtc0_context(cpu_env, arg);
5461 rn = "Context";
5462 break;
5463 case 1:
5464 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5465 rn = "ContextConfig";
5466 // break;
5467 default:
5468 goto die;
5469 }
5470 break;
5471 case 5:
5472 switch (sel) {
5473 case 0:
5474 gen_helper_mtc0_pagemask(cpu_env, arg);
5475 rn = "PageMask";
5476 break;
5477 case 1:
5478 check_insn(env, ctx, ISA_MIPS32R2);
5479 gen_helper_mtc0_pagegrain(cpu_env, arg);
5480 rn = "PageGrain";
5481 break;
5482 default:
5483 goto die;
5484 }
5485 break;
5486 case 6:
5487 switch (sel) {
5488 case 0:
5489 gen_helper_mtc0_wired(cpu_env, arg);
5490 rn = "Wired";
5491 break;
5492 case 1:
5493 check_insn(env, ctx, ISA_MIPS32R2);
5494 gen_helper_mtc0_srsconf0(cpu_env, arg);
5495 rn = "SRSConf0";
5496 break;
5497 case 2:
5498 check_insn(env, ctx, ISA_MIPS32R2);
5499 gen_helper_mtc0_srsconf1(cpu_env, arg);
5500 rn = "SRSConf1";
5501 break;
5502 case 3:
5503 check_insn(env, ctx, ISA_MIPS32R2);
5504 gen_helper_mtc0_srsconf2(cpu_env, arg);
5505 rn = "SRSConf2";
5506 break;
5507 case 4:
5508 check_insn(env, ctx, ISA_MIPS32R2);
5509 gen_helper_mtc0_srsconf3(cpu_env, arg);
5510 rn = "SRSConf3";
5511 break;
5512 case 5:
5513 check_insn(env, ctx, ISA_MIPS32R2);
5514 gen_helper_mtc0_srsconf4(cpu_env, arg);
5515 rn = "SRSConf4";
5516 break;
5517 default:
5518 goto die;
5519 }
5520 break;
5521 case 7:
5522 switch (sel) {
5523 case 0:
5524 check_insn(env, ctx, ISA_MIPS32R2);
5525 gen_helper_mtc0_hwrena(cpu_env, arg);
5526 rn = "HWREna";
5527 break;
5528 default:
5529 goto die;
5530 }
5531 break;
5532 case 8:
5533 /* ignored */
5534 rn = "BadVAddr";
5535 break;
5536 case 9:
5537 switch (sel) {
5538 case 0:
5539 gen_helper_mtc0_count(cpu_env, arg);
5540 rn = "Count";
5541 break;
5542 /* 6,7 are implementation dependent */
5543 default:
5544 goto die;
5545 }
5546 /* Stop translation as we may have switched the execution mode */
5547 ctx->bstate = BS_STOP;
5548 break;
5549 case 10:
5550 switch (sel) {
5551 case 0:
5552 gen_helper_mtc0_entryhi(cpu_env, arg);
5553 rn = "EntryHi";
5554 break;
5555 default:
5556 goto die;
5557 }
5558 break;
5559 case 11:
5560 switch (sel) {
5561 case 0:
5562 gen_helper_mtc0_compare(cpu_env, arg);
5563 rn = "Compare";
5564 break;
5565 /* 6,7 are implementation dependent */
5566 default:
5567 goto die;
5568 }
5569 /* Stop translation as we may have switched the execution mode */
5570 ctx->bstate = BS_STOP;
5571 break;
5572 case 12:
5573 switch (sel) {
5574 case 0:
5575 save_cpu_state(ctx, 1);
5576 gen_helper_mtc0_status(cpu_env, arg);
5577 /* BS_STOP isn't good enough here, hflags may have changed. */
5578 gen_save_pc(ctx->pc + 4);
5579 ctx->bstate = BS_EXCP;
5580 rn = "Status";
5581 break;
5582 case 1:
5583 check_insn(env, ctx, ISA_MIPS32R2);
5584 gen_helper_mtc0_intctl(cpu_env, arg);
5585 /* Stop translation as we may have switched the execution mode */
5586 ctx->bstate = BS_STOP;
5587 rn = "IntCtl";
5588 break;
5589 case 2:
5590 check_insn(env, ctx, ISA_MIPS32R2);
5591 gen_helper_mtc0_srsctl(cpu_env, arg);
5592 /* Stop translation as we may have switched the execution mode */
5593 ctx->bstate = BS_STOP;
5594 rn = "SRSCtl";
5595 break;
5596 case 3:
5597 check_insn(env, ctx, ISA_MIPS32R2);
5598 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5599 /* Stop translation as we may have switched the execution mode */
5600 ctx->bstate = BS_STOP;
5601 rn = "SRSMap";
5602 break;
5603 default:
5604 goto die;
5605 }
5606 break;
5607 case 13:
5608 switch (sel) {
5609 case 0:
5610 save_cpu_state(ctx, 1);
5611 /* Mark as an IO operation because we may trigger a software
5612 interrupt. */
5613 if (use_icount) {
5614 gen_io_start();
5615 }
5616 gen_helper_mtc0_cause(cpu_env, arg);
5617 if (use_icount) {
5618 gen_io_end();
5619 }
5620 /* Stop translation as we may have triggered an intetrupt */
5621 ctx->bstate = BS_STOP;
5622 rn = "Cause";
5623 break;
5624 default:
5625 goto die;
5626 }
5627 break;
5628 case 14:
5629 switch (sel) {
5630 case 0:
5631 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5632 rn = "EPC";
5633 break;
5634 default:
5635 goto die;
5636 }
5637 break;
5638 case 15:
5639 switch (sel) {
5640 case 0:
5641 /* ignored */
5642 rn = "PRid";
5643 break;
5644 case 1:
5645 check_insn(env, ctx, ISA_MIPS32R2);
5646 gen_helper_mtc0_ebase(cpu_env, arg);
5647 rn = "EBase";
5648 break;
5649 default:
5650 goto die;
5651 }
5652 break;
5653 case 16:
5654 switch (sel) {
5655 case 0:
5656 gen_helper_mtc0_config0(cpu_env, arg);
5657 rn = "Config";
5658 /* Stop translation as we may have switched the execution mode */
5659 ctx->bstate = BS_STOP;
5660 break;
5661 case 1:
5662 /* ignored, read only */
5663 rn = "Config1";
5664 break;
5665 case 2:
5666 gen_helper_mtc0_config2(cpu_env, arg);
5667 rn = "Config2";
5668 /* Stop translation as we may have switched the execution mode */
5669 ctx->bstate = BS_STOP;
5670 break;
5671 case 3:
5672 /* ignored */
5673 rn = "Config3";
5674 break;
5675 /* 6,7 are implementation dependent */
5676 default:
5677 rn = "Invalid config selector";
5678 goto die;
5679 }
5680 break;
5681 case 17:
5682 switch (sel) {
5683 case 0:
5684 gen_helper_mtc0_lladdr(cpu_env, arg);
5685 rn = "LLAddr";
5686 break;
5687 default:
5688 goto die;
5689 }
5690 break;
5691 case 18:
5692 switch (sel) {
5693 case 0 ... 7:
5694 gen_helper_0e1i(mtc0_watchlo, arg, sel);
5695 rn = "WatchLo";
5696 break;
5697 default:
5698 goto die;
5699 }
5700 break;
5701 case 19:
5702 switch (sel) {
5703 case 0 ... 7:
5704 gen_helper_0e1i(mtc0_watchhi, arg, sel);
5705 rn = "WatchHi";
5706 break;
5707 default:
5708 goto die;
5709 }
5710 break;
5711 case 20:
5712 switch (sel) {
5713 case 0:
5714 check_insn(env, ctx, ISA_MIPS3);
5715 gen_helper_mtc0_xcontext(cpu_env, arg);
5716 rn = "XContext";
5717 break;
5718 default:
5719 goto die;
5720 }
5721 break;
5722 case 21:
5723 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5724 switch (sel) {
5725 case 0:
5726 gen_helper_mtc0_framemask(cpu_env, arg);
5727 rn = "Framemask";
5728 break;
5729 default:
5730 goto die;
5731 }
5732 break;
5733 case 22:
5734 /* ignored */
5735 rn = "Diagnostic"; /* implementation dependent */
5736 break;
5737 case 23:
5738 switch (sel) {
5739 case 0:
5740 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5741 /* BS_STOP isn't good enough here, hflags may have changed. */
5742 gen_save_pc(ctx->pc + 4);
5743 ctx->bstate = BS_EXCP;
5744 rn = "Debug";
5745 break;
5746 case 1:
5747 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5748 /* Stop translation as we may have switched the execution mode */
5749 ctx->bstate = BS_STOP;
5750 rn = "TraceControl";
5751 // break;
5752 case 2:
5753 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5754 /* Stop translation as we may have switched the execution mode */
5755 ctx->bstate = BS_STOP;
5756 rn = "TraceControl2";
5757 // break;
5758 case 3:
5759 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5760 /* Stop translation as we may have switched the execution mode */
5761 ctx->bstate = BS_STOP;
5762 rn = "UserTraceData";
5763 // break;
5764 case 4:
5765 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5766 /* Stop translation as we may have switched the execution mode */
5767 ctx->bstate = BS_STOP;
5768 rn = "TraceBPC";
5769 // break;
5770 default:
5771 goto die;
5772 }
5773 break;
5774 case 24:
5775 switch (sel) {
5776 case 0:
5777 /* EJTAG support */
5778 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5779 rn = "DEPC";
5780 break;
5781 default:
5782 goto die;
5783 }
5784 break;
5785 case 25:
5786 switch (sel) {
5787 case 0:
5788 gen_helper_mtc0_performance0(cpu_env, arg);
5789 rn = "Performance0";
5790 break;
5791 case 1:
5792 // gen_helper_mtc0_performance1(cpu_env, arg);
5793 rn = "Performance1";
5794 // break;
5795 case 2:
5796 // gen_helper_mtc0_performance2(cpu_env, arg);
5797 rn = "Performance2";
5798 // break;
5799 case 3:
5800 // gen_helper_mtc0_performance3(cpu_env, arg);
5801 rn = "Performance3";
5802 // break;
5803 case 4:
5804 // gen_helper_mtc0_performance4(cpu_env, arg);
5805 rn = "Performance4";
5806 // break;
5807 case 5:
5808 // gen_helper_mtc0_performance5(cpu_env, arg);
5809 rn = "Performance5";
5810 // break;
5811 case 6:
5812 // gen_helper_mtc0_performance6(cpu_env, arg);
5813 rn = "Performance6";
5814 // break;
5815 case 7:
5816 // gen_helper_mtc0_performance7(cpu_env, arg);
5817 rn = "Performance7";
5818 // break;
5819 default:
5820 goto die;
5821 }
5822 break;
5823 case 26:
5824 /* ignored */
5825 rn = "ECC";
5826 break;
5827 case 27:
5828 switch (sel) {
5829 case 0 ... 3:
5830 /* ignored */
5831 rn = "CacheErr";
5832 break;
5833 default:
5834 goto die;
5835 }
5836 break;
5837 case 28:
5838 switch (sel) {
5839 case 0:
5840 case 2:
5841 case 4:
5842 case 6:
5843 gen_helper_mtc0_taglo(cpu_env, arg);
5844 rn = "TagLo";
5845 break;
5846 case 1:
5847 case 3:
5848 case 5:
5849 case 7:
5850 gen_helper_mtc0_datalo(cpu_env, arg);
5851 rn = "DataLo";
5852 break;
5853 default:
5854 goto die;
5855 }
5856 break;
5857 case 29:
5858 switch (sel) {
5859 case 0:
5860 case 2:
5861 case 4:
5862 case 6:
5863 gen_helper_mtc0_taghi(cpu_env, arg);
5864 rn = "TagHi";
5865 break;
5866 case 1:
5867 case 3:
5868 case 5:
5869 case 7:
5870 gen_helper_mtc0_datahi(cpu_env, arg);
5871 rn = "DataHi";
5872 break;
5873 default:
5874 rn = "invalid sel";
5875 goto die;
5876 }
5877 break;
5878 case 30:
5879 switch (sel) {
5880 case 0:
5881 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5882 rn = "ErrorEPC";
5883 break;
5884 default:
5885 goto die;
5886 }
5887 break;
5888 case 31:
5889 switch (sel) {
5890 case 0:
5891 /* EJTAG support */
5892 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5893 rn = "DESAVE";
5894 break;
5895 default:
5896 goto die;
5897 }
5898 /* Stop translation as we may have switched the execution mode */
5899 ctx->bstate = BS_STOP;
5900 break;
5901 default:
5902 goto die;
5903 }
5904 (void)rn; /* avoid a compiler warning */
5905 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5906 /* For simplicity assume that all writes can cause interrupts. */
5907 if (use_icount) {
5908 gen_io_end();
5909 ctx->bstate = BS_STOP;
5910 }
5911 return;
5912
5913 die:
5914 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5915 generate_exception(ctx, EXCP_RI);
5916 }
5917 #endif /* TARGET_MIPS64 */
5918
5919 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
5920 int u, int sel, int h)
5921 {
5922 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5923 TCGv t0 = tcg_temp_local_new();
5924
5925 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5926 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5927 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5928 tcg_gen_movi_tl(t0, -1);
5929 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5930 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5931 tcg_gen_movi_tl(t0, -1);
5932 else if (u == 0) {
5933 switch (rt) {
5934 case 1:
5935 switch (sel) {
5936 case 1:
5937 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5938 break;
5939 case 2:
5940 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5941 break;
5942 default:
5943 goto die;
5944 break;
5945 }
5946 break;
5947 case 2:
5948 switch (sel) {
5949 case 1:
5950 gen_helper_mftc0_tcstatus(t0, cpu_env);
5951 break;
5952 case 2:
5953 gen_helper_mftc0_tcbind(t0, cpu_env);
5954 break;
5955 case 3:
5956 gen_helper_mftc0_tcrestart(t0, cpu_env);
5957 break;
5958 case 4:
5959 gen_helper_mftc0_tchalt(t0, cpu_env);
5960 break;
5961 case 5:
5962 gen_helper_mftc0_tccontext(t0, cpu_env);
5963 break;
5964 case 6:
5965 gen_helper_mftc0_tcschedule(t0, cpu_env);
5966 break;
5967 case 7:
5968 gen_helper_mftc0_tcschefback(t0, cpu_env);
5969 break;
5970 default:
5971 gen_mfc0(env, ctx, t0, rt, sel);
5972 break;
5973 }
5974 break;
5975 case 10:
5976 switch (sel) {
5977 case 0:
5978 gen_helper_mftc0_entryhi(t0, cpu_env);
5979 break;
5980 default:
5981 gen_mfc0(env, ctx, t0, rt, sel);
5982 break;
5983 }
5984 case 12:
5985 switch (sel) {
5986 case 0:
5987 gen_helper_mftc0_status(t0, cpu_env);
5988 break;
5989 default:
5990 gen_mfc0(env, ctx, t0, rt, sel);
5991 break;
5992 }
5993 case 13:
5994 switch (sel) {
5995 case 0:
5996 gen_helper_mftc0_cause(t0, cpu_env);
5997 break;
5998 default:
5999 goto die;
6000 break;
6001 }
6002 break;
6003 case 14:
6004 switch (sel) {
6005 case 0:
6006 gen_helper_mftc0_epc(t0, cpu_env);
6007 break;
6008 default:
6009 goto die;
6010 break;
6011 }
6012 break;
6013 case 15:
6014 switch (sel) {
6015 case 1:
6016 gen_helper_mftc0_ebase(t0, cpu_env);
6017 break;
6018 default:
6019 goto die;
6020 break;
6021 }
6022 break;
6023 case 16:
6024 switch (sel) {
6025 case 0 ... 7:
6026 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6027 break;
6028 default:
6029 goto die;
6030 break;
6031 }
6032 break;
6033 case 23:
6034 switch (sel) {
6035 case 0:
6036 gen_helper_mftc0_debug(t0, cpu_env);
6037 break;
6038 default:
6039 gen_mfc0(env, ctx, t0, rt, sel);
6040 break;
6041 }
6042 break;
6043 default:
6044 gen_mfc0(env, ctx, t0, rt, sel);
6045 }
6046 } else switch (sel) {
6047 /* GPR registers. */
6048 case 0:
6049 gen_helper_1e0i(mftgpr, t0, rt);
6050 break;
6051 /* Auxiliary CPU registers */
6052 case 1:
6053 switch (rt) {
6054 case 0:
6055 gen_helper_1e0i(mftlo, t0, 0);
6056 break;
6057 case 1:
6058 gen_helper_1e0i(mfthi, t0, 0);
6059 break;
6060 case 2:
6061 gen_helper_1e0i(mftacx, t0, 0);
6062 break;
6063 case 4:
6064 gen_helper_1e0i(mftlo, t0, 1);
6065 break;
6066 case 5:
6067 gen_helper_1e0i(mfthi, t0, 1);
6068 break;
6069 case 6:
6070 gen_helper_1e0i(mftacx, t0, 1);
6071 break;
6072 case 8:
6073 gen_helper_1e0i(mftlo, t0, 2);
6074 break;
6075 case 9:
6076 gen_helper_1e0i(mfthi, t0, 2);
6077 break;
6078 case 10:
6079 gen_helper_1e0i(mftacx, t0, 2);
6080 break;
6081 case 12:
6082 gen_helper_1e0i(mftlo, t0, 3);
6083 break;
6084 case 13:
6085 gen_helper_1e0i(mfthi, t0, 3);
6086 break;
6087 case 14:
6088 gen_helper_1e0i(mftacx, t0, 3);
6089 break;
6090 case 16:
6091 gen_helper_mftdsp(t0, cpu_env);
6092 break;
6093 default:
6094 goto die;
6095 }
6096 break;
6097 /* Floating point (COP1). */
6098 case 2:
6099 /* XXX: For now we support only a single FPU context. */
6100 if (h == 0) {
6101 TCGv_i32 fp0 = tcg_temp_new_i32();
6102
6103 gen_load_fpr32(fp0, rt);
6104 tcg_gen_ext_i32_tl(t0, fp0);
6105 tcg_temp_free_i32(fp0);
6106 } else {
6107 TCGv_i32 fp0 = tcg_temp_new_i32();
6108
6109 gen_load_fpr32h(fp0, rt);
6110 tcg_gen_ext_i32_tl(t0, fp0);
6111 tcg_temp_free_i32(fp0);
6112 }
6113 break;
6114 case 3:
6115 /* XXX: For now we support only a single FPU context. */
6116 gen_helper_1e0i(cfc1, t0, rt);
6117 break;
6118 /* COP2: Not implemented. */
6119 case 4:
6120 case 5:
6121 /* fall through */
6122 default:
6123 goto die;
6124 }
6125 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6126 gen_store_gpr(t0, rd);
6127 tcg_temp_free(t0);
6128 return;
6129
6130 die:
6131 tcg_temp_free(t0);
6132 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6133 generate_exception(ctx, EXCP_RI);
6134 }
6135
6136 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6137 int u, int sel, int h)
6138 {
6139 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6140 TCGv t0 = tcg_temp_local_new();
6141
6142 gen_load_gpr(t0, rt);
6143 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6144 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6145 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6146 /* NOP */ ;
6147 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6148 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6149 /* NOP */ ;
6150 else if (u == 0) {
6151 switch (rd) {
6152 case 1:
6153 switch (sel) {
6154 case 1:
6155 gen_helper_mttc0_vpecontrol(cpu_env, t0);
6156 break;
6157 case 2:
6158 gen_helper_mttc0_vpeconf0(cpu_env, t0);
6159 break;
6160 default:
6161 goto die;
6162 break;
6163 }
6164 break;
6165 case 2:
6166 switch (sel) {
6167 case 1:
6168 gen_helper_mttc0_tcstatus(cpu_env, t0);
6169 break;
6170 case 2:
6171 gen_helper_mttc0_tcbind(cpu_env, t0);
6172 break;
6173 case 3:
6174 gen_helper_mttc0_tcrestart(cpu_env, t0);
6175 break;
6176 case 4:
6177 gen_helper_mttc0_tchalt(cpu_env, t0);
6178 break;
6179 case 5:
6180 gen_helper_mttc0_tccontext(cpu_env, t0);
6181 break;
6182 case 6:
6183 gen_helper_mttc0_tcschedule(cpu_env, t0);
6184 break;
6185 case 7:
6186 gen_helper_mttc0_tcschefback(cpu_env, t0);
6187 break;
6188 default:
6189 gen_mtc0(env, ctx, t0, rd, sel);
6190 break;
6191 }
6192 break;
6193 case 10:
6194 switch (sel) {
6195 case 0:
6196 gen_helper_mttc0_entryhi(cpu_env, t0);
6197 break;
6198 default:
6199 gen_mtc0(env, ctx, t0, rd, sel);
6200 break;
6201 }
6202 case 12:
6203 switch (sel) {
6204 case 0:
6205 gen_helper_mttc0_status(cpu_env, t0);
6206 break;
6207 default:
6208 gen_mtc0(env, ctx, t0, rd, sel);
6209 break;
6210 }
6211 case 13:
6212 switch (sel) {
6213 case 0:
6214 gen_helper_mttc0_cause(cpu_env, t0);
6215 break;
6216 default:
6217 goto die;
6218 break;
6219 }
6220 break;
6221 case 15:
6222 switch (sel) {
6223 case 1:
6224 gen_helper_mttc0_ebase(cpu_env, t0);
6225 break;
6226 default:
6227 goto die;
6228 break;
6229 }
6230 break;
6231 case 23:
6232 switch (sel) {
6233 case 0:
6234 gen_helper_mttc0_debug(cpu_env, t0);
6235 break;
6236 default:
6237 gen_mtc0(env, ctx, t0, rd, sel);
6238 break;
6239 }
6240 break;
6241 default:
6242 gen_mtc0(env, ctx, t0, rd, sel);
6243 }
6244 } else switch (sel) {
6245 /* GPR registers. */
6246 case 0:
6247 gen_helper_0e1i(mttgpr, t0, rd);
6248 break;
6249 /* Auxiliary CPU registers */
6250 case 1:
6251 switch (rd) {
6252 case 0:
6253 gen_helper_0e1i(mttlo, t0, 0);
6254 break;
6255 case 1:
6256 gen_helper_0e1i(mtthi, t0, 0);
6257 break;
6258 case 2:
6259 gen_helper_0e1i(mttacx, t0, 0);
6260 break;
6261 case 4:
6262 gen_helper_0e1i(mttlo, t0, 1);
6263 break;
6264 case 5:
6265 gen_helper_0e1i(mtthi, t0, 1);
6266 break;
6267 case 6:
6268 gen_helper_0e1i(mttacx, t0, 1);
6269 break;
6270 case 8:
6271 gen_helper_0e1i(mttlo, t0, 2);
6272 break;
6273 case 9:
6274 gen_helper_0e1i(mtthi, t0, 2);
6275 break;
6276 case 10:
6277 gen_helper_0e1i(mttacx, t0, 2);
6278 break;
6279 case 12:
6280 gen_helper_0e1i(mttlo, t0, 3);
6281 break;
6282 case 13:
6283 gen_helper_0e1i(mtthi, t0, 3);
6284 break;
6285 case 14:
6286 gen_helper_0e1i(mttacx, t0, 3);
6287 break;
6288 case 16:
6289 gen_helper_mttdsp(cpu_env, t0);
6290 break;
6291 default:
6292 goto die;
6293 }
6294 break;
6295 /* Floating point (COP1). */
6296 case 2:
6297 /* XXX: For now we support only a single FPU context. */
6298 if (h == 0) {
6299 TCGv_i32 fp0 = tcg_temp_new_i32();
6300
6301 tcg_gen_trunc_tl_i32(fp0, t0);
6302 gen_store_fpr32(fp0, rd);
6303 tcg_temp_free_i32(fp0);
6304 } else {
6305 TCGv_i32 fp0 = tcg_temp_new_i32();
6306
6307 tcg_gen_trunc_tl_i32(fp0, t0);
6308 gen_store_fpr32h(fp0, rd);
6309 tcg_temp_free_i32(fp0);
6310 }
6311 break;
6312 case 3:
6313 /* XXX: For now we support only a single FPU context. */
6314 gen_helper_0e1i(ctc1, t0, rd);
6315 break;
6316 /* COP2: Not implemented. */
6317 case 4:
6318 case 5:
6319 /* fall through */
6320 default:
6321 goto die;
6322 }
6323 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6324 tcg_temp_free(t0);
6325 return;
6326
6327 die:
6328 tcg_temp_free(t0);
6329 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6330 generate_exception(ctx, EXCP_RI);
6331 }
6332
6333 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6334 {
6335 const char *opn = "ldst";
6336
6337 check_cp0_enabled(ctx);
6338 switch (opc) {
6339 case OPC_MFC0:
6340 if (rt == 0) {
6341 /* Treat as NOP. */
6342 return;
6343 }
6344 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6345 opn = "mfc0";
6346 break;
6347 case OPC_MTC0:
6348 {
6349 TCGv t0 = tcg_temp_new();
6350
6351 gen_load_gpr(t0, rt);
6352 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6353 tcg_temp_free(t0);
6354 }
6355 opn = "mtc0";
6356 break;
6357 #if defined(TARGET_MIPS64)
6358 case OPC_DMFC0:
6359 check_insn(env, ctx, ISA_MIPS3);
6360 if (rt == 0) {
6361 /* Treat as NOP. */
6362 return;
6363 }
6364 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6365 opn = "dmfc0";
6366 break;
6367 case OPC_DMTC0:
6368 check_insn(env, ctx, ISA_MIPS3);
6369 {
6370 TCGv t0 = tcg_temp_new();
6371
6372 gen_load_gpr(t0, rt);
6373 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6374 tcg_temp_free(t0);
6375 }
6376 opn = "dmtc0";
6377 break;
6378 #endif
6379 case OPC_MFTR:
6380 check_insn(env, ctx, ASE_MT);
6381 if (rd == 0) {
6382 /* Treat as NOP. */
6383 return;
6384 }
6385 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6386 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6387 opn = "mftr";
6388 break;
6389 case OPC_MTTR:
6390 check_insn(env, ctx, ASE_MT);
6391 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6392 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6393 opn = "mttr";
6394 break;
6395 case OPC_TLBWI:
6396 opn = "tlbwi";
6397 if (!env->tlb->helper_tlbwi)
6398 goto die;
6399 gen_helper_tlbwi(cpu_env);
6400 break;
6401 case OPC_TLBWR:
6402 opn = "tlbwr";
6403 if (!env->tlb->helper_tlbwr)
6404 goto die;
6405 gen_helper_tlbwr(cpu_env);
6406 break;
6407 case OPC_TLBP:
6408 opn = "tlbp";
6409 if (!env->tlb->helper_tlbp)
6410 goto die;
6411 gen_helper_tlbp(cpu_env);
6412 break;
6413 case OPC_TLBR:
6414 opn = "tlbr";
6415 if (!env->tlb->helper_tlbr)
6416 goto die;
6417 gen_helper_tlbr(cpu_env);
6418 break;
6419 case OPC_ERET:
6420 opn = "eret";
6421 check_insn(env, ctx, ISA_MIPS2);
6422 gen_helper_eret(cpu_env);
6423 ctx->bstate = BS_EXCP;
6424 break;
6425 case OPC_DERET:
6426 opn = "deret";
6427 check_insn(env, ctx, ISA_MIPS32);
6428 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6429 MIPS_INVAL(opn);
6430 generate_exception(ctx, EXCP_RI);
6431 } else {
6432 gen_helper_deret(cpu_env);
6433 ctx->bstate = BS_EXCP;
6434 }
6435 break;
6436 case OPC_WAIT:
6437 opn = "wait";
6438 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
6439 /* If we get an exception, we want to restart at next instruction */
6440 ctx->pc += 4;
6441 save_cpu_state(ctx, 1);
6442 ctx->pc -= 4;
6443 gen_helper_wait(cpu_env);
6444 ctx->bstate = BS_EXCP;
6445 break;
6446 default:
6447 die:
6448 MIPS_INVAL(opn);
6449 generate_exception(ctx, EXCP_RI);
6450 return;
6451 }
6452 (void)opn; /* avoid a compiler warning */
6453 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6454 }
6455 #endif /* !CONFIG_USER_ONLY */
6456
6457 /* CP1 Branches (before delay slot) */
6458 static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
6459 int32_t cc, int32_t offset)
6460 {
6461 target_ulong btarget;
6462 const char *opn = "cp1 cond branch";
6463 TCGv_i32 t0 = tcg_temp_new_i32();
6464
6465 if (cc != 0)
6466 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6467
6468 btarget = ctx->pc + 4 + offset;
6469
6470 switch (op) {
6471 case OPC_BC1F:
6472 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6473 tcg_gen_not_i32(t0, t0);
6474 tcg_gen_andi_i32(t0, t0, 1);
6475 tcg_gen_extu_i32_tl(bcond, t0);
6476 opn = "bc1f";
6477 goto not_likely;
6478 case OPC_BC1FL:
6479 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6480 tcg_gen_not_i32(t0, t0);
6481 tcg_gen_andi_i32(t0, t0, 1);
6482 tcg_gen_extu_i32_tl(bcond, t0);
6483 opn = "bc1fl";
6484 goto likely;
6485 case OPC_BC1T:
6486 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6487 tcg_gen_andi_i32(t0, t0, 1);
6488 tcg_gen_extu_i32_tl(bcond, t0);
6489 opn = "bc1t";
6490 goto not_likely;
6491 case OPC_BC1TL:
6492 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6493 tcg_gen_andi_i32(t0, t0, 1);
6494 tcg_gen_extu_i32_tl(bcond, t0);
6495 opn = "bc1tl";
6496 likely:
6497 ctx->hflags |= MIPS_HFLAG_BL;
6498 break;
6499 case OPC_BC1FANY2:
6500 {
6501 TCGv_i32 t1 = tcg_temp_new_i32();
6502 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6503 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6504 tcg_gen_nand_i32(t0, t0, t1);
6505 tcg_temp_free_i32(t1);
6506 tcg_gen_andi_i32(t0, t0, 1);
6507 tcg_gen_extu_i32_tl(bcond, t0);
6508 }
6509 opn = "bc1any2f";
6510 goto not_likely;
6511 case OPC_BC1TANY2:
6512 {
6513 TCGv_i32 t1 = tcg_temp_new_i32();
6514 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6515 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6516 tcg_gen_or_i32(t0, t0, t1);
6517 tcg_temp_free_i32(t1);
6518 tcg_gen_andi_i32(t0, t0, 1);
6519 tcg_gen_extu_i32_tl(bcond, t0);
6520 }
6521 opn = "bc1any2t";
6522 goto not_likely;
6523 case OPC_BC1FANY4:
6524 {
6525 TCGv_i32 t1 = tcg_temp_new_i32();
6526 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6527 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6528 tcg_gen_and_i32(t0, t0, t1);
6529 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6530 tcg_gen_and_i32(t0, t0, t1);
6531 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6532 tcg_gen_nand_i32(t0, t0, t1);
6533 tcg_temp_free_i32(t1);
6534 tcg_gen_andi_i32(t0, t0, 1);
6535 tcg_gen_extu_i32_tl(bcond, t0);
6536 }
6537 opn = "bc1any4f";
6538 goto not_likely;
6539 case OPC_BC1TANY4:
6540 {
6541 TCGv_i32 t1 = tcg_temp_new_i32();
6542 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6543 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
6544 tcg_gen_or_i32(t0, t0, t1);
6545 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
6546 tcg_gen_or_i32(t0, t0, t1);
6547 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
6548 tcg_gen_or_i32(t0, t0, t1);
6549 tcg_temp_free_i32(t1);
6550 tcg_gen_andi_i32(t0, t0, 1);
6551 tcg_gen_extu_i32_tl(bcond, t0);
6552 }
6553 opn = "bc1any4t";
6554 not_likely:
6555 ctx->hflags |= MIPS_HFLAG_BC;
6556 break;
6557 default:
6558 MIPS_INVAL(opn);
6559 generate_exception (ctx, EXCP_RI);
6560 goto out;
6561 }
6562 (void)opn; /* avoid a compiler warning */
6563 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6564 ctx->hflags, btarget);
6565 ctx->btarget = btarget;
6566
6567 out:
6568 tcg_temp_free_i32(t0);
6569 }
6570
6571 /* Coprocessor 1 (FPU) */
6572
6573 #define FOP(func, fmt) (((fmt) << 21) | (func))
6574
6575 enum fopcode {
6576 OPC_ADD_S = FOP(0, FMT_S),
6577 OPC_SUB_S = FOP(1, FMT_S),
6578 OPC_MUL_S = FOP(2, FMT_S),
6579 OPC_DIV_S = FOP(3, FMT_S),
6580 OPC_SQRT_S = FOP(4, FMT_S),
6581 OPC_ABS_S = FOP(5, FMT_S),
6582 OPC_MOV_S = FOP(6, FMT_S),
6583 OPC_NEG_S = FOP(7, FMT_S),
6584 OPC_ROUND_L_S = FOP(8, FMT_S),
6585 OPC_TRUNC_L_S = FOP(9, FMT_S),
6586 OPC_CEIL_L_S = FOP(10, FMT_S),
6587 OPC_FLOOR_L_S = FOP(11, FMT_S),
6588 OPC_ROUND_W_S = FOP(12, FMT_S),
6589 OPC_TRUNC_W_S = FOP(13, FMT_S),
6590 OPC_CEIL_W_S = FOP(14, FMT_S),
6591 OPC_FLOOR_W_S = FOP(15, FMT_S),
6592 OPC_MOVCF_S = FOP(17, FMT_S),
6593 OPC_MOVZ_S = FOP(18, FMT_S),
6594 OPC_MOVN_S = FOP(19, FMT_S),
6595 OPC_RECIP_S = FOP(21, FMT_S),
6596 OPC_RSQRT_S = FOP(22, FMT_S),
6597 OPC_RECIP2_S = FOP(28, FMT_S),
6598 OPC_RECIP1_S = FOP(29, FMT_S),
6599 OPC_RSQRT1_S = FOP(30, FMT_S),
6600 OPC_RSQRT2_S = FOP(31, FMT_S),
6601 OPC_CVT_D_S = FOP(33, FMT_S),
6602 OPC_CVT_W_S = FOP(36, FMT_S),
6603 OPC_CVT_L_S = FOP(37, FMT_S),
6604 OPC_CVT_PS_S = FOP(38, FMT_S),
6605 OPC_CMP_F_S = FOP (48, FMT_S),
6606 OPC_CMP_UN_S = FOP (49, FMT_S),
6607 OPC_CMP_EQ_S = FOP (50, FMT_S),
6608 OPC_CMP_UEQ_S = FOP (51, FMT_S),
6609 OPC_CMP_OLT_S = FOP (52, FMT_S),
6610 OPC_CMP_ULT_S = FOP (53, FMT_S),
6611 OPC_CMP_OLE_S = FOP (54, FMT_S),
6612 OPC_CMP_ULE_S = FOP (55, FMT_S),
6613 OPC_CMP_SF_S = FOP (56, FMT_S),
6614 OPC_CMP_NGLE_S = FOP (57, FMT_S),
6615 OPC_CMP_SEQ_S = FOP (58, FMT_S),
6616 OPC_CMP_NGL_S = FOP (59, FMT_S),
6617 OPC_CMP_LT_S = FOP (60, FMT_S),
6618 OPC_CMP_NGE_S = FOP (61, FMT_S),
6619 OPC_CMP_LE_S = FOP (62, FMT_S),
6620 OPC_CMP_NGT_S = FOP (63, FMT_S),
6621
6622 OPC_ADD_D = FOP(0, FMT_D),
6623 OPC_SUB_D = FOP(1, FMT_D),
6624 OPC_MUL_D = FOP(2, FMT_D),
6625 OPC_DIV_D = FOP(3, FMT_D),
6626 OPC_SQRT_D = FOP(4, FMT_D),
6627 OPC_ABS_D = FOP(5, FMT_D),
6628 OPC_MOV_D = FOP(6, FMT_D),
6629 OPC_NEG_D = FOP(7, FMT_D),
6630 OPC_ROUND_L_D = FOP(8, FMT_D),
6631 OPC_TRUNC_L_D = FOP(9, FMT_D),
6632 OPC_CEIL_L_D = FOP(10, FMT_D),
6633 OPC_FLOOR_L_D = FOP(11, FMT_D),
6634 OPC_ROUND_W_D = FOP(12, FMT_D),
6635 OPC_TRUNC_W_D = FOP(13, FMT_D),
6636 OPC_CEIL_W_D = FOP(14, FMT_D),
6637 OPC_FLOOR_W_D = FOP(15, FMT_D),
6638 OPC_MOVCF_D = FOP(17, FMT_D),
6639 OPC_MOVZ_D = FOP(18, FMT_D),
6640 OPC_MOVN_D = FOP(19, FMT_D),
6641 OPC_RECIP_D = FOP(21, FMT_D),
6642 OPC_RSQRT_D = FOP(22, FMT_D),
6643 OPC_RECIP2_D = FOP(28, FMT_D),
6644 OPC_RECIP1_D = FOP(29, FMT_D),
6645 OPC_RSQRT1_D = FOP(30, FMT_D),
6646 OPC_RSQRT2_D = FOP(31, FMT_D),
6647 OPC_CVT_S_D = FOP(32, FMT_D),
6648 OPC_CVT_W_D = FOP(36, FMT_D),
6649 OPC_CVT_L_D = FOP(37, FMT_D),
6650 OPC_CMP_F_D = FOP (48, FMT_D),
6651 OPC_CMP_UN_D = FOP (49, FMT_D),
6652 OPC_CMP_EQ_D = FOP (50, FMT_D),
6653 OPC_CMP_UEQ_D = FOP (51, FMT_D),
6654 OPC_CMP_OLT_D = FOP (52, FMT_D),
6655 OPC_CMP_ULT_D = FOP (53, FMT_D),
6656 OPC_CMP_OLE_D = FOP (54, FMT_D),
6657 OPC_CMP_ULE_D = FOP (55, FMT_D),
6658 OPC_CMP_SF_D = FOP (56, FMT_D),
6659 OPC_CMP_NGLE_D = FOP (57, FMT_D),
6660 OPC_CMP_SEQ_D = FOP (58, FMT_D),
6661 OPC_CMP_NGL_D = FOP (59, FMT_D),
6662 OPC_CMP_LT_D = FOP (60, FMT_D),
6663 OPC_CMP_NGE_D = FOP (61, FMT_D),
6664 OPC_CMP_LE_D = FOP (62, FMT_D),
6665 OPC_CMP_NGT_D = FOP (63, FMT_D),
6666
6667 OPC_CVT_S_W = FOP(32, FMT_W),
6668 OPC_CVT_D_W = FOP(33, FMT_W),
6669 OPC_CVT_S_L = FOP(32, FMT_L),
6670 OPC_CVT_D_L = FOP(33, FMT_L),
6671 OPC_CVT_PS_PW = FOP(38, FMT_W),
6672
6673 OPC_ADD_PS = FOP(0, FMT_PS),
6674 OPC_SUB_PS = FOP(1, FMT_PS),
6675 OPC_MUL_PS = FOP(2, FMT_PS),
6676 OPC_DIV_PS = FOP(3, FMT_PS),
6677 OPC_ABS_PS = FOP(5, FMT_PS),
6678 OPC_MOV_PS = FOP(6, FMT_PS),
6679 OPC_NEG_PS = FOP(7, FMT_PS),
6680 OPC_MOVCF_PS = FOP(17, FMT_PS),
6681 OPC_MOVZ_PS = FOP(18, FMT_PS),
6682 OPC_MOVN_PS = FOP(19, FMT_PS),
6683 OPC_ADDR_PS = FOP(24, FMT_PS),
6684 OPC_MULR_PS = FOP(26, FMT_PS),
6685 OPC_RECIP2_PS = FOP(28, FMT_PS),
6686 OPC_RECIP1_PS = FOP(29, FMT_PS),
6687 OPC_RSQRT1_PS = FOP(30, FMT_PS),
6688 OPC_RSQRT2_PS = FOP(31, FMT_PS),
6689
6690 OPC_CVT_S_PU = FOP(32, FMT_PS),
6691 OPC_CVT_PW_PS = FOP(36, FMT_PS),
6692 OPC_CVT_S_PL = FOP(40, FMT_PS),
6693 OPC_PLL_PS = FOP(44, FMT_PS),
6694 OPC_PLU_PS = FOP(45, FMT_PS),
6695 OPC_PUL_PS = FOP(46, FMT_PS),
6696 OPC_PUU_PS = FOP(47, FMT_PS),
6697 OPC_CMP_F_PS = FOP (48, FMT_PS),
6698 OPC_CMP_UN_PS = FOP (49, FMT_PS),
6699 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
6700 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
6701 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
6702 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
6703 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
6704 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
6705 OPC_CMP_SF_PS = FOP (56, FMT_PS),
6706 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
6707 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
6708 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
6709 OPC_CMP_LT_PS = FOP (60, FMT_PS),
6710 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
6711 OPC_CMP_LE_PS = FOP (62, FMT_PS),
6712 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
6713 };
6714
6715 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6716 {
6717 const char *opn = "cp1 move";
6718 TCGv t0 = tcg_temp_new();
6719
6720 switch (opc) {
6721 case OPC_MFC1:
6722 {
6723 TCGv_i32 fp0 = tcg_temp_new_i32();
6724
6725 gen_load_fpr32(fp0, fs);
6726 tcg_gen_ext_i32_tl(t0, fp0);
6727 tcg_temp_free_i32(fp0);
6728 }
6729 gen_store_gpr(t0, rt);
6730 opn = "mfc1";
6731 break;
6732 case OPC_MTC1:
6733 gen_load_gpr(t0, rt);
6734 {
6735 TCGv_i32 fp0 = tcg_temp_new_i32();
6736
6737 tcg_gen_trunc_tl_i32(fp0, t0);
6738 gen_store_fpr32(fp0, fs);
6739 tcg_temp_free_i32(fp0);
6740 }
6741 opn = "mtc1";
6742 break;
6743 case OPC_CFC1:
6744 gen_helper_1e0i(cfc1, t0, fs);
6745 gen_store_gpr(t0, rt);
6746 opn = "cfc1";
6747 break;
6748 case OPC_CTC1:
6749 gen_load_gpr(t0, rt);
6750 gen_helper_0e1i(ctc1, t0, fs);
6751 opn = "ctc1";
6752 break;
6753 #if defined(TARGET_MIPS64)
6754 case OPC_DMFC1:
6755 gen_load_fpr64(ctx, t0, fs);
6756 gen_store_gpr(t0, rt);
6757 opn = "dmfc1";
6758 break;
6759 case OPC_DMTC1:
6760 gen_load_gpr(t0, rt);
6761 gen_store_fpr64(ctx, t0, fs);
6762 opn = "dmtc1";
6763 break;
6764 #endif
6765 case OPC_MFHC1:
6766 {
6767 TCGv_i32 fp0 = tcg_temp_new_i32();
6768
6769 gen_load_fpr32h(fp0, fs);
6770 tcg_gen_ext_i32_tl(t0, fp0);
6771 tcg_temp_free_i32(fp0);
6772 }
6773 gen_store_gpr(t0, rt);
6774 opn = "mfhc1";
6775 break;
6776 case OPC_MTHC1:
6777 gen_load_gpr(t0, rt);
6778 {
6779 TCGv_i32 fp0 = tcg_temp_new_i32();
6780
6781 tcg_gen_trunc_tl_i32(fp0, t0);
6782 gen_store_fpr32h(fp0, fs);
6783 tcg_temp_free_i32(fp0);
6784 }
6785 opn = "mthc1";
6786 break;
6787 default:
6788 MIPS_INVAL(opn);
6789 generate_exception (ctx, EXCP_RI);
6790 goto out;
6791 }
6792 (void)opn; /* avoid a compiler warning */
6793 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6794
6795 out:
6796 tcg_temp_free(t0);
6797 }
6798
6799 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
6800 {
6801 int l1;
6802 TCGCond cond;
6803 TCGv_i32 t0;
6804
6805 if (rd == 0) {
6806 /* Treat as NOP. */
6807 return;
6808 }
6809
6810 if (tf)
6811 cond = TCG_COND_EQ;
6812 else
6813 cond = TCG_COND_NE;
6814
6815 l1 = gen_new_label();
6816 t0 = tcg_temp_new_i32();
6817 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6818 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6819 tcg_temp_free_i32(t0);
6820 if (rs == 0) {
6821 tcg_gen_movi_tl(cpu_gpr[rd], 0);
6822 } else {
6823 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
6824 }
6825 gen_set_label(l1);
6826 }
6827
6828 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
6829 {
6830 int cond;
6831 TCGv_i32 t0 = tcg_temp_new_i32();
6832 int l1 = gen_new_label();
6833
6834 if (tf)
6835 cond = TCG_COND_EQ;
6836 else
6837 cond = TCG_COND_NE;
6838
6839 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6840 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6841 gen_load_fpr32(t0, fs);
6842 gen_store_fpr32(t0, fd);
6843 gen_set_label(l1);
6844 tcg_temp_free_i32(t0);
6845 }
6846
6847 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
6848 {
6849 int cond;
6850 TCGv_i32 t0 = tcg_temp_new_i32();
6851 TCGv_i64 fp0;
6852 int l1 = gen_new_label();
6853
6854 if (tf)
6855 cond = TCG_COND_EQ;
6856 else
6857 cond = TCG_COND_NE;
6858
6859 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6860 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6861 tcg_temp_free_i32(t0);
6862 fp0 = tcg_temp_new_i64();
6863 gen_load_fpr64(ctx, fp0, fs);
6864 gen_store_fpr64(ctx, fp0, fd);
6865 tcg_temp_free_i64(fp0);
6866 gen_set_label(l1);
6867 }
6868
6869 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6870 {
6871 int cond;
6872 TCGv_i32 t0 = tcg_temp_new_i32();
6873 int l1 = gen_new_label();
6874 int l2 = gen_new_label();
6875
6876 if (tf)
6877 cond = TCG_COND_EQ;
6878 else
6879 cond = TCG_COND_NE;
6880
6881 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
6882 tcg_gen_brcondi_i32(cond, t0, 0, l1);
6883 gen_load_fpr32(t0, fs);
6884 gen_store_fpr32(t0, fd);
6885 gen_set_label(l1);
6886
6887 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
6888 tcg_gen_brcondi_i32(cond, t0, 0, l2);
6889 gen_load_fpr32h(t0, fs);
6890 gen_store_fpr32h(t0, fd);
6891 tcg_temp_free_i32(t0);
6892 gen_set_label(l2);
6893 }
6894
6895
6896 static void gen_farith (DisasContext *ctx, enum fopcode op1,
6897 int ft, int fs, int fd, int cc)
6898 {
6899 const char *opn = "farith";
6900 const char *condnames[] = {
6901 "c.f",
6902 "c.un",
6903 "c.eq",
6904 "c.ueq",
6905 "c.olt",
6906 "c.ult",
6907 "c.ole",
6908 "c.ule",
6909 "c.sf",
6910 "c.ngle",
6911 "c.seq",
6912 "c.ngl",
6913 "c.lt",
6914 "c.nge",
6915 "c.le",
6916 "c.ngt",
6917 };
6918 const char *condnames_abs[] = {
6919 "cabs.f",
6920 "cabs.un",
6921 "cabs.eq",
6922 "cabs.ueq",
6923 "cabs.olt",
6924 "cabs.ult",
6925 "cabs.ole",
6926 "cabs.ule",
6927 "cabs.sf",
6928 "cabs.ngle",
6929 "cabs.seq",
6930 "cabs.ngl",
6931 "cabs.lt",
6932 "cabs.nge",
6933 "cabs.le",
6934 "cabs.ngt",
6935 };
6936 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6937 uint32_t func = ctx->opcode & 0x3f;
6938
6939 switch (op1) {
6940 case OPC_ADD_S:
6941 {
6942 TCGv_i32 fp0 = tcg_temp_new_i32();
6943 TCGv_i32 fp1 = tcg_temp_new_i32();
6944
6945 gen_load_fpr32(fp0, fs);
6946 gen_load_fpr32(fp1, ft);
6947 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
6948 tcg_temp_free_i32(fp1);
6949 gen_store_fpr32(fp0, fd);
6950 tcg_temp_free_i32(fp0);
6951 }
6952 opn = "add.s";
6953 optype = BINOP;
6954 break;
6955 case OPC_SUB_S:
6956 {
6957 TCGv_i32 fp0 = tcg_temp_new_i32();
6958 TCGv_i32 fp1 = tcg_temp_new_i32();
6959
6960 gen_load_fpr32(fp0, fs);
6961 gen_load_fpr32(fp1, ft);
6962 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
6963 tcg_temp_free_i32(fp1);
6964 gen_store_fpr32(fp0, fd);
6965 tcg_temp_free_i32(fp0);
6966 }
6967 opn = "sub.s";
6968 optype = BINOP;
6969 break;
6970 case OPC_MUL_S:
6971 {
6972 TCGv_i32 fp0 = tcg_temp_new_i32();
6973 TCGv_i32 fp1 = tcg_temp_new_i32();
6974
6975 gen_load_fpr32(fp0, fs);
6976 gen_load_fpr32(fp1, ft);
6977 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
6978 tcg_temp_free_i32(fp1);
6979 gen_store_fpr32(fp0, fd);
6980 tcg_temp_free_i32(fp0);
6981 }
6982 opn = "mul.s";
6983 optype = BINOP;
6984 break;
6985 case OPC_DIV_S:
6986 {
6987 TCGv_i32 fp0 = tcg_temp_new_i32();
6988 TCGv_i32 fp1 = tcg_temp_new_i32();
6989
6990 gen_load_fpr32(fp0, fs);
6991 gen_load_fpr32(fp1, ft);
6992 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
6993 tcg_temp_free_i32(fp1);
6994 gen_store_fpr32(fp0, fd);
6995 tcg_temp_free_i32(fp0);
6996 }
6997 opn = "div.s";
6998 optype = BINOP;
6999 break;
7000 case OPC_SQRT_S:
7001 {
7002 TCGv_i32 fp0 = tcg_temp_new_i32();
7003
7004 gen_load_fpr32(fp0, fs);
7005 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7006 gen_store_fpr32(fp0, fd);
7007 tcg_temp_free_i32(fp0);
7008 }
7009 opn = "sqrt.s";
7010 break;
7011 case OPC_ABS_S:
7012 {
7013 TCGv_i32 fp0 = tcg_temp_new_i32();
7014
7015 gen_load_fpr32(fp0, fs);
7016 gen_helper_float_abs_s(fp0, fp0);
7017 gen_store_fpr32(fp0, fd);
7018 tcg_temp_free_i32(fp0);
7019 }
7020 opn = "abs.s";
7021 break;
7022 case OPC_MOV_S:
7023 {
7024 TCGv_i32 fp0 = tcg_temp_new_i32();
7025
7026 gen_load_fpr32(fp0, fs);
7027 gen_store_fpr32(fp0, fd);
7028 tcg_temp_free_i32(fp0);
7029 }
7030 opn = "mov.s";
7031 break;
7032 case OPC_NEG_S:
7033 {
7034 TCGv_i32 fp0 = tcg_temp_new_i32();
7035
7036 gen_load_fpr32(fp0, fs);
7037 gen_helper_float_chs_s(fp0, fp0);
7038 gen_store_fpr32(fp0, fd);
7039 tcg_temp_free_i32(fp0);
7040 }
7041 opn = "neg.s";
7042 break;
7043 case OPC_ROUND_L_S:
7044 check_cp1_64bitmode(ctx);
7045 {
7046 TCGv_i32 fp32 = tcg_temp_new_i32();
7047 TCGv_i64 fp64 = tcg_temp_new_i64();
7048
7049 gen_load_fpr32(fp32, fs);
7050 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7051 tcg_temp_free_i32(fp32);
7052 gen_store_fpr64(ctx, fp64, fd);
7053 tcg_temp_free_i64(fp64);
7054 }
7055 opn = "round.l.s";
7056 break;
7057 case OPC_TRUNC_L_S:
7058 check_cp1_64bitmode(ctx);
7059 {
7060 TCGv_i32 fp32 = tcg_temp_new_i32();
7061 TCGv_i64 fp64 = tcg_temp_new_i64();
7062
7063 gen_load_fpr32(fp32, fs);
7064 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7065 tcg_temp_free_i32(fp32);
7066 gen_store_fpr64(ctx, fp64, fd);
7067 tcg_temp_free_i64(fp64);
7068 }
7069 opn = "trunc.l.s";
7070 break;
7071 case OPC_CEIL_L_S:
7072 check_cp1_64bitmode(ctx);
7073 {
7074 TCGv_i32 fp32 = tcg_temp_new_i32();
7075 TCGv_i64 fp64 = tcg_temp_new_i64();
7076
7077 gen_load_fpr32(fp32, fs);
7078 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7079 tcg_temp_free_i32(fp32);
7080 gen_store_fpr64(ctx, fp64, fd);
7081 tcg_temp_free_i64(fp64);
7082 }
7083 opn = "ceil.l.s";
7084 break;
7085 case OPC_FLOOR_L_S:
7086 check_cp1_64bitmode(ctx);
7087 {
7088 TCGv_i32 fp32 = tcg_temp_new_i32();
7089 TCGv_i64 fp64 = tcg_temp_new_i64();
7090
7091 gen_load_fpr32(fp32, fs);
7092 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7093 tcg_temp_free_i32(fp32);
7094 gen_store_fpr64(ctx, fp64, fd);
7095 tcg_temp_free_i64(fp64);
7096 }
7097 opn = "floor.l.s";
7098 break;
7099 case OPC_ROUND_W_S:
7100 {
7101 TCGv_i32 fp0 = tcg_temp_new_i32();
7102
7103 gen_load_fpr32(fp0, fs);
7104 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7105 gen_store_fpr32(fp0, fd);
7106 tcg_temp_free_i32(fp0);
7107 }
7108 opn = "round.w.s";
7109 break;
7110 case OPC_TRUNC_W_S:
7111 {
7112 TCGv_i32 fp0 = tcg_temp_new_i32();
7113
7114 gen_load_fpr32(fp0, fs);
7115 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7116 gen_store_fpr32(fp0, fd);
7117 tcg_temp_free_i32(fp0);
7118 }
7119 opn = "trunc.w.s";
7120 break;
7121 case OPC_CEIL_W_S:
7122 {
7123 TCGv_i32 fp0 = tcg_temp_new_i32();
7124
7125 gen_load_fpr32(fp0, fs);
7126 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7127 gen_store_fpr32(fp0, fd);
7128 tcg_temp_free_i32(fp0);
7129 }
7130 opn = "ceil.w.s";
7131 break;
7132 case OPC_FLOOR_W_S:
7133 {
7134 TCGv_i32 fp0 = tcg_temp_new_i32();
7135
7136 gen_load_fpr32(fp0, fs);
7137 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7138 gen_store_fpr32(fp0, fd);
7139 tcg_temp_free_i32(fp0);
7140 }
7141 opn = "floor.w.s";
7142 break;
7143 case OPC_MOVCF_S:
7144 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7145 opn = "movcf.s";
7146 break;
7147 case OPC_MOVZ_S:
7148 {
7149 int l1 = gen_new_label();
7150 TCGv_i32 fp0;
7151
7152 if (ft != 0) {
7153 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7154 }
7155 fp0 = tcg_temp_new_i32();
7156 gen_load_fpr32(fp0, fs);
7157 gen_store_fpr32(fp0, fd);
7158 tcg_temp_free_i32(fp0);
7159 gen_set_label(l1);
7160 }
7161 opn = "movz.s";
7162 break;
7163 case OPC_MOVN_S:
7164 {
7165 int l1 = gen_new_label();
7166 TCGv_i32 fp0;
7167
7168 if (ft != 0) {
7169 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7170 fp0 = tcg_temp_new_i32();
7171 gen_load_fpr32(fp0, fs);
7172 gen_store_fpr32(fp0, fd);
7173 tcg_temp_free_i32(fp0);
7174 gen_set_label(l1);
7175 }
7176 }
7177 opn = "movn.s";
7178 break;
7179 case OPC_RECIP_S:
7180 check_cop1x(ctx);
7181 {
7182 TCGv_i32 fp0 = tcg_temp_new_i32();
7183
7184 gen_load_fpr32(fp0, fs);
7185 gen_helper_float_recip_s(fp0, cpu_env, fp0);
7186 gen_store_fpr32(fp0, fd);
7187 tcg_temp_free_i32(fp0);
7188 }
7189 opn = "recip.s";
7190 break;
7191 case OPC_RSQRT_S:
7192 check_cop1x(ctx);
7193 {
7194 TCGv_i32 fp0 = tcg_temp_new_i32();
7195
7196 gen_load_fpr32(fp0, fs);
7197 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7198 gen_store_fpr32(fp0, fd);
7199 tcg_temp_free_i32(fp0);
7200 }
7201 opn = "rsqrt.s";
7202 break;
7203 case OPC_RECIP2_S:
7204 check_cp1_64bitmode(ctx);
7205 {
7206 TCGv_i32 fp0 = tcg_temp_new_i32();
7207 TCGv_i32 fp1 = tcg_temp_new_i32();
7208
7209 gen_load_fpr32(fp0, fs);
7210 gen_load_fpr32(fp1, ft);
7211 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7212 tcg_temp_free_i32(fp1);
7213 gen_store_fpr32(fp0, fd);
7214 tcg_temp_free_i32(fp0);
7215 }
7216 opn = "recip2.s";
7217 break;
7218 case OPC_RECIP1_S:
7219 check_cp1_64bitmode(ctx);
7220 {
7221 TCGv_i32 fp0 = tcg_temp_new_i32();
7222
7223 gen_load_fpr32(fp0, fs);
7224 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7225 gen_store_fpr32(fp0, fd);
7226 tcg_temp_free_i32(fp0);
7227 }
7228 opn = "recip1.s";
7229 break;
7230 case OPC_RSQRT1_S:
7231 check_cp1_64bitmode(ctx);
7232 {
7233 TCGv_i32 fp0 = tcg_temp_new_i32();
7234
7235 gen_load_fpr32(fp0, fs);
7236 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7237 gen_store_fpr32(fp0, fd);
7238 tcg_temp_free_i32(fp0);
7239 }
7240 opn = "rsqrt1.s";
7241 break;
7242 case OPC_RSQRT2_S:
7243 check_cp1_64bitmode(ctx);
7244 {
7245 TCGv_i32 fp0 = tcg_temp_new_i32();
7246 TCGv_i32 fp1 = tcg_temp_new_i32();
7247
7248 gen_load_fpr32(fp0, fs);
7249 gen_load_fpr32(fp1, ft);
7250 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7251 tcg_temp_free_i32(fp1);
7252 gen_store_fpr32(fp0, fd);
7253 tcg_temp_free_i32(fp0);
7254 }
7255 opn = "rsqrt2.s";
7256 break;
7257 case OPC_CVT_D_S:
7258 check_cp1_registers(ctx, fd);
7259 {
7260 TCGv_i32 fp32 = tcg_temp_new_i32();
7261 TCGv_i64 fp64 = tcg_temp_new_i64();
7262
7263 gen_load_fpr32(fp32, fs);
7264 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7265 tcg_temp_free_i32(fp32);
7266 gen_store_fpr64(ctx, fp64, fd);
7267 tcg_temp_free_i64(fp64);
7268 }
7269 opn = "cvt.d.s";
7270 break;
7271 case OPC_CVT_W_S:
7272 {
7273 TCGv_i32 fp0 = tcg_temp_new_i32();
7274
7275 gen_load_fpr32(fp0, fs);
7276 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7277 gen_store_fpr32(fp0, fd);
7278 tcg_temp_free_i32(fp0);
7279 }
7280 opn = "cvt.w.s";
7281 break;
7282 case OPC_CVT_L_S:
7283 check_cp1_64bitmode(ctx);
7284 {
7285 TCGv_i32 fp32 = tcg_temp_new_i32();
7286 TCGv_i64 fp64 = tcg_temp_new_i64();
7287
7288 gen_load_fpr32(fp32, fs);
7289 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7290 tcg_temp_free_i32(fp32);
7291 gen_store_fpr64(ctx, fp64, fd);
7292 tcg_temp_free_i64(fp64);
7293 }
7294 opn = "cvt.l.s";
7295 break;
7296 case OPC_CVT_PS_S:
7297 check_cp1_64bitmode(ctx);
7298 {
7299 TCGv_i64 fp64 = tcg_temp_new_i64();
7300 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7301 TCGv_i32 fp32_1 = tcg_temp_new_i32();
7302
7303 gen_load_fpr32(fp32_0, fs);
7304 gen_load_fpr32(fp32_1, ft);
7305 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7306 tcg_temp_free_i32(fp32_1);
7307 tcg_temp_free_i32(fp32_0);
7308 gen_store_fpr64(ctx, fp64, fd);
7309 tcg_temp_free_i64(fp64);
7310 }
7311 opn = "cvt.ps.s";
7312 break;
7313 case OPC_CMP_F_S:
7314 case OPC_CMP_UN_S:
7315 case OPC_CMP_EQ_S:
7316 case OPC_CMP_UEQ_S:
7317 case OPC_CMP_OLT_S:
7318 case OPC_CMP_ULT_S:
7319 case OPC_CMP_OLE_S:
7320 case OPC_CMP_ULE_S:
7321 case OPC_CMP_SF_S:
7322 case OPC_CMP_NGLE_S:
7323 case OPC_CMP_SEQ_S:
7324 case OPC_CMP_NGL_S:
7325 case OPC_CMP_LT_S:
7326 case OPC_CMP_NGE_S:
7327 case OPC_CMP_LE_S:
7328 case OPC_CMP_NGT_S:
7329 if (ctx->opcode & (1 << 6)) {
7330 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7331 opn = condnames_abs[func-48];
7332 } else {
7333 gen_cmp_s(ctx, func-48, ft, fs, cc);
7334 opn = condnames[func-48];
7335 }
7336 break;
7337 case OPC_ADD_D:
7338 check_cp1_registers(ctx, fs | ft | fd);
7339 {
7340 TCGv_i64 fp0 = tcg_temp_new_i64();
7341 TCGv_i64 fp1 = tcg_temp_new_i64();
7342
7343 gen_load_fpr64(ctx, fp0, fs);
7344 gen_load_fpr64(ctx, fp1, ft);
7345 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7346 tcg_temp_free_i64(fp1);
7347 gen_store_fpr64(ctx, fp0, fd);
7348 tcg_temp_free_i64(fp0);
7349 }
7350 opn = "add.d";
7351 optype = BINOP;
7352 break;
7353 case OPC_SUB_D:
7354 check_cp1_registers(ctx, fs | ft | fd);
7355 {
7356 TCGv_i64 fp0 = tcg_temp_new_i64();
7357 TCGv_i64 fp1 = tcg_temp_new_i64();
7358
7359 gen_load_fpr64(ctx, fp0, fs);
7360 gen_load_fpr64(ctx, fp1, ft);
7361 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7362 tcg_temp_free_i64(fp1);
7363 gen_store_fpr64(ctx, fp0, fd);
7364 tcg_temp_free_i64(fp0);
7365 }
7366 opn = "sub.d";
7367 optype = BINOP;
7368 break;
7369 case OPC_MUL_D:
7370 check_cp1_registers(ctx, fs | ft | fd);
7371 {
7372 TCGv_i64 fp0 = tcg_temp_new_i64();
7373 TCGv_i64 fp1 = tcg_temp_new_i64();
7374
7375 gen_load_fpr64(ctx, fp0, fs);
7376 gen_load_fpr64(ctx, fp1, ft);
7377 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7378 tcg_temp_free_i64(fp1);
7379 gen_store_fpr64(ctx, fp0, fd);
7380 tcg_temp_free_i64(fp0);
7381 }
7382 opn = "mul.d";
7383 optype = BINOP;
7384 break;
7385 case OPC_DIV_D:
7386 check_cp1_registers(ctx, fs | ft | fd);
7387 {
7388 TCGv_i64 fp0 = tcg_temp_new_i64();
7389 TCGv_i64 fp1 = tcg_temp_new_i64();
7390
7391 gen_load_fpr64(ctx, fp0, fs);
7392 gen_load_fpr64(ctx, fp1, ft);
7393 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7394 tcg_temp_free_i64(fp1);
7395 gen_store_fpr64(ctx, fp0, fd);
7396 tcg_temp_free_i64(fp0);
7397 }
7398 opn = "div.d";
7399 optype = BINOP;
7400 break;
7401 case OPC_SQRT_D:
7402 check_cp1_registers(ctx, fs | fd);
7403 {
7404 TCGv_i64 fp0 = tcg_temp_new_i64();
7405
7406 gen_load_fpr64(ctx, fp0, fs);
7407 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7408 gen_store_fpr64(ctx, fp0, fd);
7409 tcg_temp_free_i64(fp0);
7410 }
7411 opn = "sqrt.d";
7412 break;
7413 case OPC_ABS_D:
7414 check_cp1_registers(ctx, fs | fd);
7415 {
7416 TCGv_i64 fp0 = tcg_temp_new_i64();
7417
7418 gen_load_fpr64(ctx, fp0, fs);
7419 gen_helper_float_abs_d(fp0, fp0);
7420 gen_store_fpr64(ctx, fp0, fd);
7421 tcg_temp_free_i64(fp0);
7422 }
7423 opn = "abs.d";
7424 break;
7425 case OPC_MOV_D:
7426 check_cp1_registers(ctx, fs | fd);
7427 {
7428 TCGv_i64 fp0 = tcg_temp_new_i64();
7429
7430 gen_load_fpr64(ctx, fp0, fs);
7431 gen_store_fpr64(ctx, fp0, fd);
7432 tcg_temp_free_i64(fp0);
7433 }
7434 opn = "mov.d";
7435 break;
7436 case OPC_NEG_D:
7437 check_cp1_registers(ctx, fs | fd);
7438 {
7439 TCGv_i64 fp0 = tcg_temp_new_i64();
7440
7441 gen_load_fpr64(ctx, fp0, fs);
7442 gen_helper_float_chs_d(fp0, fp0);
7443 gen_store_fpr64(ctx, fp0, fd);
7444 tcg_temp_free_i64(fp0);
7445 }
7446 opn = "neg.d";
7447 break;
7448 case OPC_ROUND_L_D:
7449 check_cp1_64bitmode(ctx);
7450 {
7451 TCGv_i64 fp0 = tcg_temp_new_i64();
7452
7453 gen_load_fpr64(ctx, fp0, fs);
7454 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7455 gen_store_fpr64(ctx, fp0, fd);
7456 tcg_temp_free_i64(fp0);
7457 }
7458 opn = "round.l.d";
7459 break;
7460 case OPC_TRUNC_L_D:
7461 check_cp1_64bitmode(ctx);
7462 {
7463 TCGv_i64 fp0 = tcg_temp_new_i64();
7464
7465 gen_load_fpr64(ctx, fp0, fs);
7466 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7467 gen_store_fpr64(ctx, fp0, fd);
7468 tcg_temp_free_i64(fp0);
7469 }
7470 opn = "trunc.l.d";
7471 break;
7472 case OPC_CEIL_L_D:
7473 check_cp1_64bitmode(ctx);
7474 {
7475 TCGv_i64 fp0 = tcg_temp_new_i64();
7476
7477 gen_load_fpr64(ctx, fp0, fs);
7478 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
7479 gen_store_fpr64(ctx, fp0, fd);
7480 tcg_temp_free_i64(fp0);
7481 }
7482 opn = "ceil.l.d";
7483 break;
7484 case OPC_FLOOR_L_D:
7485 check_cp1_64bitmode(ctx);
7486 {
7487 TCGv_i64 fp0 = tcg_temp_new_i64();
7488
7489 gen_load_fpr64(ctx, fp0, fs);
7490 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
7491 gen_store_fpr64(ctx, fp0, fd);
7492 tcg_temp_free_i64(fp0);
7493 }
7494 opn = "floor.l.d";
7495 break;
7496 case OPC_ROUND_W_D:
7497 check_cp1_registers(ctx, fs);
7498 {
7499 TCGv_i32 fp32 = tcg_temp_new_i32();
7500 TCGv_i64 fp64 = tcg_temp_new_i64();
7501
7502 gen_load_fpr64(ctx, fp64, fs);
7503 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
7504 tcg_temp_free_i64(fp64);
7505 gen_store_fpr32(fp32, fd);
7506 tcg_temp_free_i32(fp32);
7507 }
7508 opn = "round.w.d";
7509 break;
7510 case OPC_TRUNC_W_D:
7511 check_cp1_registers(ctx, fs);
7512 {
7513 TCGv_i32 fp32 = tcg_temp_new_i32();
7514 TCGv_i64 fp64 = tcg_temp_new_i64();
7515
7516 gen_load_fpr64(ctx, fp64, fs);
7517 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
7518 tcg_temp_free_i64(fp64);
7519 gen_store_fpr32(fp32, fd);
7520 tcg_temp_free_i32(fp32);
7521 }
7522 opn = "trunc.w.d";
7523 break;
7524 case OPC_CEIL_W_D:
7525 check_cp1_registers(ctx, fs);
7526 {
7527 TCGv_i32 fp32 = tcg_temp_new_i32();
7528 TCGv_i64 fp64 = tcg_temp_new_i64();
7529
7530 gen_load_fpr64(ctx, fp64, fs);
7531 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
7532 tcg_temp_free_i64(fp64);
7533 gen_store_fpr32(fp32, fd);
7534 tcg_temp_free_i32(fp32);
7535 }
7536 opn = "ceil.w.d";
7537 break;
7538 case OPC_FLOOR_W_D:
7539 check_cp1_registers(ctx, fs);
7540 {
7541 TCGv_i32 fp32 = tcg_temp_new_i32();
7542 TCGv_i64 fp64 = tcg_temp_new_i64();
7543
7544 gen_load_fpr64(ctx, fp64, fs);
7545 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
7546 tcg_temp_free_i64(fp64);
7547 gen_store_fpr32(fp32, fd);
7548 tcg_temp_free_i32(fp32);
7549 }
7550 opn = "floor.w.d";
7551 break;
7552 case OPC_MOVCF_D:
7553 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7554 opn = "movcf.d";
7555 break;
7556 case OPC_MOVZ_D:
7557 {
7558 int l1 = gen_new_label();
7559 TCGv_i64 fp0;
7560
7561 if (ft != 0) {
7562 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7563 }
7564 fp0 = tcg_temp_new_i64();
7565 gen_load_fpr64(ctx, fp0, fs);
7566 gen_store_fpr64(ctx, fp0, fd);
7567 tcg_temp_free_i64(fp0);
7568 gen_set_label(l1);
7569 }
7570 opn = "movz.d";
7571 break;
7572 case OPC_MOVN_D:
7573 {
7574 int l1 = gen_new_label();
7575 TCGv_i64 fp0;
7576
7577 if (ft != 0) {
7578 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7579 fp0 = tcg_temp_new_i64();
7580 gen_load_fpr64(ctx, fp0, fs);
7581 gen_store_fpr64(ctx, fp0, fd);
7582 tcg_temp_free_i64(fp0);
7583 gen_set_label(l1);
7584 }
7585 }
7586 opn = "movn.d";
7587 break;
7588 case OPC_RECIP_D:
7589 check_cp1_64bitmode(ctx);
7590 {
7591 TCGv_i64 fp0 = tcg_temp_new_i64();
7592
7593 gen_load_fpr64(ctx, fp0, fs);
7594 gen_helper_float_recip_d(fp0, cpu_env, fp0);
7595 gen_store_fpr64(ctx, fp0, fd);
7596 tcg_temp_free_i64(fp0);
7597 }
7598 opn = "recip.d";
7599 break;
7600 case OPC_RSQRT_D:
7601 check_cp1_64bitmode(ctx);
7602 {
7603 TCGv_i64 fp0 = tcg_temp_new_i64();
7604
7605 gen_load_fpr64(ctx, fp0, fs);
7606 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
7607 gen_store_fpr64(ctx, fp0, fd);
7608 tcg_temp_free_i64(fp0);
7609 }
7610 opn = "rsqrt.d";
7611 break;
7612 case OPC_RECIP2_D:
7613 check_cp1_64bitmode(ctx);
7614 {
7615 TCGv_i64 fp0 = tcg_temp_new_i64();
7616 TCGv_i64 fp1 = tcg_temp_new_i64();
7617
7618 gen_load_fpr64(ctx, fp0, fs);
7619 gen_load_fpr64(ctx, fp1, ft);
7620 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
7621 tcg_temp_free_i64(fp1);
7622 gen_store_fpr64(ctx, fp0, fd);
7623 tcg_temp_free_i64(fp0);
7624 }
7625 opn = "recip2.d";
7626 break;
7627 case OPC_RECIP1_D:
7628 check_cp1_64bitmode(ctx);
7629 {
7630 TCGv_i64 fp0 = tcg_temp_new_i64();
7631
7632 gen_load_fpr64(ctx, fp0, fs);
7633 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
7634 gen_store_fpr64(ctx, fp0, fd);
7635 tcg_temp_free_i64(fp0);
7636 }
7637 opn = "recip1.d";
7638 break;
7639 case OPC_RSQRT1_D:
7640 check_cp1_64bitmode(ctx);
7641 {
7642 TCGv_i64 fp0 = tcg_temp_new_i64();
7643
7644 gen_load_fpr64(ctx, fp0, fs);
7645 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
7646 gen_store_fpr64(ctx, fp0, fd);
7647 tcg_temp_free_i64(fp0);
7648 }
7649 opn = "rsqrt1.d";
7650 break;
7651 case OPC_RSQRT2_D:
7652 check_cp1_64bitmode(ctx);
7653 {
7654 TCGv_i64 fp0 = tcg_temp_new_i64();
7655 TCGv_i64 fp1 = tcg_temp_new_i64();
7656
7657 gen_load_fpr64(ctx, fp0, fs);
7658 gen_load_fpr64(ctx, fp1, ft);
7659 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
7660 tcg_temp_free_i64(fp1);
7661 gen_store_fpr64(ctx, fp0, fd);
7662 tcg_temp_free_i64(fp0);
7663 }
7664 opn = "rsqrt2.d";
7665 break;
7666 case OPC_CMP_F_D:
7667 case OPC_CMP_UN_D:
7668 case OPC_CMP_EQ_D:
7669 case OPC_CMP_UEQ_D:
7670 case OPC_CMP_OLT_D:
7671 case OPC_CMP_ULT_D:
7672 case OPC_CMP_OLE_D:
7673 case OPC_CMP_ULE_D:
7674 case OPC_CMP_SF_D:
7675 case OPC_CMP_NGLE_D:
7676 case OPC_CMP_SEQ_D:
7677 case OPC_CMP_NGL_D:
7678 case OPC_CMP_LT_D:
7679 case OPC_CMP_NGE_D:
7680 case OPC_CMP_LE_D:
7681 case OPC_CMP_NGT_D:
7682 if (ctx->opcode & (1 << 6)) {
7683 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
7684 opn = condnames_abs[func-48];
7685 } else {
7686 gen_cmp_d(ctx, func-48, ft, fs, cc);
7687 opn = condnames[func-48];
7688 }
7689 break;
7690 case OPC_CVT_S_D:
7691 check_cp1_registers(ctx, fs);
7692 {
7693 TCGv_i32 fp32 = tcg_temp_new_i32();
7694 TCGv_i64 fp64 = tcg_temp_new_i64();
7695
7696 gen_load_fpr64(ctx, fp64, fs);
7697 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
7698 tcg_temp_free_i64(fp64);
7699 gen_store_fpr32(fp32, fd);
7700 tcg_temp_free_i32(fp32);
7701 }
7702 opn = "cvt.s.d";
7703 break;
7704 case OPC_CVT_W_D:
7705 check_cp1_registers(ctx, fs);
7706 {
7707 TCGv_i32 fp32 = tcg_temp_new_i32();
7708 TCGv_i64 fp64 = tcg_temp_new_i64();
7709
7710 gen_load_fpr64(ctx, fp64, fs);
7711 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
7712 tcg_temp_free_i64(fp64);
7713 gen_store_fpr32(fp32, fd);
7714 tcg_temp_free_i32(fp32);
7715 }
7716 opn = "cvt.w.d";
7717 break;
7718 case OPC_CVT_L_D:
7719 check_cp1_64bitmode(ctx);
7720 {
7721 TCGv_i64 fp0 = tcg_temp_new_i64();
7722
7723 gen_load_fpr64(ctx, fp0, fs);
7724 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
7725 gen_store_fpr64(ctx, fp0, fd);
7726 tcg_temp_free_i64(fp0);
7727 }
7728 opn = "cvt.l.d";
7729 break;
7730 case OPC_CVT_S_W:
7731 {
7732 TCGv_i32 fp0 = tcg_temp_new_i32();
7733
7734 gen_load_fpr32(fp0, fs);
7735 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
7736 gen_store_fpr32(fp0, fd);
7737 tcg_temp_free_i32(fp0);
7738 }
7739 opn = "cvt.s.w";
7740 break;
7741 case OPC_CVT_D_W:
7742 check_cp1_registers(ctx, fd);
7743 {
7744 TCGv_i32 fp32 = tcg_temp_new_i32();
7745 TCGv_i64 fp64 = tcg_temp_new_i64();
7746
7747 gen_load_fpr32(fp32, fs);
7748 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
7749 tcg_temp_free_i32(fp32);
7750 gen_store_fpr64(ctx, fp64, fd);
7751 tcg_temp_free_i64(fp64);
7752 }
7753 opn = "cvt.d.w";
7754 break;
7755 case OPC_CVT_S_L:
7756 check_cp1_64bitmode(ctx);
7757 {
7758 TCGv_i32 fp32 = tcg_temp_new_i32();
7759 TCGv_i64 fp64 = tcg_temp_new_i64();
7760
7761 gen_load_fpr64(ctx, fp64, fs);
7762 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
7763 tcg_temp_free_i64(fp64);
7764 gen_store_fpr32(fp32, fd);
7765 tcg_temp_free_i32(fp32);
7766 }
7767 opn = "cvt.s.l";
7768 break;
7769 case OPC_CVT_D_L:
7770 check_cp1_64bitmode(ctx);
7771 {
7772 TCGv_i64 fp0 = tcg_temp_new_i64();
7773
7774 gen_load_fpr64(ctx, fp0, fs);
7775 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
7776 gen_store_fpr64(ctx, fp0, fd);
7777 tcg_temp_free_i64(fp0);
7778 }
7779 opn = "cvt.d.l";
7780 break;
7781 case OPC_CVT_PS_PW:
7782 check_cp1_64bitmode(ctx);
7783 {
7784 TCGv_i64 fp0 = tcg_temp_new_i64();
7785
7786 gen_load_fpr64(ctx, fp0, fs);
7787 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
7788 gen_store_fpr64(ctx, fp0, fd);
7789 tcg_temp_free_i64(fp0);
7790 }
7791 opn = "cvt.ps.pw";
7792 break;
7793 case OPC_ADD_PS:
7794 check_cp1_64bitmode(ctx);
7795 {
7796 TCGv_i64 fp0 = tcg_temp_new_i64();
7797 TCGv_i64 fp1 = tcg_temp_new_i64();
7798
7799 gen_load_fpr64(ctx, fp0, fs);
7800 gen_load_fpr64(ctx, fp1, ft);
7801 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
7802 tcg_temp_free_i64(fp1);
7803 gen_store_fpr64(ctx, fp0, fd);
7804 tcg_temp_free_i64(fp0);
7805 }
7806 opn = "add.ps";
7807 break;
7808 case OPC_SUB_PS:
7809 check_cp1_64bitmode(ctx);
7810 {
7811 TCGv_i64 fp0 = tcg_temp_new_i64();
7812 TCGv_i64 fp1 = tcg_temp_new_i64();
7813
7814 gen_load_fpr64(ctx, fp0, fs);
7815 gen_load_fpr64(ctx, fp1, ft);
7816 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
7817 tcg_temp_free_i64(fp1);
7818 gen_store_fpr64(ctx, fp0, fd);
7819 tcg_temp_free_i64(fp0);
7820 }
7821 opn = "sub.ps";
7822 break;
7823 case OPC_MUL_PS:
7824 check_cp1_64bitmode(ctx);
7825 {
7826 TCGv_i64 fp0 = tcg_temp_new_i64();
7827 TCGv_i64 fp1 = tcg_temp_new_i64();
7828
7829 gen_load_fpr64(ctx, fp0, fs);
7830 gen_load_fpr64(ctx, fp1, ft);
7831 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
7832 tcg_temp_free_i64(fp1);
7833 gen_store_fpr64(ctx, fp0, fd);
7834 tcg_temp_free_i64(fp0);
7835 }
7836 opn = "mul.ps";
7837 break;
7838 case OPC_ABS_PS:
7839 check_cp1_64bitmode(ctx);
7840 {
7841 TCGv_i64 fp0 = tcg_temp_new_i64();
7842
7843 gen_load_fpr64(ctx, fp0, fs);
7844 gen_helper_float_abs_ps(fp0, fp0);
7845 gen_store_fpr64(ctx, fp0, fd);
7846 tcg_temp_free_i64(fp0);
7847 }
7848 opn = "abs.ps";
7849 break;
7850 case OPC_MOV_PS:
7851 check_cp1_64bitmode(ctx);
7852 {
7853 TCGv_i64 fp0 = tcg_temp_new_i64();
7854
7855 gen_load_fpr64(ctx, fp0, fs);
7856 gen_store_fpr64(ctx, fp0, fd);
7857 tcg_temp_free_i64(fp0);
7858 }
7859 opn = "mov.ps";
7860 break;
7861 case OPC_NEG_PS:
7862 check_cp1_64bitmode(ctx);
7863 {
7864 TCGv_i64 fp0 = tcg_temp_new_i64();
7865
7866 gen_load_fpr64(ctx, fp0, fs);
7867 gen_helper_float_chs_ps(fp0, fp0);
7868 gen_store_fpr64(ctx, fp0, fd);
7869 tcg_temp_free_i64(fp0);
7870 }
7871 opn = "neg.ps";
7872 break;
7873 case OPC_MOVCF_PS:
7874 check_cp1_64bitmode(ctx);
7875 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7876 opn = "movcf.ps";
7877 break;
7878 case OPC_MOVZ_PS:
7879 check_cp1_64bitmode(ctx);
7880 {
7881 int l1 = gen_new_label();
7882 TCGv_i64 fp0;
7883
7884 if (ft != 0)
7885 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7886 fp0 = tcg_temp_new_i64();
7887 gen_load_fpr64(ctx, fp0, fs);
7888 gen_store_fpr64(ctx, fp0, fd);
7889 tcg_temp_free_i64(fp0);
7890 gen_set_label(l1);
7891 }
7892 opn = "movz.ps";
7893 break;
7894 case OPC_MOVN_PS:
7895 check_cp1_64bitmode(ctx);
7896 {
7897 int l1 = gen_new_label();
7898 TCGv_i64 fp0;
7899
7900 if (ft != 0) {
7901 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7902 fp0 = tcg_temp_new_i64();
7903 gen_load_fpr64(ctx, fp0, fs);
7904 gen_store_fpr64(ctx, fp0, fd);
7905 tcg_temp_free_i64(fp0);
7906 gen_set_label(l1);
7907 }
7908 }
7909 opn = "movn.ps";
7910 break;
7911 case OPC_ADDR_PS:
7912 check_cp1_64bitmode(ctx);
7913 {
7914 TCGv_i64 fp0 = tcg_temp_new_i64();
7915 TCGv_i64 fp1 = tcg_temp_new_i64();
7916
7917 gen_load_fpr64(ctx, fp0, ft);
7918 gen_load_fpr64(ctx, fp1, fs);
7919 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
7920 tcg_temp_free_i64(fp1);
7921 gen_store_fpr64(ctx, fp0, fd);
7922 tcg_temp_free_i64(fp0);
7923 }
7924 opn = "addr.ps";
7925 break;
7926 case OPC_MULR_PS:
7927 check_cp1_64bitmode(ctx);
7928 {
7929 TCGv_i64 fp0 = tcg_temp_new_i64();
7930 TCGv_i64 fp1 = tcg_temp_new_i64();
7931
7932 gen_load_fpr64(ctx, fp0, ft);
7933 gen_load_fpr64(ctx, fp1, fs);
7934 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
7935 tcg_temp_free_i64(fp1);
7936 gen_store_fpr64(ctx, fp0, fd);
7937 tcg_temp_free_i64(fp0);
7938 }
7939 opn = "mulr.ps";
7940 break;
7941 case OPC_RECIP2_PS:
7942 check_cp1_64bitmode(ctx);
7943 {
7944 TCGv_i64 fp0 = tcg_temp_new_i64();
7945 TCGv_i64 fp1 = tcg_temp_new_i64();
7946
7947 gen_load_fpr64(ctx, fp0, fs);
7948 gen_load_fpr64(ctx, fp1, ft);
7949 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
7950 tcg_temp_free_i64(fp1);
7951 gen_store_fpr64(ctx, fp0, fd);
7952 tcg_temp_free_i64(fp0);
7953 }
7954 opn = "recip2.ps";
7955 break;
7956 case OPC_RECIP1_PS:
7957 check_cp1_64bitmode(ctx);
7958 {
7959 TCGv_i64 fp0 = tcg_temp_new_i64();
7960
7961 gen_load_fpr64(ctx, fp0, fs);
7962 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
7963 gen_store_fpr64(ctx, fp0, fd);
7964 tcg_temp_free_i64(fp0);
7965 }
7966 opn = "recip1.ps";
7967 break;
7968 case OPC_RSQRT1_PS:
7969 check_cp1_64bitmode(ctx);
7970 {
7971 TCGv_i64 fp0 = tcg_temp_new_i64();
7972
7973 gen_load_fpr64(ctx, fp0, fs);
7974 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
7975 gen_store_fpr64(ctx, fp0, fd);
7976 tcg_temp_free_i64(fp0);
7977 }
7978 opn = "rsqrt1.ps";
7979 break;
7980 case OPC_RSQRT2_PS:
7981 check_cp1_64bitmode(ctx);
7982 {
7983 TCGv_i64 fp0 = tcg_temp_new_i64();
7984 TCGv_i64 fp1 = tcg_temp_new_i64();
7985
7986 gen_load_fpr64(ctx, fp0, fs);
7987 gen_load_fpr64(ctx, fp1, ft);
7988 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
7989 tcg_temp_free_i64(fp1);
7990 gen_store_fpr64(ctx, fp0, fd);
7991 tcg_temp_free_i64(fp0);
7992 }
7993 opn = "rsqrt2.ps";
7994 break;
7995 case OPC_CVT_S_PU:
7996 check_cp1_64bitmode(ctx);
7997 {
7998 TCGv_i32 fp0 = tcg_temp_new_i32();
7999
8000 gen_load_fpr32h(fp0, fs);
8001 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8002 gen_store_fpr32(fp0, fd);
8003 tcg_temp_free_i32(fp0);
8004 }
8005 opn = "cvt.s.pu";
8006 break;
8007 case OPC_CVT_PW_PS:
8008 check_cp1_64bitmode(ctx);
8009 {
8010 TCGv_i64 fp0 = tcg_temp_new_i64();
8011
8012 gen_load_fpr64(ctx, fp0, fs);
8013 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8014 gen_store_fpr64(ctx, fp0, fd);
8015 tcg_temp_free_i64(fp0);
8016 }
8017 opn = "cvt.pw.ps";
8018 break;
8019 case OPC_CVT_S_PL:
8020 check_cp1_64bitmode(ctx);
8021 {
8022 TCGv_i32 fp0 = tcg_temp_new_i32();
8023
8024 gen_load_fpr32(fp0, fs);
8025 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8026 gen_store_fpr32(fp0, fd);
8027 tcg_temp_free_i32(fp0);
8028 }
8029 opn = "cvt.s.pl";
8030 break;
8031 case OPC_PLL_PS:
8032 check_cp1_64bitmode(ctx);
8033 {
8034 TCGv_i32 fp0 = tcg_temp_new_i32();
8035 TCGv_i32 fp1 = tcg_temp_new_i32();
8036
8037 gen_load_fpr32(fp0, fs);
8038 gen_load_fpr32(fp1, ft);
8039 gen_store_fpr32h(fp0, fd);
8040 gen_store_fpr32(fp1, fd);
8041 tcg_temp_free_i32(fp0);
8042 tcg_temp_free_i32(fp1);
8043 }
8044 opn = "pll.ps";
8045 break;
8046 case OPC_PLU_PS:
8047 check_cp1_64bitmode(ctx);
8048 {
8049 TCGv_i32 fp0 = tcg_temp_new_i32();
8050 TCGv_i32 fp1 = tcg_temp_new_i32();
8051
8052 gen_load_fpr32(fp0, fs);
8053 gen_load_fpr32h(fp1, ft);
8054 gen_store_fpr32(fp1, fd);
8055 gen_store_fpr32h(fp0, fd);
8056 tcg_temp_free_i32(fp0);
8057 tcg_temp_free_i32(fp1);
8058 }
8059 opn = "plu.ps";
8060 break;
8061 case OPC_PUL_PS:
8062 check_cp1_64bitmode(ctx);
8063 {
8064 TCGv_i32 fp0 = tcg_temp_new_i32();
8065 TCGv_i32 fp1 = tcg_temp_new_i32();
8066
8067 gen_load_fpr32h(fp0, fs);
8068 gen_load_fpr32(fp1, ft);
8069 gen_store_fpr32(fp1, fd);
8070 gen_store_fpr32h(fp0, fd);
8071 tcg_temp_free_i32(fp0);
8072 tcg_temp_free_i32(fp1);
8073 }
8074 opn = "pul.ps";
8075 break;
8076 case OPC_PUU_PS:
8077 check_cp1_64bitmode(ctx);
8078 {
8079 TCGv_i32 fp0 = tcg_temp_new_i32();
8080 TCGv_i32 fp1 = tcg_temp_new_i32();
8081
8082 gen_load_fpr32h(fp0, fs);
8083 gen_load_fpr32h(fp1, ft);
8084 gen_store_fpr32(fp1, fd);
8085 gen_store_fpr32h(fp0, fd);
8086 tcg_temp_free_i32(fp0);
8087 tcg_temp_free_i32(fp1);
8088 }
8089 opn = "puu.ps";
8090 break;
8091 case OPC_CMP_F_PS:
8092 case OPC_CMP_UN_PS:
8093 case OPC_CMP_EQ_PS:
8094 case OPC_CMP_UEQ_PS:
8095 case OPC_CMP_OLT_PS:
8096 case OPC_CMP_ULT_PS:
8097 case OPC_CMP_OLE_PS:
8098 case OPC_CMP_ULE_PS:
8099 case OPC_CMP_SF_PS:
8100 case OPC_CMP_NGLE_PS:
8101 case OPC_CMP_SEQ_PS:
8102 case OPC_CMP_NGL_PS:
8103 case OPC_CMP_LT_PS:
8104 case OPC_CMP_NGE_PS:
8105 case OPC_CMP_LE_PS:
8106 case OPC_CMP_NGT_PS:
8107 if (ctx->opcode & (1 << 6)) {
8108 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8109 opn = condnames_abs[func-48];
8110 } else {
8111 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8112 opn = condnames[func-48];
8113 }
8114 break;
8115 default:
8116 MIPS_INVAL(opn);
8117 generate_exception (ctx, EXCP_RI);
8118 return;
8119 }
8120 (void)opn; /* avoid a compiler warning */
8121 switch (optype) {
8122 case BINOP:
8123 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8124 break;
8125 case CMPOP:
8126 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8127 break;
8128 default:
8129 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8130 break;
8131 }
8132 }
8133
8134 /* Coprocessor 3 (FPU) */
8135 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8136 int fd, int fs, int base, int index)
8137 {
8138 const char *opn = "extended float load/store";
8139 int store = 0;
8140 TCGv t0 = tcg_temp_new();
8141
8142 if (base == 0) {
8143 gen_load_gpr(t0, index);
8144 } else if (index == 0) {
8145 gen_load_gpr(t0, base);
8146 } else {
8147 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8148 }
8149 /* Don't do NOP if destination is zero: we must perform the actual
8150 memory access. */
8151 save_cpu_state(ctx, 0);
8152 switch (opc) {
8153 case OPC_LWXC1:
8154 check_cop1x(ctx);
8155 {
8156 TCGv_i32 fp0 = tcg_temp_new_i32();
8157
8158 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8159 tcg_gen_trunc_tl_i32(fp0, t0);
8160 gen_store_fpr32(fp0, fd);
8161 tcg_temp_free_i32(fp0);
8162 }
8163 opn = "lwxc1";
8164 break;
8165 case OPC_LDXC1:
8166 check_cop1x(ctx);
8167 check_cp1_registers(ctx, fd);
8168 {
8169 TCGv_i64 fp0 = tcg_temp_new_i64();
8170
8171 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8172 gen_store_fpr64(ctx, fp0, fd);
8173 tcg_temp_free_i64(fp0);
8174 }
8175 opn = "ldxc1";
8176 break;
8177 case OPC_LUXC1:
8178 check_cp1_64bitmode(ctx);
8179 tcg_gen_andi_tl(t0, t0, ~0x7);
8180 {
8181 TCGv_i64 fp0 = tcg_temp_new_i64();
8182
8183 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8184 gen_store_fpr64(ctx, fp0, fd);
8185 tcg_temp_free_i64(fp0);
8186 }
8187 opn = "luxc1";
8188 break;
8189 case OPC_SWXC1:
8190 check_cop1x(ctx);
8191 {
8192 TCGv_i32 fp0 = tcg_temp_new_i32();
8193 TCGv t1 = tcg_temp_new();
8194
8195 gen_load_fpr32(fp0, fs);
8196 tcg_gen_extu_i32_tl(t1, fp0);
8197 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8198 tcg_temp_free_i32(fp0);
8199 tcg_temp_free(t1);
8200 }
8201 opn = "swxc1";
8202 store = 1;
8203 break;
8204 case OPC_SDXC1:
8205 check_cop1x(ctx);
8206 check_cp1_registers(ctx, fs);
8207 {
8208 TCGv_i64 fp0 = tcg_temp_new_i64();
8209
8210 gen_load_fpr64(ctx, fp0, fs);
8211 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8212 tcg_temp_free_i64(fp0);
8213 }
8214 opn = "sdxc1";
8215 store = 1;
8216 break;
8217 case OPC_SUXC1:
8218 check_cp1_64bitmode(ctx);
8219 tcg_gen_andi_tl(t0, t0, ~0x7);
8220 {
8221 TCGv_i64 fp0 = tcg_temp_new_i64();
8222
8223 gen_load_fpr64(ctx, fp0, fs);
8224 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8225 tcg_temp_free_i64(fp0);
8226 }
8227 opn = "suxc1";
8228 store = 1;
8229 break;
8230 }
8231 tcg_temp_free(t0);
8232 (void)opn; (void)store; /* avoid compiler warnings */
8233 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8234 regnames[index], regnames[base]);
8235 }
8236
8237 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8238 int fd, int fr, int fs, int ft)
8239 {
8240 const char *opn = "flt3_arith";
8241
8242 switch (opc) {
8243 case OPC_ALNV_PS:
8244 check_cp1_64bitmode(ctx);
8245 {
8246 TCGv t0 = tcg_temp_local_new();
8247 TCGv_i32 fp = tcg_temp_new_i32();
8248 TCGv_i32 fph = tcg_temp_new_i32();
8249 int l1 = gen_new_label();
8250 int l2 = gen_new_label();
8251
8252 gen_load_gpr(t0, fr);
8253 tcg_gen_andi_tl(t0, t0, 0x7);
8254
8255 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8256 gen_load_fpr32(fp, fs);
8257 gen_load_fpr32h(fph, fs);
8258 gen_store_fpr32(fp, fd);
8259 gen_store_fpr32h(fph, fd);
8260 tcg_gen_br(l2);
8261 gen_set_label(l1);
8262 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8263 tcg_temp_free(t0);
8264 #ifdef TARGET_WORDS_BIGENDIAN
8265 gen_load_fpr32(fp, fs);
8266 gen_load_fpr32h(fph, ft);
8267 gen_store_fpr32h(fp, fd);
8268 gen_store_fpr32(fph, fd);
8269 #else
8270 gen_load_fpr32h(fph, fs);
8271 gen_load_fpr32(fp, ft);
8272 gen_store_fpr32(fph, fd);
8273 gen_store_fpr32h(fp, fd);
8274 #endif
8275 gen_set_label(l2);
8276 tcg_temp_free_i32(fp);
8277 tcg_temp_free_i32(fph);
8278 }
8279 opn = "alnv.ps";
8280 break;
8281 case OPC_MADD_S:
8282 check_cop1x(ctx);
8283 {
8284 TCGv_i32 fp0 = tcg_temp_new_i32();
8285 TCGv_i32 fp1 = tcg_temp_new_i32();
8286 TCGv_i32 fp2 = tcg_temp_new_i32();
8287
8288 gen_load_fpr32(fp0, fs);
8289 gen_load_fpr32(fp1, ft);
8290 gen_load_fpr32(fp2, fr);
8291 gen_helper_float_muladd_s(fp2, cpu_env, fp0, fp1, fp2);
8292 tcg_temp_free_i32(fp0);
8293 tcg_temp_free_i32(fp1);
8294 gen_store_fpr32(fp2, fd);
8295 tcg_temp_free_i32(fp2);
8296 }
8297 opn = "madd.s";
8298 break;
8299 case OPC_MADD_D:
8300 check_cop1x(ctx);
8301 check_cp1_registers(ctx, fd | fs | ft | fr);
8302 {
8303 TCGv_i64 fp0 = tcg_temp_new_i64();
8304 TCGv_i64 fp1 = tcg_temp_new_i64();
8305 TCGv_i64 fp2 = tcg_temp_new_i64();
8306
8307 gen_load_fpr64(ctx, fp0, fs);
8308 gen_load_fpr64(ctx, fp1, ft);
8309 gen_load_fpr64(ctx, fp2, fr);
8310 gen_helper_float_muladd_d(fp2, cpu_env, fp0, fp1, fp2);
8311 tcg_temp_free_i64(fp0);
8312 tcg_temp_free_i64(fp1);
8313 gen_store_fpr64(ctx, fp2, fd);
8314 tcg_temp_free_i64(fp2);
8315 }
8316 opn = "madd.d";
8317 break;
8318 case OPC_MADD_PS:
8319 check_cp1_64bitmode(ctx);
8320 {
8321 TCGv_i64 fp0 = tcg_temp_new_i64();
8322 TCGv_i64 fp1 = tcg_temp_new_i64();
8323 TCGv_i64 fp2 = tcg_temp_new_i64();
8324
8325 gen_load_fpr64(ctx, fp0, fs);
8326 gen_load_fpr64(ctx, fp1, ft);
8327 gen_load_fpr64(ctx, fp2, fr);
8328 gen_helper_float_muladd_ps(fp2, cpu_env, fp0, fp1, fp2);
8329 tcg_temp_free_i64(fp0);
8330 tcg_temp_free_i64(fp1);
8331 gen_store_fpr64(ctx, fp2, fd);
8332 tcg_temp_free_i64(fp2);
8333 }
8334 opn = "madd.ps";
8335 break;
8336 case OPC_MSUB_S:
8337 check_cop1x(ctx);
8338 {
8339 TCGv_i32 fp0 = tcg_temp_new_i32();
8340 TCGv_i32 fp1 = tcg_temp_new_i32();
8341 TCGv_i32 fp2 = tcg_temp_new_i32();
8342
8343 gen_load_fpr32(fp0, fs);
8344 gen_load_fpr32(fp1, ft);
8345 gen_load_fpr32(fp2, fr);
8346 gen_helper_float_mulsub_s(fp2, cpu_env, fp0, fp1, fp2);
8347 tcg_temp_free_i32(fp0);
8348 tcg_temp_free_i32(fp1);
8349 gen_store_fpr32(fp2, fd);
8350 tcg_temp_free_i32(fp2);
8351 }
8352 opn = "msub.s";
8353 break;
8354 case OPC_MSUB_D:
8355 check_cop1x(ctx);
8356 check_cp1_registers(ctx, fd | fs | ft | fr);
8357 {
8358 TCGv_i64 fp0 = tcg_temp_new_i64();
8359 TCGv_i64 fp1 = tcg_temp_new_i64();
8360 TCGv_i64 fp2 = tcg_temp_new_i64();
8361
8362 gen_load_fpr64(ctx, fp0, fs);
8363 gen_load_fpr64(ctx, fp1, ft);
8364 gen_load_fpr64(ctx, fp2, fr);
8365 gen_helper_float_mulsub_d(fp2, cpu_env, fp0, fp1, fp2);
8366 tcg_temp_free_i64(fp0);
8367 tcg_temp_free_i64(fp1);
8368 gen_store_fpr64(ctx, fp2, fd);
8369 tcg_temp_free_i64(fp2);
8370 }
8371 opn = "msub.d";
8372 break;
8373 case OPC_MSUB_PS:
8374 check_cp1_64bitmode(ctx);
8375 {
8376 TCGv_i64 fp0 = tcg_temp_new_i64();
8377 TCGv_i64 fp1 = tcg_temp_new_i64();
8378 TCGv_i64 fp2 = tcg_temp_new_i64();
8379
8380 gen_load_fpr64(ctx, fp0, fs);
8381 gen_load_fpr64(ctx, fp1, ft);
8382 gen_load_fpr64(ctx, fp2, fr);
8383 gen_helper_float_mulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8384 tcg_temp_free_i64(fp0);
8385 tcg_temp_free_i64(fp1);
8386 gen_store_fpr64(ctx, fp2, fd);
8387 tcg_temp_free_i64(fp2);
8388 }
8389 opn = "msub.ps";
8390 break;
8391 case OPC_NMADD_S:
8392 check_cop1x(ctx);
8393 {
8394 TCGv_i32 fp0 = tcg_temp_new_i32();
8395 TCGv_i32 fp1 = tcg_temp_new_i32();
8396 TCGv_i32 fp2 = tcg_temp_new_i32();
8397
8398 gen_load_fpr32(fp0, fs);
8399 gen_load_fpr32(fp1, ft);
8400 gen_load_fpr32(fp2, fr);
8401 gen_helper_float_nmuladd_s(fp2, cpu_env, fp0, fp1, fp2);
8402 tcg_temp_free_i32(fp0);
8403 tcg_temp_free_i32(fp1);
8404 gen_store_fpr32(fp2, fd);
8405 tcg_temp_free_i32(fp2);
8406 }
8407 opn = "nmadd.s";
8408 break;
8409 case OPC_NMADD_D:
8410 check_cop1x(ctx);
8411 check_cp1_registers(ctx, fd | fs | ft | fr);
8412 {
8413 TCGv_i64 fp0 = tcg_temp_new_i64();
8414 TCGv_i64 fp1 = tcg_temp_new_i64();
8415 TCGv_i64 fp2 = tcg_temp_new_i64();
8416
8417 gen_load_fpr64(ctx, fp0, fs);
8418 gen_load_fpr64(ctx, fp1, ft);
8419 gen_load_fpr64(ctx, fp2, fr);
8420 gen_helper_float_nmuladd_d(fp2, cpu_env, fp0, fp1, fp2);
8421 tcg_temp_free_i64(fp0);
8422 tcg_temp_free_i64(fp1);
8423 gen_store_fpr64(ctx, fp2, fd);
8424 tcg_temp_free_i64(fp2);
8425 }
8426 opn = "nmadd.d";
8427 break;
8428 case OPC_NMADD_PS:
8429 check_cp1_64bitmode(ctx);
8430 {
8431 TCGv_i64 fp0 = tcg_temp_new_i64();
8432 TCGv_i64 fp1 = tcg_temp_new_i64();
8433 TCGv_i64 fp2 = tcg_temp_new_i64();
8434
8435 gen_load_fpr64(ctx, fp0, fs);
8436 gen_load_fpr64(ctx, fp1, ft);
8437 gen_load_fpr64(ctx, fp2, fr);
8438 gen_helper_float_nmuladd_ps(fp2, cpu_env, fp0, fp1, fp2);
8439 tcg_temp_free_i64(fp0);
8440 tcg_temp_free_i64(fp1);
8441 gen_store_fpr64(ctx, fp2, fd);
8442 tcg_temp_free_i64(fp2);
8443 }
8444 opn = "nmadd.ps";
8445 break;
8446 case OPC_NMSUB_S:
8447 check_cop1x(ctx);
8448 {
8449 TCGv_i32 fp0 = tcg_temp_new_i32();
8450 TCGv_i32 fp1 = tcg_temp_new_i32();
8451 TCGv_i32 fp2 = tcg_temp_new_i32();
8452
8453 gen_load_fpr32(fp0, fs);
8454 gen_load_fpr32(fp1, ft);
8455 gen_load_fpr32(fp2, fr);
8456 gen_helper_float_nmulsub_s(fp2, cpu_env, fp0, fp1, fp2);
8457 tcg_temp_free_i32(fp0);
8458 tcg_temp_free_i32(fp1);
8459 gen_store_fpr32(fp2, fd);
8460 tcg_temp_free_i32(fp2);
8461 }
8462 opn = "nmsub.s";
8463 break;
8464 case OPC_NMSUB_D:
8465 check_cop1x(ctx);
8466 check_cp1_registers(ctx, fd | fs | ft | fr);
8467 {
8468 TCGv_i64 fp0 = tcg_temp_new_i64();
8469 TCGv_i64 fp1 = tcg_temp_new_i64();
8470 TCGv_i64 fp2 = tcg_temp_new_i64();
8471
8472 gen_load_fpr64(ctx, fp0, fs);
8473 gen_load_fpr64(ctx, fp1, ft);
8474 gen_load_fpr64(ctx, fp2, fr);
8475 gen_helper_float_nmulsub_d(fp2, cpu_env, fp0, fp1, fp2);
8476 tcg_temp_free_i64(fp0);
8477 tcg_temp_free_i64(fp1);
8478 gen_store_fpr64(ctx, fp2, fd);
8479 tcg_temp_free_i64(fp2);
8480 }
8481 opn = "nmsub.d";
8482 break;
8483 case OPC_NMSUB_PS:
8484 check_cp1_64bitmode(ctx);
8485 {
8486 TCGv_i64 fp0 = tcg_temp_new_i64();
8487 TCGv_i64 fp1 = tcg_temp_new_i64();
8488 TCGv_i64 fp2 = tcg_temp_new_i64();
8489
8490 gen_load_fpr64(ctx, fp0, fs);
8491 gen_load_fpr64(ctx, fp1, ft);
8492 gen_load_fpr64(ctx, fp2, fr);
8493 gen_helper_float_nmulsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8494 tcg_temp_free_i64(fp0);
8495 tcg_temp_free_i64(fp1);
8496 gen_store_fpr64(ctx, fp2, fd);
8497 tcg_temp_free_i64(fp2);
8498 }
8499 opn = "nmsub.ps";
8500 break;
8501 default:
8502 MIPS_INVAL(opn);
8503 generate_exception (ctx, EXCP_RI);
8504 return;
8505 }
8506 (void)opn; /* avoid a compiler warning */
8507 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
8508 fregnames[fs], fregnames[ft]);
8509 }
8510
8511 static void
8512 gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
8513 {
8514 TCGv t0;
8515
8516 #if !defined(CONFIG_USER_ONLY)
8517 /* The Linux kernel will emulate rdhwr if it's not supported natively.
8518 Therefore only check the ISA in system mode. */
8519 check_insn(env, ctx, ISA_MIPS32R2);
8520 #endif
8521 t0 = tcg_temp_new();
8522
8523 switch (rd) {
8524 case 0:
8525 save_cpu_state(ctx, 1);
8526 gen_helper_rdhwr_cpunum(t0, cpu_env);
8527 gen_store_gpr(t0, rt);
8528 break;
8529 case 1:
8530 save_cpu_state(ctx, 1);
8531 gen_helper_rdhwr_synci_step(t0, cpu_env);
8532 gen_store_gpr(t0, rt);
8533 break;
8534 case 2:
8535 save_cpu_state(ctx, 1);
8536 gen_helper_rdhwr_cc(t0, cpu_env);
8537 gen_store_gpr(t0, rt);
8538 break;
8539 case 3:
8540 save_cpu_state(ctx, 1);
8541 gen_helper_rdhwr_ccres(t0, cpu_env);
8542 gen_store_gpr(t0, rt);
8543 break;
8544 case 29:
8545 #if defined(CONFIG_USER_ONLY)
8546 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
8547 gen_store_gpr(t0, rt);
8548 break;
8549 #else
8550 /* XXX: Some CPUs implement this in hardware.
8551 Not supported yet. */
8552 #endif
8553 default: /* Invalid */
8554 MIPS_INVAL("rdhwr");
8555 generate_exception(ctx, EXCP_RI);
8556 break;
8557 }
8558 tcg_temp_free(t0);
8559 }
8560
8561 static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
8562 int insn_bytes)
8563 {
8564 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8565 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8566 /* Branches completion */
8567 ctx->hflags &= ~MIPS_HFLAG_BMASK;
8568 ctx->bstate = BS_BRANCH;
8569 save_cpu_state(ctx, 0);
8570 /* FIXME: Need to clear can_do_io. */
8571 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
8572 case MIPS_HFLAG_B:
8573 /* unconditional branch */
8574 MIPS_DEBUG("unconditional branch");
8575 if (proc_hflags & MIPS_HFLAG_BX) {
8576 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
8577 }
8578 gen_goto_tb(ctx, 0, ctx->btarget);
8579 break;
8580 case MIPS_HFLAG_BL:
8581 /* blikely taken case */
8582 MIPS_DEBUG("blikely branch taken");
8583 gen_goto_tb(ctx, 0, ctx->btarget);
8584 break;
8585 case MIPS_HFLAG_BC:
8586 /* Conditional branch */
8587 MIPS_DEBUG("conditional branch");
8588 {
8589 int l1 = gen_new_label();
8590
8591 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8592 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
8593 gen_set_label(l1);
8594 gen_goto_tb(ctx, 0, ctx->btarget);
8595 }
8596 break;
8597 case MIPS_HFLAG_BR:
8598 /* unconditional branch to register */
8599 MIPS_DEBUG("branch to register");
8600 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
8601 TCGv t0 = tcg_temp_new();
8602 TCGv_i32 t1 = tcg_temp_new_i32();
8603
8604 tcg_gen_andi_tl(t0, btarget, 0x1);
8605 tcg_gen_trunc_tl_i32(t1, t0);
8606 tcg_temp_free(t0);
8607 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
8608 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
8609 tcg_gen_or_i32(hflags, hflags, t1);
8610 tcg_temp_free_i32(t1);
8611
8612 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
8613 } else {
8614 tcg_gen_mov_tl(cpu_PC, btarget);
8615 }
8616 if (ctx->singlestep_enabled) {
8617 save_cpu_state(ctx, 0);
8618 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
8619 }
8620 tcg_gen_exit_tb(0);
8621 break;
8622 default:
8623 MIPS_DEBUG("unknown branch");
8624 break;
8625 }
8626 }
8627 }
8628
8629 /* ISA extensions (ASEs) */
8630 /* MIPS16 extension to MIPS32 */
8631
8632 /* MIPS16 major opcodes */
8633 enum {
8634 M16_OPC_ADDIUSP = 0x00,
8635 M16_OPC_ADDIUPC = 0x01,
8636 M16_OPC_B = 0x02,
8637 M16_OPC_JAL = 0x03,
8638 M16_OPC_BEQZ = 0x04,
8639 M16_OPC_BNEQZ = 0x05,
8640 M16_OPC_SHIFT = 0x06,
8641 M16_OPC_LD = 0x07,
8642 M16_OPC_RRIA = 0x08,
8643 M16_OPC_ADDIU8 = 0x09,
8644 M16_OPC_SLTI = 0x0a,
8645 M16_OPC_SLTIU = 0x0b,
8646 M16_OPC_I8 = 0x0c,
8647 M16_OPC_LI = 0x0d,
8648 M16_OPC_CMPI = 0x0e,
8649 M16_OPC_SD = 0x0f,
8650 M16_OPC_LB = 0x10,
8651 M16_OPC_LH = 0x11,
8652 M16_OPC_LWSP = 0x12,
8653 M16_OPC_LW = 0x13,
8654 M16_OPC_LBU = 0x14,
8655 M16_OPC_LHU = 0x15,
8656 M16_OPC_LWPC = 0x16,
8657 M16_OPC_LWU = 0x17,
8658 M16_OPC_SB = 0x18,
8659 M16_OPC_SH = 0x19,
8660 M16_OPC_SWSP = 0x1a,
8661 M16_OPC_SW = 0x1b,
8662 M16_OPC_RRR = 0x1c,
8663 M16_OPC_RR = 0x1d,
8664 M16_OPC_EXTEND = 0x1e,
8665 M16_OPC_I64 = 0x1f
8666 };
8667
8668 /* I8 funct field */
8669 enum {
8670 I8_BTEQZ = 0x0,
8671 I8_BTNEZ = 0x1,
8672 I8_SWRASP = 0x2,
8673 I8_ADJSP = 0x3,
8674 I8_SVRS = 0x4,
8675 I8_MOV32R = 0x5,
8676 I8_MOVR32 = 0x7
8677 };
8678
8679 /* RRR f field */
8680 enum {
8681 RRR_DADDU = 0x0,
8682 RRR_ADDU = 0x1,
8683 RRR_DSUBU = 0x2,
8684 RRR_SUBU = 0x3
8685 };
8686
8687 /* RR funct field */
8688 enum {
8689 RR_JR = 0x00,
8690 RR_SDBBP = 0x01,
8691 RR_SLT = 0x02,
8692 RR_SLTU = 0x03,
8693 RR_SLLV = 0x04,
8694 RR_BREAK = 0x05,
8695 RR_SRLV = 0x06,
8696 RR_SRAV = 0x07,
8697 RR_DSRL = 0x08,
8698 RR_CMP = 0x0a,
8699 RR_NEG = 0x0b,
8700 RR_AND = 0x0c,
8701 RR_OR = 0x0d,
8702 RR_XOR = 0x0e,
8703 RR_NOT = 0x0f,
8704 RR_MFHI = 0x10,
8705 RR_CNVT = 0x11,
8706 RR_MFLO = 0x12,
8707 RR_DSRA = 0x13,
8708 RR_DSLLV = 0x14,
8709 RR_DSRLV = 0x16,
8710 RR_DSRAV = 0x17,
8711 RR_MULT = 0x18,
8712 RR_MULTU = 0x19,
8713 RR_DIV = 0x1a,
8714 RR_DIVU = 0x1b,
8715 RR_DMULT = 0x1c,
8716 RR_DMULTU = 0x1d,
8717 RR_DDIV = 0x1e,
8718 RR_DDIVU = 0x1f
8719 };
8720
8721 /* I64 funct field */
8722 enum {
8723 I64_LDSP = 0x0,
8724 I64_SDSP = 0x1,
8725 I64_SDRASP = 0x2,
8726 I64_DADJSP = 0x3,
8727 I64_LDPC = 0x4,
8728 I64_DADDIU5 = 0x5,
8729 I64_DADDIUPC = 0x6,
8730 I64_DADDIUSP = 0x7
8731 };
8732
8733 /* RR ry field for CNVT */
8734 enum {
8735 RR_RY_CNVT_ZEB = 0x0,
8736 RR_RY_CNVT_ZEH = 0x1,
8737 RR_RY_CNVT_ZEW = 0x2,
8738 RR_RY_CNVT_SEB = 0x4,
8739 RR_RY_CNVT_SEH = 0x5,
8740 RR_RY_CNVT_SEW = 0x6,
8741 };
8742
8743 static int xlat (int r)
8744 {
8745 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
8746
8747 return map[r];
8748 }
8749
8750 static void gen_mips16_save (DisasContext *ctx,
8751 int xsregs, int aregs,
8752 int do_ra, int do_s0, int do_s1,
8753 int framesize)
8754 {
8755 TCGv t0 = tcg_temp_new();
8756 TCGv t1 = tcg_temp_new();
8757 int args, astatic;
8758
8759 switch (aregs) {
8760 case 0:
8761 case 1:
8762 case 2:
8763 case 3:
8764 case 11:
8765 args = 0;
8766 break;
8767 case 4:
8768 case 5:
8769 case 6:
8770 case 7:
8771 args = 1;
8772 break;
8773 case 8:
8774 case 9:
8775 case 10:
8776 args = 2;
8777 break;
8778 case 12:
8779 case 13:
8780 args = 3;
8781 break;
8782 case 14:
8783 args = 4;
8784 break;
8785 default:
8786 generate_exception(ctx, EXCP_RI);
8787 return;
8788 }
8789
8790 switch (args) {
8791 case 4:
8792 gen_base_offset_addr(ctx, t0, 29, 12);
8793 gen_load_gpr(t1, 7);
8794 op_st_sw(t1, t0, ctx);
8795 /* Fall through */
8796 case 3:
8797 gen_base_offset_addr(ctx, t0, 29, 8);
8798 gen_load_gpr(t1, 6);
8799 op_st_sw(t1, t0, ctx);
8800 /* Fall through */
8801 case 2:
8802 gen_base_offset_addr(ctx, t0, 29, 4);
8803 gen_load_gpr(t1, 5);
8804 op_st_sw(t1, t0, ctx);
8805 /* Fall through */
8806 case 1:
8807 gen_base_offset_addr(ctx, t0, 29, 0);
8808 gen_load_gpr(t1, 4);
8809 op_st_sw(t1, t0, ctx);
8810 }
8811
8812 gen_load_gpr(t0, 29);
8813
8814 #define DECR_AND_STORE(reg) do { \
8815 tcg_gen_subi_tl(t0, t0, 4); \
8816 gen_load_gpr(t1, reg); \
8817 op_st_sw(t1, t0, ctx); \
8818 } while (0)
8819
8820 if (do_ra) {
8821 DECR_AND_STORE(31);
8822 }
8823
8824 switch (xsregs) {
8825 case 7:
8826 DECR_AND_STORE(30);
8827 /* Fall through */
8828 case 6:
8829 DECR_AND_STORE(23);
8830 /* Fall through */
8831 case 5:
8832 DECR_AND_STORE(22);
8833 /* Fall through */
8834 case 4:
8835 DECR_AND_STORE(21);
8836 /* Fall through */
8837 case 3:
8838 DECR_AND_STORE(20);
8839 /* Fall through */
8840 case 2:
8841 DECR_AND_STORE(19);
8842 /* Fall through */
8843 case 1:
8844 DECR_AND_STORE(18);
8845 }
8846
8847 if (do_s1) {
8848 DECR_AND_STORE(17);
8849 }
8850 if (do_s0) {
8851 DECR_AND_STORE(16);
8852 }
8853
8854 switch (aregs) {
8855 case 0:
8856 case 4:
8857 case 8:
8858 case 12:
8859 case 14:
8860 astatic = 0;
8861 break;
8862 case 1:
8863 case 5:
8864 case 9:
8865 case 13:
8866 astatic = 1;
8867 break;
8868 case 2:
8869 case 6:
8870 case 10:
8871 astatic = 2;
8872 break;
8873 case 3:
8874 case 7:
8875 astatic = 3;
8876 break;
8877 case 11:
8878 astatic = 4;
8879 break;
8880 default:
8881 generate_exception(ctx, EXCP_RI);
8882 return;
8883 }
8884
8885 if (astatic > 0) {
8886 DECR_AND_STORE(7);
8887 if (astatic > 1) {
8888 DECR_AND_STORE(6);
8889 if (astatic > 2) {
8890 DECR_AND_STORE(5);
8891 if (astatic > 3) {
8892 DECR_AND_STORE(4);
8893 }
8894 }
8895 }
8896 }
8897 #undef DECR_AND_STORE
8898
8899 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
8900 tcg_temp_free(t0);
8901 tcg_temp_free(t1);
8902 }
8903
8904 static void gen_mips16_restore (DisasContext *ctx,
8905 int xsregs, int aregs,
8906 int do_ra, int do_s0, int do_s1,
8907 int framesize)
8908 {
8909 int astatic;
8910 TCGv t0 = tcg_temp_new();
8911 TCGv t1 = tcg_temp_new();
8912
8913 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
8914
8915 #define DECR_AND_LOAD(reg) do { \
8916 tcg_gen_subi_tl(t0, t0, 4); \
8917 op_ld_lw(t1, t0, ctx); \
8918 gen_store_gpr(t1, reg); \
8919 } while (0)
8920
8921 if (do_ra) {
8922 DECR_AND_LOAD(31);
8923 }
8924
8925 switch (xsregs) {
8926 case 7:
8927 DECR_AND_LOAD(30);
8928 /* Fall through */
8929 case 6:
8930 DECR_AND_LOAD(23);
8931 /* Fall through */
8932 case 5:
8933 DECR_AND_LOAD(22);
8934 /* Fall through */
8935 case 4:
8936 DECR_AND_LOAD(21);
8937 /* Fall through */
8938 case 3:
8939 DECR_AND_LOAD(20);
8940 /* Fall through */
8941 case 2:
8942 DECR_AND_LOAD(19);
8943 /* Fall through */
8944 case 1:
8945 DECR_AND_LOAD(18);
8946 }
8947
8948 if (do_s1) {
8949 DECR_AND_LOAD(17);
8950 }
8951 if (do_s0) {
8952 DECR_AND_LOAD(16);
8953 }
8954
8955 switch (aregs) {
8956 case 0:
8957 case 4:
8958 case 8:
8959 case 12:
8960 case 14:
8961 astatic = 0;
8962 break;
8963 case 1:
8964 case 5:
8965 case 9:
8966 case 13:
8967 astatic = 1;
8968 break;
8969 case 2:
8970 case 6:
8971 case 10:
8972 astatic = 2;
8973 break;
8974 case 3:
8975 case 7:
8976 astatic = 3;
8977 break;
8978 case 11:
8979 astatic = 4;
8980 break;
8981 default:
8982 generate_exception(ctx, EXCP_RI);
8983 return;
8984 }
8985
8986 if (astatic > 0) {
8987 DECR_AND_LOAD(7);
8988 if (astatic > 1) {
8989 DECR_AND_LOAD(6);
8990 if (astatic > 2) {
8991 DECR_AND_LOAD(5);
8992 if (astatic > 3) {
8993 DECR_AND_LOAD(4);
8994 }
8995 }
8996 }
8997 }
8998 #undef DECR_AND_LOAD
8999
9000 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9001 tcg_temp_free(t0);
9002 tcg_temp_free(t1);
9003 }
9004
9005 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9006 int is_64_bit, int extended)
9007 {
9008 TCGv t0;
9009
9010 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9011 generate_exception(ctx, EXCP_RI);
9012 return;
9013 }
9014
9015 t0 = tcg_temp_new();
9016
9017 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9018 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9019 if (!is_64_bit) {
9020 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9021 }
9022
9023 tcg_temp_free(t0);
9024 }
9025
9026 #if defined(TARGET_MIPS64)
9027 static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
9028 int ry, int funct, int16_t offset,
9029 int extended)
9030 {
9031 switch (funct) {
9032 case I64_LDSP:
9033 check_mips_64(ctx);
9034 offset = extended ? offset : offset << 3;
9035 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
9036 break;
9037 case I64_SDSP:
9038 check_mips_64(ctx);
9039 offset = extended ? offset : offset << 3;
9040 gen_st(ctx, OPC_SD, ry, 29, offset);
9041 break;
9042 case I64_SDRASP:
9043 check_mips_64(ctx);
9044 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9045 gen_st(ctx, OPC_SD, 31, 29, offset);
9046 break;
9047 case I64_DADJSP:
9048 check_mips_64(ctx);
9049 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9050 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9051 break;
9052 case I64_LDPC:
9053 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9054 generate_exception(ctx, EXCP_RI);
9055 } else {
9056 offset = extended ? offset : offset << 3;
9057 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
9058 }
9059 break;
9060 case I64_DADDIU5:
9061 check_mips_64(ctx);
9062 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9063 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9064 break;
9065 case I64_DADDIUPC:
9066 check_mips_64(ctx);
9067 offset = extended ? offset : offset << 2;
9068 gen_addiupc(ctx, ry, offset, 1, extended);
9069 break;
9070 case I64_DADDIUSP:
9071 check_mips_64(ctx);
9072 offset = extended ? offset : offset << 2;
9073 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9074 break;
9075 }
9076 }
9077 #endif
9078
9079 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9080 int *is_branch)
9081 {
9082 int extend = cpu_lduw_code(env, ctx->pc + 2);
9083 int op, rx, ry, funct, sa;
9084 int16_t imm, offset;
9085
9086 ctx->opcode = (ctx->opcode << 16) | extend;
9087 op = (ctx->opcode >> 11) & 0x1f;
9088 sa = (ctx->opcode >> 22) & 0x1f;
9089 funct = (ctx->opcode >> 8) & 0x7;
9090 rx = xlat((ctx->opcode >> 8) & 0x7);
9091 ry = xlat((ctx->opcode >> 5) & 0x7);
9092 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9093 | ((ctx->opcode >> 21) & 0x3f) << 5
9094 | (ctx->opcode & 0x1f));
9095
9096 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9097 counterparts. */
9098 switch (op) {
9099 case M16_OPC_ADDIUSP:
9100 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9101 break;
9102 case M16_OPC_ADDIUPC:
9103 gen_addiupc(ctx, rx, imm, 0, 1);
9104 break;
9105 case M16_OPC_B:
9106 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9107 /* No delay slot, so just process as a normal instruction */
9108 break;
9109 case M16_OPC_BEQZ:
9110 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9111 /* No delay slot, so just process as a normal instruction */
9112 break;
9113 case M16_OPC_BNEQZ:
9114 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9115 /* No delay slot, so just process as a normal instruction */
9116 break;
9117 case M16_OPC_SHIFT:
9118 switch (ctx->opcode & 0x3) {
9119 case 0x0:
9120 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9121 break;
9122 case 0x1:
9123 #if defined(TARGET_MIPS64)
9124 check_mips_64(ctx);
9125 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9126 #else
9127 generate_exception(ctx, EXCP_RI);
9128 #endif
9129 break;
9130 case 0x2:
9131 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9132 break;
9133 case 0x3:
9134 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9135 break;
9136 }
9137 break;
9138 #if defined(TARGET_MIPS64)
9139 case M16_OPC_LD:
9140 check_mips_64(ctx);
9141 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
9142 break;
9143 #endif
9144 case M16_OPC_RRIA:
9145 imm = ctx->opcode & 0xf;
9146 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9147 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9148 imm = (int16_t) (imm << 1) >> 1;
9149 if ((ctx->opcode >> 4) & 0x1) {
9150 #if defined(TARGET_MIPS64)
9151 check_mips_64(ctx);
9152 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9153 #else
9154 generate_exception(ctx, EXCP_RI);
9155 #endif
9156 } else {
9157 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9158 }
9159 break;
9160 case M16_OPC_ADDIU8:
9161 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9162 break;
9163 case M16_OPC_SLTI:
9164 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9165 break;
9166 case M16_OPC_SLTIU:
9167 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9168 break;
9169 case M16_OPC_I8:
9170 switch (funct) {
9171 case I8_BTEQZ:
9172 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9173 break;
9174 case I8_BTNEZ:
9175 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9176 break;
9177 case I8_SWRASP:
9178 gen_st(ctx, OPC_SW, 31, 29, imm);
9179 break;
9180 case I8_ADJSP:
9181 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9182 break;
9183 case I8_SVRS:
9184 {
9185 int xsregs = (ctx->opcode >> 24) & 0x7;
9186 int aregs = (ctx->opcode >> 16) & 0xf;
9187 int do_ra = (ctx->opcode >> 6) & 0x1;
9188 int do_s0 = (ctx->opcode >> 5) & 0x1;
9189 int do_s1 = (ctx->opcode >> 4) & 0x1;
9190 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9191 | (ctx->opcode & 0xf)) << 3;
9192
9193 if (ctx->opcode & (1 << 7)) {
9194 gen_mips16_save(ctx, xsregs, aregs,
9195 do_ra, do_s0, do_s1,
9196 framesize);
9197 } else {
9198 gen_mips16_restore(ctx, xsregs, aregs,
9199 do_ra, do_s0, do_s1,
9200 framesize);
9201 }
9202 }
9203 break;
9204 default:
9205 generate_exception(ctx, EXCP_RI);
9206 break;
9207 }
9208 break;
9209 case M16_OPC_LI:
9210 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9211 break;
9212 case M16_OPC_CMPI:
9213 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9214 break;
9215 #if defined(TARGET_MIPS64)
9216 case M16_OPC_SD:
9217 gen_st(ctx, OPC_SD, ry, rx, offset);
9218 break;
9219 #endif
9220 case M16_OPC_LB:
9221 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9222 break;
9223 case M16_OPC_LH:
9224 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
9225 break;
9226 case M16_OPC_LWSP:
9227 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
9228 break;
9229 case M16_OPC_LW:
9230 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
9231 break;
9232 case M16_OPC_LBU:
9233 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9234 break;
9235 case M16_OPC_LHU:
9236 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
9237 break;
9238 case M16_OPC_LWPC:
9239 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
9240 break;
9241 #if defined(TARGET_MIPS64)
9242 case M16_OPC_LWU:
9243 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
9244 break;
9245 #endif
9246 case M16_OPC_SB:
9247 gen_st(ctx, OPC_SB, ry, rx, offset);
9248 break;
9249 case M16_OPC_SH:
9250 gen_st(ctx, OPC_SH, ry, rx, offset);
9251 break;
9252 case M16_OPC_SWSP:
9253 gen_st(ctx, OPC_SW, rx, 29, offset);
9254 break;
9255 case M16_OPC_SW:
9256 gen_st(ctx, OPC_SW, ry, rx, offset);
9257 break;
9258 #if defined(TARGET_MIPS64)
9259 case M16_OPC_I64:
9260 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9261 break;
9262 #endif
9263 default:
9264 generate_exception(ctx, EXCP_RI);
9265 break;
9266 }
9267
9268 return 4;
9269 }
9270
9271 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
9272 int *is_branch)
9273 {
9274 int rx, ry;
9275 int sa;
9276 int op, cnvt_op, op1, offset;
9277 int funct;
9278 int n_bytes;
9279
9280 op = (ctx->opcode >> 11) & 0x1f;
9281 sa = (ctx->opcode >> 2) & 0x7;
9282 sa = sa == 0 ? 8 : sa;
9283 rx = xlat((ctx->opcode >> 8) & 0x7);
9284 cnvt_op = (ctx->opcode >> 5) & 0x7;
9285 ry = xlat((ctx->opcode >> 5) & 0x7);
9286 op1 = offset = ctx->opcode & 0x1f;
9287
9288 n_bytes = 2;
9289
9290 switch (op) {
9291 case M16_OPC_ADDIUSP:
9292 {
9293 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9294
9295 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9296 }
9297 break;
9298 case M16_OPC_ADDIUPC:
9299 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9300 break;
9301 case M16_OPC_B:
9302 offset = (ctx->opcode & 0x7ff) << 1;
9303 offset = (int16_t)(offset << 4) >> 4;
9304 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9305 /* No delay slot, so just process as a normal instruction */
9306 break;
9307 case M16_OPC_JAL:
9308 offset = cpu_lduw_code(env, ctx->pc + 2);
9309 offset = (((ctx->opcode & 0x1f) << 21)
9310 | ((ctx->opcode >> 5) & 0x1f) << 16
9311 | offset) << 2;
9312 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9313 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9314 n_bytes = 4;
9315 *is_branch = 1;
9316 break;
9317 case M16_OPC_BEQZ:
9318 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9319 /* No delay slot, so just process as a normal instruction */
9320 break;
9321 case M16_OPC_BNEQZ:
9322 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9323 /* No delay slot, so just process as a normal instruction */
9324 break;
9325 case M16_OPC_SHIFT:
9326 switch (ctx->opcode & 0x3) {
9327 case 0x0:
9328 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9329 break;
9330 case 0x1:
9331 #if defined(TARGET_MIPS64)
9332 check_mips_64(ctx);
9333 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9334 #else
9335 generate_exception(ctx, EXCP_RI);
9336 #endif
9337 break;
9338 case 0x2:
9339 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9340 break;
9341 case 0x3:
9342 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9343 break;
9344 }
9345 break;
9346 #if defined(TARGET_MIPS64)
9347 case M16_OPC_LD:
9348 check_mips_64(ctx);
9349 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
9350 break;
9351 #endif
9352 case M16_OPC_RRIA:
9353 {
9354 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9355
9356 if ((ctx->opcode >> 4) & 1) {
9357 #if defined(TARGET_MIPS64)
9358 check_mips_64(ctx);
9359 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9360 #else
9361 generate_exception(ctx, EXCP_RI);
9362 #endif
9363 } else {
9364 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9365 }
9366 }
9367 break;
9368 case M16_OPC_ADDIU8:
9369 {
9370 int16_t imm = (int8_t) ctx->opcode;
9371
9372 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9373 }
9374 break;
9375 case M16_OPC_SLTI:
9376 {
9377 int16_t imm = (uint8_t) ctx->opcode;
9378 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
9379 }
9380 break;
9381 case M16_OPC_SLTIU:
9382 {
9383 int16_t imm = (uint8_t) ctx->opcode;
9384 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
9385 }
9386 break;
9387 case M16_OPC_I8:
9388 {
9389 int reg32;
9390
9391 funct = (ctx->opcode >> 8) & 0x7;
9392 switch (funct) {
9393 case I8_BTEQZ:
9394 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9395 ((int8_t)ctx->opcode) << 1);
9396 break;
9397 case I8_BTNEZ:
9398 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9399 ((int8_t)ctx->opcode) << 1);
9400 break;
9401 case I8_SWRASP:
9402 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9403 break;
9404 case I8_ADJSP:
9405 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9406 ((int8_t)ctx->opcode) << 3);
9407 break;
9408 case I8_SVRS:
9409 {
9410 int do_ra = ctx->opcode & (1 << 6);
9411 int do_s0 = ctx->opcode & (1 << 5);
9412 int do_s1 = ctx->opcode & (1 << 4);
9413 int framesize = ctx->opcode & 0xf;
9414
9415 if (framesize == 0) {
9416 framesize = 128;
9417 } else {
9418 framesize = framesize << 3;
9419 }
9420
9421 if (ctx->opcode & (1 << 7)) {
9422 gen_mips16_save(ctx, 0, 0,
9423 do_ra, do_s0, do_s1, framesize);
9424 } else {
9425 gen_mips16_restore(ctx, 0, 0,
9426 do_ra, do_s0, do_s1, framesize);
9427 }
9428 }
9429 break;
9430 case I8_MOV32R:
9431 {
9432 int rz = xlat(ctx->opcode & 0x7);
9433
9434 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9435 ((ctx->opcode >> 5) & 0x7);
9436 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9437 }
9438 break;
9439 case I8_MOVR32:
9440 reg32 = ctx->opcode & 0x1f;
9441 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9442 break;
9443 default:
9444 generate_exception(ctx, EXCP_RI);
9445 break;
9446 }
9447 }
9448 break;
9449 case M16_OPC_LI:
9450 {
9451 int16_t imm = (uint8_t) ctx->opcode;
9452
9453 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9454 }
9455 break;
9456 case M16_OPC_CMPI:
9457 {
9458 int16_t imm = (uint8_t) ctx->opcode;
9459 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
9460 }
9461 break;
9462 #if defined(TARGET_MIPS64)
9463 case M16_OPC_SD:
9464 check_mips_64(ctx);
9465 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9466 break;
9467 #endif
9468 case M16_OPC_LB:
9469 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
9470 break;
9471 case M16_OPC_LH:
9472 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
9473 break;
9474 case M16_OPC_LWSP:
9475 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9476 break;
9477 case M16_OPC_LW:
9478 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
9479 break;
9480 case M16_OPC_LBU:
9481 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
9482 break;
9483 case M16_OPC_LHU:
9484 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
9485 break;
9486 case M16_OPC_LWPC:
9487 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9488 break;
9489 #if defined (TARGET_MIPS64)
9490 case M16_OPC_LWU:
9491 check_mips_64(ctx);
9492 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
9493 break;
9494 #endif
9495 case M16_OPC_SB:
9496 gen_st(ctx, OPC_SB, ry, rx, offset);
9497 break;
9498 case M16_OPC_SH:
9499 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9500 break;
9501 case M16_OPC_SWSP:
9502 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9503 break;
9504 case M16_OPC_SW:
9505 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9506 break;
9507 case M16_OPC_RRR:
9508 {
9509 int rz = xlat((ctx->opcode >> 2) & 0x7);
9510 int mips32_op;
9511
9512 switch (ctx->opcode & 0x3) {
9513 case RRR_ADDU:
9514 mips32_op = OPC_ADDU;
9515 break;
9516 case RRR_SUBU:
9517 mips32_op = OPC_SUBU;
9518 break;
9519 #if defined(TARGET_MIPS64)
9520 case RRR_DADDU:
9521 mips32_op = OPC_DADDU;
9522 check_mips_64(ctx);
9523 break;
9524 case RRR_DSUBU:
9525 mips32_op = OPC_DSUBU;
9526 check_mips_64(ctx);
9527 break;
9528 #endif
9529 default:
9530 generate_exception(ctx, EXCP_RI);
9531 goto done;
9532 }
9533
9534 gen_arith(env, ctx, mips32_op, rz, rx, ry);
9535 done:
9536 ;
9537 }
9538 break;
9539 case M16_OPC_RR:
9540 switch (op1) {
9541 case RR_JR:
9542 {
9543 int nd = (ctx->opcode >> 7) & 0x1;
9544 int link = (ctx->opcode >> 6) & 0x1;
9545 int ra = (ctx->opcode >> 5) & 0x1;
9546
9547 if (link) {
9548 op = nd ? OPC_JALRC : OPC_JALRS;
9549 } else {
9550 op = OPC_JR;
9551 }
9552
9553 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
9554 if (!nd) {
9555 *is_branch = 1;
9556 }
9557 }
9558 break;
9559 case RR_SDBBP:
9560 /* XXX: not clear which exception should be raised
9561 * when in debug mode...
9562 */
9563 check_insn(env, ctx, ISA_MIPS32);
9564 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9565 generate_exception(ctx, EXCP_DBp);
9566 } else {
9567 generate_exception(ctx, EXCP_DBp);
9568 }
9569 break;
9570 case RR_SLT:
9571 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
9572 break;
9573 case RR_SLTU:
9574 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
9575 break;
9576 case RR_BREAK:
9577 generate_exception(ctx, EXCP_BREAK);
9578 break;
9579 case RR_SLLV:
9580 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
9581 break;
9582 case RR_SRLV:
9583 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
9584 break;
9585 case RR_SRAV:
9586 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
9587 break;
9588 #if defined (TARGET_MIPS64)
9589 case RR_DSRL:
9590 check_mips_64(ctx);
9591 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
9592 break;
9593 #endif
9594 case RR_CMP:
9595 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
9596 break;
9597 case RR_NEG:
9598 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
9599 break;
9600 case RR_AND:
9601 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
9602 break;
9603 case RR_OR:
9604 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
9605 break;
9606 case RR_XOR:
9607 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
9608 break;
9609 case RR_NOT:
9610 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
9611 break;
9612 case RR_MFHI:
9613 gen_HILO(ctx, OPC_MFHI, rx);
9614 break;
9615 case RR_CNVT:
9616 switch (cnvt_op) {
9617 case RR_RY_CNVT_ZEB:
9618 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9619 break;
9620 case RR_RY_CNVT_ZEH:
9621 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9622 break;
9623 case RR_RY_CNVT_SEB:
9624 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9625 break;
9626 case RR_RY_CNVT_SEH:
9627 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9628 break;
9629 #if defined (TARGET_MIPS64)
9630 case RR_RY_CNVT_ZEW:
9631 check_mips_64(ctx);
9632 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
9633 break;
9634 case RR_RY_CNVT_SEW:
9635 check_mips_64(ctx);
9636 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9637 break;
9638 #endif
9639 default:
9640 generate_exception(ctx, EXCP_RI);
9641 break;
9642 }
9643 break;
9644 case RR_MFLO:
9645 gen_HILO(ctx, OPC_MFLO, rx);
9646 break;
9647 #if defined (TARGET_MIPS64)
9648 case RR_DSRA:
9649 check_mips_64(ctx);
9650 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
9651 break;
9652 case RR_DSLLV:
9653 check_mips_64(ctx);
9654 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
9655 break;
9656 case RR_DSRLV:
9657 check_mips_64(ctx);
9658 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
9659 break;
9660 case RR_DSRAV:
9661 check_mips_64(ctx);
9662 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
9663 break;
9664 #endif
9665 case RR_MULT:
9666 gen_muldiv(ctx, OPC_MULT, rx, ry);
9667 break;
9668 case RR_MULTU:
9669 gen_muldiv(ctx, OPC_MULTU, rx, ry);
9670 break;
9671 case RR_DIV:
9672 gen_muldiv(ctx, OPC_DIV, rx, ry);
9673 break;
9674 case RR_DIVU:
9675 gen_muldiv(ctx, OPC_DIVU, rx, ry);
9676 break;
9677 #if defined (TARGET_MIPS64)
9678 case RR_DMULT:
9679 check_mips_64(ctx);
9680 gen_muldiv(ctx, OPC_DMULT, rx, ry);
9681 break;
9682 case RR_DMULTU:
9683 check_mips_64(ctx);
9684 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
9685 break;
9686 case RR_DDIV:
9687 check_mips_64(ctx);
9688 gen_muldiv(ctx, OPC_DDIV, rx, ry);
9689 break;
9690 case RR_DDIVU:
9691 check_mips_64(ctx);
9692 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
9693 break;
9694 #endif
9695 default:
9696 generate_exception(ctx, EXCP_RI);
9697 break;
9698 }
9699 break;
9700 case M16_OPC_EXTEND:
9701 decode_extended_mips16_opc(env, ctx, is_branch);
9702 n_bytes = 4;
9703 break;
9704 #if defined(TARGET_MIPS64)
9705 case M16_OPC_I64:
9706 funct = (ctx->opcode >> 8) & 0x7;
9707 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
9708 break;
9709 #endif
9710 default:
9711 generate_exception(ctx, EXCP_RI);
9712 break;
9713 }
9714
9715 return n_bytes;
9716 }
9717
9718 /* microMIPS extension to MIPS32 */
9719
9720 /* microMIPS32 major opcodes */
9721
9722 enum {
9723 POOL32A = 0x00,
9724 POOL16A = 0x01,
9725 LBU16 = 0x02,
9726 MOVE16 = 0x03,
9727 ADDI32 = 0x04,
9728 LBU32 = 0x05,
9729 SB32 = 0x06,
9730 LB32 = 0x07,
9731
9732 POOL32B = 0x08,
9733 POOL16B = 0x09,
9734 LHU16 = 0x0a,
9735 ANDI16 = 0x0b,
9736 ADDIU32 = 0x0c,
9737 LHU32 = 0x0d,
9738 SH32 = 0x0e,
9739 LH32 = 0x0f,
9740
9741 POOL32I = 0x10,
9742 POOL16C = 0x11,
9743 LWSP16 = 0x12,
9744 POOL16D = 0x13,
9745 ORI32 = 0x14,
9746 POOL32F = 0x15,
9747 POOL32S = 0x16,
9748 DADDIU32 = 0x17,
9749
9750 POOL32C = 0x18,
9751 LWGP16 = 0x19,
9752 LW16 = 0x1a,
9753 POOL16E = 0x1b,
9754 XORI32 = 0x1c,
9755 JALS32 = 0x1d,
9756 ADDIUPC = 0x1e,
9757 POOL48A = 0x1f,
9758
9759 /* 0x20 is reserved */
9760 RES_20 = 0x20,
9761 POOL16F = 0x21,
9762 SB16 = 0x22,
9763 BEQZ16 = 0x23,
9764 SLTI32 = 0x24,
9765 BEQ32 = 0x25,
9766 SWC132 = 0x26,
9767 LWC132 = 0x27,
9768
9769 /* 0x28 and 0x29 are reserved */
9770 RES_28 = 0x28,
9771 RES_29 = 0x29,
9772 SH16 = 0x2a,
9773 BNEZ16 = 0x2b,
9774 SLTIU32 = 0x2c,
9775 BNE32 = 0x2d,
9776 SDC132 = 0x2e,
9777 LDC132 = 0x2f,
9778
9779 /* 0x30 and 0x31 are reserved */
9780 RES_30 = 0x30,
9781 RES_31 = 0x31,
9782 SWSP16 = 0x32,
9783 B16 = 0x33,
9784 ANDI32 = 0x34,
9785 J32 = 0x35,
9786 SD32 = 0x36,
9787 LD32 = 0x37,
9788
9789 /* 0x38 and 0x39 are reserved */
9790 RES_38 = 0x38,
9791 RES_39 = 0x39,
9792 SW16 = 0x3a,
9793 LI16 = 0x3b,
9794 JALX32 = 0x3c,
9795 JAL32 = 0x3d,
9796 SW32 = 0x3e,
9797 LW32 = 0x3f
9798 };
9799
9800 /* POOL32A encoding of minor opcode field */
9801
9802 enum {
9803 /* These opcodes are distinguished only by bits 9..6; those bits are
9804 * what are recorded below. */
9805 SLL32 = 0x0,
9806 SRL32 = 0x1,
9807 SRA = 0x2,
9808 ROTR = 0x3,
9809
9810 SLLV = 0x0,
9811 SRLV = 0x1,
9812 SRAV = 0x2,
9813 ROTRV = 0x3,
9814 ADD = 0x4,
9815 ADDU32 = 0x5,
9816 SUB = 0x6,
9817 SUBU32 = 0x7,
9818 MUL = 0x8,
9819 AND = 0x9,
9820 OR32 = 0xa,
9821 NOR = 0xb,
9822 XOR32 = 0xc,
9823 SLT = 0xd,
9824 SLTU = 0xe,
9825
9826 MOVN = 0x0,
9827 MOVZ = 0x1,
9828 LWXS = 0x4,
9829
9830 /* The following can be distinguished by their lower 6 bits. */
9831 INS = 0x0c,
9832 EXT = 0x2c,
9833 POOL32AXF = 0x3c
9834 };
9835
9836 /* POOL32AXF encoding of minor opcode field extension */
9837
9838 enum {
9839 /* bits 11..6 */
9840 TEQ = 0x00,
9841 TGE = 0x08,
9842 TGEU = 0x10,
9843 TLT = 0x20,
9844 TLTU = 0x28,
9845 TNE = 0x30,
9846
9847 MFC0 = 0x03,
9848 MTC0 = 0x0b,
9849
9850 /* bits 13..12 for 0x01 */
9851 MFHI_ACC = 0x0,
9852 MFLO_ACC = 0x1,
9853 MTHI_ACC = 0x2,
9854 MTLO_ACC = 0x3,
9855
9856 /* bits 13..12 for 0x2a */
9857 MADD_ACC = 0x0,
9858 MADDU_ACC = 0x1,
9859 MSUB_ACC = 0x2,
9860 MSUBU_ACC = 0x3,
9861
9862 /* bits 13..12 for 0x32 */
9863 MULT_ACC = 0x0,
9864 MULTU_ACC = 0x0,
9865
9866 /* bits 15..12 for 0x2c */
9867 SEB = 0x2,
9868 SEH = 0x3,
9869 CLO = 0x4,
9870 CLZ = 0x5,
9871 RDHWR = 0x6,
9872 WSBH = 0x7,
9873 MULT = 0x8,
9874 MULTU = 0x9,
9875 DIV = 0xa,
9876 DIVU = 0xb,
9877 MADD = 0xc,
9878 MADDU = 0xd,
9879 MSUB = 0xe,
9880 MSUBU = 0xf,
9881
9882 /* bits 15..12 for 0x34 */
9883 MFC2 = 0x4,
9884 MTC2 = 0x5,
9885 MFHC2 = 0x8,
9886 MTHC2 = 0x9,
9887 CFC2 = 0xc,
9888 CTC2 = 0xd,
9889
9890 /* bits 15..12 for 0x3c */
9891 JALR = 0x0,
9892 JR = 0x0, /* alias */
9893 JALR_HB = 0x1,
9894 JALRS = 0x4,
9895 JALRS_HB = 0x5,
9896
9897 /* bits 15..12 for 0x05 */
9898 RDPGPR = 0xe,
9899 WRPGPR = 0xf,
9900
9901 /* bits 15..12 for 0x0d */
9902 TLBP = 0x0,
9903 TLBR = 0x1,
9904 TLBWI = 0x2,
9905 TLBWR = 0x3,
9906 WAIT = 0x9,
9907 IRET = 0xd,
9908 DERET = 0xe,
9909 ERET = 0xf,
9910
9911 /* bits 15..12 for 0x15 */
9912 DMT = 0x0,
9913 DVPE = 0x1,
9914 EMT = 0x2,
9915 EVPE = 0x3,
9916
9917 /* bits 15..12 for 0x1d */
9918 DI = 0x4,
9919 EI = 0x5,
9920
9921 /* bits 15..12 for 0x2d */
9922 SYNC = 0x6,
9923 SYSCALL = 0x8,
9924 SDBBP = 0xd,
9925
9926 /* bits 15..12 for 0x35 */
9927 MFHI32 = 0x0,
9928 MFLO32 = 0x1,
9929 MTHI32 = 0x2,
9930 MTLO32 = 0x3,
9931 };
9932
9933 /* POOL32B encoding of minor opcode field (bits 15..12) */
9934
9935 enum {
9936 LWC2 = 0x0,
9937 LWP = 0x1,
9938 LDP = 0x4,
9939 LWM32 = 0x5,
9940 CACHE = 0x6,
9941 LDM = 0x7,
9942 SWC2 = 0x8,
9943 SWP = 0x9,
9944 SDP = 0xc,
9945 SWM32 = 0xd,
9946 SDM = 0xf
9947 };
9948
9949 /* POOL32C encoding of minor opcode field (bits 15..12) */
9950
9951 enum {
9952 LWL = 0x0,
9953 SWL = 0x8,
9954 LWR = 0x1,
9955 SWR = 0x9,
9956 PREF = 0x2,
9957 /* 0xa is reserved */
9958 LL = 0x3,
9959 SC = 0xb,
9960 LDL = 0x4,
9961 SDL = 0xc,
9962 LDR = 0x5,
9963 SDR = 0xd,
9964 /* 0x6 is reserved */
9965 LWU = 0xe,
9966 LLD = 0x7,
9967 SCD = 0xf
9968 };
9969
9970 /* POOL32F encoding of minor opcode field (bits 5..0) */
9971
9972 enum {
9973 /* These are the bit 7..6 values */
9974 ADD_FMT = 0x0,
9975 MOVN_FMT = 0x0,
9976
9977 SUB_FMT = 0x1,
9978 MOVZ_FMT = 0x1,
9979
9980 MUL_FMT = 0x2,
9981
9982 DIV_FMT = 0x3,
9983
9984 /* These are the bit 8..6 values */
9985 RSQRT2_FMT = 0x0,
9986 MOVF_FMT = 0x0,
9987
9988 LWXC1 = 0x1,
9989 MOVT_FMT = 0x1,
9990
9991 PLL_PS = 0x2,
9992 SWXC1 = 0x2,
9993
9994 PLU_PS = 0x3,
9995 LDXC1 = 0x3,
9996
9997 PUL_PS = 0x4,
9998 SDXC1 = 0x4,
9999 RECIP2_FMT = 0x4,
10000
10001 PUU_PS = 0x5,
10002 LUXC1 = 0x5,
10003
10004 CVT_PS_S = 0x6,
10005 SUXC1 = 0x6,
10006 ADDR_PS = 0x6,
10007 PREFX = 0x6,
10008
10009 MULR_PS = 0x7,
10010
10011 MADD_S = 0x01,
10012 MADD_D = 0x09,
10013 MADD_PS = 0x11,
10014 ALNV_PS = 0x19,
10015 MSUB_S = 0x21,
10016 MSUB_D = 0x29,
10017 MSUB_PS = 0x31,
10018
10019 NMADD_S = 0x02,
10020 NMADD_D = 0x0a,
10021 NMADD_PS = 0x12,
10022 NMSUB_S = 0x22,
10023 NMSUB_D = 0x2a,
10024 NMSUB_PS = 0x32,
10025
10026 POOL32FXF = 0x3b,
10027
10028 CABS_COND_FMT = 0x1c, /* MIPS3D */
10029 C_COND_FMT = 0x3c
10030 };
10031
10032 /* POOL32Fxf encoding of minor opcode extension field */
10033
10034 enum {
10035 CVT_L = 0x04,
10036 RSQRT_FMT = 0x08,
10037 FLOOR_L = 0x0c,
10038 CVT_PW_PS = 0x1c,
10039 CVT_W = 0x24,
10040 SQRT_FMT = 0x28,
10041 FLOOR_W = 0x2c,
10042 CVT_PS_PW = 0x3c,
10043 CFC1 = 0x40,
10044 RECIP_FMT = 0x48,
10045 CEIL_L = 0x4c,
10046 CTC1 = 0x60,
10047 CEIL_W = 0x6c,
10048 MFC1 = 0x80,
10049 CVT_S_PL = 0x84,
10050 TRUNC_L = 0x8c,
10051 MTC1 = 0xa0,
10052 CVT_S_PU = 0xa4,
10053 TRUNC_W = 0xac,
10054 MFHC1 = 0xc0,
10055 ROUND_L = 0xcc,
10056 MTHC1 = 0xe0,
10057 ROUND_W = 0xec,
10058
10059 MOV_FMT = 0x01,
10060 MOVF = 0x05,
10061 ABS_FMT = 0x0d,
10062 RSQRT1_FMT = 0x1d,
10063 MOVT = 0x25,
10064 NEG_FMT = 0x2d,
10065 CVT_D = 0x4d,
10066 RECIP1_FMT = 0x5d,
10067 CVT_S = 0x6d
10068 };
10069
10070 /* POOL32I encoding of minor opcode field (bits 25..21) */
10071
10072 enum {
10073 BLTZ = 0x00,
10074 BLTZAL = 0x01,
10075 BGEZ = 0x02,
10076 BGEZAL = 0x03,
10077 BLEZ = 0x04,
10078 BNEZC = 0x05,
10079 BGTZ = 0x06,
10080 BEQZC = 0x07,
10081 TLTI = 0x08,
10082 TGEI = 0x09,
10083 TLTIU = 0x0a,
10084 TGEIU = 0x0b,
10085 TNEI = 0x0c,
10086 LUI = 0x0d,
10087 TEQI = 0x0e,
10088 SYNCI = 0x10,
10089 BLTZALS = 0x11,
10090 BGEZALS = 0x13,
10091 BC2F = 0x14,
10092 BC2T = 0x15,
10093 BPOSGE64 = 0x1a,
10094 BPOSGE32 = 0x1b,
10095 /* These overlap and are distinguished by bit16 of the instruction */
10096 BC1F = 0x1c,
10097 BC1T = 0x1d,
10098 BC1ANY2F = 0x1c,
10099 BC1ANY2T = 0x1d,
10100 BC1ANY4F = 0x1e,
10101 BC1ANY4T = 0x1f
10102 };
10103
10104 /* POOL16A encoding of minor opcode field */
10105
10106 enum {
10107 ADDU16 = 0x0,
10108 SUBU16 = 0x1
10109 };
10110
10111 /* POOL16B encoding of minor opcode field */
10112
10113 enum {
10114 SLL16 = 0x0,
10115 SRL16 = 0x1
10116 };
10117
10118 /* POOL16C encoding of minor opcode field */
10119
10120 enum {
10121 NOT16 = 0x00,
10122 XOR16 = 0x04,
10123 AND16 = 0x08,
10124 OR16 = 0x0c,
10125 LWM16 = 0x10,
10126 SWM16 = 0x14,
10127 JR16 = 0x18,
10128 JRC16 = 0x1a,
10129 JALR16 = 0x1c,
10130 JALR16S = 0x1e,
10131 MFHI16 = 0x20,
10132 MFLO16 = 0x24,
10133 BREAK16 = 0x28,
10134 SDBBP16 = 0x2c,
10135 JRADDIUSP = 0x30
10136 };
10137
10138 /* POOL16D encoding of minor opcode field */
10139
10140 enum {
10141 ADDIUS5 = 0x0,
10142 ADDIUSP = 0x1
10143 };
10144
10145 /* POOL16E encoding of minor opcode field */
10146
10147 enum {
10148 ADDIUR2 = 0x0,
10149 ADDIUR1SP = 0x1
10150 };
10151
10152 static int mmreg (int r)
10153 {
10154 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10155
10156 return map[r];
10157 }
10158
10159 /* Used for 16-bit store instructions. */
10160 static int mmreg2 (int r)
10161 {
10162 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10163
10164 return map[r];
10165 }
10166
10167 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10168 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10169 #define uMIPS_RS2(op) uMIPS_RS(op)
10170 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10171 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10172 #define uMIPS_RS5(op) (op & 0x1f)
10173
10174 /* Signed immediate */
10175 #define SIMM(op, start, width) \
10176 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10177 << (32-width)) \
10178 >> (32-width))
10179 /* Zero-extended immediate */
10180 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10181
10182 static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
10183 {
10184 int rd = mmreg(uMIPS_RD(ctx->opcode));
10185
10186 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10187 }
10188
10189 static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
10190 {
10191 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10192 int rd = mmreg(uMIPS_RD(ctx->opcode));
10193 int rs = mmreg(uMIPS_RS(ctx->opcode));
10194
10195 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10196 }
10197
10198 static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
10199 {
10200 int encoded = ZIMM(ctx->opcode, 1, 9);
10201 int decoded;
10202
10203 if (encoded <= 1) {
10204 decoded = 256 + encoded;
10205 } else if (encoded <= 255) {
10206 decoded = encoded;
10207 } else if (encoded <= 509) {
10208 decoded = encoded - 512;
10209 } else {
10210 decoded = encoded - 768;
10211 }
10212
10213 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10214 }
10215
10216 static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
10217 {
10218 int imm = SIMM(ctx->opcode, 1, 4);
10219 int rd = (ctx->opcode >> 5) & 0x1f;
10220
10221 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10222 }
10223
10224 static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
10225 {
10226 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10227 31, 32, 63, 64, 255, 32768, 65535 };
10228 int rd = mmreg(uMIPS_RD(ctx->opcode));
10229 int rs = mmreg(uMIPS_RS(ctx->opcode));
10230 int encoded = ZIMM(ctx->opcode, 0, 4);
10231
10232 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10233 }
10234
10235 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10236 int base, int16_t offset)
10237 {
10238 const char *opn = "ldst_multiple";
10239 TCGv t0, t1;
10240 TCGv_i32 t2;
10241
10242 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10243 generate_exception(ctx, EXCP_RI);
10244 return;
10245 }
10246
10247 t0 = tcg_temp_new();
10248
10249 gen_base_offset_addr(ctx, t0, base, offset);
10250
10251 t1 = tcg_const_tl(reglist);
10252 t2 = tcg_const_i32(ctx->mem_idx);
10253
10254 save_cpu_state(ctx, 1);
10255 switch (opc) {
10256 case LWM32:
10257 gen_helper_lwm(cpu_env, t0, t1, t2);
10258 opn = "lwm";
10259 break;
10260 case SWM32:
10261 gen_helper_swm(cpu_env, t0, t1, t2);
10262 opn = "swm";
10263 break;
10264 #ifdef TARGET_MIPS64
10265 case LDM:
10266 gen_helper_ldm(cpu_env, t0, t1, t2);
10267 opn = "ldm";
10268 break;
10269 case SDM:
10270 gen_helper_sdm(cpu_env, t0, t1, t2);
10271 opn = "sdm";
10272 break;
10273 #endif
10274 }
10275 (void)opn;
10276 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10277 tcg_temp_free(t0);
10278 tcg_temp_free(t1);
10279 tcg_temp_free_i32(t2);
10280 }
10281
10282
10283 static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
10284 {
10285 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10286 int rs = mmreg(ctx->opcode & 0x7);
10287 int opc;
10288
10289 switch (((ctx->opcode) >> 4) & 0x3f) {
10290 case NOT16 + 0:
10291 case NOT16 + 1:
10292 case NOT16 + 2:
10293 case NOT16 + 3:
10294 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
10295 break;
10296 case XOR16 + 0:
10297 case XOR16 + 1:
10298 case XOR16 + 2:
10299 case XOR16 + 3:
10300 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
10301 break;
10302 case AND16 + 0:
10303 case AND16 + 1:
10304 case AND16 + 2:
10305 case AND16 + 3:
10306 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
10307 break;
10308 case OR16 + 0:
10309 case OR16 + 1:
10310 case OR16 + 2:
10311 case OR16 + 3:
10312 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
10313 break;
10314 case LWM16 + 0:
10315 case LWM16 + 1:
10316 case LWM16 + 2:
10317 case LWM16 + 3:
10318 {
10319 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10320 int offset = ZIMM(ctx->opcode, 0, 4);
10321
10322 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10323 29, offset << 2);
10324 }
10325 break;
10326 case SWM16 + 0:
10327 case SWM16 + 1:
10328 case SWM16 + 2:
10329 case SWM16 + 3:
10330 {
10331 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10332 int offset = ZIMM(ctx->opcode, 0, 4);
10333
10334 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10335 29, offset << 2);
10336 }
10337 break;
10338 case JR16 + 0:
10339 case JR16 + 1:
10340 {
10341 int reg = ctx->opcode & 0x1f;
10342
10343 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10344 }
10345 *is_branch = 1;
10346 break;
10347 case JRC16 + 0:
10348 case JRC16 + 1:
10349 {
10350 int reg = ctx->opcode & 0x1f;
10351
10352 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10353 /* Let normal delay slot handling in our caller take us
10354 to the branch target. */
10355 }
10356 break;
10357 case JALR16 + 0:
10358 case JALR16 + 1:
10359 opc = OPC_JALR;
10360 goto do_jalr;
10361 case JALR16S + 0:
10362 case JALR16S + 1:
10363 opc = OPC_JALRS;
10364 do_jalr:
10365 {
10366 int reg = ctx->opcode & 0x1f;
10367
10368 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10369 }
10370 *is_branch = 1;
10371 break;
10372 case MFHI16 + 0:
10373 case MFHI16 + 1:
10374 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10375 break;
10376 case MFLO16 + 0:
10377 case MFLO16 + 1:
10378 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10379 break;
10380 case BREAK16:
10381 generate_exception(ctx, EXCP_BREAK);
10382 break;
10383 case SDBBP16:
10384 /* XXX: not clear which exception should be raised
10385 * when in debug mode...
10386 */
10387 check_insn(env, ctx, ISA_MIPS32);
10388 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10389 generate_exception(ctx, EXCP_DBp);
10390 } else {
10391 generate_exception(ctx, EXCP_DBp);
10392 }
10393 break;
10394 case JRADDIUSP + 0:
10395 case JRADDIUSP + 1:
10396 {
10397 int imm = ZIMM(ctx->opcode, 0, 5);
10398
10399 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10400 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10401 /* Let normal delay slot handling in our caller take us
10402 to the branch target. */
10403 }
10404 break;
10405 default:
10406 generate_exception(ctx, EXCP_RI);
10407 break;
10408 }
10409 }
10410
10411 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10412 {
10413 TCGv t0 = tcg_temp_new();
10414 TCGv t1 = tcg_temp_new();
10415
10416 gen_load_gpr(t0, base);
10417
10418 if (index != 0) {
10419 gen_load_gpr(t1, index);
10420 tcg_gen_shli_tl(t1, t1, 2);
10421 gen_op_addr_add(ctx, t0, t1, t0);
10422 }
10423
10424 save_cpu_state(ctx, 0);
10425 op_ld_lw(t1, t0, ctx);
10426 gen_store_gpr(t1, rd);
10427
10428 tcg_temp_free(t0);
10429 tcg_temp_free(t1);
10430 }
10431
10432 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10433 int base, int16_t offset)
10434 {
10435 const char *opn = "ldst_pair";
10436 TCGv t0, t1;
10437
10438 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10439 generate_exception(ctx, EXCP_RI);
10440 return;
10441 }
10442
10443 t0 = tcg_temp_new();
10444 t1 = tcg_temp_new();
10445
10446 gen_base_offset_addr(ctx, t0, base, offset);
10447
10448 switch (opc) {
10449 case LWP:
10450 if (rd == base) {
10451 generate_exception(ctx, EXCP_RI);
10452 return;
10453 }
10454 save_cpu_state(ctx, 0);
10455 op_ld_lw(t1, t0, ctx);
10456 gen_store_gpr(t1, rd);
10457 tcg_gen_movi_tl(t1, 4);
10458 gen_op_addr_add(ctx, t0, t0, t1);
10459 op_ld_lw(t1, t0, ctx);
10460 gen_store_gpr(t1, rd+1);
10461 opn = "lwp";
10462 break;
10463 case SWP:
10464 save_cpu_state(ctx, 0);
10465 gen_load_gpr(t1, rd);
10466 op_st_sw(t1, t0, ctx);
10467 tcg_gen_movi_tl(t1, 4);
10468 gen_op_addr_add(ctx, t0, t0, t1);
10469 gen_load_gpr(t1, rd+1);
10470 op_st_sw(t1, t0, ctx);
10471 opn = "swp";
10472 break;
10473 #ifdef TARGET_MIPS64
10474 case LDP:
10475 if (rd == base) {
10476 generate_exception(ctx, EXCP_RI);
10477 return;
10478 }
10479 save_cpu_state(ctx, 0);
10480 op_ld_ld(t1, t0, ctx);
10481 gen_store_gpr(t1, rd);
10482 tcg_gen_movi_tl(t1, 8);
10483 gen_op_addr_add(ctx, t0, t0, t1);
10484 op_ld_ld(t1, t0, ctx);
10485 gen_store_gpr(t1, rd+1);
10486 opn = "ldp";
10487 break;
10488 case SDP:
10489 save_cpu_state(ctx, 0);
10490 gen_load_gpr(t1, rd);
10491 op_st_sd(t1, t0, ctx);
10492 tcg_gen_movi_tl(t1, 8);
10493 gen_op_addr_add(ctx, t0, t0, t1);
10494 gen_load_gpr(t1, rd+1);
10495 op_st_sd(t1, t0, ctx);
10496 opn = "sdp";
10497 break;
10498 #endif
10499 }
10500 (void)opn; /* avoid a compiler warning */
10501 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
10502 tcg_temp_free(t0);
10503 tcg_temp_free(t1);
10504 }
10505
10506 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
10507 int *is_branch)
10508 {
10509 int extension = (ctx->opcode >> 6) & 0x3f;
10510 int minor = (ctx->opcode >> 12) & 0xf;
10511 uint32_t mips32_op;
10512
10513 switch (extension) {
10514 case TEQ:
10515 mips32_op = OPC_TEQ;
10516 goto do_trap;
10517 case TGE:
10518 mips32_op = OPC_TGE;
10519 goto do_trap;
10520 case TGEU:
10521 mips32_op = OPC_TGEU;
10522 goto do_trap;
10523 case TLT:
10524 mips32_op = OPC_TLT;
10525 goto do_trap;
10526 case TLTU:
10527 mips32_op = OPC_TLTU;
10528 goto do_trap;
10529 case TNE:
10530 mips32_op = OPC_TNE;
10531 do_trap:
10532 gen_trap(ctx, mips32_op, rs, rt, -1);
10533 break;
10534 #ifndef CONFIG_USER_ONLY
10535 case MFC0:
10536 case MFC0 + 32:
10537 check_cp0_enabled(ctx);
10538 if (rt == 0) {
10539 /* Treat as NOP. */
10540 break;
10541 }
10542 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
10543 break;
10544 case MTC0:
10545 case MTC0 + 32:
10546 check_cp0_enabled(ctx);
10547 {
10548 TCGv t0 = tcg_temp_new();
10549
10550 gen_load_gpr(t0, rt);
10551 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
10552 tcg_temp_free(t0);
10553 }
10554 break;
10555 #endif
10556 case 0x2c:
10557 switch (minor) {
10558 case SEB:
10559 gen_bshfl(ctx, OPC_SEB, rs, rt);
10560 break;
10561 case SEH:
10562 gen_bshfl(ctx, OPC_SEH, rs, rt);
10563 break;
10564 case CLO:
10565 mips32_op = OPC_CLO;
10566 goto do_cl;
10567 case CLZ:
10568 mips32_op = OPC_CLZ;
10569 do_cl:
10570 check_insn(env, ctx, ISA_MIPS32);
10571 gen_cl(ctx, mips32_op, rt, rs);
10572 break;
10573 case RDHWR:
10574 gen_rdhwr(env, ctx, rt, rs);
10575 break;
10576 case WSBH:
10577 gen_bshfl(ctx, OPC_WSBH, rs, rt);
10578 break;
10579 case MULT:
10580 mips32_op = OPC_MULT;
10581 goto do_muldiv;
10582 case MULTU:
10583 mips32_op = OPC_MULTU;
10584 goto do_muldiv;
10585 case DIV:
10586 mips32_op = OPC_DIV;
10587 goto do_muldiv;
10588 case DIVU:
10589 mips32_op = OPC_DIVU;
10590 goto do_muldiv;
10591 case MADD:
10592 mips32_op = OPC_MADD;
10593 goto do_muldiv;
10594 case MADDU:
10595 mips32_op = OPC_MADDU;
10596 goto do_muldiv;
10597 case MSUB:
10598 mips32_op = OPC_MSUB;
10599 goto do_muldiv;
10600 case MSUBU:
10601 mips32_op = OPC_MSUBU;
10602 do_muldiv:
10603 check_insn(env, ctx, ISA_MIPS32);
10604 gen_muldiv(ctx, mips32_op, rs, rt);
10605 break;
10606 default:
10607 goto pool32axf_invalid;
10608 }
10609 break;
10610 case 0x34:
10611 switch (minor) {
10612 case MFC2:
10613 case MTC2:
10614 case MFHC2:
10615 case MTHC2:
10616 case CFC2:
10617 case CTC2:
10618 generate_exception_err(ctx, EXCP_CpU, 2);
10619 break;
10620 default:
10621 goto pool32axf_invalid;
10622 }
10623 break;
10624 case 0x3c:
10625 switch (minor) {
10626 case JALR:
10627 case JALR_HB:
10628 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
10629 *is_branch = 1;
10630 break;
10631 case JALRS:
10632 case JALRS_HB:
10633 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
10634 *is_branch = 1;
10635 break;
10636 default:
10637 goto pool32axf_invalid;
10638 }
10639 break;
10640 case 0x05:
10641 switch (minor) {
10642 case RDPGPR:
10643 check_cp0_enabled(ctx);
10644 check_insn(env, ctx, ISA_MIPS32R2);
10645 gen_load_srsgpr(rt, rs);
10646 break;
10647 case WRPGPR:
10648 check_cp0_enabled(ctx);
10649 check_insn(env, ctx, ISA_MIPS32R2);
10650 gen_store_srsgpr(rt, rs);
10651 break;
10652 default:
10653 goto pool32axf_invalid;
10654 }
10655 break;
10656 #ifndef CONFIG_USER_ONLY
10657 case 0x0d:
10658 switch (minor) {
10659 case TLBP:
10660 mips32_op = OPC_TLBP;
10661 goto do_cp0;
10662 case TLBR:
10663 mips32_op = OPC_TLBR;
10664 goto do_cp0;
10665 case TLBWI:
10666 mips32_op = OPC_TLBWI;
10667 goto do_cp0;
10668 case TLBWR:
10669 mips32_op = OPC_TLBWR;
10670 goto do_cp0;
10671 case WAIT:
10672 mips32_op = OPC_WAIT;
10673 goto do_cp0;
10674 case DERET:
10675 mips32_op = OPC_DERET;
10676 goto do_cp0;
10677 case ERET:
10678 mips32_op = OPC_ERET;
10679 do_cp0:
10680 gen_cp0(env, ctx, mips32_op, rt, rs);
10681 break;
10682 default:
10683 goto pool32axf_invalid;
10684 }
10685 break;
10686 case 0x1d:
10687 switch (minor) {
10688 case DI:
10689 check_cp0_enabled(ctx);
10690 {
10691 TCGv t0 = tcg_temp_new();
10692
10693 save_cpu_state(ctx, 1);
10694 gen_helper_di(t0, cpu_env);
10695 gen_store_gpr(t0, rs);
10696 /* Stop translation as we may have switched the execution mode */
10697 ctx->bstate = BS_STOP;
10698 tcg_temp_free(t0);
10699 }
10700 break;
10701 case EI:
10702 check_cp0_enabled(ctx);
10703 {
10704 TCGv t0 = tcg_temp_new();
10705
10706 save_cpu_state(ctx, 1);
10707 gen_helper_ei(t0, cpu_env);
10708 gen_store_gpr(t0, rs);
10709 /* Stop translation as we may have switched the execution mode */
10710 ctx->bstate = BS_STOP;
10711 tcg_temp_free(t0);
10712 }
10713 break;
10714 default:
10715 goto pool32axf_invalid;
10716 }
10717 break;
10718 #endif
10719 case 0x2d:
10720 switch (minor) {
10721 case SYNC:
10722 /* NOP */
10723 break;
10724 case SYSCALL:
10725 generate_exception(ctx, EXCP_SYSCALL);
10726 ctx->bstate = BS_STOP;
10727 break;
10728 case SDBBP:
10729 check_insn(env, ctx, ISA_MIPS32);
10730 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10731 generate_exception(ctx, EXCP_DBp);
10732 } else {
10733 generate_exception(ctx, EXCP_DBp);
10734 }
10735 break;
10736 default:
10737 goto pool32axf_invalid;
10738 }
10739 break;
10740 case 0x35:
10741 switch (minor) {
10742 case MFHI32:
10743 gen_HILO(ctx, OPC_MFHI, rs);
10744 break;
10745 case MFLO32:
10746 gen_HILO(ctx, OPC_MFLO, rs);
10747 break;
10748 case MTHI32:
10749 gen_HILO(ctx, OPC_MTHI, rs);
10750 break;
10751 case MTLO32:
10752 gen_HILO(ctx, OPC_MTLO, rs);
10753 break;
10754 default:
10755 goto pool32axf_invalid;
10756 }
10757 break;
10758 default:
10759 pool32axf_invalid:
10760 MIPS_INVAL("pool32axf");
10761 generate_exception(ctx, EXCP_RI);
10762 break;
10763 }
10764 }
10765
10766 /* Values for microMIPS fmt field. Variable-width, depending on which
10767 formats the instruction supports. */
10768
10769 enum {
10770 FMT_SD_S = 0,
10771 FMT_SD_D = 1,
10772
10773 FMT_SDPS_S = 0,
10774 FMT_SDPS_D = 1,
10775 FMT_SDPS_PS = 2,
10776
10777 FMT_SWL_S = 0,
10778 FMT_SWL_W = 1,
10779 FMT_SWL_L = 2,
10780
10781 FMT_DWL_D = 0,
10782 FMT_DWL_W = 1,
10783 FMT_DWL_L = 2
10784 };
10785
10786 static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
10787 {
10788 int extension = (ctx->opcode >> 6) & 0x3ff;
10789 uint32_t mips32_op;
10790
10791 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
10792 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
10793 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
10794
10795 switch (extension) {
10796 case FLOAT_1BIT_FMT(CFC1, 0):
10797 mips32_op = OPC_CFC1;
10798 goto do_cp1;
10799 case FLOAT_1BIT_FMT(CTC1, 0):
10800 mips32_op = OPC_CTC1;
10801 goto do_cp1;
10802 case FLOAT_1BIT_FMT(MFC1, 0):
10803 mips32_op = OPC_MFC1;
10804 goto do_cp1;
10805 case FLOAT_1BIT_FMT(MTC1, 0):
10806 mips32_op = OPC_MTC1;
10807 goto do_cp1;
10808 case FLOAT_1BIT_FMT(MFHC1, 0):
10809 mips32_op = OPC_MFHC1;
10810 goto do_cp1;
10811 case FLOAT_1BIT_FMT(MTHC1, 0):
10812 mips32_op = OPC_MTHC1;
10813 do_cp1:
10814 gen_cp1(ctx, mips32_op, rt, rs);
10815 break;
10816
10817 /* Reciprocal square root */
10818 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
10819 mips32_op = OPC_RSQRT_S;
10820 goto do_unaryfp;
10821 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
10822 mips32_op = OPC_RSQRT_D;
10823 goto do_unaryfp;
10824
10825 /* Square root */
10826 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
10827 mips32_op = OPC_SQRT_S;
10828 goto do_unaryfp;
10829 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
10830 mips32_op = OPC_SQRT_D;
10831 goto do_unaryfp;
10832
10833 /* Reciprocal */
10834 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
10835 mips32_op = OPC_RECIP_S;
10836 goto do_unaryfp;
10837 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
10838 mips32_op = OPC_RECIP_D;
10839 goto do_unaryfp;
10840
10841 /* Floor */
10842 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
10843 mips32_op = OPC_FLOOR_L_S;
10844 goto do_unaryfp;
10845 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
10846 mips32_op = OPC_FLOOR_L_D;
10847 goto do_unaryfp;
10848 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
10849 mips32_op = OPC_FLOOR_W_S;
10850 goto do_unaryfp;
10851 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
10852 mips32_op = OPC_FLOOR_W_D;
10853 goto do_unaryfp;
10854
10855 /* Ceiling */
10856 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
10857 mips32_op = OPC_CEIL_L_S;
10858 goto do_unaryfp;
10859 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
10860 mips32_op = OPC_CEIL_L_D;
10861 goto do_unaryfp;
10862 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
10863 mips32_op = OPC_CEIL_W_S;
10864 goto do_unaryfp;
10865 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
10866 mips32_op = OPC_CEIL_W_D;
10867 goto do_unaryfp;
10868
10869 /* Truncation */
10870 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
10871 mips32_op = OPC_TRUNC_L_S;
10872 goto do_unaryfp;
10873 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
10874 mips32_op = OPC_TRUNC_L_D;
10875 goto do_unaryfp;
10876 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
10877 mips32_op = OPC_TRUNC_W_S;
10878 goto do_unaryfp;
10879 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
10880 mips32_op = OPC_TRUNC_W_D;
10881 goto do_unaryfp;
10882
10883 /* Round */
10884 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
10885 mips32_op = OPC_ROUND_L_S;
10886 goto do_unaryfp;
10887 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
10888 mips32_op = OPC_ROUND_L_D;
10889 goto do_unaryfp;
10890 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
10891 mips32_op = OPC_ROUND_W_S;
10892 goto do_unaryfp;
10893 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
10894 mips32_op = OPC_ROUND_W_D;
10895 goto do_unaryfp;
10896
10897 /* Integer to floating-point conversion */
10898 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
10899 mips32_op = OPC_CVT_L_S;
10900 goto do_unaryfp;
10901 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
10902 mips32_op = OPC_CVT_L_D;
10903 goto do_unaryfp;
10904 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
10905 mips32_op = OPC_CVT_W_S;
10906 goto do_unaryfp;
10907 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
10908 mips32_op = OPC_CVT_W_D;
10909 goto do_unaryfp;
10910
10911 /* Paired-foo conversions */
10912 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
10913 mips32_op = OPC_CVT_S_PL;
10914 goto do_unaryfp;
10915 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
10916 mips32_op = OPC_CVT_S_PU;
10917 goto do_unaryfp;
10918 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
10919 mips32_op = OPC_CVT_PW_PS;
10920 goto do_unaryfp;
10921 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
10922 mips32_op = OPC_CVT_PS_PW;
10923 goto do_unaryfp;
10924
10925 /* Floating-point moves */
10926 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
10927 mips32_op = OPC_MOV_S;
10928 goto do_unaryfp;
10929 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
10930 mips32_op = OPC_MOV_D;
10931 goto do_unaryfp;
10932 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
10933 mips32_op = OPC_MOV_PS;
10934 goto do_unaryfp;
10935
10936 /* Absolute value */
10937 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
10938 mips32_op = OPC_ABS_S;
10939 goto do_unaryfp;
10940 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
10941 mips32_op = OPC_ABS_D;
10942 goto do_unaryfp;
10943 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
10944 mips32_op = OPC_ABS_PS;
10945 goto do_unaryfp;
10946
10947 /* Negation */
10948 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
10949 mips32_op = OPC_NEG_S;
10950 goto do_unaryfp;
10951 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
10952 mips32_op = OPC_NEG_D;
10953 goto do_unaryfp;
10954 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
10955 mips32_op = OPC_NEG_PS;
10956 goto do_unaryfp;
10957
10958 /* Reciprocal square root step */
10959 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
10960 mips32_op = OPC_RSQRT1_S;
10961 goto do_unaryfp;
10962 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
10963 mips32_op = OPC_RSQRT1_D;
10964 goto do_unaryfp;
10965 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
10966 mips32_op = OPC_RSQRT1_PS;
10967 goto do_unaryfp;
10968
10969 /* Reciprocal step */
10970 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
10971 mips32_op = OPC_RECIP1_S;
10972 goto do_unaryfp;
10973 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
10974 mips32_op = OPC_RECIP1_S;
10975 goto do_unaryfp;
10976 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
10977 mips32_op = OPC_RECIP1_PS;
10978 goto do_unaryfp;
10979
10980 /* Conversions from double */
10981 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
10982 mips32_op = OPC_CVT_D_S;
10983 goto do_unaryfp;
10984 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
10985 mips32_op = OPC_CVT_D_W;
10986 goto do_unaryfp;
10987 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
10988 mips32_op = OPC_CVT_D_L;
10989 goto do_unaryfp;
10990
10991 /* Conversions from single */
10992 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
10993 mips32_op = OPC_CVT_S_D;
10994 goto do_unaryfp;
10995 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
10996 mips32_op = OPC_CVT_S_W;
10997 goto do_unaryfp;
10998 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
10999 mips32_op = OPC_CVT_S_L;
11000 do_unaryfp:
11001 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11002 break;
11003
11004 /* Conditional moves on floating-point codes */
11005 case COND_FLOAT_MOV(MOVT, 0):
11006 case COND_FLOAT_MOV(MOVT, 1):
11007 case COND_FLOAT_MOV(MOVT, 2):
11008 case COND_FLOAT_MOV(MOVT, 3):
11009 case COND_FLOAT_MOV(MOVT, 4):
11010 case COND_FLOAT_MOV(MOVT, 5):
11011 case COND_FLOAT_MOV(MOVT, 6):
11012 case COND_FLOAT_MOV(MOVT, 7):
11013 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11014 break;
11015 case COND_FLOAT_MOV(MOVF, 0):
11016 case COND_FLOAT_MOV(MOVF, 1):
11017 case COND_FLOAT_MOV(MOVF, 2):
11018 case COND_FLOAT_MOV(MOVF, 3):
11019 case COND_FLOAT_MOV(MOVF, 4):
11020 case COND_FLOAT_MOV(MOVF, 5):
11021 case COND_FLOAT_MOV(MOVF, 6):
11022 case COND_FLOAT_MOV(MOVF, 7):
11023 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11024 break;
11025 default:
11026 MIPS_INVAL("pool32fxf");
11027 generate_exception(ctx, EXCP_RI);
11028 break;
11029 }
11030 }
11031
11032 static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11033 uint16_t insn_hw1, int *is_branch)
11034 {
11035 int32_t offset;
11036 uint16_t insn;
11037 int rt, rs, rd, rr;
11038 int16_t imm;
11039 uint32_t op, minor, mips32_op;
11040 uint32_t cond, fmt, cc;
11041
11042 insn = cpu_lduw_code(env, ctx->pc + 2);
11043 ctx->opcode = (ctx->opcode << 16) | insn;
11044
11045 rt = (ctx->opcode >> 21) & 0x1f;
11046 rs = (ctx->opcode >> 16) & 0x1f;
11047 rd = (ctx->opcode >> 11) & 0x1f;
11048 rr = (ctx->opcode >> 6) & 0x1f;
11049 imm = (int16_t) ctx->opcode;
11050
11051 op = (ctx->opcode >> 26) & 0x3f;
11052 switch (op) {
11053 case POOL32A:
11054 minor = ctx->opcode & 0x3f;
11055 switch (minor) {
11056 case 0x00:
11057 minor = (ctx->opcode >> 6) & 0xf;
11058 switch (minor) {
11059 case SLL32:
11060 mips32_op = OPC_SLL;
11061 goto do_shifti;
11062 case SRA:
11063 mips32_op = OPC_SRA;
11064 goto do_shifti;
11065 case SRL32:
11066 mips32_op = OPC_SRL;
11067 goto do_shifti;
11068 case ROTR:
11069 mips32_op = OPC_ROTR;
11070 do_shifti:
11071 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11072 break;
11073 default:
11074 goto pool32a_invalid;
11075 }
11076 break;
11077 case 0x10:
11078 minor = (ctx->opcode >> 6) & 0xf;
11079 switch (minor) {
11080 /* Arithmetic */
11081 case ADD:
11082 mips32_op = OPC_ADD;
11083 goto do_arith;
11084 case ADDU32:
11085 mips32_op = OPC_ADDU;
11086 goto do_arith;
11087 case SUB:
11088 mips32_op = OPC_SUB;
11089 goto do_arith;
11090 case SUBU32:
11091 mips32_op = OPC_SUBU;
11092 goto do_arith;
11093 case MUL:
11094 mips32_op = OPC_MUL;
11095 do_arith:
11096 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11097 break;
11098 /* Shifts */
11099 case SLLV:
11100 mips32_op = OPC_SLLV;
11101 goto do_shift;
11102 case SRLV:
11103 mips32_op = OPC_SRLV;
11104 goto do_shift;
11105 case SRAV:
11106 mips32_op = OPC_SRAV;
11107 goto do_shift;
11108 case ROTRV:
11109 mips32_op = OPC_ROTRV;
11110 do_shift:
11111 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11112 break;
11113 /* Logical operations */
11114 case AND:
11115 mips32_op = OPC_AND;
11116 goto do_logic;
11117 case OR32:
11118 mips32_op = OPC_OR;
11119 goto do_logic;
11120 case NOR:
11121 mips32_op = OPC_NOR;
11122 goto do_logic;
11123 case XOR32:
11124 mips32_op = OPC_XOR;
11125 do_logic:
11126 gen_logic(env, ctx, mips32_op, rd, rs, rt);
11127 break;
11128 /* Set less than */
11129 case SLT:
11130 mips32_op = OPC_SLT;
11131 goto do_slt;
11132 case SLTU:
11133 mips32_op = OPC_SLTU;
11134 do_slt:
11135 gen_slt(env, ctx, mips32_op, rd, rs, rt);
11136 break;
11137 default:
11138 goto pool32a_invalid;
11139 }
11140 break;
11141 case 0x18:
11142 minor = (ctx->opcode >> 6) & 0xf;
11143 switch (minor) {
11144 /* Conditional moves */
11145 case MOVN:
11146 mips32_op = OPC_MOVN;
11147 goto do_cmov;
11148 case MOVZ:
11149 mips32_op = OPC_MOVZ;
11150 do_cmov:
11151 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
11152 break;
11153 case LWXS:
11154 gen_ldxs(ctx, rs, rt, rd);
11155 break;
11156 default:
11157 goto pool32a_invalid;
11158 }
11159 break;
11160 case INS:
11161 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11162 return;
11163 case EXT:
11164 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11165 return;
11166 case POOL32AXF:
11167 gen_pool32axf(env, ctx, rt, rs, is_branch);
11168 break;
11169 case 0x07:
11170 generate_exception(ctx, EXCP_BREAK);
11171 break;
11172 default:
11173 pool32a_invalid:
11174 MIPS_INVAL("pool32a");
11175 generate_exception(ctx, EXCP_RI);
11176 break;
11177 }
11178 break;
11179 case POOL32B:
11180 minor = (ctx->opcode >> 12) & 0xf;
11181 switch (minor) {
11182 case CACHE:
11183 check_cp0_enabled(ctx);
11184 /* Treat as no-op. */
11185 break;
11186 case LWC2:
11187 case SWC2:
11188 /* COP2: Not implemented. */
11189 generate_exception_err(ctx, EXCP_CpU, 2);
11190 break;
11191 case LWP:
11192 case SWP:
11193 #ifdef TARGET_MIPS64
11194 case LDP:
11195 case SDP:
11196 #endif
11197 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11198 break;
11199 case LWM32:
11200 case SWM32:
11201 #ifdef TARGET_MIPS64
11202 case LDM:
11203 case SDM:
11204 #endif
11205 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11206 break;
11207 default:
11208 MIPS_INVAL("pool32b");
11209 generate_exception(ctx, EXCP_RI);
11210 break;
11211 }
11212 break;
11213 case POOL32F:
11214 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11215 minor = ctx->opcode & 0x3f;
11216 check_cp1_enabled(ctx);
11217 switch (minor) {
11218 case ALNV_PS:
11219 mips32_op = OPC_ALNV_PS;
11220 goto do_madd;
11221 case MADD_S:
11222 mips32_op = OPC_MADD_S;
11223 goto do_madd;
11224 case MADD_D:
11225 mips32_op = OPC_MADD_D;
11226 goto do_madd;
11227 case MADD_PS:
11228 mips32_op = OPC_MADD_PS;
11229 goto do_madd;
11230 case MSUB_S:
11231 mips32_op = OPC_MSUB_S;
11232 goto do_madd;
11233 case MSUB_D:
11234 mips32_op = OPC_MSUB_D;
11235 goto do_madd;
11236 case MSUB_PS:
11237 mips32_op = OPC_MSUB_PS;
11238 goto do_madd;
11239 case NMADD_S:
11240 mips32_op = OPC_NMADD_S;
11241 goto do_madd;
11242 case NMADD_D:
11243 mips32_op = OPC_NMADD_D;
11244 goto do_madd;
11245 case NMADD_PS:
11246 mips32_op = OPC_NMADD_PS;
11247 goto do_madd;
11248 case NMSUB_S:
11249 mips32_op = OPC_NMSUB_S;
11250 goto do_madd;
11251 case NMSUB_D:
11252 mips32_op = OPC_NMSUB_D;
11253 goto do_madd;
11254 case NMSUB_PS:
11255 mips32_op = OPC_NMSUB_PS;
11256 do_madd:
11257 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11258 break;
11259 case CABS_COND_FMT:
11260 cond = (ctx->opcode >> 6) & 0xf;
11261 cc = (ctx->opcode >> 13) & 0x7;
11262 fmt = (ctx->opcode >> 10) & 0x3;
11263 switch (fmt) {
11264 case 0x0:
11265 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11266 break;
11267 case 0x1:
11268 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11269 break;
11270 case 0x2:
11271 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11272 break;
11273 default:
11274 goto pool32f_invalid;
11275 }
11276 break;
11277 case C_COND_FMT:
11278 cond = (ctx->opcode >> 6) & 0xf;
11279 cc = (ctx->opcode >> 13) & 0x7;
11280 fmt = (ctx->opcode >> 10) & 0x3;
11281 switch (fmt) {
11282 case 0x0:
11283 gen_cmp_s(ctx, cond, rt, rs, cc);
11284 break;
11285 case 0x1:
11286 gen_cmp_d(ctx, cond, rt, rs, cc);
11287 break;
11288 case 0x2:
11289 gen_cmp_ps(ctx, cond, rt, rs, cc);
11290 break;
11291 default:
11292 goto pool32f_invalid;
11293 }
11294 break;
11295 case POOL32FXF:
11296 gen_pool32fxf(env, ctx, rt, rs);
11297 break;
11298 case 0x00:
11299 /* PLL foo */
11300 switch ((ctx->opcode >> 6) & 0x7) {
11301 case PLL_PS:
11302 mips32_op = OPC_PLL_PS;
11303 goto do_ps;
11304 case PLU_PS:
11305 mips32_op = OPC_PLU_PS;
11306 goto do_ps;
11307 case PUL_PS:
11308 mips32_op = OPC_PUL_PS;
11309 goto do_ps;
11310 case PUU_PS:
11311 mips32_op = OPC_PUU_PS;
11312 goto do_ps;
11313 case CVT_PS_S:
11314 mips32_op = OPC_CVT_PS_S;
11315 do_ps:
11316 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11317 break;
11318 default:
11319 goto pool32f_invalid;
11320 }
11321 break;
11322 case 0x08:
11323 /* [LS][WDU]XC1 */
11324 switch ((ctx->opcode >> 6) & 0x7) {
11325 case LWXC1:
11326 mips32_op = OPC_LWXC1;
11327 goto do_ldst_cp1;
11328 case SWXC1:
11329 mips32_op = OPC_SWXC1;
11330 goto do_ldst_cp1;
11331 case LDXC1:
11332 mips32_op = OPC_LDXC1;
11333 goto do_ldst_cp1;
11334 case SDXC1:
11335 mips32_op = OPC_SDXC1;
11336 goto do_ldst_cp1;
11337 case LUXC1:
11338 mips32_op = OPC_LUXC1;
11339 goto do_ldst_cp1;
11340 case SUXC1:
11341 mips32_op = OPC_SUXC1;
11342 do_ldst_cp1:
11343 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11344 break;
11345 default:
11346 goto pool32f_invalid;
11347 }
11348 break;
11349 case 0x18:
11350 /* 3D insns */
11351 fmt = (ctx->opcode >> 9) & 0x3;
11352 switch ((ctx->opcode >> 6) & 0x7) {
11353 case RSQRT2_FMT:
11354 switch (fmt) {
11355 case FMT_SDPS_S:
11356 mips32_op = OPC_RSQRT2_S;
11357 goto do_3d;
11358 case FMT_SDPS_D:
11359 mips32_op = OPC_RSQRT2_D;
11360 goto do_3d;
11361 case FMT_SDPS_PS:
11362 mips32_op = OPC_RSQRT2_PS;
11363 goto do_3d;
11364 default:
11365 goto pool32f_invalid;
11366 }
11367 break;
11368 case RECIP2_FMT:
11369 switch (fmt) {
11370 case FMT_SDPS_S:
11371 mips32_op = OPC_RECIP2_S;
11372 goto do_3d;
11373 case FMT_SDPS_D:
11374 mips32_op = OPC_RECIP2_D;
11375 goto do_3d;
11376 case FMT_SDPS_PS:
11377 mips32_op = OPC_RECIP2_PS;
11378 goto do_3d;
11379 default:
11380 goto pool32f_invalid;
11381 }
11382 break;
11383 case ADDR_PS:
11384 mips32_op = OPC_ADDR_PS;
11385 goto do_3d;
11386 case MULR_PS:
11387 mips32_op = OPC_MULR_PS;
11388 do_3d:
11389 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11390 break;
11391 default:
11392 goto pool32f_invalid;
11393 }
11394 break;
11395 case 0x20:
11396 /* MOV[FT].fmt and PREFX */
11397 cc = (ctx->opcode >> 13) & 0x7;
11398 fmt = (ctx->opcode >> 9) & 0x3;
11399 switch ((ctx->opcode >> 6) & 0x7) {
11400 case MOVF_FMT:
11401 switch (fmt) {
11402 case FMT_SDPS_S:
11403 gen_movcf_s(rs, rt, cc, 0);
11404 break;
11405 case FMT_SDPS_D:
11406 gen_movcf_d(ctx, rs, rt, cc, 0);
11407 break;
11408 case FMT_SDPS_PS:
11409 gen_movcf_ps(rs, rt, cc, 0);
11410 break;
11411 default:
11412 goto pool32f_invalid;
11413 }
11414 break;
11415 case MOVT_FMT:
11416 switch (fmt) {
11417 case FMT_SDPS_S:
11418 gen_movcf_s(rs, rt, cc, 1);
11419 break;
11420 case FMT_SDPS_D:
11421 gen_movcf_d(ctx, rs, rt, cc, 1);
11422 break;
11423 case FMT_SDPS_PS:
11424 gen_movcf_ps(rs, rt, cc, 1);
11425 break;
11426 default:
11427 goto pool32f_invalid;
11428 }
11429 break;
11430 case PREFX:
11431 break;
11432 default:
11433 goto pool32f_invalid;
11434 }
11435 break;
11436 #define FINSN_3ARG_SDPS(prfx) \
11437 switch ((ctx->opcode >> 8) & 0x3) { \
11438 case FMT_SDPS_S: \
11439 mips32_op = OPC_##prfx##_S; \
11440 goto do_fpop; \
11441 case FMT_SDPS_D: \
11442 mips32_op = OPC_##prfx##_D; \
11443 goto do_fpop; \
11444 case FMT_SDPS_PS: \
11445 mips32_op = OPC_##prfx##_PS; \
11446 goto do_fpop; \
11447 default: \
11448 goto pool32f_invalid; \
11449 }
11450 case 0x30:
11451 /* regular FP ops */
11452 switch ((ctx->opcode >> 6) & 0x3) {
11453 case ADD_FMT:
11454 FINSN_3ARG_SDPS(ADD);
11455 break;
11456 case SUB_FMT:
11457 FINSN_3ARG_SDPS(SUB);
11458 break;
11459 case MUL_FMT:
11460 FINSN_3ARG_SDPS(MUL);
11461 break;
11462 case DIV_FMT:
11463 fmt = (ctx->opcode >> 8) & 0x3;
11464 if (fmt == 1) {
11465 mips32_op = OPC_DIV_D;
11466 } else if (fmt == 0) {
11467 mips32_op = OPC_DIV_S;
11468 } else {
11469 goto pool32f_invalid;
11470 }
11471 goto do_fpop;
11472 default:
11473 goto pool32f_invalid;
11474 }
11475 break;
11476 case 0x38:
11477 /* cmovs */
11478 switch ((ctx->opcode >> 6) & 0x3) {
11479 case MOVN_FMT:
11480 FINSN_3ARG_SDPS(MOVN);
11481 break;
11482 case MOVZ_FMT:
11483 FINSN_3ARG_SDPS(MOVZ);
11484 break;
11485 default:
11486 goto pool32f_invalid;
11487 }
11488 break;
11489 do_fpop:
11490 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11491 break;
11492 default:
11493 pool32f_invalid:
11494 MIPS_INVAL("pool32f");
11495 generate_exception(ctx, EXCP_RI);
11496 break;
11497 }
11498 } else {
11499 generate_exception_err(ctx, EXCP_CpU, 1);
11500 }
11501 break;
11502 case POOL32I:
11503 minor = (ctx->opcode >> 21) & 0x1f;
11504 switch (minor) {
11505 case BLTZ:
11506 mips32_op = OPC_BLTZ;
11507 goto do_branch;
11508 case BLTZAL:
11509 mips32_op = OPC_BLTZAL;
11510 goto do_branch;
11511 case BLTZALS:
11512 mips32_op = OPC_BLTZALS;
11513 goto do_branch;
11514 case BGEZ:
11515 mips32_op = OPC_BGEZ;
11516 goto do_branch;
11517 case BGEZAL:
11518 mips32_op = OPC_BGEZAL;
11519 goto do_branch;
11520 case BGEZALS:
11521 mips32_op = OPC_BGEZALS;
11522 goto do_branch;
11523 case BLEZ:
11524 mips32_op = OPC_BLEZ;
11525 goto do_branch;
11526 case BGTZ:
11527 mips32_op = OPC_BGTZ;
11528 do_branch:
11529 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
11530 *is_branch = 1;
11531 break;
11532
11533 /* Traps */
11534 case TLTI:
11535 mips32_op = OPC_TLTI;
11536 goto do_trapi;
11537 case TGEI:
11538 mips32_op = OPC_TGEI;
11539 goto do_trapi;
11540 case TLTIU:
11541 mips32_op = OPC_TLTIU;
11542 goto do_trapi;
11543 case TGEIU:
11544 mips32_op = OPC_TGEIU;
11545 goto do_trapi;
11546 case TNEI:
11547 mips32_op = OPC_TNEI;
11548 goto do_trapi;
11549 case TEQI:
11550 mips32_op = OPC_TEQI;
11551 do_trapi:
11552 gen_trap(ctx, mips32_op, rs, -1, imm);
11553 break;
11554
11555 case BNEZC:
11556 case BEQZC:
11557 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
11558 4, rs, 0, imm << 1);
11559 /* Compact branches don't have a delay slot, so just let
11560 the normal delay slot handling take us to the branch
11561 target. */
11562 break;
11563 case LUI:
11564 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
11565 break;
11566 case SYNCI:
11567 break;
11568 case BC2F:
11569 case BC2T:
11570 /* COP2: Not implemented. */
11571 generate_exception_err(ctx, EXCP_CpU, 2);
11572 break;
11573 case BC1F:
11574 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
11575 goto do_cp1branch;
11576 case BC1T:
11577 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
11578 goto do_cp1branch;
11579 case BC1ANY4F:
11580 mips32_op = OPC_BC1FANY4;
11581 goto do_cp1mips3d;
11582 case BC1ANY4T:
11583 mips32_op = OPC_BC1TANY4;
11584 do_cp1mips3d:
11585 check_cop1x(ctx);
11586 check_insn(env, ctx, ASE_MIPS3D);
11587 /* Fall through */
11588 do_cp1branch:
11589 gen_compute_branch1(env, ctx, mips32_op,
11590 (ctx->opcode >> 18) & 0x7, imm << 1);
11591 *is_branch = 1;
11592 break;
11593 case BPOSGE64:
11594 case BPOSGE32:
11595 /* MIPS DSP: not implemented */
11596 /* Fall through */
11597 default:
11598 MIPS_INVAL("pool32i");
11599 generate_exception(ctx, EXCP_RI);
11600 break;
11601 }
11602 break;
11603 case POOL32C:
11604 minor = (ctx->opcode >> 12) & 0xf;
11605 switch (minor) {
11606 case LWL:
11607 mips32_op = OPC_LWL;
11608 goto do_ld_lr;
11609 case SWL:
11610 mips32_op = OPC_SWL;
11611 goto do_st_lr;
11612 case LWR:
11613 mips32_op = OPC_LWR;
11614 goto do_ld_lr;
11615 case SWR:
11616 mips32_op = OPC_SWR;
11617 goto do_st_lr;
11618 #if defined(TARGET_MIPS64)
11619 case LDL:
11620 mips32_op = OPC_LDL;
11621 goto do_ld_lr;
11622 case SDL:
11623 mips32_op = OPC_SDL;
11624 goto do_st_lr;
11625 case LDR:
11626 mips32_op = OPC_LDR;
11627 goto do_ld_lr;
11628 case SDR:
11629 mips32_op = OPC_SDR;
11630 goto do_st_lr;
11631 case LWU:
11632 mips32_op = OPC_LWU;
11633 goto do_ld_lr;
11634 case LLD:
11635 mips32_op = OPC_LLD;
11636 goto do_ld_lr;
11637 #endif
11638 case LL:
11639 mips32_op = OPC_LL;
11640 goto do_ld_lr;
11641 do_ld_lr:
11642 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11643 break;
11644 do_st_lr:
11645 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
11646 break;
11647 case SC:
11648 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
11649 break;
11650 #if defined(TARGET_MIPS64)
11651 case SCD:
11652 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
11653 break;
11654 #endif
11655 case PREF:
11656 /* Treat as no-op */
11657 break;
11658 default:
11659 MIPS_INVAL("pool32c");
11660 generate_exception(ctx, EXCP_RI);
11661 break;
11662 }
11663 break;
11664 case ADDI32:
11665 mips32_op = OPC_ADDI;
11666 goto do_addi;
11667 case ADDIU32:
11668 mips32_op = OPC_ADDIU;
11669 do_addi:
11670 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
11671 break;
11672
11673 /* Logical operations */
11674 case ORI32:
11675 mips32_op = OPC_ORI;
11676 goto do_logici;
11677 case XORI32:
11678 mips32_op = OPC_XORI;
11679 goto do_logici;
11680 case ANDI32:
11681 mips32_op = OPC_ANDI;
11682 do_logici:
11683 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
11684 break;
11685
11686 /* Set less than immediate */
11687 case SLTI32:
11688 mips32_op = OPC_SLTI;
11689 goto do_slti;
11690 case SLTIU32:
11691 mips32_op = OPC_SLTIU;
11692 do_slti:
11693 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
11694 break;
11695 case JALX32:
11696 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
11697 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
11698 *is_branch = 1;
11699 break;
11700 case JALS32:
11701 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
11702 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
11703 *is_branch = 1;
11704 break;
11705 case BEQ32:
11706 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
11707 *is_branch = 1;
11708 break;
11709 case BNE32:
11710 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
11711 *is_branch = 1;
11712 break;
11713 case J32:
11714 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
11715 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11716 *is_branch = 1;
11717 break;
11718 case JAL32:
11719 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
11720 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
11721 *is_branch = 1;
11722 break;
11723 /* Floating point (COP1) */
11724 case LWC132:
11725 mips32_op = OPC_LWC1;
11726 goto do_cop1;
11727 case LDC132:
11728 mips32_op = OPC_LDC1;
11729 goto do_cop1;
11730 case SWC132:
11731 mips32_op = OPC_SWC1;
11732 goto do_cop1;
11733 case SDC132:
11734 mips32_op = OPC_SDC1;
11735 do_cop1:
11736 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
11737 break;
11738 case ADDIUPC:
11739 {
11740 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
11741 int offset = SIMM(ctx->opcode, 0, 23) << 2;
11742
11743 gen_addiupc(ctx, reg, offset, 0, 0);
11744 }
11745 break;
11746 /* Loads and stores */
11747 case LB32:
11748 mips32_op = OPC_LB;
11749 goto do_ld;
11750 case LBU32:
11751 mips32_op = OPC_LBU;
11752 goto do_ld;
11753 case LH32:
11754 mips32_op = OPC_LH;
11755 goto do_ld;
11756 case LHU32:
11757 mips32_op = OPC_LHU;
11758 goto do_ld;
11759 case LW32:
11760 mips32_op = OPC_LW;
11761 goto do_ld;
11762 #ifdef TARGET_MIPS64
11763 case LD32:
11764 mips32_op = OPC_LD;
11765 goto do_ld;
11766 case SD32:
11767 mips32_op = OPC_SD;
11768 goto do_st;
11769 #endif
11770 case SB32:
11771 mips32_op = OPC_SB;
11772 goto do_st;
11773 case SH32:
11774 mips32_op = OPC_SH;
11775 goto do_st;
11776 case SW32:
11777 mips32_op = OPC_SW;
11778 goto do_st;
11779 do_ld:
11780 gen_ld(env, ctx, mips32_op, rt, rs, imm);
11781 break;
11782 do_st:
11783 gen_st(ctx, mips32_op, rt, rs, imm);
11784 break;
11785 default:
11786 generate_exception(ctx, EXCP_RI);
11787 break;
11788 }
11789 }
11790
11791 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
11792 {
11793 uint32_t op;
11794
11795 /* make sure instructions are on a halfword boundary */
11796 if (ctx->pc & 0x1) {
11797 env->CP0_BadVAddr = ctx->pc;
11798 generate_exception(ctx, EXCP_AdEL);
11799 ctx->bstate = BS_STOP;
11800 return 2;
11801 }
11802
11803 op = (ctx->opcode >> 10) & 0x3f;
11804 /* Enforce properly-sized instructions in a delay slot */
11805 if (ctx->hflags & MIPS_HFLAG_BMASK) {
11806 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
11807
11808 switch (op) {
11809 case POOL32A:
11810 case POOL32B:
11811 case POOL32I:
11812 case POOL32C:
11813 case ADDI32:
11814 case ADDIU32:
11815 case ORI32:
11816 case XORI32:
11817 case SLTI32:
11818 case SLTIU32:
11819 case ANDI32:
11820 case JALX32:
11821 case LBU32:
11822 case LHU32:
11823 case POOL32F:
11824 case JALS32:
11825 case BEQ32:
11826 case BNE32:
11827 case J32:
11828 case JAL32:
11829 case SB32:
11830 case SH32:
11831 case POOL32S:
11832 case ADDIUPC:
11833 case SWC132:
11834 case SDC132:
11835 case SD32:
11836 case SW32:
11837 case LB32:
11838 case LH32:
11839 case DADDIU32:
11840 case POOL48A: /* ??? */
11841 case LWC132:
11842 case LDC132:
11843 case LD32:
11844 case LW32:
11845 if (bits & MIPS_HFLAG_BDS16) {
11846 generate_exception(ctx, EXCP_RI);
11847 /* Just stop translation; the user is confused. */
11848 ctx->bstate = BS_STOP;
11849 return 2;
11850 }
11851 break;
11852 case POOL16A:
11853 case POOL16B:
11854 case POOL16C:
11855 case LWGP16:
11856 case POOL16F:
11857 case LBU16:
11858 case LHU16:
11859 case LWSP16:
11860 case LW16:
11861 case SB16:
11862 case SH16:
11863 case SWSP16:
11864 case SW16:
11865 case MOVE16:
11866 case ANDI16:
11867 case POOL16D:
11868 case POOL16E:
11869 case BEQZ16:
11870 case BNEZ16:
11871 case B16:
11872 case LI16:
11873 if (bits & MIPS_HFLAG_BDS32) {
11874 generate_exception(ctx, EXCP_RI);
11875 /* Just stop translation; the user is confused. */
11876 ctx->bstate = BS_STOP;
11877 return 2;
11878 }
11879 break;
11880 default:
11881 break;
11882 }
11883 }
11884 switch (op) {
11885 case POOL16A:
11886 {
11887 int rd = mmreg(uMIPS_RD(ctx->opcode));
11888 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
11889 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
11890 uint32_t opc = 0;
11891
11892 switch (ctx->opcode & 0x1) {
11893 case ADDU16:
11894 opc = OPC_ADDU;
11895 break;
11896 case SUBU16:
11897 opc = OPC_SUBU;
11898 break;
11899 }
11900
11901 gen_arith(env, ctx, opc, rd, rs1, rs2);
11902 }
11903 break;
11904 case POOL16B:
11905 {
11906 int rd = mmreg(uMIPS_RD(ctx->opcode));
11907 int rs = mmreg(uMIPS_RS(ctx->opcode));
11908 int amount = (ctx->opcode >> 1) & 0x7;
11909 uint32_t opc = 0;
11910 amount = amount == 0 ? 8 : amount;
11911
11912 switch (ctx->opcode & 0x1) {
11913 case SLL16:
11914 opc = OPC_SLL;
11915 break;
11916 case SRL16:
11917 opc = OPC_SRL;
11918 break;
11919 }
11920
11921 gen_shift_imm(env, ctx, opc, rd, rs, amount);
11922 }
11923 break;
11924 case POOL16C:
11925 gen_pool16c_insn(env, ctx, is_branch);
11926 break;
11927 case LWGP16:
11928 {
11929 int rd = mmreg(uMIPS_RD(ctx->opcode));
11930 int rb = 28; /* GP */
11931 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
11932
11933 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11934 }
11935 break;
11936 case POOL16F:
11937 if (ctx->opcode & 1) {
11938 generate_exception(ctx, EXCP_RI);
11939 } else {
11940 /* MOVEP */
11941 int enc_dest = uMIPS_RD(ctx->opcode);
11942 int enc_rt = uMIPS_RS2(ctx->opcode);
11943 int enc_rs = uMIPS_RS1(ctx->opcode);
11944 int rd, rs, re, rt;
11945 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
11946 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
11947 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
11948
11949 rd = rd_enc[enc_dest];
11950 re = re_enc[enc_dest];
11951 rs = rs_rt_enc[enc_rs];
11952 rt = rs_rt_enc[enc_rt];
11953
11954 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
11955 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
11956 }
11957 break;
11958 case LBU16:
11959 {
11960 int rd = mmreg(uMIPS_RD(ctx->opcode));
11961 int rb = mmreg(uMIPS_RS(ctx->opcode));
11962 int16_t offset = ZIMM(ctx->opcode, 0, 4);
11963 offset = (offset == 0xf ? -1 : offset);
11964
11965 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
11966 }
11967 break;
11968 case LHU16:
11969 {
11970 int rd = mmreg(uMIPS_RD(ctx->opcode));
11971 int rb = mmreg(uMIPS_RS(ctx->opcode));
11972 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
11973
11974 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
11975 }
11976 break;
11977 case LWSP16:
11978 {
11979 int rd = (ctx->opcode >> 5) & 0x1f;
11980 int rb = 29; /* SP */
11981 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
11982
11983 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11984 }
11985 break;
11986 case LW16:
11987 {
11988 int rd = mmreg(uMIPS_RD(ctx->opcode));
11989 int rb = mmreg(uMIPS_RS(ctx->opcode));
11990 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
11991
11992 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
11993 }
11994 break;
11995 case SB16:
11996 {
11997 int rd = mmreg2(uMIPS_RD(ctx->opcode));
11998 int rb = mmreg(uMIPS_RS(ctx->opcode));
11999 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12000
12001 gen_st(ctx, OPC_SB, rd, rb, offset);
12002 }
12003 break;
12004 case SH16:
12005 {
12006 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12007 int rb = mmreg(uMIPS_RS(ctx->opcode));
12008 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12009
12010 gen_st(ctx, OPC_SH, rd, rb, offset);
12011 }
12012 break;
12013 case SWSP16:
12014 {
12015 int rd = (ctx->opcode >> 5) & 0x1f;
12016 int rb = 29; /* SP */
12017 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12018
12019 gen_st(ctx, OPC_SW, rd, rb, offset);
12020 }
12021 break;
12022 case SW16:
12023 {
12024 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12025 int rb = mmreg(uMIPS_RS(ctx->opcode));
12026 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12027
12028 gen_st(ctx, OPC_SW, rd, rb, offset);
12029 }
12030 break;
12031 case MOVE16:
12032 {
12033 int rd = uMIPS_RD5(ctx->opcode);
12034 int rs = uMIPS_RS5(ctx->opcode);
12035
12036 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12037 }
12038 break;
12039 case ANDI16:
12040 gen_andi16(env, ctx);
12041 break;
12042 case POOL16D:
12043 switch (ctx->opcode & 0x1) {
12044 case ADDIUS5:
12045 gen_addius5(env, ctx);
12046 break;
12047 case ADDIUSP:
12048 gen_addiusp(env, ctx);
12049 break;
12050 }
12051 break;
12052 case POOL16E:
12053 switch (ctx->opcode & 0x1) {
12054 case ADDIUR2:
12055 gen_addiur2(env, ctx);
12056 break;
12057 case ADDIUR1SP:
12058 gen_addiur1sp(env, ctx);
12059 break;
12060 }
12061 break;
12062 case B16:
12063 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12064 SIMM(ctx->opcode, 0, 10) << 1);
12065 *is_branch = 1;
12066 break;
12067 case BNEZ16:
12068 case BEQZ16:
12069 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12070 mmreg(uMIPS_RD(ctx->opcode)),
12071 0, SIMM(ctx->opcode, 0, 7) << 1);
12072 *is_branch = 1;
12073 break;
12074 case LI16:
12075 {
12076 int reg = mmreg(uMIPS_RD(ctx->opcode));
12077 int imm = ZIMM(ctx->opcode, 0, 7);
12078
12079 imm = (imm == 0x7f ? -1 : imm);
12080 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12081 }
12082 break;
12083 case RES_20:
12084 case RES_28:
12085 case RES_29:
12086 case RES_30:
12087 case RES_31:
12088 case RES_38:
12089 case RES_39:
12090 generate_exception(ctx, EXCP_RI);
12091 break;
12092 default:
12093 decode_micromips32_opc (env, ctx, op, is_branch);
12094 return 4;
12095 }
12096
12097 return 2;
12098 }
12099
12100 /* SmartMIPS extension to MIPS32 */
12101
12102 #if defined(TARGET_MIPS64)
12103
12104 /* MDMX extension to MIPS64 */
12105
12106 #endif
12107
12108 static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
12109 {
12110 int32_t offset;
12111 int rs, rt, rd, sa;
12112 uint32_t op, op1, op2;
12113 int16_t imm;
12114
12115 /* make sure instructions are on a word boundary */
12116 if (ctx->pc & 0x3) {
12117 env->CP0_BadVAddr = ctx->pc;
12118 generate_exception(ctx, EXCP_AdEL);
12119 return;
12120 }
12121
12122 /* Handle blikely not taken case */
12123 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
12124 int l1 = gen_new_label();
12125
12126 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
12127 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12128 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
12129 gen_goto_tb(ctx, 1, ctx->pc + 4);
12130 gen_set_label(l1);
12131 }
12132
12133 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
12134 tcg_gen_debug_insn_start(ctx->pc);
12135 }
12136
12137 op = MASK_OP_MAJOR(ctx->opcode);
12138 rs = (ctx->opcode >> 21) & 0x1f;
12139 rt = (ctx->opcode >> 16) & 0x1f;
12140 rd = (ctx->opcode >> 11) & 0x1f;
12141 sa = (ctx->opcode >> 6) & 0x1f;
12142 imm = (int16_t)ctx->opcode;
12143 switch (op) {
12144 case OPC_SPECIAL:
12145 op1 = MASK_SPECIAL(ctx->opcode);
12146 switch (op1) {
12147 case OPC_SLL: /* Shift with immediate */
12148 case OPC_SRA:
12149 gen_shift_imm(env, ctx, op1, rd, rt, sa);
12150 break;
12151 case OPC_SRL:
12152 switch ((ctx->opcode >> 21) & 0x1f) {
12153 case 1:
12154 /* rotr is decoded as srl on non-R2 CPUs */
12155 if (env->insn_flags & ISA_MIPS32R2) {
12156 op1 = OPC_ROTR;
12157 }
12158 /* Fallthrough */
12159 case 0:
12160 gen_shift_imm(env, ctx, op1, rd, rt, sa);
12161 break;
12162 default:
12163 generate_exception(ctx, EXCP_RI);
12164 break;
12165 }
12166 break;
12167 case OPC_MOVN: /* Conditional move */
12168 case OPC_MOVZ:
12169 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
12170 INSN_LOONGSON2E | INSN_LOONGSON2F);
12171 gen_cond_move(env, ctx, op1, rd, rs, rt);
12172 break;
12173 case OPC_ADD ... OPC_SUBU:
12174 gen_arith(env, ctx, op1, rd, rs, rt);
12175 break;
12176 case OPC_SLLV: /* Shifts */
12177 case OPC_SRAV:
12178 gen_shift(env, ctx, op1, rd, rs, rt);
12179 break;
12180 case OPC_SRLV:
12181 switch ((ctx->opcode >> 6) & 0x1f) {
12182 case 1:
12183 /* rotrv is decoded as srlv on non-R2 CPUs */
12184 if (env->insn_flags & ISA_MIPS32R2) {
12185 op1 = OPC_ROTRV;
12186 }
12187 /* Fallthrough */
12188 case 0:
12189 gen_shift(env, ctx, op1, rd, rs, rt);
12190 break;
12191 default:
12192 generate_exception(ctx, EXCP_RI);
12193 break;
12194 }
12195 break;
12196 case OPC_SLT: /* Set on less than */
12197 case OPC_SLTU:
12198 gen_slt(env, ctx, op1, rd, rs, rt);
12199 break;
12200 case OPC_AND: /* Logic*/
12201 case OPC_OR:
12202 case OPC_NOR:
12203 case OPC_XOR:
12204 gen_logic(env, ctx, op1, rd, rs, rt);
12205 break;
12206 case OPC_MULT ... OPC_DIVU:
12207 if (sa) {
12208 check_insn(env, ctx, INSN_VR54XX);
12209 op1 = MASK_MUL_VR54XX(ctx->opcode);
12210 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
12211 } else
12212 gen_muldiv(ctx, op1, rs, rt);
12213 break;
12214 case OPC_JR ... OPC_JALR:
12215 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
12216 *is_branch = 1;
12217 break;
12218 case OPC_TGE ... OPC_TEQ: /* Traps */
12219 case OPC_TNE:
12220 gen_trap(ctx, op1, rs, rt, -1);
12221 break;
12222 case OPC_MFHI: /* Move from HI/LO */
12223 case OPC_MFLO:
12224 gen_HILO(ctx, op1, rd);
12225 break;
12226 case OPC_MTHI:
12227 case OPC_MTLO: /* Move to HI/LO */
12228 gen_HILO(ctx, op1, rs);
12229 break;
12230 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
12231 #ifdef MIPS_STRICT_STANDARD
12232 MIPS_INVAL("PMON / selsl");
12233 generate_exception(ctx, EXCP_RI);
12234 #else
12235 gen_helper_0e0i(pmon, sa);
12236 #endif
12237 break;
12238 case OPC_SYSCALL:
12239 generate_exception(ctx, EXCP_SYSCALL);
12240 ctx->bstate = BS_STOP;
12241 break;
12242 case OPC_BREAK:
12243 generate_exception(ctx, EXCP_BREAK);
12244 break;
12245 case OPC_SPIM:
12246 #ifdef MIPS_STRICT_STANDARD
12247 MIPS_INVAL("SPIM");
12248 generate_exception(ctx, EXCP_RI);
12249 #else
12250 /* Implemented as RI exception for now. */
12251 MIPS_INVAL("spim (unofficial)");
12252 generate_exception(ctx, EXCP_RI);
12253 #endif
12254 break;
12255 case OPC_SYNC:
12256 /* Treat as NOP. */
12257 break;
12258
12259 case OPC_MOVCI:
12260 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12261 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12262 check_cp1_enabled(ctx);
12263 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
12264 (ctx->opcode >> 16) & 1);
12265 } else {
12266 generate_exception_err(ctx, EXCP_CpU, 1);
12267 }
12268 break;
12269
12270 #if defined(TARGET_MIPS64)
12271 /* MIPS64 specific opcodes */
12272 case OPC_DSLL:
12273 case OPC_DSRA:
12274 case OPC_DSLL32:
12275 case OPC_DSRA32:
12276 check_insn(env, ctx, ISA_MIPS3);
12277 check_mips_64(ctx);
12278 gen_shift_imm(env, ctx, op1, rd, rt, sa);
12279 break;
12280 case OPC_DSRL:
12281 switch ((ctx->opcode >> 21) & 0x1f) {
12282 case 1:
12283 /* drotr is decoded as dsrl on non-R2 CPUs */
12284 if (env->insn_flags & ISA_MIPS32R2) {
12285 op1 = OPC_DROTR;
12286 }
12287 /* Fallthrough */
12288 case 0:
12289 check_insn(env, ctx, ISA_MIPS3);
12290 check_mips_64(ctx);
12291 gen_shift_imm(env, ctx, op1, rd, rt, sa);
12292 break;
12293 default:
12294 generate_exception(ctx, EXCP_RI);
12295 break;
12296 }
12297 break;
12298 case OPC_DSRL32:
12299 switch ((ctx->opcode >> 21) & 0x1f) {
12300 case 1:
12301 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
12302 if (env->insn_flags & ISA_MIPS32R2) {
12303 op1 = OPC_DROTR32;
12304 }
12305 /* Fallthrough */
12306 case 0:
12307 check_insn(env, ctx, ISA_MIPS3);
12308 check_mips_64(ctx);
12309 gen_shift_imm(env, ctx, op1, rd, rt, sa);
12310 break;
12311 default:
12312 generate_exception(ctx, EXCP_RI);
12313 break;
12314 }
12315 break;
12316 case OPC_DADD ... OPC_DSUBU:
12317 check_insn(env, ctx, ISA_MIPS3);
12318 check_mips_64(ctx);
12319 gen_arith(env, ctx, op1, rd, rs, rt);
12320 break;
12321 case OPC_DSLLV:
12322 case OPC_DSRAV:
12323 check_insn(env, ctx, ISA_MIPS3);
12324 check_mips_64(ctx);
12325 gen_shift(env, ctx, op1, rd, rs, rt);
12326 break;
12327 case OPC_DSRLV:
12328 switch ((ctx->opcode >> 6) & 0x1f) {
12329 case 1:
12330 /* drotrv is decoded as dsrlv on non-R2 CPUs */
12331 if (env->insn_flags & ISA_MIPS32R2) {
12332 op1 = OPC_DROTRV;
12333 }
12334 /* Fallthrough */
12335 case 0:
12336 check_insn(env, ctx, ISA_MIPS3);
12337 check_mips_64(ctx);
12338 gen_shift(env, ctx, op1, rd, rs, rt);
12339 break;
12340 default:
12341 generate_exception(ctx, EXCP_RI);
12342 break;
12343 }
12344 break;
12345 case OPC_DMULT ... OPC_DDIVU:
12346 check_insn(env, ctx, ISA_MIPS3);
12347 check_mips_64(ctx);
12348 gen_muldiv(ctx, op1, rs, rt);
12349 break;
12350 #endif
12351 default: /* Invalid */
12352 MIPS_INVAL("special");
12353 generate_exception(ctx, EXCP_RI);
12354 break;
12355 }
12356 break;
12357 case OPC_SPECIAL2:
12358 op1 = MASK_SPECIAL2(ctx->opcode);
12359 switch (op1) {
12360 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
12361 case OPC_MSUB ... OPC_MSUBU:
12362 check_insn(env, ctx, ISA_MIPS32);
12363 gen_muldiv(ctx, op1, rs, rt);
12364 break;
12365 case OPC_MUL:
12366 gen_arith(env, ctx, op1, rd, rs, rt);
12367 break;
12368 case OPC_CLO:
12369 case OPC_CLZ:
12370 check_insn(env, ctx, ISA_MIPS32);
12371 gen_cl(ctx, op1, rd, rs);
12372 break;
12373 case OPC_SDBBP:
12374 /* XXX: not clear which exception should be raised
12375 * when in debug mode...
12376 */
12377 check_insn(env, ctx, ISA_MIPS32);
12378 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
12379 generate_exception(ctx, EXCP_DBp);
12380 } else {
12381 generate_exception(ctx, EXCP_DBp);
12382 }
12383 /* Treat as NOP. */
12384 break;
12385 case OPC_DIV_G_2F:
12386 case OPC_DIVU_G_2F:
12387 case OPC_MULT_G_2F:
12388 case OPC_MULTU_G_2F:
12389 case OPC_MOD_G_2F:
12390 case OPC_MODU_G_2F:
12391 check_insn(env, ctx, INSN_LOONGSON2F);
12392 gen_loongson_integer(ctx, op1, rd, rs, rt);
12393 break;
12394 #if defined(TARGET_MIPS64)
12395 case OPC_DCLO:
12396 case OPC_DCLZ:
12397 check_insn(env, ctx, ISA_MIPS64);
12398 check_mips_64(ctx);
12399 gen_cl(ctx, op1, rd, rs);
12400 break;
12401 case OPC_DMULT_G_2F:
12402 case OPC_DMULTU_G_2F:
12403 case OPC_DDIV_G_2F:
12404 case OPC_DDIVU_G_2F:
12405 case OPC_DMOD_G_2F:
12406 case OPC_DMODU_G_2F:
12407 check_insn(env, ctx, INSN_LOONGSON2F);
12408 gen_loongson_integer(ctx, op1, rd, rs, rt);
12409 break;
12410 #endif
12411 default: /* Invalid */
12412 MIPS_INVAL("special2");
12413 generate_exception(ctx, EXCP_RI);
12414 break;
12415 }
12416 break;
12417 case OPC_SPECIAL3:
12418 op1 = MASK_SPECIAL3(ctx->opcode);
12419 switch (op1) {
12420 case OPC_EXT:
12421 case OPC_INS:
12422 check_insn(env, ctx, ISA_MIPS32R2);
12423 gen_bitops(ctx, op1, rt, rs, sa, rd);
12424 break;
12425 case OPC_BSHFL:
12426 check_insn(env, ctx, ISA_MIPS32R2);
12427 op2 = MASK_BSHFL(ctx->opcode);
12428 gen_bshfl(ctx, op2, rt, rd);
12429 break;
12430 case OPC_RDHWR:
12431 gen_rdhwr(env, ctx, rt, rd);
12432 break;
12433 case OPC_FORK:
12434 check_insn(env, ctx, ASE_MT);
12435 {
12436 TCGv t0 = tcg_temp_new();
12437 TCGv t1 = tcg_temp_new();
12438
12439 gen_load_gpr(t0, rt);
12440 gen_load_gpr(t1, rs);
12441 gen_helper_fork(t0, t1);
12442 tcg_temp_free(t0);
12443 tcg_temp_free(t1);
12444 }
12445 break;
12446 case OPC_YIELD:
12447 check_insn(env, ctx, ASE_MT);
12448 {
12449 TCGv t0 = tcg_temp_new();
12450
12451 save_cpu_state(ctx, 1);
12452 gen_load_gpr(t0, rs);
12453 gen_helper_yield(t0, cpu_env, t0);
12454 gen_store_gpr(t0, rd);
12455 tcg_temp_free(t0);
12456 }
12457 break;
12458 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
12459 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
12460 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
12461 check_insn(env, ctx, INSN_LOONGSON2E);
12462 gen_loongson_integer(ctx, op1, rd, rs, rt);
12463 break;
12464 #if defined(TARGET_MIPS64)
12465 case OPC_DEXTM ... OPC_DEXT:
12466 case OPC_DINSM ... OPC_DINS:
12467 check_insn(env, ctx, ISA_MIPS64R2);
12468 check_mips_64(ctx);
12469 gen_bitops(ctx, op1, rt, rs, sa, rd);
12470 break;
12471 case OPC_DBSHFL:
12472 check_insn(env, ctx, ISA_MIPS64R2);
12473 check_mips_64(ctx);
12474 op2 = MASK_DBSHFL(ctx->opcode);
12475 gen_bshfl(ctx, op2, rt, rd);
12476 break;
12477 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
12478 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
12479 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
12480 check_insn(env, ctx, INSN_LOONGSON2E);
12481 gen_loongson_integer(ctx, op1, rd, rs, rt);
12482 break;
12483 #endif
12484 default: /* Invalid */
12485 MIPS_INVAL("special3");
12486 generate_exception(ctx, EXCP_RI);
12487 break;
12488 }
12489 break;
12490 case OPC_REGIMM:
12491 op1 = MASK_REGIMM(ctx->opcode);
12492 switch (op1) {
12493 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
12494 case OPC_BLTZAL ... OPC_BGEZALL:
12495 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
12496 *is_branch = 1;
12497 break;
12498 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
12499 case OPC_TNEI:
12500 gen_trap(ctx, op1, rs, -1, imm);
12501 break;
12502 case OPC_SYNCI:
12503 check_insn(env, ctx, ISA_MIPS32R2);
12504 /* Treat as NOP. */
12505 break;
12506 default: /* Invalid */
12507 MIPS_INVAL("regimm");
12508 generate_exception(ctx, EXCP_RI);
12509 break;
12510 }
12511 break;
12512 case OPC_CP0:
12513 check_cp0_enabled(ctx);
12514 op1 = MASK_CP0(ctx->opcode);
12515 switch (op1) {
12516 case OPC_MFC0:
12517 case OPC_MTC0:
12518 case OPC_MFTR:
12519 case OPC_MTTR:
12520 #if defined(TARGET_MIPS64)
12521 case OPC_DMFC0:
12522 case OPC_DMTC0:
12523 #endif
12524 #ifndef CONFIG_USER_ONLY
12525 gen_cp0(env, ctx, op1, rt, rd);
12526 #endif /* !CONFIG_USER_ONLY */
12527 break;
12528 case OPC_C0_FIRST ... OPC_C0_LAST:
12529 #ifndef CONFIG_USER_ONLY
12530 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
12531 #endif /* !CONFIG_USER_ONLY */
12532 break;
12533 case OPC_MFMC0:
12534 #ifndef CONFIG_USER_ONLY
12535 {
12536 TCGv t0 = tcg_temp_new();
12537
12538 op2 = MASK_MFMC0(ctx->opcode);
12539 switch (op2) {
12540 case OPC_DMT:
12541 check_insn(env, ctx, ASE_MT);
12542 gen_helper_dmt(t0);
12543 gen_store_gpr(t0, rt);
12544 break;
12545 case OPC_EMT:
12546 check_insn(env, ctx, ASE_MT);
12547 gen_helper_emt(t0);
12548 gen_store_gpr(t0, rt);
12549 break;
12550 case OPC_DVPE:
12551 check_insn(env, ctx, ASE_MT);
12552 gen_helper_dvpe(t0, cpu_env);
12553 gen_store_gpr(t0, rt);
12554 break;
12555 case OPC_EVPE:
12556 check_insn(env, ctx, ASE_MT);
12557 gen_helper_evpe(t0, cpu_env);
12558 gen_store_gpr(t0, rt);
12559 break;
12560 case OPC_DI:
12561 check_insn(env, ctx, ISA_MIPS32R2);
12562 save_cpu_state(ctx, 1);
12563 gen_helper_di(t0, cpu_env);
12564 gen_store_gpr(t0, rt);
12565 /* Stop translation as we may have switched the execution mode */
12566 ctx->bstate = BS_STOP;
12567 break;
12568 case OPC_EI:
12569 check_insn(env, ctx, ISA_MIPS32R2);
12570 save_cpu_state(ctx, 1);
12571 gen_helper_ei(t0, cpu_env);
12572 gen_store_gpr(t0, rt);
12573 /* Stop translation as we may have switched the execution mode */
12574 ctx->bstate = BS_STOP;
12575 break;
12576 default: /* Invalid */
12577 MIPS_INVAL("mfmc0");
12578 generate_exception(ctx, EXCP_RI);
12579 break;
12580 }
12581 tcg_temp_free(t0);
12582 }
12583 #endif /* !CONFIG_USER_ONLY */
12584 break;
12585 case OPC_RDPGPR:
12586 check_insn(env, ctx, ISA_MIPS32R2);
12587 gen_load_srsgpr(rt, rd);
12588 break;
12589 case OPC_WRPGPR:
12590 check_insn(env, ctx, ISA_MIPS32R2);
12591 gen_store_srsgpr(rt, rd);
12592 break;
12593 default:
12594 MIPS_INVAL("cp0");
12595 generate_exception(ctx, EXCP_RI);
12596 break;
12597 }
12598 break;
12599 case OPC_ADDI: /* Arithmetic with immediate opcode */
12600 case OPC_ADDIU:
12601 gen_arith_imm(env, ctx, op, rt, rs, imm);
12602 break;
12603 case OPC_SLTI: /* Set on less than with immediate opcode */
12604 case OPC_SLTIU:
12605 gen_slt_imm(env, ctx, op, rt, rs, imm);
12606 break;
12607 case OPC_ANDI: /* Arithmetic with immediate opcode */
12608 case OPC_LUI:
12609 case OPC_ORI:
12610 case OPC_XORI:
12611 gen_logic_imm(env, ctx, op, rt, rs, imm);
12612 break;
12613 case OPC_J ... OPC_JAL: /* Jump */
12614 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12615 gen_compute_branch(ctx, op, 4, rs, rt, offset);
12616 *is_branch = 1;
12617 break;
12618 case OPC_BEQ ... OPC_BGTZ: /* Branch */
12619 case OPC_BEQL ... OPC_BGTZL:
12620 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
12621 *is_branch = 1;
12622 break;
12623 case OPC_LB ... OPC_LWR: /* Load and stores */
12624 case OPC_LL:
12625 gen_ld(env, ctx, op, rt, rs, imm);
12626 break;
12627 case OPC_SB ... OPC_SW:
12628 case OPC_SWR:
12629 gen_st(ctx, op, rt, rs, imm);
12630 break;
12631 case OPC_SC:
12632 gen_st_cond(ctx, op, rt, rs, imm);
12633 break;
12634 case OPC_CACHE:
12635 check_cp0_enabled(ctx);
12636 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
12637 /* Treat as NOP. */
12638 break;
12639 case OPC_PREF:
12640 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
12641 /* Treat as NOP. */
12642 break;
12643
12644 /* Floating point (COP1). */
12645 case OPC_LWC1:
12646 case OPC_LDC1:
12647 case OPC_SWC1:
12648 case OPC_SDC1:
12649 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
12650 break;
12651
12652 case OPC_CP1:
12653 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12654 check_cp1_enabled(ctx);
12655 op1 = MASK_CP1(ctx->opcode);
12656 switch (op1) {
12657 case OPC_MFHC1:
12658 case OPC_MTHC1:
12659 check_insn(env, ctx, ISA_MIPS32R2);
12660 case OPC_MFC1:
12661 case OPC_CFC1:
12662 case OPC_MTC1:
12663 case OPC_CTC1:
12664 gen_cp1(ctx, op1, rt, rd);
12665 break;
12666 #if defined(TARGET_MIPS64)
12667 case OPC_DMFC1:
12668 case OPC_DMTC1:
12669 check_insn(env, ctx, ISA_MIPS3);
12670 gen_cp1(ctx, op1, rt, rd);
12671 break;
12672 #endif
12673 case OPC_BC1ANY2:
12674 case OPC_BC1ANY4:
12675 check_cop1x(ctx);
12676 check_insn(env, ctx, ASE_MIPS3D);
12677 /* fall through */
12678 case OPC_BC1:
12679 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
12680 (rt >> 2) & 0x7, imm << 2);
12681 *is_branch = 1;
12682 break;
12683 case OPC_S_FMT:
12684 case OPC_D_FMT:
12685 case OPC_W_FMT:
12686 case OPC_L_FMT:
12687 case OPC_PS_FMT:
12688 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
12689 (imm >> 8) & 0x7);
12690 break;
12691 default:
12692 MIPS_INVAL("cp1");
12693 generate_exception (ctx, EXCP_RI);
12694 break;
12695 }
12696 } else {
12697 generate_exception_err(ctx, EXCP_CpU, 1);
12698 }
12699 break;
12700
12701 /* COP2. */
12702 case OPC_LWC2:
12703 case OPC_LDC2:
12704 case OPC_SWC2:
12705 case OPC_SDC2:
12706 /* COP2: Not implemented. */
12707 generate_exception_err(ctx, EXCP_CpU, 2);
12708 break;
12709 case OPC_CP2:
12710 check_insn(env, ctx, INSN_LOONGSON2F);
12711 /* Note that these instructions use different fields. */
12712 gen_loongson_multimedia(ctx, sa, rd, rt);
12713 break;
12714
12715 case OPC_CP3:
12716 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
12717 check_cp1_enabled(ctx);
12718 op1 = MASK_CP3(ctx->opcode);
12719 switch (op1) {
12720 case OPC_LWXC1:
12721 case OPC_LDXC1:
12722 case OPC_LUXC1:
12723 case OPC_SWXC1:
12724 case OPC_SDXC1:
12725 case OPC_SUXC1:
12726 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
12727 break;
12728 case OPC_PREFX:
12729 /* Treat as NOP. */
12730 break;
12731 case OPC_ALNV_PS:
12732 case OPC_MADD_S:
12733 case OPC_MADD_D:
12734 case OPC_MADD_PS:
12735 case OPC_MSUB_S:
12736 case OPC_MSUB_D:
12737 case OPC_MSUB_PS:
12738 case OPC_NMADD_S:
12739 case OPC_NMADD_D:
12740 case OPC_NMADD_PS:
12741 case OPC_NMSUB_S:
12742 case OPC_NMSUB_D:
12743 case OPC_NMSUB_PS:
12744 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
12745 break;
12746 default:
12747 MIPS_INVAL("cp3");
12748 generate_exception (ctx, EXCP_RI);
12749 break;
12750 }
12751 } else {
12752 generate_exception_err(ctx, EXCP_CpU, 1);
12753 }
12754 break;
12755
12756 #if defined(TARGET_MIPS64)
12757 /* MIPS64 opcodes */
12758 case OPC_LWU:
12759 case OPC_LDL ... OPC_LDR:
12760 case OPC_LLD:
12761 case OPC_LD:
12762 check_insn(env, ctx, ISA_MIPS3);
12763 check_mips_64(ctx);
12764 gen_ld(env, ctx, op, rt, rs, imm);
12765 break;
12766 case OPC_SDL ... OPC_SDR:
12767 case OPC_SD:
12768 check_insn(env, ctx, ISA_MIPS3);
12769 check_mips_64(ctx);
12770 gen_st(ctx, op, rt, rs, imm);
12771 break;
12772 case OPC_SCD:
12773 check_insn(env, ctx, ISA_MIPS3);
12774 check_mips_64(ctx);
12775 gen_st_cond(ctx, op, rt, rs, imm);
12776 break;
12777 case OPC_DADDI:
12778 case OPC_DADDIU:
12779 check_insn(env, ctx, ISA_MIPS3);
12780 check_mips_64(ctx);
12781 gen_arith_imm(env, ctx, op, rt, rs, imm);
12782 break;
12783 #endif
12784 case OPC_JALX:
12785 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
12786 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12787 gen_compute_branch(ctx, op, 4, rs, rt, offset);
12788 *is_branch = 1;
12789 break;
12790 case OPC_MDMX:
12791 check_insn(env, ctx, ASE_MDMX);
12792 /* MDMX: Not implemented. */
12793 default: /* Invalid */
12794 MIPS_INVAL("major opcode");
12795 generate_exception(ctx, EXCP_RI);
12796 break;
12797 }
12798 }
12799
12800 static inline void
12801 gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
12802 int search_pc)
12803 {
12804 DisasContext ctx;
12805 target_ulong pc_start;
12806 uint16_t *gen_opc_end;
12807 CPUBreakpoint *bp;
12808 int j, lj = -1;
12809 int num_insns;
12810 int max_insns;
12811 int insn_bytes;
12812 int is_branch;
12813
12814 if (search_pc)
12815 qemu_log("search pc %d\n", search_pc);
12816
12817 pc_start = tb->pc;
12818 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
12819 ctx.pc = pc_start;
12820 ctx.saved_pc = -1;
12821 ctx.singlestep_enabled = env->singlestep_enabled;
12822 ctx.tb = tb;
12823 ctx.bstate = BS_NONE;
12824 /* Restore delay slot state from the tb context. */
12825 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
12826 restore_cpu_state(env, &ctx);
12827 #ifdef CONFIG_USER_ONLY
12828 ctx.mem_idx = MIPS_HFLAG_UM;
12829 #else
12830 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
12831 #endif
12832 num_insns = 0;
12833 max_insns = tb->cflags & CF_COUNT_MASK;
12834 if (max_insns == 0)
12835 max_insns = CF_COUNT_MASK;
12836 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
12837 gen_icount_start();
12838 while (ctx.bstate == BS_NONE) {
12839 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
12840 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
12841 if (bp->pc == ctx.pc) {
12842 save_cpu_state(&ctx, 1);
12843 ctx.bstate = BS_BRANCH;
12844 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
12845 /* Include the breakpoint location or the tb won't
12846 * be flushed when it must be. */
12847 ctx.pc += 4;
12848 goto done_generating;
12849 }
12850 }
12851 }
12852
12853 if (search_pc) {
12854 j = gen_opc_ptr - gen_opc_buf;
12855 if (lj < j) {
12856 lj++;
12857 while (lj < j)
12858 gen_opc_instr_start[lj++] = 0;
12859 }
12860 gen_opc_pc[lj] = ctx.pc;
12861 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
12862 gen_opc_instr_start[lj] = 1;
12863 gen_opc_icount[lj] = num_insns;
12864 }
12865 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
12866 gen_io_start();
12867
12868 is_branch = 0;
12869 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
12870 ctx.opcode = cpu_ldl_code(env, ctx.pc);
12871 insn_bytes = 4;
12872 decode_opc(env, &ctx, &is_branch);
12873 } else if (env->insn_flags & ASE_MICROMIPS) {
12874 ctx.opcode = cpu_lduw_code(env, ctx.pc);
12875 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
12876 } else if (env->insn_flags & ASE_MIPS16) {
12877 ctx.opcode = cpu_lduw_code(env, ctx.pc);
12878 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
12879 } else {
12880 generate_exception(&ctx, EXCP_RI);
12881 ctx.bstate = BS_STOP;
12882 break;
12883 }
12884 if (!is_branch) {
12885 handle_delay_slot(env, &ctx, insn_bytes);
12886 }
12887 ctx.pc += insn_bytes;
12888
12889 num_insns++;
12890
12891 /* Execute a branch and its delay slot as a single instruction.
12892 This is what GDB expects and is consistent with what the
12893 hardware does (e.g. if a delay slot instruction faults, the
12894 reported PC is the PC of the branch). */
12895 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
12896 break;
12897
12898 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
12899 break;
12900
12901 if (gen_opc_ptr >= gen_opc_end)
12902 break;
12903
12904 if (num_insns >= max_insns)
12905 break;
12906
12907 if (singlestep)
12908 break;
12909 }
12910 if (tb->cflags & CF_LAST_IO)
12911 gen_io_end();
12912 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
12913 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
12914 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
12915 } else {
12916 switch (ctx.bstate) {
12917 case BS_STOP:
12918 gen_goto_tb(&ctx, 0, ctx.pc);
12919 break;
12920 case BS_NONE:
12921 save_cpu_state(&ctx, 0);
12922 gen_goto_tb(&ctx, 0, ctx.pc);
12923 break;
12924 case BS_EXCP:
12925 tcg_gen_exit_tb(0);
12926 break;
12927 case BS_BRANCH:
12928 default:
12929 break;
12930 }
12931 }
12932 done_generating:
12933 gen_icount_end(tb, num_insns);
12934 *gen_opc_ptr = INDEX_op_end;
12935 if (search_pc) {
12936 j = gen_opc_ptr - gen_opc_buf;
12937 lj++;
12938 while (lj <= j)
12939 gen_opc_instr_start[lj++] = 0;
12940 } else {
12941 tb->size = ctx.pc - pc_start;
12942 tb->icount = num_insns;
12943 }
12944 #ifdef DEBUG_DISAS
12945 LOG_DISAS("\n");
12946 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
12947 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12948 log_target_disas(pc_start, ctx.pc - pc_start, 0);
12949 qemu_log("\n");
12950 }
12951 #endif
12952 }
12953
12954 void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
12955 {
12956 gen_intermediate_code_internal(env, tb, 0);
12957 }
12958
12959 void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
12960 {
12961 gen_intermediate_code_internal(env, tb, 1);
12962 }
12963
12964 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
12965 int flags)
12966 {
12967 int i;
12968 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
12969
12970 #define printfpr(fp) \
12971 do { \
12972 if (is_fpu64) \
12973 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12974 " fd:%13g fs:%13g psu: %13g\n", \
12975 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
12976 (double)(fp)->fd, \
12977 (double)(fp)->fs[FP_ENDIAN_IDX], \
12978 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
12979 else { \
12980 fpr_t tmp; \
12981 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
12982 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
12983 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
12984 " fd:%13g fs:%13g psu:%13g\n", \
12985 tmp.w[FP_ENDIAN_IDX], tmp.d, \
12986 (double)tmp.fd, \
12987 (double)tmp.fs[FP_ENDIAN_IDX], \
12988 (double)tmp.fs[!FP_ENDIAN_IDX]); \
12989 } \
12990 } while(0)
12991
12992
12993 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
12994 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
12995 get_float_exception_flags(&env->active_fpu.fp_status));
12996 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
12997 fpu_fprintf(f, "%3s: ", fregnames[i]);
12998 printfpr(&env->active_fpu.fpr[i]);
12999 }
13000
13001 #undef printfpr
13002 }
13003
13004 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
13005 /* Debug help: The architecture requires 32bit code to maintain proper
13006 sign-extended values on 64bit machines. */
13007
13008 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
13009
13010 static void
13011 cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
13012 fprintf_function cpu_fprintf,
13013 int flags)
13014 {
13015 int i;
13016
13017 if (!SIGN_EXT_P(env->active_tc.PC))
13018 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
13019 if (!SIGN_EXT_P(env->active_tc.HI[0]))
13020 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
13021 if (!SIGN_EXT_P(env->active_tc.LO[0]))
13022 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
13023 if (!SIGN_EXT_P(env->btarget))
13024 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
13025
13026 for (i = 0; i < 32; i++) {
13027 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
13028 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
13029 }
13030
13031 if (!SIGN_EXT_P(env->CP0_EPC))
13032 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
13033 if (!SIGN_EXT_P(env->lladdr))
13034 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
13035 }
13036 #endif
13037
13038 void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
13039 int flags)
13040 {
13041 int i;
13042
13043 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
13044 " LO=0x" TARGET_FMT_lx " ds %04x "
13045 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
13046 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
13047 env->hflags, env->btarget, env->bcond);
13048 for (i = 0; i < 32; i++) {
13049 if ((i & 3) == 0)
13050 cpu_fprintf(f, "GPR%02d:", i);
13051 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
13052 if ((i & 3) == 3)
13053 cpu_fprintf(f, "\n");
13054 }
13055
13056 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
13057 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
13058 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
13059 env->CP0_Config0, env->CP0_Config1, env->lladdr);
13060 if (env->hflags & MIPS_HFLAG_FPU)
13061 fpu_dump_state(env, f, cpu_fprintf, flags);
13062 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
13063 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
13064 #endif
13065 }
13066
13067 static void mips_tcg_init(void)
13068 {
13069 int i;
13070 static int inited;
13071
13072 /* Initialize various static tables. */
13073 if (inited)
13074 return;
13075
13076 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
13077 TCGV_UNUSED(cpu_gpr[0]);
13078 for (i = 1; i < 32; i++)
13079 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
13080 offsetof(CPUMIPSState, active_tc.gpr[i]),
13081 regnames[i]);
13082
13083 for (i = 0; i < 32; i++) {
13084 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
13085 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
13086 }
13087
13088 cpu_PC = tcg_global_mem_new(TCG_AREG0,
13089 offsetof(CPUMIPSState, active_tc.PC), "PC");
13090 for (i = 0; i < MIPS_DSP_ACC; i++) {
13091 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
13092 offsetof(CPUMIPSState, active_tc.HI[i]),
13093 regnames_HI[i]);
13094 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
13095 offsetof(CPUMIPSState, active_tc.LO[i]),
13096 regnames_LO[i]);
13097 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
13098 offsetof(CPUMIPSState, active_tc.ACX[i]),
13099 regnames_ACX[i]);
13100 }
13101 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
13102 offsetof(CPUMIPSState, active_tc.DSPControl),
13103 "DSPControl");
13104 bcond = tcg_global_mem_new(TCG_AREG0,
13105 offsetof(CPUMIPSState, bcond), "bcond");
13106 btarget = tcg_global_mem_new(TCG_AREG0,
13107 offsetof(CPUMIPSState, btarget), "btarget");
13108 hflags = tcg_global_mem_new_i32(TCG_AREG0,
13109 offsetof(CPUMIPSState, hflags), "hflags");
13110
13111 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
13112 offsetof(CPUMIPSState, active_fpu.fcr0),
13113 "fcr0");
13114 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
13115 offsetof(CPUMIPSState, active_fpu.fcr31),
13116 "fcr31");
13117
13118 /* register helpers */
13119 #define GEN_HELPER 2
13120 #include "helper.h"
13121
13122 inited = 1;
13123 }
13124
13125 #include "translate_init.c"
13126
13127 MIPSCPU *cpu_mips_init(const char *cpu_model)
13128 {
13129 MIPSCPU *cpu;
13130 CPUMIPSState *env;
13131 const mips_def_t *def;
13132
13133 def = cpu_mips_find_by_name(cpu_model);
13134 if (!def)
13135 return NULL;
13136 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
13137 env = &cpu->env;
13138 env->cpu_model = def;
13139 env->cpu_model_str = cpu_model;
13140
13141 #ifndef CONFIG_USER_ONLY
13142 mmu_init(env, def);
13143 #endif
13144 fpu_init(env, def);
13145 mvp_init(env, def);
13146 mips_tcg_init();
13147 cpu_reset(CPU(cpu));
13148 qemu_init_vcpu(env);
13149 return cpu;
13150 }
13151
13152 void cpu_state_reset(CPUMIPSState *env)
13153 {
13154 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
13155 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
13156 log_cpu_state(env, 0);
13157 }
13158
13159 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
13160 tlb_flush(env, 1);
13161
13162 /* Reset registers to their default values */
13163 env->CP0_PRid = env->cpu_model->CP0_PRid;
13164 env->CP0_Config0 = env->cpu_model->CP0_Config0;
13165 #ifdef TARGET_WORDS_BIGENDIAN
13166 env->CP0_Config0 |= (1 << CP0C0_BE);
13167 #endif
13168 env->CP0_Config1 = env->cpu_model->CP0_Config1;
13169 env->CP0_Config2 = env->cpu_model->CP0_Config2;
13170 env->CP0_Config3 = env->cpu_model->CP0_Config3;
13171 env->CP0_Config6 = env->cpu_model->CP0_Config6;
13172 env->CP0_Config7 = env->cpu_model->CP0_Config7;
13173 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
13174 << env->cpu_model->CP0_LLAddr_shift;
13175 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
13176 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
13177 env->CCRes = env->cpu_model->CCRes;
13178 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
13179 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
13180 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
13181 env->current_tc = 0;
13182 env->SEGBITS = env->cpu_model->SEGBITS;
13183 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
13184 #if defined(TARGET_MIPS64)
13185 if (env->cpu_model->insn_flags & ISA_MIPS3) {
13186 env->SEGMask |= 3ULL << 62;
13187 }
13188 #endif
13189 env->PABITS = env->cpu_model->PABITS;
13190 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
13191 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
13192 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
13193 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
13194 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
13195 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
13196 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
13197 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
13198 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
13199 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
13200 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
13201 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
13202 env->insn_flags = env->cpu_model->insn_flags;
13203
13204 #if defined(CONFIG_USER_ONLY)
13205 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
13206 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
13207 hardware registers. */
13208 env->CP0_HWREna |= 0x0000000F;
13209 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
13210 env->CP0_Status |= (1 << CP0St_CU1);
13211 }
13212 #else
13213 if (env->hflags & MIPS_HFLAG_BMASK) {
13214 /* If the exception was raised from a delay slot,
13215 come back to the jump. */
13216 env->CP0_ErrorEPC = env->active_tc.PC - 4;
13217 } else {
13218 env->CP0_ErrorEPC = env->active_tc.PC;
13219 }
13220 env->active_tc.PC = (int32_t)0xBFC00000;
13221 env->CP0_Random = env->tlb->nb_tlb - 1;
13222 env->tlb->tlb_in_use = env->tlb->nb_tlb;
13223 env->CP0_Wired = 0;
13224 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
13225 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
13226 /* vectored interrupts not implemented, timer on int 7,
13227 no performance counters. */
13228 env->CP0_IntCtl = 0xe0000000;
13229 {
13230 int i;
13231
13232 for (i = 0; i < 7; i++) {
13233 env->CP0_WatchLo[i] = 0;
13234 env->CP0_WatchHi[i] = 0x80000000;
13235 }
13236 env->CP0_WatchLo[7] = 0;
13237 env->CP0_WatchHi[7] = 0;
13238 }
13239 /* Count register increments in debug mode, EJTAG version 1 */
13240 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
13241
13242 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
13243 int i;
13244
13245 /* Only TC0 on VPE 0 starts as active. */
13246 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
13247 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
13248 env->tcs[i].CP0_TCHalt = 1;
13249 }
13250 env->active_tc.CP0_TCHalt = 1;
13251 env->halted = 1;
13252
13253 if (!env->cpu_index) {
13254 /* VPE0 starts up enabled. */
13255 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
13256 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
13257
13258 /* TC0 starts up unhalted. */
13259 env->halted = 0;
13260 env->active_tc.CP0_TCHalt = 0;
13261 env->tcs[0].CP0_TCHalt = 0;
13262 /* With thread 0 active. */
13263 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
13264 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
13265 }
13266 }
13267 #endif
13268 compute_hflags(env);
13269 env->exception_index = EXCP_NONE;
13270 }
13271
13272 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
13273 {
13274 env->active_tc.PC = gen_opc_pc[pc_pos];
13275 env->hflags &= ~MIPS_HFLAG_BMASK;
13276 env->hflags |= gen_opc_hflags[pc_pos];
13277 }