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