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