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