qemu:virtio-net: Check return size on the correct sg list (Alex Williamson)
[sniper_test.git] / target-mips / translate.c
blob8dc7976518fa04c2b9ea0e68614752d82f97f936
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_nor_tl(t0, t0, t1);
1617 opn = "nor";
1618 break;
1619 case OPC_OR:
1620 tcg_gen_or_tl(t0, t0, t1);
1621 opn = "or";
1622 break;
1623 case OPC_XOR:
1624 tcg_gen_xor_tl(t0, t0, t1);
1625 opn = "xor";
1626 break;
1627 case OPC_MUL:
1628 tcg_gen_mul_tl(t0, t0, t1);
1629 tcg_gen_ext32s_tl(t0, t0);
1630 opn = "mul";
1631 break;
1632 case OPC_MOVN:
1634 int l1 = gen_new_label();
1636 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1637 gen_store_gpr(t0, rd);
1638 gen_set_label(l1);
1640 opn = "movn";
1641 goto print;
1642 case OPC_MOVZ:
1644 int l1 = gen_new_label();
1646 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1647 gen_store_gpr(t0, rd);
1648 gen_set_label(l1);
1650 opn = "movz";
1651 goto print;
1652 case OPC_SLLV:
1653 tcg_gen_andi_tl(t0, t0, 0x1f);
1654 tcg_gen_shl_tl(t0, t1, t0);
1655 tcg_gen_ext32s_tl(t0, t0);
1656 opn = "sllv";
1657 break;
1658 case OPC_SRAV:
1659 tcg_gen_ext32s_tl(t1, t1);
1660 tcg_gen_andi_tl(t0, t0, 0x1f);
1661 tcg_gen_sar_tl(t0, t1, t0);
1662 opn = "srav";
1663 break;
1664 case OPC_SRLV:
1665 switch ((ctx->opcode >> 6) & 0x1f) {
1666 case 0:
1667 tcg_gen_ext32u_tl(t1, t1);
1668 tcg_gen_andi_tl(t0, t0, 0x1f);
1669 tcg_gen_shr_tl(t0, t1, t0);
1670 tcg_gen_ext32s_tl(t0, t0);
1671 opn = "srlv";
1672 break;
1673 case 1:
1674 /* rotrv is decoded as srlv on non-R2 CPUs */
1675 if (env->insn_flags & ISA_MIPS32R2) {
1676 int l1 = gen_new_label();
1677 int l2 = gen_new_label();
1679 tcg_gen_andi_tl(t0, t0, 0x1f);
1680 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1682 TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1683 TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1685 tcg_gen_trunc_tl_i32(r_tmp1, t0);
1686 tcg_gen_trunc_tl_i32(r_tmp2, t1);
1687 tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
1688 tcg_temp_free_i32(r_tmp1);
1689 tcg_temp_free_i32(r_tmp2);
1690 tcg_gen_br(l2);
1692 gen_set_label(l1);
1693 tcg_gen_mov_tl(t0, t1);
1694 gen_set_label(l2);
1695 opn = "rotrv";
1696 } else {
1697 tcg_gen_ext32u_tl(t1, t1);
1698 tcg_gen_andi_tl(t0, t0, 0x1f);
1699 tcg_gen_shr_tl(t0, t1, t0);
1700 tcg_gen_ext32s_tl(t0, t0);
1701 opn = "srlv";
1703 break;
1704 default:
1705 MIPS_INVAL("invalid srlv flag");
1706 generate_exception(ctx, EXCP_RI);
1707 break;
1709 break;
1710 #if defined(TARGET_MIPS64)
1711 case OPC_DSLLV:
1712 tcg_gen_andi_tl(t0, t0, 0x3f);
1713 tcg_gen_shl_tl(t0, t1, t0);
1714 opn = "dsllv";
1715 break;
1716 case OPC_DSRAV:
1717 tcg_gen_andi_tl(t0, t0, 0x3f);
1718 tcg_gen_sar_tl(t0, t1, t0);
1719 opn = "dsrav";
1720 break;
1721 case OPC_DSRLV:
1722 switch ((ctx->opcode >> 6) & 0x1f) {
1723 case 0:
1724 tcg_gen_andi_tl(t0, t0, 0x3f);
1725 tcg_gen_shr_tl(t0, t1, t0);
1726 opn = "dsrlv";
1727 break;
1728 case 1:
1729 /* drotrv is decoded as dsrlv on non-R2 CPUs */
1730 if (env->insn_flags & ISA_MIPS32R2) {
1731 int l1 = gen_new_label();
1732 int l2 = gen_new_label();
1734 tcg_gen_andi_tl(t0, t0, 0x3f);
1735 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1737 tcg_gen_rotr_tl(t0, t1, t0);
1738 tcg_gen_br(l2);
1740 gen_set_label(l1);
1741 tcg_gen_mov_tl(t0, t1);
1742 gen_set_label(l2);
1743 opn = "drotrv";
1744 } else {
1745 tcg_gen_andi_tl(t0, t0, 0x3f);
1746 tcg_gen_shr_tl(t0, t1, t0);
1747 opn = "dsrlv";
1749 break;
1750 default:
1751 MIPS_INVAL("invalid dsrlv flag");
1752 generate_exception(ctx, EXCP_RI);
1753 break;
1755 break;
1756 #endif
1757 default:
1758 MIPS_INVAL(opn);
1759 generate_exception(ctx, EXCP_RI);
1760 goto out;
1762 gen_store_gpr(t0, rd);
1763 print:
1764 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1765 out:
1766 tcg_temp_free(t0);
1767 tcg_temp_free(t1);
1770 /* Arithmetic on HI/LO registers */
1771 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1773 const char *opn = "hilo";
1775 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1776 /* Treat as NOP. */
1777 MIPS_DEBUG("NOP");
1778 return;
1780 switch (opc) {
1781 case OPC_MFHI:
1782 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1783 opn = "mfhi";
1784 break;
1785 case OPC_MFLO:
1786 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1787 opn = "mflo";
1788 break;
1789 case OPC_MTHI:
1790 if (reg != 0)
1791 tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1792 else
1793 tcg_gen_movi_tl(cpu_HI[0], 0);
1794 opn = "mthi";
1795 break;
1796 case OPC_MTLO:
1797 if (reg != 0)
1798 tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
1799 else
1800 tcg_gen_movi_tl(cpu_LO[0], 0);
1801 opn = "mtlo";
1802 break;
1803 default:
1804 MIPS_INVAL(opn);
1805 generate_exception(ctx, EXCP_RI);
1806 return;
1808 MIPS_DEBUG("%s %s", opn, regnames[reg]);
1811 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1812 int rs, int rt)
1814 const char *opn = "mul/div";
1815 TCGv t0 = tcg_temp_local_new();
1816 TCGv t1 = tcg_temp_local_new();
1818 gen_load_gpr(t0, rs);
1819 gen_load_gpr(t1, rt);
1820 switch (opc) {
1821 case OPC_DIV:
1823 int l1 = gen_new_label();
1825 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1827 int l2 = gen_new_label();
1828 TCGv_i32 r_tmp1 = tcg_temp_local_new_i32();
1829 TCGv_i32 r_tmp2 = tcg_temp_local_new_i32();
1830 TCGv_i32 r_tmp3 = tcg_temp_local_new_i32();
1832 tcg_gen_trunc_tl_i32(r_tmp1, t0);
1833 tcg_gen_trunc_tl_i32(r_tmp2, t1);
1834 tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp1, -1 << 31, l2);
1835 tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp2, -1, l2);
1836 tcg_gen_ext32s_tl(cpu_LO[0], t0);
1837 tcg_gen_movi_tl(cpu_HI[0], 0);
1838 tcg_gen_br(l1);
1839 gen_set_label(l2);
1840 tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
1841 tcg_gen_rem_i32(r_tmp2, r_tmp1, r_tmp2);
1842 tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1843 tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp2);
1844 tcg_temp_free_i32(r_tmp1);
1845 tcg_temp_free_i32(r_tmp2);
1846 tcg_temp_free_i32(r_tmp3);
1848 gen_set_label(l1);
1850 opn = "div";
1851 break;
1852 case OPC_DIVU:
1854 int l1 = gen_new_label();
1856 tcg_gen_ext32s_tl(t1, t1);
1857 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1859 TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1860 TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1861 TCGv_i32 r_tmp3 = tcg_temp_new_i32();
1863 tcg_gen_trunc_tl_i32(r_tmp1, t0);
1864 tcg_gen_trunc_tl_i32(r_tmp2, t1);
1865 tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
1866 tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
1867 tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
1868 tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp1);
1869 tcg_temp_free_i32(r_tmp1);
1870 tcg_temp_free_i32(r_tmp2);
1871 tcg_temp_free_i32(r_tmp3);
1873 gen_set_label(l1);
1875 opn = "divu";
1876 break;
1877 case OPC_MULT:
1879 TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1880 TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1882 tcg_gen_ext_tl_i64(r_tmp1, t0);
1883 tcg_gen_ext_tl_i64(r_tmp2, t1);
1884 tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1885 tcg_temp_free_i64(r_tmp2);
1886 tcg_gen_trunc_i64_tl(t0, r_tmp1);
1887 tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1888 tcg_gen_trunc_i64_tl(t1, r_tmp1);
1889 tcg_temp_free_i64(r_tmp1);
1890 tcg_gen_ext32s_tl(cpu_LO[0], t0);
1891 tcg_gen_ext32s_tl(cpu_HI[0], t1);
1893 opn = "mult";
1894 break;
1895 case OPC_MULTU:
1897 TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1898 TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1900 tcg_gen_ext32u_tl(t0, t0);
1901 tcg_gen_ext32u_tl(t1, t1);
1902 tcg_gen_extu_tl_i64(r_tmp1, t0);
1903 tcg_gen_extu_tl_i64(r_tmp2, t1);
1904 tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1905 tcg_temp_free_i64(r_tmp2);
1906 tcg_gen_trunc_i64_tl(t0, r_tmp1);
1907 tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1908 tcg_gen_trunc_i64_tl(t1, r_tmp1);
1909 tcg_temp_free_i64(r_tmp1);
1910 tcg_gen_ext32s_tl(cpu_LO[0], t0);
1911 tcg_gen_ext32s_tl(cpu_HI[0], t1);
1913 opn = "multu";
1914 break;
1915 #if defined(TARGET_MIPS64)
1916 case OPC_DDIV:
1918 int l1 = gen_new_label();
1920 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1922 int l2 = gen_new_label();
1924 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
1925 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
1926 tcg_gen_mov_tl(cpu_LO[0], t0);
1927 tcg_gen_movi_tl(cpu_HI[0], 0);
1928 tcg_gen_br(l1);
1929 gen_set_label(l2);
1930 tcg_gen_div_i64(cpu_LO[0], t0, t1);
1931 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1933 gen_set_label(l1);
1935 opn = "ddiv";
1936 break;
1937 case OPC_DDIVU:
1939 int l1 = gen_new_label();
1941 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1942 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
1943 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
1944 gen_set_label(l1);
1946 opn = "ddivu";
1947 break;
1948 case OPC_DMULT:
1949 gen_helper_dmult(t0, t1);
1950 opn = "dmult";
1951 break;
1952 case OPC_DMULTU:
1953 gen_helper_dmultu(t0, t1);
1954 opn = "dmultu";
1955 break;
1956 #endif
1957 case OPC_MADD:
1959 TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1960 TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1962 tcg_gen_ext_tl_i64(r_tmp1, t0);
1963 tcg_gen_ext_tl_i64(r_tmp2, t1);
1964 tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1965 tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1966 tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1967 tcg_temp_free_i64(r_tmp2);
1968 tcg_gen_trunc_i64_tl(t0, r_tmp1);
1969 tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1970 tcg_gen_trunc_i64_tl(t1, r_tmp1);
1971 tcg_temp_free_i64(r_tmp1);
1972 tcg_gen_ext32s_tl(cpu_LO[0], t0);
1973 tcg_gen_ext32s_tl(cpu_LO[1], t1);
1975 opn = "madd";
1976 break;
1977 case OPC_MADDU:
1979 TCGv_i64 r_tmp1 = tcg_temp_new_i64();
1980 TCGv_i64 r_tmp2 = tcg_temp_new_i64();
1982 tcg_gen_ext32u_tl(t0, t0);
1983 tcg_gen_ext32u_tl(t1, t1);
1984 tcg_gen_extu_tl_i64(r_tmp1, t0);
1985 tcg_gen_extu_tl_i64(r_tmp2, t1);
1986 tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
1987 tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
1988 tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
1989 tcg_temp_free_i64(r_tmp2);
1990 tcg_gen_trunc_i64_tl(t0, r_tmp1);
1991 tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
1992 tcg_gen_trunc_i64_tl(t1, r_tmp1);
1993 tcg_temp_free_i64(r_tmp1);
1994 tcg_gen_ext32s_tl(cpu_LO[0], t0);
1995 tcg_gen_ext32s_tl(cpu_HI[0], t1);
1997 opn = "maddu";
1998 break;
1999 case OPC_MSUB:
2001 TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2002 TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2004 tcg_gen_ext_tl_i64(r_tmp1, t0);
2005 tcg_gen_ext_tl_i64(r_tmp2, t1);
2006 tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2007 tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2008 tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2009 tcg_temp_free_i64(r_tmp2);
2010 tcg_gen_trunc_i64_tl(t0, r_tmp1);
2011 tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2012 tcg_gen_trunc_i64_tl(t1, r_tmp1);
2013 tcg_temp_free_i64(r_tmp1);
2014 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2015 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2017 opn = "msub";
2018 break;
2019 case OPC_MSUBU:
2021 TCGv_i64 r_tmp1 = tcg_temp_new_i64();
2022 TCGv_i64 r_tmp2 = tcg_temp_new_i64();
2024 tcg_gen_ext32u_tl(t0, t0);
2025 tcg_gen_ext32u_tl(t1, t1);
2026 tcg_gen_extu_tl_i64(r_tmp1, t0);
2027 tcg_gen_extu_tl_i64(r_tmp2, t1);
2028 tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
2029 tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
2030 tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
2031 tcg_temp_free_i64(r_tmp2);
2032 tcg_gen_trunc_i64_tl(t0, r_tmp1);
2033 tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
2034 tcg_gen_trunc_i64_tl(t1, r_tmp1);
2035 tcg_temp_free_i64(r_tmp1);
2036 tcg_gen_ext32s_tl(cpu_LO[0], t0);
2037 tcg_gen_ext32s_tl(cpu_HI[0], t1);
2039 opn = "msubu";
2040 break;
2041 default:
2042 MIPS_INVAL(opn);
2043 generate_exception(ctx, EXCP_RI);
2044 goto out;
2046 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2047 out:
2048 tcg_temp_free(t0);
2049 tcg_temp_free(t1);
2052 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2053 int rd, int rs, int rt)
2055 const char *opn = "mul vr54xx";
2056 TCGv t0 = tcg_temp_local_new();
2057 TCGv t1 = tcg_temp_local_new();
2059 gen_load_gpr(t0, rs);
2060 gen_load_gpr(t1, rt);
2062 switch (opc) {
2063 case OPC_VR54XX_MULS:
2064 gen_helper_muls(t0, t0, t1);
2065 opn = "muls";
2066 break;
2067 case OPC_VR54XX_MULSU:
2068 gen_helper_mulsu(t0, t0, t1);
2069 opn = "mulsu";
2070 break;
2071 case OPC_VR54XX_MACC:
2072 gen_helper_macc(t0, t0, t1);
2073 opn = "macc";
2074 break;
2075 case OPC_VR54XX_MACCU:
2076 gen_helper_maccu(t0, t0, t1);
2077 opn = "maccu";
2078 break;
2079 case OPC_VR54XX_MSAC:
2080 gen_helper_msac(t0, t0, t1);
2081 opn = "msac";
2082 break;
2083 case OPC_VR54XX_MSACU:
2084 gen_helper_msacu(t0, t0, t1);
2085 opn = "msacu";
2086 break;
2087 case OPC_VR54XX_MULHI:
2088 gen_helper_mulhi(t0, t0, t1);
2089 opn = "mulhi";
2090 break;
2091 case OPC_VR54XX_MULHIU:
2092 gen_helper_mulhiu(t0, t0, t1);
2093 opn = "mulhiu";
2094 break;
2095 case OPC_VR54XX_MULSHI:
2096 gen_helper_mulshi(t0, t0, t1);
2097 opn = "mulshi";
2098 break;
2099 case OPC_VR54XX_MULSHIU:
2100 gen_helper_mulshiu(t0, t0, t1);
2101 opn = "mulshiu";
2102 break;
2103 case OPC_VR54XX_MACCHI:
2104 gen_helper_macchi(t0, t0, t1);
2105 opn = "macchi";
2106 break;
2107 case OPC_VR54XX_MACCHIU:
2108 gen_helper_macchiu(t0, t0, t1);
2109 opn = "macchiu";
2110 break;
2111 case OPC_VR54XX_MSACHI:
2112 gen_helper_msachi(t0, t0, t1);
2113 opn = "msachi";
2114 break;
2115 case OPC_VR54XX_MSACHIU:
2116 gen_helper_msachiu(t0, t0, t1);
2117 opn = "msachiu";
2118 break;
2119 default:
2120 MIPS_INVAL("mul vr54xx");
2121 generate_exception(ctx, EXCP_RI);
2122 goto out;
2124 gen_store_gpr(t0, rd);
2125 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2127 out:
2128 tcg_temp_free(t0);
2129 tcg_temp_free(t1);
2132 static void gen_cl (DisasContext *ctx, uint32_t opc,
2133 int rd, int rs)
2135 const char *opn = "CLx";
2136 TCGv t0 = tcg_temp_local_new();
2138 if (rd == 0) {
2139 /* Treat as NOP. */
2140 MIPS_DEBUG("NOP");
2141 goto out;
2143 gen_load_gpr(t0, rs);
2144 switch (opc) {
2145 case OPC_CLO:
2146 gen_helper_clo(t0, t0);
2147 opn = "clo";
2148 break;
2149 case OPC_CLZ:
2150 gen_helper_clz(t0, t0);
2151 opn = "clz";
2152 break;
2153 #if defined(TARGET_MIPS64)
2154 case OPC_DCLO:
2155 gen_helper_dclo(t0, t0);
2156 opn = "dclo";
2157 break;
2158 case OPC_DCLZ:
2159 gen_helper_dclz(t0, t0);
2160 opn = "dclz";
2161 break;
2162 #endif
2163 default:
2164 MIPS_INVAL(opn);
2165 generate_exception(ctx, EXCP_RI);
2166 goto out;
2168 gen_store_gpr(t0, rd);
2169 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2171 out:
2172 tcg_temp_free(t0);
2175 /* Traps */
2176 static void gen_trap (DisasContext *ctx, uint32_t opc,
2177 int rs, int rt, int16_t imm)
2179 int cond;
2180 TCGv t0 = tcg_temp_local_new();
2181 TCGv t1 = tcg_temp_local_new();
2183 cond = 0;
2184 /* Load needed operands */
2185 switch (opc) {
2186 case OPC_TEQ:
2187 case OPC_TGE:
2188 case OPC_TGEU:
2189 case OPC_TLT:
2190 case OPC_TLTU:
2191 case OPC_TNE:
2192 /* Compare two registers */
2193 if (rs != rt) {
2194 gen_load_gpr(t0, rs);
2195 gen_load_gpr(t1, rt);
2196 cond = 1;
2198 break;
2199 case OPC_TEQI:
2200 case OPC_TGEI:
2201 case OPC_TGEIU:
2202 case OPC_TLTI:
2203 case OPC_TLTIU:
2204 case OPC_TNEI:
2205 /* Compare register to immediate */
2206 if (rs != 0 || imm != 0) {
2207 gen_load_gpr(t0, rs);
2208 tcg_gen_movi_tl(t1, (int32_t)imm);
2209 cond = 1;
2211 break;
2213 if (cond == 0) {
2214 switch (opc) {
2215 case OPC_TEQ: /* rs == rs */
2216 case OPC_TEQI: /* r0 == 0 */
2217 case OPC_TGE: /* rs >= rs */
2218 case OPC_TGEI: /* r0 >= 0 */
2219 case OPC_TGEU: /* rs >= rs unsigned */
2220 case OPC_TGEIU: /* r0 >= 0 unsigned */
2221 /* Always trap */
2222 tcg_gen_movi_tl(t0, 1);
2223 break;
2224 case OPC_TLT: /* rs < rs */
2225 case OPC_TLTI: /* r0 < 0 */
2226 case OPC_TLTU: /* rs < rs unsigned */
2227 case OPC_TLTIU: /* r0 < 0 unsigned */
2228 case OPC_TNE: /* rs != rs */
2229 case OPC_TNEI: /* r0 != 0 */
2230 /* Never trap: treat as NOP. */
2231 goto out;
2232 default:
2233 MIPS_INVAL("trap");
2234 generate_exception(ctx, EXCP_RI);
2235 goto out;
2237 } else {
2238 switch (opc) {
2239 case OPC_TEQ:
2240 case OPC_TEQI:
2241 gen_op_eq(t0, t1);
2242 break;
2243 case OPC_TGE:
2244 case OPC_TGEI:
2245 gen_op_ge(t0, t1);
2246 break;
2247 case OPC_TGEU:
2248 case OPC_TGEIU:
2249 gen_op_geu(t0, t1);
2250 break;
2251 case OPC_TLT:
2252 case OPC_TLTI:
2253 gen_op_lt(t0, t1);
2254 break;
2255 case OPC_TLTU:
2256 case OPC_TLTIU:
2257 gen_op_ltu(t0, t1);
2258 break;
2259 case OPC_TNE:
2260 case OPC_TNEI:
2261 gen_op_ne(t0, t1);
2262 break;
2263 default:
2264 MIPS_INVAL("trap");
2265 generate_exception(ctx, EXCP_RI);
2266 goto out;
2269 save_cpu_state(ctx, 1);
2271 int l1 = gen_new_label();
2273 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
2274 gen_helper_0i(raise_exception, EXCP_TRAP);
2275 gen_set_label(l1);
2277 ctx->bstate = BS_STOP;
2278 out:
2279 tcg_temp_free(t0);
2280 tcg_temp_free(t1);
2283 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2285 TranslationBlock *tb;
2286 tb = ctx->tb;
2287 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2288 tcg_gen_goto_tb(n);
2289 gen_save_pc(dest);
2290 tcg_gen_exit_tb((long)tb + n);
2291 } else {
2292 gen_save_pc(dest);
2293 tcg_gen_exit_tb(0);
2297 /* Branches (before delay slot) */
2298 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2299 int rs, int rt, int32_t offset)
2301 target_ulong btgt = -1;
2302 int blink = 0;
2303 int bcond_compute = 0;
2304 TCGv t0 = tcg_temp_local_new();
2305 TCGv t1 = tcg_temp_local_new();
2307 if (ctx->hflags & MIPS_HFLAG_BMASK) {
2308 #ifdef MIPS_DEBUG_DISAS
2309 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2310 #endif
2311 generate_exception(ctx, EXCP_RI);
2312 goto out;
2315 /* Load needed operands */
2316 switch (opc) {
2317 case OPC_BEQ:
2318 case OPC_BEQL:
2319 case OPC_BNE:
2320 case OPC_BNEL:
2321 /* Compare two registers */
2322 if (rs != rt) {
2323 gen_load_gpr(t0, rs);
2324 gen_load_gpr(t1, rt);
2325 bcond_compute = 1;
2327 btgt = ctx->pc + 4 + offset;
2328 break;
2329 case OPC_BGEZ:
2330 case OPC_BGEZAL:
2331 case OPC_BGEZALL:
2332 case OPC_BGEZL:
2333 case OPC_BGTZ:
2334 case OPC_BGTZL:
2335 case OPC_BLEZ:
2336 case OPC_BLEZL:
2337 case OPC_BLTZ:
2338 case OPC_BLTZAL:
2339 case OPC_BLTZALL:
2340 case OPC_BLTZL:
2341 /* Compare to zero */
2342 if (rs != 0) {
2343 gen_load_gpr(t0, rs);
2344 bcond_compute = 1;
2346 btgt = ctx->pc + 4 + offset;
2347 break;
2348 case OPC_J:
2349 case OPC_JAL:
2350 /* Jump to immediate */
2351 btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2352 break;
2353 case OPC_JR:
2354 case OPC_JALR:
2355 /* Jump to register */
2356 if (offset != 0 && offset != 16) {
2357 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2358 others are reserved. */
2359 MIPS_INVAL("jump hint");
2360 generate_exception(ctx, EXCP_RI);
2361 goto out;
2363 gen_load_gpr(btarget, rs);
2364 break;
2365 default:
2366 MIPS_INVAL("branch/jump");
2367 generate_exception(ctx, EXCP_RI);
2368 goto out;
2370 if (bcond_compute == 0) {
2371 /* No condition to be computed */
2372 switch (opc) {
2373 case OPC_BEQ: /* rx == rx */
2374 case OPC_BEQL: /* rx == rx likely */
2375 case OPC_BGEZ: /* 0 >= 0 */
2376 case OPC_BGEZL: /* 0 >= 0 likely */
2377 case OPC_BLEZ: /* 0 <= 0 */
2378 case OPC_BLEZL: /* 0 <= 0 likely */
2379 /* Always take */
2380 ctx->hflags |= MIPS_HFLAG_B;
2381 MIPS_DEBUG("balways");
2382 break;
2383 case OPC_BGEZAL: /* 0 >= 0 */
2384 case OPC_BGEZALL: /* 0 >= 0 likely */
2385 /* Always take and link */
2386 blink = 31;
2387 ctx->hflags |= MIPS_HFLAG_B;
2388 MIPS_DEBUG("balways and link");
2389 break;
2390 case OPC_BNE: /* rx != rx */
2391 case OPC_BGTZ: /* 0 > 0 */
2392 case OPC_BLTZ: /* 0 < 0 */
2393 /* Treat as NOP. */
2394 MIPS_DEBUG("bnever (NOP)");
2395 goto out;
2396 case OPC_BLTZAL: /* 0 < 0 */
2397 tcg_gen_movi_tl(t0, ctx->pc + 8);
2398 gen_store_gpr(t0, 31);
2399 MIPS_DEBUG("bnever and link");
2400 goto out;
2401 case OPC_BLTZALL: /* 0 < 0 likely */
2402 tcg_gen_movi_tl(t0, ctx->pc + 8);
2403 gen_store_gpr(t0, 31);
2404 /* Skip the instruction in the delay slot */
2405 MIPS_DEBUG("bnever, link and skip");
2406 ctx->pc += 4;
2407 goto out;
2408 case OPC_BNEL: /* rx != rx likely */
2409 case OPC_BGTZL: /* 0 > 0 likely */
2410 case OPC_BLTZL: /* 0 < 0 likely */
2411 /* Skip the instruction in the delay slot */
2412 MIPS_DEBUG("bnever and skip");
2413 ctx->pc += 4;
2414 goto out;
2415 case OPC_J:
2416 ctx->hflags |= MIPS_HFLAG_B;
2417 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2418 break;
2419 case OPC_JAL:
2420 blink = 31;
2421 ctx->hflags |= MIPS_HFLAG_B;
2422 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2423 break;
2424 case OPC_JR:
2425 ctx->hflags |= MIPS_HFLAG_BR;
2426 MIPS_DEBUG("jr %s", regnames[rs]);
2427 break;
2428 case OPC_JALR:
2429 blink = rt;
2430 ctx->hflags |= MIPS_HFLAG_BR;
2431 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2432 break;
2433 default:
2434 MIPS_INVAL("branch/jump");
2435 generate_exception(ctx, EXCP_RI);
2436 goto out;
2438 } else {
2439 switch (opc) {
2440 case OPC_BEQ:
2441 gen_op_eq(t0, t1);
2442 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2443 regnames[rs], regnames[rt], btgt);
2444 goto not_likely;
2445 case OPC_BEQL:
2446 gen_op_eq(t0, t1);
2447 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2448 regnames[rs], regnames[rt], btgt);
2449 goto likely;
2450 case OPC_BNE:
2451 gen_op_ne(t0, t1);
2452 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2453 regnames[rs], regnames[rt], btgt);
2454 goto not_likely;
2455 case OPC_BNEL:
2456 gen_op_ne(t0, t1);
2457 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2458 regnames[rs], regnames[rt], btgt);
2459 goto likely;
2460 case OPC_BGEZ:
2461 gen_op_gez(t0);
2462 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2463 goto not_likely;
2464 case OPC_BGEZL:
2465 gen_op_gez(t0);
2466 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2467 goto likely;
2468 case OPC_BGEZAL:
2469 gen_op_gez(t0);
2470 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2471 blink = 31;
2472 goto not_likely;
2473 case OPC_BGEZALL:
2474 gen_op_gez(t0);
2475 blink = 31;
2476 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2477 goto likely;
2478 case OPC_BGTZ:
2479 gen_op_gtz(t0);
2480 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2481 goto not_likely;
2482 case OPC_BGTZL:
2483 gen_op_gtz(t0);
2484 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2485 goto likely;
2486 case OPC_BLEZ:
2487 gen_op_lez(t0);
2488 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2489 goto not_likely;
2490 case OPC_BLEZL:
2491 gen_op_lez(t0);
2492 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2493 goto likely;
2494 case OPC_BLTZ:
2495 gen_op_ltz(t0);
2496 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2497 goto not_likely;
2498 case OPC_BLTZL:
2499 gen_op_ltz(t0);
2500 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2501 goto likely;
2502 case OPC_BLTZAL:
2503 gen_op_ltz(t0);
2504 blink = 31;
2505 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2506 not_likely:
2507 ctx->hflags |= MIPS_HFLAG_BC;
2508 tcg_gen_trunc_tl_i32(bcond, t0);
2509 break;
2510 case OPC_BLTZALL:
2511 gen_op_ltz(t0);
2512 blink = 31;
2513 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2514 likely:
2515 ctx->hflags |= MIPS_HFLAG_BL;
2516 tcg_gen_trunc_tl_i32(bcond, t0);
2517 break;
2518 default:
2519 MIPS_INVAL("conditional branch/jump");
2520 generate_exception(ctx, EXCP_RI);
2521 goto out;
2524 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2525 blink, ctx->hflags, btgt);
2527 ctx->btarget = btgt;
2528 if (blink > 0) {
2529 tcg_gen_movi_tl(t0, ctx->pc + 8);
2530 gen_store_gpr(t0, blink);
2533 out:
2534 tcg_temp_free(t0);
2535 tcg_temp_free(t1);
2538 /* special3 bitfield operations */
2539 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2540 int rs, int lsb, int msb)
2542 TCGv t0 = tcg_temp_new();
2543 TCGv t1 = tcg_temp_new();
2544 target_ulong mask;
2546 gen_load_gpr(t1, rs);
2547 switch (opc) {
2548 case OPC_EXT:
2549 if (lsb + msb > 31)
2550 goto fail;
2551 tcg_gen_shri_tl(t0, t1, lsb);
2552 if (msb != 31) {
2553 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2554 } else {
2555 tcg_gen_ext32s_tl(t0, t0);
2557 break;
2558 #if defined(TARGET_MIPS64)
2559 case OPC_DEXTM:
2560 tcg_gen_shri_tl(t0, t1, lsb);
2561 if (msb != 31) {
2562 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2564 break;
2565 case OPC_DEXTU:
2566 tcg_gen_shri_tl(t0, t1, lsb + 32);
2567 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2568 break;
2569 case OPC_DEXT:
2570 tcg_gen_shri_tl(t0, t1, lsb);
2571 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2572 break;
2573 #endif
2574 case OPC_INS:
2575 if (lsb > msb)
2576 goto fail;
2577 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2578 gen_load_gpr(t0, rt);
2579 tcg_gen_andi_tl(t0, t0, ~mask);
2580 tcg_gen_shli_tl(t1, t1, lsb);
2581 tcg_gen_andi_tl(t1, t1, mask);
2582 tcg_gen_or_tl(t0, t0, t1);
2583 tcg_gen_ext32s_tl(t0, t0);
2584 break;
2585 #if defined(TARGET_MIPS64)
2586 case OPC_DINSM:
2587 if (lsb > msb)
2588 goto fail;
2589 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2590 gen_load_gpr(t0, rt);
2591 tcg_gen_andi_tl(t0, t0, ~mask);
2592 tcg_gen_shli_tl(t1, t1, lsb);
2593 tcg_gen_andi_tl(t1, t1, mask);
2594 tcg_gen_or_tl(t0, t0, t1);
2595 break;
2596 case OPC_DINSU:
2597 if (lsb > msb)
2598 goto fail;
2599 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2600 gen_load_gpr(t0, rt);
2601 tcg_gen_andi_tl(t0, t0, ~mask);
2602 tcg_gen_shli_tl(t1, t1, lsb + 32);
2603 tcg_gen_andi_tl(t1, t1, mask);
2604 tcg_gen_or_tl(t0, t0, t1);
2605 break;
2606 case OPC_DINS:
2607 if (lsb > msb)
2608 goto fail;
2609 gen_load_gpr(t0, rt);
2610 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2611 gen_load_gpr(t0, rt);
2612 tcg_gen_andi_tl(t0, t0, ~mask);
2613 tcg_gen_shli_tl(t1, t1, lsb);
2614 tcg_gen_andi_tl(t1, t1, mask);
2615 tcg_gen_or_tl(t0, t0, t1);
2616 break;
2617 #endif
2618 default:
2619 fail:
2620 MIPS_INVAL("bitops");
2621 generate_exception(ctx, EXCP_RI);
2622 tcg_temp_free(t0);
2623 tcg_temp_free(t1);
2624 return;
2626 gen_store_gpr(t0, rt);
2627 tcg_temp_free(t0);
2628 tcg_temp_free(t1);
2631 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2633 TCGv t0 = tcg_temp_new();
2634 TCGv t1 = tcg_temp_new();
2636 gen_load_gpr(t1, rt);
2637 switch (op2) {
2638 case OPC_WSBH:
2639 tcg_gen_shri_tl(t0, t1, 8);
2640 tcg_gen_andi_tl(t0, t0, 0x00FF00FF);
2641 tcg_gen_shli_tl(t1, t1, 8);
2642 tcg_gen_andi_tl(t1, t1, ~0x00FF00FF);
2643 tcg_gen_or_tl(t0, t0, t1);
2644 tcg_gen_ext32s_tl(t0, t0);
2645 break;
2646 case OPC_SEB:
2647 tcg_gen_ext8s_tl(t0, t1);
2648 break;
2649 case OPC_SEH:
2650 tcg_gen_ext16s_tl(t0, t1);
2651 break;
2652 #if defined(TARGET_MIPS64)
2653 case OPC_DSBH:
2654 gen_load_gpr(t1, rt);
2655 tcg_gen_shri_tl(t0, t1, 8);
2656 tcg_gen_andi_tl(t0, t0, 0x00FF00FF00FF00FFULL);
2657 tcg_gen_shli_tl(t1, t1, 8);
2658 tcg_gen_andi_tl(t1, t1, ~0x00FF00FF00FF00FFULL);
2659 tcg_gen_or_tl(t0, t0, t1);
2660 break;
2661 case OPC_DSHD:
2662 gen_load_gpr(t1, rt);
2663 tcg_gen_shri_tl(t0, t1, 16);
2664 tcg_gen_andi_tl(t0, t0, 0x0000FFFF0000FFFFULL);
2665 tcg_gen_shli_tl(t1, t1, 16);
2666 tcg_gen_andi_tl(t1, t1, ~0x0000FFFF0000FFFFULL);
2667 tcg_gen_or_tl(t1, t0, t1);
2668 tcg_gen_shri_tl(t0, t1, 32);
2669 tcg_gen_shli_tl(t1, t1, 32);
2670 tcg_gen_or_tl(t0, t0, t1);
2671 break;
2672 #endif
2673 default:
2674 MIPS_INVAL("bsfhl");
2675 generate_exception(ctx, EXCP_RI);
2676 tcg_temp_free(t0);
2677 tcg_temp_free(t1);
2678 return;
2680 gen_store_gpr(t0, rd);
2681 tcg_temp_free(t0);
2682 tcg_temp_free(t1);
2685 #ifndef CONFIG_USER_ONLY
2686 /* CP0 (MMU and control) */
2687 static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
2689 TCGv_i32 r_tmp = tcg_temp_new_i32();
2691 tcg_gen_ld_i32(r_tmp, cpu_env, off);
2692 tcg_gen_ext_i32_tl(t, r_tmp);
2693 tcg_temp_free_i32(r_tmp);
2696 static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
2698 tcg_gen_ld_tl(t, cpu_env, off);
2699 tcg_gen_ext32s_tl(t, t);
2702 static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
2704 TCGv_i32 r_tmp = tcg_temp_new_i32();
2706 tcg_gen_trunc_tl_i32(r_tmp, t);
2707 tcg_gen_st_i32(r_tmp, cpu_env, off);
2708 tcg_temp_free_i32(r_tmp);
2711 static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
2713 tcg_gen_ext32s_tl(t, t);
2714 tcg_gen_st_tl(t, cpu_env, off);
2717 static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
2719 const char *rn = "invalid";
2721 if (sel != 0)
2722 check_insn(env, ctx, ISA_MIPS32);
2724 switch (reg) {
2725 case 0:
2726 switch (sel) {
2727 case 0:
2728 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
2729 rn = "Index";
2730 break;
2731 case 1:
2732 check_insn(env, ctx, ASE_MT);
2733 gen_helper_mfc0_mvpcontrol(t0);
2734 rn = "MVPControl";
2735 break;
2736 case 2:
2737 check_insn(env, ctx, ASE_MT);
2738 gen_helper_mfc0_mvpconf0(t0);
2739 rn = "MVPConf0";
2740 break;
2741 case 3:
2742 check_insn(env, ctx, ASE_MT);
2743 gen_helper_mfc0_mvpconf1(t0);
2744 rn = "MVPConf1";
2745 break;
2746 default:
2747 goto die;
2749 break;
2750 case 1:
2751 switch (sel) {
2752 case 0:
2753 gen_helper_mfc0_random(t0);
2754 rn = "Random";
2755 break;
2756 case 1:
2757 check_insn(env, ctx, ASE_MT);
2758 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
2759 rn = "VPEControl";
2760 break;
2761 case 2:
2762 check_insn(env, ctx, ASE_MT);
2763 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
2764 rn = "VPEConf0";
2765 break;
2766 case 3:
2767 check_insn(env, ctx, ASE_MT);
2768 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
2769 rn = "VPEConf1";
2770 break;
2771 case 4:
2772 check_insn(env, ctx, ASE_MT);
2773 gen_mfc0_load64(t0, offsetof(CPUState, CP0_YQMask));
2774 rn = "YQMask";
2775 break;
2776 case 5:
2777 check_insn(env, ctx, ASE_MT);
2778 gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPESchedule));
2779 rn = "VPESchedule";
2780 break;
2781 case 6:
2782 check_insn(env, ctx, ASE_MT);
2783 gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPEScheFBack));
2784 rn = "VPEScheFBack";
2785 break;
2786 case 7:
2787 check_insn(env, ctx, ASE_MT);
2788 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
2789 rn = "VPEOpt";
2790 break;
2791 default:
2792 goto die;
2794 break;
2795 case 2:
2796 switch (sel) {
2797 case 0:
2798 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2799 tcg_gen_ext32s_tl(t0, t0);
2800 rn = "EntryLo0";
2801 break;
2802 case 1:
2803 check_insn(env, ctx, ASE_MT);
2804 gen_helper_mfc0_tcstatus(t0);
2805 rn = "TCStatus";
2806 break;
2807 case 2:
2808 check_insn(env, ctx, ASE_MT);
2809 gen_helper_mfc0_tcbind(t0);
2810 rn = "TCBind";
2811 break;
2812 case 3:
2813 check_insn(env, ctx, ASE_MT);
2814 gen_helper_mfc0_tcrestart(t0);
2815 rn = "TCRestart";
2816 break;
2817 case 4:
2818 check_insn(env, ctx, ASE_MT);
2819 gen_helper_mfc0_tchalt(t0);
2820 rn = "TCHalt";
2821 break;
2822 case 5:
2823 check_insn(env, ctx, ASE_MT);
2824 gen_helper_mfc0_tccontext(t0);
2825 rn = "TCContext";
2826 break;
2827 case 6:
2828 check_insn(env, ctx, ASE_MT);
2829 gen_helper_mfc0_tcschedule(t0);
2830 rn = "TCSchedule";
2831 break;
2832 case 7:
2833 check_insn(env, ctx, ASE_MT);
2834 gen_helper_mfc0_tcschefback(t0);
2835 rn = "TCScheFBack";
2836 break;
2837 default:
2838 goto die;
2840 break;
2841 case 3:
2842 switch (sel) {
2843 case 0:
2844 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
2845 tcg_gen_ext32s_tl(t0, t0);
2846 rn = "EntryLo1";
2847 break;
2848 default:
2849 goto die;
2851 break;
2852 case 4:
2853 switch (sel) {
2854 case 0:
2855 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
2856 tcg_gen_ext32s_tl(t0, t0);
2857 rn = "Context";
2858 break;
2859 case 1:
2860 // gen_helper_mfc0_contextconfig(t0); /* SmartMIPS ASE */
2861 rn = "ContextConfig";
2862 // break;
2863 default:
2864 goto die;
2866 break;
2867 case 5:
2868 switch (sel) {
2869 case 0:
2870 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
2871 rn = "PageMask";
2872 break;
2873 case 1:
2874 check_insn(env, ctx, ISA_MIPS32R2);
2875 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
2876 rn = "PageGrain";
2877 break;
2878 default:
2879 goto die;
2881 break;
2882 case 6:
2883 switch (sel) {
2884 case 0:
2885 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
2886 rn = "Wired";
2887 break;
2888 case 1:
2889 check_insn(env, ctx, ISA_MIPS32R2);
2890 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
2891 rn = "SRSConf0";
2892 break;
2893 case 2:
2894 check_insn(env, ctx, ISA_MIPS32R2);
2895 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
2896 rn = "SRSConf1";
2897 break;
2898 case 3:
2899 check_insn(env, ctx, ISA_MIPS32R2);
2900 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
2901 rn = "SRSConf2";
2902 break;
2903 case 4:
2904 check_insn(env, ctx, ISA_MIPS32R2);
2905 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
2906 rn = "SRSConf3";
2907 break;
2908 case 5:
2909 check_insn(env, ctx, ISA_MIPS32R2);
2910 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
2911 rn = "SRSConf4";
2912 break;
2913 default:
2914 goto die;
2916 break;
2917 case 7:
2918 switch (sel) {
2919 case 0:
2920 check_insn(env, ctx, ISA_MIPS32R2);
2921 gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
2922 rn = "HWREna";
2923 break;
2924 default:
2925 goto die;
2927 break;
2928 case 8:
2929 switch (sel) {
2930 case 0:
2931 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
2932 tcg_gen_ext32s_tl(t0, t0);
2933 rn = "BadVAddr";
2934 break;
2935 default:
2936 goto die;
2938 break;
2939 case 9:
2940 switch (sel) {
2941 case 0:
2942 /* Mark as an IO operation because we read the time. */
2943 if (use_icount)
2944 gen_io_start();
2945 gen_helper_mfc0_count(t0);
2946 if (use_icount) {
2947 gen_io_end();
2948 ctx->bstate = BS_STOP;
2950 rn = "Count";
2951 break;
2952 /* 6,7 are implementation dependent */
2953 default:
2954 goto die;
2956 break;
2957 case 10:
2958 switch (sel) {
2959 case 0:
2960 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
2961 tcg_gen_ext32s_tl(t0, t0);
2962 rn = "EntryHi";
2963 break;
2964 default:
2965 goto die;
2967 break;
2968 case 11:
2969 switch (sel) {
2970 case 0:
2971 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
2972 rn = "Compare";
2973 break;
2974 /* 6,7 are implementation dependent */
2975 default:
2976 goto die;
2978 break;
2979 case 12:
2980 switch (sel) {
2981 case 0:
2982 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
2983 rn = "Status";
2984 break;
2985 case 1:
2986 check_insn(env, ctx, ISA_MIPS32R2);
2987 gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
2988 rn = "IntCtl";
2989 break;
2990 case 2:
2991 check_insn(env, ctx, ISA_MIPS32R2);
2992 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
2993 rn = "SRSCtl";
2994 break;
2995 case 3:
2996 check_insn(env, ctx, ISA_MIPS32R2);
2997 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
2998 rn = "SRSMap";
2999 break;
3000 default:
3001 goto die;
3003 break;
3004 case 13:
3005 switch (sel) {
3006 case 0:
3007 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
3008 rn = "Cause";
3009 break;
3010 default:
3011 goto die;
3013 break;
3014 case 14:
3015 switch (sel) {
3016 case 0:
3017 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
3018 tcg_gen_ext32s_tl(t0, t0);
3019 rn = "EPC";
3020 break;
3021 default:
3022 goto die;
3024 break;
3025 case 15:
3026 switch (sel) {
3027 case 0:
3028 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
3029 rn = "PRid";
3030 break;
3031 case 1:
3032 check_insn(env, ctx, ISA_MIPS32R2);
3033 gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
3034 rn = "EBase";
3035 break;
3036 default:
3037 goto die;
3039 break;
3040 case 16:
3041 switch (sel) {
3042 case 0:
3043 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
3044 rn = "Config";
3045 break;
3046 case 1:
3047 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
3048 rn = "Config1";
3049 break;
3050 case 2:
3051 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
3052 rn = "Config2";
3053 break;
3054 case 3:
3055 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
3056 rn = "Config3";
3057 break;
3058 /* 4,5 are reserved */
3059 /* 6,7 are implementation dependent */
3060 case 6:
3061 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
3062 rn = "Config6";
3063 break;
3064 case 7:
3065 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
3066 rn = "Config7";
3067 break;
3068 default:
3069 goto die;
3071 break;
3072 case 17:
3073 switch (sel) {
3074 case 0:
3075 gen_helper_mfc0_lladdr(t0);
3076 rn = "LLAddr";
3077 break;
3078 default:
3079 goto die;
3081 break;
3082 case 18:
3083 switch (sel) {
3084 case 0 ... 7:
3085 gen_helper_1i(mfc0_watchlo, t0, sel);
3086 rn = "WatchLo";
3087 break;
3088 default:
3089 goto die;
3091 break;
3092 case 19:
3093 switch (sel) {
3094 case 0 ...7:
3095 gen_helper_1i(mfc0_watchhi, t0, sel);
3096 rn = "WatchHi";
3097 break;
3098 default:
3099 goto die;
3101 break;
3102 case 20:
3103 switch (sel) {
3104 case 0:
3105 #if defined(TARGET_MIPS64)
3106 check_insn(env, ctx, ISA_MIPS3);
3107 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
3108 tcg_gen_ext32s_tl(t0, t0);
3109 rn = "XContext";
3110 break;
3111 #endif
3112 default:
3113 goto die;
3115 break;
3116 case 21:
3117 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3118 switch (sel) {
3119 case 0:
3120 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
3121 rn = "Framemask";
3122 break;
3123 default:
3124 goto die;
3126 break;
3127 case 22:
3128 tcg_gen_movi_tl(t0, 0); /* unimplemented */
3129 rn = "'Diagnostic"; /* implementation dependent */
3130 break;
3131 case 23:
3132 switch (sel) {
3133 case 0:
3134 gen_helper_mfc0_debug(t0); /* EJTAG support */
3135 rn = "Debug";
3136 break;
3137 case 1:
3138 // gen_helper_mfc0_tracecontrol(t0); /* PDtrace support */
3139 rn = "TraceControl";
3140 // break;
3141 case 2:
3142 // gen_helper_mfc0_tracecontrol2(t0); /* PDtrace support */
3143 rn = "TraceControl2";
3144 // break;
3145 case 3:
3146 // gen_helper_mfc0_usertracedata(t0); /* PDtrace support */
3147 rn = "UserTraceData";
3148 // break;
3149 case 4:
3150 // gen_helper_mfc0_tracebpc(t0); /* PDtrace support */
3151 rn = "TraceBPC";
3152 // break;
3153 default:
3154 goto die;
3156 break;
3157 case 24:
3158 switch (sel) {
3159 case 0:
3160 /* EJTAG support */
3161 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
3162 tcg_gen_ext32s_tl(t0, t0);
3163 rn = "DEPC";
3164 break;
3165 default:
3166 goto die;
3168 break;
3169 case 25:
3170 switch (sel) {
3171 case 0:
3172 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
3173 rn = "Performance0";
3174 break;
3175 case 1:
3176 // gen_helper_mfc0_performance1(t0);
3177 rn = "Performance1";
3178 // break;
3179 case 2:
3180 // gen_helper_mfc0_performance2(t0);
3181 rn = "Performance2";
3182 // break;
3183 case 3:
3184 // gen_helper_mfc0_performance3(t0);
3185 rn = "Performance3";
3186 // break;
3187 case 4:
3188 // gen_helper_mfc0_performance4(t0);
3189 rn = "Performance4";
3190 // break;
3191 case 5:
3192 // gen_helper_mfc0_performance5(t0);
3193 rn = "Performance5";
3194 // break;
3195 case 6:
3196 // gen_helper_mfc0_performance6(t0);
3197 rn = "Performance6";
3198 // break;
3199 case 7:
3200 // gen_helper_mfc0_performance7(t0);
3201 rn = "Performance7";
3202 // break;
3203 default:
3204 goto die;
3206 break;
3207 case 26:
3208 tcg_gen_movi_tl(t0, 0); /* unimplemented */
3209 rn = "ECC";
3210 break;
3211 case 27:
3212 switch (sel) {
3213 case 0 ... 3:
3214 tcg_gen_movi_tl(t0, 0); /* unimplemented */
3215 rn = "CacheErr";
3216 break;
3217 default:
3218 goto die;
3220 break;
3221 case 28:
3222 switch (sel) {
3223 case 0:
3224 case 2:
3225 case 4:
3226 case 6:
3227 gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
3228 rn = "TagLo";
3229 break;
3230 case 1:
3231 case 3:
3232 case 5:
3233 case 7:
3234 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
3235 rn = "DataLo";
3236 break;
3237 default:
3238 goto die;
3240 break;
3241 case 29:
3242 switch (sel) {
3243 case 0:
3244 case 2:
3245 case 4:
3246 case 6:
3247 gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
3248 rn = "TagHi";
3249 break;
3250 case 1:
3251 case 3:
3252 case 5:
3253 case 7:
3254 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
3255 rn = "DataHi";
3256 break;
3257 default:
3258 goto die;
3260 break;
3261 case 30:
3262 switch (sel) {
3263 case 0:
3264 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3265 tcg_gen_ext32s_tl(t0, t0);
3266 rn = "ErrorEPC";
3267 break;
3268 default:
3269 goto die;
3271 break;
3272 case 31:
3273 switch (sel) {
3274 case 0:
3275 /* EJTAG support */
3276 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
3277 rn = "DESAVE";
3278 break;
3279 default:
3280 goto die;
3282 break;
3283 default:
3284 goto die;
3286 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3287 return;
3289 die:
3290 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3291 generate_exception(ctx, EXCP_RI);
3294 static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3296 const char *rn = "invalid";
3298 if (sel != 0)
3299 check_insn(env, ctx, ISA_MIPS32);
3301 if (use_icount)
3302 gen_io_start();
3304 switch (reg) {
3305 case 0:
3306 switch (sel) {
3307 case 0:
3308 gen_helper_mtc0_index(t0);
3309 rn = "Index";
3310 break;
3311 case 1:
3312 check_insn(env, ctx, ASE_MT);
3313 gen_helper_mtc0_mvpcontrol(t0);
3314 rn = "MVPControl";
3315 break;
3316 case 2:
3317 check_insn(env, ctx, ASE_MT);
3318 /* ignored */
3319 rn = "MVPConf0";
3320 break;
3321 case 3:
3322 check_insn(env, ctx, ASE_MT);
3323 /* ignored */
3324 rn = "MVPConf1";
3325 break;
3326 default:
3327 goto die;
3329 break;
3330 case 1:
3331 switch (sel) {
3332 case 0:
3333 /* ignored */
3334 rn = "Random";
3335 break;
3336 case 1:
3337 check_insn(env, ctx, ASE_MT);
3338 gen_helper_mtc0_vpecontrol(t0);
3339 rn = "VPEControl";
3340 break;
3341 case 2:
3342 check_insn(env, ctx, ASE_MT);
3343 gen_helper_mtc0_vpeconf0(t0);
3344 rn = "VPEConf0";
3345 break;
3346 case 3:
3347 check_insn(env, ctx, ASE_MT);
3348 gen_helper_mtc0_vpeconf1(t0);
3349 rn = "VPEConf1";
3350 break;
3351 case 4:
3352 check_insn(env, ctx, ASE_MT);
3353 gen_helper_mtc0_yqmask(t0);
3354 rn = "YQMask";
3355 break;
3356 case 5:
3357 check_insn(env, ctx, ASE_MT);
3358 gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPESchedule));
3359 rn = "VPESchedule";
3360 break;
3361 case 6:
3362 check_insn(env, ctx, ASE_MT);
3363 gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPEScheFBack));
3364 rn = "VPEScheFBack";
3365 break;
3366 case 7:
3367 check_insn(env, ctx, ASE_MT);
3368 gen_helper_mtc0_vpeopt(t0);
3369 rn = "VPEOpt";
3370 break;
3371 default:
3372 goto die;
3374 break;
3375 case 2:
3376 switch (sel) {
3377 case 0:
3378 gen_helper_mtc0_entrylo0(t0);
3379 rn = "EntryLo0";
3380 break;
3381 case 1:
3382 check_insn(env, ctx, ASE_MT);
3383 gen_helper_mtc0_tcstatus(t0);
3384 rn = "TCStatus";
3385 break;
3386 case 2:
3387 check_insn(env, ctx, ASE_MT);
3388 gen_helper_mtc0_tcbind(t0);
3389 rn = "TCBind";
3390 break;
3391 case 3:
3392 check_insn(env, ctx, ASE_MT);
3393 gen_helper_mtc0_tcrestart(t0);
3394 rn = "TCRestart";
3395 break;
3396 case 4:
3397 check_insn(env, ctx, ASE_MT);
3398 gen_helper_mtc0_tchalt(t0);
3399 rn = "TCHalt";
3400 break;
3401 case 5:
3402 check_insn(env, ctx, ASE_MT);
3403 gen_helper_mtc0_tccontext(t0);
3404 rn = "TCContext";
3405 break;
3406 case 6:
3407 check_insn(env, ctx, ASE_MT);
3408 gen_helper_mtc0_tcschedule(t0);
3409 rn = "TCSchedule";
3410 break;
3411 case 7:
3412 check_insn(env, ctx, ASE_MT);
3413 gen_helper_mtc0_tcschefback(t0);
3414 rn = "TCScheFBack";
3415 break;
3416 default:
3417 goto die;
3419 break;
3420 case 3:
3421 switch (sel) {
3422 case 0:
3423 gen_helper_mtc0_entrylo1(t0);
3424 rn = "EntryLo1";
3425 break;
3426 default:
3427 goto die;
3429 break;
3430 case 4:
3431 switch (sel) {
3432 case 0:
3433 gen_helper_mtc0_context(t0);
3434 rn = "Context";
3435 break;
3436 case 1:
3437 // gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
3438 rn = "ContextConfig";
3439 // break;
3440 default:
3441 goto die;
3443 break;
3444 case 5:
3445 switch (sel) {
3446 case 0:
3447 gen_helper_mtc0_pagemask(t0);
3448 rn = "PageMask";
3449 break;
3450 case 1:
3451 check_insn(env, ctx, ISA_MIPS32R2);
3452 gen_helper_mtc0_pagegrain(t0);
3453 rn = "PageGrain";
3454 break;
3455 default:
3456 goto die;
3458 break;
3459 case 6:
3460 switch (sel) {
3461 case 0:
3462 gen_helper_mtc0_wired(t0);
3463 rn = "Wired";
3464 break;
3465 case 1:
3466 check_insn(env, ctx, ISA_MIPS32R2);
3467 gen_helper_mtc0_srsconf0(t0);
3468 rn = "SRSConf0";
3469 break;
3470 case 2:
3471 check_insn(env, ctx, ISA_MIPS32R2);
3472 gen_helper_mtc0_srsconf1(t0);
3473 rn = "SRSConf1";
3474 break;
3475 case 3:
3476 check_insn(env, ctx, ISA_MIPS32R2);
3477 gen_helper_mtc0_srsconf2(t0);
3478 rn = "SRSConf2";
3479 break;
3480 case 4:
3481 check_insn(env, ctx, ISA_MIPS32R2);
3482 gen_helper_mtc0_srsconf3(t0);
3483 rn = "SRSConf3";
3484 break;
3485 case 5:
3486 check_insn(env, ctx, ISA_MIPS32R2);
3487 gen_helper_mtc0_srsconf4(t0);
3488 rn = "SRSConf4";
3489 break;
3490 default:
3491 goto die;
3493 break;
3494 case 7:
3495 switch (sel) {
3496 case 0:
3497 check_insn(env, ctx, ISA_MIPS32R2);
3498 gen_helper_mtc0_hwrena(t0);
3499 rn = "HWREna";
3500 break;
3501 default:
3502 goto die;
3504 break;
3505 case 8:
3506 /* ignored */
3507 rn = "BadVAddr";
3508 break;
3509 case 9:
3510 switch (sel) {
3511 case 0:
3512 gen_helper_mtc0_count(t0);
3513 rn = "Count";
3514 break;
3515 /* 6,7 are implementation dependent */
3516 default:
3517 goto die;
3519 /* Stop translation as we may have switched the execution mode */
3520 ctx->bstate = BS_STOP;
3521 break;
3522 case 10:
3523 switch (sel) {
3524 case 0:
3525 gen_helper_mtc0_entryhi(t0);
3526 rn = "EntryHi";
3527 break;
3528 default:
3529 goto die;
3531 break;
3532 case 11:
3533 switch (sel) {
3534 case 0:
3535 gen_helper_mtc0_compare(t0);
3536 rn = "Compare";
3537 break;
3538 /* 6,7 are implementation dependent */
3539 default:
3540 goto die;
3542 /* Stop translation as we may have switched the execution mode */
3543 ctx->bstate = BS_STOP;
3544 break;
3545 case 12:
3546 switch (sel) {
3547 case 0:
3548 gen_helper_mtc0_status(t0);
3549 /* BS_STOP isn't good enough here, hflags may have changed. */
3550 gen_save_pc(ctx->pc + 4);
3551 ctx->bstate = BS_EXCP;
3552 rn = "Status";
3553 break;
3554 case 1:
3555 check_insn(env, ctx, ISA_MIPS32R2);
3556 gen_helper_mtc0_intctl(t0);
3557 /* Stop translation as we may have switched the execution mode */
3558 ctx->bstate = BS_STOP;
3559 rn = "IntCtl";
3560 break;
3561 case 2:
3562 check_insn(env, ctx, ISA_MIPS32R2);
3563 gen_helper_mtc0_srsctl(t0);
3564 /* Stop translation as we may have switched the execution mode */
3565 ctx->bstate = BS_STOP;
3566 rn = "SRSCtl";
3567 break;
3568 case 3:
3569 check_insn(env, ctx, ISA_MIPS32R2);
3570 gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
3571 /* Stop translation as we may have switched the execution mode */
3572 ctx->bstate = BS_STOP;
3573 rn = "SRSMap";
3574 break;
3575 default:
3576 goto die;
3578 break;
3579 case 13:
3580 switch (sel) {
3581 case 0:
3582 gen_helper_mtc0_cause(t0);
3583 rn = "Cause";
3584 break;
3585 default:
3586 goto die;
3588 /* Stop translation as we may have switched the execution mode */
3589 ctx->bstate = BS_STOP;
3590 break;
3591 case 14:
3592 switch (sel) {
3593 case 0:
3594 gen_mtc0_store64(t0, offsetof(CPUState, CP0_EPC));
3595 rn = "EPC";
3596 break;
3597 default:
3598 goto die;
3600 break;
3601 case 15:
3602 switch (sel) {
3603 case 0:
3604 /* ignored */
3605 rn = "PRid";
3606 break;
3607 case 1:
3608 check_insn(env, ctx, ISA_MIPS32R2);
3609 gen_helper_mtc0_ebase(t0);
3610 rn = "EBase";
3611 break;
3612 default:
3613 goto die;
3615 break;
3616 case 16:
3617 switch (sel) {
3618 case 0:
3619 gen_helper_mtc0_config0(t0);
3620 rn = "Config";
3621 /* Stop translation as we may have switched the execution mode */
3622 ctx->bstate = BS_STOP;
3623 break;
3624 case 1:
3625 /* ignored, read only */
3626 rn = "Config1";
3627 break;
3628 case 2:
3629 gen_helper_mtc0_config2(t0);
3630 rn = "Config2";
3631 /* Stop translation as we may have switched the execution mode */
3632 ctx->bstate = BS_STOP;
3633 break;
3634 case 3:
3635 /* ignored, read only */
3636 rn = "Config3";
3637 break;
3638 /* 4,5 are reserved */
3639 /* 6,7 are implementation dependent */
3640 case 6:
3641 /* ignored */
3642 rn = "Config6";
3643 break;
3644 case 7:
3645 /* ignored */
3646 rn = "Config7";
3647 break;
3648 default:
3649 rn = "Invalid config selector";
3650 goto die;
3652 break;
3653 case 17:
3654 switch (sel) {
3655 case 0:
3656 /* ignored */
3657 rn = "LLAddr";
3658 break;
3659 default:
3660 goto die;
3662 break;
3663 case 18:
3664 switch (sel) {
3665 case 0 ... 7:
3666 gen_helper_1i(mtc0_watchlo, t0, sel);
3667 rn = "WatchLo";
3668 break;
3669 default:
3670 goto die;
3672 break;
3673 case 19:
3674 switch (sel) {
3675 case 0 ... 7:
3676 gen_helper_1i(mtc0_watchhi, t0, sel);
3677 rn = "WatchHi";
3678 break;
3679 default:
3680 goto die;
3682 break;
3683 case 20:
3684 switch (sel) {
3685 case 0:
3686 #if defined(TARGET_MIPS64)
3687 check_insn(env, ctx, ISA_MIPS3);
3688 gen_helper_mtc0_xcontext(t0);
3689 rn = "XContext";
3690 break;
3691 #endif
3692 default:
3693 goto die;
3695 break;
3696 case 21:
3697 /* Officially reserved, but sel 0 is used for R1x000 framemask */
3698 switch (sel) {
3699 case 0:
3700 gen_helper_mtc0_framemask(t0);
3701 rn = "Framemask";
3702 break;
3703 default:
3704 goto die;
3706 break;
3707 case 22:
3708 /* ignored */
3709 rn = "Diagnostic"; /* implementation dependent */
3710 break;
3711 case 23:
3712 switch (sel) {
3713 case 0:
3714 gen_helper_mtc0_debug(t0); /* EJTAG support */
3715 /* BS_STOP isn't good enough here, hflags may have changed. */
3716 gen_save_pc(ctx->pc + 4);
3717 ctx->bstate = BS_EXCP;
3718 rn = "Debug";
3719 break;
3720 case 1:
3721 // gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
3722 rn = "TraceControl";
3723 /* Stop translation as we may have switched the execution mode */
3724 ctx->bstate = BS_STOP;
3725 // break;
3726 case 2:
3727 // gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
3728 rn = "TraceControl2";
3729 /* Stop translation as we may have switched the execution mode */
3730 ctx->bstate = BS_STOP;
3731 // break;
3732 case 3:
3733 /* Stop translation as we may have switched the execution mode */
3734 ctx->bstate = BS_STOP;
3735 // gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
3736 rn = "UserTraceData";
3737 /* Stop translation as we may have switched the execution mode */
3738 ctx->bstate = BS_STOP;
3739 // break;
3740 case 4:
3741 // gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
3742 /* Stop translation as we may have switched the execution mode */
3743 ctx->bstate = BS_STOP;
3744 rn = "TraceBPC";
3745 // break;
3746 default:
3747 goto die;
3749 break;
3750 case 24:
3751 switch (sel) {
3752 case 0:
3753 /* EJTAG support */
3754 gen_mtc0_store64(t0, offsetof(CPUState, CP0_DEPC));
3755 rn = "DEPC";
3756 break;
3757 default:
3758 goto die;
3760 break;
3761 case 25:
3762 switch (sel) {
3763 case 0:
3764 gen_helper_mtc0_performance0(t0);
3765 rn = "Performance0";
3766 break;
3767 case 1:
3768 // gen_helper_mtc0_performance1(t0);
3769 rn = "Performance1";
3770 // break;
3771 case 2:
3772 // gen_helper_mtc0_performance2(t0);
3773 rn = "Performance2";
3774 // break;
3775 case 3:
3776 // gen_helper_mtc0_performance3(t0);
3777 rn = "Performance3";
3778 // break;
3779 case 4:
3780 // gen_helper_mtc0_performance4(t0);
3781 rn = "Performance4";
3782 // break;
3783 case 5:
3784 // gen_helper_mtc0_performance5(t0);
3785 rn = "Performance5";
3786 // break;
3787 case 6:
3788 // gen_helper_mtc0_performance6(t0);
3789 rn = "Performance6";
3790 // break;
3791 case 7:
3792 // gen_helper_mtc0_performance7(t0);
3793 rn = "Performance7";
3794 // break;
3795 default:
3796 goto die;
3798 break;
3799 case 26:
3800 /* ignored */
3801 rn = "ECC";
3802 break;
3803 case 27:
3804 switch (sel) {
3805 case 0 ... 3:
3806 /* ignored */
3807 rn = "CacheErr";
3808 break;
3809 default:
3810 goto die;
3812 break;
3813 case 28:
3814 switch (sel) {
3815 case 0:
3816 case 2:
3817 case 4:
3818 case 6:
3819 gen_helper_mtc0_taglo(t0);
3820 rn = "TagLo";
3821 break;
3822 case 1:
3823 case 3:
3824 case 5:
3825 case 7:
3826 gen_helper_mtc0_datalo(t0);
3827 rn = "DataLo";
3828 break;
3829 default:
3830 goto die;
3832 break;
3833 case 29:
3834 switch (sel) {
3835 case 0:
3836 case 2:
3837 case 4:
3838 case 6:
3839 gen_helper_mtc0_taghi(t0);
3840 rn = "TagHi";
3841 break;
3842 case 1:
3843 case 3:
3844 case 5:
3845 case 7:
3846 gen_helper_mtc0_datahi(t0);
3847 rn = "DataHi";
3848 break;
3849 default:
3850 rn = "invalid sel";
3851 goto die;
3853 break;
3854 case 30:
3855 switch (sel) {
3856 case 0:
3857 gen_mtc0_store64(t0, offsetof(CPUState, CP0_ErrorEPC));
3858 rn = "ErrorEPC";
3859 break;
3860 default:
3861 goto die;
3863 break;
3864 case 31:
3865 switch (sel) {
3866 case 0:
3867 /* EJTAG support */
3868 gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
3869 rn = "DESAVE";
3870 break;
3871 default:
3872 goto die;
3874 /* Stop translation as we may have switched the execution mode */
3875 ctx->bstate = BS_STOP;
3876 break;
3877 default:
3878 goto die;
3880 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3881 /* For simplicity assume that all writes can cause interrupts. */
3882 if (use_icount) {
3883 gen_io_end();
3884 ctx->bstate = BS_STOP;
3886 return;
3888 die:
3889 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
3890 generate_exception(ctx, EXCP_RI);
3893 #if defined(TARGET_MIPS64)
3894 static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
3896 const char *rn = "invalid";
3898 if (sel != 0)
3899 check_insn(env, ctx, ISA_MIPS64);
3901 switch (reg) {
3902 case 0:
3903 switch (sel) {
3904 case 0:
3905 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
3906 rn = "Index";
3907 break;
3908 case 1:
3909 check_insn(env, ctx, ASE_MT);
3910 gen_helper_mfc0_mvpcontrol(t0);
3911 rn = "MVPControl";
3912 break;
3913 case 2:
3914 check_insn(env, ctx, ASE_MT);
3915 gen_helper_mfc0_mvpconf0(t0);
3916 rn = "MVPConf0";
3917 break;
3918 case 3:
3919 check_insn(env, ctx, ASE_MT);
3920 gen_helper_mfc0_mvpconf1(t0);
3921 rn = "MVPConf1";
3922 break;
3923 default:
3924 goto die;
3926 break;
3927 case 1:
3928 switch (sel) {
3929 case 0:
3930 gen_helper_mfc0_random(t0);
3931 rn = "Random";
3932 break;
3933 case 1:
3934 check_insn(env, ctx, ASE_MT);
3935 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
3936 rn = "VPEControl";
3937 break;
3938 case 2:
3939 check_insn(env, ctx, ASE_MT);
3940 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
3941 rn = "VPEConf0";
3942 break;
3943 case 3:
3944 check_insn(env, ctx, ASE_MT);
3945 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
3946 rn = "VPEConf1";
3947 break;
3948 case 4:
3949 check_insn(env, ctx, ASE_MT);
3950 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_YQMask));
3951 rn = "YQMask";
3952 break;
3953 case 5:
3954 check_insn(env, ctx, ASE_MT);
3955 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
3956 rn = "VPESchedule";
3957 break;
3958 case 6:
3959 check_insn(env, ctx, ASE_MT);
3960 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
3961 rn = "VPEScheFBack";
3962 break;
3963 case 7:
3964 check_insn(env, ctx, ASE_MT);
3965 gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
3966 rn = "VPEOpt";
3967 break;
3968 default:
3969 goto die;
3971 break;
3972 case 2:
3973 switch (sel) {
3974 case 0:
3975 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
3976 rn = "EntryLo0";
3977 break;
3978 case 1:
3979 check_insn(env, ctx, ASE_MT);
3980 gen_helper_mfc0_tcstatus(t0);
3981 rn = "TCStatus";
3982 break;
3983 case 2:
3984 check_insn(env, ctx, ASE_MT);
3985 gen_helper_mfc0_tcbind(t0);
3986 rn = "TCBind";
3987 break;
3988 case 3:
3989 check_insn(env, ctx, ASE_MT);
3990 gen_helper_dmfc0_tcrestart(t0);
3991 rn = "TCRestart";
3992 break;
3993 case 4:
3994 check_insn(env, ctx, ASE_MT);
3995 gen_helper_dmfc0_tchalt(t0);
3996 rn = "TCHalt";
3997 break;
3998 case 5:
3999 check_insn(env, ctx, ASE_MT);
4000 gen_helper_dmfc0_tccontext(t0);
4001 rn = "TCContext";
4002 break;
4003 case 6:
4004 check_insn(env, ctx, ASE_MT);
4005 gen_helper_dmfc0_tcschedule(t0);
4006 rn = "TCSchedule";
4007 break;
4008 case 7:
4009 check_insn(env, ctx, ASE_MT);
4010 gen_helper_dmfc0_tcschefback(t0);
4011 rn = "TCScheFBack";
4012 break;
4013 default:
4014 goto die;
4016 break;
4017 case 3:
4018 switch (sel) {
4019 case 0:
4020 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4021 rn = "EntryLo1";
4022 break;
4023 default:
4024 goto die;
4026 break;
4027 case 4:
4028 switch (sel) {
4029 case 0:
4030 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
4031 rn = "Context";
4032 break;
4033 case 1:
4034 // gen_helper_dmfc0_contextconfig(t0); /* SmartMIPS ASE */
4035 rn = "ContextConfig";
4036 // break;
4037 default:
4038 goto die;
4040 break;
4041 case 5:
4042 switch (sel) {
4043 case 0:
4044 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
4045 rn = "PageMask";
4046 break;
4047 case 1:
4048 check_insn(env, ctx, ISA_MIPS32R2);
4049 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
4050 rn = "PageGrain";
4051 break;
4052 default:
4053 goto die;
4055 break;
4056 case 6:
4057 switch (sel) {
4058 case 0:
4059 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
4060 rn = "Wired";
4061 break;
4062 case 1:
4063 check_insn(env, ctx, ISA_MIPS32R2);
4064 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
4065 rn = "SRSConf0";
4066 break;
4067 case 2:
4068 check_insn(env, ctx, ISA_MIPS32R2);
4069 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
4070 rn = "SRSConf1";
4071 break;
4072 case 3:
4073 check_insn(env, ctx, ISA_MIPS32R2);
4074 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
4075 rn = "SRSConf2";
4076 break;
4077 case 4:
4078 check_insn(env, ctx, ISA_MIPS32R2);
4079 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
4080 rn = "SRSConf3";
4081 break;
4082 case 5:
4083 check_insn(env, ctx, ISA_MIPS32R2);
4084 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
4085 rn = "SRSConf4";
4086 break;
4087 default:
4088 goto die;
4090 break;
4091 case 7:
4092 switch (sel) {
4093 case 0:
4094 check_insn(env, ctx, ISA_MIPS32R2);
4095 gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
4096 rn = "HWREna";
4097 break;
4098 default:
4099 goto die;
4101 break;
4102 case 8:
4103 switch (sel) {
4104 case 0:
4105 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
4106 rn = "BadVAddr";
4107 break;
4108 default:
4109 goto die;
4111 break;
4112 case 9:
4113 switch (sel) {
4114 case 0:
4115 /* Mark as an IO operation because we read the time. */
4116 if (use_icount)
4117 gen_io_start();
4118 gen_helper_mfc0_count(t0);
4119 if (use_icount) {
4120 gen_io_end();
4121 ctx->bstate = BS_STOP;
4123 rn = "Count";
4124 break;
4125 /* 6,7 are implementation dependent */
4126 default:
4127 goto die;
4129 break;
4130 case 10:
4131 switch (sel) {
4132 case 0:
4133 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
4134 rn = "EntryHi";
4135 break;
4136 default:
4137 goto die;
4139 break;
4140 case 11:
4141 switch (sel) {
4142 case 0:
4143 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
4144 rn = "Compare";
4145 break;
4146 /* 6,7 are implementation dependent */
4147 default:
4148 goto die;
4150 break;
4151 case 12:
4152 switch (sel) {
4153 case 0:
4154 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
4155 rn = "Status";
4156 break;
4157 case 1:
4158 check_insn(env, ctx, ISA_MIPS32R2);
4159 gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
4160 rn = "IntCtl";
4161 break;
4162 case 2:
4163 check_insn(env, ctx, ISA_MIPS32R2);
4164 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
4165 rn = "SRSCtl";
4166 break;
4167 case 3:
4168 check_insn(env, ctx, ISA_MIPS32R2);
4169 gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
4170 rn = "SRSMap";
4171 break;
4172 default:
4173 goto die;
4175 break;
4176 case 13:
4177 switch (sel) {
4178 case 0:
4179 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
4180 rn = "Cause";
4181 break;
4182 default:
4183 goto die;
4185 break;
4186 case 14:
4187 switch (sel) {
4188 case 0:
4189 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4190 rn = "EPC";
4191 break;
4192 default:
4193 goto die;
4195 break;
4196 case 15:
4197 switch (sel) {
4198 case 0:
4199 gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
4200 rn = "PRid";
4201 break;
4202 case 1:
4203 check_insn(env, ctx, ISA_MIPS32R2);
4204 gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
4205 rn = "EBase";
4206 break;
4207 default:
4208 goto die;
4210 break;
4211 case 16:
4212 switch (sel) {
4213 case 0:
4214 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
4215 rn = "Config";
4216 break;
4217 case 1:
4218 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
4219 rn = "Config1";
4220 break;
4221 case 2:
4222 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
4223 rn = "Config2";
4224 break;
4225 case 3:
4226 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
4227 rn = "Config3";
4228 break;
4229 /* 6,7 are implementation dependent */
4230 case 6:
4231 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
4232 rn = "Config6";
4233 break;
4234 case 7:
4235 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
4236 rn = "Config7";
4237 break;
4238 default:
4239 goto die;
4241 break;
4242 case 17:
4243 switch (sel) {
4244 case 0:
4245 gen_helper_dmfc0_lladdr(t0);
4246 rn = "LLAddr";
4247 break;
4248 default:
4249 goto die;
4251 break;
4252 case 18:
4253 switch (sel) {
4254 case 0 ... 7:
4255 gen_helper_1i(dmfc0_watchlo, t0, sel);
4256 rn = "WatchLo";
4257 break;
4258 default:
4259 goto die;
4261 break;
4262 case 19:
4263 switch (sel) {
4264 case 0 ... 7:
4265 gen_helper_1i(mfc0_watchhi, t0, sel);
4266 rn = "WatchHi";
4267 break;
4268 default:
4269 goto die;
4271 break;
4272 case 20:
4273 switch (sel) {
4274 case 0:
4275 check_insn(env, ctx, ISA_MIPS3);
4276 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
4277 rn = "XContext";
4278 break;
4279 default:
4280 goto die;
4282 break;
4283 case 21:
4284 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4285 switch (sel) {
4286 case 0:
4287 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
4288 rn = "Framemask";
4289 break;
4290 default:
4291 goto die;
4293 break;
4294 case 22:
4295 tcg_gen_movi_tl(t0, 0); /* unimplemented */
4296 rn = "'Diagnostic"; /* implementation dependent */
4297 break;
4298 case 23:
4299 switch (sel) {
4300 case 0:
4301 gen_helper_mfc0_debug(t0); /* EJTAG support */
4302 rn = "Debug";
4303 break;
4304 case 1:
4305 // gen_helper_dmfc0_tracecontrol(t0); /* PDtrace support */
4306 rn = "TraceControl";
4307 // break;
4308 case 2:
4309 // gen_helper_dmfc0_tracecontrol2(t0); /* PDtrace support */
4310 rn = "TraceControl2";
4311 // break;
4312 case 3:
4313 // gen_helper_dmfc0_usertracedata(t0); /* PDtrace support */
4314 rn = "UserTraceData";
4315 // break;
4316 case 4:
4317 // gen_helper_dmfc0_tracebpc(t0); /* PDtrace support */
4318 rn = "TraceBPC";
4319 // break;
4320 default:
4321 goto die;
4323 break;
4324 case 24:
4325 switch (sel) {
4326 case 0:
4327 /* EJTAG support */
4328 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
4329 rn = "DEPC";
4330 break;
4331 default:
4332 goto die;
4334 break;
4335 case 25:
4336 switch (sel) {
4337 case 0:
4338 gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
4339 rn = "Performance0";
4340 break;
4341 case 1:
4342 // gen_helper_dmfc0_performance1(t0);
4343 rn = "Performance1";
4344 // break;
4345 case 2:
4346 // gen_helper_dmfc0_performance2(t0);
4347 rn = "Performance2";
4348 // break;
4349 case 3:
4350 // gen_helper_dmfc0_performance3(t0);
4351 rn = "Performance3";
4352 // break;
4353 case 4:
4354 // gen_helper_dmfc0_performance4(t0);
4355 rn = "Performance4";
4356 // break;
4357 case 5:
4358 // gen_helper_dmfc0_performance5(t0);
4359 rn = "Performance5";
4360 // break;
4361 case 6:
4362 // gen_helper_dmfc0_performance6(t0);
4363 rn = "Performance6";
4364 // break;
4365 case 7:
4366 // gen_helper_dmfc0_performance7(t0);
4367 rn = "Performance7";
4368 // break;
4369 default:
4370 goto die;
4372 break;
4373 case 26:
4374 tcg_gen_movi_tl(t0, 0); /* unimplemented */
4375 rn = "ECC";
4376 break;
4377 case 27:
4378 switch (sel) {
4379 /* ignored */
4380 case 0 ... 3:
4381 tcg_gen_movi_tl(t0, 0); /* unimplemented */
4382 rn = "CacheErr";
4383 break;
4384 default:
4385 goto die;
4387 break;
4388 case 28:
4389 switch (sel) {
4390 case 0:
4391 case 2:
4392 case 4:
4393 case 6:
4394 gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
4395 rn = "TagLo";
4396 break;
4397 case 1:
4398 case 3:
4399 case 5:
4400 case 7:
4401 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
4402 rn = "DataLo";
4403 break;
4404 default:
4405 goto die;
4407 break;
4408 case 29:
4409 switch (sel) {
4410 case 0:
4411 case 2:
4412 case 4:
4413 case 6:
4414 gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
4415 rn = "TagHi";
4416 break;
4417 case 1:
4418 case 3:
4419 case 5:
4420 case 7:
4421 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
4422 rn = "DataHi";
4423 break;
4424 default:
4425 goto die;
4427 break;
4428 case 30:
4429 switch (sel) {
4430 case 0:
4431 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4432 rn = "ErrorEPC";
4433 break;
4434 default:
4435 goto die;
4437 break;
4438 case 31:
4439 switch (sel) {
4440 case 0:
4441 /* EJTAG support */
4442 gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
4443 rn = "DESAVE";
4444 break;
4445 default:
4446 goto die;
4448 break;
4449 default:
4450 goto die;
4452 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4453 return;
4455 die:
4456 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4457 generate_exception(ctx, EXCP_RI);
4460 static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
4462 const char *rn = "invalid";
4464 if (sel != 0)
4465 check_insn(env, ctx, ISA_MIPS64);
4467 if (use_icount)
4468 gen_io_start();
4470 switch (reg) {
4471 case 0:
4472 switch (sel) {
4473 case 0:
4474 gen_helper_mtc0_index(t0);
4475 rn = "Index";
4476 break;
4477 case 1:
4478 check_insn(env, ctx, ASE_MT);
4479 gen_helper_mtc0_mvpcontrol(t0);
4480 rn = "MVPControl";
4481 break;
4482 case 2:
4483 check_insn(env, ctx, ASE_MT);
4484 /* ignored */
4485 rn = "MVPConf0";
4486 break;
4487 case 3:
4488 check_insn(env, ctx, ASE_MT);
4489 /* ignored */
4490 rn = "MVPConf1";
4491 break;
4492 default:
4493 goto die;
4495 break;
4496 case 1:
4497 switch (sel) {
4498 case 0:
4499 /* ignored */
4500 rn = "Random";
4501 break;
4502 case 1:
4503 check_insn(env, ctx, ASE_MT);
4504 gen_helper_mtc0_vpecontrol(t0);
4505 rn = "VPEControl";
4506 break;
4507 case 2:
4508 check_insn(env, ctx, ASE_MT);
4509 gen_helper_mtc0_vpeconf0(t0);
4510 rn = "VPEConf0";
4511 break;
4512 case 3:
4513 check_insn(env, ctx, ASE_MT);
4514 gen_helper_mtc0_vpeconf1(t0);
4515 rn = "VPEConf1";
4516 break;
4517 case 4:
4518 check_insn(env, ctx, ASE_MT);
4519 gen_helper_mtc0_yqmask(t0);
4520 rn = "YQMask";
4521 break;
4522 case 5:
4523 check_insn(env, ctx, ASE_MT);
4524 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4525 rn = "VPESchedule";
4526 break;
4527 case 6:
4528 check_insn(env, ctx, ASE_MT);
4529 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4530 rn = "VPEScheFBack";
4531 break;
4532 case 7:
4533 check_insn(env, ctx, ASE_MT);
4534 gen_helper_mtc0_vpeopt(t0);
4535 rn = "VPEOpt";
4536 break;
4537 default:
4538 goto die;
4540 break;
4541 case 2:
4542 switch (sel) {
4543 case 0:
4544 gen_helper_mtc0_entrylo0(t0);
4545 rn = "EntryLo0";
4546 break;
4547 case 1:
4548 check_insn(env, ctx, ASE_MT);
4549 gen_helper_mtc0_tcstatus(t0);
4550 rn = "TCStatus";
4551 break;
4552 case 2:
4553 check_insn(env, ctx, ASE_MT);
4554 gen_helper_mtc0_tcbind(t0);
4555 rn = "TCBind";
4556 break;
4557 case 3:
4558 check_insn(env, ctx, ASE_MT);
4559 gen_helper_mtc0_tcrestart(t0);
4560 rn = "TCRestart";
4561 break;
4562 case 4:
4563 check_insn(env, ctx, ASE_MT);
4564 gen_helper_mtc0_tchalt(t0);
4565 rn = "TCHalt";
4566 break;
4567 case 5:
4568 check_insn(env, ctx, ASE_MT);
4569 gen_helper_mtc0_tccontext(t0);
4570 rn = "TCContext";
4571 break;
4572 case 6:
4573 check_insn(env, ctx, ASE_MT);
4574 gen_helper_mtc0_tcschedule(t0);
4575 rn = "TCSchedule";
4576 break;
4577 case 7:
4578 check_insn(env, ctx, ASE_MT);
4579 gen_helper_mtc0_tcschefback(t0);
4580 rn = "TCScheFBack";
4581 break;
4582 default:
4583 goto die;
4585 break;
4586 case 3:
4587 switch (sel) {
4588 case 0:
4589 gen_helper_mtc0_entrylo1(t0);
4590 rn = "EntryLo1";
4591 break;
4592 default:
4593 goto die;
4595 break;
4596 case 4:
4597 switch (sel) {
4598 case 0:
4599 gen_helper_mtc0_context(t0);
4600 rn = "Context";
4601 break;
4602 case 1:
4603 // gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
4604 rn = "ContextConfig";
4605 // break;
4606 default:
4607 goto die;
4609 break;
4610 case 5:
4611 switch (sel) {
4612 case 0:
4613 gen_helper_mtc0_pagemask(t0);
4614 rn = "PageMask";
4615 break;
4616 case 1:
4617 check_insn(env, ctx, ISA_MIPS32R2);
4618 gen_helper_mtc0_pagegrain(t0);
4619 rn = "PageGrain";
4620 break;
4621 default:
4622 goto die;
4624 break;
4625 case 6:
4626 switch (sel) {
4627 case 0:
4628 gen_helper_mtc0_wired(t0);
4629 rn = "Wired";
4630 break;
4631 case 1:
4632 check_insn(env, ctx, ISA_MIPS32R2);
4633 gen_helper_mtc0_srsconf0(t0);
4634 rn = "SRSConf0";
4635 break;
4636 case 2:
4637 check_insn(env, ctx, ISA_MIPS32R2);
4638 gen_helper_mtc0_srsconf1(t0);
4639 rn = "SRSConf1";
4640 break;
4641 case 3:
4642 check_insn(env, ctx, ISA_MIPS32R2);
4643 gen_helper_mtc0_srsconf2(t0);
4644 rn = "SRSConf2";
4645 break;
4646 case 4:
4647 check_insn(env, ctx, ISA_MIPS32R2);
4648 gen_helper_mtc0_srsconf3(t0);
4649 rn = "SRSConf3";
4650 break;
4651 case 5:
4652 check_insn(env, ctx, ISA_MIPS32R2);
4653 gen_helper_mtc0_srsconf4(t0);
4654 rn = "SRSConf4";
4655 break;
4656 default:
4657 goto die;
4659 break;
4660 case 7:
4661 switch (sel) {
4662 case 0:
4663 check_insn(env, ctx, ISA_MIPS32R2);
4664 gen_helper_mtc0_hwrena(t0);
4665 rn = "HWREna";
4666 break;
4667 default:
4668 goto die;
4670 break;
4671 case 8:
4672 /* ignored */
4673 rn = "BadVAddr";
4674 break;
4675 case 9:
4676 switch (sel) {
4677 case 0:
4678 gen_helper_mtc0_count(t0);
4679 rn = "Count";
4680 break;
4681 /* 6,7 are implementation dependent */
4682 default:
4683 goto die;
4685 /* Stop translation as we may have switched the execution mode */
4686 ctx->bstate = BS_STOP;
4687 break;
4688 case 10:
4689 switch (sel) {
4690 case 0:
4691 gen_helper_mtc0_entryhi(t0);
4692 rn = "EntryHi";
4693 break;
4694 default:
4695 goto die;
4697 break;
4698 case 11:
4699 switch (sel) {
4700 case 0:
4701 gen_helper_mtc0_compare(t0);
4702 rn = "Compare";
4703 break;
4704 /* 6,7 are implementation dependent */
4705 default:
4706 goto die;
4708 /* Stop translation as we may have switched the execution mode */
4709 ctx->bstate = BS_STOP;
4710 break;
4711 case 12:
4712 switch (sel) {
4713 case 0:
4714 gen_helper_mtc0_status(t0);
4715 /* BS_STOP isn't good enough here, hflags may have changed. */
4716 gen_save_pc(ctx->pc + 4);
4717 ctx->bstate = BS_EXCP;
4718 rn = "Status";
4719 break;
4720 case 1:
4721 check_insn(env, ctx, ISA_MIPS32R2);
4722 gen_helper_mtc0_intctl(t0);
4723 /* Stop translation as we may have switched the execution mode */
4724 ctx->bstate = BS_STOP;
4725 rn = "IntCtl";
4726 break;
4727 case 2:
4728 check_insn(env, ctx, ISA_MIPS32R2);
4729 gen_helper_mtc0_srsctl(t0);
4730 /* Stop translation as we may have switched the execution mode */
4731 ctx->bstate = BS_STOP;
4732 rn = "SRSCtl";
4733 break;
4734 case 3:
4735 check_insn(env, ctx, ISA_MIPS32R2);
4736 gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
4737 /* Stop translation as we may have switched the execution mode */
4738 ctx->bstate = BS_STOP;
4739 rn = "SRSMap";
4740 break;
4741 default:
4742 goto die;
4744 break;
4745 case 13:
4746 switch (sel) {
4747 case 0:
4748 gen_helper_mtc0_cause(t0);
4749 rn = "Cause";
4750 break;
4751 default:
4752 goto die;
4754 /* Stop translation as we may have switched the execution mode */
4755 ctx->bstate = BS_STOP;
4756 break;
4757 case 14:
4758 switch (sel) {
4759 case 0:
4760 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
4761 rn = "EPC";
4762 break;
4763 default:
4764 goto die;
4766 break;
4767 case 15:
4768 switch (sel) {
4769 case 0:
4770 /* ignored */
4771 rn = "PRid";
4772 break;
4773 case 1:
4774 check_insn(env, ctx, ISA_MIPS32R2);
4775 gen_helper_mtc0_ebase(t0);
4776 rn = "EBase";
4777 break;
4778 default:
4779 goto die;
4781 break;
4782 case 16:
4783 switch (sel) {
4784 case 0:
4785 gen_helper_mtc0_config0(t0);
4786 rn = "Config";
4787 /* Stop translation as we may have switched the execution mode */
4788 ctx->bstate = BS_STOP;
4789 break;
4790 case 1:
4791 /* ignored */
4792 rn = "Config1";
4793 break;
4794 case 2:
4795 gen_helper_mtc0_config2(t0);
4796 rn = "Config2";
4797 /* Stop translation as we may have switched the execution mode */
4798 ctx->bstate = BS_STOP;
4799 break;
4800 case 3:
4801 /* ignored */
4802 rn = "Config3";
4803 break;
4804 /* 6,7 are implementation dependent */
4805 default:
4806 rn = "Invalid config selector";
4807 goto die;
4809 break;
4810 case 17:
4811 switch (sel) {
4812 case 0:
4813 /* ignored */
4814 rn = "LLAddr";
4815 break;
4816 default:
4817 goto die;
4819 break;
4820 case 18:
4821 switch (sel) {
4822 case 0 ... 7:
4823 gen_helper_1i(mtc0_watchlo, t0, sel);
4824 rn = "WatchLo";
4825 break;
4826 default:
4827 goto die;
4829 break;
4830 case 19:
4831 switch (sel) {
4832 case 0 ... 7:
4833 gen_helper_1i(mtc0_watchhi, t0, sel);
4834 rn = "WatchHi";
4835 break;
4836 default:
4837 goto die;
4839 break;
4840 case 20:
4841 switch (sel) {
4842 case 0:
4843 check_insn(env, ctx, ISA_MIPS3);
4844 gen_helper_mtc0_xcontext(t0);
4845 rn = "XContext";
4846 break;
4847 default:
4848 goto die;
4850 break;
4851 case 21:
4852 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4853 switch (sel) {
4854 case 0:
4855 gen_helper_mtc0_framemask(t0);
4856 rn = "Framemask";
4857 break;
4858 default:
4859 goto die;
4861 break;
4862 case 22:
4863 /* ignored */
4864 rn = "Diagnostic"; /* implementation dependent */
4865 break;
4866 case 23:
4867 switch (sel) {
4868 case 0:
4869 gen_helper_mtc0_debug(t0); /* EJTAG support */
4870 /* BS_STOP isn't good enough here, hflags may have changed. */
4871 gen_save_pc(ctx->pc + 4);
4872 ctx->bstate = BS_EXCP;
4873 rn = "Debug";
4874 break;
4875 case 1:
4876 // gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
4877 /* Stop translation as we may have switched the execution mode */
4878 ctx->bstate = BS_STOP;
4879 rn = "TraceControl";
4880 // break;
4881 case 2:
4882 // gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
4883 /* Stop translation as we may have switched the execution mode */
4884 ctx->bstate = BS_STOP;
4885 rn = "TraceControl2";
4886 // break;
4887 case 3:
4888 // gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
4889 /* Stop translation as we may have switched the execution mode */
4890 ctx->bstate = BS_STOP;
4891 rn = "UserTraceData";
4892 // break;
4893 case 4:
4894 // gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
4895 /* Stop translation as we may have switched the execution mode */
4896 ctx->bstate = BS_STOP;
4897 rn = "TraceBPC";
4898 // break;
4899 default:
4900 goto die;
4902 break;
4903 case 24:
4904 switch (sel) {
4905 case 0:
4906 /* EJTAG support */
4907 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
4908 rn = "DEPC";
4909 break;
4910 default:
4911 goto die;
4913 break;
4914 case 25:
4915 switch (sel) {
4916 case 0:
4917 gen_helper_mtc0_performance0(t0);
4918 rn = "Performance0";
4919 break;
4920 case 1:
4921 // gen_helper_mtc0_performance1(t0);
4922 rn = "Performance1";
4923 // break;
4924 case 2:
4925 // gen_helper_mtc0_performance2(t0);
4926 rn = "Performance2";
4927 // break;
4928 case 3:
4929 // gen_helper_mtc0_performance3(t0);
4930 rn = "Performance3";
4931 // break;
4932 case 4:
4933 // gen_helper_mtc0_performance4(t0);
4934 rn = "Performance4";
4935 // break;
4936 case 5:
4937 // gen_helper_mtc0_performance5(t0);
4938 rn = "Performance5";
4939 // break;
4940 case 6:
4941 // gen_helper_mtc0_performance6(t0);
4942 rn = "Performance6";
4943 // break;
4944 case 7:
4945 // gen_helper_mtc0_performance7(t0);
4946 rn = "Performance7";
4947 // break;
4948 default:
4949 goto die;
4951 break;
4952 case 26:
4953 /* ignored */
4954 rn = "ECC";
4955 break;
4956 case 27:
4957 switch (sel) {
4958 case 0 ... 3:
4959 /* ignored */
4960 rn = "CacheErr";
4961 break;
4962 default:
4963 goto die;
4965 break;
4966 case 28:
4967 switch (sel) {
4968 case 0:
4969 case 2:
4970 case 4:
4971 case 6:
4972 gen_helper_mtc0_taglo(t0);
4973 rn = "TagLo";
4974 break;
4975 case 1:
4976 case 3:
4977 case 5:
4978 case 7:
4979 gen_helper_mtc0_datalo(t0);
4980 rn = "DataLo";
4981 break;
4982 default:
4983 goto die;
4985 break;
4986 case 29:
4987 switch (sel) {
4988 case 0:
4989 case 2:
4990 case 4:
4991 case 6:
4992 gen_helper_mtc0_taghi(t0);
4993 rn = "TagHi";
4994 break;
4995 case 1:
4996 case 3:
4997 case 5:
4998 case 7:
4999 gen_helper_mtc0_datahi(t0);
5000 rn = "DataHi";
5001 break;
5002 default:
5003 rn = "invalid sel";
5004 goto die;
5006 break;
5007 case 30:
5008 switch (sel) {
5009 case 0:
5010 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5011 rn = "ErrorEPC";
5012 break;
5013 default:
5014 goto die;
5016 break;
5017 case 31:
5018 switch (sel) {
5019 case 0:
5020 /* EJTAG support */
5021 gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
5022 rn = "DESAVE";
5023 break;
5024 default:
5025 goto die;
5027 /* Stop translation as we may have switched the execution mode */
5028 ctx->bstate = BS_STOP;
5029 break;
5030 default:
5031 goto die;
5033 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5034 /* For simplicity assume that all writes can cause interrupts. */
5035 if (use_icount) {
5036 gen_io_end();
5037 ctx->bstate = BS_STOP;
5039 return;
5041 die:
5042 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5043 generate_exception(ctx, EXCP_RI);
5045 #endif /* TARGET_MIPS64 */
5047 static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5048 int u, int sel, int h)
5050 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5051 TCGv t0 = tcg_temp_local_new();
5053 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5054 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5055 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5056 tcg_gen_movi_tl(t0, -1);
5057 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5058 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5059 tcg_gen_movi_tl(t0, -1);
5060 else if (u == 0) {
5061 switch (rt) {
5062 case 2:
5063 switch (sel) {
5064 case 1:
5065 gen_helper_mftc0_tcstatus(t0);
5066 break;
5067 case 2:
5068 gen_helper_mftc0_tcbind(t0);
5069 break;
5070 case 3:
5071 gen_helper_mftc0_tcrestart(t0);
5072 break;
5073 case 4:
5074 gen_helper_mftc0_tchalt(t0);
5075 break;
5076 case 5:
5077 gen_helper_mftc0_tccontext(t0);
5078 break;
5079 case 6:
5080 gen_helper_mftc0_tcschedule(t0);
5081 break;
5082 case 7:
5083 gen_helper_mftc0_tcschefback(t0);
5084 break;
5085 default:
5086 gen_mfc0(env, ctx, t0, rt, sel);
5087 break;
5089 break;
5090 case 10:
5091 switch (sel) {
5092 case 0:
5093 gen_helper_mftc0_entryhi(t0);
5094 break;
5095 default:
5096 gen_mfc0(env, ctx, t0, rt, sel);
5097 break;
5099 case 12:
5100 switch (sel) {
5101 case 0:
5102 gen_helper_mftc0_status(t0);
5103 break;
5104 default:
5105 gen_mfc0(env, ctx, t0, rt, sel);
5106 break;
5108 case 23:
5109 switch (sel) {
5110 case 0:
5111 gen_helper_mftc0_debug(t0);
5112 break;
5113 default:
5114 gen_mfc0(env, ctx, t0, rt, sel);
5115 break;
5117 break;
5118 default:
5119 gen_mfc0(env, ctx, t0, rt, sel);
5121 } else switch (sel) {
5122 /* GPR registers. */
5123 case 0:
5124 gen_helper_1i(mftgpr, t0, rt);
5125 break;
5126 /* Auxiliary CPU registers */
5127 case 1:
5128 switch (rt) {
5129 case 0:
5130 gen_helper_1i(mftlo, t0, 0);
5131 break;
5132 case 1:
5133 gen_helper_1i(mfthi, t0, 0);
5134 break;
5135 case 2:
5136 gen_helper_1i(mftacx, t0, 0);
5137 break;
5138 case 4:
5139 gen_helper_1i(mftlo, t0, 1);
5140 break;
5141 case 5:
5142 gen_helper_1i(mfthi, t0, 1);
5143 break;
5144 case 6:
5145 gen_helper_1i(mftacx, t0, 1);
5146 break;
5147 case 8:
5148 gen_helper_1i(mftlo, t0, 2);
5149 break;
5150 case 9:
5151 gen_helper_1i(mfthi, t0, 2);
5152 break;
5153 case 10:
5154 gen_helper_1i(mftacx, t0, 2);
5155 break;
5156 case 12:
5157 gen_helper_1i(mftlo, t0, 3);
5158 break;
5159 case 13:
5160 gen_helper_1i(mfthi, t0, 3);
5161 break;
5162 case 14:
5163 gen_helper_1i(mftacx, t0, 3);
5164 break;
5165 case 16:
5166 gen_helper_mftdsp(t0);
5167 break;
5168 default:
5169 goto die;
5171 break;
5172 /* Floating point (COP1). */
5173 case 2:
5174 /* XXX: For now we support only a single FPU context. */
5175 if (h == 0) {
5176 TCGv_i32 fp0 = tcg_temp_new_i32();
5178 gen_load_fpr32(fp0, rt);
5179 tcg_gen_ext_i32_tl(t0, fp0);
5180 tcg_temp_free_i32(fp0);
5181 } else {
5182 TCGv_i32 fp0 = tcg_temp_new_i32();
5184 gen_load_fpr32h(fp0, rt);
5185 tcg_gen_ext_i32_tl(t0, fp0);
5186 tcg_temp_free_i32(fp0);
5188 break;
5189 case 3:
5190 /* XXX: For now we support only a single FPU context. */
5191 gen_helper_1i(cfc1, t0, rt);
5192 break;
5193 /* COP2: Not implemented. */
5194 case 4:
5195 case 5:
5196 /* fall through */
5197 default:
5198 goto die;
5200 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5201 gen_store_gpr(t0, rd);
5202 tcg_temp_free(t0);
5203 return;
5205 die:
5206 tcg_temp_free(t0);
5207 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5208 generate_exception(ctx, EXCP_RI);
5211 static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5212 int u, int sel, int h)
5214 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5215 TCGv t0 = tcg_temp_local_new();
5217 gen_load_gpr(t0, rt);
5218 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5219 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5220 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5221 /* NOP */ ;
5222 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5223 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5224 /* NOP */ ;
5225 else if (u == 0) {
5226 switch (rd) {
5227 case 2:
5228 switch (sel) {
5229 case 1:
5230 gen_helper_mttc0_tcstatus(t0);
5231 break;
5232 case 2:
5233 gen_helper_mttc0_tcbind(t0);
5234 break;
5235 case 3:
5236 gen_helper_mttc0_tcrestart(t0);
5237 break;
5238 case 4:
5239 gen_helper_mttc0_tchalt(t0);
5240 break;
5241 case 5:
5242 gen_helper_mttc0_tccontext(t0);
5243 break;
5244 case 6:
5245 gen_helper_mttc0_tcschedule(t0);
5246 break;
5247 case 7:
5248 gen_helper_mttc0_tcschefback(t0);
5249 break;
5250 default:
5251 gen_mtc0(env, ctx, t0, rd, sel);
5252 break;
5254 break;
5255 case 10:
5256 switch (sel) {
5257 case 0:
5258 gen_helper_mttc0_entryhi(t0);
5259 break;
5260 default:
5261 gen_mtc0(env, ctx, t0, rd, sel);
5262 break;
5264 case 12:
5265 switch (sel) {
5266 case 0:
5267 gen_helper_mttc0_status(t0);
5268 break;
5269 default:
5270 gen_mtc0(env, ctx, t0, rd, sel);
5271 break;
5273 case 23:
5274 switch (sel) {
5275 case 0:
5276 gen_helper_mttc0_debug(t0);
5277 break;
5278 default:
5279 gen_mtc0(env, ctx, t0, rd, sel);
5280 break;
5282 break;
5283 default:
5284 gen_mtc0(env, ctx, t0, rd, sel);
5286 } else switch (sel) {
5287 /* GPR registers. */
5288 case 0:
5289 gen_helper_1i(mttgpr, t0, rd);
5290 break;
5291 /* Auxiliary CPU registers */
5292 case 1:
5293 switch (rd) {
5294 case 0:
5295 gen_helper_1i(mttlo, t0, 0);
5296 break;
5297 case 1:
5298 gen_helper_1i(mtthi, t0, 0);
5299 break;
5300 case 2:
5301 gen_helper_1i(mttacx, t0, 0);
5302 break;
5303 case 4:
5304 gen_helper_1i(mttlo, t0, 1);
5305 break;
5306 case 5:
5307 gen_helper_1i(mtthi, t0, 1);
5308 break;
5309 case 6:
5310 gen_helper_1i(mttacx, t0, 1);
5311 break;
5312 case 8:
5313 gen_helper_1i(mttlo, t0, 2);
5314 break;
5315 case 9:
5316 gen_helper_1i(mtthi, t0, 2);
5317 break;
5318 case 10:
5319 gen_helper_1i(mttacx, t0, 2);
5320 break;
5321 case 12:
5322 gen_helper_1i(mttlo, t0, 3);
5323 break;
5324 case 13:
5325 gen_helper_1i(mtthi, t0, 3);
5326 break;
5327 case 14:
5328 gen_helper_1i(mttacx, t0, 3);
5329 break;
5330 case 16:
5331 gen_helper_mttdsp(t0);
5332 break;
5333 default:
5334 goto die;
5336 break;
5337 /* Floating point (COP1). */
5338 case 2:
5339 /* XXX: For now we support only a single FPU context. */
5340 if (h == 0) {
5341 TCGv_i32 fp0 = tcg_temp_new_i32();
5343 tcg_gen_trunc_tl_i32(fp0, t0);
5344 gen_store_fpr32(fp0, rd);
5345 tcg_temp_free_i32(fp0);
5346 } else {
5347 TCGv_i32 fp0 = tcg_temp_new_i32();
5349 tcg_gen_trunc_tl_i32(fp0, t0);
5350 gen_store_fpr32h(fp0, rd);
5351 tcg_temp_free_i32(fp0);
5353 break;
5354 case 3:
5355 /* XXX: For now we support only a single FPU context. */
5356 gen_helper_1i(ctc1, t0, rd);
5357 break;
5358 /* COP2: Not implemented. */
5359 case 4:
5360 case 5:
5361 /* fall through */
5362 default:
5363 goto die;
5365 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5366 tcg_temp_free(t0);
5367 return;
5369 die:
5370 tcg_temp_free(t0);
5371 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5372 generate_exception(ctx, EXCP_RI);
5375 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5377 const char *opn = "ldst";
5379 switch (opc) {
5380 case OPC_MFC0:
5381 if (rt == 0) {
5382 /* Treat as NOP. */
5383 return;
5386 TCGv t0 = tcg_temp_local_new();
5388 gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5389 gen_store_gpr(t0, rt);
5390 tcg_temp_free(t0);
5392 opn = "mfc0";
5393 break;
5394 case OPC_MTC0:
5396 TCGv t0 = tcg_temp_local_new();
5398 gen_load_gpr(t0, rt);
5399 save_cpu_state(ctx, 1);
5400 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5401 tcg_temp_free(t0);
5403 opn = "mtc0";
5404 break;
5405 #if defined(TARGET_MIPS64)
5406 case OPC_DMFC0:
5407 check_insn(env, ctx, ISA_MIPS3);
5408 if (rt == 0) {
5409 /* Treat as NOP. */
5410 return;
5413 TCGv t0 = tcg_temp_local_new();
5415 gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5416 gen_store_gpr(t0, rt);
5417 tcg_temp_free(t0);
5419 opn = "dmfc0";
5420 break;
5421 case OPC_DMTC0:
5422 check_insn(env, ctx, ISA_MIPS3);
5424 TCGv t0 = tcg_temp_local_new();
5426 gen_load_gpr(t0, rt);
5427 save_cpu_state(ctx, 1);
5428 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5429 tcg_temp_free(t0);
5431 opn = "dmtc0";
5432 break;
5433 #endif
5434 case OPC_MFTR:
5435 check_insn(env, ctx, ASE_MT);
5436 if (rd == 0) {
5437 /* Treat as NOP. */
5438 return;
5440 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5441 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5442 opn = "mftr";
5443 break;
5444 case OPC_MTTR:
5445 check_insn(env, ctx, ASE_MT);
5446 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5447 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5448 opn = "mttr";
5449 break;
5450 case OPC_TLBWI:
5451 opn = "tlbwi";
5452 if (!env->tlb->helper_tlbwi)
5453 goto die;
5454 gen_helper_tlbwi();
5455 break;
5456 case OPC_TLBWR:
5457 opn = "tlbwr";
5458 if (!env->tlb->helper_tlbwr)
5459 goto die;
5460 gen_helper_tlbwr();
5461 break;
5462 case OPC_TLBP:
5463 opn = "tlbp";
5464 if (!env->tlb->helper_tlbp)
5465 goto die;
5466 gen_helper_tlbp();
5467 break;
5468 case OPC_TLBR:
5469 opn = "tlbr";
5470 if (!env->tlb->helper_tlbr)
5471 goto die;
5472 gen_helper_tlbr();
5473 break;
5474 case OPC_ERET:
5475 opn = "eret";
5476 check_insn(env, ctx, ISA_MIPS2);
5477 save_cpu_state(ctx, 1);
5478 gen_helper_eret();
5479 ctx->bstate = BS_EXCP;
5480 break;
5481 case OPC_DERET:
5482 opn = "deret";
5483 check_insn(env, ctx, ISA_MIPS32);
5484 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5485 MIPS_INVAL(opn);
5486 generate_exception(ctx, EXCP_RI);
5487 } else {
5488 save_cpu_state(ctx, 1);
5489 gen_helper_deret();
5490 ctx->bstate = BS_EXCP;
5492 break;
5493 case OPC_WAIT:
5494 opn = "wait";
5495 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5496 /* If we get an exception, we want to restart at next instruction */
5497 ctx->pc += 4;
5498 save_cpu_state(ctx, 1);
5499 ctx->pc -= 4;
5500 gen_helper_wait();
5501 ctx->bstate = BS_EXCP;
5502 break;
5503 default:
5504 die:
5505 MIPS_INVAL(opn);
5506 generate_exception(ctx, EXCP_RI);
5507 return;
5509 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5511 #endif /* !CONFIG_USER_ONLY */
5513 /* CP1 Branches (before delay slot) */
5514 static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5515 int32_t cc, int32_t offset)
5517 target_ulong btarget;
5518 const char *opn = "cp1 cond branch";
5519 TCGv_i32 t0 = tcg_temp_new_i32();
5521 if (cc != 0)
5522 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5524 btarget = ctx->pc + 4 + offset;
5526 switch (op) {
5527 case OPC_BC1F:
5529 int l1 = gen_new_label();
5530 int l2 = gen_new_label();
5532 get_fp_cond(t0);
5533 tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5534 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5535 tcg_gen_movi_i32(bcond, 0);
5536 tcg_gen_br(l2);
5537 gen_set_label(l1);
5538 tcg_gen_movi_i32(bcond, 1);
5539 gen_set_label(l2);
5541 opn = "bc1f";
5542 goto not_likely;
5543 case OPC_BC1FL:
5545 int l1 = gen_new_label();
5546 int l2 = gen_new_label();
5548 get_fp_cond(t0);
5549 tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5550 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5551 tcg_gen_movi_i32(bcond, 0);
5552 tcg_gen_br(l2);
5553 gen_set_label(l1);
5554 tcg_gen_movi_i32(bcond, 1);
5555 gen_set_label(l2);
5557 opn = "bc1fl";
5558 goto likely;
5559 case OPC_BC1T:
5561 int l1 = gen_new_label();
5562 int l2 = gen_new_label();
5564 get_fp_cond(t0);
5565 tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5566 tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5567 tcg_gen_movi_i32(bcond, 0);
5568 tcg_gen_br(l2);
5569 gen_set_label(l1);
5570 tcg_gen_movi_i32(bcond, 1);
5571 gen_set_label(l2);
5573 opn = "bc1t";
5574 goto not_likely;
5575 case OPC_BC1TL:
5577 int l1 = gen_new_label();
5578 int l2 = gen_new_label();
5580 get_fp_cond(t0);
5581 tcg_gen_andi_i32(t0, t0, 0x1 << cc);
5582 tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5583 tcg_gen_movi_i32(bcond, 0);
5584 tcg_gen_br(l2);
5585 gen_set_label(l1);
5586 tcg_gen_movi_i32(bcond, 1);
5587 gen_set_label(l2);
5589 opn = "bc1tl";
5590 likely:
5591 ctx->hflags |= MIPS_HFLAG_BL;
5592 break;
5593 case OPC_BC1FANY2:
5595 int l1 = gen_new_label();
5596 int l2 = gen_new_label();
5598 get_fp_cond(t0);
5599 tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5600 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5601 tcg_gen_movi_i32(bcond, 0);
5602 tcg_gen_br(l2);
5603 gen_set_label(l1);
5604 tcg_gen_movi_i32(bcond, 1);
5605 gen_set_label(l2);
5607 opn = "bc1any2f";
5608 goto not_likely;
5609 case OPC_BC1TANY2:
5611 int l1 = gen_new_label();
5612 int l2 = gen_new_label();
5614 get_fp_cond(t0);
5615 tcg_gen_andi_i32(t0, t0, 0x3 << cc);
5616 tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5617 tcg_gen_movi_i32(bcond, 0);
5618 tcg_gen_br(l2);
5619 gen_set_label(l1);
5620 tcg_gen_movi_i32(bcond, 1);
5621 gen_set_label(l2);
5623 opn = "bc1any2t";
5624 goto not_likely;
5625 case OPC_BC1FANY4:
5627 int l1 = gen_new_label();
5628 int l2 = gen_new_label();
5630 get_fp_cond(t0);
5631 tcg_gen_andi_i32(t0, t0, 0xf << cc);
5632 tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
5633 tcg_gen_movi_i32(bcond, 0);
5634 tcg_gen_br(l2);
5635 gen_set_label(l1);
5636 tcg_gen_movi_i32(bcond, 1);
5637 gen_set_label(l2);
5639 opn = "bc1any4f";
5640 goto not_likely;
5641 case OPC_BC1TANY4:
5643 int l1 = gen_new_label();
5644 int l2 = gen_new_label();
5646 get_fp_cond(t0);
5647 tcg_gen_andi_i32(t0, t0, 0xf << cc);
5648 tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
5649 tcg_gen_movi_i32(bcond, 0);
5650 tcg_gen_br(l2);
5651 gen_set_label(l1);
5652 tcg_gen_movi_i32(bcond, 1);
5653 gen_set_label(l2);
5655 opn = "bc1any4t";
5656 not_likely:
5657 ctx->hflags |= MIPS_HFLAG_BC;
5658 break;
5659 default:
5660 MIPS_INVAL(opn);
5661 generate_exception (ctx, EXCP_RI);
5662 goto out;
5664 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5665 ctx->hflags, btarget);
5666 ctx->btarget = btarget;
5668 out:
5669 tcg_temp_free_i32(t0);
5672 /* Coprocessor 1 (FPU) */
5674 #define FOP(func, fmt) (((fmt) << 21) | (func))
5676 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5678 const char *opn = "cp1 move";
5679 TCGv t0 = tcg_temp_local_new();
5681 switch (opc) {
5682 case OPC_MFC1:
5684 TCGv_i32 fp0 = tcg_temp_new_i32();
5686 gen_load_fpr32(fp0, fs);
5687 tcg_gen_ext_i32_tl(t0, fp0);
5688 tcg_temp_free_i32(fp0);
5690 gen_store_gpr(t0, rt);
5691 opn = "mfc1";
5692 break;
5693 case OPC_MTC1:
5694 gen_load_gpr(t0, rt);
5696 TCGv_i32 fp0 = tcg_temp_new_i32();
5698 tcg_gen_trunc_tl_i32(fp0, t0);
5699 gen_store_fpr32(fp0, fs);
5700 tcg_temp_free_i32(fp0);
5702 opn = "mtc1";
5703 break;
5704 case OPC_CFC1:
5705 gen_helper_1i(cfc1, t0, fs);
5706 gen_store_gpr(t0, rt);
5707 opn = "cfc1";
5708 break;
5709 case OPC_CTC1:
5710 gen_load_gpr(t0, rt);
5711 gen_helper_1i(ctc1, t0, fs);
5712 opn = "ctc1";
5713 break;
5714 case OPC_DMFC1:
5716 TCGv_i64 fp0 = tcg_temp_new_i64();
5718 gen_load_fpr64(ctx, fp0, fs);
5719 tcg_gen_trunc_i64_tl(t0, fp0);
5720 tcg_temp_free_i64(fp0);
5722 gen_store_gpr(t0, rt);
5723 opn = "dmfc1";
5724 break;
5725 case OPC_DMTC1:
5726 gen_load_gpr(t0, rt);
5728 TCGv_i64 fp0 = tcg_temp_new_i64();
5730 tcg_gen_extu_tl_i64(fp0, t0);
5731 gen_store_fpr64(ctx, fp0, fs);
5732 tcg_temp_free_i64(fp0);
5734 opn = "dmtc1";
5735 break;
5736 case OPC_MFHC1:
5738 TCGv_i32 fp0 = tcg_temp_new_i32();
5740 gen_load_fpr32h(fp0, fs);
5741 tcg_gen_ext_i32_tl(t0, fp0);
5742 tcg_temp_free_i32(fp0);
5744 gen_store_gpr(t0, rt);
5745 opn = "mfhc1";
5746 break;
5747 case OPC_MTHC1:
5748 gen_load_gpr(t0, rt);
5750 TCGv_i32 fp0 = tcg_temp_new_i32();
5752 tcg_gen_trunc_tl_i32(fp0, t0);
5753 gen_store_fpr32h(fp0, fs);
5754 tcg_temp_free_i32(fp0);
5756 opn = "mthc1";
5757 break;
5758 default:
5759 MIPS_INVAL(opn);
5760 generate_exception (ctx, EXCP_RI);
5761 goto out;
5763 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5765 out:
5766 tcg_temp_free(t0);
5769 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5771 int l1 = gen_new_label();
5772 uint32_t ccbit;
5773 TCGCond cond;
5774 TCGv t0 = tcg_temp_local_new();
5775 TCGv_i32 r_tmp = tcg_temp_new_i32();
5777 if (cc)
5778 ccbit = 1 << (24 + cc);
5779 else
5780 ccbit = 1 << 23;
5781 if (tf)
5782 cond = TCG_COND_EQ;
5783 else
5784 cond = TCG_COND_NE;
5786 gen_load_gpr(t0, rd);
5787 tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
5788 tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5789 tcg_temp_free_i32(r_tmp);
5790 gen_load_gpr(t0, rs);
5791 gen_set_label(l1);
5792 gen_store_gpr(t0, rd);
5793 tcg_temp_free(t0);
5796 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5798 uint32_t ccbit;
5799 int cond;
5800 TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5801 TCGv_i32 fp0 = tcg_temp_local_new_i32();
5802 int l1 = gen_new_label();
5804 if (cc)
5805 ccbit = 1 << (24 + cc);
5806 else
5807 ccbit = 1 << 23;
5809 if (tf)
5810 cond = TCG_COND_EQ;
5811 else
5812 cond = TCG_COND_NE;
5814 gen_load_fpr32(fp0, fd);
5815 tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5816 tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5817 tcg_temp_free_i32(r_tmp1);
5818 gen_load_fpr32(fp0, fs);
5819 gen_set_label(l1);
5820 gen_store_fpr32(fp0, fd);
5821 tcg_temp_free_i32(fp0);
5824 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5826 uint32_t ccbit;
5827 int cond;
5828 TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5829 TCGv_i64 fp0 = tcg_temp_local_new_i64();
5830 int l1 = gen_new_label();
5832 if (cc)
5833 ccbit = 1 << (24 + cc);
5834 else
5835 ccbit = 1 << 23;
5837 if (tf)
5838 cond = TCG_COND_EQ;
5839 else
5840 cond = TCG_COND_NE;
5842 gen_load_fpr64(ctx, fp0, fd);
5843 tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5844 tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5845 tcg_temp_free_i32(r_tmp1);
5846 gen_load_fpr64(ctx, fp0, fs);
5847 gen_set_label(l1);
5848 gen_store_fpr64(ctx, fp0, fd);
5849 tcg_temp_free_i64(fp0);
5852 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5854 uint32_t ccbit1, ccbit2;
5855 int cond;
5856 TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5857 TCGv_i32 fp0 = tcg_temp_local_new_i32();
5858 int l1 = gen_new_label();
5859 int l2 = gen_new_label();
5861 if (cc) {
5862 ccbit1 = 1 << (24 + cc);
5863 ccbit2 = 1 << (25 + cc);
5864 } else {
5865 ccbit1 = 1 << 23;
5866 ccbit2 = 1 << 25;
5869 if (tf)
5870 cond = TCG_COND_EQ;
5871 else
5872 cond = TCG_COND_NE;
5874 gen_load_fpr32(fp0, fd);
5875 tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
5876 tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5877 gen_load_fpr32(fp0, fs);
5878 gen_set_label(l1);
5879 gen_store_fpr32(fp0, fd);
5881 gen_load_fpr32h(fp0, fd);
5882 tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
5883 tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
5884 gen_load_fpr32h(fp0, fs);
5885 gen_set_label(l2);
5886 gen_store_fpr32h(fp0, fd);
5888 tcg_temp_free_i32(r_tmp1);
5889 tcg_temp_free_i32(fp0);
5893 static void gen_farith (DisasContext *ctx, uint32_t op1,
5894 int ft, int fs, int fd, int cc)
5896 const char *opn = "farith";
5897 const char *condnames[] = {
5898 "c.f",
5899 "c.un",
5900 "c.eq",
5901 "c.ueq",
5902 "c.olt",
5903 "c.ult",
5904 "c.ole",
5905 "c.ule",
5906 "c.sf",
5907 "c.ngle",
5908 "c.seq",
5909 "c.ngl",
5910 "c.lt",
5911 "c.nge",
5912 "c.le",
5913 "c.ngt",
5915 const char *condnames_abs[] = {
5916 "cabs.f",
5917 "cabs.un",
5918 "cabs.eq",
5919 "cabs.ueq",
5920 "cabs.olt",
5921 "cabs.ult",
5922 "cabs.ole",
5923 "cabs.ule",
5924 "cabs.sf",
5925 "cabs.ngle",
5926 "cabs.seq",
5927 "cabs.ngl",
5928 "cabs.lt",
5929 "cabs.nge",
5930 "cabs.le",
5931 "cabs.ngt",
5933 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5934 uint32_t func = ctx->opcode & 0x3f;
5936 switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5937 case FOP(0, 16):
5939 TCGv_i32 fp0 = tcg_temp_new_i32();
5940 TCGv_i32 fp1 = tcg_temp_new_i32();
5942 gen_load_fpr32(fp0, fs);
5943 gen_load_fpr32(fp1, ft);
5944 gen_helper_float_add_s(fp0, fp0, fp1);
5945 tcg_temp_free_i32(fp1);
5946 gen_store_fpr32(fp0, fd);
5947 tcg_temp_free_i32(fp0);
5949 opn = "add.s";
5950 optype = BINOP;
5951 break;
5952 case FOP(1, 16):
5954 TCGv_i32 fp0 = tcg_temp_new_i32();
5955 TCGv_i32 fp1 = tcg_temp_new_i32();
5957 gen_load_fpr32(fp0, fs);
5958 gen_load_fpr32(fp1, ft);
5959 gen_helper_float_sub_s(fp0, fp0, fp1);
5960 tcg_temp_free_i32(fp1);
5961 gen_store_fpr32(fp0, fd);
5962 tcg_temp_free_i32(fp0);
5964 opn = "sub.s";
5965 optype = BINOP;
5966 break;
5967 case FOP(2, 16):
5969 TCGv_i32 fp0 = tcg_temp_new_i32();
5970 TCGv_i32 fp1 = tcg_temp_new_i32();
5972 gen_load_fpr32(fp0, fs);
5973 gen_load_fpr32(fp1, ft);
5974 gen_helper_float_mul_s(fp0, fp0, fp1);
5975 tcg_temp_free_i32(fp1);
5976 gen_store_fpr32(fp0, fd);
5977 tcg_temp_free_i32(fp0);
5979 opn = "mul.s";
5980 optype = BINOP;
5981 break;
5982 case FOP(3, 16):
5984 TCGv_i32 fp0 = tcg_temp_new_i32();
5985 TCGv_i32 fp1 = tcg_temp_new_i32();
5987 gen_load_fpr32(fp0, fs);
5988 gen_load_fpr32(fp1, ft);
5989 gen_helper_float_div_s(fp0, fp0, fp1);
5990 tcg_temp_free_i32(fp1);
5991 gen_store_fpr32(fp0, fd);
5992 tcg_temp_free_i32(fp0);
5994 opn = "div.s";
5995 optype = BINOP;
5996 break;
5997 case FOP(4, 16):
5999 TCGv_i32 fp0 = tcg_temp_new_i32();
6001 gen_load_fpr32(fp0, fs);
6002 gen_helper_float_sqrt_s(fp0, fp0);
6003 gen_store_fpr32(fp0, fd);
6004 tcg_temp_free_i32(fp0);
6006 opn = "sqrt.s";
6007 break;
6008 case FOP(5, 16):
6010 TCGv_i32 fp0 = tcg_temp_new_i32();
6012 gen_load_fpr32(fp0, fs);
6013 gen_helper_float_abs_s(fp0, fp0);
6014 gen_store_fpr32(fp0, fd);
6015 tcg_temp_free_i32(fp0);
6017 opn = "abs.s";
6018 break;
6019 case FOP(6, 16):
6021 TCGv_i32 fp0 = tcg_temp_new_i32();
6023 gen_load_fpr32(fp0, fs);
6024 gen_store_fpr32(fp0, fd);
6025 tcg_temp_free_i32(fp0);
6027 opn = "mov.s";
6028 break;
6029 case FOP(7, 16):
6031 TCGv_i32 fp0 = tcg_temp_new_i32();
6033 gen_load_fpr32(fp0, fs);
6034 gen_helper_float_chs_s(fp0, fp0);
6035 gen_store_fpr32(fp0, fd);
6036 tcg_temp_free_i32(fp0);
6038 opn = "neg.s";
6039 break;
6040 case FOP(8, 16):
6041 check_cp1_64bitmode(ctx);
6043 TCGv_i32 fp32 = tcg_temp_new_i32();
6044 TCGv_i64 fp64 = tcg_temp_new_i64();
6046 gen_load_fpr32(fp32, fs);
6047 gen_helper_float_roundl_s(fp64, fp32);
6048 tcg_temp_free_i32(fp32);
6049 gen_store_fpr64(ctx, fp64, fd);
6050 tcg_temp_free_i64(fp64);
6052 opn = "round.l.s";
6053 break;
6054 case FOP(9, 16):
6055 check_cp1_64bitmode(ctx);
6057 TCGv_i32 fp32 = tcg_temp_new_i32();
6058 TCGv_i64 fp64 = tcg_temp_new_i64();
6060 gen_load_fpr32(fp32, fs);
6061 gen_helper_float_truncl_s(fp64, fp32);
6062 tcg_temp_free_i32(fp32);
6063 gen_store_fpr64(ctx, fp64, fd);
6064 tcg_temp_free_i64(fp64);
6066 opn = "trunc.l.s";
6067 break;
6068 case FOP(10, 16):
6069 check_cp1_64bitmode(ctx);
6071 TCGv_i32 fp32 = tcg_temp_new_i32();
6072 TCGv_i64 fp64 = tcg_temp_new_i64();
6074 gen_load_fpr32(fp32, fs);
6075 gen_helper_float_ceill_s(fp64, fp32);
6076 tcg_temp_free_i32(fp32);
6077 gen_store_fpr64(ctx, fp64, fd);
6078 tcg_temp_free_i64(fp64);
6080 opn = "ceil.l.s";
6081 break;
6082 case FOP(11, 16):
6083 check_cp1_64bitmode(ctx);
6085 TCGv_i32 fp32 = tcg_temp_new_i32();
6086 TCGv_i64 fp64 = tcg_temp_new_i64();
6088 gen_load_fpr32(fp32, fs);
6089 gen_helper_float_floorl_s(fp64, fp32);
6090 tcg_temp_free_i32(fp32);
6091 gen_store_fpr64(ctx, fp64, fd);
6092 tcg_temp_free_i64(fp64);
6094 opn = "floor.l.s";
6095 break;
6096 case FOP(12, 16):
6098 TCGv_i32 fp0 = tcg_temp_new_i32();
6100 gen_load_fpr32(fp0, fs);
6101 gen_helper_float_roundw_s(fp0, fp0);
6102 gen_store_fpr32(fp0, fd);
6103 tcg_temp_free_i32(fp0);
6105 opn = "round.w.s";
6106 break;
6107 case FOP(13, 16):
6109 TCGv_i32 fp0 = tcg_temp_new_i32();
6111 gen_load_fpr32(fp0, fs);
6112 gen_helper_float_truncw_s(fp0, fp0);
6113 gen_store_fpr32(fp0, fd);
6114 tcg_temp_free_i32(fp0);
6116 opn = "trunc.w.s";
6117 break;
6118 case FOP(14, 16):
6120 TCGv_i32 fp0 = tcg_temp_new_i32();
6122 gen_load_fpr32(fp0, fs);
6123 gen_helper_float_ceilw_s(fp0, fp0);
6124 gen_store_fpr32(fp0, fd);
6125 tcg_temp_free_i32(fp0);
6127 opn = "ceil.w.s";
6128 break;
6129 case FOP(15, 16):
6131 TCGv_i32 fp0 = tcg_temp_new_i32();
6133 gen_load_fpr32(fp0, fs);
6134 gen_helper_float_floorw_s(fp0, fp0);
6135 gen_store_fpr32(fp0, fd);
6136 tcg_temp_free_i32(fp0);
6138 opn = "floor.w.s";
6139 break;
6140 case FOP(17, 16):
6141 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6142 opn = "movcf.s";
6143 break;
6144 case FOP(18, 16):
6146 int l1 = gen_new_label();
6147 TCGv t0 = tcg_temp_new();
6148 TCGv_i32 fp0 = tcg_temp_local_new_i32();
6150 gen_load_gpr(t0, ft);
6151 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6152 gen_load_fpr32(fp0, fs);
6153 gen_store_fpr32(fp0, fd);
6154 tcg_temp_free_i32(fp0);
6155 gen_set_label(l1);
6156 tcg_temp_free(t0);
6158 opn = "movz.s";
6159 break;
6160 case FOP(19, 16):
6162 int l1 = gen_new_label();
6163 TCGv t0 = tcg_temp_new();
6164 TCGv_i32 fp0 = tcg_temp_local_new_i32();
6166 gen_load_gpr(t0, ft);
6167 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6168 gen_load_fpr32(fp0, fs);
6169 gen_store_fpr32(fp0, fd);
6170 tcg_temp_free_i32(fp0);
6171 gen_set_label(l1);
6172 tcg_temp_free(t0);
6174 opn = "movn.s";
6175 break;
6176 case FOP(21, 16):
6177 check_cop1x(ctx);
6179 TCGv_i32 fp0 = tcg_temp_new_i32();
6181 gen_load_fpr32(fp0, fs);
6182 gen_helper_float_recip_s(fp0, fp0);
6183 gen_store_fpr32(fp0, fd);
6184 tcg_temp_free_i32(fp0);
6186 opn = "recip.s";
6187 break;
6188 case FOP(22, 16):
6189 check_cop1x(ctx);
6191 TCGv_i32 fp0 = tcg_temp_new_i32();
6193 gen_load_fpr32(fp0, fs);
6194 gen_helper_float_rsqrt_s(fp0, fp0);
6195 gen_store_fpr32(fp0, fd);
6196 tcg_temp_free_i32(fp0);
6198 opn = "rsqrt.s";
6199 break;
6200 case FOP(28, 16):
6201 check_cp1_64bitmode(ctx);
6203 TCGv_i32 fp0 = tcg_temp_new_i32();
6204 TCGv_i32 fp1 = tcg_temp_new_i32();
6206 gen_load_fpr32(fp0, fs);
6207 gen_load_fpr32(fp1, fd);
6208 gen_helper_float_recip2_s(fp0, fp0, fp1);
6209 tcg_temp_free_i32(fp1);
6210 gen_store_fpr32(fp0, fd);
6211 tcg_temp_free_i32(fp0);
6213 opn = "recip2.s";
6214 break;
6215 case FOP(29, 16):
6216 check_cp1_64bitmode(ctx);
6218 TCGv_i32 fp0 = tcg_temp_new_i32();
6220 gen_load_fpr32(fp0, fs);
6221 gen_helper_float_recip1_s(fp0, fp0);
6222 gen_store_fpr32(fp0, fd);
6223 tcg_temp_free_i32(fp0);
6225 opn = "recip1.s";
6226 break;
6227 case FOP(30, 16):
6228 check_cp1_64bitmode(ctx);
6230 TCGv_i32 fp0 = tcg_temp_new_i32();
6232 gen_load_fpr32(fp0, fs);
6233 gen_helper_float_rsqrt1_s(fp0, fp0);
6234 gen_store_fpr32(fp0, fd);
6235 tcg_temp_free_i32(fp0);
6237 opn = "rsqrt1.s";
6238 break;
6239 case FOP(31, 16):
6240 check_cp1_64bitmode(ctx);
6242 TCGv_i32 fp0 = tcg_temp_new_i32();
6243 TCGv_i32 fp1 = tcg_temp_new_i32();
6245 gen_load_fpr32(fp0, fs);
6246 gen_load_fpr32(fp1, ft);
6247 gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6248 tcg_temp_free_i32(fp1);
6249 gen_store_fpr32(fp0, fd);
6250 tcg_temp_free_i32(fp0);
6252 opn = "rsqrt2.s";
6253 break;
6254 case FOP(33, 16):
6255 check_cp1_registers(ctx, fd);
6257 TCGv_i32 fp32 = tcg_temp_new_i32();
6258 TCGv_i64 fp64 = tcg_temp_new_i64();
6260 gen_load_fpr32(fp32, fs);
6261 gen_helper_float_cvtd_s(fp64, fp32);
6262 tcg_temp_free_i32(fp32);
6263 gen_store_fpr64(ctx, fp64, fd);
6264 tcg_temp_free_i64(fp64);
6266 opn = "cvt.d.s";
6267 break;
6268 case FOP(36, 16):
6270 TCGv_i32 fp0 = tcg_temp_new_i32();
6272 gen_load_fpr32(fp0, fs);
6273 gen_helper_float_cvtw_s(fp0, fp0);
6274 gen_store_fpr32(fp0, fd);
6275 tcg_temp_free_i32(fp0);
6277 opn = "cvt.w.s";
6278 break;
6279 case FOP(37, 16):
6280 check_cp1_64bitmode(ctx);
6282 TCGv_i32 fp32 = tcg_temp_new_i32();
6283 TCGv_i64 fp64 = tcg_temp_new_i64();
6285 gen_load_fpr32(fp32, fs);
6286 gen_helper_float_cvtl_s(fp64, fp32);
6287 tcg_temp_free_i32(fp32);
6288 gen_store_fpr64(ctx, fp64, fd);
6289 tcg_temp_free_i64(fp64);
6291 opn = "cvt.l.s";
6292 break;
6293 case FOP(38, 16):
6294 check_cp1_64bitmode(ctx);
6296 TCGv_i64 fp64 = tcg_temp_new_i64();
6297 TCGv_i32 fp32_0 = tcg_temp_new_i32();
6298 TCGv_i32 fp32_1 = tcg_temp_new_i32();
6300 gen_load_fpr32(fp32_0, fs);
6301 gen_load_fpr32(fp32_1, ft);
6302 tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6303 tcg_temp_free_i32(fp32_1);
6304 tcg_temp_free_i32(fp32_0);
6305 gen_store_fpr64(ctx, fp64, fd);
6306 tcg_temp_free_i64(fp64);
6308 opn = "cvt.ps.s";
6309 break;
6310 case FOP(48, 16):
6311 case FOP(49, 16):
6312 case FOP(50, 16):
6313 case FOP(51, 16):
6314 case FOP(52, 16):
6315 case FOP(53, 16):
6316 case FOP(54, 16):
6317 case FOP(55, 16):
6318 case FOP(56, 16):
6319 case FOP(57, 16):
6320 case FOP(58, 16):
6321 case FOP(59, 16):
6322 case FOP(60, 16):
6323 case FOP(61, 16):
6324 case FOP(62, 16):
6325 case FOP(63, 16):
6327 TCGv_i32 fp0 = tcg_temp_new_i32();
6328 TCGv_i32 fp1 = tcg_temp_new_i32();
6330 gen_load_fpr32(fp0, fs);
6331 gen_load_fpr32(fp1, ft);
6332 if (ctx->opcode & (1 << 6)) {
6333 check_cop1x(ctx);
6334 gen_cmpabs_s(func-48, fp0, fp1, cc);
6335 opn = condnames_abs[func-48];
6336 } else {
6337 gen_cmp_s(func-48, fp0, fp1, cc);
6338 opn = condnames[func-48];
6340 tcg_temp_free_i32(fp0);
6341 tcg_temp_free_i32(fp1);
6343 break;
6344 case FOP(0, 17):
6345 check_cp1_registers(ctx, fs | ft | fd);
6347 TCGv_i64 fp0 = tcg_temp_new_i64();
6348 TCGv_i64 fp1 = tcg_temp_new_i64();
6350 gen_load_fpr64(ctx, fp0, fs);
6351 gen_load_fpr64(ctx, fp1, ft);
6352 gen_helper_float_add_d(fp0, fp0, fp1);
6353 tcg_temp_free_i64(fp1);
6354 gen_store_fpr64(ctx, fp0, fd);
6355 tcg_temp_free_i64(fp0);
6357 opn = "add.d";
6358 optype = BINOP;
6359 break;
6360 case FOP(1, 17):
6361 check_cp1_registers(ctx, fs | ft | fd);
6363 TCGv_i64 fp0 = tcg_temp_new_i64();
6364 TCGv_i64 fp1 = tcg_temp_new_i64();
6366 gen_load_fpr64(ctx, fp0, fs);
6367 gen_load_fpr64(ctx, fp1, ft);
6368 gen_helper_float_sub_d(fp0, fp0, fp1);
6369 tcg_temp_free_i64(fp1);
6370 gen_store_fpr64(ctx, fp0, fd);
6371 tcg_temp_free_i64(fp0);
6373 opn = "sub.d";
6374 optype = BINOP;
6375 break;
6376 case FOP(2, 17):
6377 check_cp1_registers(ctx, fs | ft | fd);
6379 TCGv_i64 fp0 = tcg_temp_new_i64();
6380 TCGv_i64 fp1 = tcg_temp_new_i64();
6382 gen_load_fpr64(ctx, fp0, fs);
6383 gen_load_fpr64(ctx, fp1, ft);
6384 gen_helper_float_mul_d(fp0, fp0, fp1);
6385 tcg_temp_free_i64(fp1);
6386 gen_store_fpr64(ctx, fp0, fd);
6387 tcg_temp_free_i64(fp0);
6389 opn = "mul.d";
6390 optype = BINOP;
6391 break;
6392 case FOP(3, 17):
6393 check_cp1_registers(ctx, fs | ft | fd);
6395 TCGv_i64 fp0 = tcg_temp_new_i64();
6396 TCGv_i64 fp1 = tcg_temp_new_i64();
6398 gen_load_fpr64(ctx, fp0, fs);
6399 gen_load_fpr64(ctx, fp1, ft);
6400 gen_helper_float_div_d(fp0, fp0, fp1);
6401 tcg_temp_free_i64(fp1);
6402 gen_store_fpr64(ctx, fp0, fd);
6403 tcg_temp_free_i64(fp0);
6405 opn = "div.d";
6406 optype = BINOP;
6407 break;
6408 case FOP(4, 17):
6409 check_cp1_registers(ctx, fs | fd);
6411 TCGv_i64 fp0 = tcg_temp_new_i64();
6413 gen_load_fpr64(ctx, fp0, fs);
6414 gen_helper_float_sqrt_d(fp0, fp0);
6415 gen_store_fpr64(ctx, fp0, fd);
6416 tcg_temp_free_i64(fp0);
6418 opn = "sqrt.d";
6419 break;
6420 case FOP(5, 17):
6421 check_cp1_registers(ctx, fs | fd);
6423 TCGv_i64 fp0 = tcg_temp_new_i64();
6425 gen_load_fpr64(ctx, fp0, fs);
6426 gen_helper_float_abs_d(fp0, fp0);
6427 gen_store_fpr64(ctx, fp0, fd);
6428 tcg_temp_free_i64(fp0);
6430 opn = "abs.d";
6431 break;
6432 case FOP(6, 17):
6433 check_cp1_registers(ctx, fs | fd);
6435 TCGv_i64 fp0 = tcg_temp_new_i64();
6437 gen_load_fpr64(ctx, fp0, fs);
6438 gen_store_fpr64(ctx, fp0, fd);
6439 tcg_temp_free_i64(fp0);
6441 opn = "mov.d";
6442 break;
6443 case FOP(7, 17):
6444 check_cp1_registers(ctx, fs | fd);
6446 TCGv_i64 fp0 = tcg_temp_new_i64();
6448 gen_load_fpr64(ctx, fp0, fs);
6449 gen_helper_float_chs_d(fp0, fp0);
6450 gen_store_fpr64(ctx, fp0, fd);
6451 tcg_temp_free_i64(fp0);
6453 opn = "neg.d";
6454 break;
6455 case FOP(8, 17):
6456 check_cp1_64bitmode(ctx);
6458 TCGv_i64 fp0 = tcg_temp_new_i64();
6460 gen_load_fpr64(ctx, fp0, fs);
6461 gen_helper_float_roundl_d(fp0, fp0);
6462 gen_store_fpr64(ctx, fp0, fd);
6463 tcg_temp_free_i64(fp0);
6465 opn = "round.l.d";
6466 break;
6467 case FOP(9, 17):
6468 check_cp1_64bitmode(ctx);
6470 TCGv_i64 fp0 = tcg_temp_new_i64();
6472 gen_load_fpr64(ctx, fp0, fs);
6473 gen_helper_float_truncl_d(fp0, fp0);
6474 gen_store_fpr64(ctx, fp0, fd);
6475 tcg_temp_free_i64(fp0);
6477 opn = "trunc.l.d";
6478 break;
6479 case FOP(10, 17):
6480 check_cp1_64bitmode(ctx);
6482 TCGv_i64 fp0 = tcg_temp_new_i64();
6484 gen_load_fpr64(ctx, fp0, fs);
6485 gen_helper_float_ceill_d(fp0, fp0);
6486 gen_store_fpr64(ctx, fp0, fd);
6487 tcg_temp_free_i64(fp0);
6489 opn = "ceil.l.d";
6490 break;
6491 case FOP(11, 17):
6492 check_cp1_64bitmode(ctx);
6494 TCGv_i64 fp0 = tcg_temp_new_i64();
6496 gen_load_fpr64(ctx, fp0, fs);
6497 gen_helper_float_floorl_d(fp0, fp0);
6498 gen_store_fpr64(ctx, fp0, fd);
6499 tcg_temp_free_i64(fp0);
6501 opn = "floor.l.d";
6502 break;
6503 case FOP(12, 17):
6504 check_cp1_registers(ctx, fs);
6506 TCGv_i32 fp32 = tcg_temp_new_i32();
6507 TCGv_i64 fp64 = tcg_temp_new_i64();
6509 gen_load_fpr64(ctx, fp64, fs);
6510 gen_helper_float_roundw_d(fp32, fp64);
6511 tcg_temp_free_i64(fp64);
6512 gen_store_fpr32(fp32, fd);
6513 tcg_temp_free_i32(fp32);
6515 opn = "round.w.d";
6516 break;
6517 case FOP(13, 17):
6518 check_cp1_registers(ctx, fs);
6520 TCGv_i32 fp32 = tcg_temp_new_i32();
6521 TCGv_i64 fp64 = tcg_temp_new_i64();
6523 gen_load_fpr64(ctx, fp64, fs);
6524 gen_helper_float_truncw_d(fp32, fp64);
6525 tcg_temp_free_i64(fp64);
6526 gen_store_fpr32(fp32, fd);
6527 tcg_temp_free_i32(fp32);
6529 opn = "trunc.w.d";
6530 break;
6531 case FOP(14, 17):
6532 check_cp1_registers(ctx, fs);
6534 TCGv_i32 fp32 = tcg_temp_new_i32();
6535 TCGv_i64 fp64 = tcg_temp_new_i64();
6537 gen_load_fpr64(ctx, fp64, fs);
6538 gen_helper_float_ceilw_d(fp32, fp64);
6539 tcg_temp_free_i64(fp64);
6540 gen_store_fpr32(fp32, fd);
6541 tcg_temp_free_i32(fp32);
6543 opn = "ceil.w.d";
6544 break;
6545 case FOP(15, 17):
6546 check_cp1_registers(ctx, fs);
6548 TCGv_i32 fp32 = tcg_temp_new_i32();
6549 TCGv_i64 fp64 = tcg_temp_new_i64();
6551 gen_load_fpr64(ctx, fp64, fs);
6552 gen_helper_float_floorw_d(fp32, fp64);
6553 tcg_temp_free_i64(fp64);
6554 gen_store_fpr32(fp32, fd);
6555 tcg_temp_free_i32(fp32);
6557 opn = "floor.w.d";
6558 break;
6559 case FOP(17, 17):
6560 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6561 opn = "movcf.d";
6562 break;
6563 case FOP(18, 17):
6565 int l1 = gen_new_label();
6566 TCGv t0 = tcg_temp_new();
6567 TCGv_i64 fp0 = tcg_temp_local_new_i64();
6569 gen_load_gpr(t0, ft);
6570 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6571 gen_load_fpr64(ctx, fp0, fs);
6572 gen_store_fpr64(ctx, fp0, fd);
6573 tcg_temp_free_i64(fp0);
6574 gen_set_label(l1);
6575 tcg_temp_free(t0);
6577 opn = "movz.d";
6578 break;
6579 case FOP(19, 17):
6581 int l1 = gen_new_label();
6582 TCGv t0 = tcg_temp_new();
6583 TCGv_i64 fp0 = tcg_temp_local_new_i64();
6585 gen_load_gpr(t0, ft);
6586 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6587 gen_load_fpr64(ctx, fp0, fs);
6588 gen_store_fpr64(ctx, fp0, fd);
6589 tcg_temp_free_i64(fp0);
6590 gen_set_label(l1);
6591 tcg_temp_free(t0);
6593 opn = "movn.d";
6594 break;
6595 case FOP(21, 17):
6596 check_cp1_64bitmode(ctx);
6598 TCGv_i64 fp0 = tcg_temp_new_i64();
6600 gen_load_fpr64(ctx, fp0, fs);
6601 gen_helper_float_recip_d(fp0, fp0);
6602 gen_store_fpr64(ctx, fp0, fd);
6603 tcg_temp_free_i64(fp0);
6605 opn = "recip.d";
6606 break;
6607 case FOP(22, 17):
6608 check_cp1_64bitmode(ctx);
6610 TCGv_i64 fp0 = tcg_temp_new_i64();
6612 gen_load_fpr64(ctx, fp0, fs);
6613 gen_helper_float_rsqrt_d(fp0, fp0);
6614 gen_store_fpr64(ctx, fp0, fd);
6615 tcg_temp_free_i64(fp0);
6617 opn = "rsqrt.d";
6618 break;
6619 case FOP(28, 17):
6620 check_cp1_64bitmode(ctx);
6622 TCGv_i64 fp0 = tcg_temp_new_i64();
6623 TCGv_i64 fp1 = tcg_temp_new_i64();
6625 gen_load_fpr64(ctx, fp0, fs);
6626 gen_load_fpr64(ctx, fp1, ft);
6627 gen_helper_float_recip2_d(fp0, fp0, fp1);
6628 tcg_temp_free_i64(fp1);
6629 gen_store_fpr64(ctx, fp0, fd);
6630 tcg_temp_free_i64(fp0);
6632 opn = "recip2.d";
6633 break;
6634 case FOP(29, 17):
6635 check_cp1_64bitmode(ctx);
6637 TCGv_i64 fp0 = tcg_temp_new_i64();
6639 gen_load_fpr64(ctx, fp0, fs);
6640 gen_helper_float_recip1_d(fp0, fp0);
6641 gen_store_fpr64(ctx, fp0, fd);
6642 tcg_temp_free_i64(fp0);
6644 opn = "recip1.d";
6645 break;
6646 case FOP(30, 17):
6647 check_cp1_64bitmode(ctx);
6649 TCGv_i64 fp0 = tcg_temp_new_i64();
6651 gen_load_fpr64(ctx, fp0, fs);
6652 gen_helper_float_rsqrt1_d(fp0, fp0);
6653 gen_store_fpr64(ctx, fp0, fd);
6654 tcg_temp_free_i64(fp0);
6656 opn = "rsqrt1.d";
6657 break;
6658 case FOP(31, 17):
6659 check_cp1_64bitmode(ctx);
6661 TCGv_i64 fp0 = tcg_temp_new_i64();
6662 TCGv_i64 fp1 = tcg_temp_new_i64();
6664 gen_load_fpr64(ctx, fp0, fs);
6665 gen_load_fpr64(ctx, fp1, ft);
6666 gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6667 tcg_temp_free_i64(fp1);
6668 gen_store_fpr64(ctx, fp0, fd);
6669 tcg_temp_free_i64(fp0);
6671 opn = "rsqrt2.d";
6672 break;
6673 case FOP(48, 17):
6674 case FOP(49, 17):
6675 case FOP(50, 17):
6676 case FOP(51, 17):
6677 case FOP(52, 17):
6678 case FOP(53, 17):
6679 case FOP(54, 17):
6680 case FOP(55, 17):
6681 case FOP(56, 17):
6682 case FOP(57, 17):
6683 case FOP(58, 17):
6684 case FOP(59, 17):
6685 case FOP(60, 17):
6686 case FOP(61, 17):
6687 case FOP(62, 17):
6688 case FOP(63, 17):
6690 TCGv_i64 fp0 = tcg_temp_new_i64();
6691 TCGv_i64 fp1 = tcg_temp_new_i64();
6693 gen_load_fpr64(ctx, fp0, fs);
6694 gen_load_fpr64(ctx, fp1, ft);
6695 if (ctx->opcode & (1 << 6)) {
6696 check_cop1x(ctx);
6697 check_cp1_registers(ctx, fs | ft);
6698 gen_cmpabs_d(func-48, fp0, fp1, cc);
6699 opn = condnames_abs[func-48];
6700 } else {
6701 check_cp1_registers(ctx, fs | ft);
6702 gen_cmp_d(func-48, fp0, fp1, cc);
6703 opn = condnames[func-48];
6705 tcg_temp_free_i64(fp0);
6706 tcg_temp_free_i64(fp1);
6708 break;
6709 case FOP(32, 17):
6710 check_cp1_registers(ctx, fs);
6712 TCGv_i32 fp32 = tcg_temp_new_i32();
6713 TCGv_i64 fp64 = tcg_temp_new_i64();
6715 gen_load_fpr64(ctx, fp64, fs);
6716 gen_helper_float_cvts_d(fp32, fp64);
6717 tcg_temp_free_i64(fp64);
6718 gen_store_fpr32(fp32, fd);
6719 tcg_temp_free_i32(fp32);
6721 opn = "cvt.s.d";
6722 break;
6723 case FOP(36, 17):
6724 check_cp1_registers(ctx, fs);
6726 TCGv_i32 fp32 = tcg_temp_new_i32();
6727 TCGv_i64 fp64 = tcg_temp_new_i64();
6729 gen_load_fpr64(ctx, fp64, fs);
6730 gen_helper_float_cvtw_d(fp32, fp64);
6731 tcg_temp_free_i64(fp64);
6732 gen_store_fpr32(fp32, fd);
6733 tcg_temp_free_i32(fp32);
6735 opn = "cvt.w.d";
6736 break;
6737 case FOP(37, 17):
6738 check_cp1_64bitmode(ctx);
6740 TCGv_i64 fp0 = tcg_temp_new_i64();
6742 gen_load_fpr64(ctx, fp0, fs);
6743 gen_helper_float_cvtl_d(fp0, fp0);
6744 gen_store_fpr64(ctx, fp0, fd);
6745 tcg_temp_free_i64(fp0);
6747 opn = "cvt.l.d";
6748 break;
6749 case FOP(32, 20):
6751 TCGv_i32 fp0 = tcg_temp_new_i32();
6753 gen_load_fpr32(fp0, fs);
6754 gen_helper_float_cvts_w(fp0, fp0);
6755 gen_store_fpr32(fp0, fd);
6756 tcg_temp_free_i32(fp0);
6758 opn = "cvt.s.w";
6759 break;
6760 case FOP(33, 20):
6761 check_cp1_registers(ctx, fd);
6763 TCGv_i32 fp32 = tcg_temp_new_i32();
6764 TCGv_i64 fp64 = tcg_temp_new_i64();
6766 gen_load_fpr32(fp32, fs);
6767 gen_helper_float_cvtd_w(fp64, fp32);
6768 tcg_temp_free_i32(fp32);
6769 gen_store_fpr64(ctx, fp64, fd);
6770 tcg_temp_free_i64(fp64);
6772 opn = "cvt.d.w";
6773 break;
6774 case FOP(32, 21):
6775 check_cp1_64bitmode(ctx);
6777 TCGv_i32 fp32 = tcg_temp_new_i32();
6778 TCGv_i64 fp64 = tcg_temp_new_i64();
6780 gen_load_fpr64(ctx, fp64, fs);
6781 gen_helper_float_cvts_l(fp32, fp64);
6782 tcg_temp_free_i64(fp64);
6783 gen_store_fpr32(fp32, fd);
6784 tcg_temp_free_i32(fp32);
6786 opn = "cvt.s.l";
6787 break;
6788 case FOP(33, 21):
6789 check_cp1_64bitmode(ctx);
6791 TCGv_i64 fp0 = tcg_temp_new_i64();
6793 gen_load_fpr64(ctx, fp0, fs);
6794 gen_helper_float_cvtd_l(fp0, fp0);
6795 gen_store_fpr64(ctx, fp0, fd);
6796 tcg_temp_free_i64(fp0);
6798 opn = "cvt.d.l";
6799 break;
6800 case FOP(38, 20):
6801 check_cp1_64bitmode(ctx);
6803 TCGv_i64 fp0 = tcg_temp_new_i64();
6805 gen_load_fpr64(ctx, fp0, fs);
6806 gen_helper_float_cvtps_pw(fp0, fp0);
6807 gen_store_fpr64(ctx, fp0, fd);
6808 tcg_temp_free_i64(fp0);
6810 opn = "cvt.ps.pw";
6811 break;
6812 case FOP(0, 22):
6813 check_cp1_64bitmode(ctx);
6815 TCGv_i64 fp0 = tcg_temp_new_i64();
6816 TCGv_i64 fp1 = tcg_temp_new_i64();
6818 gen_load_fpr64(ctx, fp0, fs);
6819 gen_load_fpr64(ctx, fp1, ft);
6820 gen_helper_float_add_ps(fp0, fp0, fp1);
6821 tcg_temp_free_i64(fp1);
6822 gen_store_fpr64(ctx, fp0, fd);
6823 tcg_temp_free_i64(fp0);
6825 opn = "add.ps";
6826 break;
6827 case FOP(1, 22):
6828 check_cp1_64bitmode(ctx);
6830 TCGv_i64 fp0 = tcg_temp_new_i64();
6831 TCGv_i64 fp1 = tcg_temp_new_i64();
6833 gen_load_fpr64(ctx, fp0, fs);
6834 gen_load_fpr64(ctx, fp1, ft);
6835 gen_helper_float_sub_ps(fp0, fp0, fp1);
6836 tcg_temp_free_i64(fp1);
6837 gen_store_fpr64(ctx, fp0, fd);
6838 tcg_temp_free_i64(fp0);
6840 opn = "sub.ps";
6841 break;
6842 case FOP(2, 22):
6843 check_cp1_64bitmode(ctx);
6845 TCGv_i64 fp0 = tcg_temp_new_i64();
6846 TCGv_i64 fp1 = tcg_temp_new_i64();
6848 gen_load_fpr64(ctx, fp0, fs);
6849 gen_load_fpr64(ctx, fp1, ft);
6850 gen_helper_float_mul_ps(fp0, fp0, fp1);
6851 tcg_temp_free_i64(fp1);
6852 gen_store_fpr64(ctx, fp0, fd);
6853 tcg_temp_free_i64(fp0);
6855 opn = "mul.ps";
6856 break;
6857 case FOP(5, 22):
6858 check_cp1_64bitmode(ctx);
6860 TCGv_i64 fp0 = tcg_temp_new_i64();
6862 gen_load_fpr64(ctx, fp0, fs);
6863 gen_helper_float_abs_ps(fp0, fp0);
6864 gen_store_fpr64(ctx, fp0, fd);
6865 tcg_temp_free_i64(fp0);
6867 opn = "abs.ps";
6868 break;
6869 case FOP(6, 22):
6870 check_cp1_64bitmode(ctx);
6872 TCGv_i64 fp0 = tcg_temp_new_i64();
6874 gen_load_fpr64(ctx, fp0, fs);
6875 gen_store_fpr64(ctx, fp0, fd);
6876 tcg_temp_free_i64(fp0);
6878 opn = "mov.ps";
6879 break;
6880 case FOP(7, 22):
6881 check_cp1_64bitmode(ctx);
6883 TCGv_i64 fp0 = tcg_temp_new_i64();
6885 gen_load_fpr64(ctx, fp0, fs);
6886 gen_helper_float_chs_ps(fp0, fp0);
6887 gen_store_fpr64(ctx, fp0, fd);
6888 tcg_temp_free_i64(fp0);
6890 opn = "neg.ps";
6891 break;
6892 case FOP(17, 22):
6893 check_cp1_64bitmode(ctx);
6894 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6895 opn = "movcf.ps";
6896 break;
6897 case FOP(18, 22):
6898 check_cp1_64bitmode(ctx);
6900 int l1 = gen_new_label();
6901 TCGv t0 = tcg_temp_new();
6902 TCGv_i32 fp0 = tcg_temp_local_new_i32();
6903 TCGv_i32 fph0 = tcg_temp_local_new_i32();
6905 gen_load_gpr(t0, ft);
6906 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6907 gen_load_fpr32(fp0, fs);
6908 gen_load_fpr32h(fph0, fs);
6909 gen_store_fpr32(fp0, fd);
6910 gen_store_fpr32h(fph0, fd);
6911 tcg_temp_free_i32(fp0);
6912 tcg_temp_free_i32(fph0);
6913 gen_set_label(l1);
6914 tcg_temp_free(t0);
6916 opn = "movz.ps";
6917 break;
6918 case FOP(19, 22):
6919 check_cp1_64bitmode(ctx);
6921 int l1 = gen_new_label();
6922 TCGv t0 = tcg_temp_new();
6923 TCGv_i32 fp0 = tcg_temp_local_new_i32();
6924 TCGv_i32 fph0 = tcg_temp_local_new_i32();
6926 gen_load_gpr(t0, ft);
6927 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6928 gen_load_fpr32(fp0, fs);
6929 gen_load_fpr32h(fph0, fs);
6930 gen_store_fpr32(fp0, fd);
6931 gen_store_fpr32h(fph0, fd);
6932 tcg_temp_free_i32(fp0);
6933 tcg_temp_free_i32(fph0);
6934 gen_set_label(l1);
6935 tcg_temp_free(t0);
6937 opn = "movn.ps";
6938 break;
6939 case FOP(24, 22):
6940 check_cp1_64bitmode(ctx);
6942 TCGv_i64 fp0 = tcg_temp_new_i64();
6943 TCGv_i64 fp1 = tcg_temp_new_i64();
6945 gen_load_fpr64(ctx, fp0, ft);
6946 gen_load_fpr64(ctx, fp1, fs);
6947 gen_helper_float_addr_ps(fp0, fp0, fp1);
6948 tcg_temp_free_i64(fp1);
6949 gen_store_fpr64(ctx, fp0, fd);
6950 tcg_temp_free_i64(fp0);
6952 opn = "addr.ps";
6953 break;
6954 case FOP(26, 22):
6955 check_cp1_64bitmode(ctx);
6957 TCGv_i64 fp0 = tcg_temp_new_i64();
6958 TCGv_i64 fp1 = tcg_temp_new_i64();
6960 gen_load_fpr64(ctx, fp0, ft);
6961 gen_load_fpr64(ctx, fp1, fs);
6962 gen_helper_float_mulr_ps(fp0, fp0, fp1);
6963 tcg_temp_free_i64(fp1);
6964 gen_store_fpr64(ctx, fp0, fd);
6965 tcg_temp_free_i64(fp0);
6967 opn = "mulr.ps";
6968 break;
6969 case FOP(28, 22):
6970 check_cp1_64bitmode(ctx);
6972 TCGv_i64 fp0 = tcg_temp_new_i64();
6973 TCGv_i64 fp1 = tcg_temp_new_i64();
6975 gen_load_fpr64(ctx, fp0, fs);
6976 gen_load_fpr64(ctx, fp1, fd);
6977 gen_helper_float_recip2_ps(fp0, fp0, fp1);
6978 tcg_temp_free_i64(fp1);
6979 gen_store_fpr64(ctx, fp0, fd);
6980 tcg_temp_free_i64(fp0);
6982 opn = "recip2.ps";
6983 break;
6984 case FOP(29, 22):
6985 check_cp1_64bitmode(ctx);
6987 TCGv_i64 fp0 = tcg_temp_new_i64();
6989 gen_load_fpr64(ctx, fp0, fs);
6990 gen_helper_float_recip1_ps(fp0, fp0);
6991 gen_store_fpr64(ctx, fp0, fd);
6992 tcg_temp_free_i64(fp0);
6994 opn = "recip1.ps";
6995 break;
6996 case FOP(30, 22):
6997 check_cp1_64bitmode(ctx);
6999 TCGv_i64 fp0 = tcg_temp_new_i64();
7001 gen_load_fpr64(ctx, fp0, fs);
7002 gen_helper_float_rsqrt1_ps(fp0, fp0);
7003 gen_store_fpr64(ctx, fp0, fd);
7004 tcg_temp_free_i64(fp0);
7006 opn = "rsqrt1.ps";
7007 break;
7008 case FOP(31, 22):
7009 check_cp1_64bitmode(ctx);
7011 TCGv_i64 fp0 = tcg_temp_new_i64();
7012 TCGv_i64 fp1 = tcg_temp_new_i64();
7014 gen_load_fpr64(ctx, fp0, fs);
7015 gen_load_fpr64(ctx, fp1, ft);
7016 gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7017 tcg_temp_free_i64(fp1);
7018 gen_store_fpr64(ctx, fp0, fd);
7019 tcg_temp_free_i64(fp0);
7021 opn = "rsqrt2.ps";
7022 break;
7023 case FOP(32, 22):
7024 check_cp1_64bitmode(ctx);
7026 TCGv_i32 fp0 = tcg_temp_new_i32();
7028 gen_load_fpr32h(fp0, fs);
7029 gen_helper_float_cvts_pu(fp0, fp0);
7030 gen_store_fpr32(fp0, fd);
7031 tcg_temp_free_i32(fp0);
7033 opn = "cvt.s.pu";
7034 break;
7035 case FOP(36, 22):
7036 check_cp1_64bitmode(ctx);
7038 TCGv_i64 fp0 = tcg_temp_new_i64();
7040 gen_load_fpr64(ctx, fp0, fs);
7041 gen_helper_float_cvtpw_ps(fp0, fp0);
7042 gen_store_fpr64(ctx, fp0, fd);
7043 tcg_temp_free_i64(fp0);
7045 opn = "cvt.pw.ps";
7046 break;
7047 case FOP(40, 22):
7048 check_cp1_64bitmode(ctx);
7050 TCGv_i32 fp0 = tcg_temp_new_i32();
7052 gen_load_fpr32(fp0, fs);
7053 gen_helper_float_cvts_pl(fp0, fp0);
7054 gen_store_fpr32(fp0, fd);
7055 tcg_temp_free_i32(fp0);
7057 opn = "cvt.s.pl";
7058 break;
7059 case FOP(44, 22):
7060 check_cp1_64bitmode(ctx);
7062 TCGv_i32 fp0 = tcg_temp_new_i32();
7063 TCGv_i32 fp1 = tcg_temp_new_i32();
7065 gen_load_fpr32(fp0, fs);
7066 gen_load_fpr32(fp1, ft);
7067 gen_store_fpr32h(fp0, fd);
7068 gen_store_fpr32(fp1, fd);
7069 tcg_temp_free_i32(fp0);
7070 tcg_temp_free_i32(fp1);
7072 opn = "pll.ps";
7073 break;
7074 case FOP(45, 22):
7075 check_cp1_64bitmode(ctx);
7077 TCGv_i32 fp0 = tcg_temp_new_i32();
7078 TCGv_i32 fp1 = tcg_temp_new_i32();
7080 gen_load_fpr32(fp0, fs);
7081 gen_load_fpr32h(fp1, ft);
7082 gen_store_fpr32(fp1, fd);
7083 gen_store_fpr32h(fp0, fd);
7084 tcg_temp_free_i32(fp0);
7085 tcg_temp_free_i32(fp1);
7087 opn = "plu.ps";
7088 break;
7089 case FOP(46, 22):
7090 check_cp1_64bitmode(ctx);
7092 TCGv_i32 fp0 = tcg_temp_new_i32();
7093 TCGv_i32 fp1 = tcg_temp_new_i32();
7095 gen_load_fpr32h(fp0, fs);
7096 gen_load_fpr32(fp1, ft);
7097 gen_store_fpr32(fp1, fd);
7098 gen_store_fpr32h(fp0, fd);
7099 tcg_temp_free_i32(fp0);
7100 tcg_temp_free_i32(fp1);
7102 opn = "pul.ps";
7103 break;
7104 case FOP(47, 22):
7105 check_cp1_64bitmode(ctx);
7107 TCGv_i32 fp0 = tcg_temp_new_i32();
7108 TCGv_i32 fp1 = tcg_temp_new_i32();
7110 gen_load_fpr32h(fp0, fs);
7111 gen_load_fpr32h(fp1, ft);
7112 gen_store_fpr32(fp1, fd);
7113 gen_store_fpr32h(fp0, fd);
7114 tcg_temp_free_i32(fp0);
7115 tcg_temp_free_i32(fp1);
7117 opn = "puu.ps";
7118 break;
7119 case FOP(48, 22):
7120 case FOP(49, 22):
7121 case FOP(50, 22):
7122 case FOP(51, 22):
7123 case FOP(52, 22):
7124 case FOP(53, 22):
7125 case FOP(54, 22):
7126 case FOP(55, 22):
7127 case FOP(56, 22):
7128 case FOP(57, 22):
7129 case FOP(58, 22):
7130 case FOP(59, 22):
7131 case FOP(60, 22):
7132 case FOP(61, 22):
7133 case FOP(62, 22):
7134 case FOP(63, 22):
7135 check_cp1_64bitmode(ctx);
7137 TCGv_i64 fp0 = tcg_temp_new_i64();
7138 TCGv_i64 fp1 = tcg_temp_new_i64();
7140 gen_load_fpr64(ctx, fp0, fs);
7141 gen_load_fpr64(ctx, fp1, ft);
7142 if (ctx->opcode & (1 << 6)) {
7143 gen_cmpabs_ps(func-48, fp0, fp1, cc);
7144 opn = condnames_abs[func-48];
7145 } else {
7146 gen_cmp_ps(func-48, fp0, fp1, cc);
7147 opn = condnames[func-48];
7149 tcg_temp_free_i64(fp0);
7150 tcg_temp_free_i64(fp1);
7152 break;
7153 default:
7154 MIPS_INVAL(opn);
7155 generate_exception (ctx, EXCP_RI);
7156 return;
7158 switch (optype) {
7159 case BINOP:
7160 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7161 break;
7162 case CMPOP:
7163 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7164 break;
7165 default:
7166 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7167 break;
7171 /* Coprocessor 3 (FPU) */
7172 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7173 int fd, int fs, int base, int index)
7175 const char *opn = "extended float load/store";
7176 int store = 0;
7177 TCGv t0 = tcg_temp_local_new();
7178 TCGv t1 = tcg_temp_local_new();
7180 if (base == 0) {
7181 gen_load_gpr(t0, index);
7182 } else if (index == 0) {
7183 gen_load_gpr(t0, base);
7184 } else {
7185 gen_load_gpr(t0, index);
7186 gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7188 /* Don't do NOP if destination is zero: we must perform the actual
7189 memory access. */
7190 switch (opc) {
7191 case OPC_LWXC1:
7192 check_cop1x(ctx);
7194 TCGv_i32 fp0 = tcg_temp_new_i32();
7196 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7197 tcg_gen_trunc_tl_i32(fp0, t1);
7198 gen_store_fpr32(fp0, fd);
7199 tcg_temp_free_i32(fp0);
7201 opn = "lwxc1";
7202 break;
7203 case OPC_LDXC1:
7204 check_cop1x(ctx);
7205 check_cp1_registers(ctx, fd);
7207 TCGv_i64 fp0 = tcg_temp_new_i64();
7209 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7210 gen_store_fpr64(ctx, fp0, fd);
7211 tcg_temp_free_i64(fp0);
7213 opn = "ldxc1";
7214 break;
7215 case OPC_LUXC1:
7216 check_cp1_64bitmode(ctx);
7217 tcg_gen_andi_tl(t0, t0, ~0x7);
7219 TCGv_i64 fp0 = tcg_temp_new_i64();
7221 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7222 gen_store_fpr64(ctx, fp0, fd);
7223 tcg_temp_free_i64(fp0);
7225 opn = "luxc1";
7226 break;
7227 case OPC_SWXC1:
7228 check_cop1x(ctx);
7230 TCGv_i32 fp0 = tcg_temp_new_i32();
7232 gen_load_fpr32(fp0, fs);
7233 tcg_gen_extu_i32_tl(t1, fp0);
7234 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7235 tcg_temp_free_i32(fp0);
7237 opn = "swxc1";
7238 store = 1;
7239 break;
7240 case OPC_SDXC1:
7241 check_cop1x(ctx);
7242 check_cp1_registers(ctx, fs);
7244 TCGv_i64 fp0 = tcg_temp_new_i64();
7246 gen_load_fpr64(ctx, fp0, fs);
7247 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7248 tcg_temp_free_i64(fp0);
7250 opn = "sdxc1";
7251 store = 1;
7252 break;
7253 case OPC_SUXC1:
7254 check_cp1_64bitmode(ctx);
7255 tcg_gen_andi_tl(t0, t0, ~0x7);
7257 TCGv_i64 fp0 = tcg_temp_new_i64();
7259 gen_load_fpr64(ctx, fp0, fs);
7260 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7261 tcg_temp_free_i64(fp0);
7263 opn = "suxc1";
7264 store = 1;
7265 break;
7266 default:
7267 MIPS_INVAL(opn);
7268 generate_exception(ctx, EXCP_RI);
7269 tcg_temp_free(t0);
7270 tcg_temp_free(t1);
7271 return;
7273 tcg_temp_free(t0);
7274 tcg_temp_free(t1);
7275 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7276 regnames[index], regnames[base]);
7279 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7280 int fd, int fr, int fs, int ft)
7282 const char *opn = "flt3_arith";
7284 switch (opc) {
7285 case OPC_ALNV_PS:
7286 check_cp1_64bitmode(ctx);
7288 TCGv t0 = tcg_temp_local_new();
7289 TCGv_i32 fp0 = tcg_temp_local_new_i32();
7290 TCGv_i32 fph0 = tcg_temp_local_new_i32();
7291 TCGv_i32 fp1 = tcg_temp_local_new_i32();
7292 TCGv_i32 fph1 = tcg_temp_local_new_i32();
7293 int l1 = gen_new_label();
7294 int l2 = gen_new_label();
7296 gen_load_gpr(t0, fr);
7297 tcg_gen_andi_tl(t0, t0, 0x7);
7298 gen_load_fpr32(fp0, fs);
7299 gen_load_fpr32h(fph0, fs);
7300 gen_load_fpr32(fp1, ft);
7301 gen_load_fpr32h(fph1, ft);
7303 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7304 gen_store_fpr32(fp0, fd);
7305 gen_store_fpr32h(fph0, fd);
7306 tcg_gen_br(l2);
7307 gen_set_label(l1);
7308 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7309 tcg_temp_free(t0);
7310 #ifdef TARGET_WORDS_BIGENDIAN
7311 gen_store_fpr32(fph1, fd);
7312 gen_store_fpr32h(fp0, fd);
7313 #else
7314 gen_store_fpr32(fph0, fd);
7315 gen_store_fpr32h(fp1, fd);
7316 #endif
7317 gen_set_label(l2);
7318 tcg_temp_free_i32(fp0);
7319 tcg_temp_free_i32(fph0);
7320 tcg_temp_free_i32(fp1);
7321 tcg_temp_free_i32(fph1);
7323 opn = "alnv.ps";
7324 break;
7325 case OPC_MADD_S:
7326 check_cop1x(ctx);
7328 TCGv_i32 fp0 = tcg_temp_new_i32();
7329 TCGv_i32 fp1 = tcg_temp_new_i32();
7330 TCGv_i32 fp2 = tcg_temp_new_i32();
7332 gen_load_fpr32(fp0, fs);
7333 gen_load_fpr32(fp1, ft);
7334 gen_load_fpr32(fp2, fr);
7335 gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7336 tcg_temp_free_i32(fp0);
7337 tcg_temp_free_i32(fp1);
7338 gen_store_fpr32(fp2, fd);
7339 tcg_temp_free_i32(fp2);
7341 opn = "madd.s";
7342 break;
7343 case OPC_MADD_D:
7344 check_cop1x(ctx);
7345 check_cp1_registers(ctx, fd | fs | ft | fr);
7347 TCGv_i64 fp0 = tcg_temp_new_i64();
7348 TCGv_i64 fp1 = tcg_temp_new_i64();
7349 TCGv_i64 fp2 = tcg_temp_new_i64();
7351 gen_load_fpr64(ctx, fp0, fs);
7352 gen_load_fpr64(ctx, fp1, ft);
7353 gen_load_fpr64(ctx, fp2, fr);
7354 gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7355 tcg_temp_free_i64(fp0);
7356 tcg_temp_free_i64(fp1);
7357 gen_store_fpr64(ctx, fp2, fd);
7358 tcg_temp_free_i64(fp2);
7360 opn = "madd.d";
7361 break;
7362 case OPC_MADD_PS:
7363 check_cp1_64bitmode(ctx);
7365 TCGv_i64 fp0 = tcg_temp_new_i64();
7366 TCGv_i64 fp1 = tcg_temp_new_i64();
7367 TCGv_i64 fp2 = tcg_temp_new_i64();
7369 gen_load_fpr64(ctx, fp0, fs);
7370 gen_load_fpr64(ctx, fp1, ft);
7371 gen_load_fpr64(ctx, fp2, fr);
7372 gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7373 tcg_temp_free_i64(fp0);
7374 tcg_temp_free_i64(fp1);
7375 gen_store_fpr64(ctx, fp2, fd);
7376 tcg_temp_free_i64(fp2);
7378 opn = "madd.ps";
7379 break;
7380 case OPC_MSUB_S:
7381 check_cop1x(ctx);
7383 TCGv_i32 fp0 = tcg_temp_new_i32();
7384 TCGv_i32 fp1 = tcg_temp_new_i32();
7385 TCGv_i32 fp2 = tcg_temp_new_i32();
7387 gen_load_fpr32(fp0, fs);
7388 gen_load_fpr32(fp1, ft);
7389 gen_load_fpr32(fp2, fr);
7390 gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7391 tcg_temp_free_i32(fp0);
7392 tcg_temp_free_i32(fp1);
7393 gen_store_fpr32(fp2, fd);
7394 tcg_temp_free_i32(fp2);
7396 opn = "msub.s";
7397 break;
7398 case OPC_MSUB_D:
7399 check_cop1x(ctx);
7400 check_cp1_registers(ctx, fd | fs | ft | fr);
7402 TCGv_i64 fp0 = tcg_temp_new_i64();
7403 TCGv_i64 fp1 = tcg_temp_new_i64();
7404 TCGv_i64 fp2 = tcg_temp_new_i64();
7406 gen_load_fpr64(ctx, fp0, fs);
7407 gen_load_fpr64(ctx, fp1, ft);
7408 gen_load_fpr64(ctx, fp2, fr);
7409 gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7410 tcg_temp_free_i64(fp0);
7411 tcg_temp_free_i64(fp1);
7412 gen_store_fpr64(ctx, fp2, fd);
7413 tcg_temp_free_i64(fp2);
7415 opn = "msub.d";
7416 break;
7417 case OPC_MSUB_PS:
7418 check_cp1_64bitmode(ctx);
7420 TCGv_i64 fp0 = tcg_temp_new_i64();
7421 TCGv_i64 fp1 = tcg_temp_new_i64();
7422 TCGv_i64 fp2 = tcg_temp_new_i64();
7424 gen_load_fpr64(ctx, fp0, fs);
7425 gen_load_fpr64(ctx, fp1, ft);
7426 gen_load_fpr64(ctx, fp2, fr);
7427 gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7428 tcg_temp_free_i64(fp0);
7429 tcg_temp_free_i64(fp1);
7430 gen_store_fpr64(ctx, fp2, fd);
7431 tcg_temp_free_i64(fp2);
7433 opn = "msub.ps";
7434 break;
7435 case OPC_NMADD_S:
7436 check_cop1x(ctx);
7438 TCGv_i32 fp0 = tcg_temp_new_i32();
7439 TCGv_i32 fp1 = tcg_temp_new_i32();
7440 TCGv_i32 fp2 = tcg_temp_new_i32();
7442 gen_load_fpr32(fp0, fs);
7443 gen_load_fpr32(fp1, ft);
7444 gen_load_fpr32(fp2, fr);
7445 gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7446 tcg_temp_free_i32(fp0);
7447 tcg_temp_free_i32(fp1);
7448 gen_store_fpr32(fp2, fd);
7449 tcg_temp_free_i32(fp2);
7451 opn = "nmadd.s";
7452 break;
7453 case OPC_NMADD_D:
7454 check_cop1x(ctx);
7455 check_cp1_registers(ctx, fd | fs | ft | fr);
7457 TCGv_i64 fp0 = tcg_temp_new_i64();
7458 TCGv_i64 fp1 = tcg_temp_new_i64();
7459 TCGv_i64 fp2 = tcg_temp_new_i64();
7461 gen_load_fpr64(ctx, fp0, fs);
7462 gen_load_fpr64(ctx, fp1, ft);
7463 gen_load_fpr64(ctx, fp2, fr);
7464 gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7465 tcg_temp_free_i64(fp0);
7466 tcg_temp_free_i64(fp1);
7467 gen_store_fpr64(ctx, fp2, fd);
7468 tcg_temp_free_i64(fp2);
7470 opn = "nmadd.d";
7471 break;
7472 case OPC_NMADD_PS:
7473 check_cp1_64bitmode(ctx);
7475 TCGv_i64 fp0 = tcg_temp_new_i64();
7476 TCGv_i64 fp1 = tcg_temp_new_i64();
7477 TCGv_i64 fp2 = tcg_temp_new_i64();
7479 gen_load_fpr64(ctx, fp0, fs);
7480 gen_load_fpr64(ctx, fp1, ft);
7481 gen_load_fpr64(ctx, fp2, fr);
7482 gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7483 tcg_temp_free_i64(fp0);
7484 tcg_temp_free_i64(fp1);
7485 gen_store_fpr64(ctx, fp2, fd);
7486 tcg_temp_free_i64(fp2);
7488 opn = "nmadd.ps";
7489 break;
7490 case OPC_NMSUB_S:
7491 check_cop1x(ctx);
7493 TCGv_i32 fp0 = tcg_temp_new_i32();
7494 TCGv_i32 fp1 = tcg_temp_new_i32();
7495 TCGv_i32 fp2 = tcg_temp_new_i32();
7497 gen_load_fpr32(fp0, fs);
7498 gen_load_fpr32(fp1, ft);
7499 gen_load_fpr32(fp2, fr);
7500 gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7501 tcg_temp_free_i32(fp0);
7502 tcg_temp_free_i32(fp1);
7503 gen_store_fpr32(fp2, fd);
7504 tcg_temp_free_i32(fp2);
7506 opn = "nmsub.s";
7507 break;
7508 case OPC_NMSUB_D:
7509 check_cop1x(ctx);
7510 check_cp1_registers(ctx, fd | fs | ft | fr);
7512 TCGv_i64 fp0 = tcg_temp_new_i64();
7513 TCGv_i64 fp1 = tcg_temp_new_i64();
7514 TCGv_i64 fp2 = tcg_temp_new_i64();
7516 gen_load_fpr64(ctx, fp0, fs);
7517 gen_load_fpr64(ctx, fp1, ft);
7518 gen_load_fpr64(ctx, fp2, fr);
7519 gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7520 tcg_temp_free_i64(fp0);
7521 tcg_temp_free_i64(fp1);
7522 gen_store_fpr64(ctx, fp2, fd);
7523 tcg_temp_free_i64(fp2);
7525 opn = "nmsub.d";
7526 break;
7527 case OPC_NMSUB_PS:
7528 check_cp1_64bitmode(ctx);
7530 TCGv_i64 fp0 = tcg_temp_new_i64();
7531 TCGv_i64 fp1 = tcg_temp_new_i64();
7532 TCGv_i64 fp2 = tcg_temp_new_i64();
7534 gen_load_fpr64(ctx, fp0, fs);
7535 gen_load_fpr64(ctx, fp1, ft);
7536 gen_load_fpr64(ctx, fp2, fr);
7537 gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7538 tcg_temp_free_i64(fp0);
7539 tcg_temp_free_i64(fp1);
7540 gen_store_fpr64(ctx, fp2, fd);
7541 tcg_temp_free_i64(fp2);
7543 opn = "nmsub.ps";
7544 break;
7545 default:
7546 MIPS_INVAL(opn);
7547 generate_exception (ctx, EXCP_RI);
7548 return;
7550 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7551 fregnames[fs], fregnames[ft]);
7554 /* ISA extensions (ASEs) */
7555 /* MIPS16 extension to MIPS32 */
7556 /* SmartMIPS extension to MIPS32 */
7558 #if defined(TARGET_MIPS64)
7560 /* MDMX extension to MIPS64 */
7562 #endif
7564 static void decode_opc (CPUState *env, DisasContext *ctx)
7566 int32_t offset;
7567 int rs, rt, rd, sa;
7568 uint32_t op, op1, op2;
7569 int16_t imm;
7571 /* make sure instructions are on a word boundary */
7572 if (ctx->pc & 0x3) {
7573 env->CP0_BadVAddr = ctx->pc;
7574 generate_exception(ctx, EXCP_AdEL);
7575 return;
7578 /* Handle blikely not taken case */
7579 if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7580 int l1 = gen_new_label();
7582 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7583 tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7585 TCGv_i32 r_tmp = tcg_temp_new_i32();
7587 tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7588 tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7589 tcg_temp_free_i32(r_tmp);
7591 gen_goto_tb(ctx, 1, ctx->pc + 4);
7592 gen_set_label(l1);
7594 op = MASK_OP_MAJOR(ctx->opcode);
7595 rs = (ctx->opcode >> 21) & 0x1f;
7596 rt = (ctx->opcode >> 16) & 0x1f;
7597 rd = (ctx->opcode >> 11) & 0x1f;
7598 sa = (ctx->opcode >> 6) & 0x1f;
7599 imm = (int16_t)ctx->opcode;
7600 switch (op) {
7601 case OPC_SPECIAL:
7602 op1 = MASK_SPECIAL(ctx->opcode);
7603 switch (op1) {
7604 case OPC_SLL: /* Arithmetic with immediate */
7605 case OPC_SRL ... OPC_SRA:
7606 gen_arith_imm(env, ctx, op1, rd, rt, sa);
7607 break;
7608 case OPC_MOVZ ... OPC_MOVN:
7609 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7610 case OPC_SLLV: /* Arithmetic */
7611 case OPC_SRLV ... OPC_SRAV:
7612 case OPC_ADD ... OPC_NOR:
7613 case OPC_SLT ... OPC_SLTU:
7614 gen_arith(env, ctx, op1, rd, rs, rt);
7615 break;
7616 case OPC_MULT ... OPC_DIVU:
7617 if (sa) {
7618 check_insn(env, ctx, INSN_VR54XX);
7619 op1 = MASK_MUL_VR54XX(ctx->opcode);
7620 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7621 } else
7622 gen_muldiv(ctx, op1, rs, rt);
7623 break;
7624 case OPC_JR ... OPC_JALR:
7625 gen_compute_branch(ctx, op1, rs, rd, sa);
7626 return;
7627 case OPC_TGE ... OPC_TEQ: /* Traps */
7628 case OPC_TNE:
7629 gen_trap(ctx, op1, rs, rt, -1);
7630 break;
7631 case OPC_MFHI: /* Move from HI/LO */
7632 case OPC_MFLO:
7633 gen_HILO(ctx, op1, rd);
7634 break;
7635 case OPC_MTHI:
7636 case OPC_MTLO: /* Move to HI/LO */
7637 gen_HILO(ctx, op1, rs);
7638 break;
7639 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
7640 #ifdef MIPS_STRICT_STANDARD
7641 MIPS_INVAL("PMON / selsl");
7642 generate_exception(ctx, EXCP_RI);
7643 #else
7644 gen_helper_0i(pmon, sa);
7645 #endif
7646 break;
7647 case OPC_SYSCALL:
7648 generate_exception(ctx, EXCP_SYSCALL);
7649 break;
7650 case OPC_BREAK:
7651 generate_exception(ctx, EXCP_BREAK);
7652 break;
7653 case OPC_SPIM:
7654 #ifdef MIPS_STRICT_STANDARD
7655 MIPS_INVAL("SPIM");
7656 generate_exception(ctx, EXCP_RI);
7657 #else
7658 /* Implemented as RI exception for now. */
7659 MIPS_INVAL("spim (unofficial)");
7660 generate_exception(ctx, EXCP_RI);
7661 #endif
7662 break;
7663 case OPC_SYNC:
7664 /* Treat as NOP. */
7665 break;
7667 case OPC_MOVCI:
7668 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7669 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7670 save_cpu_state(ctx, 1);
7671 check_cp1_enabled(ctx);
7672 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7673 (ctx->opcode >> 16) & 1);
7674 } else {
7675 generate_exception_err(ctx, EXCP_CpU, 1);
7677 break;
7679 #if defined(TARGET_MIPS64)
7680 /* MIPS64 specific opcodes */
7681 case OPC_DSLL:
7682 case OPC_DSRL ... OPC_DSRA:
7683 case OPC_DSLL32:
7684 case OPC_DSRL32 ... OPC_DSRA32:
7685 check_insn(env, ctx, ISA_MIPS3);
7686 check_mips_64(ctx);
7687 gen_arith_imm(env, ctx, op1, rd, rt, sa);
7688 break;
7689 case OPC_DSLLV:
7690 case OPC_DSRLV ... OPC_DSRAV:
7691 case OPC_DADD ... OPC_DSUBU:
7692 check_insn(env, ctx, ISA_MIPS3);
7693 check_mips_64(ctx);
7694 gen_arith(env, ctx, op1, rd, rs, rt);
7695 break;
7696 case OPC_DMULT ... OPC_DDIVU:
7697 check_insn(env, ctx, ISA_MIPS3);
7698 check_mips_64(ctx);
7699 gen_muldiv(ctx, op1, rs, rt);
7700 break;
7701 #endif
7702 default: /* Invalid */
7703 MIPS_INVAL("special");
7704 generate_exception(ctx, EXCP_RI);
7705 break;
7707 break;
7708 case OPC_SPECIAL2:
7709 op1 = MASK_SPECIAL2(ctx->opcode);
7710 switch (op1) {
7711 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7712 case OPC_MSUB ... OPC_MSUBU:
7713 check_insn(env, ctx, ISA_MIPS32);
7714 gen_muldiv(ctx, op1, rs, rt);
7715 break;
7716 case OPC_MUL:
7717 gen_arith(env, ctx, op1, rd, rs, rt);
7718 break;
7719 case OPC_CLZ ... OPC_CLO:
7720 check_insn(env, ctx, ISA_MIPS32);
7721 gen_cl(ctx, op1, rd, rs);
7722 break;
7723 case OPC_SDBBP:
7724 /* XXX: not clear which exception should be raised
7725 * when in debug mode...
7727 check_insn(env, ctx, ISA_MIPS32);
7728 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7729 generate_exception(ctx, EXCP_DBp);
7730 } else {
7731 generate_exception(ctx, EXCP_DBp);
7733 /* Treat as NOP. */
7734 break;
7735 #if defined(TARGET_MIPS64)
7736 case OPC_DCLZ ... OPC_DCLO:
7737 check_insn(env, ctx, ISA_MIPS64);
7738 check_mips_64(ctx);
7739 gen_cl(ctx, op1, rd, rs);
7740 break;
7741 #endif
7742 default: /* Invalid */
7743 MIPS_INVAL("special2");
7744 generate_exception(ctx, EXCP_RI);
7745 break;
7747 break;
7748 case OPC_SPECIAL3:
7749 op1 = MASK_SPECIAL3(ctx->opcode);
7750 switch (op1) {
7751 case OPC_EXT:
7752 case OPC_INS:
7753 check_insn(env, ctx, ISA_MIPS32R2);
7754 gen_bitops(ctx, op1, rt, rs, sa, rd);
7755 break;
7756 case OPC_BSHFL:
7757 check_insn(env, ctx, ISA_MIPS32R2);
7758 op2 = MASK_BSHFL(ctx->opcode);
7759 gen_bshfl(ctx, op2, rt, rd);
7760 break;
7761 case OPC_RDHWR:
7762 check_insn(env, ctx, ISA_MIPS32R2);
7764 TCGv t0 = tcg_temp_local_new();
7766 switch (rd) {
7767 case 0:
7768 save_cpu_state(ctx, 1);
7769 gen_helper_rdhwr_cpunum(t0);
7770 break;
7771 case 1:
7772 save_cpu_state(ctx, 1);
7773 gen_helper_rdhwr_synci_step(t0);
7774 break;
7775 case 2:
7776 save_cpu_state(ctx, 1);
7777 gen_helper_rdhwr_cc(t0);
7778 break;
7779 case 3:
7780 save_cpu_state(ctx, 1);
7781 gen_helper_rdhwr_ccres(t0);
7782 break;
7783 case 29:
7784 #if defined(CONFIG_USER_ONLY)
7785 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7786 break;
7787 #else
7788 /* XXX: Some CPUs implement this in hardware.
7789 Not supported yet. */
7790 #endif
7791 default: /* Invalid */
7792 MIPS_INVAL("rdhwr");
7793 generate_exception(ctx, EXCP_RI);
7794 break;
7796 gen_store_gpr(t0, rt);
7797 tcg_temp_free(t0);
7799 break;
7800 case OPC_FORK:
7801 check_insn(env, ctx, ASE_MT);
7803 TCGv t0 = tcg_temp_local_new();
7804 TCGv t1 = tcg_temp_local_new();
7806 gen_load_gpr(t0, rt);
7807 gen_load_gpr(t1, rs);
7808 gen_helper_fork(t0, t1);
7809 tcg_temp_free(t0);
7810 tcg_temp_free(t1);
7812 break;
7813 case OPC_YIELD:
7814 check_insn(env, ctx, ASE_MT);
7816 TCGv t0 = tcg_temp_local_new();
7818 gen_load_gpr(t0, rs);
7819 gen_helper_yield(t0, t0);
7820 gen_store_gpr(t0, rd);
7821 tcg_temp_free(t0);
7823 break;
7824 #if defined(TARGET_MIPS64)
7825 case OPC_DEXTM ... OPC_DEXT:
7826 case OPC_DINSM ... OPC_DINS:
7827 check_insn(env, ctx, ISA_MIPS64R2);
7828 check_mips_64(ctx);
7829 gen_bitops(ctx, op1, rt, rs, sa, rd);
7830 break;
7831 case OPC_DBSHFL:
7832 check_insn(env, ctx, ISA_MIPS64R2);
7833 check_mips_64(ctx);
7834 op2 = MASK_DBSHFL(ctx->opcode);
7835 gen_bshfl(ctx, op2, rt, rd);
7836 break;
7837 #endif
7838 default: /* Invalid */
7839 MIPS_INVAL("special3");
7840 generate_exception(ctx, EXCP_RI);
7841 break;
7843 break;
7844 case OPC_REGIMM:
7845 op1 = MASK_REGIMM(ctx->opcode);
7846 switch (op1) {
7847 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7848 case OPC_BLTZAL ... OPC_BGEZALL:
7849 gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7850 return;
7851 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7852 case OPC_TNEI:
7853 gen_trap(ctx, op1, rs, -1, imm);
7854 break;
7855 case OPC_SYNCI:
7856 check_insn(env, ctx, ISA_MIPS32R2);
7857 /* Treat as NOP. */
7858 break;
7859 default: /* Invalid */
7860 MIPS_INVAL("regimm");
7861 generate_exception(ctx, EXCP_RI);
7862 break;
7864 break;
7865 case OPC_CP0:
7866 check_cp0_enabled(ctx);
7867 op1 = MASK_CP0(ctx->opcode);
7868 switch (op1) {
7869 case OPC_MFC0:
7870 case OPC_MTC0:
7871 case OPC_MFTR:
7872 case OPC_MTTR:
7873 #if defined(TARGET_MIPS64)
7874 case OPC_DMFC0:
7875 case OPC_DMTC0:
7876 #endif
7877 #ifndef CONFIG_USER_ONLY
7878 gen_cp0(env, ctx, op1, rt, rd);
7879 #endif /* !CONFIG_USER_ONLY */
7880 break;
7881 case OPC_C0_FIRST ... OPC_C0_LAST:
7882 #ifndef CONFIG_USER_ONLY
7883 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7884 #endif /* !CONFIG_USER_ONLY */
7885 break;
7886 case OPC_MFMC0:
7887 #ifndef CONFIG_USER_ONLY
7889 TCGv t0 = tcg_temp_local_new();
7891 op2 = MASK_MFMC0(ctx->opcode);
7892 switch (op2) {
7893 case OPC_DMT:
7894 check_insn(env, ctx, ASE_MT);
7895 gen_helper_dmt(t0, t0);
7896 break;
7897 case OPC_EMT:
7898 check_insn(env, ctx, ASE_MT);
7899 gen_helper_emt(t0, t0);
7900 break;
7901 case OPC_DVPE:
7902 check_insn(env, ctx, ASE_MT);
7903 gen_helper_dvpe(t0, t0);
7904 break;
7905 case OPC_EVPE:
7906 check_insn(env, ctx, ASE_MT);
7907 gen_helper_evpe(t0, t0);
7908 break;
7909 case OPC_DI:
7910 check_insn(env, ctx, ISA_MIPS32R2);
7911 save_cpu_state(ctx, 1);
7912 gen_helper_di(t0);
7913 /* Stop translation as we may have switched the execution mode */
7914 ctx->bstate = BS_STOP;
7915 break;
7916 case OPC_EI:
7917 check_insn(env, ctx, ISA_MIPS32R2);
7918 save_cpu_state(ctx, 1);
7919 gen_helper_ei(t0);
7920 /* Stop translation as we may have switched the execution mode */
7921 ctx->bstate = BS_STOP;
7922 break;
7923 default: /* Invalid */
7924 MIPS_INVAL("mfmc0");
7925 generate_exception(ctx, EXCP_RI);
7926 break;
7928 gen_store_gpr(t0, rt);
7929 tcg_temp_free(t0);
7931 #endif /* !CONFIG_USER_ONLY */
7932 break;
7933 case OPC_RDPGPR:
7934 check_insn(env, ctx, ISA_MIPS32R2);
7935 gen_load_srsgpr(rt, rd);
7936 break;
7937 case OPC_WRPGPR:
7938 check_insn(env, ctx, ISA_MIPS32R2);
7939 gen_store_srsgpr(rt, rd);
7940 break;
7941 default:
7942 MIPS_INVAL("cp0");
7943 generate_exception(ctx, EXCP_RI);
7944 break;
7946 break;
7947 case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7948 gen_arith_imm(env, ctx, op, rt, rs, imm);
7949 break;
7950 case OPC_J ... OPC_JAL: /* Jump */
7951 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7952 gen_compute_branch(ctx, op, rs, rt, offset);
7953 return;
7954 case OPC_BEQ ... OPC_BGTZ: /* Branch */
7955 case OPC_BEQL ... OPC_BGTZL:
7956 gen_compute_branch(ctx, op, rs, rt, imm << 2);
7957 return;
7958 case OPC_LB ... OPC_LWR: /* Load and stores */
7959 case OPC_SB ... OPC_SW:
7960 case OPC_SWR:
7961 case OPC_LL:
7962 case OPC_SC:
7963 gen_ldst(ctx, op, rt, rs, imm);
7964 break;
7965 case OPC_CACHE:
7966 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7967 /* Treat as NOP. */
7968 break;
7969 case OPC_PREF:
7970 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7971 /* Treat as NOP. */
7972 break;
7974 /* Floating point (COP1). */
7975 case OPC_LWC1:
7976 case OPC_LDC1:
7977 case OPC_SWC1:
7978 case OPC_SDC1:
7979 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7980 save_cpu_state(ctx, 1);
7981 check_cp1_enabled(ctx);
7982 gen_flt_ldst(ctx, op, rt, rs, imm);
7983 } else {
7984 generate_exception_err(ctx, EXCP_CpU, 1);
7986 break;
7988 case OPC_CP1:
7989 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7990 save_cpu_state(ctx, 1);
7991 check_cp1_enabled(ctx);
7992 op1 = MASK_CP1(ctx->opcode);
7993 switch (op1) {
7994 case OPC_MFHC1:
7995 case OPC_MTHC1:
7996 check_insn(env, ctx, ISA_MIPS32R2);
7997 case OPC_MFC1:
7998 case OPC_CFC1:
7999 case OPC_MTC1:
8000 case OPC_CTC1:
8001 gen_cp1(ctx, op1, rt, rd);
8002 break;
8003 #if defined(TARGET_MIPS64)
8004 case OPC_DMFC1:
8005 case OPC_DMTC1:
8006 check_insn(env, ctx, ISA_MIPS3);
8007 gen_cp1(ctx, op1, rt, rd);
8008 break;
8009 #endif
8010 case OPC_BC1ANY2:
8011 case OPC_BC1ANY4:
8012 check_cop1x(ctx);
8013 check_insn(env, ctx, ASE_MIPS3D);
8014 /* fall through */
8015 case OPC_BC1:
8016 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8017 (rt >> 2) & 0x7, imm << 2);
8018 return;
8019 case OPC_S_FMT:
8020 case OPC_D_FMT:
8021 case OPC_W_FMT:
8022 case OPC_L_FMT:
8023 case OPC_PS_FMT:
8024 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8025 (imm >> 8) & 0x7);
8026 break;
8027 default:
8028 MIPS_INVAL("cp1");
8029 generate_exception (ctx, EXCP_RI);
8030 break;
8032 } else {
8033 generate_exception_err(ctx, EXCP_CpU, 1);
8035 break;
8037 /* COP2. */
8038 case OPC_LWC2:
8039 case OPC_LDC2:
8040 case OPC_SWC2:
8041 case OPC_SDC2:
8042 case OPC_CP2:
8043 /* COP2: Not implemented. */
8044 generate_exception_err(ctx, EXCP_CpU, 2);
8045 break;
8047 case OPC_CP3:
8048 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8049 save_cpu_state(ctx, 1);
8050 check_cp1_enabled(ctx);
8051 op1 = MASK_CP3(ctx->opcode);
8052 switch (op1) {
8053 case OPC_LWXC1:
8054 case OPC_LDXC1:
8055 case OPC_LUXC1:
8056 case OPC_SWXC1:
8057 case OPC_SDXC1:
8058 case OPC_SUXC1:
8059 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8060 break;
8061 case OPC_PREFX:
8062 /* Treat as NOP. */
8063 break;
8064 case OPC_ALNV_PS:
8065 case OPC_MADD_S:
8066 case OPC_MADD_D:
8067 case OPC_MADD_PS:
8068 case OPC_MSUB_S:
8069 case OPC_MSUB_D:
8070 case OPC_MSUB_PS:
8071 case OPC_NMADD_S:
8072 case OPC_NMADD_D:
8073 case OPC_NMADD_PS:
8074 case OPC_NMSUB_S:
8075 case OPC_NMSUB_D:
8076 case OPC_NMSUB_PS:
8077 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8078 break;
8079 default:
8080 MIPS_INVAL("cp3");
8081 generate_exception (ctx, EXCP_RI);
8082 break;
8084 } else {
8085 generate_exception_err(ctx, EXCP_CpU, 1);
8087 break;
8089 #if defined(TARGET_MIPS64)
8090 /* MIPS64 opcodes */
8091 case OPC_LWU:
8092 case OPC_LDL ... OPC_LDR:
8093 case OPC_SDL ... OPC_SDR:
8094 case OPC_LLD:
8095 case OPC_LD:
8096 case OPC_SCD:
8097 case OPC_SD:
8098 check_insn(env, ctx, ISA_MIPS3);
8099 check_mips_64(ctx);
8100 gen_ldst(ctx, op, rt, rs, imm);
8101 break;
8102 case OPC_DADDI ... OPC_DADDIU:
8103 check_insn(env, ctx, ISA_MIPS3);
8104 check_mips_64(ctx);
8105 gen_arith_imm(env, ctx, op, rt, rs, imm);
8106 break;
8107 #endif
8108 case OPC_JALX:
8109 check_insn(env, ctx, ASE_MIPS16);
8110 /* MIPS16: Not implemented. */
8111 case OPC_MDMX:
8112 check_insn(env, ctx, ASE_MDMX);
8113 /* MDMX: Not implemented. */
8114 default: /* Invalid */
8115 MIPS_INVAL("major opcode");
8116 generate_exception(ctx, EXCP_RI);
8117 break;
8119 if (ctx->hflags & MIPS_HFLAG_BMASK) {
8120 int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8121 /* Branches completion */
8122 ctx->hflags &= ~MIPS_HFLAG_BMASK;
8123 ctx->bstate = BS_BRANCH;
8124 save_cpu_state(ctx, 0);
8125 /* FIXME: Need to clear can_do_io. */
8126 switch (hflags) {
8127 case MIPS_HFLAG_B:
8128 /* unconditional branch */
8129 MIPS_DEBUG("unconditional branch");
8130 gen_goto_tb(ctx, 0, ctx->btarget);
8131 break;
8132 case MIPS_HFLAG_BL:
8133 /* blikely taken case */
8134 MIPS_DEBUG("blikely branch taken");
8135 gen_goto_tb(ctx, 0, ctx->btarget);
8136 break;
8137 case MIPS_HFLAG_BC:
8138 /* Conditional branch */
8139 MIPS_DEBUG("conditional branch");
8141 int l1 = gen_new_label();
8143 tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8144 gen_goto_tb(ctx, 1, ctx->pc + 4);
8145 gen_set_label(l1);
8146 gen_goto_tb(ctx, 0, ctx->btarget);
8148 break;
8149 case MIPS_HFLAG_BR:
8150 /* unconditional branch to register */
8151 MIPS_DEBUG("branch to register");
8152 tcg_gen_mov_tl(cpu_PC, btarget);
8153 tcg_gen_exit_tb(0);
8154 break;
8155 default:
8156 MIPS_DEBUG("unknown branch");
8157 break;
8162 static inline void
8163 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8164 int search_pc)
8166 DisasContext ctx;
8167 target_ulong pc_start;
8168 uint16_t *gen_opc_end;
8169 CPUBreakpoint *bp;
8170 int j, lj = -1;
8171 int num_insns;
8172 int max_insns;
8174 if (search_pc)
8175 qemu_log("search pc %d\n", search_pc);
8177 pc_start = tb->pc;
8178 /* Leave some spare opc slots for branch handling. */
8179 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8180 ctx.pc = pc_start;
8181 ctx.saved_pc = -1;
8182 ctx.tb = tb;
8183 ctx.bstate = BS_NONE;
8184 /* Restore delay slot state from the tb context. */
8185 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8186 restore_cpu_state(env, &ctx);
8187 #ifdef CONFIG_USER_ONLY
8188 ctx.mem_idx = MIPS_HFLAG_UM;
8189 #else
8190 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8191 #endif
8192 num_insns = 0;
8193 max_insns = tb->cflags & CF_COUNT_MASK;
8194 if (max_insns == 0)
8195 max_insns = CF_COUNT_MASK;
8196 #ifdef DEBUG_DISAS
8197 qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8198 /* FIXME: This may print out stale hflags from env... */
8199 log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8200 #endif
8201 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8202 gen_icount_start();
8203 while (ctx.bstate == BS_NONE) {
8204 if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8205 TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8206 if (bp->pc == ctx.pc) {
8207 save_cpu_state(&ctx, 1);
8208 ctx.bstate = BS_BRANCH;
8209 gen_helper_0i(raise_exception, EXCP_DEBUG);
8210 /* Include the breakpoint location or the tb won't
8211 * be flushed when it must be. */
8212 ctx.pc += 4;
8213 goto done_generating;
8218 if (search_pc) {
8219 j = gen_opc_ptr - gen_opc_buf;
8220 if (lj < j) {
8221 lj++;
8222 while (lj < j)
8223 gen_opc_instr_start[lj++] = 0;
8225 gen_opc_pc[lj] = ctx.pc;
8226 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8227 gen_opc_instr_start[lj] = 1;
8228 gen_opc_icount[lj] = num_insns;
8230 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8231 gen_io_start();
8232 ctx.opcode = ldl_code(ctx.pc);
8233 decode_opc(env, &ctx);
8234 ctx.pc += 4;
8235 num_insns++;
8237 if (env->singlestep_enabled)
8238 break;
8240 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8241 break;
8243 if (gen_opc_ptr >= gen_opc_end)
8244 break;
8246 if (num_insns >= max_insns)
8247 break;
8248 #if defined (MIPS_SINGLE_STEP)
8249 break;
8250 #endif
8252 if (tb->cflags & CF_LAST_IO)
8253 gen_io_end();
8254 if (env->singlestep_enabled) {
8255 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8256 gen_helper_0i(raise_exception, EXCP_DEBUG);
8257 } else {
8258 switch (ctx.bstate) {
8259 case BS_STOP:
8260 gen_helper_interrupt_restart();
8261 gen_goto_tb(&ctx, 0, ctx.pc);
8262 break;
8263 case BS_NONE:
8264 save_cpu_state(&ctx, 0);
8265 gen_goto_tb(&ctx, 0, ctx.pc);
8266 break;
8267 case BS_EXCP:
8268 gen_helper_interrupt_restart();
8269 tcg_gen_exit_tb(0);
8270 break;
8271 case BS_BRANCH:
8272 default:
8273 break;
8276 done_generating:
8277 gen_icount_end(tb, num_insns);
8278 *gen_opc_ptr = INDEX_op_end;
8279 if (search_pc) {
8280 j = gen_opc_ptr - gen_opc_buf;
8281 lj++;
8282 while (lj <= j)
8283 gen_opc_instr_start[lj++] = 0;
8284 } else {
8285 tb->size = ctx.pc - pc_start;
8286 tb->icount = num_insns;
8288 #ifdef DEBUG_DISAS
8289 LOG_DISAS("\n");
8290 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8291 qemu_log("IN: %s\n", lookup_symbol(pc_start));
8292 log_target_disas(pc_start, ctx.pc - pc_start, 0);
8293 qemu_log("\n");
8295 qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8296 #endif
8299 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8301 gen_intermediate_code_internal(env, tb, 0);
8304 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8306 gen_intermediate_code_internal(env, tb, 1);
8309 static void fpu_dump_state(CPUState *env, FILE *f,
8310 int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8311 int flags)
8313 int i;
8314 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8316 #define printfpr(fp) \
8317 do { \
8318 if (is_fpu64) \
8319 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n", \
8320 (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd, \
8321 (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8322 else { \
8323 fpr_t tmp; \
8324 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
8325 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
8326 fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n", \
8327 tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd, \
8328 tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]); \
8330 } while(0)
8333 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%08x(0x%02x)\n",
8334 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8335 get_float_exception_flags(&env->active_fpu.fp_status));
8336 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8337 fpu_fprintf(f, "%3s: ", fregnames[i]);
8338 printfpr(&env->active_fpu.fpr[i]);
8341 #undef printfpr
8344 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8345 /* Debug help: The architecture requires 32bit code to maintain proper
8346 sign-extended values on 64bit machines. */
8348 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8350 static void
8351 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8352 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8353 int flags)
8355 int i;
8357 if (!SIGN_EXT_P(env->active_tc.PC))
8358 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8359 if (!SIGN_EXT_P(env->active_tc.HI[0]))
8360 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8361 if (!SIGN_EXT_P(env->active_tc.LO[0]))
8362 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8363 if (!SIGN_EXT_P(env->btarget))
8364 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8366 for (i = 0; i < 32; i++) {
8367 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8368 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8371 if (!SIGN_EXT_P(env->CP0_EPC))
8372 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8373 if (!SIGN_EXT_P(env->CP0_LLAddr))
8374 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8376 #endif
8378 void cpu_dump_state (CPUState *env, FILE *f,
8379 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8380 int flags)
8382 int i;
8384 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",
8385 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8386 env->hflags, env->btarget, env->bcond);
8387 for (i = 0; i < 32; i++) {
8388 if ((i & 3) == 0)
8389 cpu_fprintf(f, "GPR%02d:", i);
8390 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8391 if ((i & 3) == 3)
8392 cpu_fprintf(f, "\n");
8395 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
8396 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8397 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8398 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8399 if (env->hflags & MIPS_HFLAG_FPU)
8400 fpu_dump_state(env, f, cpu_fprintf, flags);
8401 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8402 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8403 #endif
8406 static void mips_tcg_init(void)
8408 int i;
8409 static int inited;
8411 /* Initialize various static tables. */
8412 if (inited)
8413 return;
8415 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8416 for (i = 0; i < 32; i++)
8417 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8418 offsetof(CPUState, active_tc.gpr[i]),
8419 regnames[i]);
8420 cpu_PC = tcg_global_mem_new(TCG_AREG0,
8421 offsetof(CPUState, active_tc.PC), "PC");
8422 for (i = 0; i < MIPS_DSP_ACC; i++) {
8423 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8424 offsetof(CPUState, active_tc.HI[i]),
8425 regnames_HI[i]);
8426 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8427 offsetof(CPUState, active_tc.LO[i]),
8428 regnames_LO[i]);
8429 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8430 offsetof(CPUState, active_tc.ACX[i]),
8431 regnames_ACX[i]);
8433 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8434 offsetof(CPUState, active_tc.DSPControl),
8435 "DSPControl");
8436 bcond = tcg_global_mem_new_i32(TCG_AREG0,
8437 offsetof(CPUState, bcond), "bcond");
8438 btarget = tcg_global_mem_new(TCG_AREG0,
8439 offsetof(CPUState, btarget), "btarget");
8440 for (i = 0; i < 32; i++)
8441 fpu_fpr32[i] = tcg_global_mem_new_i32(TCG_AREG0,
8442 offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
8443 fregnames[i]);
8444 for (i = 0; i < 32; i++)
8445 fpu_fpr64[i] = tcg_global_mem_new_i64(TCG_AREG0,
8446 offsetof(CPUState, active_fpu.fpr[i]),
8447 fregnames_64[i]);
8448 for (i = 0; i < 32; i++)
8449 fpu_fpr32h[i] = tcg_global_mem_new_i32(TCG_AREG0,
8450 offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
8451 fregnames_h[i]);
8452 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8453 offsetof(CPUState, active_fpu.fcr0),
8454 "fcr0");
8455 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8456 offsetof(CPUState, active_fpu.fcr31),
8457 "fcr31");
8459 /* register helpers */
8460 #define GEN_HELPER 2
8461 #include "helper.h"
8463 inited = 1;
8466 #include "translate_init.c"
8468 CPUMIPSState *cpu_mips_init (const char *cpu_model)
8470 CPUMIPSState *env;
8471 const mips_def_t *def;
8473 def = cpu_mips_find_by_name(cpu_model);
8474 if (!def)
8475 return NULL;
8476 env = qemu_mallocz(sizeof(CPUMIPSState));
8477 env->cpu_model = def;
8479 cpu_exec_init(env);
8480 env->cpu_model_str = cpu_model;
8481 mips_tcg_init();
8482 cpu_reset(env);
8483 return env;
8486 void cpu_reset (CPUMIPSState *env)
8488 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8489 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8490 log_cpu_state(env, 0);
8493 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8495 tlb_flush(env, 1);
8497 /* Minimal init */
8498 #if defined(CONFIG_USER_ONLY)
8499 env->hflags = MIPS_HFLAG_UM;
8500 #else
8501 if (env->hflags & MIPS_HFLAG_BMASK) {
8502 /* If the exception was raised from a delay slot,
8503 come back to the jump. */
8504 env->CP0_ErrorEPC = env->active_tc.PC - 4;
8505 } else {
8506 env->CP0_ErrorEPC = env->active_tc.PC;
8508 env->active_tc.PC = (int32_t)0xBFC00000;
8509 env->CP0_Wired = 0;
8510 /* SMP not implemented */
8511 env->CP0_EBase = 0x80000000;
8512 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8513 /* vectored interrupts not implemented, timer on int 7,
8514 no performance counters. */
8515 env->CP0_IntCtl = 0xe0000000;
8517 int i;
8519 for (i = 0; i < 7; i++) {
8520 env->CP0_WatchLo[i] = 0;
8521 env->CP0_WatchHi[i] = 0x80000000;
8523 env->CP0_WatchLo[7] = 0;
8524 env->CP0_WatchHi[7] = 0;
8526 /* Count register increments in debug mode, EJTAG version 1 */
8527 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8528 env->hflags = MIPS_HFLAG_CP0;
8529 #endif
8530 env->exception_index = EXCP_NONE;
8531 cpu_mips_register(env, env->cpu_model);
8534 void gen_pc_load(CPUState *env, TranslationBlock *tb,
8535 unsigned long searched_pc, int pc_pos, void *puc)
8537 env->active_tc.PC = gen_opc_pc[pc_pos];
8538 env->hflags &= ~MIPS_HFLAG_BMASK;
8539 env->hflags |= gen_opc_hflags[pc_pos];