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