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