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