]> git.proxmox.com Git - qemu.git/blob - target-mips/translate.c
target-mips: fix DINSU instruction
[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 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <stdarg.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <inttypes.h>
27
28 #include "cpu.h"
29 #include "exec-all.h"
30 #include "disas.h"
31 #include "tcg-op.h"
32 #include "qemu-common.h"
33
34 #include "helper.h"
35 #define GEN_HELPER 1
36 #include "helper.h"
37
38 //#define MIPS_DEBUG_DISAS
39 //#define MIPS_DEBUG_SIGN_EXTENSIONS
40
41 /* MIPS major opcodes */
42 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
43
44 enum {
45 /* indirect opcode tables */
46 OPC_SPECIAL = (0x00 << 26),
47 OPC_REGIMM = (0x01 << 26),
48 OPC_CP0 = (0x10 << 26),
49 OPC_CP1 = (0x11 << 26),
50 OPC_CP2 = (0x12 << 26),
51 OPC_CP3 = (0x13 << 26),
52 OPC_SPECIAL2 = (0x1C << 26),
53 OPC_SPECIAL3 = (0x1F << 26),
54 /* arithmetic with immediate */
55 OPC_ADDI = (0x08 << 26),
56 OPC_ADDIU = (0x09 << 26),
57 OPC_SLTI = (0x0A << 26),
58 OPC_SLTIU = (0x0B << 26),
59 /* logic with immediate */
60 OPC_ANDI = (0x0C << 26),
61 OPC_ORI = (0x0D << 26),
62 OPC_XORI = (0x0E << 26),
63 OPC_LUI = (0x0F << 26),
64 /* arithmetic with immediate */
65 OPC_DADDI = (0x18 << 26),
66 OPC_DADDIU = (0x19 << 26),
67 /* Jump and branches */
68 OPC_J = (0x02 << 26),
69 OPC_JAL = (0x03 << 26),
70 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
71 OPC_BEQL = (0x14 << 26),
72 OPC_BNE = (0x05 << 26),
73 OPC_BNEL = (0x15 << 26),
74 OPC_BLEZ = (0x06 << 26),
75 OPC_BLEZL = (0x16 << 26),
76 OPC_BGTZ = (0x07 << 26),
77 OPC_BGTZL = (0x17 << 26),
78 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
79 /* Load and stores */
80 OPC_LDL = (0x1A << 26),
81 OPC_LDR = (0x1B << 26),
82 OPC_LB = (0x20 << 26),
83 OPC_LH = (0x21 << 26),
84 OPC_LWL = (0x22 << 26),
85 OPC_LW = (0x23 << 26),
86 OPC_LBU = (0x24 << 26),
87 OPC_LHU = (0x25 << 26),
88 OPC_LWR = (0x26 << 26),
89 OPC_LWU = (0x27 << 26),
90 OPC_SB = (0x28 << 26),
91 OPC_SH = (0x29 << 26),
92 OPC_SWL = (0x2A << 26),
93 OPC_SW = (0x2B << 26),
94 OPC_SDL = (0x2C << 26),
95 OPC_SDR = (0x2D << 26),
96 OPC_SWR = (0x2E << 26),
97 OPC_LL = (0x30 << 26),
98 OPC_LLD = (0x34 << 26),
99 OPC_LD = (0x37 << 26),
100 OPC_SC = (0x38 << 26),
101 OPC_SCD = (0x3C << 26),
102 OPC_SD = (0x3F << 26),
103 /* Floating point load/store */
104 OPC_LWC1 = (0x31 << 26),
105 OPC_LWC2 = (0x32 << 26),
106 OPC_LDC1 = (0x35 << 26),
107 OPC_LDC2 = (0x36 << 26),
108 OPC_SWC1 = (0x39 << 26),
109 OPC_SWC2 = (0x3A << 26),
110 OPC_SDC1 = (0x3D << 26),
111 OPC_SDC2 = (0x3E << 26),
112 /* MDMX ASE specific */
113 OPC_MDMX = (0x1E << 26),
114 /* Cache and prefetch */
115 OPC_CACHE = (0x2F << 26),
116 OPC_PREF = (0x33 << 26),
117 /* Reserved major opcode */
118 OPC_MAJOR3B_RESERVED = (0x3B << 26),
119 };
120
121 /* MIPS special opcodes */
122 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
123
124 enum {
125 /* Shifts */
126 OPC_SLL = 0x00 | OPC_SPECIAL,
127 /* NOP is SLL r0, r0, 0 */
128 /* SSNOP is SLL r0, r0, 1 */
129 /* EHB is SLL r0, r0, 3 */
130 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
131 OPC_SRA = 0x03 | OPC_SPECIAL,
132 OPC_SLLV = 0x04 | OPC_SPECIAL,
133 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
137 OPC_DSRAV = 0x17 | OPC_SPECIAL,
138 OPC_DSLL = 0x38 | OPC_SPECIAL,
139 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
140 OPC_DSRA = 0x3B | OPC_SPECIAL,
141 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
142 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
143 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
144 /* Multiplication / division */
145 OPC_MULT = 0x18 | OPC_SPECIAL,
146 OPC_MULTU = 0x19 | OPC_SPECIAL,
147 OPC_DIV = 0x1A | OPC_SPECIAL,
148 OPC_DIVU = 0x1B | OPC_SPECIAL,
149 OPC_DMULT = 0x1C | OPC_SPECIAL,
150 OPC_DMULTU = 0x1D | OPC_SPECIAL,
151 OPC_DDIV = 0x1E | OPC_SPECIAL,
152 OPC_DDIVU = 0x1F | OPC_SPECIAL,
153 /* 2 registers arithmetic / logic */
154 OPC_ADD = 0x20 | OPC_SPECIAL,
155 OPC_ADDU = 0x21 | OPC_SPECIAL,
156 OPC_SUB = 0x22 | OPC_SPECIAL,
157 OPC_SUBU = 0x23 | OPC_SPECIAL,
158 OPC_AND = 0x24 | OPC_SPECIAL,
159 OPC_OR = 0x25 | OPC_SPECIAL,
160 OPC_XOR = 0x26 | OPC_SPECIAL,
161 OPC_NOR = 0x27 | OPC_SPECIAL,
162 OPC_SLT = 0x2A | OPC_SPECIAL,
163 OPC_SLTU = 0x2B | OPC_SPECIAL,
164 OPC_DADD = 0x2C | OPC_SPECIAL,
165 OPC_DADDU = 0x2D | OPC_SPECIAL,
166 OPC_DSUB = 0x2E | OPC_SPECIAL,
167 OPC_DSUBU = 0x2F | OPC_SPECIAL,
168 /* Jumps */
169 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
170 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
171 /* Traps */
172 OPC_TGE = 0x30 | OPC_SPECIAL,
173 OPC_TGEU = 0x31 | OPC_SPECIAL,
174 OPC_TLT = 0x32 | OPC_SPECIAL,
175 OPC_TLTU = 0x33 | OPC_SPECIAL,
176 OPC_TEQ = 0x34 | OPC_SPECIAL,
177 OPC_TNE = 0x36 | OPC_SPECIAL,
178 /* HI / LO registers load & stores */
179 OPC_MFHI = 0x10 | OPC_SPECIAL,
180 OPC_MTHI = 0x11 | OPC_SPECIAL,
181 OPC_MFLO = 0x12 | OPC_SPECIAL,
182 OPC_MTLO = 0x13 | OPC_SPECIAL,
183 /* Conditional moves */
184 OPC_MOVZ = 0x0A | OPC_SPECIAL,
185 OPC_MOVN = 0x0B | OPC_SPECIAL,
186
187 OPC_MOVCI = 0x01 | OPC_SPECIAL,
188
189 /* Special */
190 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
191 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
192 OPC_BREAK = 0x0D | OPC_SPECIAL,
193 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
194 OPC_SYNC = 0x0F | OPC_SPECIAL,
195
196 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
197 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
198 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
199 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
200 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
201 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
202 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
203 };
204
205 /* Multiplication variants of the vr54xx. */
206 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
207
208 enum {
209 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
210 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
211 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
212 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
213 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
214 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
215 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
216 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
217 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
218 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
219 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
220 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
221 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
222 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
223 };
224
225 /* REGIMM (rt field) opcodes */
226 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
227
228 enum {
229 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
230 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
231 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
232 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
233 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
234 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
235 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
236 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
237 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
238 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
239 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
240 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
241 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
242 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
243 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
244 };
245
246 /* Special2 opcodes */
247 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
248
249 enum {
250 /* Multiply & xxx operations */
251 OPC_MADD = 0x00 | OPC_SPECIAL2,
252 OPC_MADDU = 0x01 | OPC_SPECIAL2,
253 OPC_MUL = 0x02 | OPC_SPECIAL2,
254 OPC_MSUB = 0x04 | OPC_SPECIAL2,
255 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
256 /* Misc */
257 OPC_CLZ = 0x20 | OPC_SPECIAL2,
258 OPC_CLO = 0x21 | OPC_SPECIAL2,
259 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
260 OPC_DCLO = 0x25 | OPC_SPECIAL2,
261 /* Special */
262 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
263 };
264
265 /* Special3 opcodes */
266 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
267
268 enum {
269 OPC_EXT = 0x00 | OPC_SPECIAL3,
270 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
271 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
272 OPC_DEXT = 0x03 | OPC_SPECIAL3,
273 OPC_INS = 0x04 | OPC_SPECIAL3,
274 OPC_DINSM = 0x05 | OPC_SPECIAL3,
275 OPC_DINSU = 0x06 | OPC_SPECIAL3,
276 OPC_DINS = 0x07 | OPC_SPECIAL3,
277 OPC_FORK = 0x08 | OPC_SPECIAL3,
278 OPC_YIELD = 0x09 | OPC_SPECIAL3,
279 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
280 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
281 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
282 };
283
284 /* BSHFL opcodes */
285 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
286
287 enum {
288 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
289 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
290 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
291 };
292
293 /* DBSHFL opcodes */
294 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
295
296 enum {
297 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
298 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
299 };
300
301 /* Coprocessor 0 (rs field) */
302 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
303
304 enum {
305 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
306 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
307 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
308 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
309 OPC_MFTR = (0x08 << 21) | OPC_CP0,
310 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
311 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
312 OPC_MTTR = (0x0C << 21) | OPC_CP0,
313 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
314 OPC_C0 = (0x10 << 21) | OPC_CP0,
315 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
316 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
317 };
318
319 /* MFMC0 opcodes */
320 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
321
322 enum {
323 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
324 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
325 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
326 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
327 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
328 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
329 };
330
331 /* Coprocessor 0 (with rs == C0) */
332 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
333
334 enum {
335 OPC_TLBR = 0x01 | OPC_C0,
336 OPC_TLBWI = 0x02 | OPC_C0,
337 OPC_TLBWR = 0x06 | OPC_C0,
338 OPC_TLBP = 0x08 | OPC_C0,
339 OPC_RFE = 0x10 | OPC_C0,
340 OPC_ERET = 0x18 | OPC_C0,
341 OPC_DERET = 0x1F | OPC_C0,
342 OPC_WAIT = 0x20 | OPC_C0,
343 };
344
345 /* Coprocessor 1 (rs field) */
346 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
347
348 enum {
349 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
350 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
351 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
352 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
353 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
354 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
355 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
356 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
357 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
358 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
359 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
360 OPC_S_FMT = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
361 OPC_D_FMT = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
362 OPC_E_FMT = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
363 OPC_Q_FMT = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
364 OPC_W_FMT = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
365 OPC_L_FMT = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
366 OPC_PS_FMT = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
367 };
368
369 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
370 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
371
372 enum {
373 OPC_BC1F = (0x00 << 16) | OPC_BC1,
374 OPC_BC1T = (0x01 << 16) | OPC_BC1,
375 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
376 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
377 };
378
379 enum {
380 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
381 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
382 };
383
384 enum {
385 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
386 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
387 };
388
389 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
390
391 enum {
392 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
393 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
394 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
395 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
396 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
397 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
398 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
399 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
400 OPC_BC2 = (0x08 << 21) | OPC_CP2,
401 };
402
403 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
404
405 enum {
406 OPC_LWXC1 = 0x00 | OPC_CP3,
407 OPC_LDXC1 = 0x01 | OPC_CP3,
408 OPC_LUXC1 = 0x05 | OPC_CP3,
409 OPC_SWXC1 = 0x08 | OPC_CP3,
410 OPC_SDXC1 = 0x09 | OPC_CP3,
411 OPC_SUXC1 = 0x0D | OPC_CP3,
412 OPC_PREFX = 0x0F | OPC_CP3,
413 OPC_ALNV_PS = 0x1E | OPC_CP3,
414 OPC_MADD_S = 0x20 | OPC_CP3,
415 OPC_MADD_D = 0x21 | OPC_CP3,
416 OPC_MADD_PS = 0x26 | OPC_CP3,
417 OPC_MSUB_S = 0x28 | OPC_CP3,
418 OPC_MSUB_D = 0x29 | OPC_CP3,
419 OPC_MSUB_PS = 0x2E | OPC_CP3,
420 OPC_NMADD_S = 0x30 | OPC_CP3,
421 OPC_NMADD_D = 0x31 | OPC_CP3,
422 OPC_NMADD_PS= 0x36 | OPC_CP3,
423 OPC_NMSUB_S = 0x38 | OPC_CP3,
424 OPC_NMSUB_D = 0x39 | OPC_CP3,
425 OPC_NMSUB_PS= 0x3E | OPC_CP3,
426 };
427
428 /* global register indices */
429 static TCGv_ptr cpu_env;
430 static TCGv cpu_gpr[32], cpu_PC;
431 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
432 static TCGv cpu_dspctrl, btarget, bcond;
433 static TCGv_i32 hflags;
434 static TCGv_i32 fpu_fcr0, fpu_fcr31;
435
436 #include "gen-icount.h"
437
438 #define gen_helper_0i(name, arg) do { \
439 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
440 gen_helper_##name(helper_tmp); \
441 tcg_temp_free_i32(helper_tmp); \
442 } while(0)
443
444 #define gen_helper_1i(name, arg1, arg2) do { \
445 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
446 gen_helper_##name(arg1, helper_tmp); \
447 tcg_temp_free_i32(helper_tmp); \
448 } while(0)
449
450 #define gen_helper_2i(name, arg1, arg2, arg3) do { \
451 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
452 gen_helper_##name(arg1, arg2, helper_tmp); \
453 tcg_temp_free_i32(helper_tmp); \
454 } while(0)
455
456 #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do { \
457 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
458 gen_helper_##name(arg1, arg2, arg3, helper_tmp); \
459 tcg_temp_free_i32(helper_tmp); \
460 } while(0)
461
462 typedef struct DisasContext {
463 struct TranslationBlock *tb;
464 target_ulong pc, saved_pc;
465 uint32_t opcode;
466 int singlestep_enabled;
467 /* Routine used to access memory */
468 int mem_idx;
469 uint32_t hflags, saved_hflags;
470 int bstate;
471 target_ulong btarget;
472 } DisasContext;
473
474 enum {
475 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
476 * exception condition */
477 BS_STOP = 1, /* We want to stop translation for any reason */
478 BS_BRANCH = 2, /* We reached a branch condition */
479 BS_EXCP = 3, /* We reached an exception condition */
480 };
481
482 static const char *regnames[] =
483 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
484 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
485 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
486 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
487
488 static const char *regnames_HI[] =
489 { "HI0", "HI1", "HI2", "HI3", };
490
491 static const char *regnames_LO[] =
492 { "LO0", "LO1", "LO2", "LO3", };
493
494 static const char *regnames_ACX[] =
495 { "ACX0", "ACX1", "ACX2", "ACX3", };
496
497 static const char *fregnames[] =
498 { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
499 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
500 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
501 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
502
503 #ifdef MIPS_DEBUG_DISAS
504 #define MIPS_DEBUG(fmt, ...) \
505 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
506 TARGET_FMT_lx ": %08x " fmt "\n", \
507 ctx->pc, ctx->opcode , ## __VA_ARGS__)
508 #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
509 #else
510 #define MIPS_DEBUG(fmt, ...) do { } while(0)
511 #define LOG_DISAS(...) do { } while (0)
512 #endif
513
514 #define MIPS_INVAL(op) \
515 do { \
516 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
517 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
518 } while (0)
519
520 /* General purpose registers moves. */
521 static inline void gen_load_gpr (TCGv t, int reg)
522 {
523 if (reg == 0)
524 tcg_gen_movi_tl(t, 0);
525 else
526 tcg_gen_mov_tl(t, cpu_gpr[reg]);
527 }
528
529 static inline void gen_store_gpr (TCGv t, int reg)
530 {
531 if (reg != 0)
532 tcg_gen_mov_tl(cpu_gpr[reg], t);
533 }
534
535 /* Moves to/from ACX register. */
536 static inline void gen_load_ACX (TCGv t, int reg)
537 {
538 tcg_gen_mov_tl(t, cpu_ACX[reg]);
539 }
540
541 static inline void gen_store_ACX (TCGv t, int reg)
542 {
543 tcg_gen_mov_tl(cpu_ACX[reg], t);
544 }
545
546 /* Moves to/from shadow registers. */
547 static inline void gen_load_srsgpr (int from, int to)
548 {
549 TCGv t0 = tcg_temp_new();
550
551 if (from == 0)
552 tcg_gen_movi_tl(t0, 0);
553 else {
554 TCGv_i32 t2 = tcg_temp_new_i32();
555 TCGv_ptr addr = tcg_temp_new_ptr();
556
557 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
558 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
559 tcg_gen_andi_i32(t2, t2, 0xf);
560 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
561 tcg_gen_ext_i32_ptr(addr, t2);
562 tcg_gen_add_ptr(addr, cpu_env, addr);
563
564 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
565 tcg_temp_free_ptr(addr);
566 tcg_temp_free_i32(t2);
567 }
568 gen_store_gpr(t0, to);
569 tcg_temp_free(t0);
570 }
571
572 static inline void gen_store_srsgpr (int from, int to)
573 {
574 if (to != 0) {
575 TCGv t0 = tcg_temp_new();
576 TCGv_i32 t2 = tcg_temp_new_i32();
577 TCGv_ptr addr = tcg_temp_new_ptr();
578
579 gen_load_gpr(t0, from);
580 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
581 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
582 tcg_gen_andi_i32(t2, t2, 0xf);
583 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
584 tcg_gen_ext_i32_ptr(addr, t2);
585 tcg_gen_add_ptr(addr, cpu_env, addr);
586
587 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
588 tcg_temp_free_ptr(addr);
589 tcg_temp_free_i32(t2);
590 tcg_temp_free(t0);
591 }
592 }
593
594 /* Floating point register moves. */
595 static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
596 {
597 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
598 }
599
600 static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
601 {
602 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
603 }
604
605 static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
606 {
607 tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
608 }
609
610 static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
611 {
612 tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
613 }
614
615 static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
616 {
617 if (ctx->hflags & MIPS_HFLAG_F64) {
618 tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
619 } else {
620 TCGv_i32 t0 = tcg_temp_new_i32();
621 TCGv_i32 t1 = tcg_temp_new_i32();
622 gen_load_fpr32(t0, reg & ~1);
623 gen_load_fpr32(t1, reg | 1);
624 tcg_gen_concat_i32_i64(t, t0, t1);
625 tcg_temp_free_i32(t0);
626 tcg_temp_free_i32(t1);
627 }
628 }
629
630 static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
631 {
632 if (ctx->hflags & MIPS_HFLAG_F64) {
633 tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
634 } else {
635 TCGv_i64 t0 = tcg_temp_new_i64();
636 TCGv_i32 t1 = tcg_temp_new_i32();
637 tcg_gen_trunc_i64_i32(t1, t);
638 gen_store_fpr32(t1, reg & ~1);
639 tcg_gen_shri_i64(t0, t, 32);
640 tcg_gen_trunc_i64_i32(t1, t0);
641 gen_store_fpr32(t1, reg | 1);
642 tcg_temp_free_i32(t1);
643 tcg_temp_free_i64(t0);
644 }
645 }
646
647 static inline int get_fp_bit (int cc)
648 {
649 if (cc)
650 return 24 + cc;
651 else
652 return 23;
653 }
654
655 #define FOP_CONDS(type, fmt, bits) \
656 static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a, \
657 TCGv_i##bits b, int cc) \
658 { \
659 switch (n) { \
660 case 0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc); break;\
661 case 1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc); break;\
662 case 2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc); break;\
663 case 3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc); break;\
664 case 4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc); break;\
665 case 5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc); break;\
666 case 6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc); break;\
667 case 7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc); break;\
668 case 8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc); break;\
669 case 9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
670 case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc); break;\
671 case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc); break;\
672 case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc); break;\
673 case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc); break;\
674 case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc); break;\
675 case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc); break;\
676 default: abort(); \
677 } \
678 }
679
680 FOP_CONDS(, d, 64)
681 FOP_CONDS(abs, d, 64)
682 FOP_CONDS(, s, 32)
683 FOP_CONDS(abs, s, 32)
684 FOP_CONDS(, ps, 64)
685 FOP_CONDS(abs, ps, 64)
686 #undef FOP_CONDS
687
688 /* Tests */
689 #define OP_COND(name, cond) \
690 static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \
691 { \
692 int l1 = gen_new_label(); \
693 int l2 = gen_new_label(); \
694 \
695 tcg_gen_brcond_tl(cond, t0, t1, l1); \
696 tcg_gen_movi_tl(ret, 0); \
697 tcg_gen_br(l2); \
698 gen_set_label(l1); \
699 tcg_gen_movi_tl(ret, 1); \
700 gen_set_label(l2); \
701 }
702 OP_COND(eq, TCG_COND_EQ);
703 OP_COND(ne, TCG_COND_NE);
704 OP_COND(ge, TCG_COND_GE);
705 OP_COND(geu, TCG_COND_GEU);
706 OP_COND(lt, TCG_COND_LT);
707 OP_COND(ltu, TCG_COND_LTU);
708 #undef OP_COND
709
710 #define OP_CONDI(name, cond) \
711 static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \
712 { \
713 int l1 = gen_new_label(); \
714 int l2 = gen_new_label(); \
715 \
716 tcg_gen_brcondi_tl(cond, t0, val, l1); \
717 tcg_gen_movi_tl(ret, 0); \
718 tcg_gen_br(l2); \
719 gen_set_label(l1); \
720 tcg_gen_movi_tl(ret, 1); \
721 gen_set_label(l2); \
722 }
723 OP_CONDI(lti, TCG_COND_LT);
724 OP_CONDI(ltiu, TCG_COND_LTU);
725 #undef OP_CONDI
726
727 #define OP_CONDZ(name, cond) \
728 static inline void glue(gen_op_, name) (TCGv ret, TCGv t0) \
729 { \
730 int l1 = gen_new_label(); \
731 int l2 = gen_new_label(); \
732 \
733 tcg_gen_brcondi_tl(cond, t0, 0, l1); \
734 tcg_gen_movi_tl(ret, 0); \
735 tcg_gen_br(l2); \
736 gen_set_label(l1); \
737 tcg_gen_movi_tl(ret, 1); \
738 gen_set_label(l2); \
739 }
740 OP_CONDZ(gez, TCG_COND_GE);
741 OP_CONDZ(gtz, TCG_COND_GT);
742 OP_CONDZ(lez, TCG_COND_LE);
743 OP_CONDZ(ltz, TCG_COND_LT);
744 #undef OP_CONDZ
745
746 static inline void gen_save_pc(target_ulong pc)
747 {
748 tcg_gen_movi_tl(cpu_PC, pc);
749 }
750
751 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
752 {
753 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
754 if (do_save_pc && ctx->pc != ctx->saved_pc) {
755 gen_save_pc(ctx->pc);
756 ctx->saved_pc = ctx->pc;
757 }
758 if (ctx->hflags != ctx->saved_hflags) {
759 tcg_gen_movi_i32(hflags, ctx->hflags);
760 ctx->saved_hflags = ctx->hflags;
761 switch (ctx->hflags & MIPS_HFLAG_BMASK) {
762 case MIPS_HFLAG_BR:
763 break;
764 case MIPS_HFLAG_BC:
765 case MIPS_HFLAG_BL:
766 case MIPS_HFLAG_B:
767 tcg_gen_movi_tl(btarget, ctx->btarget);
768 break;
769 }
770 }
771 }
772
773 static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
774 {
775 ctx->saved_hflags = ctx->hflags;
776 switch (ctx->hflags & MIPS_HFLAG_BMASK) {
777 case MIPS_HFLAG_BR:
778 break;
779 case MIPS_HFLAG_BC:
780 case MIPS_HFLAG_BL:
781 case MIPS_HFLAG_B:
782 ctx->btarget = env->btarget;
783 break;
784 }
785 }
786
787 static inline void
788 generate_exception_err (DisasContext *ctx, int excp, int err)
789 {
790 TCGv_i32 texcp = tcg_const_i32(excp);
791 TCGv_i32 terr = tcg_const_i32(err);
792 save_cpu_state(ctx, 1);
793 gen_helper_raise_exception_err(texcp, terr);
794 tcg_temp_free_i32(terr);
795 tcg_temp_free_i32(texcp);
796 }
797
798 static inline void
799 generate_exception (DisasContext *ctx, int excp)
800 {
801 save_cpu_state(ctx, 1);
802 gen_helper_0i(raise_exception, excp);
803 }
804
805 /* Addresses computation */
806 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
807 {
808 tcg_gen_add_tl(ret, arg0, arg1);
809
810 #if defined(TARGET_MIPS64)
811 /* For compatibility with 32-bit code, data reference in user mode
812 with Status_UX = 0 should be casted to 32-bit and sign extended.
813 See the MIPS64 PRA manual, section 4.10. */
814 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
815 !(ctx->hflags & MIPS_HFLAG_UX)) {
816 tcg_gen_ext32s_i64(ret, ret);
817 }
818 #endif
819 }
820
821 static inline void check_cp0_enabled(DisasContext *ctx)
822 {
823 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
824 generate_exception_err(ctx, EXCP_CpU, 0);
825 }
826
827 static inline void check_cp1_enabled(DisasContext *ctx)
828 {
829 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
830 generate_exception_err(ctx, EXCP_CpU, 1);
831 }
832
833 /* Verify that the processor is running with COP1X instructions enabled.
834 This is associated with the nabla symbol in the MIPS32 and MIPS64
835 opcode tables. */
836
837 static inline void check_cop1x(DisasContext *ctx)
838 {
839 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
840 generate_exception(ctx, EXCP_RI);
841 }
842
843 /* Verify that the processor is running with 64-bit floating-point
844 operations enabled. */
845
846 static inline void check_cp1_64bitmode(DisasContext *ctx)
847 {
848 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
849 generate_exception(ctx, EXCP_RI);
850 }
851
852 /*
853 * Verify if floating point register is valid; an operation is not defined
854 * if bit 0 of any register specification is set and the FR bit in the
855 * Status register equals zero, since the register numbers specify an
856 * even-odd pair of adjacent coprocessor general registers. When the FR bit
857 * in the Status register equals one, both even and odd register numbers
858 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
859 *
860 * Multiple 64 bit wide registers can be checked by calling
861 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
862 */
863 static inline void check_cp1_registers(DisasContext *ctx, int regs)
864 {
865 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
866 generate_exception(ctx, EXCP_RI);
867 }
868
869 /* This code generates a "reserved instruction" exception if the
870 CPU does not support the instruction set corresponding to flags. */
871 static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
872 {
873 if (unlikely(!(env->insn_flags & flags)))
874 generate_exception(ctx, EXCP_RI);
875 }
876
877 /* This code generates a "reserved instruction" exception if 64-bit
878 instructions are not enabled. */
879 static inline void check_mips_64(DisasContext *ctx)
880 {
881 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
882 generate_exception(ctx, EXCP_RI);
883 }
884
885 /* load/store instructions. */
886 #define OP_LD(insn,fname) \
887 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
888 { \
889 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
890 }
891 OP_LD(lb,ld8s);
892 OP_LD(lbu,ld8u);
893 OP_LD(lh,ld16s);
894 OP_LD(lhu,ld16u);
895 OP_LD(lw,ld32s);
896 #if defined(TARGET_MIPS64)
897 OP_LD(lwu,ld32u);
898 OP_LD(ld,ld64);
899 #endif
900 #undef OP_LD
901
902 #define OP_ST(insn,fname) \
903 static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
904 { \
905 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
906 }
907 OP_ST(sb,st8);
908 OP_ST(sh,st16);
909 OP_ST(sw,st32);
910 #if defined(TARGET_MIPS64)
911 OP_ST(sd,st64);
912 #endif
913 #undef OP_ST
914
915 #ifdef CONFIG_USER_ONLY
916 #define OP_LD_ATOMIC(insn,fname) \
917 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
918 { \
919 TCGv t0 = tcg_temp_new(); \
920 tcg_gen_mov_tl(t0, arg1); \
921 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
922 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr)); \
923 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval)); \
924 tcg_temp_free(t0); \
925 }
926 #else
927 #define OP_LD_ATOMIC(insn,fname) \
928 static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
929 { \
930 gen_helper_2i(insn, ret, arg1, ctx->mem_idx); \
931 }
932 #endif
933 OP_LD_ATOMIC(ll,ld32s);
934 #if defined(TARGET_MIPS64)
935 OP_LD_ATOMIC(lld,ld64);
936 #endif
937 #undef OP_LD_ATOMIC
938
939 #ifdef CONFIG_USER_ONLY
940 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
941 static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
942 { \
943 TCGv t0 = tcg_temp_new(); \
944 int l1 = gen_new_label(); \
945 int l2 = gen_new_label(); \
946 \
947 tcg_gen_andi_tl(t0, arg2, almask); \
948 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
949 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
950 generate_exception(ctx, EXCP_AdES); \
951 gen_set_label(l1); \
952 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr)); \
953 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
954 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
955 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg)); \
956 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval)); \
957 gen_helper_0i(raise_exception, EXCP_SC); \
958 gen_set_label(l2); \
959 tcg_gen_movi_tl(t0, 0); \
960 gen_store_gpr(t0, rt); \
961 tcg_temp_free(t0); \
962 }
963 #else
964 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
965 static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
966 { \
967 TCGv t0 = tcg_temp_new(); \
968 gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx); \
969 gen_store_gpr(t0, rt); \
970 tcg_temp_free(t0); \
971 }
972 #endif
973 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
974 #if defined(TARGET_MIPS64)
975 OP_ST_ATOMIC(scd,st64,ld64,0x7);
976 #endif
977 #undef OP_ST_ATOMIC
978
979 /* Load and store */
980 static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
981 int base, int16_t offset)
982 {
983 const char *opn = "ldst";
984 TCGv t0 = tcg_temp_new();
985 TCGv t1 = tcg_temp_new();
986
987 if (base == 0) {
988 tcg_gen_movi_tl(t0, offset);
989 } else if (offset == 0) {
990 gen_load_gpr(t0, base);
991 } else {
992 tcg_gen_movi_tl(t0, offset);
993 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
994 }
995 /* Don't do NOP if destination is zero: we must perform the actual
996 memory access. */
997 switch (opc) {
998 #if defined(TARGET_MIPS64)
999 case OPC_LWU:
1000 save_cpu_state(ctx, 0);
1001 op_ldst_lwu(t0, t0, ctx);
1002 gen_store_gpr(t0, rt);
1003 opn = "lwu";
1004 break;
1005 case OPC_LD:
1006 save_cpu_state(ctx, 0);
1007 op_ldst_ld(t0, t0, ctx);
1008 gen_store_gpr(t0, rt);
1009 opn = "ld";
1010 break;
1011 case OPC_LLD:
1012 save_cpu_state(ctx, 0);
1013 op_ldst_lld(t0, t0, ctx);
1014 gen_store_gpr(t0, rt);
1015 opn = "lld";
1016 break;
1017 case OPC_SD:
1018 save_cpu_state(ctx, 0);
1019 gen_load_gpr(t1, rt);
1020 op_ldst_sd(t1, t0, ctx);
1021 opn = "sd";
1022 break;
1023 case OPC_LDL:
1024 save_cpu_state(ctx, 1);
1025 gen_load_gpr(t1, rt);
1026 gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1027 gen_store_gpr(t1, rt);
1028 opn = "ldl";
1029 break;
1030 case OPC_SDL:
1031 save_cpu_state(ctx, 1);
1032 gen_load_gpr(t1, rt);
1033 gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1034 opn = "sdl";
1035 break;
1036 case OPC_LDR:
1037 save_cpu_state(ctx, 1);
1038 gen_load_gpr(t1, rt);
1039 gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1040 gen_store_gpr(t1, rt);
1041 opn = "ldr";
1042 break;
1043 case OPC_SDR:
1044 save_cpu_state(ctx, 1);
1045 gen_load_gpr(t1, rt);
1046 gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1047 opn = "sdr";
1048 break;
1049 #endif
1050 case OPC_LW:
1051 save_cpu_state(ctx, 0);
1052 op_ldst_lw(t0, t0, ctx);
1053 gen_store_gpr(t0, rt);
1054 opn = "lw";
1055 break;
1056 case OPC_SW:
1057 save_cpu_state(ctx, 0);
1058 gen_load_gpr(t1, rt);
1059 op_ldst_sw(t1, t0, ctx);
1060 opn = "sw";
1061 break;
1062 case OPC_LH:
1063 save_cpu_state(ctx, 0);
1064 op_ldst_lh(t0, t0, ctx);
1065 gen_store_gpr(t0, rt);
1066 opn = "lh";
1067 break;
1068 case OPC_SH:
1069 save_cpu_state(ctx, 0);
1070 gen_load_gpr(t1, rt);
1071 op_ldst_sh(t1, t0, ctx);
1072 opn = "sh";
1073 break;
1074 case OPC_LHU:
1075 save_cpu_state(ctx, 0);
1076 op_ldst_lhu(t0, t0, ctx);
1077 gen_store_gpr(t0, rt);
1078 opn = "lhu";
1079 break;
1080 case OPC_LB:
1081 save_cpu_state(ctx, 0);
1082 op_ldst_lb(t0, t0, ctx);
1083 gen_store_gpr(t0, rt);
1084 opn = "lb";
1085 break;
1086 case OPC_SB:
1087 save_cpu_state(ctx, 0);
1088 gen_load_gpr(t1, rt);
1089 op_ldst_sb(t1, t0, ctx);
1090 opn = "sb";
1091 break;
1092 case OPC_LBU:
1093 save_cpu_state(ctx, 0);
1094 op_ldst_lbu(t0, t0, ctx);
1095 gen_store_gpr(t0, rt);
1096 opn = "lbu";
1097 break;
1098 case OPC_LWL:
1099 save_cpu_state(ctx, 1);
1100 gen_load_gpr(t1, rt);
1101 gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1102 gen_store_gpr(t1, rt);
1103 opn = "lwl";
1104 break;
1105 case OPC_SWL:
1106 save_cpu_state(ctx, 1);
1107 gen_load_gpr(t1, rt);
1108 gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1109 opn = "swr";
1110 break;
1111 case OPC_LWR:
1112 save_cpu_state(ctx, 1);
1113 gen_load_gpr(t1, rt);
1114 gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1115 gen_store_gpr(t1, rt);
1116 opn = "lwr";
1117 break;
1118 case OPC_SWR:
1119 save_cpu_state(ctx, 1);
1120 gen_load_gpr(t1, rt);
1121 gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1122 opn = "swr";
1123 break;
1124 case OPC_LL:
1125 save_cpu_state(ctx, 1);
1126 op_ldst_ll(t0, t0, ctx);
1127 gen_store_gpr(t0, rt);
1128 opn = "ll";
1129 break;
1130 }
1131 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1132 tcg_temp_free(t0);
1133 tcg_temp_free(t1);
1134 }
1135
1136 /* Store conditional */
1137 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1138 int base, int16_t offset)
1139 {
1140 const char *opn = "st_cond";
1141 TCGv t0, t1;
1142
1143 t0 = tcg_temp_local_new();
1144
1145 if (base == 0) {
1146 tcg_gen_movi_tl(t0, offset);
1147 } else if (offset == 0) {
1148 gen_load_gpr(t0, base);
1149 } else {
1150 tcg_gen_movi_tl(t0, offset);
1151 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1152 }
1153 /* Don't do NOP if destination is zero: we must perform the actual
1154 memory access. */
1155
1156 t1 = tcg_temp_local_new();
1157 gen_load_gpr(t1, rt);
1158 switch (opc) {
1159 #if defined(TARGET_MIPS64)
1160 case OPC_SCD:
1161 save_cpu_state(ctx, 0);
1162 op_ldst_scd(t1, t0, rt, ctx);
1163 opn = "scd";
1164 break;
1165 #endif
1166 case OPC_SC:
1167 save_cpu_state(ctx, 1);
1168 op_ldst_sc(t1, t0, rt, ctx);
1169 opn = "sc";
1170 break;
1171 }
1172 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1173 tcg_temp_free(t1);
1174 tcg_temp_free(t0);
1175 }
1176
1177 /* Load and store */
1178 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1179 int base, int16_t offset)
1180 {
1181 const char *opn = "flt_ldst";
1182 TCGv t0 = tcg_temp_new();
1183
1184 if (base == 0) {
1185 tcg_gen_movi_tl(t0, offset);
1186 } else if (offset == 0) {
1187 gen_load_gpr(t0, base);
1188 } else {
1189 tcg_gen_movi_tl(t0, offset);
1190 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1191 }
1192 /* Don't do NOP if destination is zero: we must perform the actual
1193 memory access. */
1194 switch (opc) {
1195 case OPC_LWC1:
1196 {
1197 TCGv_i32 fp0 = tcg_temp_new_i32();
1198
1199 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1200 tcg_gen_trunc_tl_i32(fp0, t0);
1201 gen_store_fpr32(fp0, ft);
1202 tcg_temp_free_i32(fp0);
1203 }
1204 opn = "lwc1";
1205 break;
1206 case OPC_SWC1:
1207 {
1208 TCGv_i32 fp0 = tcg_temp_new_i32();
1209 TCGv t1 = tcg_temp_new();
1210
1211 gen_load_fpr32(fp0, ft);
1212 tcg_gen_extu_i32_tl(t1, fp0);
1213 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1214 tcg_temp_free(t1);
1215 tcg_temp_free_i32(fp0);
1216 }
1217 opn = "swc1";
1218 break;
1219 case OPC_LDC1:
1220 {
1221 TCGv_i64 fp0 = tcg_temp_new_i64();
1222
1223 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1224 gen_store_fpr64(ctx, fp0, ft);
1225 tcg_temp_free_i64(fp0);
1226 }
1227 opn = "ldc1";
1228 break;
1229 case OPC_SDC1:
1230 {
1231 TCGv_i64 fp0 = tcg_temp_new_i64();
1232
1233 gen_load_fpr64(ctx, fp0, ft);
1234 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1235 tcg_temp_free_i64(fp0);
1236 }
1237 opn = "sdc1";
1238 break;
1239 default:
1240 MIPS_INVAL(opn);
1241 generate_exception(ctx, EXCP_RI);
1242 goto out;
1243 }
1244 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1245 out:
1246 tcg_temp_free(t0);
1247 }
1248
1249 /* Arithmetic with immediate operand */
1250 static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1251 int rt, int rs, int16_t imm)
1252 {
1253 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1254 const char *opn = "imm arith";
1255
1256 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1257 /* If no destination, treat it as a NOP.
1258 For addi, we must generate the overflow exception when needed. */
1259 MIPS_DEBUG("NOP");
1260 return;
1261 }
1262 switch (opc) {
1263 case OPC_ADDI:
1264 {
1265 TCGv t0 = tcg_temp_local_new();
1266 TCGv t1 = tcg_temp_new();
1267 TCGv t2 = tcg_temp_new();
1268 int l1 = gen_new_label();
1269
1270 gen_load_gpr(t1, rs);
1271 tcg_gen_addi_tl(t0, t1, uimm);
1272 tcg_gen_ext32s_tl(t0, t0);
1273
1274 tcg_gen_xori_tl(t1, t1, ~uimm);
1275 tcg_gen_xori_tl(t2, t0, uimm);
1276 tcg_gen_and_tl(t1, t1, t2);
1277 tcg_temp_free(t2);
1278 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1279 tcg_temp_free(t1);
1280 /* operands of same sign, result different sign */
1281 generate_exception(ctx, EXCP_OVERFLOW);
1282 gen_set_label(l1);
1283 tcg_gen_ext32s_tl(t0, t0);
1284 gen_store_gpr(t0, rt);
1285 tcg_temp_free(t0);
1286 }
1287 opn = "addi";
1288 break;
1289 case OPC_ADDIU:
1290 if (rs != 0) {
1291 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1292 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1293 } else {
1294 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1295 }
1296 opn = "addiu";
1297 break;
1298 #if defined(TARGET_MIPS64)
1299 case OPC_DADDI:
1300 {
1301 TCGv t0 = tcg_temp_local_new();
1302 TCGv t1 = tcg_temp_new();
1303 TCGv t2 = tcg_temp_new();
1304 int l1 = gen_new_label();
1305
1306 gen_load_gpr(t1, rs);
1307 tcg_gen_addi_tl(t0, t1, uimm);
1308
1309 tcg_gen_xori_tl(t1, t1, ~uimm);
1310 tcg_gen_xori_tl(t2, t0, uimm);
1311 tcg_gen_and_tl(t1, t1, t2);
1312 tcg_temp_free(t2);
1313 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1314 tcg_temp_free(t1);
1315 /* operands of same sign, result different sign */
1316 generate_exception(ctx, EXCP_OVERFLOW);
1317 gen_set_label(l1);
1318 gen_store_gpr(t0, rt);
1319 tcg_temp_free(t0);
1320 }
1321 opn = "daddi";
1322 break;
1323 case OPC_DADDIU:
1324 if (rs != 0) {
1325 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1326 } else {
1327 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1328 }
1329 opn = "daddiu";
1330 break;
1331 #endif
1332 }
1333 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1334 }
1335
1336 /* Logic with immediate operand */
1337 static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1338 {
1339 target_ulong uimm;
1340 const char *opn = "imm logic";
1341
1342 if (rt == 0) {
1343 /* If no destination, treat it as a NOP. */
1344 MIPS_DEBUG("NOP");
1345 return;
1346 }
1347 uimm = (uint16_t)imm;
1348 switch (opc) {
1349 case OPC_ANDI:
1350 if (likely(rs != 0))
1351 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1352 else
1353 tcg_gen_movi_tl(cpu_gpr[rt], 0);
1354 opn = "andi";
1355 break;
1356 case OPC_ORI:
1357 if (rs != 0)
1358 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1359 else
1360 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1361 opn = "ori";
1362 break;
1363 case OPC_XORI:
1364 if (likely(rs != 0))
1365 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1366 else
1367 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1368 opn = "xori";
1369 break;
1370 case OPC_LUI:
1371 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1372 opn = "lui";
1373 break;
1374 }
1375 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1376 }
1377
1378 /* Set on less than with immediate operand */
1379 static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1380 {
1381 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1382 const char *opn = "imm arith";
1383 TCGv t0;
1384
1385 if (rt == 0) {
1386 /* If no destination, treat it as a NOP. */
1387 MIPS_DEBUG("NOP");
1388 return;
1389 }
1390 t0 = tcg_temp_new();
1391 gen_load_gpr(t0, rs);
1392 switch (opc) {
1393 case OPC_SLTI:
1394 gen_op_lti(cpu_gpr[rt], t0, uimm);
1395 opn = "slti";
1396 break;
1397 case OPC_SLTIU:
1398 gen_op_ltiu(cpu_gpr[rt], t0, uimm);
1399 opn = "sltiu";
1400 break;
1401 }
1402 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1403 tcg_temp_free(t0);
1404 }
1405
1406 /* Shifts with immediate operand */
1407 static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1408 int rt, int rs, int16_t imm)
1409 {
1410 target_ulong uimm = ((uint16_t)imm) & 0x1f;
1411 const char *opn = "imm shift";
1412 TCGv t0;
1413
1414 if (rt == 0) {
1415 /* If no destination, treat it as a NOP. */
1416 MIPS_DEBUG("NOP");
1417 return;
1418 }
1419
1420 t0 = tcg_temp_new();
1421 gen_load_gpr(t0, rs);
1422 switch (opc) {
1423 case OPC_SLL:
1424 tcg_gen_shli_tl(t0, t0, uimm);
1425 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1426 opn = "sll";
1427 break;
1428 case OPC_SRA:
1429 tcg_gen_ext32s_tl(t0, t0);
1430 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1431 opn = "sra";
1432 break;
1433 case OPC_SRL:
1434 switch ((ctx->opcode >> 21) & 0x1f) {
1435 case 0:
1436 if (uimm != 0) {
1437 tcg_gen_ext32u_tl(t0, t0);
1438 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1439 } else {
1440 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1441 }
1442 opn = "srl";
1443 break;
1444 case 1:
1445 /* rotr is decoded as srl on non-R2 CPUs */
1446 if (env->insn_flags & ISA_MIPS32R2) {
1447 if (uimm != 0) {
1448 TCGv_i32 t1 = tcg_temp_new_i32();
1449
1450 tcg_gen_trunc_tl_i32(t1, t0);
1451 tcg_gen_rotri_i32(t1, t1, uimm);
1452 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1453 tcg_temp_free_i32(t1);
1454 } else {
1455 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1456 }
1457 opn = "rotr";
1458 } else {
1459 if (uimm != 0) {
1460 tcg_gen_ext32u_tl(t0, t0);
1461 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1462 } else {
1463 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1464 }
1465 opn = "srl";
1466 }
1467 break;
1468 default:
1469 MIPS_INVAL("invalid srl flag");
1470 generate_exception(ctx, EXCP_RI);
1471 break;
1472 }
1473 break;
1474 #if defined(TARGET_MIPS64)
1475 case OPC_DSLL:
1476 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1477 opn = "dsll";
1478 break;
1479 case OPC_DSRA:
1480 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1481 opn = "dsra";
1482 break;
1483 case OPC_DSRL:
1484 switch ((ctx->opcode >> 21) & 0x1f) {
1485 case 0:
1486 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1487 opn = "dsrl";
1488 break;
1489 case 1:
1490 /* drotr is decoded as dsrl on non-R2 CPUs */
1491 if (env->insn_flags & ISA_MIPS32R2) {
1492 if (uimm != 0) {
1493 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1494 } else {
1495 tcg_gen_mov_tl(cpu_gpr[rt], t0);
1496 }
1497 opn = "drotr";
1498 } else {
1499 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1500 opn = "dsrl";
1501 }
1502 break;
1503 default:
1504 MIPS_INVAL("invalid dsrl flag");
1505 generate_exception(ctx, EXCP_RI);
1506 break;
1507 }
1508 break;
1509 case OPC_DSLL32:
1510 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1511 opn = "dsll32";
1512 break;
1513 case OPC_DSRA32:
1514 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1515 opn = "dsra32";
1516 break;
1517 case OPC_DSRL32:
1518 switch ((ctx->opcode >> 21) & 0x1f) {
1519 case 0:
1520 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1521 opn = "dsrl32";
1522 break;
1523 case 1:
1524 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1525 if (env->insn_flags & ISA_MIPS32R2) {
1526 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1527 opn = "drotr32";
1528 } else {
1529 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1530 opn = "dsrl32";
1531 }
1532 break;
1533 default:
1534 MIPS_INVAL("invalid dsrl32 flag");
1535 generate_exception(ctx, EXCP_RI);
1536 break;
1537 }
1538 break;
1539 #endif
1540 }
1541 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1542 tcg_temp_free(t0);
1543 }
1544
1545 /* Arithmetic */
1546 static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1547 int rd, int rs, int rt)
1548 {
1549 const char *opn = "arith";
1550
1551 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1552 && opc != OPC_DADD && opc != OPC_DSUB) {
1553 /* If no destination, treat it as a NOP.
1554 For add & sub, we must generate the overflow exception when needed. */
1555 MIPS_DEBUG("NOP");
1556 return;
1557 }
1558
1559 switch (opc) {
1560 case OPC_ADD:
1561 {
1562 TCGv t0 = tcg_temp_local_new();
1563 TCGv t1 = tcg_temp_new();
1564 TCGv t2 = tcg_temp_new();
1565 int l1 = gen_new_label();
1566
1567 gen_load_gpr(t1, rs);
1568 gen_load_gpr(t2, rt);
1569 tcg_gen_add_tl(t0, t1, t2);
1570 tcg_gen_ext32s_tl(t0, t0);
1571 tcg_gen_xor_tl(t1, t1, t2);
1572 tcg_gen_not_tl(t1, t1);
1573 tcg_gen_xor_tl(t2, t0, t2);
1574 tcg_gen_and_tl(t1, t1, t2);
1575 tcg_temp_free(t2);
1576 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1577 tcg_temp_free(t1);
1578 /* operands of same sign, result different sign */
1579 generate_exception(ctx, EXCP_OVERFLOW);
1580 gen_set_label(l1);
1581 gen_store_gpr(t0, rd);
1582 tcg_temp_free(t0);
1583 }
1584 opn = "add";
1585 break;
1586 case OPC_ADDU:
1587 if (rs != 0 && rt != 0) {
1588 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1589 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1590 } else if (rs == 0 && rt != 0) {
1591 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1592 } else if (rs != 0 && rt == 0) {
1593 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1594 } else {
1595 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1596 }
1597 opn = "addu";
1598 break;
1599 case OPC_SUB:
1600 {
1601 TCGv t0 = tcg_temp_local_new();
1602 TCGv t1 = tcg_temp_new();
1603 TCGv t2 = tcg_temp_new();
1604 int l1 = gen_new_label();
1605
1606 gen_load_gpr(t1, rs);
1607 gen_load_gpr(t2, rt);
1608 tcg_gen_sub_tl(t0, t1, t2);
1609 tcg_gen_ext32s_tl(t0, t0);
1610 tcg_gen_xor_tl(t2, t1, t2);
1611 tcg_gen_xor_tl(t1, t0, t1);
1612 tcg_gen_and_tl(t1, t1, t2);
1613 tcg_temp_free(t2);
1614 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1615 tcg_temp_free(t1);
1616 /* operands of different sign, first operand and result different sign */
1617 generate_exception(ctx, EXCP_OVERFLOW);
1618 gen_set_label(l1);
1619 gen_store_gpr(t0, rd);
1620 tcg_temp_free(t0);
1621 }
1622 opn = "sub";
1623 break;
1624 case OPC_SUBU:
1625 if (rs != 0 && rt != 0) {
1626 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1627 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1628 } else if (rs == 0 && rt != 0) {
1629 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1630 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1631 } else if (rs != 0 && rt == 0) {
1632 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1633 } else {
1634 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1635 }
1636 opn = "subu";
1637 break;
1638 #if defined(TARGET_MIPS64)
1639 case OPC_DADD:
1640 {
1641 TCGv t0 = tcg_temp_local_new();
1642 TCGv t1 = tcg_temp_new();
1643 TCGv t2 = tcg_temp_new();
1644 int l1 = gen_new_label();
1645
1646 gen_load_gpr(t1, rs);
1647 gen_load_gpr(t2, rt);
1648 tcg_gen_add_tl(t0, t1, t2);
1649 tcg_gen_xor_tl(t1, t1, t2);
1650 tcg_gen_not_tl(t1, t1);
1651 tcg_gen_xor_tl(t2, t0, t2);
1652 tcg_gen_and_tl(t1, t1, t2);
1653 tcg_temp_free(t2);
1654 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1655 tcg_temp_free(t1);
1656 /* operands of same sign, result different sign */
1657 generate_exception(ctx, EXCP_OVERFLOW);
1658 gen_set_label(l1);
1659 gen_store_gpr(t0, rd);
1660 tcg_temp_free(t0);
1661 }
1662 opn = "dadd";
1663 break;
1664 case OPC_DADDU:
1665 if (rs != 0 && rt != 0) {
1666 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1667 } else if (rs == 0 && rt != 0) {
1668 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1669 } else if (rs != 0 && rt == 0) {
1670 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1671 } else {
1672 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1673 }
1674 opn = "daddu";
1675 break;
1676 case OPC_DSUB:
1677 {
1678 TCGv t0 = tcg_temp_local_new();
1679 TCGv t1 = tcg_temp_new();
1680 TCGv t2 = tcg_temp_new();
1681 int l1 = gen_new_label();
1682
1683 gen_load_gpr(t1, rs);
1684 gen_load_gpr(t2, rt);
1685 tcg_gen_sub_tl(t0, t1, t2);
1686 tcg_gen_xor_tl(t2, t1, t2);
1687 tcg_gen_xor_tl(t1, t0, t1);
1688 tcg_gen_and_tl(t1, t1, t2);
1689 tcg_temp_free(t2);
1690 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1691 tcg_temp_free(t1);
1692 /* operands of different sign, first operand and result different sign */
1693 generate_exception(ctx, EXCP_OVERFLOW);
1694 gen_set_label(l1);
1695 gen_store_gpr(t0, rd);
1696 tcg_temp_free(t0);
1697 }
1698 opn = "dsub";
1699 break;
1700 case OPC_DSUBU:
1701 if (rs != 0 && rt != 0) {
1702 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1703 } else if (rs == 0 && rt != 0) {
1704 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1705 } else if (rs != 0 && rt == 0) {
1706 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1707 } else {
1708 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1709 }
1710 opn = "dsubu";
1711 break;
1712 #endif
1713 case OPC_MUL:
1714 if (likely(rs != 0 && rt != 0)) {
1715 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1716 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1717 } else {
1718 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1719 }
1720 opn = "mul";
1721 break;
1722 }
1723 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1724 }
1725
1726 /* Conditional move */
1727 static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1728 {
1729 const char *opn = "cond move";
1730 int l1;
1731
1732 if (rd == 0) {
1733 /* If no destination, treat it as a NOP.
1734 For add & sub, we must generate the overflow exception when needed. */
1735 MIPS_DEBUG("NOP");
1736 return;
1737 }
1738
1739 l1 = gen_new_label();
1740 switch (opc) {
1741 case OPC_MOVN:
1742 if (likely(rt != 0))
1743 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1744 else
1745 tcg_gen_br(l1);
1746 opn = "movn";
1747 break;
1748 case OPC_MOVZ:
1749 if (likely(rt != 0))
1750 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1751 opn = "movz";
1752 break;
1753 }
1754 if (rs != 0)
1755 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1756 else
1757 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1758 gen_set_label(l1);
1759
1760 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1761 }
1762
1763 /* Logic */
1764 static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1765 {
1766 const char *opn = "logic";
1767
1768 if (rd == 0) {
1769 /* If no destination, treat it as a NOP. */
1770 MIPS_DEBUG("NOP");
1771 return;
1772 }
1773
1774 switch (opc) {
1775 case OPC_AND:
1776 if (likely(rs != 0 && rt != 0)) {
1777 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1778 } else {
1779 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1780 }
1781 opn = "and";
1782 break;
1783 case OPC_NOR:
1784 if (rs != 0 && rt != 0) {
1785 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1786 } else if (rs == 0 && rt != 0) {
1787 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1788 } else if (rs != 0 && rt == 0) {
1789 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1790 } else {
1791 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1792 }
1793 opn = "nor";
1794 break;
1795 case OPC_OR:
1796 if (likely(rs != 0 && rt != 0)) {
1797 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1798 } else if (rs == 0 && rt != 0) {
1799 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1800 } else if (rs != 0 && rt == 0) {
1801 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1802 } else {
1803 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1804 }
1805 opn = "or";
1806 break;
1807 case OPC_XOR:
1808 if (likely(rs != 0 && rt != 0)) {
1809 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1810 } else if (rs == 0 && rt != 0) {
1811 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1812 } else if (rs != 0 && rt == 0) {
1813 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1814 } else {
1815 tcg_gen_movi_tl(cpu_gpr[rd], 0);
1816 }
1817 opn = "xor";
1818 break;
1819 }
1820 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1821 }
1822
1823 /* Set on lower than */
1824 static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1825 {
1826 const char *opn = "slt";
1827 TCGv t0, t1;
1828
1829 if (rd == 0) {
1830 /* If no destination, treat it as a NOP. */
1831 MIPS_DEBUG("NOP");
1832 return;
1833 }
1834
1835 t0 = tcg_temp_new();
1836 t1 = tcg_temp_new();
1837 gen_load_gpr(t0, rs);
1838 gen_load_gpr(t1, rt);
1839 switch (opc) {
1840 case OPC_SLT:
1841 gen_op_lt(cpu_gpr[rd], t0, t1);
1842 opn = "slt";
1843 break;
1844 case OPC_SLTU:
1845 gen_op_ltu(cpu_gpr[rd], t0, t1);
1846 opn = "sltu";
1847 break;
1848 }
1849 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1850 tcg_temp_free(t0);
1851 tcg_temp_free(t1);
1852 }
1853
1854 /* Shifts */
1855 static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1856 int rd, int rs, int rt)
1857 {
1858 const char *opn = "shifts";
1859 TCGv t0, t1;
1860
1861 if (rd == 0) {
1862 /* If no destination, treat it as a NOP.
1863 For add & sub, we must generate the overflow exception when needed. */
1864 MIPS_DEBUG("NOP");
1865 return;
1866 }
1867
1868 t0 = tcg_temp_new();
1869 t1 = tcg_temp_new();
1870 gen_load_gpr(t0, rs);
1871 gen_load_gpr(t1, rt);
1872 switch (opc) {
1873 case OPC_SLLV:
1874 tcg_gen_andi_tl(t0, t0, 0x1f);
1875 tcg_gen_shl_tl(t0, t1, t0);
1876 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1877 opn = "sllv";
1878 break;
1879 case OPC_SRAV:
1880 tcg_gen_ext32s_tl(t1, t1);
1881 tcg_gen_andi_tl(t0, t0, 0x1f);
1882 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1883 opn = "srav";
1884 break;
1885 case OPC_SRLV:
1886 switch ((ctx->opcode >> 6) & 0x1f) {
1887 case 0:
1888 tcg_gen_ext32u_tl(t1, t1);
1889 tcg_gen_andi_tl(t0, t0, 0x1f);
1890 tcg_gen_shr_tl(t0, t1, t0);
1891 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1892 opn = "srlv";
1893 break;
1894 case 1:
1895 /* rotrv is decoded as srlv on non-R2 CPUs */
1896 if (env->insn_flags & ISA_MIPS32R2) {
1897 TCGv_i32 t2 = tcg_temp_new_i32();
1898 TCGv_i32 t3 = tcg_temp_new_i32();
1899
1900 tcg_gen_trunc_tl_i32(t2, t0);
1901 tcg_gen_trunc_tl_i32(t3, t1);
1902 tcg_gen_andi_i32(t2, t2, 0x1f);
1903 tcg_gen_rotr_i32(t2, t3, t2);
1904 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1905 tcg_temp_free_i32(t2);
1906 tcg_temp_free_i32(t3);
1907 opn = "rotrv";
1908 } else {
1909 tcg_gen_ext32u_tl(t1, t1);
1910 tcg_gen_andi_tl(t0, t0, 0x1f);
1911 tcg_gen_shr_tl(t0, t1, t0);
1912 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1913 opn = "srlv";
1914 }
1915 break;
1916 default:
1917 MIPS_INVAL("invalid srlv flag");
1918 generate_exception(ctx, EXCP_RI);
1919 break;
1920 }
1921 break;
1922 #if defined(TARGET_MIPS64)
1923 case OPC_DSLLV:
1924 tcg_gen_andi_tl(t0, t0, 0x3f);
1925 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1926 opn = "dsllv";
1927 break;
1928 case OPC_DSRAV:
1929 tcg_gen_andi_tl(t0, t0, 0x3f);
1930 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1931 opn = "dsrav";
1932 break;
1933 case OPC_DSRLV:
1934 switch ((ctx->opcode >> 6) & 0x1f) {
1935 case 0:
1936 tcg_gen_andi_tl(t0, t0, 0x3f);
1937 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1938 opn = "dsrlv";
1939 break;
1940 case 1:
1941 /* drotrv is decoded as dsrlv on non-R2 CPUs */
1942 if (env->insn_flags & ISA_MIPS32R2) {
1943 tcg_gen_andi_tl(t0, t0, 0x3f);
1944 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1945 opn = "drotrv";
1946 } else {
1947 tcg_gen_andi_tl(t0, t0, 0x3f);
1948 tcg_gen_shr_tl(t0, t1, t0);
1949 opn = "dsrlv";
1950 }
1951 break;
1952 default:
1953 MIPS_INVAL("invalid dsrlv flag");
1954 generate_exception(ctx, EXCP_RI);
1955 break;
1956 }
1957 break;
1958 #endif
1959 }
1960 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1961 tcg_temp_free(t0);
1962 tcg_temp_free(t1);
1963 }
1964
1965 /* Arithmetic on HI/LO registers */
1966 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1967 {
1968 const char *opn = "hilo";
1969
1970 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1971 /* Treat as NOP. */
1972 MIPS_DEBUG("NOP");
1973 return;
1974 }
1975 switch (opc) {
1976 case OPC_MFHI:
1977 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1978 opn = "mfhi";
1979 break;
1980 case OPC_MFLO:
1981 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1982 opn = "mflo";
1983 break;
1984 case OPC_MTHI:
1985 if (reg != 0)
1986 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1987 else
1988 tcg_gen_movi_tl(cpu_HI[0], 0);
1989 opn = "mthi";
1990 break;
1991 case OPC_MTLO:
1992 if (reg != 0)
1993 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1994 else
1995 tcg_gen_movi_tl(cpu_LO[0], 0);
1996 opn = "mtlo";
1997 break;
1998 }
1999 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2000 }
2001
2002 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2003 int rs, int rt)
2004 {
2005 const char *opn = "mul/div";
2006 TCGv t0, t1;
2007
2008 switch (opc) {
2009 case OPC_DIV:
2010 case OPC_DIVU:
2011 #if defined(TARGET_MIPS64)
2012 case OPC_DDIV:
2013 case OPC_DDIVU:
2014 #endif
2015 t0 = tcg_temp_local_new();
2016 t1 = tcg_temp_local_new();
2017 break;
2018 default:
2019 t0 = tcg_temp_new();
2020 t1 = tcg_temp_new();
2021 break;
2022 }
2023
2024 gen_load_gpr(t0, rs);
2025 gen_load_gpr(t1, rt);
2026 switch (opc) {
2027 case OPC_DIV:
2028 {
2029 int l1 = gen_new_label();
2030 int l2 = gen_new_label();
2031
2032 tcg_gen_ext32s_tl(t0, t0);
2033 tcg_gen_ext32s_tl(t1, t1);
2034 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2035 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2036 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2037
2038 tcg_gen_mov_tl(cpu_LO[0], t0);
2039 tcg_gen_movi_tl(cpu_HI[0], 0);
2040 tcg_gen_br(l1);
2041 gen_set_label(l2);
2042 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2043 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2044 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2045 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2046 gen_set_label(l1);
2047 }
2048 opn = "div";
2049 break;
2050 case OPC_DIVU:
2051 {
2052 int l1 = gen_new_label();
2053
2054 tcg_gen_ext32u_tl(t0, t0);
2055 tcg_gen_ext32u_tl(t1, t1);
2056 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2057 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2058 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2059 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2060 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2061 gen_set_label(l1);
2062 }
2063 opn = "divu";
2064 break;
2065 case OPC_MULT:
2066 {
2067 TCGv_i64 t2 = tcg_temp_new_i64();
2068 TCGv_i64 t3 = tcg_temp_new_i64();
2069
2070 tcg_gen_ext_tl_i64(t2, t0);
2071 tcg_gen_ext_tl_i64(t3, t1);
2072 tcg_gen_mul_i64(t2, t2, t3);
2073 tcg_temp_free_i64(t3);
2074 tcg_gen_trunc_i64_tl(t0, t2);
2075 tcg_gen_shri_i64(t2, t2, 32);
2076 tcg_gen_trunc_i64_tl(t1, t2);
2077 tcg_temp_free_i64(t2);
2078 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2079 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2080 }
2081 opn = "mult";
2082 break;
2083 case OPC_MULTU:
2084 {
2085 TCGv_i64 t2 = tcg_temp_new_i64();
2086 TCGv_i64 t3 = tcg_temp_new_i64();
2087
2088 tcg_gen_ext32u_tl(t0, t0);
2089 tcg_gen_ext32u_tl(t1, t1);
2090 tcg_gen_extu_tl_i64(t2, t0);
2091 tcg_gen_extu_tl_i64(t3, t1);
2092 tcg_gen_mul_i64(t2, t2, t3);
2093 tcg_temp_free_i64(t3);
2094 tcg_gen_trunc_i64_tl(t0, t2);
2095 tcg_gen_shri_i64(t2, t2, 32);
2096 tcg_gen_trunc_i64_tl(t1, t2);
2097 tcg_temp_free_i64(t2);
2098 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2099 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2100 }
2101 opn = "multu";
2102 break;
2103 #if defined(TARGET_MIPS64)
2104 case OPC_DDIV:
2105 {
2106 int l1 = gen_new_label();
2107 int l2 = gen_new_label();
2108
2109 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2110 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2111 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2112 tcg_gen_mov_tl(cpu_LO[0], t0);
2113 tcg_gen_movi_tl(cpu_HI[0], 0);
2114 tcg_gen_br(l1);
2115 gen_set_label(l2);
2116 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2117 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2118 gen_set_label(l1);
2119 }
2120 opn = "ddiv";
2121 break;
2122 case OPC_DDIVU:
2123 {
2124 int l1 = gen_new_label();
2125
2126 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2127 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2128 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2129 gen_set_label(l1);
2130 }
2131 opn = "ddivu";
2132 break;
2133 case OPC_DMULT:
2134 gen_helper_dmult(t0, t1);
2135 opn = "dmult";
2136 break;
2137 case OPC_DMULTU:
2138 gen_helper_dmultu(t0, t1);
2139 opn = "dmultu";
2140 break;
2141 #endif
2142 case OPC_MADD:
2143 {
2144 TCGv_i64 t2 = tcg_temp_new_i64();
2145 TCGv_i64 t3 = tcg_temp_new_i64();
2146
2147 tcg_gen_ext_tl_i64(t2, t0);
2148 tcg_gen_ext_tl_i64(t3, t1);
2149 tcg_gen_mul_i64(t2, t2, t3);
2150 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2151 tcg_gen_add_i64(t2, t2, t3);
2152 tcg_temp_free_i64(t3);
2153 tcg_gen_trunc_i64_tl(t0, t2);
2154 tcg_gen_shri_i64(t2, t2, 32);
2155 tcg_gen_trunc_i64_tl(t1, t2);
2156 tcg_temp_free_i64(t2);
2157 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2158 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2159 }
2160 opn = "madd";
2161 break;
2162 case OPC_MADDU:
2163 {
2164 TCGv_i64 t2 = tcg_temp_new_i64();
2165 TCGv_i64 t3 = tcg_temp_new_i64();
2166
2167 tcg_gen_ext32u_tl(t0, t0);
2168 tcg_gen_ext32u_tl(t1, t1);
2169 tcg_gen_extu_tl_i64(t2, t0);
2170 tcg_gen_extu_tl_i64(t3, t1);
2171 tcg_gen_mul_i64(t2, t2, t3);
2172 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2173 tcg_gen_add_i64(t2, t2, t3);
2174 tcg_temp_free_i64(t3);
2175 tcg_gen_trunc_i64_tl(t0, t2);
2176 tcg_gen_shri_i64(t2, t2, 32);
2177 tcg_gen_trunc_i64_tl(t1, t2);
2178 tcg_temp_free_i64(t2);
2179 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2180 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2181 }
2182 opn = "maddu";
2183 break;
2184 case OPC_MSUB:
2185 {
2186 TCGv_i64 t2 = tcg_temp_new_i64();
2187 TCGv_i64 t3 = tcg_temp_new_i64();
2188
2189 tcg_gen_ext_tl_i64(t2, t0);
2190 tcg_gen_ext_tl_i64(t3, t1);
2191 tcg_gen_mul_i64(t2, t2, t3);
2192 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2193 tcg_gen_sub_i64(t2, t3, t2);
2194 tcg_temp_free_i64(t3);
2195 tcg_gen_trunc_i64_tl(t0, t2);
2196 tcg_gen_shri_i64(t2, t2, 32);
2197 tcg_gen_trunc_i64_tl(t1, t2);
2198 tcg_temp_free_i64(t2);
2199 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2200 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2201 }
2202 opn = "msub";
2203 break;
2204 case OPC_MSUBU:
2205 {
2206 TCGv_i64 t2 = tcg_temp_new_i64();
2207 TCGv_i64 t3 = tcg_temp_new_i64();
2208
2209 tcg_gen_ext32u_tl(t0, t0);
2210 tcg_gen_ext32u_tl(t1, t1);
2211 tcg_gen_extu_tl_i64(t2, t0);
2212 tcg_gen_extu_tl_i64(t3, t1);
2213 tcg_gen_mul_i64(t2, t2, t3);
2214 tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2215 tcg_gen_sub_i64(t2, t3, t2);
2216 tcg_temp_free_i64(t3);
2217 tcg_gen_trunc_i64_tl(t0, t2);
2218 tcg_gen_shri_i64(t2, t2, 32);
2219 tcg_gen_trunc_i64_tl(t1, t2);
2220 tcg_temp_free_i64(t2);
2221 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2222 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2223 }
2224 opn = "msubu";
2225 break;
2226 default:
2227 MIPS_INVAL(opn);
2228 generate_exception(ctx, EXCP_RI);
2229 goto out;
2230 }
2231 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2232 out:
2233 tcg_temp_free(t0);
2234 tcg_temp_free(t1);
2235 }
2236
2237 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2238 int rd, int rs, int rt)
2239 {
2240 const char *opn = "mul vr54xx";
2241 TCGv t0 = tcg_temp_new();
2242 TCGv t1 = tcg_temp_new();
2243
2244 gen_load_gpr(t0, rs);
2245 gen_load_gpr(t1, rt);
2246
2247 switch (opc) {
2248 case OPC_VR54XX_MULS:
2249 gen_helper_muls(t0, t0, t1);
2250 opn = "muls";
2251 break;
2252 case OPC_VR54XX_MULSU:
2253 gen_helper_mulsu(t0, t0, t1);
2254 opn = "mulsu";
2255 break;
2256 case OPC_VR54XX_MACC:
2257 gen_helper_macc(t0, t0, t1);
2258 opn = "macc";
2259 break;
2260 case OPC_VR54XX_MACCU:
2261 gen_helper_maccu(t0, t0, t1);
2262 opn = "maccu";
2263 break;
2264 case OPC_VR54XX_MSAC:
2265 gen_helper_msac(t0, t0, t1);
2266 opn = "msac";
2267 break;
2268 case OPC_VR54XX_MSACU:
2269 gen_helper_msacu(t0, t0, t1);
2270 opn = "msacu";
2271 break;
2272 case OPC_VR54XX_MULHI:
2273 gen_helper_mulhi(t0, t0, t1);
2274 opn = "mulhi";
2275 break;
2276 case OPC_VR54XX_MULHIU:
2277 gen_helper_mulhiu(t0, t0, t1);
2278 opn = "mulhiu";
2279 break;
2280 case OPC_VR54XX_MULSHI:
2281 gen_helper_mulshi(t0, t0, t1);
2282 opn = "mulshi";
2283 break;
2284 case OPC_VR54XX_MULSHIU:
2285 gen_helper_mulshiu(t0, t0, t1);
2286 opn = "mulshiu";
2287 break;
2288 case OPC_VR54XX_MACCHI:
2289 gen_helper_macchi(t0, t0, t1);
2290 opn = "macchi";
2291 break;
2292 case OPC_VR54XX_MACCHIU:
2293 gen_helper_macchiu(t0, t0, t1);
2294 opn = "macchiu";
2295 break;
2296 case OPC_VR54XX_MSACHI:
2297 gen_helper_msachi(t0, t0, t1);
2298 opn = "msachi";
2299 break;
2300 case OPC_VR54XX_MSACHIU:
2301 gen_helper_msachiu(t0, t0, t1);
2302 opn = "msachiu";
2303 break;
2304 default:
2305 MIPS_INVAL("mul vr54xx");
2306 generate_exception(ctx, EXCP_RI);
2307 goto out;
2308 }
2309 gen_store_gpr(t0, rd);
2310 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2311
2312 out:
2313 tcg_temp_free(t0);
2314 tcg_temp_free(t1);
2315 }
2316
2317 static void gen_cl (DisasContext *ctx, uint32_t opc,
2318 int rd, int rs)
2319 {
2320 const char *opn = "CLx";
2321 TCGv t0;
2322
2323 if (rd == 0) {
2324 /* Treat as NOP. */
2325 MIPS_DEBUG("NOP");
2326 return;
2327 }
2328 t0 = tcg_temp_new();
2329 gen_load_gpr(t0, rs);
2330 switch (opc) {
2331 case OPC_CLO:
2332 gen_helper_clo(cpu_gpr[rd], t0);
2333 opn = "clo";
2334 break;
2335 case OPC_CLZ:
2336 gen_helper_clz(cpu_gpr[rd], t0);
2337 opn = "clz";
2338 break;
2339 #if defined(TARGET_MIPS64)
2340 case OPC_DCLO:
2341 gen_helper_dclo(cpu_gpr[rd], t0);
2342 opn = "dclo";
2343 break;
2344 case OPC_DCLZ:
2345 gen_helper_dclz(cpu_gpr[rd], t0);
2346 opn = "dclz";
2347 break;
2348 #endif
2349 }
2350 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2351 tcg_temp_free(t0);
2352 }
2353
2354 /* Traps */
2355 static void gen_trap (DisasContext *ctx, uint32_t opc,
2356 int rs, int rt, int16_t imm)
2357 {
2358 int cond;
2359 TCGv t0 = tcg_temp_new();
2360 TCGv t1 = tcg_temp_new();
2361
2362 cond = 0;
2363 /* Load needed operands */
2364 switch (opc) {
2365 case OPC_TEQ:
2366 case OPC_TGE:
2367 case OPC_TGEU:
2368 case OPC_TLT:
2369 case OPC_TLTU:
2370 case OPC_TNE:
2371 /* Compare two registers */
2372 if (rs != rt) {
2373 gen_load_gpr(t0, rs);
2374 gen_load_gpr(t1, rt);
2375 cond = 1;
2376 }
2377 break;
2378 case OPC_TEQI:
2379 case OPC_TGEI:
2380 case OPC_TGEIU:
2381 case OPC_TLTI:
2382 case OPC_TLTIU:
2383 case OPC_TNEI:
2384 /* Compare register to immediate */
2385 if (rs != 0 || imm != 0) {
2386 gen_load_gpr(t0, rs);
2387 tcg_gen_movi_tl(t1, (int32_t)imm);
2388 cond = 1;
2389 }
2390 break;
2391 }
2392 if (cond == 0) {
2393 switch (opc) {
2394 case OPC_TEQ: /* rs == rs */
2395 case OPC_TEQI: /* r0 == 0 */
2396 case OPC_TGE: /* rs >= rs */
2397 case OPC_TGEI: /* r0 >= 0 */
2398 case OPC_TGEU: /* rs >= rs unsigned */
2399 case OPC_TGEIU: /* r0 >= 0 unsigned */
2400 /* Always trap */
2401 generate_exception(ctx, EXCP_TRAP);
2402 break;
2403 case OPC_TLT: /* rs < rs */
2404 case OPC_TLTI: /* r0 < 0 */
2405 case OPC_TLTU: /* rs < rs unsigned */
2406 case OPC_TLTIU: /* r0 < 0 unsigned */
2407 case OPC_TNE: /* rs != rs */
2408 case OPC_TNEI: /* r0 != 0 */
2409 /* Never trap: treat as NOP. */
2410 break;
2411 }
2412 } else {
2413 int l1 = gen_new_label();
2414
2415 switch (opc) {
2416 case OPC_TEQ:
2417 case OPC_TEQI:
2418 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2419 break;
2420 case OPC_TGE:
2421 case OPC_TGEI:
2422 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2423 break;
2424 case OPC_TGEU:
2425 case OPC_TGEIU:
2426 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2427 break;
2428 case OPC_TLT:
2429 case OPC_TLTI:
2430 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2431 break;
2432 case OPC_TLTU:
2433 case OPC_TLTIU:
2434 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2435 break;
2436 case OPC_TNE:
2437 case OPC_TNEI:
2438 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2439 break;
2440 }
2441 generate_exception(ctx, EXCP_TRAP);
2442 gen_set_label(l1);
2443 }
2444 tcg_temp_free(t0);
2445 tcg_temp_free(t1);
2446 }
2447
2448 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2449 {
2450 TranslationBlock *tb;
2451 tb = ctx->tb;
2452 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
2453 likely(!ctx->singlestep_enabled)) {
2454 tcg_gen_goto_tb(n);
2455 gen_save_pc(dest);
2456 tcg_gen_exit_tb((long)tb + n);
2457 } else {
2458 gen_save_pc(dest);
2459 if (ctx->singlestep_enabled) {
2460 save_cpu_state(ctx, 0);
2461 gen_helper_0i(raise_exception, EXCP_DEBUG);
2462 }
2463 tcg_gen_exit_tb(0);
2464 }
2465 }
2466
2467 /* Branches (before delay slot) */
2468 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2469 int rs, int rt, int32_t offset)
2470 {
2471 target_ulong btgt = -1;
2472 int blink = 0;
2473 int bcond_compute = 0;
2474 TCGv t0 = tcg_temp_new();
2475 TCGv t1 = tcg_temp_new();
2476
2477 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2478 #ifdef MIPS_DEBUG_DISAS
2479 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2480 #endif
2481 generate_exception(ctx, EXCP_RI);
2482 goto out;
2483 }
2484
2485 /* Load needed operands */
2486 switch (opc) {
2487 case OPC_BEQ:
2488 case OPC_BEQL:
2489 case OPC_BNE:
2490 case OPC_BNEL:
2491 /* Compare two registers */
2492 if (rs != rt) {
2493 gen_load_gpr(t0, rs);
2494 gen_load_gpr(t1, rt);
2495 bcond_compute = 1;
2496 }
2497 btgt = ctx->pc + 4 + offset;
2498 break;
2499 case OPC_BGEZ:
2500 case OPC_BGEZAL:
2501 case OPC_BGEZALL:
2502 case OPC_BGEZL:
2503 case OPC_BGTZ:
2504 case OPC_BGTZL:
2505 case OPC_BLEZ:
2506 case OPC_BLEZL:
2507 case OPC_BLTZ:
2508 case OPC_BLTZAL:
2509 case OPC_BLTZALL:
2510 case OPC_BLTZL:
2511 /* Compare to zero */
2512 if (rs != 0) {
2513 gen_load_gpr(t0, rs);
2514 bcond_compute = 1;
2515 }
2516 btgt = ctx->pc + 4 + offset;
2517 break;
2518 case OPC_J:
2519 case OPC_JAL:
2520 /* Jump to immediate */
2521 btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2522 break;
2523 case OPC_JR:
2524 case OPC_JALR:
2525 /* Jump to register */
2526 if (offset != 0 && offset != 16) {
2527 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2528 others are reserved. */
2529 MIPS_INVAL("jump hint");
2530 generate_exception(ctx, EXCP_RI);
2531 goto out;
2532 }
2533 gen_load_gpr(btarget, rs);
2534 break;
2535 default:
2536 MIPS_INVAL("branch/jump");
2537 generate_exception(ctx, EXCP_RI);
2538 goto out;
2539 }
2540 if (bcond_compute == 0) {
2541 /* No condition to be computed */
2542 switch (opc) {
2543 case OPC_BEQ: /* rx == rx */
2544 case OPC_BEQL: /* rx == rx likely */
2545 case OPC_BGEZ: /* 0 >= 0 */
2546 case OPC_BGEZL: /* 0 >= 0 likely */
2547 case OPC_BLEZ: /* 0 <= 0 */
2548 case OPC_BLEZL: /* 0 <= 0 likely */
2549 /* Always take */
2550 ctx->hflags |= MIPS_HFLAG_B;
2551 MIPS_DEBUG("balways");
2552 break;
2553 case OPC_BGEZAL: /* 0 >= 0 */
2554 case OPC_BGEZALL: /* 0 >= 0 likely */
2555 /* Always take and link */
2556 blink = 31;
2557 ctx->hflags |= MIPS_HFLAG_B;
2558 MIPS_DEBUG("balways and link");
2559 break;
2560 case OPC_BNE: /* rx != rx */
2561 case OPC_BGTZ: /* 0 > 0 */
2562 case OPC_BLTZ: /* 0 < 0 */
2563 /* Treat as NOP. */
2564 MIPS_DEBUG("bnever (NOP)");
2565 goto out;
2566 case OPC_BLTZAL: /* 0 < 0 */
2567 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2568 MIPS_DEBUG("bnever and link");
2569 goto out;
2570 case OPC_BLTZALL: /* 0 < 0 likely */
2571 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2572 /* Skip the instruction in the delay slot */
2573 MIPS_DEBUG("bnever, link and skip");
2574 ctx->pc += 4;
2575 goto out;
2576 case OPC_BNEL: /* rx != rx likely */
2577 case OPC_BGTZL: /* 0 > 0 likely */
2578 case OPC_BLTZL: /* 0 < 0 likely */
2579 /* Skip the instruction in the delay slot */
2580 MIPS_DEBUG("bnever and skip");
2581 ctx->pc += 4;
2582 goto out;
2583 case OPC_J:
2584 ctx->hflags |= MIPS_HFLAG_B;
2585 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2586 break;
2587 case OPC_JAL:
2588 blink = 31;
2589 ctx->hflags |= MIPS_HFLAG_B;
2590 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2591 break;
2592 case OPC_JR:
2593 ctx->hflags |= MIPS_HFLAG_BR;
2594 MIPS_DEBUG("jr %s", regnames[rs]);
2595 break;
2596 case OPC_JALR:
2597 blink = rt;
2598 ctx->hflags |= MIPS_HFLAG_BR;
2599 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2600 break;
2601 default:
2602 MIPS_INVAL("branch/jump");
2603 generate_exception(ctx, EXCP_RI);
2604 goto out;
2605 }
2606 } else {
2607 switch (opc) {
2608 case OPC_BEQ:
2609 gen_op_eq(bcond, t0, t1);
2610 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2611 regnames[rs], regnames[rt], btgt);
2612 goto not_likely;
2613 case OPC_BEQL:
2614 gen_op_eq(bcond, t0, t1);
2615 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2616 regnames[rs], regnames[rt], btgt);
2617 goto likely;
2618 case OPC_BNE:
2619 gen_op_ne(bcond, t0, t1);
2620 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2621 regnames[rs], regnames[rt], btgt);
2622 goto not_likely;
2623 case OPC_BNEL:
2624 gen_op_ne(bcond, t0, t1);
2625 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2626 regnames[rs], regnames[rt], btgt);
2627 goto likely;
2628 case OPC_BGEZ:
2629 gen_op_gez(bcond, t0);
2630 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2631 goto not_likely;
2632 case OPC_BGEZL:
2633 gen_op_gez(bcond, t0);
2634 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2635 goto likely;
2636 case OPC_BGEZAL:
2637 gen_op_gez(bcond, t0);
2638 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2639 blink = 31;
2640 goto not_likely;
2641 case OPC_BGEZALL:
2642 gen_op_gez(bcond, t0);
2643 blink = 31;
2644 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2645 goto likely;
2646 case OPC_BGTZ:
2647 gen_op_gtz(bcond, t0);
2648 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2649 goto not_likely;
2650 case OPC_BGTZL:
2651 gen_op_gtz(bcond, t0);
2652 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2653 goto likely;
2654 case OPC_BLEZ:
2655 gen_op_lez(bcond, t0);
2656 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2657 goto not_likely;
2658 case OPC_BLEZL:
2659 gen_op_lez(bcond, t0);
2660 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2661 goto likely;
2662 case OPC_BLTZ:
2663 gen_op_ltz(bcond, t0);
2664 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2665 goto not_likely;
2666 case OPC_BLTZL:
2667 gen_op_ltz(bcond, t0);
2668 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2669 goto likely;
2670 case OPC_BLTZAL:
2671 gen_op_ltz(bcond, t0);
2672 blink = 31;
2673 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2674 not_likely:
2675 ctx->hflags |= MIPS_HFLAG_BC;
2676 break;
2677 case OPC_BLTZALL:
2678 gen_op_ltz(bcond, t0);
2679 blink = 31;
2680 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2681 likely:
2682 ctx->hflags |= MIPS_HFLAG_BL;
2683 break;
2684 default:
2685 MIPS_INVAL("conditional branch/jump");
2686 generate_exception(ctx, EXCP_RI);
2687 goto out;
2688 }
2689 }
2690 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2691 blink, ctx->hflags, btgt);
2692
2693 ctx->btarget = btgt;
2694 if (blink > 0) {
2695 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2696 }
2697
2698 out:
2699 tcg_temp_free(t0);
2700 tcg_temp_free(t1);
2701 }
2702
2703 /* special3 bitfield operations */
2704 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2705 int rs, int lsb, int msb)
2706 {
2707 TCGv t0 = tcg_temp_new();
2708 TCGv t1 = tcg_temp_new();
2709 target_ulong mask;
2710
2711 gen_load_gpr(t1, rs);
2712 switch (opc) {
2713 case OPC_EXT:
2714 if (lsb + msb > 31)
2715 goto fail;
2716 tcg_gen_shri_tl(t0, t1, lsb);
2717 if (msb != 31) {
2718 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2719 } else {
2720 tcg_gen_ext32s_tl(t0, t0);
2721 }
2722 break;
2723 #if defined(TARGET_MIPS64)
2724 case OPC_DEXTM:
2725 tcg_gen_shri_tl(t0, t1, lsb);
2726 if (msb != 31) {
2727 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2728 }
2729 break;
2730 case OPC_DEXTU:
2731 tcg_gen_shri_tl(t0, t1, lsb + 32);
2732 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2733 break;
2734 case OPC_DEXT:
2735 tcg_gen_shri_tl(t0, t1, lsb);
2736 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2737 break;
2738 #endif
2739 case OPC_INS:
2740 if (lsb > msb)
2741 goto fail;
2742 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2743 gen_load_gpr(t0, rt);
2744 tcg_gen_andi_tl(t0, t0, ~mask);
2745 tcg_gen_shli_tl(t1, t1, lsb);
2746 tcg_gen_andi_tl(t1, t1, mask);
2747 tcg_gen_or_tl(t0, t0, t1);
2748 tcg_gen_ext32s_tl(t0, t0);
2749 break;
2750 #if defined(TARGET_MIPS64)
2751 case OPC_DINSM:
2752 if (lsb > msb)
2753 goto fail;
2754 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2755 gen_load_gpr(t0, rt);
2756 tcg_gen_andi_tl(t0, t0, ~mask);
2757 tcg_gen_shli_tl(t1, t1, lsb);
2758 tcg_gen_andi_tl(t1, t1, mask);
2759 tcg_gen_or_tl(t0, t0, t1);
2760 break;
2761 case OPC_DINSU:
2762 if (lsb > msb)
2763 goto fail;
2764 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
2765 gen_load_gpr(t0, rt);
2766 tcg_gen_andi_tl(t0, t0, ~mask);
2767 tcg_gen_shli_tl(t1, t1, lsb + 32);
2768 tcg_gen_andi_tl(t1, t1, mask);
2769 tcg_gen_or_tl(t0, t0, t1);
2770 break;
2771 case OPC_DINS:
2772 if (lsb > msb)
2773 goto fail;
2774 gen_load_gpr(t0, rt);
2775 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2776 gen_load_gpr(t0, rt);
2777 tcg_gen_andi_tl(t0, t0, ~mask);
2778 tcg_gen_shli_tl(t1, t1, lsb);
2779 tcg_gen_andi_tl(t1, t1, mask);
2780 tcg_gen_or_tl(t0, t0, t1);
2781 break;
2782 #endif
2783 default:
2784 fail:
2785 MIPS_INVAL("bitops");
2786 generate_exception(ctx, EXCP_RI);
2787 tcg_temp_free(t0);
2788 tcg_temp_free(t1);
2789 return;
2790 }
2791 gen_store_gpr(t0, rt);
2792 tcg_temp_free(t0);
2793 tcg_temp_free(t1);
2794 }
2795
2796 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2797 {
2798 TCGv t0;
2799
2800 if (rd == 0) {
2801 /* If no destination, treat it as a NOP. */
2802 MIPS_DEBUG("NOP");
2803 return;
2804 }
2805
2806 t0 = tcg_temp_new();
2807 gen_load_gpr(t0, rt);
2808 switch (op2) {
2809 case OPC_WSBH:
2810 {
2811 TCGv t1 = tcg_temp_new();
2812
2813 tcg_gen_shri_tl(t1, t0, 8);
2814 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2815 tcg_gen_shli_tl(t0, t0, 8);
2816 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2817 tcg_gen_or_tl(t0, t0, t1);
2818 tcg_temp_free(t1);
2819 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2820 }
2821 break;
2822 case OPC_SEB:
2823 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2824 break;
2825 case OPC_SEH:
2826 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2827 break;
2828 #if defined(TARGET_MIPS64)
2829 case OPC_DSBH:
2830 {
2831 TCGv t1 = tcg_temp_new();
2832
2833 tcg_gen_shri_tl(t1, t0, 8);
2834 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2835 tcg_gen_shli_tl(t0, t0, 8);
2836 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2837 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2838 tcg_temp_free(t1);
2839 }
2840 break;
2841 case OPC_DSHD:
2842 {
2843 TCGv t1 = tcg_temp_new();
2844
2845 tcg_gen_shri_tl(t1, t0, 16);
2846 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2847 tcg_gen_shli_tl(t0, t0, 16);
2848 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2849 tcg_gen_or_tl(t0, t0, t1);
2850 tcg_gen_shri_tl(t1, t0, 32);
2851 tcg_gen_shli_tl(t0, t0, 32);
2852 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2853 tcg_temp_free(t1);
2854 }
2855 break;
2856 #endif
2857 default:
2858 MIPS_INVAL("bsfhl");
2859 generate_exception(ctx, EXCP_RI);
2860 tcg_temp_free(t0);
2861 return;
2862 }
2863 tcg_temp_free(t0);
2864 }
2865
2866 #ifndef CONFIG_USER_ONLY
2867 /* CP0 (MMU and control) */
2868 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2869 {
2870 TCGv_i32 t0 = tcg_temp_new_i32();
2871
2872 tcg_gen_ld_i32(t0, cpu_env, off);
2873 tcg_gen_ext_i32_tl(arg, t0);
2874 tcg_temp_free_i32(t0);
2875 }
2876
2877 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2878 {
2879 tcg_gen_ld_tl(arg, cpu_env, off);
2880 tcg_gen_ext32s_tl(arg, arg);
2881 }
2882
2883 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2884 {
2885 TCGv_i32 t0 = tcg_temp_new_i32();
2886
2887 tcg_gen_trunc_tl_i32(t0, arg);
2888 tcg_gen_st_i32(t0, cpu_env, off);
2889 tcg_temp_free_i32(t0);
2890 }
2891
2892 static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2893 {
2894 tcg_gen_ext32s_tl(arg, arg);
2895 tcg_gen_st_tl(arg, cpu_env, off);
2896 }
2897
2898 static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2899 {
2900 const char *rn = "invalid";
2901
2902 if (sel != 0)
2903 check_insn(env, ctx, ISA_MIPS32);
2904
2905 switch (reg) {
2906 case 0:
2907 switch (sel) {
2908 case 0:
2909 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
2910 rn = "Index";
2911 break;
2912 case 1:
2913 check_insn(env, ctx, ASE_MT);
2914 gen_helper_mfc0_mvpcontrol(arg);
2915 rn = "MVPControl";
2916 break;
2917 case 2:
2918 check_insn(env, ctx, ASE_MT);
2919 gen_helper_mfc0_mvpconf0(arg);
2920 rn = "MVPConf0";
2921 break;
2922 case 3:
2923 check_insn(env, ctx, ASE_MT);
2924 gen_helper_mfc0_mvpconf1(arg);
2925 rn = "MVPConf1";
2926 break;
2927 default:
2928 goto die;
2929 }
2930 break;
2931 case 1:
2932 switch (sel) {
2933 case 0:
2934 gen_helper_mfc0_random(arg);
2935 rn = "Random";
2936 break;
2937 case 1:
2938 check_insn(env, ctx, ASE_MT);
2939 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
2940 rn = "VPEControl";
2941 break;
2942 case 2:
2943 check_insn(env, ctx, ASE_MT);
2944 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
2945 rn = "VPEConf0";
2946 break;
2947 case 3:
2948 check_insn(env, ctx, ASE_MT);
2949 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
2950 rn = "VPEConf1";
2951 break;
2952 case 4:
2953 check_insn(env, ctx, ASE_MT);
2954 gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
2955 rn = "YQMask";
2956 break;
2957 case 5:
2958 check_insn(env, ctx, ASE_MT);
2959 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
2960 rn = "VPESchedule";
2961 break;
2962 case 6:
2963 check_insn(env, ctx, ASE_MT);
2964 gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
2965 rn = "VPEScheFBack";
2966 break;
2967 case 7:
2968 check_insn(env, ctx, ASE_MT);
2969 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
2970 rn = "VPEOpt";
2971 break;
2972 default:
2973 goto die;
2974 }
2975 break;
2976 case 2:
2977 switch (sel) {
2978 case 0:
2979 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2980 tcg_gen_ext32s_tl(arg, arg);
2981 rn = "EntryLo0";
2982 break;
2983 case 1:
2984 check_insn(env, ctx, ASE_MT);
2985 gen_helper_mfc0_tcstatus(arg);
2986 rn = "TCStatus";
2987 break;
2988 case 2:
2989 check_insn(env, ctx, ASE_MT);
2990 gen_helper_mfc0_tcbind(arg);
2991 rn = "TCBind";
2992 break;
2993 case 3:
2994 check_insn(env, ctx, ASE_MT);
2995 gen_helper_mfc0_tcrestart(arg);
2996 rn = "TCRestart";
2997 break;
2998 case 4:
2999 check_insn(env, ctx, ASE_MT);
3000 gen_helper_mfc0_tchalt(arg);
3001 rn = "TCHalt";
3002 break;
3003 case 5:
3004 check_insn(env, ctx, ASE_MT);
3005 gen_helper_mfc0_tccontext(arg);
3006 rn = "TCContext";
3007 break;
3008 case 6:
3009 check_insn(env, ctx, ASE_MT);
3010 gen_helper_mfc0_tcschedule(arg);
3011 rn = "TCSchedule";
3012 break;
3013 case 7:
3014 check_insn(env, ctx, ASE_MT);
3015 gen_helper_mfc0_tcschefback(arg);
3016 rn = "TCScheFBack";
3017 break;
3018 default:
3019 goto die;
3020 }
3021 break;
3022 case 3:
3023 switch (sel) {
3024 case 0:
3025 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3026 tcg_gen_ext32s_tl(arg, arg);
3027 rn = "EntryLo1";
3028 break;
3029 default:
3030 goto die;
3031 }
3032 break;
3033 case 4:
3034 switch (sel) {
3035 case 0:
3036 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3037 tcg_gen_ext32s_tl(arg, arg);
3038 rn = "Context";
3039 break;
3040 case 1:
3041 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3042 rn = "ContextConfig";
3043 // break;
3044 default:
3045 goto die;
3046 }
3047 break;
3048 case 5:
3049 switch (sel) {
3050 case 0:
3051 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3052 rn = "PageMask";
3053 break;
3054 case 1:
3055 check_insn(env, ctx, ISA_MIPS32R2);
3056 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3057 rn = "PageGrain";
3058 break;
3059 default:
3060 goto die;
3061 }
3062 break;
3063 case 6:
3064 switch (sel) {
3065 case 0:
3066 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3067 rn = "Wired";
3068 break;
3069 case 1:
3070 check_insn(env, ctx, ISA_MIPS32R2);
3071 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3072 rn = "SRSConf0";
3073 break;
3074 case 2:
3075 check_insn(env, ctx, ISA_MIPS32R2);
3076 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3077 rn = "SRSConf1";
3078 break;
3079 case 3:
3080 check_insn(env, ctx, ISA_MIPS32R2);
3081 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3082 rn = "SRSConf2";
3083 break;
3084 case 4:
3085 check_insn(env, ctx, ISA_MIPS32R2);
3086 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3087 rn = "SRSConf3";
3088 break;
3089 case 5:
3090 check_insn(env, ctx, ISA_MIPS32R2);
3091 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3092 rn = "SRSConf4";
3093 break;
3094 default:
3095 goto die;
3096 }
3097 break;
3098 case 7:
3099 switch (sel) {
3100 case 0:
3101 check_insn(env, ctx, ISA_MIPS32R2);
3102 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3103 rn = "HWREna";
3104 break;
3105 default:
3106 goto die;
3107 }
3108 break;
3109 case 8:
3110 switch (sel) {
3111 case 0:
3112 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3113 tcg_gen_ext32s_tl(arg, arg);
3114 rn = "BadVAddr";
3115 break;
3116 default:
3117 goto die;
3118 }
3119 break;
3120 case 9:
3121 switch (sel) {
3122 case 0:
3123 /* Mark as an IO operation because we read the time. */
3124 if (use_icount)
3125 gen_io_start();
3126 gen_helper_mfc0_count(arg);
3127 if (use_icount) {
3128 gen_io_end();
3129 ctx->bstate = BS_STOP;
3130 }
3131 rn = "Count";
3132 break;
3133 /* 6,7 are implementation dependent */
3134 default:
3135 goto die;
3136 }
3137 break;
3138 case 10:
3139 switch (sel) {
3140 case 0:
3141 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3142 tcg_gen_ext32s_tl(arg, arg);
3143 rn = "EntryHi";
3144 break;
3145 default:
3146 goto die;
3147 }
3148 break;
3149 case 11:
3150 switch (sel) {
3151 case 0:
3152 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3153 rn = "Compare";
3154 break;
3155 /* 6,7 are implementation dependent */
3156 default:
3157 goto die;
3158 }
3159 break;
3160 case 12:
3161 switch (sel) {
3162 case 0:
3163 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3164 rn = "Status";
3165 break;
3166 case 1:
3167 check_insn(env, ctx, ISA_MIPS32R2);
3168 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3169 rn = "IntCtl";
3170 break;
3171 case 2:
3172 check_insn(env, ctx, ISA_MIPS32R2);
3173 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3174 rn = "SRSCtl";
3175 break;
3176 case 3:
3177 check_insn(env, ctx, ISA_MIPS32R2);
3178 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3179 rn = "SRSMap";
3180 break;
3181 default:
3182 goto die;
3183 }
3184 break;
3185 case 13:
3186 switch (sel) {
3187 case 0:
3188 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3189 rn = "Cause";
3190 break;
3191 default:
3192 goto die;
3193 }
3194 break;
3195 case 14:
3196 switch (sel) {
3197 case 0:
3198 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3199 tcg_gen_ext32s_tl(arg, arg);
3200 rn = "EPC";
3201 break;
3202 default:
3203 goto die;
3204 }
3205 break;
3206 case 15:
3207 switch (sel) {
3208 case 0:
3209 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3210 rn = "PRid";
3211 break;
3212 case 1:
3213 check_insn(env, ctx, ISA_MIPS32R2);
3214 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3215 rn = "EBase";
3216 break;
3217 default:
3218 goto die;
3219 }
3220 break;
3221 case 16:
3222 switch (sel) {
3223 case 0:
3224 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3225 rn = "Config";
3226 break;
3227 case 1:
3228 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3229 rn = "Config1";
3230 break;
3231 case 2:
3232 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3233 rn = "Config2";
3234 break;
3235 case 3:
3236 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3237 rn = "Config3";
3238 break;
3239 /* 4,5 are reserved */
3240 /* 6,7 are implementation dependent */
3241 case 6:
3242 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3243 rn = "Config6";
3244 break;
3245 case 7:
3246 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3247 rn = "Config7";
3248 break;
3249 default:
3250 goto die;
3251 }
3252 break;
3253 case 17:
3254 switch (sel) {
3255 case 0:
3256 gen_helper_mfc0_lladdr(arg);
3257 rn = "LLAddr";
3258 break;
3259 default:
3260 goto die;
3261 }
3262 break;
3263 case 18:
3264 switch (sel) {
3265 case 0 ... 7:
3266 gen_helper_1i(mfc0_watchlo, arg, sel);
3267 rn = "WatchLo";
3268 break;
3269 default:
3270 goto die;
3271 }
3272 break;
3273 case 19:
3274 switch (sel) {
3275 case 0 ...7:
3276 gen_helper_1i(mfc0_watchhi, arg, sel);
3277 rn = "WatchHi";
3278 break;
3279 default:
3280 goto die;
3281 }
3282 break;
3283 case 20:
3284 switch (sel) {
3285 case 0:
3286 #if defined(TARGET_MIPS64)
3287 check_insn(env, ctx, ISA_MIPS3);
3288 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3289 tcg_gen_ext32s_tl(arg, arg);
3290 rn = "XContext";
3291 break;
3292 #endif
3293 default:
3294 goto die;
3295 }
3296 break;
3297 case 21:
3298 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3299 switch (sel) {
3300 case 0:
3301 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3302 rn = "Framemask";
3303 break;
3304 default:
3305 goto die;
3306 }
3307 break;
3308 case 22:
3309 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3310 rn = "'Diagnostic"; /* implementation dependent */
3311 break;
3312 case 23:
3313 switch (sel) {
3314 case 0:
3315 gen_helper_mfc0_debug(arg); /* EJTAG support */
3316 rn = "Debug";
3317 break;
3318 case 1:
3319 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3320 rn = "TraceControl";
3321 // break;
3322 case 2:
3323 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3324 rn = "TraceControl2";
3325 // break;
3326 case 3:
3327 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3328 rn = "UserTraceData";
3329 // break;
3330 case 4:
3331 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3332 rn = "TraceBPC";
3333 // break;
3334 default:
3335 goto die;
3336 }
3337 break;
3338 case 24:
3339 switch (sel) {
3340 case 0:
3341 /* EJTAG support */
3342 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3343 tcg_gen_ext32s_tl(arg, arg);
3344 rn = "DEPC";
3345 break;
3346 default:
3347 goto die;
3348 }
3349 break;
3350 case 25:
3351 switch (sel) {
3352 case 0:
3353 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3354 rn = "Performance0";
3355 break;
3356 case 1:
3357 // gen_helper_mfc0_performance1(arg);
3358 rn = "Performance1";
3359 // break;
3360 case 2:
3361 // gen_helper_mfc0_performance2(arg);
3362 rn = "Performance2";
3363 // break;
3364 case 3:
3365 // gen_helper_mfc0_performance3(arg);
3366 rn = "Performance3";
3367 // break;
3368 case 4:
3369 // gen_helper_mfc0_performance4(arg);
3370 rn = "Performance4";
3371 // break;
3372 case 5:
3373 // gen_helper_mfc0_performance5(arg);
3374 rn = "Performance5";
3375 // break;
3376 case 6:
3377 // gen_helper_mfc0_performance6(arg);
3378 rn = "Performance6";
3379 // break;
3380 case 7:
3381 // gen_helper_mfc0_performance7(arg);
3382 rn = "Performance7";
3383 // break;
3384 default:
3385 goto die;
3386 }
3387 break;
3388 case 26:
3389 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3390 rn = "ECC";
3391 break;
3392 case 27:
3393 switch (sel) {
3394 case 0 ... 3:
3395 tcg_gen_movi_tl(arg, 0); /* unimplemented */
3396 rn = "CacheErr";
3397 break;
3398 default:
3399 goto die;
3400 }
3401 break;
3402 case 28:
3403 switch (sel) {
3404 case 0:
3405 case 2:
3406 case 4:
3407 case 6:
3408 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3409 rn = "TagLo";
3410 break;
3411 case 1:
3412 case 3:
3413 case 5:
3414 case 7:
3415 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3416 rn = "DataLo";
3417 break;
3418 default:
3419 goto die;
3420 }
3421 break;
3422 case 29:
3423 switch (sel) {
3424 case 0:
3425 case 2:
3426 case 4:
3427 case 6:
3428 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3429 rn = "TagHi";
3430 break;
3431 case 1:
3432 case 3:
3433 case 5:
3434 case 7:
3435 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3436 rn = "DataHi";
3437 break;
3438 default:
3439 goto die;
3440 }
3441 break;
3442 case 30:
3443 switch (sel) {
3444 case 0:
3445 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3446 tcg_gen_ext32s_tl(arg, arg);
3447 rn = "ErrorEPC";
3448 break;
3449 default:
3450 goto die;
3451 }
3452 break;
3453 case 31:
3454 switch (sel) {
3455 case 0:
3456 /* EJTAG support */
3457 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3458 rn = "DESAVE";
3459 break;
3460 default:
3461 goto die;
3462 }
3463 break;
3464 default:
3465 goto die;
3466 }
3467 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3468 return;
3469
3470 die:
3471 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3472 generate_exception(ctx, EXCP_RI);
3473 }
3474
3475 static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3476 {
3477 const char *rn = "invalid";
3478
3479 if (sel != 0)
3480 check_insn(env, ctx, ISA_MIPS32);
3481
3482 if (use_icount)
3483 gen_io_start();
3484
3485 switch (reg) {
3486 case 0:
3487 switch (sel) {
3488 case 0:
3489 gen_helper_mtc0_index(arg);
3490 rn = "Index";
3491 break;
3492 case 1:
3493 check_insn(env, ctx, ASE_MT);
3494 gen_helper_mtc0_mvpcontrol(arg);
3495 rn = "MVPControl";
3496 break;
3497 case 2:
3498 check_insn(env, ctx, ASE_MT);
3499 /* ignored */
3500 rn = "MVPConf0";
3501 break;
3502 case 3:
3503 check_insn(env, ctx, ASE_MT);
3504 /* ignored */
3505 rn = "MVPConf1";
3506 break;
3507 default:
3508 goto die;
3509 }
3510 break;
3511 case 1:
3512 switch (sel) {
3513 case 0:
3514 /* ignored */
3515 rn = "Random";
3516 break;
3517 case 1:
3518 check_insn(env, ctx, ASE_MT);
3519 gen_helper_mtc0_vpecontrol(arg);
3520 rn = "VPEControl";
3521 break;
3522 case 2:
3523 check_insn(env, ctx, ASE_MT);
3524 gen_helper_mtc0_vpeconf0(arg);
3525 rn = "VPEConf0";
3526 break;
3527 case 3:
3528 check_insn(env, ctx, ASE_MT);
3529 gen_helper_mtc0_vpeconf1(arg);
3530 rn = "VPEConf1";
3531 break;
3532 case 4:
3533 check_insn(env, ctx, ASE_MT);
3534 gen_helper_mtc0_yqmask(arg);
3535 rn = "YQMask";
3536 break;
3537 case 5:
3538 check_insn(env, ctx, ASE_MT);
3539 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3540 rn = "VPESchedule";
3541 break;
3542 case 6:
3543 check_insn(env, ctx, ASE_MT);
3544 gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3545 rn = "VPEScheFBack";
3546 break;
3547 case 7:
3548 check_insn(env, ctx, ASE_MT);
3549 gen_helper_mtc0_vpeopt(arg);
3550 rn = "VPEOpt";
3551 break;
3552 default:
3553 goto die;
3554 }
3555 break;
3556 case 2:
3557 switch (sel) {
3558 case 0:
3559 gen_helper_mtc0_entrylo0(arg);
3560 rn = "EntryLo0";
3561 break;
3562 case 1:
3563 check_insn(env, ctx, ASE_MT);
3564 gen_helper_mtc0_tcstatus(arg);
3565 rn = "TCStatus";
3566 break;
3567 case 2:
3568 check_insn(env, ctx, ASE_MT);
3569 gen_helper_mtc0_tcbind(arg);
3570 rn = "TCBind";
3571 break;
3572 case 3:
3573 check_insn(env, ctx, ASE_MT);
3574 gen_helper_mtc0_tcrestart(arg);
3575 rn = "TCRestart";
3576 break;
3577 case 4:
3578 check_insn(env, ctx, ASE_MT);
3579 gen_helper_mtc0_tchalt(arg);
3580 rn = "TCHalt";
3581 break;
3582 case 5:
3583 check_insn(env, ctx, ASE_MT);
3584 gen_helper_mtc0_tccontext(arg);
3585 rn = "TCContext";
3586 break;
3587 case 6:
3588 check_insn(env, ctx, ASE_MT);
3589 gen_helper_mtc0_tcschedule(arg);
3590 rn = "TCSchedule";
3591 break;
3592 case 7:
3593 check_insn(env, ctx, ASE_MT);
3594 gen_helper_mtc0_tcschefback(arg);
3595 rn = "TCScheFBack";
3596 break;
3597 default:
3598 goto die;
3599 }
3600 break;
3601 case 3:
3602 switch (sel) {
3603 case 0:
3604 gen_helper_mtc0_entrylo1(arg);
3605 rn = "EntryLo1";
3606 break;
3607 default:
3608 goto die;
3609 }
3610 break;
3611 case 4:
3612 switch (sel) {
3613 case 0:
3614 gen_helper_mtc0_context(arg);
3615 rn = "Context";
3616 break;
3617 case 1:
3618 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3619 rn = "ContextConfig";
3620 // break;
3621 default:
3622 goto die;
3623 }
3624 break;
3625 case 5:
3626 switch (sel) {
3627 case 0:
3628 gen_helper_mtc0_pagemask(arg);
3629 rn = "PageMask";
3630 break;
3631 case 1:
3632 check_insn(env, ctx, ISA_MIPS32R2);
3633 gen_helper_mtc0_pagegrain(arg);
3634 rn = "PageGrain";
3635 break;
3636 default:
3637 goto die;
3638 }
3639 break;
3640 case 6:
3641 switch (sel) {
3642 case 0:
3643 gen_helper_mtc0_wired(arg);
3644 rn = "Wired";
3645 break;
3646 case 1:
3647 check_insn(env, ctx, ISA_MIPS32R2);
3648 gen_helper_mtc0_srsconf0(arg);
3649 rn = "SRSConf0";
3650 break;
3651 case 2:
3652 check_insn(env, ctx, ISA_MIPS32R2);
3653 gen_helper_mtc0_srsconf1(arg);
3654 rn = "SRSConf1";
3655 break;
3656 case 3:
3657 check_insn(env, ctx, ISA_MIPS32R2);
3658 gen_helper_mtc0_srsconf2(arg);
3659 rn = "SRSConf2";
3660 break;
3661 case 4:
3662 check_insn(env, ctx, ISA_MIPS32R2);
3663 gen_helper_mtc0_srsconf3(arg);
3664 rn = "SRSConf3";
3665 break;
3666 case 5:
3667 check_insn(env, ctx, ISA_MIPS32R2);
3668 gen_helper_mtc0_srsconf4(arg);
3669 rn = "SRSConf4";
3670 break;
3671 default:
3672 goto die;
3673 }
3674 break;
3675 case 7:
3676 switch (sel) {
3677 case 0:
3678 check_insn(env, ctx, ISA_MIPS32R2);
3679 gen_helper_mtc0_hwrena(arg);
3680 rn = "HWREna";
3681 break;
3682 default:
3683 goto die;
3684 }
3685 break;
3686 case 8:
3687 /* ignored */
3688 rn = "BadVAddr";
3689 break;
3690 case 9:
3691 switch (sel) {
3692 case 0:
3693 gen_helper_mtc0_count(arg);
3694 rn = "Count";
3695 break;
3696 /* 6,7 are implementation dependent */
3697 default:
3698 goto die;
3699 }
3700 break;
3701 case 10:
3702 switch (sel) {
3703 case 0:
3704 gen_helper_mtc0_entryhi(arg);
3705 rn = "EntryHi";
3706 break;
3707 default:
3708 goto die;
3709 }
3710 break;
3711 case 11:
3712 switch (sel) {
3713 case 0:
3714 gen_helper_mtc0_compare(arg);
3715 rn = "Compare";
3716 break;
3717 /* 6,7 are implementation dependent */
3718 default:
3719 goto die;
3720 }
3721 break;
3722 case 12:
3723 switch (sel) {
3724 case 0:
3725 save_cpu_state(ctx, 1);
3726 gen_helper_mtc0_status(arg);
3727 /* BS_STOP isn't good enough here, hflags may have changed. */
3728 gen_save_pc(ctx->pc + 4);
3729 ctx->bstate = BS_EXCP;
3730 rn = "Status";
3731 break;
3732 case 1:
3733 check_insn(env, ctx, ISA_MIPS32R2);
3734 gen_helper_mtc0_intctl(arg);
3735 /* Stop translation as we may have switched the execution mode */
3736 ctx->bstate = BS_STOP;
3737 rn = "IntCtl";
3738 break;
3739 case 2:
3740 check_insn(env, ctx, ISA_MIPS32R2);
3741 gen_helper_mtc0_srsctl(arg);
3742 /* Stop translation as we may have switched the execution mode */
3743 ctx->bstate = BS_STOP;
3744 rn = "SRSCtl";
3745 break;
3746 case 3:
3747 check_insn(env, ctx, ISA_MIPS32R2);
3748 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
3749 /* Stop translation as we may have switched the execution mode */
3750 ctx->bstate = BS_STOP;
3751 rn = "SRSMap";
3752 break;
3753 default:
3754 goto die;
3755 }
3756 break;
3757 case 13:
3758 switch (sel) {
3759 case 0:
3760 save_cpu_state(ctx, 1);
3761 gen_helper_mtc0_cause(arg);
3762 rn = "Cause";
3763 break;
3764 default:
3765 goto die;
3766 }
3767 break;
3768 case 14:
3769 switch (sel) {
3770 case 0:
3771 gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
3772 rn = "EPC";
3773 break;
3774 default:
3775 goto die;
3776 }
3777 break;
3778 case 15:
3779 switch (sel) {
3780 case 0:
3781 /* ignored */
3782 rn = "PRid";
3783 break;
3784 case 1:
3785 check_insn(env, ctx, ISA_MIPS32R2);
3786 gen_helper_mtc0_ebase(arg);
3787 rn = "EBase";
3788 break;
3789 default:
3790 goto die;
3791 }
3792 break;
3793 case 16:
3794 switch (sel) {
3795 case 0:
3796 gen_helper_mtc0_config0(arg);
3797 rn = "Config";
3798 /* Stop translation as we may have switched the execution mode */
3799 ctx->bstate = BS_STOP;
3800 break;
3801 case 1:
3802 /* ignored, read only */
3803 rn = "Config1";
3804 break;
3805 case 2:
3806 gen_helper_mtc0_config2(arg);
3807 rn = "Config2";
3808 /* Stop translation as we may have switched the execution mode */
3809 ctx->bstate = BS_STOP;
3810 break;
3811 case 3:
3812 /* ignored, read only */
3813 rn = "Config3";
3814 break;
3815 /* 4,5 are reserved */
3816 /* 6,7 are implementation dependent */
3817 case 6:
3818 /* ignored */
3819 rn = "Config6";
3820 break;
3821 case 7:
3822 /* ignored */
3823 rn = "Config7";
3824 break;
3825 default:
3826 rn = "Invalid config selector";
3827 goto die;
3828 }
3829 break;
3830 case 17:
3831 switch (sel) {
3832 case 0:
3833 gen_helper_mtc0_lladdr(arg);
3834 rn = "LLAddr";
3835 break;
3836 default:
3837 goto die;
3838 }
3839 break;
3840 case 18:
3841 switch (sel) {
3842 case 0 ... 7:
3843 gen_helper_1i(mtc0_watchlo, arg, sel);
3844 rn = "WatchLo";
3845 break;
3846 default:
3847 goto die;
3848 }
3849 break;
3850 case 19:
3851 switch (sel) {
3852 case 0 ... 7:
3853 gen_helper_1i(mtc0_watchhi, arg, sel);
3854 rn = "WatchHi";
3855 break;
3856 default:
3857 goto die;
3858 }
3859 break;
3860 case 20:
3861 switch (sel) {
3862 case 0:
3863 #if defined(TARGET_MIPS64)
3864 check_insn(env, ctx, ISA_MIPS3);
3865 gen_helper_mtc0_xcontext(arg);
3866 rn = "XContext";
3867 break;
3868 #endif
3869 default:
3870 goto die;
3871 }
3872 break;
3873 case 21:
3874 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3875 switch (sel) {
3876 case 0:
3877 gen_helper_mtc0_framemask(arg);
3878 rn = "Framemask";
3879 break;
3880 default:
3881 goto die;
3882 }
3883 break;
3884 case 22:
3885 /* ignored */
3886 rn = "Diagnostic"; /* implementation dependent */
3887 break;
3888 case 23:
3889 switch (sel) {
3890 case 0:
3891 gen_helper_mtc0_debug(arg); /* EJTAG support */
3892 /* BS_STOP isn't good enough here, hflags may have changed. */
3893 gen_save_pc(ctx->pc + 4);
3894 ctx->bstate = BS_EXCP;
3895 rn = "Debug";
3896 break;
3897 case 1:
3898 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
3899 rn = "TraceControl";
3900 /* Stop translation as we may have switched the execution mode */
3901 ctx->bstate = BS_STOP;
3902 // break;
3903 case 2:
3904 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
3905 rn = "TraceControl2";
3906 /* Stop translation as we may have switched the execution mode */
3907 ctx->bstate = BS_STOP;
3908 // break;
3909 case 3:
3910 /* Stop translation as we may have switched the execution mode */
3911 ctx->bstate = BS_STOP;
3912 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
3913 rn = "UserTraceData";
3914 /* Stop translation as we may have switched the execution mode */
3915 ctx->bstate = BS_STOP;
3916 // break;
3917 case 4:
3918 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
3919 /* Stop translation as we may have switched the execution mode */
3920 ctx->bstate = BS_STOP;
3921 rn = "TraceBPC";
3922 // break;
3923 default:
3924 goto die;
3925 }
3926 break;
3927 case 24:
3928 switch (sel) {
3929 case 0:
3930 /* EJTAG support */
3931 gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
3932 rn = "DEPC";
3933 break;
3934 default:
3935 goto die;
3936 }
3937 break;
3938 case 25:
3939 switch (sel) {
3940 case 0:
3941 gen_helper_mtc0_performance0(arg);
3942 rn = "Performance0";
3943 break;
3944 case 1:
3945 // gen_helper_mtc0_performance1(arg);
3946 rn = "Performance1";
3947 // break;
3948 case 2:
3949 // gen_helper_mtc0_performance2(arg);
3950 rn = "Performance2";
3951 // break;
3952 case 3:
3953 // gen_helper_mtc0_performance3(arg);
3954 rn = "Performance3";
3955 // break;
3956 case 4:
3957 // gen_helper_mtc0_performance4(arg);
3958 rn = "Performance4";
3959 // break;
3960 case 5:
3961 // gen_helper_mtc0_performance5(arg);
3962 rn = "Performance5";
3963 // break;
3964 case 6:
3965 // gen_helper_mtc0_performance6(arg);
3966 rn = "Performance6";
3967 // break;
3968 case 7:
3969 // gen_helper_mtc0_performance7(arg);
3970 rn = "Performance7";
3971 // break;
3972 default:
3973 goto die;
3974 }
3975 break;
3976 case 26:
3977 /* ignored */
3978 rn = "ECC";
3979 break;
3980 case 27:
3981 switch (sel) {
3982 case 0 ... 3:
3983 /* ignored */
3984 rn = "CacheErr";
3985 break;
3986 default:
3987 goto die;
3988 }
3989 break;
3990 case 28:
3991 switch (sel) {
3992 case 0:
3993 case 2:
3994 case 4:
3995 case 6:
3996 gen_helper_mtc0_taglo(arg);
3997 rn = "TagLo";
3998 break;
3999 case 1:
4000 case 3:
4001 case 5:
4002 case 7:
4003 gen_helper_mtc0_datalo(arg);
4004 rn = "DataLo";
4005 break;
4006 default:
4007 goto die;
4008 }
4009 break;
4010 case 29:
4011 switch (sel) {
4012 case 0:
4013 case 2:
4014 case 4:
4015 case 6:
4016 gen_helper_mtc0_taghi(arg);
4017 rn = "TagHi";
4018 break;
4019 case 1:
4020 case 3:
4021 case 5:
4022 case 7:
4023 gen_helper_mtc0_datahi(arg);
4024 rn = "DataHi";
4025 break;
4026 default:
4027 rn = "invalid sel";
4028 goto die;
4029 }
4030 break;
4031 case 30:
4032 switch (sel) {
4033 case 0:
4034 gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4035 rn = "ErrorEPC";
4036 break;
4037 default:
4038 goto die;
4039 }
4040 break;
4041 case 31:
4042 switch (sel) {
4043 case 0:
4044 /* EJTAG support */
4045 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4046 rn = "DESAVE";
4047 break;
4048 default:
4049 goto die;
4050 }
4051 /* Stop translation as we may have switched the execution mode */
4052 ctx->bstate = BS_STOP;
4053 break;
4054 default:
4055 goto die;
4056 }
4057 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4058 /* For simplicity assume that all writes can cause interrupts. */
4059 if (use_icount) {
4060 gen_io_end();
4061 ctx->bstate = BS_STOP;
4062 }
4063 return;
4064
4065 die:
4066 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4067 generate_exception(ctx, EXCP_RI);
4068 }
4069
4070 #if defined(TARGET_MIPS64)
4071 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4072 {
4073 const char *rn = "invalid";
4074
4075 if (sel != 0)
4076 check_insn(env, ctx, ISA_MIPS64);
4077
4078 switch (reg) {
4079 case 0:
4080 switch (sel) {
4081 case 0:
4082 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4083 rn = "Index";
4084 break;
4085 case 1:
4086 check_insn(env, ctx, ASE_MT);
4087 gen_helper_mfc0_mvpcontrol(arg);
4088 rn = "MVPControl";
4089 break;
4090 case 2:
4091 check_insn(env, ctx, ASE_MT);
4092 gen_helper_mfc0_mvpconf0(arg);
4093 rn = "MVPConf0";
4094 break;
4095 case 3:
4096 check_insn(env, ctx, ASE_MT);
4097 gen_helper_mfc0_mvpconf1(arg);
4098 rn = "MVPConf1";
4099 break;
4100 default:
4101 goto die;
4102 }
4103 break;
4104 case 1:
4105 switch (sel) {
4106 case 0:
4107 gen_helper_mfc0_random(arg);
4108 rn = "Random";
4109 break;
4110 case 1:
4111 check_insn(env, ctx, ASE_MT);
4112 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4113 rn = "VPEControl";
4114 break;
4115 case 2:
4116 check_insn(env, ctx, ASE_MT);
4117 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4118 rn = "VPEConf0";
4119 break;
4120 case 3:
4121 check_insn(env, ctx, ASE_MT);
4122 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4123 rn = "VPEConf1";
4124 break;
4125 case 4:
4126 check_insn(env, ctx, ASE_MT);
4127 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4128 rn = "YQMask";
4129 break;
4130 case 5:
4131 check_insn(env, ctx, ASE_MT);
4132 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4133 rn = "VPESchedule";
4134 break;
4135 case 6:
4136 check_insn(env, ctx, ASE_MT);
4137 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4138 rn = "VPEScheFBack";
4139 break;
4140 case 7:
4141 check_insn(env, ctx, ASE_MT);
4142 gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4143 rn = "VPEOpt";
4144 break;
4145 default:
4146 goto die;
4147 }
4148 break;
4149 case 2:
4150 switch (sel) {
4151 case 0:
4152 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4153 rn = "EntryLo0";
4154 break;
4155 case 1:
4156 check_insn(env, ctx, ASE_MT);
4157 gen_helper_mfc0_tcstatus(arg);
4158 rn = "TCStatus";
4159 break;
4160 case 2:
4161 check_insn(env, ctx, ASE_MT);
4162 gen_helper_mfc0_tcbind(arg);
4163 rn = "TCBind";
4164 break;
4165 case 3:
4166 check_insn(env, ctx, ASE_MT);
4167 gen_helper_dmfc0_tcrestart(arg);
4168 rn = "TCRestart";
4169 break;
4170 case 4:
4171 check_insn(env, ctx, ASE_MT);
4172 gen_helper_dmfc0_tchalt(arg);
4173 rn = "TCHalt";
4174 break;
4175 case 5:
4176 check_insn(env, ctx, ASE_MT);
4177 gen_helper_dmfc0_tccontext(arg);
4178 rn = "TCContext";
4179 break;
4180 case 6:
4181 check_insn(env, ctx, ASE_MT);
4182 gen_helper_dmfc0_tcschedule(arg);
4183 rn = "TCSchedule";
4184 break;
4185 case 7:
4186 check_insn(env, ctx, ASE_MT);
4187 gen_helper_dmfc0_tcschefback(arg);
4188 rn = "TCScheFBack";
4189 break;
4190 default:
4191 goto die;
4192 }
4193 break;
4194 case 3:
4195 switch (sel) {
4196 case 0:
4197 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4198 rn = "EntryLo1";
4199 break;
4200 default:
4201 goto die;
4202 }
4203 break;
4204 case 4:
4205 switch (sel) {
4206 case 0:
4207 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4208 rn = "Context";
4209 break;
4210 case 1:
4211 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
4212 rn = "ContextConfig";
4213 // break;
4214 default:
4215 goto die;
4216 }
4217 break;
4218 case 5:
4219 switch (sel) {
4220 case 0:
4221 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
4222 rn = "PageMask";
4223 break;
4224 case 1:
4225 check_insn(env, ctx, ISA_MIPS32R2);
4226 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
4227 rn = "PageGrain";
4228 break;
4229 default:
4230 goto die;
4231 }
4232 break;
4233 case 6:
4234 switch (sel) {
4235 case 0:
4236 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
4237 rn = "Wired";
4238 break;
4239 case 1:
4240 check_insn(env, ctx, ISA_MIPS32R2);
4241 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4242 rn = "SRSConf0";
4243 break;
4244 case 2:
4245 check_insn(env, ctx, ISA_MIPS32R2);
4246 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4247 rn = "SRSConf1";
4248 break;
4249 case 3:
4250 check_insn(env, ctx, ISA_MIPS32R2);
4251 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4252 rn = "SRSConf2";
4253 break;
4254 case 4:
4255 check_insn(env, ctx, ISA_MIPS32R2);
4256 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4257 rn = "SRSConf3";
4258 break;
4259 case 5:
4260 check_insn(env, ctx, ISA_MIPS32R2);
4261 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
4262 rn = "SRSConf4";
4263 break;
4264 default:
4265 goto die;
4266 }
4267 break;
4268 case 7:
4269 switch (sel) {
4270 case 0:
4271 check_insn(env, ctx, ISA_MIPS32R2);
4272 gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
4273 rn = "HWREna";
4274 break;
4275 default:
4276 goto die;
4277 }
4278 break;
4279 case 8:
4280 switch (sel) {
4281 case 0:
4282 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4283 rn = "BadVAddr";
4284 break;
4285 default:
4286 goto die;
4287 }
4288 break;
4289 case 9:
4290 switch (sel) {
4291 case 0:
4292 /* Mark as an IO operation because we read the time. */
4293 if (use_icount)
4294 gen_io_start();
4295 gen_helper_mfc0_count(arg);
4296 if (use_icount) {
4297 gen_io_end();
4298 ctx->bstate = BS_STOP;
4299 }
4300 rn = "Count";
4301 break;
4302 /* 6,7 are implementation dependent */
4303 default:
4304 goto die;
4305 }
4306 break;
4307 case 10:
4308 switch (sel) {
4309 case 0:
4310 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4311 rn = "EntryHi";
4312 break;
4313 default:
4314 goto die;
4315 }
4316 break;
4317 case 11:
4318 switch (sel) {
4319 case 0:
4320 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4321 rn = "Compare";
4322 break;
4323 /* 6,7 are implementation dependent */
4324 default:
4325 goto die;
4326 }
4327 break;
4328 case 12:
4329 switch (sel) {
4330 case 0:
4331 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4332 rn = "Status";
4333 break;
4334 case 1:
4335 check_insn(env, ctx, ISA_MIPS32R2);
4336 gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4337 rn = "IntCtl";
4338 break;
4339 case 2:
4340 check_insn(env, ctx, ISA_MIPS32R2);
4341 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4342 rn = "SRSCtl";
4343 break;
4344 case 3:
4345 check_insn(env, ctx, ISA_MIPS32R2);
4346 gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4347 rn = "SRSMap";
4348 break;
4349 default:
4350 goto die;
4351 }
4352 break;
4353 case 13:
4354 switch (sel) {
4355 case 0:
4356 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4357 rn = "Cause";
4358 break;
4359 default:
4360 goto die;
4361 }
4362 break;
4363 case 14:
4364 switch (sel) {
4365 case 0:
4366 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4367 rn = "EPC";
4368 break;
4369 default:
4370 goto die;
4371 }
4372 break;
4373 case 15:
4374 switch (sel) {
4375 case 0:
4376 gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4377 rn = "PRid";
4378 break;
4379 case 1:
4380 check_insn(env, ctx, ISA_MIPS32R2);
4381 gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4382 rn = "EBase";
4383 break;
4384 default:
4385 goto die;
4386 }
4387 break;
4388 case 16:
4389 switch (sel) {
4390 case 0:
4391 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4392 rn = "Config";
4393 break;
4394 case 1:
4395 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4396 rn = "Config1";
4397 break;
4398 case 2:
4399 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4400 rn = "Config2";
4401 break;
4402 case 3:
4403 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4404 rn = "Config3";
4405 break;
4406 /* 6,7 are implementation dependent */
4407 case 6:
4408 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4409 rn = "Config6";
4410 break;
4411 case 7:
4412 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4413 rn = "Config7";
4414 break;
4415 default:
4416 goto die;
4417 }
4418 break;
4419 case 17:
4420 switch (sel) {
4421 case 0:
4422 gen_helper_dmfc0_lladdr(arg);
4423 rn = "LLAddr";
4424 break;
4425 default:
4426 goto die;
4427 }
4428 break;
4429 case 18:
4430 switch (sel) {
4431 case 0 ... 7:
4432 gen_helper_1i(dmfc0_watchlo, arg, sel);
4433 rn = "WatchLo";
4434 break;
4435 default:
4436 goto die;
4437 }
4438 break;
4439 case 19:
4440 switch (sel) {
4441 case 0 ... 7:
4442 gen_helper_1i(mfc0_watchhi, arg, sel);
4443 rn = "WatchHi";
4444 break;
4445 default:
4446 goto die;
4447 }
4448 break;
4449 case 20:
4450 switch (sel) {
4451 case 0:
4452 check_insn(env, ctx, ISA_MIPS3);
4453 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4454 rn = "XContext";
4455 break;
4456 default:
4457 goto die;
4458 }
4459 break;
4460 case 21:
4461 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4462 switch (sel) {
4463 case 0:
4464 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4465 rn = "Framemask";
4466 break;
4467 default:
4468 goto die;
4469 }
4470 break;
4471 case 22:
4472 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4473 rn = "'Diagnostic"; /* implementation dependent */
4474 break;
4475 case 23:
4476 switch (sel) {
4477 case 0:
4478 gen_helper_mfc0_debug(arg); /* EJTAG support */
4479 rn = "Debug";
4480 break;
4481 case 1:
4482 // gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4483 rn = "TraceControl";
4484 // break;
4485 case 2:
4486 // gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4487 rn = "TraceControl2";
4488 // break;
4489 case 3:
4490 // gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4491 rn = "UserTraceData";
4492 // break;
4493 case 4:
4494 // gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4495 rn = "TraceBPC";
4496 // break;
4497 default:
4498 goto die;
4499 }
4500 break;
4501 case 24:
4502 switch (sel) {
4503 case 0:
4504 /* EJTAG support */
4505 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4506 rn = "DEPC";
4507 break;
4508 default:
4509 goto die;
4510 }
4511 break;
4512 case 25:
4513 switch (sel) {
4514 case 0:
4515 gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4516 rn = "Performance0";
4517 break;
4518 case 1:
4519 // gen_helper_dmfc0_performance1(arg);
4520 rn = "Performance1";
4521 // break;
4522 case 2:
4523 // gen_helper_dmfc0_performance2(arg);
4524 rn = "Performance2";
4525 // break;
4526 case 3:
4527 // gen_helper_dmfc0_performance3(arg);
4528 rn = "Performance3";
4529 // break;
4530 case 4:
4531 // gen_helper_dmfc0_performance4(arg);
4532 rn = "Performance4";
4533 // break;
4534 case 5:
4535 // gen_helper_dmfc0_performance5(arg);
4536 rn = "Performance5";
4537 // break;
4538 case 6:
4539 // gen_helper_dmfc0_performance6(arg);
4540 rn = "Performance6";
4541 // break;
4542 case 7:
4543 // gen_helper_dmfc0_performance7(arg);
4544 rn = "Performance7";
4545 // break;
4546 default:
4547 goto die;
4548 }
4549 break;
4550 case 26:
4551 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4552 rn = "ECC";
4553 break;
4554 case 27:
4555 switch (sel) {
4556 /* ignored */
4557 case 0 ... 3:
4558 tcg_gen_movi_tl(arg, 0); /* unimplemented */
4559 rn = "CacheErr";
4560 break;
4561 default:
4562 goto die;
4563 }
4564 break;
4565 case 28:
4566 switch (sel) {
4567 case 0:
4568 case 2:
4569 case 4:
4570 case 6:
4571 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4572 rn = "TagLo";
4573 break;
4574 case 1:
4575 case 3:
4576 case 5:
4577 case 7:
4578 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4579 rn = "DataLo";
4580 break;
4581 default:
4582 goto die;
4583 }
4584 break;
4585 case 29:
4586 switch (sel) {
4587 case 0:
4588 case 2:
4589 case 4:
4590 case 6:
4591 gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4592 rn = "TagHi";
4593 break;
4594 case 1:
4595 case 3:
4596 case 5:
4597 case 7:
4598 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4599 rn = "DataHi";
4600 break;
4601 default:
4602 goto die;
4603 }
4604 break;
4605 case 30:
4606 switch (sel) {
4607 case 0:
4608 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4609 rn = "ErrorEPC";
4610 break;
4611 default:
4612 goto die;
4613 }
4614 break;
4615 case 31:
4616 switch (sel) {
4617 case 0:
4618 /* EJTAG support */
4619 gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4620 rn = "DESAVE";
4621 break;
4622 default:
4623 goto die;
4624 }
4625 break;
4626 default:
4627 goto die;
4628 }
4629 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4630 return;
4631
4632 die:
4633 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4634 generate_exception(ctx, EXCP_RI);
4635 }
4636
4637 static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4638 {
4639 const char *rn = "invalid";
4640
4641 if (sel != 0)
4642 check_insn(env, ctx, ISA_MIPS64);
4643
4644 if (use_icount)
4645 gen_io_start();
4646
4647 switch (reg) {
4648 case 0:
4649 switch (sel) {
4650 case 0:
4651 gen_helper_mtc0_index(arg);
4652 rn = "Index";
4653 break;
4654 case 1:
4655 check_insn(env, ctx, ASE_MT);
4656 gen_helper_mtc0_mvpcontrol(arg);
4657 rn = "MVPControl";
4658 break;
4659 case 2:
4660 check_insn(env, ctx, ASE_MT);
4661 /* ignored */
4662 rn = "MVPConf0";
4663 break;
4664 case 3:
4665 check_insn(env, ctx, ASE_MT);
4666 /* ignored */
4667 rn = "MVPConf1";
4668 break;
4669 default:
4670 goto die;
4671 }
4672 break;
4673 case 1:
4674 switch (sel) {
4675 case 0:
4676 /* ignored */
4677 rn = "Random";
4678 break;
4679 case 1:
4680 check_insn(env, ctx, ASE_MT);
4681 gen_helper_mtc0_vpecontrol(arg);
4682 rn = "VPEControl";
4683 break;
4684 case 2:
4685 check_insn(env, ctx, ASE_MT);
4686 gen_helper_mtc0_vpeconf0(arg);
4687 rn = "VPEConf0";
4688 break;
4689 case 3:
4690 check_insn(env, ctx, ASE_MT);
4691 gen_helper_mtc0_vpeconf1(arg);
4692 rn = "VPEConf1";
4693 break;
4694 case 4:
4695 check_insn(env, ctx, ASE_MT);
4696 gen_helper_mtc0_yqmask(arg);
4697 rn = "YQMask";
4698 break;
4699 case 5:
4700 check_insn(env, ctx, ASE_MT);
4701 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4702 rn = "VPESchedule";
4703 break;
4704 case 6:
4705 check_insn(env, ctx, ASE_MT);
4706 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4707 rn = "VPEScheFBack";
4708 break;
4709 case 7:
4710 check_insn(env, ctx, ASE_MT);
4711 gen_helper_mtc0_vpeopt(arg);
4712 rn = "VPEOpt";
4713 break;
4714 default:
4715 goto die;
4716 }
4717 break;
4718 case 2:
4719 switch (sel) {
4720 case 0:
4721 gen_helper_mtc0_entrylo0(arg);
4722 rn = "EntryLo0";
4723 break;
4724 case 1:
4725 check_insn(env, ctx, ASE_MT);
4726 gen_helper_mtc0_tcstatus(arg);
4727 rn = "TCStatus";
4728 break;
4729 case 2:
4730 check_insn(env, ctx, ASE_MT);
4731 gen_helper_mtc0_tcbind(arg);
4732 rn = "TCBind";
4733 break;
4734 case 3:
4735 check_insn(env, ctx, ASE_MT);
4736 gen_helper_mtc0_tcrestart(arg);
4737 rn = "TCRestart";
4738 break;
4739 case 4:
4740 check_insn(env, ctx, ASE_MT);
4741 gen_helper_mtc0_tchalt(arg);
4742 rn = "TCHalt";
4743 break;
4744 case 5:
4745 check_insn(env, ctx, ASE_MT);
4746 gen_helper_mtc0_tccontext(arg);
4747 rn = "TCContext";
4748 break;
4749 case 6:
4750 check_insn(env, ctx, ASE_MT);
4751 gen_helper_mtc0_tcschedule(arg);
4752 rn = "TCSchedule";
4753 break;
4754 case 7:
4755 check_insn(env, ctx, ASE_MT);
4756 gen_helper_mtc0_tcschefback(arg);
4757 rn = "TCScheFBack";
4758 break;
4759 default:
4760 goto die;
4761 }
4762 break;
4763 case 3:
4764 switch (sel) {
4765 case 0:
4766 gen_helper_mtc0_entrylo1(arg);
4767 rn = "EntryLo1";
4768 break;
4769 default:
4770 goto die;
4771 }
4772 break;
4773 case 4:
4774 switch (sel) {
4775 case 0:
4776 gen_helper_mtc0_context(arg);
4777 rn = "Context";
4778 break;
4779 case 1:
4780 // gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
4781 rn = "ContextConfig";
4782 // break;
4783 default:
4784 goto die;
4785 }
4786 break;
4787 case 5:
4788 switch (sel) {
4789 case 0:
4790 gen_helper_mtc0_pagemask(arg);
4791 rn = "PageMask";
4792 break;
4793 case 1:
4794 check_insn(env, ctx, ISA_MIPS32R2);
4795 gen_helper_mtc0_pagegrain(arg);
4796 rn = "PageGrain";
4797 break;
4798 default:
4799 goto die;
4800 }
4801 break;
4802 case 6:
4803 switch (sel) {
4804 case 0:
4805 gen_helper_mtc0_wired(arg);
4806 rn = "Wired";
4807 break;
4808 case 1:
4809 check_insn(env, ctx, ISA_MIPS32R2);
4810 gen_helper_mtc0_srsconf0(arg);
4811 rn = "SRSConf0";
4812 break;
4813 case 2:
4814 check_insn(env, ctx, ISA_MIPS32R2);
4815 gen_helper_mtc0_srsconf1(arg);
4816 rn = "SRSConf1";
4817 break;
4818 case 3:
4819 check_insn(env, ctx, ISA_MIPS32R2);
4820 gen_helper_mtc0_srsconf2(arg);
4821 rn = "SRSConf2";
4822 break;
4823 case 4:
4824 check_insn(env, ctx, ISA_MIPS32R2);
4825 gen_helper_mtc0_srsconf3(arg);
4826 rn = "SRSConf3";
4827 break;
4828 case 5:
4829 check_insn(env, ctx, ISA_MIPS32R2);
4830 gen_helper_mtc0_srsconf4(arg);
4831 rn = "SRSConf4";
4832 break;
4833 default:
4834 goto die;
4835 }
4836 break;
4837 case 7:
4838 switch (sel) {
4839 case 0:
4840 check_insn(env, ctx, ISA_MIPS32R2);
4841 gen_helper_mtc0_hwrena(arg);
4842 rn = "HWREna";
4843 break;
4844 default:
4845 goto die;
4846 }
4847 break;
4848 case 8:
4849 /* ignored */
4850 rn = "BadVAddr";
4851 break;
4852 case 9:
4853 switch (sel) {
4854 case 0:
4855 gen_helper_mtc0_count(arg);
4856 rn = "Count";
4857 break;
4858 /* 6,7 are implementation dependent */
4859 default:
4860 goto die;
4861 }
4862 /* Stop translation as we may have switched the execution mode */
4863 ctx->bstate = BS_STOP;
4864 break;
4865 case 10:
4866 switch (sel) {
4867 case 0:
4868 gen_helper_mtc0_entryhi(arg);
4869 rn = "EntryHi";
4870 break;
4871 default:
4872 goto die;
4873 }
4874 break;
4875 case 11:
4876 switch (sel) {
4877 case 0:
4878 gen_helper_mtc0_compare(arg);
4879 rn = "Compare";
4880 break;
4881 /* 6,7 are implementation dependent */
4882 default:
4883 goto die;
4884 }
4885 /* Stop translation as we may have switched the execution mode */
4886 ctx->bstate = BS_STOP;
4887 break;
4888 case 12:
4889 switch (sel) {
4890 case 0:
4891 save_cpu_state(ctx, 1);
4892 gen_helper_mtc0_status(arg);
4893 /* BS_STOP isn't good enough here, hflags may have changed. */
4894 gen_save_pc(ctx->pc + 4);
4895 ctx->bstate = BS_EXCP;
4896 rn = "Status";
4897 break;
4898 case 1:
4899 check_insn(env, ctx, ISA_MIPS32R2);
4900 gen_helper_mtc0_intctl(arg);
4901 /* Stop translation as we may have switched the execution mode */
4902 ctx->bstate = BS_STOP;
4903 rn = "IntCtl";
4904 break;
4905 case 2:
4906 check_insn(env, ctx, ISA_MIPS32R2);
4907 gen_helper_mtc0_srsctl(arg);
4908 /* Stop translation as we may have switched the execution mode */
4909 ctx->bstate = BS_STOP;
4910 rn = "SRSCtl";
4911 break;
4912 case 3:
4913 check_insn(env, ctx, ISA_MIPS32R2);
4914 gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
4915 /* Stop translation as we may have switched the execution mode */
4916 ctx->bstate = BS_STOP;
4917 rn = "SRSMap";
4918 break;
4919 default:
4920 goto die;
4921 }
4922 break;
4923 case 13:
4924 switch (sel) {
4925 case 0:
4926 save_cpu_state(ctx, 1);
4927 gen_helper_mtc0_cause(arg);
4928 rn = "Cause";
4929 break;
4930 default:
4931 goto die;
4932 }
4933 break;
4934 case 14:
4935 switch (sel) {
4936 case 0:
4937 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4938 rn = "EPC";
4939 break;
4940 default:
4941 goto die;
4942 }
4943 break;
4944 case 15:
4945 switch (sel) {
4946 case 0:
4947 /* ignored */
4948 rn = "PRid";
4949 break;
4950 case 1:
4951 check_insn(env, ctx, ISA_MIPS32R2);
4952 gen_helper_mtc0_ebase(arg);
4953 rn = "EBase";
4954 break;
4955 default:
4956 goto die;
4957 }
4958 break;
4959 case 16:
4960 switch (sel) {
4961 case 0:
4962 gen_helper_mtc0_config0(arg);
4963 rn = "Config";
4964 /* Stop translation as we may have switched the execution mode */
4965 ctx->bstate = BS_STOP;
4966 break;
4967 case 1:
4968 /* ignored, read only */
4969 rn = "Config1";
4970 break;
4971 case 2:
4972 gen_helper_mtc0_config2(arg);
4973 rn = "Config2";
4974 /* Stop translation as we may have switched the execution mode */
4975 ctx->bstate = BS_STOP;
4976 break;
4977 case 3:
4978 /* ignored */
4979 rn = "Config3";
4980 break;
4981 /* 6,7 are implementation dependent */
4982 default:
4983 rn = "Invalid config selector";
4984 goto die;
4985 }
4986 break;
4987 case 17:
4988 switch (sel) {
4989 case 0:
4990 gen_helper_mtc0_lladdr(arg);
4991 rn = "LLAddr";
4992 break;
4993 default:
4994 goto die;
4995 }
4996 break;
4997 case 18:
4998 switch (sel) {
4999 case 0 ... 7:
5000 gen_helper_1i(mtc0_watchlo, arg, sel);
5001 rn = "WatchLo";
5002 break;
5003 default:
5004 goto die;
5005 }
5006 break;
5007 case 19:
5008 switch (sel) {
5009 case 0 ... 7:
5010 gen_helper_1i(mtc0_watchhi, arg, sel);
5011 rn = "WatchHi";
5012 break;
5013 default:
5014 goto die;
5015 }
5016 break;
5017 case 20:
5018 switch (sel) {
5019 case 0:
5020 check_insn(env, ctx, ISA_MIPS3);
5021 gen_helper_mtc0_xcontext(arg);
5022 rn = "XContext";
5023 break;
5024 default:
5025 goto die;
5026 }
5027 break;
5028 case 21:
5029 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5030 switch (sel) {
5031 case 0:
5032 gen_helper_mtc0_framemask(arg);
5033 rn = "Framemask";
5034 break;
5035 default:
5036 goto die;
5037 }
5038 break;
5039 case 22:
5040 /* ignored */
5041 rn = "Diagnostic"; /* implementation dependent */
5042 break;
5043 case 23:
5044 switch (sel) {
5045 case 0:
5046 gen_helper_mtc0_debug(arg); /* EJTAG support */
5047 /* BS_STOP isn't good enough here, hflags may have changed. */
5048 gen_save_pc(ctx->pc + 4);
5049 ctx->bstate = BS_EXCP;
5050 rn = "Debug";
5051 break;
5052 case 1:
5053 // gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5054 /* Stop translation as we may have switched the execution mode */
5055 ctx->bstate = BS_STOP;
5056 rn = "TraceControl";
5057 // break;
5058 case 2:
5059 // gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5060 /* Stop translation as we may have switched the execution mode */
5061 ctx->bstate = BS_STOP;
5062 rn = "TraceControl2";
5063 // break;
5064 case 3:
5065 // gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5066 /* Stop translation as we may have switched the execution mode */
5067 ctx->bstate = BS_STOP;
5068 rn = "UserTraceData";
5069 // break;
5070 case 4:
5071 // gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5072 /* Stop translation as we may have switched the execution mode */
5073 ctx->bstate = BS_STOP;
5074 rn = "TraceBPC";
5075 // break;
5076 default:
5077 goto die;
5078 }
5079 break;
5080 case 24:
5081 switch (sel) {
5082 case 0:
5083 /* EJTAG support */
5084 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
5085 rn = "DEPC";
5086 break;
5087 default:
5088 goto die;
5089 }
5090 break;
5091 case 25:
5092 switch (sel) {
5093 case 0:
5094 gen_helper_mtc0_performance0(arg);
5095 rn = "Performance0";
5096 break;
5097 case 1:
5098 // gen_helper_mtc0_performance1(arg);
5099 rn = "Performance1";
5100 // break;
5101 case 2:
5102 // gen_helper_mtc0_performance2(arg);
5103 rn = "Performance2";
5104 // break;
5105 case 3:
5106 // gen_helper_mtc0_performance3(arg);
5107 rn = "Performance3";
5108 // break;
5109 case 4:
5110 // gen_helper_mtc0_performance4(arg);
5111 rn = "Performance4";
5112 // break;
5113 case 5:
5114 // gen_helper_mtc0_performance5(arg);
5115 rn = "Performance5";
5116 // break;
5117 case 6:
5118 // gen_helper_mtc0_performance6(arg);
5119 rn = "Performance6";
5120 // break;
5121 case 7:
5122 // gen_helper_mtc0_performance7(arg);
5123 rn = "Performance7";
5124 // break;
5125 default:
5126 goto die;
5127 }
5128 break;
5129 case 26:
5130 /* ignored */
5131 rn = "ECC";
5132 break;
5133 case 27:
5134 switch (sel) {
5135 case 0 ... 3:
5136 /* ignored */
5137 rn = "CacheErr";
5138 break;
5139 default:
5140 goto die;
5141 }
5142 break;
5143 case 28:
5144 switch (sel) {
5145 case 0:
5146 case 2:
5147 case 4:
5148 case 6:
5149 gen_helper_mtc0_taglo(arg);
5150 rn = "TagLo";
5151 break;
5152 case 1:
5153 case 3:
5154 case 5:
5155 case 7:
5156 gen_helper_mtc0_datalo(arg);
5157 rn = "DataLo";
5158 break;
5159 default:
5160 goto die;
5161 }
5162 break;
5163 case 29:
5164 switch (sel) {
5165 case 0:
5166 case 2:
5167 case 4:
5168 case 6:
5169 gen_helper_mtc0_taghi(arg);
5170 rn = "TagHi";
5171 break;
5172 case 1:
5173 case 3:
5174 case 5:
5175 case 7:
5176 gen_helper_mtc0_datahi(arg);
5177 rn = "DataHi";
5178 break;
5179 default:
5180 rn = "invalid sel";
5181 goto die;
5182 }
5183 break;
5184 case 30:
5185 switch (sel) {
5186 case 0:
5187 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5188 rn = "ErrorEPC";
5189 break;
5190 default:
5191 goto die;
5192 }
5193 break;
5194 case 31:
5195 switch (sel) {
5196 case 0:
5197 /* EJTAG support */
5198 gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
5199 rn = "DESAVE";
5200 break;
5201 default:
5202 goto die;
5203 }
5204 /* Stop translation as we may have switched the execution mode */
5205 ctx->bstate = BS_STOP;
5206 break;
5207 default:
5208 goto die;
5209 }
5210 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5211 /* For simplicity assume that all writes can cause interrupts. */
5212 if (use_icount) {
5213 gen_io_end();
5214 ctx->bstate = BS_STOP;
5215 }
5216 return;
5217
5218 die:
5219 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5220 generate_exception(ctx, EXCP_RI);
5221 }
5222 #endif /* TARGET_MIPS64 */
5223
5224 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5225 int u, int sel, int h)
5226 {
5227 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5228 TCGv t0 = tcg_temp_local_new();
5229
5230 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5231 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5232 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5233 tcg_gen_movi_tl(t0, -1);
5234 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5235 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5236 tcg_gen_movi_tl(t0, -1);
5237 else if (u == 0) {
5238 switch (rt) {
5239 case 2:
5240 switch (sel) {
5241 case 1:
5242 gen_helper_mftc0_tcstatus(t0);
5243 break;
5244 case 2:
5245 gen_helper_mftc0_tcbind(t0);
5246 break;
5247 case 3:
5248 gen_helper_mftc0_tcrestart(t0);
5249 break;
5250 case 4:
5251 gen_helper_mftc0_tchalt(t0);
5252 break;
5253 case 5:
5254 gen_helper_mftc0_tccontext(t0);
5255 break;
5256 case 6:
5257 gen_helper_mftc0_tcschedule(t0);
5258 break;
5259 case 7:
5260 gen_helper_mftc0_tcschefback(t0);
5261 break;
5262 default:
5263 gen_mfc0(env, ctx, t0, rt, sel);
5264 break;
5265 }
5266 break;
5267 case 10:
5268 switch (sel) {
5269 case 0:
5270 gen_helper_mftc0_entryhi(t0);
5271 break;
5272 default:
5273 gen_mfc0(env, ctx, t0, rt, sel);
5274 break;
5275 }
5276 case 12:
5277 switch (sel) {
5278 case 0:
5279 gen_helper_mftc0_status(t0);
5280 break;
5281 default:
5282 gen_mfc0(env, ctx, t0, rt, sel);
5283 break;
5284 }
5285 case 23:
5286 switch (sel) {
5287 case 0:
5288 gen_helper_mftc0_debug(t0);
5289 break;
5290 default:
5291 gen_mfc0(env, ctx, t0, rt, sel);
5292 break;
5293 }
5294 break;
5295 default:
5296 gen_mfc0(env, ctx, t0, rt, sel);
5297 }
5298 } else switch (sel) {
5299 /* GPR registers. */
5300 case 0:
5301 gen_helper_1i(mftgpr, t0, rt);
5302 break;
5303 /* Auxiliary CPU registers */
5304 case 1:
5305 switch (rt) {
5306 case 0:
5307 gen_helper_1i(mftlo, t0, 0);
5308 break;
5309 case 1:
5310 gen_helper_1i(mfthi, t0, 0);
5311 break;
5312 case 2:
5313 gen_helper_1i(mftacx, t0, 0);
5314 break;
5315 case 4:
5316 gen_helper_1i(mftlo, t0, 1);
5317 break;
5318 case 5:
5319 gen_helper_1i(mfthi, t0, 1);
5320 break;
5321 case 6:
5322 gen_helper_1i(mftacx, t0, 1);
5323 break;
5324 case 8:
5325 gen_helper_1i(mftlo, t0, 2);
5326 break;
5327 case 9:
5328 gen_helper_1i(mfthi, t0, 2);
5329 break;
5330 case 10:
5331 gen_helper_1i(mftacx, t0, 2);
5332 break;
5333 case 12:
5334 gen_helper_1i(mftlo, t0, 3);
5335 break;
5336 case 13:
5337 gen_helper_1i(mfthi, t0, 3);
5338 break;
5339 case 14:
5340 gen_helper_1i(mftacx, t0, 3);
5341 break;
5342 case 16:
5343 gen_helper_mftdsp(t0);
5344 break;
5345 default:
5346 goto die;
5347 }
5348 break;
5349 /* Floating point (COP1). */
5350 case 2:
5351 /* XXX: For now we support only a single FPU context. */
5352 if (h == 0) {
5353 TCGv_i32 fp0 = tcg_temp_new_i32();
5354
5355 gen_load_fpr32(fp0, rt);
5356 tcg_gen_ext_i32_tl(t0, fp0);
5357 tcg_temp_free_i32(fp0);
5358 } else {
5359 TCGv_i32 fp0 = tcg_temp_new_i32();
5360
5361 gen_load_fpr32h(fp0, rt);
5362 tcg_gen_ext_i32_tl(t0, fp0);
5363 tcg_temp_free_i32(fp0);
5364 }
5365 break;
5366 case 3:
5367 /* XXX: For now we support only a single FPU context. */
5368 gen_helper_1i(cfc1, t0, rt);
5369 break;
5370 /* COP2: Not implemented. */
5371 case 4:
5372 case 5:
5373 /* fall through */
5374 default:
5375 goto die;
5376 }
5377 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5378 gen_store_gpr(t0, rd);
5379 tcg_temp_free(t0);
5380 return;
5381
5382 die:
5383 tcg_temp_free(t0);
5384 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5385 generate_exception(ctx, EXCP_RI);
5386 }
5387
5388 static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5389 int u, int sel, int h)
5390 {
5391 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5392 TCGv t0 = tcg_temp_local_new();
5393
5394 gen_load_gpr(t0, rt);
5395 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5396 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5397 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5398 /* NOP */ ;
5399 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5400 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5401 /* NOP */ ;
5402 else if (u == 0) {
5403 switch (rd) {
5404 case 2:
5405 switch (sel) {
5406 case 1:
5407 gen_helper_mttc0_tcstatus(t0);
5408 break;
5409 case 2:
5410 gen_helper_mttc0_tcbind(t0);
5411 break;
5412 case 3:
5413 gen_helper_mttc0_tcrestart(t0);
5414 break;
5415 case 4:
5416 gen_helper_mttc0_tchalt(t0);
5417 break;
5418 case 5:
5419 gen_helper_mttc0_tccontext(t0);
5420 break;
5421 case 6:
5422 gen_helper_mttc0_tcschedule(t0);
5423 break;
5424 case 7:
5425 gen_helper_mttc0_tcschefback(t0);
5426 break;
5427 default:
5428 gen_mtc0(env, ctx, t0, rd, sel);
5429 break;
5430 }
5431 break;
5432 case 10:
5433 switch (sel) {
5434 case 0:
5435 gen_helper_mttc0_entryhi(t0);
5436 break;
5437 default:
5438 gen_mtc0(env, ctx, t0, rd, sel);
5439 break;
5440 }
5441 case 12:
5442 switch (sel) {
5443 case 0:
5444 gen_helper_mttc0_status(t0);
5445 break;
5446 default:
5447 gen_mtc0(env, ctx, t0, rd, sel);
5448 break;
5449 }
5450 case 23:
5451 switch (sel) {
5452 case 0:
5453 gen_helper_mttc0_debug(t0);
5454 break;
5455 default:
5456 gen_mtc0(env, ctx, t0, rd, sel);
5457 break;
5458 }
5459 break;
5460 default:
5461 gen_mtc0(env, ctx, t0, rd, sel);
5462 }
5463 } else switch (sel) {
5464 /* GPR registers. */
5465 case 0:
5466 gen_helper_1i(mttgpr, t0, rd);
5467 break;
5468 /* Auxiliary CPU registers */
5469 case 1:
5470 switch (rd) {
5471 case 0:
5472 gen_helper_1i(mttlo, t0, 0);
5473 break;
5474 case 1:
5475 gen_helper_1i(mtthi, t0, 0);
5476 break;
5477 case 2:
5478 gen_helper_1i(mttacx, t0, 0);
5479 break;
5480 case 4:
5481 gen_helper_1i(mttlo, t0, 1);
5482 break;
5483 case 5:
5484 gen_helper_1i(mtthi, t0, 1);
5485 break;
5486 case 6:
5487 gen_helper_1i(mttacx, t0, 1);
5488 break;
5489 case 8:
5490 gen_helper_1i(mttlo, t0, 2);
5491 break;
5492 case 9:
5493 gen_helper_1i(mtthi, t0, 2);
5494 break;
5495 case 10:
5496 gen_helper_1i(mttacx, t0, 2);
5497 break;
5498 case 12:
5499 gen_helper_1i(mttlo, t0, 3);
5500 break;
5501 case 13:
5502 gen_helper_1i(mtthi, t0, 3);
5503 break;
5504 case 14:
5505 gen_helper_1i(mttacx, t0, 3);
5506 break;
5507 case 16:
5508 gen_helper_mttdsp(t0);
5509 break;
5510 default:
5511 goto die;
5512 }
5513 break;
5514 /* Floating point (COP1). */
5515 case 2:
5516 /* XXX: For now we support only a single FPU context. */
5517 if (h == 0) {
5518 TCGv_i32 fp0 = tcg_temp_new_i32();
5519
5520 tcg_gen_trunc_tl_i32(fp0, t0);
5521 gen_store_fpr32(fp0, rd);
5522 tcg_temp_free_i32(fp0);
5523 } else {
5524 TCGv_i32 fp0 = tcg_temp_new_i32();
5525
5526 tcg_gen_trunc_tl_i32(fp0, t0);
5527 gen_store_fpr32h(fp0, rd);
5528 tcg_temp_free_i32(fp0);
5529 }
5530 break;
5531 case 3:
5532 /* XXX: For now we support only a single FPU context. */
5533 gen_helper_1i(ctc1, t0, rd);
5534 break;
5535 /* COP2: Not implemented. */
5536 case 4:
5537 case 5:
5538 /* fall through */
5539 default:
5540 goto die;
5541 }
5542 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5543 tcg_temp_free(t0);
5544 return;
5545
5546 die:
5547 tcg_temp_free(t0);
5548 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5549 generate_exception(ctx, EXCP_RI);
5550 }
5551
5552 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5553 {
5554 const char *opn = "ldst";
5555
5556 switch (opc) {
5557 case OPC_MFC0:
5558 if (rt == 0) {
5559 /* Treat as NOP. */
5560 return;
5561 }
5562 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5563 opn = "mfc0";
5564 break;
5565 case OPC_MTC0:
5566 {
5567 TCGv t0 = tcg_temp_new();
5568
5569 gen_load_gpr(t0, rt);
5570 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5571 tcg_temp_free(t0);
5572 }
5573 opn = "mtc0";
5574 break;
5575 #if defined(TARGET_MIPS64)
5576 case OPC_DMFC0:
5577 check_insn(env, ctx, ISA_MIPS3);
5578 if (rt == 0) {
5579 /* Treat as NOP. */
5580 return;
5581 }
5582 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5583 opn = "dmfc0";
5584 break;
5585 case OPC_DMTC0:
5586 check_insn(env, ctx, ISA_MIPS3);
5587 {
5588 TCGv t0 = tcg_temp_new();
5589
5590 gen_load_gpr(t0, rt);
5591 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5592 tcg_temp_free(t0);
5593 }
5594 opn = "dmtc0";
5595 break;
5596 #endif
5597 case OPC_MFTR:
5598 check_insn(env, ctx, ASE_MT);
5599 if (rd == 0) {
5600 /* Treat as NOP. */
5601 return;
5602 }
5603 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5604 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5605 opn = "mftr";
5606 break;
5607 case OPC_MTTR:
5608 check_insn(env, ctx, ASE_MT);
5609 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5610 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5611 opn = "mttr";
5612 break;
5613 case OPC_TLBWI:
5614 opn = "tlbwi";
5615 if (!env->tlb->helper_tlbwi)
5616 goto die;
5617 gen_helper_tlbwi();
5618 break;
5619 case OPC_TLBWR:
5620 opn = "tlbwr";
5621 if (!env->tlb->helper_tlbwr)
5622 goto die;
5623 gen_helper_tlbwr();
5624 break;
5625 case OPC_TLBP:
5626 opn = "tlbp";
5627 if (!env->tlb->helper_tlbp)
5628 goto die;
5629 gen_helper_tlbp();
5630 break;
5631 case OPC_TLBR:
5632 opn = "tlbr";
5633 if (!env->tlb->helper_tlbr)
5634 goto die;
5635 gen_helper_tlbr();
5636 break;
5637 case OPC_ERET:
5638 opn = "eret";
5639 check_insn(env, ctx, ISA_MIPS2);
5640 gen_helper_eret();
5641 ctx->bstate = BS_EXCP;
5642 break;
5643 case OPC_DERET:
5644 opn = "deret";
5645 check_insn(env, ctx, ISA_MIPS32);
5646 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5647 MIPS_INVAL(opn);
5648 generate_exception(ctx, EXCP_RI);
5649 } else {
5650 gen_helper_deret();
5651 ctx->bstate = BS_EXCP;
5652 }
5653 break;
5654 case OPC_WAIT:
5655 opn = "wait";
5656 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5657 /* If we get an exception, we want to restart at next instruction */
5658 ctx->pc += 4;
5659 save_cpu_state(ctx, 1);
5660 ctx->pc -= 4;
5661 gen_helper_wait();
5662 ctx->bstate = BS_EXCP;
5663 break;
5664 default:
5665 die:
5666 MIPS_INVAL(opn);
5667 generate_exception(ctx, EXCP_RI);
5668 return;
5669 }
5670 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5671 }
5672 #endif /* !CONFIG_USER_ONLY */
5673
5674 /* CP1 Branches (before delay slot) */
5675 static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5676 int32_t cc, int32_t offset)
5677 {
5678 target_ulong btarget;
5679 const char *opn = "cp1 cond branch";
5680 TCGv_i32 t0 = tcg_temp_new_i32();
5681
5682 if (cc != 0)
5683 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5684
5685 btarget = ctx->pc + 4 + offset;
5686
5687 switch (op) {
5688 case OPC_BC1F:
5689 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5690 tcg_gen_not_i32(t0, t0);
5691 tcg_gen_andi_i32(t0, t0, 1);
5692 tcg_gen_extu_i32_tl(bcond, t0);
5693 opn = "bc1f";
5694 goto not_likely;
5695 case OPC_BC1FL:
5696 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5697 tcg_gen_not_i32(t0, t0);
5698 tcg_gen_andi_i32(t0, t0, 1);
5699 tcg_gen_extu_i32_tl(bcond, t0);
5700 opn = "bc1fl";
5701 goto likely;
5702 case OPC_BC1T:
5703 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5704 tcg_gen_andi_i32(t0, t0, 1);
5705 tcg_gen_extu_i32_tl(bcond, t0);
5706 opn = "bc1t";
5707 goto not_likely;
5708 case OPC_BC1TL:
5709 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5710 tcg_gen_andi_i32(t0, t0, 1);
5711 tcg_gen_extu_i32_tl(bcond, t0);
5712 opn = "bc1tl";
5713 likely:
5714 ctx->hflags |= MIPS_HFLAG_BL;
5715 break;
5716 case OPC_BC1FANY2:
5717 {
5718 TCGv_i32 t1 = tcg_temp_new_i32();
5719 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5720 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5721 tcg_gen_or_i32(t0, t0, t1);
5722 tcg_temp_free_i32(t1);
5723 tcg_gen_not_i32(t0, t0);
5724 tcg_gen_andi_i32(t0, t0, 1);
5725 tcg_gen_extu_i32_tl(bcond, t0);
5726 }
5727 opn = "bc1any2f";
5728 goto not_likely;
5729 case OPC_BC1TANY2:
5730 {
5731 TCGv_i32 t1 = tcg_temp_new_i32();
5732 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5733 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5734 tcg_gen_or_i32(t0, t0, t1);
5735 tcg_temp_free_i32(t1);
5736 tcg_gen_andi_i32(t0, t0, 1);
5737 tcg_gen_extu_i32_tl(bcond, t0);
5738 }
5739 opn = "bc1any2t";
5740 goto not_likely;
5741 case OPC_BC1FANY4:
5742 {
5743 TCGv_i32 t1 = tcg_temp_new_i32();
5744 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5745 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5746 tcg_gen_or_i32(t0, t0, t1);
5747 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5748 tcg_gen_or_i32(t0, t0, t1);
5749 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5750 tcg_gen_or_i32(t0, t0, t1);
5751 tcg_temp_free_i32(t1);
5752 tcg_gen_not_i32(t0, t0);
5753 tcg_gen_andi_i32(t0, t0, 1);
5754 tcg_gen_extu_i32_tl(bcond, t0);
5755 }
5756 opn = "bc1any4f";
5757 goto not_likely;
5758 case OPC_BC1TANY4:
5759 {
5760 TCGv_i32 t1 = tcg_temp_new_i32();
5761 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5762 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5763 tcg_gen_or_i32(t0, t0, t1);
5764 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5765 tcg_gen_or_i32(t0, t0, t1);
5766 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5767 tcg_gen_or_i32(t0, t0, t1);
5768 tcg_temp_free_i32(t1);
5769 tcg_gen_andi_i32(t0, t0, 1);
5770 tcg_gen_extu_i32_tl(bcond, t0);
5771 }
5772 opn = "bc1any4t";
5773 not_likely:
5774 ctx->hflags |= MIPS_HFLAG_BC;
5775 break;
5776 default:
5777 MIPS_INVAL(opn);
5778 generate_exception (ctx, EXCP_RI);
5779 goto out;
5780 }
5781 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5782 ctx->hflags, btarget);
5783 ctx->btarget = btarget;
5784
5785 out:
5786 tcg_temp_free_i32(t0);
5787 }
5788
5789 /* Coprocessor 1 (FPU) */
5790
5791 #define FOP(func, fmt) (((fmt) << 21) | (func))
5792
5793 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5794 {
5795 const char *opn = "cp1 move";
5796 TCGv t0 = tcg_temp_new();
5797
5798 switch (opc) {
5799 case OPC_MFC1:
5800 {
5801 TCGv_i32 fp0 = tcg_temp_new_i32();
5802
5803 gen_load_fpr32(fp0, fs);
5804 tcg_gen_ext_i32_tl(t0, fp0);
5805 tcg_temp_free_i32(fp0);
5806 }
5807 gen_store_gpr(t0, rt);
5808 opn = "mfc1";
5809 break;
5810 case OPC_MTC1:
5811 gen_load_gpr(t0, rt);
5812 {
5813 TCGv_i32 fp0 = tcg_temp_new_i32();
5814
5815 tcg_gen_trunc_tl_i32(fp0, t0);
5816 gen_store_fpr32(fp0, fs);
5817 tcg_temp_free_i32(fp0);
5818 }
5819 opn = "mtc1";
5820 break;
5821 case OPC_CFC1:
5822 gen_helper_1i(cfc1, t0, fs);
5823 gen_store_gpr(t0, rt);
5824 opn = "cfc1";
5825 break;
5826 case OPC_CTC1:
5827 gen_load_gpr(t0, rt);
5828 gen_helper_1i(ctc1, t0, fs);
5829 opn = "ctc1";
5830 break;
5831 #if defined(TARGET_MIPS64)
5832 case OPC_DMFC1:
5833 gen_load_fpr64(ctx, t0, fs);
5834 gen_store_gpr(t0, rt);
5835 opn = "dmfc1";
5836 break;
5837 case OPC_DMTC1:
5838 gen_load_gpr(t0, rt);
5839 gen_store_fpr64(ctx, t0, fs);
5840 opn = "dmtc1";
5841 break;
5842 #endif
5843 case OPC_MFHC1:
5844 {
5845 TCGv_i32 fp0 = tcg_temp_new_i32();
5846
5847 gen_load_fpr32h(fp0, fs);
5848 tcg_gen_ext_i32_tl(t0, fp0);
5849 tcg_temp_free_i32(fp0);
5850 }
5851 gen_store_gpr(t0, rt);
5852 opn = "mfhc1";
5853 break;
5854 case OPC_MTHC1:
5855 gen_load_gpr(t0, rt);
5856 {
5857 TCGv_i32 fp0 = tcg_temp_new_i32();
5858
5859 tcg_gen_trunc_tl_i32(fp0, t0);
5860 gen_store_fpr32h(fp0, fs);
5861 tcg_temp_free_i32(fp0);
5862 }
5863 opn = "mthc1";
5864 break;
5865 default:
5866 MIPS_INVAL(opn);
5867 generate_exception (ctx, EXCP_RI);
5868 goto out;
5869 }
5870 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5871
5872 out:
5873 tcg_temp_free(t0);
5874 }
5875
5876 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5877 {
5878 int l1;
5879 TCGCond cond;
5880 TCGv_i32 t0;
5881
5882 if (rd == 0) {
5883 /* Treat as NOP. */
5884 return;
5885 }
5886
5887 if (tf)
5888 cond = TCG_COND_EQ;
5889 else
5890 cond = TCG_COND_NE;
5891
5892 l1 = gen_new_label();
5893 t0 = tcg_temp_new_i32();
5894 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5895 tcg_gen_brcondi_i32(cond, t0, 0, l1);
5896 tcg_temp_free_i32(t0);
5897 if (rs == 0) {
5898 tcg_gen_movi_tl(cpu_gpr[rd], 0);
5899 } else {
5900 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5901 }
5902 gen_set_label(l1);
5903 }
5904
5905 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5906 {
5907 int cond;
5908 TCGv_i32 t0 = tcg_temp_new_i32();
5909 int l1 = gen_new_label();
5910
5911 if (tf)
5912 cond = TCG_COND_EQ;
5913 else
5914 cond = TCG_COND_NE;
5915
5916 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5917 tcg_gen_brcondi_i32(cond, t0, 0, l1);
5918 gen_load_fpr32(t0, fs);
5919 gen_store_fpr32(t0, fd);
5920 gen_set_label(l1);
5921 tcg_temp_free_i32(t0);
5922 }
5923
5924 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5925 {
5926 int cond;
5927 TCGv_i32 t0 = tcg_temp_new_i32();
5928 TCGv_i64 fp0;
5929 int l1 = gen_new_label();
5930
5931 if (tf)
5932 cond = TCG_COND_EQ;
5933 else
5934 cond = TCG_COND_NE;
5935
5936 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5937 tcg_gen_brcondi_i32(cond, t0, 0, l1);
5938 tcg_temp_free_i32(t0);
5939 fp0 = tcg_temp_new_i64();
5940 gen_load_fpr64(ctx, fp0, fs);
5941 gen_store_fpr64(ctx, fp0, fd);
5942 tcg_temp_free_i64(fp0);
5943 gen_set_label(l1);
5944 }
5945
5946 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5947 {
5948 int cond;
5949 TCGv_i32 t0 = tcg_temp_new_i32();
5950 int l1 = gen_new_label();
5951 int l2 = gen_new_label();
5952
5953 if (tf)
5954 cond = TCG_COND_EQ;
5955 else
5956 cond = TCG_COND_NE;
5957
5958 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5959 tcg_gen_brcondi_i32(cond, t0, 0, l1);
5960 gen_load_fpr32(t0, fs);
5961 gen_store_fpr32(t0, fd);
5962 gen_set_label(l1);
5963
5964 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
5965 tcg_gen_brcondi_i32(cond, t0, 0, l2);
5966 gen_load_fpr32h(t0, fs);
5967 gen_store_fpr32h(t0, fd);
5968 tcg_temp_free_i32(t0);
5969 gen_set_label(l2);
5970 }
5971
5972
5973 static void gen_farith (DisasContext *ctx, uint32_t op1,
5974 int ft, int fs, int fd, int cc)
5975 {
5976 const char *opn = "farith";
5977 const char *condnames[] = {
5978 "c.f",
5979 "c.un",
5980 "c.eq",
5981 "c.ueq",
5982 "c.olt",
5983 "c.ult",
5984 "c.ole",
5985 "c.ule",
5986 "c.sf",
5987 "c.ngle",
5988 "c.seq",
5989 "c.ngl",
5990 "c.lt",
5991 "c.nge",
5992 "c.le",
5993 "c.ngt",
5994 };
5995 const char *condnames_abs[] = {
5996 "cabs.f",
5997 "cabs.un",
5998 "cabs.eq",
5999 "cabs.ueq",
6000 "cabs.olt",
6001 "cabs.ult",
6002 "cabs.ole",
6003 "cabs.ule",
6004 "cabs.sf",
6005 "cabs.ngle",
6006 "cabs.seq",
6007 "cabs.ngl",
6008 "cabs.lt",
6009 "cabs.nge",
6010 "cabs.le",
6011 "cabs.ngt",
6012 };
6013 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6014 uint32_t func = ctx->opcode & 0x3f;
6015
6016 switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6017 case FOP(0, 16):
6018 {
6019 TCGv_i32 fp0 = tcg_temp_new_i32();
6020 TCGv_i32 fp1 = tcg_temp_new_i32();
6021
6022 gen_load_fpr32(fp0, fs);
6023 gen_load_fpr32(fp1, ft);
6024 gen_helper_float_add_s(fp0, fp0, fp1);
6025 tcg_temp_free_i32(fp1);
6026 gen_store_fpr32(fp0, fd);
6027 tcg_temp_free_i32(fp0);
6028 }
6029 opn = "add.s";
6030 optype = BINOP;
6031 break;
6032 case FOP(1, 16):
6033 {
6034 TCGv_i32 fp0 = tcg_temp_new_i32();
6035 TCGv_i32 fp1 = tcg_temp_new_i32();
6036
6037 gen_load_fpr32(fp0, fs);
6038 gen_load_fpr32(fp1, ft);
6039 gen_helper_float_sub_s(fp0, fp0, fp1);
6040 tcg_temp_free_i32(fp1);
6041 gen_store_fpr32(fp0, fd);
6042 tcg_temp_free_i32(fp0);
6043 }
6044 opn = "sub.s";
6045 optype = BINOP;
6046 break;
6047 case FOP(2, 16):
6048 {
6049 TCGv_i32 fp0 = tcg_temp_new_i32();
6050 TCGv_i32 fp1 = tcg_temp_new_i32();
6051
6052 gen_load_fpr32(fp0, fs);
6053 gen_load_fpr32(fp1, ft);
6054 gen_helper_float_mul_s(fp0, fp0, fp1);
6055 tcg_temp_free_i32(fp1);
6056 gen_store_fpr32(fp0, fd);
6057 tcg_temp_free_i32(fp0);
6058 }
6059 opn = "mul.s";
6060 optype = BINOP;
6061 break;
6062 case FOP(3, 16):
6063 {
6064 TCGv_i32 fp0 = tcg_temp_new_i32();
6065 TCGv_i32 fp1 = tcg_temp_new_i32();
6066
6067 gen_load_fpr32(fp0, fs);
6068 gen_load_fpr32(fp1, ft);
6069 gen_helper_float_div_s(fp0, fp0, fp1);
6070 tcg_temp_free_i32(fp1);
6071 gen_store_fpr32(fp0, fd);
6072 tcg_temp_free_i32(fp0);
6073 }
6074 opn = "div.s";
6075 optype = BINOP;
6076 break;
6077 case FOP(4, 16):
6078 {
6079 TCGv_i32 fp0 = tcg_temp_new_i32();
6080
6081 gen_load_fpr32(fp0, fs);
6082 gen_helper_float_sqrt_s(fp0, fp0);
6083 gen_store_fpr32(fp0, fd);
6084 tcg_temp_free_i32(fp0);
6085 }
6086 opn = "sqrt.s";
6087 break;
6088 case FOP(5, 16):
6089 {
6090 TCGv_i32 fp0 = tcg_temp_new_i32();
6091
6092 gen_load_fpr32(fp0, fs);
6093 gen_helper_float_abs_s(fp0, fp0);
6094 gen_store_fpr32(fp0, fd);
6095 tcg_temp_free_i32(fp0);
6096 }
6097 opn = "abs.s";
6098 break;
6099 case FOP(6, 16):
6100 {
6101 TCGv_i32 fp0 = tcg_temp_new_i32();
6102
6103 gen_load_fpr32(fp0, fs);
6104 gen_store_fpr32(fp0, fd);
6105 tcg_temp_free_i32(fp0);
6106 }
6107 opn = "mov.s";
6108 break;
6109 case FOP(7, 16):
6110 {
6111 TCGv_i32 fp0 = tcg_temp_new_i32();
6112
6113 gen_load_fpr32(fp0, fs);
6114 gen_helper_float_chs_s(fp0, fp0);
6115 gen_store_fpr32(fp0, fd);
6116 tcg_temp_free_i32(fp0);
6117 }
6118 opn = "neg.s";
6119 break;
6120 case FOP(8, 16):
6121 check_cp1_64bitmode(ctx);
6122 {
6123 TCGv_i32 fp32 = tcg_temp_new_i32();
6124 TCGv_i64 fp64 = tcg_temp_new_i64();
6125
6126 gen_load_fpr32(fp32, fs);
6127 gen_helper_float_roundl_s(fp64, fp32);
6128 tcg_temp_free_i32(fp32);
6129 gen_store_fpr64(ctx, fp64, fd);
6130 tcg_temp_free_i64(fp64);
6131 }
6132 opn = "round.l.s";
6133 break;
6134 case FOP(9, 16):
6135 check_cp1_64bitmode(ctx);
6136 {
6137 TCGv_i32 fp32 = tcg_temp_new_i32();
6138 TCGv_i64 fp64 = tcg_temp_new_i64();
6139
6140 gen_load_fpr32(fp32, fs);
6141 gen_helper_float_truncl_s(fp64, fp32);
6142 tcg_temp_free_i32(fp32);
6143 gen_store_fpr64(ctx, fp64, fd);
6144 tcg_temp_free_i64(fp64);
6145 }
6146 opn = "trunc.l.s";
6147 break;
6148 case FOP(10, 16):
6149 check_cp1_64bitmode(ctx);
6150 {
6151 TCGv_i32 fp32 = tcg_temp_new_i32();
6152 TCGv_i64 fp64 = tcg_temp_new_i64();
6153
6154 gen_load_fpr32(fp32, fs);
6155 gen_helper_float_ceill_s(fp64, fp32);
6156 tcg_temp_free_i32(fp32);
6157 gen_store_fpr64(ctx, fp64, fd);
6158 tcg_temp_free_i64(fp64);
6159 }
6160 opn = "ceil.l.s";
6161 break;
6162 case FOP(11, 16):
6163 check_cp1_64bitmode(ctx);
6164 {
6165 TCGv_i32 fp32 = tcg_temp_new_i32();
6166 TCGv_i64 fp64 = tcg_temp_new_i64();
6167
6168 gen_load_fpr32(fp32, fs);
6169 gen_helper_float_floorl_s(fp64, fp32);
6170 tcg_temp_free_i32(fp32);
6171 gen_store_fpr64(ctx, fp64, fd);
6172 tcg_temp_free_i64(fp64);
6173 }
6174 opn = "floor.l.s";
6175 break;
6176 case FOP(12, 16):
6177 {
6178 TCGv_i32 fp0 = tcg_temp_new_i32();
6179
6180 gen_load_fpr32(fp0, fs);
6181 gen_helper_float_roundw_s(fp0, fp0);
6182 gen_store_fpr32(fp0, fd);
6183 tcg_temp_free_i32(fp0);
6184 }
6185 opn = "round.w.s";
6186 break;
6187 case FOP(13, 16):
6188 {
6189 TCGv_i32 fp0 = tcg_temp_new_i32();
6190
6191 gen_load_fpr32(fp0, fs);
6192 gen_helper_float_truncw_s(fp0, fp0);
6193 gen_store_fpr32(fp0, fd);
6194 tcg_temp_free_i32(fp0);
6195 }
6196 opn = "trunc.w.s";
6197 break;
6198 case FOP(14, 16):
6199 {
6200 TCGv_i32 fp0 = tcg_temp_new_i32();
6201
6202 gen_load_fpr32(fp0, fs);
6203 gen_helper_float_ceilw_s(fp0, fp0);
6204 gen_store_fpr32(fp0, fd);
6205 tcg_temp_free_i32(fp0);
6206 }
6207 opn = "ceil.w.s";
6208 break;
6209 case FOP(15, 16):
6210 {
6211 TCGv_i32 fp0 = tcg_temp_new_i32();
6212
6213 gen_load_fpr32(fp0, fs);
6214 gen_helper_float_floorw_s(fp0, fp0);
6215 gen_store_fpr32(fp0, fd);
6216 tcg_temp_free_i32(fp0);
6217 }
6218 opn = "floor.w.s";
6219 break;
6220 case FOP(17, 16):
6221 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6222 opn = "movcf.s";
6223 break;
6224 case FOP(18, 16):
6225 {
6226 int l1 = gen_new_label();
6227 TCGv_i32 fp0;
6228
6229 if (ft != 0) {
6230 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6231 }
6232 fp0 = tcg_temp_new_i32();
6233 gen_load_fpr32(fp0, fs);
6234 gen_store_fpr32(fp0, fd);
6235 tcg_temp_free_i32(fp0);
6236 gen_set_label(l1);
6237 }
6238 opn = "movz.s";
6239 break;
6240 case FOP(19, 16):
6241 {
6242 int l1 = gen_new_label();
6243 TCGv_i32 fp0;
6244
6245 if (ft != 0) {
6246 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6247 fp0 = tcg_temp_new_i32();
6248 gen_load_fpr32(fp0, fs);
6249 gen_store_fpr32(fp0, fd);
6250 tcg_temp_free_i32(fp0);
6251 gen_set_label(l1);
6252 }
6253 }
6254 opn = "movn.s";
6255 break;
6256 case FOP(21, 16):
6257 check_cop1x(ctx);
6258 {
6259 TCGv_i32 fp0 = tcg_temp_new_i32();
6260
6261 gen_load_fpr32(fp0, fs);
6262 gen_helper_float_recip_s(fp0, fp0);
6263 gen_store_fpr32(fp0, fd);
6264 tcg_temp_free_i32(fp0);
6265 }
6266 opn = "recip.s";
6267 break;
6268 case FOP(22, 16):
6269 check_cop1x(ctx);
6270 {
6271 TCGv_i32 fp0 = tcg_temp_new_i32();
6272
6273 gen_load_fpr32(fp0, fs);
6274 gen_helper_float_rsqrt_s(fp0, fp0);
6275 gen_store_fpr32(fp0, fd);
6276 tcg_temp_free_i32(fp0);
6277 }
6278 opn = "rsqrt.s";
6279 break;
6280 case FOP(28, 16):
6281 check_cp1_64bitmode(ctx);
6282 {
6283 TCGv_i32 fp0 = tcg_temp_new_i32();
6284 TCGv_i32 fp1 = tcg_temp_new_i32();
6285
6286 gen_load_fpr32(fp0, fs);
6287 gen_load_fpr32(fp1, fd);
6288 gen_helper_float_recip2_s(fp0, fp0, fp1);
6289 tcg_temp_free_i32(fp1);
6290 gen_store_fpr32(fp0, fd);
6291 tcg_temp_free_i32(fp0);
6292 }
6293 opn = "recip2.s";
6294 break;
6295 case FOP(29, 16):
6296 check_cp1_64bitmode(ctx);
6297 {
6298 TCGv_i32 fp0 = tcg_temp_new_i32();
6299
6300 gen_load_fpr32(fp0, fs);
6301 gen_helper_float_recip1_s(fp0, fp0);
6302 gen_store_fpr32(fp0, fd);
6303 tcg_temp_free_i32(fp0);
6304 }
6305 opn = "recip1.s";
6306 break;
6307 case FOP(30, 16):
6308 check_cp1_64bitmode(ctx);
6309 {
6310 TCGv_i32 fp0 = tcg_temp_new_i32();
6311
6312 gen_load_fpr32(fp0, fs);
6313 gen_helper_float_rsqrt1_s(fp0, fp0);
6314 gen_store_fpr32(fp0, fd);
6315 tcg_temp_free_i32(fp0);
6316 }
6317 opn = "rsqrt1.s";
6318 break;
6319 case FOP(31, 16):
6320 check_cp1_64bitmode(ctx);
6321 {
6322 TCGv_i32 fp0 = tcg_temp_new_i32();
6323 TCGv_i32 fp1 = tcg_temp_new_i32();
6324
6325 gen_load_fpr32(fp0, fs);
6326 gen_load_fpr32(fp1, ft);
6327 gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6328 tcg_temp_free_i32(fp1);
6329 gen_store_fpr32(fp0, fd);
6330 tcg_temp_free_i32(fp0);
6331 }
6332 opn = "rsqrt2.s";
6333 break;
6334 case FOP(33, 16):
6335 check_cp1_registers(ctx, fd);
6336 {
6337 TCGv_i32 fp32 = tcg_temp_new_i32();
6338 TCGv_i64 fp64 = tcg_temp_new_i64();
6339
6340 gen_load_fpr32(fp32, fs);
6341 gen_helper_float_cvtd_s(fp64, fp32);
6342 tcg_temp_free_i32(fp32);
6343 gen_store_fpr64(ctx, fp64, fd);
6344 tcg_temp_free_i64(fp64);
6345 }
6346 opn = "cvt.d.s";
6347 break;
6348 case FOP(36, 16):
6349 {
6350 TCGv_i32 fp0 = tcg_temp_new_i32();
6351
6352 gen_load_fpr32(fp0, fs);
6353 gen_helper_float_cvtw_s(fp0, fp0);
6354 gen_store_fpr32(fp0, fd);
6355 tcg_temp_free_i32(fp0);
6356 }
6357 opn = "cvt.w.s";
6358 break;
6359 case FOP(37, 16):
6360 check_cp1_64bitmode(ctx);
6361 {
6362 TCGv_i32 fp32 = tcg_temp_new_i32();
6363 TCGv_i64 fp64 = tcg_temp_new_i64();
6364
6365 gen_load_fpr32(fp32, fs);
6366 gen_helper_float_cvtl_s(fp64, fp32);
6367 tcg_temp_free_i32(fp32);
6368 gen_store_fpr64(ctx, fp64, fd);
6369 tcg_temp_free_i64(fp64);
6370 }
6371 opn = "cvt.l.s";
6372 break;
6373 case FOP(38, 16):
6374 check_cp1_64bitmode(ctx);
6375 {
6376 TCGv_i64 fp64 = tcg_temp_new_i64();
6377 TCGv_i32 fp32_0 = tcg_temp_new_i32();
6378 TCGv_i32 fp32_1 = tcg_temp_new_i32();
6379
6380 gen_load_fpr32(fp32_0, fs);
6381 gen_load_fpr32(fp32_1, ft);
6382 tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6383 tcg_temp_free_i32(fp32_1);
6384 tcg_temp_free_i32(fp32_0);
6385 gen_store_fpr64(ctx, fp64, fd);
6386 tcg_temp_free_i64(fp64);
6387 }
6388 opn = "cvt.ps.s";
6389 break;
6390 case FOP(48, 16):
6391 case FOP(49, 16):
6392 case FOP(50, 16):
6393 case FOP(51, 16):
6394 case FOP(52, 16):
6395 case FOP(53, 16):
6396 case FOP(54, 16):
6397 case FOP(55, 16):
6398 case FOP(56, 16):
6399 case FOP(57, 16):
6400 case FOP(58, 16):
6401 case FOP(59, 16):
6402 case FOP(60, 16):
6403 case FOP(61, 16):
6404 case FOP(62, 16):
6405 case FOP(63, 16):
6406 {
6407 TCGv_i32 fp0 = tcg_temp_new_i32();
6408 TCGv_i32 fp1 = tcg_temp_new_i32();
6409
6410 gen_load_fpr32(fp0, fs);
6411 gen_load_fpr32(fp1, ft);
6412 if (ctx->opcode & (1 << 6)) {
6413 check_cop1x(ctx);
6414 gen_cmpabs_s(func-48, fp0, fp1, cc);
6415 opn = condnames_abs[func-48];
6416 } else {
6417 gen_cmp_s(func-48, fp0, fp1, cc);
6418 opn = condnames[func-48];
6419 }
6420 tcg_temp_free_i32(fp0);
6421 tcg_temp_free_i32(fp1);
6422 }
6423 break;
6424 case FOP(0, 17):
6425 check_cp1_registers(ctx, fs | ft | fd);
6426 {
6427 TCGv_i64 fp0 = tcg_temp_new_i64();
6428 TCGv_i64 fp1 = tcg_temp_new_i64();
6429
6430 gen_load_fpr64(ctx, fp0, fs);
6431 gen_load_fpr64(ctx, fp1, ft);
6432 gen_helper_float_add_d(fp0, fp0, fp1);
6433 tcg_temp_free_i64(fp1);
6434 gen_store_fpr64(ctx, fp0, fd);
6435 tcg_temp_free_i64(fp0);
6436 }
6437 opn = "add.d";
6438 optype = BINOP;
6439 break;
6440 case FOP(1, 17):
6441 check_cp1_registers(ctx, fs | ft | fd);
6442 {
6443 TCGv_i64 fp0 = tcg_temp_new_i64();
6444 TCGv_i64 fp1 = tcg_temp_new_i64();
6445
6446 gen_load_fpr64(ctx, fp0, fs);
6447 gen_load_fpr64(ctx, fp1, ft);
6448 gen_helper_float_sub_d(fp0, fp0, fp1);
6449 tcg_temp_free_i64(fp1);
6450 gen_store_fpr64(ctx, fp0, fd);
6451 tcg_temp_free_i64(fp0);
6452 }
6453 opn = "sub.d";
6454 optype = BINOP;
6455 break;
6456 case FOP(2, 17):
6457 check_cp1_registers(ctx, fs | ft | fd);
6458 {
6459 TCGv_i64 fp0 = tcg_temp_new_i64();
6460 TCGv_i64 fp1 = tcg_temp_new_i64();
6461
6462 gen_load_fpr64(ctx, fp0, fs);
6463 gen_load_fpr64(ctx, fp1, ft);
6464 gen_helper_float_mul_d(fp0, fp0, fp1);
6465 tcg_temp_free_i64(fp1);
6466 gen_store_fpr64(ctx, fp0, fd);
6467 tcg_temp_free_i64(fp0);
6468 }
6469 opn = "mul.d";
6470 optype = BINOP;
6471 break;
6472 case FOP(3, 17):
6473 check_cp1_registers(ctx, fs | ft | fd);
6474 {
6475 TCGv_i64 fp0 = tcg_temp_new_i64();
6476 TCGv_i64 fp1 = tcg_temp_new_i64();
6477
6478 gen_load_fpr64(ctx, fp0, fs);
6479 gen_load_fpr64(ctx, fp1, ft);
6480 gen_helper_float_div_d(fp0, fp0, fp1);
6481 tcg_temp_free_i64(fp1);
6482 gen_store_fpr64(ctx, fp0, fd);
6483 tcg_temp_free_i64(fp0);
6484 }
6485 opn = "div.d";
6486 optype = BINOP;
6487 break;
6488 case FOP(4, 17):
6489 check_cp1_registers(ctx, fs | fd);
6490 {
6491 TCGv_i64 fp0 = tcg_temp_new_i64();
6492
6493 gen_load_fpr64(ctx, fp0, fs);
6494 gen_helper_float_sqrt_d(fp0, fp0);
6495 gen_store_fpr64(ctx, fp0, fd);
6496 tcg_temp_free_i64(fp0);
6497 }
6498 opn = "sqrt.d";
6499 break;
6500 case FOP(5, 17):
6501 check_cp1_registers(ctx, fs | fd);
6502 {
6503 TCGv_i64 fp0 = tcg_temp_new_i64();
6504
6505 gen_load_fpr64(ctx, fp0, fs);
6506 gen_helper_float_abs_d(fp0, fp0);
6507 gen_store_fpr64(ctx, fp0, fd);
6508 tcg_temp_free_i64(fp0);
6509 }
6510 opn = "abs.d";
6511 break;
6512 case FOP(6, 17):
6513 check_cp1_registers(ctx, fs | fd);
6514 {
6515 TCGv_i64 fp0 = tcg_temp_new_i64();
6516
6517 gen_load_fpr64(ctx, fp0, fs);
6518 gen_store_fpr64(ctx, fp0, fd);
6519 tcg_temp_free_i64(fp0);
6520 }
6521 opn = "mov.d";
6522 break;
6523 case FOP(7, 17):
6524 check_cp1_registers(ctx, fs | fd);
6525 {
6526 TCGv_i64 fp0 = tcg_temp_new_i64();
6527
6528 gen_load_fpr64(ctx, fp0, fs);
6529 gen_helper_float_chs_d(fp0, fp0);
6530 gen_store_fpr64(ctx, fp0, fd);
6531 tcg_temp_free_i64(fp0);
6532 }
6533 opn = "neg.d";
6534 break;
6535 case FOP(8, 17):
6536 check_cp1_64bitmode(ctx);
6537 {
6538 TCGv_i64 fp0 = tcg_temp_new_i64();
6539
6540 gen_load_fpr64(ctx, fp0, fs);
6541 gen_helper_float_roundl_d(fp0, fp0);
6542 gen_store_fpr64(ctx, fp0, fd);
6543 tcg_temp_free_i64(fp0);
6544 }
6545 opn = "round.l.d";
6546 break;
6547 case FOP(9, 17):
6548 check_cp1_64bitmode(ctx);
6549 {
6550 TCGv_i64 fp0 = tcg_temp_new_i64();
6551
6552 gen_load_fpr64(ctx, fp0, fs);
6553 gen_helper_float_truncl_d(fp0, fp0);
6554 gen_store_fpr64(ctx, fp0, fd);
6555 tcg_temp_free_i64(fp0);
6556 }
6557 opn = "trunc.l.d";
6558 break;
6559 case FOP(10, 17):
6560 check_cp1_64bitmode(ctx);
6561 {
6562 TCGv_i64 fp0 = tcg_temp_new_i64();
6563
6564 gen_load_fpr64(ctx, fp0, fs);
6565 gen_helper_float_ceill_d(fp0, fp0);
6566 gen_store_fpr64(ctx, fp0, fd);
6567 tcg_temp_free_i64(fp0);
6568 }
6569 opn = "ceil.l.d";
6570 break;
6571 case FOP(11, 17):
6572 check_cp1_64bitmode(ctx);
6573 {
6574 TCGv_i64 fp0 = tcg_temp_new_i64();
6575
6576 gen_load_fpr64(ctx, fp0, fs);
6577 gen_helper_float_floorl_d(fp0, fp0);
6578 gen_store_fpr64(ctx, fp0, fd);
6579 tcg_temp_free_i64(fp0);
6580 }
6581 opn = "floor.l.d";
6582 break;
6583 case FOP(12, 17):
6584 check_cp1_registers(ctx, fs);
6585 {
6586 TCGv_i32 fp32 = tcg_temp_new_i32();
6587 TCGv_i64 fp64 = tcg_temp_new_i64();
6588
6589 gen_load_fpr64(ctx, fp64, fs);
6590 gen_helper_float_roundw_d(fp32, fp64);
6591 tcg_temp_free_i64(fp64);
6592 gen_store_fpr32(fp32, fd);
6593 tcg_temp_free_i32(fp32);
6594 }
6595 opn = "round.w.d";
6596 break;
6597 case FOP(13, 17):
6598 check_cp1_registers(ctx, fs);
6599 {
6600 TCGv_i32 fp32 = tcg_temp_new_i32();
6601 TCGv_i64 fp64 = tcg_temp_new_i64();
6602
6603 gen_load_fpr64(ctx, fp64, fs);
6604 gen_helper_float_truncw_d(fp32, fp64);
6605 tcg_temp_free_i64(fp64);
6606 gen_store_fpr32(fp32, fd);
6607 tcg_temp_free_i32(fp32);
6608 }
6609 opn = "trunc.w.d";
6610 break;
6611 case FOP(14, 17):
6612 check_cp1_registers(ctx, fs);
6613 {
6614 TCGv_i32 fp32 = tcg_temp_new_i32();
6615 TCGv_i64 fp64 = tcg_temp_new_i64();
6616
6617 gen_load_fpr64(ctx, fp64, fs);
6618 gen_helper_float_ceilw_d(fp32, fp64);
6619 tcg_temp_free_i64(fp64);
6620 gen_store_fpr32(fp32, fd);
6621 tcg_temp_free_i32(fp32);
6622 }
6623 opn = "ceil.w.d";
6624 break;
6625 case FOP(15, 17):
6626 check_cp1_registers(ctx, fs);
6627 {
6628 TCGv_i32 fp32 = tcg_temp_new_i32();
6629 TCGv_i64 fp64 = tcg_temp_new_i64();
6630
6631 gen_load_fpr64(ctx, fp64, fs);
6632 gen_helper_float_floorw_d(fp32, fp64);
6633 tcg_temp_free_i64(fp64);
6634 gen_store_fpr32(fp32, fd);
6635 tcg_temp_free_i32(fp32);
6636 }
6637 opn = "floor.w.d";
6638 break;
6639 case FOP(17, 17):
6640 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6641 opn = "movcf.d";
6642 break;
6643 case FOP(18, 17):
6644 {
6645 int l1 = gen_new_label();
6646 TCGv_i64 fp0;
6647
6648 if (ft != 0) {
6649 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6650 }
6651 fp0 = tcg_temp_new_i64();
6652 gen_load_fpr64(ctx, fp0, fs);
6653 gen_store_fpr64(ctx, fp0, fd);
6654 tcg_temp_free_i64(fp0);
6655 gen_set_label(l1);
6656 }
6657 opn = "movz.d";
6658 break;
6659 case FOP(19, 17):
6660 {
6661 int l1 = gen_new_label();
6662 TCGv_i64 fp0;
6663
6664 if (ft != 0) {
6665 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6666 fp0 = tcg_temp_new_i64();
6667 gen_load_fpr64(ctx, fp0, fs);
6668 gen_store_fpr64(ctx, fp0, fd);
6669 tcg_temp_free_i64(fp0);
6670 gen_set_label(l1);
6671 }
6672 }
6673 opn = "movn.d";
6674 break;
6675 case FOP(21, 17):
6676 check_cp1_64bitmode(ctx);
6677 {
6678 TCGv_i64 fp0 = tcg_temp_new_i64();
6679
6680 gen_load_fpr64(ctx, fp0, fs);
6681 gen_helper_float_recip_d(fp0, fp0);
6682 gen_store_fpr64(ctx, fp0, fd);
6683 tcg_temp_free_i64(fp0);
6684 }
6685 opn = "recip.d";
6686 break;
6687 case FOP(22, 17):
6688 check_cp1_64bitmode(ctx);
6689 {
6690 TCGv_i64 fp0 = tcg_temp_new_i64();
6691
6692 gen_load_fpr64(ctx, fp0, fs);
6693 gen_helper_float_rsqrt_d(fp0, fp0);
6694 gen_store_fpr64(ctx, fp0, fd);
6695 tcg_temp_free_i64(fp0);
6696 }
6697 opn = "rsqrt.d";
6698 break;
6699 case FOP(28, 17):
6700 check_cp1_64bitmode(ctx);
6701 {
6702 TCGv_i64 fp0 = tcg_temp_new_i64();
6703 TCGv_i64 fp1 = tcg_temp_new_i64();
6704
6705 gen_load_fpr64(ctx, fp0, fs);
6706 gen_load_fpr64(ctx, fp1, ft);
6707 gen_helper_float_recip2_d(fp0, fp0, fp1);
6708 tcg_temp_free_i64(fp1);
6709 gen_store_fpr64(ctx, fp0, fd);
6710 tcg_temp_free_i64(fp0);
6711 }
6712 opn = "recip2.d";
6713 break;
6714 case FOP(29, 17):
6715 check_cp1_64bitmode(ctx);
6716 {
6717 TCGv_i64 fp0 = tcg_temp_new_i64();
6718
6719 gen_load_fpr64(ctx, fp0, fs);
6720 gen_helper_float_recip1_d(fp0, fp0);
6721 gen_store_fpr64(ctx, fp0, fd);
6722 tcg_temp_free_i64(fp0);
6723 }
6724 opn = "recip1.d";
6725 break;
6726 case FOP(30, 17):
6727 check_cp1_64bitmode(ctx);
6728 {
6729 TCGv_i64 fp0 = tcg_temp_new_i64();
6730
6731 gen_load_fpr64(ctx, fp0, fs);
6732 gen_helper_float_rsqrt1_d(fp0, fp0);
6733 gen_store_fpr64(ctx, fp0, fd);
6734 tcg_temp_free_i64(fp0);
6735 }
6736 opn = "rsqrt1.d";
6737 break;
6738 case FOP(31, 17):
6739 check_cp1_64bitmode(ctx);
6740 {
6741 TCGv_i64 fp0 = tcg_temp_new_i64();
6742 TCGv_i64 fp1 = tcg_temp_new_i64();
6743
6744 gen_load_fpr64(ctx, fp0, fs);
6745 gen_load_fpr64(ctx, fp1, ft);
6746 gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6747 tcg_temp_free_i64(fp1);
6748 gen_store_fpr64(ctx, fp0, fd);
6749 tcg_temp_free_i64(fp0);
6750 }
6751 opn = "rsqrt2.d";
6752 break;
6753 case FOP(48, 17):
6754 case FOP(49, 17):
6755 case FOP(50, 17):
6756 case FOP(51, 17):
6757 case FOP(52, 17):
6758 case FOP(53, 17):
6759 case FOP(54, 17):
6760 case FOP(55, 17):
6761 case FOP(56, 17):
6762 case FOP(57, 17):
6763 case FOP(58, 17):
6764 case FOP(59, 17):
6765 case FOP(60, 17):
6766 case FOP(61, 17):
6767 case FOP(62, 17):
6768 case FOP(63, 17):
6769 {
6770 TCGv_i64 fp0 = tcg_temp_new_i64();
6771 TCGv_i64 fp1 = tcg_temp_new_i64();
6772
6773 gen_load_fpr64(ctx, fp0, fs);
6774 gen_load_fpr64(ctx, fp1, ft);
6775 if (ctx->opcode & (1 << 6)) {
6776 check_cop1x(ctx);
6777 check_cp1_registers(ctx, fs | ft);
6778 gen_cmpabs_d(func-48, fp0, fp1, cc);
6779 opn = condnames_abs[func-48];
6780 } else {
6781 check_cp1_registers(ctx, fs | ft);
6782 gen_cmp_d(func-48, fp0, fp1, cc);
6783 opn = condnames[func-48];
6784 }
6785 tcg_temp_free_i64(fp0);
6786 tcg_temp_free_i64(fp1);
6787 }
6788 break;
6789 case FOP(32, 17):
6790 check_cp1_registers(ctx, fs);
6791 {
6792 TCGv_i32 fp32 = tcg_temp_new_i32();
6793 TCGv_i64 fp64 = tcg_temp_new_i64();
6794
6795 gen_load_fpr64(ctx, fp64, fs);
6796 gen_helper_float_cvts_d(fp32, fp64);
6797 tcg_temp_free_i64(fp64);
6798 gen_store_fpr32(fp32, fd);
6799 tcg_temp_free_i32(fp32);
6800 }
6801 opn = "cvt.s.d";
6802 break;
6803 case FOP(36, 17):
6804 check_cp1_registers(ctx, fs);
6805 {
6806 TCGv_i32 fp32 = tcg_temp_new_i32();
6807 TCGv_i64 fp64 = tcg_temp_new_i64();
6808
6809 gen_load_fpr64(ctx, fp64, fs);
6810 gen_helper_float_cvtw_d(fp32, fp64);
6811 tcg_temp_free_i64(fp64);
6812 gen_store_fpr32(fp32, fd);
6813 tcg_temp_free_i32(fp32);
6814 }
6815 opn = "cvt.w.d";
6816 break;
6817 case FOP(37, 17):
6818 check_cp1_64bitmode(ctx);
6819 {
6820 TCGv_i64 fp0 = tcg_temp_new_i64();
6821
6822 gen_load_fpr64(ctx, fp0, fs);
6823 gen_helper_float_cvtl_d(fp0, fp0);
6824 gen_store_fpr64(ctx, fp0, fd);
6825 tcg_temp_free_i64(fp0);
6826 }
6827 opn = "cvt.l.d";
6828 break;
6829 case FOP(32, 20):
6830 {
6831 TCGv_i32 fp0 = tcg_temp_new_i32();
6832
6833 gen_load_fpr32(fp0, fs);
6834 gen_helper_float_cvts_w(fp0, fp0);
6835 gen_store_fpr32(fp0, fd);
6836 tcg_temp_free_i32(fp0);
6837 }
6838 opn = "cvt.s.w";
6839 break;
6840 case FOP(33, 20):
6841 check_cp1_registers(ctx, fd);
6842 {
6843 TCGv_i32 fp32 = tcg_temp_new_i32();
6844 TCGv_i64 fp64 = tcg_temp_new_i64();
6845
6846 gen_load_fpr32(fp32, fs);
6847 gen_helper_float_cvtd_w(fp64, fp32);
6848 tcg_temp_free_i32(fp32);
6849 gen_store_fpr64(ctx, fp64, fd);
6850 tcg_temp_free_i64(fp64);
6851 }
6852 opn = "cvt.d.w";
6853 break;
6854 case FOP(32, 21):
6855 check_cp1_64bitmode(ctx);
6856 {
6857 TCGv_i32 fp32 = tcg_temp_new_i32();
6858 TCGv_i64 fp64 = tcg_temp_new_i64();
6859
6860 gen_load_fpr64(ctx, fp64, fs);
6861 gen_helper_float_cvts_l(fp32, fp64);
6862 tcg_temp_free_i64(fp64);
6863 gen_store_fpr32(fp32, fd);
6864 tcg_temp_free_i32(fp32);
6865 }
6866 opn = "cvt.s.l";
6867 break;
6868 case FOP(33, 21):
6869 check_cp1_64bitmode(ctx);
6870 {
6871 TCGv_i64 fp0 = tcg_temp_new_i64();
6872
6873 gen_load_fpr64(ctx, fp0, fs);
6874 gen_helper_float_cvtd_l(fp0, fp0);
6875 gen_store_fpr64(ctx, fp0, fd);
6876 tcg_temp_free_i64(fp0);
6877 }
6878 opn = "cvt.d.l";
6879 break;
6880 case FOP(38, 20):
6881 check_cp1_64bitmode(ctx);
6882 {
6883 TCGv_i64 fp0 = tcg_temp_new_i64();
6884
6885 gen_load_fpr64(ctx, fp0, fs);
6886 gen_helper_float_cvtps_pw(fp0, fp0);
6887 gen_store_fpr64(ctx, fp0, fd);
6888 tcg_temp_free_i64(fp0);
6889 }
6890 opn = "cvt.ps.pw";
6891 break;
6892 case FOP(0, 22):
6893 check_cp1_64bitmode(ctx);
6894 {
6895 TCGv_i64 fp0 = tcg_temp_new_i64();
6896 TCGv_i64 fp1 = tcg_temp_new_i64();
6897
6898 gen_load_fpr64(ctx, fp0, fs);
6899 gen_load_fpr64(ctx, fp1, ft);
6900 gen_helper_float_add_ps(fp0, fp0, fp1);
6901 tcg_temp_free_i64(fp1);
6902 gen_store_fpr64(ctx, fp0, fd);
6903 tcg_temp_free_i64(fp0);
6904 }
6905 opn = "add.ps";
6906 break;
6907 case FOP(1, 22):
6908 check_cp1_64bitmode(ctx);
6909 {
6910 TCGv_i64 fp0 = tcg_temp_new_i64();
6911 TCGv_i64 fp1 = tcg_temp_new_i64();
6912
6913 gen_load_fpr64(ctx, fp0, fs);
6914 gen_load_fpr64(ctx, fp1, ft);
6915 gen_helper_float_sub_ps(fp0, fp0, fp1);
6916 tcg_temp_free_i64(fp1);
6917 gen_store_fpr64(ctx, fp0, fd);
6918 tcg_temp_free_i64(fp0);
6919 }
6920 opn = "sub.ps";
6921 break;
6922 case FOP(2, 22):
6923 check_cp1_64bitmode(ctx);
6924 {
6925 TCGv_i64 fp0 = tcg_temp_new_i64();
6926 TCGv_i64 fp1 = tcg_temp_new_i64();
6927
6928 gen_load_fpr64(ctx, fp0, fs);
6929 gen_load_fpr64(ctx, fp1, ft);
6930 gen_helper_float_mul_ps(fp0, fp0, fp1);
6931 tcg_temp_free_i64(fp1);
6932 gen_store_fpr64(ctx, fp0, fd);
6933 tcg_temp_free_i64(fp0);
6934 }
6935 opn = "mul.ps";
6936 break;
6937 case FOP(5, 22):
6938 check_cp1_64bitmode(ctx);
6939 {
6940 TCGv_i64 fp0 = tcg_temp_new_i64();
6941
6942 gen_load_fpr64(ctx, fp0, fs);
6943 gen_helper_float_abs_ps(fp0, fp0);
6944 gen_store_fpr64(ctx, fp0, fd);
6945 tcg_temp_free_i64(fp0);
6946 }
6947 opn = "abs.ps";
6948 break;
6949 case FOP(6, 22):
6950 check_cp1_64bitmode(ctx);
6951 {
6952 TCGv_i64 fp0 = tcg_temp_new_i64();
6953
6954 gen_load_fpr64(ctx, fp0, fs);
6955 gen_store_fpr64(ctx, fp0, fd);
6956 tcg_temp_free_i64(fp0);
6957 }
6958 opn = "mov.ps";
6959 break;
6960 case FOP(7, 22):
6961 check_cp1_64bitmode(ctx);
6962 {
6963 TCGv_i64 fp0 = tcg_temp_new_i64();
6964
6965 gen_load_fpr64(ctx, fp0, fs);
6966 gen_helper_float_chs_ps(fp0, fp0);
6967 gen_store_fpr64(ctx, fp0, fd);
6968 tcg_temp_free_i64(fp0);
6969 }
6970 opn = "neg.ps";
6971 break;
6972 case FOP(17, 22):
6973 check_cp1_64bitmode(ctx);
6974 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6975 opn = "movcf.ps";
6976 break;
6977 case FOP(18, 22):
6978 check_cp1_64bitmode(ctx);
6979 {
6980 int l1 = gen_new_label();
6981 TCGv_i64 fp0;
6982
6983 if (ft != 0)
6984 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6985 fp0 = tcg_temp_new_i64();
6986 gen_load_fpr64(ctx, fp0, fs);
6987 gen_store_fpr64(ctx, fp0, fd);
6988 tcg_temp_free_i64(fp0);
6989 gen_set_label(l1);
6990 }
6991 opn = "movz.ps";
6992 break;
6993 case FOP(19, 22):
6994 check_cp1_64bitmode(ctx);
6995 {
6996 int l1 = gen_new_label();
6997 TCGv_i64 fp0;
6998
6999 if (ft != 0) {
7000 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7001 fp0 = tcg_temp_new_i64();
7002 gen_load_fpr64(ctx, fp0, fs);
7003 gen_store_fpr64(ctx, fp0, fd);
7004 tcg_temp_free_i64(fp0);
7005 gen_set_label(l1);
7006 }
7007 }
7008 opn = "movn.ps";
7009 break;
7010 case FOP(24, 22):
7011 check_cp1_64bitmode(ctx);
7012 {
7013 TCGv_i64 fp0 = tcg_temp_new_i64();
7014 TCGv_i64 fp1 = tcg_temp_new_i64();
7015
7016 gen_load_fpr64(ctx, fp0, ft);
7017 gen_load_fpr64(ctx, fp1, fs);
7018 gen_helper_float_addr_ps(fp0, fp0, fp1);
7019 tcg_temp_free_i64(fp1);
7020 gen_store_fpr64(ctx, fp0, fd);
7021 tcg_temp_free_i64(fp0);
7022 }
7023 opn = "addr.ps";
7024 break;
7025 case FOP(26, 22):
7026 check_cp1_64bitmode(ctx);
7027 {
7028 TCGv_i64 fp0 = tcg_temp_new_i64();
7029 TCGv_i64 fp1 = tcg_temp_new_i64();
7030
7031 gen_load_fpr64(ctx, fp0, ft);
7032 gen_load_fpr64(ctx, fp1, fs);
7033 gen_helper_float_mulr_ps(fp0, fp0, fp1);
7034 tcg_temp_free_i64(fp1);
7035 gen_store_fpr64(ctx, fp0, fd);
7036 tcg_temp_free_i64(fp0);
7037 }
7038 opn = "mulr.ps";
7039 break;
7040 case FOP(28, 22):
7041 check_cp1_64bitmode(ctx);
7042 {
7043 TCGv_i64 fp0 = tcg_temp_new_i64();
7044 TCGv_i64 fp1 = tcg_temp_new_i64();
7045
7046 gen_load_fpr64(ctx, fp0, fs);
7047 gen_load_fpr64(ctx, fp1, fd);
7048 gen_helper_float_recip2_ps(fp0, fp0, fp1);
7049 tcg_temp_free_i64(fp1);
7050 gen_store_fpr64(ctx, fp0, fd);
7051 tcg_temp_free_i64(fp0);
7052 }
7053 opn = "recip2.ps";
7054 break;
7055 case FOP(29, 22):
7056 check_cp1_64bitmode(ctx);
7057 {
7058 TCGv_i64 fp0 = tcg_temp_new_i64();
7059
7060 gen_load_fpr64(ctx, fp0, fs);
7061 gen_helper_float_recip1_ps(fp0, fp0);
7062 gen_store_fpr64(ctx, fp0, fd);
7063 tcg_temp_free_i64(fp0);
7064 }
7065 opn = "recip1.ps";
7066 break;
7067 case FOP(30, 22):
7068 check_cp1_64bitmode(ctx);
7069 {
7070 TCGv_i64 fp0 = tcg_temp_new_i64();
7071
7072 gen_load_fpr64(ctx, fp0, fs);
7073 gen_helper_float_rsqrt1_ps(fp0, fp0);
7074 gen_store_fpr64(ctx, fp0, fd);
7075 tcg_temp_free_i64(fp0);
7076 }
7077 opn = "rsqrt1.ps";
7078 break;
7079 case FOP(31, 22):
7080 check_cp1_64bitmode(ctx);
7081 {
7082 TCGv_i64 fp0 = tcg_temp_new_i64();
7083 TCGv_i64 fp1 = tcg_temp_new_i64();
7084
7085 gen_load_fpr64(ctx, fp0, fs);
7086 gen_load_fpr64(ctx, fp1, ft);
7087 gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7088 tcg_temp_free_i64(fp1);
7089 gen_store_fpr64(ctx, fp0, fd);
7090 tcg_temp_free_i64(fp0);
7091 }
7092 opn = "rsqrt2.ps";
7093 break;
7094 case FOP(32, 22):
7095 check_cp1_64bitmode(ctx);
7096 {
7097 TCGv_i32 fp0 = tcg_temp_new_i32();
7098
7099 gen_load_fpr32h(fp0, fs);
7100 gen_helper_float_cvts_pu(fp0, fp0);
7101 gen_store_fpr32(fp0, fd);
7102 tcg_temp_free_i32(fp0);
7103 }
7104 opn = "cvt.s.pu";
7105 break;
7106 case FOP(36, 22):
7107 check_cp1_64bitmode(ctx);
7108 {
7109 TCGv_i64 fp0 = tcg_temp_new_i64();
7110
7111 gen_load_fpr64(ctx, fp0, fs);
7112 gen_helper_float_cvtpw_ps(fp0, fp0);
7113 gen_store_fpr64(ctx, fp0, fd);
7114 tcg_temp_free_i64(fp0);
7115 }
7116 opn = "cvt.pw.ps";
7117 break;
7118 case FOP(40, 22):
7119 check_cp1_64bitmode(ctx);
7120 {
7121 TCGv_i32 fp0 = tcg_temp_new_i32();
7122
7123 gen_load_fpr32(fp0, fs);
7124 gen_helper_float_cvts_pl(fp0, fp0);
7125 gen_store_fpr32(fp0, fd);
7126 tcg_temp_free_i32(fp0);
7127 }
7128 opn = "cvt.s.pl";
7129 break;
7130 case FOP(44, 22):
7131 check_cp1_64bitmode(ctx);
7132 {
7133 TCGv_i32 fp0 = tcg_temp_new_i32();
7134 TCGv_i32 fp1 = tcg_temp_new_i32();
7135
7136 gen_load_fpr32(fp0, fs);
7137 gen_load_fpr32(fp1, ft);
7138 gen_store_fpr32h(fp0, fd);
7139 gen_store_fpr32(fp1, fd);
7140 tcg_temp_free_i32(fp0);
7141 tcg_temp_free_i32(fp1);
7142 }
7143 opn = "pll.ps";
7144 break;
7145 case FOP(45, 22):
7146 check_cp1_64bitmode(ctx);
7147 {
7148 TCGv_i32 fp0 = tcg_temp_new_i32();
7149 TCGv_i32 fp1 = tcg_temp_new_i32();
7150
7151 gen_load_fpr32(fp0, fs);
7152 gen_load_fpr32h(fp1, ft);
7153 gen_store_fpr32(fp1, fd);
7154 gen_store_fpr32h(fp0, fd);
7155 tcg_temp_free_i32(fp0);
7156 tcg_temp_free_i32(fp1);
7157 }
7158 opn = "plu.ps";
7159 break;
7160 case FOP(46, 22):
7161 check_cp1_64bitmode(ctx);
7162 {
7163 TCGv_i32 fp0 = tcg_temp_new_i32();
7164 TCGv_i32 fp1 = tcg_temp_new_i32();
7165
7166 gen_load_fpr32h(fp0, fs);
7167 gen_load_fpr32(fp1, ft);
7168 gen_store_fpr32(fp1, fd);
7169 gen_store_fpr32h(fp0, fd);
7170 tcg_temp_free_i32(fp0);
7171 tcg_temp_free_i32(fp1);
7172 }
7173 opn = "pul.ps";
7174 break;
7175 case FOP(47, 22):
7176 check_cp1_64bitmode(ctx);
7177 {
7178 TCGv_i32 fp0 = tcg_temp_new_i32();
7179 TCGv_i32 fp1 = tcg_temp_new_i32();
7180
7181 gen_load_fpr32h(fp0, fs);
7182 gen_load_fpr32h(fp1, ft);
7183 gen_store_fpr32(fp1, fd);
7184 gen_store_fpr32h(fp0, fd);
7185 tcg_temp_free_i32(fp0);
7186 tcg_temp_free_i32(fp1);
7187 }
7188 opn = "puu.ps";
7189 break;
7190 case FOP(48, 22):
7191 case FOP(49, 22):
7192 case FOP(50, 22):
7193 case FOP(51, 22):
7194 case FOP(52, 22):
7195 case FOP(53, 22):
7196 case FOP(54, 22):
7197 case FOP(55, 22):
7198 case FOP(56, 22):
7199 case FOP(57, 22):
7200 case FOP(58, 22):
7201 case FOP(59, 22):
7202 case FOP(60, 22):
7203 case FOP(61, 22):
7204 case FOP(62, 22):
7205 case FOP(63, 22):
7206 check_cp1_64bitmode(ctx);
7207 {
7208 TCGv_i64 fp0 = tcg_temp_new_i64();
7209 TCGv_i64 fp1 = tcg_temp_new_i64();
7210
7211 gen_load_fpr64(ctx, fp0, fs);
7212 gen_load_fpr64(ctx, fp1, ft);
7213 if (ctx->opcode & (1 << 6)) {
7214 gen_cmpabs_ps(func-48, fp0, fp1, cc);
7215 opn = condnames_abs[func-48];
7216 } else {
7217 gen_cmp_ps(func-48, fp0, fp1, cc);
7218 opn = condnames[func-48];
7219 }
7220 tcg_temp_free_i64(fp0);
7221 tcg_temp_free_i64(fp1);
7222 }
7223 break;
7224 default:
7225 MIPS_INVAL(opn);
7226 generate_exception (ctx, EXCP_RI);
7227 return;
7228 }
7229 switch (optype) {
7230 case BINOP:
7231 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7232 break;
7233 case CMPOP:
7234 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7235 break;
7236 default:
7237 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7238 break;
7239 }
7240 }
7241
7242 /* Coprocessor 3 (FPU) */
7243 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7244 int fd, int fs, int base, int index)
7245 {
7246 const char *opn = "extended float load/store";
7247 int store = 0;
7248 TCGv t0 = tcg_temp_new();
7249
7250 if (base == 0) {
7251 gen_load_gpr(t0, index);
7252 } else if (index == 0) {
7253 gen_load_gpr(t0, base);
7254 } else {
7255 gen_load_gpr(t0, index);
7256 gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
7257 }
7258 /* Don't do NOP if destination is zero: we must perform the actual
7259 memory access. */
7260 save_cpu_state(ctx, 0);
7261 switch (opc) {
7262 case OPC_LWXC1:
7263 check_cop1x(ctx);
7264 {
7265 TCGv_i32 fp0 = tcg_temp_new_i32();
7266
7267 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7268 tcg_gen_trunc_tl_i32(fp0, t0);
7269 gen_store_fpr32(fp0, fd);
7270 tcg_temp_free_i32(fp0);
7271 }
7272 opn = "lwxc1";
7273 break;
7274 case OPC_LDXC1:
7275 check_cop1x(ctx);
7276 check_cp1_registers(ctx, fd);
7277 {
7278 TCGv_i64 fp0 = tcg_temp_new_i64();
7279
7280 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7281 gen_store_fpr64(ctx, fp0, fd);
7282 tcg_temp_free_i64(fp0);
7283 }
7284 opn = "ldxc1";
7285 break;
7286 case OPC_LUXC1:
7287 check_cp1_64bitmode(ctx);
7288 tcg_gen_andi_tl(t0, t0, ~0x7);
7289 {
7290 TCGv_i64 fp0 = tcg_temp_new_i64();
7291
7292 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7293 gen_store_fpr64(ctx, fp0, fd);
7294 tcg_temp_free_i64(fp0);
7295 }
7296 opn = "luxc1";
7297 break;
7298 case OPC_SWXC1:
7299 check_cop1x(ctx);
7300 {
7301 TCGv_i32 fp0 = tcg_temp_new_i32();
7302 TCGv t1 = tcg_temp_new();
7303
7304 gen_load_fpr32(fp0, fs);
7305 tcg_gen_extu_i32_tl(t1, fp0);
7306 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7307 tcg_temp_free_i32(fp0);
7308 tcg_temp_free(t1);
7309 }
7310 opn = "swxc1";
7311 store = 1;
7312 break;
7313 case OPC_SDXC1:
7314 check_cop1x(ctx);
7315 check_cp1_registers(ctx, fs);
7316 {
7317 TCGv_i64 fp0 = tcg_temp_new_i64();
7318
7319 gen_load_fpr64(ctx, fp0, fs);
7320 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7321 tcg_temp_free_i64(fp0);
7322 }
7323 opn = "sdxc1";
7324 store = 1;
7325 break;
7326 case OPC_SUXC1:
7327 check_cp1_64bitmode(ctx);
7328 tcg_gen_andi_tl(t0, t0, ~0x7);
7329 {
7330 TCGv_i64 fp0 = tcg_temp_new_i64();
7331
7332 gen_load_fpr64(ctx, fp0, fs);
7333 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7334 tcg_temp_free_i64(fp0);
7335 }
7336 opn = "suxc1";
7337 store = 1;
7338 break;
7339 }
7340 tcg_temp_free(t0);
7341 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7342 regnames[index], regnames[base]);
7343 }
7344
7345 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7346 int fd, int fr, int fs, int ft)
7347 {
7348 const char *opn = "flt3_arith";
7349
7350 switch (opc) {
7351 case OPC_ALNV_PS:
7352 check_cp1_64bitmode(ctx);
7353 {
7354 TCGv t0 = tcg_temp_local_new();
7355 TCGv_i32 fp = tcg_temp_new_i32();
7356 TCGv_i32 fph = tcg_temp_new_i32();
7357 int l1 = gen_new_label();
7358 int l2 = gen_new_label();
7359
7360 gen_load_gpr(t0, fr);
7361 tcg_gen_andi_tl(t0, t0, 0x7);
7362
7363 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7364 gen_load_fpr32(fp, fs);
7365 gen_load_fpr32h(fph, fs);
7366 gen_store_fpr32(fp, fd);
7367 gen_store_fpr32h(fph, fd);
7368 tcg_gen_br(l2);
7369 gen_set_label(l1);
7370 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7371 tcg_temp_free(t0);
7372 #ifdef TARGET_WORDS_BIGENDIAN
7373 gen_load_fpr32(fp, fs);
7374 gen_load_fpr32h(fph, ft);
7375 gen_store_fpr32h(fp, fd);
7376 gen_store_fpr32(fph, fd);
7377 #else
7378 gen_load_fpr32h(fph, fs);
7379 gen_load_fpr32(fp, ft);
7380 gen_store_fpr32(fph, fd);
7381 gen_store_fpr32h(fp, fd);
7382 #endif
7383 gen_set_label(l2);
7384 tcg_temp_free_i32(fp);
7385 tcg_temp_free_i32(fph);
7386 }
7387 opn = "alnv.ps";
7388 break;
7389 case OPC_MADD_S:
7390 check_cop1x(ctx);
7391 {
7392 TCGv_i32 fp0 = tcg_temp_new_i32();
7393 TCGv_i32 fp1 = tcg_temp_new_i32();
7394 TCGv_i32 fp2 = tcg_temp_new_i32();
7395
7396 gen_load_fpr32(fp0, fs);
7397 gen_load_fpr32(fp1, ft);
7398 gen_load_fpr32(fp2, fr);
7399 gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7400 tcg_temp_free_i32(fp0);
7401 tcg_temp_free_i32(fp1);
7402 gen_store_fpr32(fp2, fd);
7403 tcg_temp_free_i32(fp2);
7404 }
7405 opn = "madd.s";
7406 break;
7407 case OPC_MADD_D:
7408 check_cop1x(ctx);
7409 check_cp1_registers(ctx, fd | fs | ft | fr);
7410 {
7411 TCGv_i64 fp0 = tcg_temp_new_i64();
7412 TCGv_i64 fp1 = tcg_temp_new_i64();
7413 TCGv_i64 fp2 = tcg_temp_new_i64();
7414
7415 gen_load_fpr64(ctx, fp0, fs);
7416 gen_load_fpr64(ctx, fp1, ft);
7417 gen_load_fpr64(ctx, fp2, fr);
7418 gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7419 tcg_temp_free_i64(fp0);
7420 tcg_temp_free_i64(fp1);
7421 gen_store_fpr64(ctx, fp2, fd);
7422 tcg_temp_free_i64(fp2);
7423 }
7424 opn = "madd.d";
7425 break;
7426 case OPC_MADD_PS:
7427 check_cp1_64bitmode(ctx);
7428 {
7429 TCGv_i64 fp0 = tcg_temp_new_i64();
7430 TCGv_i64 fp1 = tcg_temp_new_i64();
7431 TCGv_i64 fp2 = tcg_temp_new_i64();
7432
7433 gen_load_fpr64(ctx, fp0, fs);
7434 gen_load_fpr64(ctx, fp1, ft);
7435 gen_load_fpr64(ctx, fp2, fr);
7436 gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7437 tcg_temp_free_i64(fp0);
7438 tcg_temp_free_i64(fp1);
7439 gen_store_fpr64(ctx, fp2, fd);
7440 tcg_temp_free_i64(fp2);
7441 }
7442 opn = "madd.ps";
7443 break;
7444 case OPC_MSUB_S:
7445 check_cop1x(ctx);
7446 {
7447 TCGv_i32 fp0 = tcg_temp_new_i32();
7448 TCGv_i32 fp1 = tcg_temp_new_i32();
7449 TCGv_i32 fp2 = tcg_temp_new_i32();
7450
7451 gen_load_fpr32(fp0, fs);
7452 gen_load_fpr32(fp1, ft);
7453 gen_load_fpr32(fp2, fr);
7454 gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7455 tcg_temp_free_i32(fp0);
7456 tcg_temp_free_i32(fp1);
7457 gen_store_fpr32(fp2, fd);
7458 tcg_temp_free_i32(fp2);
7459 }
7460 opn = "msub.s";
7461 break;
7462 case OPC_MSUB_D:
7463 check_cop1x(ctx);
7464 check_cp1_registers(ctx, fd | fs | ft | fr);
7465 {
7466 TCGv_i64 fp0 = tcg_temp_new_i64();
7467 TCGv_i64 fp1 = tcg_temp_new_i64();
7468 TCGv_i64 fp2 = tcg_temp_new_i64();
7469
7470 gen_load_fpr64(ctx, fp0, fs);
7471 gen_load_fpr64(ctx, fp1, ft);
7472 gen_load_fpr64(ctx, fp2, fr);
7473 gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7474 tcg_temp_free_i64(fp0);
7475 tcg_temp_free_i64(fp1);
7476 gen_store_fpr64(ctx, fp2, fd);
7477 tcg_temp_free_i64(fp2);
7478 }
7479 opn = "msub.d";
7480 break;
7481 case OPC_MSUB_PS:
7482 check_cp1_64bitmode(ctx);
7483 {
7484 TCGv_i64 fp0 = tcg_temp_new_i64();
7485 TCGv_i64 fp1 = tcg_temp_new_i64();
7486 TCGv_i64 fp2 = tcg_temp_new_i64();
7487
7488 gen_load_fpr64(ctx, fp0, fs);
7489 gen_load_fpr64(ctx, fp1, ft);
7490 gen_load_fpr64(ctx, fp2, fr);
7491 gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7492 tcg_temp_free_i64(fp0);
7493 tcg_temp_free_i64(fp1);
7494 gen_store_fpr64(ctx, fp2, fd);
7495 tcg_temp_free_i64(fp2);
7496 }
7497 opn = "msub.ps";
7498 break;
7499 case OPC_NMADD_S:
7500 check_cop1x(ctx);
7501 {
7502 TCGv_i32 fp0 = tcg_temp_new_i32();
7503 TCGv_i32 fp1 = tcg_temp_new_i32();
7504 TCGv_i32 fp2 = tcg_temp_new_i32();
7505
7506 gen_load_fpr32(fp0, fs);
7507 gen_load_fpr32(fp1, ft);
7508 gen_load_fpr32(fp2, fr);
7509 gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7510 tcg_temp_free_i32(fp0);
7511 tcg_temp_free_i32(fp1);
7512 gen_store_fpr32(fp2, fd);
7513 tcg_temp_free_i32(fp2);
7514 }
7515 opn = "nmadd.s";
7516 break;
7517 case OPC_NMADD_D:
7518 check_cop1x(ctx);
7519 check_cp1_registers(ctx, fd | fs | ft | fr);
7520 {
7521 TCGv_i64 fp0 = tcg_temp_new_i64();
7522 TCGv_i64 fp1 = tcg_temp_new_i64();
7523 TCGv_i64 fp2 = tcg_temp_new_i64();
7524
7525 gen_load_fpr64(ctx, fp0, fs);
7526 gen_load_fpr64(ctx, fp1, ft);
7527 gen_load_fpr64(ctx, fp2, fr);
7528 gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7529 tcg_temp_free_i64(fp0);
7530 tcg_temp_free_i64(fp1);
7531 gen_store_fpr64(ctx, fp2, fd);
7532 tcg_temp_free_i64(fp2);
7533 }
7534 opn = "nmadd.d";
7535 break;
7536 case OPC_NMADD_PS:
7537 check_cp1_64bitmode(ctx);
7538 {
7539 TCGv_i64 fp0 = tcg_temp_new_i64();
7540 TCGv_i64 fp1 = tcg_temp_new_i64();
7541 TCGv_i64 fp2 = tcg_temp_new_i64();
7542
7543 gen_load_fpr64(ctx, fp0, fs);
7544 gen_load_fpr64(ctx, fp1, ft);
7545 gen_load_fpr64(ctx, fp2, fr);
7546 gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7547 tcg_temp_free_i64(fp0);
7548 tcg_temp_free_i64(fp1);
7549 gen_store_fpr64(ctx, fp2, fd);
7550 tcg_temp_free_i64(fp2);
7551 }
7552 opn = "nmadd.ps";
7553 break;
7554 case OPC_NMSUB_S:
7555 check_cop1x(ctx);
7556 {
7557 TCGv_i32 fp0 = tcg_temp_new_i32();
7558 TCGv_i32 fp1 = tcg_temp_new_i32();
7559 TCGv_i32 fp2 = tcg_temp_new_i32();
7560
7561 gen_load_fpr32(fp0, fs);
7562 gen_load_fpr32(fp1, ft);
7563 gen_load_fpr32(fp2, fr);
7564 gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7565 tcg_temp_free_i32(fp0);
7566 tcg_temp_free_i32(fp1);
7567 gen_store_fpr32(fp2, fd);
7568 tcg_temp_free_i32(fp2);
7569 }
7570 opn = "nmsub.s";
7571 break;
7572 case OPC_NMSUB_D:
7573 check_cop1x(ctx);
7574 check_cp1_registers(ctx, fd | fs | ft | fr);
7575 {
7576 TCGv_i64 fp0 = tcg_temp_new_i64();
7577 TCGv_i64 fp1 = tcg_temp_new_i64();
7578 TCGv_i64 fp2 = tcg_temp_new_i64();
7579
7580 gen_load_fpr64(ctx, fp0, fs);
7581 gen_load_fpr64(ctx, fp1, ft);
7582 gen_load_fpr64(ctx, fp2, fr);
7583 gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7584 tcg_temp_free_i64(fp0);
7585 tcg_temp_free_i64(fp1);
7586 gen_store_fpr64(ctx, fp2, fd);
7587 tcg_temp_free_i64(fp2);
7588 }
7589 opn = "nmsub.d";
7590 break;
7591 case OPC_NMSUB_PS:
7592 check_cp1_64bitmode(ctx);
7593 {
7594 TCGv_i64 fp0 = tcg_temp_new_i64();
7595 TCGv_i64 fp1 = tcg_temp_new_i64();
7596 TCGv_i64 fp2 = tcg_temp_new_i64();
7597
7598 gen_load_fpr64(ctx, fp0, fs);
7599 gen_load_fpr64(ctx, fp1, ft);
7600 gen_load_fpr64(ctx, fp2, fr);
7601 gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7602 tcg_temp_free_i64(fp0);
7603 tcg_temp_free_i64(fp1);
7604 gen_store_fpr64(ctx, fp2, fd);
7605 tcg_temp_free_i64(fp2);
7606 }
7607 opn = "nmsub.ps";
7608 break;
7609 default:
7610 MIPS_INVAL(opn);
7611 generate_exception (ctx, EXCP_RI);
7612 return;
7613 }
7614 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7615 fregnames[fs], fregnames[ft]);
7616 }
7617
7618 /* ISA extensions (ASEs) */
7619 /* MIPS16 extension to MIPS32 */
7620 /* SmartMIPS extension to MIPS32 */
7621
7622 #if defined(TARGET_MIPS64)
7623
7624 /* MDMX extension to MIPS64 */
7625
7626 #endif
7627
7628 static void decode_opc (CPUState *env, DisasContext *ctx)
7629 {
7630 int32_t offset;
7631 int rs, rt, rd, sa;
7632 uint32_t op, op1, op2;
7633 int16_t imm;
7634
7635 /* make sure instructions are on a word boundary */
7636 if (ctx->pc & 0x3) {
7637 env->CP0_BadVAddr = ctx->pc;
7638 generate_exception(ctx, EXCP_AdEL);
7639 return;
7640 }
7641
7642 /* Handle blikely not taken case */
7643 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7644 int l1 = gen_new_label();
7645
7646 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7647 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7648 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7649 gen_goto_tb(ctx, 1, ctx->pc + 4);
7650 gen_set_label(l1);
7651 }
7652
7653 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
7654 tcg_gen_debug_insn_start(ctx->pc);
7655
7656 op = MASK_OP_MAJOR(ctx->opcode);
7657 rs = (ctx->opcode >> 21) & 0x1f;
7658 rt = (ctx->opcode >> 16) & 0x1f;
7659 rd = (ctx->opcode >> 11) & 0x1f;
7660 sa = (ctx->opcode >> 6) & 0x1f;
7661 imm = (int16_t)ctx->opcode;
7662 switch (op) {
7663 case OPC_SPECIAL:
7664 op1 = MASK_SPECIAL(ctx->opcode);
7665 switch (op1) {
7666 case OPC_SLL: /* Shift with immediate */
7667 case OPC_SRA:
7668 case OPC_SRL:
7669 gen_shift_imm(env, ctx, op1, rd, rt, sa);
7670 break;
7671 case OPC_MOVN: /* Conditional move */
7672 case OPC_MOVZ:
7673 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7674 gen_cond_move(env, op1, rd, rs, rt);
7675 break;
7676 case OPC_ADD ... OPC_SUBU:
7677 gen_arith(env, ctx, op1, rd, rs, rt);
7678 break;
7679 case OPC_SLLV: /* Shifts */
7680 case OPC_SRLV:
7681 case OPC_SRAV:
7682 gen_shift(env, ctx, op1, rd, rs, rt);
7683 break;
7684 case OPC_SLT: /* Set on less than */
7685 case OPC_SLTU:
7686 gen_slt(env, op1, rd, rs, rt);
7687 break;
7688 case OPC_AND: /* Logic*/
7689 case OPC_OR:
7690 case OPC_NOR:
7691 case OPC_XOR:
7692 gen_logic(env, op1, rd, rs, rt);
7693 break;
7694 case OPC_MULT ... OPC_DIVU:
7695 if (sa) {
7696 check_insn(env, ctx, INSN_VR54XX);
7697 op1 = MASK_MUL_VR54XX(ctx->opcode);
7698 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7699 } else
7700 gen_muldiv(ctx, op1, rs, rt);
7701 break;
7702 case OPC_JR ... OPC_JALR:
7703 gen_compute_branch(ctx, op1, rs, rd, sa);
7704 return;
7705 case OPC_TGE ... OPC_TEQ: /* Traps */
7706 case OPC_TNE:
7707 gen_trap(ctx, op1, rs, rt, -1);
7708 break;
7709 case OPC_MFHI: /* Move from HI/LO */
7710 case OPC_MFLO:
7711 gen_HILO(ctx, op1, rd);
7712 break;
7713 case OPC_MTHI:
7714 case OPC_MTLO: /* Move to HI/LO */
7715 gen_HILO(ctx, op1, rs);
7716 break;
7717 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
7718 #ifdef MIPS_STRICT_STANDARD
7719 MIPS_INVAL("PMON / selsl");
7720 generate_exception(ctx, EXCP_RI);
7721 #else
7722 gen_helper_0i(pmon, sa);
7723 #endif
7724 break;
7725 case OPC_SYSCALL:
7726 generate_exception(ctx, EXCP_SYSCALL);
7727 ctx->bstate = BS_STOP;
7728 break;
7729 case OPC_BREAK:
7730 generate_exception(ctx, EXCP_BREAK);
7731 break;
7732 case OPC_SPIM:
7733 #ifdef MIPS_STRICT_STANDARD
7734 MIPS_INVAL("SPIM");
7735 generate_exception(ctx, EXCP_RI);
7736 #else
7737 /* Implemented as RI exception for now. */
7738 MIPS_INVAL("spim (unofficial)");
7739 generate_exception(ctx, EXCP_RI);
7740 #endif
7741 break;
7742 case OPC_SYNC:
7743 /* Treat as NOP. */
7744 break;
7745
7746 case OPC_MOVCI:
7747 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7748 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7749 check_cp1_enabled(ctx);
7750 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7751 (ctx->opcode >> 16) & 1);
7752 } else {
7753 generate_exception_err(ctx, EXCP_CpU, 1);
7754 }
7755 break;
7756
7757 #if defined(TARGET_MIPS64)
7758 /* MIPS64 specific opcodes */
7759 case OPC_DSLL:
7760 case OPC_DSRA:
7761 case OPC_DSRL:
7762 case OPC_DSLL32:
7763 case OPC_DSRA32:
7764 case OPC_DSRL32:
7765 check_insn(env, ctx, ISA_MIPS3);
7766 check_mips_64(ctx);
7767 gen_shift_imm(env, ctx, op1, rd, rt, sa);
7768 break;
7769 case OPC_DADD ... OPC_DSUBU:
7770 check_insn(env, ctx, ISA_MIPS3);
7771 check_mips_64(ctx);
7772 gen_arith(env, ctx, op1, rd, rs, rt);
7773 break;
7774 case OPC_DSLLV:
7775 case OPC_DSRAV:
7776 case OPC_DSRLV:
7777 check_insn(env, ctx, ISA_MIPS3);
7778 check_mips_64(ctx);
7779 gen_shift(env, ctx, op1, rd, rs, rt);
7780 break;
7781 case OPC_DMULT ... OPC_DDIVU:
7782 check_insn(env, ctx, ISA_MIPS3);
7783 check_mips_64(ctx);
7784 gen_muldiv(ctx, op1, rs, rt);
7785 break;
7786 #endif
7787 default: /* Invalid */
7788 MIPS_INVAL("special");
7789 generate_exception(ctx, EXCP_RI);
7790 break;
7791 }
7792 break;
7793 case OPC_SPECIAL2:
7794 op1 = MASK_SPECIAL2(ctx->opcode);
7795 switch (op1) {
7796 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7797 case OPC_MSUB ... OPC_MSUBU:
7798 check_insn(env, ctx, ISA_MIPS32);
7799 gen_muldiv(ctx, op1, rs, rt);
7800 break;
7801 case OPC_MUL:
7802 gen_arith(env, ctx, op1, rd, rs, rt);
7803 break;
7804 case OPC_CLO:
7805 case OPC_CLZ:
7806 check_insn(env, ctx, ISA_MIPS32);
7807 gen_cl(ctx, op1, rd, rs);
7808 break;
7809 case OPC_SDBBP:
7810 /* XXX: not clear which exception should be raised
7811 * when in debug mode...
7812 */
7813 check_insn(env, ctx, ISA_MIPS32);
7814 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7815 generate_exception(ctx, EXCP_DBp);
7816 } else {
7817 generate_exception(ctx, EXCP_DBp);
7818 }
7819 /* Treat as NOP. */
7820 break;
7821 #if defined(TARGET_MIPS64)
7822 case OPC_DCLO:
7823 case OPC_DCLZ:
7824 check_insn(env, ctx, ISA_MIPS64);
7825 check_mips_64(ctx);
7826 gen_cl(ctx, op1, rd, rs);
7827 break;
7828 #endif
7829 default: /* Invalid */
7830 MIPS_INVAL("special2");
7831 generate_exception(ctx, EXCP_RI);
7832 break;
7833 }
7834 break;
7835 case OPC_SPECIAL3:
7836 op1 = MASK_SPECIAL3(ctx->opcode);
7837 switch (op1) {
7838 case OPC_EXT:
7839 case OPC_INS:
7840 check_insn(env, ctx, ISA_MIPS32R2);
7841 gen_bitops(ctx, op1, rt, rs, sa, rd);
7842 break;
7843 case OPC_BSHFL:
7844 check_insn(env, ctx, ISA_MIPS32R2);
7845 op2 = MASK_BSHFL(ctx->opcode);
7846 gen_bshfl(ctx, op2, rt, rd);
7847 break;
7848 case OPC_RDHWR:
7849 check_insn(env, ctx, ISA_MIPS32R2);
7850 {
7851 TCGv t0 = tcg_temp_new();
7852
7853 switch (rd) {
7854 case 0:
7855 save_cpu_state(ctx, 1);
7856 gen_helper_rdhwr_cpunum(t0);
7857 gen_store_gpr(t0, rt);
7858 break;
7859 case 1:
7860 save_cpu_state(ctx, 1);
7861 gen_helper_rdhwr_synci_step(t0);
7862 gen_store_gpr(t0, rt);
7863 break;
7864 case 2:
7865 save_cpu_state(ctx, 1);
7866 gen_helper_rdhwr_cc(t0);
7867 gen_store_gpr(t0, rt);
7868 break;
7869 case 3:
7870 save_cpu_state(ctx, 1);
7871 gen_helper_rdhwr_ccres(t0);
7872 gen_store_gpr(t0, rt);
7873 break;
7874 case 29:
7875 #if defined(CONFIG_USER_ONLY)
7876 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7877 gen_store_gpr(t0, rt);
7878 break;
7879 #else
7880 /* XXX: Some CPUs implement this in hardware.
7881 Not supported yet. */
7882 #endif
7883 default: /* Invalid */
7884 MIPS_INVAL("rdhwr");
7885 generate_exception(ctx, EXCP_RI);
7886 break;
7887 }
7888 tcg_temp_free(t0);
7889 }
7890 break;
7891 case OPC_FORK:
7892 check_insn(env, ctx, ASE_MT);
7893 {
7894 TCGv t0 = tcg_temp_new();
7895 TCGv t1 = tcg_temp_new();
7896
7897 gen_load_gpr(t0, rt);
7898 gen_load_gpr(t1, rs);
7899 gen_helper_fork(t0, t1);
7900 tcg_temp_free(t0);
7901 tcg_temp_free(t1);
7902 }
7903 break;
7904 case OPC_YIELD:
7905 check_insn(env, ctx, ASE_MT);
7906 {
7907 TCGv t0 = tcg_temp_new();
7908
7909 save_cpu_state(ctx, 1);
7910 gen_load_gpr(t0, rs);
7911 gen_helper_yield(t0, t0);
7912 gen_store_gpr(t0, rd);
7913 tcg_temp_free(t0);
7914 }
7915 break;
7916 #if defined(TARGET_MIPS64)
7917 case OPC_DEXTM ... OPC_DEXT:
7918 case OPC_DINSM ... OPC_DINS:
7919 check_insn(env, ctx, ISA_MIPS64R2);
7920 check_mips_64(ctx);
7921 gen_bitops(ctx, op1, rt, rs, sa, rd);
7922 break;
7923 case OPC_DBSHFL:
7924 check_insn(env, ctx, ISA_MIPS64R2);
7925 check_mips_64(ctx);
7926 op2 = MASK_DBSHFL(ctx->opcode);
7927 gen_bshfl(ctx, op2, rt, rd);
7928 break;
7929 #endif
7930 default: /* Invalid */
7931 MIPS_INVAL("special3");
7932 generate_exception(ctx, EXCP_RI);
7933 break;
7934 }
7935 break;
7936 case OPC_REGIMM:
7937 op1 = MASK_REGIMM(ctx->opcode);
7938 switch (op1) {
7939 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7940 case OPC_BLTZAL ... OPC_BGEZALL:
7941 gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7942 return;
7943 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7944 case OPC_TNEI:
7945 gen_trap(ctx, op1, rs, -1, imm);
7946 break;
7947 case OPC_SYNCI:
7948 check_insn(env, ctx, ISA_MIPS32R2);
7949 /* Treat as NOP. */
7950 break;
7951 default: /* Invalid */
7952 MIPS_INVAL("regimm");
7953 generate_exception(ctx, EXCP_RI);
7954 break;
7955 }
7956 break;
7957 case OPC_CP0:
7958 check_cp0_enabled(ctx);
7959 op1 = MASK_CP0(ctx->opcode);
7960 switch (op1) {
7961 case OPC_MFC0:
7962 case OPC_MTC0:
7963 case OPC_MFTR:
7964 case OPC_MTTR:
7965 #if defined(TARGET_MIPS64)
7966 case OPC_DMFC0:
7967 case OPC_DMTC0:
7968 #endif
7969 #ifndef CONFIG_USER_ONLY
7970 gen_cp0(env, ctx, op1, rt, rd);
7971 #endif /* !CONFIG_USER_ONLY */
7972 break;
7973 case OPC_C0_FIRST ... OPC_C0_LAST:
7974 #ifndef CONFIG_USER_ONLY
7975 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7976 #endif /* !CONFIG_USER_ONLY */
7977 break;
7978 case OPC_MFMC0:
7979 #ifndef CONFIG_USER_ONLY
7980 {
7981 TCGv t0 = tcg_temp_new();
7982
7983 op2 = MASK_MFMC0(ctx->opcode);
7984 switch (op2) {
7985 case OPC_DMT:
7986 check_insn(env, ctx, ASE_MT);
7987 gen_helper_dmt(t0, t0);
7988 gen_store_gpr(t0, rt);
7989 break;
7990 case OPC_EMT:
7991 check_insn(env, ctx, ASE_MT);
7992 gen_helper_emt(t0, t0);
7993 gen_store_gpr(t0, rt);
7994 break;
7995 case OPC_DVPE:
7996 check_insn(env, ctx, ASE_MT);
7997 gen_helper_dvpe(t0, t0);
7998 gen_store_gpr(t0, rt);
7999 break;
8000 case OPC_EVPE:
8001 check_insn(env, ctx, ASE_MT);
8002 gen_helper_evpe(t0, t0);
8003 gen_store_gpr(t0, rt);
8004 break;
8005 case OPC_DI:
8006 check_insn(env, ctx, ISA_MIPS32R2);
8007 save_cpu_state(ctx, 1);
8008 gen_helper_di(t0);
8009 gen_store_gpr(t0, rt);
8010 /* Stop translation as we may have switched the execution mode */
8011 ctx->bstate = BS_STOP;
8012 break;
8013 case OPC_EI:
8014 check_insn(env, ctx, ISA_MIPS32R2);
8015 save_cpu_state(ctx, 1);
8016 gen_helper_ei(t0);
8017 gen_store_gpr(t0, rt);
8018 /* Stop translation as we may have switched the execution mode */
8019 ctx->bstate = BS_STOP;
8020 break;
8021 default: /* Invalid */
8022 MIPS_INVAL("mfmc0");
8023 generate_exception(ctx, EXCP_RI);
8024 break;
8025 }
8026 tcg_temp_free(t0);
8027 }
8028 #endif /* !CONFIG_USER_ONLY */
8029 break;
8030 case OPC_RDPGPR:
8031 check_insn(env, ctx, ISA_MIPS32R2);
8032 gen_load_srsgpr(rt, rd);
8033 break;
8034 case OPC_WRPGPR:
8035 check_insn(env, ctx, ISA_MIPS32R2);
8036 gen_store_srsgpr(rt, rd);
8037 break;
8038 default:
8039 MIPS_INVAL("cp0");
8040 generate_exception(ctx, EXCP_RI);
8041 break;
8042 }
8043 break;
8044 case OPC_ADDI: /* Arithmetic with immediate opcode */
8045 case OPC_ADDIU:
8046 gen_arith_imm(env, ctx, op, rt, rs, imm);
8047 break;
8048 case OPC_SLTI: /* Set on less than with immediate opcode */
8049 case OPC_SLTIU:
8050 gen_slt_imm(env, op, rt, rs, imm);
8051 break;
8052 case OPC_ANDI: /* Arithmetic with immediate opcode */
8053 case OPC_LUI:
8054 case OPC_ORI:
8055 case OPC_XORI:
8056 gen_logic_imm(env, op, rt, rs, imm);
8057 break;
8058 case OPC_J ... OPC_JAL: /* Jump */
8059 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8060 gen_compute_branch(ctx, op, rs, rt, offset);
8061 return;
8062 case OPC_BEQ ... OPC_BGTZ: /* Branch */
8063 case OPC_BEQL ... OPC_BGTZL:
8064 gen_compute_branch(ctx, op, rs, rt, imm << 2);
8065 return;
8066 case OPC_LB ... OPC_LWR: /* Load and stores */
8067 case OPC_SB ... OPC_SW:
8068 case OPC_SWR:
8069 case OPC_LL:
8070 gen_ldst(ctx, op, rt, rs, imm);
8071 break;
8072 case OPC_SC:
8073 gen_st_cond(ctx, op, rt, rs, imm);
8074 break;
8075 case OPC_CACHE:
8076 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8077 /* Treat as NOP. */
8078 break;
8079 case OPC_PREF:
8080 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8081 /* Treat as NOP. */
8082 break;
8083
8084 /* Floating point (COP1). */
8085 case OPC_LWC1:
8086 case OPC_LDC1:
8087 case OPC_SWC1:
8088 case OPC_SDC1:
8089 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8090 check_cp1_enabled(ctx);
8091 gen_flt_ldst(ctx, op, rt, rs, imm);
8092 } else {
8093 generate_exception_err(ctx, EXCP_CpU, 1);
8094 }
8095 break;
8096
8097 case OPC_CP1:
8098 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8099 check_cp1_enabled(ctx);
8100 op1 = MASK_CP1(ctx->opcode);
8101 switch (op1) {
8102 case OPC_MFHC1:
8103 case OPC_MTHC1:
8104 check_insn(env, ctx, ISA_MIPS32R2);
8105 case OPC_MFC1:
8106 case OPC_CFC1:
8107 case OPC_MTC1:
8108 case OPC_CTC1:
8109 gen_cp1(ctx, op1, rt, rd);
8110 break;
8111 #if defined(TARGET_MIPS64)
8112 case OPC_DMFC1:
8113 case OPC_DMTC1:
8114 check_insn(env, ctx, ISA_MIPS3);
8115 gen_cp1(ctx, op1, rt, rd);
8116 break;
8117 #endif
8118 case OPC_BC1ANY2:
8119 case OPC_BC1ANY4:
8120 check_cop1x(ctx);
8121 check_insn(env, ctx, ASE_MIPS3D);
8122 /* fall through */
8123 case OPC_BC1:
8124 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8125 (rt >> 2) & 0x7, imm << 2);
8126 return;
8127 case OPC_S_FMT:
8128 case OPC_D_FMT:
8129 case OPC_W_FMT:
8130 case OPC_L_FMT:
8131 case OPC_PS_FMT:
8132 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8133 (imm >> 8) & 0x7);
8134 break;
8135 default:
8136 MIPS_INVAL("cp1");
8137 generate_exception (ctx, EXCP_RI);
8138 break;
8139 }
8140 } else {
8141 generate_exception_err(ctx, EXCP_CpU, 1);
8142 }
8143 break;
8144
8145 /* COP2. */
8146 case OPC_LWC2:
8147 case OPC_LDC2:
8148 case OPC_SWC2:
8149 case OPC_SDC2:
8150 case OPC_CP2:
8151 /* COP2: Not implemented. */
8152 generate_exception_err(ctx, EXCP_CpU, 2);
8153 break;
8154
8155 case OPC_CP3:
8156 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8157 check_cp1_enabled(ctx);
8158 op1 = MASK_CP3(ctx->opcode);
8159 switch (op1) {
8160 case OPC_LWXC1:
8161 case OPC_LDXC1:
8162 case OPC_LUXC1:
8163 case OPC_SWXC1:
8164 case OPC_SDXC1:
8165 case OPC_SUXC1:
8166 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8167 break;
8168 case OPC_PREFX:
8169 /* Treat as NOP. */
8170 break;
8171 case OPC_ALNV_PS:
8172 case OPC_MADD_S:
8173 case OPC_MADD_D:
8174 case OPC_MADD_PS:
8175 case OPC_MSUB_S:
8176 case OPC_MSUB_D:
8177 case OPC_MSUB_PS:
8178 case OPC_NMADD_S:
8179 case OPC_NMADD_D:
8180 case OPC_NMADD_PS:
8181 case OPC_NMSUB_S:
8182 case OPC_NMSUB_D:
8183 case OPC_NMSUB_PS:
8184 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8185 break;
8186 default:
8187 MIPS_INVAL("cp3");
8188 generate_exception (ctx, EXCP_RI);
8189 break;
8190 }
8191 } else {
8192 generate_exception_err(ctx, EXCP_CpU, 1);
8193 }
8194 break;
8195
8196 #if defined(TARGET_MIPS64)
8197 /* MIPS64 opcodes */
8198 case OPC_LWU:
8199 case OPC_LDL ... OPC_LDR:
8200 case OPC_SDL ... OPC_SDR:
8201 case OPC_LLD:
8202 case OPC_LD:
8203 case OPC_SD:
8204 check_insn(env, ctx, ISA_MIPS3);
8205 check_mips_64(ctx);
8206 gen_ldst(ctx, op, rt, rs, imm);
8207 break;
8208 case OPC_SCD:
8209 check_insn(env, ctx, ISA_MIPS3);
8210 check_mips_64(ctx);
8211 gen_st_cond(ctx, op, rt, rs, imm);
8212 break;
8213 case OPC_DADDI:
8214 case OPC_DADDIU:
8215 check_insn(env, ctx, ISA_MIPS3);
8216 check_mips_64(ctx);
8217 gen_arith_imm(env, ctx, op, rt, rs, imm);
8218 break;
8219 #endif
8220 case OPC_JALX:
8221 check_insn(env, ctx, ASE_MIPS16);
8222 /* MIPS16: Not implemented. */
8223 case OPC_MDMX:
8224 check_insn(env, ctx, ASE_MDMX);
8225 /* MDMX: Not implemented. */
8226 default: /* Invalid */
8227 MIPS_INVAL("major opcode");
8228 generate_exception(ctx, EXCP_RI);
8229 break;
8230 }
8231 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8232 int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8233 /* Branches completion */
8234 ctx->hflags &= ~MIPS_HFLAG_BMASK;
8235 ctx->bstate = BS_BRANCH;
8236 save_cpu_state(ctx, 0);
8237 /* FIXME: Need to clear can_do_io. */
8238 switch (hflags) {
8239 case MIPS_HFLAG_B:
8240 /* unconditional branch */
8241 MIPS_DEBUG("unconditional branch");
8242 gen_goto_tb(ctx, 0, ctx->btarget);
8243 break;
8244 case MIPS_HFLAG_BL:
8245 /* blikely taken case */
8246 MIPS_DEBUG("blikely branch taken");
8247 gen_goto_tb(ctx, 0, ctx->btarget);
8248 break;
8249 case MIPS_HFLAG_BC:
8250 /* Conditional branch */
8251 MIPS_DEBUG("conditional branch");
8252 {
8253 int l1 = gen_new_label();
8254
8255 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8256 gen_goto_tb(ctx, 1, ctx->pc + 4);
8257 gen_set_label(l1);
8258 gen_goto_tb(ctx, 0, ctx->btarget);
8259 }
8260 break;
8261 case MIPS_HFLAG_BR:
8262 /* unconditional branch to register */
8263 MIPS_DEBUG("branch to register");
8264 tcg_gen_mov_tl(cpu_PC, btarget);
8265 if (ctx->singlestep_enabled) {
8266 save_cpu_state(ctx, 0);
8267 gen_helper_0i(raise_exception, EXCP_DEBUG);
8268 }
8269 tcg_gen_exit_tb(0);
8270 break;
8271 default:
8272 MIPS_DEBUG("unknown branch");
8273 break;
8274 }
8275 }
8276 }
8277
8278 static inline void
8279 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8280 int search_pc)
8281 {
8282 DisasContext ctx;
8283 target_ulong pc_start;
8284 uint16_t *gen_opc_end;
8285 CPUBreakpoint *bp;
8286 int j, lj = -1;
8287 int num_insns;
8288 int max_insns;
8289
8290 if (search_pc)
8291 qemu_log("search pc %d\n", search_pc);
8292
8293 pc_start = tb->pc;
8294 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
8295 ctx.pc = pc_start;
8296 ctx.saved_pc = -1;
8297 ctx.singlestep_enabled = env->singlestep_enabled;
8298 ctx.tb = tb;
8299 ctx.bstate = BS_NONE;
8300 /* Restore delay slot state from the tb context. */
8301 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8302 restore_cpu_state(env, &ctx);
8303 #ifdef CONFIG_USER_ONLY
8304 ctx.mem_idx = MIPS_HFLAG_UM;
8305 #else
8306 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8307 #endif
8308 num_insns = 0;
8309 max_insns = tb->cflags & CF_COUNT_MASK;
8310 if (max_insns == 0)
8311 max_insns = CF_COUNT_MASK;
8312 #ifdef DEBUG_DISAS
8313 qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8314 /* FIXME: This may print out stale hflags from env... */
8315 log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8316 #endif
8317 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8318 gen_icount_start();
8319 while (ctx.bstate == BS_NONE) {
8320 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
8321 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
8322 if (bp->pc == ctx.pc) {
8323 save_cpu_state(&ctx, 1);
8324 ctx.bstate = BS_BRANCH;
8325 gen_helper_0i(raise_exception, EXCP_DEBUG);
8326 /* Include the breakpoint location or the tb won't
8327 * be flushed when it must be. */
8328 ctx.pc += 4;
8329 goto done_generating;
8330 }
8331 }
8332 }
8333
8334 if (search_pc) {
8335 j = gen_opc_ptr - gen_opc_buf;
8336 if (lj < j) {
8337 lj++;
8338 while (lj < j)
8339 gen_opc_instr_start[lj++] = 0;
8340 }
8341 gen_opc_pc[lj] = ctx.pc;
8342 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8343 gen_opc_instr_start[lj] = 1;
8344 gen_opc_icount[lj] = num_insns;
8345 }
8346 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8347 gen_io_start();
8348 ctx.opcode = ldl_code(ctx.pc);
8349 decode_opc(env, &ctx);
8350 ctx.pc += 4;
8351 num_insns++;
8352
8353 /* Execute a branch and its delay slot as a single instruction.
8354 This is what GDB expects and is consistent with what the
8355 hardware does (e.g. if a delay slot instruction faults, the
8356 reported PC is the PC of the branch). */
8357 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
8358 break;
8359
8360 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8361 break;
8362
8363 if (gen_opc_ptr >= gen_opc_end)
8364 break;
8365
8366 if (num_insns >= max_insns)
8367 break;
8368
8369 if (singlestep)
8370 break;
8371 }
8372 if (tb->cflags & CF_LAST_IO)
8373 gen_io_end();
8374 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
8375 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8376 gen_helper_0i(raise_exception, EXCP_DEBUG);
8377 } else {
8378 switch (ctx.bstate) {
8379 case BS_STOP:
8380 gen_helper_interrupt_restart();
8381 gen_goto_tb(&ctx, 0, ctx.pc);
8382 break;
8383 case BS_NONE:
8384 save_cpu_state(&ctx, 0);
8385 gen_goto_tb(&ctx, 0, ctx.pc);
8386 break;
8387 case BS_EXCP:
8388 gen_helper_interrupt_restart();
8389 tcg_gen_exit_tb(0);
8390 break;
8391 case BS_BRANCH:
8392 default:
8393 break;
8394 }
8395 }
8396 done_generating:
8397 gen_icount_end(tb, num_insns);
8398 *gen_opc_ptr = INDEX_op_end;
8399 if (search_pc) {
8400 j = gen_opc_ptr - gen_opc_buf;
8401 lj++;
8402 while (lj <= j)
8403 gen_opc_instr_start[lj++] = 0;
8404 } else {
8405 tb->size = ctx.pc - pc_start;
8406 tb->icount = num_insns;
8407 }
8408 #ifdef DEBUG_DISAS
8409 LOG_DISAS("\n");
8410 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8411 qemu_log("IN: %s\n", lookup_symbol(pc_start));
8412 log_target_disas(pc_start, ctx.pc - pc_start, 0);
8413 qemu_log("\n");
8414 }
8415 qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8416 #endif
8417 }
8418
8419 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8420 {
8421 gen_intermediate_code_internal(env, tb, 0);
8422 }
8423
8424 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8425 {
8426 gen_intermediate_code_internal(env, tb, 1);
8427 }
8428
8429 static void fpu_dump_state(CPUState *env, FILE *f,
8430 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8431 int flags)
8432 {
8433 int i;
8434 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8435
8436 #define printfpr(fp) \
8437 do { \
8438 if (is_fpu64) \
8439 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n", \
8440 (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd, \
8441 (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8442 else { \
8443 fpr_t tmp; \
8444 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
8445 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
8446 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n", \
8447 tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd, \
8448 tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]); \
8449 } \
8450 } while(0)
8451
8452
8453 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n",
8454 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8455 get_float_exception_flags(&env->active_fpu.fp_status));
8456 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8457 fpu_fprintf(f, "%3s: ", fregnames[i]);
8458 printfpr(&env->active_fpu.fpr[i]);
8459 }
8460
8461 #undef printfpr
8462 }
8463
8464 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8465 /* Debug help: The architecture requires 32bit code to maintain proper
8466 sign-extended values on 64bit machines. */
8467
8468 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8469
8470 static void
8471 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8472 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8473 int flags)
8474 {
8475 int i;
8476
8477 if (!SIGN_EXT_P(env->active_tc.PC))
8478 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8479 if (!SIGN_EXT_P(env->active_tc.HI[0]))
8480 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8481 if (!SIGN_EXT_P(env->active_tc.LO[0]))
8482 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8483 if (!SIGN_EXT_P(env->btarget))
8484 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8485
8486 for (i = 0; i < 32; i++) {
8487 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8488 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8489 }
8490
8491 if (!SIGN_EXT_P(env->CP0_EPC))
8492 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8493 if (!SIGN_EXT_P(env->lladdr))
8494 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
8495 }
8496 #endif
8497
8498 void cpu_dump_state (CPUState *env, FILE *f,
8499 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8500 int flags)
8501 {
8502 int i;
8503
8504 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
8505 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8506 env->hflags, env->btarget, env->bcond);
8507 for (i = 0; i < 32; i++) {
8508 if ((i & 3) == 0)
8509 cpu_fprintf(f, "GPR%02d:", i);
8510 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8511 if ((i & 3) == 3)
8512 cpu_fprintf(f, "\n");
8513 }
8514
8515 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
8516 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8517 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8518 env->CP0_Config0, env->CP0_Config1, env->lladdr);
8519 if (env->hflags & MIPS_HFLAG_FPU)
8520 fpu_dump_state(env, f, cpu_fprintf, flags);
8521 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8522 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8523 #endif
8524 }
8525
8526 static void mips_tcg_init(void)
8527 {
8528 int i;
8529 static int inited;
8530
8531 /* Initialize various static tables. */
8532 if (inited)
8533 return;
8534
8535 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8536 TCGV_UNUSED(cpu_gpr[0]);
8537 for (i = 1; i < 32; i++)
8538 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8539 offsetof(CPUState, active_tc.gpr[i]),
8540 regnames[i]);
8541 cpu_PC = tcg_global_mem_new(TCG_AREG0,
8542 offsetof(CPUState, active_tc.PC), "PC");
8543 for (i = 0; i < MIPS_DSP_ACC; i++) {
8544 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8545 offsetof(CPUState, active_tc.HI[i]),
8546 regnames_HI[i]);
8547 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8548 offsetof(CPUState, active_tc.LO[i]),
8549 regnames_LO[i]);
8550 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8551 offsetof(CPUState, active_tc.ACX[i]),
8552 regnames_ACX[i]);
8553 }
8554 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8555 offsetof(CPUState, active_tc.DSPControl),
8556 "DSPControl");
8557 bcond = tcg_global_mem_new(TCG_AREG0,
8558 offsetof(CPUState, bcond), "bcond");
8559 btarget = tcg_global_mem_new(TCG_AREG0,
8560 offsetof(CPUState, btarget), "btarget");
8561 hflags = tcg_global_mem_new_i32(TCG_AREG0,
8562 offsetof(CPUState, hflags), "hflags");
8563
8564 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8565 offsetof(CPUState, active_fpu.fcr0),
8566 "fcr0");
8567 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8568 offsetof(CPUState, active_fpu.fcr31),
8569 "fcr31");
8570
8571 /* register helpers */
8572 #define GEN_HELPER 2
8573 #include "helper.h"
8574
8575 inited = 1;
8576 }
8577
8578 #include "translate_init.c"
8579
8580 CPUMIPSState *cpu_mips_init (const char *cpu_model)
8581 {
8582 CPUMIPSState *env;
8583 const mips_def_t *def;
8584
8585 def = cpu_mips_find_by_name(cpu_model);
8586 if (!def)
8587 return NULL;
8588 env = qemu_mallocz(sizeof(CPUMIPSState));
8589 env->cpu_model = def;
8590 env->cpu_model_str = cpu_model;
8591
8592 cpu_exec_init(env);
8593 #ifndef CONFIG_USER_ONLY
8594 mmu_init(env, def);
8595 #endif
8596 fpu_init(env, def);
8597 mvp_init(env, def);
8598 mips_tcg_init();
8599 cpu_reset(env);
8600 qemu_init_vcpu(env);
8601 return env;
8602 }
8603
8604 void cpu_reset (CPUMIPSState *env)
8605 {
8606 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8607 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8608 log_cpu_state(env, 0);
8609 }
8610
8611 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8612 tlb_flush(env, 1);
8613
8614 /* Reset registers to their default values */
8615 env->CP0_PRid = env->cpu_model->CP0_PRid;
8616 env->CP0_Config0 = env->cpu_model->CP0_Config0;
8617 #ifdef TARGET_WORDS_BIGENDIAN
8618 env->CP0_Config0 |= (1 << CP0C0_BE);
8619 #endif
8620 env->CP0_Config1 = env->cpu_model->CP0_Config1;
8621 env->CP0_Config2 = env->cpu_model->CP0_Config2;
8622 env->CP0_Config3 = env->cpu_model->CP0_Config3;
8623 env->CP0_Config6 = env->cpu_model->CP0_Config6;
8624 env->CP0_Config7 = env->cpu_model->CP0_Config7;
8625 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
8626 << env->cpu_model->CP0_LLAddr_shift;
8627 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
8628 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
8629 env->CCRes = env->cpu_model->CCRes;
8630 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
8631 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
8632 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
8633 env->current_tc = 0;
8634 env->SEGBITS = env->cpu_model->SEGBITS;
8635 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
8636 #if defined(TARGET_MIPS64)
8637 if (env->cpu_model->insn_flags & ISA_MIPS3) {
8638 env->SEGMask |= 3ULL << 62;
8639 }
8640 #endif
8641 env->PABITS = env->cpu_model->PABITS;
8642 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
8643 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
8644 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
8645 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
8646 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
8647 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
8648 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
8649 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
8650 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
8651 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
8652 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
8653 env->insn_flags = env->cpu_model->insn_flags;
8654
8655 #if defined(CONFIG_USER_ONLY)
8656 env->hflags = MIPS_HFLAG_UM;
8657 /* Enable access to the SYNCI_Step register. */
8658 env->CP0_HWREna |= (1 << 1);
8659 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8660 env->hflags |= MIPS_HFLAG_FPU;
8661 }
8662 #ifdef TARGET_MIPS64
8663 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
8664 env->hflags |= MIPS_HFLAG_F64;
8665 }
8666 #endif
8667 #else
8668 if (env->hflags & MIPS_HFLAG_BMASK) {
8669 /* If the exception was raised from a delay slot,
8670 come back to the jump. */
8671 env->CP0_ErrorEPC = env->active_tc.PC - 4;
8672 } else {
8673 env->CP0_ErrorEPC = env->active_tc.PC;
8674 }
8675 env->active_tc.PC = (int32_t)0xBFC00000;
8676 env->CP0_Random = env->tlb->nb_tlb - 1;
8677 env->tlb->tlb_in_use = env->tlb->nb_tlb;
8678 env->CP0_Wired = 0;
8679 /* SMP not implemented */
8680 env->CP0_EBase = 0x80000000;
8681 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8682 /* vectored interrupts not implemented, timer on int 7,
8683 no performance counters. */
8684 env->CP0_IntCtl = 0xe0000000;
8685 {
8686 int i;
8687
8688 for (i = 0; i < 7; i++) {
8689 env->CP0_WatchLo[i] = 0;
8690 env->CP0_WatchHi[i] = 0x80000000;
8691 }
8692 env->CP0_WatchLo[7] = 0;
8693 env->CP0_WatchHi[7] = 0;
8694 }
8695 /* Count register increments in debug mode, EJTAG version 1 */
8696 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8697 env->hflags = MIPS_HFLAG_CP0;
8698 #endif
8699 #if defined(TARGET_MIPS64)
8700 if (env->cpu_model->insn_flags & ISA_MIPS3) {
8701 env->hflags |= MIPS_HFLAG_64;
8702 }
8703 #endif
8704 env->exception_index = EXCP_NONE;
8705 }
8706
8707 void gen_pc_load(CPUState *env, TranslationBlock *tb,
8708 unsigned long searched_pc, int pc_pos, void *puc)
8709 {
8710 env->active_tc.PC = gen_opc_pc[pc_pos];
8711 env->hflags &= ~MIPS_HFLAG_BMASK;
8712 env->hflags |= gen_opc_hflags[pc_pos];
8713 }