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