]> git.proxmox.com Git - qemu.git/blame - target-mips/translate.c
target-mips: restore CPU state after an FPU exception
[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)
3c824109 7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
4133498f 8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
6af0bf9c
FB
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
8167ee88 21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
6af0bf9c
FB
22 */
23
6af0bf9c 24#include "cpu.h"
6af0bf9c 25#include "disas.h"
57fec1fe 26#include "tcg-op.h"
6af0bf9c 27
a7812ae4
PB
28#include "helper.h"
29#define GEN_HELPER 1
30#include "helper.h"
31
fb7729e2 32#define MIPS_DEBUG_DISAS 0
c570fd16 33//#define MIPS_DEBUG_SIGN_EXTENSIONS
6af0bf9c 34
7a387fff
TS
35/* MIPS major opcodes */
36#define MASK_OP_MAJOR(op) (op & (0x3F << 26))
e37e863f
FB
37
38enum {
39 /* indirect opcode tables */
7a387fff
TS
40 OPC_SPECIAL = (0x00 << 26),
41 OPC_REGIMM = (0x01 << 26),
42 OPC_CP0 = (0x10 << 26),
43 OPC_CP1 = (0x11 << 26),
44 OPC_CP2 = (0x12 << 26),
45 OPC_CP3 = (0x13 << 26),
46 OPC_SPECIAL2 = (0x1C << 26),
47 OPC_SPECIAL3 = (0x1F << 26),
e37e863f 48 /* arithmetic with immediate */
7a387fff
TS
49 OPC_ADDI = (0x08 << 26),
50 OPC_ADDIU = (0x09 << 26),
51 OPC_SLTI = (0x0A << 26),
52 OPC_SLTIU = (0x0B << 26),
324d9e32 53 /* logic with immediate */
7a387fff
TS
54 OPC_ANDI = (0x0C << 26),
55 OPC_ORI = (0x0D << 26),
56 OPC_XORI = (0x0E << 26),
57 OPC_LUI = (0x0F << 26),
324d9e32 58 /* arithmetic with immediate */
7a387fff
TS
59 OPC_DADDI = (0x18 << 26),
60 OPC_DADDIU = (0x19 << 26),
e37e863f 61 /* Jump and branches */
7a387fff
TS
62 OPC_J = (0x02 << 26),
63 OPC_JAL = (0x03 << 26),
620e48f6 64 OPC_JALS = OPC_JAL | 0x5,
7a387fff
TS
65 OPC_BEQ = (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL = (0x14 << 26),
67 OPC_BNE = (0x05 << 26),
68 OPC_BNEL = (0x15 << 26),
69 OPC_BLEZ = (0x06 << 26),
70 OPC_BLEZL = (0x16 << 26),
71 OPC_BGTZ = (0x07 << 26),
72 OPC_BGTZL = (0x17 << 26),
73 OPC_JALX = (0x1D << 26), /* MIPS 16 only */
620e48f6 74 OPC_JALXS = OPC_JALX | 0x5,
e37e863f 75 /* Load and stores */
7a387fff
TS
76 OPC_LDL = (0x1A << 26),
77 OPC_LDR = (0x1B << 26),
78 OPC_LB = (0x20 << 26),
79 OPC_LH = (0x21 << 26),
80 OPC_LWL = (0x22 << 26),
81 OPC_LW = (0x23 << 26),
364d4831 82 OPC_LWPC = OPC_LW | 0x5,
7a387fff
TS
83 OPC_LBU = (0x24 << 26),
84 OPC_LHU = (0x25 << 26),
85 OPC_LWR = (0x26 << 26),
86 OPC_LWU = (0x27 << 26),
87 OPC_SB = (0x28 << 26),
88 OPC_SH = (0x29 << 26),
89 OPC_SWL = (0x2A << 26),
90 OPC_SW = (0x2B << 26),
91 OPC_SDL = (0x2C << 26),
92 OPC_SDR = (0x2D << 26),
93 OPC_SWR = (0x2E << 26),
94 OPC_LL = (0x30 << 26),
95 OPC_LLD = (0x34 << 26),
96 OPC_LD = (0x37 << 26),
364d4831 97 OPC_LDPC = OPC_LD | 0x5,
7a387fff
TS
98 OPC_SC = (0x38 << 26),
99 OPC_SCD = (0x3C << 26),
100 OPC_SD = (0x3F << 26),
e37e863f 101 /* Floating point load/store */
7a387fff
TS
102 OPC_LWC1 = (0x31 << 26),
103 OPC_LWC2 = (0x32 << 26),
104 OPC_LDC1 = (0x35 << 26),
105 OPC_LDC2 = (0x36 << 26),
106 OPC_SWC1 = (0x39 << 26),
107 OPC_SWC2 = (0x3A << 26),
108 OPC_SDC1 = (0x3D << 26),
109 OPC_SDC2 = (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX = (0x1E << 26),
e37e863f 112 /* Cache and prefetch */
7a387fff
TS
113 OPC_CACHE = (0x2F << 26),
114 OPC_PREF = (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED = (0x3B << 26),
e37e863f
FB
117};
118
119/* MIPS special opcodes */
7a387fff
TS
120#define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
121
e37e863f
FB
122enum {
123 /* Shifts */
7a387fff 124 OPC_SLL = 0x00 | OPC_SPECIAL,
e37e863f
FB
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
7a387fff
TS
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL = 0x02 | OPC_SPECIAL, /* also ROTR */
ea63e2c3 129 OPC_ROTR = OPC_SRL | (1 << 21),
7a387fff
TS
130 OPC_SRA = 0x03 | OPC_SPECIAL,
131 OPC_SLLV = 0x04 | OPC_SPECIAL,
e189e748 132 OPC_SRLV = 0x06 | OPC_SPECIAL, /* also ROTRV */
ea63e2c3 133 OPC_ROTRV = OPC_SRLV | (1 << 6),
7a387fff
TS
134 OPC_SRAV = 0x07 | OPC_SPECIAL,
135 OPC_DSLLV = 0x14 | OPC_SPECIAL,
136 OPC_DSRLV = 0x16 | OPC_SPECIAL, /* also DROTRV */
ea63e2c3 137 OPC_DROTRV = OPC_DSRLV | (1 << 6),
7a387fff
TS
138 OPC_DSRAV = 0x17 | OPC_SPECIAL,
139 OPC_DSLL = 0x38 | OPC_SPECIAL,
140 OPC_DSRL = 0x3A | OPC_SPECIAL, /* also DROTR */
ea63e2c3 141 OPC_DROTR = OPC_DSRL | (1 << 21),
7a387fff
TS
142 OPC_DSRA = 0x3B | OPC_SPECIAL,
143 OPC_DSLL32 = 0x3C | OPC_SPECIAL,
144 OPC_DSRL32 = 0x3E | OPC_SPECIAL, /* also DROTR32 */
ea63e2c3 145 OPC_DROTR32 = OPC_DSRL32 | (1 << 21),
7a387fff 146 OPC_DSRA32 = 0x3F | OPC_SPECIAL,
e37e863f 147 /* Multiplication / division */
7a387fff
TS
148 OPC_MULT = 0x18 | OPC_SPECIAL,
149 OPC_MULTU = 0x19 | OPC_SPECIAL,
150 OPC_DIV = 0x1A | OPC_SPECIAL,
151 OPC_DIVU = 0x1B | OPC_SPECIAL,
152 OPC_DMULT = 0x1C | OPC_SPECIAL,
153 OPC_DMULTU = 0x1D | OPC_SPECIAL,
154 OPC_DDIV = 0x1E | OPC_SPECIAL,
155 OPC_DDIVU = 0x1F | OPC_SPECIAL,
e37e863f 156 /* 2 registers arithmetic / logic */
7a387fff
TS
157 OPC_ADD = 0x20 | OPC_SPECIAL,
158 OPC_ADDU = 0x21 | OPC_SPECIAL,
159 OPC_SUB = 0x22 | OPC_SPECIAL,
160 OPC_SUBU = 0x23 | OPC_SPECIAL,
161 OPC_AND = 0x24 | OPC_SPECIAL,
162 OPC_OR = 0x25 | OPC_SPECIAL,
163 OPC_XOR = 0x26 | OPC_SPECIAL,
164 OPC_NOR = 0x27 | OPC_SPECIAL,
165 OPC_SLT = 0x2A | OPC_SPECIAL,
166 OPC_SLTU = 0x2B | OPC_SPECIAL,
167 OPC_DADD = 0x2C | OPC_SPECIAL,
168 OPC_DADDU = 0x2D | OPC_SPECIAL,
169 OPC_DSUB = 0x2E | OPC_SPECIAL,
170 OPC_DSUBU = 0x2F | OPC_SPECIAL,
e37e863f 171 /* Jumps */
7a387fff
TS
172 OPC_JR = 0x08 | OPC_SPECIAL, /* Also JR.HB */
173 OPC_JALR = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
364d4831 174 OPC_JALRC = OPC_JALR | (0x5 << 6),
620e48f6 175 OPC_JALRS = 0x10 | OPC_SPECIAL | (0x5 << 6),
e37e863f 176 /* Traps */
7a387fff
TS
177 OPC_TGE = 0x30 | OPC_SPECIAL,
178 OPC_TGEU = 0x31 | OPC_SPECIAL,
179 OPC_TLT = 0x32 | OPC_SPECIAL,
180 OPC_TLTU = 0x33 | OPC_SPECIAL,
181 OPC_TEQ = 0x34 | OPC_SPECIAL,
182 OPC_TNE = 0x36 | OPC_SPECIAL,
e37e863f 183 /* HI / LO registers load & stores */
7a387fff
TS
184 OPC_MFHI = 0x10 | OPC_SPECIAL,
185 OPC_MTHI = 0x11 | OPC_SPECIAL,
186 OPC_MFLO = 0x12 | OPC_SPECIAL,
187 OPC_MTLO = 0x13 | OPC_SPECIAL,
e37e863f 188 /* Conditional moves */
7a387fff
TS
189 OPC_MOVZ = 0x0A | OPC_SPECIAL,
190 OPC_MOVN = 0x0B | OPC_SPECIAL,
e37e863f 191
7a387fff 192 OPC_MOVCI = 0x01 | OPC_SPECIAL,
e37e863f
FB
193
194 /* Special */
a0d700e4 195 OPC_PMON = 0x05 | OPC_SPECIAL, /* unofficial */
7a387fff
TS
196 OPC_SYSCALL = 0x0C | OPC_SPECIAL,
197 OPC_BREAK = 0x0D | OPC_SPECIAL,
a0d700e4 198 OPC_SPIM = 0x0E | OPC_SPECIAL, /* unofficial */
7a387fff
TS
199 OPC_SYNC = 0x0F | OPC_SPECIAL,
200
201 OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
202 OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
203 OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
204 OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
205 OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
206 OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
207 OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
208};
209
e9c71dd1
TS
210/* Multiplication variants of the vr54xx. */
211#define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
212
213enum {
214 OPC_VR54XX_MULS = (0x03 << 6) | OPC_MULT,
215 OPC_VR54XX_MULSU = (0x03 << 6) | OPC_MULTU,
216 OPC_VR54XX_MACC = (0x05 << 6) | OPC_MULT,
217 OPC_VR54XX_MACCU = (0x05 << 6) | OPC_MULTU,
218 OPC_VR54XX_MSAC = (0x07 << 6) | OPC_MULT,
219 OPC_VR54XX_MSACU = (0x07 << 6) | OPC_MULTU,
220 OPC_VR54XX_MULHI = (0x09 << 6) | OPC_MULT,
221 OPC_VR54XX_MULHIU = (0x09 << 6) | OPC_MULTU,
222 OPC_VR54XX_MULSHI = (0x0B << 6) | OPC_MULT,
223 OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
224 OPC_VR54XX_MACCHI = (0x0D << 6) | OPC_MULT,
225 OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
226 OPC_VR54XX_MSACHI = (0x0F << 6) | OPC_MULT,
227 OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
228};
229
7a387fff
TS
230/* REGIMM (rt field) opcodes */
231#define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
232
233enum {
234 OPC_BLTZ = (0x00 << 16) | OPC_REGIMM,
235 OPC_BLTZL = (0x02 << 16) | OPC_REGIMM,
236 OPC_BGEZ = (0x01 << 16) | OPC_REGIMM,
237 OPC_BGEZL = (0x03 << 16) | OPC_REGIMM,
238 OPC_BLTZAL = (0x10 << 16) | OPC_REGIMM,
3c824109 239 OPC_BLTZALS = OPC_BLTZAL | 0x5, /* microMIPS */
7a387fff
TS
240 OPC_BLTZALL = (0x12 << 16) | OPC_REGIMM,
241 OPC_BGEZAL = (0x11 << 16) | OPC_REGIMM,
3c824109 242 OPC_BGEZALS = OPC_BGEZAL | 0x5, /* microMIPS */
7a387fff
TS
243 OPC_BGEZALL = (0x13 << 16) | OPC_REGIMM,
244 OPC_TGEI = (0x08 << 16) | OPC_REGIMM,
245 OPC_TGEIU = (0x09 << 16) | OPC_REGIMM,
246 OPC_TLTI = (0x0A << 16) | OPC_REGIMM,
247 OPC_TLTIU = (0x0B << 16) | OPC_REGIMM,
248 OPC_TEQI = (0x0C << 16) | OPC_REGIMM,
249 OPC_TNEI = (0x0E << 16) | OPC_REGIMM,
250 OPC_SYNCI = (0x1F << 16) | OPC_REGIMM,
e37e863f
FB
251};
252
7a387fff
TS
253/* Special2 opcodes */
254#define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
255
e37e863f 256enum {
7a387fff
TS
257 /* Multiply & xxx operations */
258 OPC_MADD = 0x00 | OPC_SPECIAL2,
259 OPC_MADDU = 0x01 | OPC_SPECIAL2,
260 OPC_MUL = 0x02 | OPC_SPECIAL2,
261 OPC_MSUB = 0x04 | OPC_SPECIAL2,
262 OPC_MSUBU = 0x05 | OPC_SPECIAL2,
161f85e6
AJ
263 /* Loongson 2F */
264 OPC_MULT_G_2F = 0x10 | OPC_SPECIAL2,
265 OPC_DMULT_G_2F = 0x11 | OPC_SPECIAL2,
266 OPC_MULTU_G_2F = 0x12 | OPC_SPECIAL2,
267 OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
268 OPC_DIV_G_2F = 0x14 | OPC_SPECIAL2,
269 OPC_DDIV_G_2F = 0x15 | OPC_SPECIAL2,
270 OPC_DIVU_G_2F = 0x16 | OPC_SPECIAL2,
271 OPC_DDIVU_G_2F = 0x17 | OPC_SPECIAL2,
272 OPC_MOD_G_2F = 0x1c | OPC_SPECIAL2,
273 OPC_DMOD_G_2F = 0x1d | OPC_SPECIAL2,
274 OPC_MODU_G_2F = 0x1e | OPC_SPECIAL2,
275 OPC_DMODU_G_2F = 0x1f | OPC_SPECIAL2,
e37e863f 276 /* Misc */
7a387fff
TS
277 OPC_CLZ = 0x20 | OPC_SPECIAL2,
278 OPC_CLO = 0x21 | OPC_SPECIAL2,
279 OPC_DCLZ = 0x24 | OPC_SPECIAL2,
280 OPC_DCLO = 0x25 | OPC_SPECIAL2,
e37e863f 281 /* Special */
7a387fff
TS
282 OPC_SDBBP = 0x3F | OPC_SPECIAL2,
283};
284
285/* Special3 opcodes */
286#define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
287
288enum {
289 OPC_EXT = 0x00 | OPC_SPECIAL3,
290 OPC_DEXTM = 0x01 | OPC_SPECIAL3,
291 OPC_DEXTU = 0x02 | OPC_SPECIAL3,
292 OPC_DEXT = 0x03 | OPC_SPECIAL3,
293 OPC_INS = 0x04 | OPC_SPECIAL3,
294 OPC_DINSM = 0x05 | OPC_SPECIAL3,
295 OPC_DINSU = 0x06 | OPC_SPECIAL3,
296 OPC_DINS = 0x07 | OPC_SPECIAL3,
ead9360e
TS
297 OPC_FORK = 0x08 | OPC_SPECIAL3,
298 OPC_YIELD = 0x09 | OPC_SPECIAL3,
7a387fff
TS
299 OPC_BSHFL = 0x20 | OPC_SPECIAL3,
300 OPC_DBSHFL = 0x24 | OPC_SPECIAL3,
301 OPC_RDHWR = 0x3B | OPC_SPECIAL3,
161f85e6
AJ
302
303 /* Loongson 2E */
304 OPC_MULT_G_2E = 0x18 | OPC_SPECIAL3,
305 OPC_MULTU_G_2E = 0x19 | OPC_SPECIAL3,
306 OPC_DIV_G_2E = 0x1A | OPC_SPECIAL3,
307 OPC_DIVU_G_2E = 0x1B | OPC_SPECIAL3,
308 OPC_DMULT_G_2E = 0x1C | OPC_SPECIAL3,
309 OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
310 OPC_DDIV_G_2E = 0x1E | OPC_SPECIAL3,
311 OPC_DDIVU_G_2E = 0x1F | OPC_SPECIAL3,
312 OPC_MOD_G_2E = 0x22 | OPC_SPECIAL3,
313 OPC_MODU_G_2E = 0x23 | OPC_SPECIAL3,
314 OPC_DMOD_G_2E = 0x26 | OPC_SPECIAL3,
315 OPC_DMODU_G_2E = 0x27 | OPC_SPECIAL3,
9b1a1d68
JL
316
317 /* MIPS DSP Load */
318 OPC_LX_DSP = 0x0A | OPC_SPECIAL3,
461c08df
JL
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP = 0x10 | OPC_SPECIAL3,
461c08df 321 OPC_ADDU_OB_DSP = 0x14 | OPC_SPECIAL3,
461c08df 322 OPC_ABSQ_S_PH_DSP = 0x12 | OPC_SPECIAL3,
461c08df 323 OPC_ABSQ_S_QH_DSP = 0x16 | OPC_SPECIAL3,
461c08df
JL
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
461c08df 327 OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
77c5fa8b
JL
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP = 0x13 | OPC_SPECIAL3,
77c5fa8b 330 OPC_SHLL_OB_DSP = 0x17 | OPC_SPECIAL3,
77c5fa8b
JL
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP = 0x30 | OPC_SPECIAL3,
77c5fa8b 335 OPC_DPAQ_W_QH_DSP = 0x34 | OPC_SPECIAL3,
1cb6686c
JL
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP = 0x0C | OPC_SPECIAL3,
1cb6686c 338 OPC_DINSV_DSP = 0x0D | OPC_SPECIAL3,
26690560
JL
339 /* MIPS DSP Compare-Pick Sub-class */
340 OPC_APPEND_DSP = 0x31 | OPC_SPECIAL3,
26690560 341 OPC_DAPPEND_DSP = 0x35 | OPC_SPECIAL3,
b53371ed
JL
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3,
b53371ed 344 OPC_DEXTR_W_DSP = 0x3C | OPC_SPECIAL3,
e37e863f
FB
345};
346
7a387fff
TS
347/* BSHFL opcodes */
348#define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
349
e37e863f 350enum {
7a387fff
TS
351 OPC_WSBH = (0x02 << 6) | OPC_BSHFL,
352 OPC_SEB = (0x10 << 6) | OPC_BSHFL,
353 OPC_SEH = (0x18 << 6) | OPC_BSHFL,
e37e863f
FB
354};
355
7a387fff
TS
356/* DBSHFL opcodes */
357#define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
358
e37e863f 359enum {
7a387fff
TS
360 OPC_DSBH = (0x02 << 6) | OPC_DBSHFL,
361 OPC_DSHD = (0x05 << 6) | OPC_DBSHFL,
e37e863f
FB
362};
363
e45a93e2
JL
364/* MIPS DSP REGIMM opcodes */
365enum {
366 OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
e45a93e2 367 OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
e45a93e2
JL
368};
369
9b1a1d68
JL
370#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
371/* MIPS DSP Load */
372enum {
373 OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
374 OPC_LHX = (0x04 << 6) | OPC_LX_DSP,
375 OPC_LWX = (0x00 << 6) | OPC_LX_DSP,
9b1a1d68 376 OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
9b1a1d68
JL
377};
378
461c08df
JL
379#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
380enum {
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH = (0x0A << 6) | OPC_ADDU_QB_DSP,
383 OPC_ADDQ_S_PH = (0x0E << 6) | OPC_ADDU_QB_DSP,
384 OPC_ADDQ_S_W = (0x16 << 6) | OPC_ADDU_QB_DSP,
385 OPC_ADDU_QB = (0x00 << 6) | OPC_ADDU_QB_DSP,
386 OPC_ADDU_S_QB = (0x04 << 6) | OPC_ADDU_QB_DSP,
387 OPC_ADDU_PH = (0x08 << 6) | OPC_ADDU_QB_DSP,
388 OPC_ADDU_S_PH = (0x0C << 6) | OPC_ADDU_QB_DSP,
389 OPC_SUBQ_PH = (0x0B << 6) | OPC_ADDU_QB_DSP,
390 OPC_SUBQ_S_PH = (0x0F << 6) | OPC_ADDU_QB_DSP,
391 OPC_SUBQ_S_W = (0x17 << 6) | OPC_ADDU_QB_DSP,
392 OPC_SUBU_QB = (0x01 << 6) | OPC_ADDU_QB_DSP,
393 OPC_SUBU_S_QB = (0x05 << 6) | OPC_ADDU_QB_DSP,
394 OPC_SUBU_PH = (0x09 << 6) | OPC_ADDU_QB_DSP,
395 OPC_SUBU_S_PH = (0x0D << 6) | OPC_ADDU_QB_DSP,
396 OPC_ADDSC = (0x10 << 6) | OPC_ADDU_QB_DSP,
397 OPC_ADDWC = (0x11 << 6) | OPC_ADDU_QB_DSP,
398 OPC_MODSUB = (0x12 << 6) | OPC_ADDU_QB_DSP,
399 OPC_RADDU_W_QB = (0x14 << 6) | OPC_ADDU_QB_DSP,
a22260ae
JL
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
402 OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
403 OPC_MULQ_RS_PH = (0x1F << 6) | OPC_ADDU_QB_DSP,
404 OPC_MULEQ_S_W_PHL = (0x1C << 6) | OPC_ADDU_QB_DSP,
405 OPC_MULEQ_S_W_PHR = (0x1D << 6) | OPC_ADDU_QB_DSP,
406 OPC_MULQ_S_PH = (0x1E << 6) | OPC_ADDU_QB_DSP,
461c08df
JL
407};
408
409#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
411enum {
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB = (0x00 << 6) | OPC_ADDUH_QB_DSP,
414 OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
415 OPC_ADDQH_PH = (0x08 << 6) | OPC_ADDUH_QB_DSP,
416 OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
417 OPC_ADDQH_W = (0x10 << 6) | OPC_ADDUH_QB_DSP,
418 OPC_ADDQH_R_W = (0x12 << 6) | OPC_ADDUH_QB_DSP,
419 OPC_SUBUH_QB = (0x01 << 6) | OPC_ADDUH_QB_DSP,
420 OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
421 OPC_SUBQH_PH = (0x09 << 6) | OPC_ADDUH_QB_DSP,
422 OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
423 OPC_SUBQH_W = (0x11 << 6) | OPC_ADDUH_QB_DSP,
424 OPC_SUBQH_R_W = (0x13 << 6) | OPC_ADDUH_QB_DSP,
a22260ae
JL
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH = (0x0C << 6) | OPC_ADDUH_QB_DSP,
427 OPC_MUL_S_PH = (0x0E << 6) | OPC_ADDUH_QB_DSP,
428 OPC_MULQ_S_W = (0x16 << 6) | OPC_ADDUH_QB_DSP,
429 OPC_MULQ_RS_W = (0x17 << 6) | OPC_ADDUH_QB_DSP,
461c08df
JL
430};
431
432#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
433enum {
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
436 OPC_ABSQ_S_PH = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
437 OPC_ABSQ_S_W = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
438 OPC_PRECEQ_W_PHL = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
439 OPC_PRECEQ_W_PHR = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
440 OPC_PRECEQU_PH_QBL = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
441 OPC_PRECEQU_PH_QBR = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
442 OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
443 OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
444 OPC_PRECEU_PH_QBL = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
445 OPC_PRECEU_PH_QBR = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
446 OPC_PRECEU_PH_QBLA = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
447 OPC_PRECEU_PH_QBRA = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
1cb6686c
JL
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
450 OPC_REPL_QB = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
451 OPC_REPLV_QB = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
452 OPC_REPL_PH = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
453 OPC_REPLV_PH = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
461c08df
JL
454};
455
456#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457enum {
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
460 OPC_PRECRQ_QB_PH = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
461 OPC_PRECR_SRA_PH_W = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
462 OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
463 OPC_PRECRQ_PH_W = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
464 OPC_PRECRQ_RS_PH_W = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
465 OPC_PRECRQU_S_QB_PH = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
26690560
JL
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
468 OPC_CMPU_LT_QB = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
469 OPC_CMPU_LE_QB = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
470 OPC_CMPGU_EQ_QB = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
471 OPC_CMPGU_LT_QB = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
472 OPC_CMPGU_LE_QB = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
473 OPC_CMPGDU_EQ_QB = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
474 OPC_CMPGDU_LT_QB = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
475 OPC_CMPGDU_LE_QB = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
476 OPC_CMP_EQ_PH = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
477 OPC_CMP_LT_PH = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
478 OPC_CMP_LE_PH = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
479 OPC_PICK_QB = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
480 OPC_PICK_PH = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
481 OPC_PACKRL_PH = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
461c08df 482};
a22260ae 483
77c5fa8b
JL
484#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485enum {
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB = (0x00 << 6) | OPC_SHLL_QB_DSP,
488 OPC_SHLLV_QB = (0x02 << 6) | OPC_SHLL_QB_DSP,
489 OPC_SHLL_PH = (0x08 << 6) | OPC_SHLL_QB_DSP,
490 OPC_SHLLV_PH = (0x0A << 6) | OPC_SHLL_QB_DSP,
491 OPC_SHLL_S_PH = (0x0C << 6) | OPC_SHLL_QB_DSP,
492 OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
493 OPC_SHLL_S_W = (0x14 << 6) | OPC_SHLL_QB_DSP,
494 OPC_SHLLV_S_W = (0x16 << 6) | OPC_SHLL_QB_DSP,
495 OPC_SHRL_QB = (0x01 << 6) | OPC_SHLL_QB_DSP,
496 OPC_SHRLV_QB = (0x03 << 6) | OPC_SHLL_QB_DSP,
497 OPC_SHRL_PH = (0x19 << 6) | OPC_SHLL_QB_DSP,
498 OPC_SHRLV_PH = (0x1B << 6) | OPC_SHLL_QB_DSP,
499 OPC_SHRA_QB = (0x04 << 6) | OPC_SHLL_QB_DSP,
500 OPC_SHRA_R_QB = (0x05 << 6) | OPC_SHLL_QB_DSP,
501 OPC_SHRAV_QB = (0x06 << 6) | OPC_SHLL_QB_DSP,
502 OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
503 OPC_SHRA_PH = (0x09 << 6) | OPC_SHLL_QB_DSP,
504 OPC_SHRAV_PH = (0x0B << 6) | OPC_SHLL_QB_DSP,
505 OPC_SHRA_R_PH = (0x0D << 6) | OPC_SHLL_QB_DSP,
506 OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
507 OPC_SHRA_R_W = (0x15 << 6) | OPC_SHLL_QB_DSP,
508 OPC_SHRAV_R_W = (0x17 << 6) | OPC_SHLL_QB_DSP,
509};
461c08df 510
a22260ae
JL
511#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
512enum {
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL = (0x03 << 6) | OPC_DPA_W_PH_DSP,
515 OPC_DPAU_H_QBR = (0x07 << 6) | OPC_DPA_W_PH_DSP,
516 OPC_DPSU_H_QBL = (0x0B << 6) | OPC_DPA_W_PH_DSP,
517 OPC_DPSU_H_QBR = (0x0F << 6) | OPC_DPA_W_PH_DSP,
518 OPC_DPA_W_PH = (0x00 << 6) | OPC_DPA_W_PH_DSP,
519 OPC_DPAX_W_PH = (0x08 << 6) | OPC_DPA_W_PH_DSP,
520 OPC_DPAQ_S_W_PH = (0x04 << 6) | OPC_DPA_W_PH_DSP,
521 OPC_DPAQX_S_W_PH = (0x18 << 6) | OPC_DPA_W_PH_DSP,
522 OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
523 OPC_DPS_W_PH = (0x01 << 6) | OPC_DPA_W_PH_DSP,
524 OPC_DPSX_W_PH = (0x09 << 6) | OPC_DPA_W_PH_DSP,
525 OPC_DPSQ_S_W_PH = (0x05 << 6) | OPC_DPA_W_PH_DSP,
526 OPC_DPSQX_S_W_PH = (0x19 << 6) | OPC_DPA_W_PH_DSP,
527 OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
528 OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
529 OPC_DPAQ_SA_L_W = (0x0C << 6) | OPC_DPA_W_PH_DSP,
530 OPC_DPSQ_SA_L_W = (0x0D << 6) | OPC_DPA_W_PH_DSP,
531 OPC_MAQ_S_W_PHL = (0x14 << 6) | OPC_DPA_W_PH_DSP,
532 OPC_MAQ_S_W_PHR = (0x16 << 6) | OPC_DPA_W_PH_DSP,
533 OPC_MAQ_SA_W_PHL = (0x10 << 6) | OPC_DPA_W_PH_DSP,
534 OPC_MAQ_SA_W_PHR = (0x12 << 6) | OPC_DPA_W_PH_DSP,
535 OPC_MULSA_W_PH = (0x02 << 6) | OPC_DPA_W_PH_DSP,
536};
537
1cb6686c
JL
538#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539enum {
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
542};
543
26690560
JL
544#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545enum {
546 /* MIPS DSP Compare-Pick Sub-class */
547 OPC_APPEND = (0x00 << 6) | OPC_APPEND_DSP,
548 OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
549 OPC_BALIGN = (0x10 << 6) | OPC_APPEND_DSP,
550};
551
b53371ed
JL
552#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553enum {
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W = (0x00 << 6) | OPC_EXTR_W_DSP,
556 OPC_EXTR_R_W = (0x04 << 6) | OPC_EXTR_W_DSP,
557 OPC_EXTR_RS_W = (0x06 << 6) | OPC_EXTR_W_DSP,
558 OPC_EXTR_S_H = (0x0E << 6) | OPC_EXTR_W_DSP,
559 OPC_EXTRV_S_H = (0x0F << 6) | OPC_EXTR_W_DSP,
560 OPC_EXTRV_W = (0x01 << 6) | OPC_EXTR_W_DSP,
561 OPC_EXTRV_R_W = (0x05 << 6) | OPC_EXTR_W_DSP,
562 OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
563 OPC_EXTP = (0x02 << 6) | OPC_EXTR_W_DSP,
564 OPC_EXTPV = (0x03 << 6) | OPC_EXTR_W_DSP,
565 OPC_EXTPDP = (0x0A << 6) | OPC_EXTR_W_DSP,
566 OPC_EXTPDPV = (0x0B << 6) | OPC_EXTR_W_DSP,
567 OPC_SHILO = (0x1A << 6) | OPC_EXTR_W_DSP,
568 OPC_SHILOV = (0x1B << 6) | OPC_EXTR_W_DSP,
569 OPC_MTHLIP = (0x1F << 6) | OPC_EXTR_W_DSP,
570 OPC_WRDSP = (0x13 << 6) | OPC_EXTR_W_DSP,
571 OPC_RDDSP = (0x12 << 6) | OPC_EXTR_W_DSP,
572};
573
461c08df
JL
574#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575enum {
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
578 OPC_PRECEQ_L_PWR = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
579 OPC_PRECEQ_PW_QHL = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
580 OPC_PRECEQ_PW_QHR = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
581 OPC_PRECEQ_PW_QHLA = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
582 OPC_PRECEQ_PW_QHRA = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
583 OPC_PRECEQU_QH_OBL = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
584 OPC_PRECEQU_QH_OBR = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
585 OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
586 OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
587 OPC_PRECEU_QH_OBL = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
588 OPC_PRECEU_QH_OBR = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
589 OPC_PRECEU_QH_OBLA = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
590 OPC_PRECEU_QH_OBRA = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
591 OPC_ABSQ_S_OB = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
592 OPC_ABSQ_S_PW = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
593 OPC_ABSQ_S_QH = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
1cb6686c
JL
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
596 OPC_REPL_PW = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
597 OPC_REPL_QH = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
598 OPC_REPLV_OB = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
599 OPC_REPLV_PW = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
600 OPC_REPLV_QH = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
461c08df 601};
461c08df 602
461c08df
JL
603#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604enum {
a22260ae
JL
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
607 OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
608 OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
609 OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
610 OPC_MULQ_RS_QH = (0x1F << 6) | OPC_ADDU_OB_DSP,
461c08df
JL
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB = (0x14 << 6) | OPC_ADDU_OB_DSP,
613 OPC_SUBQ_PW = (0x13 << 6) | OPC_ADDU_OB_DSP,
614 OPC_SUBQ_S_PW = (0x17 << 6) | OPC_ADDU_OB_DSP,
615 OPC_SUBQ_QH = (0x0B << 6) | OPC_ADDU_OB_DSP,
616 OPC_SUBQ_S_QH = (0x0F << 6) | OPC_ADDU_OB_DSP,
617 OPC_SUBU_OB = (0x01 << 6) | OPC_ADDU_OB_DSP,
618 OPC_SUBU_S_OB = (0x05 << 6) | OPC_ADDU_OB_DSP,
619 OPC_SUBU_QH = (0x09 << 6) | OPC_ADDU_OB_DSP,
620 OPC_SUBU_S_QH = (0x0D << 6) | OPC_ADDU_OB_DSP,
621 OPC_SUBUH_OB = (0x19 << 6) | OPC_ADDU_OB_DSP,
622 OPC_SUBUH_R_OB = (0x1B << 6) | OPC_ADDU_OB_DSP,
623 OPC_ADDQ_PW = (0x12 << 6) | OPC_ADDU_OB_DSP,
624 OPC_ADDQ_S_PW = (0x16 << 6) | OPC_ADDU_OB_DSP,
625 OPC_ADDQ_QH = (0x0A << 6) | OPC_ADDU_OB_DSP,
626 OPC_ADDQ_S_QH = (0x0E << 6) | OPC_ADDU_OB_DSP,
627 OPC_ADDU_OB = (0x00 << 6) | OPC_ADDU_OB_DSP,
628 OPC_ADDU_S_OB = (0x04 << 6) | OPC_ADDU_OB_DSP,
629 OPC_ADDU_QH = (0x08 << 6) | OPC_ADDU_OB_DSP,
630 OPC_ADDU_S_QH = (0x0C << 6) | OPC_ADDU_OB_DSP,
631 OPC_ADDUH_OB = (0x18 << 6) | OPC_ADDU_OB_DSP,
632 OPC_ADDUH_R_OB = (0x1A << 6) | OPC_ADDU_OB_DSP,
633};
461c08df 634
461c08df
JL
635#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636enum {
26690560
JL
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
639 OPC_CMP_LT_PW = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
640 OPC_CMP_LE_PW = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
641 OPC_CMP_EQ_QH = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
642 OPC_CMP_LT_QH = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
643 OPC_CMP_LE_QH = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
644 OPC_CMPGDU_EQ_OB = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
645 OPC_CMPGDU_LT_OB = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
646 OPC_CMPGDU_LE_OB = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
647 OPC_CMPGU_EQ_OB = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
648 OPC_CMPGU_LT_OB = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
649 OPC_CMPGU_LE_OB = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
650 OPC_CMPU_EQ_OB = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
651 OPC_CMPU_LT_OB = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
652 OPC_CMPU_LE_OB = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
653 OPC_PACKRL_PW = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
654 OPC_PICK_OB = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
655 OPC_PICK_PW = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
656 OPC_PICK_QH = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
461c08df
JL
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
659 OPC_PRECR_SRA_QH_PW = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
660 OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
661 OPC_PRECRQ_OB_QH = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
662 OPC_PRECRQ_PW_L = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
663 OPC_PRECRQ_QH_PW = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
664 OPC_PRECRQ_RS_QH_PW = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
665 OPC_PRECRQU_S_OB_QH = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
666};
461c08df 667
26690560
JL
668#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669enum {
670 /* DSP Compare-Pick Sub-class */
671 OPC_DAPPEND = (0x00 << 6) | OPC_DAPPEND_DSP,
672 OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
673 OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
674 OPC_DBALIGN = (0x10 << 6) | OPC_DAPPEND_DSP,
675};
26690560 676
b53371ed
JL
677#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678enum {
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP = (0x1F << 6) | OPC_DEXTR_W_DSP,
681 OPC_DSHILO = (0x1A << 6) | OPC_DEXTR_W_DSP,
682 OPC_DEXTP = (0x02 << 6) | OPC_DEXTR_W_DSP,
683 OPC_DEXTPDP = (0x0A << 6) | OPC_DEXTR_W_DSP,
684 OPC_DEXTPDPV = (0x0B << 6) | OPC_DEXTR_W_DSP,
685 OPC_DEXTPV = (0x03 << 6) | OPC_DEXTR_W_DSP,
686 OPC_DEXTR_L = (0x10 << 6) | OPC_DEXTR_W_DSP,
687 OPC_DEXTR_R_L = (0x14 << 6) | OPC_DEXTR_W_DSP,
688 OPC_DEXTR_RS_L = (0x16 << 6) | OPC_DEXTR_W_DSP,
689 OPC_DEXTR_W = (0x00 << 6) | OPC_DEXTR_W_DSP,
690 OPC_DEXTR_R_W = (0x04 << 6) | OPC_DEXTR_W_DSP,
691 OPC_DEXTR_RS_W = (0x06 << 6) | OPC_DEXTR_W_DSP,
692 OPC_DEXTR_S_H = (0x0E << 6) | OPC_DEXTR_W_DSP,
693 OPC_DEXTRV_L = (0x11 << 6) | OPC_DEXTR_W_DSP,
694 OPC_DEXTRV_R_L = (0x15 << 6) | OPC_DEXTR_W_DSP,
695 OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
696 OPC_DEXTRV_S_H = (0x0F << 6) | OPC_DEXTR_W_DSP,
697 OPC_DEXTRV_W = (0x01 << 6) | OPC_DEXTR_W_DSP,
698 OPC_DEXTRV_R_W = (0x05 << 6) | OPC_DEXTR_W_DSP,
699 OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
700 OPC_DSHILOV = (0x1B << 6) | OPC_DEXTR_W_DSP,
701};
702
1cb6686c
JL
703#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704enum {
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
707};
1cb6686c 708
a22260ae
JL
709#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710enum {
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
713 OPC_DMADDU = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
714 OPC_DMSUB = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
715 OPC_DMSUBU = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
716 OPC_DPA_W_QH = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
717 OPC_DPAQ_S_W_QH = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
718 OPC_DPAQ_SA_L_PW = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
719 OPC_DPAU_H_OBL = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
720 OPC_DPAU_H_OBR = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
721 OPC_DPS_W_QH = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
722 OPC_DPSQ_S_W_QH = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
723 OPC_DPSQ_SA_L_PW = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
724 OPC_DPSU_H_OBL = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
725 OPC_DPSU_H_OBR = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
726 OPC_MAQ_S_L_PWL = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
727 OPC_MAQ_S_L_PWR = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
728 OPC_MAQ_S_W_QHLL = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
729 OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
730 OPC_MAQ_S_W_QHLR = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
731 OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
732 OPC_MAQ_S_W_QHRL = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
733 OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
734 OPC_MAQ_S_W_QHRR = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
735 OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
736 OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
737 OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
738};
a22260ae 739
77c5fa8b
JL
740#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741enum {
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW = (0x10 << 6) | OPC_SHLL_OB_DSP,
744 OPC_SHLL_S_PW = (0x14 << 6) | OPC_SHLL_OB_DSP,
745 OPC_SHLLV_OB = (0x02 << 6) | OPC_SHLL_OB_DSP,
746 OPC_SHLLV_PW = (0x12 << 6) | OPC_SHLL_OB_DSP,
747 OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
748 OPC_SHLLV_QH = (0x0A << 6) | OPC_SHLL_OB_DSP,
749 OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
750 OPC_SHRA_PW = (0x11 << 6) | OPC_SHLL_OB_DSP,
751 OPC_SHRA_R_PW = (0x15 << 6) | OPC_SHLL_OB_DSP,
752 OPC_SHRAV_OB = (0x06 << 6) | OPC_SHLL_OB_DSP,
753 OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
754 OPC_SHRAV_PW = (0x13 << 6) | OPC_SHLL_OB_DSP,
755 OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
756 OPC_SHRAV_QH = (0x0B << 6) | OPC_SHLL_OB_DSP,
757 OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
758 OPC_SHRLV_OB = (0x03 << 6) | OPC_SHLL_OB_DSP,
759 OPC_SHRLV_QH = (0x1B << 6) | OPC_SHLL_OB_DSP,
760 OPC_SHLL_OB = (0x00 << 6) | OPC_SHLL_OB_DSP,
761 OPC_SHLL_QH = (0x08 << 6) | OPC_SHLL_OB_DSP,
762 OPC_SHLL_S_QH = (0x0C << 6) | OPC_SHLL_OB_DSP,
763 OPC_SHRA_OB = (0x04 << 6) | OPC_SHLL_OB_DSP,
764 OPC_SHRA_R_OB = (0x05 << 6) | OPC_SHLL_OB_DSP,
765 OPC_SHRA_QH = (0x09 << 6) | OPC_SHLL_OB_DSP,
766 OPC_SHRA_R_QH = (0x0D << 6) | OPC_SHLL_OB_DSP,
767 OPC_SHRL_OB = (0x01 << 6) | OPC_SHLL_OB_DSP,
768 OPC_SHRL_QH = (0x19 << 6) | OPC_SHLL_OB_DSP,
769};
77c5fa8b 770
7a387fff
TS
771/* Coprocessor 0 (rs field) */
772#define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
773
6ea83fed 774enum {
7a387fff
TS
775 OPC_MFC0 = (0x00 << 21) | OPC_CP0,
776 OPC_DMFC0 = (0x01 << 21) | OPC_CP0,
777 OPC_MTC0 = (0x04 << 21) | OPC_CP0,
778 OPC_DMTC0 = (0x05 << 21) | OPC_CP0,
ead9360e 779 OPC_MFTR = (0x08 << 21) | OPC_CP0,
7a387fff
TS
780 OPC_RDPGPR = (0x0A << 21) | OPC_CP0,
781 OPC_MFMC0 = (0x0B << 21) | OPC_CP0,
ead9360e 782 OPC_MTTR = (0x0C << 21) | OPC_CP0,
7a387fff
TS
783 OPC_WRPGPR = (0x0E << 21) | OPC_CP0,
784 OPC_C0 = (0x10 << 21) | OPC_CP0,
785 OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
786 OPC_C0_LAST = (0x1F << 21) | OPC_CP0,
6ea83fed 787};
7a387fff
TS
788
789/* MFMC0 opcodes */
b48cfdff 790#define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
7a387fff
TS
791
792enum {
ead9360e
TS
793 OPC_DMT = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
794 OPC_EMT = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
795 OPC_DVPE = 0x01 | (0 << 5) | OPC_MFMC0,
796 OPC_EVPE = 0x01 | (1 << 5) | OPC_MFMC0,
7a387fff
TS
797 OPC_DI = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
798 OPC_EI = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
799};
800
801/* Coprocessor 0 (with rs == C0) */
802#define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
803
804enum {
805 OPC_TLBR = 0x01 | OPC_C0,
806 OPC_TLBWI = 0x02 | OPC_C0,
807 OPC_TLBWR = 0x06 | OPC_C0,
808 OPC_TLBP = 0x08 | OPC_C0,
809 OPC_RFE = 0x10 | OPC_C0,
810 OPC_ERET = 0x18 | OPC_C0,
811 OPC_DERET = 0x1F | OPC_C0,
812 OPC_WAIT = 0x20 | OPC_C0,
813};
814
815/* Coprocessor 1 (rs field) */
816#define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
817
bf4120ad
NF
818/* Values for the fmt field in FP instructions */
819enum {
820 /* 0 - 15 are reserved */
e459440a
AJ
821 FMT_S = 16, /* single fp */
822 FMT_D = 17, /* double fp */
823 FMT_E = 18, /* extended fp */
824 FMT_Q = 19, /* quad fp */
825 FMT_W = 20, /* 32-bit fixed */
826 FMT_L = 21, /* 64-bit fixed */
827 FMT_PS = 22, /* paired single fp */
bf4120ad
NF
828 /* 23 - 31 are reserved */
829};
830
7a387fff
TS
831enum {
832 OPC_MFC1 = (0x00 << 21) | OPC_CP1,
833 OPC_DMFC1 = (0x01 << 21) | OPC_CP1,
834 OPC_CFC1 = (0x02 << 21) | OPC_CP1,
5a5012ec 835 OPC_MFHC1 = (0x03 << 21) | OPC_CP1,
7a387fff
TS
836 OPC_MTC1 = (0x04 << 21) | OPC_CP1,
837 OPC_DMTC1 = (0x05 << 21) | OPC_CP1,
838 OPC_CTC1 = (0x06 << 21) | OPC_CP1,
5a5012ec 839 OPC_MTHC1 = (0x07 << 21) | OPC_CP1,
7a387fff 840 OPC_BC1 = (0x08 << 21) | OPC_CP1, /* bc */
5a5012ec
TS
841 OPC_BC1ANY2 = (0x09 << 21) | OPC_CP1,
842 OPC_BC1ANY4 = (0x0A << 21) | OPC_CP1,
e459440a
AJ
843 OPC_S_FMT = (FMT_S << 21) | OPC_CP1,
844 OPC_D_FMT = (FMT_D << 21) | OPC_CP1,
845 OPC_E_FMT = (FMT_E << 21) | OPC_CP1,
846 OPC_Q_FMT = (FMT_Q << 21) | OPC_CP1,
847 OPC_W_FMT = (FMT_W << 21) | OPC_CP1,
848 OPC_L_FMT = (FMT_L << 21) | OPC_CP1,
849 OPC_PS_FMT = (FMT_PS << 21) | OPC_CP1,
7a387fff
TS
850};
851
5a5012ec
TS
852#define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853#define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
854
7a387fff
TS
855enum {
856 OPC_BC1F = (0x00 << 16) | OPC_BC1,
857 OPC_BC1T = (0x01 << 16) | OPC_BC1,
858 OPC_BC1FL = (0x02 << 16) | OPC_BC1,
859 OPC_BC1TL = (0x03 << 16) | OPC_BC1,
860};
861
5a5012ec
TS
862enum {
863 OPC_BC1FANY2 = (0x00 << 16) | OPC_BC1ANY2,
864 OPC_BC1TANY2 = (0x01 << 16) | OPC_BC1ANY2,
865};
866
867enum {
868 OPC_BC1FANY4 = (0x00 << 16) | OPC_BC1ANY4,
869 OPC_BC1TANY4 = (0x01 << 16) | OPC_BC1ANY4,
870};
7a387fff
TS
871
872#define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
e0c84da7
TS
873
874enum {
875 OPC_MFC2 = (0x00 << 21) | OPC_CP2,
876 OPC_DMFC2 = (0x01 << 21) | OPC_CP2,
877 OPC_CFC2 = (0x02 << 21) | OPC_CP2,
878 OPC_MFHC2 = (0x03 << 21) | OPC_CP2,
879 OPC_MTC2 = (0x04 << 21) | OPC_CP2,
880 OPC_DMTC2 = (0x05 << 21) | OPC_CP2,
881 OPC_CTC2 = (0x06 << 21) | OPC_CP2,
882 OPC_MTHC2 = (0x07 << 21) | OPC_CP2,
883 OPC_BC2 = (0x08 << 21) | OPC_CP2,
884};
885
bd277fa1
RH
886#define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
887
888enum {
889 OPC_PADDSH = (24 << 21) | (0x00) | OPC_CP2,
890 OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
891 OPC_PADDH = (26 << 21) | (0x00) | OPC_CP2,
892 OPC_PADDW = (27 << 21) | (0x00) | OPC_CP2,
893 OPC_PADDSB = (28 << 21) | (0x00) | OPC_CP2,
894 OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
895 OPC_PADDB = (30 << 21) | (0x00) | OPC_CP2,
896 OPC_PADDD = (31 << 21) | (0x00) | OPC_CP2,
897
898 OPC_PSUBSH = (24 << 21) | (0x01) | OPC_CP2,
899 OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
900 OPC_PSUBH = (26 << 21) | (0x01) | OPC_CP2,
901 OPC_PSUBW = (27 << 21) | (0x01) | OPC_CP2,
902 OPC_PSUBSB = (28 << 21) | (0x01) | OPC_CP2,
903 OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
904 OPC_PSUBB = (30 << 21) | (0x01) | OPC_CP2,
905 OPC_PSUBD = (31 << 21) | (0x01) | OPC_CP2,
906
907 OPC_PSHUFH = (24 << 21) | (0x02) | OPC_CP2,
908 OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
909 OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
910 OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
911 OPC_XOR_CP2 = (28 << 21) | (0x02) | OPC_CP2,
912 OPC_NOR_CP2 = (29 << 21) | (0x02) | OPC_CP2,
913 OPC_AND_CP2 = (30 << 21) | (0x02) | OPC_CP2,
914 OPC_PANDN = (31 << 21) | (0x02) | OPC_CP2,
915
916 OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
917 OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
918 OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
919 OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
920 OPC_PINSRH_0 = (28 << 21) | (0x03) | OPC_CP2,
921 OPC_PINSRH_1 = (29 << 21) | (0x03) | OPC_CP2,
922 OPC_PINSRH_2 = (30 << 21) | (0x03) | OPC_CP2,
923 OPC_PINSRH_3 = (31 << 21) | (0x03) | OPC_CP2,
924
925 OPC_PAVGH = (24 << 21) | (0x08) | OPC_CP2,
926 OPC_PAVGB = (25 << 21) | (0x08) | OPC_CP2,
927 OPC_PMAXSH = (26 << 21) | (0x08) | OPC_CP2,
928 OPC_PMINSH = (27 << 21) | (0x08) | OPC_CP2,
929 OPC_PMAXUB = (28 << 21) | (0x08) | OPC_CP2,
930 OPC_PMINUB = (29 << 21) | (0x08) | OPC_CP2,
931
932 OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
933 OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
934 OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
935 OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
936 OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
937 OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
938
939 OPC_PSLLW = (24 << 21) | (0x0A) | OPC_CP2,
940 OPC_PSLLH = (25 << 21) | (0x0A) | OPC_CP2,
941 OPC_PMULLH = (26 << 21) | (0x0A) | OPC_CP2,
942 OPC_PMULHH = (27 << 21) | (0x0A) | OPC_CP2,
943 OPC_PMULUW = (28 << 21) | (0x0A) | OPC_CP2,
944 OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
945
946 OPC_PSRLW = (24 << 21) | (0x0B) | OPC_CP2,
947 OPC_PSRLH = (25 << 21) | (0x0B) | OPC_CP2,
948 OPC_PSRAW = (26 << 21) | (0x0B) | OPC_CP2,
949 OPC_PSRAH = (27 << 21) | (0x0B) | OPC_CP2,
950 OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
951 OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
952
953 OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
954 OPC_OR_CP2 = (25 << 21) | (0x0C) | OPC_CP2,
955 OPC_ADD_CP2 = (26 << 21) | (0x0C) | OPC_CP2,
956 OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
957 OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
958 OPC_SEQ_CP2 = (29 << 21) | (0x0C) | OPC_CP2,
959
960 OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
961 OPC_PASUBUB = (25 << 21) | (0x0D) | OPC_CP2,
962 OPC_SUB_CP2 = (26 << 21) | (0x0D) | OPC_CP2,
963 OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
964 OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
965 OPC_SLT_CP2 = (29 << 21) | (0x0D) | OPC_CP2,
966
967 OPC_SLL_CP2 = (24 << 21) | (0x0E) | OPC_CP2,
968 OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
969 OPC_PEXTRH = (26 << 21) | (0x0E) | OPC_CP2,
970 OPC_PMADDHW = (27 << 21) | (0x0E) | OPC_CP2,
971 OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
972 OPC_SLE_CP2 = (29 << 21) | (0x0E) | OPC_CP2,
973
974 OPC_SRL_CP2 = (24 << 21) | (0x0F) | OPC_CP2,
975 OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
976 OPC_SRA_CP2 = (26 << 21) | (0x0F) | OPC_CP2,
977 OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
978 OPC_BIADD = (28 << 21) | (0x0F) | OPC_CP2,
979 OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
980};
981
982
e0c84da7
TS
983#define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
984
985enum {
986 OPC_LWXC1 = 0x00 | OPC_CP3,
987 OPC_LDXC1 = 0x01 | OPC_CP3,
988 OPC_LUXC1 = 0x05 | OPC_CP3,
989 OPC_SWXC1 = 0x08 | OPC_CP3,
990 OPC_SDXC1 = 0x09 | OPC_CP3,
991 OPC_SUXC1 = 0x0D | OPC_CP3,
992 OPC_PREFX = 0x0F | OPC_CP3,
993 OPC_ALNV_PS = 0x1E | OPC_CP3,
994 OPC_MADD_S = 0x20 | OPC_CP3,
995 OPC_MADD_D = 0x21 | OPC_CP3,
996 OPC_MADD_PS = 0x26 | OPC_CP3,
997 OPC_MSUB_S = 0x28 | OPC_CP3,
998 OPC_MSUB_D = 0x29 | OPC_CP3,
999 OPC_MSUB_PS = 0x2E | OPC_CP3,
1000 OPC_NMADD_S = 0x30 | OPC_CP3,
fbcc6828 1001 OPC_NMADD_D = 0x31 | OPC_CP3,
e0c84da7
TS
1002 OPC_NMADD_PS= 0x36 | OPC_CP3,
1003 OPC_NMSUB_S = 0x38 | OPC_CP3,
1004 OPC_NMSUB_D = 0x39 | OPC_CP3,
1005 OPC_NMSUB_PS= 0x3E | OPC_CP3,
1006};
1007
39454628 1008/* global register indices */
a7812ae4
PB
1009static TCGv_ptr cpu_env;
1010static TCGv cpu_gpr[32], cpu_PC;
4b2eb8d2 1011static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
41db4607
AJ
1012static TCGv cpu_dspctrl, btarget, bcond;
1013static TCGv_i32 hflags;
a7812ae4 1014static TCGv_i32 fpu_fcr0, fpu_fcr31;
d73ee8a2 1015static TCGv_i64 fpu_f64[32];
aa0bf00b 1016
1a7ff922 1017static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
4636401d 1018static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1a7ff922 1019
2e70f6ef
PB
1020#include "gen-icount.h"
1021
895c2d04 1022#define gen_helper_0e0i(name, arg) do { \
a7812ae4 1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
895c2d04 1024 gen_helper_##name(cpu_env, helper_tmp); \
a7812ae4
PB
1025 tcg_temp_free_i32(helper_tmp); \
1026 } while(0)
be24bb4f 1027
895c2d04 1028#define gen_helper_0e1i(name, arg1, arg2) do { \
a7812ae4 1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
895c2d04 1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
a7812ae4
PB
1031 tcg_temp_free_i32(helper_tmp); \
1032 } while(0)
be24bb4f 1033
895c2d04
BS
1034#define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1038 } while(0)
1039
1040#define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1044 } while(0)
1045
1046#define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1050 } while(0)
1051
1052#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
a7812ae4 1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
895c2d04 1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
a7812ae4
PB
1055 tcg_temp_free_i32(helper_tmp); \
1056 } while(0)
be24bb4f 1057
895c2d04 1058#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
a7812ae4 1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
895c2d04 1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
a7812ae4
PB
1061 tcg_temp_free_i32(helper_tmp); \
1062 } while(0)
c239529e 1063
8e9ade68
TS
1064typedef struct DisasContext {
1065 struct TranslationBlock *tb;
1066 target_ulong pc, saved_pc;
1067 uint32_t opcode;
7b270ef2 1068 int singlestep_enabled;
8e9ade68
TS
1069 /* Routine used to access memory */
1070 int mem_idx;
1071 uint32_t hflags, saved_hflags;
1072 int bstate;
1073 target_ulong btarget;
1074} DisasContext;
1075
1076enum {
1077 BS_NONE = 0, /* We go out of the TB without reaching a branch or an
d077b6f7 1078 * exception condition */
8e9ade68
TS
1079 BS_STOP = 1, /* We want to stop translation for any reason */
1080 BS_BRANCH = 2, /* We reached a branch condition */
1081 BS_EXCP = 3, /* We reached an exception condition */
1082};
1083
d73ee8a2
RH
1084static const char * const regnames[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1089};
6af0bf9c 1090
d73ee8a2
RH
1091static const char * const regnames_HI[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1093};
4b2eb8d2 1094
d73ee8a2
RH
1095static const char * const regnames_LO[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1097};
4b2eb8d2 1098
d73ee8a2
RH
1099static const char * const regnames_ACX[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1101};
4b2eb8d2 1102
d73ee8a2
RH
1103static const char * const fregnames[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1108};
958fb4a9 1109
fb7729e2
RH
1110#define MIPS_DEBUG(fmt, ...) \
1111 do { \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1116 } \
1117 } while (0)
1118
1119#define LOG_DISAS(...) \
1120 do { \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1123 } \
1124 } while (0)
958fb4a9 1125
8e9ade68 1126#define MIPS_INVAL(op) \
8e9ade68 1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
fb7729e2 1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
ead9360e 1129
8e9ade68
TS
1130/* General purpose registers moves. */
1131static inline void gen_load_gpr (TCGv t, int reg)
aaa9128a 1132{
8e9ade68
TS
1133 if (reg == 0)
1134 tcg_gen_movi_tl(t, 0);
1135 else
4b2eb8d2 1136 tcg_gen_mov_tl(t, cpu_gpr[reg]);
aaa9128a
TS
1137}
1138
8e9ade68 1139static inline void gen_store_gpr (TCGv t, int reg)
aaa9128a 1140{
8e9ade68 1141 if (reg != 0)
4b2eb8d2 1142 tcg_gen_mov_tl(cpu_gpr[reg], t);
aaa9128a
TS
1143}
1144
b10fa3c9 1145/* Moves to/from ACX register. */
4b2eb8d2 1146static inline void gen_load_ACX (TCGv t, int reg)
893f9865 1147{
4b2eb8d2 1148 tcg_gen_mov_tl(t, cpu_ACX[reg]);
893f9865
TS
1149}
1150
4b2eb8d2 1151static inline void gen_store_ACX (TCGv t, int reg)
893f9865 1152{
4b2eb8d2 1153 tcg_gen_mov_tl(cpu_ACX[reg], t);
893f9865
TS
1154}
1155
8e9ade68 1156/* Moves to/from shadow registers. */
be24bb4f 1157static inline void gen_load_srsgpr (int from, int to)
aaa9128a 1158{
d9bea114 1159 TCGv t0 = tcg_temp_new();
be24bb4f
TS
1160
1161 if (from == 0)
d9bea114 1162 tcg_gen_movi_tl(t0, 0);
8e9ade68 1163 else {
d9bea114 1164 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1165 TCGv_ptr addr = tcg_temp_new_ptr();
aaa9128a 1166
7db13fae 1167 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1168 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1169 tcg_gen_andi_i32(t2, t2, 0xf);
1170 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1171 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1172 tcg_gen_add_ptr(addr, cpu_env, addr);
aaa9128a 1173
d9bea114 1174 tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
a7812ae4 1175 tcg_temp_free_ptr(addr);
d9bea114 1176 tcg_temp_free_i32(t2);
8e9ade68 1177 }
d9bea114
AJ
1178 gen_store_gpr(t0, to);
1179 tcg_temp_free(t0);
aaa9128a
TS
1180}
1181
be24bb4f 1182static inline void gen_store_srsgpr (int from, int to)
aaa9128a 1183{
be24bb4f 1184 if (to != 0) {
d9bea114
AJ
1185 TCGv t0 = tcg_temp_new();
1186 TCGv_i32 t2 = tcg_temp_new_i32();
a7812ae4 1187 TCGv_ptr addr = tcg_temp_new_ptr();
be24bb4f 1188
d9bea114 1189 gen_load_gpr(t0, from);
7db13fae 1190 tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
d9bea114
AJ
1191 tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1192 tcg_gen_andi_i32(t2, t2, 0xf);
1193 tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1194 tcg_gen_ext_i32_ptr(addr, t2);
a7812ae4 1195 tcg_gen_add_ptr(addr, cpu_env, addr);
be24bb4f 1196
d9bea114 1197 tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
a7812ae4 1198 tcg_temp_free_ptr(addr);
d9bea114
AJ
1199 tcg_temp_free_i32(t2);
1200 tcg_temp_free(t0);
8e9ade68 1201 }
aaa9128a
TS
1202}
1203
aaa9128a 1204/* Floating point register moves. */
d73ee8a2 1205static void gen_load_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1206{
d73ee8a2 1207 tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
6ea83fed
FB
1208}
1209
d73ee8a2 1210static void gen_store_fpr32(TCGv_i32 t, int reg)
aa0bf00b 1211{
d73ee8a2
RH
1212 TCGv_i64 t64 = tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64, t);
1214 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1215 tcg_temp_free_i64(t64);
6d066274
AJ
1216}
1217
d73ee8a2 1218static void gen_load_fpr32h(TCGv_i32 t, int reg)
6d066274 1219{
d73ee8a2
RH
1220 TCGv_i64 t64 = tcg_temp_new_i64();
1221 tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1222 tcg_gen_trunc_i64_i32(t, t64);
1223 tcg_temp_free_i64(t64);
6d066274
AJ
1224}
1225
d73ee8a2 1226static void gen_store_fpr32h(TCGv_i32 t, int reg)
6d066274 1227{
d73ee8a2
RH
1228 TCGv_i64 t64 = tcg_temp_new_i64();
1229 tcg_gen_extu_i32_i64(t64, t);
1230 tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1231 tcg_temp_free_i64(t64);
aa0bf00b 1232}
6ea83fed 1233
d73ee8a2 1234static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1235{
f364515c 1236 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1237 tcg_gen_mov_i64(t, fpu_f64[reg]);
f364515c 1238 } else {
d73ee8a2 1239 tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
aa0bf00b
TS
1240 }
1241}
6ea83fed 1242
d73ee8a2 1243static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
aa0bf00b 1244{
f364515c 1245 if (ctx->hflags & MIPS_HFLAG_F64) {
d73ee8a2 1246 tcg_gen_mov_i64(fpu_f64[reg], t);
f364515c 1247 } else {
d73ee8a2
RH
1248 TCGv_i64 t0;
1249 tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1250 t0 = tcg_temp_new_i64();
6d066274 1251 tcg_gen_shri_i64(t0, t, 32);
d73ee8a2 1252 tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
6d066274 1253 tcg_temp_free_i64(t0);
aa0bf00b
TS
1254 }
1255}
6ea83fed 1256
d94536f4 1257static inline int get_fp_bit (int cc)
a16336e4 1258{
d94536f4
AJ
1259 if (cc)
1260 return 24 + cc;
1261 else
1262 return 23;
a16336e4
TS
1263}
1264
30898801 1265/* Tests */
8e9ade68
TS
1266static inline void gen_save_pc(target_ulong pc)
1267{
1eb75d4a 1268 tcg_gen_movi_tl(cpu_PC, pc);
8e9ade68 1269}
30898801 1270
356265ae 1271static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
6af0bf9c 1272{
d12d51d5 1273 LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
6af0bf9c 1274 if (do_save_pc && ctx->pc != ctx->saved_pc) {
9b9e4393 1275 gen_save_pc(ctx->pc);
6af0bf9c
FB
1276 ctx->saved_pc = ctx->pc;
1277 }
1278 if (ctx->hflags != ctx->saved_hflags) {
41db4607 1279 tcg_gen_movi_i32(hflags, ctx->hflags);
6af0bf9c 1280 ctx->saved_hflags = ctx->hflags;
364d4831 1281 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
5a5012ec 1282 case MIPS_HFLAG_BR:
5a5012ec
TS
1283 break;
1284 case MIPS_HFLAG_BC:
5a5012ec 1285 case MIPS_HFLAG_BL:
5a5012ec 1286 case MIPS_HFLAG_B:
d077b6f7 1287 tcg_gen_movi_tl(btarget, ctx->btarget);
5a5012ec 1288 break;
6af0bf9c
FB
1289 }
1290 }
1291}
1292
7db13fae 1293static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
5a5012ec 1294{
fd4a04eb 1295 ctx->saved_hflags = ctx->hflags;
364d4831 1296 switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
fd4a04eb 1297 case MIPS_HFLAG_BR:
fd4a04eb
TS
1298 break;
1299 case MIPS_HFLAG_BC:
1300 case MIPS_HFLAG_BL:
39454628 1301 case MIPS_HFLAG_B:
fd4a04eb 1302 ctx->btarget = env->btarget;
fd4a04eb 1303 break;
5a5012ec
TS
1304 }
1305}
1306
356265ae 1307static inline void
48d38ca5 1308generate_exception_err (DisasContext *ctx, int excp, int err)
aaa9128a 1309{
a7812ae4
PB
1310 TCGv_i32 texcp = tcg_const_i32(excp);
1311 TCGv_i32 terr = tcg_const_i32(err);
aaa9128a 1312 save_cpu_state(ctx, 1);
895c2d04 1313 gen_helper_raise_exception_err(cpu_env, texcp, terr);
a7812ae4
PB
1314 tcg_temp_free_i32(terr);
1315 tcg_temp_free_i32(texcp);
aaa9128a
TS
1316}
1317
356265ae 1318static inline void
48d38ca5 1319generate_exception (DisasContext *ctx, int excp)
aaa9128a 1320{
6af0bf9c 1321 save_cpu_state(ctx, 1);
895c2d04 1322 gen_helper_0e0i(raise_exception, excp);
6af0bf9c
FB
1323}
1324
48d38ca5 1325/* Addresses computation */
941694d0 1326static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
4ad40f36 1327{
941694d0 1328 tcg_gen_add_tl(ret, arg0, arg1);
48d38ca5
TS
1329
1330#if defined(TARGET_MIPS64)
1331 /* For compatibility with 32-bit code, data reference in user mode
1332 with Status_UX = 0 should be casted to 32-bit and sign extended.
1333 See the MIPS64 PRA manual, section 4.10. */
2623c1ec
AJ
1334 if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1335 !(ctx->hflags & MIPS_HFLAG_UX)) {
941694d0 1336 tcg_gen_ext32s_i64(ret, ret);
48d38ca5
TS
1337 }
1338#endif
4ad40f36
FB
1339}
1340
356265ae 1341static inline void check_cp0_enabled(DisasContext *ctx)
387a8fe5 1342{
fe253235 1343 if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
c2c65dab 1344 generate_exception_err(ctx, EXCP_CpU, 0);
387a8fe5
TS
1345}
1346
356265ae 1347static inline void check_cp1_enabled(DisasContext *ctx)
5e755519 1348{
fe253235 1349 if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
5e755519
TS
1350 generate_exception_err(ctx, EXCP_CpU, 1);
1351}
1352
b8aa4598
TS
1353/* Verify that the processor is running with COP1X instructions enabled.
1354 This is associated with the nabla symbol in the MIPS32 and MIPS64
1355 opcode tables. */
1356
356265ae 1357static inline void check_cop1x(DisasContext *ctx)
b8aa4598
TS
1358{
1359 if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1360 generate_exception(ctx, EXCP_RI);
1361}
1362
1363/* Verify that the processor is running with 64-bit floating-point
1364 operations enabled. */
1365
356265ae 1366static inline void check_cp1_64bitmode(DisasContext *ctx)
5e755519 1367{
b8aa4598 1368 if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
5e755519
TS
1369 generate_exception(ctx, EXCP_RI);
1370}
1371
1372/*
1373 * Verify if floating point register is valid; an operation is not defined
1374 * if bit 0 of any register specification is set and the FR bit in the
1375 * Status register equals zero, since the register numbers specify an
1376 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1377 * in the Status register equals one, both even and odd register numbers
1378 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1379 *
1380 * Multiple 64 bit wide registers can be checked by calling
1381 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1382 */
356265ae 1383static inline void check_cp1_registers(DisasContext *ctx, int regs)
5e755519 1384{
fe253235 1385 if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
5e755519
TS
1386 generate_exception(ctx, EXCP_RI);
1387}
1388
853c3240
JL
1389/* Verify that the processor is running with DSP instructions enabled.
1390 This is enabled by CP0 Status register MX(24) bit.
1391 */
1392
1393static inline void check_dsp(DisasContext *ctx)
1394{
1395 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1396 generate_exception(ctx, EXCP_DSPDIS);
1397 }
1398}
1399
1400static inline void check_dspr2(DisasContext *ctx)
1401{
1402 if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1403 generate_exception(ctx, EXCP_DSPDIS);
1404 }
1405}
1406
3a95e3a7 1407/* This code generates a "reserved instruction" exception if the
e189e748 1408 CPU does not support the instruction set corresponding to flags. */
7db13fae 1409static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
3a95e3a7 1410{
e189e748 1411 if (unlikely(!(env->insn_flags & flags)))
3a95e3a7
TS
1412 generate_exception(ctx, EXCP_RI);
1413}
1414
e189e748
TS
1415/* This code generates a "reserved instruction" exception if 64-bit
1416 instructions are not enabled. */
356265ae 1417static inline void check_mips_64(DisasContext *ctx)
e189e748 1418{
fe253235 1419 if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
e189e748
TS
1420 generate_exception(ctx, EXCP_RI);
1421}
1422
8153667c
NF
1423/* Define small wrappers for gen_load_fpr* so that we have a uniform
1424 calling interface for 32 and 64-bit FPRs. No sense in changing
1425 all callers for gen_load_fpr32 when we need the CTX parameter for
1426 this one use. */
1427#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1428#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1429#define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1430static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1431 int ft, int fs, int cc) \
1432{ \
1433 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1434 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1435 switch (ifmt) { \
1436 case FMT_PS: \
1437 check_cp1_64bitmode(ctx); \
1438 break; \
1439 case FMT_D: \
1440 if (abs) { \
1441 check_cop1x(ctx); \
1442 } \
1443 check_cp1_registers(ctx, fs | ft); \
1444 break; \
1445 case FMT_S: \
1446 if (abs) { \
1447 check_cop1x(ctx); \
1448 } \
1449 break; \
1450 } \
1451 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1452 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1453 switch (n) { \
895c2d04
BS
1454 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1455 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1456 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1457 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1458 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1459 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1460 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1461 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1462 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1463 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1464 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1465 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1466 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1467 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1468 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1469 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
8153667c
NF
1470 default: abort(); \
1471 } \
1472 tcg_temp_free_i##bits (fp0); \
1473 tcg_temp_free_i##bits (fp1); \
1474}
1475
1476FOP_CONDS(, 0, d, FMT_D, 64)
1477FOP_CONDS(abs, 1, d, FMT_D, 64)
1478FOP_CONDS(, 0, s, FMT_S, 32)
1479FOP_CONDS(abs, 1, s, FMT_S, 32)
1480FOP_CONDS(, 0, ps, FMT_PS, 64)
1481FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1482#undef FOP_CONDS
1483#undef gen_ldcmp_fpr32
1484#undef gen_ldcmp_fpr64
1485
958fb4a9 1486/* load/store instructions. */
d9bea114 1487#define OP_LD(insn,fname) \
5c13fdfd 1488static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1489{ \
1490 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
aaa9128a
TS
1491}
1492OP_LD(lb,ld8s);
1493OP_LD(lbu,ld8u);
1494OP_LD(lh,ld16s);
1495OP_LD(lhu,ld16u);
1496OP_LD(lw,ld32s);
1497#if defined(TARGET_MIPS64)
1498OP_LD(lwu,ld32u);
1499OP_LD(ld,ld64);
1500#endif
1501#undef OP_LD
1502
d9bea114 1503#define OP_ST(insn,fname) \
5c13fdfd 1504static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
d9bea114
AJ
1505{ \
1506 tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx); \
aaa9128a
TS
1507}
1508OP_ST(sb,st8);
1509OP_ST(sh,st16);
1510OP_ST(sw,st32);
1511#if defined(TARGET_MIPS64)
1512OP_ST(sd,st64);
1513#endif
1514#undef OP_ST
1515
e7139c44 1516#ifdef CONFIG_USER_ONLY
d9bea114 1517#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1518static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
d9bea114
AJ
1519{ \
1520 TCGv t0 = tcg_temp_new(); \
1521 tcg_gen_mov_tl(t0, arg1); \
1522 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
7db13fae
AF
1523 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1524 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
d9bea114 1525 tcg_temp_free(t0); \
aaa9128a 1526}
e7139c44
AJ
1527#else
1528#define OP_LD_ATOMIC(insn,fname) \
5c13fdfd 1529static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
e7139c44 1530{ \
895c2d04 1531 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
e7139c44
AJ
1532}
1533#endif
aaa9128a
TS
1534OP_LD_ATOMIC(ll,ld32s);
1535#if defined(TARGET_MIPS64)
1536OP_LD_ATOMIC(lld,ld64);
1537#endif
1538#undef OP_LD_ATOMIC
1539
590bc601
PB
1540#ifdef CONFIG_USER_ONLY
1541#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1542static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1543{ \
1544 TCGv t0 = tcg_temp_new(); \
1545 int l1 = gen_new_label(); \
1546 int l2 = gen_new_label(); \
1547 \
1548 tcg_gen_andi_tl(t0, arg2, almask); \
1549 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
7db13fae 1550 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
590bc601
PB
1551 generate_exception(ctx, EXCP_AdES); \
1552 gen_set_label(l1); \
7db13fae 1553 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
590bc601
PB
1554 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1555 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
7db13fae
AF
1556 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1557 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
895c2d04 1558 gen_helper_0e0i(raise_exception, EXCP_SC); \
590bc601
PB
1559 gen_set_label(l2); \
1560 tcg_gen_movi_tl(t0, 0); \
1561 gen_store_gpr(t0, rt); \
1562 tcg_temp_free(t0); \
1563}
1564#else
1565#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
5c13fdfd 1566static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
590bc601
PB
1567{ \
1568 TCGv t0 = tcg_temp_new(); \
895c2d04 1569 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
590bc601 1570 gen_store_gpr(t0, rt); \
590bc601
PB
1571 tcg_temp_free(t0); \
1572}
1573#endif
590bc601 1574OP_ST_ATOMIC(sc,st32,ld32s,0x3);
aaa9128a 1575#if defined(TARGET_MIPS64)
590bc601 1576OP_ST_ATOMIC(scd,st64,ld64,0x7);
aaa9128a
TS
1577#endif
1578#undef OP_ST_ATOMIC
1579
662d7485
NF
1580static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1581 int base, int16_t offset)
1582{
1583 if (base == 0) {
1584 tcg_gen_movi_tl(addr, offset);
1585 } else if (offset == 0) {
1586 gen_load_gpr(addr, base);
1587 } else {
1588 tcg_gen_movi_tl(addr, offset);
1589 gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1590 }
1591}
1592
364d4831
NF
1593static target_ulong pc_relative_pc (DisasContext *ctx)
1594{
1595 target_ulong pc = ctx->pc;
1596
1597 if (ctx->hflags & MIPS_HFLAG_BMASK) {
1598 int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1599
1600 pc -= branch_bytes;
1601 }
1602
1603 pc &= ~(target_ulong)3;
1604 return pc;
1605}
1606
5c13fdfd 1607/* Load */
7db13fae 1608static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
afa88c3a 1609 int rt, int base, int16_t offset)
6af0bf9c 1610{
5c13fdfd 1611 const char *opn = "ld";
afa88c3a
AJ
1612 TCGv t0, t1;
1613
1614 if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1615 /* Loongson CPU uses a load to zero register for prefetch.
1616 We emulate it as a NOP. On other CPU we must perform the
1617 actual memory access. */
1618 MIPS_DEBUG("NOP");
1619 return;
1620 }
6af0bf9c 1621
afa88c3a
AJ
1622 t0 = tcg_temp_new();
1623 t1 = tcg_temp_new();
662d7485 1624 gen_base_offset_addr(ctx, t0, base, offset);
afa88c3a 1625
6af0bf9c 1626 switch (opc) {
d26bc211 1627#if defined(TARGET_MIPS64)
6e473128 1628 case OPC_LWU:
5c13fdfd 1629 op_ld_lwu(t0, t0, ctx);
78723684 1630 gen_store_gpr(t0, rt);
6e473128
TS
1631 opn = "lwu";
1632 break;
6af0bf9c 1633 case OPC_LD:
5c13fdfd 1634 op_ld_ld(t0, t0, ctx);
78723684 1635 gen_store_gpr(t0, rt);
6af0bf9c
FB
1636 opn = "ld";
1637 break;
7a387fff 1638 case OPC_LLD:
b835e919 1639 save_cpu_state(ctx, 1);
5c13fdfd 1640 op_ld_lld(t0, t0, ctx);
78723684 1641 gen_store_gpr(t0, rt);
7a387fff
TS
1642 opn = "lld";
1643 break;
6af0bf9c 1644 case OPC_LDL:
c8c2227e 1645 save_cpu_state(ctx, 1);
78723684 1646 gen_load_gpr(t1, rt);
895c2d04 1647 gen_helper_1e2i(ldl, t1, t1, t0, ctx->mem_idx);
78723684 1648 gen_store_gpr(t1, rt);
6af0bf9c
FB
1649 opn = "ldl";
1650 break;
6af0bf9c 1651 case OPC_LDR:
c8c2227e 1652 save_cpu_state(ctx, 1);
78723684 1653 gen_load_gpr(t1, rt);
895c2d04 1654 gen_helper_1e2i(ldr, t1, t1, t0, ctx->mem_idx);
78723684 1655 gen_store_gpr(t1, rt);
6af0bf9c
FB
1656 opn = "ldr";
1657 break;
364d4831 1658 case OPC_LDPC:
364d4831
NF
1659 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1660 gen_op_addr_add(ctx, t0, t0, t1);
5c13fdfd 1661 op_ld_ld(t0, t0, ctx);
364d4831 1662 gen_store_gpr(t0, rt);
5c13fdfd 1663 opn = "ldpc";
364d4831 1664 break;
6af0bf9c 1665#endif
364d4831 1666 case OPC_LWPC:
364d4831
NF
1667 tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
1668 gen_op_addr_add(ctx, t0, t0, t1);
5c13fdfd 1669 op_ld_lw(t0, t0, ctx);
364d4831 1670 gen_store_gpr(t0, rt);
5c13fdfd 1671 opn = "lwpc";
364d4831 1672 break;
6af0bf9c 1673 case OPC_LW:
5c13fdfd 1674 op_ld_lw(t0, t0, ctx);
78723684 1675 gen_store_gpr(t0, rt);
6af0bf9c
FB
1676 opn = "lw";
1677 break;
6af0bf9c 1678 case OPC_LH:
5c13fdfd 1679 op_ld_lh(t0, t0, ctx);
78723684 1680 gen_store_gpr(t0, rt);
6af0bf9c
FB
1681 opn = "lh";
1682 break;
6af0bf9c 1683 case OPC_LHU:
5c13fdfd 1684 op_ld_lhu(t0, t0, ctx);
78723684 1685 gen_store_gpr(t0, rt);
6af0bf9c
FB
1686 opn = "lhu";
1687 break;
1688 case OPC_LB:
5c13fdfd 1689 op_ld_lb(t0, t0, ctx);
78723684 1690 gen_store_gpr(t0, rt);
6af0bf9c
FB
1691 opn = "lb";
1692 break;
6af0bf9c 1693 case OPC_LBU:
5c13fdfd 1694 op_ld_lbu(t0, t0, ctx);
78723684 1695 gen_store_gpr(t0, rt);
6af0bf9c
FB
1696 opn = "lbu";
1697 break;
1698 case OPC_LWL:
c8c2227e 1699 save_cpu_state(ctx, 1);
6958549d 1700 gen_load_gpr(t1, rt);
895c2d04 1701 gen_helper_1e2i(lwl, t1, t1, t0, ctx->mem_idx);
78723684 1702 gen_store_gpr(t1, rt);
6af0bf9c
FB
1703 opn = "lwl";
1704 break;
6af0bf9c 1705 case OPC_LWR:
c8c2227e 1706 save_cpu_state(ctx, 1);
6958549d 1707 gen_load_gpr(t1, rt);
895c2d04 1708 gen_helper_1e2i(lwr, t1, t1, t0, ctx->mem_idx);
78723684 1709 gen_store_gpr(t1, rt);
6af0bf9c
FB
1710 opn = "lwr";
1711 break;
6af0bf9c 1712 case OPC_LL:
e7139c44 1713 save_cpu_state(ctx, 1);
5c13fdfd 1714 op_ld_ll(t0, t0, ctx);
78723684 1715 gen_store_gpr(t0, rt);
6af0bf9c
FB
1716 opn = "ll";
1717 break;
d66c7132 1718 }
2abf314d 1719 (void)opn; /* avoid a compiler warning */
d66c7132
AJ
1720 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1721 tcg_temp_free(t0);
1722 tcg_temp_free(t1);
1723}
1724
5c13fdfd
AJ
1725/* Store */
1726static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1727 int base, int16_t offset)
1728{
1729 const char *opn = "st";
1730 TCGv t0 = tcg_temp_new();
1731 TCGv t1 = tcg_temp_new();
1732
1733 gen_base_offset_addr(ctx, t0, base, offset);
1734 gen_load_gpr(t1, rt);
1735 switch (opc) {
1736#if defined(TARGET_MIPS64)
1737 case OPC_SD:
5c13fdfd
AJ
1738 op_st_sd(t1, t0, ctx);
1739 opn = "sd";
1740 break;
1741 case OPC_SDL:
1742 save_cpu_state(ctx, 1);
895c2d04 1743 gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1744 opn = "sdl";
1745 break;
1746 case OPC_SDR:
1747 save_cpu_state(ctx, 1);
895c2d04 1748 gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1749 opn = "sdr";
1750 break;
1751#endif
1752 case OPC_SW:
5c13fdfd
AJ
1753 op_st_sw(t1, t0, ctx);
1754 opn = "sw";
1755 break;
1756 case OPC_SH:
5c13fdfd
AJ
1757 op_st_sh(t1, t0, ctx);
1758 opn = "sh";
1759 break;
1760 case OPC_SB:
5c13fdfd
AJ
1761 op_st_sb(t1, t0, ctx);
1762 opn = "sb";
1763 break;
1764 case OPC_SWL:
1765 save_cpu_state(ctx, 1);
895c2d04 1766 gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1767 opn = "swl";
1768 break;
1769 case OPC_SWR:
1770 save_cpu_state(ctx, 1);
895c2d04 1771 gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
5c13fdfd
AJ
1772 opn = "swr";
1773 break;
1774 }
2abf314d 1775 (void)opn; /* avoid a compiler warning */
5c13fdfd
AJ
1776 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1777 tcg_temp_free(t0);
1778 tcg_temp_free(t1);
1779}
1780
1781
d66c7132
AJ
1782/* Store conditional */
1783static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1784 int base, int16_t offset)
1785{
1786 const char *opn = "st_cond";
1787 TCGv t0, t1;
1788
1789 t0 = tcg_temp_local_new();
1790
662d7485 1791 gen_base_offset_addr(ctx, t0, base, offset);
d66c7132
AJ
1792 /* Don't do NOP if destination is zero: we must perform the actual
1793 memory access. */
1794
1795 t1 = tcg_temp_local_new();
1796 gen_load_gpr(t1, rt);
1797 switch (opc) {
1798#if defined(TARGET_MIPS64)
1799 case OPC_SCD:
b835e919 1800 save_cpu_state(ctx, 1);
5c13fdfd 1801 op_st_scd(t1, t0, rt, ctx);
d66c7132
AJ
1802 opn = "scd";
1803 break;
1804#endif
6af0bf9c 1805 case OPC_SC:
e7139c44 1806 save_cpu_state(ctx, 1);
5c13fdfd 1807 op_st_sc(t1, t0, rt, ctx);
6af0bf9c
FB
1808 opn = "sc";
1809 break;
6af0bf9c 1810 }
2abf314d 1811 (void)opn; /* avoid a compiler warning */
6af0bf9c 1812 MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
78723684 1813 tcg_temp_free(t1);
d66c7132 1814 tcg_temp_free(t0);
6af0bf9c
FB
1815}
1816
6ea83fed 1817/* Load and store */
7a387fff 1818static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
356265ae 1819 int base, int16_t offset)
6ea83fed 1820{
923617a3 1821 const char *opn = "flt_ldst";
4e2474d6 1822 TCGv t0 = tcg_temp_new();
6ea83fed 1823
662d7485 1824 gen_base_offset_addr(ctx, t0, base, offset);
6ea83fed 1825 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 1826 memory access. */
6ea83fed
FB
1827 switch (opc) {
1828 case OPC_LWC1:
b6d96bed 1829 {
a7812ae4 1830 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 1831
c407df81
AJ
1832 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1833 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 1834 gen_store_fpr32(fp0, ft);
a7812ae4 1835 tcg_temp_free_i32(fp0);
b6d96bed 1836 }
6ea83fed
FB
1837 opn = "lwc1";
1838 break;
1839 case OPC_SWC1:
b6d96bed 1840 {
a7812ae4
PB
1841 TCGv_i32 fp0 = tcg_temp_new_i32();
1842 TCGv t1 = tcg_temp_new();
b6d96bed
TS
1843
1844 gen_load_fpr32(fp0, ft);
a7812ae4
PB
1845 tcg_gen_extu_i32_tl(t1, fp0);
1846 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1847 tcg_temp_free(t1);
1848 tcg_temp_free_i32(fp0);
b6d96bed 1849 }
6ea83fed
FB
1850 opn = "swc1";
1851 break;
1852 case OPC_LDC1:
b6d96bed 1853 {
a7812ae4 1854 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1855
1856 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1857 gen_store_fpr64(ctx, fp0, ft);
a7812ae4 1858 tcg_temp_free_i64(fp0);
b6d96bed 1859 }
6ea83fed
FB
1860 opn = "ldc1";
1861 break;
1862 case OPC_SDC1:
b6d96bed 1863 {
a7812ae4 1864 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
1865
1866 gen_load_fpr64(ctx, fp0, ft);
1867 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 1868 tcg_temp_free_i64(fp0);
b6d96bed 1869 }
6ea83fed
FB
1870 opn = "sdc1";
1871 break;
1872 default:
923617a3 1873 MIPS_INVAL(opn);
e397ee33 1874 generate_exception(ctx, EXCP_RI);
78723684 1875 goto out;
6ea83fed 1876 }
2abf314d 1877 (void)opn; /* avoid a compiler warning */
6ea83fed 1878 MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
78723684
TS
1879 out:
1880 tcg_temp_free(t0);
6ea83fed 1881}
6ea83fed 1882
7db13fae 1883static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
26ebe468
NF
1884 uint32_t op, int rt, int rs, int16_t imm)
1885{
1886 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1887 check_cp1_enabled(ctx);
1888 gen_flt_ldst(ctx, op, rt, rs, imm);
1889 } else {
1890 generate_exception_err(ctx, EXCP_CpU, 1);
1891 }
1892}
1893
6af0bf9c 1894/* Arithmetic with immediate operand */
7db13fae 1895static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
e189e748 1896 int rt, int rs, int16_t imm)
6af0bf9c 1897{
324d9e32 1898 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
923617a3 1899 const char *opn = "imm arith";
6af0bf9c 1900
7a387fff 1901 if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
ead9360e
TS
1902 /* If no destination, treat it as a NOP.
1903 For addi, we must generate the overflow exception when needed. */
6af0bf9c 1904 MIPS_DEBUG("NOP");
324d9e32 1905 return;
6af0bf9c
FB
1906 }
1907 switch (opc) {
1908 case OPC_ADDI:
48d38ca5 1909 {
324d9e32
AJ
1910 TCGv t0 = tcg_temp_local_new();
1911 TCGv t1 = tcg_temp_new();
1912 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1913 int l1 = gen_new_label();
1914
324d9e32
AJ
1915 gen_load_gpr(t1, rs);
1916 tcg_gen_addi_tl(t0, t1, uimm);
1917 tcg_gen_ext32s_tl(t0, t0);
48d38ca5 1918
324d9e32
AJ
1919 tcg_gen_xori_tl(t1, t1, ~uimm);
1920 tcg_gen_xori_tl(t2, t0, uimm);
1921 tcg_gen_and_tl(t1, t1, t2);
1922 tcg_temp_free(t2);
1923 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1924 tcg_temp_free(t1);
48d38ca5
TS
1925 /* operands of same sign, result different sign */
1926 generate_exception(ctx, EXCP_OVERFLOW);
1927 gen_set_label(l1);
78723684 1928 tcg_gen_ext32s_tl(t0, t0);
324d9e32
AJ
1929 gen_store_gpr(t0, rt);
1930 tcg_temp_free(t0);
48d38ca5 1931 }
6af0bf9c
FB
1932 opn = "addi";
1933 break;
1934 case OPC_ADDIU:
324d9e32
AJ
1935 if (rs != 0) {
1936 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1937 tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1938 } else {
1939 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1940 }
6af0bf9c
FB
1941 opn = "addiu";
1942 break;
d26bc211 1943#if defined(TARGET_MIPS64)
7a387fff 1944 case OPC_DADDI:
48d38ca5 1945 {
324d9e32
AJ
1946 TCGv t0 = tcg_temp_local_new();
1947 TCGv t1 = tcg_temp_new();
1948 TCGv t2 = tcg_temp_new();
48d38ca5
TS
1949 int l1 = gen_new_label();
1950
324d9e32
AJ
1951 gen_load_gpr(t1, rs);
1952 tcg_gen_addi_tl(t0, t1, uimm);
48d38ca5 1953
324d9e32
AJ
1954 tcg_gen_xori_tl(t1, t1, ~uimm);
1955 tcg_gen_xori_tl(t2, t0, uimm);
1956 tcg_gen_and_tl(t1, t1, t2);
1957 tcg_temp_free(t2);
1958 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1959 tcg_temp_free(t1);
48d38ca5
TS
1960 /* operands of same sign, result different sign */
1961 generate_exception(ctx, EXCP_OVERFLOW);
1962 gen_set_label(l1);
324d9e32
AJ
1963 gen_store_gpr(t0, rt);
1964 tcg_temp_free(t0);
48d38ca5 1965 }
7a387fff
TS
1966 opn = "daddi";
1967 break;
1968 case OPC_DADDIU:
324d9e32
AJ
1969 if (rs != 0) {
1970 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1971 } else {
1972 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1973 }
7a387fff
TS
1974 opn = "daddiu";
1975 break;
1976#endif
324d9e32 1977 }
2abf314d 1978 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
1979 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1980}
1981
1982/* Logic with immediate operand */
9fa77488
RH
1983static void gen_logic_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1984 int rt, int rs, int16_t imm)
324d9e32
AJ
1985{
1986 target_ulong uimm;
1987 const char *opn = "imm logic";
1988
1989 if (rt == 0) {
1990 /* If no destination, treat it as a NOP. */
1991 MIPS_DEBUG("NOP");
1992 return;
1993 }
1994 uimm = (uint16_t)imm;
1995 switch (opc) {
6af0bf9c 1996 case OPC_ANDI:
324d9e32
AJ
1997 if (likely(rs != 0))
1998 tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1999 else
2000 tcg_gen_movi_tl(cpu_gpr[rt], 0);
6af0bf9c
FB
2001 opn = "andi";
2002 break;
2003 case OPC_ORI:
324d9e32
AJ
2004 if (rs != 0)
2005 tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2006 else
2007 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2008 opn = "ori";
2009 break;
2010 case OPC_XORI:
324d9e32
AJ
2011 if (likely(rs != 0))
2012 tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2013 else
2014 tcg_gen_movi_tl(cpu_gpr[rt], uimm);
6af0bf9c
FB
2015 opn = "xori";
2016 break;
2017 case OPC_LUI:
324d9e32 2018 tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
6af0bf9c
FB
2019 opn = "lui";
2020 break;
324d9e32 2021 }
2abf314d 2022 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2023 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2024}
2025
2026/* Set on less than with immediate operand */
9fa77488
RH
2027static void gen_slt_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2028 int rt, int rs, int16_t imm)
324d9e32
AJ
2029{
2030 target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2031 const char *opn = "imm arith";
2032 TCGv t0;
2033
2034 if (rt == 0) {
2035 /* If no destination, treat it as a NOP. */
2036 MIPS_DEBUG("NOP");
2037 return;
2038 }
2039 t0 = tcg_temp_new();
2040 gen_load_gpr(t0, rs);
2041 switch (opc) {
2042 case OPC_SLTI:
e68dd28f 2043 tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2044 opn = "slti";
2045 break;
2046 case OPC_SLTIU:
e68dd28f 2047 tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
324d9e32
AJ
2048 opn = "sltiu";
2049 break;
2050 }
2abf314d 2051 (void)opn; /* avoid a compiler warning */
324d9e32
AJ
2052 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2053 tcg_temp_free(t0);
2054}
2055
2056/* Shifts with immediate operand */
7db13fae 2057static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
324d9e32
AJ
2058 int rt, int rs, int16_t imm)
2059{
2060 target_ulong uimm = ((uint16_t)imm) & 0x1f;
2061 const char *opn = "imm shift";
2062 TCGv t0;
2063
2064 if (rt == 0) {
2065 /* If no destination, treat it as a NOP. */
2066 MIPS_DEBUG("NOP");
2067 return;
2068 }
2069
2070 t0 = tcg_temp_new();
2071 gen_load_gpr(t0, rs);
2072 switch (opc) {
6af0bf9c 2073 case OPC_SLL:
78723684 2074 tcg_gen_shli_tl(t0, t0, uimm);
324d9e32 2075 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
6af0bf9c
FB
2076 opn = "sll";
2077 break;
2078 case OPC_SRA:
324d9e32 2079 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
6af0bf9c
FB
2080 opn = "sra";
2081 break;
2082 case OPC_SRL:
ea63e2c3
NF
2083 if (uimm != 0) {
2084 tcg_gen_ext32u_tl(t0, t0);
2085 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2086 } else {
2087 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
5a63bcb2 2088 }
ea63e2c3
NF
2089 opn = "srl";
2090 break;
2091 case OPC_ROTR:
2092 if (uimm != 0) {
2093 TCGv_i32 t1 = tcg_temp_new_i32();
2094
2095 tcg_gen_trunc_tl_i32(t1, t0);
2096 tcg_gen_rotri_i32(t1, t1, uimm);
2097 tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2098 tcg_temp_free_i32(t1);
3399e30f
NF
2099 } else {
2100 tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
ea63e2c3
NF
2101 }
2102 opn = "rotr";
7a387fff 2103 break;
d26bc211 2104#if defined(TARGET_MIPS64)
7a387fff 2105 case OPC_DSLL:
324d9e32 2106 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2107 opn = "dsll";
2108 break;
2109 case OPC_DSRA:
324d9e32 2110 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
7a387fff
TS
2111 opn = "dsra";
2112 break;
2113 case OPC_DSRL:
ea63e2c3
NF
2114 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2115 opn = "dsrl";
2116 break;
2117 case OPC_DROTR:
2118 if (uimm != 0) {
2119 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3399e30f
NF
2120 } else {
2121 tcg_gen_mov_tl(cpu_gpr[rt], t0);
5a63bcb2 2122 }
ea63e2c3 2123 opn = "drotr";
7a387fff
TS
2124 break;
2125 case OPC_DSLL32:
324d9e32 2126 tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2127 opn = "dsll32";
2128 break;
2129 case OPC_DSRA32:
324d9e32 2130 tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
7a387fff
TS
2131 opn = "dsra32";
2132 break;
2133 case OPC_DSRL32:
ea63e2c3
NF
2134 tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2135 opn = "dsrl32";
2136 break;
2137 case OPC_DROTR32:
2138 tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2139 opn = "drotr32";
6af0bf9c 2140 break;
7a387fff 2141#endif
6af0bf9c 2142 }
2abf314d 2143 (void)opn; /* avoid a compiler warning */
93b12ccc 2144 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
78723684 2145 tcg_temp_free(t0);
6af0bf9c
FB
2146}
2147
2148/* Arithmetic */
7db13fae 2149static void gen_arith (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2150 int rd, int rs, int rt)
2151{
923617a3 2152 const char *opn = "arith";
6af0bf9c 2153
7a387fff
TS
2154 if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2155 && opc != OPC_DADD && opc != OPC_DSUB) {
ead9360e
TS
2156 /* If no destination, treat it as a NOP.
2157 For add & sub, we must generate the overflow exception when needed. */
6af0bf9c 2158 MIPS_DEBUG("NOP");
460f00c4 2159 return;
185f0762 2160 }
460f00c4 2161
6af0bf9c
FB
2162 switch (opc) {
2163 case OPC_ADD:
48d38ca5 2164 {
460f00c4
AJ
2165 TCGv t0 = tcg_temp_local_new();
2166 TCGv t1 = tcg_temp_new();
2167 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2168 int l1 = gen_new_label();
2169
460f00c4
AJ
2170 gen_load_gpr(t1, rs);
2171 gen_load_gpr(t2, rt);
2172 tcg_gen_add_tl(t0, t1, t2);
2173 tcg_gen_ext32s_tl(t0, t0);
2174 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2175 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2176 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2177 tcg_temp_free(t2);
2178 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2179 tcg_temp_free(t1);
48d38ca5
TS
2180 /* operands of same sign, result different sign */
2181 generate_exception(ctx, EXCP_OVERFLOW);
2182 gen_set_label(l1);
460f00c4
AJ
2183 gen_store_gpr(t0, rd);
2184 tcg_temp_free(t0);
48d38ca5 2185 }
6af0bf9c
FB
2186 opn = "add";
2187 break;
2188 case OPC_ADDU:
460f00c4
AJ
2189 if (rs != 0 && rt != 0) {
2190 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2191 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2192 } else if (rs == 0 && rt != 0) {
2193 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2194 } else if (rs != 0 && rt == 0) {
2195 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2196 } else {
2197 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2198 }
6af0bf9c
FB
2199 opn = "addu";
2200 break;
2201 case OPC_SUB:
48d38ca5 2202 {
460f00c4
AJ
2203 TCGv t0 = tcg_temp_local_new();
2204 TCGv t1 = tcg_temp_new();
2205 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2206 int l1 = gen_new_label();
2207
460f00c4
AJ
2208 gen_load_gpr(t1, rs);
2209 gen_load_gpr(t2, rt);
2210 tcg_gen_sub_tl(t0, t1, t2);
2211 tcg_gen_ext32s_tl(t0, t0);
2212 tcg_gen_xor_tl(t2, t1, t2);
2213 tcg_gen_xor_tl(t1, t0, t1);
2214 tcg_gen_and_tl(t1, t1, t2);
2215 tcg_temp_free(t2);
2216 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2217 tcg_temp_free(t1);
31e3104f 2218 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2219 generate_exception(ctx, EXCP_OVERFLOW);
2220 gen_set_label(l1);
460f00c4
AJ
2221 gen_store_gpr(t0, rd);
2222 tcg_temp_free(t0);
48d38ca5 2223 }
6af0bf9c
FB
2224 opn = "sub";
2225 break;
2226 case OPC_SUBU:
460f00c4
AJ
2227 if (rs != 0 && rt != 0) {
2228 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2229 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2230 } else if (rs == 0 && rt != 0) {
2231 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
6bb72b18 2232 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
460f00c4
AJ
2233 } else if (rs != 0 && rt == 0) {
2234 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2235 } else {
2236 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2237 }
6af0bf9c
FB
2238 opn = "subu";
2239 break;
d26bc211 2240#if defined(TARGET_MIPS64)
7a387fff 2241 case OPC_DADD:
48d38ca5 2242 {
460f00c4
AJ
2243 TCGv t0 = tcg_temp_local_new();
2244 TCGv t1 = tcg_temp_new();
2245 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2246 int l1 = gen_new_label();
2247
460f00c4
AJ
2248 gen_load_gpr(t1, rs);
2249 gen_load_gpr(t2, rt);
2250 tcg_gen_add_tl(t0, t1, t2);
2251 tcg_gen_xor_tl(t1, t1, t2);
460f00c4 2252 tcg_gen_xor_tl(t2, t0, t2);
deb4203d 2253 tcg_gen_andc_tl(t1, t2, t1);
460f00c4
AJ
2254 tcg_temp_free(t2);
2255 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2256 tcg_temp_free(t1);
48d38ca5
TS
2257 /* operands of same sign, result different sign */
2258 generate_exception(ctx, EXCP_OVERFLOW);
2259 gen_set_label(l1);
460f00c4
AJ
2260 gen_store_gpr(t0, rd);
2261 tcg_temp_free(t0);
48d38ca5 2262 }
7a387fff
TS
2263 opn = "dadd";
2264 break;
2265 case OPC_DADDU:
460f00c4
AJ
2266 if (rs != 0 && rt != 0) {
2267 tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2268 } else if (rs == 0 && rt != 0) {
2269 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2270 } else if (rs != 0 && rt == 0) {
2271 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2272 } else {
2273 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2274 }
7a387fff
TS
2275 opn = "daddu";
2276 break;
2277 case OPC_DSUB:
48d38ca5 2278 {
460f00c4
AJ
2279 TCGv t0 = tcg_temp_local_new();
2280 TCGv t1 = tcg_temp_new();
2281 TCGv t2 = tcg_temp_new();
48d38ca5
TS
2282 int l1 = gen_new_label();
2283
460f00c4
AJ
2284 gen_load_gpr(t1, rs);
2285 gen_load_gpr(t2, rt);
2286 tcg_gen_sub_tl(t0, t1, t2);
2287 tcg_gen_xor_tl(t2, t1, t2);
2288 tcg_gen_xor_tl(t1, t0, t1);
2289 tcg_gen_and_tl(t1, t1, t2);
2290 tcg_temp_free(t2);
2291 tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2292 tcg_temp_free(t1);
31e3104f 2293 /* operands of different sign, first operand and result different sign */
48d38ca5
TS
2294 generate_exception(ctx, EXCP_OVERFLOW);
2295 gen_set_label(l1);
460f00c4
AJ
2296 gen_store_gpr(t0, rd);
2297 tcg_temp_free(t0);
48d38ca5 2298 }
7a387fff
TS
2299 opn = "dsub";
2300 break;
2301 case OPC_DSUBU:
460f00c4
AJ
2302 if (rs != 0 && rt != 0) {
2303 tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2304 } else if (rs == 0 && rt != 0) {
2305 tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2306 } else if (rs != 0 && rt == 0) {
2307 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2308 } else {
2309 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2310 }
7a387fff
TS
2311 opn = "dsubu";
2312 break;
2313#endif
460f00c4
AJ
2314 case OPC_MUL:
2315 if (likely(rs != 0 && rt != 0)) {
2316 tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2317 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2318 } else {
2319 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2320 }
2321 opn = "mul";
6af0bf9c 2322 break;
460f00c4 2323 }
2abf314d 2324 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2325 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2326}
2327
2328/* Conditional move */
9fa77488
RH
2329static void gen_cond_move(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2330 int rd, int rs, int rt)
460f00c4
AJ
2331{
2332 const char *opn = "cond move";
2333 int l1;
2334
2335 if (rd == 0) {
2336 /* If no destination, treat it as a NOP.
2337 For add & sub, we must generate the overflow exception when needed. */
2338 MIPS_DEBUG("NOP");
2339 return;
2340 }
2341
2342 l1 = gen_new_label();
2343 switch (opc) {
2344 case OPC_MOVN:
2345 if (likely(rt != 0))
2346 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
2347 else
2348 tcg_gen_br(l1);
2349 opn = "movn";
6af0bf9c 2350 break;
460f00c4
AJ
2351 case OPC_MOVZ:
2352 if (likely(rt != 0))
2353 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
2354 opn = "movz";
2355 break;
2356 }
2357 if (rs != 0)
2358 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2359 else
2360 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2361 gen_set_label(l1);
2362
2abf314d 2363 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2364 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2365}
2366
2367/* Logic */
9fa77488
RH
2368static void gen_logic(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2369 int rd, int rs, int rt)
460f00c4
AJ
2370{
2371 const char *opn = "logic";
2372
2373 if (rd == 0) {
2374 /* If no destination, treat it as a NOP. */
2375 MIPS_DEBUG("NOP");
2376 return;
2377 }
2378
2379 switch (opc) {
6af0bf9c 2380 case OPC_AND:
460f00c4
AJ
2381 if (likely(rs != 0 && rt != 0)) {
2382 tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2383 } else {
2384 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2385 }
6af0bf9c
FB
2386 opn = "and";
2387 break;
2388 case OPC_NOR:
460f00c4
AJ
2389 if (rs != 0 && rt != 0) {
2390 tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2391 } else if (rs == 0 && rt != 0) {
2392 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2393 } else if (rs != 0 && rt == 0) {
2394 tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2395 } else {
2396 tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2397 }
6af0bf9c
FB
2398 opn = "nor";
2399 break;
2400 case OPC_OR:
460f00c4
AJ
2401 if (likely(rs != 0 && rt != 0)) {
2402 tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2403 } else if (rs == 0 && rt != 0) {
2404 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2405 } else if (rs != 0 && rt == 0) {
2406 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2407 } else {
2408 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2409 }
6af0bf9c
FB
2410 opn = "or";
2411 break;
2412 case OPC_XOR:
460f00c4
AJ
2413 if (likely(rs != 0 && rt != 0)) {
2414 tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2415 } else if (rs == 0 && rt != 0) {
2416 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2417 } else if (rs != 0 && rt == 0) {
2418 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2419 } else {
2420 tcg_gen_movi_tl(cpu_gpr[rd], 0);
2421 }
6af0bf9c
FB
2422 opn = "xor";
2423 break;
460f00c4 2424 }
2abf314d 2425 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2426 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2427}
2428
2429/* Set on lower than */
9fa77488
RH
2430static void gen_slt(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
2431 int rd, int rs, int rt)
460f00c4
AJ
2432{
2433 const char *opn = "slt";
2434 TCGv t0, t1;
2435
2436 if (rd == 0) {
2437 /* If no destination, treat it as a NOP. */
2438 MIPS_DEBUG("NOP");
2439 return;
2440 }
2441
2442 t0 = tcg_temp_new();
2443 t1 = tcg_temp_new();
2444 gen_load_gpr(t0, rs);
2445 gen_load_gpr(t1, rt);
2446 switch (opc) {
2447 case OPC_SLT:
e68dd28f 2448 tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
460f00c4 2449 opn = "slt";
6af0bf9c 2450 break;
460f00c4 2451 case OPC_SLTU:
e68dd28f 2452 tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
460f00c4
AJ
2453 opn = "sltu";
2454 break;
2455 }
2abf314d 2456 (void)opn; /* avoid a compiler warning */
460f00c4
AJ
2457 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2458 tcg_temp_free(t0);
2459 tcg_temp_free(t1);
2460}
20c4c97c 2461
460f00c4 2462/* Shifts */
7db13fae 2463static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
460f00c4
AJ
2464 int rd, int rs, int rt)
2465{
2466 const char *opn = "shifts";
2467 TCGv t0, t1;
20c4c97c 2468
460f00c4
AJ
2469 if (rd == 0) {
2470 /* If no destination, treat it as a NOP.
2471 For add & sub, we must generate the overflow exception when needed. */
2472 MIPS_DEBUG("NOP");
2473 return;
2474 }
2475
2476 t0 = tcg_temp_new();
2477 t1 = tcg_temp_new();
2478 gen_load_gpr(t0, rs);
2479 gen_load_gpr(t1, rt);
2480 switch (opc) {
6af0bf9c 2481 case OPC_SLLV:
78723684
TS
2482 tcg_gen_andi_tl(t0, t0, 0x1f);
2483 tcg_gen_shl_tl(t0, t1, t0);
460f00c4 2484 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6af0bf9c
FB
2485 opn = "sllv";
2486 break;
2487 case OPC_SRAV:
78723684 2488 tcg_gen_andi_tl(t0, t0, 0x1f);
460f00c4 2489 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
6af0bf9c
FB
2490 opn = "srav";
2491 break;
2492 case OPC_SRLV:
ea63e2c3
NF
2493 tcg_gen_ext32u_tl(t1, t1);
2494 tcg_gen_andi_tl(t0, t0, 0x1f);
2495 tcg_gen_shr_tl(t0, t1, t0);
2496 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2497 opn = "srlv";
2498 break;
2499 case OPC_ROTRV:
2500 {
2501 TCGv_i32 t2 = tcg_temp_new_i32();
2502 TCGv_i32 t3 = tcg_temp_new_i32();
2503
2504 tcg_gen_trunc_tl_i32(t2, t0);
2505 tcg_gen_trunc_tl_i32(t3, t1);
2506 tcg_gen_andi_i32(t2, t2, 0x1f);
2507 tcg_gen_rotr_i32(t2, t3, t2);
2508 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2509 tcg_temp_free_i32(t2);
2510 tcg_temp_free_i32(t3);
2511 opn = "rotrv";
5a63bcb2 2512 }
7a387fff 2513 break;
d26bc211 2514#if defined(TARGET_MIPS64)
7a387fff 2515 case OPC_DSLLV:
78723684 2516 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2517 tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2518 opn = "dsllv";
2519 break;
2520 case OPC_DSRAV:
78723684 2521 tcg_gen_andi_tl(t0, t0, 0x3f);
460f00c4 2522 tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
7a387fff
TS
2523 opn = "dsrav";
2524 break;
2525 case OPC_DSRLV:
ea63e2c3
NF
2526 tcg_gen_andi_tl(t0, t0, 0x3f);
2527 tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2528 opn = "dsrlv";
2529 break;
2530 case OPC_DROTRV:
2531 tcg_gen_andi_tl(t0, t0, 0x3f);
2532 tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2533 opn = "drotrv";
6af0bf9c 2534 break;
7a387fff 2535#endif
6af0bf9c 2536 }
2abf314d 2537 (void)opn; /* avoid a compiler warning */
6af0bf9c 2538 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
78723684
TS
2539 tcg_temp_free(t0);
2540 tcg_temp_free(t1);
6af0bf9c
FB
2541}
2542
2543/* Arithmetic on HI/LO registers */
7a387fff 2544static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
6af0bf9c 2545{
923617a3 2546 const char *opn = "hilo";
4133498f 2547 unsigned int acc;
6af0bf9c
FB
2548
2549 if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
ead9360e 2550 /* Treat as NOP. */
6af0bf9c 2551 MIPS_DEBUG("NOP");
a1f6684d 2552 return;
6af0bf9c 2553 }
4133498f
JL
2554
2555 if (opc == OPC_MFHI || opc == OPC_MFLO) {
2556 acc = ((ctx->opcode) >> 21) & 0x03;
2557 } else {
2558 acc = ((ctx->opcode) >> 11) & 0x03;
2559 }
2560
2561 if (acc != 0) {
2562 check_dsp(ctx);
2563 }
2564
6af0bf9c
FB
2565 switch (opc) {
2566 case OPC_MFHI:
4133498f
JL
2567#if defined(TARGET_MIPS64)
2568 if (acc != 0) {
2569 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2570 } else
2571#endif
2572 {
2573 tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2574 }
6af0bf9c
FB
2575 opn = "mfhi";
2576 break;
2577 case OPC_MFLO:
4133498f
JL
2578#if defined(TARGET_MIPS64)
2579 if (acc != 0) {
2580 tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2581 } else
2582#endif
2583 {
2584 tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2585 }
6af0bf9c
FB
2586 opn = "mflo";
2587 break;
2588 case OPC_MTHI:
4133498f
JL
2589 if (reg != 0) {
2590#if defined(TARGET_MIPS64)
2591 if (acc != 0) {
2592 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2593 } else
2594#endif
2595 {
2596 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2597 }
2598 } else {
2599 tcg_gen_movi_tl(cpu_HI[acc], 0);
2600 }
6af0bf9c
FB
2601 opn = "mthi";
2602 break;
2603 case OPC_MTLO:
4133498f
JL
2604 if (reg != 0) {
2605#if defined(TARGET_MIPS64)
2606 if (acc != 0) {
2607 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2608 } else
2609#endif
2610 {
2611 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2612 }
2613 } else {
2614 tcg_gen_movi_tl(cpu_LO[acc], 0);
2615 }
6af0bf9c
FB
2616 opn = "mtlo";
2617 break;
6af0bf9c 2618 }
2abf314d 2619 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
2620 MIPS_DEBUG("%s %s", opn, regnames[reg]);
2621}
2622
7a387fff 2623static void gen_muldiv (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2624 int rs, int rt)
2625{
923617a3 2626 const char *opn = "mul/div";
d45f89f4 2627 TCGv t0, t1;
4133498f 2628 unsigned int acc;
d45f89f4
AJ
2629
2630 switch (opc) {
2631 case OPC_DIV:
2632 case OPC_DIVU:
2633#if defined(TARGET_MIPS64)
2634 case OPC_DDIV:
2635 case OPC_DDIVU:
2636#endif
2637 t0 = tcg_temp_local_new();
2638 t1 = tcg_temp_local_new();
2639 break;
2640 default:
2641 t0 = tcg_temp_new();
2642 t1 = tcg_temp_new();
2643 break;
2644 }
6af0bf9c 2645
78723684
TS
2646 gen_load_gpr(t0, rs);
2647 gen_load_gpr(t1, rt);
6af0bf9c
FB
2648 switch (opc) {
2649 case OPC_DIV:
48d38ca5
TS
2650 {
2651 int l1 = gen_new_label();
d45f89f4 2652 int l2 = gen_new_label();
48d38ca5 2653
d45f89f4
AJ
2654 tcg_gen_ext32s_tl(t0, t0);
2655 tcg_gen_ext32s_tl(t1, t1);
78723684 2656 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
d45f89f4
AJ
2657 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2658 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2659
2660 tcg_gen_mov_tl(cpu_LO[0], t0);
2661 tcg_gen_movi_tl(cpu_HI[0], 0);
2662 tcg_gen_br(l1);
2663 gen_set_label(l2);
2664 tcg_gen_div_tl(cpu_LO[0], t0, t1);
2665 tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2666 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2667 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
48d38ca5
TS
2668 gen_set_label(l1);
2669 }
6af0bf9c
FB
2670 opn = "div";
2671 break;
2672 case OPC_DIVU:
48d38ca5
TS
2673 {
2674 int l1 = gen_new_label();
2675
0c0ed03b
AJ
2676 tcg_gen_ext32u_tl(t0, t0);
2677 tcg_gen_ext32u_tl(t1, t1);
78723684 2678 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
d45f89f4
AJ
2679 tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2680 tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2681 tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2682 tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
48d38ca5
TS
2683 gen_set_label(l1);
2684 }
6af0bf9c
FB
2685 opn = "divu";
2686 break;
2687 case OPC_MULT:
214c465f 2688 {
d45f89f4
AJ
2689 TCGv_i64 t2 = tcg_temp_new_i64();
2690 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2691 acc = ((ctx->opcode) >> 11) & 0x03;
2692 if (acc != 0) {
2693 check_dsp(ctx);
2694 }
d45f89f4
AJ
2695
2696 tcg_gen_ext_tl_i64(t2, t0);
2697 tcg_gen_ext_tl_i64(t3, t1);
2698 tcg_gen_mul_i64(t2, t2, t3);
2699 tcg_temp_free_i64(t3);
2700 tcg_gen_trunc_i64_tl(t0, t2);
2701 tcg_gen_shri_i64(t2, t2, 32);
2702 tcg_gen_trunc_i64_tl(t1, t2);
2703 tcg_temp_free_i64(t2);
4133498f
JL
2704 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2705 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2706 }
6af0bf9c
FB
2707 opn = "mult";
2708 break;
2709 case OPC_MULTU:
214c465f 2710 {
d45f89f4
AJ
2711 TCGv_i64 t2 = tcg_temp_new_i64();
2712 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2713 acc = ((ctx->opcode) >> 11) & 0x03;
2714 if (acc != 0) {
2715 check_dsp(ctx);
2716 }
214c465f 2717
78723684
TS
2718 tcg_gen_ext32u_tl(t0, t0);
2719 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2720 tcg_gen_extu_tl_i64(t2, t0);
2721 tcg_gen_extu_tl_i64(t3, t1);
2722 tcg_gen_mul_i64(t2, t2, t3);
2723 tcg_temp_free_i64(t3);
2724 tcg_gen_trunc_i64_tl(t0, t2);
2725 tcg_gen_shri_i64(t2, t2, 32);
2726 tcg_gen_trunc_i64_tl(t1, t2);
2727 tcg_temp_free_i64(t2);
4133498f
JL
2728 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2729 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2730 }
6af0bf9c
FB
2731 opn = "multu";
2732 break;
d26bc211 2733#if defined(TARGET_MIPS64)
7a387fff 2734 case OPC_DDIV:
48d38ca5
TS
2735 {
2736 int l1 = gen_new_label();
d45f89f4 2737 int l2 = gen_new_label();
48d38ca5 2738
78723684 2739 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
d45f89f4
AJ
2740 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2741 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2742 tcg_gen_mov_tl(cpu_LO[0], t0);
2743 tcg_gen_movi_tl(cpu_HI[0], 0);
2744 tcg_gen_br(l1);
2745 gen_set_label(l2);
2746 tcg_gen_div_i64(cpu_LO[0], t0, t1);
2747 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
48d38ca5
TS
2748 gen_set_label(l1);
2749 }
7a387fff
TS
2750 opn = "ddiv";
2751 break;
2752 case OPC_DDIVU:
48d38ca5
TS
2753 {
2754 int l1 = gen_new_label();
2755
78723684 2756 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
b10fa3c9
AJ
2757 tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2758 tcg_gen_remu_i64(cpu_HI[0], t0, t1);
48d38ca5
TS
2759 gen_set_label(l1);
2760 }
7a387fff
TS
2761 opn = "ddivu";
2762 break;
2763 case OPC_DMULT:
895c2d04 2764 gen_helper_dmult(cpu_env, t0, t1);
7a387fff
TS
2765 opn = "dmult";
2766 break;
2767 case OPC_DMULTU:
895c2d04 2768 gen_helper_dmultu(cpu_env, t0, t1);
7a387fff
TS
2769 opn = "dmultu";
2770 break;
2771#endif
6af0bf9c 2772 case OPC_MADD:
214c465f 2773 {
d45f89f4
AJ
2774 TCGv_i64 t2 = tcg_temp_new_i64();
2775 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2776 acc = ((ctx->opcode) >> 11) & 0x03;
2777 if (acc != 0) {
2778 check_dsp(ctx);
2779 }
d45f89f4
AJ
2780
2781 tcg_gen_ext_tl_i64(t2, t0);
2782 tcg_gen_ext_tl_i64(t3, t1);
2783 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2784 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2785 tcg_gen_add_i64(t2, t2, t3);
2786 tcg_temp_free_i64(t3);
2787 tcg_gen_trunc_i64_tl(t0, t2);
2788 tcg_gen_shri_i64(t2, t2, 32);
2789 tcg_gen_trunc_i64_tl(t1, t2);
2790 tcg_temp_free_i64(t2);
4133498f
JL
2791 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2792 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2793 }
6af0bf9c
FB
2794 opn = "madd";
2795 break;
2796 case OPC_MADDU:
4133498f 2797 {
d45f89f4
AJ
2798 TCGv_i64 t2 = tcg_temp_new_i64();
2799 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2800 acc = ((ctx->opcode) >> 11) & 0x03;
2801 if (acc != 0) {
2802 check_dsp(ctx);
2803 }
214c465f 2804
78723684
TS
2805 tcg_gen_ext32u_tl(t0, t0);
2806 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2807 tcg_gen_extu_tl_i64(t2, t0);
2808 tcg_gen_extu_tl_i64(t3, t1);
2809 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2810 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
d45f89f4
AJ
2811 tcg_gen_add_i64(t2, t2, t3);
2812 tcg_temp_free_i64(t3);
2813 tcg_gen_trunc_i64_tl(t0, t2);
2814 tcg_gen_shri_i64(t2, t2, 32);
2815 tcg_gen_trunc_i64_tl(t1, t2);
2816 tcg_temp_free_i64(t2);
4133498f
JL
2817 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2818 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2819 }
6af0bf9c
FB
2820 opn = "maddu";
2821 break;
2822 case OPC_MSUB:
214c465f 2823 {
d45f89f4
AJ
2824 TCGv_i64 t2 = tcg_temp_new_i64();
2825 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2826 acc = ((ctx->opcode) >> 11) & 0x03;
2827 if (acc != 0) {
2828 check_dsp(ctx);
2829 }
d45f89f4
AJ
2830
2831 tcg_gen_ext_tl_i64(t2, t0);
2832 tcg_gen_ext_tl_i64(t3, t1);
2833 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2834 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2835 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2836 tcg_temp_free_i64(t3);
2837 tcg_gen_trunc_i64_tl(t0, t2);
2838 tcg_gen_shri_i64(t2, t2, 32);
2839 tcg_gen_trunc_i64_tl(t1, t2);
2840 tcg_temp_free_i64(t2);
4133498f
JL
2841 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2842 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2843 }
6af0bf9c
FB
2844 opn = "msub";
2845 break;
2846 case OPC_MSUBU:
214c465f 2847 {
d45f89f4
AJ
2848 TCGv_i64 t2 = tcg_temp_new_i64();
2849 TCGv_i64 t3 = tcg_temp_new_i64();
4133498f
JL
2850 acc = ((ctx->opcode) >> 11) & 0x03;
2851 if (acc != 0) {
2852 check_dsp(ctx);
2853 }
214c465f 2854
78723684
TS
2855 tcg_gen_ext32u_tl(t0, t0);
2856 tcg_gen_ext32u_tl(t1, t1);
d45f89f4
AJ
2857 tcg_gen_extu_tl_i64(t2, t0);
2858 tcg_gen_extu_tl_i64(t3, t1);
2859 tcg_gen_mul_i64(t2, t2, t3);
4133498f 2860 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
98070ce0 2861 tcg_gen_sub_i64(t2, t3, t2);
d45f89f4
AJ
2862 tcg_temp_free_i64(t3);
2863 tcg_gen_trunc_i64_tl(t0, t2);
2864 tcg_gen_shri_i64(t2, t2, 32);
2865 tcg_gen_trunc_i64_tl(t1, t2);
2866 tcg_temp_free_i64(t2);
4133498f
JL
2867 tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2868 tcg_gen_ext32s_tl(cpu_HI[acc], t1);
214c465f 2869 }
6af0bf9c
FB
2870 opn = "msubu";
2871 break;
2872 default:
923617a3 2873 MIPS_INVAL(opn);
6af0bf9c 2874 generate_exception(ctx, EXCP_RI);
78723684 2875 goto out;
6af0bf9c 2876 }
2abf314d 2877 (void)opn; /* avoid a compiler warning */
6af0bf9c 2878 MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
78723684
TS
2879 out:
2880 tcg_temp_free(t0);
2881 tcg_temp_free(t1);
6af0bf9c
FB
2882}
2883
e9c71dd1
TS
2884static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2885 int rd, int rs, int rt)
2886{
2887 const char *opn = "mul vr54xx";
f157bfe1
AJ
2888 TCGv t0 = tcg_temp_new();
2889 TCGv t1 = tcg_temp_new();
e9c71dd1 2890
6c5c1e20
TS
2891 gen_load_gpr(t0, rs);
2892 gen_load_gpr(t1, rt);
e9c71dd1
TS
2893
2894 switch (opc) {
2895 case OPC_VR54XX_MULS:
895c2d04 2896 gen_helper_muls(t0, cpu_env, t0, t1);
e9c71dd1 2897 opn = "muls";
6958549d 2898 break;
e9c71dd1 2899 case OPC_VR54XX_MULSU:
895c2d04 2900 gen_helper_mulsu(t0, cpu_env, t0, t1);
e9c71dd1 2901 opn = "mulsu";
6958549d 2902 break;
e9c71dd1 2903 case OPC_VR54XX_MACC:
895c2d04 2904 gen_helper_macc(t0, cpu_env, t0, t1);
e9c71dd1 2905 opn = "macc";
6958549d 2906 break;
e9c71dd1 2907 case OPC_VR54XX_MACCU:
895c2d04 2908 gen_helper_maccu(t0, cpu_env, t0, t1);
e9c71dd1 2909 opn = "maccu";
6958549d 2910 break;
e9c71dd1 2911 case OPC_VR54XX_MSAC:
895c2d04 2912 gen_helper_msac(t0, cpu_env, t0, t1);
e9c71dd1 2913 opn = "msac";
6958549d 2914 break;
e9c71dd1 2915 case OPC_VR54XX_MSACU:
895c2d04 2916 gen_helper_msacu(t0, cpu_env, t0, t1);
e9c71dd1 2917 opn = "msacu";
6958549d 2918 break;
e9c71dd1 2919 case OPC_VR54XX_MULHI:
895c2d04 2920 gen_helper_mulhi(t0, cpu_env, t0, t1);
e9c71dd1 2921 opn = "mulhi";
6958549d 2922 break;
e9c71dd1 2923 case OPC_VR54XX_MULHIU:
895c2d04 2924 gen_helper_mulhiu(t0, cpu_env, t0, t1);
e9c71dd1 2925 opn = "mulhiu";
6958549d 2926 break;
e9c71dd1 2927 case OPC_VR54XX_MULSHI:
895c2d04 2928 gen_helper_mulshi(t0, cpu_env, t0, t1);
e9c71dd1 2929 opn = "mulshi";
6958549d 2930 break;
e9c71dd1 2931 case OPC_VR54XX_MULSHIU:
895c2d04 2932 gen_helper_mulshiu(t0, cpu_env, t0, t1);
e9c71dd1 2933 opn = "mulshiu";
6958549d 2934 break;
e9c71dd1 2935 case OPC_VR54XX_MACCHI:
895c2d04 2936 gen_helper_macchi(t0, cpu_env, t0, t1);
e9c71dd1 2937 opn = "macchi";
6958549d 2938 break;
e9c71dd1 2939 case OPC_VR54XX_MACCHIU:
895c2d04 2940 gen_helper_macchiu(t0, cpu_env, t0, t1);
e9c71dd1 2941 opn = "macchiu";
6958549d 2942 break;
e9c71dd1 2943 case OPC_VR54XX_MSACHI:
895c2d04 2944 gen_helper_msachi(t0, cpu_env, t0, t1);
e9c71dd1 2945 opn = "msachi";
6958549d 2946 break;
e9c71dd1 2947 case OPC_VR54XX_MSACHIU:
895c2d04 2948 gen_helper_msachiu(t0, cpu_env, t0, t1);
e9c71dd1 2949 opn = "msachiu";
6958549d 2950 break;
e9c71dd1
TS
2951 default:
2952 MIPS_INVAL("mul vr54xx");
2953 generate_exception(ctx, EXCP_RI);
6c5c1e20 2954 goto out;
e9c71dd1 2955 }
6c5c1e20 2956 gen_store_gpr(t0, rd);
2abf314d 2957 (void)opn; /* avoid a compiler warning */
e9c71dd1 2958 MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
6c5c1e20
TS
2959
2960 out:
2961 tcg_temp_free(t0);
2962 tcg_temp_free(t1);
e9c71dd1
TS
2963}
2964
7a387fff 2965static void gen_cl (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
2966 int rd, int rs)
2967{
923617a3 2968 const char *opn = "CLx";
20e1fb52 2969 TCGv t0;
6c5c1e20 2970
6af0bf9c 2971 if (rd == 0) {
ead9360e 2972 /* Treat as NOP. */
6af0bf9c 2973 MIPS_DEBUG("NOP");
20e1fb52 2974 return;
6af0bf9c 2975 }
20e1fb52 2976 t0 = tcg_temp_new();
6c5c1e20 2977 gen_load_gpr(t0, rs);
6af0bf9c
FB
2978 switch (opc) {
2979 case OPC_CLO:
20e1fb52 2980 gen_helper_clo(cpu_gpr[rd], t0);
6af0bf9c
FB
2981 opn = "clo";
2982 break;
2983 case OPC_CLZ:
20e1fb52 2984 gen_helper_clz(cpu_gpr[rd], t0);
6af0bf9c
FB
2985 opn = "clz";
2986 break;
d26bc211 2987#if defined(TARGET_MIPS64)
7a387fff 2988 case OPC_DCLO:
20e1fb52 2989 gen_helper_dclo(cpu_gpr[rd], t0);
7a387fff
TS
2990 opn = "dclo";
2991 break;
2992 case OPC_DCLZ:
20e1fb52 2993 gen_helper_dclz(cpu_gpr[rd], t0);
7a387fff
TS
2994 opn = "dclz";
2995 break;
2996#endif
6af0bf9c 2997 }
2abf314d 2998 (void)opn; /* avoid a compiler warning */
6af0bf9c 2999 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
6c5c1e20 3000 tcg_temp_free(t0);
6af0bf9c
FB
3001}
3002
161f85e6 3003/* Godson integer instructions */
bd277fa1
RH
3004static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3005 int rd, int rs, int rt)
161f85e6
AJ
3006{
3007 const char *opn = "loongson";
3008 TCGv t0, t1;
3009
3010 if (rd == 0) {
3011 /* Treat as NOP. */
3012 MIPS_DEBUG("NOP");
3013 return;
3014 }
3015
3016 switch (opc) {
3017 case OPC_MULT_G_2E:
3018 case OPC_MULT_G_2F:
3019 case OPC_MULTU_G_2E:
3020 case OPC_MULTU_G_2F:
3021#if defined(TARGET_MIPS64)
3022 case OPC_DMULT_G_2E:
3023 case OPC_DMULT_G_2F:
3024 case OPC_DMULTU_G_2E:
3025 case OPC_DMULTU_G_2F:
3026#endif
3027 t0 = tcg_temp_new();
3028 t1 = tcg_temp_new();
3029 break;
3030 default:
3031 t0 = tcg_temp_local_new();
3032 t1 = tcg_temp_local_new();
3033 break;
3034 }
3035
3036 gen_load_gpr(t0, rs);
3037 gen_load_gpr(t1, rt);
3038
3039 switch (opc) {
3040 case OPC_MULT_G_2E:
3041 case OPC_MULT_G_2F:
3042 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3043 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3044 opn = "mult.g";
3045 break;
3046 case OPC_MULTU_G_2E:
3047 case OPC_MULTU_G_2F:
3048 tcg_gen_ext32u_tl(t0, t0);
3049 tcg_gen_ext32u_tl(t1, t1);
3050 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3051 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3052 opn = "multu.g";
3053 break;
3054 case OPC_DIV_G_2E:
3055 case OPC_DIV_G_2F:
3056 {
3057 int l1 = gen_new_label();
3058 int l2 = gen_new_label();
3059 int l3 = gen_new_label();
3060 tcg_gen_ext32s_tl(t0, t0);
3061 tcg_gen_ext32s_tl(t1, t1);
3062 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3063 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3064 tcg_gen_br(l3);
3065 gen_set_label(l1);
3066 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3067 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3068 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3069 tcg_gen_br(l3);
3070 gen_set_label(l2);
3071 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3072 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3073 gen_set_label(l3);
3074 }
3075 opn = "div.g";
3076 break;
3077 case OPC_DIVU_G_2E:
3078 case OPC_DIVU_G_2F:
3079 {
3080 int l1 = gen_new_label();
3081 int l2 = gen_new_label();
3082 tcg_gen_ext32u_tl(t0, t0);
3083 tcg_gen_ext32u_tl(t1, t1);
3084 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3085 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3086 tcg_gen_br(l2);
3087 gen_set_label(l1);
3088 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3089 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3090 gen_set_label(l2);
3091 }
3092 opn = "divu.g";
3093 break;
3094 case OPC_MOD_G_2E:
3095 case OPC_MOD_G_2F:
3096 {
3097 int l1 = gen_new_label();
3098 int l2 = gen_new_label();
3099 int l3 = gen_new_label();
3100 tcg_gen_ext32u_tl(t0, t0);
3101 tcg_gen_ext32u_tl(t1, t1);
3102 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3103 tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3104 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3105 gen_set_label(l1);
3106 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3107 tcg_gen_br(l3);
3108 gen_set_label(l2);
3109 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3110 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3111 gen_set_label(l3);
3112 }
3113 opn = "mod.g";
3114 break;
3115 case OPC_MODU_G_2E:
3116 case OPC_MODU_G_2F:
3117 {
3118 int l1 = gen_new_label();
3119 int l2 = gen_new_label();
3120 tcg_gen_ext32u_tl(t0, t0);
3121 tcg_gen_ext32u_tl(t1, t1);
3122 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3123 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3124 tcg_gen_br(l2);
3125 gen_set_label(l1);
3126 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3127 tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3128 gen_set_label(l2);
3129 }
3130 opn = "modu.g";
3131 break;
3132#if defined(TARGET_MIPS64)
3133 case OPC_DMULT_G_2E:
3134 case OPC_DMULT_G_2F:
3135 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3136 opn = "dmult.g";
3137 break;
3138 case OPC_DMULTU_G_2E:
3139 case OPC_DMULTU_G_2F:
3140 tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3141 opn = "dmultu.g";
3142 break;
3143 case OPC_DDIV_G_2E:
3144 case OPC_DDIV_G_2F:
3145 {
3146 int l1 = gen_new_label();
3147 int l2 = gen_new_label();
3148 int l3 = gen_new_label();
3149 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3150 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3151 tcg_gen_br(l3);
3152 gen_set_label(l1);
3153 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3154 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3155 tcg_gen_mov_tl(cpu_gpr[rd], t0);
3156 tcg_gen_br(l3);
3157 gen_set_label(l2);
3158 tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3159 gen_set_label(l3);
3160 }
3161 opn = "ddiv.g";
3162 break;
3163 case OPC_DDIVU_G_2E:
3164 case OPC_DDIVU_G_2F:
3165 {
3166 int l1 = gen_new_label();
3167 int l2 = gen_new_label();
3168 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3169 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3170 tcg_gen_br(l2);
3171 gen_set_label(l1);
3172 tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3173 gen_set_label(l2);
3174 }
3175 opn = "ddivu.g";
3176 break;
3177 case OPC_DMOD_G_2E:
3178 case OPC_DMOD_G_2F:
3179 {
3180 int l1 = gen_new_label();
3181 int l2 = gen_new_label();
3182 int l3 = gen_new_label();
3183 tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3184 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3185 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3186 gen_set_label(l1);
3187 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3188 tcg_gen_br(l3);
3189 gen_set_label(l2);
3190 tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3191 gen_set_label(l3);
3192 }
3193 opn = "dmod.g";
3194 break;
3195 case OPC_DMODU_G_2E:
3196 case OPC_DMODU_G_2F:
3197 {
3198 int l1 = gen_new_label();
3199 int l2 = gen_new_label();
3200 tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3201 tcg_gen_movi_tl(cpu_gpr[rd], 0);
3202 tcg_gen_br(l2);
3203 gen_set_label(l1);
3204 tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3205 gen_set_label(l2);
3206 }
3207 opn = "dmodu.g";
3208 break;
3209#endif
3210 }
3211
2abf314d 3212 (void)opn; /* avoid a compiler warning */
161f85e6
AJ
3213 MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3214 tcg_temp_free(t0);
3215 tcg_temp_free(t1);
3216}
3217
bd277fa1
RH
3218/* Loongson multimedia instructions */
3219static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3220{
3221 const char *opn = "loongson_cp2";
3222 uint32_t opc, shift_max;
3223 TCGv_i64 t0, t1;
3224
3225 opc = MASK_LMI(ctx->opcode);
3226 switch (opc) {
3227 case OPC_ADD_CP2:
3228 case OPC_SUB_CP2:
3229 case OPC_DADD_CP2:
3230 case OPC_DSUB_CP2:
3231 t0 = tcg_temp_local_new_i64();
3232 t1 = tcg_temp_local_new_i64();
3233 break;
3234 default:
3235 t0 = tcg_temp_new_i64();
3236 t1 = tcg_temp_new_i64();
3237 break;
3238 }
3239
3240 gen_load_fpr64(ctx, t0, rs);
3241 gen_load_fpr64(ctx, t1, rt);
3242
3243#define LMI_HELPER(UP, LO) \
3244 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3245#define LMI_HELPER_1(UP, LO) \
3246 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3247#define LMI_DIRECT(UP, LO, OP) \
3248 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3249
3250 switch (opc) {
3251 LMI_HELPER(PADDSH, paddsh);
3252 LMI_HELPER(PADDUSH, paddush);
3253 LMI_HELPER(PADDH, paddh);
3254 LMI_HELPER(PADDW, paddw);
3255 LMI_HELPER(PADDSB, paddsb);
3256 LMI_HELPER(PADDUSB, paddusb);
3257 LMI_HELPER(PADDB, paddb);
3258
3259 LMI_HELPER(PSUBSH, psubsh);
3260 LMI_HELPER(PSUBUSH, psubush);
3261 LMI_HELPER(PSUBH, psubh);
3262 LMI_HELPER(PSUBW, psubw);
3263 LMI_HELPER(PSUBSB, psubsb);
3264 LMI_HELPER(PSUBUSB, psubusb);
3265 LMI_HELPER(PSUBB, psubb);
3266
3267 LMI_HELPER(PSHUFH, pshufh);
3268 LMI_HELPER(PACKSSWH, packsswh);
3269 LMI_HELPER(PACKSSHB, packsshb);
3270 LMI_HELPER(PACKUSHB, packushb);
3271
3272 LMI_HELPER(PUNPCKLHW, punpcklhw);
3273 LMI_HELPER(PUNPCKHHW, punpckhhw);
3274 LMI_HELPER(PUNPCKLBH, punpcklbh);
3275 LMI_HELPER(PUNPCKHBH, punpckhbh);
3276 LMI_HELPER(PUNPCKLWD, punpcklwd);
3277 LMI_HELPER(PUNPCKHWD, punpckhwd);
3278
3279 LMI_HELPER(PAVGH, pavgh);
3280 LMI_HELPER(PAVGB, pavgb);
3281 LMI_HELPER(PMAXSH, pmaxsh);
3282 LMI_HELPER(PMINSH, pminsh);
3283 LMI_HELPER(PMAXUB, pmaxub);
3284 LMI_HELPER(PMINUB, pminub);
3285
3286 LMI_HELPER(PCMPEQW, pcmpeqw);
3287 LMI_HELPER(PCMPGTW, pcmpgtw);
3288 LMI_HELPER(PCMPEQH, pcmpeqh);
3289 LMI_HELPER(PCMPGTH, pcmpgth);
3290 LMI_HELPER(PCMPEQB, pcmpeqb);
3291 LMI_HELPER(PCMPGTB, pcmpgtb);
3292
3293 LMI_HELPER(PSLLW, psllw);
3294 LMI_HELPER(PSLLH, psllh);
3295 LMI_HELPER(PSRLW, psrlw);
3296 LMI_HELPER(PSRLH, psrlh);
3297 LMI_HELPER(PSRAW, psraw);
3298 LMI_HELPER(PSRAH, psrah);
3299
3300 LMI_HELPER(PMULLH, pmullh);
3301 LMI_HELPER(PMULHH, pmulhh);
3302 LMI_HELPER(PMULHUH, pmulhuh);
3303 LMI_HELPER(PMADDHW, pmaddhw);
3304
3305 LMI_HELPER(PASUBUB, pasubub);
3306 LMI_HELPER_1(BIADD, biadd);
3307 LMI_HELPER_1(PMOVMSKB, pmovmskb);
3308
3309 LMI_DIRECT(PADDD, paddd, add);
3310 LMI_DIRECT(PSUBD, psubd, sub);
3311 LMI_DIRECT(XOR_CP2, xor, xor);
3312 LMI_DIRECT(NOR_CP2, nor, nor);
3313 LMI_DIRECT(AND_CP2, and, and);
3314 LMI_DIRECT(PANDN, pandn, andc);
3315 LMI_DIRECT(OR, or, or);
3316
3317 case OPC_PINSRH_0:
3318 tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3319 opn = "pinsrh_0";
3320 break;
3321 case OPC_PINSRH_1:
3322 tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3323 opn = "pinsrh_1";
3324 break;
3325 case OPC_PINSRH_2:
3326 tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3327 opn = "pinsrh_2";
3328 break;
3329 case OPC_PINSRH_3:
3330 tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3331 opn = "pinsrh_3";
3332 break;
3333
3334 case OPC_PEXTRH:
3335 tcg_gen_andi_i64(t1, t1, 3);
3336 tcg_gen_shli_i64(t1, t1, 4);
3337 tcg_gen_shr_i64(t0, t0, t1);
3338 tcg_gen_ext16u_i64(t0, t0);
3339 opn = "pextrh";
3340 break;
3341
3342 case OPC_ADDU_CP2:
3343 tcg_gen_add_i64(t0, t0, t1);
3344 tcg_gen_ext32s_i64(t0, t0);
3345 opn = "addu";
3346 break;
3347 case OPC_SUBU_CP2:
3348 tcg_gen_sub_i64(t0, t0, t1);
3349 tcg_gen_ext32s_i64(t0, t0);
3350 opn = "addu";
3351 break;
3352
3353 case OPC_SLL_CP2:
3354 opn = "sll";
3355 shift_max = 32;
3356 goto do_shift;
3357 case OPC_SRL_CP2:
3358 opn = "srl";
3359 shift_max = 32;
3360 goto do_shift;
3361 case OPC_SRA_CP2:
3362 opn = "sra";
3363 shift_max = 32;
3364 goto do_shift;
3365 case OPC_DSLL_CP2:
3366 opn = "dsll";
3367 shift_max = 64;
3368 goto do_shift;
3369 case OPC_DSRL_CP2:
3370 opn = "dsrl";
3371 shift_max = 64;
3372 goto do_shift;
3373 case OPC_DSRA_CP2:
3374 opn = "dsra";
3375 shift_max = 64;
3376 goto do_shift;
3377 do_shift:
3378 /* Make sure shift count isn't TCG undefined behaviour. */
3379 tcg_gen_andi_i64(t1, t1, shift_max - 1);
3380
3381 switch (opc) {
3382 case OPC_SLL_CP2:
3383 case OPC_DSLL_CP2:
3384 tcg_gen_shl_i64(t0, t0, t1);
3385 break;
3386 case OPC_SRA_CP2:
3387 case OPC_DSRA_CP2:
3388 /* Since SRA is UndefinedResult without sign-extended inputs,
3389 we can treat SRA and DSRA the same. */
3390 tcg_gen_sar_i64(t0, t0, t1);
3391 break;
3392 case OPC_SRL_CP2:
3393 /* We want to shift in zeros for SRL; zero-extend first. */
3394 tcg_gen_ext32u_i64(t0, t0);
3395 /* FALLTHRU */
3396 case OPC_DSRL_CP2:
3397 tcg_gen_shr_i64(t0, t0, t1);
3398 break;
3399 }
3400
3401 if (shift_max == 32) {
3402 tcg_gen_ext32s_i64(t0, t0);
3403 }
3404
3405 /* Shifts larger than MAX produce zero. */
3406 tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3407 tcg_gen_neg_i64(t1, t1);
3408 tcg_gen_and_i64(t0, t0, t1);
3409 break;
3410
3411 case OPC_ADD_CP2:
3412 case OPC_DADD_CP2:
3413 {
3414 TCGv_i64 t2 = tcg_temp_new_i64();
3415 int lab = gen_new_label();
3416
3417 tcg_gen_mov_i64(t2, t0);
3418 tcg_gen_add_i64(t0, t1, t2);
3419 if (opc == OPC_ADD_CP2) {
3420 tcg_gen_ext32s_i64(t0, t0);
3421 }
3422 tcg_gen_xor_i64(t1, t1, t2);
3423 tcg_gen_xor_i64(t2, t2, t0);
3424 tcg_gen_andc_i64(t1, t2, t1);
3425 tcg_temp_free_i64(t2);
3426 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3427 generate_exception(ctx, EXCP_OVERFLOW);
3428 gen_set_label(lab);
3429
3430 opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3431 break;
3432 }
3433
3434 case OPC_SUB_CP2:
3435 case OPC_DSUB_CP2:
3436 {
3437 TCGv_i64 t2 = tcg_temp_new_i64();
3438 int lab = gen_new_label();
3439
3440 tcg_gen_mov_i64(t2, t0);
3441 tcg_gen_sub_i64(t0, t1, t2);
3442 if (opc == OPC_SUB_CP2) {
3443 tcg_gen_ext32s_i64(t0, t0);
3444 }
3445 tcg_gen_xor_i64(t1, t1, t2);
3446 tcg_gen_xor_i64(t2, t2, t0);
3447 tcg_gen_and_i64(t1, t1, t2);
3448 tcg_temp_free_i64(t2);
3449 tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3450 generate_exception(ctx, EXCP_OVERFLOW);
3451 gen_set_label(lab);
3452
3453 opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3454 break;
3455 }
3456
3457 case OPC_PMULUW:
3458 tcg_gen_ext32u_i64(t0, t0);
3459 tcg_gen_ext32u_i64(t1, t1);
3460 tcg_gen_mul_i64(t0, t0, t1);
3461 opn = "pmuluw";
3462 break;
3463
3464 case OPC_SEQU_CP2:
3465 case OPC_SEQ_CP2:
3466 case OPC_SLTU_CP2:
3467 case OPC_SLT_CP2:
3468 case OPC_SLEU_CP2:
3469 case OPC_SLE_CP2:
3470 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3471 FD field is the CC field? */
3472 default:
3473 MIPS_INVAL(opn);
3474 generate_exception(ctx, EXCP_RI);
3475 return;
3476 }
3477
3478#undef LMI_HELPER
3479#undef LMI_DIRECT
3480
3481 gen_store_fpr64(ctx, t0, rd);
3482
3483 (void)opn; /* avoid a compiler warning */
3484 MIPS_DEBUG("%s %s, %s, %s", opn,
3485 fregnames[rd], fregnames[rs], fregnames[rt]);
3486 tcg_temp_free_i64(t0);
3487 tcg_temp_free_i64(t1);
3488}
3489
6af0bf9c 3490/* Traps */
7a387fff 3491static void gen_trap (DisasContext *ctx, uint32_t opc,
6af0bf9c
FB
3492 int rs, int rt, int16_t imm)
3493{
3494 int cond;
cdc0faa6 3495 TCGv t0 = tcg_temp_new();
1ba74fb8 3496 TCGv t1 = tcg_temp_new();
6af0bf9c
FB
3497
3498 cond = 0;
3499 /* Load needed operands */
3500 switch (opc) {
3501 case OPC_TEQ:
3502 case OPC_TGE:
3503 case OPC_TGEU:
3504 case OPC_TLT:
3505 case OPC_TLTU:
3506 case OPC_TNE:
3507 /* Compare two registers */
3508 if (rs != rt) {
be24bb4f
TS
3509 gen_load_gpr(t0, rs);
3510 gen_load_gpr(t1, rt);
6af0bf9c
FB
3511 cond = 1;
3512 }
179e32bb 3513 break;
6af0bf9c
FB
3514 case OPC_TEQI:
3515 case OPC_TGEI:
3516 case OPC_TGEIU:
3517 case OPC_TLTI:
3518 case OPC_TLTIU:
3519 case OPC_TNEI:
3520 /* Compare register to immediate */
3521 if (rs != 0 || imm != 0) {
be24bb4f
TS
3522 gen_load_gpr(t0, rs);
3523 tcg_gen_movi_tl(t1, (int32_t)imm);
6af0bf9c
FB
3524 cond = 1;
3525 }
3526 break;
3527 }
3528 if (cond == 0) {
3529 switch (opc) {
3530 case OPC_TEQ: /* rs == rs */
3531 case OPC_TEQI: /* r0 == 0 */
3532 case OPC_TGE: /* rs >= rs */
3533 case OPC_TGEI: /* r0 >= 0 */
3534 case OPC_TGEU: /* rs >= rs unsigned */
3535 case OPC_TGEIU: /* r0 >= 0 unsigned */
3536 /* Always trap */
cdc0faa6 3537 generate_exception(ctx, EXCP_TRAP);
6af0bf9c
FB
3538 break;
3539 case OPC_TLT: /* rs < rs */
3540 case OPC_TLTI: /* r0 < 0 */
3541 case OPC_TLTU: /* rs < rs unsigned */
3542 case OPC_TLTIU: /* r0 < 0 unsigned */
3543 case OPC_TNE: /* rs != rs */
3544 case OPC_TNEI: /* r0 != 0 */
ead9360e 3545 /* Never trap: treat as NOP. */
cdc0faa6 3546 break;
6af0bf9c
FB
3547 }
3548 } else {
cdc0faa6
AJ
3549 int l1 = gen_new_label();
3550
6af0bf9c
FB
3551 switch (opc) {
3552 case OPC_TEQ:
3553 case OPC_TEQI:
cdc0faa6 3554 tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
6af0bf9c
FB
3555 break;
3556 case OPC_TGE:
3557 case OPC_TGEI:
cdc0faa6 3558 tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
6af0bf9c
FB
3559 break;
3560 case OPC_TGEU:
3561 case OPC_TGEIU:
cdc0faa6 3562 tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
6af0bf9c
FB
3563 break;
3564 case OPC_TLT:
3565 case OPC_TLTI:
cdc0faa6 3566 tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
6af0bf9c
FB
3567 break;
3568 case OPC_TLTU:
3569 case OPC_TLTIU:
cdc0faa6 3570 tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
6af0bf9c
FB
3571 break;
3572 case OPC_TNE:
3573 case OPC_TNEI:
cdc0faa6 3574 tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
6af0bf9c 3575 break;
6af0bf9c 3576 }
cdc0faa6 3577 generate_exception(ctx, EXCP_TRAP);
08ba7963
TS
3578 gen_set_label(l1);
3579 }
be24bb4f
TS
3580 tcg_temp_free(t0);
3581 tcg_temp_free(t1);
6af0bf9c
FB
3582}
3583
356265ae 3584static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
c53be334 3585{
6e256c93
FB
3586 TranslationBlock *tb;
3587 tb = ctx->tb;
7b270ef2
NF
3588 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3589 likely(!ctx->singlestep_enabled)) {
57fec1fe 3590 tcg_gen_goto_tb(n);
9b9e4393 3591 gen_save_pc(dest);
4b4a72e5 3592 tcg_gen_exit_tb((tcg_target_long)tb + n);
6e256c93 3593 } else {
9b9e4393 3594 gen_save_pc(dest);
7b270ef2
NF
3595 if (ctx->singlestep_enabled) {
3596 save_cpu_state(ctx, 0);
895c2d04 3597 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
7b270ef2 3598 }
57fec1fe 3599 tcg_gen_exit_tb(0);
6e256c93 3600 }
c53be334
FB
3601}
3602
6af0bf9c 3603/* Branches (before delay slot) */
7a387fff 3604static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
7dca4ad0 3605 int insn_bytes,
6af0bf9c
FB
3606 int rs, int rt, int32_t offset)
3607{
d077b6f7 3608 target_ulong btgt = -1;
3ad4bb2d 3609 int blink = 0;
2fdbad25 3610 int bcond_compute = 0;
1ba74fb8
AJ
3611 TCGv t0 = tcg_temp_new();
3612 TCGv t1 = tcg_temp_new();
3ad4bb2d
TS
3613
3614 if (ctx->hflags & MIPS_HFLAG_BMASK) {
923617a3 3615#ifdef MIPS_DEBUG_DISAS
d12d51d5 3616 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
923617a3 3617#endif
3ad4bb2d 3618 generate_exception(ctx, EXCP_RI);
6c5c1e20 3619 goto out;
3ad4bb2d 3620 }
6af0bf9c 3621
6af0bf9c
FB
3622 /* Load needed operands */
3623 switch (opc) {
3624 case OPC_BEQ:
3625 case OPC_BEQL:
3626 case OPC_BNE:
3627 case OPC_BNEL:
3628 /* Compare two registers */
3629 if (rs != rt) {
6c5c1e20
TS
3630 gen_load_gpr(t0, rs);
3631 gen_load_gpr(t1, rt);
2fdbad25 3632 bcond_compute = 1;
6af0bf9c 3633 }
7dca4ad0 3634 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c
FB
3635 break;
3636 case OPC_BGEZ:
3637 case OPC_BGEZAL:
3c824109 3638 case OPC_BGEZALS:
6af0bf9c
FB
3639 case OPC_BGEZALL:
3640 case OPC_BGEZL:
3641 case OPC_BGTZ:
3642 case OPC_BGTZL:
3643 case OPC_BLEZ:
3644 case OPC_BLEZL:
3645 case OPC_BLTZ:
3646 case OPC_BLTZAL:
3c824109 3647 case OPC_BLTZALS:
6af0bf9c
FB
3648 case OPC_BLTZALL:
3649 case OPC_BLTZL:
3650 /* Compare to zero */
3651 if (rs != 0) {
6c5c1e20 3652 gen_load_gpr(t0, rs);
2fdbad25 3653 bcond_compute = 1;
6af0bf9c 3654 }
7dca4ad0 3655 btgt = ctx->pc + insn_bytes + offset;
6af0bf9c 3656 break;
e45a93e2
JL
3657 case OPC_BPOSGE32:
3658#if defined(TARGET_MIPS64)
3659 case OPC_BPOSGE64:
3660 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3661#else
3662 tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3663#endif
3664 bcond_compute = 1;
3665 btgt = ctx->pc + insn_bytes + offset;
3666 break;
6af0bf9c
FB
3667 case OPC_J:
3668 case OPC_JAL:
364d4831 3669 case OPC_JALX:
620e48f6
NF
3670 case OPC_JALS:
3671 case OPC_JALXS:
6af0bf9c 3672 /* Jump to immediate */
7dca4ad0 3673 btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
6af0bf9c
FB
3674 break;
3675 case OPC_JR:
3676 case OPC_JALR:
364d4831 3677 case OPC_JALRC:
620e48f6 3678 case OPC_JALRS:
6af0bf9c 3679 /* Jump to register */
7a387fff
TS
3680 if (offset != 0 && offset != 16) {
3681 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
cbeb0857 3682 others are reserved. */
923617a3 3683 MIPS_INVAL("jump hint");
6af0bf9c 3684 generate_exception(ctx, EXCP_RI);
6c5c1e20 3685 goto out;
6af0bf9c 3686 }
d077b6f7 3687 gen_load_gpr(btarget, rs);
6af0bf9c
FB
3688 break;
3689 default:
3690 MIPS_INVAL("branch/jump");
3691 generate_exception(ctx, EXCP_RI);
6c5c1e20 3692 goto out;
6af0bf9c 3693 }
2fdbad25 3694 if (bcond_compute == 0) {
6af0bf9c
FB
3695 /* No condition to be computed */
3696 switch (opc) {
3697 case OPC_BEQ: /* rx == rx */
3698 case OPC_BEQL: /* rx == rx likely */
3699 case OPC_BGEZ: /* 0 >= 0 */
3700 case OPC_BGEZL: /* 0 >= 0 likely */
3701 case OPC_BLEZ: /* 0 <= 0 */
3702 case OPC_BLEZL: /* 0 <= 0 likely */
3703 /* Always take */
4ad40f36 3704 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3705 MIPS_DEBUG("balways");
3706 break;
3c824109 3707 case OPC_BGEZALS:
6af0bf9c
FB
3708 case OPC_BGEZAL: /* 0 >= 0 */
3709 case OPC_BGEZALL: /* 0 >= 0 likely */
3c824109
NF
3710 ctx->hflags |= (opc == OPC_BGEZALS
3711 ? MIPS_HFLAG_BDS16
3712 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3713 /* Always take and link */
3714 blink = 31;
4ad40f36 3715 ctx->hflags |= MIPS_HFLAG_B;
6af0bf9c
FB
3716 MIPS_DEBUG("balways and link");
3717 break;
3718 case OPC_BNE: /* rx != rx */
3719 case OPC_BGTZ: /* 0 > 0 */
3720 case OPC_BLTZ: /* 0 < 0 */
ead9360e 3721 /* Treat as NOP. */
6af0bf9c 3722 MIPS_DEBUG("bnever (NOP)");
6c5c1e20 3723 goto out;
3c824109 3724 case OPC_BLTZALS:
eeef26cd 3725 case OPC_BLTZAL: /* 0 < 0 */
3c824109
NF
3726 ctx->hflags |= (opc == OPC_BLTZALS
3727 ? MIPS_HFLAG_BDS16
3728 : MIPS_HFLAG_BDS32);
3729 /* Handle as an unconditional branch to get correct delay
3730 slot checking. */
3731 blink = 31;
3732 btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3733 ctx->hflags |= MIPS_HFLAG_B;
9898128f 3734 MIPS_DEBUG("bnever and link");
3c824109 3735 break;
eeef26cd 3736 case OPC_BLTZALL: /* 0 < 0 likely */
1ba74fb8 3737 tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
9898128f
TS
3738 /* Skip the instruction in the delay slot */
3739 MIPS_DEBUG("bnever, link and skip");
3740 ctx->pc += 4;
6c5c1e20 3741 goto out;
6af0bf9c
FB
3742 case OPC_BNEL: /* rx != rx likely */
3743 case OPC_BGTZL: /* 0 > 0 likely */
6af0bf9c
FB
3744 case OPC_BLTZL: /* 0 < 0 likely */
3745 /* Skip the instruction in the delay slot */
3746 MIPS_DEBUG("bnever and skip");
9898128f 3747 ctx->pc += 4;
6c5c1e20 3748 goto out;
6af0bf9c 3749 case OPC_J:
4ad40f36 3750 ctx->hflags |= MIPS_HFLAG_B;
d077b6f7 3751 MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
6af0bf9c 3752 break;
620e48f6 3753 case OPC_JALXS:
364d4831
NF
3754 case OPC_JALX:
3755 ctx->hflags |= MIPS_HFLAG_BX;
3756 /* Fallthrough */
620e48f6 3757 case OPC_JALS:
6af0bf9c
FB
3758 case OPC_JAL:
3759 blink = 31;
4ad40f36 3760 ctx->hflags |= MIPS_HFLAG_B;
620e48f6 3761 ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
364d4831
NF
3762 ? MIPS_HFLAG_BDS16
3763 : MIPS_HFLAG_BDS32);
d077b6f7 3764 MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
6af0bf9c
FB
3765 break;
3766 case OPC_JR:
4ad40f36 3767 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3768 if (insn_bytes == 4)
3769 ctx->hflags |= MIPS_HFLAG_BDS32;
6af0bf9c
FB
3770 MIPS_DEBUG("jr %s", regnames[rs]);
3771 break;
620e48f6 3772 case OPC_JALRS:
6af0bf9c 3773 case OPC_JALR:
364d4831 3774 case OPC_JALRC:
6af0bf9c 3775 blink = rt;
4ad40f36 3776 ctx->hflags |= MIPS_HFLAG_BR;
620e48f6
NF
3777 ctx->hflags |= (opc == OPC_JALRS
3778 ? MIPS_HFLAG_BDS16
3779 : MIPS_HFLAG_BDS32);
6af0bf9c
FB
3780 MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3781 break;
3782 default:
3783 MIPS_INVAL("branch/jump");
3784 generate_exception(ctx, EXCP_RI);
6c5c1e20 3785 goto out;
6af0bf9c
FB
3786 }
3787 } else {
3788 switch (opc) {
3789 case OPC_BEQ:
e68dd28f 3790 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3791 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
d077b6f7 3792 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3793 goto not_likely;
3794 case OPC_BEQL:
e68dd28f 3795 tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
923617a3 3796 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
d077b6f7 3797 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3798 goto likely;
3799 case OPC_BNE:
e68dd28f 3800 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3801 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
d077b6f7 3802 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3803 goto not_likely;
3804 case OPC_BNEL:
e68dd28f 3805 tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
923617a3 3806 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
d077b6f7 3807 regnames[rs], regnames[rt], btgt);
6af0bf9c
FB
3808 goto likely;
3809 case OPC_BGEZ:
e68dd28f 3810 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3811 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3812 goto not_likely;
3813 case OPC_BGEZL:
e68dd28f 3814 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3815 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3816 goto likely;
3c824109 3817 case OPC_BGEZALS:
6af0bf9c 3818 case OPC_BGEZAL:
3c824109
NF
3819 ctx->hflags |= (opc == OPC_BGEZALS
3820 ? MIPS_HFLAG_BDS16
3821 : MIPS_HFLAG_BDS32);
e68dd28f 3822 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
d077b6f7 3823 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3824 blink = 31;
3825 goto not_likely;
3826 case OPC_BGEZALL:
e68dd28f 3827 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6af0bf9c 3828 blink = 31;
d077b6f7 3829 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3830 goto likely;
3831 case OPC_BGTZ:
e68dd28f 3832 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3833 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3834 goto not_likely;
3835 case OPC_BGTZL:
e68dd28f 3836 tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
d077b6f7 3837 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3838 goto likely;
3839 case OPC_BLEZ:
e68dd28f 3840 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3841 MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3842 goto not_likely;
3843 case OPC_BLEZL:
e68dd28f 3844 tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
d077b6f7 3845 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3846 goto likely;
3847 case OPC_BLTZ:
e68dd28f 3848 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3849 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c
FB
3850 goto not_likely;
3851 case OPC_BLTZL:
e68dd28f 3852 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
d077b6f7 3853 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3854 goto likely;
e45a93e2
JL
3855 case OPC_BPOSGE32:
3856 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3857 MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3858 goto not_likely;
3859#if defined(TARGET_MIPS64)
3860 case OPC_BPOSGE64:
3861 tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3862 MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3863 goto not_likely;
3864#endif
3c824109 3865 case OPC_BLTZALS:
6af0bf9c 3866 case OPC_BLTZAL:
3c824109
NF
3867 ctx->hflags |= (opc == OPC_BLTZALS
3868 ? MIPS_HFLAG_BDS16
3869 : MIPS_HFLAG_BDS32);
e68dd28f 3870 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3871 blink = 31;
d077b6f7 3872 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3873 not_likely:
4ad40f36 3874 ctx->hflags |= MIPS_HFLAG_BC;
6af0bf9c
FB
3875 break;
3876 case OPC_BLTZALL:
e68dd28f 3877 tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6af0bf9c 3878 blink = 31;
d077b6f7 3879 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
6af0bf9c 3880 likely:
4ad40f36 3881 ctx->hflags |= MIPS_HFLAG_BL;
6af0bf9c 3882 break;
c53f4a62
TS
3883 default:
3884 MIPS_INVAL("conditional branch/jump");
3885 generate_exception(ctx, EXCP_RI);
6c5c1e20 3886 goto out;
6af0bf9c 3887 }
6af0bf9c 3888 }
923617a3 3889 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
d077b6f7 3890 blink, ctx->hflags, btgt);
9b9e4393 3891
d077b6f7 3892 ctx->btarget = btgt;
6af0bf9c 3893 if (blink > 0) {
364d4831
NF
3894 int post_delay = insn_bytes;
3895 int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3896
3897 if (opc != OPC_JALRC)
3898 post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3899
3900 tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
6af0bf9c 3901 }
6c5c1e20
TS
3902
3903 out:
364d4831
NF
3904 if (insn_bytes == 2)
3905 ctx->hflags |= MIPS_HFLAG_B16;
6c5c1e20
TS
3906 tcg_temp_free(t0);
3907 tcg_temp_free(t1);
6af0bf9c
FB
3908}
3909
7a387fff
TS
3910/* special3 bitfield operations */
3911static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
356265ae 3912 int rs, int lsb, int msb)
7a387fff 3913{
a7812ae4
PB
3914 TCGv t0 = tcg_temp_new();
3915 TCGv t1 = tcg_temp_new();
505ad7c2 3916 target_ulong mask;
6c5c1e20
TS
3917
3918 gen_load_gpr(t1, rs);
7a387fff
TS
3919 switch (opc) {
3920 case OPC_EXT:
3921 if (lsb + msb > 31)
3922 goto fail;
505ad7c2
AJ
3923 tcg_gen_shri_tl(t0, t1, lsb);
3924 if (msb != 31) {
3925 tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3926 } else {
3927 tcg_gen_ext32s_tl(t0, t0);
3928 }
7a387fff 3929 break;
c6d6dd7c 3930#if defined(TARGET_MIPS64)
7a387fff 3931 case OPC_DEXTM:
505ad7c2
AJ
3932 tcg_gen_shri_tl(t0, t1, lsb);
3933 if (msb != 31) {
3934 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3935 }
7a387fff
TS
3936 break;
3937 case OPC_DEXTU:
505ad7c2
AJ
3938 tcg_gen_shri_tl(t0, t1, lsb + 32);
3939 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff
TS
3940 break;
3941 case OPC_DEXT:
505ad7c2
AJ
3942 tcg_gen_shri_tl(t0, t1, lsb);
3943 tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
7a387fff 3944 break;
c6d6dd7c 3945#endif
7a387fff
TS
3946 case OPC_INS:
3947 if (lsb > msb)
3948 goto fail;
505ad7c2 3949 mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
6c5c1e20 3950 gen_load_gpr(t0, rt);
505ad7c2
AJ
3951 tcg_gen_andi_tl(t0, t0, ~mask);
3952 tcg_gen_shli_tl(t1, t1, lsb);
3953 tcg_gen_andi_tl(t1, t1, mask);
3954 tcg_gen_or_tl(t0, t0, t1);
3955 tcg_gen_ext32s_tl(t0, t0);
7a387fff 3956 break;
c6d6dd7c 3957#if defined(TARGET_MIPS64)
7a387fff
TS
3958 case OPC_DINSM:
3959 if (lsb > msb)
3960 goto fail;
505ad7c2 3961 mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
6c5c1e20 3962 gen_load_gpr(t0, rt);
505ad7c2
AJ
3963 tcg_gen_andi_tl(t0, t0, ~mask);
3964 tcg_gen_shli_tl(t1, t1, lsb);
3965 tcg_gen_andi_tl(t1, t1, mask);
3966 tcg_gen_or_tl(t0, t0, t1);
7a387fff
TS
3967 break;
3968 case OPC_DINSU:
3969 if (lsb > msb)
3970 goto fail;
6fbab869 3971 mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
6c5c1e20 3972 gen_load_gpr(t0, rt);
505ad7c2
AJ
3973 tcg_gen_andi_tl(t0, t0, ~mask);
3974 tcg_gen_shli_tl(t1, t1, lsb + 32);
3975 tcg_gen_andi_tl(t1, t1, mask);
3976 tcg_gen_or_tl(t0, t0, t1);
7a387fff
TS
3977 break;
3978 case OPC_DINS:
3979 if (lsb > msb)
3980 goto fail;
6c5c1e20 3981 gen_load_gpr(t0, rt);
505ad7c2
AJ
3982 mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
3983 gen_load_gpr(t0, rt);
3984 tcg_gen_andi_tl(t0, t0, ~mask);
3985 tcg_gen_shli_tl(t1, t1, lsb);
3986 tcg_gen_andi_tl(t1, t1, mask);
3987 tcg_gen_or_tl(t0, t0, t1);
7a387fff 3988 break;
c6d6dd7c 3989#endif
7a387fff
TS
3990 default:
3991fail:
3992 MIPS_INVAL("bitops");
3993 generate_exception(ctx, EXCP_RI);
6c5c1e20
TS
3994 tcg_temp_free(t0);
3995 tcg_temp_free(t1);
7a387fff
TS
3996 return;
3997 }
6c5c1e20
TS
3998 gen_store_gpr(t0, rt);
3999 tcg_temp_free(t0);
4000 tcg_temp_free(t1);
7a387fff
TS
4001}
4002
49bcf33c
AJ
4003static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
4004{
3a55fa47 4005 TCGv t0;
49bcf33c 4006
3a55fa47
AJ
4007 if (rd == 0) {
4008 /* If no destination, treat it as a NOP. */
4009 MIPS_DEBUG("NOP");
4010 return;
4011 }
4012
4013 t0 = tcg_temp_new();
4014 gen_load_gpr(t0, rt);
49bcf33c
AJ
4015 switch (op2) {
4016 case OPC_WSBH:
3a55fa47
AJ
4017 {
4018 TCGv t1 = tcg_temp_new();
4019
4020 tcg_gen_shri_tl(t1, t0, 8);
4021 tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
4022 tcg_gen_shli_tl(t0, t0, 8);
4023 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
4024 tcg_gen_or_tl(t0, t0, t1);
4025 tcg_temp_free(t1);
4026 tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4027 }
49bcf33c
AJ
4028 break;
4029 case OPC_SEB:
3a55fa47 4030 tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4031 break;
4032 case OPC_SEH:
3a55fa47 4033 tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
49bcf33c
AJ
4034 break;
4035#if defined(TARGET_MIPS64)
4036 case OPC_DSBH:
3a55fa47
AJ
4037 {
4038 TCGv t1 = tcg_temp_new();
4039
4040 tcg_gen_shri_tl(t1, t0, 8);
4041 tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4042 tcg_gen_shli_tl(t0, t0, 8);
4043 tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4044 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4045 tcg_temp_free(t1);
4046 }
49bcf33c
AJ
4047 break;
4048 case OPC_DSHD:
3a55fa47
AJ
4049 {
4050 TCGv t1 = tcg_temp_new();
4051
4052 tcg_gen_shri_tl(t1, t0, 16);
4053 tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4054 tcg_gen_shli_tl(t0, t0, 16);
4055 tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4056 tcg_gen_or_tl(t0, t0, t1);
4057 tcg_gen_shri_tl(t1, t0, 32);
4058 tcg_gen_shli_tl(t0, t0, 32);
4059 tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4060 tcg_temp_free(t1);
4061 }
49bcf33c
AJ
4062 break;
4063#endif
4064 default:
4065 MIPS_INVAL("bsfhl");
4066 generate_exception(ctx, EXCP_RI);
4067 tcg_temp_free(t0);
49bcf33c
AJ
4068 return;
4069 }
49bcf33c 4070 tcg_temp_free(t0);
49bcf33c
AJ
4071}
4072
f1aa6320 4073#ifndef CONFIG_USER_ONLY
0eaef5aa 4074/* CP0 (MMU and control) */
d9bea114 4075static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4f57689a 4076{
d9bea114 4077 TCGv_i32 t0 = tcg_temp_new_i32();
4f57689a 4078
d9bea114
AJ
4079 tcg_gen_ld_i32(t0, cpu_env, off);
4080 tcg_gen_ext_i32_tl(arg, t0);
4081 tcg_temp_free_i32(t0);
4f57689a
TS
4082}
4083
d9bea114 4084static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4f57689a 4085{
d9bea114
AJ
4086 tcg_gen_ld_tl(arg, cpu_env, off);
4087 tcg_gen_ext32s_tl(arg, arg);
4f57689a
TS
4088}
4089
d9bea114 4090static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
f1aa6320 4091{
d9bea114 4092 TCGv_i32 t0 = tcg_temp_new_i32();
f1aa6320 4093
d9bea114
AJ
4094 tcg_gen_trunc_tl_i32(t0, arg);
4095 tcg_gen_st_i32(t0, cpu_env, off);
4096 tcg_temp_free_i32(t0);
f1aa6320
TS
4097}
4098
d9bea114 4099static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
f1aa6320 4100{
d9bea114
AJ
4101 tcg_gen_ext32s_tl(arg, arg);
4102 tcg_gen_st_tl(arg, cpu_env, off);
f1aa6320
TS
4103}
4104
7db13fae 4105static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
873eb012 4106{
7a387fff 4107 const char *rn = "invalid";
873eb012 4108
e189e748
TS
4109 if (sel != 0)
4110 check_insn(env, ctx, ISA_MIPS32);
4111
873eb012
TS
4112 switch (reg) {
4113 case 0:
7a387fff
TS
4114 switch (sel) {
4115 case 0:
7db13fae 4116 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7a387fff
TS
4117 rn = "Index";
4118 break;
4119 case 1:
7385ac0b 4120 check_insn(env, ctx, ASE_MT);
895c2d04 4121 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7a387fff 4122 rn = "MVPControl";
ead9360e 4123 break;
7a387fff 4124 case 2:
7385ac0b 4125 check_insn(env, ctx, ASE_MT);
895c2d04 4126 gen_helper_mfc0_mvpconf0(arg, cpu_env);
7a387fff 4127 rn = "MVPConf0";
ead9360e 4128 break;
7a387fff 4129 case 3:
7385ac0b 4130 check_insn(env, ctx, ASE_MT);
895c2d04 4131 gen_helper_mfc0_mvpconf1(arg, cpu_env);
7a387fff 4132 rn = "MVPConf1";
ead9360e 4133 break;
7a387fff
TS
4134 default:
4135 goto die;
4136 }
873eb012
TS
4137 break;
4138 case 1:
7a387fff
TS
4139 switch (sel) {
4140 case 0:
895c2d04 4141 gen_helper_mfc0_random(arg, cpu_env);
7a387fff 4142 rn = "Random";
2423f660 4143 break;
7a387fff 4144 case 1:
7385ac0b 4145 check_insn(env, ctx, ASE_MT);
7db13fae 4146 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7a387fff 4147 rn = "VPEControl";
ead9360e 4148 break;
7a387fff 4149 case 2:
7385ac0b 4150 check_insn(env, ctx, ASE_MT);
7db13fae 4151 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7a387fff 4152 rn = "VPEConf0";
ead9360e 4153 break;
7a387fff 4154 case 3:
7385ac0b 4155 check_insn(env, ctx, ASE_MT);
7db13fae 4156 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7a387fff 4157 rn = "VPEConf1";
ead9360e 4158 break;
7a387fff 4159 case 4:
7385ac0b 4160 check_insn(env, ctx, ASE_MT);
7db13fae 4161 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
7a387fff 4162 rn = "YQMask";
ead9360e 4163 break;
7a387fff 4164 case 5:
7385ac0b 4165 check_insn(env, ctx, ASE_MT);
7db13fae 4166 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4167 rn = "VPESchedule";
ead9360e 4168 break;
7a387fff 4169 case 6:
7385ac0b 4170 check_insn(env, ctx, ASE_MT);
7db13fae 4171 gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4172 rn = "VPEScheFBack";
ead9360e 4173 break;
7a387fff 4174 case 7:
7385ac0b 4175 check_insn(env, ctx, ASE_MT);
7db13fae 4176 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7a387fff 4177 rn = "VPEOpt";
ead9360e 4178 break;
7a387fff
TS
4179 default:
4180 goto die;
4181 }
873eb012
TS
4182 break;
4183 case 2:
7a387fff
TS
4184 switch (sel) {
4185 case 0:
7db13fae 4186 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
d9bea114 4187 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4188 rn = "EntryLo0";
4189 break;
7a387fff 4190 case 1:
7385ac0b 4191 check_insn(env, ctx, ASE_MT);
895c2d04 4192 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 4193 rn = "TCStatus";
ead9360e 4194 break;
7a387fff 4195 case 2:
7385ac0b 4196 check_insn(env, ctx, ASE_MT);
895c2d04 4197 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 4198 rn = "TCBind";
ead9360e 4199 break;
7a387fff 4200 case 3:
7385ac0b 4201 check_insn(env, ctx, ASE_MT);
895c2d04 4202 gen_helper_mfc0_tcrestart(arg, cpu_env);
2423f660 4203 rn = "TCRestart";
ead9360e 4204 break;
7a387fff 4205 case 4:
7385ac0b 4206 check_insn(env, ctx, ASE_MT);
895c2d04 4207 gen_helper_mfc0_tchalt(arg, cpu_env);
2423f660 4208 rn = "TCHalt";
ead9360e 4209 break;
7a387fff 4210 case 5:
7385ac0b 4211 check_insn(env, ctx, ASE_MT);
895c2d04 4212 gen_helper_mfc0_tccontext(arg, cpu_env);
2423f660 4213 rn = "TCContext";
ead9360e 4214 break;
7a387fff 4215 case 6:
7385ac0b 4216 check_insn(env, ctx, ASE_MT);
895c2d04 4217 gen_helper_mfc0_tcschedule(arg, cpu_env);
2423f660 4218 rn = "TCSchedule";
ead9360e 4219 break;
7a387fff 4220 case 7:
7385ac0b 4221 check_insn(env, ctx, ASE_MT);
895c2d04 4222 gen_helper_mfc0_tcschefback(arg, cpu_env);
2423f660 4223 rn = "TCScheFBack";
ead9360e 4224 break;
7a387fff
TS
4225 default:
4226 goto die;
4227 }
873eb012
TS
4228 break;
4229 case 3:
7a387fff
TS
4230 switch (sel) {
4231 case 0:
7db13fae 4232 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
d9bea114 4233 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4234 rn = "EntryLo1";
4235 break;
7a387fff
TS
4236 default:
4237 goto die;
1579a72e 4238 }
873eb012
TS
4239 break;
4240 case 4:
7a387fff
TS
4241 switch (sel) {
4242 case 0:
7db13fae 4243 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
d9bea114 4244 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4245 rn = "Context";
4246 break;
7a387fff 4247 case 1:
d9bea114 4248// gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
4249 rn = "ContextConfig";
4250// break;
7a387fff
TS
4251 default:
4252 goto die;
1579a72e 4253 }
873eb012
TS
4254 break;
4255 case 5:
7a387fff
TS
4256 switch (sel) {
4257 case 0:
7db13fae 4258 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
4259 rn = "PageMask";
4260 break;
7a387fff 4261 case 1:
e189e748 4262 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4263 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
4264 rn = "PageGrain";
4265 break;
7a387fff
TS
4266 default:
4267 goto die;
1579a72e 4268 }
873eb012
TS
4269 break;
4270 case 6:
7a387fff
TS
4271 switch (sel) {
4272 case 0:
7db13fae 4273 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
4274 rn = "Wired";
4275 break;
7a387fff 4276 case 1:
e189e748 4277 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4278 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 4279 rn = "SRSConf0";
ead9360e 4280 break;
7a387fff 4281 case 2:
e189e748 4282 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4283 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 4284 rn = "SRSConf1";
ead9360e 4285 break;
7a387fff 4286 case 3:
e189e748 4287 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4288 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 4289 rn = "SRSConf2";
ead9360e 4290 break;
7a387fff 4291 case 4:
e189e748 4292 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 4294 rn = "SRSConf3";
ead9360e 4295 break;
7a387fff 4296 case 5:
e189e748 4297 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4298 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 4299 rn = "SRSConf4";
ead9360e 4300 break;
7a387fff
TS
4301 default:
4302 goto die;
1579a72e 4303 }
873eb012 4304 break;
8c0fdd85 4305 case 7:
7a387fff
TS
4306 switch (sel) {
4307 case 0:
e189e748 4308 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4309 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
4310 rn = "HWREna";
4311 break;
7a387fff
TS
4312 default:
4313 goto die;
1579a72e 4314 }
8c0fdd85 4315 break;
873eb012 4316 case 8:
7a387fff
TS
4317 switch (sel) {
4318 case 0:
7db13fae 4319 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
d9bea114 4320 tcg_gen_ext32s_tl(arg, arg);
f0b3f3ae 4321 rn = "BadVAddr";
2423f660 4322 break;
7a387fff
TS
4323 default:
4324 goto die;
4325 }
873eb012
TS
4326 break;
4327 case 9:
7a387fff
TS
4328 switch (sel) {
4329 case 0:
2e70f6ef
PB
4330 /* Mark as an IO operation because we read the time. */
4331 if (use_icount)
4332 gen_io_start();
895c2d04 4333 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
4334 if (use_icount) {
4335 gen_io_end();
2e70f6ef 4336 }
55807224
EI
4337 /* Break the TB to be able to take timer interrupts immediately
4338 after reading count. */
4339 ctx->bstate = BS_STOP;
2423f660
TS
4340 rn = "Count";
4341 break;
4342 /* 6,7 are implementation dependent */
7a387fff
TS
4343 default:
4344 goto die;
2423f660 4345 }
873eb012
TS
4346 break;
4347 case 10:
7a387fff
TS
4348 switch (sel) {
4349 case 0:
7db13fae 4350 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
d9bea114 4351 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4352 rn = "EntryHi";
4353 break;
7a387fff
TS
4354 default:
4355 goto die;
1579a72e 4356 }
873eb012
TS
4357 break;
4358 case 11:
7a387fff
TS
4359 switch (sel) {
4360 case 0:
7db13fae 4361 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
4362 rn = "Compare";
4363 break;
4364 /* 6,7 are implementation dependent */
7a387fff
TS
4365 default:
4366 goto die;
2423f660 4367 }
873eb012
TS
4368 break;
4369 case 12:
7a387fff
TS
4370 switch (sel) {
4371 case 0:
7db13fae 4372 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
4373 rn = "Status";
4374 break;
7a387fff 4375 case 1:
e189e748 4376 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4377 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
4378 rn = "IntCtl";
4379 break;
7a387fff 4380 case 2:
e189e748 4381 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4382 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
4383 rn = "SRSCtl";
4384 break;
7a387fff 4385 case 3:
e189e748 4386 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4387 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660 4388 rn = "SRSMap";
fd88b6ab 4389 break;
7a387fff
TS
4390 default:
4391 goto die;
4392 }
873eb012
TS
4393 break;
4394 case 13:
7a387fff
TS
4395 switch (sel) {
4396 case 0:
7db13fae 4397 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
4398 rn = "Cause";
4399 break;
7a387fff
TS
4400 default:
4401 goto die;
4402 }
873eb012
TS
4403 break;
4404 case 14:
7a387fff
TS
4405 switch (sel) {
4406 case 0:
7db13fae 4407 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
d9bea114 4408 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4409 rn = "EPC";
4410 break;
7a387fff
TS
4411 default:
4412 goto die;
1579a72e 4413 }
873eb012
TS
4414 break;
4415 case 15:
7a387fff
TS
4416 switch (sel) {
4417 case 0:
7db13fae 4418 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
4419 rn = "PRid";
4420 break;
7a387fff 4421 case 1:
e189e748 4422 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4423 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
4424 rn = "EBase";
4425 break;
7a387fff
TS
4426 default:
4427 goto die;
4428 }
873eb012
TS
4429 break;
4430 case 16:
4431 switch (sel) {
4432 case 0:
7db13fae 4433 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
873eb012
TS
4434 rn = "Config";
4435 break;
4436 case 1:
7db13fae 4437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
873eb012
TS
4438 rn = "Config1";
4439 break;
7a387fff 4440 case 2:
7db13fae 4441 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7a387fff
TS
4442 rn = "Config2";
4443 break;
4444 case 3:
7db13fae 4445 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7a387fff
TS
4446 rn = "Config3";
4447 break;
e397ee33
TS
4448 /* 4,5 are reserved */
4449 /* 6,7 are implementation dependent */
4450 case 6:
7db13fae 4451 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
e397ee33
TS
4452 rn = "Config6";
4453 break;
4454 case 7:
7db13fae 4455 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
e397ee33
TS
4456 rn = "Config7";
4457 break;
873eb012 4458 default:
873eb012
TS
4459 goto die;
4460 }
4461 break;
4462 case 17:
7a387fff
TS
4463 switch (sel) {
4464 case 0:
895c2d04 4465 gen_helper_mfc0_lladdr(arg, cpu_env);
2423f660
TS
4466 rn = "LLAddr";
4467 break;
7a387fff
TS
4468 default:
4469 goto die;
4470 }
873eb012
TS
4471 break;
4472 case 18:
7a387fff 4473 switch (sel) {
fd88b6ab 4474 case 0 ... 7:
895c2d04 4475 gen_helper_1e0i(mfc0_watchlo, arg, sel);
2423f660
TS
4476 rn = "WatchLo";
4477 break;
7a387fff
TS
4478 default:
4479 goto die;
4480 }
873eb012
TS
4481 break;
4482 case 19:
7a387fff 4483 switch (sel) {
fd88b6ab 4484 case 0 ...7:
895c2d04 4485 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
4486 rn = "WatchHi";
4487 break;
7a387fff
TS
4488 default:
4489 goto die;
4490 }
873eb012 4491 break;
8c0fdd85 4492 case 20:
7a387fff
TS
4493 switch (sel) {
4494 case 0:
d26bc211 4495#if defined(TARGET_MIPS64)
e189e748 4496 check_insn(env, ctx, ISA_MIPS3);
7db13fae 4497 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
d9bea114 4498 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4499 rn = "XContext";
4500 break;
703eaf37 4501#endif
7a387fff
TS
4502 default:
4503 goto die;
4504 }
8c0fdd85
TS
4505 break;
4506 case 21:
7a387fff
TS
4507 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4508 switch (sel) {
4509 case 0:
7db13fae 4510 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
4511 rn = "Framemask";
4512 break;
7a387fff
TS
4513 default:
4514 goto die;
4515 }
8c0fdd85
TS
4516 break;
4517 case 22:
d9bea114 4518 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4519 rn = "'Diagnostic"; /* implementation dependent */
4520 break;
873eb012 4521 case 23:
7a387fff
TS
4522 switch (sel) {
4523 case 0:
895c2d04 4524 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
4525 rn = "Debug";
4526 break;
7a387fff 4527 case 1:
d9bea114 4528// gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
2423f660
TS
4529 rn = "TraceControl";
4530// break;
7a387fff 4531 case 2:
d9bea114 4532// gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
2423f660
TS
4533 rn = "TraceControl2";
4534// break;
7a387fff 4535 case 3:
d9bea114 4536// gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
2423f660
TS
4537 rn = "UserTraceData";
4538// break;
7a387fff 4539 case 4:
d9bea114 4540// gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
2423f660
TS
4541 rn = "TraceBPC";
4542// break;
7a387fff
TS
4543 default:
4544 goto die;
4545 }
873eb012
TS
4546 break;
4547 case 24:
7a387fff
TS
4548 switch (sel) {
4549 case 0:
f0b3f3ae 4550 /* EJTAG support */
7db13fae 4551 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
d9bea114 4552 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4553 rn = "DEPC";
4554 break;
7a387fff
TS
4555 default:
4556 goto die;
4557 }
873eb012 4558 break;
8c0fdd85 4559 case 25:
7a387fff
TS
4560 switch (sel) {
4561 case 0:
7db13fae 4562 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 4563 rn = "Performance0";
7a387fff
TS
4564 break;
4565 case 1:
d9bea114 4566// gen_helper_mfc0_performance1(arg);
2423f660
TS
4567 rn = "Performance1";
4568// break;
7a387fff 4569 case 2:
d9bea114 4570// gen_helper_mfc0_performance2(arg);
2423f660
TS
4571 rn = "Performance2";
4572// break;
7a387fff 4573 case 3:
d9bea114 4574// gen_helper_mfc0_performance3(arg);
2423f660
TS
4575 rn = "Performance3";
4576// break;
7a387fff 4577 case 4:
d9bea114 4578// gen_helper_mfc0_performance4(arg);
2423f660
TS
4579 rn = "Performance4";
4580// break;
7a387fff 4581 case 5:
d9bea114 4582// gen_helper_mfc0_performance5(arg);
2423f660
TS
4583 rn = "Performance5";
4584// break;
7a387fff 4585 case 6:
d9bea114 4586// gen_helper_mfc0_performance6(arg);
2423f660
TS
4587 rn = "Performance6";
4588// break;
7a387fff 4589 case 7:
d9bea114 4590// gen_helper_mfc0_performance7(arg);
2423f660
TS
4591 rn = "Performance7";
4592// break;
7a387fff
TS
4593 default:
4594 goto die;
4595 }
8c0fdd85
TS
4596 break;
4597 case 26:
d9bea114 4598 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
4599 rn = "ECC";
4600 break;
8c0fdd85 4601 case 27:
7a387fff 4602 switch (sel) {
7a387fff 4603 case 0 ... 3:
d9bea114 4604 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
4605 rn = "CacheErr";
4606 break;
7a387fff
TS
4607 default:
4608 goto die;
4609 }
8c0fdd85 4610 break;
873eb012
TS
4611 case 28:
4612 switch (sel) {
4613 case 0:
7a387fff
TS
4614 case 2:
4615 case 4:
4616 case 6:
7db13fae 4617 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
873eb012
TS
4618 rn = "TagLo";
4619 break;
4620 case 1:
7a387fff
TS
4621 case 3:
4622 case 5:
4623 case 7:
7db13fae 4624 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
873eb012
TS
4625 rn = "DataLo";
4626 break;
4627 default:
873eb012
TS
4628 goto die;
4629 }
4630 break;
8c0fdd85 4631 case 29:
7a387fff
TS
4632 switch (sel) {
4633 case 0:
4634 case 2:
4635 case 4:
4636 case 6:
7db13fae 4637 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7a387fff
TS
4638 rn = "TagHi";
4639 break;
4640 case 1:
4641 case 3:
4642 case 5:
4643 case 7:
7db13fae 4644 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7a387fff
TS
4645 rn = "DataHi";
4646 break;
4647 default:
4648 goto die;
4649 }
8c0fdd85 4650 break;
873eb012 4651 case 30:
7a387fff
TS
4652 switch (sel) {
4653 case 0:
7db13fae 4654 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
d9bea114 4655 tcg_gen_ext32s_tl(arg, arg);
2423f660
TS
4656 rn = "ErrorEPC";
4657 break;
7a387fff
TS
4658 default:
4659 goto die;
4660 }
873eb012
TS
4661 break;
4662 case 31:
7a387fff
TS
4663 switch (sel) {
4664 case 0:
f0b3f3ae 4665 /* EJTAG support */
7db13fae 4666 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
4667 rn = "DESAVE";
4668 break;
7a387fff
TS
4669 default:
4670 goto die;
4671 }
873eb012
TS
4672 break;
4673 default:
873eb012
TS
4674 goto die;
4675 }
2abf314d 4676 (void)rn; /* avoid a compiler warning */
d12d51d5 4677 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4678 return;
4679
4680die:
d12d51d5 4681 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
873eb012
TS
4682 generate_exception(ctx, EXCP_RI);
4683}
4684
7db13fae 4685static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
8c0fdd85 4686{
7a387fff
TS
4687 const char *rn = "invalid";
4688
e189e748
TS
4689 if (sel != 0)
4690 check_insn(env, ctx, ISA_MIPS32);
4691
2e70f6ef
PB
4692 if (use_icount)
4693 gen_io_start();
4694
8c0fdd85
TS
4695 switch (reg) {
4696 case 0:
7a387fff
TS
4697 switch (sel) {
4698 case 0:
895c2d04 4699 gen_helper_mtc0_index(cpu_env, arg);
7a387fff
TS
4700 rn = "Index";
4701 break;
4702 case 1:
7385ac0b 4703 check_insn(env, ctx, ASE_MT);
895c2d04 4704 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7a387fff 4705 rn = "MVPControl";
ead9360e 4706 break;
7a387fff 4707 case 2:
7385ac0b 4708 check_insn(env, ctx, ASE_MT);
ead9360e 4709 /* ignored */
7a387fff 4710 rn = "MVPConf0";
ead9360e 4711 break;
7a387fff 4712 case 3:
7385ac0b 4713 check_insn(env, ctx, ASE_MT);
ead9360e 4714 /* ignored */
7a387fff 4715 rn = "MVPConf1";
ead9360e 4716 break;
7a387fff
TS
4717 default:
4718 goto die;
4719 }
8c0fdd85
TS
4720 break;
4721 case 1:
7a387fff
TS
4722 switch (sel) {
4723 case 0:
2423f660 4724 /* ignored */
7a387fff 4725 rn = "Random";
2423f660 4726 break;
7a387fff 4727 case 1:
7385ac0b 4728 check_insn(env, ctx, ASE_MT);
895c2d04 4729 gen_helper_mtc0_vpecontrol(cpu_env, arg);
7a387fff 4730 rn = "VPEControl";
ead9360e 4731 break;
7a387fff 4732 case 2:
7385ac0b 4733 check_insn(env, ctx, ASE_MT);
895c2d04 4734 gen_helper_mtc0_vpeconf0(cpu_env, arg);
7a387fff 4735 rn = "VPEConf0";
ead9360e 4736 break;
7a387fff 4737 case 3:
7385ac0b 4738 check_insn(env, ctx, ASE_MT);
895c2d04 4739 gen_helper_mtc0_vpeconf1(cpu_env, arg);
7a387fff 4740 rn = "VPEConf1";
ead9360e 4741 break;
7a387fff 4742 case 4:
7385ac0b 4743 check_insn(env, ctx, ASE_MT);
895c2d04 4744 gen_helper_mtc0_yqmask(cpu_env, arg);
7a387fff 4745 rn = "YQMask";
ead9360e 4746 break;
7a387fff 4747 case 5:
7385ac0b 4748 check_insn(env, ctx, ASE_MT);
7db13fae 4749 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
7a387fff 4750 rn = "VPESchedule";
ead9360e 4751 break;
7a387fff 4752 case 6:
7385ac0b 4753 check_insn(env, ctx, ASE_MT);
7db13fae 4754 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7a387fff 4755 rn = "VPEScheFBack";
ead9360e 4756 break;
7a387fff 4757 case 7:
7385ac0b 4758 check_insn(env, ctx, ASE_MT);
895c2d04 4759 gen_helper_mtc0_vpeopt(cpu_env, arg);
7a387fff 4760 rn = "VPEOpt";
ead9360e 4761 break;
7a387fff
TS
4762 default:
4763 goto die;
4764 }
8c0fdd85
TS
4765 break;
4766 case 2:
7a387fff
TS
4767 switch (sel) {
4768 case 0:
895c2d04 4769 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
4770 rn = "EntryLo0";
4771 break;
7a387fff 4772 case 1:
7385ac0b 4773 check_insn(env, ctx, ASE_MT);
895c2d04 4774 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 4775 rn = "TCStatus";
ead9360e 4776 break;
7a387fff 4777 case 2:
7385ac0b 4778 check_insn(env, ctx, ASE_MT);
895c2d04 4779 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 4780 rn = "TCBind";
ead9360e 4781 break;
7a387fff 4782 case 3:
7385ac0b 4783 check_insn(env, ctx, ASE_MT);
895c2d04 4784 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 4785 rn = "TCRestart";
ead9360e 4786 break;
7a387fff 4787 case 4:
7385ac0b 4788 check_insn(env, ctx, ASE_MT);
895c2d04 4789 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 4790 rn = "TCHalt";
ead9360e 4791 break;
7a387fff 4792 case 5:
7385ac0b 4793 check_insn(env, ctx, ASE_MT);
895c2d04 4794 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 4795 rn = "TCContext";
ead9360e 4796 break;
7a387fff 4797 case 6:
7385ac0b 4798 check_insn(env, ctx, ASE_MT);
895c2d04 4799 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 4800 rn = "TCSchedule";
ead9360e 4801 break;
7a387fff 4802 case 7:
7385ac0b 4803 check_insn(env, ctx, ASE_MT);
895c2d04 4804 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 4805 rn = "TCScheFBack";
ead9360e 4806 break;
7a387fff
TS
4807 default:
4808 goto die;
4809 }
8c0fdd85
TS
4810 break;
4811 case 3:
7a387fff
TS
4812 switch (sel) {
4813 case 0:
895c2d04 4814 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
4815 rn = "EntryLo1";
4816 break;
7a387fff
TS
4817 default:
4818 goto die;
876d4b07 4819 }
8c0fdd85
TS
4820 break;
4821 case 4:
7a387fff
TS
4822 switch (sel) {
4823 case 0:
895c2d04 4824 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
4825 rn = "Context";
4826 break;
7a387fff 4827 case 1:
895c2d04 4828// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
4829 rn = "ContextConfig";
4830// break;
7a387fff
TS
4831 default:
4832 goto die;
876d4b07 4833 }
8c0fdd85
TS
4834 break;
4835 case 5:
7a387fff
TS
4836 switch (sel) {
4837 case 0:
895c2d04 4838 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
4839 rn = "PageMask";
4840 break;
7a387fff 4841 case 1:
e189e748 4842 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4843 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
4844 rn = "PageGrain";
4845 break;
7a387fff
TS
4846 default:
4847 goto die;
876d4b07 4848 }
8c0fdd85
TS
4849 break;
4850 case 6:
7a387fff
TS
4851 switch (sel) {
4852 case 0:
895c2d04 4853 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
4854 rn = "Wired";
4855 break;
7a387fff 4856 case 1:
e189e748 4857 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4858 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 4859 rn = "SRSConf0";
ead9360e 4860 break;
7a387fff 4861 case 2:
e189e748 4862 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4863 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 4864 rn = "SRSConf1";
ead9360e 4865 break;
7a387fff 4866 case 3:
e189e748 4867 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4868 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 4869 rn = "SRSConf2";
ead9360e 4870 break;
7a387fff 4871 case 4:
e189e748 4872 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4873 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 4874 rn = "SRSConf3";
ead9360e 4875 break;
7a387fff 4876 case 5:
e189e748 4877 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4878 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 4879 rn = "SRSConf4";
ead9360e 4880 break;
7a387fff
TS
4881 default:
4882 goto die;
876d4b07 4883 }
8c0fdd85
TS
4884 break;
4885 case 7:
7a387fff
TS
4886 switch (sel) {
4887 case 0:
e189e748 4888 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4889 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
4890 rn = "HWREna";
4891 break;
7a387fff
TS
4892 default:
4893 goto die;
876d4b07 4894 }
8c0fdd85
TS
4895 break;
4896 case 8:
7a387fff 4897 /* ignored */
f0b3f3ae 4898 rn = "BadVAddr";
8c0fdd85
TS
4899 break;
4900 case 9:
7a387fff
TS
4901 switch (sel) {
4902 case 0:
895c2d04 4903 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
4904 rn = "Count";
4905 break;
876d4b07 4906 /* 6,7 are implementation dependent */
7a387fff
TS
4907 default:
4908 goto die;
876d4b07 4909 }
8c0fdd85
TS
4910 break;
4911 case 10:
7a387fff
TS
4912 switch (sel) {
4913 case 0:
895c2d04 4914 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
4915 rn = "EntryHi";
4916 break;
7a387fff
TS
4917 default:
4918 goto die;
876d4b07 4919 }
8c0fdd85
TS
4920 break;
4921 case 11:
7a387fff
TS
4922 switch (sel) {
4923 case 0:
895c2d04 4924 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
4925 rn = "Compare";
4926 break;
4927 /* 6,7 are implementation dependent */
7a387fff
TS
4928 default:
4929 goto die;
876d4b07 4930 }
8c0fdd85
TS
4931 break;
4932 case 12:
7a387fff
TS
4933 switch (sel) {
4934 case 0:
867abc7e 4935 save_cpu_state(ctx, 1);
895c2d04 4936 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
4937 /* BS_STOP isn't good enough here, hflags may have changed. */
4938 gen_save_pc(ctx->pc + 4);
4939 ctx->bstate = BS_EXCP;
2423f660
TS
4940 rn = "Status";
4941 break;
7a387fff 4942 case 1:
e189e748 4943 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4944 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
4945 /* Stop translation as we may have switched the execution mode */
4946 ctx->bstate = BS_STOP;
2423f660
TS
4947 rn = "IntCtl";
4948 break;
7a387fff 4949 case 2:
e189e748 4950 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4951 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
4952 /* Stop translation as we may have switched the execution mode */
4953 ctx->bstate = BS_STOP;
2423f660
TS
4954 rn = "SRSCtl";
4955 break;
7a387fff 4956 case 3:
e189e748 4957 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 4958 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
4959 /* Stop translation as we may have switched the execution mode */
4960 ctx->bstate = BS_STOP;
2423f660 4961 rn = "SRSMap";
fd88b6ab 4962 break;
7a387fff
TS
4963 default:
4964 goto die;
876d4b07 4965 }
8c0fdd85
TS
4966 break;
4967 case 13:
7a387fff
TS
4968 switch (sel) {
4969 case 0:
867abc7e 4970 save_cpu_state(ctx, 1);
895c2d04 4971 gen_helper_mtc0_cause(cpu_env, arg);
2423f660
TS
4972 rn = "Cause";
4973 break;
7a387fff
TS
4974 default:
4975 goto die;
876d4b07 4976 }
8c0fdd85
TS
4977 break;
4978 case 14:
7a387fff
TS
4979 switch (sel) {
4980 case 0:
7db13fae 4981 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
4982 rn = "EPC";
4983 break;
7a387fff
TS
4984 default:
4985 goto die;
876d4b07 4986 }
8c0fdd85
TS
4987 break;
4988 case 15:
7a387fff
TS
4989 switch (sel) {
4990 case 0:
2423f660
TS
4991 /* ignored */
4992 rn = "PRid";
4993 break;
7a387fff 4994 case 1:
e189e748 4995 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 4996 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
4997 rn = "EBase";
4998 break;
7a387fff
TS
4999 default:
5000 goto die;
1579a72e 5001 }
8c0fdd85
TS
5002 break;
5003 case 16:
5004 switch (sel) {
5005 case 0:
895c2d04 5006 gen_helper_mtc0_config0(cpu_env, arg);
7a387fff 5007 rn = "Config";
2423f660
TS
5008 /* Stop translation as we may have switched the execution mode */
5009 ctx->bstate = BS_STOP;
7a387fff
TS
5010 break;
5011 case 1:
e397ee33 5012 /* ignored, read only */
7a387fff
TS
5013 rn = "Config1";
5014 break;
5015 case 2:
895c2d04 5016 gen_helper_mtc0_config2(cpu_env, arg);
7a387fff 5017 rn = "Config2";
2423f660
TS
5018 /* Stop translation as we may have switched the execution mode */
5019 ctx->bstate = BS_STOP;
8c0fdd85 5020 break;
7a387fff 5021 case 3:
e397ee33 5022 /* ignored, read only */
7a387fff
TS
5023 rn = "Config3";
5024 break;
e397ee33
TS
5025 /* 4,5 are reserved */
5026 /* 6,7 are implementation dependent */
5027 case 6:
5028 /* ignored */
5029 rn = "Config6";
5030 break;
5031 case 7:
5032 /* ignored */
5033 rn = "Config7";
5034 break;
8c0fdd85
TS
5035 default:
5036 rn = "Invalid config selector";
5037 goto die;
5038 }
5039 break;
5040 case 17:
7a387fff
TS
5041 switch (sel) {
5042 case 0:
895c2d04 5043 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
5044 rn = "LLAddr";
5045 break;
7a387fff
TS
5046 default:
5047 goto die;
5048 }
8c0fdd85
TS
5049 break;
5050 case 18:
7a387fff 5051 switch (sel) {
fd88b6ab 5052 case 0 ... 7:
895c2d04 5053 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
5054 rn = "WatchLo";
5055 break;
7a387fff
TS
5056 default:
5057 goto die;
5058 }
8c0fdd85
TS
5059 break;
5060 case 19:
7a387fff 5061 switch (sel) {
fd88b6ab 5062 case 0 ... 7:
895c2d04 5063 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
5064 rn = "WatchHi";
5065 break;
7a387fff
TS
5066 default:
5067 goto die;
5068 }
8c0fdd85
TS
5069 break;
5070 case 20:
7a387fff
TS
5071 switch (sel) {
5072 case 0:
d26bc211 5073#if defined(TARGET_MIPS64)
e189e748 5074 check_insn(env, ctx, ISA_MIPS3);
895c2d04 5075 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
5076 rn = "XContext";
5077 break;
703eaf37 5078#endif
7a387fff
TS
5079 default:
5080 goto die;
5081 }
8c0fdd85
TS
5082 break;
5083 case 21:
7a387fff
TS
5084 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5085 switch (sel) {
5086 case 0:
895c2d04 5087 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
5088 rn = "Framemask";
5089 break;
7a387fff
TS
5090 default:
5091 goto die;
5092 }
5093 break;
8c0fdd85 5094 case 22:
7a387fff
TS
5095 /* ignored */
5096 rn = "Diagnostic"; /* implementation dependent */
2423f660 5097 break;
8c0fdd85 5098 case 23:
7a387fff
TS
5099 switch (sel) {
5100 case 0:
895c2d04 5101 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
5102 /* BS_STOP isn't good enough here, hflags may have changed. */
5103 gen_save_pc(ctx->pc + 4);
5104 ctx->bstate = BS_EXCP;
2423f660
TS
5105 rn = "Debug";
5106 break;
7a387fff 5107 case 1:
895c2d04 5108// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
2423f660 5109 rn = "TraceControl";
8487327a
TS
5110 /* Stop translation as we may have switched the execution mode */
5111 ctx->bstate = BS_STOP;
2423f660 5112// break;
7a387fff 5113 case 2:
895c2d04 5114// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
2423f660 5115 rn = "TraceControl2";
8487327a
TS
5116 /* Stop translation as we may have switched the execution mode */
5117 ctx->bstate = BS_STOP;
2423f660 5118// break;
7a387fff 5119 case 3:
8487327a
TS
5120 /* Stop translation as we may have switched the execution mode */
5121 ctx->bstate = BS_STOP;
895c2d04 5122// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
2423f660 5123 rn = "UserTraceData";
8487327a
TS
5124 /* Stop translation as we may have switched the execution mode */
5125 ctx->bstate = BS_STOP;
2423f660 5126// break;
7a387fff 5127 case 4:
895c2d04 5128// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
5129 /* Stop translation as we may have switched the execution mode */
5130 ctx->bstate = BS_STOP;
2423f660
TS
5131 rn = "TraceBPC";
5132// break;
7a387fff
TS
5133 default:
5134 goto die;
5135 }
8c0fdd85
TS
5136 break;
5137 case 24:
7a387fff
TS
5138 switch (sel) {
5139 case 0:
f1aa6320 5140 /* EJTAG support */
7db13fae 5141 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5142 rn = "DEPC";
5143 break;
7a387fff
TS
5144 default:
5145 goto die;
5146 }
8c0fdd85
TS
5147 break;
5148 case 25:
7a387fff
TS
5149 switch (sel) {
5150 case 0:
895c2d04 5151 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
5152 rn = "Performance0";
5153 break;
7a387fff 5154 case 1:
d9bea114 5155// gen_helper_mtc0_performance1(arg);
2423f660
TS
5156 rn = "Performance1";
5157// break;
7a387fff 5158 case 2:
d9bea114 5159// gen_helper_mtc0_performance2(arg);
2423f660
TS
5160 rn = "Performance2";
5161// break;
7a387fff 5162 case 3:
d9bea114 5163// gen_helper_mtc0_performance3(arg);
2423f660
TS
5164 rn = "Performance3";
5165// break;
7a387fff 5166 case 4:
d9bea114 5167// gen_helper_mtc0_performance4(arg);
2423f660
TS
5168 rn = "Performance4";
5169// break;
7a387fff 5170 case 5:
d9bea114 5171// gen_helper_mtc0_performance5(arg);
2423f660
TS
5172 rn = "Performance5";
5173// break;
7a387fff 5174 case 6:
d9bea114 5175// gen_helper_mtc0_performance6(arg);
2423f660
TS
5176 rn = "Performance6";
5177// break;
7a387fff 5178 case 7:
d9bea114 5179// gen_helper_mtc0_performance7(arg);
2423f660
TS
5180 rn = "Performance7";
5181// break;
7a387fff
TS
5182 default:
5183 goto die;
5184 }
8c0fdd85
TS
5185 break;
5186 case 26:
2423f660 5187 /* ignored */
8c0fdd85 5188 rn = "ECC";
2423f660 5189 break;
8c0fdd85 5190 case 27:
7a387fff
TS
5191 switch (sel) {
5192 case 0 ... 3:
2423f660
TS
5193 /* ignored */
5194 rn = "CacheErr";
5195 break;
7a387fff
TS
5196 default:
5197 goto die;
5198 }
8c0fdd85
TS
5199 break;
5200 case 28:
5201 switch (sel) {
5202 case 0:
7a387fff
TS
5203 case 2:
5204 case 4:
5205 case 6:
895c2d04 5206 gen_helper_mtc0_taglo(cpu_env, arg);
8c0fdd85
TS
5207 rn = "TagLo";
5208 break;
7a387fff
TS
5209 case 1:
5210 case 3:
5211 case 5:
5212 case 7:
895c2d04 5213 gen_helper_mtc0_datalo(cpu_env, arg);
7a387fff
TS
5214 rn = "DataLo";
5215 break;
8c0fdd85 5216 default:
8c0fdd85
TS
5217 goto die;
5218 }
5219 break;
5220 case 29:
7a387fff
TS
5221 switch (sel) {
5222 case 0:
5223 case 2:
5224 case 4:
5225 case 6:
895c2d04 5226 gen_helper_mtc0_taghi(cpu_env, arg);
7a387fff
TS
5227 rn = "TagHi";
5228 break;
5229 case 1:
5230 case 3:
5231 case 5:
5232 case 7:
895c2d04 5233 gen_helper_mtc0_datahi(cpu_env, arg);
7a387fff
TS
5234 rn = "DataHi";
5235 break;
5236 default:
5237 rn = "invalid sel";
5238 goto die;
5239 }
8c0fdd85
TS
5240 break;
5241 case 30:
7a387fff
TS
5242 switch (sel) {
5243 case 0:
7db13fae 5244 gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5245 rn = "ErrorEPC";
5246 break;
7a387fff
TS
5247 default:
5248 goto die;
5249 }
8c0fdd85
TS
5250 break;
5251 case 31:
7a387fff
TS
5252 switch (sel) {
5253 case 0:
f1aa6320 5254 /* EJTAG support */
7db13fae 5255 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5256 rn = "DESAVE";
5257 break;
7a387fff
TS
5258 default:
5259 goto die;
5260 }
2423f660
TS
5261 /* Stop translation as we may have switched the execution mode */
5262 ctx->bstate = BS_STOP;
8c0fdd85
TS
5263 break;
5264 default:
8c0fdd85
TS
5265 goto die;
5266 }
2abf314d 5267 (void)rn; /* avoid a compiler warning */
d12d51d5 5268 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 5269 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
5270 if (use_icount) {
5271 gen_io_end();
5272 ctx->bstate = BS_STOP;
5273 }
8c0fdd85
TS
5274 return;
5275
5276die:
d12d51d5 5277 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8c0fdd85
TS
5278 generate_exception(ctx, EXCP_RI);
5279}
5280
d26bc211 5281#if defined(TARGET_MIPS64)
7db13fae 5282static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5283{
5284 const char *rn = "invalid";
5285
e189e748
TS
5286 if (sel != 0)
5287 check_insn(env, ctx, ISA_MIPS64);
5288
9c2149c8
TS
5289 switch (reg) {
5290 case 0:
5291 switch (sel) {
5292 case 0:
7db13fae 5293 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
9c2149c8
TS
5294 rn = "Index";
5295 break;
5296 case 1:
7385ac0b 5297 check_insn(env, ctx, ASE_MT);
895c2d04 5298 gen_helper_mfc0_mvpcontrol(arg, cpu_env);
9c2149c8 5299 rn = "MVPControl";
ead9360e 5300 break;
9c2149c8 5301 case 2:
7385ac0b 5302 check_insn(env, ctx, ASE_MT);
895c2d04 5303 gen_helper_mfc0_mvpconf0(arg, cpu_env);
9c2149c8 5304 rn = "MVPConf0";
ead9360e 5305 break;
9c2149c8 5306 case 3:
7385ac0b 5307 check_insn(env, ctx, ASE_MT);
895c2d04 5308 gen_helper_mfc0_mvpconf1(arg, cpu_env);
9c2149c8 5309 rn = "MVPConf1";
ead9360e 5310 break;
9c2149c8
TS
5311 default:
5312 goto die;
5313 }
5314 break;
5315 case 1:
5316 switch (sel) {
5317 case 0:
895c2d04 5318 gen_helper_mfc0_random(arg, cpu_env);
9c2149c8 5319 rn = "Random";
2423f660 5320 break;
9c2149c8 5321 case 1:
7385ac0b 5322 check_insn(env, ctx, ASE_MT);
7db13fae 5323 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
9c2149c8 5324 rn = "VPEControl";
ead9360e 5325 break;
9c2149c8 5326 case 2:
7385ac0b 5327 check_insn(env, ctx, ASE_MT);
7db13fae 5328 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
9c2149c8 5329 rn = "VPEConf0";
ead9360e 5330 break;
9c2149c8 5331 case 3:
7385ac0b 5332 check_insn(env, ctx, ASE_MT);
7db13fae 5333 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
9c2149c8 5334 rn = "VPEConf1";
ead9360e 5335 break;
9c2149c8 5336 case 4:
7385ac0b 5337 check_insn(env, ctx, ASE_MT);
7db13fae 5338 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
9c2149c8 5339 rn = "YQMask";
ead9360e 5340 break;
9c2149c8 5341 case 5:
7385ac0b 5342 check_insn(env, ctx, ASE_MT);
7db13fae 5343 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5344 rn = "VPESchedule";
ead9360e 5345 break;
9c2149c8 5346 case 6:
7385ac0b 5347 check_insn(env, ctx, ASE_MT);
7db13fae 5348 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5349 rn = "VPEScheFBack";
ead9360e 5350 break;
9c2149c8 5351 case 7:
7385ac0b 5352 check_insn(env, ctx, ASE_MT);
7db13fae 5353 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
9c2149c8 5354 rn = "VPEOpt";
ead9360e 5355 break;
9c2149c8
TS
5356 default:
5357 goto die;
5358 }
5359 break;
5360 case 2:
5361 switch (sel) {
5362 case 0:
7db13fae 5363 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
2423f660
TS
5364 rn = "EntryLo0";
5365 break;
9c2149c8 5366 case 1:
7385ac0b 5367 check_insn(env, ctx, ASE_MT);
895c2d04 5368 gen_helper_mfc0_tcstatus(arg, cpu_env);
2423f660 5369 rn = "TCStatus";
ead9360e 5370 break;
9c2149c8 5371 case 2:
7385ac0b 5372 check_insn(env, ctx, ASE_MT);
895c2d04 5373 gen_helper_mfc0_tcbind(arg, cpu_env);
2423f660 5374 rn = "TCBind";
ead9360e 5375 break;
9c2149c8 5376 case 3:
7385ac0b 5377 check_insn(env, ctx, ASE_MT);
895c2d04 5378 gen_helper_dmfc0_tcrestart(arg, cpu_env);
2423f660 5379 rn = "TCRestart";
ead9360e 5380 break;
9c2149c8 5381 case 4:
7385ac0b 5382 check_insn(env, ctx, ASE_MT);
895c2d04 5383 gen_helper_dmfc0_tchalt(arg, cpu_env);
2423f660 5384 rn = "TCHalt";
ead9360e 5385 break;
9c2149c8 5386 case 5:
7385ac0b 5387 check_insn(env, ctx, ASE_MT);
895c2d04 5388 gen_helper_dmfc0_tccontext(arg, cpu_env);
2423f660 5389 rn = "TCContext";
ead9360e 5390 break;
9c2149c8 5391 case 6:
7385ac0b 5392 check_insn(env, ctx, ASE_MT);
895c2d04 5393 gen_helper_dmfc0_tcschedule(arg, cpu_env);
2423f660 5394 rn = "TCSchedule";
ead9360e 5395 break;
9c2149c8 5396 case 7:
7385ac0b 5397 check_insn(env, ctx, ASE_MT);
895c2d04 5398 gen_helper_dmfc0_tcschefback(arg, cpu_env);
2423f660 5399 rn = "TCScheFBack";
ead9360e 5400 break;
9c2149c8
TS
5401 default:
5402 goto die;
5403 }
5404 break;
5405 case 3:
5406 switch (sel) {
5407 case 0:
7db13fae 5408 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
2423f660
TS
5409 rn = "EntryLo1";
5410 break;
9c2149c8
TS
5411 default:
5412 goto die;
1579a72e 5413 }
9c2149c8
TS
5414 break;
5415 case 4:
5416 switch (sel) {
5417 case 0:
7db13fae 5418 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
2423f660
TS
5419 rn = "Context";
5420 break;
9c2149c8 5421 case 1:
d9bea114 5422// gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
2423f660
TS
5423 rn = "ContextConfig";
5424// break;
9c2149c8
TS
5425 default:
5426 goto die;
876d4b07 5427 }
9c2149c8
TS
5428 break;
5429 case 5:
5430 switch (sel) {
5431 case 0:
7db13fae 5432 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
2423f660
TS
5433 rn = "PageMask";
5434 break;
9c2149c8 5435 case 1:
e189e748 5436 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5437 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
2423f660
TS
5438 rn = "PageGrain";
5439 break;
9c2149c8
TS
5440 default:
5441 goto die;
876d4b07 5442 }
9c2149c8
TS
5443 break;
5444 case 6:
5445 switch (sel) {
5446 case 0:
7db13fae 5447 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
2423f660
TS
5448 rn = "Wired";
5449 break;
9c2149c8 5450 case 1:
e189e748 5451 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5452 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
2423f660 5453 rn = "SRSConf0";
ead9360e 5454 break;
9c2149c8 5455 case 2:
e189e748 5456 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5457 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
2423f660 5458 rn = "SRSConf1";
ead9360e 5459 break;
9c2149c8 5460 case 3:
e189e748 5461 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5462 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
2423f660 5463 rn = "SRSConf2";
ead9360e 5464 break;
9c2149c8 5465 case 4:
e189e748 5466 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5467 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
2423f660 5468 rn = "SRSConf3";
ead9360e 5469 break;
9c2149c8 5470 case 5:
e189e748 5471 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5472 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
2423f660 5473 rn = "SRSConf4";
ead9360e 5474 break;
9c2149c8
TS
5475 default:
5476 goto die;
876d4b07 5477 }
9c2149c8
TS
5478 break;
5479 case 7:
5480 switch (sel) {
5481 case 0:
e189e748 5482 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5483 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
2423f660
TS
5484 rn = "HWREna";
5485 break;
9c2149c8
TS
5486 default:
5487 goto die;
876d4b07 5488 }
9c2149c8
TS
5489 break;
5490 case 8:
5491 switch (sel) {
5492 case 0:
7db13fae 5493 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
f0b3f3ae 5494 rn = "BadVAddr";
2423f660 5495 break;
9c2149c8
TS
5496 default:
5497 goto die;
876d4b07 5498 }
9c2149c8
TS
5499 break;
5500 case 9:
5501 switch (sel) {
5502 case 0:
2e70f6ef
PB
5503 /* Mark as an IO operation because we read the time. */
5504 if (use_icount)
5505 gen_io_start();
895c2d04 5506 gen_helper_mfc0_count(arg, cpu_env);
2e70f6ef
PB
5507 if (use_icount) {
5508 gen_io_end();
2e70f6ef 5509 }
55807224
EI
5510 /* Break the TB to be able to take timer interrupts immediately
5511 after reading count. */
5512 ctx->bstate = BS_STOP;
2423f660
TS
5513 rn = "Count";
5514 break;
5515 /* 6,7 are implementation dependent */
9c2149c8
TS
5516 default:
5517 goto die;
876d4b07 5518 }
9c2149c8
TS
5519 break;
5520 case 10:
5521 switch (sel) {
5522 case 0:
7db13fae 5523 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
2423f660
TS
5524 rn = "EntryHi";
5525 break;
9c2149c8
TS
5526 default:
5527 goto die;
876d4b07 5528 }
9c2149c8
TS
5529 break;
5530 case 11:
5531 switch (sel) {
5532 case 0:
7db13fae 5533 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
2423f660
TS
5534 rn = "Compare";
5535 break;
876d4b07 5536 /* 6,7 are implementation dependent */
9c2149c8
TS
5537 default:
5538 goto die;
876d4b07 5539 }
9c2149c8
TS
5540 break;
5541 case 12:
5542 switch (sel) {
5543 case 0:
7db13fae 5544 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
2423f660
TS
5545 rn = "Status";
5546 break;
9c2149c8 5547 case 1:
e189e748 5548 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5549 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
2423f660
TS
5550 rn = "IntCtl";
5551 break;
9c2149c8 5552 case 2:
e189e748 5553 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5554 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
2423f660
TS
5555 rn = "SRSCtl";
5556 break;
9c2149c8 5557 case 3:
e189e748 5558 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5559 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
2423f660
TS
5560 rn = "SRSMap";
5561 break;
9c2149c8
TS
5562 default:
5563 goto die;
876d4b07 5564 }
9c2149c8
TS
5565 break;
5566 case 13:
5567 switch (sel) {
5568 case 0:
7db13fae 5569 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
2423f660
TS
5570 rn = "Cause";
5571 break;
9c2149c8
TS
5572 default:
5573 goto die;
876d4b07 5574 }
9c2149c8
TS
5575 break;
5576 case 14:
5577 switch (sel) {
5578 case 0:
7db13fae 5579 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
5580 rn = "EPC";
5581 break;
9c2149c8
TS
5582 default:
5583 goto die;
876d4b07 5584 }
9c2149c8
TS
5585 break;
5586 case 15:
5587 switch (sel) {
5588 case 0:
7db13fae 5589 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
2423f660
TS
5590 rn = "PRid";
5591 break;
9c2149c8 5592 case 1:
e189e748 5593 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 5594 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
2423f660
TS
5595 rn = "EBase";
5596 break;
9c2149c8
TS
5597 default:
5598 goto die;
876d4b07 5599 }
9c2149c8
TS
5600 break;
5601 case 16:
5602 switch (sel) {
5603 case 0:
7db13fae 5604 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
9c2149c8
TS
5605 rn = "Config";
5606 break;
5607 case 1:
7db13fae 5608 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
9c2149c8
TS
5609 rn = "Config1";
5610 break;
5611 case 2:
7db13fae 5612 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
9c2149c8
TS
5613 rn = "Config2";
5614 break;
5615 case 3:
7db13fae 5616 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
9c2149c8
TS
5617 rn = "Config3";
5618 break;
5619 /* 6,7 are implementation dependent */
f0b3f3ae 5620 case 6:
7db13fae 5621 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
f0b3f3ae
TS
5622 rn = "Config6";
5623 break;
5624 case 7:
7db13fae 5625 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
f0b3f3ae
TS
5626 rn = "Config7";
5627 break;
9c2149c8
TS
5628 default:
5629 goto die;
5630 }
5631 break;
5632 case 17:
5633 switch (sel) {
5634 case 0:
895c2d04 5635 gen_helper_dmfc0_lladdr(arg, cpu_env);
2423f660
TS
5636 rn = "LLAddr";
5637 break;
9c2149c8
TS
5638 default:
5639 goto die;
5640 }
5641 break;
5642 case 18:
5643 switch (sel) {
fd88b6ab 5644 case 0 ... 7:
895c2d04 5645 gen_helper_1e0i(dmfc0_watchlo, arg, sel);
2423f660
TS
5646 rn = "WatchLo";
5647 break;
9c2149c8
TS
5648 default:
5649 goto die;
5650 }
5651 break;
5652 case 19:
5653 switch (sel) {
fd88b6ab 5654 case 0 ... 7:
895c2d04 5655 gen_helper_1e0i(mfc0_watchhi, arg, sel);
2423f660
TS
5656 rn = "WatchHi";
5657 break;
9c2149c8
TS
5658 default:
5659 goto die;
5660 }
5661 break;
5662 case 20:
5663 switch (sel) {
5664 case 0:
e189e748 5665 check_insn(env, ctx, ISA_MIPS3);
7db13fae 5666 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
2423f660
TS
5667 rn = "XContext";
5668 break;
9c2149c8
TS
5669 default:
5670 goto die;
5671 }
5672 break;
5673 case 21:
5674 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5675 switch (sel) {
5676 case 0:
7db13fae 5677 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
2423f660
TS
5678 rn = "Framemask";
5679 break;
9c2149c8
TS
5680 default:
5681 goto die;
5682 }
5683 break;
5684 case 22:
d9bea114 5685 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5686 rn = "'Diagnostic"; /* implementation dependent */
5687 break;
9c2149c8
TS
5688 case 23:
5689 switch (sel) {
5690 case 0:
895c2d04 5691 gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
2423f660
TS
5692 rn = "Debug";
5693 break;
9c2149c8 5694 case 1:
895c2d04 5695// gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
2423f660
TS
5696 rn = "TraceControl";
5697// break;
9c2149c8 5698 case 2:
895c2d04 5699// gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
2423f660
TS
5700 rn = "TraceControl2";
5701// break;
9c2149c8 5702 case 3:
895c2d04 5703// gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
2423f660
TS
5704 rn = "UserTraceData";
5705// break;
9c2149c8 5706 case 4:
895c2d04 5707// gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
2423f660
TS
5708 rn = "TraceBPC";
5709// break;
9c2149c8
TS
5710 default:
5711 goto die;
5712 }
5713 break;
5714 case 24:
5715 switch (sel) {
5716 case 0:
f0b3f3ae 5717 /* EJTAG support */
7db13fae 5718 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
5719 rn = "DEPC";
5720 break;
9c2149c8
TS
5721 default:
5722 goto die;
5723 }
5724 break;
5725 case 25:
5726 switch (sel) {
5727 case 0:
7db13fae 5728 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
2423f660 5729 rn = "Performance0";
9c2149c8
TS
5730 break;
5731 case 1:
d9bea114 5732// gen_helper_dmfc0_performance1(arg);
2423f660
TS
5733 rn = "Performance1";
5734// break;
9c2149c8 5735 case 2:
d9bea114 5736// gen_helper_dmfc0_performance2(arg);
2423f660
TS
5737 rn = "Performance2";
5738// break;
9c2149c8 5739 case 3:
d9bea114 5740// gen_helper_dmfc0_performance3(arg);
2423f660
TS
5741 rn = "Performance3";
5742// break;
9c2149c8 5743 case 4:
d9bea114 5744// gen_helper_dmfc0_performance4(arg);
2423f660
TS
5745 rn = "Performance4";
5746// break;
9c2149c8 5747 case 5:
d9bea114 5748// gen_helper_dmfc0_performance5(arg);
2423f660
TS
5749 rn = "Performance5";
5750// break;
9c2149c8 5751 case 6:
d9bea114 5752// gen_helper_dmfc0_performance6(arg);
2423f660
TS
5753 rn = "Performance6";
5754// break;
9c2149c8 5755 case 7:
d9bea114 5756// gen_helper_dmfc0_performance7(arg);
2423f660
TS
5757 rn = "Performance7";
5758// break;
9c2149c8
TS
5759 default:
5760 goto die;
5761 }
5762 break;
5763 case 26:
d9bea114 5764 tcg_gen_movi_tl(arg, 0); /* unimplemented */
da80682b
AJ
5765 rn = "ECC";
5766 break;
9c2149c8
TS
5767 case 27:
5768 switch (sel) {
5769 /* ignored */
5770 case 0 ... 3:
d9bea114 5771 tcg_gen_movi_tl(arg, 0); /* unimplemented */
2423f660
TS
5772 rn = "CacheErr";
5773 break;
9c2149c8
TS
5774 default:
5775 goto die;
5776 }
5777 break;
5778 case 28:
5779 switch (sel) {
5780 case 0:
5781 case 2:
5782 case 4:
5783 case 6:
7db13fae 5784 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
9c2149c8
TS
5785 rn = "TagLo";
5786 break;
5787 case 1:
5788 case 3:
5789 case 5:
5790 case 7:
7db13fae 5791 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
9c2149c8
TS
5792 rn = "DataLo";
5793 break;
5794 default:
5795 goto die;
5796 }
5797 break;
5798 case 29:
5799 switch (sel) {
5800 case 0:
5801 case 2:
5802 case 4:
5803 case 6:
7db13fae 5804 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
9c2149c8
TS
5805 rn = "TagHi";
5806 break;
5807 case 1:
5808 case 3:
5809 case 5:
5810 case 7:
7db13fae 5811 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
9c2149c8
TS
5812 rn = "DataHi";
5813 break;
5814 default:
5815 goto die;
5816 }
5817 break;
5818 case 30:
5819 switch (sel) {
5820 case 0:
7db13fae 5821 tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
5822 rn = "ErrorEPC";
5823 break;
9c2149c8
TS
5824 default:
5825 goto die;
5826 }
5827 break;
5828 case 31:
5829 switch (sel) {
5830 case 0:
f0b3f3ae 5831 /* EJTAG support */
7db13fae 5832 gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
5833 rn = "DESAVE";
5834 break;
9c2149c8
TS
5835 default:
5836 goto die;
5837 }
5838 break;
5839 default:
876d4b07 5840 goto die;
9c2149c8 5841 }
2abf314d 5842 (void)rn; /* avoid a compiler warning */
d12d51d5 5843 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5844 return;
5845
5846die:
d12d51d5 5847 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
5848 generate_exception(ctx, EXCP_RI);
5849}
5850
7db13fae 5851static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
9c2149c8
TS
5852{
5853 const char *rn = "invalid";
5854
e189e748
TS
5855 if (sel != 0)
5856 check_insn(env, ctx, ISA_MIPS64);
5857
2e70f6ef
PB
5858 if (use_icount)
5859 gen_io_start();
5860
9c2149c8
TS
5861 switch (reg) {
5862 case 0:
5863 switch (sel) {
5864 case 0:
895c2d04 5865 gen_helper_mtc0_index(cpu_env, arg);
9c2149c8
TS
5866 rn = "Index";
5867 break;
5868 case 1:
7385ac0b 5869 check_insn(env, ctx, ASE_MT);
895c2d04 5870 gen_helper_mtc0_mvpcontrol(cpu_env, arg);
9c2149c8 5871 rn = "MVPControl";
ead9360e 5872 break;
9c2149c8 5873 case 2:
7385ac0b 5874 check_insn(env, ctx, ASE_MT);
ead9360e 5875 /* ignored */
9c2149c8 5876 rn = "MVPConf0";
ead9360e 5877 break;
9c2149c8 5878 case 3:
7385ac0b 5879 check_insn(env, ctx, ASE_MT);
ead9360e 5880 /* ignored */
9c2149c8 5881 rn = "MVPConf1";
ead9360e 5882 break;
9c2149c8
TS
5883 default:
5884 goto die;
5885 }
5886 break;
5887 case 1:
5888 switch (sel) {
5889 case 0:
2423f660 5890 /* ignored */
9c2149c8 5891 rn = "Random";
2423f660 5892 break;
9c2149c8 5893 case 1:
7385ac0b 5894 check_insn(env, ctx, ASE_MT);
895c2d04 5895 gen_helper_mtc0_vpecontrol(cpu_env, arg);
9c2149c8 5896 rn = "VPEControl";
ead9360e 5897 break;
9c2149c8 5898 case 2:
7385ac0b 5899 check_insn(env, ctx, ASE_MT);
895c2d04 5900 gen_helper_mtc0_vpeconf0(cpu_env, arg);
9c2149c8 5901 rn = "VPEConf0";
ead9360e 5902 break;
9c2149c8 5903 case 3:
7385ac0b 5904 check_insn(env, ctx, ASE_MT);
895c2d04 5905 gen_helper_mtc0_vpeconf1(cpu_env, arg);
9c2149c8 5906 rn = "VPEConf1";
ead9360e 5907 break;
9c2149c8 5908 case 4:
7385ac0b 5909 check_insn(env, ctx, ASE_MT);
895c2d04 5910 gen_helper_mtc0_yqmask(cpu_env, arg);
9c2149c8 5911 rn = "YQMask";
ead9360e 5912 break;
9c2149c8 5913 case 5:
7385ac0b 5914 check_insn(env, ctx, ASE_MT);
7db13fae 5915 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9c2149c8 5916 rn = "VPESchedule";
ead9360e 5917 break;
9c2149c8 5918 case 6:
7385ac0b 5919 check_insn(env, ctx, ASE_MT);
7db13fae 5920 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9c2149c8 5921 rn = "VPEScheFBack";
ead9360e 5922 break;
9c2149c8 5923 case 7:
7385ac0b 5924 check_insn(env, ctx, ASE_MT);
895c2d04 5925 gen_helper_mtc0_vpeopt(cpu_env, arg);
9c2149c8 5926 rn = "VPEOpt";
ead9360e 5927 break;
9c2149c8
TS
5928 default:
5929 goto die;
5930 }
5931 break;
5932 case 2:
5933 switch (sel) {
5934 case 0:
895c2d04 5935 gen_helper_mtc0_entrylo0(cpu_env, arg);
2423f660
TS
5936 rn = "EntryLo0";
5937 break;
9c2149c8 5938 case 1:
7385ac0b 5939 check_insn(env, ctx, ASE_MT);
895c2d04 5940 gen_helper_mtc0_tcstatus(cpu_env, arg);
2423f660 5941 rn = "TCStatus";
ead9360e 5942 break;
9c2149c8 5943 case 2:
7385ac0b 5944 check_insn(env, ctx, ASE_MT);
895c2d04 5945 gen_helper_mtc0_tcbind(cpu_env, arg);
2423f660 5946 rn = "TCBind";
ead9360e 5947 break;
9c2149c8 5948 case 3:
7385ac0b 5949 check_insn(env, ctx, ASE_MT);
895c2d04 5950 gen_helper_mtc0_tcrestart(cpu_env, arg);
2423f660 5951 rn = "TCRestart";
ead9360e 5952 break;
9c2149c8 5953 case 4:
7385ac0b 5954 check_insn(env, ctx, ASE_MT);
895c2d04 5955 gen_helper_mtc0_tchalt(cpu_env, arg);
2423f660 5956 rn = "TCHalt";
ead9360e 5957 break;
9c2149c8 5958 case 5:
7385ac0b 5959 check_insn(env, ctx, ASE_MT);
895c2d04 5960 gen_helper_mtc0_tccontext(cpu_env, arg);
2423f660 5961 rn = "TCContext";
ead9360e 5962 break;
9c2149c8 5963 case 6:
7385ac0b 5964 check_insn(env, ctx, ASE_MT);
895c2d04 5965 gen_helper_mtc0_tcschedule(cpu_env, arg);
2423f660 5966 rn = "TCSchedule";
ead9360e 5967 break;
9c2149c8 5968 case 7:
7385ac0b 5969 check_insn(env, ctx, ASE_MT);
895c2d04 5970 gen_helper_mtc0_tcschefback(cpu_env, arg);
2423f660 5971 rn = "TCScheFBack";
ead9360e 5972 break;
9c2149c8
TS
5973 default:
5974 goto die;
5975 }
5976 break;
5977 case 3:
5978 switch (sel) {
5979 case 0:
895c2d04 5980 gen_helper_mtc0_entrylo1(cpu_env, arg);
2423f660
TS
5981 rn = "EntryLo1";
5982 break;
9c2149c8
TS
5983 default:
5984 goto die;
876d4b07 5985 }
9c2149c8
TS
5986 break;
5987 case 4:
5988 switch (sel) {
5989 case 0:
895c2d04 5990 gen_helper_mtc0_context(cpu_env, arg);
2423f660
TS
5991 rn = "Context";
5992 break;
9c2149c8 5993 case 1:
895c2d04 5994// gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
2423f660
TS
5995 rn = "ContextConfig";
5996// break;
9c2149c8
TS
5997 default:
5998 goto die;
876d4b07 5999 }
9c2149c8
TS
6000 break;
6001 case 5:
6002 switch (sel) {
6003 case 0:
895c2d04 6004 gen_helper_mtc0_pagemask(cpu_env, arg);
2423f660
TS
6005 rn = "PageMask";
6006 break;
9c2149c8 6007 case 1:
e189e748 6008 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6009 gen_helper_mtc0_pagegrain(cpu_env, arg);
2423f660
TS
6010 rn = "PageGrain";
6011 break;
9c2149c8
TS
6012 default:
6013 goto die;
876d4b07 6014 }
9c2149c8
TS
6015 break;
6016 case 6:
6017 switch (sel) {
6018 case 0:
895c2d04 6019 gen_helper_mtc0_wired(cpu_env, arg);
2423f660
TS
6020 rn = "Wired";
6021 break;
9c2149c8 6022 case 1:
e189e748 6023 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6024 gen_helper_mtc0_srsconf0(cpu_env, arg);
2423f660 6025 rn = "SRSConf0";
ead9360e 6026 break;
9c2149c8 6027 case 2:
e189e748 6028 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6029 gen_helper_mtc0_srsconf1(cpu_env, arg);
2423f660 6030 rn = "SRSConf1";
ead9360e 6031 break;
9c2149c8 6032 case 3:
e189e748 6033 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6034 gen_helper_mtc0_srsconf2(cpu_env, arg);
2423f660 6035 rn = "SRSConf2";
ead9360e 6036 break;
9c2149c8 6037 case 4:
e189e748 6038 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6039 gen_helper_mtc0_srsconf3(cpu_env, arg);
2423f660 6040 rn = "SRSConf3";
ead9360e 6041 break;
9c2149c8 6042 case 5:
e189e748 6043 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6044 gen_helper_mtc0_srsconf4(cpu_env, arg);
2423f660 6045 rn = "SRSConf4";
ead9360e 6046 break;
9c2149c8
TS
6047 default:
6048 goto die;
876d4b07 6049 }
9c2149c8
TS
6050 break;
6051 case 7:
6052 switch (sel) {
6053 case 0:
e189e748 6054 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6055 gen_helper_mtc0_hwrena(cpu_env, arg);
2423f660
TS
6056 rn = "HWREna";
6057 break;
9c2149c8
TS
6058 default:
6059 goto die;
876d4b07 6060 }
9c2149c8
TS
6061 break;
6062 case 8:
6063 /* ignored */
f0b3f3ae 6064 rn = "BadVAddr";
9c2149c8
TS
6065 break;
6066 case 9:
6067 switch (sel) {
6068 case 0:
895c2d04 6069 gen_helper_mtc0_count(cpu_env, arg);
2423f660
TS
6070 rn = "Count";
6071 break;
876d4b07 6072 /* 6,7 are implementation dependent */
9c2149c8
TS
6073 default:
6074 goto die;
876d4b07
TS
6075 }
6076 /* Stop translation as we may have switched the execution mode */
6077 ctx->bstate = BS_STOP;
9c2149c8
TS
6078 break;
6079 case 10:
6080 switch (sel) {
6081 case 0:
895c2d04 6082 gen_helper_mtc0_entryhi(cpu_env, arg);
2423f660
TS
6083 rn = "EntryHi";
6084 break;
9c2149c8
TS
6085 default:
6086 goto die;
876d4b07 6087 }
9c2149c8
TS
6088 break;
6089 case 11:
6090 switch (sel) {
6091 case 0:
895c2d04 6092 gen_helper_mtc0_compare(cpu_env, arg);
2423f660
TS
6093 rn = "Compare";
6094 break;
876d4b07 6095 /* 6,7 are implementation dependent */
9c2149c8
TS
6096 default:
6097 goto die;
876d4b07 6098 }
de9a95f0
AJ
6099 /* Stop translation as we may have switched the execution mode */
6100 ctx->bstate = BS_STOP;
9c2149c8
TS
6101 break;
6102 case 12:
6103 switch (sel) {
6104 case 0:
867abc7e 6105 save_cpu_state(ctx, 1);
895c2d04 6106 gen_helper_mtc0_status(cpu_env, arg);
8487327a
TS
6107 /* BS_STOP isn't good enough here, hflags may have changed. */
6108 gen_save_pc(ctx->pc + 4);
6109 ctx->bstate = BS_EXCP;
2423f660
TS
6110 rn = "Status";
6111 break;
9c2149c8 6112 case 1:
e189e748 6113 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6114 gen_helper_mtc0_intctl(cpu_env, arg);
8487327a
TS
6115 /* Stop translation as we may have switched the execution mode */
6116 ctx->bstate = BS_STOP;
2423f660
TS
6117 rn = "IntCtl";
6118 break;
9c2149c8 6119 case 2:
e189e748 6120 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6121 gen_helper_mtc0_srsctl(cpu_env, arg);
8487327a
TS
6122 /* Stop translation as we may have switched the execution mode */
6123 ctx->bstate = BS_STOP;
2423f660
TS
6124 rn = "SRSCtl";
6125 break;
9c2149c8 6126 case 3:
e189e748 6127 check_insn(env, ctx, ISA_MIPS32R2);
7db13fae 6128 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8487327a
TS
6129 /* Stop translation as we may have switched the execution mode */
6130 ctx->bstate = BS_STOP;
2423f660
TS
6131 rn = "SRSMap";
6132 break;
6133 default:
9c2149c8 6134 goto die;
876d4b07 6135 }
9c2149c8
TS
6136 break;
6137 case 13:
6138 switch (sel) {
6139 case 0:
867abc7e 6140 save_cpu_state(ctx, 1);
5dc5d9f0
AJ
6141 /* Mark as an IO operation because we may trigger a software
6142 interrupt. */
6143 if (use_icount) {
6144 gen_io_start();
6145 }
895c2d04 6146 gen_helper_mtc0_cause(cpu_env, arg);
5dc5d9f0
AJ
6147 if (use_icount) {
6148 gen_io_end();
6149 }
6150 /* Stop translation as we may have triggered an intetrupt */
6151 ctx->bstate = BS_STOP;
2423f660
TS
6152 rn = "Cause";
6153 break;
9c2149c8
TS
6154 default:
6155 goto die;
876d4b07 6156 }
9c2149c8
TS
6157 break;
6158 case 14:
6159 switch (sel) {
6160 case 0:
7db13fae 6161 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
2423f660
TS
6162 rn = "EPC";
6163 break;
9c2149c8
TS
6164 default:
6165 goto die;
876d4b07 6166 }
9c2149c8
TS
6167 break;
6168 case 15:
6169 switch (sel) {
6170 case 0:
2423f660
TS
6171 /* ignored */
6172 rn = "PRid";
6173 break;
9c2149c8 6174 case 1:
e189e748 6175 check_insn(env, ctx, ISA_MIPS32R2);
895c2d04 6176 gen_helper_mtc0_ebase(cpu_env, arg);
2423f660
TS
6177 rn = "EBase";
6178 break;
9c2149c8
TS
6179 default:
6180 goto die;
876d4b07 6181 }
9c2149c8
TS
6182 break;
6183 case 16:
6184 switch (sel) {
6185 case 0:
895c2d04 6186 gen_helper_mtc0_config0(cpu_env, arg);
9c2149c8 6187 rn = "Config";
2423f660
TS
6188 /* Stop translation as we may have switched the execution mode */
6189 ctx->bstate = BS_STOP;
9c2149c8
TS
6190 break;
6191 case 1:
1fc7bf6e 6192 /* ignored, read only */
9c2149c8
TS
6193 rn = "Config1";
6194 break;
6195 case 2:
895c2d04 6196 gen_helper_mtc0_config2(cpu_env, arg);
9c2149c8 6197 rn = "Config2";
2423f660
TS
6198 /* Stop translation as we may have switched the execution mode */
6199 ctx->bstate = BS_STOP;
9c2149c8
TS
6200 break;
6201 case 3:
2423f660 6202 /* ignored */
9c2149c8
TS
6203 rn = "Config3";
6204 break;
6205 /* 6,7 are implementation dependent */
6206 default:
6207 rn = "Invalid config selector";
6208 goto die;
6209 }
9c2149c8
TS
6210 break;
6211 case 17:
6212 switch (sel) {
6213 case 0:
895c2d04 6214 gen_helper_mtc0_lladdr(cpu_env, arg);
2423f660
TS
6215 rn = "LLAddr";
6216 break;
9c2149c8
TS
6217 default:
6218 goto die;
6219 }
6220 break;
6221 case 18:
6222 switch (sel) {
fd88b6ab 6223 case 0 ... 7:
895c2d04 6224 gen_helper_0e1i(mtc0_watchlo, arg, sel);
2423f660
TS
6225 rn = "WatchLo";
6226 break;
9c2149c8
TS
6227 default:
6228 goto die;
6229 }
6230 break;
6231 case 19:
6232 switch (sel) {
fd88b6ab 6233 case 0 ... 7:
895c2d04 6234 gen_helper_0e1i(mtc0_watchhi, arg, sel);
2423f660
TS
6235 rn = "WatchHi";
6236 break;
9c2149c8
TS
6237 default:
6238 goto die;
6239 }
6240 break;
6241 case 20:
6242 switch (sel) {
6243 case 0:
e189e748 6244 check_insn(env, ctx, ISA_MIPS3);
895c2d04 6245 gen_helper_mtc0_xcontext(cpu_env, arg);
2423f660
TS
6246 rn = "XContext";
6247 break;
9c2149c8
TS
6248 default:
6249 goto die;
6250 }
6251 break;
6252 case 21:
6253 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6254 switch (sel) {
6255 case 0:
895c2d04 6256 gen_helper_mtc0_framemask(cpu_env, arg);
2423f660
TS
6257 rn = "Framemask";
6258 break;
9c2149c8
TS
6259 default:
6260 goto die;
6261 }
6262 break;
6263 case 22:
6264 /* ignored */
6265 rn = "Diagnostic"; /* implementation dependent */
876d4b07 6266 break;
9c2149c8
TS
6267 case 23:
6268 switch (sel) {
6269 case 0:
895c2d04 6270 gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8487327a
TS
6271 /* BS_STOP isn't good enough here, hflags may have changed. */
6272 gen_save_pc(ctx->pc + 4);
6273 ctx->bstate = BS_EXCP;
2423f660
TS
6274 rn = "Debug";
6275 break;
9c2149c8 6276 case 1:
895c2d04 6277// gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8487327a
TS
6278 /* Stop translation as we may have switched the execution mode */
6279 ctx->bstate = BS_STOP;
2423f660
TS
6280 rn = "TraceControl";
6281// break;
9c2149c8 6282 case 2:
895c2d04 6283// gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8487327a
TS
6284 /* Stop translation as we may have switched the execution mode */
6285 ctx->bstate = BS_STOP;
2423f660
TS
6286 rn = "TraceControl2";
6287// break;
9c2149c8 6288 case 3:
895c2d04 6289// gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8487327a
TS
6290 /* Stop translation as we may have switched the execution mode */
6291 ctx->bstate = BS_STOP;
2423f660
TS
6292 rn = "UserTraceData";
6293// break;
9c2149c8 6294 case 4:
895c2d04 6295// gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8487327a
TS
6296 /* Stop translation as we may have switched the execution mode */
6297 ctx->bstate = BS_STOP;
2423f660
TS
6298 rn = "TraceBPC";
6299// break;
9c2149c8
TS
6300 default:
6301 goto die;
6302 }
9c2149c8
TS
6303 break;
6304 case 24:
6305 switch (sel) {
6306 case 0:
f1aa6320 6307 /* EJTAG support */
7db13fae 6308 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
2423f660
TS
6309 rn = "DEPC";
6310 break;
9c2149c8
TS
6311 default:
6312 goto die;
6313 }
6314 break;
6315 case 25:
6316 switch (sel) {
6317 case 0:
895c2d04 6318 gen_helper_mtc0_performance0(cpu_env, arg);
2423f660
TS
6319 rn = "Performance0";
6320 break;
9c2149c8 6321 case 1:
895c2d04 6322// gen_helper_mtc0_performance1(cpu_env, arg);
2423f660
TS
6323 rn = "Performance1";
6324// break;
9c2149c8 6325 case 2:
895c2d04 6326// gen_helper_mtc0_performance2(cpu_env, arg);
2423f660
TS
6327 rn = "Performance2";
6328// break;
9c2149c8 6329 case 3:
895c2d04 6330// gen_helper_mtc0_performance3(cpu_env, arg);
2423f660
TS
6331 rn = "Performance3";
6332// break;
9c2149c8 6333 case 4:
895c2d04 6334// gen_helper_mtc0_performance4(cpu_env, arg);
2423f660
TS
6335 rn = "Performance4";
6336// break;
9c2149c8 6337 case 5:
895c2d04 6338// gen_helper_mtc0_performance5(cpu_env, arg);
2423f660
TS
6339 rn = "Performance5";
6340// break;
9c2149c8 6341 case 6:
895c2d04 6342// gen_helper_mtc0_performance6(cpu_env, arg);
2423f660
TS
6343 rn = "Performance6";
6344// break;
9c2149c8 6345 case 7:
895c2d04 6346// gen_helper_mtc0_performance7(cpu_env, arg);
2423f660
TS
6347 rn = "Performance7";
6348// break;
9c2149c8
TS
6349 default:
6350 goto die;
6351 }
876d4b07 6352 break;
9c2149c8 6353 case 26:
876d4b07 6354 /* ignored */
9c2149c8 6355 rn = "ECC";
876d4b07 6356 break;
9c2149c8
TS
6357 case 27:
6358 switch (sel) {
6359 case 0 ... 3:
2423f660
TS
6360 /* ignored */
6361 rn = "CacheErr";
6362 break;
9c2149c8
TS
6363 default:
6364 goto die;
6365 }
876d4b07 6366 break;
9c2149c8
TS
6367 case 28:
6368 switch (sel) {
6369 case 0:
6370 case 2:
6371 case 4:
6372 case 6:
895c2d04 6373 gen_helper_mtc0_taglo(cpu_env, arg);
9c2149c8
TS
6374 rn = "TagLo";
6375 break;
6376 case 1:
6377 case 3:
6378 case 5:
6379 case 7:
895c2d04 6380 gen_helper_mtc0_datalo(cpu_env, arg);
9c2149c8
TS
6381 rn = "DataLo";
6382 break;
6383 default:
6384 goto die;
6385 }
6386 break;
6387 case 29:
6388 switch (sel) {
6389 case 0:
6390 case 2:
6391 case 4:
6392 case 6:
895c2d04 6393 gen_helper_mtc0_taghi(cpu_env, arg);
9c2149c8
TS
6394 rn = "TagHi";
6395 break;
6396 case 1:
6397 case 3:
6398 case 5:
6399 case 7:
895c2d04 6400 gen_helper_mtc0_datahi(cpu_env, arg);
9c2149c8
TS
6401 rn = "DataHi";
6402 break;
6403 default:
6404 rn = "invalid sel";
6405 goto die;
6406 }
876d4b07 6407 break;
9c2149c8
TS
6408 case 30:
6409 switch (sel) {
6410 case 0:
7db13fae 6411 tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
2423f660
TS
6412 rn = "ErrorEPC";
6413 break;
9c2149c8
TS
6414 default:
6415 goto die;
6416 }
6417 break;
6418 case 31:
6419 switch (sel) {
6420 case 0:
f1aa6320 6421 /* EJTAG support */
7db13fae 6422 gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
2423f660
TS
6423 rn = "DESAVE";
6424 break;
9c2149c8
TS
6425 default:
6426 goto die;
6427 }
876d4b07
TS
6428 /* Stop translation as we may have switched the execution mode */
6429 ctx->bstate = BS_STOP;
9c2149c8
TS
6430 break;
6431 default:
876d4b07 6432 goto die;
9c2149c8 6433 }
2abf314d 6434 (void)rn; /* avoid a compiler warning */
d12d51d5 6435 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
bf20dc07 6436 /* For simplicity assume that all writes can cause interrupts. */
2e70f6ef
PB
6437 if (use_icount) {
6438 gen_io_end();
6439 ctx->bstate = BS_STOP;
6440 }
9c2149c8
TS
6441 return;
6442
6443die:
d12d51d5 6444 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
9c2149c8
TS
6445 generate_exception(ctx, EXCP_RI);
6446}
d26bc211 6447#endif /* TARGET_MIPS64 */
9c2149c8 6448
7db13fae 6449static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
ead9360e
TS
6450 int u, int sel, int h)
6451{
6452 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6453 TCGv t0 = tcg_temp_local_new();
ead9360e
TS
6454
6455 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6456 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6457 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1a3fd9c3 6458 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6459 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6460 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1a3fd9c3 6461 tcg_gen_movi_tl(t0, -1);
ead9360e
TS
6462 else if (u == 0) {
6463 switch (rt) {
5a25ce94
EI
6464 case 1:
6465 switch (sel) {
6466 case 1:
895c2d04 6467 gen_helper_mftc0_vpecontrol(t0, cpu_env);
5a25ce94
EI
6468 break;
6469 case 2:
895c2d04 6470 gen_helper_mftc0_vpeconf0(t0, cpu_env);
5a25ce94
EI
6471 break;
6472 default:
6473 goto die;
6474 break;
6475 }
6476 break;
ead9360e
TS
6477 case 2:
6478 switch (sel) {
6479 case 1:
895c2d04 6480 gen_helper_mftc0_tcstatus(t0, cpu_env);
ead9360e
TS
6481 break;
6482 case 2:
895c2d04 6483 gen_helper_mftc0_tcbind(t0, cpu_env);
ead9360e
TS
6484 break;
6485 case 3:
895c2d04 6486 gen_helper_mftc0_tcrestart(t0, cpu_env);
ead9360e
TS
6487 break;
6488 case 4:
895c2d04 6489 gen_helper_mftc0_tchalt(t0, cpu_env);
ead9360e
TS
6490 break;
6491 case 5:
895c2d04 6492 gen_helper_mftc0_tccontext(t0, cpu_env);
ead9360e
TS
6493 break;
6494 case 6:
895c2d04 6495 gen_helper_mftc0_tcschedule(t0, cpu_env);
ead9360e
TS
6496 break;
6497 case 7:
895c2d04 6498 gen_helper_mftc0_tcschefback(t0, cpu_env);
ead9360e
TS
6499 break;
6500 default:
1a3fd9c3 6501 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6502 break;
6503 }
6504 break;
6505 case 10:
6506 switch (sel) {
6507 case 0:
895c2d04 6508 gen_helper_mftc0_entryhi(t0, cpu_env);
ead9360e
TS
6509 break;
6510 default:
1a3fd9c3 6511 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6512 break;
6513 }
6514 case 12:
6515 switch (sel) {
6516 case 0:
895c2d04 6517 gen_helper_mftc0_status(t0, cpu_env);
ead9360e
TS
6518 break;
6519 default:
1a3fd9c3 6520 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6521 break;
6522 }
5a25ce94
EI
6523 case 13:
6524 switch (sel) {
6525 case 0:
895c2d04 6526 gen_helper_mftc0_cause(t0, cpu_env);
5a25ce94
EI
6527 break;
6528 default:
6529 goto die;
6530 break;
6531 }
6532 break;
6533 case 14:
6534 switch (sel) {
6535 case 0:
895c2d04 6536 gen_helper_mftc0_epc(t0, cpu_env);
5a25ce94
EI
6537 break;
6538 default:
6539 goto die;
6540 break;
6541 }
6542 break;
6543 case 15:
6544 switch (sel) {
6545 case 1:
895c2d04 6546 gen_helper_mftc0_ebase(t0, cpu_env);
5a25ce94
EI
6547 break;
6548 default:
6549 goto die;
6550 break;
6551 }
6552 break;
6553 case 16:
6554 switch (sel) {
6555 case 0 ... 7:
895c2d04 6556 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
5a25ce94
EI
6557 break;
6558 default:
6559 goto die;
6560 break;
6561 }
6562 break;
ead9360e
TS
6563 case 23:
6564 switch (sel) {
6565 case 0:
895c2d04 6566 gen_helper_mftc0_debug(t0, cpu_env);
ead9360e
TS
6567 break;
6568 default:
1a3fd9c3 6569 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6570 break;
6571 }
6572 break;
6573 default:
1a3fd9c3 6574 gen_mfc0(env, ctx, t0, rt, sel);
ead9360e
TS
6575 }
6576 } else switch (sel) {
6577 /* GPR registers. */
6578 case 0:
895c2d04 6579 gen_helper_1e0i(mftgpr, t0, rt);
ead9360e
TS
6580 break;
6581 /* Auxiliary CPU registers */
6582 case 1:
6583 switch (rt) {
6584 case 0:
895c2d04 6585 gen_helper_1e0i(mftlo, t0, 0);
ead9360e
TS
6586 break;
6587 case 1:
895c2d04 6588 gen_helper_1e0i(mfthi, t0, 0);
ead9360e
TS
6589 break;
6590 case 2:
895c2d04 6591 gen_helper_1e0i(mftacx, t0, 0);
ead9360e
TS
6592 break;
6593 case 4:
895c2d04 6594 gen_helper_1e0i(mftlo, t0, 1);
ead9360e
TS
6595 break;
6596 case 5:
895c2d04 6597 gen_helper_1e0i(mfthi, t0, 1);
ead9360e
TS
6598 break;
6599 case 6:
895c2d04 6600 gen_helper_1e0i(mftacx, t0, 1);
ead9360e
TS
6601 break;
6602 case 8:
895c2d04 6603 gen_helper_1e0i(mftlo, t0, 2);
ead9360e
TS
6604 break;
6605 case 9:
895c2d04 6606 gen_helper_1e0i(mfthi, t0, 2);
ead9360e
TS
6607 break;
6608 case 10:
895c2d04 6609 gen_helper_1e0i(mftacx, t0, 2);
ead9360e
TS
6610 break;
6611 case 12:
895c2d04 6612 gen_helper_1e0i(mftlo, t0, 3);
ead9360e
TS
6613 break;
6614 case 13:
895c2d04 6615 gen_helper_1e0i(mfthi, t0, 3);
ead9360e
TS
6616 break;
6617 case 14:
895c2d04 6618 gen_helper_1e0i(mftacx, t0, 3);
ead9360e
TS
6619 break;
6620 case 16:
895c2d04 6621 gen_helper_mftdsp(t0, cpu_env);
ead9360e
TS
6622 break;
6623 default:
6624 goto die;
6625 }
6626 break;
6627 /* Floating point (COP1). */
6628 case 2:
6629 /* XXX: For now we support only a single FPU context. */
6630 if (h == 0) {
a7812ae4 6631 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6632
6633 gen_load_fpr32(fp0, rt);
6634 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6635 tcg_temp_free_i32(fp0);
ead9360e 6636 } else {
a7812ae4 6637 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6638
6639 gen_load_fpr32h(fp0, rt);
6640 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 6641 tcg_temp_free_i32(fp0);
ead9360e
TS
6642 }
6643 break;
6644 case 3:
6645 /* XXX: For now we support only a single FPU context. */
895c2d04 6646 gen_helper_1e0i(cfc1, t0, rt);
ead9360e
TS
6647 break;
6648 /* COP2: Not implemented. */
6649 case 4:
6650 case 5:
6651 /* fall through */
6652 default:
6653 goto die;
6654 }
d12d51d5 6655 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1a3fd9c3
TS
6656 gen_store_gpr(t0, rd);
6657 tcg_temp_free(t0);
ead9360e
TS
6658 return;
6659
6660die:
1a3fd9c3 6661 tcg_temp_free(t0);
d12d51d5 6662 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
ead9360e
TS
6663 generate_exception(ctx, EXCP_RI);
6664}
6665
7db13fae 6666static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
ead9360e
TS
6667 int u, int sel, int h)
6668{
6669 int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
a7812ae4 6670 TCGv t0 = tcg_temp_local_new();
ead9360e 6671
1a3fd9c3 6672 gen_load_gpr(t0, rt);
ead9360e 6673 if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
b5dc7732
TS
6674 ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6675 (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
ead9360e
TS
6676 /* NOP */ ;
6677 else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6678 (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6679 /* NOP */ ;
6680 else if (u == 0) {
6681 switch (rd) {
5a25ce94
EI
6682 case 1:
6683 switch (sel) {
6684 case 1:
895c2d04 6685 gen_helper_mttc0_vpecontrol(cpu_env, t0);
5a25ce94
EI
6686 break;
6687 case 2:
895c2d04 6688 gen_helper_mttc0_vpeconf0(cpu_env, t0);
5a25ce94
EI
6689 break;
6690 default:
6691 goto die;
6692 break;
6693 }
6694 break;
ead9360e
TS
6695 case 2:
6696 switch (sel) {
6697 case 1:
895c2d04 6698 gen_helper_mttc0_tcstatus(cpu_env, t0);
ead9360e
TS
6699 break;
6700 case 2:
895c2d04 6701 gen_helper_mttc0_tcbind(cpu_env, t0);
ead9360e
TS
6702 break;
6703 case 3:
895c2d04 6704 gen_helper_mttc0_tcrestart(cpu_env, t0);
ead9360e
TS
6705 break;
6706 case 4:
895c2d04 6707 gen_helper_mttc0_tchalt(cpu_env, t0);
ead9360e
TS
6708 break;
6709 case 5:
895c2d04 6710 gen_helper_mttc0_tccontext(cpu_env, t0);
ead9360e
TS
6711 break;
6712 case 6:
895c2d04 6713 gen_helper_mttc0_tcschedule(cpu_env, t0);
ead9360e
TS
6714 break;
6715 case 7:
895c2d04 6716 gen_helper_mttc0_tcschefback(cpu_env, t0);
ead9360e
TS
6717 break;
6718 default:
1a3fd9c3 6719 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6720 break;
6721 }
6722 break;
6723 case 10:
6724 switch (sel) {
6725 case 0:
895c2d04 6726 gen_helper_mttc0_entryhi(cpu_env, t0);
ead9360e
TS
6727 break;
6728 default:
1a3fd9c3 6729 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6730 break;
6731 }
6732 case 12:
6733 switch (sel) {
6734 case 0:
895c2d04 6735 gen_helper_mttc0_status(cpu_env, t0);
ead9360e
TS
6736 break;
6737 default:
1a3fd9c3 6738 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6739 break;
6740 }
5a25ce94
EI
6741 case 13:
6742 switch (sel) {
6743 case 0:
895c2d04 6744 gen_helper_mttc0_cause(cpu_env, t0);
5a25ce94
EI
6745 break;
6746 default:
6747 goto die;
6748 break;
6749 }
6750 break;
6751 case 15:
6752 switch (sel) {
6753 case 1:
895c2d04 6754 gen_helper_mttc0_ebase(cpu_env, t0);
5a25ce94
EI
6755 break;
6756 default:
6757 goto die;
6758 break;
6759 }
6760 break;
ead9360e
TS
6761 case 23:
6762 switch (sel) {
6763 case 0:
895c2d04 6764 gen_helper_mttc0_debug(cpu_env, t0);
ead9360e
TS
6765 break;
6766 default:
1a3fd9c3 6767 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6768 break;
6769 }
6770 break;
6771 default:
1a3fd9c3 6772 gen_mtc0(env, ctx, t0, rd, sel);
ead9360e
TS
6773 }
6774 } else switch (sel) {
6775 /* GPR registers. */
6776 case 0:
895c2d04 6777 gen_helper_0e1i(mttgpr, t0, rd);
ead9360e
TS
6778 break;
6779 /* Auxiliary CPU registers */
6780 case 1:
6781 switch (rd) {
6782 case 0:
895c2d04 6783 gen_helper_0e1i(mttlo, t0, 0);
ead9360e
TS
6784 break;
6785 case 1:
895c2d04 6786 gen_helper_0e1i(mtthi, t0, 0);
ead9360e
TS
6787 break;
6788 case 2:
895c2d04 6789 gen_helper_0e1i(mttacx, t0, 0);
ead9360e
TS
6790 break;
6791 case 4:
895c2d04 6792 gen_helper_0e1i(mttlo, t0, 1);
ead9360e
TS
6793 break;
6794 case 5:
895c2d04 6795 gen_helper_0e1i(mtthi, t0, 1);
ead9360e
TS
6796 break;
6797 case 6:
895c2d04 6798 gen_helper_0e1i(mttacx, t0, 1);
ead9360e
TS
6799 break;
6800 case 8:
895c2d04 6801 gen_helper_0e1i(mttlo, t0, 2);
ead9360e
TS
6802 break;
6803 case 9:
895c2d04 6804 gen_helper_0e1i(mtthi, t0, 2);
ead9360e
TS
6805 break;
6806 case 10:
895c2d04 6807 gen_helper_0e1i(mttacx, t0, 2);
ead9360e
TS
6808 break;
6809 case 12:
895c2d04 6810 gen_helper_0e1i(mttlo, t0, 3);
ead9360e
TS
6811 break;
6812 case 13:
895c2d04 6813 gen_helper_0e1i(mtthi, t0, 3);
ead9360e
TS
6814 break;
6815 case 14:
895c2d04 6816 gen_helper_0e1i(mttacx, t0, 3);
ead9360e
TS
6817 break;
6818 case 16:
895c2d04 6819 gen_helper_mttdsp(cpu_env, t0);
ead9360e
TS
6820 break;
6821 default:
6822 goto die;
6823 }
6824 break;
6825 /* Floating point (COP1). */
6826 case 2:
6827 /* XXX: For now we support only a single FPU context. */
6828 if (h == 0) {
a7812ae4 6829 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6830
6831 tcg_gen_trunc_tl_i32(fp0, t0);
6832 gen_store_fpr32(fp0, rd);
a7812ae4 6833 tcg_temp_free_i32(fp0);
ead9360e 6834 } else {
a7812ae4 6835 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
6836
6837 tcg_gen_trunc_tl_i32(fp0, t0);
6838 gen_store_fpr32h(fp0, rd);
a7812ae4 6839 tcg_temp_free_i32(fp0);
ead9360e
TS
6840 }
6841 break;
6842 case 3:
6843 /* XXX: For now we support only a single FPU context. */
895c2d04 6844 gen_helper_0e1i(ctc1, t0, rd);
ead9360e
TS
6845 break;
6846 /* COP2: Not implemented. */
6847 case 4:
6848 case 5:
6849 /* fall through */
6850 default:
6851 goto die;
6852 }
d12d51d5 6853 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1a3fd9c3 6854 tcg_temp_free(t0);
ead9360e
TS
6855 return;
6856
6857die:
1a3fd9c3 6858 tcg_temp_free(t0);
d12d51d5 6859 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
ead9360e
TS
6860 generate_exception(ctx, EXCP_RI);
6861}
6862
7db13fae 6863static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6af0bf9c 6864{
287c4b84 6865 const char *opn = "ldst";
6af0bf9c 6866
2e15497c 6867 check_cp0_enabled(ctx);
6af0bf9c
FB
6868 switch (opc) {
6869 case OPC_MFC0:
6870 if (rt == 0) {
ead9360e 6871 /* Treat as NOP. */
6af0bf9c
FB
6872 return;
6873 }
1fc7bf6e 6874 gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6af0bf9c
FB
6875 opn = "mfc0";
6876 break;
6877 case OPC_MTC0:
1a3fd9c3 6878 {
1fc7bf6e 6879 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6880
6881 gen_load_gpr(t0, rt);
1a3fd9c3
TS
6882 gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6883 tcg_temp_free(t0);
6884 }
6af0bf9c
FB
6885 opn = "mtc0";
6886 break;
d26bc211 6887#if defined(TARGET_MIPS64)
9c2149c8 6888 case OPC_DMFC0:
e189e748 6889 check_insn(env, ctx, ISA_MIPS3);
9c2149c8 6890 if (rt == 0) {
ead9360e 6891 /* Treat as NOP. */
9c2149c8
TS
6892 return;
6893 }
1fc7bf6e 6894 gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9c2149c8
TS
6895 opn = "dmfc0";
6896 break;
6897 case OPC_DMTC0:
e189e748 6898 check_insn(env, ctx, ISA_MIPS3);
1a3fd9c3 6899 {
1fc7bf6e 6900 TCGv t0 = tcg_temp_new();
1a3fd9c3
TS
6901
6902 gen_load_gpr(t0, rt);
1a3fd9c3
TS
6903 gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
6904 tcg_temp_free(t0);
6905 }
9c2149c8
TS
6906 opn = "dmtc0";
6907 break;
534ce69f 6908#endif
ead9360e 6909 case OPC_MFTR:
7385ac0b 6910 check_insn(env, ctx, ASE_MT);
ead9360e
TS
6911 if (rd == 0) {
6912 /* Treat as NOP. */
6913 return;
6914 }
6c5c1e20 6915 gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
ead9360e 6916 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
ead9360e
TS
6917 opn = "mftr";
6918 break;
6919 case OPC_MTTR:
7385ac0b 6920 check_insn(env, ctx, ASE_MT);
6c5c1e20 6921 gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
ead9360e
TS
6922 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6923 opn = "mttr";
6924 break;
6af0bf9c 6925 case OPC_TLBWI:
6af0bf9c 6926 opn = "tlbwi";
c01fccd2 6927 if (!env->tlb->helper_tlbwi)
29929e34 6928 goto die;
895c2d04 6929 gen_helper_tlbwi(cpu_env);
6af0bf9c
FB
6930 break;
6931 case OPC_TLBWR:
6af0bf9c 6932 opn = "tlbwr";
c01fccd2 6933 if (!env->tlb->helper_tlbwr)
29929e34 6934 goto die;
895c2d04 6935 gen_helper_tlbwr(cpu_env);
6af0bf9c
FB
6936 break;
6937 case OPC_TLBP:
6af0bf9c 6938 opn = "tlbp";
c01fccd2 6939 if (!env->tlb->helper_tlbp)
29929e34 6940 goto die;
895c2d04 6941 gen_helper_tlbp(cpu_env);
6af0bf9c
FB
6942 break;
6943 case OPC_TLBR:
6af0bf9c 6944 opn = "tlbr";
c01fccd2 6945 if (!env->tlb->helper_tlbr)
29929e34 6946 goto die;
895c2d04 6947 gen_helper_tlbr(cpu_env);
6af0bf9c 6948 break;
6af0bf9c
FB
6949 case OPC_ERET:
6950 opn = "eret";
e189e748 6951 check_insn(env, ctx, ISA_MIPS2);
895c2d04 6952 gen_helper_eret(cpu_env);
6af0bf9c
FB
6953 ctx->bstate = BS_EXCP;
6954 break;
6955 case OPC_DERET:
6956 opn = "deret";
e189e748 6957 check_insn(env, ctx, ISA_MIPS32);
6af0bf9c 6958 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
923617a3 6959 MIPS_INVAL(opn);
6af0bf9c
FB
6960 generate_exception(ctx, EXCP_RI);
6961 } else {
895c2d04 6962 gen_helper_deret(cpu_env);
6af0bf9c
FB
6963 ctx->bstate = BS_EXCP;
6964 }
6965 break;
4ad40f36
FB
6966 case OPC_WAIT:
6967 opn = "wait";
e189e748 6968 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
4ad40f36
FB
6969 /* If we get an exception, we want to restart at next instruction */
6970 ctx->pc += 4;
6971 save_cpu_state(ctx, 1);
6972 ctx->pc -= 4;
895c2d04 6973 gen_helper_wait(cpu_env);
4ad40f36
FB
6974 ctx->bstate = BS_EXCP;
6975 break;
6af0bf9c 6976 default:
29929e34 6977 die:
923617a3 6978 MIPS_INVAL(opn);
6af0bf9c
FB
6979 generate_exception(ctx, EXCP_RI);
6980 return;
6981 }
2abf314d 6982 (void)opn; /* avoid a compiler warning */
6af0bf9c
FB
6983 MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6984}
f1aa6320 6985#endif /* !CONFIG_USER_ONLY */
6af0bf9c 6986
6ea83fed 6987/* CP1 Branches (before delay slot) */
7db13fae 6988static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
5a5012ec 6989 int32_t cc, int32_t offset)
6ea83fed
FB
6990{
6991 target_ulong btarget;
923617a3 6992 const char *opn = "cp1 cond branch";
a7812ae4 6993 TCGv_i32 t0 = tcg_temp_new_i32();
6ea83fed 6994
e189e748
TS
6995 if (cc != 0)
6996 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
6997
6ea83fed
FB
6998 btarget = ctx->pc + 4 + offset;
6999
7a387fff
TS
7000 switch (op) {
7001 case OPC_BC1F:
d94536f4
AJ
7002 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7003 tcg_gen_not_i32(t0, t0);
7004 tcg_gen_andi_i32(t0, t0, 1);
7005 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7006 opn = "bc1f";
6ea83fed 7007 goto not_likely;
7a387fff 7008 case OPC_BC1FL:
d94536f4
AJ
7009 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7010 tcg_gen_not_i32(t0, t0);
7011 tcg_gen_andi_i32(t0, t0, 1);
7012 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7013 opn = "bc1fl";
6ea83fed 7014 goto likely;
7a387fff 7015 case OPC_BC1T:
d94536f4
AJ
7016 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7017 tcg_gen_andi_i32(t0, t0, 1);
7018 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7019 opn = "bc1t";
5a5012ec 7020 goto not_likely;
7a387fff 7021 case OPC_BC1TL:
d94536f4
AJ
7022 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7023 tcg_gen_andi_i32(t0, t0, 1);
7024 tcg_gen_extu_i32_tl(bcond, t0);
923617a3 7025 opn = "bc1tl";
6ea83fed
FB
7026 likely:
7027 ctx->hflags |= MIPS_HFLAG_BL;
7028 break;
5a5012ec 7029 case OPC_BC1FANY2:
a16336e4 7030 {
d94536f4
AJ
7031 TCGv_i32 t1 = tcg_temp_new_i32();
7032 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7033 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7034 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7035 tcg_temp_free_i32(t1);
d94536f4
AJ
7036 tcg_gen_andi_i32(t0, t0, 1);
7037 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7038 }
fd4a04eb 7039 opn = "bc1any2f";
5a5012ec
TS
7040 goto not_likely;
7041 case OPC_BC1TANY2:
a16336e4 7042 {
d94536f4
AJ
7043 TCGv_i32 t1 = tcg_temp_new_i32();
7044 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7045 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7046 tcg_gen_or_i32(t0, t0, t1);
7047 tcg_temp_free_i32(t1);
7048 tcg_gen_andi_i32(t0, t0, 1);
7049 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7050 }
fd4a04eb 7051 opn = "bc1any2t";
5a5012ec
TS
7052 goto not_likely;
7053 case OPC_BC1FANY4:
a16336e4 7054 {
d94536f4
AJ
7055 TCGv_i32 t1 = tcg_temp_new_i32();
7056 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7057 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
d7f66b52 7058 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7059 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
d7f66b52 7060 tcg_gen_and_i32(t0, t0, t1);
d94536f4 7061 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
d7f66b52 7062 tcg_gen_nand_i32(t0, t0, t1);
d94536f4 7063 tcg_temp_free_i32(t1);
d94536f4
AJ
7064 tcg_gen_andi_i32(t0, t0, 1);
7065 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7066 }
fd4a04eb 7067 opn = "bc1any4f";
5a5012ec
TS
7068 goto not_likely;
7069 case OPC_BC1TANY4:
a16336e4 7070 {
d94536f4
AJ
7071 TCGv_i32 t1 = tcg_temp_new_i32();
7072 tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7073 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7074 tcg_gen_or_i32(t0, t0, t1);
7075 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7076 tcg_gen_or_i32(t0, t0, t1);
7077 tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7078 tcg_gen_or_i32(t0, t0, t1);
7079 tcg_temp_free_i32(t1);
7080 tcg_gen_andi_i32(t0, t0, 1);
7081 tcg_gen_extu_i32_tl(bcond, t0);
a16336e4 7082 }
fd4a04eb 7083 opn = "bc1any4t";
5a5012ec
TS
7084 not_likely:
7085 ctx->hflags |= MIPS_HFLAG_BC;
5a5012ec
TS
7086 break;
7087 default:
923617a3 7088 MIPS_INVAL(opn);
e397ee33 7089 generate_exception (ctx, EXCP_RI);
6c5c1e20 7090 goto out;
6ea83fed 7091 }
2abf314d 7092 (void)opn; /* avoid a compiler warning */
923617a3 7093 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
6ea83fed
FB
7094 ctx->hflags, btarget);
7095 ctx->btarget = btarget;
6c5c1e20
TS
7096
7097 out:
a7812ae4 7098 tcg_temp_free_i32(t0);
6ea83fed
FB
7099}
7100
6af0bf9c 7101/* Coprocessor 1 (FPU) */
5a5012ec 7102
5a5012ec
TS
7103#define FOP(func, fmt) (((fmt) << 21) | (func))
7104
bf4120ad
NF
7105enum fopcode {
7106 OPC_ADD_S = FOP(0, FMT_S),
7107 OPC_SUB_S = FOP(1, FMT_S),
7108 OPC_MUL_S = FOP(2, FMT_S),
7109 OPC_DIV_S = FOP(3, FMT_S),
7110 OPC_SQRT_S = FOP(4, FMT_S),
7111 OPC_ABS_S = FOP(5, FMT_S),
7112 OPC_MOV_S = FOP(6, FMT_S),
7113 OPC_NEG_S = FOP(7, FMT_S),
7114 OPC_ROUND_L_S = FOP(8, FMT_S),
7115 OPC_TRUNC_L_S = FOP(9, FMT_S),
7116 OPC_CEIL_L_S = FOP(10, FMT_S),
7117 OPC_FLOOR_L_S = FOP(11, FMT_S),
7118 OPC_ROUND_W_S = FOP(12, FMT_S),
7119 OPC_TRUNC_W_S = FOP(13, FMT_S),
7120 OPC_CEIL_W_S = FOP(14, FMT_S),
7121 OPC_FLOOR_W_S = FOP(15, FMT_S),
7122 OPC_MOVCF_S = FOP(17, FMT_S),
7123 OPC_MOVZ_S = FOP(18, FMT_S),
7124 OPC_MOVN_S = FOP(19, FMT_S),
7125 OPC_RECIP_S = FOP(21, FMT_S),
7126 OPC_RSQRT_S = FOP(22, FMT_S),
7127 OPC_RECIP2_S = FOP(28, FMT_S),
7128 OPC_RECIP1_S = FOP(29, FMT_S),
7129 OPC_RSQRT1_S = FOP(30, FMT_S),
7130 OPC_RSQRT2_S = FOP(31, FMT_S),
7131 OPC_CVT_D_S = FOP(33, FMT_S),
7132 OPC_CVT_W_S = FOP(36, FMT_S),
7133 OPC_CVT_L_S = FOP(37, FMT_S),
7134 OPC_CVT_PS_S = FOP(38, FMT_S),
7135 OPC_CMP_F_S = FOP (48, FMT_S),
7136 OPC_CMP_UN_S = FOP (49, FMT_S),
7137 OPC_CMP_EQ_S = FOP (50, FMT_S),
7138 OPC_CMP_UEQ_S = FOP (51, FMT_S),
7139 OPC_CMP_OLT_S = FOP (52, FMT_S),
7140 OPC_CMP_ULT_S = FOP (53, FMT_S),
7141 OPC_CMP_OLE_S = FOP (54, FMT_S),
7142 OPC_CMP_ULE_S = FOP (55, FMT_S),
7143 OPC_CMP_SF_S = FOP (56, FMT_S),
7144 OPC_CMP_NGLE_S = FOP (57, FMT_S),
7145 OPC_CMP_SEQ_S = FOP (58, FMT_S),
7146 OPC_CMP_NGL_S = FOP (59, FMT_S),
7147 OPC_CMP_LT_S = FOP (60, FMT_S),
7148 OPC_CMP_NGE_S = FOP (61, FMT_S),
7149 OPC_CMP_LE_S = FOP (62, FMT_S),
7150 OPC_CMP_NGT_S = FOP (63, FMT_S),
7151
7152 OPC_ADD_D = FOP(0, FMT_D),
7153 OPC_SUB_D = FOP(1, FMT_D),
7154 OPC_MUL_D = FOP(2, FMT_D),
7155 OPC_DIV_D = FOP(3, FMT_D),
7156 OPC_SQRT_D = FOP(4, FMT_D),
7157 OPC_ABS_D = FOP(5, FMT_D),
7158 OPC_MOV_D = FOP(6, FMT_D),
7159 OPC_NEG_D = FOP(7, FMT_D),
7160 OPC_ROUND_L_D = FOP(8, FMT_D),
7161 OPC_TRUNC_L_D = FOP(9, FMT_D),
7162 OPC_CEIL_L_D = FOP(10, FMT_D),
7163 OPC_FLOOR_L_D = FOP(11, FMT_D),
7164 OPC_ROUND_W_D = FOP(12, FMT_D),
7165 OPC_TRUNC_W_D = FOP(13, FMT_D),
7166 OPC_CEIL_W_D = FOP(14, FMT_D),
7167 OPC_FLOOR_W_D = FOP(15, FMT_D),
7168 OPC_MOVCF_D = FOP(17, FMT_D),
7169 OPC_MOVZ_D = FOP(18, FMT_D),
7170 OPC_MOVN_D = FOP(19, FMT_D),
7171 OPC_RECIP_D = FOP(21, FMT_D),
7172 OPC_RSQRT_D = FOP(22, FMT_D),
7173 OPC_RECIP2_D = FOP(28, FMT_D),
7174 OPC_RECIP1_D = FOP(29, FMT_D),
7175 OPC_RSQRT1_D = FOP(30, FMT_D),
7176 OPC_RSQRT2_D = FOP(31, FMT_D),
7177 OPC_CVT_S_D = FOP(32, FMT_D),
7178 OPC_CVT_W_D = FOP(36, FMT_D),
7179 OPC_CVT_L_D = FOP(37, FMT_D),
7180 OPC_CMP_F_D = FOP (48, FMT_D),
7181 OPC_CMP_UN_D = FOP (49, FMT_D),
7182 OPC_CMP_EQ_D = FOP (50, FMT_D),
7183 OPC_CMP_UEQ_D = FOP (51, FMT_D),
7184 OPC_CMP_OLT_D = FOP (52, FMT_D),
7185 OPC_CMP_ULT_D = FOP (53, FMT_D),
7186 OPC_CMP_OLE_D = FOP (54, FMT_D),
7187 OPC_CMP_ULE_D = FOP (55, FMT_D),
7188 OPC_CMP_SF_D = FOP (56, FMT_D),
7189 OPC_CMP_NGLE_D = FOP (57, FMT_D),
7190 OPC_CMP_SEQ_D = FOP (58, FMT_D),
7191 OPC_CMP_NGL_D = FOP (59, FMT_D),
7192 OPC_CMP_LT_D = FOP (60, FMT_D),
7193 OPC_CMP_NGE_D = FOP (61, FMT_D),
7194 OPC_CMP_LE_D = FOP (62, FMT_D),
7195 OPC_CMP_NGT_D = FOP (63, FMT_D),
7196
7197 OPC_CVT_S_W = FOP(32, FMT_W),
7198 OPC_CVT_D_W = FOP(33, FMT_W),
7199 OPC_CVT_S_L = FOP(32, FMT_L),
7200 OPC_CVT_D_L = FOP(33, FMT_L),
7201 OPC_CVT_PS_PW = FOP(38, FMT_W),
7202
7203 OPC_ADD_PS = FOP(0, FMT_PS),
7204 OPC_SUB_PS = FOP(1, FMT_PS),
7205 OPC_MUL_PS = FOP(2, FMT_PS),
7206 OPC_DIV_PS = FOP(3, FMT_PS),
7207 OPC_ABS_PS = FOP(5, FMT_PS),
7208 OPC_MOV_PS = FOP(6, FMT_PS),
7209 OPC_NEG_PS = FOP(7, FMT_PS),
7210 OPC_MOVCF_PS = FOP(17, FMT_PS),
7211 OPC_MOVZ_PS = FOP(18, FMT_PS),
7212 OPC_MOVN_PS = FOP(19, FMT_PS),
7213 OPC_ADDR_PS = FOP(24, FMT_PS),
7214 OPC_MULR_PS = FOP(26, FMT_PS),
7215 OPC_RECIP2_PS = FOP(28, FMT_PS),
7216 OPC_RECIP1_PS = FOP(29, FMT_PS),
7217 OPC_RSQRT1_PS = FOP(30, FMT_PS),
7218 OPC_RSQRT2_PS = FOP(31, FMT_PS),
7219
7220 OPC_CVT_S_PU = FOP(32, FMT_PS),
7221 OPC_CVT_PW_PS = FOP(36, FMT_PS),
7222 OPC_CVT_S_PL = FOP(40, FMT_PS),
7223 OPC_PLL_PS = FOP(44, FMT_PS),
7224 OPC_PLU_PS = FOP(45, FMT_PS),
7225 OPC_PUL_PS = FOP(46, FMT_PS),
7226 OPC_PUU_PS = FOP(47, FMT_PS),
7227 OPC_CMP_F_PS = FOP (48, FMT_PS),
7228 OPC_CMP_UN_PS = FOP (49, FMT_PS),
7229 OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7230 OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7231 OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7232 OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7233 OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7234 OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7235 OPC_CMP_SF_PS = FOP (56, FMT_PS),
7236 OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7237 OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7238 OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7239 OPC_CMP_LT_PS = FOP (60, FMT_PS),
7240 OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7241 OPC_CMP_LE_PS = FOP (62, FMT_PS),
7242 OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7243};
7244
7a387fff 7245static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
6ea83fed 7246{
923617a3 7247 const char *opn = "cp1 move";
72c3a3ee 7248 TCGv t0 = tcg_temp_new();
6ea83fed
FB
7249
7250 switch (opc) {
7251 case OPC_MFC1:
b6d96bed 7252 {
a7812ae4 7253 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7254
7255 gen_load_fpr32(fp0, fs);
7256 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7257 tcg_temp_free_i32(fp0);
6958549d 7258 }
6c5c1e20 7259 gen_store_gpr(t0, rt);
6ea83fed
FB
7260 opn = "mfc1";
7261 break;
7262 case OPC_MTC1:
6c5c1e20 7263 gen_load_gpr(t0, rt);
b6d96bed 7264 {
a7812ae4 7265 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7266
7267 tcg_gen_trunc_tl_i32(fp0, t0);
7268 gen_store_fpr32(fp0, fs);
a7812ae4 7269 tcg_temp_free_i32(fp0);
6958549d 7270 }
6ea83fed
FB
7271 opn = "mtc1";
7272 break;
7273 case OPC_CFC1:
895c2d04 7274 gen_helper_1e0i(cfc1, t0, fs);
6c5c1e20 7275 gen_store_gpr(t0, rt);
6ea83fed
FB
7276 opn = "cfc1";
7277 break;
7278 case OPC_CTC1:
6c5c1e20 7279 gen_load_gpr(t0, rt);
895c2d04 7280 gen_helper_0e1i(ctc1, t0, fs);
6ea83fed
FB
7281 opn = "ctc1";
7282 break;
72c3a3ee 7283#if defined(TARGET_MIPS64)
9c2149c8 7284 case OPC_DMFC1:
72c3a3ee 7285 gen_load_fpr64(ctx, t0, fs);
6c5c1e20 7286 gen_store_gpr(t0, rt);
5a5012ec
TS
7287 opn = "dmfc1";
7288 break;
9c2149c8 7289 case OPC_DMTC1:
6c5c1e20 7290 gen_load_gpr(t0, rt);
72c3a3ee 7291 gen_store_fpr64(ctx, t0, fs);
5a5012ec
TS
7292 opn = "dmtc1";
7293 break;
72c3a3ee 7294#endif
5a5012ec 7295 case OPC_MFHC1:
b6d96bed 7296 {
a7812ae4 7297 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7298
7299 gen_load_fpr32h(fp0, fs);
7300 tcg_gen_ext_i32_tl(t0, fp0);
a7812ae4 7301 tcg_temp_free_i32(fp0);
6958549d 7302 }
6c5c1e20 7303 gen_store_gpr(t0, rt);
5a5012ec
TS
7304 opn = "mfhc1";
7305 break;
7306 case OPC_MTHC1:
6c5c1e20 7307 gen_load_gpr(t0, rt);
b6d96bed 7308 {
a7812ae4 7309 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7310
7311 tcg_gen_trunc_tl_i32(fp0, t0);
7312 gen_store_fpr32h(fp0, fs);
a7812ae4 7313 tcg_temp_free_i32(fp0);
6958549d 7314 }
5a5012ec
TS
7315 opn = "mthc1";
7316 break;
6ea83fed 7317 default:
923617a3 7318 MIPS_INVAL(opn);
e397ee33 7319 generate_exception (ctx, EXCP_RI);
6c5c1e20 7320 goto out;
6ea83fed 7321 }
2abf314d 7322 (void)opn; /* avoid a compiler warning */
6ea83fed 7323 MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
6c5c1e20
TS
7324
7325 out:
7326 tcg_temp_free(t0);
6ea83fed
FB
7327}
7328
5a5012ec
TS
7329static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7330{
af58f9ca 7331 int l1;
e214b9bb 7332 TCGCond cond;
af58f9ca
AJ
7333 TCGv_i32 t0;
7334
7335 if (rd == 0) {
7336 /* Treat as NOP. */
7337 return;
7338 }
6ea83fed 7339
e214b9bb 7340 if (tf)
e214b9bb 7341 cond = TCG_COND_EQ;
27848470
TS
7342 else
7343 cond = TCG_COND_NE;
7344
af58f9ca
AJ
7345 l1 = gen_new_label();
7346 t0 = tcg_temp_new_i32();
fa31af0e 7347 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
af58f9ca 7348 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7349 tcg_temp_free_i32(t0);
af58f9ca
AJ
7350 if (rs == 0) {
7351 tcg_gen_movi_tl(cpu_gpr[rd], 0);
7352 } else {
7353 tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7354 }
e214b9bb 7355 gen_set_label(l1);
5a5012ec
TS
7356}
7357
b6d96bed 7358static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
a16336e4 7359{
a16336e4 7360 int cond;
cbc37b28 7361 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7362 int l1 = gen_new_label();
7363
a16336e4
TS
7364 if (tf)
7365 cond = TCG_COND_EQ;
7366 else
7367 cond = TCG_COND_NE;
7368
fa31af0e 7369 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7370 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7371 gen_load_fpr32(t0, fs);
7372 gen_store_fpr32(t0, fd);
a16336e4 7373 gen_set_label(l1);
cbc37b28 7374 tcg_temp_free_i32(t0);
5a5012ec 7375}
a16336e4 7376
b6d96bed 7377static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
a16336e4 7378{
a16336e4 7379 int cond;
cbc37b28
AJ
7380 TCGv_i32 t0 = tcg_temp_new_i32();
7381 TCGv_i64 fp0;
a16336e4
TS
7382 int l1 = gen_new_label();
7383
a16336e4
TS
7384 if (tf)
7385 cond = TCG_COND_EQ;
7386 else
7387 cond = TCG_COND_NE;
7388
fa31af0e 7389 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28 7390 tcg_gen_brcondi_i32(cond, t0, 0, l1);
a4e8338d 7391 tcg_temp_free_i32(t0);
11f94258 7392 fp0 = tcg_temp_new_i64();
9bf3eb2c 7393 gen_load_fpr64(ctx, fp0, fs);
9bf3eb2c 7394 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7395 tcg_temp_free_i64(fp0);
cbc37b28 7396 gen_set_label(l1);
a16336e4
TS
7397}
7398
b6d96bed 7399static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
a16336e4
TS
7400{
7401 int cond;
cbc37b28 7402 TCGv_i32 t0 = tcg_temp_new_i32();
a16336e4
TS
7403 int l1 = gen_new_label();
7404 int l2 = gen_new_label();
7405
7406 if (tf)
7407 cond = TCG_COND_EQ;
7408 else
7409 cond = TCG_COND_NE;
7410
fa31af0e 7411 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
cbc37b28
AJ
7412 tcg_gen_brcondi_i32(cond, t0, 0, l1);
7413 gen_load_fpr32(t0, fs);
7414 gen_store_fpr32(t0, fd);
a16336e4 7415 gen_set_label(l1);
9bf3eb2c 7416
fa31af0e 7417 tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
cbc37b28
AJ
7418 tcg_gen_brcondi_i32(cond, t0, 0, l2);
7419 gen_load_fpr32h(t0, fs);
7420 gen_store_fpr32h(t0, fd);
52a0e9eb 7421 tcg_temp_free_i32(t0);
a16336e4 7422 gen_set_label(l2);
a16336e4
TS
7423}
7424
6ea83fed 7425
bf4120ad 7426static void gen_farith (DisasContext *ctx, enum fopcode op1,
5e755519 7427 int ft, int fs, int fd, int cc)
6ea83fed 7428{
923617a3 7429 const char *opn = "farith";
6ea83fed
FB
7430 const char *condnames[] = {
7431 "c.f",
7432 "c.un",
7433 "c.eq",
7434 "c.ueq",
7435 "c.olt",
7436 "c.ult",
7437 "c.ole",
7438 "c.ule",
7439 "c.sf",
7440 "c.ngle",
7441 "c.seq",
7442 "c.ngl",
7443 "c.lt",
7444 "c.nge",
7445 "c.le",
7446 "c.ngt",
7447 };
5a1e8ffb
TS
7448 const char *condnames_abs[] = {
7449 "cabs.f",
7450 "cabs.un",
7451 "cabs.eq",
7452 "cabs.ueq",
7453 "cabs.olt",
7454 "cabs.ult",
7455 "cabs.ole",
7456 "cabs.ule",
7457 "cabs.sf",
7458 "cabs.ngle",
7459 "cabs.seq",
7460 "cabs.ngl",
7461 "cabs.lt",
7462 "cabs.nge",
7463 "cabs.le",
7464 "cabs.ngt",
7465 };
7466 enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7a387fff
TS
7467 uint32_t func = ctx->opcode & 0x3f;
7468
bf4120ad
NF
7469 switch (op1) {
7470 case OPC_ADD_S:
b6d96bed 7471 {
a7812ae4
PB
7472 TCGv_i32 fp0 = tcg_temp_new_i32();
7473 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7474
7475 gen_load_fpr32(fp0, fs);
7476 gen_load_fpr32(fp1, ft);
895c2d04 7477 gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7478 tcg_temp_free_i32(fp1);
b6d96bed 7479 gen_store_fpr32(fp0, fd);
a7812ae4 7480 tcg_temp_free_i32(fp0);
b6d96bed 7481 }
5a5012ec 7482 opn = "add.s";
5a1e8ffb 7483 optype = BINOP;
5a5012ec 7484 break;
bf4120ad 7485 case OPC_SUB_S:
b6d96bed 7486 {
a7812ae4
PB
7487 TCGv_i32 fp0 = tcg_temp_new_i32();
7488 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7489
7490 gen_load_fpr32(fp0, fs);
7491 gen_load_fpr32(fp1, ft);
895c2d04 7492 gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7493 tcg_temp_free_i32(fp1);
b6d96bed 7494 gen_store_fpr32(fp0, fd);
a7812ae4 7495 tcg_temp_free_i32(fp0);
b6d96bed 7496 }
5a5012ec 7497 opn = "sub.s";
5a1e8ffb 7498 optype = BINOP;
5a5012ec 7499 break;
bf4120ad 7500 case OPC_MUL_S:
b6d96bed 7501 {
a7812ae4
PB
7502 TCGv_i32 fp0 = tcg_temp_new_i32();
7503 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7504
7505 gen_load_fpr32(fp0, fs);
7506 gen_load_fpr32(fp1, ft);
895c2d04 7507 gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7508 tcg_temp_free_i32(fp1);
b6d96bed 7509 gen_store_fpr32(fp0, fd);
a7812ae4 7510 tcg_temp_free_i32(fp0);
b6d96bed 7511 }
5a5012ec 7512 opn = "mul.s";
5a1e8ffb 7513 optype = BINOP;
5a5012ec 7514 break;
bf4120ad 7515 case OPC_DIV_S:
b6d96bed 7516 {
a7812ae4
PB
7517 TCGv_i32 fp0 = tcg_temp_new_i32();
7518 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7519
7520 gen_load_fpr32(fp0, fs);
7521 gen_load_fpr32(fp1, ft);
895c2d04 7522 gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7523 tcg_temp_free_i32(fp1);
b6d96bed 7524 gen_store_fpr32(fp0, fd);
a7812ae4 7525 tcg_temp_free_i32(fp0);
b6d96bed 7526 }
5a5012ec 7527 opn = "div.s";
5a1e8ffb 7528 optype = BINOP;
5a5012ec 7529 break;
bf4120ad 7530 case OPC_SQRT_S:
b6d96bed 7531 {
a7812ae4 7532 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7533
7534 gen_load_fpr32(fp0, fs);
895c2d04 7535 gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
b6d96bed 7536 gen_store_fpr32(fp0, fd);
a7812ae4 7537 tcg_temp_free_i32(fp0);
b6d96bed 7538 }
5a5012ec
TS
7539 opn = "sqrt.s";
7540 break;
bf4120ad 7541 case OPC_ABS_S:
b6d96bed 7542 {
a7812ae4 7543 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7544
7545 gen_load_fpr32(fp0, fs);
a7812ae4 7546 gen_helper_float_abs_s(fp0, fp0);
b6d96bed 7547 gen_store_fpr32(fp0, fd);
a7812ae4 7548 tcg_temp_free_i32(fp0);
b6d96bed 7549 }
5a5012ec
TS
7550 opn = "abs.s";
7551 break;
bf4120ad 7552 case OPC_MOV_S:
b6d96bed 7553 {
a7812ae4 7554 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7555
7556 gen_load_fpr32(fp0, fs);
7557 gen_store_fpr32(fp0, fd);
a7812ae4 7558 tcg_temp_free_i32(fp0);
b6d96bed 7559 }
5a5012ec
TS
7560 opn = "mov.s";
7561 break;
bf4120ad 7562 case OPC_NEG_S:
b6d96bed 7563 {
a7812ae4 7564 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7565
7566 gen_load_fpr32(fp0, fs);
a7812ae4 7567 gen_helper_float_chs_s(fp0, fp0);
b6d96bed 7568 gen_store_fpr32(fp0, fd);
a7812ae4 7569 tcg_temp_free_i32(fp0);
b6d96bed 7570 }
5a5012ec
TS
7571 opn = "neg.s";
7572 break;
bf4120ad 7573 case OPC_ROUND_L_S:
5e755519 7574 check_cp1_64bitmode(ctx);
b6d96bed 7575 {
a7812ae4
PB
7576 TCGv_i32 fp32 = tcg_temp_new_i32();
7577 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7578
7579 gen_load_fpr32(fp32, fs);
895c2d04 7580 gen_helper_float_roundl_s(fp64, cpu_env, fp32);
a7812ae4 7581 tcg_temp_free_i32(fp32);
b6d96bed 7582 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7583 tcg_temp_free_i64(fp64);
b6d96bed 7584 }
5a5012ec
TS
7585 opn = "round.l.s";
7586 break;
bf4120ad 7587 case OPC_TRUNC_L_S:
5e755519 7588 check_cp1_64bitmode(ctx);
b6d96bed 7589 {
a7812ae4
PB
7590 TCGv_i32 fp32 = tcg_temp_new_i32();
7591 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7592
7593 gen_load_fpr32(fp32, fs);
895c2d04 7594 gen_helper_float_truncl_s(fp64, cpu_env, fp32);
a7812ae4 7595 tcg_temp_free_i32(fp32);
b6d96bed 7596 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7597 tcg_temp_free_i64(fp64);
b6d96bed 7598 }
5a5012ec
TS
7599 opn = "trunc.l.s";
7600 break;
bf4120ad 7601 case OPC_CEIL_L_S:
5e755519 7602 check_cp1_64bitmode(ctx);
b6d96bed 7603 {
a7812ae4
PB
7604 TCGv_i32 fp32 = tcg_temp_new_i32();
7605 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7606
7607 gen_load_fpr32(fp32, fs);
895c2d04 7608 gen_helper_float_ceill_s(fp64, cpu_env, fp32);
a7812ae4 7609 tcg_temp_free_i32(fp32);
b6d96bed 7610 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7611 tcg_temp_free_i64(fp64);
b6d96bed 7612 }
5a5012ec
TS
7613 opn = "ceil.l.s";
7614 break;
bf4120ad 7615 case OPC_FLOOR_L_S:
5e755519 7616 check_cp1_64bitmode(ctx);
b6d96bed 7617 {
a7812ae4
PB
7618 TCGv_i32 fp32 = tcg_temp_new_i32();
7619 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7620
7621 gen_load_fpr32(fp32, fs);
895c2d04 7622 gen_helper_float_floorl_s(fp64, cpu_env, fp32);
a7812ae4 7623 tcg_temp_free_i32(fp32);
b6d96bed 7624 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7625 tcg_temp_free_i64(fp64);
b6d96bed 7626 }
5a5012ec
TS
7627 opn = "floor.l.s";
7628 break;
bf4120ad 7629 case OPC_ROUND_W_S:
b6d96bed 7630 {
a7812ae4 7631 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7632
7633 gen_load_fpr32(fp0, fs);
895c2d04 7634 gen_helper_float_roundw_s(fp0, cpu_env, fp0);
b6d96bed 7635 gen_store_fpr32(fp0, fd);
a7812ae4 7636 tcg_temp_free_i32(fp0);
b6d96bed 7637 }
5a5012ec
TS
7638 opn = "round.w.s";
7639 break;
bf4120ad 7640 case OPC_TRUNC_W_S:
b6d96bed 7641 {
a7812ae4 7642 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7643
7644 gen_load_fpr32(fp0, fs);
895c2d04 7645 gen_helper_float_truncw_s(fp0, cpu_env, fp0);
b6d96bed 7646 gen_store_fpr32(fp0, fd);
a7812ae4 7647 tcg_temp_free_i32(fp0);
b6d96bed 7648 }
5a5012ec
TS
7649 opn = "trunc.w.s";
7650 break;
bf4120ad 7651 case OPC_CEIL_W_S:
b6d96bed 7652 {
a7812ae4 7653 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7654
7655 gen_load_fpr32(fp0, fs);
895c2d04 7656 gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
b6d96bed 7657 gen_store_fpr32(fp0, fd);
a7812ae4 7658 tcg_temp_free_i32(fp0);
b6d96bed 7659 }
5a5012ec
TS
7660 opn = "ceil.w.s";
7661 break;
bf4120ad 7662 case OPC_FLOOR_W_S:
b6d96bed 7663 {
a7812ae4 7664 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7665
7666 gen_load_fpr32(fp0, fs);
895c2d04 7667 gen_helper_float_floorw_s(fp0, cpu_env, fp0);
b6d96bed 7668 gen_store_fpr32(fp0, fd);
a7812ae4 7669 tcg_temp_free_i32(fp0);
b6d96bed 7670 }
5a5012ec
TS
7671 opn = "floor.w.s";
7672 break;
bf4120ad 7673 case OPC_MOVCF_S:
b6d96bed 7674 gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec
TS
7675 opn = "movcf.s";
7676 break;
bf4120ad 7677 case OPC_MOVZ_S:
a16336e4
TS
7678 {
7679 int l1 = gen_new_label();
c9297f4d 7680 TCGv_i32 fp0;
a16336e4 7681
c9297f4d
AJ
7682 if (ft != 0) {
7683 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7684 }
7685 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7686 gen_load_fpr32(fp0, fs);
7687 gen_store_fpr32(fp0, fd);
a7812ae4 7688 tcg_temp_free_i32(fp0);
a16336e4
TS
7689 gen_set_label(l1);
7690 }
5a5012ec
TS
7691 opn = "movz.s";
7692 break;
bf4120ad 7693 case OPC_MOVN_S:
a16336e4
TS
7694 {
7695 int l1 = gen_new_label();
c9297f4d
AJ
7696 TCGv_i32 fp0;
7697
7698 if (ft != 0) {
7699 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7700 fp0 = tcg_temp_new_i32();
7701 gen_load_fpr32(fp0, fs);
7702 gen_store_fpr32(fp0, fd);
7703 tcg_temp_free_i32(fp0);
7704 gen_set_label(l1);
7705 }
a16336e4 7706 }
5a5012ec
TS
7707 opn = "movn.s";
7708 break;
bf4120ad 7709 case OPC_RECIP_S:
b8aa4598 7710 check_cop1x(ctx);
b6d96bed 7711 {
a7812ae4 7712 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7713
7714 gen_load_fpr32(fp0, fs);
895c2d04 7715 gen_helper_float_recip_s(fp0, cpu_env, fp0);
b6d96bed 7716 gen_store_fpr32(fp0, fd);
a7812ae4 7717 tcg_temp_free_i32(fp0);
b6d96bed 7718 }
57fa1fb3
TS
7719 opn = "recip.s";
7720 break;
bf4120ad 7721 case OPC_RSQRT_S:
b8aa4598 7722 check_cop1x(ctx);
b6d96bed 7723 {
a7812ae4 7724 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7725
7726 gen_load_fpr32(fp0, fs);
895c2d04 7727 gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
b6d96bed 7728 gen_store_fpr32(fp0, fd);
a7812ae4 7729 tcg_temp_free_i32(fp0);
b6d96bed 7730 }
57fa1fb3
TS
7731 opn = "rsqrt.s";
7732 break;
bf4120ad 7733 case OPC_RECIP2_S:
5e755519 7734 check_cp1_64bitmode(ctx);
b6d96bed 7735 {
a7812ae4
PB
7736 TCGv_i32 fp0 = tcg_temp_new_i32();
7737 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7738
7739 gen_load_fpr32(fp0, fs);
d22d7289 7740 gen_load_fpr32(fp1, ft);
895c2d04 7741 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7742 tcg_temp_free_i32(fp1);
b6d96bed 7743 gen_store_fpr32(fp0, fd);
a7812ae4 7744 tcg_temp_free_i32(fp0);
b6d96bed 7745 }
57fa1fb3
TS
7746 opn = "recip2.s";
7747 break;
bf4120ad 7748 case OPC_RECIP1_S:
5e755519 7749 check_cp1_64bitmode(ctx);
b6d96bed 7750 {
a7812ae4 7751 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7752
7753 gen_load_fpr32(fp0, fs);
895c2d04 7754 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
b6d96bed 7755 gen_store_fpr32(fp0, fd);
a7812ae4 7756 tcg_temp_free_i32(fp0);
b6d96bed 7757 }
57fa1fb3
TS
7758 opn = "recip1.s";
7759 break;
bf4120ad 7760 case OPC_RSQRT1_S:
5e755519 7761 check_cp1_64bitmode(ctx);
b6d96bed 7762 {
a7812ae4 7763 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7764
7765 gen_load_fpr32(fp0, fs);
895c2d04 7766 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
b6d96bed 7767 gen_store_fpr32(fp0, fd);
a7812ae4 7768 tcg_temp_free_i32(fp0);
b6d96bed 7769 }
57fa1fb3
TS
7770 opn = "rsqrt1.s";
7771 break;
bf4120ad 7772 case OPC_RSQRT2_S:
5e755519 7773 check_cp1_64bitmode(ctx);
b6d96bed 7774 {
a7812ae4
PB
7775 TCGv_i32 fp0 = tcg_temp_new_i32();
7776 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
7777
7778 gen_load_fpr32(fp0, fs);
7779 gen_load_fpr32(fp1, ft);
895c2d04 7780 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
a7812ae4 7781 tcg_temp_free_i32(fp1);
b6d96bed 7782 gen_store_fpr32(fp0, fd);
a7812ae4 7783 tcg_temp_free_i32(fp0);
b6d96bed 7784 }
57fa1fb3
TS
7785 opn = "rsqrt2.s";
7786 break;
bf4120ad 7787 case OPC_CVT_D_S:
5e755519 7788 check_cp1_registers(ctx, fd);
b6d96bed 7789 {
a7812ae4
PB
7790 TCGv_i32 fp32 = tcg_temp_new_i32();
7791 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7792
7793 gen_load_fpr32(fp32, fs);
895c2d04 7794 gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
a7812ae4 7795 tcg_temp_free_i32(fp32);
b6d96bed 7796 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7797 tcg_temp_free_i64(fp64);
b6d96bed 7798 }
5a5012ec
TS
7799 opn = "cvt.d.s";
7800 break;
bf4120ad 7801 case OPC_CVT_W_S:
b6d96bed 7802 {
a7812ae4 7803 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
7804
7805 gen_load_fpr32(fp0, fs);
895c2d04 7806 gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
b6d96bed 7807 gen_store_fpr32(fp0, fd);
a7812ae4 7808 tcg_temp_free_i32(fp0);
b6d96bed 7809 }
5a5012ec
TS
7810 opn = "cvt.w.s";
7811 break;
bf4120ad 7812 case OPC_CVT_L_S:
5e755519 7813 check_cp1_64bitmode(ctx);
b6d96bed 7814 {
a7812ae4
PB
7815 TCGv_i32 fp32 = tcg_temp_new_i32();
7816 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
7817
7818 gen_load_fpr32(fp32, fs);
895c2d04 7819 gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
a7812ae4 7820 tcg_temp_free_i32(fp32);
b6d96bed 7821 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7822 tcg_temp_free_i64(fp64);
b6d96bed 7823 }
5a5012ec
TS
7824 opn = "cvt.l.s";
7825 break;
bf4120ad 7826 case OPC_CVT_PS_S:
5e755519 7827 check_cp1_64bitmode(ctx);
b6d96bed 7828 {
a7812ae4
PB
7829 TCGv_i64 fp64 = tcg_temp_new_i64();
7830 TCGv_i32 fp32_0 = tcg_temp_new_i32();
7831 TCGv_i32 fp32_1 = tcg_temp_new_i32();
b6d96bed
TS
7832
7833 gen_load_fpr32(fp32_0, fs);
7834 gen_load_fpr32(fp32_1, ft);
13d24f49 7835 tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
a7812ae4
PB
7836 tcg_temp_free_i32(fp32_1);
7837 tcg_temp_free_i32(fp32_0);
36aa55dc 7838 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 7839 tcg_temp_free_i64(fp64);
b6d96bed 7840 }
5a5012ec
TS
7841 opn = "cvt.ps.s";
7842 break;
bf4120ad
NF
7843 case OPC_CMP_F_S:
7844 case OPC_CMP_UN_S:
7845 case OPC_CMP_EQ_S:
7846 case OPC_CMP_UEQ_S:
7847 case OPC_CMP_OLT_S:
7848 case OPC_CMP_ULT_S:
7849 case OPC_CMP_OLE_S:
7850 case OPC_CMP_ULE_S:
7851 case OPC_CMP_SF_S:
7852 case OPC_CMP_NGLE_S:
7853 case OPC_CMP_SEQ_S:
7854 case OPC_CMP_NGL_S:
7855 case OPC_CMP_LT_S:
7856 case OPC_CMP_NGE_S:
7857 case OPC_CMP_LE_S:
7858 case OPC_CMP_NGT_S:
8153667c
NF
7859 if (ctx->opcode & (1 << 6)) {
7860 gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7861 opn = condnames_abs[func-48];
7862 } else {
7863 gen_cmp_s(ctx, func-48, ft, fs, cc);
7864 opn = condnames[func-48];
5a1e8ffb 7865 }
5a5012ec 7866 break;
bf4120ad 7867 case OPC_ADD_D:
5e755519 7868 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7869 {
a7812ae4
PB
7870 TCGv_i64 fp0 = tcg_temp_new_i64();
7871 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7872
7873 gen_load_fpr64(ctx, fp0, fs);
7874 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7875 gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7876 tcg_temp_free_i64(fp1);
b6d96bed 7877 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7878 tcg_temp_free_i64(fp0);
b6d96bed 7879 }
6ea83fed 7880 opn = "add.d";
5a1e8ffb 7881 optype = BINOP;
6ea83fed 7882 break;
bf4120ad 7883 case OPC_SUB_D:
5e755519 7884 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7885 {
a7812ae4
PB
7886 TCGv_i64 fp0 = tcg_temp_new_i64();
7887 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7888
7889 gen_load_fpr64(ctx, fp0, fs);
7890 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7891 gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7892 tcg_temp_free_i64(fp1);
b6d96bed 7893 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7894 tcg_temp_free_i64(fp0);
b6d96bed 7895 }
6ea83fed 7896 opn = "sub.d";
5a1e8ffb 7897 optype = BINOP;
6ea83fed 7898 break;
bf4120ad 7899 case OPC_MUL_D:
5e755519 7900 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7901 {
a7812ae4
PB
7902 TCGv_i64 fp0 = tcg_temp_new_i64();
7903 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7904
7905 gen_load_fpr64(ctx, fp0, fs);
7906 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7907 gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7908 tcg_temp_free_i64(fp1);
b6d96bed 7909 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7910 tcg_temp_free_i64(fp0);
b6d96bed 7911 }
6ea83fed 7912 opn = "mul.d";
5a1e8ffb 7913 optype = BINOP;
6ea83fed 7914 break;
bf4120ad 7915 case OPC_DIV_D:
5e755519 7916 check_cp1_registers(ctx, fs | ft | fd);
b6d96bed 7917 {
a7812ae4
PB
7918 TCGv_i64 fp0 = tcg_temp_new_i64();
7919 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
7920
7921 gen_load_fpr64(ctx, fp0, fs);
7922 gen_load_fpr64(ctx, fp1, ft);
895c2d04 7923 gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
a7812ae4 7924 tcg_temp_free_i64(fp1);
b6d96bed 7925 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7926 tcg_temp_free_i64(fp0);
b6d96bed 7927 }
6ea83fed 7928 opn = "div.d";
5a1e8ffb 7929 optype = BINOP;
6ea83fed 7930 break;
bf4120ad 7931 case OPC_SQRT_D:
5e755519 7932 check_cp1_registers(ctx, fs | fd);
b6d96bed 7933 {
a7812ae4 7934 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7935
7936 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7937 gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
b6d96bed 7938 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7939 tcg_temp_free_i64(fp0);
b6d96bed 7940 }
6ea83fed
FB
7941 opn = "sqrt.d";
7942 break;
bf4120ad 7943 case OPC_ABS_D:
5e755519 7944 check_cp1_registers(ctx, fs | fd);
b6d96bed 7945 {
a7812ae4 7946 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7947
7948 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7949 gen_helper_float_abs_d(fp0, fp0);
b6d96bed 7950 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7951 tcg_temp_free_i64(fp0);
b6d96bed 7952 }
6ea83fed
FB
7953 opn = "abs.d";
7954 break;
bf4120ad 7955 case OPC_MOV_D:
5e755519 7956 check_cp1_registers(ctx, fs | fd);
b6d96bed 7957 {
a7812ae4 7958 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7959
7960 gen_load_fpr64(ctx, fp0, fs);
7961 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7962 tcg_temp_free_i64(fp0);
b6d96bed 7963 }
6ea83fed
FB
7964 opn = "mov.d";
7965 break;
bf4120ad 7966 case OPC_NEG_D:
5e755519 7967 check_cp1_registers(ctx, fs | fd);
b6d96bed 7968 {
a7812ae4 7969 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7970
7971 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 7972 gen_helper_float_chs_d(fp0, fp0);
b6d96bed 7973 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7974 tcg_temp_free_i64(fp0);
b6d96bed 7975 }
6ea83fed
FB
7976 opn = "neg.d";
7977 break;
bf4120ad 7978 case OPC_ROUND_L_D:
5e755519 7979 check_cp1_64bitmode(ctx);
b6d96bed 7980 {
a7812ae4 7981 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7982
7983 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7984 gen_helper_float_roundl_d(fp0, cpu_env, fp0);
b6d96bed 7985 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7986 tcg_temp_free_i64(fp0);
b6d96bed 7987 }
5a5012ec
TS
7988 opn = "round.l.d";
7989 break;
bf4120ad 7990 case OPC_TRUNC_L_D:
5e755519 7991 check_cp1_64bitmode(ctx);
b6d96bed 7992 {
a7812ae4 7993 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
7994
7995 gen_load_fpr64(ctx, fp0, fs);
895c2d04 7996 gen_helper_float_truncl_d(fp0, cpu_env, fp0);
b6d96bed 7997 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 7998 tcg_temp_free_i64(fp0);
b6d96bed 7999 }
5a5012ec
TS
8000 opn = "trunc.l.d";
8001 break;
bf4120ad 8002 case OPC_CEIL_L_D:
5e755519 8003 check_cp1_64bitmode(ctx);
b6d96bed 8004 {
a7812ae4 8005 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8006
8007 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8008 gen_helper_float_ceill_d(fp0, cpu_env, fp0);
b6d96bed 8009 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8010 tcg_temp_free_i64(fp0);
b6d96bed 8011 }
5a5012ec
TS
8012 opn = "ceil.l.d";
8013 break;
bf4120ad 8014 case OPC_FLOOR_L_D:
5e755519 8015 check_cp1_64bitmode(ctx);
b6d96bed 8016 {
a7812ae4 8017 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8018
8019 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8020 gen_helper_float_floorl_d(fp0, cpu_env, fp0);
b6d96bed 8021 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8022 tcg_temp_free_i64(fp0);
b6d96bed 8023 }
5a5012ec
TS
8024 opn = "floor.l.d";
8025 break;
bf4120ad 8026 case OPC_ROUND_W_D:
5e755519 8027 check_cp1_registers(ctx, fs);
b6d96bed 8028 {
a7812ae4
PB
8029 TCGv_i32 fp32 = tcg_temp_new_i32();
8030 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8031
8032 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8033 gen_helper_float_roundw_d(fp32, cpu_env, fp64);
a7812ae4 8034 tcg_temp_free_i64(fp64);
b6d96bed 8035 gen_store_fpr32(fp32, fd);
a7812ae4 8036 tcg_temp_free_i32(fp32);
b6d96bed 8037 }
6ea83fed
FB
8038 opn = "round.w.d";
8039 break;
bf4120ad 8040 case OPC_TRUNC_W_D:
5e755519 8041 check_cp1_registers(ctx, fs);
b6d96bed 8042 {
a7812ae4
PB
8043 TCGv_i32 fp32 = tcg_temp_new_i32();
8044 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8045
8046 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8047 gen_helper_float_truncw_d(fp32, cpu_env, fp64);
a7812ae4 8048 tcg_temp_free_i64(fp64);
b6d96bed 8049 gen_store_fpr32(fp32, fd);
a7812ae4 8050 tcg_temp_free_i32(fp32);
b6d96bed 8051 }
6ea83fed
FB
8052 opn = "trunc.w.d";
8053 break;
bf4120ad 8054 case OPC_CEIL_W_D:
5e755519 8055 check_cp1_registers(ctx, fs);
b6d96bed 8056 {
a7812ae4
PB
8057 TCGv_i32 fp32 = tcg_temp_new_i32();
8058 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8059
8060 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8061 gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
a7812ae4 8062 tcg_temp_free_i64(fp64);
b6d96bed 8063 gen_store_fpr32(fp32, fd);
a7812ae4 8064 tcg_temp_free_i32(fp32);
b6d96bed 8065 }
6ea83fed
FB
8066 opn = "ceil.w.d";
8067 break;
bf4120ad 8068 case OPC_FLOOR_W_D:
5e755519 8069 check_cp1_registers(ctx, fs);
b6d96bed 8070 {
a7812ae4
PB
8071 TCGv_i32 fp32 = tcg_temp_new_i32();
8072 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8073
8074 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8075 gen_helper_float_floorw_d(fp32, cpu_env, fp64);
a7812ae4 8076 tcg_temp_free_i64(fp64);
b6d96bed 8077 gen_store_fpr32(fp32, fd);
a7812ae4 8078 tcg_temp_free_i32(fp32);
b6d96bed 8079 }
7a387fff 8080 opn = "floor.w.d";
6ea83fed 8081 break;
bf4120ad 8082 case OPC_MOVCF_D:
b6d96bed 8083 gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8084 opn = "movcf.d";
dd016883 8085 break;
bf4120ad 8086 case OPC_MOVZ_D:
a16336e4
TS
8087 {
8088 int l1 = gen_new_label();
c9297f4d 8089 TCGv_i64 fp0;
a16336e4 8090
c9297f4d
AJ
8091 if (ft != 0) {
8092 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8093 }
8094 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8095 gen_load_fpr64(ctx, fp0, fs);
8096 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8097 tcg_temp_free_i64(fp0);
a16336e4
TS
8098 gen_set_label(l1);
8099 }
5a5012ec
TS
8100 opn = "movz.d";
8101 break;
bf4120ad 8102 case OPC_MOVN_D:
a16336e4
TS
8103 {
8104 int l1 = gen_new_label();
c9297f4d
AJ
8105 TCGv_i64 fp0;
8106
8107 if (ft != 0) {
8108 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8109 fp0 = tcg_temp_new_i64();
8110 gen_load_fpr64(ctx, fp0, fs);
8111 gen_store_fpr64(ctx, fp0, fd);
8112 tcg_temp_free_i64(fp0);
8113 gen_set_label(l1);
8114 }
a16336e4 8115 }
5a5012ec 8116 opn = "movn.d";
6ea83fed 8117 break;
bf4120ad 8118 case OPC_RECIP_D:
b8aa4598 8119 check_cp1_64bitmode(ctx);
b6d96bed 8120 {
a7812ae4 8121 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8122
8123 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8124 gen_helper_float_recip_d(fp0, cpu_env, fp0);
b6d96bed 8125 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8126 tcg_temp_free_i64(fp0);
b6d96bed 8127 }
57fa1fb3
TS
8128 opn = "recip.d";
8129 break;
bf4120ad 8130 case OPC_RSQRT_D:
b8aa4598 8131 check_cp1_64bitmode(ctx);
b6d96bed 8132 {
a7812ae4 8133 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8134
8135 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8136 gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
b6d96bed 8137 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8138 tcg_temp_free_i64(fp0);
b6d96bed 8139 }
57fa1fb3
TS
8140 opn = "rsqrt.d";
8141 break;
bf4120ad 8142 case OPC_RECIP2_D:
5e755519 8143 check_cp1_64bitmode(ctx);
b6d96bed 8144 {
a7812ae4
PB
8145 TCGv_i64 fp0 = tcg_temp_new_i64();
8146 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8147
8148 gen_load_fpr64(ctx, fp0, fs);
8149 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8150 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8151 tcg_temp_free_i64(fp1);
b6d96bed 8152 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8153 tcg_temp_free_i64(fp0);
b6d96bed 8154 }
57fa1fb3
TS
8155 opn = "recip2.d";
8156 break;
bf4120ad 8157 case OPC_RECIP1_D:
5e755519 8158 check_cp1_64bitmode(ctx);
b6d96bed 8159 {
a7812ae4 8160 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8161
8162 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8163 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
b6d96bed 8164 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8165 tcg_temp_free_i64(fp0);
b6d96bed 8166 }
57fa1fb3
TS
8167 opn = "recip1.d";
8168 break;
bf4120ad 8169 case OPC_RSQRT1_D:
5e755519 8170 check_cp1_64bitmode(ctx);
b6d96bed 8171 {
a7812ae4 8172 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8173
8174 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8175 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
b6d96bed 8176 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8177 tcg_temp_free_i64(fp0);
b6d96bed 8178 }
57fa1fb3
TS
8179 opn = "rsqrt1.d";
8180 break;
bf4120ad 8181 case OPC_RSQRT2_D:
5e755519 8182 check_cp1_64bitmode(ctx);
b6d96bed 8183 {
a7812ae4
PB
8184 TCGv_i64 fp0 = tcg_temp_new_i64();
8185 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8186
8187 gen_load_fpr64(ctx, fp0, fs);
8188 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8189 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
a7812ae4 8190 tcg_temp_free_i64(fp1);
b6d96bed 8191 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8192 tcg_temp_free_i64(fp0);
b6d96bed 8193 }
57fa1fb3
TS
8194 opn = "rsqrt2.d";
8195 break;
bf4120ad
NF
8196 case OPC_CMP_F_D:
8197 case OPC_CMP_UN_D:
8198 case OPC_CMP_EQ_D:
8199 case OPC_CMP_UEQ_D:
8200 case OPC_CMP_OLT_D:
8201 case OPC_CMP_ULT_D:
8202 case OPC_CMP_OLE_D:
8203 case OPC_CMP_ULE_D:
8204 case OPC_CMP_SF_D:
8205 case OPC_CMP_NGLE_D:
8206 case OPC_CMP_SEQ_D:
8207 case OPC_CMP_NGL_D:
8208 case OPC_CMP_LT_D:
8209 case OPC_CMP_NGE_D:
8210 case OPC_CMP_LE_D:
8211 case OPC_CMP_NGT_D:
8153667c
NF
8212 if (ctx->opcode & (1 << 6)) {
8213 gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8214 opn = condnames_abs[func-48];
8215 } else {
8216 gen_cmp_d(ctx, func-48, ft, fs, cc);
8217 opn = condnames[func-48];
5a1e8ffb 8218 }
6ea83fed 8219 break;
bf4120ad 8220 case OPC_CVT_S_D:
5e755519 8221 check_cp1_registers(ctx, fs);
b6d96bed 8222 {
a7812ae4
PB
8223 TCGv_i32 fp32 = tcg_temp_new_i32();
8224 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8225
8226 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8227 gen_helper_float_cvts_d(fp32, cpu_env, fp64);
a7812ae4 8228 tcg_temp_free_i64(fp64);
b6d96bed 8229 gen_store_fpr32(fp32, fd);
a7812ae4 8230 tcg_temp_free_i32(fp32);
b6d96bed 8231 }
5a5012ec
TS
8232 opn = "cvt.s.d";
8233 break;
bf4120ad 8234 case OPC_CVT_W_D:
5e755519 8235 check_cp1_registers(ctx, fs);
b6d96bed 8236 {
a7812ae4
PB
8237 TCGv_i32 fp32 = tcg_temp_new_i32();
8238 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8239
8240 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8241 gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
a7812ae4 8242 tcg_temp_free_i64(fp64);
b6d96bed 8243 gen_store_fpr32(fp32, fd);
a7812ae4 8244 tcg_temp_free_i32(fp32);
b6d96bed 8245 }
5a5012ec
TS
8246 opn = "cvt.w.d";
8247 break;
bf4120ad 8248 case OPC_CVT_L_D:
5e755519 8249 check_cp1_64bitmode(ctx);
b6d96bed 8250 {
a7812ae4 8251 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8252
8253 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8254 gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
b6d96bed 8255 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8256 tcg_temp_free_i64(fp0);
b6d96bed 8257 }
5a5012ec
TS
8258 opn = "cvt.l.d";
8259 break;
bf4120ad 8260 case OPC_CVT_S_W:
b6d96bed 8261 {
a7812ae4 8262 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8263
8264 gen_load_fpr32(fp0, fs);
895c2d04 8265 gen_helper_float_cvts_w(fp0, cpu_env, fp0);
b6d96bed 8266 gen_store_fpr32(fp0, fd);
a7812ae4 8267 tcg_temp_free_i32(fp0);
b6d96bed 8268 }
5a5012ec 8269 opn = "cvt.s.w";
6ea83fed 8270 break;
bf4120ad 8271 case OPC_CVT_D_W:
5e755519 8272 check_cp1_registers(ctx, fd);
b6d96bed 8273 {
a7812ae4
PB
8274 TCGv_i32 fp32 = tcg_temp_new_i32();
8275 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8276
8277 gen_load_fpr32(fp32, fs);
895c2d04 8278 gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
a7812ae4 8279 tcg_temp_free_i32(fp32);
b6d96bed 8280 gen_store_fpr64(ctx, fp64, fd);
a7812ae4 8281 tcg_temp_free_i64(fp64);
b6d96bed 8282 }
5a5012ec
TS
8283 opn = "cvt.d.w";
8284 break;
bf4120ad 8285 case OPC_CVT_S_L:
5e755519 8286 check_cp1_64bitmode(ctx);
b6d96bed 8287 {
a7812ae4
PB
8288 TCGv_i32 fp32 = tcg_temp_new_i32();
8289 TCGv_i64 fp64 = tcg_temp_new_i64();
b6d96bed
TS
8290
8291 gen_load_fpr64(ctx, fp64, fs);
895c2d04 8292 gen_helper_float_cvts_l(fp32, cpu_env, fp64);
a7812ae4 8293 tcg_temp_free_i64(fp64);
b6d96bed 8294 gen_store_fpr32(fp32, fd);
a7812ae4 8295 tcg_temp_free_i32(fp32);
b6d96bed 8296 }
5a5012ec
TS
8297 opn = "cvt.s.l";
8298 break;
bf4120ad 8299 case OPC_CVT_D_L:
5e755519 8300 check_cp1_64bitmode(ctx);
b6d96bed 8301 {
a7812ae4 8302 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8303
8304 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8305 gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
b6d96bed 8306 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8307 tcg_temp_free_i64(fp0);
b6d96bed 8308 }
5a5012ec
TS
8309 opn = "cvt.d.l";
8310 break;
bf4120ad 8311 case OPC_CVT_PS_PW:
5e755519 8312 check_cp1_64bitmode(ctx);
b6d96bed 8313 {
a7812ae4 8314 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8315
8316 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8317 gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
b6d96bed 8318 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8319 tcg_temp_free_i64(fp0);
b6d96bed 8320 }
5a5012ec
TS
8321 opn = "cvt.ps.pw";
8322 break;
bf4120ad 8323 case OPC_ADD_PS:
5e755519 8324 check_cp1_64bitmode(ctx);
b6d96bed 8325 {
a7812ae4
PB
8326 TCGv_i64 fp0 = tcg_temp_new_i64();
8327 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8328
8329 gen_load_fpr64(ctx, fp0, fs);
8330 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8331 gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8332 tcg_temp_free_i64(fp1);
b6d96bed 8333 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8334 tcg_temp_free_i64(fp0);
b6d96bed 8335 }
5a5012ec 8336 opn = "add.ps";
6ea83fed 8337 break;
bf4120ad 8338 case OPC_SUB_PS:
5e755519 8339 check_cp1_64bitmode(ctx);
b6d96bed 8340 {
a7812ae4
PB
8341 TCGv_i64 fp0 = tcg_temp_new_i64();
8342 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8343
8344 gen_load_fpr64(ctx, fp0, fs);
8345 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8346 gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8347 tcg_temp_free_i64(fp1);
b6d96bed 8348 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8349 tcg_temp_free_i64(fp0);
b6d96bed 8350 }
5a5012ec 8351 opn = "sub.ps";
6ea83fed 8352 break;
bf4120ad 8353 case OPC_MUL_PS:
5e755519 8354 check_cp1_64bitmode(ctx);
b6d96bed 8355 {
a7812ae4
PB
8356 TCGv_i64 fp0 = tcg_temp_new_i64();
8357 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8358
8359 gen_load_fpr64(ctx, fp0, fs);
8360 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8361 gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8362 tcg_temp_free_i64(fp1);
b6d96bed 8363 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8364 tcg_temp_free_i64(fp0);
b6d96bed 8365 }
5a5012ec 8366 opn = "mul.ps";
6ea83fed 8367 break;
bf4120ad 8368 case OPC_ABS_PS:
5e755519 8369 check_cp1_64bitmode(ctx);
b6d96bed 8370 {
a7812ae4 8371 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8372
8373 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8374 gen_helper_float_abs_ps(fp0, fp0);
b6d96bed 8375 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8376 tcg_temp_free_i64(fp0);
b6d96bed 8377 }
5a5012ec 8378 opn = "abs.ps";
6ea83fed 8379 break;
bf4120ad 8380 case OPC_MOV_PS:
5e755519 8381 check_cp1_64bitmode(ctx);
b6d96bed 8382 {
a7812ae4 8383 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8384
8385 gen_load_fpr64(ctx, fp0, fs);
8386 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8387 tcg_temp_free_i64(fp0);
b6d96bed 8388 }
5a5012ec 8389 opn = "mov.ps";
6ea83fed 8390 break;
bf4120ad 8391 case OPC_NEG_PS:
5e755519 8392 check_cp1_64bitmode(ctx);
b6d96bed 8393 {
a7812ae4 8394 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8395
8396 gen_load_fpr64(ctx, fp0, fs);
a7812ae4 8397 gen_helper_float_chs_ps(fp0, fp0);
b6d96bed 8398 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8399 tcg_temp_free_i64(fp0);
b6d96bed 8400 }
5a5012ec 8401 opn = "neg.ps";
6ea83fed 8402 break;
bf4120ad 8403 case OPC_MOVCF_PS:
5e755519 8404 check_cp1_64bitmode(ctx);
b6d96bed 8405 gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
5a5012ec 8406 opn = "movcf.ps";
6ea83fed 8407 break;
bf4120ad 8408 case OPC_MOVZ_PS:
5e755519 8409 check_cp1_64bitmode(ctx);
a16336e4
TS
8410 {
8411 int l1 = gen_new_label();
30a3848b 8412 TCGv_i64 fp0;
a16336e4 8413
c9297f4d
AJ
8414 if (ft != 0)
8415 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8416 fp0 = tcg_temp_new_i64();
8417 gen_load_fpr64(ctx, fp0, fs);
8418 gen_store_fpr64(ctx, fp0, fd);
8419 tcg_temp_free_i64(fp0);
a16336e4
TS
8420 gen_set_label(l1);
8421 }
5a5012ec 8422 opn = "movz.ps";
6ea83fed 8423 break;
bf4120ad 8424 case OPC_MOVN_PS:
5e755519 8425 check_cp1_64bitmode(ctx);
a16336e4
TS
8426 {
8427 int l1 = gen_new_label();
30a3848b 8428 TCGv_i64 fp0;
c9297f4d
AJ
8429
8430 if (ft != 0) {
8431 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8432 fp0 = tcg_temp_new_i64();
8433 gen_load_fpr64(ctx, fp0, fs);
8434 gen_store_fpr64(ctx, fp0, fd);
8435 tcg_temp_free_i64(fp0);
8436 gen_set_label(l1);
8437 }
a16336e4 8438 }
5a5012ec 8439 opn = "movn.ps";
6ea83fed 8440 break;
bf4120ad 8441 case OPC_ADDR_PS:
5e755519 8442 check_cp1_64bitmode(ctx);
b6d96bed 8443 {
a7812ae4
PB
8444 TCGv_i64 fp0 = tcg_temp_new_i64();
8445 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8446
8447 gen_load_fpr64(ctx, fp0, ft);
8448 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8449 gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8450 tcg_temp_free_i64(fp1);
b6d96bed 8451 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8452 tcg_temp_free_i64(fp0);
b6d96bed 8453 }
fbcc6828
TS
8454 opn = "addr.ps";
8455 break;
bf4120ad 8456 case OPC_MULR_PS:
5e755519 8457 check_cp1_64bitmode(ctx);
b6d96bed 8458 {
a7812ae4
PB
8459 TCGv_i64 fp0 = tcg_temp_new_i64();
8460 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8461
8462 gen_load_fpr64(ctx, fp0, ft);
8463 gen_load_fpr64(ctx, fp1, fs);
895c2d04 8464 gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8465 tcg_temp_free_i64(fp1);
b6d96bed 8466 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8467 tcg_temp_free_i64(fp0);
b6d96bed 8468 }
57fa1fb3
TS
8469 opn = "mulr.ps";
8470 break;
bf4120ad 8471 case OPC_RECIP2_PS:
5e755519 8472 check_cp1_64bitmode(ctx);
b6d96bed 8473 {
a7812ae4
PB
8474 TCGv_i64 fp0 = tcg_temp_new_i64();
8475 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8476
8477 gen_load_fpr64(ctx, fp0, fs);
d22d7289 8478 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8479 gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8480 tcg_temp_free_i64(fp1);
b6d96bed 8481 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8482 tcg_temp_free_i64(fp0);
b6d96bed 8483 }
57fa1fb3
TS
8484 opn = "recip2.ps";
8485 break;
bf4120ad 8486 case OPC_RECIP1_PS:
5e755519 8487 check_cp1_64bitmode(ctx);
b6d96bed 8488 {
a7812ae4 8489 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8490
8491 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8492 gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
b6d96bed 8493 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8494 tcg_temp_free_i64(fp0);
b6d96bed 8495 }
57fa1fb3
TS
8496 opn = "recip1.ps";
8497 break;
bf4120ad 8498 case OPC_RSQRT1_PS:
5e755519 8499 check_cp1_64bitmode(ctx);
b6d96bed 8500 {
a7812ae4 8501 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8502
8503 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8504 gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
b6d96bed 8505 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8506 tcg_temp_free_i64(fp0);
b6d96bed 8507 }
57fa1fb3
TS
8508 opn = "rsqrt1.ps";
8509 break;
bf4120ad 8510 case OPC_RSQRT2_PS:
5e755519 8511 check_cp1_64bitmode(ctx);
b6d96bed 8512 {
a7812ae4
PB
8513 TCGv_i64 fp0 = tcg_temp_new_i64();
8514 TCGv_i64 fp1 = tcg_temp_new_i64();
b6d96bed
TS
8515
8516 gen_load_fpr64(ctx, fp0, fs);
8517 gen_load_fpr64(ctx, fp1, ft);
895c2d04 8518 gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
a7812ae4 8519 tcg_temp_free_i64(fp1);
b6d96bed 8520 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8521 tcg_temp_free_i64(fp0);
b6d96bed 8522 }
57fa1fb3
TS
8523 opn = "rsqrt2.ps";
8524 break;
bf4120ad 8525 case OPC_CVT_S_PU:
5e755519 8526 check_cp1_64bitmode(ctx);
b6d96bed 8527 {
a7812ae4 8528 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8529
8530 gen_load_fpr32h(fp0, fs);
895c2d04 8531 gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
b6d96bed 8532 gen_store_fpr32(fp0, fd);
a7812ae4 8533 tcg_temp_free_i32(fp0);
b6d96bed 8534 }
5a5012ec 8535 opn = "cvt.s.pu";
dd016883 8536 break;
bf4120ad 8537 case OPC_CVT_PW_PS:
5e755519 8538 check_cp1_64bitmode(ctx);
b6d96bed 8539 {
a7812ae4 8540 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8541
8542 gen_load_fpr64(ctx, fp0, fs);
895c2d04 8543 gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
b6d96bed 8544 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8545 tcg_temp_free_i64(fp0);
b6d96bed 8546 }
5a5012ec 8547 opn = "cvt.pw.ps";
6ea83fed 8548 break;
bf4120ad 8549 case OPC_CVT_S_PL:
5e755519 8550 check_cp1_64bitmode(ctx);
b6d96bed 8551 {
a7812ae4 8552 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed
TS
8553
8554 gen_load_fpr32(fp0, fs);
895c2d04 8555 gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
b6d96bed 8556 gen_store_fpr32(fp0, fd);
a7812ae4 8557 tcg_temp_free_i32(fp0);
b6d96bed 8558 }
5a5012ec 8559 opn = "cvt.s.pl";
6ea83fed 8560 break;
bf4120ad 8561 case OPC_PLL_PS:
5e755519 8562 check_cp1_64bitmode(ctx);
b6d96bed 8563 {
a7812ae4
PB
8564 TCGv_i32 fp0 = tcg_temp_new_i32();
8565 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8566
8567 gen_load_fpr32(fp0, fs);
8568 gen_load_fpr32(fp1, ft);
8569 gen_store_fpr32h(fp0, fd);
8570 gen_store_fpr32(fp1, fd);
a7812ae4
PB
8571 tcg_temp_free_i32(fp0);
8572 tcg_temp_free_i32(fp1);
b6d96bed 8573 }
5a5012ec 8574 opn = "pll.ps";
6ea83fed 8575 break;
bf4120ad 8576 case OPC_PLU_PS:
5e755519 8577 check_cp1_64bitmode(ctx);
b6d96bed 8578 {
a7812ae4
PB
8579 TCGv_i32 fp0 = tcg_temp_new_i32();
8580 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8581
8582 gen_load_fpr32(fp0, fs);
8583 gen_load_fpr32h(fp1, ft);
8584 gen_store_fpr32(fp1, fd);
8585 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8586 tcg_temp_free_i32(fp0);
8587 tcg_temp_free_i32(fp1);
b6d96bed 8588 }
5a5012ec
TS
8589 opn = "plu.ps";
8590 break;
bf4120ad 8591 case OPC_PUL_PS:
5e755519 8592 check_cp1_64bitmode(ctx);
b6d96bed 8593 {
a7812ae4
PB
8594 TCGv_i32 fp0 = tcg_temp_new_i32();
8595 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8596
8597 gen_load_fpr32h(fp0, fs);
8598 gen_load_fpr32(fp1, ft);
8599 gen_store_fpr32(fp1, fd);
8600 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8601 tcg_temp_free_i32(fp0);
8602 tcg_temp_free_i32(fp1);
b6d96bed 8603 }
5a5012ec
TS
8604 opn = "pul.ps";
8605 break;
bf4120ad 8606 case OPC_PUU_PS:
5e755519 8607 check_cp1_64bitmode(ctx);
b6d96bed 8608 {
a7812ae4
PB
8609 TCGv_i32 fp0 = tcg_temp_new_i32();
8610 TCGv_i32 fp1 = tcg_temp_new_i32();
b6d96bed
TS
8611
8612 gen_load_fpr32h(fp0, fs);
8613 gen_load_fpr32h(fp1, ft);
8614 gen_store_fpr32(fp1, fd);
8615 gen_store_fpr32h(fp0, fd);
a7812ae4
PB
8616 tcg_temp_free_i32(fp0);
8617 tcg_temp_free_i32(fp1);
b6d96bed 8618 }
5a5012ec
TS
8619 opn = "puu.ps";
8620 break;
bf4120ad
NF
8621 case OPC_CMP_F_PS:
8622 case OPC_CMP_UN_PS:
8623 case OPC_CMP_EQ_PS:
8624 case OPC_CMP_UEQ_PS:
8625 case OPC_CMP_OLT_PS:
8626 case OPC_CMP_ULT_PS:
8627 case OPC_CMP_OLE_PS:
8628 case OPC_CMP_ULE_PS:
8629 case OPC_CMP_SF_PS:
8630 case OPC_CMP_NGLE_PS:
8631 case OPC_CMP_SEQ_PS:
8632 case OPC_CMP_NGL_PS:
8633 case OPC_CMP_LT_PS:
8634 case OPC_CMP_NGE_PS:
8635 case OPC_CMP_LE_PS:
8636 case OPC_CMP_NGT_PS:
8153667c
NF
8637 if (ctx->opcode & (1 << 6)) {
8638 gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8639 opn = condnames_abs[func-48];
8640 } else {
8641 gen_cmp_ps(ctx, func-48, ft, fs, cc);
8642 opn = condnames[func-48];
5a1e8ffb 8643 }
6ea83fed 8644 break;
5a5012ec 8645 default:
923617a3 8646 MIPS_INVAL(opn);
e397ee33 8647 generate_exception (ctx, EXCP_RI);
6ea83fed
FB
8648 return;
8649 }
2abf314d 8650 (void)opn; /* avoid a compiler warning */
5a1e8ffb
TS
8651 switch (optype) {
8652 case BINOP:
6ea83fed 8653 MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5a1e8ffb
TS
8654 break;
8655 case CMPOP:
8656 MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8657 break;
8658 default:
6ea83fed 8659 MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5a1e8ffb
TS
8660 break;
8661 }
6ea83fed 8662}
6af0bf9c 8663
5a5012ec 8664/* Coprocessor 3 (FPU) */
5e755519
TS
8665static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8666 int fd, int fs, int base, int index)
7a387fff 8667{
923617a3 8668 const char *opn = "extended float load/store";
93b12ccc 8669 int store = 0;
4e2474d6 8670 TCGv t0 = tcg_temp_new();
7a387fff 8671
93b12ccc 8672 if (base == 0) {
6c5c1e20 8673 gen_load_gpr(t0, index);
93b12ccc 8674 } else if (index == 0) {
6c5c1e20 8675 gen_load_gpr(t0, base);
93b12ccc 8676 } else {
05168674 8677 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
93b12ccc 8678 }
5a5012ec 8679 /* Don't do NOP if destination is zero: we must perform the actual
ead9360e 8680 memory access. */
5a5012ec
TS
8681 switch (opc) {
8682 case OPC_LWXC1:
8c0ab41f 8683 check_cop1x(ctx);
b6d96bed 8684 {
a7812ae4 8685 TCGv_i32 fp0 = tcg_temp_new_i32();
b6d96bed 8686
585c88d5
AJ
8687 tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8688 tcg_gen_trunc_tl_i32(fp0, t0);
b6d96bed 8689 gen_store_fpr32(fp0, fd);
a7812ae4 8690 tcg_temp_free_i32(fp0);
b6d96bed 8691 }
5a5012ec
TS
8692 opn = "lwxc1";
8693 break;
8694 case OPC_LDXC1:
8c0ab41f
AJ
8695 check_cop1x(ctx);
8696 check_cp1_registers(ctx, fd);
b6d96bed 8697 {
a7812ae4 8698 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8699
8700 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8701 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8702 tcg_temp_free_i64(fp0);
b6d96bed 8703 }
5a5012ec
TS
8704 opn = "ldxc1";
8705 break;
8706 case OPC_LUXC1:
8c0ab41f 8707 check_cp1_64bitmode(ctx);
6c5c1e20 8708 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8709 {
a7812ae4 8710 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8711
8712 tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8713 gen_store_fpr64(ctx, fp0, fd);
a7812ae4 8714 tcg_temp_free_i64(fp0);
b6d96bed 8715 }
5a5012ec
TS
8716 opn = "luxc1";
8717 break;
8718 case OPC_SWXC1:
8c0ab41f 8719 check_cop1x(ctx);
b6d96bed 8720 {
a7812ae4 8721 TCGv_i32 fp0 = tcg_temp_new_i32();
585c88d5 8722 TCGv t1 = tcg_temp_new();
b6d96bed
TS
8723
8724 gen_load_fpr32(fp0, fs);
a7812ae4
PB
8725 tcg_gen_extu_i32_tl(t1, fp0);
8726 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8727 tcg_temp_free_i32(fp0);
a6035857 8728 tcg_temp_free(t1);
b6d96bed 8729 }
5a5012ec 8730 opn = "swxc1";
93b12ccc 8731 store = 1;
5a5012ec
TS
8732 break;
8733 case OPC_SDXC1:
8c0ab41f
AJ
8734 check_cop1x(ctx);
8735 check_cp1_registers(ctx, fs);
b6d96bed 8736 {
a7812ae4 8737 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8738
8739 gen_load_fpr64(ctx, fp0, fs);
8740 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8741 tcg_temp_free_i64(fp0);
b6d96bed 8742 }
5a5012ec 8743 opn = "sdxc1";
93b12ccc 8744 store = 1;
5a5012ec
TS
8745 break;
8746 case OPC_SUXC1:
8c0ab41f 8747 check_cp1_64bitmode(ctx);
6c5c1e20 8748 tcg_gen_andi_tl(t0, t0, ~0x7);
b6d96bed 8749 {
a7812ae4 8750 TCGv_i64 fp0 = tcg_temp_new_i64();
b6d96bed
TS
8751
8752 gen_load_fpr64(ctx, fp0, fs);
8753 tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
a7812ae4 8754 tcg_temp_free_i64(fp0);
b6d96bed 8755 }
5a5012ec 8756 opn = "suxc1";
93b12ccc 8757 store = 1;
5a5012ec 8758 break;
5a5012ec 8759 }
6c5c1e20 8760 tcg_temp_free(t0);
2abf314d 8761 (void)opn; (void)store; /* avoid compiler warnings */
93b12ccc
TS
8762 MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8763 regnames[index], regnames[base]);
5a5012ec
TS
8764}
8765
5e755519
TS
8766static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8767 int fd, int fr, int fs, int ft)
5a5012ec 8768{
923617a3 8769 const char *opn = "flt3_arith";
5a5012ec 8770
5a5012ec
TS
8771 switch (opc) {
8772 case OPC_ALNV_PS:
b8aa4598 8773 check_cp1_64bitmode(ctx);
a16336e4 8774 {
a7812ae4 8775 TCGv t0 = tcg_temp_local_new();
c905fdac
AJ
8776 TCGv_i32 fp = tcg_temp_new_i32();
8777 TCGv_i32 fph = tcg_temp_new_i32();
a16336e4
TS
8778 int l1 = gen_new_label();
8779 int l2 = gen_new_label();
8780
6c5c1e20
TS
8781 gen_load_gpr(t0, fr);
8782 tcg_gen_andi_tl(t0, t0, 0x7);
6c5c1e20
TS
8783
8784 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
c905fdac
AJ
8785 gen_load_fpr32(fp, fs);
8786 gen_load_fpr32h(fph, fs);
8787 gen_store_fpr32(fp, fd);
8788 gen_store_fpr32h(fph, fd);
a16336e4
TS
8789 tcg_gen_br(l2);
8790 gen_set_label(l1);
6c5c1e20
TS
8791 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8792 tcg_temp_free(t0);
a16336e4 8793#ifdef TARGET_WORDS_BIGENDIAN
c905fdac
AJ
8794 gen_load_fpr32(fp, fs);
8795 gen_load_fpr32h(fph, ft);
8796 gen_store_fpr32h(fp, fd);
8797 gen_store_fpr32(fph, fd);
a16336e4 8798#else
c905fdac
AJ
8799 gen_load_fpr32h(fph, fs);
8800 gen_load_fpr32(fp, ft);
8801 gen_store_fpr32(fph, fd);
8802 gen_store_fpr32h(fp, fd);
a16336e4
TS
8803#endif
8804 gen_set_label(l2);
c905fdac
AJ
8805 tcg_temp_free_i32(fp);
8806 tcg_temp_free_i32(fph);
a16336e4 8807 }
5a5012ec
TS
8808 opn = "alnv.ps";
8809 break;
8810 case OPC_MADD_S:
b8aa4598 8811 check_cop1x(ctx);
b6d96bed 8812 {
a7812ae4
PB
8813 TCGv_i32 fp0 = tcg_temp_new_i32();
8814 TCGv_i32 fp1 = tcg_temp_new_i32();
8815 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8816
8817 gen_load_fpr32(fp0, fs);
8818 gen_load_fpr32(fp1, ft);
8819 gen_load_fpr32(fp2, fr);
b3d6cd44 8820 gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8821 tcg_temp_free_i32(fp0);
8822 tcg_temp_free_i32(fp1);
b6d96bed 8823 gen_store_fpr32(fp2, fd);
a7812ae4 8824 tcg_temp_free_i32(fp2);
b6d96bed 8825 }
5a5012ec
TS
8826 opn = "madd.s";
8827 break;
8828 case OPC_MADD_D:
b8aa4598
TS
8829 check_cop1x(ctx);
8830 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8831 {
a7812ae4
PB
8832 TCGv_i64 fp0 = tcg_temp_new_i64();
8833 TCGv_i64 fp1 = tcg_temp_new_i64();
8834 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8835
8836 gen_load_fpr64(ctx, fp0, fs);
8837 gen_load_fpr64(ctx, fp1, ft);
8838 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8839 gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8840 tcg_temp_free_i64(fp0);
8841 tcg_temp_free_i64(fp1);
b6d96bed 8842 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8843 tcg_temp_free_i64(fp2);
b6d96bed 8844 }
5a5012ec
TS
8845 opn = "madd.d";
8846 break;
8847 case OPC_MADD_PS:
b8aa4598 8848 check_cp1_64bitmode(ctx);
b6d96bed 8849 {
a7812ae4
PB
8850 TCGv_i64 fp0 = tcg_temp_new_i64();
8851 TCGv_i64 fp1 = tcg_temp_new_i64();
8852 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8853
8854 gen_load_fpr64(ctx, fp0, fs);
8855 gen_load_fpr64(ctx, fp1, ft);
8856 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8857 gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8858 tcg_temp_free_i64(fp0);
8859 tcg_temp_free_i64(fp1);
b6d96bed 8860 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8861 tcg_temp_free_i64(fp2);
b6d96bed 8862 }
5a5012ec
TS
8863 opn = "madd.ps";
8864 break;
8865 case OPC_MSUB_S:
b8aa4598 8866 check_cop1x(ctx);
b6d96bed 8867 {
a7812ae4
PB
8868 TCGv_i32 fp0 = tcg_temp_new_i32();
8869 TCGv_i32 fp1 = tcg_temp_new_i32();
8870 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8871
8872 gen_load_fpr32(fp0, fs);
8873 gen_load_fpr32(fp1, ft);
8874 gen_load_fpr32(fp2, fr);
b3d6cd44 8875 gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8876 tcg_temp_free_i32(fp0);
8877 tcg_temp_free_i32(fp1);
b6d96bed 8878 gen_store_fpr32(fp2, fd);
a7812ae4 8879 tcg_temp_free_i32(fp2);
b6d96bed 8880 }
5a5012ec
TS
8881 opn = "msub.s";
8882 break;
8883 case OPC_MSUB_D:
b8aa4598
TS
8884 check_cop1x(ctx);
8885 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8886 {
a7812ae4
PB
8887 TCGv_i64 fp0 = tcg_temp_new_i64();
8888 TCGv_i64 fp1 = tcg_temp_new_i64();
8889 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8890
8891 gen_load_fpr64(ctx, fp0, fs);
8892 gen_load_fpr64(ctx, fp1, ft);
8893 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8894 gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8895 tcg_temp_free_i64(fp0);
8896 tcg_temp_free_i64(fp1);
b6d96bed 8897 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8898 tcg_temp_free_i64(fp2);
b6d96bed 8899 }
5a5012ec
TS
8900 opn = "msub.d";
8901 break;
8902 case OPC_MSUB_PS:
b8aa4598 8903 check_cp1_64bitmode(ctx);
b6d96bed 8904 {
a7812ae4
PB
8905 TCGv_i64 fp0 = tcg_temp_new_i64();
8906 TCGv_i64 fp1 = tcg_temp_new_i64();
8907 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8908
8909 gen_load_fpr64(ctx, fp0, fs);
8910 gen_load_fpr64(ctx, fp1, ft);
8911 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8912 gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8913 tcg_temp_free_i64(fp0);
8914 tcg_temp_free_i64(fp1);
b6d96bed 8915 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8916 tcg_temp_free_i64(fp2);
b6d96bed 8917 }
5a5012ec
TS
8918 opn = "msub.ps";
8919 break;
8920 case OPC_NMADD_S:
b8aa4598 8921 check_cop1x(ctx);
b6d96bed 8922 {
a7812ae4
PB
8923 TCGv_i32 fp0 = tcg_temp_new_i32();
8924 TCGv_i32 fp1 = tcg_temp_new_i32();
8925 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8926
8927 gen_load_fpr32(fp0, fs);
8928 gen_load_fpr32(fp1, ft);
8929 gen_load_fpr32(fp2, fr);
b3d6cd44 8930 gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8931 tcg_temp_free_i32(fp0);
8932 tcg_temp_free_i32(fp1);
b6d96bed 8933 gen_store_fpr32(fp2, fd);
a7812ae4 8934 tcg_temp_free_i32(fp2);
b6d96bed 8935 }
5a5012ec
TS
8936 opn = "nmadd.s";
8937 break;
8938 case OPC_NMADD_D:
b8aa4598
TS
8939 check_cop1x(ctx);
8940 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8941 {
a7812ae4
PB
8942 TCGv_i64 fp0 = tcg_temp_new_i64();
8943 TCGv_i64 fp1 = tcg_temp_new_i64();
8944 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8945
8946 gen_load_fpr64(ctx, fp0, fs);
8947 gen_load_fpr64(ctx, fp1, ft);
8948 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8949 gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8950 tcg_temp_free_i64(fp0);
8951 tcg_temp_free_i64(fp1);
b6d96bed 8952 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8953 tcg_temp_free_i64(fp2);
b6d96bed 8954 }
5a5012ec
TS
8955 opn = "nmadd.d";
8956 break;
8957 case OPC_NMADD_PS:
b8aa4598 8958 check_cp1_64bitmode(ctx);
b6d96bed 8959 {
a7812ae4
PB
8960 TCGv_i64 fp0 = tcg_temp_new_i64();
8961 TCGv_i64 fp1 = tcg_temp_new_i64();
8962 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
8963
8964 gen_load_fpr64(ctx, fp0, fs);
8965 gen_load_fpr64(ctx, fp1, ft);
8966 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 8967 gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8968 tcg_temp_free_i64(fp0);
8969 tcg_temp_free_i64(fp1);
b6d96bed 8970 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 8971 tcg_temp_free_i64(fp2);
b6d96bed 8972 }
5a5012ec
TS
8973 opn = "nmadd.ps";
8974 break;
8975 case OPC_NMSUB_S:
b8aa4598 8976 check_cop1x(ctx);
b6d96bed 8977 {
a7812ae4
PB
8978 TCGv_i32 fp0 = tcg_temp_new_i32();
8979 TCGv_i32 fp1 = tcg_temp_new_i32();
8980 TCGv_i32 fp2 = tcg_temp_new_i32();
b6d96bed
TS
8981
8982 gen_load_fpr32(fp0, fs);
8983 gen_load_fpr32(fp1, ft);
8984 gen_load_fpr32(fp2, fr);
b3d6cd44 8985 gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
8986 tcg_temp_free_i32(fp0);
8987 tcg_temp_free_i32(fp1);
b6d96bed 8988 gen_store_fpr32(fp2, fd);
a7812ae4 8989 tcg_temp_free_i32(fp2);
b6d96bed 8990 }
5a5012ec
TS
8991 opn = "nmsub.s";
8992 break;
8993 case OPC_NMSUB_D:
b8aa4598
TS
8994 check_cop1x(ctx);
8995 check_cp1_registers(ctx, fd | fs | ft | fr);
b6d96bed 8996 {
a7812ae4
PB
8997 TCGv_i64 fp0 = tcg_temp_new_i64();
8998 TCGv_i64 fp1 = tcg_temp_new_i64();
8999 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9000
9001 gen_load_fpr64(ctx, fp0, fs);
9002 gen_load_fpr64(ctx, fp1, ft);
9003 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9004 gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9005 tcg_temp_free_i64(fp0);
9006 tcg_temp_free_i64(fp1);
b6d96bed 9007 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9008 tcg_temp_free_i64(fp2);
b6d96bed 9009 }
5a5012ec
TS
9010 opn = "nmsub.d";
9011 break;
9012 case OPC_NMSUB_PS:
b8aa4598 9013 check_cp1_64bitmode(ctx);
b6d96bed 9014 {
a7812ae4
PB
9015 TCGv_i64 fp0 = tcg_temp_new_i64();
9016 TCGv_i64 fp1 = tcg_temp_new_i64();
9017 TCGv_i64 fp2 = tcg_temp_new_i64();
b6d96bed
TS
9018
9019 gen_load_fpr64(ctx, fp0, fs);
9020 gen_load_fpr64(ctx, fp1, ft);
9021 gen_load_fpr64(ctx, fp2, fr);
b3d6cd44 9022 gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
a7812ae4
PB
9023 tcg_temp_free_i64(fp0);
9024 tcg_temp_free_i64(fp1);
b6d96bed 9025 gen_store_fpr64(ctx, fp2, fd);
a7812ae4 9026 tcg_temp_free_i64(fp2);
b6d96bed 9027 }
5a5012ec
TS
9028 opn = "nmsub.ps";
9029 break;
923617a3
TS
9030 default:
9031 MIPS_INVAL(opn);
5a5012ec
TS
9032 generate_exception (ctx, EXCP_RI);
9033 return;
9034 }
2abf314d 9035 (void)opn; /* avoid a compiler warning */
5a5012ec
TS
9036 MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9037 fregnames[fs], fregnames[ft]);
7a387fff
TS
9038}
9039
26ebe468 9040static void
7db13fae 9041gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
26ebe468
NF
9042{
9043 TCGv t0;
9044
b3167288
RH
9045#if !defined(CONFIG_USER_ONLY)
9046 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9047 Therefore only check the ISA in system mode. */
26ebe468 9048 check_insn(env, ctx, ISA_MIPS32R2);
b3167288 9049#endif
26ebe468
NF
9050 t0 = tcg_temp_new();
9051
9052 switch (rd) {
9053 case 0:
9054 save_cpu_state(ctx, 1);
895c2d04 9055 gen_helper_rdhwr_cpunum(t0, cpu_env);
26ebe468
NF
9056 gen_store_gpr(t0, rt);
9057 break;
9058 case 1:
9059 save_cpu_state(ctx, 1);
895c2d04 9060 gen_helper_rdhwr_synci_step(t0, cpu_env);
26ebe468
NF
9061 gen_store_gpr(t0, rt);
9062 break;
9063 case 2:
9064 save_cpu_state(ctx, 1);
895c2d04 9065 gen_helper_rdhwr_cc(t0, cpu_env);
26ebe468
NF
9066 gen_store_gpr(t0, rt);
9067 break;
9068 case 3:
9069 save_cpu_state(ctx, 1);
895c2d04 9070 gen_helper_rdhwr_ccres(t0, cpu_env);
26ebe468
NF
9071 gen_store_gpr(t0, rt);
9072 break;
9073 case 29:
9074#if defined(CONFIG_USER_ONLY)
7db13fae 9075 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
26ebe468
NF
9076 gen_store_gpr(t0, rt);
9077 break;
9078#else
9079 /* XXX: Some CPUs implement this in hardware.
9080 Not supported yet. */
9081#endif
9082 default: /* Invalid */
9083 MIPS_INVAL("rdhwr");
9084 generate_exception(ctx, EXCP_RI);
9085 break;
9086 }
9087 tcg_temp_free(t0);
9088}
9089
7db13fae 9090static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
c9602061
NF
9091 int insn_bytes)
9092{
9093 if (ctx->hflags & MIPS_HFLAG_BMASK) {
364d4831 9094 int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
c9602061
NF
9095 /* Branches completion */
9096 ctx->hflags &= ~MIPS_HFLAG_BMASK;
9097 ctx->bstate = BS_BRANCH;
9098 save_cpu_state(ctx, 0);
9099 /* FIXME: Need to clear can_do_io. */
364d4831 9100 switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
c9602061
NF
9101 case MIPS_HFLAG_B:
9102 /* unconditional branch */
9103 MIPS_DEBUG("unconditional branch");
364d4831
NF
9104 if (proc_hflags & MIPS_HFLAG_BX) {
9105 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9106 }
c9602061
NF
9107 gen_goto_tb(ctx, 0, ctx->btarget);
9108 break;
9109 case MIPS_HFLAG_BL:
9110 /* blikely taken case */
9111 MIPS_DEBUG("blikely branch taken");
9112 gen_goto_tb(ctx, 0, ctx->btarget);
9113 break;
9114 case MIPS_HFLAG_BC:
9115 /* Conditional branch */
9116 MIPS_DEBUG("conditional branch");
9117 {
9118 int l1 = gen_new_label();
9119
9120 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9121 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9122 gen_set_label(l1);
9123 gen_goto_tb(ctx, 0, ctx->btarget);
9124 }
9125 break;
9126 case MIPS_HFLAG_BR:
9127 /* unconditional branch to register */
9128 MIPS_DEBUG("branch to register");
3c824109 9129 if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
364d4831
NF
9130 TCGv t0 = tcg_temp_new();
9131 TCGv_i32 t1 = tcg_temp_new_i32();
9132
9133 tcg_gen_andi_tl(t0, btarget, 0x1);
9134 tcg_gen_trunc_tl_i32(t1, t0);
9135 tcg_temp_free(t0);
9136 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9137 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9138 tcg_gen_or_i32(hflags, hflags, t1);
9139 tcg_temp_free_i32(t1);
9140
9141 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9142 } else {
9143 tcg_gen_mov_tl(cpu_PC, btarget);
9144 }
c9602061
NF
9145 if (ctx->singlestep_enabled) {
9146 save_cpu_state(ctx, 0);
895c2d04 9147 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
c9602061
NF
9148 }
9149 tcg_gen_exit_tb(0);
9150 break;
9151 default:
9152 MIPS_DEBUG("unknown branch");
9153 break;
9154 }
9155 }
9156}
9157
7a387fff 9158/* ISA extensions (ASEs) */
6af0bf9c 9159/* MIPS16 extension to MIPS32 */
6ea219d0
NF
9160
9161/* MIPS16 major opcodes */
9162enum {
9163 M16_OPC_ADDIUSP = 0x00,
9164 M16_OPC_ADDIUPC = 0x01,
9165 M16_OPC_B = 0x02,
9166 M16_OPC_JAL = 0x03,
9167 M16_OPC_BEQZ = 0x04,
9168 M16_OPC_BNEQZ = 0x05,
9169 M16_OPC_SHIFT = 0x06,
9170 M16_OPC_LD = 0x07,
9171 M16_OPC_RRIA = 0x08,
9172 M16_OPC_ADDIU8 = 0x09,
9173 M16_OPC_SLTI = 0x0a,
9174 M16_OPC_SLTIU = 0x0b,
9175 M16_OPC_I8 = 0x0c,
9176 M16_OPC_LI = 0x0d,
9177 M16_OPC_CMPI = 0x0e,
9178 M16_OPC_SD = 0x0f,
9179 M16_OPC_LB = 0x10,
9180 M16_OPC_LH = 0x11,
9181 M16_OPC_LWSP = 0x12,
9182 M16_OPC_LW = 0x13,
9183 M16_OPC_LBU = 0x14,
9184 M16_OPC_LHU = 0x15,
9185 M16_OPC_LWPC = 0x16,
9186 M16_OPC_LWU = 0x17,
9187 M16_OPC_SB = 0x18,
9188 M16_OPC_SH = 0x19,
9189 M16_OPC_SWSP = 0x1a,
9190 M16_OPC_SW = 0x1b,
9191 M16_OPC_RRR = 0x1c,
9192 M16_OPC_RR = 0x1d,
9193 M16_OPC_EXTEND = 0x1e,
9194 M16_OPC_I64 = 0x1f
9195};
9196
9197/* I8 funct field */
9198enum {
9199 I8_BTEQZ = 0x0,
9200 I8_BTNEZ = 0x1,
9201 I8_SWRASP = 0x2,
9202 I8_ADJSP = 0x3,
9203 I8_SVRS = 0x4,
9204 I8_MOV32R = 0x5,
9205 I8_MOVR32 = 0x7
9206};
9207
9208/* RRR f field */
9209enum {
9210 RRR_DADDU = 0x0,
9211 RRR_ADDU = 0x1,
9212 RRR_DSUBU = 0x2,
9213 RRR_SUBU = 0x3
9214};
9215
9216/* RR funct field */
9217enum {
9218 RR_JR = 0x00,
9219 RR_SDBBP = 0x01,
9220 RR_SLT = 0x02,
9221 RR_SLTU = 0x03,
9222 RR_SLLV = 0x04,
9223 RR_BREAK = 0x05,
9224 RR_SRLV = 0x06,
9225 RR_SRAV = 0x07,
9226 RR_DSRL = 0x08,
9227 RR_CMP = 0x0a,
9228 RR_NEG = 0x0b,
9229 RR_AND = 0x0c,
9230 RR_OR = 0x0d,
9231 RR_XOR = 0x0e,
9232 RR_NOT = 0x0f,
9233 RR_MFHI = 0x10,
9234 RR_CNVT = 0x11,
9235 RR_MFLO = 0x12,
9236 RR_DSRA = 0x13,
9237 RR_DSLLV = 0x14,
9238 RR_DSRLV = 0x16,
9239 RR_DSRAV = 0x17,
9240 RR_MULT = 0x18,
9241 RR_MULTU = 0x19,
9242 RR_DIV = 0x1a,
9243 RR_DIVU = 0x1b,
9244 RR_DMULT = 0x1c,
9245 RR_DMULTU = 0x1d,
9246 RR_DDIV = 0x1e,
9247 RR_DDIVU = 0x1f
9248};
9249
9250/* I64 funct field */
9251enum {
9252 I64_LDSP = 0x0,
9253 I64_SDSP = 0x1,
9254 I64_SDRASP = 0x2,
9255 I64_DADJSP = 0x3,
9256 I64_LDPC = 0x4,
364d4831 9257 I64_DADDIU5 = 0x5,
6ea219d0
NF
9258 I64_DADDIUPC = 0x6,
9259 I64_DADDIUSP = 0x7
9260};
9261
9262/* RR ry field for CNVT */
9263enum {
9264 RR_RY_CNVT_ZEB = 0x0,
9265 RR_RY_CNVT_ZEH = 0x1,
9266 RR_RY_CNVT_ZEW = 0x2,
9267 RR_RY_CNVT_SEB = 0x4,
9268 RR_RY_CNVT_SEH = 0x5,
9269 RR_RY_CNVT_SEW = 0x6,
9270};
9271
364d4831
NF
9272static int xlat (int r)
9273{
9274 static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9275
9276 return map[r];
9277}
9278
9279static void gen_mips16_save (DisasContext *ctx,
9280 int xsregs, int aregs,
9281 int do_ra, int do_s0, int do_s1,
9282 int framesize)
9283{
9284 TCGv t0 = tcg_temp_new();
9285 TCGv t1 = tcg_temp_new();
9286 int args, astatic;
9287
9288 switch (aregs) {
9289 case 0:
9290 case 1:
9291 case 2:
9292 case 3:
9293 case 11:
9294 args = 0;
9295 break;
9296 case 4:
9297 case 5:
9298 case 6:
9299 case 7:
9300 args = 1;
9301 break;
9302 case 8:
9303 case 9:
9304 case 10:
9305 args = 2;
9306 break;
9307 case 12:
9308 case 13:
9309 args = 3;
9310 break;
9311 case 14:
9312 args = 4;
9313 break;
9314 default:
9315 generate_exception(ctx, EXCP_RI);
9316 return;
9317 }
9318
9319 switch (args) {
9320 case 4:
9321 gen_base_offset_addr(ctx, t0, 29, 12);
9322 gen_load_gpr(t1, 7);
5c13fdfd 9323 op_st_sw(t1, t0, ctx);
364d4831
NF
9324 /* Fall through */
9325 case 3:
9326 gen_base_offset_addr(ctx, t0, 29, 8);
9327 gen_load_gpr(t1, 6);
5c13fdfd 9328 op_st_sw(t1, t0, ctx);
364d4831
NF
9329 /* Fall through */
9330 case 2:
9331 gen_base_offset_addr(ctx, t0, 29, 4);
9332 gen_load_gpr(t1, 5);
5c13fdfd 9333 op_st_sw(t1, t0, ctx);
364d4831
NF
9334 /* Fall through */
9335 case 1:
9336 gen_base_offset_addr(ctx, t0, 29, 0);
9337 gen_load_gpr(t1, 4);
5c13fdfd 9338 op_st_sw(t1, t0, ctx);
364d4831
NF
9339 }
9340
9341 gen_load_gpr(t0, 29);
9342
9343#define DECR_AND_STORE(reg) do { \
9344 tcg_gen_subi_tl(t0, t0, 4); \
9345 gen_load_gpr(t1, reg); \
5c13fdfd 9346 op_st_sw(t1, t0, ctx); \
364d4831
NF
9347 } while (0)
9348
9349 if (do_ra) {
9350 DECR_AND_STORE(31);
9351 }
9352
9353 switch (xsregs) {
9354 case 7:
9355 DECR_AND_STORE(30);
9356 /* Fall through */
9357 case 6:
9358 DECR_AND_STORE(23);
9359 /* Fall through */
9360 case 5:
9361 DECR_AND_STORE(22);
9362 /* Fall through */
9363 case 4:
9364 DECR_AND_STORE(21);
9365 /* Fall through */
9366 case 3:
9367 DECR_AND_STORE(20);
9368 /* Fall through */
9369 case 2:
9370 DECR_AND_STORE(19);
9371 /* Fall through */
9372 case 1:
9373 DECR_AND_STORE(18);
9374 }
9375
9376 if (do_s1) {
9377 DECR_AND_STORE(17);
9378 }
9379 if (do_s0) {
9380 DECR_AND_STORE(16);
9381 }
9382
9383 switch (aregs) {
9384 case 0:
9385 case 4:
9386 case 8:
9387 case 12:
9388 case 14:
9389 astatic = 0;
9390 break;
9391 case 1:
9392 case 5:
9393 case 9:
9394 case 13:
9395 astatic = 1;
9396 break;
9397 case 2:
9398 case 6:
9399 case 10:
9400 astatic = 2;
9401 break;
9402 case 3:
9403 case 7:
9404 astatic = 3;
9405 break;
9406 case 11:
9407 astatic = 4;
9408 break;
9409 default:
9410 generate_exception(ctx, EXCP_RI);
9411 return;
9412 }
9413
9414 if (astatic > 0) {
9415 DECR_AND_STORE(7);
9416 if (astatic > 1) {
9417 DECR_AND_STORE(6);
9418 if (astatic > 2) {
9419 DECR_AND_STORE(5);
9420 if (astatic > 3) {
9421 DECR_AND_STORE(4);
9422 }
9423 }
9424 }
9425 }
9426#undef DECR_AND_STORE
9427
9428 tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9429 tcg_temp_free(t0);
9430 tcg_temp_free(t1);
9431}
9432
9433static void gen_mips16_restore (DisasContext *ctx,
9434 int xsregs, int aregs,
9435 int do_ra, int do_s0, int do_s1,
9436 int framesize)
9437{
9438 int astatic;
9439 TCGv t0 = tcg_temp_new();
9440 TCGv t1 = tcg_temp_new();
9441
9442 tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9443
9444#define DECR_AND_LOAD(reg) do { \
9445 tcg_gen_subi_tl(t0, t0, 4); \
5c13fdfd 9446 op_ld_lw(t1, t0, ctx); \
364d4831
NF
9447 gen_store_gpr(t1, reg); \
9448 } while (0)
9449
9450 if (do_ra) {
9451 DECR_AND_LOAD(31);
9452 }
9453
9454 switch (xsregs) {
9455 case 7:
9456 DECR_AND_LOAD(30);
9457 /* Fall through */
9458 case 6:
9459 DECR_AND_LOAD(23);
9460 /* Fall through */
9461 case 5:
9462 DECR_AND_LOAD(22);
9463 /* Fall through */
9464 case 4:
9465 DECR_AND_LOAD(21);
9466 /* Fall through */
9467 case 3:
9468 DECR_AND_LOAD(20);
9469 /* Fall through */
9470 case 2:
9471 DECR_AND_LOAD(19);
9472 /* Fall through */
9473 case 1:
9474 DECR_AND_LOAD(18);
9475 }
9476
9477 if (do_s1) {
9478 DECR_AND_LOAD(17);
9479 }
9480 if (do_s0) {
9481 DECR_AND_LOAD(16);
9482 }
9483
9484 switch (aregs) {
9485 case 0:
9486 case 4:
9487 case 8:
9488 case 12:
9489 case 14:
9490 astatic = 0;
9491 break;
9492 case 1:
9493 case 5:
9494 case 9:
9495 case 13:
9496 astatic = 1;
9497 break;
9498 case 2:
9499 case 6:
9500 case 10:
9501 astatic = 2;
9502 break;
9503 case 3:
9504 case 7:
9505 astatic = 3;
9506 break;
9507 case 11:
9508 astatic = 4;
9509 break;
9510 default:
9511 generate_exception(ctx, EXCP_RI);
9512 return;
9513 }
9514
9515 if (astatic > 0) {
9516 DECR_AND_LOAD(7);
9517 if (astatic > 1) {
9518 DECR_AND_LOAD(6);
9519 if (astatic > 2) {
9520 DECR_AND_LOAD(5);
9521 if (astatic > 3) {
9522 DECR_AND_LOAD(4);
9523 }
9524 }
9525 }
9526 }
9527#undef DECR_AND_LOAD
9528
9529 tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9530 tcg_temp_free(t0);
9531 tcg_temp_free(t1);
9532}
9533
9534static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9535 int is_64_bit, int extended)
9536{
9537 TCGv t0;
9538
9539 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9540 generate_exception(ctx, EXCP_RI);
9541 return;
9542 }
9543
9544 t0 = tcg_temp_new();
9545
9546 tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9547 tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9548 if (!is_64_bit) {
9549 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9550 }
9551
9552 tcg_temp_free(t0);
9553}
9554
9555#if defined(TARGET_MIPS64)
7db13fae 9556static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9557 int ry, int funct, int16_t offset,
9558 int extended)
9559{
9560 switch (funct) {
9561 case I64_LDSP:
9562 check_mips_64(ctx);
9563 offset = extended ? offset : offset << 3;
afa88c3a 9564 gen_ld(env, ctx, OPC_LD, ry, 29, offset);
364d4831
NF
9565 break;
9566 case I64_SDSP:
9567 check_mips_64(ctx);
9568 offset = extended ? offset : offset << 3;
5c13fdfd 9569 gen_st(ctx, OPC_SD, ry, 29, offset);
364d4831
NF
9570 break;
9571 case I64_SDRASP:
9572 check_mips_64(ctx);
9573 offset = extended ? offset : (ctx->opcode & 0xff) << 3;
5c13fdfd 9574 gen_st(ctx, OPC_SD, 31, 29, offset);
364d4831
NF
9575 break;
9576 case I64_DADJSP:
9577 check_mips_64(ctx);
9578 offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9579 gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
9580 break;
9581 case I64_LDPC:
9582 if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9583 generate_exception(ctx, EXCP_RI);
9584 } else {
9585 offset = extended ? offset : offset << 3;
afa88c3a 9586 gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
364d4831
NF
9587 }
9588 break;
9589 case I64_DADDIU5:
9590 check_mips_64(ctx);
9591 offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9592 gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
9593 break;
9594 case I64_DADDIUPC:
9595 check_mips_64(ctx);
9596 offset = extended ? offset : offset << 2;
9597 gen_addiupc(ctx, ry, offset, 1, extended);
9598 break;
9599 case I64_DADDIUSP:
9600 check_mips_64(ctx);
9601 offset = extended ? offset : offset << 2;
9602 gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
9603 break;
9604 }
9605}
9606#endif
9607
7db13fae 9608static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9609 int *is_branch)
9610{
895c2d04 9611 int extend = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9612 int op, rx, ry, funct, sa;
9613 int16_t imm, offset;
9614
9615 ctx->opcode = (ctx->opcode << 16) | extend;
9616 op = (ctx->opcode >> 11) & 0x1f;
9617 sa = (ctx->opcode >> 22) & 0x1f;
9618 funct = (ctx->opcode >> 8) & 0x7;
9619 rx = xlat((ctx->opcode >> 8) & 0x7);
9620 ry = xlat((ctx->opcode >> 5) & 0x7);
9621 offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9622 | ((ctx->opcode >> 21) & 0x3f) << 5
9623 | (ctx->opcode & 0x1f));
9624
9625 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9626 counterparts. */
9627 switch (op) {
9628 case M16_OPC_ADDIUSP:
9629 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9630 break;
9631 case M16_OPC_ADDIUPC:
9632 gen_addiupc(ctx, rx, imm, 0, 1);
9633 break;
9634 case M16_OPC_B:
9635 gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9636 /* No delay slot, so just process as a normal instruction */
9637 break;
9638 case M16_OPC_BEQZ:
9639 gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9640 /* No delay slot, so just process as a normal instruction */
9641 break;
9642 case M16_OPC_BNEQZ:
9643 gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9644 /* No delay slot, so just process as a normal instruction */
9645 break;
9646 case M16_OPC_SHIFT:
9647 switch (ctx->opcode & 0x3) {
9648 case 0x0:
9649 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9650 break;
9651 case 0x1:
9652#if defined(TARGET_MIPS64)
9653 check_mips_64(ctx);
9654 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9655#else
9656 generate_exception(ctx, EXCP_RI);
9657#endif
9658 break;
9659 case 0x2:
9660 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9661 break;
9662 case 0x3:
9663 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9664 break;
9665 }
9666 break;
9667#if defined(TARGET_MIPS64)
9668 case M16_OPC_LD:
9669 check_mips_64(ctx);
afa88c3a 9670 gen_ld(env, ctx, OPC_LD, ry, rx, offset);
364d4831
NF
9671 break;
9672#endif
9673 case M16_OPC_RRIA:
9674 imm = ctx->opcode & 0xf;
9675 imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9676 imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9677 imm = (int16_t) (imm << 1) >> 1;
9678 if ((ctx->opcode >> 4) & 0x1) {
9679#if defined(TARGET_MIPS64)
9680 check_mips_64(ctx);
9681 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9682#else
9683 generate_exception(ctx, EXCP_RI);
9684#endif
9685 } else {
9686 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9687 }
9688 break;
9689 case M16_OPC_ADDIU8:
9690 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9691 break;
9692 case M16_OPC_SLTI:
9fa77488 9693 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9694 break;
9695 case M16_OPC_SLTIU:
9fa77488 9696 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9697 break;
9698 case M16_OPC_I8:
9699 switch (funct) {
9700 case I8_BTEQZ:
9701 gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9702 break;
9703 case I8_BTNEZ:
9704 gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9705 break;
9706 case I8_SWRASP:
5c13fdfd 9707 gen_st(ctx, OPC_SW, 31, 29, imm);
364d4831
NF
9708 break;
9709 case I8_ADJSP:
9710 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
9711 break;
9712 case I8_SVRS:
9713 {
9714 int xsregs = (ctx->opcode >> 24) & 0x7;
9715 int aregs = (ctx->opcode >> 16) & 0xf;
9716 int do_ra = (ctx->opcode >> 6) & 0x1;
9717 int do_s0 = (ctx->opcode >> 5) & 0x1;
9718 int do_s1 = (ctx->opcode >> 4) & 0x1;
9719 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9720 | (ctx->opcode & 0xf)) << 3;
9721
9722 if (ctx->opcode & (1 << 7)) {
9723 gen_mips16_save(ctx, xsregs, aregs,
9724 do_ra, do_s0, do_s1,
9725 framesize);
9726 } else {
9727 gen_mips16_restore(ctx, xsregs, aregs,
9728 do_ra, do_s0, do_s1,
9729 framesize);
9730 }
9731 }
9732 break;
9733 default:
9734 generate_exception(ctx, EXCP_RI);
9735 break;
9736 }
9737 break;
9738 case M16_OPC_LI:
9739 tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9740 break;
9741 case M16_OPC_CMPI:
9742 tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9743 break;
9744#if defined(TARGET_MIPS64)
9745 case M16_OPC_SD:
5c13fdfd 9746 gen_st(ctx, OPC_SD, ry, rx, offset);
364d4831
NF
9747 break;
9748#endif
9749 case M16_OPC_LB:
afa88c3a 9750 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9751 break;
9752 case M16_OPC_LH:
afa88c3a 9753 gen_ld(env, ctx, OPC_LH, ry, rx, offset);
364d4831
NF
9754 break;
9755 case M16_OPC_LWSP:
afa88c3a 9756 gen_ld(env, ctx, OPC_LW, rx, 29, offset);
364d4831
NF
9757 break;
9758 case M16_OPC_LW:
afa88c3a 9759 gen_ld(env, ctx, OPC_LW, ry, rx, offset);
364d4831
NF
9760 break;
9761 case M16_OPC_LBU:
afa88c3a 9762 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
9763 break;
9764 case M16_OPC_LHU:
afa88c3a 9765 gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
364d4831
NF
9766 break;
9767 case M16_OPC_LWPC:
afa88c3a 9768 gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
364d4831
NF
9769 break;
9770#if defined(TARGET_MIPS64)
9771 case M16_OPC_LWU:
afa88c3a 9772 gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
364d4831
NF
9773 break;
9774#endif
9775 case M16_OPC_SB:
5c13fdfd 9776 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
9777 break;
9778 case M16_OPC_SH:
5c13fdfd 9779 gen_st(ctx, OPC_SH, ry, rx, offset);
364d4831
NF
9780 break;
9781 case M16_OPC_SWSP:
5c13fdfd 9782 gen_st(ctx, OPC_SW, rx, 29, offset);
364d4831
NF
9783 break;
9784 case M16_OPC_SW:
5c13fdfd 9785 gen_st(ctx, OPC_SW, ry, rx, offset);
364d4831
NF
9786 break;
9787#if defined(TARGET_MIPS64)
9788 case M16_OPC_I64:
9789 decode_i64_mips16(env, ctx, ry, funct, offset, 1);
9790 break;
9791#endif
9792 default:
9793 generate_exception(ctx, EXCP_RI);
9794 break;
9795 }
9796
9797 return 4;
9798}
9799
7db13fae 9800static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
364d4831
NF
9801 int *is_branch)
9802{
9803 int rx, ry;
9804 int sa;
9805 int op, cnvt_op, op1, offset;
9806 int funct;
9807 int n_bytes;
9808
9809 op = (ctx->opcode >> 11) & 0x1f;
9810 sa = (ctx->opcode >> 2) & 0x7;
9811 sa = sa == 0 ? 8 : sa;
9812 rx = xlat((ctx->opcode >> 8) & 0x7);
9813 cnvt_op = (ctx->opcode >> 5) & 0x7;
9814 ry = xlat((ctx->opcode >> 5) & 0x7);
9815 op1 = offset = ctx->opcode & 0x1f;
9816
9817 n_bytes = 2;
9818
9819 switch (op) {
9820 case M16_OPC_ADDIUSP:
9821 {
9822 int16_t imm = ((uint8_t) ctx->opcode) << 2;
9823
9824 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
9825 }
9826 break;
9827 case M16_OPC_ADDIUPC:
9828 gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9829 break;
9830 case M16_OPC_B:
9831 offset = (ctx->opcode & 0x7ff) << 1;
9832 offset = (int16_t)(offset << 4) >> 4;
9833 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9834 /* No delay slot, so just process as a normal instruction */
9835 break;
9836 case M16_OPC_JAL:
895c2d04 9837 offset = cpu_lduw_code(env, ctx->pc + 2);
364d4831
NF
9838 offset = (((ctx->opcode & 0x1f) << 21)
9839 | ((ctx->opcode >> 5) & 0x1f) << 16
9840 | offset) << 2;
620e48f6 9841 op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
364d4831
NF
9842 gen_compute_branch(ctx, op, 4, rx, ry, offset);
9843 n_bytes = 4;
9844 *is_branch = 1;
9845 break;
9846 case M16_OPC_BEQZ:
9847 gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9848 /* No delay slot, so just process as a normal instruction */
9849 break;
9850 case M16_OPC_BNEQZ:
9851 gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9852 /* No delay slot, so just process as a normal instruction */
9853 break;
9854 case M16_OPC_SHIFT:
9855 switch (ctx->opcode & 0x3) {
9856 case 0x0:
9857 gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
9858 break;
9859 case 0x1:
9860#if defined(TARGET_MIPS64)
9861 check_mips_64(ctx);
9862 gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
9863#else
9864 generate_exception(ctx, EXCP_RI);
9865#endif
9866 break;
9867 case 0x2:
9868 gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
9869 break;
9870 case 0x3:
9871 gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
9872 break;
9873 }
9874 break;
9875#if defined(TARGET_MIPS64)
9876 case M16_OPC_LD:
9877 check_mips_64(ctx);
afa88c3a 9878 gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
364d4831
NF
9879 break;
9880#endif
9881 case M16_OPC_RRIA:
9882 {
9883 int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9884
9885 if ((ctx->opcode >> 4) & 1) {
9886#if defined(TARGET_MIPS64)
9887 check_mips_64(ctx);
9888 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
9889#else
9890 generate_exception(ctx, EXCP_RI);
9891#endif
9892 } else {
9893 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
9894 }
9895 }
9896 break;
9897 case M16_OPC_ADDIU8:
9898 {
9899 int16_t imm = (int8_t) ctx->opcode;
9900
9901 gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
9902 }
9903 break;
9904 case M16_OPC_SLTI:
9905 {
9906 int16_t imm = (uint8_t) ctx->opcode;
9fa77488 9907 gen_slt_imm(env, ctx, OPC_SLTI, 24, rx, imm);
364d4831
NF
9908 }
9909 break;
9910 case M16_OPC_SLTIU:
9911 {
9912 int16_t imm = (uint8_t) ctx->opcode;
9fa77488 9913 gen_slt_imm(env, ctx, OPC_SLTIU, 24, rx, imm);
364d4831
NF
9914 }
9915 break;
9916 case M16_OPC_I8:
9917 {
9918 int reg32;
9919
9920 funct = (ctx->opcode >> 8) & 0x7;
9921 switch (funct) {
9922 case I8_BTEQZ:
9923 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9924 ((int8_t)ctx->opcode) << 1);
9925 break;
9926 case I8_BTNEZ:
9927 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9928 ((int8_t)ctx->opcode) << 1);
9929 break;
9930 case I8_SWRASP:
5c13fdfd 9931 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
364d4831
NF
9932 break;
9933 case I8_ADJSP:
9934 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
9935 ((int8_t)ctx->opcode) << 3);
9936 break;
9937 case I8_SVRS:
9938 {
9939 int do_ra = ctx->opcode & (1 << 6);
9940 int do_s0 = ctx->opcode & (1 << 5);
9941 int do_s1 = ctx->opcode & (1 << 4);
9942 int framesize = ctx->opcode & 0xf;
9943
9944 if (framesize == 0) {
9945 framesize = 128;
9946 } else {
9947 framesize = framesize << 3;
9948 }
9949
9950 if (ctx->opcode & (1 << 7)) {
9951 gen_mips16_save(ctx, 0, 0,
9952 do_ra, do_s0, do_s1, framesize);
9953 } else {
9954 gen_mips16_restore(ctx, 0, 0,
9955 do_ra, do_s0, do_s1, framesize);
9956 }
9957 }
9958 break;
9959 case I8_MOV32R:
9960 {
9961 int rz = xlat(ctx->opcode & 0x7);
9962
9963 reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9964 ((ctx->opcode >> 5) & 0x7);
9965 gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
9966 }
9967 break;
9968 case I8_MOVR32:
9969 reg32 = ctx->opcode & 0x1f;
9970 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
9971 break;
9972 default:
9973 generate_exception(ctx, EXCP_RI);
9974 break;
9975 }
9976 }
9977 break;
9978 case M16_OPC_LI:
9979 {
9980 int16_t imm = (uint8_t) ctx->opcode;
9981
9982 gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
9983 }
9984 break;
9985 case M16_OPC_CMPI:
9986 {
9987 int16_t imm = (uint8_t) ctx->opcode;
9fa77488 9988 gen_logic_imm(env, ctx, OPC_XORI, 24, rx, imm);
364d4831
NF
9989 }
9990 break;
9991#if defined(TARGET_MIPS64)
9992 case M16_OPC_SD:
9993 check_mips_64(ctx);
5c13fdfd 9994 gen_st(ctx, OPC_SD, ry, rx, offset << 3);
364d4831
NF
9995 break;
9996#endif
9997 case M16_OPC_LB:
afa88c3a 9998 gen_ld(env, ctx, OPC_LB, ry, rx, offset);
364d4831
NF
9999 break;
10000 case M16_OPC_LH:
afa88c3a 10001 gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
364d4831
NF
10002 break;
10003 case M16_OPC_LWSP:
afa88c3a 10004 gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10005 break;
10006 case M16_OPC_LW:
afa88c3a 10007 gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
364d4831
NF
10008 break;
10009 case M16_OPC_LBU:
afa88c3a 10010 gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
364d4831
NF
10011 break;
10012 case M16_OPC_LHU:
afa88c3a 10013 gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
364d4831
NF
10014 break;
10015 case M16_OPC_LWPC:
afa88c3a 10016 gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10017 break;
10018#if defined (TARGET_MIPS64)
10019 case M16_OPC_LWU:
10020 check_mips_64(ctx);
afa88c3a 10021 gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
364d4831
NF
10022 break;
10023#endif
10024 case M16_OPC_SB:
5c13fdfd 10025 gen_st(ctx, OPC_SB, ry, rx, offset);
364d4831
NF
10026 break;
10027 case M16_OPC_SH:
5c13fdfd 10028 gen_st(ctx, OPC_SH, ry, rx, offset << 1);
364d4831
NF
10029 break;
10030 case M16_OPC_SWSP:
5c13fdfd 10031 gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
364d4831
NF
10032 break;
10033 case M16_OPC_SW:
5c13fdfd 10034 gen_st(ctx, OPC_SW, ry, rx, offset << 2);
364d4831
NF
10035 break;
10036 case M16_OPC_RRR:
10037 {
10038 int rz = xlat((ctx->opcode >> 2) & 0x7);
10039 int mips32_op;
10040
10041 switch (ctx->opcode & 0x3) {
10042 case RRR_ADDU:
10043 mips32_op = OPC_ADDU;
10044 break;
10045 case RRR_SUBU:
10046 mips32_op = OPC_SUBU;
10047 break;
10048#if defined(TARGET_MIPS64)
10049 case RRR_DADDU:
10050 mips32_op = OPC_DADDU;
10051 check_mips_64(ctx);
10052 break;
10053 case RRR_DSUBU:
10054 mips32_op = OPC_DSUBU;
10055 check_mips_64(ctx);
10056 break;
10057#endif
10058 default:
10059 generate_exception(ctx, EXCP_RI);
10060 goto done;
10061 }
10062
10063 gen_arith(env, ctx, mips32_op, rz, rx, ry);
10064 done:
10065 ;
10066 }
10067 break;
10068 case M16_OPC_RR:
10069 switch (op1) {
10070 case RR_JR:
10071 {
10072 int nd = (ctx->opcode >> 7) & 0x1;
10073 int link = (ctx->opcode >> 6) & 0x1;
10074 int ra = (ctx->opcode >> 5) & 0x1;
10075
10076 if (link) {
620e48f6 10077 op = nd ? OPC_JALRC : OPC_JALRS;
364d4831
NF
10078 } else {
10079 op = OPC_JR;
10080 }
10081
10082 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10083 if (!nd) {
10084 *is_branch = 1;
10085 }
10086 }
10087 break;
10088 case RR_SDBBP:
10089 /* XXX: not clear which exception should be raised
10090 * when in debug mode...
10091 */
10092 check_insn(env, ctx, ISA_MIPS32);
10093 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10094 generate_exception(ctx, EXCP_DBp);
10095 } else {
10096 generate_exception(ctx, EXCP_DBp);
10097 }
10098 break;
10099 case RR_SLT:
9fa77488 10100 gen_slt(env, ctx, OPC_SLT, 24, rx, ry);
364d4831
NF
10101 break;
10102 case RR_SLTU:
9fa77488 10103 gen_slt(env, ctx, OPC_SLTU, 24, rx, ry);
364d4831
NF
10104 break;
10105 case RR_BREAK:
10106 generate_exception(ctx, EXCP_BREAK);
10107 break;
10108 case RR_SLLV:
10109 gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
10110 break;
10111 case RR_SRLV:
10112 gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
10113 break;
10114 case RR_SRAV:
10115 gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
10116 break;
10117#if defined (TARGET_MIPS64)
10118 case RR_DSRL:
10119 check_mips_64(ctx);
10120 gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
10121 break;
10122#endif
10123 case RR_CMP:
9fa77488 10124 gen_logic(env, ctx, OPC_XOR, 24, rx, ry);
364d4831
NF
10125 break;
10126 case RR_NEG:
10127 gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
10128 break;
10129 case RR_AND:
9fa77488 10130 gen_logic(env, ctx, OPC_AND, rx, rx, ry);
364d4831
NF
10131 break;
10132 case RR_OR:
9fa77488 10133 gen_logic(env, ctx, OPC_OR, rx, rx, ry);
364d4831
NF
10134 break;
10135 case RR_XOR:
9fa77488 10136 gen_logic(env, ctx, OPC_XOR, rx, rx, ry);
364d4831
NF
10137 break;
10138 case RR_NOT:
9fa77488 10139 gen_logic(env, ctx, OPC_NOR, rx, ry, 0);
364d4831
NF
10140 break;
10141 case RR_MFHI:
10142 gen_HILO(ctx, OPC_MFHI, rx);
10143 break;
10144 case RR_CNVT:
10145 switch (cnvt_op) {
10146 case RR_RY_CNVT_ZEB:
10147 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10148 break;
10149 case RR_RY_CNVT_ZEH:
10150 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10151 break;
10152 case RR_RY_CNVT_SEB:
10153 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10154 break;
10155 case RR_RY_CNVT_SEH:
10156 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10157 break;
10158#if defined (TARGET_MIPS64)
10159 case RR_RY_CNVT_ZEW:
10160 check_mips_64(ctx);
10161 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10162 break;
10163 case RR_RY_CNVT_SEW:
10164 check_mips_64(ctx);
10165 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10166 break;
10167#endif
10168 default:
10169 generate_exception(ctx, EXCP_RI);
10170 break;
10171 }
10172 break;
10173 case RR_MFLO:
10174 gen_HILO(ctx, OPC_MFLO, rx);
10175 break;
10176#if defined (TARGET_MIPS64)
10177 case RR_DSRA:
10178 check_mips_64(ctx);
10179 gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
10180 break;
10181 case RR_DSLLV:
10182 check_mips_64(ctx);
10183 gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
10184 break;
10185 case RR_DSRLV:
10186 check_mips_64(ctx);
10187 gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
10188 break;
10189 case RR_DSRAV:
10190 check_mips_64(ctx);
10191 gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
10192 break;
10193#endif
10194 case RR_MULT:
10195 gen_muldiv(ctx, OPC_MULT, rx, ry);
10196 break;
10197 case RR_MULTU:
10198 gen_muldiv(ctx, OPC_MULTU, rx, ry);
10199 break;
10200 case RR_DIV:
10201 gen_muldiv(ctx, OPC_DIV, rx, ry);
10202 break;
10203 case RR_DIVU:
10204 gen_muldiv(ctx, OPC_DIVU, rx, ry);
10205 break;
10206#if defined (TARGET_MIPS64)
10207 case RR_DMULT:
10208 check_mips_64(ctx);
10209 gen_muldiv(ctx, OPC_DMULT, rx, ry);
10210 break;
10211 case RR_DMULTU:
10212 check_mips_64(ctx);
10213 gen_muldiv(ctx, OPC_DMULTU, rx, ry);
10214 break;
10215 case RR_DDIV:
10216 check_mips_64(ctx);
10217 gen_muldiv(ctx, OPC_DDIV, rx, ry);
10218 break;
10219 case RR_DDIVU:
10220 check_mips_64(ctx);
10221 gen_muldiv(ctx, OPC_DDIVU, rx, ry);
10222 break;
10223#endif
10224 default:
10225 generate_exception(ctx, EXCP_RI);
10226 break;
10227 }
10228 break;
10229 case M16_OPC_EXTEND:
10230 decode_extended_mips16_opc(env, ctx, is_branch);
10231 n_bytes = 4;
10232 break;
10233#if defined(TARGET_MIPS64)
10234 case M16_OPC_I64:
10235 funct = (ctx->opcode >> 8) & 0x7;
10236 decode_i64_mips16(env, ctx, ry, funct, offset, 0);
10237 break;
10238#endif
10239 default:
10240 generate_exception(ctx, EXCP_RI);
10241 break;
10242 }
10243
10244 return n_bytes;
10245}
10246
3c824109 10247/* microMIPS extension to MIPS32 */
6af0bf9c 10248
3c824109 10249/* microMIPS32 major opcodes */
6af0bf9c 10250
3c824109
NF
10251enum {
10252 POOL32A = 0x00,
10253 POOL16A = 0x01,
10254 LBU16 = 0x02,
10255 MOVE16 = 0x03,
10256 ADDI32 = 0x04,
10257 LBU32 = 0x05,
10258 SB32 = 0x06,
10259 LB32 = 0x07,
10260
10261 POOL32B = 0x08,
10262 POOL16B = 0x09,
10263 LHU16 = 0x0a,
10264 ANDI16 = 0x0b,
10265 ADDIU32 = 0x0c,
10266 LHU32 = 0x0d,
10267 SH32 = 0x0e,
10268 LH32 = 0x0f,
10269
10270 POOL32I = 0x10,
10271 POOL16C = 0x11,
10272 LWSP16 = 0x12,
10273 POOL16D = 0x13,
10274 ORI32 = 0x14,
10275 POOL32F = 0x15,
10276 POOL32S = 0x16,
10277 DADDIU32 = 0x17,
10278
10279 POOL32C = 0x18,
10280 LWGP16 = 0x19,
10281 LW16 = 0x1a,
10282 POOL16E = 0x1b,
10283 XORI32 = 0x1c,
10284 JALS32 = 0x1d,
10285 ADDIUPC = 0x1e,
10286 POOL48A = 0x1f,
10287
10288 /* 0x20 is reserved */
10289 RES_20 = 0x20,
10290 POOL16F = 0x21,
10291 SB16 = 0x22,
10292 BEQZ16 = 0x23,
10293 SLTI32 = 0x24,
10294 BEQ32 = 0x25,
10295 SWC132 = 0x26,
10296 LWC132 = 0x27,
10297
10298 /* 0x28 and 0x29 are reserved */
10299 RES_28 = 0x28,
10300 RES_29 = 0x29,
10301 SH16 = 0x2a,
10302 BNEZ16 = 0x2b,
10303 SLTIU32 = 0x2c,
10304 BNE32 = 0x2d,
10305 SDC132 = 0x2e,
10306 LDC132 = 0x2f,
10307
10308 /* 0x30 and 0x31 are reserved */
10309 RES_30 = 0x30,
10310 RES_31 = 0x31,
10311 SWSP16 = 0x32,
10312 B16 = 0x33,
10313 ANDI32 = 0x34,
10314 J32 = 0x35,
10315 SD32 = 0x36,
10316 LD32 = 0x37,
10317
10318 /* 0x38 and 0x39 are reserved */
10319 RES_38 = 0x38,
10320 RES_39 = 0x39,
10321 SW16 = 0x3a,
10322 LI16 = 0x3b,
10323 JALX32 = 0x3c,
10324 JAL32 = 0x3d,
10325 SW32 = 0x3e,
10326 LW32 = 0x3f
10327};
10328
10329/* POOL32A encoding of minor opcode field */
10330
10331enum {
10332 /* These opcodes are distinguished only by bits 9..6; those bits are
10333 * what are recorded below. */
10334 SLL32 = 0x0,
10335 SRL32 = 0x1,
10336 SRA = 0x2,
10337 ROTR = 0x3,
10338
10339 SLLV = 0x0,
10340 SRLV = 0x1,
10341 SRAV = 0x2,
10342 ROTRV = 0x3,
10343 ADD = 0x4,
10344 ADDU32 = 0x5,
10345 SUB = 0x6,
10346 SUBU32 = 0x7,
10347 MUL = 0x8,
10348 AND = 0x9,
10349 OR32 = 0xa,
10350 NOR = 0xb,
10351 XOR32 = 0xc,
10352 SLT = 0xd,
10353 SLTU = 0xe,
10354
10355 MOVN = 0x0,
10356 MOVZ = 0x1,
10357 LWXS = 0x4,
10358
10359 /* The following can be distinguished by their lower 6 bits. */
10360 INS = 0x0c,
10361 EXT = 0x2c,
10362 POOL32AXF = 0x3c
10363};
10364
10365/* POOL32AXF encoding of minor opcode field extension */
10366
10367enum {
10368 /* bits 11..6 */
10369 TEQ = 0x00,
10370 TGE = 0x08,
10371 TGEU = 0x10,
10372 TLT = 0x20,
10373 TLTU = 0x28,
10374 TNE = 0x30,
10375
10376 MFC0 = 0x03,
10377 MTC0 = 0x0b,
10378
10379 /* bits 13..12 for 0x01 */
10380 MFHI_ACC = 0x0,
10381 MFLO_ACC = 0x1,
10382 MTHI_ACC = 0x2,
10383 MTLO_ACC = 0x3,
10384
10385 /* bits 13..12 for 0x2a */
10386 MADD_ACC = 0x0,
10387 MADDU_ACC = 0x1,
10388 MSUB_ACC = 0x2,
10389 MSUBU_ACC = 0x3,
10390
10391 /* bits 13..12 for 0x32 */
10392 MULT_ACC = 0x0,
10393 MULTU_ACC = 0x0,
10394
10395 /* bits 15..12 for 0x2c */
10396 SEB = 0x2,
10397 SEH = 0x3,
10398 CLO = 0x4,
10399 CLZ = 0x5,
10400 RDHWR = 0x6,
10401 WSBH = 0x7,
10402 MULT = 0x8,
10403 MULTU = 0x9,
10404 DIV = 0xa,
10405 DIVU = 0xb,
10406 MADD = 0xc,
10407 MADDU = 0xd,
10408 MSUB = 0xe,
10409 MSUBU = 0xf,
10410
10411 /* bits 15..12 for 0x34 */
10412 MFC2 = 0x4,
10413 MTC2 = 0x5,
10414 MFHC2 = 0x8,
10415 MTHC2 = 0x9,
10416 CFC2 = 0xc,
10417 CTC2 = 0xd,
10418
10419 /* bits 15..12 for 0x3c */
10420 JALR = 0x0,
10421 JR = 0x0, /* alias */
10422 JALR_HB = 0x1,
10423 JALRS = 0x4,
10424 JALRS_HB = 0x5,
10425
10426 /* bits 15..12 for 0x05 */
10427 RDPGPR = 0xe,
10428 WRPGPR = 0xf,
10429
10430 /* bits 15..12 for 0x0d */
10431 TLBP = 0x0,
10432 TLBR = 0x1,
10433 TLBWI = 0x2,
10434 TLBWR = 0x3,
10435 WAIT = 0x9,
10436 IRET = 0xd,
10437 DERET = 0xe,
10438 ERET = 0xf,
10439
10440 /* bits 15..12 for 0x15 */
10441 DMT = 0x0,
10442 DVPE = 0x1,
10443 EMT = 0x2,
10444 EVPE = 0x3,
10445
10446 /* bits 15..12 for 0x1d */
10447 DI = 0x4,
10448 EI = 0x5,
10449
10450 /* bits 15..12 for 0x2d */
10451 SYNC = 0x6,
10452 SYSCALL = 0x8,
10453 SDBBP = 0xd,
10454
10455 /* bits 15..12 for 0x35 */
10456 MFHI32 = 0x0,
10457 MFLO32 = 0x1,
10458 MTHI32 = 0x2,
10459 MTLO32 = 0x3,
10460};
10461
10462/* POOL32B encoding of minor opcode field (bits 15..12) */
10463
10464enum {
10465 LWC2 = 0x0,
10466 LWP = 0x1,
10467 LDP = 0x4,
10468 LWM32 = 0x5,
10469 CACHE = 0x6,
10470 LDM = 0x7,
10471 SWC2 = 0x8,
10472 SWP = 0x9,
10473 SDP = 0xc,
10474 SWM32 = 0xd,
10475 SDM = 0xf
10476};
10477
10478/* POOL32C encoding of minor opcode field (bits 15..12) */
10479
10480enum {
10481 LWL = 0x0,
10482 SWL = 0x8,
10483 LWR = 0x1,
10484 SWR = 0x9,
10485 PREF = 0x2,
10486 /* 0xa is reserved */
10487 LL = 0x3,
10488 SC = 0xb,
10489 LDL = 0x4,
10490 SDL = 0xc,
10491 LDR = 0x5,
10492 SDR = 0xd,
10493 /* 0x6 is reserved */
10494 LWU = 0xe,
10495 LLD = 0x7,
10496 SCD = 0xf
10497};
10498
10499/* POOL32F encoding of minor opcode field (bits 5..0) */
10500
10501enum {
10502 /* These are the bit 7..6 values */
10503 ADD_FMT = 0x0,
10504 MOVN_FMT = 0x0,
10505
10506 SUB_FMT = 0x1,
10507 MOVZ_FMT = 0x1,
10508
10509 MUL_FMT = 0x2,
10510
10511 DIV_FMT = 0x3,
10512
10513 /* These are the bit 8..6 values */
10514 RSQRT2_FMT = 0x0,
10515 MOVF_FMT = 0x0,
10516
10517 LWXC1 = 0x1,
10518 MOVT_FMT = 0x1,
10519
10520 PLL_PS = 0x2,
10521 SWXC1 = 0x2,
10522
10523 PLU_PS = 0x3,
10524 LDXC1 = 0x3,
10525
10526 PUL_PS = 0x4,
10527 SDXC1 = 0x4,
10528 RECIP2_FMT = 0x4,
10529
10530 PUU_PS = 0x5,
10531 LUXC1 = 0x5,
10532
10533 CVT_PS_S = 0x6,
10534 SUXC1 = 0x6,
10535 ADDR_PS = 0x6,
10536 PREFX = 0x6,
10537
10538 MULR_PS = 0x7,
10539
10540 MADD_S = 0x01,
10541 MADD_D = 0x09,
10542 MADD_PS = 0x11,
10543 ALNV_PS = 0x19,
10544 MSUB_S = 0x21,
10545 MSUB_D = 0x29,
10546 MSUB_PS = 0x31,
10547
10548 NMADD_S = 0x02,
10549 NMADD_D = 0x0a,
10550 NMADD_PS = 0x12,
10551 NMSUB_S = 0x22,
10552 NMSUB_D = 0x2a,
10553 NMSUB_PS = 0x32,
10554
10555 POOL32FXF = 0x3b,
10556
10557 CABS_COND_FMT = 0x1c, /* MIPS3D */
10558 C_COND_FMT = 0x3c
10559};
10560
10561/* POOL32Fxf encoding of minor opcode extension field */
10562
10563enum {
10564 CVT_L = 0x04,
10565 RSQRT_FMT = 0x08,
10566 FLOOR_L = 0x0c,
10567 CVT_PW_PS = 0x1c,
10568 CVT_W = 0x24,
10569 SQRT_FMT = 0x28,
10570 FLOOR_W = 0x2c,
10571 CVT_PS_PW = 0x3c,
10572 CFC1 = 0x40,
10573 RECIP_FMT = 0x48,
10574 CEIL_L = 0x4c,
10575 CTC1 = 0x60,
10576 CEIL_W = 0x6c,
10577 MFC1 = 0x80,
10578 CVT_S_PL = 0x84,
10579 TRUNC_L = 0x8c,
10580 MTC1 = 0xa0,
10581 CVT_S_PU = 0xa4,
10582 TRUNC_W = 0xac,
10583 MFHC1 = 0xc0,
10584 ROUND_L = 0xcc,
10585 MTHC1 = 0xe0,
10586 ROUND_W = 0xec,
10587
10588 MOV_FMT = 0x01,
10589 MOVF = 0x05,
10590 ABS_FMT = 0x0d,
10591 RSQRT1_FMT = 0x1d,
10592 MOVT = 0x25,
10593 NEG_FMT = 0x2d,
10594 CVT_D = 0x4d,
10595 RECIP1_FMT = 0x5d,
10596 CVT_S = 0x6d
10597};
10598
10599/* POOL32I encoding of minor opcode field (bits 25..21) */
10600
10601enum {
10602 BLTZ = 0x00,
10603 BLTZAL = 0x01,
10604 BGEZ = 0x02,
10605 BGEZAL = 0x03,
10606 BLEZ = 0x04,
10607 BNEZC = 0x05,
10608 BGTZ = 0x06,
10609 BEQZC = 0x07,
10610 TLTI = 0x08,
10611 TGEI = 0x09,
10612 TLTIU = 0x0a,
10613 TGEIU = 0x0b,
10614 TNEI = 0x0c,
10615 LUI = 0x0d,
10616 TEQI = 0x0e,
10617 SYNCI = 0x10,
10618 BLTZALS = 0x11,
10619 BGEZALS = 0x13,
10620 BC2F = 0x14,
10621 BC2T = 0x15,
10622 BPOSGE64 = 0x1a,
10623 BPOSGE32 = 0x1b,
10624 /* These overlap and are distinguished by bit16 of the instruction */
10625 BC1F = 0x1c,
10626 BC1T = 0x1d,
10627 BC1ANY2F = 0x1c,
10628 BC1ANY2T = 0x1d,
10629 BC1ANY4F = 0x1e,
10630 BC1ANY4T = 0x1f
10631};
10632
10633/* POOL16A encoding of minor opcode field */
10634
10635enum {
10636 ADDU16 = 0x0,
10637 SUBU16 = 0x1
10638};
10639
10640/* POOL16B encoding of minor opcode field */
10641
10642enum {
10643 SLL16 = 0x0,
10644 SRL16 = 0x1
10645};
10646
10647/* POOL16C encoding of minor opcode field */
10648
10649enum {
10650 NOT16 = 0x00,
10651 XOR16 = 0x04,
10652 AND16 = 0x08,
10653 OR16 = 0x0c,
10654 LWM16 = 0x10,
10655 SWM16 = 0x14,
10656 JR16 = 0x18,
10657 JRC16 = 0x1a,
10658 JALR16 = 0x1c,
10659 JALR16S = 0x1e,
10660 MFHI16 = 0x20,
10661 MFLO16 = 0x24,
10662 BREAK16 = 0x28,
10663 SDBBP16 = 0x2c,
10664 JRADDIUSP = 0x30
10665};
10666
10667/* POOL16D encoding of minor opcode field */
10668
10669enum {
10670 ADDIUS5 = 0x0,
10671 ADDIUSP = 0x1
10672};
10673
10674/* POOL16E encoding of minor opcode field */
10675
10676enum {
10677 ADDIUR2 = 0x0,
10678 ADDIUR1SP = 0x1
10679};
10680
10681static int mmreg (int r)
10682{
10683 static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10684
10685 return map[r];
10686}
10687
10688/* Used for 16-bit store instructions. */
10689static int mmreg2 (int r)
10690{
10691 static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10692
10693 return map[r];
10694}
10695
10696#define uMIPS_RD(op) ((op >> 7) & 0x7)
10697#define uMIPS_RS(op) ((op >> 4) & 0x7)
10698#define uMIPS_RS2(op) uMIPS_RS(op)
10699#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10700#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10701#define uMIPS_RS5(op) (op & 0x1f)
10702
10703/* Signed immediate */
10704#define SIMM(op, start, width) \
10705 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10706 << (32-width)) \
10707 >> (32-width))
10708/* Zero-extended immediate */
10709#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10710
7db13fae 10711static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10712{
10713 int rd = mmreg(uMIPS_RD(ctx->opcode));
10714
10715 gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10716}
10717
7db13fae 10718static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10719{
10720 static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10721 int rd = mmreg(uMIPS_RD(ctx->opcode));
10722 int rs = mmreg(uMIPS_RS(ctx->opcode));
10723
10724 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10725}
10726
7db13fae 10727static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10728{
10729 int encoded = ZIMM(ctx->opcode, 1, 9);
10730 int decoded;
10731
10732 if (encoded <= 1) {
10733 decoded = 256 + encoded;
10734 } else if (encoded <= 255) {
10735 decoded = encoded;
10736 } else if (encoded <= 509) {
10737 decoded = encoded - 512;
10738 } else {
10739 decoded = encoded - 768;
10740 }
10741
10742 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
10743}
10744
7db13fae 10745static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10746{
10747 int imm = SIMM(ctx->opcode, 1, 4);
10748 int rd = (ctx->opcode >> 5) & 0x1f;
10749
10750 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
10751}
10752
7db13fae 10753static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
3c824109
NF
10754{
10755 static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10756 31, 32, 63, 64, 255, 32768, 65535 };
10757 int rd = mmreg(uMIPS_RD(ctx->opcode));
10758 int rs = mmreg(uMIPS_RS(ctx->opcode));
10759 int encoded = ZIMM(ctx->opcode, 0, 4);
10760
9fa77488 10761 gen_logic_imm(env, ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
3c824109
NF
10762}
10763
10764static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10765 int base, int16_t offset)
10766{
e1050a76 10767 const char *opn = "ldst_multiple";
3c824109
NF
10768 TCGv t0, t1;
10769 TCGv_i32 t2;
10770
10771 if (ctx->hflags & MIPS_HFLAG_BMASK) {
10772 generate_exception(ctx, EXCP_RI);
10773 return;
10774 }
10775
10776 t0 = tcg_temp_new();
10777
10778 gen_base_offset_addr(ctx, t0, base, offset);
10779
10780 t1 = tcg_const_tl(reglist);
10781 t2 = tcg_const_i32(ctx->mem_idx);
6af0bf9c 10782
3c824109
NF
10783 save_cpu_state(ctx, 1);
10784 switch (opc) {
10785 case LWM32:
895c2d04 10786 gen_helper_lwm(cpu_env, t0, t1, t2);
e1050a76 10787 opn = "lwm";
3c824109
NF
10788 break;
10789 case SWM32:
895c2d04 10790 gen_helper_swm(cpu_env, t0, t1, t2);
e1050a76 10791 opn = "swm";
3c824109
NF
10792 break;
10793#ifdef TARGET_MIPS64
10794 case LDM:
895c2d04 10795 gen_helper_ldm(cpu_env, t0, t1, t2);
e1050a76 10796 opn = "ldm";
3c824109
NF
10797 break;
10798 case SDM:
895c2d04 10799 gen_helper_sdm(cpu_env, t0, t1, t2);
e1050a76 10800 opn = "sdm";
3c824109 10801 break;
6af0bf9c 10802#endif
3c824109 10803 }
e1050a76 10804 (void)opn;
3c824109
NF
10805 MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10806 tcg_temp_free(t0);
33087598 10807 tcg_temp_free(t1);
3c824109
NF
10808 tcg_temp_free_i32(t2);
10809}
6af0bf9c 10810
3c824109 10811
7db13fae 10812static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
6af0bf9c 10813{
3c824109
NF
10814 int rd = mmreg((ctx->opcode >> 3) & 0x7);
10815 int rs = mmreg(ctx->opcode & 0x7);
10816 int opc;
6af0bf9c 10817
3c824109
NF
10818 switch (((ctx->opcode) >> 4) & 0x3f) {
10819 case NOT16 + 0:
10820 case NOT16 + 1:
10821 case NOT16 + 2:
10822 case NOT16 + 3:
9fa77488 10823 gen_logic(env, ctx, OPC_NOR, rd, rs, 0);
3c824109
NF
10824 break;
10825 case XOR16 + 0:
10826 case XOR16 + 1:
10827 case XOR16 + 2:
10828 case XOR16 + 3:
9fa77488 10829 gen_logic(env, ctx, OPC_XOR, rd, rd, rs);
3c824109
NF
10830 break;
10831 case AND16 + 0:
10832 case AND16 + 1:
10833 case AND16 + 2:
10834 case AND16 + 3:
9fa77488 10835 gen_logic(env, ctx, OPC_AND, rd, rd, rs);
3c824109
NF
10836 break;
10837 case OR16 + 0:
10838 case OR16 + 1:
10839 case OR16 + 2:
10840 case OR16 + 3:
9fa77488 10841 gen_logic(env, ctx, OPC_OR, rd, rd, rs);
3c824109
NF
10842 break;
10843 case LWM16 + 0:
10844 case LWM16 + 1:
10845 case LWM16 + 2:
10846 case LWM16 + 3:
10847 {
10848 static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10849 int offset = ZIMM(ctx->opcode, 0, 4);
10850
10851 gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10852 29, offset << 2);
10853 }
10854 break;
10855 case SWM16 + 0:
10856 case SWM16 + 1:
10857 case SWM16 + 2:
10858 case SWM16 + 3:
10859 {
10860 static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10861 int offset = ZIMM(ctx->opcode, 0, 4);
10862
10863 gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10864 29, offset << 2);
10865 }
10866 break;
10867 case JR16 + 0:
10868 case JR16 + 1:
10869 {
10870 int reg = ctx->opcode & 0x1f;
10871
10872 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10873 }
10874 *is_branch = 1;
10875 break;
10876 case JRC16 + 0:
10877 case JRC16 + 1:
10878 {
10879 int reg = ctx->opcode & 0x1f;
10880
10881 gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10882 /* Let normal delay slot handling in our caller take us
10883 to the branch target. */
10884 }
10885 break;
10886 case JALR16 + 0:
10887 case JALR16 + 1:
10888 opc = OPC_JALR;
10889 goto do_jalr;
10890 case JALR16S + 0:
10891 case JALR16S + 1:
10892 opc = OPC_JALRS;
10893 do_jalr:
10894 {
10895 int reg = ctx->opcode & 0x1f;
10896
10897 gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10898 }
10899 *is_branch = 1;
10900 break;
10901 case MFHI16 + 0:
10902 case MFHI16 + 1:
10903 gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
10904 break;
10905 case MFLO16 + 0:
10906 case MFLO16 + 1:
10907 gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
10908 break;
10909 case BREAK16:
10910 generate_exception(ctx, EXCP_BREAK);
10911 break;
10912 case SDBBP16:
10913 /* XXX: not clear which exception should be raised
10914 * when in debug mode...
10915 */
10916 check_insn(env, ctx, ISA_MIPS32);
10917 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10918 generate_exception(ctx, EXCP_DBp);
10919 } else {
10920 generate_exception(ctx, EXCP_DBp);
10921 }
10922 break;
10923 case JRADDIUSP + 0:
10924 case JRADDIUSP + 1:
10925 {
10926 int imm = ZIMM(ctx->opcode, 0, 5);
10927
10928 gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10929 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
10930 /* Let normal delay slot handling in our caller take us
10931 to the branch target. */
10932 }
10933 break;
10934 default:
10935 generate_exception(ctx, EXCP_RI);
10936 break;
10937 }
10938}
10939
10940static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10941{
10942 TCGv t0 = tcg_temp_new();
10943 TCGv t1 = tcg_temp_new();
10944
10945 gen_load_gpr(t0, base);
10946
10947 if (index != 0) {
10948 gen_load_gpr(t1, index);
10949 tcg_gen_shli_tl(t1, t1, 2);
10950 gen_op_addr_add(ctx, t0, t1, t0);
10951 }
10952
5c13fdfd 10953 op_ld_lw(t1, t0, ctx);
3c824109
NF
10954 gen_store_gpr(t1, rd);
10955
10956 tcg_temp_free(t0);
10957 tcg_temp_free(t1);
10958}
10959
10960static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10961 int base, int16_t offset)
10962{
10963 const char *opn = "ldst_pair";
10964 TCGv t0, t1;
10965
36c6711b 10966 if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
3c824109 10967 generate_exception(ctx, EXCP_RI);
d796321b
FB
10968 return;
10969 }
10970
3c824109
NF
10971 t0 = tcg_temp_new();
10972 t1 = tcg_temp_new();
8e9ade68 10973
3c824109
NF
10974 gen_base_offset_addr(ctx, t0, base, offset);
10975
10976 switch (opc) {
10977 case LWP:
36c6711b
EJ
10978 if (rd == base) {
10979 generate_exception(ctx, EXCP_RI);
10980 return;
10981 }
5c13fdfd 10982 op_ld_lw(t1, t0, ctx);
3c824109
NF
10983 gen_store_gpr(t1, rd);
10984 tcg_gen_movi_tl(t1, 4);
10985 gen_op_addr_add(ctx, t0, t0, t1);
5c13fdfd 10986 op_ld_lw(t1, t0, ctx);
3c824109
NF
10987 gen_store_gpr(t1, rd+1);
10988 opn = "lwp";
10989 break;
10990 case SWP:
3c824109 10991 gen_load_gpr(t1, rd);
5c13fdfd 10992 op_st_sw(t1, t0, ctx);
3c824109
NF
10993 tcg_gen_movi_tl(t1, 4);
10994 gen_op_addr_add(ctx, t0, t0, t1);
10995 gen_load_gpr(t1, rd+1);
5c13fdfd 10996 op_st_sw(t1, t0, ctx);
3c824109
NF
10997 opn = "swp";
10998 break;
10999#ifdef TARGET_MIPS64
11000 case LDP:
36c6711b
EJ
11001 if (rd == base) {
11002 generate_exception(ctx, EXCP_RI);
11003 return;
11004 }
5c13fdfd 11005 op_ld_ld(t1, t0, ctx);
3c824109
NF
11006 gen_store_gpr(t1, rd);
11007 tcg_gen_movi_tl(t1, 8);
11008 gen_op_addr_add(ctx, t0, t0, t1);
5c13fdfd 11009 op_ld_ld(t1, t0, ctx);
3c824109
NF
11010 gen_store_gpr(t1, rd+1);
11011 opn = "ldp";
11012 break;
11013 case SDP:
3c824109 11014 gen_load_gpr(t1, rd);
5c13fdfd 11015 op_st_sd(t1, t0, ctx);
3c824109
NF
11016 tcg_gen_movi_tl(t1, 8);
11017 gen_op_addr_add(ctx, t0, t0, t1);
11018 gen_load_gpr(t1, rd+1);
5c13fdfd 11019 op_st_sd(t1, t0, ctx);
3c824109
NF
11020 opn = "sdp";
11021 break;
11022#endif
6af0bf9c 11023 }
2abf314d 11024 (void)opn; /* avoid a compiler warning */
3c824109
NF
11025 MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11026 tcg_temp_free(t0);
11027 tcg_temp_free(t1);
11028}
618b0fe9 11029
7db13fae 11030static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
3c824109
NF
11031 int *is_branch)
11032{
11033 int extension = (ctx->opcode >> 6) & 0x3f;
11034 int minor = (ctx->opcode >> 12) & 0xf;
11035 uint32_t mips32_op;
11036
11037 switch (extension) {
11038 case TEQ:
11039 mips32_op = OPC_TEQ;
11040 goto do_trap;
11041 case TGE:
11042 mips32_op = OPC_TGE;
11043 goto do_trap;
11044 case TGEU:
11045 mips32_op = OPC_TGEU;
11046 goto do_trap;
11047 case TLT:
11048 mips32_op = OPC_TLT;
11049 goto do_trap;
11050 case TLTU:
11051 mips32_op = OPC_TLTU;
11052 goto do_trap;
11053 case TNE:
11054 mips32_op = OPC_TNE;
11055 do_trap:
11056 gen_trap(ctx, mips32_op, rs, rt, -1);
11057 break;
11058#ifndef CONFIG_USER_ONLY
11059 case MFC0:
11060 case MFC0 + 32:
2e15497c 11061 check_cp0_enabled(ctx);
3c824109
NF
11062 if (rt == 0) {
11063 /* Treat as NOP. */
11064 break;
11065 }
11066 gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11067 break;
11068 case MTC0:
11069 case MTC0 + 32:
2e15497c 11070 check_cp0_enabled(ctx);
3c824109
NF
11071 {
11072 TCGv t0 = tcg_temp_new();
618b0fe9 11073
3c824109
NF
11074 gen_load_gpr(t0, rt);
11075 gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11076 tcg_temp_free(t0);
11077 }
11078 break;
11079#endif
11080 case 0x2c:
11081 switch (minor) {
11082 case SEB:
11083 gen_bshfl(ctx, OPC_SEB, rs, rt);
11084 break;
11085 case SEH:
11086 gen_bshfl(ctx, OPC_SEH, rs, rt);
11087 break;
11088 case CLO:
11089 mips32_op = OPC_CLO;
11090 goto do_cl;
11091 case CLZ:
11092 mips32_op = OPC_CLZ;
11093 do_cl:
11094 check_insn(env, ctx, ISA_MIPS32);
11095 gen_cl(ctx, mips32_op, rt, rs);
11096 break;
11097 case RDHWR:
11098 gen_rdhwr(env, ctx, rt, rs);
11099 break;
11100 case WSBH:
11101 gen_bshfl(ctx, OPC_WSBH, rs, rt);
11102 break;
11103 case MULT:
11104 mips32_op = OPC_MULT;
11105 goto do_muldiv;
11106 case MULTU:
11107 mips32_op = OPC_MULTU;
11108 goto do_muldiv;
11109 case DIV:
11110 mips32_op = OPC_DIV;
11111 goto do_muldiv;
11112 case DIVU:
11113 mips32_op = OPC_DIVU;
11114 goto do_muldiv;
11115 case MADD:
11116 mips32_op = OPC_MADD;
11117 goto do_muldiv;
11118 case MADDU:
11119 mips32_op = OPC_MADDU;
11120 goto do_muldiv;
11121 case MSUB:
11122 mips32_op = OPC_MSUB;
11123 goto do_muldiv;
11124 case MSUBU:
11125 mips32_op = OPC_MSUBU;
11126 do_muldiv:
11127 check_insn(env, ctx, ISA_MIPS32);
11128 gen_muldiv(ctx, mips32_op, rs, rt);
11129 break;
11130 default:
11131 goto pool32axf_invalid;
11132 }
11133 break;
11134 case 0x34:
11135 switch (minor) {
11136 case MFC2:
11137 case MTC2:
11138 case MFHC2:
11139 case MTHC2:
11140 case CFC2:
11141 case CTC2:
11142 generate_exception_err(ctx, EXCP_CpU, 2);
11143 break;
11144 default:
11145 goto pool32axf_invalid;
11146 }
11147 break;
11148 case 0x3c:
11149 switch (minor) {
11150 case JALR:
11151 case JALR_HB:
11152 gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11153 *is_branch = 1;
11154 break;
11155 case JALRS:
11156 case JALRS_HB:
11157 gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11158 *is_branch = 1;
11159 break;
11160 default:
11161 goto pool32axf_invalid;
11162 }
11163 break;
11164 case 0x05:
11165 switch (minor) {
11166 case RDPGPR:
2e15497c 11167 check_cp0_enabled(ctx);
3c824109
NF
11168 check_insn(env, ctx, ISA_MIPS32R2);
11169 gen_load_srsgpr(rt, rs);
11170 break;
11171 case WRPGPR:
2e15497c 11172 check_cp0_enabled(ctx);
3c824109
NF
11173 check_insn(env, ctx, ISA_MIPS32R2);
11174 gen_store_srsgpr(rt, rs);
11175 break;
11176 default:
11177 goto pool32axf_invalid;
11178 }
11179 break;
11180#ifndef CONFIG_USER_ONLY
11181 case 0x0d:
11182 switch (minor) {
11183 case TLBP:
11184 mips32_op = OPC_TLBP;
11185 goto do_cp0;
11186 case TLBR:
11187 mips32_op = OPC_TLBR;
11188 goto do_cp0;
11189 case TLBWI:
11190 mips32_op = OPC_TLBWI;
11191 goto do_cp0;
11192 case TLBWR:
11193 mips32_op = OPC_TLBWR;
11194 goto do_cp0;
11195 case WAIT:
11196 mips32_op = OPC_WAIT;
11197 goto do_cp0;
11198 case DERET:
11199 mips32_op = OPC_DERET;
11200 goto do_cp0;
11201 case ERET:
11202 mips32_op = OPC_ERET;
11203 do_cp0:
11204 gen_cp0(env, ctx, mips32_op, rt, rs);
11205 break;
11206 default:
11207 goto pool32axf_invalid;
11208 }
11209 break;
11210 case 0x1d:
11211 switch (minor) {
11212 case DI:
2e15497c 11213 check_cp0_enabled(ctx);
3c824109
NF
11214 {
11215 TCGv t0 = tcg_temp_new();
11216
11217 save_cpu_state(ctx, 1);
895c2d04 11218 gen_helper_di(t0, cpu_env);
3c824109
NF
11219 gen_store_gpr(t0, rs);
11220 /* Stop translation as we may have switched the execution mode */
11221 ctx->bstate = BS_STOP;
11222 tcg_temp_free(t0);
11223 }
11224 break;
11225 case EI:
2e15497c 11226 check_cp0_enabled(ctx);
3c824109
NF
11227 {
11228 TCGv t0 = tcg_temp_new();
11229
11230 save_cpu_state(ctx, 1);
895c2d04 11231 gen_helper_ei(t0, cpu_env);
3c824109
NF
11232 gen_store_gpr(t0, rs);
11233 /* Stop translation as we may have switched the execution mode */
11234 ctx->bstate = BS_STOP;
11235 tcg_temp_free(t0);
11236 }
11237 break;
11238 default:
11239 goto pool32axf_invalid;
11240 }
11241 break;
11242#endif
11243 case 0x2d:
11244 switch (minor) {
11245 case SYNC:
11246 /* NOP */
11247 break;
11248 case SYSCALL:
11249 generate_exception(ctx, EXCP_SYSCALL);
11250 ctx->bstate = BS_STOP;
11251 break;
11252 case SDBBP:
11253 check_insn(env, ctx, ISA_MIPS32);
11254 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11255 generate_exception(ctx, EXCP_DBp);
11256 } else {
11257 generate_exception(ctx, EXCP_DBp);
11258 }
11259 break;
11260 default:
11261 goto pool32axf_invalid;
11262 }
11263 break;
11264 case 0x35:
11265 switch (minor) {
11266 case MFHI32:
11267 gen_HILO(ctx, OPC_MFHI, rs);
11268 break;
11269 case MFLO32:
11270 gen_HILO(ctx, OPC_MFLO, rs);
11271 break;
11272 case MTHI32:
11273 gen_HILO(ctx, OPC_MTHI, rs);
11274 break;
11275 case MTLO32:
11276 gen_HILO(ctx, OPC_MTLO, rs);
11277 break;
11278 default:
11279 goto pool32axf_invalid;
11280 }
11281 break;
11282 default:
11283 pool32axf_invalid:
11284 MIPS_INVAL("pool32axf");
11285 generate_exception(ctx, EXCP_RI);
11286 break;
11287 }
11288}
11289
11290/* Values for microMIPS fmt field. Variable-width, depending on which
11291 formats the instruction supports. */
11292
11293enum {
11294 FMT_SD_S = 0,
11295 FMT_SD_D = 1,
11296
11297 FMT_SDPS_S = 0,
11298 FMT_SDPS_D = 1,
11299 FMT_SDPS_PS = 2,
11300
11301 FMT_SWL_S = 0,
11302 FMT_SWL_W = 1,
11303 FMT_SWL_L = 2,
11304
11305 FMT_DWL_D = 0,
11306 FMT_DWL_W = 1,
11307 FMT_DWL_L = 2
11308};
11309
7db13fae 11310static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
3c824109
NF
11311{
11312 int extension = (ctx->opcode >> 6) & 0x3ff;
11313 uint32_t mips32_op;
11314
11315#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11316#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11317#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11318
11319 switch (extension) {
11320 case FLOAT_1BIT_FMT(CFC1, 0):
11321 mips32_op = OPC_CFC1;
11322 goto do_cp1;
11323 case FLOAT_1BIT_FMT(CTC1, 0):
11324 mips32_op = OPC_CTC1;
11325 goto do_cp1;
11326 case FLOAT_1BIT_FMT(MFC1, 0):
11327 mips32_op = OPC_MFC1;
11328 goto do_cp1;
11329 case FLOAT_1BIT_FMT(MTC1, 0):
11330 mips32_op = OPC_MTC1;
11331 goto do_cp1;
11332 case FLOAT_1BIT_FMT(MFHC1, 0):
11333 mips32_op = OPC_MFHC1;
11334 goto do_cp1;
11335 case FLOAT_1BIT_FMT(MTHC1, 0):
11336 mips32_op = OPC_MTHC1;
11337 do_cp1:
11338 gen_cp1(ctx, mips32_op, rt, rs);
11339 break;
11340
11341 /* Reciprocal square root */
11342 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11343 mips32_op = OPC_RSQRT_S;
11344 goto do_unaryfp;
11345 case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11346 mips32_op = OPC_RSQRT_D;
11347 goto do_unaryfp;
11348
11349 /* Square root */
11350 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11351 mips32_op = OPC_SQRT_S;
11352 goto do_unaryfp;
11353 case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11354 mips32_op = OPC_SQRT_D;
11355 goto do_unaryfp;
11356
11357 /* Reciprocal */
11358 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11359 mips32_op = OPC_RECIP_S;
11360 goto do_unaryfp;
11361 case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11362 mips32_op = OPC_RECIP_D;
11363 goto do_unaryfp;
11364
11365 /* Floor */
11366 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11367 mips32_op = OPC_FLOOR_L_S;
11368 goto do_unaryfp;
11369 case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11370 mips32_op = OPC_FLOOR_L_D;
11371 goto do_unaryfp;
11372 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11373 mips32_op = OPC_FLOOR_W_S;
11374 goto do_unaryfp;
11375 case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11376 mips32_op = OPC_FLOOR_W_D;
11377 goto do_unaryfp;
11378
11379 /* Ceiling */
11380 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11381 mips32_op = OPC_CEIL_L_S;
11382 goto do_unaryfp;
11383 case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11384 mips32_op = OPC_CEIL_L_D;
11385 goto do_unaryfp;
11386 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11387 mips32_op = OPC_CEIL_W_S;
11388 goto do_unaryfp;
11389 case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11390 mips32_op = OPC_CEIL_W_D;
11391 goto do_unaryfp;
11392
11393 /* Truncation */
11394 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11395 mips32_op = OPC_TRUNC_L_S;
11396 goto do_unaryfp;
11397 case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11398 mips32_op = OPC_TRUNC_L_D;
11399 goto do_unaryfp;
11400 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11401 mips32_op = OPC_TRUNC_W_S;
11402 goto do_unaryfp;
11403 case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11404 mips32_op = OPC_TRUNC_W_D;
11405 goto do_unaryfp;
11406
11407 /* Round */
11408 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11409 mips32_op = OPC_ROUND_L_S;
11410 goto do_unaryfp;
11411 case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11412 mips32_op = OPC_ROUND_L_D;
11413 goto do_unaryfp;
11414 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11415 mips32_op = OPC_ROUND_W_S;
11416 goto do_unaryfp;
11417 case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11418 mips32_op = OPC_ROUND_W_D;
11419 goto do_unaryfp;
11420
11421 /* Integer to floating-point conversion */
11422 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11423 mips32_op = OPC_CVT_L_S;
11424 goto do_unaryfp;
11425 case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11426 mips32_op = OPC_CVT_L_D;
11427 goto do_unaryfp;
11428 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11429 mips32_op = OPC_CVT_W_S;
11430 goto do_unaryfp;
11431 case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11432 mips32_op = OPC_CVT_W_D;
11433 goto do_unaryfp;
11434
11435 /* Paired-foo conversions */
11436 case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11437 mips32_op = OPC_CVT_S_PL;
11438 goto do_unaryfp;
11439 case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11440 mips32_op = OPC_CVT_S_PU;
11441 goto do_unaryfp;
11442 case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11443 mips32_op = OPC_CVT_PW_PS;
11444 goto do_unaryfp;
11445 case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11446 mips32_op = OPC_CVT_PS_PW;
11447 goto do_unaryfp;
11448
11449 /* Floating-point moves */
11450 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11451 mips32_op = OPC_MOV_S;
11452 goto do_unaryfp;
11453 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11454 mips32_op = OPC_MOV_D;
11455 goto do_unaryfp;
11456 case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11457 mips32_op = OPC_MOV_PS;
11458 goto do_unaryfp;
11459
11460 /* Absolute value */
11461 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11462 mips32_op = OPC_ABS_S;
11463 goto do_unaryfp;
11464 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11465 mips32_op = OPC_ABS_D;
11466 goto do_unaryfp;
11467 case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11468 mips32_op = OPC_ABS_PS;
11469 goto do_unaryfp;
11470
11471 /* Negation */
11472 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11473 mips32_op = OPC_NEG_S;
11474 goto do_unaryfp;
11475 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11476 mips32_op = OPC_NEG_D;
11477 goto do_unaryfp;
11478 case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11479 mips32_op = OPC_NEG_PS;
11480 goto do_unaryfp;
11481
11482 /* Reciprocal square root step */
11483 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11484 mips32_op = OPC_RSQRT1_S;
11485 goto do_unaryfp;
11486 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11487 mips32_op = OPC_RSQRT1_D;
11488 goto do_unaryfp;
11489 case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11490 mips32_op = OPC_RSQRT1_PS;
11491 goto do_unaryfp;
11492
11493 /* Reciprocal step */
11494 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11495 mips32_op = OPC_RECIP1_S;
11496 goto do_unaryfp;
11497 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11498 mips32_op = OPC_RECIP1_S;
11499 goto do_unaryfp;
11500 case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11501 mips32_op = OPC_RECIP1_PS;
11502 goto do_unaryfp;
11503
11504 /* Conversions from double */
11505 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11506 mips32_op = OPC_CVT_D_S;
11507 goto do_unaryfp;
11508 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11509 mips32_op = OPC_CVT_D_W;
11510 goto do_unaryfp;
11511 case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11512 mips32_op = OPC_CVT_D_L;
11513 goto do_unaryfp;
11514
11515 /* Conversions from single */
11516 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11517 mips32_op = OPC_CVT_S_D;
11518 goto do_unaryfp;
11519 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11520 mips32_op = OPC_CVT_S_W;
11521 goto do_unaryfp;
11522 case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11523 mips32_op = OPC_CVT_S_L;
11524 do_unaryfp:
11525 gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11526 break;
11527
11528 /* Conditional moves on floating-point codes */
11529 case COND_FLOAT_MOV(MOVT, 0):
11530 case COND_FLOAT_MOV(MOVT, 1):
11531 case COND_FLOAT_MOV(MOVT, 2):
11532 case COND_FLOAT_MOV(MOVT, 3):
11533 case COND_FLOAT_MOV(MOVT, 4):
11534 case COND_FLOAT_MOV(MOVT, 5):
11535 case COND_FLOAT_MOV(MOVT, 6):
11536 case COND_FLOAT_MOV(MOVT, 7):
11537 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11538 break;
11539 case COND_FLOAT_MOV(MOVF, 0):
11540 case COND_FLOAT_MOV(MOVF, 1):
11541 case COND_FLOAT_MOV(MOVF, 2):
11542 case COND_FLOAT_MOV(MOVF, 3):
11543 case COND_FLOAT_MOV(MOVF, 4):
11544 case COND_FLOAT_MOV(MOVF, 5):
11545 case COND_FLOAT_MOV(MOVF, 6):
11546 case COND_FLOAT_MOV(MOVF, 7):
11547 gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11548 break;
11549 default:
11550 MIPS_INVAL("pool32fxf");
11551 generate_exception(ctx, EXCP_RI);
11552 break;
11553 }
11554}
11555
7db13fae 11556static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
3c824109
NF
11557 uint16_t insn_hw1, int *is_branch)
11558{
11559 int32_t offset;
11560 uint16_t insn;
11561 int rt, rs, rd, rr;
11562 int16_t imm;
11563 uint32_t op, minor, mips32_op;
11564 uint32_t cond, fmt, cc;
11565
895c2d04 11566 insn = cpu_lduw_code(env, ctx->pc + 2);
3c824109
NF
11567 ctx->opcode = (ctx->opcode << 16) | insn;
11568
11569 rt = (ctx->opcode >> 21) & 0x1f;
11570 rs = (ctx->opcode >> 16) & 0x1f;
11571 rd = (ctx->opcode >> 11) & 0x1f;
11572 rr = (ctx->opcode >> 6) & 0x1f;
11573 imm = (int16_t) ctx->opcode;
11574
11575 op = (ctx->opcode >> 26) & 0x3f;
11576 switch (op) {
11577 case POOL32A:
11578 minor = ctx->opcode & 0x3f;
11579 switch (minor) {
11580 case 0x00:
11581 minor = (ctx->opcode >> 6) & 0xf;
11582 switch (minor) {
11583 case SLL32:
11584 mips32_op = OPC_SLL;
11585 goto do_shifti;
11586 case SRA:
11587 mips32_op = OPC_SRA;
11588 goto do_shifti;
11589 case SRL32:
11590 mips32_op = OPC_SRL;
11591 goto do_shifti;
11592 case ROTR:
11593 mips32_op = OPC_ROTR;
11594 do_shifti:
11595 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
11596 break;
11597 default:
11598 goto pool32a_invalid;
11599 }
11600 break;
11601 case 0x10:
11602 minor = (ctx->opcode >> 6) & 0xf;
11603 switch (minor) {
11604 /* Arithmetic */
11605 case ADD:
11606 mips32_op = OPC_ADD;
11607 goto do_arith;
11608 case ADDU32:
11609 mips32_op = OPC_ADDU;
11610 goto do_arith;
11611 case SUB:
11612 mips32_op = OPC_SUB;
11613 goto do_arith;
11614 case SUBU32:
11615 mips32_op = OPC_SUBU;
11616 goto do_arith;
11617 case MUL:
11618 mips32_op = OPC_MUL;
11619 do_arith:
11620 gen_arith(env, ctx, mips32_op, rd, rs, rt);
11621 break;
11622 /* Shifts */
11623 case SLLV:
11624 mips32_op = OPC_SLLV;
11625 goto do_shift;
11626 case SRLV:
11627 mips32_op = OPC_SRLV;
11628 goto do_shift;
11629 case SRAV:
11630 mips32_op = OPC_SRAV;
11631 goto do_shift;
11632 case ROTRV:
11633 mips32_op = OPC_ROTRV;
11634 do_shift:
11635 gen_shift(env, ctx, mips32_op, rd, rs, rt);
11636 break;
11637 /* Logical operations */
11638 case AND:
11639 mips32_op = OPC_AND;
11640 goto do_logic;
11641 case OR32:
11642 mips32_op = OPC_OR;
11643 goto do_logic;
11644 case NOR:
11645 mips32_op = OPC_NOR;
11646 goto do_logic;
11647 case XOR32:
11648 mips32_op = OPC_XOR;
11649 do_logic:
9fa77488 11650 gen_logic(env, ctx, mips32_op, rd, rs, rt);
3c824109
NF
11651 break;
11652 /* Set less than */
11653 case SLT:
11654 mips32_op = OPC_SLT;
11655 goto do_slt;
11656 case SLTU:
11657 mips32_op = OPC_SLTU;
11658 do_slt:
9fa77488 11659 gen_slt(env, ctx, mips32_op, rd, rs, rt);
3c824109
NF
11660 break;
11661 default:
11662 goto pool32a_invalid;
11663 }
11664 break;
11665 case 0x18:
11666 minor = (ctx->opcode >> 6) & 0xf;
11667 switch (minor) {
11668 /* Conditional moves */
11669 case MOVN:
11670 mips32_op = OPC_MOVN;
11671 goto do_cmov;
11672 case MOVZ:
11673 mips32_op = OPC_MOVZ;
11674 do_cmov:
9fa77488 11675 gen_cond_move(env, ctx, mips32_op, rd, rs, rt);
3c824109
NF
11676 break;
11677 case LWXS:
11678 gen_ldxs(ctx, rs, rt, rd);
11679 break;
11680 default:
11681 goto pool32a_invalid;
11682 }
11683 break;
11684 case INS:
11685 gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11686 return;
11687 case EXT:
11688 gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11689 return;
11690 case POOL32AXF:
11691 gen_pool32axf(env, ctx, rt, rs, is_branch);
11692 break;
11693 case 0x07:
11694 generate_exception(ctx, EXCP_BREAK);
11695 break;
11696 default:
11697 pool32a_invalid:
11698 MIPS_INVAL("pool32a");
11699 generate_exception(ctx, EXCP_RI);
11700 break;
11701 }
11702 break;
11703 case POOL32B:
11704 minor = (ctx->opcode >> 12) & 0xf;
11705 switch (minor) {
11706 case CACHE:
2e15497c 11707 check_cp0_enabled(ctx);
3c824109
NF
11708 /* Treat as no-op. */
11709 break;
11710 case LWC2:
11711 case SWC2:
11712 /* COP2: Not implemented. */
11713 generate_exception_err(ctx, EXCP_CpU, 2);
11714 break;
11715 case LWP:
11716 case SWP:
11717#ifdef TARGET_MIPS64
11718 case LDP:
11719 case SDP:
11720#endif
11721 gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11722 break;
11723 case LWM32:
11724 case SWM32:
11725#ifdef TARGET_MIPS64
11726 case LDM:
11727 case SDM:
11728#endif
11729 gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11730 break;
11731 default:
11732 MIPS_INVAL("pool32b");
11733 generate_exception(ctx, EXCP_RI);
11734 break;
11735 }
11736 break;
11737 case POOL32F:
11738 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11739 minor = ctx->opcode & 0x3f;
11740 check_cp1_enabled(ctx);
11741 switch (minor) {
11742 case ALNV_PS:
11743 mips32_op = OPC_ALNV_PS;
11744 goto do_madd;
11745 case MADD_S:
11746 mips32_op = OPC_MADD_S;
11747 goto do_madd;
11748 case MADD_D:
11749 mips32_op = OPC_MADD_D;
11750 goto do_madd;
11751 case MADD_PS:
11752 mips32_op = OPC_MADD_PS;
11753 goto do_madd;
11754 case MSUB_S:
11755 mips32_op = OPC_MSUB_S;
11756 goto do_madd;
11757 case MSUB_D:
11758 mips32_op = OPC_MSUB_D;
11759 goto do_madd;
11760 case MSUB_PS:
11761 mips32_op = OPC_MSUB_PS;
11762 goto do_madd;
11763 case NMADD_S:
11764 mips32_op = OPC_NMADD_S;
11765 goto do_madd;
11766 case NMADD_D:
11767 mips32_op = OPC_NMADD_D;
11768 goto do_madd;
11769 case NMADD_PS:
11770 mips32_op = OPC_NMADD_PS;
11771 goto do_madd;
11772 case NMSUB_S:
11773 mips32_op = OPC_NMSUB_S;
11774 goto do_madd;
11775 case NMSUB_D:
11776 mips32_op = OPC_NMSUB_D;
11777 goto do_madd;
11778 case NMSUB_PS:
11779 mips32_op = OPC_NMSUB_PS;
11780 do_madd:
11781 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11782 break;
11783 case CABS_COND_FMT:
11784 cond = (ctx->opcode >> 6) & 0xf;
11785 cc = (ctx->opcode >> 13) & 0x7;
11786 fmt = (ctx->opcode >> 10) & 0x3;
11787 switch (fmt) {
11788 case 0x0:
11789 gen_cmpabs_s(ctx, cond, rt, rs, cc);
11790 break;
11791 case 0x1:
11792 gen_cmpabs_d(ctx, cond, rt, rs, cc);
11793 break;
11794 case 0x2:
11795 gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11796 break;
11797 default:
11798 goto pool32f_invalid;
11799 }
11800 break;
11801 case C_COND_FMT:
11802 cond = (ctx->opcode >> 6) & 0xf;
11803 cc = (ctx->opcode >> 13) & 0x7;
11804 fmt = (ctx->opcode >> 10) & 0x3;
11805 switch (fmt) {
11806 case 0x0:
11807 gen_cmp_s(ctx, cond, rt, rs, cc);
11808 break;
11809 case 0x1:
11810 gen_cmp_d(ctx, cond, rt, rs, cc);
11811 break;
11812 case 0x2:
11813 gen_cmp_ps(ctx, cond, rt, rs, cc);
11814 break;
11815 default:
11816 goto pool32f_invalid;
11817 }
11818 break;
11819 case POOL32FXF:
11820 gen_pool32fxf(env, ctx, rt, rs);
11821 break;
11822 case 0x00:
11823 /* PLL foo */
11824 switch ((ctx->opcode >> 6) & 0x7) {
11825 case PLL_PS:
11826 mips32_op = OPC_PLL_PS;
11827 goto do_ps;
11828 case PLU_PS:
11829 mips32_op = OPC_PLU_PS;
11830 goto do_ps;
11831 case PUL_PS:
11832 mips32_op = OPC_PUL_PS;
11833 goto do_ps;
11834 case PUU_PS:
11835 mips32_op = OPC_PUU_PS;
11836 goto do_ps;
11837 case CVT_PS_S:
11838 mips32_op = OPC_CVT_PS_S;
11839 do_ps:
11840 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11841 break;
11842 default:
11843 goto pool32f_invalid;
11844 }
11845 break;
11846 case 0x08:
11847 /* [LS][WDU]XC1 */
11848 switch ((ctx->opcode >> 6) & 0x7) {
11849 case LWXC1:
11850 mips32_op = OPC_LWXC1;
11851 goto do_ldst_cp1;
11852 case SWXC1:
11853 mips32_op = OPC_SWXC1;
11854 goto do_ldst_cp1;
11855 case LDXC1:
11856 mips32_op = OPC_LDXC1;
11857 goto do_ldst_cp1;
11858 case SDXC1:
11859 mips32_op = OPC_SDXC1;
11860 goto do_ldst_cp1;
11861 case LUXC1:
11862 mips32_op = OPC_LUXC1;
11863 goto do_ldst_cp1;
11864 case SUXC1:
11865 mips32_op = OPC_SUXC1;
11866 do_ldst_cp1:
11867 gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11868 break;
11869 default:
11870 goto pool32f_invalid;
11871 }
11872 break;
11873 case 0x18:
11874 /* 3D insns */
11875 fmt = (ctx->opcode >> 9) & 0x3;
11876 switch ((ctx->opcode >> 6) & 0x7) {
11877 case RSQRT2_FMT:
11878 switch (fmt) {
11879 case FMT_SDPS_S:
11880 mips32_op = OPC_RSQRT2_S;
11881 goto do_3d;
11882 case FMT_SDPS_D:
11883 mips32_op = OPC_RSQRT2_D;
11884 goto do_3d;
11885 case FMT_SDPS_PS:
11886 mips32_op = OPC_RSQRT2_PS;
11887 goto do_3d;
11888 default:
11889 goto pool32f_invalid;
11890 }
11891 break;
11892 case RECIP2_FMT:
11893 switch (fmt) {
11894 case FMT_SDPS_S:
11895 mips32_op = OPC_RECIP2_S;
11896 goto do_3d;
11897 case FMT_SDPS_D:
11898 mips32_op = OPC_RECIP2_D;
11899 goto do_3d;
11900 case FMT_SDPS_PS:
11901 mips32_op = OPC_RECIP2_PS;
11902 goto do_3d;
11903 default:
11904 goto pool32f_invalid;
11905 }
11906 break;
11907 case ADDR_PS:
11908 mips32_op = OPC_ADDR_PS;
11909 goto do_3d;
11910 case MULR_PS:
11911 mips32_op = OPC_MULR_PS;
11912 do_3d:
11913 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11914 break;
11915 default:
11916 goto pool32f_invalid;
11917 }
11918 break;
11919 case 0x20:
11920 /* MOV[FT].fmt and PREFX */
11921 cc = (ctx->opcode >> 13) & 0x7;
11922 fmt = (ctx->opcode >> 9) & 0x3;
11923 switch ((ctx->opcode >> 6) & 0x7) {
11924 case MOVF_FMT:
11925 switch (fmt) {
11926 case FMT_SDPS_S:
11927 gen_movcf_s(rs, rt, cc, 0);
11928 break;
11929 case FMT_SDPS_D:
11930 gen_movcf_d(ctx, rs, rt, cc, 0);
11931 break;
11932 case FMT_SDPS_PS:
11933 gen_movcf_ps(rs, rt, cc, 0);
11934 break;
11935 default:
11936 goto pool32f_invalid;
11937 }
11938 break;
11939 case MOVT_FMT:
11940 switch (fmt) {
11941 case FMT_SDPS_S:
11942 gen_movcf_s(rs, rt, cc, 1);
11943 break;
11944 case FMT_SDPS_D:
11945 gen_movcf_d(ctx, rs, rt, cc, 1);
11946 break;
11947 case FMT_SDPS_PS:
11948 gen_movcf_ps(rs, rt, cc, 1);
11949 break;
11950 default:
11951 goto pool32f_invalid;
11952 }
11953 break;
11954 case PREFX:
11955 break;
11956 default:
11957 goto pool32f_invalid;
11958 }
11959 break;
11960#define FINSN_3ARG_SDPS(prfx) \
11961 switch ((ctx->opcode >> 8) & 0x3) { \
11962 case FMT_SDPS_S: \
11963 mips32_op = OPC_##prfx##_S; \
11964 goto do_fpop; \
11965 case FMT_SDPS_D: \
11966 mips32_op = OPC_##prfx##_D; \
11967 goto do_fpop; \
11968 case FMT_SDPS_PS: \
11969 mips32_op = OPC_##prfx##_PS; \
11970 goto do_fpop; \
11971 default: \
11972 goto pool32f_invalid; \
11973 }
11974 case 0x30:
11975 /* regular FP ops */
11976 switch ((ctx->opcode >> 6) & 0x3) {
11977 case ADD_FMT:
11978 FINSN_3ARG_SDPS(ADD);
11979 break;
11980 case SUB_FMT:
11981 FINSN_3ARG_SDPS(SUB);
11982 break;
11983 case MUL_FMT:
11984 FINSN_3ARG_SDPS(MUL);
11985 break;
11986 case DIV_FMT:
11987 fmt = (ctx->opcode >> 8) & 0x3;
11988 if (fmt == 1) {
11989 mips32_op = OPC_DIV_D;
11990 } else if (fmt == 0) {
11991 mips32_op = OPC_DIV_S;
11992 } else {
11993 goto pool32f_invalid;
11994 }
11995 goto do_fpop;
11996 default:
11997 goto pool32f_invalid;
11998 }
11999 break;
12000 case 0x38:
12001 /* cmovs */
12002 switch ((ctx->opcode >> 6) & 0x3) {
12003 case MOVN_FMT:
12004 FINSN_3ARG_SDPS(MOVN);
12005 break;
12006 case MOVZ_FMT:
12007 FINSN_3ARG_SDPS(MOVZ);
12008 break;
12009 default:
12010 goto pool32f_invalid;
12011 }
12012 break;
12013 do_fpop:
12014 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12015 break;
12016 default:
12017 pool32f_invalid:
12018 MIPS_INVAL("pool32f");
12019 generate_exception(ctx, EXCP_RI);
12020 break;
12021 }
12022 } else {
12023 generate_exception_err(ctx, EXCP_CpU, 1);
12024 }
12025 break;
12026 case POOL32I:
12027 minor = (ctx->opcode >> 21) & 0x1f;
12028 switch (minor) {
12029 case BLTZ:
12030 mips32_op = OPC_BLTZ;
12031 goto do_branch;
12032 case BLTZAL:
12033 mips32_op = OPC_BLTZAL;
12034 goto do_branch;
12035 case BLTZALS:
12036 mips32_op = OPC_BLTZALS;
12037 goto do_branch;
12038 case BGEZ:
12039 mips32_op = OPC_BGEZ;
12040 goto do_branch;
12041 case BGEZAL:
12042 mips32_op = OPC_BGEZAL;
12043 goto do_branch;
12044 case BGEZALS:
12045 mips32_op = OPC_BGEZALS;
12046 goto do_branch;
12047 case BLEZ:
12048 mips32_op = OPC_BLEZ;
12049 goto do_branch;
12050 case BGTZ:
12051 mips32_op = OPC_BGTZ;
12052 do_branch:
12053 gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12054 *is_branch = 1;
12055 break;
12056
12057 /* Traps */
12058 case TLTI:
12059 mips32_op = OPC_TLTI;
12060 goto do_trapi;
12061 case TGEI:
12062 mips32_op = OPC_TGEI;
12063 goto do_trapi;
12064 case TLTIU:
12065 mips32_op = OPC_TLTIU;
12066 goto do_trapi;
12067 case TGEIU:
12068 mips32_op = OPC_TGEIU;
12069 goto do_trapi;
12070 case TNEI:
12071 mips32_op = OPC_TNEI;
12072 goto do_trapi;
12073 case TEQI:
12074 mips32_op = OPC_TEQI;
12075 do_trapi:
12076 gen_trap(ctx, mips32_op, rs, -1, imm);
12077 break;
12078
12079 case BNEZC:
12080 case BEQZC:
12081 gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12082 4, rs, 0, imm << 1);
12083 /* Compact branches don't have a delay slot, so just let
12084 the normal delay slot handling take us to the branch
12085 target. */
12086 break;
12087 case LUI:
9fa77488 12088 gen_logic_imm(env, ctx, OPC_LUI, rs, -1, imm);
3c824109
NF
12089 break;
12090 case SYNCI:
12091 break;
12092 case BC2F:
12093 case BC2T:
12094 /* COP2: Not implemented. */
12095 generate_exception_err(ctx, EXCP_CpU, 2);
12096 break;
12097 case BC1F:
12098 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12099 goto do_cp1branch;
12100 case BC1T:
12101 mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12102 goto do_cp1branch;
12103 case BC1ANY4F:
12104 mips32_op = OPC_BC1FANY4;
12105 goto do_cp1mips3d;
12106 case BC1ANY4T:
12107 mips32_op = OPC_BC1TANY4;
12108 do_cp1mips3d:
12109 check_cop1x(ctx);
12110 check_insn(env, ctx, ASE_MIPS3D);
12111 /* Fall through */
12112 do_cp1branch:
12113 gen_compute_branch1(env, ctx, mips32_op,
12114 (ctx->opcode >> 18) & 0x7, imm << 1);
12115 *is_branch = 1;
12116 break;
12117 case BPOSGE64:
12118 case BPOSGE32:
12119 /* MIPS DSP: not implemented */
12120 /* Fall through */
12121 default:
12122 MIPS_INVAL("pool32i");
12123 generate_exception(ctx, EXCP_RI);
12124 break;
12125 }
12126 break;
12127 case POOL32C:
12128 minor = (ctx->opcode >> 12) & 0xf;
12129 switch (minor) {
12130 case LWL:
12131 mips32_op = OPC_LWL;
5c13fdfd 12132 goto do_ld_lr;
3c824109
NF
12133 case SWL:
12134 mips32_op = OPC_SWL;
5c13fdfd 12135 goto do_st_lr;
3c824109
NF
12136 case LWR:
12137 mips32_op = OPC_LWR;
5c13fdfd 12138 goto do_ld_lr;
3c824109
NF
12139 case SWR:
12140 mips32_op = OPC_SWR;
5c13fdfd 12141 goto do_st_lr;
3c824109
NF
12142#if defined(TARGET_MIPS64)
12143 case LDL:
12144 mips32_op = OPC_LDL;
5c13fdfd 12145 goto do_ld_lr;
3c824109
NF
12146 case SDL:
12147 mips32_op = OPC_SDL;
5c13fdfd 12148 goto do_st_lr;
3c824109
NF
12149 case LDR:
12150 mips32_op = OPC_LDR;
5c13fdfd 12151 goto do_ld_lr;
3c824109
NF
12152 case SDR:
12153 mips32_op = OPC_SDR;
5c13fdfd 12154 goto do_st_lr;
3c824109
NF
12155 case LWU:
12156 mips32_op = OPC_LWU;
5c13fdfd 12157 goto do_ld_lr;
3c824109
NF
12158 case LLD:
12159 mips32_op = OPC_LLD;
5c13fdfd 12160 goto do_ld_lr;
3c824109
NF
12161#endif
12162 case LL:
12163 mips32_op = OPC_LL;
5c13fdfd
AJ
12164 goto do_ld_lr;
12165 do_ld_lr:
afa88c3a 12166 gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
5c13fdfd
AJ
12167 break;
12168 do_st_lr:
12169 gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
3c824109
NF
12170 break;
12171 case SC:
12172 gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12173 break;
12174#if defined(TARGET_MIPS64)
12175 case SCD:
12176 gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12177 break;
12178#endif
12179 case PREF:
12180 /* Treat as no-op */
12181 break;
12182 default:
12183 MIPS_INVAL("pool32c");
12184 generate_exception(ctx, EXCP_RI);
12185 break;
12186 }
12187 break;
12188 case ADDI32:
12189 mips32_op = OPC_ADDI;
12190 goto do_addi;
12191 case ADDIU32:
12192 mips32_op = OPC_ADDIU;
12193 do_addi:
12194 gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
12195 break;
12196
12197 /* Logical operations */
12198 case ORI32:
12199 mips32_op = OPC_ORI;
12200 goto do_logici;
12201 case XORI32:
12202 mips32_op = OPC_XORI;
12203 goto do_logici;
12204 case ANDI32:
12205 mips32_op = OPC_ANDI;
12206 do_logici:
9fa77488 12207 gen_logic_imm(env, ctx, mips32_op, rt, rs, imm);
3c824109
NF
12208 break;
12209
12210 /* Set less than immediate */
12211 case SLTI32:
12212 mips32_op = OPC_SLTI;
12213 goto do_slti;
12214 case SLTIU32:
12215 mips32_op = OPC_SLTIU;
12216 do_slti:
9fa77488 12217 gen_slt_imm(env, ctx, mips32_op, rt, rs, imm);
3c824109
NF
12218 break;
12219 case JALX32:
12220 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12221 gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12222 *is_branch = 1;
12223 break;
12224 case JALS32:
12225 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12226 gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12227 *is_branch = 1;
12228 break;
12229 case BEQ32:
12230 gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12231 *is_branch = 1;
12232 break;
12233 case BNE32:
12234 gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12235 *is_branch = 1;
12236 break;
12237 case J32:
12238 gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12239 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12240 *is_branch = 1;
12241 break;
12242 case JAL32:
12243 gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12244 (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12245 *is_branch = 1;
12246 break;
12247 /* Floating point (COP1) */
12248 case LWC132:
12249 mips32_op = OPC_LWC1;
12250 goto do_cop1;
12251 case LDC132:
12252 mips32_op = OPC_LDC1;
12253 goto do_cop1;
12254 case SWC132:
12255 mips32_op = OPC_SWC1;
12256 goto do_cop1;
12257 case SDC132:
12258 mips32_op = OPC_SDC1;
12259 do_cop1:
12260 gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12261 break;
12262 case ADDIUPC:
12263 {
12264 int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12265 int offset = SIMM(ctx->opcode, 0, 23) << 2;
12266
12267 gen_addiupc(ctx, reg, offset, 0, 0);
12268 }
12269 break;
12270 /* Loads and stores */
12271 case LB32:
12272 mips32_op = OPC_LB;
5c13fdfd 12273 goto do_ld;
3c824109
NF
12274 case LBU32:
12275 mips32_op = OPC_LBU;
5c13fdfd 12276 goto do_ld;
3c824109
NF
12277 case LH32:
12278 mips32_op = OPC_LH;
5c13fdfd 12279 goto do_ld;
3c824109
NF
12280 case LHU32:
12281 mips32_op = OPC_LHU;
5c13fdfd 12282 goto do_ld;
3c824109
NF
12283 case LW32:
12284 mips32_op = OPC_LW;
5c13fdfd 12285 goto do_ld;
3c824109
NF
12286#ifdef TARGET_MIPS64
12287 case LD32:
12288 mips32_op = OPC_LD;
5c13fdfd 12289 goto do_ld;
3c824109
NF
12290 case SD32:
12291 mips32_op = OPC_SD;
5c13fdfd 12292 goto do_st;
3c824109
NF
12293#endif
12294 case SB32:
12295 mips32_op = OPC_SB;
5c13fdfd 12296 goto do_st;
3c824109
NF
12297 case SH32:
12298 mips32_op = OPC_SH;
5c13fdfd 12299 goto do_st;
3c824109
NF
12300 case SW32:
12301 mips32_op = OPC_SW;
5c13fdfd
AJ
12302 goto do_st;
12303 do_ld:
afa88c3a 12304 gen_ld(env, ctx, mips32_op, rt, rs, imm);
5c13fdfd
AJ
12305 break;
12306 do_st:
12307 gen_st(ctx, mips32_op, rt, rs, imm);
3c824109
NF
12308 break;
12309 default:
12310 generate_exception(ctx, EXCP_RI);
12311 break;
12312 }
12313}
12314
7db13fae 12315static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
12316{
12317 uint32_t op;
12318
12319 /* make sure instructions are on a halfword boundary */
12320 if (ctx->pc & 0x1) {
12321 env->CP0_BadVAddr = ctx->pc;
12322 generate_exception(ctx, EXCP_AdEL);
12323 ctx->bstate = BS_STOP;
12324 return 2;
12325 }
12326
12327 op = (ctx->opcode >> 10) & 0x3f;
12328 /* Enforce properly-sized instructions in a delay slot */
12329 if (ctx->hflags & MIPS_HFLAG_BMASK) {
12330 int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12331
12332 switch (op) {
12333 case POOL32A:
12334 case POOL32B:
12335 case POOL32I:
12336 case POOL32C:
12337 case ADDI32:
12338 case ADDIU32:
12339 case ORI32:
12340 case XORI32:
12341 case SLTI32:
12342 case SLTIU32:
12343 case ANDI32:
12344 case JALX32:
12345 case LBU32:
12346 case LHU32:
12347 case POOL32F:
12348 case JALS32:
12349 case BEQ32:
12350 case BNE32:
12351 case J32:
12352 case JAL32:
12353 case SB32:
12354 case SH32:
12355 case POOL32S:
12356 case ADDIUPC:
12357 case SWC132:
12358 case SDC132:
12359 case SD32:
12360 case SW32:
12361 case LB32:
12362 case LH32:
12363 case DADDIU32:
12364 case POOL48A: /* ??? */
12365 case LWC132:
12366 case LDC132:
12367 case LD32:
12368 case LW32:
12369 if (bits & MIPS_HFLAG_BDS16) {
12370 generate_exception(ctx, EXCP_RI);
12371 /* Just stop translation; the user is confused. */
12372 ctx->bstate = BS_STOP;
12373 return 2;
12374 }
12375 break;
12376 case POOL16A:
12377 case POOL16B:
12378 case POOL16C:
12379 case LWGP16:
12380 case POOL16F:
12381 case LBU16:
12382 case LHU16:
12383 case LWSP16:
12384 case LW16:
12385 case SB16:
12386 case SH16:
12387 case SWSP16:
12388 case SW16:
12389 case MOVE16:
12390 case ANDI16:
12391 case POOL16D:
12392 case POOL16E:
12393 case BEQZ16:
12394 case BNEZ16:
12395 case B16:
12396 case LI16:
12397 if (bits & MIPS_HFLAG_BDS32) {
12398 generate_exception(ctx, EXCP_RI);
12399 /* Just stop translation; the user is confused. */
12400 ctx->bstate = BS_STOP;
12401 return 2;
12402 }
12403 break;
12404 default:
12405 break;
12406 }
12407 }
12408 switch (op) {
12409 case POOL16A:
12410 {
12411 int rd = mmreg(uMIPS_RD(ctx->opcode));
12412 int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12413 int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12414 uint32_t opc = 0;
12415
12416 switch (ctx->opcode & 0x1) {
12417 case ADDU16:
12418 opc = OPC_ADDU;
12419 break;
12420 case SUBU16:
12421 opc = OPC_SUBU;
12422 break;
12423 }
12424
12425 gen_arith(env, ctx, opc, rd, rs1, rs2);
12426 }
12427 break;
12428 case POOL16B:
12429 {
12430 int rd = mmreg(uMIPS_RD(ctx->opcode));
12431 int rs = mmreg(uMIPS_RS(ctx->opcode));
12432 int amount = (ctx->opcode >> 1) & 0x7;
12433 uint32_t opc = 0;
12434 amount = amount == 0 ? 8 : amount;
12435
12436 switch (ctx->opcode & 0x1) {
12437 case SLL16:
12438 opc = OPC_SLL;
12439 break;
12440 case SRL16:
12441 opc = OPC_SRL;
12442 break;
12443 }
12444
12445 gen_shift_imm(env, ctx, opc, rd, rs, amount);
12446 }
12447 break;
12448 case POOL16C:
12449 gen_pool16c_insn(env, ctx, is_branch);
12450 break;
12451 case LWGP16:
12452 {
12453 int rd = mmreg(uMIPS_RD(ctx->opcode));
12454 int rb = 28; /* GP */
12455 int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12456
afa88c3a 12457 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12458 }
12459 break;
12460 case POOL16F:
12461 if (ctx->opcode & 1) {
12462 generate_exception(ctx, EXCP_RI);
12463 } else {
12464 /* MOVEP */
12465 int enc_dest = uMIPS_RD(ctx->opcode);
12466 int enc_rt = uMIPS_RS2(ctx->opcode);
12467 int enc_rs = uMIPS_RS1(ctx->opcode);
12468 int rd, rs, re, rt;
12469 static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12470 static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12471 static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12472
12473 rd = rd_enc[enc_dest];
12474 re = re_enc[enc_dest];
12475 rs = rs_rt_enc[enc_rs];
12476 rt = rs_rt_enc[enc_rt];
12477
12478 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12479 gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
12480 }
12481 break;
12482 case LBU16:
12483 {
12484 int rd = mmreg(uMIPS_RD(ctx->opcode));
12485 int rb = mmreg(uMIPS_RS(ctx->opcode));
12486 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12487 offset = (offset == 0xf ? -1 : offset);
12488
afa88c3a 12489 gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
3c824109
NF
12490 }
12491 break;
12492 case LHU16:
12493 {
12494 int rd = mmreg(uMIPS_RD(ctx->opcode));
12495 int rb = mmreg(uMIPS_RS(ctx->opcode));
12496 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12497
afa88c3a 12498 gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
3c824109
NF
12499 }
12500 break;
12501 case LWSP16:
12502 {
12503 int rd = (ctx->opcode >> 5) & 0x1f;
12504 int rb = 29; /* SP */
12505 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12506
afa88c3a 12507 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12508 }
12509 break;
12510 case LW16:
12511 {
12512 int rd = mmreg(uMIPS_RD(ctx->opcode));
12513 int rb = mmreg(uMIPS_RS(ctx->opcode));
12514 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12515
afa88c3a 12516 gen_ld(env, ctx, OPC_LW, rd, rb, offset);
3c824109
NF
12517 }
12518 break;
12519 case SB16:
12520 {
12521 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12522 int rb = mmreg(uMIPS_RS(ctx->opcode));
12523 int16_t offset = ZIMM(ctx->opcode, 0, 4);
12524
5c13fdfd 12525 gen_st(ctx, OPC_SB, rd, rb, offset);
3c824109
NF
12526 }
12527 break;
12528 case SH16:
12529 {
12530 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12531 int rb = mmreg(uMIPS_RS(ctx->opcode));
12532 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12533
5c13fdfd 12534 gen_st(ctx, OPC_SH, rd, rb, offset);
3c824109
NF
12535 }
12536 break;
12537 case SWSP16:
12538 {
12539 int rd = (ctx->opcode >> 5) & 0x1f;
12540 int rb = 29; /* SP */
12541 int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12542
5c13fdfd 12543 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12544 }
12545 break;
12546 case SW16:
12547 {
12548 int rd = mmreg2(uMIPS_RD(ctx->opcode));
12549 int rb = mmreg(uMIPS_RS(ctx->opcode));
12550 int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12551
5c13fdfd 12552 gen_st(ctx, OPC_SW, rd, rb, offset);
3c824109
NF
12553 }
12554 break;
12555 case MOVE16:
12556 {
12557 int rd = uMIPS_RD5(ctx->opcode);
12558 int rs = uMIPS_RS5(ctx->opcode);
12559
12560 gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
12561 }
12562 break;
12563 case ANDI16:
12564 gen_andi16(env, ctx);
12565 break;
12566 case POOL16D:
12567 switch (ctx->opcode & 0x1) {
12568 case ADDIUS5:
12569 gen_addius5(env, ctx);
12570 break;
12571 case ADDIUSP:
12572 gen_addiusp(env, ctx);
12573 break;
12574 }
12575 break;
12576 case POOL16E:
12577 switch (ctx->opcode & 0x1) {
12578 case ADDIUR2:
12579 gen_addiur2(env, ctx);
12580 break;
12581 case ADDIUR1SP:
12582 gen_addiur1sp(env, ctx);
12583 break;
12584 }
12585 break;
12586 case B16:
12587 gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12588 SIMM(ctx->opcode, 0, 10) << 1);
12589 *is_branch = 1;
12590 break;
12591 case BNEZ16:
12592 case BEQZ16:
12593 gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12594 mmreg(uMIPS_RD(ctx->opcode)),
12595 0, SIMM(ctx->opcode, 0, 7) << 1);
12596 *is_branch = 1;
12597 break;
12598 case LI16:
12599 {
12600 int reg = mmreg(uMIPS_RD(ctx->opcode));
12601 int imm = ZIMM(ctx->opcode, 0, 7);
12602
12603 imm = (imm == 0x7f ? -1 : imm);
12604 tcg_gen_movi_tl(cpu_gpr[reg], imm);
12605 }
12606 break;
12607 case RES_20:
12608 case RES_28:
12609 case RES_29:
12610 case RES_30:
12611 case RES_31:
12612 case RES_38:
12613 case RES_39:
12614 generate_exception(ctx, EXCP_RI);
12615 break;
12616 default:
12617 decode_micromips32_opc (env, ctx, op, is_branch);
12618 return 4;
12619 }
12620
12621 return 2;
12622}
12623
12624/* SmartMIPS extension to MIPS32 */
12625
12626#if defined(TARGET_MIPS64)
12627
12628/* MDMX extension to MIPS64 */
12629
12630#endif
12631
9b1a1d68
JL
12632/* MIPSDSP functions. */
12633static void gen_mipsdsp_ld(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
12634 int rd, int base, int offset)
12635{
12636 const char *opn = "ldx";
12637 TCGv t0;
12638
12639 if (rd == 0) {
12640 MIPS_DEBUG("NOP");
12641 return;
12642 }
12643
12644 check_dsp(ctx);
12645 t0 = tcg_temp_new();
12646
12647 if (base == 0) {
12648 gen_load_gpr(t0, offset);
12649 } else if (offset == 0) {
12650 gen_load_gpr(t0, base);
12651 } else {
12652 gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12653 }
12654
9b1a1d68
JL
12655 switch (opc) {
12656 case OPC_LBUX:
12657 op_ld_lbu(t0, t0, ctx);
12658 gen_store_gpr(t0, rd);
12659 opn = "lbux";
12660 break;
12661 case OPC_LHX:
12662 op_ld_lh(t0, t0, ctx);
12663 gen_store_gpr(t0, rd);
12664 opn = "lhx";
12665 break;
12666 case OPC_LWX:
12667 op_ld_lw(t0, t0, ctx);
12668 gen_store_gpr(t0, rd);
12669 opn = "lwx";
12670 break;
12671#if defined(TARGET_MIPS64)
12672 case OPC_LDX:
12673 op_ld_ld(t0, t0, ctx);
12674 gen_store_gpr(t0, rd);
12675 opn = "ldx";
12676 break;
12677#endif
12678 }
12679 (void)opn; /* avoid a compiler warning */
12680 MIPS_DEBUG("%s %s, %s(%s)", opn,
12681 regnames[rd], regnames[offset], regnames[base]);
12682 tcg_temp_free(t0);
12683}
12684
461c08df
JL
12685static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12686 int ret, int v1, int v2)
12687{
12688 const char *opn = "mipsdsp arith";
12689 TCGv v1_t;
12690 TCGv v2_t;
12691
12692 if (ret == 0) {
12693 /* Treat as NOP. */
12694 MIPS_DEBUG("NOP");
12695 return;
12696 }
12697
12698 v1_t = tcg_temp_new();
12699 v2_t = tcg_temp_new();
12700
12701 gen_load_gpr(v1_t, v1);
12702 gen_load_gpr(v2_t, v2);
12703
12704 switch (op1) {
12705 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12706 case OPC_MULT_G_2E:
12707 check_dspr2(ctx);
12708 switch (op2) {
12709 case OPC_ADDUH_QB:
12710 gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12711 break;
12712 case OPC_ADDUH_R_QB:
12713 gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12714 break;
12715 case OPC_ADDQH_PH:
12716 gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12717 break;
12718 case OPC_ADDQH_R_PH:
12719 gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12720 break;
12721 case OPC_ADDQH_W:
12722 gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12723 break;
12724 case OPC_ADDQH_R_W:
12725 gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12726 break;
12727 case OPC_SUBUH_QB:
12728 gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12729 break;
12730 case OPC_SUBUH_R_QB:
12731 gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12732 break;
12733 case OPC_SUBQH_PH:
12734 gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12735 break;
12736 case OPC_SUBQH_R_PH:
12737 gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12738 break;
12739 case OPC_SUBQH_W:
12740 gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12741 break;
12742 case OPC_SUBQH_R_W:
12743 gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12744 break;
12745 }
12746 break;
12747 case OPC_ABSQ_S_PH_DSP:
12748 switch (op2) {
12749 case OPC_ABSQ_S_QB:
12750 check_dspr2(ctx);
12751 gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12752 break;
12753 case OPC_ABSQ_S_PH:
12754 check_dsp(ctx);
12755 gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12756 break;
12757 case OPC_ABSQ_S_W:
12758 check_dsp(ctx);
12759 gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12760 break;
12761 case OPC_PRECEQ_W_PHL:
12762 check_dsp(ctx);
12763 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12764 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12765 break;
12766 case OPC_PRECEQ_W_PHR:
12767 check_dsp(ctx);
12768 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12769 tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12770 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12771 break;
12772 case OPC_PRECEQU_PH_QBL:
12773 check_dsp(ctx);
12774 gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12775 break;
12776 case OPC_PRECEQU_PH_QBR:
12777 check_dsp(ctx);
12778 gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12779 break;
12780 case OPC_PRECEQU_PH_QBLA:
12781 check_dsp(ctx);
12782 gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12783 break;
12784 case OPC_PRECEQU_PH_QBRA:
12785 check_dsp(ctx);
12786 gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12787 break;
12788 case OPC_PRECEU_PH_QBL:
12789 check_dsp(ctx);
12790 gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12791 break;
12792 case OPC_PRECEU_PH_QBR:
12793 check_dsp(ctx);
12794 gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12795 break;
12796 case OPC_PRECEU_PH_QBLA:
12797 check_dsp(ctx);
12798 gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12799 break;
12800 case OPC_PRECEU_PH_QBRA:
12801 check_dsp(ctx);
12802 gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12803 break;
12804 }
12805 break;
12806 case OPC_ADDU_QB_DSP:
12807 switch (op2) {
12808 case OPC_ADDQ_PH:
12809 check_dsp(ctx);
12810 gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12811 break;
12812 case OPC_ADDQ_S_PH:
12813 check_dsp(ctx);
12814 gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12815 break;
12816 case OPC_ADDQ_S_W:
12817 check_dsp(ctx);
12818 gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12819 break;
12820 case OPC_ADDU_QB:
12821 check_dsp(ctx);
12822 gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12823 break;
12824 case OPC_ADDU_S_QB:
12825 check_dsp(ctx);
12826 gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12827 break;
12828 case OPC_ADDU_PH:
12829 check_dspr2(ctx);
12830 gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12831 break;
12832 case OPC_ADDU_S_PH:
12833 check_dspr2(ctx);
12834 gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12835 break;
12836 case OPC_SUBQ_PH:
12837 check_dsp(ctx);
12838 gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12839 break;
12840 case OPC_SUBQ_S_PH:
12841 check_dsp(ctx);
12842 gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12843 break;
12844 case OPC_SUBQ_S_W:
12845 check_dsp(ctx);
12846 gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12847 break;
12848 case OPC_SUBU_QB:
12849 check_dsp(ctx);
12850 gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12851 break;
12852 case OPC_SUBU_S_QB:
12853 check_dsp(ctx);
12854 gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12855 break;
12856 case OPC_SUBU_PH:
12857 check_dspr2(ctx);
12858 gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12859 break;
12860 case OPC_SUBU_S_PH:
12861 check_dspr2(ctx);
12862 gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12863 break;
12864 case OPC_ADDSC:
12865 check_dsp(ctx);
12866 gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12867 break;
12868 case OPC_ADDWC:
12869 check_dsp(ctx);
12870 gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12871 break;
12872 case OPC_MODSUB:
12873 check_dsp(ctx);
12874 gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12875 break;
12876 case OPC_RADDU_W_QB:
12877 check_dsp(ctx);
12878 gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12879 break;
12880 }
12881 break;
12882 case OPC_CMPU_EQ_QB_DSP:
12883 switch (op2) {
12884 case OPC_PRECR_QB_PH:
12885 check_dspr2(ctx);
12886 gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12887 break;
12888 case OPC_PRECRQ_QB_PH:
12889 check_dsp(ctx);
12890 gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12891 break;
12892 case OPC_PRECR_SRA_PH_W:
12893 check_dspr2(ctx);
12894 {
12895 TCGv_i32 sa_t = tcg_const_i32(v2);
12896 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12897 cpu_gpr[ret]);
12898 tcg_temp_free_i32(sa_t);
12899 break;
12900 }
12901 case OPC_PRECR_SRA_R_PH_W:
12902 check_dspr2(ctx);
12903 {
12904 TCGv_i32 sa_t = tcg_const_i32(v2);
12905 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12906 cpu_gpr[ret]);
12907 tcg_temp_free_i32(sa_t);
12908 break;
12909 }
12910 case OPC_PRECRQ_PH_W:
12911 check_dsp(ctx);
12912 gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12913 break;
12914 case OPC_PRECRQ_RS_PH_W:
12915 check_dsp(ctx);
12916 gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12917 break;
12918 case OPC_PRECRQU_S_QB_PH:
12919 check_dsp(ctx);
12920 gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12921 break;
12922 }
12923 break;
12924#ifdef TARGET_MIPS64
12925 case OPC_ABSQ_S_QH_DSP:
12926 switch (op2) {
12927 case OPC_PRECEQ_L_PWL:
12928 check_dsp(ctx);
12929 tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12930 break;
12931 case OPC_PRECEQ_L_PWR:
12932 check_dsp(ctx);
12933 tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12934 break;
12935 case OPC_PRECEQ_PW_QHL:
12936 check_dsp(ctx);
12937 gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12938 break;
12939 case OPC_PRECEQ_PW_QHR:
12940 check_dsp(ctx);
12941 gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12942 break;
12943 case OPC_PRECEQ_PW_QHLA:
12944 check_dsp(ctx);
12945 gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12946 break;
12947 case OPC_PRECEQ_PW_QHRA:
12948 check_dsp(ctx);
12949 gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12950 break;
12951 case OPC_PRECEQU_QH_OBL:
12952 check_dsp(ctx);
12953 gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12954 break;
12955 case OPC_PRECEQU_QH_OBR:
12956 check_dsp(ctx);
12957 gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12958 break;
12959 case OPC_PRECEQU_QH_OBLA:
12960 check_dsp(ctx);
12961 gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12962 break;
12963 case OPC_PRECEQU_QH_OBRA:
12964 check_dsp(ctx);
12965 gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12966 break;
12967 case OPC_PRECEU_QH_OBL:
12968 check_dsp(ctx);
12969 gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12970 break;
12971 case OPC_PRECEU_QH_OBR:
12972 check_dsp(ctx);
12973 gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12974 break;
12975 case OPC_PRECEU_QH_OBLA:
12976 check_dsp(ctx);
12977 gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12978 break;
12979 case OPC_PRECEU_QH_OBRA:
12980 check_dsp(ctx);
12981 gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12982 break;
12983 case OPC_ABSQ_S_OB:
12984 check_dspr2(ctx);
12985 gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12986 break;
12987 case OPC_ABSQ_S_PW:
12988 check_dsp(ctx);
12989 gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12990 break;
12991 case OPC_ABSQ_S_QH:
12992 check_dsp(ctx);
12993 gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12994 break;
12995 }
12996 break;
12997 case OPC_ADDU_OB_DSP:
12998 switch (op2) {
12999 case OPC_RADDU_L_OB:
13000 check_dsp(ctx);
13001 gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13002 break;
13003 case OPC_SUBQ_PW:
13004 check_dsp(ctx);
13005 gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13006 break;
13007 case OPC_SUBQ_S_PW:
13008 check_dsp(ctx);
13009 gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13010 break;
13011 case OPC_SUBQ_QH:
13012 check_dsp(ctx);
13013 gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13014 break;
13015 case OPC_SUBQ_S_QH:
13016 check_dsp(ctx);
13017 gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13018 break;
13019 case OPC_SUBU_OB:
13020 check_dsp(ctx);
13021 gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13022 break;
13023 case OPC_SUBU_S_OB:
13024 check_dsp(ctx);
13025 gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13026 break;
13027 case OPC_SUBU_QH:
13028 check_dspr2(ctx);
13029 gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13030 break;
13031 case OPC_SUBU_S_QH:
13032 check_dspr2(ctx);
13033 gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13034 break;
13035 case OPC_SUBUH_OB:
13036 check_dspr2(ctx);
13037 gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13038 break;
13039 case OPC_SUBUH_R_OB:
13040 check_dspr2(ctx);
13041 gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13042 break;
13043 case OPC_ADDQ_PW:
13044 check_dsp(ctx);
13045 gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13046 break;
13047 case OPC_ADDQ_S_PW:
13048 check_dsp(ctx);
13049 gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13050 break;
13051 case OPC_ADDQ_QH:
13052 check_dsp(ctx);
13053 gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13054 break;
13055 case OPC_ADDQ_S_QH:
13056 check_dsp(ctx);
13057 gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13058 break;
13059 case OPC_ADDU_OB:
13060 check_dsp(ctx);
13061 gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13062 break;
13063 case OPC_ADDU_S_OB:
13064 check_dsp(ctx);
13065 gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13066 break;
13067 case OPC_ADDU_QH:
13068 check_dspr2(ctx);
13069 gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13070 break;
13071 case OPC_ADDU_S_QH:
13072 check_dspr2(ctx);
13073 gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13074 break;
13075 case OPC_ADDUH_OB:
13076 check_dspr2(ctx);
13077 gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13078 break;
13079 case OPC_ADDUH_R_OB:
13080 check_dspr2(ctx);
13081 gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13082 break;
13083 }
13084 break;
13085 case OPC_CMPU_EQ_OB_DSP:
13086 switch (op2) {
13087 case OPC_PRECR_OB_QH:
13088 check_dspr2(ctx);
13089 gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13090 break;
13091 case OPC_PRECR_SRA_QH_PW:
13092 check_dspr2(ctx);
13093 {
13094 TCGv_i32 ret_t = tcg_const_i32(ret);
13095 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13096 tcg_temp_free_i32(ret_t);
13097 break;
13098 }
13099 case OPC_PRECR_SRA_R_QH_PW:
13100 check_dspr2(ctx);
13101 {
13102 TCGv_i32 sa_v = tcg_const_i32(ret);
13103 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13104 tcg_temp_free_i32(sa_v);
13105 break;
13106 }
13107 case OPC_PRECRQ_OB_QH:
13108 check_dsp(ctx);
13109 gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13110 break;
13111 case OPC_PRECRQ_PW_L:
13112 check_dsp(ctx);
13113 gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13114 break;
13115 case OPC_PRECRQ_QH_PW:
13116 check_dsp(ctx);
13117 gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13118 break;
13119 case OPC_PRECRQ_RS_QH_PW:
13120 check_dsp(ctx);
13121 gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13122 break;
13123 case OPC_PRECRQU_S_OB_QH:
13124 check_dsp(ctx);
13125 gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13126 break;
13127 }
13128 break;
13129#endif
13130 }
13131
13132 tcg_temp_free(v1_t);
13133 tcg_temp_free(v2_t);
13134
13135 (void)opn; /* avoid a compiler warning */
13136 MIPS_DEBUG("%s", opn);
13137}
9b1a1d68 13138
77c5fa8b
JL
13139static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13140 int ret, int v1, int v2)
13141{
13142 uint32_t op2;
13143 const char *opn = "mipsdsp shift";
13144 TCGv t0;
13145 TCGv v1_t;
13146 TCGv v2_t;
13147
13148 if (ret == 0) {
13149 /* Treat as NOP. */
13150 MIPS_DEBUG("NOP");
13151 return;
13152 }
13153
13154 t0 = tcg_temp_new();
13155 v1_t = tcg_temp_new();
13156 v2_t = tcg_temp_new();
13157
13158 tcg_gen_movi_tl(t0, v1);
13159 gen_load_gpr(v1_t, v1);
13160 gen_load_gpr(v2_t, v2);
13161
13162 switch (opc) {
13163 case OPC_SHLL_QB_DSP:
13164 {
13165 op2 = MASK_SHLL_QB(ctx->opcode);
13166 switch (op2) {
13167 case OPC_SHLL_QB:
13168 check_dsp(ctx);
13169 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13170 break;
13171 case OPC_SHLLV_QB:
13172 check_dsp(ctx);
13173 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13174 break;
13175 case OPC_SHLL_PH:
13176 check_dsp(ctx);
13177 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13178 break;
13179 case OPC_SHLLV_PH:
13180 check_dsp(ctx);
13181 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13182 break;
13183 case OPC_SHLL_S_PH:
13184 check_dsp(ctx);
13185 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13186 break;
13187 case OPC_SHLLV_S_PH:
13188 check_dsp(ctx);
13189 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13190 break;
13191 case OPC_SHLL_S_W:
13192 check_dsp(ctx);
13193 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13194 break;
13195 case OPC_SHLLV_S_W:
13196 check_dsp(ctx);
13197 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13198 break;
13199 case OPC_SHRL_QB:
13200 check_dsp(ctx);
13201 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13202 break;
13203 case OPC_SHRLV_QB:
13204 check_dsp(ctx);
13205 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13206 break;
13207 case OPC_SHRL_PH:
13208 check_dspr2(ctx);
13209 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13210 break;
13211 case OPC_SHRLV_PH:
13212 check_dspr2(ctx);
13213 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13214 break;
13215 case OPC_SHRA_QB:
13216 check_dspr2(ctx);
13217 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13218 break;
13219 case OPC_SHRA_R_QB:
13220 check_dspr2(ctx);
13221 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13222 break;
13223 case OPC_SHRAV_QB:
13224 check_dspr2(ctx);
13225 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13226 break;
13227 case OPC_SHRAV_R_QB:
13228 check_dspr2(ctx);
13229 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13230 break;
13231 case OPC_SHRA_PH:
13232 check_dsp(ctx);
13233 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13234 break;
13235 case OPC_SHRA_R_PH:
13236 check_dsp(ctx);
13237 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13238 break;
13239 case OPC_SHRAV_PH:
13240 check_dsp(ctx);
13241 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13242 break;
13243 case OPC_SHRAV_R_PH:
13244 check_dsp(ctx);
13245 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13246 break;
13247 case OPC_SHRA_R_W:
13248 check_dsp(ctx);
13249 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13250 break;
13251 case OPC_SHRAV_R_W:
13252 check_dsp(ctx);
13253 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13254 break;
13255 default: /* Invalid */
13256 MIPS_INVAL("MASK SHLL.QB");
13257 generate_exception(ctx, EXCP_RI);
13258 break;
13259 }
13260 break;
13261 }
13262#ifdef TARGET_MIPS64
13263 case OPC_SHLL_OB_DSP:
13264 op2 = MASK_SHLL_OB(ctx->opcode);
13265 switch (op2) {
13266 case OPC_SHLL_PW:
13267 check_dsp(ctx);
13268 gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13269 break;
13270 case OPC_SHLLV_PW:
13271 check_dsp(ctx);
13272 gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13273 break;
13274 case OPC_SHLL_S_PW:
13275 check_dsp(ctx);
13276 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13277 break;
13278 case OPC_SHLLV_S_PW:
13279 check_dsp(ctx);
13280 gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13281 break;
13282 case OPC_SHLL_OB:
13283 check_dsp(ctx);
13284 gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13285 break;
13286 case OPC_SHLLV_OB:
13287 check_dsp(ctx);
13288 gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13289 break;
13290 case OPC_SHLL_QH:
13291 check_dsp(ctx);
13292 gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13293 break;
13294 case OPC_SHLLV_QH:
13295 check_dsp(ctx);
13296 gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13297 break;
13298 case OPC_SHLL_S_QH:
13299 check_dsp(ctx);
13300 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13301 break;
13302 case OPC_SHLLV_S_QH:
13303 check_dsp(ctx);
13304 gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13305 break;
13306 case OPC_SHRA_OB:
13307 check_dspr2(ctx);
13308 gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13309 break;
13310 case OPC_SHRAV_OB:
13311 check_dspr2(ctx);
13312 gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13313 break;
13314 case OPC_SHRA_R_OB:
13315 check_dspr2(ctx);
13316 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13317 break;
13318 case OPC_SHRAV_R_OB:
13319 check_dspr2(ctx);
13320 gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13321 break;
13322 case OPC_SHRA_PW:
13323 check_dsp(ctx);
13324 gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13325 break;
13326 case OPC_SHRAV_PW:
13327 check_dsp(ctx);
13328 gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13329 break;
13330 case OPC_SHRA_R_PW:
13331 check_dsp(ctx);
13332 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13333 break;
13334 case OPC_SHRAV_R_PW:
13335 check_dsp(ctx);
13336 gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13337 break;
13338 case OPC_SHRA_QH:
13339 check_dsp(ctx);
13340 gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13341 break;
13342 case OPC_SHRAV_QH:
13343 check_dsp(ctx);
13344 gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13345 break;
13346 case OPC_SHRA_R_QH:
13347 check_dsp(ctx);
13348 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13349 break;
13350 case OPC_SHRAV_R_QH:
13351 check_dsp(ctx);
13352 gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13353 break;
13354 case OPC_SHRL_OB:
13355 check_dsp(ctx);
13356 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13357 break;
13358 case OPC_SHRLV_OB:
13359 check_dsp(ctx);
13360 gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13361 break;
13362 case OPC_SHRL_QH:
13363 check_dspr2(ctx);
13364 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13365 break;
13366 case OPC_SHRLV_QH:
13367 check_dspr2(ctx);
13368 gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13369 break;
13370 default: /* Invalid */
13371 MIPS_INVAL("MASK SHLL.OB");
13372 generate_exception(ctx, EXCP_RI);
13373 break;
13374 }
13375 break;
13376#endif
13377 }
13378
13379 tcg_temp_free(t0);
13380 tcg_temp_free(v1_t);
13381 tcg_temp_free(v2_t);
13382 (void)opn; /* avoid a compiler warning */
13383 MIPS_DEBUG("%s", opn);
13384}
13385
a22260ae
JL
13386static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13387 int ret, int v1, int v2, int check_ret)
13388{
13389 const char *opn = "mipsdsp multiply";
13390 TCGv_i32 t0;
13391 TCGv v1_t;
13392 TCGv v2_t;
13393
13394 if ((ret == 0) && (check_ret == 1)) {
13395 /* Treat as NOP. */
13396 MIPS_DEBUG("NOP");
13397 return;
13398 }
13399
13400 t0 = tcg_temp_new_i32();
13401 v1_t = tcg_temp_new();
13402 v2_t = tcg_temp_new();
13403
13404 tcg_gen_movi_i32(t0, ret);
13405 gen_load_gpr(v1_t, v1);
13406 gen_load_gpr(v2_t, v2);
13407
13408 switch (op1) {
13409 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13410 * the same mask and op1. */
13411 case OPC_MULT_G_2E:
13412 switch (op2) {
13413 case OPC_MUL_PH:
13414 gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13415 break;
13416 case OPC_MUL_S_PH:
13417 gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13418 break;
13419 case OPC_MULQ_S_W:
13420 gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13421 break;
13422 case OPC_MULQ_RS_W:
13423 gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13424 break;
13425 }
13426 break;
13427 case OPC_DPA_W_PH_DSP:
13428 switch (op2) {
13429 case OPC_DPAU_H_QBL:
13430 check_dsp(ctx);
13431 gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13432 break;
13433 case OPC_DPAU_H_QBR:
13434 check_dsp(ctx);
13435 gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13436 break;
13437 case OPC_DPSU_H_QBL:
13438 check_dsp(ctx);
13439 gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13440 break;
13441 case OPC_DPSU_H_QBR:
13442 check_dsp(ctx);
13443 gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13444 break;
13445 case OPC_DPA_W_PH:
13446 check_dspr2(ctx);
13447 gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13448 break;
13449 case OPC_DPAX_W_PH:
13450 check_dspr2(ctx);
13451 gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13452 break;
13453 case OPC_DPAQ_S_W_PH:
13454 check_dsp(ctx);
13455 gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13456 break;
13457 case OPC_DPAQX_S_W_PH:
13458 check_dspr2(ctx);
13459 gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13460 break;
13461 case OPC_DPAQX_SA_W_PH:
13462 check_dspr2(ctx);
13463 gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13464 break;
13465 case OPC_DPS_W_PH:
13466 check_dspr2(ctx);
13467 gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13468 break;
13469 case OPC_DPSX_W_PH:
13470 check_dspr2(ctx);
13471 gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13472 break;
13473 case OPC_DPSQ_S_W_PH:
13474 check_dsp(ctx);
13475 gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13476 break;
13477 case OPC_DPSQX_S_W_PH:
13478 check_dspr2(ctx);
13479 gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13480 break;
13481 case OPC_DPSQX_SA_W_PH:
13482 check_dspr2(ctx);
13483 gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13484 break;
13485 case OPC_MULSAQ_S_W_PH:
13486 check_dsp(ctx);
13487 gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13488 break;
13489 case OPC_DPAQ_SA_L_W:
13490 check_dsp(ctx);
13491 gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13492 break;
13493 case OPC_DPSQ_SA_L_W:
13494 check_dsp(ctx);
13495 gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13496 break;
13497 case OPC_MAQ_S_W_PHL:
13498 check_dsp(ctx);
13499 gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13500 break;
13501 case OPC_MAQ_S_W_PHR:
13502 check_dsp(ctx);
13503 gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13504 break;
13505 case OPC_MAQ_SA_W_PHL:
13506 check_dsp(ctx);
13507 gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13508 break;
13509 case OPC_MAQ_SA_W_PHR:
13510 check_dsp(ctx);
13511 gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13512 break;
13513 case OPC_MULSA_W_PH:
13514 check_dspr2(ctx);
13515 gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13516 break;
13517 }
13518 break;
13519#ifdef TARGET_MIPS64
13520 case OPC_DPAQ_W_QH_DSP:
13521 {
13522 int ac = ret & 0x03;
13523 tcg_gen_movi_i32(t0, ac);
13524
13525 switch (op2) {
13526 case OPC_DMADD:
13527 check_dsp(ctx);
13528 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13529 break;
13530 case OPC_DMADDU:
13531 check_dsp(ctx);
13532 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13533 break;
13534 case OPC_DMSUB:
13535 check_dsp(ctx);
13536 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13537 break;
13538 case OPC_DMSUBU:
13539 check_dsp(ctx);
13540 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13541 break;
13542 case OPC_DPA_W_QH:
13543 check_dspr2(ctx);
13544 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13545 break;
13546 case OPC_DPAQ_S_W_QH:
13547 check_dsp(ctx);
13548 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13549 break;
13550 case OPC_DPAQ_SA_L_PW:
13551 check_dsp(ctx);
13552 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13553 break;
13554 case OPC_DPAU_H_OBL:
13555 check_dsp(ctx);
13556 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13557 break;
13558 case OPC_DPAU_H_OBR:
13559 check_dsp(ctx);
13560 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13561 break;
13562 case OPC_DPS_W_QH:
13563 check_dspr2(ctx);
13564 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13565 break;
13566 case OPC_DPSQ_S_W_QH:
13567 check_dsp(ctx);
13568 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13569 break;
13570 case OPC_DPSQ_SA_L_PW:
13571 check_dsp(ctx);
13572 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13573 break;
13574 case OPC_DPSU_H_OBL:
13575 check_dsp(ctx);
13576 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13577 break;
13578 case OPC_DPSU_H_OBR:
13579 check_dsp(ctx);
13580 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13581 break;
13582 case OPC_MAQ_S_L_PWL:
13583 check_dsp(ctx);
13584 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13585 break;
13586 case OPC_MAQ_S_L_PWR:
13587 check_dsp(ctx);
13588 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13589 break;
13590 case OPC_MAQ_S_W_QHLL:
13591 check_dsp(ctx);
13592 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13593 break;
13594 case OPC_MAQ_SA_W_QHLL:
13595 check_dsp(ctx);
13596 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13597 break;
13598 case OPC_MAQ_S_W_QHLR:
13599 check_dsp(ctx);
13600 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13601 break;
13602 case OPC_MAQ_SA_W_QHLR:
13603 check_dsp(ctx);
13604 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13605 break;
13606 case OPC_MAQ_S_W_QHRL:
13607 check_dsp(ctx);
13608 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13609 break;
13610 case OPC_MAQ_SA_W_QHRL:
13611 check_dsp(ctx);
13612 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13613 break;
13614 case OPC_MAQ_S_W_QHRR:
13615 check_dsp(ctx);
13616 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13617 break;
13618 case OPC_MAQ_SA_W_QHRR:
13619 check_dsp(ctx);
13620 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13621 break;
13622 case OPC_MULSAQ_S_L_PW:
13623 check_dsp(ctx);
13624 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13625 break;
13626 case OPC_MULSAQ_S_W_QH:
13627 check_dsp(ctx);
13628 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13629 break;
13630 }
13631 }
13632 break;
13633#endif
13634 case OPC_ADDU_QB_DSP:
13635 switch (op2) {
13636 case OPC_MULEU_S_PH_QBL:
13637 check_dsp(ctx);
13638 gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13639 break;
13640 case OPC_MULEU_S_PH_QBR:
13641 check_dsp(ctx);
13642 gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13643 break;
13644 case OPC_MULQ_RS_PH:
13645 check_dsp(ctx);
13646 gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13647 break;
13648 case OPC_MULEQ_S_W_PHL:
13649 check_dsp(ctx);
13650 gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13651 break;
13652 case OPC_MULEQ_S_W_PHR:
13653 check_dsp(ctx);
13654 gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13655 break;
13656 case OPC_MULQ_S_PH:
13657 check_dspr2(ctx);
13658 gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13659 break;
13660 }
13661 break;
13662#ifdef TARGET_MIPS64
13663 case OPC_ADDU_OB_DSP:
13664 switch (op2) {
13665 case OPC_MULEQ_S_PW_QHL:
13666 check_dsp(ctx);
13667 gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13668 break;
13669 case OPC_MULEQ_S_PW_QHR:
13670 check_dsp(ctx);
13671 gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13672 break;
13673 case OPC_MULEU_S_QH_OBL:
13674 check_dsp(ctx);
13675 gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13676 break;
13677 case OPC_MULEU_S_QH_OBR:
13678 check_dsp(ctx);
13679 gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13680 break;
13681 case OPC_MULQ_RS_QH:
13682 check_dsp(ctx);
13683 gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13684 break;
13685 }
13686 break;
13687#endif
13688 }
13689
13690 tcg_temp_free_i32(t0);
13691 tcg_temp_free(v1_t);
13692 tcg_temp_free(v2_t);
13693
13694 (void)opn; /* avoid a compiler warning */
13695 MIPS_DEBUG("%s", opn);
13696
13697}
13698
1cb6686c
JL
13699static void gen_mipsdsp_bitinsn(CPUMIPSState *env, DisasContext *ctx,
13700 uint32_t op1, uint32_t op2,
13701 int ret, int val)
13702{
13703 const char *opn = "mipsdsp Bit/ Manipulation";
13704 int16_t imm;
13705 TCGv t0;
13706 TCGv val_t;
13707
13708 if (ret == 0) {
13709 /* Treat as NOP. */
13710 MIPS_DEBUG("NOP");
13711 return;
13712 }
13713
13714 t0 = tcg_temp_new();
13715 val_t = tcg_temp_new();
13716 gen_load_gpr(val_t, val);
13717
13718 switch (op1) {
13719 case OPC_ABSQ_S_PH_DSP:
13720 switch (op2) {
13721 case OPC_BITREV:
13722 check_dsp(ctx);
13723 gen_helper_bitrev(cpu_gpr[ret], val_t);
13724 break;
13725 case OPC_REPL_QB:
13726 check_dsp(ctx);
13727 {
13728 target_long result;
13729 imm = (ctx->opcode >> 16) & 0xFF;
13730 result = (uint32_t)imm << 24 |
13731 (uint32_t)imm << 16 |
13732 (uint32_t)imm << 8 |
13733 (uint32_t)imm;
13734 result = (int32_t)result;
13735 tcg_gen_movi_tl(cpu_gpr[ret], result);
13736 }
13737 break;
13738 case OPC_REPLV_QB:
13739 check_dsp(ctx);
13740 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13741 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13742 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13743 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13744 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13745 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13746 break;
13747 case OPC_REPL_PH:
13748 check_dsp(ctx);
13749 {
13750 imm = (ctx->opcode >> 16) & 0x03FF;
13751 tcg_gen_movi_tl(cpu_gpr[ret], \
13752 (target_long)((int32_t)imm << 16 | \
13753 (uint32_t)(uint16_t)imm));
13754 }
13755 break;
13756 case OPC_REPLV_PH:
13757 check_dsp(ctx);
13758 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13759 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13760 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13761 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13762 break;
13763 }
13764 break;
13765#ifdef TARGET_MIPS64
13766 case OPC_ABSQ_S_QH_DSP:
13767 switch (op2) {
13768 case OPC_REPL_OB:
13769 check_dsp(ctx);
13770 {
13771 target_long temp;
13772
13773 imm = (ctx->opcode >> 16) & 0xFF;
13774 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13775 temp = (temp << 16) | temp;
13776 temp = (temp << 32) | temp;
13777 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13778 break;
13779 }
13780 case OPC_REPL_PW:
13781 check_dsp(ctx);
13782 {
13783 target_long temp;
13784
13785 imm = (ctx->opcode >> 16) & 0x03FF;
13786 imm = (int16_t)(imm << 6) >> 6;
13787 temp = ((target_long)imm << 32) \
13788 | ((target_long)imm & 0xFFFFFFFF);
13789 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13790 break;
13791 }
13792 case OPC_REPL_QH:
13793 check_dsp(ctx);
13794 {
13795 target_long temp;
13796
13797 imm = (ctx->opcode >> 16) & 0x03FF;
13798 imm = (int16_t)(imm << 6) >> 6;
13799
13800 temp = ((uint64_t)(uint16_t)imm << 48) |
13801 ((uint64_t)(uint16_t)imm << 32) |
13802 ((uint64_t)(uint16_t)imm << 16) |
13803 (uint64_t)(uint16_t)imm;
13804 tcg_gen_movi_tl(cpu_gpr[ret], temp);
13805 break;
13806 }
13807 case OPC_REPLV_OB:
13808 check_dsp(ctx);
13809 tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13810 tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13811 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13812 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13813 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13814 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13815 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13816 break;
13817 case OPC_REPLV_PW:
13818 check_dsp(ctx);
13819 tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13820 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13821 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13822 break;
13823 case OPC_REPLV_QH:
13824 check_dsp(ctx);
13825 tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13826 tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13827 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13828 tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13829 tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13830 break;
13831 }
13832 break;
13833#endif
13834 }
13835 tcg_temp_free(t0);
13836 tcg_temp_free(val_t);
13837
13838 (void)opn; /* avoid a compiler warning */
13839 MIPS_DEBUG("%s", opn);
13840}
13841
26690560
JL
13842static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13843 uint32_t op1, uint32_t op2,
13844 int ret, int v1, int v2, int check_ret)
13845{
13846 const char *opn = "mipsdsp add compare pick";
13847 TCGv_i32 t0;
13848 TCGv t1;
13849 TCGv v1_t;
13850 TCGv v2_t;
13851
13852 if ((ret == 0) && (check_ret == 1)) {
13853 /* Treat as NOP. */
13854 MIPS_DEBUG("NOP");
13855 return;
13856 }
13857
13858 t0 = tcg_temp_new_i32();
13859 t1 = tcg_temp_new();
13860 v1_t = tcg_temp_new();
13861 v2_t = tcg_temp_new();
13862
13863 gen_load_gpr(v1_t, v1);
13864 gen_load_gpr(v2_t, v2);
13865
13866 switch (op1) {
13867 case OPC_APPEND_DSP:
13868 switch (op2) {
13869 case OPC_APPEND:
13870 tcg_gen_movi_i32(t0, v2);
13871 gen_helper_append(cpu_gpr[ret], cpu_gpr[ret], v1_t, t0);
13872 break;
13873 case OPC_PREPEND:
13874 tcg_gen_movi_i32(t0, v2);
13875 gen_helper_prepend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13876 break;
13877 case OPC_BALIGN:
13878 tcg_gen_movi_i32(t0, v2);
13879 gen_helper_balign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
13880 break;
13881 default: /* Invid */
13882 MIPS_INVAL("MASK APPEND");
13883 generate_exception(ctx, EXCP_RI);
13884 break;
13885 }
13886 break;
13887 case OPC_CMPU_EQ_QB_DSP:
13888 switch (op2) {
13889 case OPC_CMPU_EQ_QB:
13890 check_dsp(ctx);
13891 gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13892 break;
13893 case OPC_CMPU_LT_QB:
13894 check_dsp(ctx);
13895 gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13896 break;
13897 case OPC_CMPU_LE_QB:
13898 check_dsp(ctx);
13899 gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13900 break;
13901 case OPC_CMPGU_EQ_QB:
13902 check_dsp(ctx);
13903 gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13904 break;
13905 case OPC_CMPGU_LT_QB:
13906 check_dsp(ctx);
13907 gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13908 break;
13909 case OPC_CMPGU_LE_QB:
13910 check_dsp(ctx);
13911 gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13912 break;
13913 case OPC_CMPGDU_EQ_QB:
13914 check_dspr2(ctx);
13915 gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13916 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13917 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13918 tcg_gen_shli_tl(t1, t1, 24);
13919 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13920 break;
13921 case OPC_CMPGDU_LT_QB:
13922 check_dspr2(ctx);
13923 gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13924 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13925 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13926 tcg_gen_shli_tl(t1, t1, 24);
13927 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13928 break;
13929 case OPC_CMPGDU_LE_QB:
13930 check_dspr2(ctx);
13931 gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13932 tcg_gen_mov_tl(cpu_gpr[ret], t1);
13933 tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13934 tcg_gen_shli_tl(t1, t1, 24);
13935 tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13936 break;
13937 case OPC_CMP_EQ_PH:
13938 check_dsp(ctx);
13939 gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13940 break;
13941 case OPC_CMP_LT_PH:
13942 check_dsp(ctx);
13943 gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13944 break;
13945 case OPC_CMP_LE_PH:
13946 check_dsp(ctx);
13947 gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13948 break;
13949 case OPC_PICK_QB:
13950 check_dsp(ctx);
13951 gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13952 break;
13953 case OPC_PICK_PH:
13954 check_dsp(ctx);
13955 gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13956 break;
13957 case OPC_PACKRL_PH:
13958 check_dsp(ctx);
13959 gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13960 break;
13961 }
13962 break;
13963#ifdef TARGET_MIPS64
13964 case OPC_CMPU_EQ_OB_DSP:
13965 switch (op2) {
13966 case OPC_CMP_EQ_PW:
13967 check_dsp(ctx);
13968 gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13969 break;
13970 case OPC_CMP_LT_PW:
13971 check_dsp(ctx);
13972 gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13973 break;
13974 case OPC_CMP_LE_PW:
13975 check_dsp(ctx);
13976 gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13977 break;
13978 case OPC_CMP_EQ_QH:
13979 check_dsp(ctx);
13980 gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13981 break;
13982 case OPC_CMP_LT_QH:
13983 check_dsp(ctx);
13984 gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13985 break;
13986 case OPC_CMP_LE_QH:
13987 check_dsp(ctx);
13988 gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13989 break;
13990 case OPC_CMPGDU_EQ_OB:
13991 check_dspr2(ctx);
13992 gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13993 break;
13994 case OPC_CMPGDU_LT_OB:
13995 check_dspr2(ctx);
13996 gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13997 break;
13998 case OPC_CMPGDU_LE_OB:
13999 check_dspr2(ctx);
14000 gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14001 break;
14002 case OPC_CMPGU_EQ_OB:
14003 check_dsp(ctx);
14004 gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14005 break;
14006 case OPC_CMPGU_LT_OB:
14007 check_dsp(ctx);
14008 gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14009 break;
14010 case OPC_CMPGU_LE_OB:
14011 check_dsp(ctx);
14012 gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14013 break;
14014 case OPC_CMPU_EQ_OB:
14015 check_dsp(ctx);
14016 gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14017 break;
14018 case OPC_CMPU_LT_OB:
14019 check_dsp(ctx);
14020 gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14021 break;
14022 case OPC_CMPU_LE_OB:
14023 check_dsp(ctx);
14024 gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14025 break;
14026 case OPC_PACKRL_PW:
14027 check_dsp(ctx);
14028 gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14029 break;
14030 case OPC_PICK_OB:
14031 check_dsp(ctx);
14032 gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14033 break;
14034 case OPC_PICK_PW:
14035 check_dsp(ctx);
14036 gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14037 break;
14038 case OPC_PICK_QH:
14039 check_dsp(ctx);
14040 gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14041 break;
14042 }
14043 break;
14044 case OPC_DAPPEND_DSP:
14045 switch (op2) {
14046 case OPC_DAPPEND:
14047 tcg_gen_movi_i32(t0, v2);
14048 gen_helper_dappend(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14049 break;
14050 case OPC_PREPENDD:
14051 tcg_gen_movi_i32(t0, v2);
14052 gen_helper_prependd(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14053 break;
14054 case OPC_PREPENDW:
14055 tcg_gen_movi_i32(t0, v2);
14056 gen_helper_prependw(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14057 break;
14058 case OPC_DBALIGN:
14059 tcg_gen_movi_i32(t0, v2);
14060 gen_helper_dbalign(cpu_gpr[ret], v1_t, cpu_gpr[ret], t0);
14061 break;
14062 default: /* Invalid */
14063 MIPS_INVAL("MASK DAPPEND");
14064 generate_exception(ctx, EXCP_RI);
14065 break;
14066 }
14067 break;
14068#endif
14069 }
14070
14071 tcg_temp_free_i32(t0);
14072 tcg_temp_free(t1);
14073 tcg_temp_free(v1_t);
14074 tcg_temp_free(v2_t);
14075
14076 (void)opn; /* avoid a compiler warning */
14077 MIPS_DEBUG("%s", opn);
14078}
14079
b53371ed
JL
14080static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14081 int ret, int v1, int v2, int check_ret)
14082
14083{
14084 const char *opn = "mipsdsp accumulator";
14085 TCGv t0;
14086 TCGv t1;
14087 TCGv v1_t;
14088 TCGv v2_t;
14089 int16_t imm;
14090
14091 if ((ret == 0) && (check_ret == 1)) {
14092 /* Treat as NOP. */
14093 MIPS_DEBUG("NOP");
14094 return;
14095 }
14096
14097 t0 = tcg_temp_new();
14098 t1 = tcg_temp_new();
14099 v1_t = tcg_temp_new();
14100 v2_t = tcg_temp_new();
14101
14102 gen_load_gpr(v1_t, v1);
14103 gen_load_gpr(v2_t, v2);
14104
14105 switch (op1) {
14106 case OPC_EXTR_W_DSP:
14107 check_dsp(ctx);
14108 switch (op2) {
14109 case OPC_EXTR_W:
14110 tcg_gen_movi_tl(t0, v2);
14111 tcg_gen_movi_tl(t1, v1);
14112 gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14113 break;
14114 case OPC_EXTR_R_W:
14115 tcg_gen_movi_tl(t0, v2);
14116 tcg_gen_movi_tl(t1, v1);
14117 gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14118 break;
14119 case OPC_EXTR_RS_W:
14120 tcg_gen_movi_tl(t0, v2);
14121 tcg_gen_movi_tl(t1, v1);
14122 gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14123 break;
14124 case OPC_EXTR_S_H:
14125 tcg_gen_movi_tl(t0, v2);
14126 tcg_gen_movi_tl(t1, v1);
14127 gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14128 break;
14129 case OPC_EXTRV_S_H:
14130 tcg_gen_movi_tl(t0, v2);
14131 gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14132 break;
14133 case OPC_EXTRV_W:
14134 tcg_gen_movi_tl(t0, v2);
14135 gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14136 break;
14137 case OPC_EXTRV_R_W:
14138 tcg_gen_movi_tl(t0, v2);
14139 gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14140 break;
14141 case OPC_EXTRV_RS_W:
14142 tcg_gen_movi_tl(t0, v2);
14143 gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14144 break;
14145 case OPC_EXTP:
14146 tcg_gen_movi_tl(t0, v2);
14147 tcg_gen_movi_tl(t1, v1);
14148 gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14149 break;
14150 case OPC_EXTPV:
14151 tcg_gen_movi_tl(t0, v2);
14152 gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14153 break;
14154 case OPC_EXTPDP:
14155 tcg_gen_movi_tl(t0, v2);
14156 tcg_gen_movi_tl(t1, v1);
14157 gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14158 break;
14159 case OPC_EXTPDPV:
14160 tcg_gen_movi_tl(t0, v2);
14161 gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14162 break;
14163 case OPC_SHILO:
14164 imm = (ctx->opcode >> 20) & 0x3F;
14165 tcg_gen_movi_tl(t0, ret);
14166 tcg_gen_movi_tl(t1, imm);
14167 gen_helper_shilo(t0, t1, cpu_env);
14168 break;
14169 case OPC_SHILOV:
14170 tcg_gen_movi_tl(t0, ret);
14171 gen_helper_shilo(t0, v1_t, cpu_env);
14172 break;
14173 case OPC_MTHLIP:
14174 tcg_gen_movi_tl(t0, ret);
14175 gen_helper_mthlip(t0, v1_t, cpu_env);
14176 break;
14177 case OPC_WRDSP:
14178 imm = (ctx->opcode >> 11) & 0x3FF;
14179 tcg_gen_movi_tl(t0, imm);
14180 gen_helper_wrdsp(v1_t, t0, cpu_env);
14181 break;
14182 case OPC_RDDSP:
14183 imm = (ctx->opcode >> 16) & 0x03FF;
14184 tcg_gen_movi_tl(t0, imm);
14185 gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14186 break;
14187 }
14188 break;
14189#ifdef TARGET_MIPS64
14190 case OPC_DEXTR_W_DSP:
14191 check_dsp(ctx);
14192 switch (op2) {
14193 case OPC_DMTHLIP:
14194 tcg_gen_movi_tl(t0, ret);
14195 gen_helper_dmthlip(v1_t, t0, cpu_env);
14196 break;
14197 case OPC_DSHILO:
14198 {
14199 int shift = (ctx->opcode >> 19) & 0x7F;
14200 int ac = (ctx->opcode >> 11) & 0x03;
14201 tcg_gen_movi_tl(t0, shift);
14202 tcg_gen_movi_tl(t1, ac);
14203 gen_helper_dshilo(t0, t1, cpu_env);
14204 break;
14205 }
14206 case OPC_DSHILOV:
14207 {
14208 int ac = (ctx->opcode >> 11) & 0x03;
14209 tcg_gen_movi_tl(t0, ac);
14210 gen_helper_dshilo(v1_t, t0, cpu_env);
14211 break;
14212 }
14213 case OPC_DEXTP:
14214 tcg_gen_movi_tl(t0, v2);
14215 tcg_gen_movi_tl(t1, v1);
14216
14217 gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14218 break;
14219 case OPC_DEXTPV:
14220 tcg_gen_movi_tl(t0, v2);
14221 gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14222 break;
14223 case OPC_DEXTPDP:
14224 tcg_gen_movi_tl(t0, v2);
14225 tcg_gen_movi_tl(t1, v1);
14226 gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14227 break;
14228 case OPC_DEXTPDPV:
14229 tcg_gen_movi_tl(t0, v2);
14230 gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14231 break;
14232 case OPC_DEXTR_L:
14233 tcg_gen_movi_tl(t0, v2);
14234 tcg_gen_movi_tl(t1, v1);
14235 gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14236 break;
14237 case OPC_DEXTR_R_L:
14238 tcg_gen_movi_tl(t0, v2);
14239 tcg_gen_movi_tl(t1, v1);
14240 gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14241 break;
14242 case OPC_DEXTR_RS_L:
14243 tcg_gen_movi_tl(t0, v2);
14244 tcg_gen_movi_tl(t1, v1);
14245 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14246 break;
14247 case OPC_DEXTR_W:
14248 tcg_gen_movi_tl(t0, v2);
14249 tcg_gen_movi_tl(t1, v1);
14250 gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14251 break;
14252 case OPC_DEXTR_R_W:
14253 tcg_gen_movi_tl(t0, v2);
14254 tcg_gen_movi_tl(t1, v1);
14255 gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14256 break;
14257 case OPC_DEXTR_RS_W:
14258 tcg_gen_movi_tl(t0, v2);
14259 tcg_gen_movi_tl(t1, v1);
14260 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14261 break;
14262 case OPC_DEXTR_S_H:
14263 tcg_gen_movi_tl(t0, v2);
14264 tcg_gen_movi_tl(t1, v1);
14265 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14266 break;
14267 case OPC_DEXTRV_S_H:
14268 tcg_gen_movi_tl(t0, v2);
14269 tcg_gen_movi_tl(t1, v1);
14270 gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14271 break;
14272 case OPC_DEXTRV_L:
14273 tcg_gen_movi_tl(t0, v2);
14274 gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14275 break;
14276 case OPC_DEXTRV_R_L:
14277 tcg_gen_movi_tl(t0, v2);
14278 gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14279 break;
14280 case OPC_DEXTRV_RS_L:
14281 tcg_gen_movi_tl(t0, v2);
14282 gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14283 break;
14284 case OPC_DEXTRV_W:
14285 tcg_gen_movi_tl(t0, v2);
14286 gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14287 break;
14288 case OPC_DEXTRV_R_W:
14289 tcg_gen_movi_tl(t0, v2);
14290 gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14291 break;
14292 case OPC_DEXTRV_RS_W:
14293 tcg_gen_movi_tl(t0, v2);
14294 gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14295 break;
14296 }
14297 break;
14298#endif
14299 }
14300
14301 tcg_temp_free(t0);
14302 tcg_temp_free(t1);
14303 tcg_temp_free(v1_t);
14304 tcg_temp_free(v2_t);
14305
14306 (void)opn; /* avoid a compiler warning */
14307 MIPS_DEBUG("%s", opn);
14308}
14309
9b1a1d68
JL
14310/* End MIPSDSP functions. */
14311
7db13fae 14312static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
3c824109
NF
14313{
14314 int32_t offset;
14315 int rs, rt, rd, sa;
14316 uint32_t op, op1, op2;
14317 int16_t imm;
14318
14319 /* make sure instructions are on a word boundary */
14320 if (ctx->pc & 0x3) {
14321 env->CP0_BadVAddr = ctx->pc;
14322 generate_exception(ctx, EXCP_AdEL);
14323 return;
14324 }
14325
14326 /* Handle blikely not taken case */
14327 if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14328 int l1 = gen_new_label();
14329
14330 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14331 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14332 tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14333 gen_goto_tb(ctx, 1, ctx->pc + 4);
14334 gen_set_label(l1);
14335 }
14336
fdefe51c 14337 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
3c824109 14338 tcg_gen_debug_insn_start(ctx->pc);
fdefe51c 14339 }
3c824109
NF
14340
14341 op = MASK_OP_MAJOR(ctx->opcode);
14342 rs = (ctx->opcode >> 21) & 0x1f;
14343 rt = (ctx->opcode >> 16) & 0x1f;
14344 rd = (ctx->opcode >> 11) & 0x1f;
14345 sa = (ctx->opcode >> 6) & 0x1f;
14346 imm = (int16_t)ctx->opcode;
14347 switch (op) {
7a387fff
TS
14348 case OPC_SPECIAL:
14349 op1 = MASK_SPECIAL(ctx->opcode);
6af0bf9c 14350 switch (op1) {
324d9e32
AJ
14351 case OPC_SLL: /* Shift with immediate */
14352 case OPC_SRA:
324d9e32 14353 gen_shift_imm(env, ctx, op1, rd, rt, sa);
7a387fff 14354 break;
ea63e2c3
NF
14355 case OPC_SRL:
14356 switch ((ctx->opcode >> 21) & 0x1f) {
14357 case 1:
14358 /* rotr is decoded as srl on non-R2 CPUs */
14359 if (env->insn_flags & ISA_MIPS32R2) {
14360 op1 = OPC_ROTR;
14361 }
14362 /* Fallthrough */
14363 case 0:
14364 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14365 break;
14366 default:
14367 generate_exception(ctx, EXCP_RI);
14368 break;
14369 }
14370 break;
460f00c4
AJ
14371 case OPC_MOVN: /* Conditional move */
14372 case OPC_MOVZ:
aa8f4009
AJ
14373 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
14374 INSN_LOONGSON2E | INSN_LOONGSON2F);
9fa77488 14375 gen_cond_move(env, ctx, op1, rd, rs, rt);
460f00c4
AJ
14376 break;
14377 case OPC_ADD ... OPC_SUBU:
e189e748 14378 gen_arith(env, ctx, op1, rd, rs, rt);
7a387fff 14379 break;
460f00c4 14380 case OPC_SLLV: /* Shifts */
460f00c4
AJ
14381 case OPC_SRAV:
14382 gen_shift(env, ctx, op1, rd, rs, rt);
14383 break;
ea63e2c3
NF
14384 case OPC_SRLV:
14385 switch ((ctx->opcode >> 6) & 0x1f) {
14386 case 1:
14387 /* rotrv is decoded as srlv on non-R2 CPUs */
14388 if (env->insn_flags & ISA_MIPS32R2) {
14389 op1 = OPC_ROTRV;
14390 }
14391 /* Fallthrough */
14392 case 0:
14393 gen_shift(env, ctx, op1, rd, rs, rt);
14394 break;
14395 default:
14396 generate_exception(ctx, EXCP_RI);
14397 break;
14398 }
14399 break;
460f00c4
AJ
14400 case OPC_SLT: /* Set on less than */
14401 case OPC_SLTU:
9fa77488 14402 gen_slt(env, ctx, op1, rd, rs, rt);
460f00c4
AJ
14403 break;
14404 case OPC_AND: /* Logic*/
14405 case OPC_OR:
14406 case OPC_NOR:
14407 case OPC_XOR:
9fa77488 14408 gen_logic(env, ctx, op1, rd, rs, rt);
460f00c4 14409 break;
7a387fff 14410 case OPC_MULT ... OPC_DIVU:
e9c71dd1
TS
14411 if (sa) {
14412 check_insn(env, ctx, INSN_VR54XX);
14413 op1 = MASK_MUL_VR54XX(ctx->opcode);
14414 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14415 } else
14416 gen_muldiv(ctx, op1, rs, rt);
7a387fff
TS
14417 break;
14418 case OPC_JR ... OPC_JALR:
7dca4ad0 14419 gen_compute_branch(ctx, op1, 4, rs, rd, sa);
c9602061
NF
14420 *is_branch = 1;
14421 break;
7a387fff
TS
14422 case OPC_TGE ... OPC_TEQ: /* Traps */
14423 case OPC_TNE:
14424 gen_trap(ctx, op1, rs, rt, -1);
6af0bf9c 14425 break;
7a387fff
TS
14426 case OPC_MFHI: /* Move from HI/LO */
14427 case OPC_MFLO:
14428 gen_HILO(ctx, op1, rd);
6af0bf9c 14429 break;
7a387fff
TS
14430 case OPC_MTHI:
14431 case OPC_MTLO: /* Move to HI/LO */
14432 gen_HILO(ctx, op1, rs);
6af0bf9c 14433 break;
b48cfdff
TS
14434 case OPC_PMON: /* Pmon entry point, also R4010 selsl */
14435#ifdef MIPS_STRICT_STANDARD
14436 MIPS_INVAL("PMON / selsl");
14437 generate_exception(ctx, EXCP_RI);
14438#else
895c2d04 14439 gen_helper_0e0i(pmon, sa);
b48cfdff 14440#endif
7a387fff
TS
14441 break;
14442 case OPC_SYSCALL:
6af0bf9c 14443 generate_exception(ctx, EXCP_SYSCALL);
8e0f950d 14444 ctx->bstate = BS_STOP;
6af0bf9c 14445 break;
7a387fff 14446 case OPC_BREAK:
6af0bf9c
FB
14447 generate_exception(ctx, EXCP_BREAK);
14448 break;
b48cfdff
TS
14449 case OPC_SPIM:
14450#ifdef MIPS_STRICT_STANDARD
14451 MIPS_INVAL("SPIM");
14452 generate_exception(ctx, EXCP_RI);
14453#else
7a387fff
TS
14454 /* Implemented as RI exception for now. */
14455 MIPS_INVAL("spim (unofficial)");
14456 generate_exception(ctx, EXCP_RI);
b48cfdff 14457#endif
6af0bf9c 14458 break;
7a387fff 14459 case OPC_SYNC:
ead9360e 14460 /* Treat as NOP. */
6af0bf9c 14461 break;
4ad40f36 14462
7a387fff 14463 case OPC_MOVCI:
e189e748 14464 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
36d23958 14465 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 14466 check_cp1_enabled(ctx);
36d23958
TS
14467 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14468 (ctx->opcode >> 16) & 1);
14469 } else {
e397ee33 14470 generate_exception_err(ctx, EXCP_CpU, 1);
36d23958 14471 }
4ad40f36
FB
14472 break;
14473
d26bc211 14474#if defined(TARGET_MIPS64)
7a387fff
TS
14475 /* MIPS64 specific opcodes */
14476 case OPC_DSLL:
324d9e32 14477 case OPC_DSRA:
7a387fff 14478 case OPC_DSLL32:
324d9e32 14479 case OPC_DSRA32:
e189e748
TS
14480 check_insn(env, ctx, ISA_MIPS3);
14481 check_mips_64(ctx);
324d9e32 14482 gen_shift_imm(env, ctx, op1, rd, rt, sa);
7a387fff 14483 break;
ea63e2c3
NF
14484 case OPC_DSRL:
14485 switch ((ctx->opcode >> 21) & 0x1f) {
14486 case 1:
14487 /* drotr is decoded as dsrl on non-R2 CPUs */
14488 if (env->insn_flags & ISA_MIPS32R2) {
14489 op1 = OPC_DROTR;
14490 }
14491 /* Fallthrough */
14492 case 0:
14493 check_insn(env, ctx, ISA_MIPS3);
14494 check_mips_64(ctx);
14495 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14496 break;
14497 default:
14498 generate_exception(ctx, EXCP_RI);
14499 break;
14500 }
14501 break;
14502 case OPC_DSRL32:
14503 switch ((ctx->opcode >> 21) & 0x1f) {
14504 case 1:
14505 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14506 if (env->insn_flags & ISA_MIPS32R2) {
14507 op1 = OPC_DROTR32;
14508 }
14509 /* Fallthrough */
14510 case 0:
14511 check_insn(env, ctx, ISA_MIPS3);
14512 check_mips_64(ctx);
14513 gen_shift_imm(env, ctx, op1, rd, rt, sa);
14514 break;
14515 default:
14516 generate_exception(ctx, EXCP_RI);
14517 break;
14518 }
14519 break;
7a387fff 14520 case OPC_DADD ... OPC_DSUBU:
e189e748
TS
14521 check_insn(env, ctx, ISA_MIPS3);
14522 check_mips_64(ctx);
14523 gen_arith(env, ctx, op1, rd, rs, rt);
7a387fff 14524 break;
460f00c4
AJ
14525 case OPC_DSLLV:
14526 case OPC_DSRAV:
460f00c4
AJ
14527 check_insn(env, ctx, ISA_MIPS3);
14528 check_mips_64(ctx);
14529 gen_shift(env, ctx, op1, rd, rs, rt);
14530 break;
ea63e2c3
NF
14531 case OPC_DSRLV:
14532 switch ((ctx->opcode >> 6) & 0x1f) {
14533 case 1:
14534 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14535 if (env->insn_flags & ISA_MIPS32R2) {
14536 op1 = OPC_DROTRV;
14537 }
14538 /* Fallthrough */
14539 case 0:
14540 check_insn(env, ctx, ISA_MIPS3);
14541 check_mips_64(ctx);
14542 gen_shift(env, ctx, op1, rd, rs, rt);
14543 break;
14544 default:
14545 generate_exception(ctx, EXCP_RI);
14546 break;
14547 }
14548 break;
7a387fff 14549 case OPC_DMULT ... OPC_DDIVU:
e189e748
TS
14550 check_insn(env, ctx, ISA_MIPS3);
14551 check_mips_64(ctx);
7a387fff
TS
14552 gen_muldiv(ctx, op1, rs, rt);
14553 break;
6af0bf9c
FB
14554#endif
14555 default: /* Invalid */
14556 MIPS_INVAL("special");
14557 generate_exception(ctx, EXCP_RI);
14558 break;
14559 }
14560 break;
7a387fff
TS
14561 case OPC_SPECIAL2:
14562 op1 = MASK_SPECIAL2(ctx->opcode);
6af0bf9c 14563 switch (op1) {
7a387fff
TS
14564 case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14565 case OPC_MSUB ... OPC_MSUBU:
e189e748 14566 check_insn(env, ctx, ISA_MIPS32);
7a387fff 14567 gen_muldiv(ctx, op1, rs, rt);
6af0bf9c 14568 break;
7a387fff 14569 case OPC_MUL:
e189e748 14570 gen_arith(env, ctx, op1, rd, rs, rt);
6af0bf9c 14571 break;
20e1fb52
AJ
14572 case OPC_CLO:
14573 case OPC_CLZ:
e189e748 14574 check_insn(env, ctx, ISA_MIPS32);
7a387fff 14575 gen_cl(ctx, op1, rd, rs);
6af0bf9c 14576 break;
7a387fff 14577 case OPC_SDBBP:
6af0bf9c
FB
14578 /* XXX: not clear which exception should be raised
14579 * when in debug mode...
14580 */
e189e748 14581 check_insn(env, ctx, ISA_MIPS32);
6af0bf9c
FB
14582 if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14583 generate_exception(ctx, EXCP_DBp);
14584 } else {
14585 generate_exception(ctx, EXCP_DBp);
14586 }
ead9360e 14587 /* Treat as NOP. */
6af0bf9c 14588 break;
161f85e6
AJ
14589 case OPC_DIV_G_2F:
14590 case OPC_DIVU_G_2F:
14591 case OPC_MULT_G_2F:
14592 case OPC_MULTU_G_2F:
14593 case OPC_MOD_G_2F:
14594 case OPC_MODU_G_2F:
14595 check_insn(env, ctx, INSN_LOONGSON2F);
14596 gen_loongson_integer(ctx, op1, rd, rs, rt);
14597 break;
d26bc211 14598#if defined(TARGET_MIPS64)
20e1fb52
AJ
14599 case OPC_DCLO:
14600 case OPC_DCLZ:
e189e748
TS
14601 check_insn(env, ctx, ISA_MIPS64);
14602 check_mips_64(ctx);
7a387fff
TS
14603 gen_cl(ctx, op1, rd, rs);
14604 break;
161f85e6
AJ
14605 case OPC_DMULT_G_2F:
14606 case OPC_DMULTU_G_2F:
14607 case OPC_DDIV_G_2F:
14608 case OPC_DDIVU_G_2F:
14609 case OPC_DMOD_G_2F:
14610 case OPC_DMODU_G_2F:
14611 check_insn(env, ctx, INSN_LOONGSON2F);
14612 gen_loongson_integer(ctx, op1, rd, rs, rt);
14613 break;
7a387fff 14614#endif
6af0bf9c
FB
14615 default: /* Invalid */
14616 MIPS_INVAL("special2");
14617 generate_exception(ctx, EXCP_RI);
14618 break;
14619 }
14620 break;
7a387fff 14621 case OPC_SPECIAL3:
2b0233ab
TS
14622 op1 = MASK_SPECIAL3(ctx->opcode);
14623 switch (op1) {
14624 case OPC_EXT:
14625 case OPC_INS:
14626 check_insn(env, ctx, ISA_MIPS32R2);
14627 gen_bitops(ctx, op1, rt, rs, sa, rd);
14628 break;
14629 case OPC_BSHFL:
14630 check_insn(env, ctx, ISA_MIPS32R2);
14631 op2 = MASK_BSHFL(ctx->opcode);
49bcf33c 14632 gen_bshfl(ctx, op2, rt, rd);
7a387fff 14633 break;
1579a72e 14634 case OPC_RDHWR:
26ebe468 14635 gen_rdhwr(env, ctx, rt, rd);
1579a72e 14636 break;
ead9360e 14637 case OPC_FORK:
7385ac0b 14638 check_insn(env, ctx, ASE_MT);
6c5c1e20 14639 {
35fbce2c
AJ
14640 TCGv t0 = tcg_temp_new();
14641 TCGv t1 = tcg_temp_new();
6c5c1e20
TS
14642
14643 gen_load_gpr(t0, rt);
14644 gen_load_gpr(t1, rs);
a7812ae4 14645 gen_helper_fork(t0, t1);
6c5c1e20
TS
14646 tcg_temp_free(t0);
14647 tcg_temp_free(t1);
14648 }
ead9360e
TS
14649 break;
14650 case OPC_YIELD:
7385ac0b 14651 check_insn(env, ctx, ASE_MT);
6c5c1e20 14652 {
35fbce2c 14653 TCGv t0 = tcg_temp_new();
6c5c1e20 14654
35fbce2c 14655 save_cpu_state(ctx, 1);
6c5c1e20 14656 gen_load_gpr(t0, rs);
895c2d04 14657 gen_helper_yield(t0, cpu_env, t0);
6c5c1e20
TS
14658 gen_store_gpr(t0, rd);
14659 tcg_temp_free(t0);
14660 }
ead9360e 14661 break;
161f85e6 14662 case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
161f85e6 14663 case OPC_MOD_G_2E ... OPC_MODU_G_2E:
461c08df
JL
14664 case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14665 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14666 * the same mask and op1. */
14667 if ((env->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14668 op2 = MASK_ADDUH_QB(ctx->opcode);
14669 switch (op2) {
14670 case OPC_ADDUH_QB:
14671 case OPC_ADDUH_R_QB:
14672 case OPC_ADDQH_PH:
14673 case OPC_ADDQH_R_PH:
14674 case OPC_ADDQH_W:
14675 case OPC_ADDQH_R_W:
14676 case OPC_SUBUH_QB:
14677 case OPC_SUBUH_R_QB:
14678 case OPC_SUBQH_PH:
14679 case OPC_SUBQH_R_PH:
14680 case OPC_SUBQH_W:
14681 case OPC_SUBQH_R_W:
14682 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14683 break;
a22260ae
JL
14684 case OPC_MUL_PH:
14685 case OPC_MUL_S_PH:
14686 case OPC_MULQ_S_W:
14687 case OPC_MULQ_RS_W:
14688 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14689 break;
461c08df
JL
14690 default:
14691 MIPS_INVAL("MASK ADDUH.QB");
14692 generate_exception(ctx, EXCP_RI);
14693 break;
14694 }
14695 } else if (env->insn_flags & INSN_LOONGSON2E) {
14696 gen_loongson_integer(ctx, op1, rd, rs, rt);
14697 } else {
14698 generate_exception(ctx, EXCP_RI);
14699 }
161f85e6 14700 break;
9b1a1d68
JL
14701 case OPC_LX_DSP:
14702 op2 = MASK_LX(ctx->opcode);
14703 switch (op2) {
14704#if defined(TARGET_MIPS64)
14705 case OPC_LDX:
14706#endif
14707 case OPC_LBUX:
14708 case OPC_LHX:
14709 case OPC_LWX:
14710 gen_mipsdsp_ld(env, ctx, op2, rd, rs, rt);
14711 break;
14712 default: /* Invalid */
14713 MIPS_INVAL("MASK LX");
14714 generate_exception(ctx, EXCP_RI);
14715 break;
14716 }
14717 break;
461c08df
JL
14718 case OPC_ABSQ_S_PH_DSP:
14719 op2 = MASK_ABSQ_S_PH(ctx->opcode);
14720 switch (op2) {
14721 case OPC_ABSQ_S_QB:
14722 case OPC_ABSQ_S_PH:
14723 case OPC_ABSQ_S_W:
14724 case OPC_PRECEQ_W_PHL:
14725 case OPC_PRECEQ_W_PHR:
14726 case OPC_PRECEQU_PH_QBL:
14727 case OPC_PRECEQU_PH_QBR:
14728 case OPC_PRECEQU_PH_QBLA:
14729 case OPC_PRECEQU_PH_QBRA:
14730 case OPC_PRECEU_PH_QBL:
14731 case OPC_PRECEU_PH_QBR:
14732 case OPC_PRECEU_PH_QBLA:
14733 case OPC_PRECEU_PH_QBRA:
14734 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14735 break;
1cb6686c
JL
14736 case OPC_BITREV:
14737 case OPC_REPL_QB:
14738 case OPC_REPLV_QB:
14739 case OPC_REPL_PH:
14740 case OPC_REPLV_PH:
14741 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14742 break;
461c08df
JL
14743 default:
14744 MIPS_INVAL("MASK ABSQ_S.PH");
14745 generate_exception(ctx, EXCP_RI);
14746 break;
14747 }
14748 break;
14749 case OPC_ADDU_QB_DSP:
14750 op2 = MASK_ADDU_QB(ctx->opcode);
14751 switch (op2) {
14752 case OPC_ADDQ_PH:
14753 case OPC_ADDQ_S_PH:
14754 case OPC_ADDQ_S_W:
14755 case OPC_ADDU_QB:
14756 case OPC_ADDU_S_QB:
14757 case OPC_ADDU_PH:
14758 case OPC_ADDU_S_PH:
14759 case OPC_SUBQ_PH:
14760 case OPC_SUBQ_S_PH:
14761 case OPC_SUBQ_S_W:
14762 case OPC_SUBU_QB:
14763 case OPC_SUBU_S_QB:
14764 case OPC_SUBU_PH:
14765 case OPC_SUBU_S_PH:
14766 case OPC_ADDSC:
14767 case OPC_ADDWC:
14768 case OPC_MODSUB:
14769 case OPC_RADDU_W_QB:
14770 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14771 break;
a22260ae
JL
14772 case OPC_MULEU_S_PH_QBL:
14773 case OPC_MULEU_S_PH_QBR:
14774 case OPC_MULQ_RS_PH:
14775 case OPC_MULEQ_S_W_PHL:
14776 case OPC_MULEQ_S_W_PHR:
14777 case OPC_MULQ_S_PH:
14778 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14779 break;
461c08df
JL
14780 default: /* Invalid */
14781 MIPS_INVAL("MASK ADDU.QB");
14782 generate_exception(ctx, EXCP_RI);
14783 break;
14784
14785 }
14786 break;
14787 case OPC_CMPU_EQ_QB_DSP:
14788 op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14789 switch (op2) {
14790 case OPC_PRECR_SRA_PH_W:
14791 case OPC_PRECR_SRA_R_PH_W:
14792 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14793 break;
14794 case OPC_PRECR_QB_PH:
14795 case OPC_PRECRQ_QB_PH:
14796 case OPC_PRECRQ_PH_W:
14797 case OPC_PRECRQ_RS_PH_W:
14798 case OPC_PRECRQU_S_QB_PH:
14799 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14800 break;
26690560
JL
14801 case OPC_CMPU_EQ_QB:
14802 case OPC_CMPU_LT_QB:
14803 case OPC_CMPU_LE_QB:
14804 case OPC_CMP_EQ_PH:
14805 case OPC_CMP_LT_PH:
14806 case OPC_CMP_LE_PH:
14807 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14808 break;
14809 case OPC_CMPGU_EQ_QB:
14810 case OPC_CMPGU_LT_QB:
14811 case OPC_CMPGU_LE_QB:
14812 case OPC_CMPGDU_EQ_QB:
14813 case OPC_CMPGDU_LT_QB:
14814 case OPC_CMPGDU_LE_QB:
14815 case OPC_PICK_QB:
14816 case OPC_PICK_PH:
14817 case OPC_PACKRL_PH:
14818 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14819 break;
461c08df
JL
14820 default: /* Invalid */
14821 MIPS_INVAL("MASK CMPU.EQ.QB");
14822 generate_exception(ctx, EXCP_RI);
14823 break;
14824 }
14825 break;
77c5fa8b
JL
14826 case OPC_SHLL_QB_DSP:
14827 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14828 break;
a22260ae
JL
14829 case OPC_DPA_W_PH_DSP:
14830 op2 = MASK_DPA_W_PH(ctx->opcode);
14831 switch (op2) {
14832 case OPC_DPAU_H_QBL:
14833 case OPC_DPAU_H_QBR:
14834 case OPC_DPSU_H_QBL:
14835 case OPC_DPSU_H_QBR:
14836 case OPC_DPA_W_PH:
14837 case OPC_DPAX_W_PH:
14838 case OPC_DPAQ_S_W_PH:
14839 case OPC_DPAQX_S_W_PH:
14840 case OPC_DPAQX_SA_W_PH:
14841 case OPC_DPS_W_PH:
14842 case OPC_DPSX_W_PH:
14843 case OPC_DPSQ_S_W_PH:
14844 case OPC_DPSQX_S_W_PH:
14845 case OPC_DPSQX_SA_W_PH:
14846 case OPC_MULSAQ_S_W_PH:
14847 case OPC_DPAQ_SA_L_W:
14848 case OPC_DPSQ_SA_L_W:
14849 case OPC_MAQ_S_W_PHL:
14850 case OPC_MAQ_S_W_PHR:
14851 case OPC_MAQ_SA_W_PHL:
14852 case OPC_MAQ_SA_W_PHR:
14853 case OPC_MULSA_W_PH:
14854 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14855 break;
14856 default: /* Invalid */
14857 MIPS_INVAL("MASK DPAW.PH");
14858 generate_exception(ctx, EXCP_RI);
14859 break;
14860 }
14861 break;
1cb6686c
JL
14862 case OPC_INSV_DSP:
14863 op2 = MASK_INSV(ctx->opcode);
14864 switch (op2) {
14865 case OPC_INSV:
14866 check_dsp(ctx);
14867 {
14868 TCGv t0, t1;
14869
14870 if (rt == 0) {
14871 MIPS_DEBUG("NOP");
14872 break;
14873 }
14874
14875 t0 = tcg_temp_new();
14876 t1 = tcg_temp_new();
14877
14878 gen_load_gpr(t0, rt);
14879 gen_load_gpr(t1, rs);
14880
14881 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14882
14883 tcg_temp_free(t0);
14884 tcg_temp_free(t1);
14885 break;
14886 }
14887 default: /* Invalid */
14888 MIPS_INVAL("MASK INSV");
14889 generate_exception(ctx, EXCP_RI);
14890 break;
14891 }
14892 break;
26690560
JL
14893 case OPC_APPEND_DSP:
14894 check_dspr2(ctx);
14895 op2 = MASK_APPEND(ctx->opcode);
14896 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
14897 break;
b53371ed
JL
14898 case OPC_EXTR_W_DSP:
14899 op2 = MASK_EXTR_W(ctx->opcode);
14900 switch (op2) {
14901 case OPC_EXTR_W:
14902 case OPC_EXTR_R_W:
14903 case OPC_EXTR_RS_W:
14904 case OPC_EXTR_S_H:
14905 case OPC_EXTRV_S_H:
14906 case OPC_EXTRV_W:
14907 case OPC_EXTRV_R_W:
14908 case OPC_EXTRV_RS_W:
14909 case OPC_EXTP:
14910 case OPC_EXTPV:
14911 case OPC_EXTPDP:
14912 case OPC_EXTPDPV:
14913 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14914 break;
14915 case OPC_RDDSP:
14916 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14917 break;
14918 case OPC_SHILO:
14919 case OPC_SHILOV:
14920 case OPC_MTHLIP:
14921 case OPC_WRDSP:
14922 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14923 break;
14924 default: /* Invalid */
14925 MIPS_INVAL("MASK EXTR.W");
14926 generate_exception(ctx, EXCP_RI);
14927 break;
14928 }
14929 break;
d26bc211 14930#if defined(TARGET_MIPS64)
1579a72e
TS
14931 case OPC_DEXTM ... OPC_DEXT:
14932 case OPC_DINSM ... OPC_DINS:
e189e748
TS
14933 check_insn(env, ctx, ISA_MIPS64R2);
14934 check_mips_64(ctx);
1579a72e 14935 gen_bitops(ctx, op1, rt, rs, sa, rd);
7a387fff 14936 break;
1579a72e 14937 case OPC_DBSHFL:
e189e748
TS
14938 check_insn(env, ctx, ISA_MIPS64R2);
14939 check_mips_64(ctx);
1579a72e 14940 op2 = MASK_DBSHFL(ctx->opcode);
49bcf33c 14941 gen_bshfl(ctx, op2, rt, rd);
c6d6dd7c 14942 break;
161f85e6
AJ
14943 case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
14944 case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
14945 case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
14946 check_insn(env, ctx, INSN_LOONGSON2E);
14947 gen_loongson_integer(ctx, op1, rd, rs, rt);
14948 break;
461c08df
JL
14949 case OPC_ABSQ_S_QH_DSP:
14950 op2 = MASK_ABSQ_S_QH(ctx->opcode);
14951 switch (op2) {
14952 case OPC_PRECEQ_L_PWL:
14953 case OPC_PRECEQ_L_PWR:
14954 case OPC_PRECEQ_PW_QHL:
14955 case OPC_PRECEQ_PW_QHR:
14956 case OPC_PRECEQ_PW_QHLA:
14957 case OPC_PRECEQ_PW_QHRA:
14958 case OPC_PRECEQU_QH_OBL:
14959 case OPC_PRECEQU_QH_OBR:
14960 case OPC_PRECEQU_QH_OBLA:
14961 case OPC_PRECEQU_QH_OBRA:
14962 case OPC_PRECEU_QH_OBL:
14963 case OPC_PRECEU_QH_OBR:
14964 case OPC_PRECEU_QH_OBLA:
14965 case OPC_PRECEU_QH_OBRA:
14966 case OPC_ABSQ_S_OB:
14967 case OPC_ABSQ_S_PW:
14968 case OPC_ABSQ_S_QH:
14969 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14970 break;
1cb6686c
JL
14971 case OPC_REPL_OB:
14972 case OPC_REPL_PW:
14973 case OPC_REPL_QH:
14974 case OPC_REPLV_OB:
14975 case OPC_REPLV_PW:
14976 case OPC_REPLV_QH:
14977 gen_mipsdsp_bitinsn(env, ctx, op1, op2, rd, rt);
14978 break;
461c08df
JL
14979 default: /* Invalid */
14980 MIPS_INVAL("MASK ABSQ_S.QH");
14981 generate_exception(ctx, EXCP_RI);
14982 break;
14983 }
14984 break;
14985 case OPC_ADDU_OB_DSP:
14986 op2 = MASK_ADDU_OB(ctx->opcode);
14987 switch (op2) {
14988 case OPC_RADDU_L_OB:
14989 case OPC_SUBQ_PW:
14990 case OPC_SUBQ_S_PW:
14991 case OPC_SUBQ_QH:
14992 case OPC_SUBQ_S_QH:
14993 case OPC_SUBU_OB:
14994 case OPC_SUBU_S_OB:
14995 case OPC_SUBU_QH:
14996 case OPC_SUBU_S_QH:
14997 case OPC_SUBUH_OB:
14998 case OPC_SUBUH_R_OB:
14999 case OPC_ADDQ_PW:
15000 case OPC_ADDQ_S_PW:
15001 case OPC_ADDQ_QH:
15002 case OPC_ADDQ_S_QH:
15003 case OPC_ADDU_OB:
15004 case OPC_ADDU_S_OB:
15005 case OPC_ADDU_QH:
15006 case OPC_ADDU_S_QH:
15007 case OPC_ADDUH_OB:
15008 case OPC_ADDUH_R_OB:
15009 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15010 break;
a22260ae
JL
15011 case OPC_MULEQ_S_PW_QHL:
15012 case OPC_MULEQ_S_PW_QHR:
15013 case OPC_MULEU_S_QH_OBL:
15014 case OPC_MULEU_S_QH_OBR:
15015 case OPC_MULQ_RS_QH:
15016 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15017 break;
461c08df
JL
15018 default: /* Invalid */
15019 MIPS_INVAL("MASK ADDU.OB");
15020 generate_exception(ctx, EXCP_RI);
15021 break;
15022 }
15023 break;
15024 case OPC_CMPU_EQ_OB_DSP:
15025 op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15026 switch (op2) {
15027 case OPC_PRECR_SRA_QH_PW:
15028 case OPC_PRECR_SRA_R_QH_PW:
15029 /* Return value is rt. */
15030 gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15031 break;
15032 case OPC_PRECR_OB_QH:
15033 case OPC_PRECRQ_OB_QH:
15034 case OPC_PRECRQ_PW_L:
15035 case OPC_PRECRQ_QH_PW:
15036 case OPC_PRECRQ_RS_QH_PW:
15037 case OPC_PRECRQU_S_OB_QH:
15038 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15039 break;
26690560
JL
15040 case OPC_CMPU_EQ_OB:
15041 case OPC_CMPU_LT_OB:
15042 case OPC_CMPU_LE_OB:
15043 case OPC_CMP_EQ_QH:
15044 case OPC_CMP_LT_QH:
15045 case OPC_CMP_LE_QH:
15046 case OPC_CMP_EQ_PW:
15047 case OPC_CMP_LT_PW:
15048 case OPC_CMP_LE_PW:
15049 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15050 break;
15051 case OPC_CMPGDU_EQ_OB:
15052 case OPC_CMPGDU_LT_OB:
15053 case OPC_CMPGDU_LE_OB:
15054 case OPC_CMPGU_EQ_OB:
15055 case OPC_CMPGU_LT_OB:
15056 case OPC_CMPGU_LE_OB:
15057 case OPC_PACKRL_PW:
15058 case OPC_PICK_OB:
15059 case OPC_PICK_PW:
15060 case OPC_PICK_QH:
15061 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15062 break;
461c08df
JL
15063 default: /* Invalid */
15064 MIPS_INVAL("MASK CMPU_EQ.OB");
15065 generate_exception(ctx, EXCP_RI);
15066 break;
15067 }
15068 break;
26690560
JL
15069 case OPC_DAPPEND_DSP:
15070 check_dspr2(ctx);
15071 op2 = MASK_DAPPEND(ctx->opcode);
15072 gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rt, rs, rd, 1);
15073 break;
b53371ed
JL
15074 case OPC_DEXTR_W_DSP:
15075 op2 = MASK_DEXTR_W(ctx->opcode);
15076 switch (op2) {
15077 case OPC_DEXTP:
15078 case OPC_DEXTPDP:
15079 case OPC_DEXTPDPV:
15080 case OPC_DEXTPV:
15081 case OPC_DEXTR_L:
15082 case OPC_DEXTR_R_L:
15083 case OPC_DEXTR_RS_L:
15084 case OPC_DEXTR_W:
15085 case OPC_DEXTR_R_W:
15086 case OPC_DEXTR_RS_W:
15087 case OPC_DEXTR_S_H:
15088 case OPC_DEXTRV_L:
15089 case OPC_DEXTRV_R_L:
15090 case OPC_DEXTRV_RS_L:
15091 case OPC_DEXTRV_S_H:
15092 case OPC_DEXTRV_W:
15093 case OPC_DEXTRV_R_W:
15094 case OPC_DEXTRV_RS_W:
15095 gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15096 break;
15097 case OPC_DMTHLIP:
15098 case OPC_DSHILO:
15099 case OPC_DSHILOV:
15100 gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15101 break;
15102 default: /* Invalid */
15103 MIPS_INVAL("MASK EXTR.W");
15104 generate_exception(ctx, EXCP_RI);
15105 break;
15106 }
15107 break;
a22260ae
JL
15108 case OPC_DPAQ_W_QH_DSP:
15109 op2 = MASK_DPAQ_W_QH(ctx->opcode);
15110 switch (op2) {
15111 case OPC_DPAU_H_OBL:
15112 case OPC_DPAU_H_OBR:
15113 case OPC_DPSU_H_OBL:
15114 case OPC_DPSU_H_OBR:
15115 case OPC_DPA_W_QH:
15116 case OPC_DPAQ_S_W_QH:
15117 case OPC_DPS_W_QH:
15118 case OPC_DPSQ_S_W_QH:
15119 case OPC_MULSAQ_S_W_QH:
15120 case OPC_DPAQ_SA_L_PW:
15121 case OPC_DPSQ_SA_L_PW:
15122 case OPC_MULSAQ_S_L_PW:
15123 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15124 break;
15125 case OPC_MAQ_S_W_QHLL:
15126 case OPC_MAQ_S_W_QHLR:
15127 case OPC_MAQ_S_W_QHRL:
15128 case OPC_MAQ_S_W_QHRR:
15129 case OPC_MAQ_SA_W_QHLL:
15130 case OPC_MAQ_SA_W_QHLR:
15131 case OPC_MAQ_SA_W_QHRL:
15132 case OPC_MAQ_SA_W_QHRR:
15133 case OPC_MAQ_S_L_PWL:
15134 case OPC_MAQ_S_L_PWR:
15135 case OPC_DMADD:
15136 case OPC_DMADDU:
15137 case OPC_DMSUB:
15138 case OPC_DMSUBU:
15139 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15140 break;
15141 default: /* Invalid */
15142 MIPS_INVAL("MASK DPAQ.W.QH");
15143 generate_exception(ctx, EXCP_RI);
15144 break;
15145 }
15146 break;
1cb6686c
JL
15147 case OPC_DINSV_DSP:
15148 op2 = MASK_INSV(ctx->opcode);
15149 switch (op2) {
15150 case OPC_DINSV:
15151 {
15152 TCGv t0, t1;
15153
15154 if (rt == 0) {
15155 MIPS_DEBUG("NOP");
15156 break;
15157 }
15158 check_dsp(ctx);
15159
15160 t0 = tcg_temp_new();
15161 t1 = tcg_temp_new();
15162
15163 gen_load_gpr(t0, rt);
15164 gen_load_gpr(t1, rs);
15165
15166 gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15167 break;
15168 }
15169 default: /* Invalid */
15170 MIPS_INVAL("MASK DINSV");
15171 generate_exception(ctx, EXCP_RI);
15172 break;
15173 }
15174 break;
77c5fa8b
JL
15175 case OPC_SHLL_OB_DSP:
15176 gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15177 break;
7a387fff
TS
15178#endif
15179 default: /* Invalid */
15180 MIPS_INVAL("special3");
15181 generate_exception(ctx, EXCP_RI);
15182 break;
15183 }
15184 break;
15185 case OPC_REGIMM:
15186 op1 = MASK_REGIMM(ctx->opcode);
15187 switch (op1) {
15188 case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15189 case OPC_BLTZAL ... OPC_BGEZALL:
7dca4ad0 15190 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
c9602061
NF
15191 *is_branch = 1;
15192 break;
7a387fff
TS
15193 case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15194 case OPC_TNEI:
15195 gen_trap(ctx, op1, rs, -1, imm);
15196 break;
15197 case OPC_SYNCI:
e189e748 15198 check_insn(env, ctx, ISA_MIPS32R2);
ead9360e 15199 /* Treat as NOP. */
6af0bf9c 15200 break;
e45a93e2
JL
15201 case OPC_BPOSGE32: /* MIPS DSP branch */
15202#if defined(TARGET_MIPS64)
15203 case OPC_BPOSGE64:
15204#endif
15205 check_dsp(ctx);
15206 gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15207 *is_branch = 1;
15208 break;
6af0bf9c 15209 default: /* Invalid */
923617a3 15210 MIPS_INVAL("regimm");
6af0bf9c
FB
15211 generate_exception(ctx, EXCP_RI);
15212 break;
15213 }
15214 break;
7a387fff 15215 case OPC_CP0:
387a8fe5 15216 check_cp0_enabled(ctx);
7a387fff 15217 op1 = MASK_CP0(ctx->opcode);
6af0bf9c 15218 switch (op1) {
7a387fff
TS
15219 case OPC_MFC0:
15220 case OPC_MTC0:
ead9360e
TS
15221 case OPC_MFTR:
15222 case OPC_MTTR:
d26bc211 15223#if defined(TARGET_MIPS64)
7a387fff
TS
15224 case OPC_DMFC0:
15225 case OPC_DMTC0:
15226#endif
f1aa6320 15227#ifndef CONFIG_USER_ONLY
932e71cd 15228 gen_cp0(env, ctx, op1, rt, rd);
0eaef5aa 15229#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15230 break;
15231 case OPC_C0_FIRST ... OPC_C0_LAST:
f1aa6320 15232#ifndef CONFIG_USER_ONLY
932e71cd 15233 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
0eaef5aa 15234#endif /* !CONFIG_USER_ONLY */
7a387fff
TS
15235 break;
15236 case OPC_MFMC0:
8706c382 15237#ifndef CONFIG_USER_ONLY
932e71cd 15238 {
35fbce2c 15239 TCGv t0 = tcg_temp_new();
6c5c1e20 15240
0eaef5aa 15241 op2 = MASK_MFMC0(ctx->opcode);
6c5c1e20
TS
15242 switch (op2) {
15243 case OPC_DMT:
15244 check_insn(env, ctx, ASE_MT);
9ed5726c 15245 gen_helper_dmt(t0);
35fbce2c 15246 gen_store_gpr(t0, rt);
6c5c1e20
TS
15247 break;
15248 case OPC_EMT:
15249 check_insn(env, ctx, ASE_MT);
9ed5726c 15250 gen_helper_emt(t0);
35fbce2c 15251 gen_store_gpr(t0, rt);
da80682b 15252 break;
6c5c1e20
TS
15253 case OPC_DVPE:
15254 check_insn(env, ctx, ASE_MT);
895c2d04 15255 gen_helper_dvpe(t0, cpu_env);
35fbce2c 15256 gen_store_gpr(t0, rt);
6c5c1e20
TS
15257 break;
15258 case OPC_EVPE:
15259 check_insn(env, ctx, ASE_MT);
895c2d04 15260 gen_helper_evpe(t0, cpu_env);
35fbce2c 15261 gen_store_gpr(t0, rt);
6c5c1e20
TS
15262 break;
15263 case OPC_DI:
15264 check_insn(env, ctx, ISA_MIPS32R2);
867abc7e 15265 save_cpu_state(ctx, 1);
895c2d04 15266 gen_helper_di(t0, cpu_env);
35fbce2c 15267 gen_store_gpr(t0, rt);
6c5c1e20
TS
15268 /* Stop translation as we may have switched the execution mode */
15269 ctx->bstate = BS_STOP;
15270 break;
15271 case OPC_EI:
15272 check_insn(env, ctx, ISA_MIPS32R2);
867abc7e 15273 save_cpu_state(ctx, 1);
895c2d04 15274 gen_helper_ei(t0, cpu_env);
35fbce2c 15275 gen_store_gpr(t0, rt);
6c5c1e20
TS
15276 /* Stop translation as we may have switched the execution mode */
15277 ctx->bstate = BS_STOP;
15278 break;
15279 default: /* Invalid */
15280 MIPS_INVAL("mfmc0");
15281 generate_exception(ctx, EXCP_RI);
15282 break;
15283 }
6c5c1e20 15284 tcg_temp_free(t0);
7a387fff 15285 }
0eaef5aa 15286#endif /* !CONFIG_USER_ONLY */
6af0bf9c 15287 break;
7a387fff 15288 case OPC_RDPGPR:
e189e748 15289 check_insn(env, ctx, ISA_MIPS32R2);
be24bb4f 15290 gen_load_srsgpr(rt, rd);
ead9360e 15291 break;
7a387fff 15292 case OPC_WRPGPR:
e189e748 15293 check_insn(env, ctx, ISA_MIPS32R2);
be24bb4f 15294 gen_store_srsgpr(rt, rd);
38121543 15295 break;
6af0bf9c 15296 default:
923617a3 15297 MIPS_INVAL("cp0");
7a387fff 15298 generate_exception(ctx, EXCP_RI);
6af0bf9c
FB
15299 break;
15300 }
15301 break;
324d9e32
AJ
15302 case OPC_ADDI: /* Arithmetic with immediate opcode */
15303 case OPC_ADDIU:
e189e748 15304 gen_arith_imm(env, ctx, op, rt, rs, imm);
7a387fff 15305 break;
324d9e32
AJ
15306 case OPC_SLTI: /* Set on less than with immediate opcode */
15307 case OPC_SLTIU:
9fa77488 15308 gen_slt_imm(env, ctx, op, rt, rs, imm);
324d9e32
AJ
15309 break;
15310 case OPC_ANDI: /* Arithmetic with immediate opcode */
15311 case OPC_LUI:
15312 case OPC_ORI:
15313 case OPC_XORI:
9fa77488 15314 gen_logic_imm(env, ctx, op, rt, rs, imm);
324d9e32 15315 break;
7a387fff
TS
15316 case OPC_J ... OPC_JAL: /* Jump */
15317 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7dca4ad0 15318 gen_compute_branch(ctx, op, 4, rs, rt, offset);
c9602061
NF
15319 *is_branch = 1;
15320 break;
7a387fff
TS
15321 case OPC_BEQ ... OPC_BGTZ: /* Branch */
15322 case OPC_BEQL ... OPC_BGTZL:
7dca4ad0 15323 gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
c9602061
NF
15324 *is_branch = 1;
15325 break;
7a387fff 15326 case OPC_LB ... OPC_LWR: /* Load and stores */
5c13fdfd 15327 case OPC_LL:
afa88c3a 15328 gen_ld(env, ctx, op, rt, rs, imm);
5c13fdfd 15329 break;
7a387fff
TS
15330 case OPC_SB ... OPC_SW:
15331 case OPC_SWR:
5c13fdfd 15332 gen_st(ctx, op, rt, rs, imm);
7a387fff 15333 break;
d66c7132
AJ
15334 case OPC_SC:
15335 gen_st_cond(ctx, op, rt, rs, imm);
15336 break;
7a387fff 15337 case OPC_CACHE:
2e15497c 15338 check_cp0_enabled(ctx);
e189e748 15339 check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
ead9360e 15340 /* Treat as NOP. */
34ae7b51 15341 break;
7a387fff 15342 case OPC_PREF:
e189e748 15343 check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
ead9360e 15344 /* Treat as NOP. */
6af0bf9c 15345 break;
4ad40f36 15346
923617a3 15347 /* Floating point (COP1). */
7a387fff
TS
15348 case OPC_LWC1:
15349 case OPC_LDC1:
15350 case OPC_SWC1:
15351 case OPC_SDC1:
26ebe468 15352 gen_cop1_ldst(env, ctx, op, rt, rs, imm);
6ea83fed
FB
15353 break;
15354
7a387fff 15355 case OPC_CP1:
36d23958 15356 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15357 check_cp1_enabled(ctx);
36d23958
TS
15358 op1 = MASK_CP1(ctx->opcode);
15359 switch (op1) {
3a95e3a7
TS
15360 case OPC_MFHC1:
15361 case OPC_MTHC1:
e189e748 15362 check_insn(env, ctx, ISA_MIPS32R2);
36d23958
TS
15363 case OPC_MFC1:
15364 case OPC_CFC1:
15365 case OPC_MTC1:
15366 case OPC_CTC1:
e189e748
TS
15367 gen_cp1(ctx, op1, rt, rd);
15368 break;
d26bc211 15369#if defined(TARGET_MIPS64)
36d23958
TS
15370 case OPC_DMFC1:
15371 case OPC_DMTC1:
e189e748 15372 check_insn(env, ctx, ISA_MIPS3);
36d23958
TS
15373 gen_cp1(ctx, op1, rt, rd);
15374 break;
e189e748 15375#endif
fbcc6828
TS
15376 case OPC_BC1ANY2:
15377 case OPC_BC1ANY4:
b8aa4598 15378 check_cop1x(ctx);
7385ac0b 15379 check_insn(env, ctx, ASE_MIPS3D);
d8a5950a
TS
15380 /* fall through */
15381 case OPC_BC1:
e189e748 15382 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
5a5012ec 15383 (rt >> 2) & 0x7, imm << 2);
c9602061
NF
15384 *is_branch = 1;
15385 break;
36d23958
TS
15386 case OPC_S_FMT:
15387 case OPC_D_FMT:
15388 case OPC_W_FMT:
15389 case OPC_L_FMT:
5a5012ec 15390 case OPC_PS_FMT:
bf4120ad 15391 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
5a5012ec 15392 (imm >> 8) & 0x7);
36d23958
TS
15393 break;
15394 default:
923617a3 15395 MIPS_INVAL("cp1");
e397ee33 15396 generate_exception (ctx, EXCP_RI);
36d23958
TS
15397 break;
15398 }
15399 } else {
15400 generate_exception_err(ctx, EXCP_CpU, 1);
6ea83fed 15401 }
4ad40f36
FB
15402 break;
15403
15404 /* COP2. */
7a387fff
TS
15405 case OPC_LWC2:
15406 case OPC_LDC2:
15407 case OPC_SWC2:
15408 case OPC_SDC2:
7a387fff 15409 /* COP2: Not implemented. */
4ad40f36
FB
15410 generate_exception_err(ctx, EXCP_CpU, 2);
15411 break;
bd277fa1
RH
15412 case OPC_CP2:
15413 check_insn(env, ctx, INSN_LOONGSON2F);
15414 /* Note that these instructions use different fields. */
15415 gen_loongson_multimedia(ctx, sa, rd, rt);
15416 break;
4ad40f36 15417
7a387fff 15418 case OPC_CP3:
36d23958 15419 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5e755519 15420 check_cp1_enabled(ctx);
36d23958
TS
15421 op1 = MASK_CP3(ctx->opcode);
15422 switch (op1) {
5a5012ec
TS
15423 case OPC_LWXC1:
15424 case OPC_LDXC1:
15425 case OPC_LUXC1:
15426 case OPC_SWXC1:
15427 case OPC_SDXC1:
15428 case OPC_SUXC1:
93b12ccc 15429 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5a5012ec 15430 break;
e0c84da7 15431 case OPC_PREFX:
ead9360e 15432 /* Treat as NOP. */
e0c84da7 15433 break;
5a5012ec
TS
15434 case OPC_ALNV_PS:
15435 case OPC_MADD_S:
15436 case OPC_MADD_D:
15437 case OPC_MADD_PS:
15438 case OPC_MSUB_S:
15439 case OPC_MSUB_D:
15440 case OPC_MSUB_PS:
15441 case OPC_NMADD_S:
15442 case OPC_NMADD_D:
15443 case OPC_NMADD_PS:
15444 case OPC_NMSUB_S:
15445 case OPC_NMSUB_D:
15446 case OPC_NMSUB_PS:
15447 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15448 break;
36d23958 15449 default:
923617a3 15450 MIPS_INVAL("cp3");
e397ee33 15451 generate_exception (ctx, EXCP_RI);
36d23958
TS
15452 break;
15453 }
15454 } else {
e397ee33 15455 generate_exception_err(ctx, EXCP_CpU, 1);
7a387fff 15456 }
4ad40f36
FB
15457 break;
15458
d26bc211 15459#if defined(TARGET_MIPS64)
7a387fff
TS
15460 /* MIPS64 opcodes */
15461 case OPC_LWU:
15462 case OPC_LDL ... OPC_LDR:
7a387fff
TS
15463 case OPC_LLD:
15464 case OPC_LD:
5c13fdfd
AJ
15465 check_insn(env, ctx, ISA_MIPS3);
15466 check_mips_64(ctx);
afa88c3a 15467 gen_ld(env, ctx, op, rt, rs, imm);
5c13fdfd
AJ
15468 break;
15469 case OPC_SDL ... OPC_SDR:
7a387fff 15470 case OPC_SD:
e189e748
TS
15471 check_insn(env, ctx, ISA_MIPS3);
15472 check_mips_64(ctx);
5c13fdfd 15473 gen_st(ctx, op, rt, rs, imm);
7a387fff 15474 break;
d66c7132
AJ
15475 case OPC_SCD:
15476 check_insn(env, ctx, ISA_MIPS3);
15477 check_mips_64(ctx);
15478 gen_st_cond(ctx, op, rt, rs, imm);
15479 break;
324d9e32
AJ
15480 case OPC_DADDI:
15481 case OPC_DADDIU:
e189e748
TS
15482 check_insn(env, ctx, ISA_MIPS3);
15483 check_mips_64(ctx);
15484 gen_arith_imm(env, ctx, op, rt, rs, imm);
7a387fff 15485 break;
6af0bf9c 15486#endif
7a387fff 15487 case OPC_JALX:
3c824109 15488 check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
364d4831
NF
15489 offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15490 gen_compute_branch(ctx, op, 4, rs, rt, offset);
15491 *is_branch = 1;
15492 break;
7a387fff 15493 case OPC_MDMX:
e189e748 15494 check_insn(env, ctx, ASE_MDMX);
7a387fff 15495 /* MDMX: Not implemented. */
6af0bf9c 15496 default: /* Invalid */
923617a3 15497 MIPS_INVAL("major opcode");
6af0bf9c
FB
15498 generate_exception(ctx, EXCP_RI);
15499 break;
15500 }
6af0bf9c
FB
15501}
15502
2cfc5f17 15503static inline void
7db13fae 15504gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
820e00f2 15505 int search_pc)
6af0bf9c 15506{
278d0702 15507 DisasContext ctx;
6af0bf9c
FB
15508 target_ulong pc_start;
15509 uint16_t *gen_opc_end;
a1d1bb31 15510 CPUBreakpoint *bp;
6af0bf9c 15511 int j, lj = -1;
2e70f6ef
PB
15512 int num_insns;
15513 int max_insns;
c9602061
NF
15514 int insn_bytes;
15515 int is_branch;
6af0bf9c 15516
93fcfe39
AL
15517 if (search_pc)
15518 qemu_log("search pc %d\n", search_pc);
4ad40f36 15519
6af0bf9c 15520 pc_start = tb->pc;
d42320c2 15521 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
6af0bf9c 15522 ctx.pc = pc_start;
4ad40f36 15523 ctx.saved_pc = -1;
7b270ef2 15524 ctx.singlestep_enabled = env->singlestep_enabled;
6af0bf9c
FB
15525 ctx.tb = tb;
15526 ctx.bstate = BS_NONE;
4ad40f36 15527 /* Restore delay slot state from the tb context. */
c068688b 15528 ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
fd4a04eb 15529 restore_cpu_state(env, &ctx);
932e71cd 15530#ifdef CONFIG_USER_ONLY
0eaef5aa 15531 ctx.mem_idx = MIPS_HFLAG_UM;
932e71cd 15532#else
0eaef5aa 15533 ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
932e71cd 15534#endif
2e70f6ef
PB
15535 num_insns = 0;
15536 max_insns = tb->cflags & CF_COUNT_MASK;
15537 if (max_insns == 0)
15538 max_insns = CF_COUNT_MASK;
d12d51d5 15539 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
2e70f6ef 15540 gen_icount_start();
faf7aaa9 15541 while (ctx.bstate == BS_NONE) {
72cf2d4f
BS
15542 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15543 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 15544 if (bp->pc == ctx.pc) {
278d0702 15545 save_cpu_state(&ctx, 1);
4ad40f36 15546 ctx.bstate = BS_BRANCH;
895c2d04 15547 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
ce62e5ba
TS
15548 /* Include the breakpoint location or the tb won't
15549 * be flushed when it must be. */
15550 ctx.pc += 4;
4ad40f36
FB
15551 goto done_generating;
15552 }
15553 }
15554 }
15555
6af0bf9c
FB
15556 if (search_pc) {
15557 j = gen_opc_ptr - gen_opc_buf;
6af0bf9c
FB
15558 if (lj < j) {
15559 lj++;
15560 while (lj < j)
15561 gen_opc_instr_start[lj++] = 0;
6af0bf9c 15562 }
4ad40f36
FB
15563 gen_opc_pc[lj] = ctx.pc;
15564 gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
4636401d 15565 gen_opc_btarget[lj] = ctx.btarget;
4ad40f36 15566 gen_opc_instr_start[lj] = 1;
2e70f6ef 15567 gen_opc_icount[lj] = num_insns;
6af0bf9c 15568 }
2e70f6ef
PB
15569 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15570 gen_io_start();
c9602061
NF
15571
15572 is_branch = 0;
364d4831 15573 if (!(ctx.hflags & MIPS_HFLAG_M16)) {
895c2d04 15574 ctx.opcode = cpu_ldl_code(env, ctx.pc);
c9602061
NF
15575 insn_bytes = 4;
15576 decode_opc(env, &ctx, &is_branch);
3c824109 15577 } else if (env->insn_flags & ASE_MICROMIPS) {
895c2d04 15578 ctx.opcode = cpu_lduw_code(env, ctx.pc);
3c824109 15579 insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
364d4831 15580 } else if (env->insn_flags & ASE_MIPS16) {
895c2d04 15581 ctx.opcode = cpu_lduw_code(env, ctx.pc);
364d4831 15582 insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
c9602061
NF
15583 } else {
15584 generate_exception(&ctx, EXCP_RI);
3c824109 15585 ctx.bstate = BS_STOP;
c9602061
NF
15586 break;
15587 }
15588 if (!is_branch) {
15589 handle_delay_slot(env, &ctx, insn_bytes);
15590 }
15591 ctx.pc += insn_bytes;
15592
2e70f6ef 15593 num_insns++;
4ad40f36 15594
7b270ef2
NF
15595 /* Execute a branch and its delay slot as a single instruction.
15596 This is what GDB expects and is consistent with what the
15597 hardware does (e.g. if a delay slot instruction faults, the
15598 reported PC is the PC of the branch). */
15599 if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
4ad40f36
FB
15600 break;
15601
6af0bf9c
FB
15602 if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15603 break;
4ad40f36 15604
faf7aaa9
TS
15605 if (gen_opc_ptr >= gen_opc_end)
15606 break;
15607
2e70f6ef
PB
15608 if (num_insns >= max_insns)
15609 break;
1b530a6d
AJ
15610
15611 if (singlestep)
15612 break;
6af0bf9c 15613 }
2e70f6ef
PB
15614 if (tb->cflags & CF_LAST_IO)
15615 gen_io_end();
7b270ef2 15616 if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
278d0702 15617 save_cpu_state(&ctx, ctx.bstate == BS_NONE);
895c2d04 15618 gen_helper_0e0i(raise_exception, EXCP_DEBUG);
16c00cb2 15619 } else {
6958549d 15620 switch (ctx.bstate) {
16c00cb2 15621 case BS_STOP:
df1561e2
TS
15622 gen_goto_tb(&ctx, 0, ctx.pc);
15623 break;
16c00cb2 15624 case BS_NONE:
278d0702 15625 save_cpu_state(&ctx, 0);
16c00cb2
TS
15626 gen_goto_tb(&ctx, 0, ctx.pc);
15627 break;
5a5012ec 15628 case BS_EXCP:
57fec1fe 15629 tcg_gen_exit_tb(0);
16c00cb2 15630 break;
5a5012ec
TS
15631 case BS_BRANCH:
15632 default:
15633 break;
6958549d 15634 }
6af0bf9c 15635 }
4ad40f36 15636done_generating:
2e70f6ef 15637 gen_icount_end(tb, num_insns);
6af0bf9c
FB
15638 *gen_opc_ptr = INDEX_op_end;
15639 if (search_pc) {
15640 j = gen_opc_ptr - gen_opc_buf;
15641 lj++;
15642 while (lj <= j)
15643 gen_opc_instr_start[lj++] = 0;
6af0bf9c
FB
15644 } else {
15645 tb->size = ctx.pc - pc_start;
2e70f6ef 15646 tb->icount = num_insns;
6af0bf9c
FB
15647 }
15648#ifdef DEBUG_DISAS
d12d51d5 15649 LOG_DISAS("\n");
8fec2b8c 15650 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39
AL
15651 qemu_log("IN: %s\n", lookup_symbol(pc_start));
15652 log_target_disas(pc_start, ctx.pc - pc_start, 0);
15653 qemu_log("\n");
6af0bf9c
FB
15654 }
15655#endif
6af0bf9c
FB
15656}
15657
7db13fae 15658void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15659{
2cfc5f17 15660 gen_intermediate_code_internal(env, tb, 0);
6af0bf9c
FB
15661}
15662
7db13fae 15663void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
6af0bf9c 15664{
2cfc5f17 15665 gen_intermediate_code_internal(env, tb, 1);
6af0bf9c
FB
15666}
15667
7db13fae 15668static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
8706c382 15669 int flags)
6ea83fed
FB
15670{
15671 int i;
5e755519 15672 int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5a5012ec 15673
2a5612e6
SW
15674#define printfpr(fp) \
15675 do { \
15676 if (is_fpu64) \
15677 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15678 " fd:%13g fs:%13g psu: %13g\n", \
15679 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15680 (double)(fp)->fd, \
15681 (double)(fp)->fs[FP_ENDIAN_IDX], \
15682 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15683 else { \
15684 fpr_t tmp; \
15685 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15686 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15687 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15688 " fd:%13g fs:%13g psu:%13g\n", \
15689 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15690 (double)tmp.fd, \
15691 (double)tmp.fs[FP_ENDIAN_IDX], \
15692 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15693 } \
6ea83fed
FB
15694 } while(0)
15695
5a5012ec 15696
9a78eead
SW
15697 fpu_fprintf(f, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15698 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
f01be154 15699 get_float_exception_flags(&env->active_fpu.fp_status));
5a5012ec
TS
15700 for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15701 fpu_fprintf(f, "%3s: ", fregnames[i]);
f01be154 15702 printfpr(&env->active_fpu.fpr[i]);
6ea83fed
FB
15703 }
15704
15705#undef printfpr
15706}
15707
d26bc211 15708#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16 15709/* Debug help: The architecture requires 32bit code to maintain proper
c7e8a937 15710 sign-extended values on 64bit machines. */
c570fd16
TS
15711
15712#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15713
8706c382 15714static void
7db13fae 15715cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
9a78eead 15716 fprintf_function cpu_fprintf,
8706c382 15717 int flags)
c570fd16
TS
15718{
15719 int i;
15720
b5dc7732
TS
15721 if (!SIGN_EXT_P(env->active_tc.PC))
15722 cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15723 if (!SIGN_EXT_P(env->active_tc.HI[0]))
15724 cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15725 if (!SIGN_EXT_P(env->active_tc.LO[0]))
15726 cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
c570fd16 15727 if (!SIGN_EXT_P(env->btarget))
3594c774 15728 cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
c570fd16
TS
15729
15730 for (i = 0; i < 32; i++) {
b5dc7732
TS
15731 if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15732 cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
c570fd16
TS
15733 }
15734
15735 if (!SIGN_EXT_P(env->CP0_EPC))
3594c774 15736 cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
5499b6ff
AJ
15737 if (!SIGN_EXT_P(env->lladdr))
15738 cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
c570fd16
TS
15739}
15740#endif
15741
7db13fae 15742void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
6af0bf9c
FB
15743 int flags)
15744{
15745 int i;
3b46e624 15746
a7200c9f
SW
15747 cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15748 " LO=0x" TARGET_FMT_lx " ds %04x "
15749 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
3d5be870
TS
15750 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15751 env->hflags, env->btarget, env->bcond);
6af0bf9c
FB
15752 for (i = 0; i < 32; i++) {
15753 if ((i & 3) == 0)
15754 cpu_fprintf(f, "GPR%02d:", i);
b5dc7732 15755 cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
6af0bf9c
FB
15756 if ((i & 3) == 3)
15757 cpu_fprintf(f, "\n");
15758 }
568b600d 15759
3594c774 15760 cpu_fprintf(f, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx "\n",
5e755519 15761 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
3594c774 15762 cpu_fprintf(f, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
5499b6ff 15763 env->CP0_Config0, env->CP0_Config1, env->lladdr);
5e755519 15764 if (env->hflags & MIPS_HFLAG_FPU)
7a387fff 15765 fpu_dump_state(env, f, cpu_fprintf, flags);
d26bc211 15766#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
c570fd16
TS
15767 cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15768#endif
6af0bf9c
FB
15769}
15770
39454628
TS
15771static void mips_tcg_init(void)
15772{
f01be154 15773 int i;
39454628
TS
15774 static int inited;
15775
15776 /* Initialize various static tables. */
15777 if (inited)
6958549d 15778 return;
39454628 15779
a7812ae4 15780 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
f2c94b92 15781 TCGV_UNUSED(cpu_gpr[0]);
bb928dbe 15782 for (i = 1; i < 32; i++)
a7812ae4 15783 cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15784 offsetof(CPUMIPSState, active_tc.gpr[i]),
4b2eb8d2 15785 regnames[i]);
d73ee8a2
RH
15786
15787 for (i = 0; i < 32; i++) {
15788 int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15789 fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15790 }
15791
a7812ae4 15792 cpu_PC = tcg_global_mem_new(TCG_AREG0,
7db13fae 15793 offsetof(CPUMIPSState, active_tc.PC), "PC");
4b2eb8d2 15794 for (i = 0; i < MIPS_DSP_ACC; i++) {
a7812ae4 15795 cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15796 offsetof(CPUMIPSState, active_tc.HI[i]),
4b2eb8d2 15797 regnames_HI[i]);
a7812ae4 15798 cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15799 offsetof(CPUMIPSState, active_tc.LO[i]),
4b2eb8d2 15800 regnames_LO[i]);
a7812ae4 15801 cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
7db13fae 15802 offsetof(CPUMIPSState, active_tc.ACX[i]),
4b2eb8d2
TS
15803 regnames_ACX[i]);
15804 }
a7812ae4 15805 cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
7db13fae 15806 offsetof(CPUMIPSState, active_tc.DSPControl),
4b2eb8d2 15807 "DSPControl");
1ba74fb8 15808 bcond = tcg_global_mem_new(TCG_AREG0,
7db13fae 15809 offsetof(CPUMIPSState, bcond), "bcond");
a7812ae4 15810 btarget = tcg_global_mem_new(TCG_AREG0,
7db13fae 15811 offsetof(CPUMIPSState, btarget), "btarget");
41db4607 15812 hflags = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15813 offsetof(CPUMIPSState, hflags), "hflags");
41db4607 15814
a7812ae4 15815 fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15816 offsetof(CPUMIPSState, active_fpu.fcr0),
a7812ae4
PB
15817 "fcr0");
15818 fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
7db13fae 15819 offsetof(CPUMIPSState, active_fpu.fcr31),
a7812ae4 15820 "fcr31");
39454628 15821
7dd9e556 15822 /* register helpers */
a7812ae4 15823#define GEN_HELPER 2
7dd9e556
TS
15824#include "helper.h"
15825
39454628
TS
15826 inited = 1;
15827}
15828
aaed909a
FB
15829#include "translate_init.c"
15830
30bf942d 15831MIPSCPU *cpu_mips_init(const char *cpu_model)
6af0bf9c 15832{
0f71a709 15833 MIPSCPU *cpu;
6af0bf9c 15834 CPUMIPSState *env;
c227f099 15835 const mips_def_t *def;
6af0bf9c 15836
aaed909a
FB
15837 def = cpu_mips_find_by_name(cpu_model);
15838 if (!def)
15839 return NULL;
0f71a709
AF
15840 cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15841 env = &cpu->env;
aaed909a 15842 env->cpu_model = def;
51cc2e78 15843 env->cpu_model_str = cpu_model;
aaed909a 15844
51cc2e78
BS
15845#ifndef CONFIG_USER_ONLY
15846 mmu_init(env, def);
15847#endif
15848 fpu_init(env, def);
15849 mvp_init(env, def);
39454628 15850 mips_tcg_init();
3bd4122e 15851 cpu_reset(CPU(cpu));
0bf46a40 15852 qemu_init_vcpu(env);
30bf942d 15853 return cpu;
6ae81775
TS
15854}
15855
1bba0dc9 15856void cpu_state_reset(CPUMIPSState *env)
6ae81775 15857{
eca1bdf4
AL
15858 if (qemu_loglevel_mask(CPU_LOG_RESET)) {
15859 qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
15860 log_cpu_state(env, 0);
15861 }
15862
6ae81775 15863 memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6af0bf9c 15864 tlb_flush(env, 1);
6ae81775 15865
51cc2e78
BS
15866 /* Reset registers to their default values */
15867 env->CP0_PRid = env->cpu_model->CP0_PRid;
15868 env->CP0_Config0 = env->cpu_model->CP0_Config0;
15869#ifdef TARGET_WORDS_BIGENDIAN
15870 env->CP0_Config0 |= (1 << CP0C0_BE);
15871#endif
15872 env->CP0_Config1 = env->cpu_model->CP0_Config1;
15873 env->CP0_Config2 = env->cpu_model->CP0_Config2;
15874 env->CP0_Config3 = env->cpu_model->CP0_Config3;
15875 env->CP0_Config6 = env->cpu_model->CP0_Config6;
15876 env->CP0_Config7 = env->cpu_model->CP0_Config7;
2a6e32dd
AJ
15877 env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15878 << env->cpu_model->CP0_LLAddr_shift;
15879 env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
51cc2e78
BS
15880 env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15881 env->CCRes = env->cpu_model->CCRes;
15882 env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15883 env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15884 env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15885 env->current_tc = 0;
15886 env->SEGBITS = env->cpu_model->SEGBITS;
15887 env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15888#if defined(TARGET_MIPS64)
15889 if (env->cpu_model->insn_flags & ISA_MIPS3) {
15890 env->SEGMask |= 3ULL << 62;
15891 }
15892#endif
15893 env->PABITS = env->cpu_model->PABITS;
15894 env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15895 env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15896 env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15897 env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15898 env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15899 env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15900 env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15901 env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15902 env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15903 env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15904 env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
f1cb0951 15905 env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
51cc2e78
BS
15906 env->insn_flags = env->cpu_model->insn_flags;
15907
0eaef5aa 15908#if defined(CONFIG_USER_ONLY)
03e6e501 15909 env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
94159135
MI
15910 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15911 hardware registers. */
15912 env->CP0_HWREna |= 0x0000000F;
91a75935 15913 if (env->CP0_Config1 & (1 << CP0C1_FP)) {
03e6e501 15914 env->CP0_Status |= (1 << CP0St_CU1);
91a75935 15915 }
853c3240
JL
15916 if (env->cpu_model->insn_flags & ASE_DSPR2) {
15917 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
15918 } else if (env->cpu_model->insn_flags & ASE_DSP) {
15919 env->hflags |= MIPS_HFLAG_DSP;
15920 }
932e71cd
AJ
15921#else
15922 if (env->hflags & MIPS_HFLAG_BMASK) {
15923 /* If the exception was raised from a delay slot,
15924 come back to the jump. */
15925 env->CP0_ErrorEPC = env->active_tc.PC - 4;
aa328add 15926 } else {
932e71cd
AJ
15927 env->CP0_ErrorEPC = env->active_tc.PC;
15928 }
15929 env->active_tc.PC = (int32_t)0xBFC00000;
51cc2e78
BS
15930 env->CP0_Random = env->tlb->nb_tlb - 1;
15931 env->tlb->tlb_in_use = env->tlb->nb_tlb;
932e71cd 15932 env->CP0_Wired = 0;
671b0f36 15933 env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
932e71cd
AJ
15934 env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
15935 /* vectored interrupts not implemented, timer on int 7,
15936 no performance counters. */
15937 env->CP0_IntCtl = 0xe0000000;
15938 {
15939 int i;
15940
15941 for (i = 0; i < 7; i++) {
15942 env->CP0_WatchLo[i] = 0;
15943 env->CP0_WatchHi[i] = 0x80000000;
fd88b6ab 15944 }
932e71cd
AJ
15945 env->CP0_WatchLo[7] = 0;
15946 env->CP0_WatchHi[7] = 0;
fd88b6ab 15947 }
932e71cd
AJ
15948 /* Count register increments in debug mode, EJTAG version 1 */
15949 env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
9e56e756
EI
15950
15951 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
15952 int i;
15953
15954 /* Only TC0 on VPE 0 starts as active. */
15955 for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
15956 env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
15957 env->tcs[i].CP0_TCHalt = 1;
15958 }
15959 env->active_tc.CP0_TCHalt = 1;
15960 env->halted = 1;
15961
15962 if (!env->cpu_index) {
15963 /* VPE0 starts up enabled. */
15964 env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
15965 env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
15966
15967 /* TC0 starts up unhalted. */
15968 env->halted = 0;
15969 env->active_tc.CP0_TCHalt = 0;
15970 env->tcs[0].CP0_TCHalt = 0;
15971 /* With thread 0 active. */
15972 env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
15973 env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
15974 }
15975 }
51cc2e78 15976#endif
03e6e501 15977 compute_hflags(env);
6af0bf9c 15978 env->exception_index = EXCP_NONE;
6af0bf9c 15979}
d2856f1a 15980
7db13fae 15981void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
d2856f1a 15982{
b5dc7732 15983 env->active_tc.PC = gen_opc_pc[pc_pos];
d2856f1a
AJ
15984 env->hflags &= ~MIPS_HFLAG_BMASK;
15985 env->hflags |= gen_opc_hflags[pc_pos];
4636401d
AJ
15986 switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
15987 case MIPS_HFLAG_BR:
15988 break;
15989 case MIPS_HFLAG_BC:
15990 case MIPS_HFLAG_BL:
15991 case MIPS_HFLAG_B:
15992 env->btarget = gen_opc_btarget[pc_pos];
15993 break;
15994 }
d2856f1a 15995}