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