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